Update: I tracked down the current issue to errors generated by numerically integrating over the boundary mesh. What's the proper way to integrate a function over the boundary of an implicit region? That is, what's the proper way to write the last line in the following code?
r = 0.1; \[Theta] = 0.5; g = 4;
c = Sqrt[1 + r^2] E^(I \[Theta]);
\[CapitalOmega]w = ImplicitRegion[x^2 + y^2 <= 1 && Norm[(x + I y) - c] >= r && \[Pi]/g >= Arg[x + I y] >= 0, {x, y}];
NIntegrate[1, {x, y} \[Element] RegionBoundary[\[CapitalOmega]w]]
The output is 2.878, while the expected analytic result is 2.880 (from below). I get the same result when playing around with AccuracyGoal and PrecisionGoal too.
Previous Question
Consider a domain defined in the complex w-plane defined as follows:
|w|≤1 and |w−c|≥r with c=√1+r2eiθ and 0≤arg(w)≤π/g
This domain looks like a piece of pizza with a bite taken out of it in the form of a circle centered at c with radius r. I would like to change variables to z=wg/2 so the range is 0≤arg(z)≤π/2. Doing so I need to remember dw=2g|z|2/g−1dz
Now I'd like to construct this domain as an element mesh in Mathematica. First we can define some parameters (which should be changed when testing the code).
g = 4; R1 = 0.1; θ = 0.5;
Next, define the mesh.
<< NDSolve`FEM`
ZtoW[g_][{x_, y_}] := (x + I y)^(2/g);
C1 = Sqrt[1 + R1^2] E^(I θ);
\[CapitalOmega] = ImplicitRegion[x^2 + y^2 <= 1 && Norm[ZtoW[g][{x, y}]- C1] >= R1, {{x, 0, 1}, {y, 0, 1}}];
mesh = ToElementMesh[\[CapitalOmega], MaxCellMeasure -> 0.005, AccuracyGoal -> 4];
The mesh has good accuracy as determined by the area determined by numerically integrating the mesh versus the region:
1 - NIntegrate[1, {x, y} \[Elem] mesh]/NIntegrate[1, {x, y} \[Elem] \[CapitalOmega]]
which gives an accuracy of around 10−5.
However, if we extract the boundary mesh as follows:
bcoords = mesh["Coordinates"][[DeleteDuplicates@Flatten[List @@ (mesh["BoundaryElements"][[1]])]]];
meshB = ToBoundaryMesh["Coordinates" -> mesh["Coordinates"], "BoundaryElements" -> mesh["BoundaryElements"]];
we can determine it's accuracy by noting we can analytically determine ∫∂Dwdw=2+πg−2tan−1(r)+2rtan−1(1/r)
The last expression we can compute numerically using
NIntegrate[(2/g Norm[{x, y}]^(2/g - 1)), {x, y} \[Elem] meshB]
which differs from the analytic result by about 1.7% with the originally defined parameters.
If you play around with different g, r, and θ, the situation is worse for higher g and doesn't depend as much on r and θ (just make sure you choose r and θ so the analytic formula still holds). For g=2 the bug goes away, and so I am allowing for the possibility this is a bug in my analytic formulas and not Mathematica.
Also, in my full code I'm using a slightly different method to compute the length of the boundary, but the bug persists. This example hopefully gets at the core concept.
Added: To test the procedure, one can use the following code:
<< NDSolve`FEM`
ZtoW[g_][{x_, y_}] := (x + I y)^(2/g);
Test[g_, \[Theta]_, r_] := Block[{},
R1 = r; C1 = Sqrt[1 + r^2] E^(I \[Theta]);
\[CapitalOmega] = ImplicitRegion[ x^2 + y^2 <= 1 && Norm[ZtoW[g][{x, y}] - C1] >= R1, {{x, 0, 1}, {y, 0, 1}}];
mesh = ToElementMesh[\[CapitalOmega], MaxCellMeasure -> 0.005, AccuracyGoal -> 4];
meshB = ToBoundaryMesh[mesh, "MeshOrder" -> 2];
{1 - NIntegrate[1, {x, y} \[Element] mesh]/ NIntegrate[1, {x, y}\[Element] \[CapitalOmega]], 1 - NIntegrate[(2/g Norm[{x, y}]^(2/g - 1)), {x, y} \[Element] meshB]/(2 + \[Pi]/g - 2 ArcTan[R1] + 2 ArcTan[1/R1] R1)}
]
This function outputs a list of two numbers, the first is the estimation of the mesh accuracy and the second is the estimation of the boundary accuracy. The goal is that evaluations of Test for different values of g, θ, and r should give two numbers that are roughly equal in order of mangitude (or at least the second one should always be able to be made less that 10−3 without the code taking forever to run.
Also added: Here is an analytic derivation of my formula for the area of the boundary. For g=4, r=0.1, and θ=0.5 The boundary in the w-plane looks like so:
The length is given by 2+π/g from the contribution of the two straight edges and the unit circle, minus the chunk taken out by the "bite", plus the length of the bite. We can solve for when the bite intersects the unit circle defined by |eiα−c|=r
Now we have to add back the length of the bite. We now wish to solve |r+ceiα|=1
Putting everything together we get the analytic formula. ∫∂Dwdw=2+πg−2tan−1(r)+2rtan−1(1/r)
Update 3: I am able to get a decent boundary mesh if I don't us complex coordinates, but it takes a very long time to run the code. This also makes me think it's a Mathematica bug, as I'm explicitly checking my analytic formula. Does anyone know a way to speed up the time it takes to create a mesh? Or does anyone know workarounds to the bug I mentioned?
Comments
Post a Comment