I am working with a set of three coupled reaction-diffusion PDEs, and for some parameter values I am getting some not so great solutions. I have been searching documentation and tutorials, and I have been trying to implement various methods and change various settings, but I feel like I am just blindly trying things without fully understanding what is going on. The equations might look intimidating, but I have supplied my code as well to help make everything reproducible.
As a summary, I was asking about why a bad solution is obtained for a certain parameter set. As I went through testing my problem to make this post I came across a second issue where the solution behavior also depended on the end time of integration, which seems odd to me. Why am I running into these issues?
Equations
The set of equations I am working with is as follows: $$\frac{\partial x}{\partial t}=\left(1+\frac{\gamma_{pL}\cdot y_T}{(1+\gamma_P\cdot x)^2}\right)^{-1}\cdot\left[\gamma_{D_P}\cdot\nabla^2x+\gamma_a\cdot x_I+\gamma_c\cdot\frac{\gamma_{pL}}{\gamma_P}\cdot\left(\frac{\gamma_P\cdot x}{1+\gamma_P\cdot x}\right)^2\cdot y_T\right]$$
$$\frac{\partial y_T}{\partial t}=-\gamma_c\cdot\frac{\gamma_P\cdot x}{1+\gamma_P\cdot x}\cdot y_T$$
$$\frac{\partial z}{\partial t}=\left(1+\frac{\gamma_R}{(1+\gamma_L\cdot z)^2}\right)^{-1}\cdot\left[\gamma_{D_L}\cdot\nabla^2z+\gamma_c\cdot\frac{\gamma_P\cdot x}{1+\gamma_P\cdot x}\cdot y_T\right]$$
where $x$, $y_T$, and $z$ are functions of $r$ (polar coordinate) and $t$ (time), $x_I$ is a source term given by $$x_I=\frac{1}{2\cdot\gamma_{D_P}\cdot t+1}\cdot\exp\left(-\frac{r^2}{2\cdot(2\cdot\gamma_{D_P}\cdot t+1)}-\gamma_a\cdot t\right)$$ and all $\gamma_i$ terms are parameters.
Initial conditions and boundary conditions are as follows: $$x(r,0)=z(r,0)=0,\ y_T(r,0)=1$$ $$\left.\frac{\partial x}{\partial t}\right|_{r=0}=\left.\frac{\partial z}{\partial t}\right|_{r=0}=0$$ $$x(\infty,0)=z(\infty,0)=0$$
In words, we start off with no $x$ and $z$, and $y_T$ starts at a maximum value of $1$ across all space. The no-flux boundary condition at the origin is because the system has radial symmetry, and we want $x$ and $z$ to go to $0$ at $\infty$.
Code
To tweak the above equations to work nicely in Mathematica (I think?), we need to use a "large" value of $r$ in place of $\infty$ and we need to use a point close to $r=0$ rather than $r=0$ itself (due to the $1/r$ term in the Laplacian in polar coordinates).
dr = .001; (*"small" r since we cannot use the origin in polar coordinates*)
ρFar = 100.; (*r that is "infinity"*)
τmax = 6.38;(*time to solve out to*)
The equations above:
xI = 1/(2*γDP*t + 1)*Exp[-(r-dr)^2/(2*(2*γDP*t + 1)) - γa*t];
dx = D[x[r, t],t] == (1 + (γpL*yT[r, t])/(1 + γP*x[r,t])^2)^-1*(γDP*Laplacian[x[r, t], {r, θ}, "Polar"] + γa*xI + γc*γpL/γP*((γP*x[r, t])/(1 + γP*x[r, t]))^2*yT[r, t]);
dyT = D[yT[r, t], t] == (-γc*γP*x[r, t]*yT[r, t])/(1 + γP*x[r, t]);
dz = D[z[r, t],t] == (1 + γR/(1 + γL*z[r, t])^2)^-1*(γDL*Laplacian[z[r, t], {r, θ},"Polar"] + (γc*γP*x[r, t]*yT[r, t])/(1 + γP*x[r, t]));
Intial/Boundary Conditions:
initx = x[r, 0] == 0.;
bc1x = (D[x[r, t], r] == 0) /. r -> dr;
bc2x = x[ρFar, t] == 0.;
inityT = yT[r, 0] == 1.;
initz = z[r, 0] == 0;
bc1z = (D[z[r, t], r] == 0) /. r -> dr;
bc2z = z[ρFar, t] == 0.;
Putting it all together:
deqns = {dx, dyT, dz, initx, bc1x, bc2x, inityT, initz, bc1z, bc2z};
Problem
My problem arises for certain parameter values (not all). I have also found that using
MaxStepSize -> .1
for NDSolveValue seems to help with some instances of my problem, but not all. An example of a "good solution" can be obtained with the following parameters
paramsGood = {γDP -> 0.001222, γDL -> 122.2, γa -> 1., γc -> 100., γP -> 0.01, γpL -> 0.01, γL -> 100., γR -> 0.01};
zSoln = NDSolveValue[deqns /. paramsGood, z, {r, dr, ρFar}, {t,0., τmax}, MaxStepSize -> .1];
Plot[zSoln[r, 2.6], {r, dr, 15}, PlotRange -> {-.002, .002}]
However, the following bad parameter set
paramsBad = {γDP -> 0.1222, γDL -> 122.2, γa -> 100., γc -> 1., γP -> 0.01, γpL -> 100., γL -> 1000., γR -> 100.};
gives an issue in the solution for $z$ (I have picked the time $t=2.6$ to show the bad solution, but the solution doesn't seem good from the start).
zSoln = NDSolveValue[deqns /. paramsBad, z, {r, dr, ρFar}, {t,0., τmax}, MaxStepSize -> .1];
Plot[zSoln[r, 2.6], {r, dr, 15}, PlotRange -> {-.002, .002}]
None of the dependent variables should be negative.
I have tried modifying the MaxStepSize, StartingStepSize, and specifying a spatial discretization as suggested in the documentation:
Method -> {"PDEDiscretization" -> {"MethodOfLines", "SpatialDiscretization" -> {"TensorProductGrid", "MinPoints" -> 1000}}}
but I cannot seem to fix this issue. Sometimes these things fix the problem, but then for other parameter values the issues come right back (for example, I think making the MinPoints option above larger fixes for this parameter set, but not for all of the. Additionally the solution ends up taking a long time). Why is this happening for the numerical solver, and what is the most efficient way to determine a well-behaved solution Note that I need to be able to solve these equations fairly quickly.
Second Problem
If I just change the end time to $t=6.5$ the solution ends up behaving differently. There is a very small response in $z$, but it at least looks well-behaved?
zSoln = NDSolveValue[deqns /. paramsBad, z, {r, dr, ρFar}, {t,0., 6.5}, MaxStepSize -> .1];
Plot[zSoln[r, 2.6], {r, dr, 15}, PlotRange -> {-.002, .002}]
Also, this issue does not occur for the "good parameter set"; the solution does not show any notable difference in choice of the final integration time.
So this really makes me question how do I make sure I am getting a legitimate solution here? Which settings should I employ to be confident in my solutions for a wide range of parameters?
MaxStepSize -> .1
is not close to providing adequate resolution neart = 0
andr = 0
forparamsBad
. In fact it really is not adequate forparamsGood
. However, just decreasingMaxStepSize
to .001
leads to a very slow computation. I am exploring various options. I should add that you really need to usePlot3D
to see whether your answers are reasonable. $\endgroup$t = 6.5
does not solve the problem either. It just moves it to a different time slice. "Why" remains a good question, though. $\endgroup$t = 0
,r = 0
to see a negative spike even fortmax = 6.5
This differs fromtmax = 6.38
, because the temporal zoning changes.Use
zSoln["Coordinates"]` to see the zoning.. I shall look at this some more tomorrow. $\endgroup$