Skip to content

Commit

Permalink
Add traits to modify HBModel and SWModel for coupling
Browse files Browse the repository at this point in the history
drive shallow water model by HB model

add coupling traits, use to replace forcing traits in shallow water model

move coupling for SWModel to file in SplitExplicit

add coupling to HBModel, get fully coupled model to converge to analytic solution

Add hydrostatic spindown tests with actual multi-rate happening

remove old integral models

get flow deviation working with new reshape&broadcast setup (on cpu).

Remove stub functions for partial coupling

use Coupling trait for dispatch instead of boolean in SplitExplicitMethod.

use abbreviated model names

Update to new functions from CliMA#1280
  • Loading branch information
blallen committed Jul 22, 2020
1 parent a7066de commit 6f34be4
Show file tree
Hide file tree
Showing 14 changed files with 593 additions and 186 deletions.
125 changes: 50 additions & 75 deletions src/Numerics/ODESolvers/SplitExplicitMethod.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ of the model at a faster rate than the full model. This results in a first-
order time stepper.
""" SplitExplicitSolver
mutable struct SplitExplicitSolver{SS, FS, RT, BT, MSA} <: AbstractODESolver
mutable struct SplitExplicitSolver{SS, FS, RT, MSA} <: AbstractODESolver
"slow solver"
slow_solver::SS
"fast solver"
Expand All @@ -36,10 +36,6 @@ mutable struct SplitExplicitSolver{SS, FS, RT, BT, MSA} <: AbstractODESolver
dt::RT
"time"
t::RT
"flag to drive fast model by slow model"
coupled::BT
"flag to reconcile slow model with fast model"
reconcile::BT
"storage for transfer tendency"
dQ2fast::MSA

Expand All @@ -49,25 +45,19 @@ mutable struct SplitExplicitSolver{SS, FS, RT, BT, MSA} <: AbstractODESolver
Q = nothing;
dt = getdt(slow_solver),
t0 = slow_solver.t,
coupled = true,
reconcile = true,
) where {AT <: AbstractArray}
SS = typeof(slow_solver)
FS = typeof(fast_solver)
RT = real(eltype(slow_solver.dQ))
BT = typeof(coupled)

dQ2fast = similar(slow_solver.dQ)
dQ2fast .= -0
MSA = typeof(dQ2fast)

return new{SS, FS, RT, BT, MSA}(
return new{SS, FS, RT, MSA}(
slow_solver,
fast_solver,
RT(dt),
RT(t0),
coupled,
reconcile,
dQ2fast,
)
end
Expand Down Expand Up @@ -102,54 +92,28 @@ function dostep!(

# Initialize fast model and tendency adjustment
# before evalution of slow mode
if split.coupled
initialize_states!(
slow_bl,
fast_bl,
slow.rhs!,
fast.rhs!,
Qslow,
Qfast,
)

# 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
tendency_from_slow_to_fast!(
slow_bl,
fast_bl,
slow.rhs!,
fast.rhs!,
Qslow,
Qfast,
dQ2fast,
split.reconcile,
)
end
initialize_states!(slow_bl, fast_bl, slow.rhs!, fast.rhs!, Qslow, Qfast)

# 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
tendency_from_slow_to_fast!(
slow_bl,
fast_bl,
slow.rhs!,
fast.rhs!,
Qslow,
Qfast,
dQ2fast,
)

# 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]
Expand All @@ -167,31 +131,42 @@ function dostep!(
for substep in 1:nsubsteps
fast_time = slow_stage_time + (substep - 1) * fast_dt
dostep!(Qfast, fast, param, fast_time)
if split.coupled
cummulate_fast_solution!(
slow_bl,
fast_bl,
fast.rhs!,
Qfast,
fast_time,
fast_dt,
substep,
)
end
end

# reconcile slow equation using fast equation
if split.coupled
reconcile_from_fast_to_slow!(
cummulate_fast_solution!(
slow_bl,
fast_bl,
slow.rhs!,
fast.rhs!,
Qslow,
Qfast,
split.reconcile,
fast_time,
fast_dt,
substep,
)
end

# 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)

# reconcile slow equation using fast equation
reconcile_from_fast_to_slow!(
slow_bl,
fast_bl,
slow.rhs!,
fast.rhs!,
Qslow,
Qfast,
)
end
updatedt!(fast, fast_dt_in)

Expand Down
Loading

0 comments on commit 6f34be4

Please sign in to comment.