|
Tempus Version of the Day
Time Integration
|
The primary goal of Example 5: Introduce Stepper is to introduce Tempus::Stepper through Tempus::StepperForwardEuler while preserving the same Thyra::ModelEvaluator-based van der Pol model, the same Tempus::SolutionHistory, and the same application-managed time loop used in Example 4: Add SolutionHistory.
Tempus::Stepper performs a single time step by applying the algorithm associated with a particular ODE formulation, such as an explicit update formula or an implicit linear or nonlinear solve. In doing so, it uses the governing equations provided by the Thyra::ModelEvaluator in their explicit and/or implicit forms.
Upon completion of the step, the Tempus::Stepper updates the next Tempus::SolutionState (the working state), reports the solution status (for example, passed or failed), and may propose a timestep size for the next step. In this way, Tempus::Stepper separates the time-stepping algorithm from the details of the governing equations in the Thyra::ModelEvaluator, the linear and nonlinear solver infrastructure (for example, Belos and NOX), and the orchestration of multiple time steps, which is introduced later in Utilize IntegratorBasic.
New concepts introduced are:
setModel(...)initialize()setInitialConditions(...)takeStep(...)Note: A solution state is termed "<b>consistent</b>" when the solution and its derivatives satisfy the governing equations at time 

This is the first step in separating the stepping algorithm from the surrounding application logic. Rather than coding the Forward Euler right-hand-side evaluation and update directly in the time loop, the application now delegates that work to a Tempus stepper object.
The code excerpts below highlight the main changes needed to replace the hand-written Forward Euler update with a Tempus::StepperForwardEuler.
Create and initialize a StepperForwardEuler. The application now constructs a Tempus::StepperForwardEuler. A Tempus::Stepper needs access to the governing equations through a Thyra::ModelEvaluator, so the model is attached to the stepper. Because the stepper is constructed in stages, initialize() is then called to complete its setup before stepping begins. Finally, setInitialConditions(...) ensures that the initial Tempus::SolutionHistory is consistent with both the governing equations and the stepper.
Before
After
This introduces the first Tempus stepping abstraction in the progression tutorial.
Delegate the step to the stepper. The details of the Forward Euler update, including interaction with the Thyra::ModelEvaluator, are now handled by Tempus::StepperForwardEuler. In this way, the stepper encapsulates everything needed to perform a single Forward Euler time step. This also makes it easier to replace Forward Euler with another Tempus::Stepper while leaving the surrounding application-level time-loop logic unchanged.
Before
After
The stepper now performs the model evaluation and Forward Euler update.
Use the solution status set by the stepper. The Tempus::Stepper sets the status of the working state as part of takeStep(...). As a result, the application no longer needs to set the pass/fail status explicitly after the Forward Euler update. The remaining task is to promote the working state through the solution history.
Before
After
The time loop is still application-controlled; only the single-step algorithm and step-status assignment have moved into the stepper.
A more detailed comparison can be made by diffing:
examples/04_Adding_SolutionHistory/04_Adding_SolutionHistory.cppexamples/05_Intro_Stepper/05_Intro_Stepper.cppFrom the packages/tempus directory, a focused comparison of the main time-integration logic between these two examples can be generated locally in bash or zsh with:
This ignores leading header lines (e.g., #include statements and Doxygen comments) and trailing regression-testing lines.