Refactor PETSc preconditioner for CVODE#3382
Conversation
Use the same coloring, preconditioning code in CVODE, PETSc and SNES time-integration solvers. Major refactoring by Codex. Much more testing needed.
Setting `cvode_precon_method` to `none` disables preconditioning. The default `auto` uses the user-supplied preconditioner if present, then PETSc if available, then SUNDIALS' BBD preconditioner.
cvode_lsetup_frequency and cvode_jac_eval_frequency modify how often the Jacobian and preconditioner are recalculated.
| PetscCall(VecGetArray(f, &fdata)); | ||
|
|
||
| try { | ||
| s->rhs(s->petsc_t, const_cast<BoutReal*>(xdata), s->petsc_rhs_tmp.data(), true); |
There was a problem hiding this comment.
warning: do not use const_cast to remove const qualifier [cppcoreguidelines-pro-type-const-cast]
{
^`CVodeSetLSetupFrequency` and `CVodeSetJacEvalFrequency` are not available in Sundials version 4.1.0 on CI.
test-delp2 answer changes slightly (~1e-6) if preconditioning is enabled.
Hermes-3 braginskii_conduction creates a "type" subsection in every section of options. PetscLib throws an exception when the "petsc" section contains a subsection.
| if ((*options)["use_precon"].isSet()) { | ||
| output_warn << "WARNING: solver:use_precon is deprecated for CVODE and is now " | ||
| "ignored. Use solver:cvode_precon_method=none to disable " | ||
| "preconditioning.\n"; | ||
| } |
There was a problem hiding this comment.
Should this be an error?
We throw also errors for unused options, so I think we should also force the users here to update.
| // around a bug in Hermes-3 braginskii_conduction that creates a | ||
| // "petsc:type" subsection. |
There was a problem hiding this comment.
How hard would it be to fix it in hermes?
There was a problem hiding this comment.
It's fairly straightforward to fix (I've fixed it in a branch) so hopefully this is a short-lived patch.
| const int band_width_default = std::accumulate( | ||
| begin(f3d), end(f3d), 0, [](int a, const VarStr<Field3D>& fvar) { | ||
| const Mesh* localmesh = fvar.var->getMesh(); | ||
| return a + localmesh->xend - localmesh->xstart + 3; |
There was a problem hiding this comment.
That means the ddx must only use one guard cell, and higher order stencils will perform poorly, do to wrong preconditioning?
There was a problem hiding this comment.
The whole BBD preconditioner is of quite dubious benefit really. It doesn't know anything about spatial stencils so only preconditions coupling between variables that appear next to each other in the 1D state vector. In practice I think that means it's only good for preconditioning coupling between variables in the same cell. I've not yet seen a case where BBD preconditioning improved performance, so it's really here in case someone wants to try it as a last resort.
| output_progress.write("Creating Jacobian coloring\n"); | ||
| updateColoring(); | ||
|
|
||
| #if 0 |
There was a problem hiding this comment.
That seems to be the code that has been moved to petsc_preconditioner.cxx, thus I deleted it.
Refactors the Jacobian coloring preconditioner and makes it available as a CVODE preconditioner.
test2 from scratch. 10 steps of size 1.
No preconditioning:
User preconditioning:
petsc preconditioning (ksp_type=preonly, pc_type=hypre):
With PETSc preconditioning the number of linear iterations per Newton step is small, and the timesteps seem to be bigger than other methods. When using STRUMPACK rather than hypre there is an error on the first iteration but it continues and accelerates after:
It runs fine with STRUMPACK after the first step, but this factorization failure makes me a bit suspicious.