@@ -44,22 +44,84 @@ using ClimaCore.RecursiveApply: rzero
44
44
function ᶜremaining_tendency_ρ (ᶜY, ᶠY, p, t)
45
45
:ρ in propertynames (ᶜY) || return ()
46
46
∑tendencies = zero (eltype (ᶜY. ρ))
47
- return (; ρ = ∑tendencies)
47
+ ᶜJ = Fields. local_geometry_field (ᶜY). J
48
+ ᶠJ = Fields. local_geometry_field (ᶠY). J
49
+
50
+ if ! (p. atmos. moisture_model isa DryModel)
51
+ ᶜwₜqₜ = compute_ᶜwₜqₜ (ᶜY, ᶠY, p, t)
52
+ ∑tendencies = lazy .(∑tendencies .- water_adv (ᶜρ, ᶜJ, ᶠJ, ᶜwₜqₜ))
53
+ end
54
+ return (;ρ= ∑tendencies)
48
55
end
49
56
function ᶜremaining_tendency_uₕ (ᶜY, ᶠY, p, t)
50
57
:uₕ in propertynames (ᶜY) || return ()
51
58
∑tendencies = zero (eltype (ᶜY. uₕ))
52
- return (; uₕ = ∑tendencies)
59
+ (; viscous_sponge, rayleigh_sponge) = p. atmos
60
+ ᶜuₕ = ᶜY. uₕ
61
+ ∑tendencies = lazy .(∑tendencies .+ viscous_sponge_tendency_uₕ (ᶜuₕ, viscous_sponge))
62
+ ∑tendencies = lazy .(∑tendencies .+ rayleigh_sponge_tendency_uₕ (ᶜuₕ, rayleigh_sponge))
63
+
64
+ return (;uₕ= ∑tendencies)
53
65
end
54
66
function ᶜremaining_tendency_ρe_tot (ᶜY, ᶠY, p, t)
55
67
:ρe_tot in propertynames (ᶜY) || return ()
56
68
∑tendencies = zero (eltype (ᶜY. ρe_tot))
57
- return (; ρe_tot = ∑tendencies)
69
+
70
+ (; moisture_model, viscous_sponge, precip_model) = p. atmos
71
+ (; energy_upwinding) = p. atmos. numerics
72
+ thermo_params = CAP. thermodynamics_params (p. params)
73
+ thermo_args = (thermo_params, moisture_model, precip_model)
74
+ ᶜz = Fields. coordinate_field (ᶜY). z
75
+ ᶜρ = ᶜY. ρ
76
+ ᶜuₕ = ᶜY. uₕ
77
+ ᶜρe_tot = ᶜY. ρe_tot
78
+ ᶜts = compute_ᶜts (ᶜY, ᶠY, p, t)
79
+ ᶜp = @. lazy (TD. air_pressure (thermo_params, ᶜts))
80
+ ᶜe_tot = @. lazy (ᶜρe_tot / ᶜρ)
81
+ ᶜh_tot = @. lazy (TD. total_specific_enthalpy (thermo_params, ᶜts, ᶜe_tot))
82
+
83
+ if ! (p. atmos. moisture_model isa DryModel)
84
+ ᶜwₕhₜ = compute_ᶜwₕhₜ (ᶜY, ᶠY, p, t)
85
+ ∑tendencies = lazy .(∑tendencies .- water_adv (ᶜρ, ᶜJ, ᶠJ, ᶜwₕhₜ))
86
+ end
87
+ if energy_upwinding != Val (:none )
88
+ (; dt) = p
89
+ ᶠu³ = compute_ᶠu³ (ᶜY, ᶠY)
90
+ vtt = vertical_transport (ᶜρ, ᶠu³, ᶜh_tot, float (dt), energy_upwinding)
91
+ ∑tendencies = lazy .(∑tendencies .+ vtt)
92
+ vtt_central = vertical_transport (ᶜρ, ᶠu³, ᶜh_tot, float (dt), Val (:none ))
93
+ # need to improve NullBroadcast support for this.
94
+ ∑tendencies = lazy .(∑tendencies .+ (- 1 ) .* vtt_central)
95
+ end
96
+
97
+ ∑tendencies = lazy .(∑tendencies .+ viscous_sponge_tendency_ρe_tot (ᶜρ, ᶜh_tot, viscous_sponge))
98
+ return (;ρe_tot= ∑tendencies)
58
99
end
59
100
function ᶜremaining_tendency_ρq_tot (ᶜY, ᶠY, p, t)
60
101
:ρq_tot in propertynames (ᶜY) || return ()
61
102
∑tendencies = zero (eltype (ᶜY. ρq_tot))
62
- return (; ρq_tot = ∑tendencies)
103
+ ᶜJ = Fields. local_geometry_field (ᶜY). J
104
+ ᶠJ = Fields. local_geometry_field (ᶠY). J
105
+ ᶜρ = ᶜY. ρ
106
+ if ! (p. atmos. moisture_model isa DryModel)
107
+ ᶜwₜqₜ = compute_ᶜwₜqₜ (ᶜY, ᶠY, p, t)
108
+ cmc = CAP. microphysics_cloud_params (p. params)
109
+ cmp = CAP. microphysics_1m_params (p. params)
110
+ thp = CAP. thermodynamics_params (p. params)
111
+ ∑tendencies = lazy .(∑tendencies .- water_adv (ᶜρ, ᶜJ, ᶠJ, ᶜwₜqₜ))
112
+ end
113
+ (; tracer_upwinding) = p. atmos. numerics
114
+ if ! (p. atmos. moisture_model isa DryModel) && tracer_upwinding != Val (:none )
115
+ (; dt) = p
116
+ (; ᶜspecific) = p. precomputed
117
+ ᶜq_tot = @. lazy (ᶜY. ρq_tot / ᶜY. ρ)
118
+ ᶠu³ = compute_ᶠu³ (ᶜY, ᶠY)
119
+ vtt = vertical_transport (ᶜρ, ᶠu³, ᶜq_tot, float (dt), tracer_upwinding)
120
+ vtt_central = vertical_transport (ᶜρ, ᶠu³, ᶜq_tot, float (dt), Val (:none ))
121
+ ∑tendencies = lazy .(∑tendencies .+ vtt .- vtt_central)
122
+ end
123
+
124
+ return (;ρq_tot= ∑tendencies)
63
125
end
64
126
function ᶜremaining_tendency_ρq_liq (ᶜY, ᶠY, p, t)
65
127
:ρq_liq in propertynames (ᶜY) || return ()
94
156
function ᶠremaining_tendency_u₃ (ᶜY, ᶠY, p, t)
95
157
:u₃ in propertynames (ᶠY) || return ()
96
158
∑tendencies = zero (eltype (ᶠY. u₃))
97
- return (; u₃ = ∑tendencies)
159
+ (; viscous_sponge) = p. atmos
160
+ ᶜρ = ᶜY. ρ
161
+ ᶜuₕ = ᶜY. uₕ
162
+ ᶠuₕ³ = compute_ᶠuₕ³ (ᶜuₕ, ᶜρ)
163
+ ᶠu₃ = compute_ᶠu₃_with_bcs (ᶠY. u₃, ᶠuₕ³)
164
+ ∑tendencies = lazy .(∑tendencies .+ viscous_sponge_tendency_u₃ (ᶠu₃, viscous_sponge))
165
+ return (;u₃= ∑tendencies)
98
166
end
99
167
function ᶠremaining_tendency_sgsʲs (ᶜY, ᶠY, p, t)
100
168
:sgsʲs in propertynames (ᶠY) || return ()
@@ -103,6 +171,64 @@ function ᶠremaining_tendency_sgsʲs(ᶜY, ᶠY, p, t)
103
171
end
104
172
105
173
174
+ water_adv (ᶜρ, ᶜJ, ᶠJ, ᶜχ) =
175
+ @. lazy (ᶜprecipdivᵥ (ᶠinterp (ᶜρ * ᶜJ) / ᶠJ * ᶠright_bias (- (ᶜχ))))
176
+
177
+ function surface_velocity_full (ᶠu₃, ᶠuₕ³)
178
+ assert_eltype (ᶠuₕ³, Geometry. Contravariant3Vector)
179
+ assert_eltype (ᶠu₃, Geometry. Covariant3Vector)
180
+ ᶠlg = Fields. local_geometry_field (axes (ᶠu₃))
181
+ sfc_u₃ = ᶠu₃ # Fields.level(ᶠu₃.components.data.:1, half)
182
+ sfc_uₕ³ = ᶠuₕ³ # Fields.level(ᶠuₕ³.components.data.:1, half)
183
+ sfc_g³³ = g³³_field (axes (sfc_u₃))
184
+ w₃ = @. lazy (- C3 (sfc_uₕ³ / sfc_g³³, ᶠlg)) # u³ = uₕ³ + w³ = uₕ³ + w₃ * g³³
185
+ assert_eltype (w₃, Geometry. Covariant3Vector)
186
+ return w₃
187
+ end
188
+
189
+ function compute_ᶜts (ᶜY, ᶠY, p, t)
190
+ (; moisture_model, precip_model) = p. atmos
191
+ thermo_params = CAP. thermodynamics_params (p. params)
192
+ thermo_args = (thermo_params, moisture_model, precip_model)
193
+ ᶜz = Fields. coordinate_field (ᶜY). z
194
+ FT = Spaces. undertype (axes (ᶜY))
195
+ grav = FT (CAP. grav (p. params))
196
+ ᶜΦ = @. lazy (grav * ᶜz)
197
+
198
+ ᶜρ = ᶜY. ρ
199
+ ᶜuₕ = ᶜY. uₕ
200
+ ᶠuₕ³ = compute_ᶠuₕ³ (ᶜuₕ, ᶜρ)
201
+ ᶠu₃ = compute_ᶠu₃_with_bcs (ᶠY. u₃, ᶠuₕ³)
202
+ ᶜK = compute_kinetic (ᶜuₕ, ᶠu₃)
203
+ ᶜspecific = @. lazy (specific_gs (ᶜY))
204
+ return @. lazy (ts_gs (thermo_args... , ᶜspecific, ᶜK, ᶜΦ, ᶜρ))
205
+ end
206
+
207
+ assert_eltype (bc:: Base.AbstractBroadcasted , :: Type{T} ) where {T} =
208
+ assert_eltype (eltype (bc), T)
209
+ assert_eltype (f:: Fields.Field , :: Type{T} ) where {T} =
210
+ assert_eltype (Fields. field_values (f), T)
211
+ assert_eltype (data:: DataLayouts.AbstractData , :: Type{T} ) where {T} =
212
+ assert_eltype (eltype (data), T)
213
+ assert_eltype (:: Type{S} , :: Type{T} ) where {S, T} =
214
+ @assert S <: T " Type $S should be a subtype of $T "
215
+
216
+ function compute_ᶠu₃_with_bcs (ᶠu₃, ᶠuₕ³)
217
+ assert_eltype (ᶠu₃, Geometry. Covariant3Vector)
218
+ assert_eltype (ᶠuₕ³, Geometry. Contravariant3Vector)
219
+ ᶠz = Fields. coordinate_field (axes (ᶠu₃)). z
220
+ sfc_u₃ = surface_velocity_full (ᶠu₃, ᶠuₕ³)
221
+ # todo: generalize this with z_min
222
+ return @. lazy (ifelse (iszero (ᶠz), sfc_u₃, ᶠu₃))
223
+ end
224
+ function compute_ᶠu³ (ᶜY, ᶠY)
225
+ ᶜρ = ᶜY. ρ
226
+ ᶜuₕ = ᶜY. uₕ
227
+ ᶠuₕ³ = compute_ᶠuₕ³ (ᶜuₕ, ᶜρ)
228
+ ᶠu₃ = compute_ᶠu₃_with_bcs (ᶠY. u₃, ᶠuₕ³)
229
+ return @. lazy (ᶠuₕ³ + CT3 (ᶠu₃))
230
+ end
231
+
106
232
NVTX. @annotate function remaining_tendency! (Yₜ, Yₜ_lim, Y, p, t)
107
233
Yₜ_lim .= zero (eltype (Yₜ_lim))
108
234
device = ClimaComms. device (axes (Y. c))
@@ -111,7 +237,12 @@ NVTX.@annotate function remaining_tendency!(Yₜ, Yₜ_lim, Y, p, t)
111
237
else
112
238
Val (false ), Val (false )
113
239
end
114
- p_kernel = (;)
240
+ (; moisture_model, viscous_sponge, precip_model) = p. atmos
241
+ p_kernel = (;
242
+ atmos = p. atmos,
243
+ params = p. params,
244
+ dt = p. dt,
245
+ )
115
246
if :sfc in propertynames (Y) # columnwise! does not yet handle .sfc
116
247
parent (Yₜ. sfc) .= zero (Spaces. undertype (axes (Y. c)))
117
248
end
@@ -133,7 +264,6 @@ NVTX.@annotate function remaining_tendency!(Yₜ, Yₜ_lim, Y, p, t)
133
264
horizontal_advection_tendency! (Yₜ, Y, p, t)
134
265
hyperdiffusion_tendency! (Yₜ, Yₜ_lim, Y, p, t)
135
266
explicit_vertical_advection_tendency! (Yₜ, Y, p, t)
136
- vertical_advection_of_water_tendency! (Yₜ, Y, p, t)
137
267
additional_tendency! (Yₜ, Y, p, t)
138
268
return Yₜ
139
269
end
@@ -161,24 +291,13 @@ NVTX.@annotate function additional_tendency!(Yₜ, Y, p, t)
161
291
thermo_params = CAP. thermodynamics_params (params)
162
292
(; ᶜp, sfc_conditions, ᶜts) = p. precomputed
163
293
164
- vst_uₕ = viscous_sponge_tendency_uₕ (ᶜuₕ, viscous_sponge)
165
- vst_u₃ = viscous_sponge_tendency_u₃ (ᶠu₃, viscous_sponge)
166
- vst_ρe_tot = viscous_sponge_tendency_ρe_tot (ᶜρ, ᶜh_tot, viscous_sponge)
167
- rst_uₕ = rayleigh_sponge_tendency_uₕ (ᶜuₕ, rayleigh_sponge)
168
294
hs_args = (ᶜuₕ, ᶜp, params, sfc_conditions. ts, moisture_model, forcing_type)
169
295
hs_tendency_uₕ = held_suarez_forcing_tendency_uₕ (hs_args... )
170
296
hs_tendency_ρe_tot = held_suarez_forcing_tendency_ρe_tot (ᶜρ, hs_args... )
171
297
edmf_cor_tend_uₕ = edmf_coriolis_tendency_uₕ (ᶜuₕ, edmf_coriolis)
172
298
lsa_args = (ᶜρ, thermo_params, ᶜts, t, ls_adv)
173
299
bc_lsa_tend_ρe_tot = large_scale_advection_tendency_ρe_tot (lsa_args... )
174
300
175
- # TODO : fuse, once we fix
176
- # https://github.com/CliMA/ClimaCore.jl/issues/2165
177
- @. Yₜ. c. uₕ += vst_uₕ
178
- @. Yₜ. c. uₕ += rst_uₕ
179
- @. Yₜ. f. u₃. components. data.:1 += vst_u₃
180
- @. Yₜ. c. ρe_tot += vst_ρe_tot
181
-
182
301
# TODO : can we write this out explicitly?
183
302
for (ᶜρχₜ, ᶜχ, χ_name) in matching_subfields (Yₜ. c, ᶜspecific)
184
303
χ_name == :e_tot && continue
0 commit comments