@@ -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