Skip to content

Commit 965ee2a

Browse files
Merge pull request #348 from CliMA/dy/move_dss
Move DSS to the end of each implicit stage
2 parents 95e6109 + 94c089d commit 965ee2a

File tree

7 files changed

+49
-46
lines changed

7 files changed

+49
-46
lines changed

.buildkite/Manifest.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ version = "0.2.11"
283283
deps = ["ClimaComms", "Colors", "DataStructures", "DiffEqBase", "KernelAbstractions", "Krylov", "LinearAlgebra", "LinearOperators", "NVTX", "SciMLBase", "StaticArrays"]
284284
path = ".."
285285
uuid = "595c0a79-7f3d-439a-bc5a-b232dc3bde79"
286-
version = "0.7.38"
286+
version = "0.7.39"
287287
weakdeps = ["BenchmarkTools", "CUDA", "OrderedCollections", "PrettyTables", "StatsBase"]
288288

289289
[deps.ClimaTimeSteppers.extensions]

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ClimaTimeSteppers"
22
uuid = "595c0a79-7f3d-439a-bc5a-b232dc3bde79"
33
authors = ["Climate Modeling Alliance"]
4-
version = "0.7.38"
4+
version = "0.7.39"
55

66
[deps]
77
ClimaComms = "3a4d1b5c-c61d-41fd-a00a-5873ba7a1b0d"

docs/Manifest.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ version = "0.2.11"
241241
deps = ["ClimaComms", "Colors", "DataStructures", "DiffEqBase", "KernelAbstractions", "Krylov", "LinearAlgebra", "LinearOperators", "NVTX", "SciMLBase", "StaticArrays"]
242242
path = ".."
243243
uuid = "595c0a79-7f3d-439a-bc5a-b232dc3bde79"
244-
version = "0.7.38"
244+
version = "0.7.39"
245245

246246
[deps.ClimaTimeSteppers.extensions]
247247
ClimaTimeSteppersBenchmarkToolsExt = ["CUDA", "BenchmarkTools", "OrderedCollections", "StatsBase", "PrettyTables"]

src/solvers/hard_coded_ars343.jl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ function step_u!(integrator, cache::IMEXARKCache, ::ARS343)
3333
@. U = u + dt * a_exp[i, 1] * T_lim[1]
3434
lim!(U, p, t_exp, u)
3535
@. U += dt * a_exp[i, 1] * T_exp[1]
36-
dss!(U, p, t_exp)
3736
post_explicit!(U, p, t_exp)
3837

3938
@. temp = U # used in closures
@@ -49,13 +48,18 @@ function step_u!(integrator, cache::IMEXARKCache, ::ARS343)
4948
call_post_implicit! = Ui -> begin
5049
post_implicit!(Ui, p, t_imp)
5150
end
51+
call_post_implicit_last! = Ui -> begin
52+
dss!(Ui, p, t_imp)
53+
post_implicit!(Ui, p, t_imp)
54+
end
5255
solve_newton!(
5356
newtons_method,
5457
newtons_method_cache,
5558
U,
5659
implicit_equation_residual!,
5760
implicit_equation_jacobian!,
5861
call_post_implicit!,
62+
call_post_implicit_last!,
5963
)
6064
end
6165

@@ -69,7 +73,6 @@ function step_u!(integrator, cache::IMEXARKCache, ::ARS343)
6973
@. U = u + dt * a_exp[i, 1] * T_lim[1] + dt * a_exp[i, 2] * T_lim[2]
7074
lim!(U, p, t_exp, u)
7175
@. U += dt * a_exp[i, 1] * T_exp[1] + dt * a_exp[i, 2] * T_exp[2] + dt * a_imp[i, 2] * T_imp[2]
72-
dss!(U, p, t_exp)
7376
post_explicit!(U, p, t_exp)
7477

7578
@. temp = U # used in closures
@@ -85,13 +88,18 @@ function step_u!(integrator, cache::IMEXARKCache, ::ARS343)
8588
call_post_implicit! = Ui -> begin
8689
post_implicit!(Ui, p, t_imp)
8790
end
91+
call_post_implicit_last! = Ui -> begin
92+
dss!(Ui, p, t_imp)
93+
post_implicit!(Ui, p, t_imp)
94+
end
8895
solve_newton!(
8996
newtons_method,
9097
newtons_method_cache,
9198
U,
9299
implicit_equation_residual!,
93100
implicit_equation_jacobian!,
94101
call_post_implicit!,
102+
call_post_implicit_last!,
95103
)
96104
end
97105

@@ -109,7 +117,6 @@ function step_u!(integrator, cache::IMEXARKCache, ::ARS343)
109117
dt * a_exp[i, 3] * T_exp[3] +
110118
dt * a_imp[i, 2] * T_imp[2] +
111119
dt * a_imp[i, 3] * T_imp[3]
112-
dss!(U, p, t_exp)
113120
post_explicit!(U, p, t_exp)
114121

115122
@. temp = U # used in closures
@@ -125,13 +132,18 @@ function step_u!(integrator, cache::IMEXARKCache, ::ARS343)
125132
call_post_implicit! = Ui -> begin
126133
post_implicit!(Ui, p, t_imp)
127134
end
135+
call_post_implicit_last! = Ui -> begin
136+
dss!(Ui, p, t_imp)
137+
post_implicit!(Ui, p, t_imp)
138+
end
128139
solve_newton!(
129140
newtons_method,
130141
newtons_method_cache,
131142
U,
132143
implicit_equation_residual!,
133144
implicit_equation_jacobian!,
134145
call_post_implicit!,
146+
call_post_implicit_last!,
135147
)
136148
end
137149

src/solvers/imex_ark.jl

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,14 @@ end
119119
has_T_exp(f) && fused_increment!(U, dt, a_exp, T_exp, Val(i))
120120
isnothing(T_imp!) || fused_increment!(U, dt, a_imp, T_imp, Val(i))
121121

122-
i 1 && dss!(U, p, t_exp)
123-
124-
if !(!isnothing(T_imp!) && !iszero(a_imp[i, i]))
122+
if isnothing(T_imp!) || iszero(a_imp[i, i])
123+
i 1 && dss!(U, p, t_imp)
125124
i 1 && post_explicit!(U, p, t_imp)
126125
else # Implicit solve
127126
@assert !isnothing(newtons_method)
128127
@. temp = U
128+
# We do not need to apply DSS yet because the implicit solve does not
129+
# involve any horizontal derivatives.
129130
i 1 && post_explicit!(U, p, t_imp)
130131
# TODO: can/should we remove these closures?
131132
implicit_equation_residual! = (residual, Ui) -> begin
@@ -137,11 +138,7 @@ end
137138
post_implicit!(Ui, p, t_imp)
138139
end
139140
call_post_implicit_last! = Ui -> begin
140-
if (!all(iszero, a_imp[:, i]) || !iszero(b_imp[i])) && !iszero(a_imp[i, i])
141-
# If T_imp[i] is being treated implicitly, ensure that it
142-
# exactly satisfies the implicit equation.
143-
@. T_imp[i] = (Ui - temp) / (dt * a_imp[i, i])
144-
end
141+
dss!(Ui, p, t_imp)
145142
post_implicit!(Ui, p, t_imp)
146143
end
147144

@@ -156,15 +153,15 @@ end
156153
)
157154
end
158155

159-
# We do not need to DSS U again because the implicit solve should
160-
# give the same results for redundant columns (as long as the implicit
161-
# tendency only acts in the vertical direction).
162-
163156
if !all(iszero, a_imp[:, i]) || !iszero(b_imp[i])
164-
if iszero(a_imp[i, i]) && !isnothing(T_imp!)
157+
if iszero(a_imp[i, i])
165158
# If its coefficient is 0, T_imp[i] is effectively being
166159
# treated explicitly.
167-
T_imp!(T_imp[i], U, p, t_imp)
160+
isnothing(T_imp!) || T_imp!(T_imp[i], U, p, t_imp)
161+
else
162+
# If T_imp[i] is being treated implicitly, ensure that it
163+
# exactly satisfies the implicit equation.
164+
isnothing(T_imp!) || @. T_imp[i] = (U - temp) / (dt * a_imp[i, i])
168165
end
169166
end
170167

src/solvers/imex_ssprk.jl

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ function step_u!(integrator, cache::IMEXSSPRKCache)
9494
@. U_exp = (1 - β[i - 1]) * u + β[i - 1] * U_exp
9595
end
9696

97-
i 1 && dss!(U_exp, p, t_exp)
98-
9997
@. U = U_exp
10098
if !isnothing(T_imp!) # Update based on implicit tendencies from previous stages
10199
for j in 1:(i - 1)
@@ -104,11 +102,14 @@ function step_u!(integrator, cache::IMEXSSPRKCache)
104102
end
105103
end
106104

107-
if !(!isnothing(T_imp!) && !iszero(a_imp[i, i]))
105+
if isnothing(T_imp!) || iszero(a_imp[i, i])
106+
i 1 && dss!(U, p, t_imp)
108107
i 1 && post_explicit!(U, p, t_imp)
109108
else # Implicit solve
110109
@assert !isnothing(newtons_method)
111110
@. temp = U
111+
# We do not need to apply DSS yet because the implicit solve does
112+
# not involve any horizontal derivatives.
112113
post_explicit!(U, p, t_imp)
113114
# TODO: can/should we remove these closures?
114115
implicit_equation_residual! = (residual, Ui) -> begin
@@ -119,15 +120,10 @@ function step_u!(integrator, cache::IMEXSSPRKCache)
119120
call_post_implicit! = Ui -> begin
120121
post_implicit!(Ui, p, t_imp)
121122
end
122-
call_post_implicit_last! =
123-
Ui -> begin
124-
if (!all(iszero, a_imp[:, i]) || !iszero(b_imp[i])) && !iszero(a_imp[i, i])
125-
# If T_imp[i] is being treated implicitly, ensure that it
126-
# exactly satisfies the implicit equation.
127-
@. T_imp[i] = (Ui - temp) / (dt * a_imp[i, i])
128-
end
129-
post_implicit!(Ui, p, t_imp)
130-
end
123+
call_post_implicit_last! = Ui -> begin
124+
dss!(Ui, p, t_imp)
125+
post_implicit!(Ui, p, t_imp)
126+
end
131127

132128
solve_newton!(
133129
newtons_method,
@@ -140,15 +136,15 @@ function step_u!(integrator, cache::IMEXSSPRKCache)
140136
)
141137
end
142138

143-
# We do not need to DSS U again because the implicit solve should
144-
# give the same results for redundant columns (as long as the implicit
145-
# tendency only acts in the vertical direction).
146-
147139
if !all(iszero, a_imp[:, i]) || !iszero(b_imp[i])
148-
if iszero(a_imp[i, i]) && !isnothing(T_imp!)
140+
if iszero(a_imp[i, i])
149141
# If its coefficient is 0, T_imp[i] is effectively being
150142
# treated explicitly.
151-
T_imp!(T_imp[i], U, p, t_imp)
143+
isnothing(T_imp!) || T_imp!(T_imp[i], U, p, t_imp)
144+
else
145+
# If T_imp[i] is being treated implicitly, ensure that it
146+
# exactly satisfies the implicit equation.
147+
isnothing(T_imp!) || @. T_imp[i] = (U - temp) / (dt * a_imp[i, i])
152148
end
153149
end
154150

src/solvers/rosenbrock.jl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,12 @@ function step_u!(int, cache::RosenbrockCache{Nstages}) where {Nstages}
152152

153153
# NOTE: post_implicit! is a misnomer
154154
if !isnothing(post_implicit!)
155-
# We update p on every stage but the first, and at the end of each
156-
# timestep. Since the first stage is unchanged from the end of the
157-
# previous timestep, this order of operations ensures that p is
158-
# always consistent with the state, including between timesteps.
155+
# We apply DSS and update p on every stage but the first, and at the
156+
# end of each timestep. Since the first stage is unchanged from the
157+
# end of the previous timestep, this order of operations ensures
158+
# that the state is always continuous and that p is consistent with
159+
# the state, including between timesteps.
160+
(i != 1) && dss!(U, p, t + αi * dt)
159161
(i != 1) && post_implicit!(U, p, t + αi * dt)
160162
end
161163

@@ -179,10 +181,6 @@ function step_u!(int, cache::RosenbrockCache{Nstages}) where {Nstages}
179181
fU .+= γi .* dt .* ∂Y∂t
180182
end
181183

182-
# We dss the tendency at every stage but the last. At the last stage, we
183-
# dss the incremented state
184-
(i != Nstages) && dss!(fU, p, t + αi * dt)
185-
186184
for j in 1:(i - 1)
187185
fU .+= (C[i, j] / dt) .* k[j]
188186
end

0 commit comments

Comments
 (0)