@@ -9,7 +9,7 @@ import ClimaCore: Geometry
99"""
1010 set_smagorinsky_lilly_precomputed_quantities!(Y, p)
1111
12- Compute the Smagorinsky-Lilly diffusivity tensors, `ᶜτ_smag`, `ᶠτ_smag`, `ᶜD_smag`, and `ᶠD_smag`.
12+ Compute the Smagorinsky-Lilly horizontal and vertical length scales `ᶜL_h` and `ᶜL_v`.
1313Store in the precomputed quantities `p.precomputed`.
1414
1515The subgrid-scale momentum flux tensor is defined by `τ = -2 νₜ ∘ S`, where `νₜ` is the Smagorinsky-Lilly eddy viscosity
@@ -26,66 +26,33 @@ These quantities are computed for both cell centers and faces, with prefixes `
2626- `p`: The model parameters, e.g. `AtmosCache`.
2727"""
2828function set_smagorinsky_lilly_precomputed_quantities!(Y, p)
29-
30- (; atmos, precomputed, scratch, params) = p
31- c_smag = CAP. c_smag(params)
32- Pr_t = CAP. Prandtl_number_0(CAP. turbconv_params(params))
33- (; ᶜu, ᶠu³, ᶜts, ᶜτ_smag, ᶠτ_smag, ᶜD_smag, ᶠD_smag) = precomputed
3429 FT = eltype(Y)
35- grav = CAP. grav(params)
36- thermo_params = CAP. thermodynamics_params(params)
37- (; ᶜtemp_UVWxUVW, ᶠtemp_UVWxUVW, ᶜtemp_strain, ᶠtemp_strain) = scratch
38- (; ᶜtemp_scalar, ᶜtemp_scalar_2, ᶠtemp_scalar, ᶜtemp_UVW, ᶠtemp_UVW) = scratch
39-
40- ∇ᵥuvw_boundary = Geometry. outer(Geometry. WVector(0 ), UVW(0 , 0 , 0 ))
41- ᶠgradᵥ_uvw = Operators. GradientC2F(
42- bottom = Operators. SetGradient(∇ᵥuvw_boundary),
43- top = Operators. SetGradient(∇ᵥuvw_boundary),
44- )
45- axis_uvw = (Geometry. UVWAxis(),)
46-
47- # Compute UVW velocities
48- ᶜu_uvw = @. ᶜtemp_UVW = UVW(ᶜu)
49- ᶠu_uvw = @. ᶠtemp_UVW = UVW(ᶠinterp(Y. c. uₕ)) + UVW(ᶠu³)
50-
51- # Gradients
52- # # cell centers
53- ∇ᶜu_uvw = @. ᶜtemp_UVWxUVW = Geometry. project(axis_uvw, ᶜgradᵥ(ᶠu_uvw)) # vertical component
54- @. ∇ᶜu_uvw += Geometry. project(axis_uvw, gradₕ(ᶜu_uvw)) # horizontal component
55- # # cell faces
56- ∇ᶠu_uvw = @. ᶠtemp_UVWxUVW = Geometry. project(axis_uvw, ᶠgradᵥ_uvw(ᶜu_uvw)) # vertical component
57- @. ∇ᶠu_uvw += Geometry. project(axis_uvw, gradₕ(ᶠu_uvw)) # horizontal component
58-
30+ (; ᶠu, ᶜts, ᶜL_h, ᶜL_v) = p. precomputed
31+ c_smag = CAP. c_smag(p. params)
32+ grav = CAP. grav(p. params)
33+ Pr_t = CAP. Prandtl_number_0(CAP. turbconv_params(p. params))
34+ thermo_params = CAP. thermodynamics_params(p. params)
35+ (; ᶜtemp_scalar, ᶜtemp_scalar_2) = p. scratch
36+
5937 # Strain rate tensor
60- ᶜS = @. ᶜtemp_strain = (∇ᶜu_uvw + adjoint(∇ᶜu_uvw)) / 2
61- ᶠS = @. ᶠtemp_strain = (∇ᶠu_uvw + adjoint(∇ᶠu_uvw)) / 2
38+ ᶜS = compute_strain_rate_center(ᶠu)
6239
6340 # Stratification correction
64- ᶜθ_v = @. ᶜtemp_scalar = TD. virtual_pottemp(thermo_params, ᶜts)
41+ ᶜθ_v = @. lazy( TD. virtual_pottemp(thermo_params, ᶜts) )
6542 ᶜ∇ᵥθ = @. ᶜtemp_scalar_2 = Geometry. WVector(ᶜgradᵥ(ᶠinterp(ᶜθ_v))). components. data.:1
6643 ᶜN² = @. ᶜtemp_scalar = grav / ᶜθ_v * ᶜ∇ᵥθ
67- ᶜS_norm = @. ᶜtemp_scalar_2 = √ (2 * CA . norm_sqr(ᶜS))
44+ ᶜS_norm = @. ᶜtemp_scalar_2 = √ (2 * norm_sqr(ᶜS))
6845
6946 ᶜRi = @. ᶜtemp_scalar = ᶜN² / (ᶜS_norm^ 2 + eps(FT)) # Ri = N² / |S|²
7047 ᶜfb = @. ᶜtemp_scalar = ifelse(ᶜRi ≤ 0 , 1 , max(0 , 1 - ᶜRi / Pr_t)^ (1 / 4 ))
7148
7249 # filter scale
7350 h_space = Spaces. horizontal_space(axes(Y. c))
74- Δ_xy = Spaces. node_horizontal_length_scale(h_space)^ 2 # Δ_x * Δ_y
51+ Δ_h = Spaces. node_horizontal_length_scale(h_space)
7552 ᶜΔ_z = Fields. Δz_field(Y. c)
76- ᶜΔ = @. ᶜtemp_scalar = ∛ (Δ_xy * ᶜΔ_z) * ᶜfb
7753
78- # Smagorinsky-Lilly eddy viscosity
79- ᶜνₜ = @. ᶜtemp_scalar = c_smag^ 2 * ᶜΔ^ 2 * ᶜS_norm
80- ᶠνₜ = @. ᶠtemp_scalar = ᶠinterp(ᶜνₜ)
81-
82- # Subgrid-scale momentum flux tensor, `τ = -2 νₜ ∘ S`
83- @. ᶜτ_smag = - 2 * ᶜνₜ * ᶜS
84- @. ᶠτ_smag = - 2 * ᶠνₜ * ᶠS
85-
86- # Turbulent diffusivity
87- @. ᶜD_smag = ᶜνₜ / Pr_t
88- @. ᶠD_smag = ᶠνₜ / Pr_t
54+ @. ᶜL_v = c_smag * ᶜΔ_z * ᶜfb
55+ @. ᶜL_h = c_smag * Δ_h
8956
9057 nothing
9158end
@@ -94,11 +61,28 @@ horizontal_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, ::Nothing) = nothing
9461vertical_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, :: Nothing ) = nothing
9562
9663function horizontal_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, :: SmagorinskyLilly )
97- (; ᶜτ_smag, ᶠτ_smag, ᶜD_smag, ᶜts) = p. precomputed
64+ (; ᶜu, ᶠu, ᶜts, ᶜL_h) = p. precomputed
65+ (; ᶜtemp_UVWxUVW, ᶠtemp_UVWxUVW, ᶜtemp_scalar, ᶠtemp_scalar) = p. scratch
9866 thermo_params = CAP. thermodynamics_params(p. params)
67+ Pr_t = CAP. Prandtl_number_0(CAP. turbconv_params(p. params))
9968
10069 # # Momentum tendencies
101- ᶠρ = @. p. scratch. ᶠtemp_scalar = ᶠinterp(Y. c. ρ)
70+ ᶜS = compute_strain_rate_center(ᶠu)
71+ ᶠS = compute_strain_rate_face(ᶜu)
72+ ᶜS_norm = @. lazy(√ (2 * norm_sqr(ᶜS))) # TODO : This should be the UV-components only
73+
74+ # Smagorinsky eddy viscosity
75+ ᶜνₜ_h = @. lazy(ᶜL_h^ 2 * ᶜS_norm)
76+ ᶠνₜ_h = @. lazy(ᶠinterp(ᶜνₜ_h))
77+
78+ # Turbulent diffusivity
79+ ᶜD_smag = @. ᶜtemp_scalar = ᶜνₜ_h / Pr_t
80+
81+ # Subgrid-scale momentum flux tensor, `τ = -2 νₜ ∘ S`
82+ ᶜτ_smag = @. ᶜtemp_UVWxUVW = - 2 * ᶜνₜ_h * ᶜS # TODO : Lazify once we can mix lazy horizontal & vertical operations
83+ ᶠτ_smag = @. ᶠtemp_UVWxUVW = - 2 * ᶠνₜ_h * ᶠS
84+
85+ ᶠρ = ᶠtemp_scalar .= face_density(Y)
10286 @. Yₜ. c. uₕ -= C12(wdivₕ(Y. c. ρ * ᶜτ_smag) / Y. c. ρ)
10387 @. Yₜ. f. u₃ -= C3(wdivₕ(ᶠρ * ᶠτ_smag) / ᶠρ)
10488
@@ -121,15 +105,12 @@ function horizontal_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, ::SmagorinskyLill
121105
122106end
123107
124- import UnrolledUtilities as UU
125-
126108function vertical_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, :: SmagorinskyLilly )
127109 FT = eltype(Y)
128- (; sfc_temp_C3, ᶠtemp_scalar) = p. scratch
129- (; ᶜτ_smag, ᶠτ_smag, ᶠD_smag, sfc_conditions) = p. precomputed
130- (; ρ_flux_uₕ, ρ_flux_h_tot) = sfc_conditions
131- (; ᶜts) = p. precomputed
110+ (; ᶜu, ᶠu, ᶜts, ᶜL_v) = p. precomputed
111+ (; ᶜtemp_UVWxUVW, ᶠtemp_UVWxUVW, ᶠtemp_scalar, ᶠtemp_scalar_2) = p. scratch
132112 thermo_params = CAP. thermodynamics_params(p. params)
113+ Pr_t = CAP. Prandtl_number_0(CAP. turbconv_params(p. params))
133114
134115 # Define operators
135116 ᶠgradᵥ = Operators. GradientC2F() # apply BCs to ᶜdivᵥ, which wraps ᶠgradᵥ
@@ -146,9 +127,25 @@ function vertical_smagorinsky_lilly_tendency!(Yₜ, Y, p, t, ::SmagorinskyLilly)
146127 bottom = Operators. SetValue(C3(FT(0 ))),
147128 )
148129
130+ # # Momentum tendencies
131+ ᶜS = compute_strain_rate_center(ᶠu)
132+ ᶠS = compute_strain_rate_face(ᶜu)
133+ ᶜS_norm = @. lazy(√ (2 * norm_sqr(ᶜS))) # TODO : This should be the W-component only
134+
135+ # Smagorinsky eddy viscosity
136+ ᶜνₜ_v = @. lazy(ᶜL_v^ 2 * ᶜS_norm)
137+ ᶠνₜ_v = @. lazy(ᶠinterp(ᶜνₜ_v))
138+
139+ # Subgrid-scale momentum flux tensor, `τ = -2 νₜ ∘ S`
140+ ᶜτ_smag = @. ᶜtemp_UVWxUVW = - 2 * ᶜνₜ_v * ᶜS
141+ ᶠτ_smag = @. ᶠtemp_UVWxUVW = - 2 * ᶠνₜ_v * ᶠS
142+
143+ # Turbulent diffusivity
144+ ᶠD_smag = @. ᶠtemp_scalar_2 = ᶠνₜ_v / Pr_t
145+
149146 # Apply to tendencies
150147 # # Horizontal momentum tendency
151- ᶠρ = @. ᶠtemp_scalar = ᶠinterp(Y . c . ρ )
148+ ᶠρ = ᶠtemp_scalar . = face_density(Y )
152149 @. Yₜ. c. uₕ -= C12(ᶜdivᵥ(ᶠρ * ᶠτ_smag) / Y. c. ρ)
153150 # # Apply boundary condition for momentum flux
154151 @. Yₜ. c. uₕ -= ᶜdivᵥ_uₕ(- (FT(0 ) * ᶠgradᵥ(Y. c. uₕ))) / Y. c. ρ
0 commit comments