Skip to content

Commit 24cce82

Browse files
committed
wip: implicit vertical smagorinsky diffusion
1 parent edb54cf commit 24cce82

File tree

1 file changed

+32
-41
lines changed

1 file changed

+32
-41
lines changed

src/prognostic_equations/implicit/manual_sparse_jacobian.jl

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -77,39 +77,30 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
7777
BidiagonalRow_C3 = BidiagonalMatrixRow{C3{FT}}
7878
TridiagonalRow_ACT12 = TridiagonalMatrixRow{Adjoint{FT, CT12{FT}}}
7979
BidiagonalRow_ACT3 = BidiagonalMatrixRow{Adjoint{FT, CT3{FT}}}
80-
BidiagonalRow_C3xACT12 =
81-
BidiagonalMatrixRow{typeof(zero(C3{FT}) * zero(CT12{FT})')}
82-
DiagonalRow_C3xACT3 =
83-
DiagonalMatrixRow{typeof(zero(C3{FT}) * zero(CT3{FT})')}
84-
TridiagonalRow_C3xACT3 =
85-
TridiagonalMatrixRow{typeof(zero(C3{FT}) * zero(CT3{FT})')}
80+
BidiagonalRow_C3xACT12 = BidiagonalMatrixRow{typeof(zero(C3{FT}) * zero(CT12{FT})')}
81+
DiagonalRow_C3xACT3 = DiagonalMatrixRow{typeof(zero(C3{FT}) * zero(CT3{FT})')}
82+
TridiagonalRow_C3xACT3 = TridiagonalMatrixRow{typeof(zero(C3{FT}) * zero(CT3{FT})')}
8683

8784
is_in_Y(name) = MatrixFields.has_field(Y, name)
8885

8986
ρq_tot_if_available = is_in_Y(@name(c.ρq_tot)) ? (@name(c.ρq_tot),) : ()
90-
ρatke_if_available =
91-
is_in_Y(@name(c.sgs⁰.ρatke)) ? (@name(c.sgs⁰.ρatke),) : ()
87+
ρatke_if_available = is_in_Y(@name(c.sgs⁰.ρatke)) ? (@name(c.sgs⁰.ρatke),) : ()
9288
sfc_if_available = is_in_Y(@name(sfc)) ? (@name(sfc),) : ()
9389

9490
condensate_mass_names = (
95-
@name(c.ρq_liq),
96-
@name(c.ρq_ice),
97-
@name(c.ρq_rai),
98-
@name(c.ρq_sno),
91+
@name(c.ρq_liq), @name(c.ρq_ice), @name(c.ρq_rai), @name(c.ρq_sno), # 1M,2M
92+
@name(c.ρq_rim) # P3 frozen
9993
)
10094
available_condensate_mass_names =
10195
MatrixFields.unrolled_filter(is_in_Y, condensate_mass_names)
102-
condensate_names = (
103-
condensate_mass_names...,
104-
@name(c.ρn_liq),
105-
@name(c.ρn_rai),
96+
condensate_names = (condensate_mass_names...,
97+
# 2M number concentrations
98+
@name(c.ρn_liq), @name(c.ρn_rai),
10699
# P3 frozen
107-
@name(c.ρn_ice), @name(c.ρq_rim), @name(c.ρb_rim),
100+
@name(c.ρn_ice), @name(c.ρb_rim),
108101
)
109-
available_condensate_names =
110-
MatrixFields.unrolled_filter(is_in_Y, condensate_names)
111-
available_tracer_names =
112-
(ρq_tot_if_available..., available_condensate_names...)
102+
available_condensate_names = MatrixFields.unrolled_filter(is_in_Y, condensate_names)
103+
available_tracer_names = (ρq_tot_if_available..., available_condensate_names...)
113104

114105
# we define the list of condensate masses separately because ρa and q_tot
115106
# depend on the masses via sedimentation
@@ -134,11 +125,9 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
134125
@name(c.sgsʲs.:(1).mse),
135126
@name(c.sgsʲs.:(1).ρa)
136127
)
137-
available_sgs_scalar_names =
138-
MatrixFields.unrolled_filter(is_in_Y, sgs_scalar_names)
128+
available_sgs_scalar_names = MatrixFields.unrolled_filter(is_in_Y, sgs_scalar_names)
139129

140-
sgs_u³_if_available =
141-
is_in_Y(@name(f.sgsʲs.:(1).u₃)) ? (@name(f.sgsʲs.:(1).u₃),) : ()
130+
sgs_u³_if_available = is_in_Y(@name(f.sgsʲs.:(1).u₃)) ? (@name(f.sgsʲs.:(1).u₃),) : ()
142131

143132
# Note: We have to use FT(-1) * I instead of -I because inv(-1) == -1.0,
144133
# which means that multiplying inv(-1) by a Float32 will yield a Float64.
@@ -177,22 +166,19 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
177166
diffused_scalar_names = (@name(c.ρe_tot), available_tracer_names...)
178167
diffusion_blocks = if use_derivative(diffusion_flag)
179168
(
180-
MatrixFields.unrolled_map(
169+
MatrixFields.unrolled_map( # ∂ρχ / ∂ρ
181170
name -> (name, @name(c.ρ)) => similar(Y.c, TridiagonalRow),
182171
(diffused_scalar_names..., ρatke_if_available...),
183172
)...,
184-
MatrixFields.unrolled_map(
173+
MatrixFields.unrolled_map( # ∂ρχ / ∂ρχ
185174
name -> (name, name) => similar(Y.c, TridiagonalRow),
186175
(diffused_scalar_names..., ρatke_if_available...),
187176
)...,
188177
(
189-
is_in_Y(@name(c.ρq_tot)) ?
190-
(
191-
(@name(c.ρe_tot), @name(c.ρq_tot)) =>
192-
similar(Y.c, TridiagonalRow),
193-
) : ()
178+
is_in_Y(@name(c.ρq_tot)) ? # ∂ρe_tot / ∂ρq_tot
179+
((@name(c.ρe_tot), @name(c.ρq_tot)) => similar(Y.c, TridiagonalRow)) : ()
194180
)...,
195-
MatrixFields.unrolled_map(
181+
MatrixFields.unrolled_map( # ∂ρe_tot / ∂ρχ
196182
name -> (@name(c.ρe_tot), name) => similar(Y.c, TridiagonalRow),
197183
available_condensate_mass_names,
198184
)...,
@@ -213,8 +199,7 @@ function jacobian_cache(alg::ManualSparseJacobian, Y, atmos)
213199
name -> (name, name) => similar(Y.c, TridiagonalRow),
214200
diffused_scalar_names,
215201
)...,
216-
(@name(c.ρe_tot), @name(c.ρq_tot)) =>
217-
similar(Y.c, TridiagonalRow),
202+
(@name(c.ρe_tot), @name(c.ρq_tot)) => similar(Y.c, TridiagonalRow),
218203
MatrixFields.unrolled_map(
219204
name -> (name, name) => FT(-1) * I,
220205
(ρatke_if_available..., @name(c.uₕ)),
@@ -691,7 +676,8 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
691676
if (
692677
MatrixFields.has_field(Y, @name(c.sgs⁰.ρatke)) ||
693678
!isnothing(p.atmos.turbconv_model) ||
694-
!disable_momentum_vertical_diffusion(p.atmos.vertical_diffusion)
679+
!disable_momentum_vertical_diffusion(p.atmos.vertical_diffusion) ||
680+
is_smagorinsky_vertical(smagorinsky_lilly)
695681
)
696682
@. ∂ᶠρχ_dif_flux_∂ᶜχ =
697683
DiagonalMatrixRow(ᶠinterp(ᶜρ) * ᶠinterp(ᶜK_u)) ᶠgradᵥ_matrix()
@@ -727,8 +713,7 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
727713
∂ᶜρχ_err_∂ᶜρ = matrix[ρχ_name, @name(c.ρ)]
728714
∂ᶜρχ_err_∂ᶜρχ = matrix[ρχ_name, ρχ_name]
729715
@. ∂ᶜρχ_err_∂ᶜρ = zero(typeof(∂ᶜρχ_err_∂ᶜρ))
730-
@. ∂ᶜρχ_err_∂ᶜρχ +=
731-
dtγ * α * ᶜdiffusion_h_matrix DiagonalMatrixRow(1 / ᶜρ)
716+
@. ∂ᶜρχ_err_∂ᶜρχ += dtγ * α * ᶜdiffusion_h_matrix DiagonalMatrixRow(1 / ᶜρ)
732717
end
733718

734719
if MatrixFields.has_field(Y, @name(c.sgs⁰.ρatke))
@@ -779,11 +764,17 @@ function update_jacobian!(alg::ManualSparseJacobian, cache, Y, p, dtγ, t)
779764

780765
if (
781766
!isnothing(p.atmos.turbconv_model) ||
782-
!disable_momentum_vertical_diffusion(p.atmos.vertical_diffusion)
767+
!disable_momentum_vertical_diffusion(p.atmos.vertical_diffusion) ||
768+
is_smagorinsky_vertical(smagorinsky_lilly)
783769
)
784770
∂ᶜuₕ_err_∂ᶜuₕ = matrix[@name(c.uₕ), @name(c.uₕ)]
785-
@. ∂ᶜuₕ_err_∂ᶜuₕ =
786-
dtγ * DiagonalMatrixRow(1 / ᶜρ) ᶜdiffusion_u_matrix - (I,)
771+
@. ∂ᶜuₕ_err_∂ᶜuₕ = dtγ * DiagonalMatrixRow(1 / ᶜρ) ᶜdiffusion_u_matrix - (I,)
772+
end
773+
774+
if is_smagorinsky_vertical(smagorinsky_lilly)
775+
# Factor `2` from: τ=-2νS, where "S₃₃ = ∂u₃/∂z"
776+
# in contrast to the horizontal diffusion, where "S₁₃ = ∂u₁/∂z / 2"
777+
@. ∂ᶠu₃_err_∂ᶠu₃ += dtγ * DiagonalMatrixRow(1 / ᶜρ) (2 * ᶜdiffusion_u_matrix)
787778
end
788779

789780
end

0 commit comments

Comments
 (0)