Motivation
As discussed here, NDSolve
uses different difference orders for various spatial derivatives and the implicit design could cause trouble in certain cases.
Thus, it may be useful to specify the difference order for spatial derivatives as well as customize difference scheme for time advance in some applications. And that's why I'm trying to use a finite difference method (FDM) encoded in NDSolve
to construct a lower-level PDE solver instead of using the high-level NDSolve
black box directly.
Problem
Consider a system of PDEs which will be solved with specified FDM encoded in
myFDM[points, xdifforder, torder]
:
secondDop[x_, α_] = (D[#, {x, 2}] - (α^2 + 1)*#) &; (*define a differential operator*)
With[{a = a[t, x], b = b[t, x], c = c[t, x], q = q[t, x], U = x},
eq = {I*α*a - D[b, x] + I*c == 0,
-D[a, t] == 1/m*secondDop[x, α][a] - I*α*U*a - I α q,
-D[b, t] == -a*D[U, x] + 1/m*secondDop[x, α][b] -
I*α*U*b + D[q, x],
-D[c, t] == 1/m*secondDop[x, α][c] - I*α*U*c - I*q};
(* values in ICs could be adjusted to allow the code to be run *)
ic = {a == 1-x^2, b == Sin[x π], c == 0, q == 1} /. t -> endtime;
bc = {{a == 0, b == 0, c == 0, q == 1} /.
x -> -1, {a == 0, b == 0, c == 0, q == 1} /. x -> 1};]
endtime = 5; points = 100;
m=200;
xdifforder = 2; torder = 2; (* Difference orders in x and t *)
grid = Array[# &, points, {-1, 1}]; (*spatial points separated by a distance of 2/points*)
bsol=NDSolveValue[{eq, ic, bc}, {a, b, c, q}, {t, endtime, 0}, {x, -1, 1},
Method -> [myFDM[points, xdifforder, torder]]]
Specifications and Questions
I believe the desired function myFDM
should be a modification of the pdetoode
solver developed here by xzczd with the following significant differences. (Although I have learned Wolfram language for a long time some parts in pdetoode
are still confusing for me, e.g. the line to remove redundant equations from every PDE/IC in moveredundant
...)
My problem includes 4 PDEs instead of one PDE;
These PDEs will be integrated from
endtime
to0
due to mathematical reasons, i.e. backward, as implied by the minus sign before each time derivative term on the LHS.
Thank you very much.
NDSolve
to solve the PDE system, similar to those introduced intutorial/NDSolveExplicitRungeKutta
? If so, I should say it's very hard, if not impossible.ExplicitRungeKutta
seems to be the only method that can be highly customized inNDSolve
, at least according to the introduction in the document. That's the reason I createpdetoode
,fix
etc. attempting to break the limitation somewhat outside ofNDSolve
. BTW, your problem is similar to this one: mathematica.stackexchange.com/q/163923/1871 The bottleneck iseq[[1]]
. $\endgroup$pdetoode
and fix the order of the derivatives, then solve the obtained ODEs. R2. yes,eq[[1]]
is hard to handle due to the absence of time derivative. From above link I realized thatD
oneq[[1]]
allowsNDSolve
to choose an ODE solver. Questions: Q1. Inpdetoode
, can u explicitly choose the spatial scheme, say, 2nd-order central difference? Did u mean it's impossible or very hard to control time-marching scheme inNDSolve
even withpdetoode
? $\endgroup$pdetoode
is set to2
, 2nd order central difference formula is chosen for all the grid points except for those on the boundary, you can play with a coarse grid, say,Array[#&, 5, {0,1}]
and observe the resulting system. 2. By "customize" I mean creating something not built-in. If you just want to control the ODE solver, it's not hard, but do notice the ODE solver is robust enough and don't need any manual adjustion in most cases, the bottleneck for PDE solving is almost always the spatial discretization. $\endgroup$D[eq[[1]], t]
won't invoke ODE solver, because the system still doesn't involveD[q, t]
term afterwards. $\endgroup$