From 98a1439477e53edd91c009e985cd5af4885b544c Mon Sep 17 00:00:00 2001 From: Maciej Waruszewski Date: Tue, 2 Jul 2024 23:13:30 -0600 Subject: [PATCH] Add some basic notes on time stepping design --- components/omega/doc/design/TimeStepping.md | 82 ++++++++++++++++++++- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/components/omega/doc/design/TimeStepping.md b/components/omega/doc/design/TimeStepping.md index 4b670e6caa28..c9f117391fb7 100644 --- a/components/omega/doc/design/TimeStepping.md +++ b/components/omega/doc/design/TimeStepping.md @@ -91,13 +91,89 @@ If time permits, other schemes will be added and tested. This includes the four- ## 4 Design -Design specifics will be added at a later time. +To ensure modularity, each time stepper is implemented as a separate class. Since there will be common functionality and common interface between different time steppers, every time stepper inherits from an abstract `TimeStepper` base class. + +### 4.1 Data types and parameters + +#### 4.1.1 Parameters + +The time stepper can be specified in the input configuration file: +```yaml +TimeIntegration: + TimeStepper: Forward-Backward +``` +In the code, the time stepper type is represented by an enum: +```c++ +enum TimeStepperType { + ForwardBackward, + AdamsBashforth2, + RungeKutta4, + ... +} +``` + +#### 4.1.2 Class/structs/data types + +#### 4.1.2.1 TimeStepper + +The abstract `TimeStepper` class defines the interface that every time stepper needs to implement, and provides common data members and functionality. + +```c++ +class TimeStepper { + public: + TimeStepper(TimeStepperType TSType, Tendencies* ModelTendencies); + virtual void doStep(State* ModelState, Clock* ModelClock) const = 0; + virtual ~TimeStepper() = default; + + TimeStepperType TSType; + private: + Tendencies* ModelTendencies; +}; +``` + +#### 4.1.2.2 Example of a derived class +As an example, the fourth order Runge-Kutta stepper extends the base class by storing the scheme weights and provides a concrete implementation of the `doStep` method. + +```c++ +class RK4Stepper : public TimeStepper { + public: + RK4Stepper(Tendencies* ModelTendencies); + void doStep(State* ModelState, Clock* ModelClock) const override; + private: + R8 RKWeights[4]; + R8 RKSubstepWeights[4]; +}; +``` + +### 4.2 Methods + +Every time stepper needs to have a constructor and an implementation of the `doStep` method. + +#### 4.2.1 Constructor + +The constructor will typically call the base class constructor with the right time stepper type, and +then perform scheme-specific initialization + +```c++ +RK4Stepper::RK4Stepper(Tendencies* ModelTendencies) : TimeStepper(RungeKutta4, ModelTendencies) { + // fill RKWeights and RKSubstepWeights + ... +} +``` + +#### 4.2.2 Time step advance + +The public `doStep` method +```c++ + void doStep(State* ModelState, Clock* ModelClock) const; +``` +advances the model state and clock by one time step. ## 5 Verification and Testing The timestepping will be tested with a time-only convergence test on the equations $$ -\frac{\partial \boldsymbol{u}}{\partial t} = +\frac{\partial \boldsymbol{u}}{\partial t} = -Ra \, \boldsymbol{u} \hspace{1cm} (1) $$ @@ -108,7 +184,7 @@ $$ $$ $$ -\frac{\partial h \phi}{\partial t} = +\frac{\partial h \phi}{\partial t} = - \frac{h}{\tau} \left( \phi - \phi_0 \right) \hspace{1cm} (3) $$