Skip to content

Commit d469658

Browse files
szy21sajjadazimi
authored andcommitted
add du3_dq jacobian for microphysics tracers
1 parent c38638e commit d469658

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

src/parameters/Parameters.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ for var in fieldnames(TD.Parameters.ThermodynamicsParameters)
138138
@eval $var(ps::ACAP) = TD.Parameters.$var(thermodynamics_params(ps))
139139
end
140140
# Thermodynamics derived parameters
141-
for var in [:Rv_over_Rd, :kappa_d, :e_int_v0, :cv_v, :cv_l, :cv_d]
141+
for var in [:Rv_over_Rd, :kappa_d, :e_int_v0, :e_int_i0, :cv_v, :cv_l, :cv_d]
142142
@eval $var(ps::ACAP) = TD.Parameters.$var(thermodynamics_params(ps))
143143
end
144144

src/prognostic_equations/implicit/manual_sparse_jacobian.jl

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,16 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
9191
is_in_Y(@name(c.sgs⁰.ρatke)) ? (@name(c.sgs⁰.ρatke),) : ()
9292
sfc_if_available = is_in_Y(@name(sfc)) ? (@name(sfc),) : ()
9393

94-
condensate_names = (
94+
condensate_mass_names = (
9595
@name(c.ρq_liq),
9696
@name(c.ρq_ice),
9797
@name(c.ρq_rai),
9898
@name(c.ρq_sno),
99+
)
100+
available_condensate_mass_names =
101+
MatrixFields.unrolled_filter(is_in_Y, condensate_mass_names)
102+
condensate_names = (
103+
condensate_mass_names...,
99104
@name(c.ρn_liq),
100105
@name(c.ρn_rai),
101106
# P3 frozen
@@ -161,6 +166,10 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
161166
name -> (@name(f.u₃), name) => similar(Y.f, BidiagonalRow_C3),
162167
active_scalar_names,
163168
)...,
169+
MatrixFields.unrolled_map(
170+
name -> (@name(f.u₃), name) => similar(Y.f, BidiagonalRow_C3),
171+
available_condensate_mass_names,
172+
)...,
164173
(@name(f.u₃), @name(c.uₕ)) => similar(Y.f, BidiagonalRow_C3xACT12),
165174
(@name(f.u₃), @name(f.u₃)) => similar(Y.f, TridiagonalRow_C3xACT3),
166175
)
@@ -183,6 +192,10 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
183192
similar(Y.c, TridiagonalRow),
184193
) : ()
185194
)...,
195+
MatrixFields.unrolled_map(
196+
name -> (@name(c.ρe_tot), name) => similar(Y.c, TridiagonalRow),
197+
available_condensate_mass_names,
198+
)...,
186199
(@name(c.uₕ), @name(c.uₕ)) =>
187200
!isnothing(atmos.turbconv_model) ||
188201
!disable_momentum_vertical_diffusion(
@@ -333,7 +346,10 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
333346
use_derivative(sgs_advection_flag) ||
334347
!(atmos.moisture_model isa DryModel)
335348
gs_scalar_subalg = if !(atmos.moisture_model isa DryModel)
336-
MatrixFields.BlockLowerTriangularSolve(@name(c.ρq_tot))
349+
MatrixFields.BlockLowerTriangularSolve(
350+
@name(c.ρq_tot),
351+
available_condensate_mass_names...,
352+
)
337353
else
338354
MatrixFields.BlockDiagonalSolve()
339355
end
@@ -377,6 +393,8 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
377393
return (; matrix = MatrixFields.FieldMatrixWithSolver(matrix, Y, full_alg))
378394
end
379395

396+
# TODO: There are a few for loops in this function. This is because
397+
# using unrolled_foreach allocates (breaks the flame tests)
380398
function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
381399
(;
382400
topography_flag,
@@ -421,10 +439,14 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
421439
LH_s0 = FT(CAP.LH_s0(params))
422440
Δcp_l = FT(CAP.cp_l(params) - CAP.cp_v(params))
423441
Δcp_i = FT(CAP.cp_i(params) - CAP.cp_v(params))
442+
Δcv_l = FT(CAP.cp_l(params) - CAP.cv_v(params))
443+
Δcv_i = FT(CAP.cp_i(params) - CAP.cv_v(params))
444+
e_int_v0 = FT(CAP.e_int_v0(params))
445+
e_int_s0 = FT(CAP.e_int_i0(params)) + e_int_v0
424446
# This term appears a few times in the Jacobian, and is technically
425447
# minus ∂e_int_∂q_tot
426-
thermo_params = CAP.thermodynamics_params(params)
427448
∂e_int_∂q_tot = T_0 * (Δcv_v - R_d) - e_int_v0
449+
thermo_params = CAP.thermodynamics_params(params)
428450
ᶜh_tot = @. lazy(
429451
TD.total_specific_enthalpy(
430452
thermo_params,
@@ -532,6 +554,26 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
532554
dtγ * ᶠp_grad_matrix DiagonalMatrixRow(ᶜ∂p∂ρq_tot)
533555
end
534556

557+
microphysics_tracers =
558+
p.atmos.moisture_model isa NonEquilMoistModel && (
559+
p.atmos.microphysics_model isa Microphysics1Moment ||
560+
p.atmos.microphysics_model isa Microphysics2Moment
561+
) ?
562+
(
563+
(@name(c.ρq_liq), e_int_v0, Δcv_l),
564+
(@name(c.ρq_ice), e_int_s0, Δcv_i),
565+
(@name(c.ρq_rai), e_int_v0, Δcv_l),
566+
(@name(c.ρq_sno), e_int_s0, Δcv_i),
567+
) : (;)
568+
569+
for (q_name, e_int_q, ∂cv∂q) in microphysics_tracers
570+
MatrixFields.has_field(Y, q_name) || continue
571+
∂ᶠu₃_err_∂ᶜρq = matrix[@name(f.u₃), q_name]
572+
@. ∂ᶠu₃_err_∂ᶜρq =
573+
dtγ * ᶠp_grad_matrix
574+
DiagonalMatrixRow(ᶜkappa_m * (e_int_q - ∂cv∂q * (T - T_0)) - R_v * T)
575+
end
576+
535577
∂ᶠu₃_err_∂ᶜuₕ = matrix[@name(f.u₃), @name(c.uₕ)]
536578
∂ᶠu₃_err_∂ᶠu₃ = matrix[@name(f.u₃), @name(f.u₃)]
537579
I_u₃ = DiagonalMatrixRow(one_C3xACT3)
@@ -690,6 +732,14 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
690732
dtγ * ᶜdiffusion_h_matrix DiagonalMatrixRow(1 / ᶜρ)
691733
end
692734

735+
for (q_name, e_int_q, ∂cv∂q) in microphysics_tracers
736+
MatrixFields.has_field(Y, q_name) || continue
737+
∂ᶜρe_tot_err_∂ᶜρq = matrix[@name(c.ρe_tot), q_name]
738+
@. ∂ᶜρe_tot_err_∂ᶜρq =
739+
dtγ * ᶜdiffusion_h_matrix
740+
DiagonalMatrixRow((ᶜkappa_m * (e_int_q - ∂cv∂q * (T - T_0)) - R_v * T) / ᶜρ)
741+
end
742+
693743
MatrixFields.unrolled_foreach(tracer_info) do (ρχ_name, _, α)
694744
MatrixFields.has_field(Y, ρχ_name) || return
695745
∂ᶜρχ_err_∂ᶜρ = matrix[ρχ_name, @name(c.ρ)]
@@ -913,10 +963,7 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
913963
) : (
914964
(@name(c.sgsʲs.:(1).q_tot), -LH_v0, Δcp_v, ΔR_v),
915965
)
916-
# TODO using unrolled_foreach here allocates! (breaks the flame tests)
917-
# MatrixFields.unrolled_foreach(
918-
# sgs_microphysics_tracers,
919-
# ) do (qʲ_name, LH, ∂cp∂q, ∂Rm∂q)
966+
920967
for (qʲ_name, LH, ∂cp∂q, ∂Rm∂q) in sgs_microphysics_tracers
921968
MatrixFields.has_field(Y, qʲ_name) || continue
922969

@@ -1218,6 +1265,16 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
12181265
p.scratch.ᶜtridiagonal_matrix_scalar
12191266
DiagonalMatrixRow(ᶜ∂p∂ρq_tot / ᶜρ)
12201267

1268+
for (q_name, e_int_q, ∂cv∂q) in microphysics_tracers
1269+
MatrixFields.has_field(Y, q_name) || continue
1270+
∂ᶜρe_tot_err_∂ᶜρq = matrix[@name(c.ρe_tot), q_name]
1271+
@. ∂ᶜρe_tot_err_∂ᶜρq +=
1272+
p.scratch.ᶜtridiagonal_matrix_scalar
1273+
DiagonalMatrixRow(
1274+
(ᶜkappa_m * (e_int_q - ∂cv∂q * (T - T_0)) - R_v * T) / ᶜρ,
1275+
)
1276+
end
1277+
12211278
@. ∂ᶜρe_tot_err_∂ᶜρe_tot +=
12221279
p.scratch.ᶜtridiagonal_matrix_scalar
12231280
DiagonalMatrixRow((1 + ᶜkappa_m) / ᶜρ)

0 commit comments

Comments
 (0)