Skip to content

Commit a10f2d7

Browse files
authored
Merge pull request #3653 from CliMA/cc/implicit_up_mf_flag
Add flag for running updraft massflux implicitly in GM equations
2 parents cedbf1b + 16aa9eb commit a10f2d7

File tree

7 files changed

+85
-4
lines changed

7 files changed

+85
-4
lines changed

config/default_configs/default_config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ zero_tendency:
315315
implicit_sgs_advection:
316316
help: "Whether to treat the subgrid-scale vertical advection tendency implicitly [`false` (default), `true`]"
317317
value: false
318+
implicit_sgs_mass_flux:
319+
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`]"
320+
value: false
318321
edmf_coriolis:
319322
help: "EDMF coriolis [`nothing` (default), `Bomex`,`LifeCycleTan2018`,`Rico`,`ARM_SGP`,`DYCOMS_RF01`,`DYCOMS_RF02`,`GABLS`]"
320323
value: ~

config/model_configs/prognostic_edmfx_soares_column.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ surface_setup: "Soares"
33
rayleigh_sponge: true
44
turbconv: "prognostic_edmfx"
55
implicit_diffusion: true
6-
implicit_sgs_advection: false
6+
implicit_sgs_advection: true
7+
implicit_sgs_mass_flux: true
78
approximate_linear_solve_iters: 2
89
edmfx_upwinding: "first_order"
910
edmfx_entr_model: "Generalized"

src/prognostic_equations/implicit/implicit_solver.jl

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ struct ImplicitEquationJacobian{
9898
F1 <: DerivativeFlag,
9999
F2 <: DerivativeFlag,
100100
F3 <: DerivativeFlag,
101+
F4 <: DerivativeFlag,
101102
T <: Fields.FieldVector,
102103
R <: Base.RefValue,
103104
}
@@ -111,6 +112,7 @@ struct ImplicitEquationJacobian{
111112
diffusion_flag::F1
112113
topography_flag::F2
113114
sgs_advection_flag::F3
115+
sgs_mass_flux_flag::F4
114116

115117
# required by Krylov.jl to evaluate ldiv! with AbstractVector inputs
116118
temp_b::T
@@ -128,6 +130,7 @@ function Base.zero(jac::ImplicitEquationJacobian)
128130
jac.diffusion_flag,
129131
jac.topography_flag,
130132
jac.sgs_advection_flag,
133+
jac.sgs_mass_flux_flag,
131134
jac.temp_b,
132135
jac.temp_x,
133136
jac.transform_flag,
@@ -145,6 +148,8 @@ function ImplicitEquationJacobian(
145148
IgnoreDerivative(),
146149
sgs_advection_flag = atmos.sgs_adv_mode == Implicit() ? UseDerivative() :
147150
IgnoreDerivative(),
151+
sgs_mass_flux_flag = atmos.sgs_mf_mode == Implicit() ? UseDerivative() :
152+
IgnoreDerivative(),
148153
transform_flag = false,
149154
)
150155
FT = Spaces.undertype(axes(Y.c))
@@ -297,11 +302,28 @@ function ImplicitEquationJacobian(
297302
()
298303
end
299304

305+
sgs_massflux_blocks = if atmos.turbconv_model isa PrognosticEDMFX
306+
@assert n_prognostic_mass_flux_subdomains(atmos.turbconv_model) == 1
307+
if use_derivative(sgs_mass_flux_flag)
308+
(
309+
(@name(c.ρe_tot), @name(c.sgsʲs.:(1).mse)) =>
310+
similar(Y.c, TridiagonalRow),
311+
(@name(c.ρq_tot), @name(c.sgsʲs.:(1).q_tot)) =>
312+
similar(Y.c, TridiagonalRow),
313+
)
314+
else
315+
()
316+
end
317+
else
318+
()
319+
end
320+
300321
matrix = MatrixFields.FieldMatrix(
301322
identity_blocks...,
302323
sgs_advection_blocks...,
303324
advection_blocks...,
304325
diffusion_blocks...,
326+
sgs_massflux_blocks...,
305327
)
306328

307329
sgs_names_if_available = if atmos.turbconv_model isa PrognosticEDMFX
@@ -381,6 +403,7 @@ function ImplicitEquationJacobian(
381403
diffusion_flag,
382404
topography_flag,
383405
sgs_advection_flag,
406+
sgs_mass_flux_flag,
384407
similar(Y),
385408
similar(Y),
386409
transform_flag,
@@ -498,7 +521,13 @@ end
498521

499522
function update_implicit_equation_jacobian!(A, Y, p, dtγ)
500523
dtγ = float(dtγ)
501-
(; matrix, diffusion_flag, sgs_advection_flag, topography_flag) = A
524+
(;
525+
matrix,
526+
diffusion_flag,
527+
sgs_advection_flag,
528+
topography_flag,
529+
sgs_mass_flux_flag,
530+
) = A
502531
(; ᶜspecific, ᶜK, ᶜts, ᶜp, ᶜΦ, ᶠgradᵥ_ᶜΦ, ᶜh_tot) = p
503532
(;
504533
ᶜtemp_C3,
@@ -945,6 +974,42 @@ function update_implicit_equation_jacobian!(A, Y, p, dtγ)
945974
dtγ * ᶠtridiagonal_matrix_c3
946975
DiagonalMatrixRow(adjoint(CT3(Y.f.sgsʲs.:(1).u₃))) - (I_u₃,)
947976
end
977+
# add updraft mass flux contributions to grid-mean
978+
if use_derivative(sgs_mass_flux_flag)
979+
980+
(; ᶜgradᵥ_ᶠΦ, ᶜρʲs, ᶠu³ʲs, ᶜtsʲs) = p
981+
(; bdmr_l, bdmr_r, bdmr) = p
982+
is_third_order = edmfx_upwinding == Val(:third_order)
983+
ᶠupwind = is_third_order ? ᶠupwind3 : ᶠupwind1
984+
ᶠset_upwind_bcs = Operators.SetBoundaryOperator(;
985+
top = Operators.SetValue(zero(CT3{FT})),
986+
bottom = Operators.SetValue(zero(CT3{FT})),
987+
) # Need to wrap ᶠupwind in this for well-defined boundaries.
988+
UpwindMatrixRowType =
989+
is_third_order ? QuaddiagonalMatrixRow : BidiagonalMatrixRow
990+
ᶠupwind_matrix =
991+
is_third_order ? ᶠupwind3_matrix : ᶠupwind1_matrix
992+
993+
ᶜkappa_mʲ = p.ᶜtemp_scalar
994+
@. ᶜkappa_mʲ =
995+
TD.gas_constant_air(thermo_params, ᶜtsʲs.:(1)) /
996+
TD.cv_m(thermo_params, ᶜtsʲs.:(1))
997+
998+
# Placeholders for jacobian contributions of updraft massflux to grid-mean
999+
# Initialize all derivatives to zero
1000+
1001+
## grid-mean ρρe_tot
1002+
∂ᶜρe_tot_err_∂ᶜmseʲ =
1003+
matrix[@name(c.ρe_tot), @name(c.sgsʲs.:(1).mse)]
1004+
∂ᶜρe_tot_err_∂ᶜmseʲ .= (zero(eltype(∂ᶜρe_tot_err_∂ᶜmseʲ)),)
1005+
1006+
## grid-mean ρq_tot
1007+
∂ᶜρq_tot_err_∂ᶜq_totʲ =
1008+
matrix[@name(c.ρq_tot), @name(c.sgsʲs.:(1).q_tot)]
1009+
∂ᶜρq_tot_err_∂ᶜq_totʲ .= (zero(eltype(∂ᶜρq_tot_err_∂ᶜq_totʲ)),)
1010+
1011+
end
1012+
9481013
elseif rs isa RayleighSponge
9491014
∂ᶠu₃ʲ_err_∂ᶠu₃ʲ =
9501015
matrix[@name(f.sgsʲs.:(1).u₃), @name(f.sgsʲs.:(1).u₃)]
@@ -955,5 +1020,4 @@ function update_implicit_equation_jacobian!(A, Y, p, dtγ)
9551020
) - (I_u₃,)
9561021
end
9571022
end
958-
9591023
end

src/prognostic_equations/implicit/implicit_tendency.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ NVTX.@annotate function implicit_tendency!(Yₜ, Y, p, t)
2929
)
3030
edmfx_sgs_diffusive_flux_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
3131
end
32+
33+
if p.atmos.sgs_mf_mode == Implicit()
34+
edmfx_sgs_mass_flux_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
35+
end
36+
3237
# NOTE: All ρa tendencies should be applied before calling this function
3338
pressure_work_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
3439

src/prognostic_equations/remaining_tendency.jl

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

112112
radiation_tendency!(Yₜ, Y, p, t, p.atmos.radiation_mode)
113113
edmfx_entr_detr_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
114-
edmfx_sgs_mass_flux_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
114+
if p.atmos.sgs_mf_mode == Explicit()
115+
edmfx_sgs_mass_flux_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
116+
end
115117
edmfx_nh_pressure_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
116118
edmfx_filter_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)
117119
edmfx_tke_tendency!(Yₜ, Y, p, t, p.atmos.turbconv_model)

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_mass_flux = parsed_args["implicit_sgs_mass_flux"]
59+
@assert implicit_sgs_mass_flux in (true, false)
60+
5861
edmfx_model = EDMFXModel(;
5962
entr_model = get_entrainment_model(parsed_args),
6063
detr_model = get_detrainment_model(parsed_args),
@@ -96,6 +99,7 @@ function get_atmos(config::AtmosConfig, params)
9699
vert_diff,
97100
diff_mode = implicit_diffusion ? Implicit() : Explicit(),
98101
sgs_adv_mode = implicit_sgs_advection ? Implicit() : Explicit(),
102+
sgs_mf_mode = implicit_sgs_mass_flux ? Implicit() : Explicit(),
99103
viscous_sponge = get_viscous_sponge_model(parsed_args, params, FT),
100104
smagorinsky_lilly = get_smagorinsky_lilly_model(parsed_args),
101105
rayleigh_sponge = get_rayleigh_sponge_model(parsed_args, params, FT),

src/solver/types.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ Base.@kwdef struct AtmosModel{
516516
VD,
517517
DM,
518518
SAM,
519+
SMM,
519520
VS,
520521
SL,
521522
RS,
@@ -553,6 +554,7 @@ Base.@kwdef struct AtmosModel{
553554
vert_diff::VD = nothing
554555
diff_mode::DM = nothing
555556
sgs_adv_mode::SAM = nothing
557+
sgs_mf_mode::SMM = nothing
556558
viscous_sponge::VS = nothing
557559
smagorinsky_lilly::SL = nothing
558560
rayleigh_sponge::RS = nothing

0 commit comments

Comments
 (0)