I have two PDEs that describe the movement of fluid:
- $h_t + [h^3(1-h)^3((1+\varepsilon h)\sin \theta - \varepsilon h_\theta \cos \theta]_\theta$ = 0
- $h_t - [h^3(1-h)^3 \varepsilon h_\theta]_\theta$ = 0
You will note that 1) reduces to 2) at $\theta = 0$.
I solve these two PDE's via a finite difference scheme. The first as follows
n = 1001; ϵ = 0.5;
ds = Pi/(n - 1);
ClearAll[dh, t]; endtime = 100;
dh[h_List] := With[{ϵ = 0.5, s = Array[#1 & , n, {-(Pi/2), Pi/2}], d1 = ListCorrelate[{-0.5, 0, 0.5}/ds, #1] & , d2 = ListCorrelate[{1, -2, 1}/ds^2, #1] & },
((-1 + h)^2*h^2*(3*(1 - 2*h)*ϵ*Cos[s]*d1[#1]^2 + (-1 + h)*h*Cos[s]*(1 + h*ϵ - ϵ*d2[#1]) + (-3 + h*(6 + (-5 + 8*h)*ϵ))*d1[#1]*Sin[s]) & )[Join[{0.99}, h, {0.99}]]];
h0 = Table[Piecewise[{{0.01, -0.25510204081632654 < θ < 0.25510204081632654}}, 0.99], {θ, -(Pi/2), Pi/2, ds}];
Clear[h];
sol = With[{h = (h[#1][t] & ) /@ Range[n]}, NDSolveValue[{D[h, t] == dh[h], (h /. t -> 0) == h0}, Head /@ h, {t, 0, endtime}]]; valh = Transpose[(#1["ValuesOnGrid"] & ) /@ sol];
ti = Flatten[sol[[1]]["Grid"]];
s = Array[#1 & , n, {-(Pi/2), Pi/2}]; h = ListInterpolation[valh, {ti, s}, InterpolationOrder -> 1];
This solves reasonably quickly. I check area conservation between $t = 0$ and $t = 100$ with the following:
Table[Integrate[Interpolation[Table[{θ, 0.99 - h[t, θ]}, {θ, -(Pi/2), Pi/2, Pi/3000}], InterpolationOrder -> 1][θ], {θ, -(Pi/2), Pi/2}], {t, {0, 100}}]
An error of $0.96 \%$, which I can reduce to $0.19\%$ by increasing $n$ to 2001. I am happy with this.
However, my problem comes in when solving the second PDE (which I feel in theory should be easier as it is a simplification of the first one). I solve in the same manner (initial condition is flipped due to minus sign and physical reasons).
n = 1001; ϵ = 0.5;
ds = Pi/(n - 1);
ClearAll[dz, t]; endtime = 100;
dz[z_List] := With[{ϵ = 0.5, s = Array[#1 & , n, {-(Pi/2), Pi/2}], d1 = ListCorrelate[{-0.5, 0, 0.5}/ds, #1] & ,
d2 = ListCorrelate[{1, -2, 1}/ds^2, #1] & }, ((-ϵ)*(-1 + z)^2*z^2*((-3 + 6*z)*d1[#1]^2 + (-1 + z)*z*d2[#1]) & )[Join[{0.01}, z, {0.01}]]];
z0 = Table[Piecewise[{{0.99, -0.25510204081632654 < x < 0.25510204081632654}}, 0.01], {x, -(Pi/2), Pi/2, ds}];
Clear[z];
solz = With[{z = (z[#1][t] & ) /@ Range[n]}, NDSolveValue[{D[z, t] == dz[z], (z /. t -> 0) == z0}, Head /@ z, {t, 0, endtime}]];
valz = Transpose[(#1["ValuesOnGrid"] & ) /@ solz];
tiz = Flatten[solz[[1]]["Grid"]];
s = Array[#1 & , n, {-(Pi/2), Pi/2}]; z = ListInterpolation[valz, {tiz, s}, InterpolationOrder -> 1]
Firstly, with $n = 1001$ this takes an age to run on my machine. Secondly, when I check conservation of area for PDE 2.
Table[Integrate[Interpolation[Table[{θ, z[t, θ] - 0.01}, {θ, -(Pi/2), Pi/2, Pi/3000}], InterpolationOrder -> 1][θ], {θ, -(Pi/2), Pi/2}], {t, {0, 100}}]
I get a massive $13.5 \%$ discrepancy between the initial and final error. I could in theory reduce this by increasing $n$, however I tried with $n = 2001$ and the code was running for 8+ hours before I aborted it.
Does anyone have any pointers? My ultimate aim is to have PDE 2 conserving area and solving quickly. Does my FD scheme need some work?
All comments and questions welcomed.
EDIT
By adding the option Method -> {"EquationSimplification" -> "Residual"}
to NDSolveValue
for equation 2 I can solve for $n = 5001$ points in about 30 minutes. This still gives an intolerable error of $\approx 5 \%$.
NDSolve
"out of the box"? Could you also describe what the initial and boundary conditions are for this problem? Spreading of a droplet on some sort of wetting surface? $\endgroup$