Skip to main content
edited body
Source Link
user21
  • 40.7k
  • 8
  • 114
  • 170

Update: I have updated the code a bit to work in other cases as well.

Yes, this is too difficult. Here is a workaround for this case. It's not trivial bitbut it works well for the problem at hand. Basically, we generate a boundary mesh from a 2D mesh that has an interior region:

m = ToElementMesh[Annulus[{0, 0}, {9/10, 1}], "RegionHoles" -> None, 
   "MeshOrder" -> 1, MaxCellMeasure -> Infinity];
m["Wireframe"]

enter image description here

Next, we extract the coordinates and get the largest incident number.

coords = m["Coordinates"];
c1 = Join[coords, ConstantArray[{0.}, {Length[coords]}], 2];
c2 = Join[coords, ConstantArray[{1.}, {Length[coords]}], 2];
ele = m["MeshElements"];
max = Max[ElementIncidents[ele]]
136

We extract the boundary elements from the mesh and construct the sides:

tohigherIndex[type_[inci_, marker___], max_] := 
 type[inci + max, marker]
(* old code: not good *)
(* tmpBM = ToBoundaryMesh[m];
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];*)
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[m["BoundaryElements"]]]];

We now construct the boundary mesh:

bm = ToBoundaryMesh["Coordinates" -> Join[c1, c2], 
  "BoundaryElements" -> 
   Join[ele, tohigherIndex[#, max] & /@ ele, sides]]

bm["Wireframe"]

enter image description here

And generate the full mesh:

ToElementMesh[bm]["Wireframe"]

enter image description here

Hope this helps.

With the updated version I get this for your second mesh:

enter image description here

Yes, this is too difficult. Here is a workaround for this case. It's not trivial bit it works well for the problem at hand. Basically, we generate a boundary mesh from a 2D mesh that has an interior region:

m = ToElementMesh[Annulus[{0, 0}, {9/10, 1}], "RegionHoles" -> None, 
   "MeshOrder" -> 1, MaxCellMeasure -> Infinity];
m["Wireframe"]

enter image description here

Next, we extract the coordinates and get the largest incident number.

coords = m["Coordinates"];
c1 = Join[coords, ConstantArray[{0.}, {Length[coords]}], 2];
c2 = Join[coords, ConstantArray[{1.}, {Length[coords]}], 2];
ele = m["MeshElements"];
max = Max[ElementIncidents[ele]]
136

We extract the boundary elements from the mesh and construct the sides:

tohigherIndex[type_[inci_, marker___], max_] := 
 type[inci + max, marker]
(* old code: not good *)
(* tmpBM = ToBoundaryMesh[m];
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];*)
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[m["BoundaryElements"]]]];

We now construct the boundary mesh:

bm = ToBoundaryMesh["Coordinates" -> Join[c1, c2], 
  "BoundaryElements" -> 
   Join[ele, tohigherIndex[#, max] & /@ ele, sides]]

bm["Wireframe"]

enter image description here

And generate the full mesh:

ToElementMesh[bm]["Wireframe"]

enter image description here

Hope this helps.

With the updated version I get this for your second mesh:

enter image description here

Update: I have updated the code a bit to work in other cases as well.

Yes, this is too difficult. Here is a workaround for this case. It's not trivial but it works well for the problem at hand. Basically, we generate a boundary mesh from a 2D mesh that has an interior region:

m = ToElementMesh[Annulus[{0, 0}, {9/10, 1}], "RegionHoles" -> None, 
   "MeshOrder" -> 1, MaxCellMeasure -> Infinity];
m["Wireframe"]

enter image description here

Next, we extract the coordinates and get the largest incident number.

coords = m["Coordinates"];
c1 = Join[coords, ConstantArray[{0.}, {Length[coords]}], 2];
c2 = Join[coords, ConstantArray[{1.}, {Length[coords]}], 2];
ele = m["MeshElements"];
max = Max[ElementIncidents[ele]]
136

We extract the boundary elements from the mesh and construct the sides:

tohigherIndex[type_[inci_, marker___], max_] := 
 type[inci + max, marker]
(* old code: not good *)
(* tmpBM = ToBoundaryMesh[m];
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];*)
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[m["BoundaryElements"]]]];

We now construct the boundary mesh:

bm = ToBoundaryMesh["Coordinates" -> Join[c1, c2], 
  "BoundaryElements" -> 
   Join[ele, tohigherIndex[#, max] & /@ ele, sides]]

bm["Wireframe"]

enter image description here

And generate the full mesh:

ToElementMesh[bm]["Wireframe"]

enter image description here

Hope this helps.

With the updated version I get this for your second mesh:

enter image description here

added 332 characters in body
Source Link
user21
  • 40.7k
  • 8
  • 114
  • 170

Yes, this is too difficult. Here is a workaround for this case. It's not trivial bit it works well for the problem at hand. Basically, we generate a boundary mesh from a 2D mesh that has an interior region:

m = ToElementMesh[Annulus[{0, 0}, {9/10, 1}], "RegionHoles" -> None, 
   "MeshOrder" -> 1, MaxCellMeasure -> Infinity];
m["Wireframe"]

enter image description here

Next, we extract the coordinates and get the largest incident number.

coords = m["Coordinates"];
c1 = Join[coords, ConstantArray[{0.}, {Length[coords]}], 2];
c2 = Join[coords, ConstantArray[{1.}, {Length[coords]}], 2];
ele = m["MeshElements"];
max = Max[ElementIncidents[ele]]
136

From a temporary boundary mesh weWe extract the boundary elements from the mesh and construct the sides:

tohigherIndex[type_[inci_, marker___], max_] := 
 type[inci + max, marker]
(* old code: not good *)
(* tmpBM = ToBoundaryMesh[m];
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];*)
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[m["BoundaryElements"]]]];

We now construct the boundary mesh:

bm = ToBoundaryMesh["Coordinates" -> Join[c1, c2], 
  "BoundaryElements" -> 
   Join[ele, tohigherIndex[#, max] & /@ ele, sides]]

bm["Wireframe"]

enter image description here

And generate the full mesh:

ToElementMesh[bm]["Wireframe"]

enter image description here

Hope this helps.

With the updated version I get this for your second mesh:

enter image description here

Yes, this is too difficult. Here is a workaround for this case. It's not trivial bit it works well for the problem at hand. Basically, we generate a boundary mesh from a 2D mesh that has an interior region:

m = ToElementMesh[Annulus[{0, 0}, {9/10, 1}], "RegionHoles" -> None, 
   "MeshOrder" -> 1, MaxCellMeasure -> Infinity];
m["Wireframe"]

enter image description here

Next, we extract the coordinates and get the largest incident number.

coords = m["Coordinates"];
c1 = Join[coords, ConstantArray[{0.}, {Length[coords]}], 2];
c2 = Join[coords, ConstantArray[{1.}, {Length[coords]}], 2];
ele = m["MeshElements"];
max = Max[ElementIncidents[ele]]
136

From a temporary boundary mesh we extract the boundary elements and construct the sides:

tohigherIndex[type_[inci_, marker___], max_] := 
 type[inci + max, marker]
tmpBM = ToBoundaryMesh[m];
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];

We now construct the boundary mesh:

bm = ToBoundaryMesh["Coordinates" -> Join[c1, c2], 
  "BoundaryElements" -> 
   Join[ele, tohigherIndex[#, max] & /@ ele, sides]]

bm["Wireframe"]

enter image description here

And generate the full mesh:

ToElementMesh[bm]["Wireframe"]

enter image description here

Hope this helps.

Yes, this is too difficult. Here is a workaround for this case. It's not trivial bit it works well for the problem at hand. Basically, we generate a boundary mesh from a 2D mesh that has an interior region:

m = ToElementMesh[Annulus[{0, 0}, {9/10, 1}], "RegionHoles" -> None, 
   "MeshOrder" -> 1, MaxCellMeasure -> Infinity];
m["Wireframe"]

enter image description here

Next, we extract the coordinates and get the largest incident number.

coords = m["Coordinates"];
c1 = Join[coords, ConstantArray[{0.}, {Length[coords]}], 2];
c2 = Join[coords, ConstantArray[{1.}, {Length[coords]}], 2];
ele = m["MeshElements"];
max = Max[ElementIncidents[ele]]
136

We extract the boundary elements from the mesh and construct the sides:

tohigherIndex[type_[inci_, marker___], max_] := 
 type[inci + max, marker]
(* old code: not good *)
(* tmpBM = ToBoundaryMesh[m];
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];*)
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[m["BoundaryElements"]]]];

We now construct the boundary mesh:

bm = ToBoundaryMesh["Coordinates" -> Join[c1, c2], 
  "BoundaryElements" -> 
   Join[ele, tohigherIndex[#, max] & /@ ele, sides]]

bm["Wireframe"]

enter image description here

And generate the full mesh:

ToElementMesh[bm]["Wireframe"]

enter image description here

Hope this helps.

With the updated version I get this for your second mesh:

enter image description here

Source Link
user21
  • 40.7k
  • 8
  • 114
  • 170

Yes, this is too difficult. Here is a workaround for this case. It's not trivial bit it works well for the problem at hand. Basically, we generate a boundary mesh from a 2D mesh that has an interior region:

m = ToElementMesh[Annulus[{0, 0}, {9/10, 1}], "RegionHoles" -> None, 
   "MeshOrder" -> 1, MaxCellMeasure -> Infinity];
m["Wireframe"]

enter image description here

Next, we extract the coordinates and get the largest incident number.

coords = m["Coordinates"];
c1 = Join[coords, ConstantArray[{0.}, {Length[coords]}], 2];
c2 = Join[coords, ConstantArray[{1.}, {Length[coords]}], 2];
ele = m["MeshElements"];
max = Max[ElementIncidents[ele]]
136

From a temporary boundary mesh we extract the boundary elements and construct the sides:

tohigherIndex[type_[inci_, marker___], max_] := 
 type[inci + max, marker]
tmpBM = ToBoundaryMesh[m];
sides = QuadElement[Map[Join[#1, Reverse[#1 + max]] &, #]] & /@ 
   ElementIncidents[
    Flatten[MeshElementSplitByMarker[tmpBM["BoundaryElements"]]]];

We now construct the boundary mesh:

bm = ToBoundaryMesh["Coordinates" -> Join[c1, c2], 
  "BoundaryElements" -> 
   Join[ele, tohigherIndex[#, max] & /@ ele, sides]]

bm["Wireframe"]

enter image description here

And generate the full mesh:

ToElementMesh[bm]["Wireframe"]

enter image description here

Hope this helps.