@@ -419,8 +419,9 @@ Timestepping Modes
419419
420420The solver supports several timestepping strategies controlled by ``equation_form ``:
421421
422- **Backward Euler (default) **
423- Standard implicit backward Euler method. Good for general timestepping.
422+ **Rearranged Backward Euler (default) **
423+ Standard implicit backward Euler method, written in a rearranged form that is useful
424+ for robust convergence to steady state.
424425
425426 .. code-block :: ini
426427
@@ -429,6 +430,14 @@ The solver supports several timestepping strategies controlled by ``equation_for
429430 This method has low accuracy in time but its dissipative properties
430431 are helpful when evolving to steady state solutions.
431432
433+ **Backward Euler (DAE/constraints) **
434+ Backward Euler with explicit support for algebraic constraint variables. This form is
435+ required when using BOUT++ ``Solver::constraint(...) `` with the SNES solver.
436+
437+ .. code-block :: ini
438+
439+ equation_form = backward_euler
440+
432441 **Direct Newton **
433442 Solves the steady-state problem F(u) = 0 directly without timestepping.
434443
@@ -450,6 +459,56 @@ The solver supports several timestepping strategies controlled by ``equation_for
450459 This uses the same form as rearranged_backward_euler, but the time step
451460 can be different for each cell.
452461
462+ Constraints (DAEs)
463+ ~~~~~~~~~~~~~~~~~~
464+
465+ BOUT++ can define algebraic constraints in a physics model using the ``Solver::constraint(...) ``
466+ API. With the SNES solver these are treated as a differential-algebraic equation (DAE) system:
467+
468+ - Differential variables: advanced with backward Euler
469+ - Algebraic (constraint) variables: solved from the algebraic equations ``G(x) = 0 `` at each step
470+
471+ Current limitations:
472+
473+ - Constraints are supported only with ``equation_form = backward_euler ``.
474+ - Constraint splitting requires ``matrix_free = false `` (``matrix_free_operator `` may still be
475+ used).
476+
477+ Preconditioner splitting
478+ ^^^^^^^^^^^^^^^^^^^^^^^^
479+
480+ When constraints are enabled, the SNES solver can optionally split the preconditioner into a
481+ differential part and an algebraic part using PETSc ``fieldsplit ``. The split names are:
482+
483+ - ``diff ``: differential variables
484+ - ``alg ``: algebraic (constraint) variables
485+
486+ To enable the split, set ``pc_type = fieldsplit `` in the ``[solver] `` section, then configure PETSc
487+ using standard fieldsplit options (in ``[petsc] `` or on the command line).
488+
489+ Example:
490+
491+ .. code-block :: ini
492+
493+ [solver]
494+ type = snes
495+ equation_form = backward_euler
496+ pc_type = fieldsplit
497+
498+ [petsc]
499+ # Preconditioner splitting
500+ pc_fieldsplit_type = multiplicative # additive, multiplicative, schur, gkb, ...
501+
502+ # Differential block
503+ fieldsplit_diff_ksp_type = preonly
504+ fieldsplit_diff_pc_type = hypre
505+ fieldsplit_diff_pc_hypre_type = ilu
506+
507+ # Algebraic (constraint) block
508+ fieldsplit_alg_ksp_type = preonly
509+ fieldsplit_alg_pc_type = hypre
510+ fieldsplit_alg_pc_hypre_type = boomeramg
511+
453512 Adaptive Timestepping
454513~~~~~~~~~~~~~~~~~~~~~
455514
0 commit comments