I have been working a certain type of 3D cylindrical diffusion equation for a bit now. I am trying to simulate a longitudinal diffusion process in a cylinder with a dislocation defect that will make the heat flow spiral upward as you can see underneath with these two animations :
Here you can find the code I used to simulate an upward diffusion process along a cylinder.
(*parameters*)
r0 = 0.5;
r1 = 1;
h = 10;
\[Beta] = 1;
(*arg[z_]/;Im[z]<0:=Arg[z]+2 \
Pi;arg[z_]/;Im[z]\[GreaterEqual]0:=Arg[z] possible alternative to \
Mod[Artan[x,y],2Pi]*)
(*region definition*)
reg = Cuboid[{r0, 0., 0.}, {r1, 2 Pi, h}];
reg3D = ImplicitRegion[
r0^2 <= x^2 + y^2 <= 1 && 0 <= z <= h, {x, y, z}];
(*equation + conditions*)
eq3 = D[u[t, r, \[Theta], z],
t] - (D[u[t, r, \[Theta], z], r, r] + (1/r)*
D[u[t, r, \[Theta], z], r] +
1/(r^2)*D[
u[t, r, \[Theta],
z], \[Theta], \[Theta]] + (r^2 + \[Beta]^2)/(r^2)*
D[u[t, r, \[Theta], z], z, z] - (2 \[Beta]^2/r^2) D[
u[t, r, \[Theta], z], z, \[Theta]]);
ic = u[0, r, \[Theta], z] == 1;
bc = DirichletCondition[u[t, r, \[Theta], z] == 0, z == 0];
nV = NeumannValue[0, r == r1] + NeumannValue[0, r == r0] +
NeumannValue[1, z == h];
(*solution computation*)
sol = NDSolveValue[{eq3 == nV, ic, bc},
u, {t, 0, 5}, {r, \[Theta], z} \[Element] reg];
frames = Table[
DensityPlot3D[
sol[t, Sqrt[x^2 + y^2],
Mod[Arctan[x, y], 2 Pi],z], {x, y, z} \[Element] reg3D,
ColorFunction -> "Rainbow", OpacityFunction -> None,
Boxed -> False, Axes -> False, PlotRange -> All, PlotPoints -> 50,
PlotLabel -> Row[{"t = ", t}],
ColorFunctionScaling -> False], {t, .05, 5, .05}];
Export["better view all.mov", frames]
As you can see with these animations, there seem to be a discontinuity on the left side of the cylinder. This discontinuity left me quite puzzled as I could not find any physical explanation. The equation itself does not hint at any kind of irregularities with respect to theta. The solution should be continuous around the cylinder, especially if we imagine that the solution represents temperature for instance, then such behavior would be prohibited.
After discussing this with some other people, I remembered a very simple fact that I had totally missed. The discontinuity I was trying hard to explain could simply come from the Arctan[x,y]
function I was using when I tried to animate the whole diffusion process.
I tried using other alternatives, for instance, I tried using Mod[Arctan[y/x],2Pi]
instead but it gave me the following animation.
At least I now know that it's the conversion between cartesian and polar coordinates that gives me such a peculiar discontinuity.
I also tried using the Arg
function and even tried building one that goes from 0 to 2Pi following the answers found here. However it pretty much gave me the same result as with Mod[Arctan[x,y],2Pi]
.
I searched for some similar questions asked here regarding the Arctan function and found this question here showing us how to build a version of Arctan that could potentially help me here. However it was fruitless in the end as the simulation failed this time and gave me a blank video showing a white background.
Eventually I was very interested in how the discontinuity in the Arctan function was bypassed in this post by using the derivative of said function and then integrating when needed, however I am still working on that lead (I'm still a beginner when it comes to Mathematica alright...).
In the end, I'm fairly sure that it isn't a "physical discontinuity" but instead is induced by my own algorithm but I would like to know your opinion on that matter as I could very well be wrong from the start. And if so, is there a way for me to possibly get a nice simulation without such a discontinuity ?
I would really appreciate the help, even just tiny hints. Thanks in advance.
Edit : Thanks the advice of user xzczd, I revised my code so that It contains periodic boundary conditions, following the example given here using double pbcs and ghost vicinity. I now have the following code :
(*parameters*)
r0 = 0.5;
r1 = 1;
h = 5;
\[Beta] = .5;
(*Ghost vivinity parameter*)
epsilon = 0;
(*region definition*)
reg = Cuboid[{r0, -2 Pi - epsilon, 0.}, {r1, 2 Pi + epsilon, h}];
reg3D = ImplicitRegion[
r0^2 <= x^2 + y^2 <= r1 && 0 <= z <= h, {x, y, z}];
(*Diffusion equation*)
eq = D[u[t, r, \[Theta], z],
t] - (D[u[t, r, \[Theta], z], r, r] + (1/r)*
D[u[t, r, \[Theta], z], r] +
1/(r^2)*D[
u[t, r, \[Theta],
z], \[Theta], \[Theta]] + (r^2 + \[Beta]^2)/(r^2)*
D[u[t, r, \[Theta], z], z, z] - (2 \[Beta]^2/r^2) D[
u[t, r, \[Theta], z], z, \[Theta]]);
(*Initial and boundary conditions*)
ic = u[0, r, \[Theta], z] == 1;
bc = DirichletCondition[u[t, r, \[Theta], z] == 0,
z == 0];
pbc={PeriodicBoundaryCondition[u[t,r,\[Theta],z],\[Theta]\
\[Equal]2Pi+epsilon&&0<z<h,TranslationTransform[{0,-2Pi,0}]\
],PeriodicBoundaryCondition[u[t,r,\[Theta],z],\[Theta]\[Equal]0-\
epsilon&&0<z<h,TranslationTransform[{0,2Pi,2Pi*\[Beta]0e[0, r == r0] +
NeumannValue[1, z == h];
(*solution computation*)
sol = NDSolveValue[{eq == nV, ic, bc(*,pbc*)},
u, {t, 0, 15}, {r, \[Theta], z} \[Element] reg];
(*Animation of the diffusion process*)
frames = Table[
DensityPlot3D[
sol[t, Sqrt[x^2 + y^2], Mod[ArcTan[x, y], 2 Pi],
z], {x, y, z} \[Element] reg3D, ColorFunction -> "Rainbow",
OpacityFunction -> None, Boxed -> False, Axes -> False,
PlotRange -> All, PlotPoints -> 50, PlotLabel -> Row[{"t = ", t}],
ColorFunctionScaling -> False], {t, .05, 15, .05}];
Export["beta=1.mov", frames]
This new code allows me to get a nice continuous animation, at the expense of the spiraling motion, however, which completely defeats the purpose...
I really don't know what to do now.
sol[t, Sqrt[x^2 + y^2], Mod[ArcTan[x, y], 2 Pi], z]
? $\endgroup$PeriodicBoundaryCondition
properly. TryPeriodicBoundaryCondition[u[t, r, \[Theta], z], \[Theta] == 0 && 0 < z < h, TranslationTransform[{0, 2 Pi, 0}]]
. Also, you need 2PeriodicBoundaryCondition
. For more info please check the answer linked in my last comment. $\endgroup$TriangleElement
is only for spatially 2D problem. Now ghost vicinity as shown here seems to be the only choice. Also, since your domain is regular, the old goodTensorProductGrid
is also a possible choice. (It's much easier to set periodic b.c. whenTensorProductGrid
method is chosen. ) $\endgroup$