Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some basic notes on time stepping design #95

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 79 additions & 3 deletions components/omega/doc/design/TimeStepping.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
$$
Expand All @@ -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)
$$
Expand Down