Function Repository Resource:

BoundaryElementMeshJoin

Source Notebook

Join multiple boundaries to form a single boundary ElementMesh

Contributed by: Oliver Rübenkönig

ResourceFunction["BoundaryElementMeshJoin"][bmesh1,bmesh2,]

returns a boundary ElementMesh consisting of joined boundary MeshRegion or ElementMesh objects bmeshi.

Details and Options

ResourceFunction["BoundaryElementMeshJoin"] accepts the options for ToBoundaryMesh.
Inputs can be either MeshRegion or ElementMesh objects.

Examples

Basic Examples (4) 

Load the Finite Element Method package:

In[1]:=
<< NDSolve`FEM`

Define two boundary meshes:

In[2]:=
mr1 = \!\(\*
GraphicsBox[
TagBox[
DynamicModuleBox[{
       Typeset`mesh = {MeshRegion, {Properties -> {{1, {1, 2, 3, 4, 5,
              6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80}} -> (
            MeshCellMarker -> {1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3}), {1, Default} -> (
            MeshCellMarker -> 0)}}}}, 
TagBox[GraphicsComplexBox[CompressedData["
1:eJx1ktEJwjAYhIObOIMDZAVxBEFfnUc3cIQ++1RQKBSEgg8tLSWlIWQEbfGv
5MP/h1KOJJfL3a33p91hZYzZfr7pr83lPM3Vpjhb8GaeG9Zzm7IU2F8u+DjP
E+erBT/u07zAV2N/A/4W5zvc14PPgW8A3wg+D74Avmj/+yZY1jPF12jpa4rl
fK74Hr//QslB+Esll2iZS4rl/krJLVrmlmLRVyu5Cn+j5Cz6W+hvcX+H+zu8
r8f7euhz0Oegb4C+AfpG6Buhz0Ofh74AfQH6IvSxd+wZe8UesTfsCXvBHjB3
5sxcmSNzY07MhTnQd/pMX38+vgGZwkZb
"], 
{Hue[0.6, 0.3, 0.75], 
TagBox[LineBox[{{1, 22}, {2, 1}, {3, 2}, {4, 3}, {5, 4}, {6, 5}, {7, 6}, {8, 7}, {9, 8}, {10, 9}, {11, 10}, {12, 11}, {13, 12}, {14, 13}, {15, 14}, {16, 15}, {17, 16}, {18, 17}, {
            19, 18}, {20, 19}, {23, 21}, {21, 20}, {22, 24}, {25, 23}, {24, 26}, {27, 25}, {26, 28}, {29, 27}, {28, 30}, {
            31, 29}, {30, 32}, {33, 31}, {32, 34}, {35, 33}, {34, 36}, {37, 35}, {36, 38}, {39, 37}, {38, 40}, {41, 39}, {
            40, 42}, {43, 41}, {42, 44}, {45, 43}, {44, 46}, {47, 45}, {46, 48}, {49, 47}, {48, 50}, {51, 49}, {50, 52}, {
            53, 51}, {52, 54}, {55, 53}, {54, 56}, {57, 55}, {56, 58}, {59, 57}, {58, 60}, {60, 61}, {61, 62}, {62, 63}, {
            63, 64}, {64, 65}, {65, 66}, {66, 67}, {67, 68}, {68, 69}, {69, 70}, {70, 71}, {71, 72}, {72, 73}, {73, 74}, {
            74, 75}, {75, 76}, {76, 77}, {77, 78}, {78, 79}, {79, 80}, {80, 59}}],
Annotation[#, "Geometry"]& ], PointBox[{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
            45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
            74, 75, 76, 77, 78, 79, 80}]}],
MouseAppearanceTag["LinkHand"]],
AllowKernelInitialization->False],
"MeshGraphics",
AutoDelete->True,
Editable->False,
Selectable->False],
DefaultBaseStyle->{"MeshGraphics", FrontEnd`GraphicsHighlightColor -> Hue[0.1, 1, 0.7]}]\);
mr2 = \!\(\*
GraphicsBox[
TagBox[
DynamicModuleBox[{
       Typeset`mesh = {MeshRegion, {Properties -> {{1, {1, 2, 3, 4, 5,
              6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48}} -> (
            MeshCellMarker -> {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}), {1, Default} -> (MeshCellMarker -> 0)}}}}, 
TagBox[GraphicsComplexBox[CompressedData["
1:eJw90m1Ik1EUwPFpW5SFUkYfbIhb0UyzxFARggPFlkXNUoxgvc1ZbBZNU2Ji
y5fESP2QNm2W2JQ0RWNhA8Oak4xlTelx6abN1V50j9oSV/Zm0cp7rztwOV/P
j/vnZMnTzwUzGIz4/29545kBvB1wJEmo7ZunoaqiUXlorRMe9TeWaXpoGFLW
32/e4oKjTTvsbSIaJo0Hkq1b3bDPpBq6M+mBs95vvgX2FARV3vP69nrgeHZG
bVLwNMzXPxn/UjwNOl5oouDtNCwKouVdHVPQopiRxZR4YBvHoE8xuKFV2j+v
2EBDgmrPjYRXLsiWsbjVJTRsypQN1L1xQkthUbLfRAO3XRR22+IAX8Gqi72L
NGgiYpnLd/vR0OD1GpkXPtthNhE75D/N/c8HbRBiwI58UW7NsacTkNeAHe1/
wtmRRisU92GHa/aErfb3GMzlYMeaaHddvngUhoXYEcfbtbPTb4bKVh5yVPcq
uaH2EYh8oUeOk6yvz+i/FIR1xiNHCH91TZCUgv2pEuRgX/3Oq9pMweG0NOTA
f0DBL/5G5JhTSZrLuBQcpLHDW2pc6rtFwSXiiBru4nenjkAucTCvW85TAjO0
EcfumNfb2RXvwEEc0qwGYQRjDFjEsaB7zHnYZYFY4nhZVF5eXToecLg6mnx3
894HHFfkKYWjOZOwnjgkYrFzIv1DwLGuwPbD7/8YcJy6ibvhEoeJdNN2DTts
pJszA9hxmnSjkGFHBulm6dMgcnSTbqLMauTQkG7CL2uR4wHpRqcvRQ4J6UZt
VSPHSjfmzDjkWOmmR5uKHP8A2tqKSg==
"], 
{Hue[0.6, 0.3, 0.75], 
TagBox[LineBox[{{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {10, 11}, {11, 12}, {12, 13}, {13, 14}, {14, 15}, {15, 16}, {16, 17}, {17, 18}, {18, 19}, {
            19, 20}, {20, 21}, {21, 22}, {22, 23}, {23, 24}, {24, 25}, {25, 26}, {26, 27}, {27, 28}, {28, 29}, {29, 30}, {
            30, 31}, {31, 32}, {32, 33}, {33, 34}, {34, 35}, {35, 36}, {36, 37}, {37, 38}, {38, 39}, {39, 40}, {40, 41}, {
            41, 42}, {42, 43}, {43, 44}, {44, 45}, {45, 46}, {46, 47}, {47, 48}, {48, 1}}],
Annotation[#, "Geometry"]& ], PointBox[{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
            45, 46, 47, 48}]}],
MouseAppearanceTag["LinkHand"]],
AllowKernelInitialization->False],
"MeshGraphics",
AutoDelete->True,
Editable->False,
Selectable->False],
DefaultBaseStyle->{"MeshGraphics", FrontEnd`GraphicsHighlightColor -> Hue[0.1, 1, 0.7]}]\);

Join the two:

In[3]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][mr1, mr2]
Out[3]=

Visualize the resulting boundary ElementMesh:

In[4]:=
bmesh["Wireframe"]
Out[4]=

Scope (7) 

Create boundary element meshes directly:

In[5]:=
bmesh1 = ToBoundaryMesh[Rectangle[]];
bmesh2 = ToBoundaryMesh[Disk[{1/2, 1/2}, 1/4]];

Join the boundary meshes:

In[6]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2]
Out[6]=

Visualize the resulting boundary ElementMesh:

In[7]:=
bmesh["Wireframe"]
Out[7]=

Generate a full ElementMesh with the internal circle boundary:

In[8]:=
ToElementMesh[bmesh]["Wireframe"]
Out[8]=

Create three boundary meshes:

In[9]:=
bmesh1 = ToBoundaryMesh[Rectangle[], "MaxBoundaryCellMeasure" -> Infinity];
bmesh2 = ToBoundaryMesh["Coordinates" -> {{1/4, 1/2}, {2/3, 1/2}}, "BoundaryElements" -> {LineElement[{{1, 2}}]}];
bmesh3 = ToBoundaryMesh[Rectangle[{2/3, 1/3}, {4/5, 2/3}], "MaxBoundaryCellMeasure" -> Infinity];

Join the boundary meshes:

In[10]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2, bmesh3]
Out[10]=

Visualize the resulting boundary ElementMesh:

In[11]:=
bmesh["Wireframe"]
Out[11]=

Generate a full ElementMesh with the internal line boundary and a region hole in the box:

In[12]:=
ToElementMesh[bmesh, "RegionHoles" -> {{7/10, 1/2}}]["Wireframe"]
Out[12]=

Create two boundary meshes:

In[13]:=
bmesh1 = ToBoundaryMesh[Rectangle[{-1, -1}, {1, 1}]];
bmesh2 = ToBoundaryMesh[Rectangle[{-2, -1/2}, {2, 1/2}]];

Join the boundary meshes:

In[14]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2]
Out[14]=

Visualize the resulting boundary ElementMesh:

In[15]:=
bmesh["Wireframe"]
Out[15]=

Generate a full ElementMesh with the internal boundaries:

In[16]:=
ToElementMesh[bmesh]["Wireframe"]
Out[16]=

Create two boundary meshes:

In[17]:=
bmesh1 = ToBoundaryMesh[Rectangle[{0, 0}, {1, 1}], MaxCellMeasure -> Infinity];
bmesh2 = ToBoundaryMesh[Rectangle[{1/4, 1}, {3/4, 2}], MaxCellMeasure -> Infinity];

Join the boundary meshes:

In[18]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2]
Out[18]=

Visualize the resulting boundary ElementMesh:

In[19]:=
bmesh["Wireframe"]
Out[19]=

Generate a full ElementMesh with an internal boundary at the connection:

In[20]:=
ToElementMesh[bmesh]["Wireframe"]
Out[20]=

Create two boundary meshes:

In[21]:=
bmesh1 = ToBoundaryMesh[Annulus[{0, 0}, {3/2, 2}]];
bmesh2 = ToBoundaryMesh[Disk[{3/2, 0}, 2]];

Join the boundary meshes:

In[22]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2]
Out[22]=

Visualize the resulting boundary ElementMesh:

In[23]:=
bmesh["Wireframe"]
Out[23]=

Generate a full ElementMesh with the internal boundaries:

In[24]:=
ToElementMesh[bmesh]["Wireframe"]
Out[24]=

Generate a full ElementMesh with the internal boundaries and a region hole:

In[25]:=
ToElementMesh[bmesh, "RegionHoles" -> {{-1/2, 0}}]["Wireframe"]
Out[25]=

Create two boundary meshes in 3D:

In[26]:=
bmesh1 = ToBoundaryMesh[Cuboid[], MaxCellMeasure -> Infinity];
bmesh2 = ToBoundaryMesh[Ball[{1/2, 1/2, 1/2}, 1/4]];

Join the boundary meshes:

In[27]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2]
Out[27]=

Visualize the resulting boundary ElementMesh:

In[28]:=
bmesh["Wireframe"]
Out[28]=

Generate a full ElementMesh with the internal ball boundary:

In[29]:=
ToElementMesh[bmesh]["Wireframe"]
Out[29]=

Create two boundary meshes in 3D:

In[30]:=
bmesh1 = ToBoundaryMesh[Cuboid[], "MaxBoundaryCellMeasure" -> 1/40];
bmesh2 = ToBoundaryMesh[
   Cylinder[{{1 - 1/5, 1/2, 1/2}, {1, 1/2, 1/2}}, 1/8]];

Join the boundary meshes:

In[31]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2]
Out[31]=

Visualize the resulting boundary ElementMesh:

In[32]:=
bmesh["Wireframe"]
Out[32]=

Generate a full ElementMesh:

In[33]:=
ToElementMesh[bmesh]["Wireframe"]
Out[33]=

Applications (2) 

Use an image to generate a mesh that has material regions. Set up the image:

In[34]:=
\!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
1: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
TRQqKvQ/7RRk6g==
"], {{0, 102}, {275, 0}}, {0, 255},
ColorFunction->RGBColor],
BoxForm`ImageTag["Byte", ColorSpace -> "RGB", Interleaving -> True],
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSize->{137.5, Automatic},
ImageSizeRaw->{275, 102},
PlotRange->{{0, 275}, {0, 102}}]\)

Find the image components:

In[35]:=
components = ComponentMeasurements[ArrayComponents[ImageData@img, 2], "Mask", #Area > 10000 &];

Generate mesh regions:

In[36]:=
meshes = components /. (idx_ -> mask_) :> ImageMesh[Image[mask]]
Out[36]=

Generate boundary ElementMesh objects and join them:

In[37]:=
bm = ResourceFunction[
  "BoundaryElementMeshJoin"] @@ (ToBoundaryMesh /@ meshes)
Out[37]=

Visualize the boundary ElementMesh:

In[38]:=
bm["Wireframe"]
Out[38]=

Find the centroids of the meshes:

In[39]:=
centrds = RegionCentroid /@ meshes
Out[39]=

Generate the full ElementMesh with region markers:

In[40]:=
(mesh = ToElementMesh[bm, "RegionMarker" -> Transpose[{centrds, Range[Length[centrds]]}]])[
 "Wireframe"[
  "MeshElementStyle" -> (FaceForm[#] & /@ {Green, Blue, Red})]]
Out[40]=

Solve a PDE with different coefficient values in the different material regions:

In[41]:=
uif = NDSolveValue[{Inactive[Div][
      Piecewise[{{-10, ElementMarker == 1}, {-25, ElementMarker == 2}}, -1] Inactive[Grad][
        u[x, y], {x, y}], {x, y}] == 0, DirichletCondition[u[x, y] == 1, x == 0], DirichletCondition[u[x, y] == 0, x == 1264]}, u, {x, y} \[Element] mesh];

Visualize the solution:

In[42]:=
Show[ContourPlot[uif[x, y], {x, y} \[Element] mesh], bm["Wireframe"], AspectRatio -> Automatic]
Out[42]=

Create two boundary meshes in 3D:

In[43]:=
bmesh1 = ToBoundaryMesh[
   Polygon[{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}}]];
bmesh2 = ToBoundaryMesh[
   Polygon[{{0, 0, 0}, {1, 0, 0}, {1, 0, 1}, {0, 0, 1}}]];

Join the meshes:

In[44]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2]
Out[44]=

Visualize the boundary ElementMesh:

In[45]:=
bmesh["Wireframe"]
Out[45]=

Numerically integrate over the boundary ElementMesh:

In[46]:=
NIntegrate[1, {x, y, z} \[Element] bmesh]
Out[46]=

Possible Issues (6) 

Sometimes the boundary mesh quality is not good enough to generate a full ElementMesh. Create two boundary ElementMesh objects:

In[47]:=
bmesh1 = ToBoundaryMesh[Rectangle[]];
bmesh2 = ToBoundaryMesh[Disk[{1, 1/2}, 1/2]];

Join the boundary meshes:

In[48]:=
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2]
Out[48]=

Visualize the resulting boundary ElementMesh:

In[49]:=
bmesh["Wireframe"]
Out[49]=

Generate a full ElementMesh with the internal circle boundary:

In[50]:=
ToElementMesh[bmesh]["Wireframe"]
Out[50]=

In that case, generate a small offset at the intersecting boundary:

In[51]:=
offset = 10^-3;
bmesh1 = ToBoundaryMesh[Rectangle[]];
bmesh2 = ToBoundaryMesh[Disk[{1, 1/2}, 1/2 - offset]];
bmesh = ResourceFunction["BoundaryElementMeshJoin"][bmesh1, bmesh2];

Generate a full ElementMesh with the internal circle boundary:

In[52]:=
ToElementMesh[bmesh]["Wireframe"]
Out[52]=

Publisher

OliverRubenkonig

Version History

  • 1.0.0 – 20 January 2020

License Information