Skip to main content
1 of 4
Will.Mo
  • 1.2k
  • 6
  • 12

Curved mesh boundary from space curve

This is a follow-up question to an earlier question.

Context: A curved boundary allows a better representation of a region, as demonstrated by comparing the area of exact and numerical regions. See Documentation (“Region Approximation Quality”).

Consider a weakly non-circular boundary:

In[400]:= r[t_] = (1 - .1 Cos[2 t]);
In[438]:= \[ScriptCapitalR] = ImplicitRegion[x^2 + y^2 <= r[ArcTan[x, y]]^2, {x, y}];
nr = ToNumericalRegion[\[ScriptCapitalR]];
mesh1 = ToElementMesh[nr];
In[442]:= AreaExact = Integrate[r[\[Theta]]^2/2, {\[Theta], 0, 2 Pi}]
Out[442]= 3.1573
In[443]:= AreaExact - Total[mesh1["MeshElementMeasure"], 2]
Out[443]= 2.23124*10^-6

Because the region is defined implicitly, i.e. using ImplicitRegion, information about the curvature of the boundary is automatically passed during the call to ToElementMesh, and the mesh boundary is curved, giving a better approximation of the region.

Question: what if the boundary of the region is defined by a general space curve xy[t_] = {x[t], y[t]}? How can the region be generated to yield a mesh with a curved boundary, if ImplicitRegion cannot be used? (A related question has appeared before, but is more specialized.)

A crude approach is to extract a sequence of points, and use them as boundary nodes. This however produces a piecewise linear boundary (polygonal) with a large “error” in the area.

In[444]:= xy[t_] = r[t] {Cos[t], Sin[t]};
In[445]:= Nt = 100; Coords = 
 Table[N[xy[t]], {t, 0, 2 Pi - 2 Pi/Nt, 2 Pi/Nt}]; LElms = 
 Table[{Mod[i + 2, Nt, 1], i, i + 1}, {i, 1, Nt - 1, 2}]; bm = 
 ToBoundaryMesh["Coordinates" -> Coords, 
  "BoundaryElements" -> {LineElement[LElms]}]; mesh2 = 
 ToElementMesh[bm];
In[447]:= AreaExact - Total[mesh2["MeshElementMeasure"], 2]
Out[447]= 0.00879532

Note that the error scales quadratically with 1/Nt, whereas the implicit region error scales as the fourth order of "MaxBoundaryCellMeasure” parameter.

Assuming a curved boundary, one would guess that simply interpolating the points during the construction of the mesh boundary would be a significant improvement to the "polygonal" approximation since the order of interpolation could match the order of the mesh itself. Can this be done? If not, is there a reason why? (I understand that one sometimes requires non-differentiable points, e.g. corners, on the boundary, but surely such points can be accommodated.)

Note that I have explored using ParametricRegion:

\[ScriptCapitalR] = 
  ParametricRegion[xy[\[Rho], t], {{t, 0, 2 \[Pi]}, {\[Rho], 0, 1}}];

However, this seems to require a full coordinate mapping xy[\[Rho],t] depending on a "radial" coordinate \[Rho], i.e. it is not addressing the stated problem. Furthermore, the error seems no better than the polygonal approximation:

In[499]:= nr3 = ToNumericalRegion[\[ScriptCapitalR]];
In[500]:= mesh3 = ToElementMesh[nr3];
In[501]:= AreaExact - Total[mesh3["MeshElementMeasure"], 2]
Out[501]= 0.0033998
Will.Mo
  • 1.2k
  • 6
  • 12