9
$\begingroup$

I do have FEM mesh related question. I am trying to mesh some inclusion from a png file using ToElementMesh. Thats working quite nicely even for more complex structures.

<< NDSolve`FEM`
img = Import[NotebookDirectory[] <> "2_round_inclusions.png"];
Show[img, Axes -> True]

enter image description here

mesh = ToElementMesh[img, "RegionHoles" -> None, 
  "RegionMarker" -> {{{150, 250}, 1, 100}, {{400, 125}, 1, 
     100}, {{1, 1}, 1, 1000}}]

enter image description here

But now I want to have another inclusion within both inclusions and that seem not to work out straight forward. I tried to do it the same way as before:

<< NDSolve`FEM`
img = Import[NotebookDirectory[] <> "grain_in_grain.png"];
Show[img, Axes -> True]

enter image description here

mesh = ToElementMesh[img, "RegionHoles" -> None, 
   "RegionMarker" -> {{{250, 200}, 1, 1000}, {{100, 200}, 1, 
      1000}, {{20, 200}, 1, 1000}}];

,but no mesh is generated. Instead Mathematica crashes. Does anyone have an idea how to go on from that point?

Thanks in advances

Max

enter image description here

enter image description here

$\endgroup$
2
  • 1
    $\begingroup$ Could you share the images without the Axis? $\endgroup$ – user21 Mar 5 at 15:39
  • $\begingroup$ Sure! Is it okay like this? $\endgroup$ – Max Mar 5 at 16:07
8
$\begingroup$

Updated answer

This update describes the workflow to create an inclusion within an inclusion mesh based on an image in more detail.

In this case, ImageForestingComponents appears to do a good job separating the regions. We can use DominantColors to separate by color and view as a dataset.

pts = {{250, 200}, {100, 200}, {20, 200}};
ifc = ImageForestingComponents[img, pts, 3] // Colorize;
ds = DominantColors[ifc, 
  3, {"NearestHTMLColor", "Coverage", "CoverageImage"}, "Dataset"]

Dominant color dataset

Ultimately, we want an image with the middle region stripped out. This way, we will be able to create an element mesh that we can extract a boundary mesh so that we can apply region markers. The negative of the coverage image of row 2 meets the requirement.

Print["Image of the middle region removed"]
domImg = ds[2, -1] // ColorNegate

Domain image

Now, we will create a mesh based on the above image, extract a boundary mesh, and build a mesh with the appropriate region markers.

Print["Mesh the domain image"]
(m = ToElementMesh[domImg])["Wireframe"]
Print["Extract boundary mesh"]
(bm = ToBoundaryMesh[m])["Wireframe"]
Print["Final mesh with region markers"]
mesh = ToElementMesh[bm, "RegionHoles" -> None, 
   "RegionMarker" -> {{#1, 1, 1000}, {#2, 2, 1000}, {#3, 3, 1000}} & @@
     pts];
mesh["Wireframe"[
  "MeshElementStyle" -> {FaceForm[Green], FaceForm[Red], 
    FaceForm[LightBlue]}]]

Updated meshes

Original answer

Something like this works, but you may want to do something to smooth the outer ellipse because it is over-refined.

cc = ClusteringComponents[img, 3];
bm = ToBoundaryMesh@
   ToElementMesh[Colorize[cc /. {3 -> 0}] // Binarize];
mesh = ToElementMesh[bm, "RegionHoles" -> None, 
   "RegionMarker" -> {{{250, 200}, 1, 1000}, {{100, 200}, 2, 
      1000}, {{20, 200}, 3, 1000}}];
mesh["Wireframe"[
  "MeshElementStyle" -> {FaceForm[Green], FaceForm[Red], 
    FaceForm[LightBlue]}]]

enter image description here

Here is a version that applies a GaussianFilter to the image.

bm = ToBoundaryMesh@
   ToElementMesh[
    GaussianFilter[Colorize[cc /. {3 -> 0}], 10] // Binarize];
mesh = ToElementMesh[bm, "RegionHoles" -> None, 
   "RegionMarker" -> {{{250, 200}, 1, 1000}, {{100, 200}, 2, 
      1000}, {{20, 200}, 3, 1000}}];
mesh["Wireframe"[
  "MeshElementStyle" -> {FaceForm[Green], FaceForm[Red], 
    FaceForm[LightBlue]}]]

Filtered

The results are much nicer.

$\endgroup$
1
  • $\begingroup$ This are pretty nice examples and they are working quite well! Great! $\endgroup$ – Max Mar 8 at 13:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.