Conversation
Allows the target to be set to push timestep rather than stall once reaching a set number of iterations.
Calculates a moving average of recent SNES failures. Enables timestep controllers to be more cautious when SNES is repeatedly failing.
Separate out the global timestep control into a function
Now always calculates local and global residuals. If pseudo timestepping is used then another loop over variables is used to update per-cell timesteps and set `dt_vec`. When `diagnose=true`, the local residual will be saved as `snes_local_residual`, and the global residual will be printed after each internal timestep.
Selects the trigger for writing an output. The default is `fixed_time_interval` that outputs at regular time intervals. Other choice is `residual_ratio` that outputs when the global residual falls by a factor `output_residual_ratio`.
Describe new settings `timestep_control` and `output_trigger` that select different strategies to adjust global timesteps and output simulation state.
Save the global residual diagnostic
Uses setting `pid_controller` rather than `pid_nonlinear_its`.
| int loop_count = 0; | ||
| recent_failure_rate = 0.0; | ||
|
|
||
| BoutReal start_global_residual = global_residual; |
There was a problem hiding this comment.
warning: variable 'start_global_residual' of type 'BoutReal' (aka 'double') can be declared 'const' [misc-const-correctness]
| BoutReal start_global_residual = global_residual; | |
| BoutReal const start_global_residual = global_residual; |
| if ((output_trigger == BoutSnesOutput::fixed_time_interval && (simtime >= target)) | ||
| || (output_trigger == BoutSnesOutput::residual_ratio | ||
| && (global_residual <= start_global_residual * output_residual_ratio))) | ||
| break; // Could happen if step over multiple outputs |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| break; // Could happen if step over multiple outputs | |
| && (global_residual <= start_global_residual * output_residual_ratio))) { | |
| break; // Could happen if step over multiple outputs | |
| } |
| break; | ||
| } | ||
| return timestep; // No change | ||
| } |
There was a problem hiding this comment.
warning: no header providing "copy" is directly included [misc-include-cleaner]
d
^| } | ||
| return timestep; // No change | ||
| } | ||
|
|
There was a problem hiding this comment.
warning: no header providing "copy" is directly included [misc-include-cleaner]
;
^| PetscCall(rhs_function(x, snes_f, false)); | ||
|
|
||
| // Reading the residual vectors | ||
| const BoutReal* current_residual = nullptr; |
There was a problem hiding this comment.
warning: pointee of variable 'mesh' of type 'Mesh *' can be declared 'const' [misc-const-correctness]
| const BoutReal* current_residual = nullptr; | |
| n const |
| } | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
warning: no header providing "mean" is directly included [misc-include-cleaner]
)
^| history_based, ///< Grow/shrink dt based on residual decrease/increase | ||
| hybrid); ///< Combine inverse_residual and history_based strategies | ||
|
|
||
| BOUT_ENUM_CLASS(BoutSnesTimestep, |
There was a problem hiding this comment.
warning: enum 'BoutSnesTimestep' uses a larger base type ('int', size: 4 bytes) than necessary for its value set, consider using 'std::uint8_t' (1 byte) as the base type to reduce its size [performance-enum-size]
BOUT_ENUM_CLASS(BoutSnesTimestep,
^| residual_ratio, ///< Use ratio of previous and current residual | ||
| fixed); ///< Fixed timestep (no adaptation) | ||
|
|
||
| BOUT_ENUM_CLASS(BoutSnesOutput, |
There was a problem hiding this comment.
warning: enum 'BoutSnesOutput' uses a larger base type ('int', size: 4 bytes) than necessary for its value set, consider using 'std::uint8_t' (1 byte) as the base type to reduce its size [performance-enum-size]
BOUT_ENUM_CLASS(BoutSnesOutput,
^False by default. If true, re-uses the Jacobian and preconditioner across SNES calls.
| int saved_jacobian_lag = 0; | ||
| int loop_count = 0; | ||
| recent_failure_rate = 0.0; | ||
|
|
There was a problem hiding this comment.
warning: variable 'start_global_residual' of type 'BoutReal' (aka 'double') can be declared 'const' [misc-const-correctness]
| BoutReal const start_global_residual = global_residual; |
| int loop_count = 0; | ||
| recent_failure_rate = 0.0; | ||
|
|
||
| BoutReal start_global_residual = global_residual; |
There was a problem hiding this comment.
warning: avoid do-while loops [cppcoreguidelines-avoid-do-while]
do {
^|
|
||
| PetscErrorCode SNESSolver::updateResiduals(Vec x) { | ||
| // Push residuals to previous residuals | ||
| // Copying so that data is not shared |
There was a problem hiding this comment.
warning: no header providing "copy" is directly included [misc-include-cleaner]
d
^| PetscErrorCode SNESSolver::updateResiduals(Vec x) { | ||
| // Push residuals to previous residuals | ||
| // Copying so that data is not shared | ||
| local_residual_prev = copy(local_residual); |
There was a problem hiding this comment.
warning: no header providing "copy" is directly included [misc-include-cleaner]
;
^| PetscCall(VecGetArrayRead(snes_f, ¤t_residual)); | ||
|
|
||
| // Note: The ordering of quantities in the PETSc vectors | ||
| // depends on the Solver::loop_vars function |
There was a problem hiding this comment.
warning: pointee of variable 'mesh' of type 'Mesh *' can be declared 'const' [misc-const-correctness]
| // depends on the Solver::loop_vars function | |
| n const |
| // Restore Vec data arrays | ||
| PetscCall(VecRestoreArrayRead(snes_f, ¤t_residual)); | ||
|
|
||
| // Global residual metric (RMS) |
There was a problem hiding this comment.
warning: no header providing "mean" is directly included [misc-include-cleaner]
)
^
timestep_controlreplacespid_controllerboolean. Choices are:pid_nonlinear_itsthat uses a PID controller and the nonlinear iteration count. This is now the default.residual_ratiothat uses the ratio of the global residual (Root-Mean-Square of the time derivatives, averaged over all fields and cells). The algorithm is taken from PETSc TSPSEUDO: https://petsc.org/release/manualpages/TS/TSPSEUDO/ .threshold_nonlinear_itsis the previous default, that increases and decreases timestep based on thresholds in the number of nonlinear iterationsfixedis for testing; no timestep controloutput_triggerchanges when outputs are written:fixed_time_intervalis the default, outputting at regular time intervals.residual_ratiooutputs when the global residual has reduced below a given factor (output_residual_ratiooption, default 0.5) times the residual at the previous output. This is a useful measure of progress towards steady state.