@@ -28,6 +28,7 @@ These quantities are computed for both cell centers and faces, with prefixes `
2828function set_smagorinsky_lilly_precomputed_quantities! (Y, p)
2929 FT = eltype (Y)
3030 (; ᶜu, ᶠu, ᶜts, ᶜL_h, ᶜL_v, ᶠS, ᶜS) = p. precomputed
31+ (; ᶜstrain_rate_norm_h, ᶜstrain_rate_norm_v) = p. precomputed # diagnostics
3132 c_smag = CAP. c_smag (p. params)
3233 grav = CAP. grav (p. params)
3334 Pr_t = CAP. Prandtl_number_0 (CAP. turbconv_params (p. params))
6162horizontal_smagorinsky_lilly_tendency! (Yₜ, Y, p, t, :: Nothing ) = nothing
6263vertical_smagorinsky_lilly_tendency! (Yₜ, Y, p, t, :: Nothing ) = nothing
6364
64- function projected_strain_rate_norm (ᶜS, axis)
65- ᶜS_proj = @. lazy (Geometry. project ((axis,), ᶜS, (axis,)))
66- ᶜS_norm = @. lazy (√ (2 * norm_sqr (ᶜS_proj)))
67- return ᶜS_norm
65+ function projected_strain_rate_norm (S, axis)
66+ S_proj = @. lazy (Geometry. project ((axis,), S, (axis,)))
67+ S_norm = @. lazy (√ (2 * norm_sqr (S_proj)))
68+ return S_norm
69+ end
70+
71+ function horizontal_smagorinsky_eddy_viscosity (L, S)
72+ S_norm = projected_strain_rate_norm (S, Geometry. UVAxis ())
73+ νₜ = @. lazy (L^ 2 * S_norm)
74+ return νₜ
75+ end
76+
77+ function vertical_smagorinsky_eddy_viscosity (L, S)
78+ S_norm = projected_strain_rate_norm (S, Geometry. WAxis ())
79+ νₜ = @. lazy (L^ 2 * S_norm)
80+ return νₜ
6881end
6982
7083function horizontal_smagorinsky_lilly_tendency! (Yₜ, Y, p, t, :: SmagorinskyLilly )
7184 (; ᶜts, ᶜL_h, ᶠS, ᶜS) = p. precomputed
7285 (; ᶜtemp_UVWxUVW, ᶠtemp_UVWxUVW, ᶜtemp_scalar, ᶠtemp_scalar) = p. scratch
7386 thermo_params = CAP. thermodynamics_params (p. params)
7487 Pr_t = CAP. Prandtl_number_0 (CAP. turbconv_params (p. params))
75-
76- # # Momentum tendencies
77- ᶜS_norm = projected_strain_rate_norm (ᶜS, Geometry. UVAxis ())
78- @. p. precomputed. ᶜstrain_rate_norm_h = ᶜS_norm # save to diagnostics
88+ ᶜρ = Y. c. ρ
7989
8090 # Smagorinsky eddy viscosity
81- ᶜνₜ_h = @. lazy (ᶜL_h^ 2 * ᶜS_norm )
91+ ᶜνₜ_h = horizontal_smagorinsky_eddy_viscosity (ᶜL_h, ᶜS )
8292 ᶠνₜ_h = @. lazy (ᶠinterp (ᶜνₜ_h))
8393
8494 # Turbulent diffusivity
@@ -90,22 +100,22 @@ function horizontal_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, ::SmagorinskyLill
90100 ᶠτ_smag = @. ᶠtemp_UVWxUVW = - 2 * ᶠνₜ_h * ᶠS
91101
92102 ᶠρ = ᶠtemp_scalar .= face_density (Y)
93- @. Yₜ. c. uₕ -= C12 (wdivₕ (Y . c . ρ * ᶜτ_smag) / Y . c . ρ )
103+ @. Yₜ. c. uₕ -= C12 (wdivₕ (ᶜρ * ᶜτ_smag) / ᶜρ )
94104 @. Yₜ. f. u₃ -= C3 (wdivₕ (ᶠρ * ᶠτ_smag) / ᶠρ)
95105
96106 # # Total energy tendency
97- ᶜe_tot = @. lazy (specific (Y. c. ρe_tot, Y . c . ρ ))
107+ ᶜe_tot = @. lazy (specific (Y. c. ρe_tot, ᶜρ ))
98108 ᶜh_tot = @. lazy (TD. total_specific_enthalpy (thermo_params, ᶜts, ᶜe_tot))
99- @. Yₜ. c. ρe_tot += wdivₕ (Y . c . ρ * ᶜD_smag * gradₕ (ᶜh_tot))
109+ @. Yₜ. c. ρe_tot += wdivₕ (ᶜρ * ᶜD_smag * gradₕ (ᶜh_tot))
100110
101111 # # Tracer diffusion and associated mass changes
102112 foreach_gs_tracer (Yₜ, Y) do ᶜρχₜ, ᶜρχ, ρχ_name
103- ᶜχ = @. lazy (specific (ᶜρχ, Y . c . ρ ))
104- ᶜρχₜ_diffusion = @. lazy (wdivₕ (Y . c . ρ * ᶜD_smag * gradₕ (ᶜχ)))
105- @. ᶜρχₜ += ᶜρχₜ_diffusion
113+ ᶜχ = @. lazy (specific (ᶜρχ, ᶜρ ))
114+ ᶜ∇ₕρD∇χₜ = @. lazy (wdivₕ (ᶜρ * ᶜD_smag * gradₕ (ᶜχ)))
115+ @. ᶜρχₜ += ᶜ∇ₕρD∇χₜ
106116 # Rain and snow does not affect the mass
107117 if ρχ_name == @name (ρq_tot)
108- @. Yₜ. c. ρ += ᶜρχₜ_diffusion
118+ @. Yₜ. c. ρ += ᶜ∇ₕρD∇χₜ
109119 end
110120 end
111121
@@ -117,6 +127,7 @@ function vertical_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, ::SmagorinskyLilly)
117127 (; ᶜtemp_UVWxUVW, ᶠtemp_UVWxUVW, ᶠtemp_scalar, ᶠtemp_scalar_2) = p. scratch
118128 thermo_params = CAP. thermodynamics_params (p. params)
119129 Pr_t = CAP. Prandtl_number_0 (CAP. turbconv_params (p. params))
130+ ᶜρ = Y. c. ρ
120131
121132 # Define operators
122133 ᶠgradᵥ = Operators. GradientC2F () # apply BCs to ᶜdivᵥ, which wraps ᶠgradᵥ
@@ -125,20 +136,14 @@ function vertical_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, ::SmagorinskyLilly)
125136 bottom = Operators. SetValue (C3 (FT (0 )) ⊗ C12 (FT (0 ), FT (0 ))),
126137 )
127138 ᶠdivᵥ = Operators. DivergenceC2F (
128- bottom = Operators. SetDivergence (FT (0 )),
129- top = Operators. SetDivergence (FT (0 )),
139+ bottom = Operators. SetDivergence (FT (0 )), top = Operators. SetDivergence (FT (0 )),
130140 )
131- ᶜdivᵥ_ρe_tot = Operators. DivergenceF2C (;
132- top = Operators. SetValue (C3 (FT (0 ))),
133- bottom = Operators. SetValue (C3 (FT (0 ))),
141+ ᶜdivᵥ_ρχ = Operators. DivergenceF2C (;
142+ top = Operators. SetValue (C3 (FT (0 ))), bottom = Operators. SetValue (C3 (FT (0 ))),
134143 )
135144
136- # # Momentum tendencies
137- ᶜS_norm = projected_strain_rate_norm (ᶜS, Geometry. WAxis ())
138- @. p. precomputed. ᶜstrain_rate_norm_v = ᶜS_norm # save to diagnostics
139-
140145 # Smagorinsky eddy viscosity
141- ᶜνₜ_v = @. lazy (ᶜL_v^ 2 * ᶜS_norm )
146+ ᶜνₜ_v = vertical_smagorinsky_eddy_viscosity (ᶜL_v, ᶜS )
142147 ᶠνₜ_v = @. lazy (ᶠinterp (ᶜνₜ_v))
143148
144149 # Subgrid-scale momentum flux tensor, `τ = -2 νₜ ∘ S`
@@ -147,30 +152,26 @@ function vertical_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, ::SmagorinskyLilly)
147152
148153 # Turbulent diffusivity
149154 ᶠD_smag = @. ᶠtemp_scalar_2 = ᶠνₜ_v / Pr_t
150- @. p. precomputed. ᶠD_v = ᶠD_smag # save to diagnostics
155+ @. p. precomputed. ᶜD_v = ᶜνₜ_v / Pr_t # save to diagnostics, on centers
151156
152157 # Apply to tendencies
153158 # # Horizontal momentum tendency
154159 ᶠρ = ᶠtemp_scalar .= face_density (Y)
155- @. Yₜ. c. uₕ -= C12 (ᶜdivᵥ (ᶠρ * ᶠτ_smag) / Y . c . ρ )
160+ @. Yₜ. c. uₕ -= C12 (ᶜdivᵥ (ᶠρ * ᶠτ_smag) / ᶜρ )
156161 # # Apply boundary condition for momentum flux
157- @. Yₜ. c. uₕ -= ᶜdivᵥ_uₕ (- (FT (0 ) * ᶠgradᵥ (Y. c. uₕ))) / Y . c . ρ
162+ @. Yₜ. c. uₕ -= ᶜdivᵥ_uₕ (- (FT (0 ) * ᶠgradᵥ (Y. c. uₕ))) / ᶜρ
158163 # # Vertical momentum tendency
159- @. Yₜ. f. u₃ -= C3 (ᶠdivᵥ (Y . c . ρ * ᶜτ_smag) / ᶠρ)
164+ @. Yₜ. f. u₃ -= C3 (ᶠdivᵥ (ᶜρ * ᶜτ_smag) / ᶠρ)
160165
161166 # # Total energy tendency
162- ᶜe_tot = @. lazy (specific (Y. c. ρe_tot, Y . c . ρ ))
167+ ᶜe_tot = @. lazy (specific (Y. c. ρe_tot, ᶜρ ))
163168 ᶜh_tot = @. lazy (TD. total_specific_enthalpy (thermo_params, ᶜts, ᶜe_tot))
164- @. Yₜ. c. ρe_tot -= ᶜdivᵥ_ρe_tot (- (ᶠρ * ᶠD_smag * ᶠgradᵥ (ᶜh_tot)))
169+ @. Yₜ. c. ρe_tot -= ᶜdivᵥ_ρχ (- (ᶠρ * ᶠD_smag * ᶠgradᵥ (ᶜh_tot)))
165170
166171 # # Tracer diffusion and associated mass changes
167- ᶜdivᵥ_ρχ = Operators. DivergenceF2C (;
168- top = Operators. SetValue (C3 (FT (0 ))),
169- bottom = Operators. SetValue (C3 (FT (0 ))),
170- )
171-
172172 foreach_gs_tracer (Yₜ, Y) do ᶜρχₜ, ᶜρχ, ρχ_name
173- ᶜ∇ᵥρD∇χₜ = @. lazy (ᶜdivᵥ_ρχ (- (ᶠρ * ᶠD_smag * ᶠgradᵥ (specific (ᶜρχ, Y. c. ρ)))))
173+ ᶜχ = @. lazy (specific (ᶜρχ, ᶜρ))
174+ ᶜ∇ᵥρD∇χₜ = @. lazy (ᶜdivᵥ_ρχ (- (ᶠρ * ᶠD_smag * ᶠgradᵥ (ᶜχ))))
174175 @. ᶜρχₜ -= ᶜ∇ᵥρD∇χₜ
175176 # Rain and snow does not affect the mass
176177 if ρχ_name == @name (ρq_tot)
0 commit comments