Skip to content

Commit 1d9eab1

Browse files
authored
Merge pull request #3708 from CliMA/zs/implicit_entrainment
make entrainment and detrainment implicit
2 parents 3d99876 + 550a98c commit 1d9eab1

File tree

9 files changed

+50
-6
lines changed

9 files changed

+50
-6
lines changed

config/default_configs/default_config.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,11 @@ zero_tendency:
318318
implicit_sgs_advection:
319319
help: "Whether to treat the subgrid-scale vertical advection tendency implicitly [`false` (default), `true`]"
320320
value: false
321+
implicit_sgs_entr_detr:
322+
help: "Whether to treat the subgrid-scale entrainment and detrainment tendency implicitly [`false` (default), `true`]. Setting it to true only works if implicit_sgs_advection is set to true."
323+
value: false
321324
implicit_sgs_mass_flux:
322-
help: "Whether to treat the subgrid-scale mass flux tendency implicitly or explicitly in grid-mean equations. Currently updraft only with Jacobian terms 0. [`false` (default), `true`]"
325+
help: "Whether to treat the subgrid-scale mass flux tendency implicitly or explicitly in grid-mean equations. Currently updraft only with Jacobian terms 0. [`false` (default), `true`]. Setting it to true only works if both implicit_sgs_advection and implicit_diffusion are set to true."
323326
value: false
324327
edmf_coriolis:
325328
help: "EDMF coriolis [`nothing` (default), `Bomex`,`LifeCycleTan2018`,`Rico`,`ARM_SGP`,`DYCOMS_RF01`,`DYCOMS_RF02`,`GABLS`]"

config/model_configs/prognostic_edmfx_bomex_implicit_column.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ surface_setup: "Bomex"
66
turbconv: "prognostic_edmfx"
77
implicit_diffusion: true
88
implicit_sgs_advection: true
9+
implicit_sgs_entr_detr: true
910
implicit_sgs_mass_flux: true
1011
approximate_linear_solve_iters: 2
1112
max_newton_iters_ode: 3

config/perf_configs/bm_aquaplanet_progedmf.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ rayleigh_sponge: true
99
viscous_sponge: true
1010
implicit_diffusion: true
1111
implicit_sgs_advection: true
12+
implicit_sgs_entr_detr: true
1213
implicit_sgs_mass_flux: true
1314
approximate_linear_solve_iters: 2
1415
moist: equil

src/cache/temporary_quantities.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ function temporary_quantities(Y, atmos)
6666
),
6767
ᶜdiffusion_h_matrix = similar(Y.c, TridiagonalMatrixRow{FT}),
6868
ᶜdiffusion_h_matrix_scaled = similar(Y.c, TridiagonalMatrixRow{FT}),
69-
ᶜtridiagonal_matrix_scalar = similar(Y.c, TridiagonalMatrixRow{FT}),
7069
ᶜdiffusion_u_matrix = similar(Y.c, TridiagonalMatrixRow{FT}),
7170
ᶠtridiagonal_matrix_c3 = similar(Y.f, TridiagonalMatrixRow{C3{FT}}),
7271
)

src/prognostic_equations/implicit/implicit_solver.jl

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ struct ImplicitEquationJacobian{
9999
F2 <: DerivativeFlag,
100100
F3 <: DerivativeFlag,
101101
F4 <: DerivativeFlag,
102+
F5 <: DerivativeFlag,
102103
T <: Fields.FieldVector,
103104
R <: Base.RefValue,
104105
}
@@ -112,7 +113,8 @@ struct ImplicitEquationJacobian{
112113
diffusion_flag::F1
113114
topography_flag::F2
114115
sgs_advection_flag::F3
115-
sgs_mass_flux_flag::F4
116+
sgs_entr_detr_flag::F4
117+
sgs_mass_flux_flag::F5
116118

117119
# required by Krylov.jl to evaluate ldiv! with AbstractVector inputs
118120
temp_b::T
@@ -130,6 +132,7 @@ function Base.zero(jac::ImplicitEquationJacobian)
130132
jac.diffusion_flag,
131133
jac.topography_flag,
132134
jac.sgs_advection_flag,
135+
jac.sgs_entr_detr_flag,
133136
jac.sgs_mass_flux_flag,
134137
jac.temp_b,
135138
jac.temp_x,
@@ -148,6 +151,8 @@ function ImplicitEquationJacobian(
148151
IgnoreDerivative(),
149152
sgs_advection_flag = atmos.sgs_adv_mode == Implicit() ? UseDerivative() :
150153
IgnoreDerivative(),
154+
sgs_entr_detr_flag = atmos.sgs_entr_detr_mode == Implicit() ?
155+
UseDerivative() : IgnoreDerivative(),
151156
sgs_mass_flux_flag = atmos.sgs_mf_mode == Implicit() ? UseDerivative() :
152157
IgnoreDerivative(),
153158
transform_flag = false,
@@ -403,6 +408,7 @@ function ImplicitEquationJacobian(
403408
diffusion_flag,
404409
topography_flag,
405410
sgs_advection_flag,
411+
sgs_entr_detr_flag,
406412
sgs_mass_flux_flag,
407413
similar(Y),
408414
similar(Y),
@@ -491,6 +497,9 @@ NVTX.@annotate function Wfact!(A, Y, p, dtγ, t)
491497
p.precomputed.bdmr_l,
492498
p.precomputed.bdmr_r,
493499
p.precomputed.bdmr,
500+
p.precomputed.ᶜentrʲs,
501+
p.precomputed.ᶜdetrʲs,
502+
p.precomputed.ᶜturb_entrʲs,
494503
) : (;)
495504
)...,
496505
p.core.ᶜΦ,
@@ -504,7 +513,6 @@ NVTX.@annotate function Wfact!(A, Y, p, dtγ, t)
504513
p.scratch.ᶜadvection_matrix,
505514
p.scratch.ᶜdiffusion_h_matrix,
506515
p.scratch.ᶜdiffusion_h_matrix_scaled,
507-
p.scratch.ᶜtridiagonal_matrix_scalar,
508516
p.scratch.ᶜdiffusion_u_matrix,
509517
p.scratch.ᶠbidiagonal_matrix_ct3,
510518
p.scratch.ᶠbidiagonal_matrix_ct3_2,
@@ -528,6 +536,7 @@ function update_implicit_equation_jacobian!(A, Y, p, dtγ)
528536
matrix,
529537
diffusion_flag,
530538
sgs_advection_flag,
539+
sgs_entr_detr_flag,
531540
topography_flag,
532541
sgs_mass_flux_flag,
533542
) = A
@@ -545,7 +554,6 @@ function update_implicit_equation_jacobian!(A, Y, p, dtγ)
545554
(;
546555
ᶜdiffusion_h_matrix,
547556
ᶜdiffusion_h_matrix_scaled,
548-
ᶜtridiagonal_matrix_scalar,
549557
ᶜdiffusion_u_matrix,
550558
params,
551559
) = p
@@ -851,6 +859,7 @@ function update_implicit_equation_jacobian!(A, Y, p, dtγ)
851859
@. ᶜkappa_mʲ =
852860
TD.gas_constant_air(thermo_params, ᶜtsʲs.:(1)) /
853861
TD.cv_m(thermo_params, ᶜtsʲs.:(1))
862+
854863
∂ᶜq_totʲ_err_∂ᶜq_totʲ =
855864
matrix[@name(c.sgsʲs.:(1).q_tot), @name(c.sgsʲs.:(1).q_tot)]
856865
@. ∂ᶜq_totʲ_err_∂ᶜq_totʲ =
@@ -995,6 +1004,22 @@ function update_implicit_equation_jacobian!(A, Y, p, dtγ)
9951004
dtγ * ᶠtridiagonal_matrix_c3
9961005
DiagonalMatrixRow(adjoint(CT3(Y.f.sgsʲs.:(1).u₃))) - (I_u₃,)
9971006
end
1007+
1008+
# entrainment and detrainment
1009+
(; ᶜentrʲs, ᶜdetrʲs, ᶜturb_entrʲs) = p
1010+
# This assumes entrainment and detrainment rates are constant in the Jacobian
1011+
@. ∂ᶜq_totʲ_err_∂ᶜq_totʲ -=
1012+
dtγ * DiagonalMatrixRow(ᶜentrʲs.:(1) + ᶜturb_entrʲs.:(1))
1013+
@. ∂ᶜmseʲ_err_∂ᶜmseʲ -=
1014+
dtγ * DiagonalMatrixRow(ᶜentrʲs.:(1) + ᶜturb_entrʲs.:(1))
1015+
@. ∂ᶜρaʲ_err_∂ᶜρaʲ +=
1016+
dtγ * DiagonalMatrixRow(ᶜentrʲs.:(1) - ᶜdetrʲs.:(1))
1017+
@. ∂ᶠu₃ʲ_err_∂ᶠu₃ʲ -=
1018+
dtγ * (DiagonalMatrixRow(
1019+
(ᶠinterp(ᶜentrʲs.:(1) + ᶜturb_entrʲs.:(1))) *
1020+
(one_C3xACT3,),
1021+
))
1022+
9981023
# add updraft mass flux contributions to grid-mean
9991024
if use_derivative(sgs_mass_flux_flag)
10001025

src/prognostic_equations/implicit/implicit_tendency.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ NVTX.@annotate function implicit_tendency!(Yₜ, Y, p, t)
3030
edmfx_sgs_diffusive_flux_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
3131
end
3232

33+
34+
if p.atmos.sgs_entr_detr_mode == Implicit()
35+
edmfx_entr_detr_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
36+
end
37+
3338
if p.atmos.sgs_mf_mode == Implicit()
3439
edmfx_sgs_mass_flux_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
3540
end

src/prognostic_equations/remaining_tendency.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ NVTX.@annotate function additional_tendency!(Yₜ, Y, p, t)
112112
surface_flux_tendency!(Yₜ, Y, p, t)
113113

114114
radiation_tendency!(Yₜ, Y, p, t, p.atmos.radiation_mode)
115-
edmfx_entr_detr_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
115+
if p.atmos.sgs_entr_detr_mode == Explicit()
116+
edmfx_entr_detr_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
117+
end
116118
if p.atmos.sgs_mf_mode == Explicit()
117119
edmfx_sgs_mass_flux_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
118120
end

src/solver/type_getters.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ function get_atmos(config::AtmosConfig, params)
5555
implicit_sgs_advection = parsed_args["implicit_sgs_advection"]
5656
@assert implicit_sgs_advection in (true, false)
5757

58+
implicit_sgs_entr_detr = parsed_args["implicit_sgs_entr_detr"]
59+
@assert implicit_sgs_entr_detr in (true, false)
60+
5861
implicit_sgs_mass_flux = parsed_args["implicit_sgs_mass_flux"]
5962
@assert implicit_sgs_mass_flux in (true, false)
6063

@@ -103,6 +106,7 @@ function get_atmos(config::AtmosConfig, params)
103106
vert_diff,
104107
diff_mode = implicit_diffusion ? Implicit() : Explicit(),
105108
sgs_adv_mode = implicit_sgs_advection ? Implicit() : Explicit(),
109+
sgs_entr_detr_mode = implicit_sgs_entr_detr ? Implicit() : Explicit(),
106110
sgs_mf_mode = implicit_sgs_mass_flux ? Implicit() : Explicit(),
107111
viscous_sponge = get_viscous_sponge_model(parsed_args, params, FT),
108112
smagorinsky_lilly = get_smagorinsky_lilly_model(parsed_args),

src/solver/types.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ Base.@kwdef struct AtmosModel{
519519
VD,
520520
DM,
521521
SAM,
522+
SEDM,
522523
SMM,
523524
VS,
524525
SL,
@@ -557,6 +558,9 @@ Base.@kwdef struct AtmosModel{
557558
vert_diff::VD = nothing
558559
diff_mode::DM = nothing
559560
sgs_adv_mode::SAM = nothing
561+
"""sgs_entr_detr_mode == Implicit() only works if sgs_adv_mode == Implicit()"""
562+
sgs_entr_detr_mode::SEDM = nothing
563+
"""sgs_mf_mode == Implicit() only works if sgs_adv_mode == Implicit() and diff_mode == Implicit()"""
560564
sgs_mf_mode::SMM = nothing
561565
viscous_sponge::VS = nothing
562566
smagorinsky_lilly::SL = nothing

0 commit comments

Comments
 (0)