# Inaccurate (non-smooth) boundary of the mesh generated by ToElementMesh

I try to generate a mesh over a region, which has a wavy boundary at its bottom and needs very fine mesh around the bottom.

However, the generated mesh boundary is not as smooth as the specified one. The region is The generated mesh is If we zone-in we will find the bottom boundary is not

I further try to generate the boundary first. Here is what I found.

The boundary is not generated correctly.

Anyone know how to generate the correct meshed boundary?

## Adding a range of {{x,-0.6,0.6},{y,0,0.3}} in defining the region.

The minimum work code is as follows.

Needs["NDSolveFEM"];

width = 1;
heigth = 0.25;
ydatum = 0.006;
Aw = 2 10^-3;
λw = 0.1;
ℛ =
ImplicitRegion[
Abs[x] <= width/2 && y <= heigth + ydatum &&
y >= x^2/(2 radius) + Aw (1 - Cos[(2 π x)/λw]) +
ydatum, {{x,-0.6,0.6},{y,0,0.3}}];
RegionPlot[ℛ, FrameTicks -> None, PlotPoints -> 20000,
AspectRatio -> Automatic, ImageSize -> Large,
PlotRange -> {{-0.48, 0.48}, {0.005, 0.256}}]

bmesh = ToBoundaryMesh[ℛ,
"BoundaryMeshGenerator" -> "Continuation", AccuracyGoal -> 2]
bmesh["Wireframe"]

meshrefine =
Function[{vertices, area},
Block[{x, y}, {x, y} = Mean[vertices];
If[ydatum < y < ydatum + 0.01, area > 2.1*10^-7, area > 0.001]]];
mesh1 = ToElementMesh[ℛ, "MeshOrder" -> 1,
MeshRefinementFunction -> meshrefine]

mesh1["Wireframe"]

Show[mesh1["Wireframe"],
PlotRange -> {{-0.025, 0.025}, {0.005, 0.02}}, ImageSize -> 800]

• Weird. I do not know why this happens. In my opinion, this is not the expected behavior and you should consider filing a bug report at Wolfram support. For the moment, I can get it working by adding the option MaxCellMeasure -> 0.0002 to the call to ToElementMesh: This adds only a few thousand triangles but the boundary seems to be discretized accurately. – Henrik Schumacher Nov 12 '17 at 7:48
• Thank you. The option MaxCellMeasure -> 0.0002 works for me. Maybe because the mesh size has a large gradient in my original case? – Wilhelm Nov 12 '17 at 18:54
• You're welcome. I also thought so. Maybe using a smoother MeshRefinementFunction will also help. – Henrik Schumacher Nov 12 '17 at 19:32
• Could you please clarify how to using a smoother MeshRefinementFunction? The same problem happens if I increase the amplitude of the wavy boundary, although I played around with changing the value of MaxCellMeasure. See the updated post. – Wilhelm Nov 12 '17 at 21:25
• The MeshRefinementFunction you use has discontinuities in y = ydatum + 0.01 and y = ydatum This causes that several triangles that are adjacent to each other are treated completely different. If I were a meshing algorithm, I wouldn't like to get such inputs/ – Henrik Schumacher Nov 12 '17 at 22:02

If you use a better refinement function things works as expected:

reg = ImplicitRegion[
Abs[x] <= width/2 && y <= heigth + ydatum &&
y >= x^2/(2 radius) + Aw (1 - Cos[(2 π x)/λw]) +
ydatum, {x, y}];
mesh1 = ToElementMesh[reg, "MeshOrder" -> 1,
MeshRefinementFunction ->
Function[{vertices, area},
area > 0.0005 Mean[vertices[[All, 2]]]]];
mesh1["Wireframe"]


• Thank you. I'm not quite understand how the refine mesh function works. For example, what does Mean[vertices[[All, 2]]] mean? There is a computation balance in my case since I need to cut down the computation time. Hence I need a very fine meh at the bottom, but not at the rest part, e.g., say the mesh size (MaxCellMeasure->{"Length"->0.001/3}) at the bottom is about 0.001/3, but the mesh size at the rest part can be larger. At the same time, I want to generate the mesh as a gradient change of mesh size as you did (instead of a abrupt change of mesh size in my post). – Wilhelm Nov 14 '17 at 16:56
• @Wilhelm have a look at the documentation. Look for MeshRefinementFunction and in the options of ToElementMesh to see examples. – user21 Nov 14 '17 at 22:54
• Thank you @user21. – Wilhelm Nov 19 '17 at 2:56