Closed mjyshin closed 2 years ago
Yeah this is a complex one. DiffEqApproxFun was a fun project but ultimately it wasn't the most efficient way to do things. There's a few things going on that made it a bit awkward to connect. Simply putting Fun objects into the differential equation solver works (or at least used to work), and so we had quite a few nice demos showcasing it.
That said, mixing it with the stiff ODE solvers was always precarious because of how the adaptivity works. ApproxFun.jl always tries to expand the function in the basis to floating point eps accuracy. The stiff ODE solvers are trying to solve a linear solve (Krylov etc. if you choose it) to some tolerance, some nonlinear solve to a tolerance, and then checking that the error of a step is within tolerance. This tolerance of course is usually much higher than 1e-16, so ApproxFun ends up doing a ton of work to get something that is more accuracy than necessary. On top of that, this iterative process only ever can increase the number of Fourier modes. So while it was working, we saw that it could easily overflow the memory, even when using L-stable solvers (our hypothesis at first was that L-stability was required in order to achieve stability with this adaptivity. While that may be the case, this numerical issue is moreso simply a result of reasonable adaptivity rules clashing). So in the end, one could use automated code generation to get something to work here, but it wasn't the fastest implementation and it only really worked well with non-stiff ODE solvers, where we really wanted the implicit methods and such.
The better ways to do this are to do things like, generating code for a pseudospectral discretization and only adaptive between steps, not operations or stages. This can be done by pairing a pseudospectral discretization with a callback that resize!
s the integrator based on the integrator.EEst
estimates and such. And since the time of ApproxFun, we've also built out an entirely new set of automation on PDEs. Specifically, the ModelingToolkit.jl PDESystem interface gives someone a generic symbolic way of defining a PDE that can be consumed by any discretizer, of which there are currently MethodOfLines.jl for finite difference and NeuralPDE.jl for physics-informed neural network PDE solvers. We plan to then extend this implementation to include NeuralOperators.jl for Fourier Neural Operator and DeepONet solvers, a wrapper to Gridap.jl/FEniCS.jl, and, you guessed it, a pseudospectral discretizer (most likely built on ApproxFun.jl). Not only would this make the syntax a lot cleaner (it would allow a user to simply describe the equations symbolically), it would allow for more optimal code, allow for putting this all in an interface where the solution handling is the same between all PDE solvers, and allow for symbolic manipulations to improve the PDE's formulation before the numerical solve occurs. Because of how this is strictly better, we have halted most of the tests with ApproxFun.jl for now, are finishing MethodOfLines.jl, and then will continue that project to the spectral parts.
In the meantime, there are some documentation examples for how to use ApproxFun-generated operators for things like transforms and application of derivatives in a given basis. You can find examples of doing this in the SciMLBenchmarks, such as
https://benchmarks.sciml.ai/html/MOLPDE/burgers_spectral_wpd.html
And that's the kind of workflow that we plan to generate from the symbolic PDE descriptions.
In the documentation, it says that there is full compatibility with ApproxFun types, but I am having trouble timestepping (nonlinear) PDEs forward as ODEs of ApproxFun
Fun
s. Using the periodic example in the now-deprecated DiffEqApproxFun.jl's readme, I would imagine it might be possible to do something likewhich builds the problem type just fine, but then be able to solve using
which currently doesn't work. Also, I liked the general idea of putting nontrivial boundary conditions in the callback argument (I think this is different from how
ode15s
is used in MATLAB's Chebfun because there the BCs are baked into the nonlinear operator object), although it might be nice to have something in the same vein asBVProblem
like(no doubt much easier said than done). I am wondering why the DiffEqApproxFun.jl project (and SpectralTimeStepping.jl) has been discontinued? The readme says that there are "better ways to do this"... What are those ways?