Skip to content

Refactor simulation flowchart wrt. time step control #1582

@jwboth

Description

@jwboth

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 within run_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 of SolutionStrategy.after_nonlinear_convergence and Solution.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_convergence and SolutionStrategy.after_nonlinear_failure are most crucial.
  • Split exporting solutions and saving SolverStatistics. Use only the latter for success and failure and the former in case of success.
  • Refactor NewtonSolver and LinearSolver to 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_model still come across any time step control?

Milestones of the project:

  1. Flowchart is presented to and accepted by core dev group.
  2. Code is reorganized and current tests run.
  3. 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.

Sub-issues

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions