ContextQuestion: Given a general space curve xy[t_] = {x[t], y[t]}
, how can a region be generated to yield a mesh with a curved boundary? (A related question has appeared before, but is more specialized.)
Background: A curvedAn implicitly defined boundary (i.e. an exact curve) allows a better representation of a region, as compared to one generated the usual way (from a set of points connected by line segments). This fact is demonstrated by comparing the area of exact and numerical regions. See Documentation (“Region Approximation Quality”).
Consider, for simplicity, a weakly non-circularcircular boundary:
In[399]:= Needs["NDSolve`FEM`"]
In[400]:= r[t_] = (1 - .1 Cos[2 t]);
In[438]:= \[ScriptCapitalR]R = ImplicitRegion[x^2 + y^2 <= r[ArcTan[x, y]]^21, {x, y}];
nr = ToNumericalRegion[\[ScriptCapitalR]];ToNumericalRegion[R];
mesh1 = ToElementMesh[nr];
In[442]:= AreaExact = Integrate[r[\[Theta]]^2/2, {\[Theta], 0, 2 Pi}]
Out[442]= 3.1573Pi;
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.
2.00118*10^-6
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 generatedNow compare this to yieldbuilding a custom mesh with a curved boundary, if ImplicitRegion
cannot be used? (A related question has appeared before, but is more specialized.)
A 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” inlet us take this number equal to the areanumber of nodes of mesh1
).
In[444]:Nt = Length[DeleteDuplicates[Flatten[mesh1["BoundaryElements"][[1, 1]]]]];
xy[t_] = r[t] {Cos[t], Sin[t]};
In[445]:= Ntcoords = 100; Coords =Table[N[xy[(2
Pi)/Nt Table[N[xy[t]]i]], {ti, 0, 2 Pi - 2 Pi/Nt, 2- Pi/Nt1}];
LElms =
Table[{Mod[i + 2, Nt, 1], i, i + 1}, {i, 1, Nt - 1, 2}];
bm =
ToBoundaryMesh["Coordinates" -> Coordscoords,
"BoundaryElements" -> {LineElement[LElms]}];
mesh2 =
ToElementMesh[bm];
In[447]:= AreaExact - Total[mesh2["MeshElementMeasure"], 2]
Out[447]= 0.00879532
0.00896404
Because the region R
is defined implicitly, i.e. using ImplicitRegion
, information about the curvature of the boundary is automatically passed during the call to ToElementMesh
, and mesh1
is endowed with a curved boundary, making it a better approximation of the region. For the custom mesh (mesh2
), a piecewise linear boundary (polygonal) results, causing a large “error” in the area.
Note that the error scales quadratically with 1/Nt, whereas, for comparison, the implicit region error scales as the fourth order of "MaxBoundaryCellMeasure”
parameter.
Assuming a curved boundaryxy[t]
is smooth, 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.)
\[ScriptCapitalR]R =
ParametricRegion[xy[\[Rho], t], {{t, 0, 2 \[Pi]}, {\[Rho], 0, 1}}];
In[499]:= nr3 = ToNumericalRegion[\[ScriptCapitalR]];ToNumericalRegion[R];
In[500]:= mesh3 = ToElementMesh[nr3];
In[501]:= AreaExact - Total[mesh3["MeshElementMeasure"], 2]
Out[501]= 0.0033998