-
Notifications
You must be signed in to change notification settings - Fork 5
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 TimeStepper base class plus ForwardBackward and RK4 time steppers #120
Add TimeStepper base class plus ForwardBackward and RK4 time steppers #120
Conversation
Added the RK2 time stepper and opened a PR to mwarusz#1. |
I merged @hyungyukang's RK2 PR into this branch. |
869f488
to
2398e13
Compare
2398e13
to
e4d9af3
Compare
Passes all tests on perlmutter with CPU and GPU: details:
If you copy these instructions, change paths to your own. |
@mwarusz thank you for the additional comments within the code. That is helpful! |
To fully test this PR, I quickly built a test version of the shallow water model using this PR. It was relatively straightforward to integrate this PR with the previous Omega-0 test model by invoking I have also added the struct for the manufactured solutions ( In the test model, the time-stepping component is structured as follows (as a rough example): Config Options;
auto *TestAuxState =
AuxiliaryState::create("TestAuxState", Mesh, NVertLevels);
auto *TestTendencies =
Tendencies::create("TestTendencies", Mesh, NVertLevels, &Options,
ManufacturedThicknessTendency{}, ManufacturedVelocityTendency{});
auto *TestTimeStepper = TimeStepper::create(
"TestTimeStepper", TimeStepperType::RungeKutta2, TestTendencies, TestAuxState, Mesh, DefHalo);
const auto *Stepper = TimeStepper::get("TestTimeStepper");
for (int step = 0; step < nsteps; ++step) {
// Compute current time
CurrentTime = step * dt;
Stepper->doStep(State, CurrentTime, dt);
sw_check_status(printInterval, CurrentTime, dt, Comm, Env, Mesh, State);
} With the different time steppers implemented in this PR (ForwardBackward, RungeKutta2, RungeKutta4), I obtained the following convergence rates across various horizontal resolutions: Based on the results above, it can be concluded that the time steppers implemented and the other changes introduced in this PR are functioning correctly. @mwarusz , thank you very much for your efforts on this PR! I have additional minor comments, so I will add them to the codes soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @mwarusz for you dedicated effort on this PR. Approving based on visual inspection, my testing on perlmutter, and @hyungyukang's convergence plot and testing by adding RK2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great. I just have a couple minor comments so far.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I'll be heading out on vacation, I will go ahead and approve now based on a code read-through and testing by others. The code is already starting to get somewhat more complex than I'd like so the added comments and a good DevGuide section will be important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on @mark-petersen 's ctests on Perlmutter, my own full functional testing with the manufactured solution and visual inspection by others, I approve this PR. The other changes look good as well. @mwarusz , thank you very much for your hard work on this PR.
If you have any other concerns about the time level changes, please disregard my suggestions.
}); | ||
} | ||
|
||
if (CustomThicknessTend) { | ||
CustomThicknessTend(LocLayerThicknessTend, State, AuxState, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume tendencies for the manufactured solution will be computed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mwarusz, @hyungyukang - Do we want to add the manufactured solution tendency terms to this PR, or add them in another?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do it in another PR.
}; | ||
|
||
struct DecayVelocityTendency { | ||
Real Coeff = 0.5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if it would be easy to import some constants defined in a YAML file here. For example, the wavenumber of the manufactured solution is defined in the YAML file and we need to include it here. I think it should be easy, but I thought it would be good to check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be straightforward. Just make the constructor of this class take in Config
.
|
||
// The main method that every time stepper needs to define. Advances state by | ||
// by one time step, from Time to Time + TimeStep | ||
virtual void doStep(OceanState *State, Real Time, Real TimeStep) const = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused by the Time being included as an argument of the doStep function here, and in the various compute tendencies functions in the Tendency class. The tendency calculations are not generally dependent on the time directly, and the only thing I'm seeing it used for in the PR is for computing the exact solution in the unit test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, since the TimeStep is kind of core to the purpose of the TimeStepper, maybe makes sense to just store it as a member variable of the class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The manufactured solution has forcings that depend explicitly on time. I agree about the TimeStep
. Initially I thought that making it an argument will make it easier to support varying it during a simulation, but now I think that, if we want to support that, having a changeTimeStep
method would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For down the road, tidal potential forcing also depends on time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I was thinking of the TimeStepper as being more or less equivalent to the various time integrator subroutines in mpas-ocean, which only directly take the time step as an argument, but I guess in mpas they have the overall simulation time buried in modules for sim-time-dependent forcings (like ocn_vel_tidal_potential_tend). When we end up adding forcings we could could have the simulation time stored within class objects representing those forcings, but this is all kind of arbitrary and can be worked out as we go along.
I do think that as opposed to a Real representing Time, it should probably be a TimeInstant object, which represents an instant in time (obviously) on a particular Calendar object, which it contains a pointer to. There is a NoCalendar type, in which the TimeInstant just becomes the elapsed time in seconds, which can be used for unit tests and test problems like the manufactured solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the TimeStep
a member, and changed Time
and TimeStep
to use types TimeInstant
and TimeInterval
, respectively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ran the unit tests successfully. Aside from maybe some quibbles on structure, looks good to me.
Co-authored-by: Steven Brus <steven.r.brus@gmail.com>
91a4201
to
68c4c0c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was running into issues with a local merge into develop, but with the rebase, this now passes CTests on Frontier CPU and GPU. Thanks for all your work on this @mwarusz!
078cd53
to
1964e62
Compare
c27471d
to
f67aaeb
Compare
I re-ran the tests and everything passes on Chrysalis, Frontier CPU and GPU, and Perlmutter CPU and GPU. |
Thanks! I will review documentation today. |
One comment I have is that it may make more sense for each |
@sbrus89 I see two options:
|
@mwarusz, I think the first option is the most straightforward. Perhaps we could have an optional argument to the State constructor that requires you either propvide an explicit NTimeLevels value, or a TimeStepper instance? That way we don't have a hard dependency on the TimeStepper being initialized. |
3a6c34f
to
44268f8
Compare
After several updates in this PR, I have tested this branch again by implementing a shallow water model with a time stepping loop from this PR. I conducted two tests:
Based on the above results, I can say the most recent version of this branch is working properly. Thanks @mwarusz again for your work! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The developers doc is good! I just had the one question.
This PR adds a base class for all Omega time steppers and two concrete implementations of simple explicit time steppers:
A test for the above is also added. This PR depends on #109 and includes it with some modifications. Since this PR is missing comments and documentation and is based on a draft PR I am marking it also as a draft.
@hyungyukang
Checklist