This repository has been archived by the owner on Mar 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
738 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
export SplitExplicitSolver | ||
|
||
using ClimateMachine.DGMethods: | ||
initialize_states!, | ||
tendency_from_slow_to_fast!, | ||
cummulate_fast_solution!, | ||
reconcile_from_fast_to_slow! | ||
|
||
LSRK2N = LowStorageRungeKutta2N | ||
|
||
""" | ||
SplitExplicitMethod(slow_solver, fast_solver; dt, t0 = 0) | ||
This is a time stepping object for explicitly time stepping the differential | ||
equation given by the right-hand-side function `f` with the state `Q`, i.e., | ||
```math | ||
\\dot{Q_fast} = f_fast(Q_fast, Q_slow, t) | ||
\\dot{Q_slow} = f_slow(Q_slow, Q_fast, t) | ||
``` | ||
with the required time step size `dt` and optional initial time `t0`. This | ||
time stepping object is intended to be passed to the `solve!` command. | ||
This method performs an operator splitting to timestep the vertical average of the model at a faster rate than the full model. This results in a first-order time stepper. | ||
### References | ||
""" | ||
mutable struct SplitExplicitSolver{SS, FS, RT} <: AbstractODESolver | ||
"slow solver" | ||
slow_solver::SS | ||
"fast solver" | ||
fast_solver::FS | ||
"time step" | ||
dt::RT | ||
"time" | ||
t::RT | ||
"param to couple the models" | ||
coupled::Bool | ||
"param to step past slow dt" | ||
add_fast_substeps::RT | ||
|
||
function SplitExplicitSolver( | ||
slow_solver::LSRK2N, | ||
fast_solver, | ||
Q = nothing; | ||
dt = getdt(slow_solver), | ||
t0 = slow_solver.t, | ||
coupled = true, | ||
add_fast_substeps = 0, | ||
) where {AT <: AbstractArray} | ||
SS = typeof(slow_solver) | ||
FS = typeof(fast_solver) | ||
RT = real(eltype(slow_solver.dQ)) | ||
return new{SS, FS, RT}( | ||
slow_solver, | ||
fast_solver, | ||
RT(dt), | ||
RT(t0), | ||
coupled, | ||
RT(add_fast_substeps), | ||
) | ||
end | ||
end | ||
|
||
function dostep!( | ||
Qvec, | ||
split::SplitExplicitSolver{SS}, | ||
param, | ||
time::Real, | ||
) where {SS <: LSRK2N} | ||
slow = split.slow_solver | ||
fast = split.fast_solver | ||
|
||
Qslow = Qvec.slow | ||
Qfast = Qvec.fast | ||
|
||
dQslow = slow.dQ | ||
dQ2fast = similar(dQslow) | ||
|
||
slow_bl = slow.rhs!.balance_law | ||
fast_bl = fast.rhs!.balance_law | ||
|
||
groupsize = 256 | ||
|
||
slow_dt = getdt(slow) | ||
fast_dt_in = getdt(fast) | ||
|
||
for slow_s in 1:length(slow.RKA) | ||
# Current slow state time | ||
slow_stage_time = time + slow.RKC[slow_s] * slow_dt | ||
|
||
# Initialize fast model and tentency adjustment before evalution of slow mode | ||
if split.coupled | ||
initialize_states!( | ||
slow_bl, | ||
fast_bl, | ||
slow.rhs!, | ||
fast.rhs!, | ||
Qslow, | ||
Qfast, | ||
) | ||
end | ||
|
||
# Evaluate the slow mode | ||
# --> save tendency for the fast | ||
slow.rhs!(dQ2fast, Qslow, param, slow_stage_time, increment = false) | ||
|
||
# vertically integrate slow tendency to advance fast equation | ||
# and use vertical mean for slow model (negative source) | ||
# ---> work with dQ2fast as input | ||
if split.coupled | ||
tendency_from_slow_to_fast!( | ||
slow_bl, | ||
fast_bl, | ||
slow.rhs!, | ||
fast.rhs!, | ||
Qslow, | ||
Qfast, | ||
dQ2fast, | ||
) | ||
end | ||
|
||
# Compute (and RK update) slow tendency | ||
slow.rhs!(dQslow, Qslow, param, slow_stage_time, increment = true) | ||
|
||
# Update (RK-stage) slow state | ||
event = Event(array_device(Qslow)) | ||
event = update!(array_device(Qslow), groupsize)( | ||
realview(dQslow), | ||
realview(Qslow), | ||
slow.RKA[slow_s % length(slow.RKA) + 1], | ||
slow.RKB[slow_s], | ||
slow_dt, | ||
nothing, | ||
nothing, | ||
nothing; | ||
ndrange = length(realview(Qslow)), | ||
dependencies = (event,), | ||
) | ||
wait(array_device(Qslow), event) | ||
|
||
# Fractional time for slow stage | ||
if slow_s == length(slow.RKA) | ||
γ = 1 - slow.RKC[slow_s] | ||
else | ||
γ = slow.RKC[slow_s + 1] - slow.RKC[slow_s] | ||
end | ||
|
||
# RKB for the slow with fractional time factor remove (since full | ||
# integration of fast will result in scaling by γ) | ||
nsubsteps = fast_dt_in > 0 ? ceil(Int, γ * slow_dt / fast_dt_in) : 1 | ||
fast_dt = γ * slow_dt / nsubsteps | ||
|
||
updatedt!(fast, fast_dt) | ||
|
||
for substep in 1:nsubsteps | ||
fast_time = slow_stage_time + (substep - 1) * fast_dt | ||
dostep!(Qfast, fast, param, fast_time) | ||
# ---> need to cumulate U at this time (and not at each RKB sub-time-step) | ||
if split.coupled | ||
cummulate_fast_solution!( | ||
slow_bl, | ||
fast_bl, | ||
fast.rhs!, | ||
Qfast, | ||
fast_time, | ||
fast_dt, | ||
substep, | ||
# fast_steps, | ||
# fast_time_rec, | ||
) | ||
end | ||
end | ||
|
||
# reconcile slow equation using fast equation | ||
if split.coupled | ||
reconcile_from_fast_to_slow!( | ||
slow_bl, | ||
fast_bl, | ||
slow.rhs!, | ||
fast.rhs!, | ||
Qslow, | ||
Qfast, | ||
# fast_time_rec, | ||
) | ||
end | ||
end | ||
updatedt!(fast, fast_dt_in) | ||
|
||
return nothing | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
module SplitExplicit | ||
|
||
using ..HydrostaticBoussinesq | ||
using ..ShallowWater | ||
|
||
import ..DGMethods: | ||
initialize_states!, | ||
tendency_from_slow_to_fast!, | ||
cummulate_fast_solution!, | ||
reconcile_from_fast_to_slow! | ||
|
||
@inline initialize_states!( | ||
slow::HydrostaticBoussinesqModel, | ||
fast::ShallowWaterModel, | ||
_..., | ||
) = nothing | ||
|
||
@inline tendency_from_slow_to_fast!( | ||
slow::HydrostaticBoussinesqModel, | ||
fast::ShallowWaterModel, | ||
_..., | ||
) = nothing | ||
|
||
@inline cummulate_fast_solution!( | ||
slow::HydrostaticBoussinesqModel, | ||
fast::ShallowWaterModel, | ||
_..., | ||
) = nothing | ||
|
||
@inline reconcile_from_fast_to_slow!( | ||
slow::HydrostaticBoussinesqModel, | ||
fast::ShallowWaterModel, | ||
_..., | ||
) = nothing | ||
|
||
end |
Oops, something went wrong.