# Nearly equally spaced 3D-mesh

How to mesh a volume (3D region) with nearly equaly spaced vertices?

Example: Disk with radius 50 and height 15

disk = ImplicitRegion[0 < x^2 + y^2 < 50^2 && 0 < z < 15, {x, y, z}];


Is there an easy way to mesh the volume such that the vertices are constrained to around 5?

I tried

ToElementMesh[disk, MaxCellMeasure -> {1 ->100}]["Wireframe"]


which only gives a nonuniform mesh

Thanks!

• You can mesh with tetrahedra. Each tetraheada has 4 vertices. Do you just want a total of 5 vertices so that the disk is very poorly meshed?
– Hugh
Sep 8, 2019 at 12:37
• @Hugh Yes , 3 or 4 elements along the thickness direction would be ok. Sep 8, 2019 at 12:41
• Could you not make use of the answers given to your similar question here? Sep 9, 2019 at 5:58

### Coarse cylinder

Using the Cylinder primitive seems to do the trick:

MeshRegion[
DiscretizeRegion[Cylinder[{{0, 0, 0}, {0, 0, 15}}, 50], MaxCellMeasure -> {1 -> 100}],
PlotTheme -> "Lines",
MeshCellStyle -> {1 -> Black}
]


### General region

Notice that the boundary is being discretized finer than you'd like. It looks like if we can workaround this, we could get a coarse mesh with higher quality elements.

One way is through stricter sampling options:

cyl = ImplicitRegion[0 < x^2 + y^2 < 50^2 && 0 < z < 15, {x, y, z}];
mr = DiscretizeRegion[cyl,
MaxCellMeasure -> {1 -> 100, 3 -> 200},
Method -> {"RegionPlot3D", PlotPoints -> 6}
];

MeshCellCount[mr]

{386, 1990, 2902, 1297}

MeshRegion[mr, PlotTheme -> "Lines", MeshCellStyle -> {1 -> Black}]


Histogram[PropertyValue[{mr, 3}, MeshCellQuality]]


Here's another example:

ball = ImplicitRegion[x^2 + y^2 + z^2 <= 50^2, {x, y, z}];

mr1 = DiscretizeRegion[ball, MaxCellMeasure -> {1 -> 100}];
mr2 = DiscretizeRegion[ball, MaxCellMeasure -> {1 -> 100, 3 -> 200},
Method -> {"RegionPlot3D", PlotPoints -> 6}];

MeshRegion[mr1, PlotTheme -> "Lines", MeshCellStyle -> {1 -> Black}]
MeshRegion[mr2, PlotTheme -> "Lines", MeshCellStyle -> {1 -> Black}]


Histogram[PropertyValue[{mr1, 3}, MeshCellQuality]]
Histogram[PropertyValue[{mr2, 3}, MeshCellQuality]]


• Thank you , that works fine for a cylinder. If I expand the problem to a flat hollow cylinder(thickness 15, radius 25...75) using RegionDifference the number of elements increase dramatically. Do you have an idea how to avoid ? Sep 9, 2019 at 7:38
• Yes, any boolean operation will effect the triangulation of the model and then we'd need some remeshing scheme. Perhaps in this case you could extrude from 2D? Something coarse like TriangulateMesh[ RegionProduct[ DiscretizeRegion[Annulus[{0, 0}, {25, 75}], MaxCellMeasure -> {1 -> 100}, AccuracyGoal -> 0], Line[{{0.}, {15.}}]], MaxCellMeasure -> ∞]. Sep 9, 2019 at 12:13

Structured mesh will give you more control over element size for such basic geometric shapes (e.g. cylinder). My package MeshTools can help you with that.

Needs["MeshTools"]
"Version" /. PacletInformation["MeshTools"]
(* 1.0.0 *)

mesh = CylinderMesh[{{0, 0, 0}, {0, 0, 15}}, 50, {10, 3}];
size = Flatten@mesh["MeshElementMeasure"];
quality = Flatten@mesh["Quality"];

mesh["Wireframe"["MeshElementStyle" -> FaceForm@LightBlue, PlotLabel -> \$Version]]


It gives you high quality mesh.

Min@quality
(* 0.889 *)
Histogram[quality, {0.05}, PlotRange -> {{0, 1}, Automatic}]


It works with Mathematica 11.0.1, I have tested it right now.

Here is a possible way forward. I think the standard meshing algorithm attempt to give you a good circular boundary and then this dictates a general mesh size which is too fine for your purposes. Here I define my own boundary points and then mesh from there. I have your five vertices across the disk thickness and put a similar spacing around the circumference.

   Needs["NDSolveFEM"]
h = 15; (* height *)
r = 50; (* radius *)
nn = 79; (* number of edges *)
pts = Partition[Flatten[Table[
Table[{r Cos[2 π k/nn], r Sin[2 π k/nn], z}, {k, 0,
nn - 1}],
{z, 0, h, h/4}]], 3];
Graphics3D[{
Point[pts]
}

]


Now I make the boundary mesh which is not fine.

m = DelaunayMesh[pts];
bmesh = ToBoundaryMesh[m];
bmesh["Wireframe"]


Now the mesh density seems to follow from the boundary

mesh = ToElementMesh[bmesh];
mesh["Wireframe"]


I don't know how to best check the mesh size within the boundaries. Perhaps someone can suggest a method. Here is a section showing the nodes. There are mid side nodes on each tetrahedra but I think I have your 5 vertices across the thickness.

cc = mesh["Coordinates"];
Show[
Graphics3D[Point[cc], PlotRange -> {All, {0, 10}, All}],
mesh["Wireframe"]
]


Also we can look at the mesh quality

Histogram[mesh["Quality"]]


The histogram suggests that there is a dominant size around 0.8. I am not sure of the units here. Is the horizontal axis the volume of elements?

Does this help?

• The mesh quality can vary from -1 to 1 and you'd need all elements to be above 0 to make a FEA work but the higher the better. This documented in the section called ElementMesh quality in the ElementMesh generation tutorial Sep 9, 2019 at 6:04
• @Hugh It helps a lot, thanks. In my underlying problem I try to mesh a flat hollow cylinder , but the mesh size exceeds to 100000 elements. I'll try your way... Sep 9, 2019 at 7:24
• @user21 Am I correct in thinking that the meshing starts from the boundary? If so what resolution does it use for i) a plain edge and ii) a cylindrical edge? Are there formula? Can this resolution be prescribed? I think that what have done here is to replace the circular cylinder with a polygonal cylinder. This has required fewer points to represent the boundaries. Is this correct?
– Hugh
Sep 9, 2019 at 17:46
• Have a look at the AccuracyGoial option for ToBoundaryMesh` here and in the section Region Approximation Quality in the ElementMesh generation tutorial. Concerning your last question, I think this is correct. Sep 10, 2019 at 11:18