# Meshing an inclusion in an inclusion

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.

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


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


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:

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



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?

Max

• Could you share the images without the Axis? – user21 Mar 5 at 15:39
• Sure! Is it okay like this? – Max Mar 5 at 16:07

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"]


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


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]}]]


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]}]]


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]}]]


The results are much nicer.

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