-
Notifications
You must be signed in to change notification settings - Fork 99
Description
Aim. Refactor the logical "time stepping -> nonlinear solution -> linear solution" pipeline to make the simulation flow more robust, maintainable, and easier to extend, while reducing the risk of subtle bugs in time stepping and solution control.
The current design for running non-stationary simulations in PorePy distributes the responsibility for time stepping and control logic across several classes and methods, primarily:
time_step(called withinrun_time_dependent_model)SolutionStratgey.before_nonlinear_loop(called within a (nonlinear) solver) - note its well attempted but wrongfully executed docstring.SolutionStrategy.after_nonlinear_convergence(called within a (nonlinear) solver).Solution.Strategy.after_nonlinear_failure(called within a (nonlinear) solver).
Additionally, saving the status via SolverStatistics and using the Exporter to export solutions are tightly coupled to this flow. See in particular:
- the method
save_data_time_step(called as part ofSolutionStrategy.after_nonlinear_convergenceandSolution.Strategy.after_nonlinear_failure).
There have been several issues related to unexpected behavior in time stepping, especially when nonlinear solution fails (see #1421, #1422, PR #1471, and related closed issues).
This issue aims at a wholistic approach to provide more solid ground for better communication and coordination between the aforementioned classes. The primary goal is to align and clarify the responsibilities related to time stepping, so that the hierarchy is: "time stepping -> nonlinear solution -> linear solution". Each level should only be responsible for its own purpose. In particular, nonlinear solvers should not be responsible for reacting to time step failure or resetting time steps.
Several steps are suggested as a guideline (pre-planning will be nevertheless needed and is central in an aligned plan):
- Define a flowchart for that follows a hierarchical design "time stepping/time step control -> nonlinear solution -> linear solution" with clear responsibilities per level. Include exporting and logging, recomputation of time steps, and restarting failed time steps.
- Reevaluate the aforementioned methods (and their use) and reorganize them. Initial guess is that
time_step,SolutionStrategy.after_nonlinear_convergenceandSolutionStrategy.after_nonlinear_failureare most crucial. - Split exporting solutions and saving
SolverStatistics. Use only the latter for success and failure and the former in case of success. - Refactor
NewtonSolverandLinearSolverto take sole responsibility for solving a given time step (and not resetting it). Time step control is to be moved to a suitable location outside the "nonlinear solution -> linear solution" levels. Observation: Solvers report convergence success in form of a bool. - Adapt and double check: does
run_stationary_modelstill come across any time step control?
Milestones of the project:
- Flowchart is presented to and accepted by core dev group.
- Code is reorganized and current tests run.
- Evaluate and implement any new unit tests required by the refactored design.
Friendly warning:
This issue is orthogonal but strongly connected to PR #1448. In this PR the NewtonSolver and LinearSolver are refactored and define status objects carrying information on success and failure. Merging the above time step control and the herein mention solver refactoring should be likely not a bit deal.