-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding an adaptive, arbitrary order, Adams-Bashforth solver #1846
Conversation
Currently performs similarly to other adaptive explicit solvers such as rkgeneric. Has the advantage that in certain cases we need the minimal number of rhs calls per step possible. Could be modified to add adaptive order as well as adaptive timestep. This may help improve performance in cases where solver stability can be limiting.
The Newton-Cotes integration routines are very repetitive so I'd hope we could make the code a bit more generic and just pass in the parameters but my initial attempts at doing this didn't work when I wanted to make everything |
I've pushed |
Fairly crude approx that costs one extra rhs per successful internal step. For the test-drift-instability test case enabling this options leads to a factor two reduction in runtime for the longest running case (but this still remains an order of magnitude longer than with pvode).
Changed target to v4.4.0-alpha. I've also added an initial attempt at adaptive order - it could probably be more efficient but still seems to help for some test cases. |
Currently the adaptive order has unintended behaviour in that as soon as one internal timesteps flags that the order should be lowered we do not increase the order for the remainder of the output step. On fixing this I saw that total time actually increased, if I limited the maximum order to 2 (essentially disabling the adaptive order code) I got about the same time as with this "broken" version so I think the majority of the performance gain was essentially just coming from limiting the order to 2. With the fixed version I do still find a decent saving for the test case when using a maximum order of 5 and enabling adaptive order (72s vs 45s, the "broken" version is about 36s). Looking into this a bit more it seems that with the fixed adaptive order approach there are more failed internal steps, likely due to the smaller regions of stability as the order increases (and we allow more time at higher order in the fixed version). This explains some of the increase in runtime but not all of it (maybe 10-20% of it). The rest must come from an increase in the number of right hand side calls due to an average smaller dt. We could perhaps be more aggressive in how we pick the timestep but in practice this seems to generally make things worse. We currently unconditionally increase the order up to the maximum order unless we've just decided to use the lower order method, perhaps we should be more conservative about this and just increase the order when the timestep gets too small with the current order (or similar). |
Testing on the interchange test case the current AB solver seems to fair much worse than rkgeneric with the cash-karp scheme. With AB the test case fails due to exceeding MXSTEP whilst rkgeneric passes the test with just 7 rhs per output time. One area of difference is in the definition of the error, for rkgeneric it's |
Ah, it seems there was a fairly significant bug -- the state vector was only being put into the fields at the end of output steps and inside the adaptive algorithm. This means that for adaptive runs the derivative used at the current time was actually lagging behind by half a time step and for non-adaptive runs it was lagging behind by a whole output step. Fixing this makes the interchange test pass and speeds up the drift test case (down to 28s, c.f. 64s for Cash-Karp) whilst maintaining accuracy. I guess this also highlights that our current tests aren't that sensitive to solvers doing exactly the correct thing. |
Also be a little more aggressive with our timestep changes
Now we don't actually calculate the rhs again at half time step point with the lower order. This saves one rhs call per successful internal timestep when adaptive_order is true.
Wishlist for future work:
|
* next: (953 commits) Add paragraph on setting staggered location for Laplacian solvers Update info on allowed staggering in derivatives Fix reference to sec-iterating Add MUMPS removal to list of breaking changes Typofix fix typo Add dash as travis job Avoid bashism += in configure Fix formatting of 'Obtaining BOUT++' section heading Remove MUMPS prefer PETSc over petsc with pkg-config Find PETSc with pkg-conf using configure ensure quiet script isn't to verbose on error Don't use old-style-cast Adjust field compat messages for fmt Better debug messages for fields compatibility fix requires in options-netcdf test improve error messages Ensure ffts are OpenMP thread safe Improve CPU detection in run_wrapper ...
Avoids else-after-break and reduces indentation
- "implicit bools" - extra semicolons - sign comparison - braced conditionals
Sorry, I had already merged in |
Changes look good to me, thanks for tidying this. |
This is nice and self-contained and could be back-ported |
Currently performs similarly to other adaptive explicit solvers such as
rkgeneric. Has the advantage that in certain cases we need the minimal
number of rhs calls per step possible.
Could possibly be modified to add adaptive order as well as adaptive
timestep. This may help improve performance in cases where solver
stability can be limiting.
Code may well need some restructuring but I'd thought I'd create the PR now so we can have the discussion here.
This is a candidate for backporting and as it is essentially just new files (and changes to makefiles) it was recommended that I branch from master, and hence my PR is currently targeting
masterv4.4.0-alpha. This should be easy to apply to other branches.