This is my first attempt to use the Finite Element method available in version 10. There are questions and I am very open to suggestions. My example is flow around a cylinder which is a well known example of a potential problem. I wish to extend this to more general shapes. I first set up the region which is straightforward.
Needs["NDSolve`FEM`"];
x2 = 2; y2 = 1; r = 1/8;
reg = ImplicitRegion[0 <= x <= x2 &&0 <= y <= y2 &&
(x - x2/2)^2 + (y - y2/2)^2 >= r^2,{x, y}];
I make the mesh.
Question 1: can I just put the refined boundary on the inner circle and not on the outer boundary?
mesh = ToElementMesh[reg, MaxCellMeasure -> 0.0005, "MaxBoundaryCellMeasure" ->0.01];
Show[mesh["Wireframe"], Frame -> True, PlotRange -> All]
There is a problem around the circle at about 1 o'clock—expanded view below.
Question 2: is this a problem with the grid generation or the plotting of the grid?
Show[mesh["Wireframe"], Frame -> True,PlotRange -> {{0.6, 1.4}, {0.3, 0.7}}]
The differential equation is just the Laplacian and a solution is found easily.
sol = NDSolveValue[{Laplacian[u[x, y], {x, y}] ==
NeumannValue[1., x == 0] + NeumannValue[-1, x == 2]},
u, Element[{x, y}, reg]];
The solution looks good except for the artifact close to {0, 0}. This artifact disappears if PlotPoints
is increased to {50,25}.
Question 3: Is this just a plotting bug that can be ignored?
Column[{
Plot3D[sol[x, y], Element[{x, y}, reg], BoxRatios -> {2, 1, 1},
ImageSize -> 300],
Plot3D[sol[x, y], Element[{x, y}, reg], BoxRatios -> {2, 1, 1},
ImageSize -> 300, PlotPoints -> {50, 25}]
}]
A plot of the potential function around the circle, below, looks good.
Question 4: if the grid is made up as a polygon how does the solution find the values that are on the circle but not on the grid?
Plot[Evaluate[sol[1 + (r) Cos[θ], 0.5 + (r) Sin[θ]]],
{θ, 0,2 π}]
I am interested in the velocity which is the gradient of the potential function. I calculate the velocity using Grad.
ClearAll[f];
f[x_, y_] := Evaluate[Grad[sol[x, y], {x, y}, "Cartesian"]]
The following should plot the speed of the fluid around the circle.
Question 5: what is going wrong?
ϵ = 0.0;
Plot[Evaluate[Norm[f[1 + (r + ϵ) Cos[θ],
0.5 + (r + ϵ) Sin[θ]]]], {θ, 0, 2 π}]
Moving off the circle does not help much.
ϵ = 0.1;
Plot[Evaluate[ Norm[f[1 + (r + ϵ) Cos[θ],
0.5 + (r + ϵ) Sin[θ]]]], {θ, 0, 2 π}]
As usual StreamPlot has a mind of its own and does not produce the streamlines I ask for.
Question 6: is there a way of using the region defined at the start rather than a new RegionFunction
?
spts = Table[{0.001, y}, {y, 0, 1, 0.02}];
StreamPlot[f[x, y], {x, 0, 2}, {y, 0, 1}, AspectRatio -> Automatic,
RegionFunction ->
Function[{x, y, vx, vy, n}, (x - x2/2)^2 + (y - y2/2)^2 >= r^2],
StreamPoints -> spts,
Epilog -> {Point[spts], Circle[{x2/2, y2/2}, r]}]
This is an edit to my problem which may help to establish the issue as being one of a bad mesh. Starting again but making a finer mesh we see that it is sill bad but good in parts. Question: Are there other methods for making a mesh?
mesh = ToElementMesh[reg, MaxCellMeasure -> 0.00001,
"MaxBoundaryCellMeasure" -> 0.01];
Show[mesh["Wireframe"], Frame -> True,PlotRange -> {{0.95, 1.2}, {0.5, 0.7}}]
If we now solve using this faulty mesh rather than in the original question by using a default mesh we have:
sol = NDSolveValue[{Laplacian[u[x, y], {x, y}] ==
NeumannValue[1., x == 0] + NeumannValue[-1, x == 2]}, u,
Element[{x, y}, mesh]];
Calculating the gradient as before
ClearAll[f];
f[x_, y_] := Evaluate[Grad[sol[x, y], {x, y}, "Cartesian"]]
The plot of the speed is now
ϵ = 0.0;
Plot[Evaluate[Norm[f[1 + (r + ϵ) Cos[θ],
0.5 + (r + ϵ) Sin[θ]]]], {θ, 0, 2 π}]
This is good at locations away from the bad mesh. Thus the problem seems to be a mesh problem with improved mesh resolution giving better results.
NDSolveValue
is anInterpolatingFunction
, which describes how to compute values between points on the grid. That answers your question 4 and also indicates what's going on in question 5 - namely the interpolation order is too low to expect to do better. Unfortunately, I don't think it's so easy to increase that on an unstructured grid. Also, I'm not so sure how wellMaxBoundaryCellMeasure
works and your problem with the mes on the circle seems to be alleviated when you delete it. That option isn't even available toDiscretizeRegion
. $\endgroup$MaxBoundaryCellMeasure
is ignored in your code, which is why it alleviates the problem. UsingToElementMesh
directly onreg
allows one to at least reduce the value ofMaxBoundaryCellMeasure
somewhat before the problem starts. $\endgroup$