Edit2: Added code to back-substitute numerical solution into DE
Edit1: Changed after studying solution
Plotting sol[x,y,8] below one sees it begins very small oscillations between positive and negative values assuming the machine-precision FEM method employed yields and accurate solution and the oscillations aren't spurious. One could back-substitue the solution to check this. Assuming the solution is indeed correct, then this is of course problematic if one is interested in taking the log of the solution unless further processing of the solution is acceptable such as using absolute values or other methods.
Back-substitution of solution into DE:
(* compute solution with cell measure=0.0005 *)
cellMeasure = 0.0005;
delt[x_, y_] :=
PDF[MultinormalDistribution[{0, 0}, {{1/2, 0}, {0, 1/2}}], {x,
y}];
b = 1; k = 1; n = 4; S = 1/2; a = 2/10;
FPE = \!\(
\*SubscriptBox[\(\[PartialD]\), \(t\)]\(p[x, y, t]\)\) == s*\!\(
\*SubscriptBox[\(\[PartialD]\), \(x, x\)]\(p[x, y, t]\)\) + s*\!\(
\*SubscriptBox[\(\[PartialD]\), \(y, y\)]\(p[x, y, t]\)\) - \!\(
\*SubscriptBox[\(\[PartialD]\), \(x\)]\((\((\((a*x^n)\)/\((S^n +
x^n)\) + \((b*S^n)\)/\((S^n + y^n)\) - k*x)\)*
p[x, y, t])\)\) - \!\(
\*SubscriptBox[\(\[PartialD]\), \(y\)]\((\((\((\((a*y^n)\)/\((S^n +
y^n)\) + \((b*S^n)\)/\((S^n + x^n)\) - k*y)\))\)*
p[x, y, t])\)\);
s = 1/100;
sol = NDSolveValue[ {FPE, p[x, y, 0] == delt[x, y],
p[3, y, t] == 0,
p[0, y, t] == 0,
p[x, 0, t] == 0,
p[x, 3, t] == 0
}, p, {t, 0, 10}, {y, 0, 3}, {x, 0, 3},
Method -> {"MethodOfLines", "TemporalVariable" -> t,
"SpatialDiscretization" -> {"FiniteElement",
"MeshOptions" -> MaxCellMeasure -> cellMeasure}}];
Now plot p(x,y,t) and a yellow trace of p(x,0.8,8) just for visualization:
(* Plot magnified solution and a yellow trace of the solution \
p(x,0.8,8) *)
trace1 =
ParametricPlot3D[{x, 0.8, sol[x, 0.8, 8]}, {x, 0, 3},
PlotStyle -> Yellow, PlotRange -> All];
magPlot =
Plot3D[sol[x, y, 8], {x, 0, 3}, {y, 0, 3}, PlotPoints -> 250,
BoxRatios -> {1, 1, 0.5},
PlotLabel -> Style["Magnified Plot", 16, Bold, Black],
AxesLabel -> {Style["x", 16, Bold, Black],
Style["y", 16, Bold, Black], Style["p(x,y,8)", 16, Bold, Black]},
ClippingStyle -> None];
Show[{magPlot, trace1}]
Now compare the left side of the DE with the right side of the DE at the point (1.2,0.8,8) along the yellow trace (or any other point (x,y,8) and print the values:
tVal = 8;
yVal = .8;
xVal = 1.2;
leftSide = (\!\(
\*SubscriptBox[\(\[PartialD]\), \(t\)]\(p[x, y, t]\)\) //. {p -> sol,
x -> xVal, y -> yVal, t -> tVal});
rightSide = (s*\!\(
\*SubscriptBox[\(\[PartialD]\), \(x, x\)]\(p[x, y, t]\)\) + s*\!\(
\*SubscriptBox[\(\[PartialD]\), \(y, y\)]\(p[x, y, t]\)\) - \!\(
\*SubscriptBox[\(\[PartialD]\), \(x\)]\((\((\((a*x^n)\)/\((S^n +
x^n)\) + \((b*S^n)\)/\((S^n + y^n)\) - k*x)\)*
p[x, y, t])\)\) - \!\(
\*SubscriptBox[\(\[PartialD]\), \(y\)]\((\((\((\((a*y^n)\)/\((S^n +
y^n)\) + \((b*S^n)\)/\((S^n + x^n)\) - k*y)\))\)*
p[x, y, t])\)\)) //. {p -> sol, x -> xVal, y -> yVal,
t -> tVal};
Print["Left side: ", leftSide];
Print["Right side: ", rightSide];
(* Left side: -3.92564*10^-7 *)
(* Right side: 0.0000816017 *)
The difference is not small. I'm not proficient with PDEs and now sure why. You should be able to study this code and test it at other points.
sol[x,y,8]
, the function plots fine (also p needs to be capitalized in Plot3D):Plot3D[sol[x, y, 8], {x, 0, 3}, {y, 0, 3}, PlotRange -> All]
If we look atNMinValue[{sol[x, y,8], 0 <= x <= 3, 0 <= y <= 3}, {x, y}]
we see thatsol[x,y,8]
is negative at some points in the plot domain, so I thought maybe looking atLog@Abs[sol[x,y,8]]
might be able to plot, or plottingsol[x,y,8]
with "SignedLog" scaling on the z-axis would work, but it does not for me.DiscretePlot
does work however: (cont'd in next comment) $\endgroup$DiscretePlot3D[Log[Abs[sol[x, y, 8]]], {x, 0, 3, 0.01}, {y, 0, 3, 0.01}, ColorFunction -> "TemperatureMap", Joined -> True, Filling -> None]
Note I plot Log[Abs[sol[x,y,8]] since it is negative in parts of the domain. $\endgroup$RealExponent[...]
instead which gives Log[Abs[...]]]:Plot3D[-RealExponent[sol[x, y, 8]], {x, 0, 3}, {y, 0, 3}, PlotRange -> All, ColorFunction -> "TemperatureMap", PlotPoints -> 100]
this plotted for me. $\endgroup$RealExponent
is base 10, while default forLog
is base E. To change to base E, do RealExponent[x,E]. To completely ignore negative values, you could clip values of sol[x,y,8] to be 0 when they are negative. This is really slow to plot with Plot3D however so I just make a table of values and ListPlot3D them:clipped[x_, y_] := Clip[sol[x, y, 8], {0, Infinity}]; cTab = Flatten[Table[{x, y, -Log[clipped[x, y]]}, {x, 0, 3, 0.01}, {y, 0, 3, 0.01}], 1]; ListPlot3D[cTab, PlotRange -> All, ColorFunction -> "TemperatureMap"]
$\endgroup$