I know this error is very common. I checked out a good number of proposed solutions to this problem, but unfortunately, none of them helped in my case.
I would appreciate any help or hints on how to overcome this issue.
My program is quite simple. It is supposed to solve two coupled time-dependent partial differential equations on a sphere. I don't know if it's relevant, but from the physical point of view, it's actually the semi-classical approximation of a modified Schrodinger's equation on a sphere, with the Newtonian gravitational potential made scale-invariant.
The program is supposed to solve the PDE up to t=100, but it breaks down even at a value as low as 0.01. Here's the code with some comments for further information:
(* defining the potential that will be used in the equations. *)
V[ϕ_, θ_] :=
0.045360921162651446/Sqrt[1 + Cos[ϕ] Sin[θ]] +
0.045360921162651446/Sqrt[
1 - Sin[θ] Sin[π/6 - ϕ]] + 0.045360921162651446/
Sqrt[1 - Sin[θ] Sin[π/6 + ϕ]];
(* defining the region in which the differential equation is to be solved. θ = π/2 is avoided on purpose because of the singularities of V *)
Π1 =
ImplicitRegion[
0 <= ϕ <= 2 π &&
0 <= θ <= π/2 - 0.001, {ϕ, θ}];
Π2 =
ImplicitRegion[
0 <= ϕ <=
2 π && π/2 +
0.001 <= θ <= π, {ϕ, θ}];
Π = RegionUnion[Π1, Π2];
(* defining the two coupled PDEs. *)
firsteq = {-D[Subscript[S, 0][ϕ, θ, t], t] == -V[ϕ, θ] + (Derivative[0, 1, 0][Subscript[S, 0]][ϕ, θ, t]^2 +
Sec[θ]^2*Derivative[1, 0, 0][Subscript[S, 0]][ϕ, θ, t]^2)};
secondeq = {-D[Subscript[S, 1][ϕ, θ, t], t] == -((-Tan[θ])*Derivative[0, 1, 0][Subscript[S, 0]][ϕ, θ, t] +
Derivative[0, 2, 0][Subscript[S, 0]][ϕ, θ, t] + Sec[θ]^2*Derivative[2, 0, 0][Subscript[S, 0]][ϕ, θ, t]) +
2*(Derivative[0, 1, 0][Subscript[S, 0]][ϕ, θ, t]*Derivative[0, 1, 0][Subscript[S, 1]][ϕ, θ, t] +
Sec[θ]^2*Derivative[1, 0, 0][Subscript[S, 0]][ϕ, θ, t]*Derivative[1, 0, 0][Subscript[S, 1]][ϕ, θ, t])};
(* defining the initial conditions *)
initial = {Subscript[S, 0][ϕ, θ, 0] == Sin[θ],
Subscript[S, 1][ϕ, θ, 0] == Sin[θ]^2};
Equations = Join[firsteq, secondeq, initial];
(* Solving the equations ... *)
Solution =
NDSolve[Equations, {Subscript[S, 0], Subscript[S, 1]}, {t, 0,
100}, {ϕ, θ} ∈ Π,
Method -> "Automatic"];
I get the error:
NDSolve::ndsz: At t == 0.011684614824200409`, step size is effectively zero; singularity or stiff system suspected.
The system is indeed singular. I plotted the incomplete solution and it appears that very soon the solution diverges over some regions near the poles and equator. Is there some way to overcome this problem?
Thank you very much.
Edit:
I modified the potential to remove its singularities:
V[ϕ_, θ_] :=
0.045360921162651446/Sqrt[1.00001 + Cos[ϕ] Sin[θ]] +
0.045360921162651446/Sqrt[
1.00001 - Sin[θ] Sin[π/6 - ϕ]] + 0.045360921162651446/
Sqrt[1.00001 - Sin[θ] Sin[π/6 + ϕ]];
Following the suggestions in the comments, I tried to correct another issue in the code and define periodic boundary conditions for ϕ
. Here's the code I added. I'm grateful to @xzczd for this.
δ = 10^-5;
periodicity = {PeriodicBoundaryCondition[
Subscript[S, 0][ϕ, θ, t], ϕ == 0 &&
0 <= θ <= π , Function[x, x + {2 π, 0}]],
PeriodicBoundaryCondition[
Subscript[S, 0][ϕ, θ,
t], ϕ == 2 π + δ && 0 <= θ <= π ,
Function[x, x + {-2 π, 0}]],
PeriodicBoundaryCondition[
Subscript[S, 1][ϕ, θ, t], ϕ == 0 &&
0 <= θ <= π , Function[x, x + {2 π, 0}]],
PeriodicBoundaryCondition[
Subscript[S, 1][ϕ, θ,
t], ϕ == 2 π + δ && 0 <= θ <= π ,
Function[x, x + {-2 π, 0}]]};
But this time, I got this error:
NDSolve::ndcf: Repeated convergence test failure at t == 0.`; unable to continue.
Following @xzczd's helpful suggestion, I decided to forget about FiniteElements
and use the TensorProduct
method instead. Here's the final code. I also changed the initial conditions.
firsteq = {-D[Subscript[S, 0][ϕ, θ, t], t] == -V[ϕ, θ] + (Derivative[0, 1, 0][Subscript[S, 0]][ϕ, θ, t]^2 + Csc[θ]^2*Derivative[1, 0, 0][Subscript[S, 0]][ϕ, θ, t]^2)};
secondeq = {-D[Subscript[S, 1][ϕ, θ, t], t] == -((-Cot[θ])*Derivative[0, 1, 0][Subscript[S, 0]][ϕ, θ, t] + Derivative[0, 2, 0][Subscript[S, 0]][ϕ, θ, t] + Csc[θ]^2*Derivative[2, 0, 0][Subscript[S, 0]][ϕ, θ, t]) +
2*(Derivative[0, 1, 0][Subscript[S, 0]][ϕ, θ, t]*Derivative[0, 1, 0][Subscript[S, 1]][ϕ, θ, t] + Csc[θ]^2*Derivative[1, 0, 0][Subscript[S, 0]][ϕ, θ, t]*Derivative[1, 0, 0][Subscript[S, 1]][ϕ, θ, t])};
initial = {Subscript[S, 0][ϕ, θ, 0] == Sin[θ]^2,
Subscript[S, 1][ϕ, θ, 0] == Sin[θ]^2};
Periodicity = {Subscript[S, 0][0, θ, t] ==
Subscript[S, 0][2 π, θ, t],
Subscript[S, 1][0, θ, t] ==
Subscript[S, 1][2 π, θ, t]};
Equations = Join[firsteq, secondeq, initial, periodicity];
Solution =
NDSolve[Equations, {Subscript[S, 0], Subscript[S, 1]}, {t, 0,
10}, {ϕ, 0, 2 π}, {θ, 0, π},
Method -> {"PDEDiscretization" -> {"MethodOfLines",
"SpatialDiscretization" -> {"TensorProductGrid",
"MaxPoints" -> 500, "MinPoints" -> 500}}}];
However, after about half an hour, I got this error:
NDSolve::ndsz: At t == 0.00003716693557750961`, step size is effectively zero; singularity or stiff system suspected.
NDSolve::eerr: Warning: scaled local spatial error estimate of 1.0182820651808292`*^12 at t = 0.00003716693557750961` in the direction of independent variable ϕ is much greater than the prescribed error tolerance. Grid spacing with 500 points may be too large to achieve the desired accuracy or precision. A singularity may have formed or a smaller grid spacing can be specified using the MaxStepSize or MinPoints method options.
I tried to make the discretization finer, but the kernel crashed for MaxPoints, MinPoints = 1000.
\[Phi]
is just another symbol. You seem to think that you get away with simply cutting out a $0.001$-neighborhood near some singularity. No, you are creating a new boundary. Also, spherical coordinates are themselves singular at the north and south poles. $\endgroup$TensorProductGrid
is a better choice, see e.g. discussions here and here. And, I believe you need to re-consider the definition of the potential, can you turn to a potential free of singularity? $\endgroup$Element
andPeriodicBoundaryCondition
in your code. (See this post for more info. ) Anyway, if you want to usePeriodicBoundaryCondition
:t
should not be part of the domain, becauseFiniteElement
method is only used for spatial discretization, something likePeriodicBoundaryCondition[ Subscript[S, 0][\[Phi], \[Theta], t], \[Phi] == 0 && 0 <= \[Theta] <= \[Pi], Function[x, x + {2 \[Pi], 0}]]
(You need to modify the other 3 accordingly, of course) should work. $\endgroup$Sec[θ]
term is undoubtedly hard to handle. There might exist certain clever variable transformation that can avoid this singularity (an example is this post) but I can't think out one. Anyway, by adding a relatively large artificial viscosity term (μ=10^-1
) and choosing a relatively coarse grid (100
points for each dimension) I obtain the following $S_0$ (firsteq
only involves $S_0$, so I solve it separately): i.sstatic.net/EhS5J.png Is this solution expected? $\endgroup$