@@ -44,22 +44,84 @@ using ClimaCore.RecursiveApply: rzero
4444function ᶜremaining_tendency_ρ (ᶜY, ᶠY, p, t)
4545 :ρ in propertynames (ᶜY) || return ()
4646 ∑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)
4855end
4956function ᶜremaining_tendency_uₕ (ᶜY, ᶠY, p, t)
5057 :uₕ in propertynames (ᶜY) || return ()
5158 ∑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)
5365end
5466function ᶜremaining_tendency_ρe_tot (ᶜY, ᶠY, p, t)
5567 :ρe_tot in propertynames (ᶜY) || return ()
5668 ∑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)
5899end
59100function ᶜremaining_tendency_ρq_tot (ᶜY, ᶠY, p, t)
60101 :ρq_tot in propertynames (ᶜY) || return ()
61102 ∑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)
63125end
64126function ᶜremaining_tendency_ρq_liq (ᶜY, ᶠY, p, t)
65127 :ρq_liq in propertynames (ᶜY) || return ()
94156function ᶠremaining_tendency_u₃ (ᶜY, ᶠY, p, t)
95157 :u₃ in propertynames (ᶠY) || return ()
96158 ∑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)
98166end
99167function ᶠremaining_tendency_sgsʲs (ᶜY, ᶠY, p, t)
100168 :sgsʲs in propertynames (ᶠY) || return ()
@@ -103,6 +171,64 @@ function ᶠremaining_tendency_sgsʲs(ᶜY, ᶠY, p, t)
103171end
104172
105173
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+
106232NVTX. @annotate function remaining_tendency! (Yₜ, Yₜ_lim, Y, p, t)
107233 Yₜ_lim .= zero (eltype (Yₜ_lim))
108234 device = ClimaComms. device (axes (Y. c))
@@ -111,7 +237,12 @@ NVTX.@annotate function remaining_tendency!(Yₜ, Yₜ_lim, Y, p, t)
111237 else
112238 Val (false ), Val (false )
113239 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+ )
115246 if :sfc in propertynames (Y) # columnwise! does not yet handle .sfc
116247 parent (Yₜ. sfc) .= zero (Spaces. undertype (axes (Y. c)))
117248 end
@@ -133,7 +264,6 @@ NVTX.@annotate function remaining_tendency!(Yₜ, Yₜ_lim, Y, p, t)
133264 horizontal_advection_tendency! (Yₜ, Y, p, t)
134265 hyperdiffusion_tendency! (Yₜ, Yₜ_lim, Y, p, t)
135266 explicit_vertical_advection_tendency! (Yₜ, Y, p, t)
136- vertical_advection_of_water_tendency! (Yₜ, Y, p, t)
137267 additional_tendency! (Yₜ, Y, p, t)
138268 return Yₜ
139269end
@@ -161,24 +291,13 @@ NVTX.@annotate function additional_tendency!(Yₜ, Y, p, t)
161291 thermo_params = CAP. thermodynamics_params (params)
162292 (; ᶜp, sfc_conditions, ᶜts) = p. precomputed
163293
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)
168294 hs_args = (ᶜuₕ, ᶜp, params, sfc_conditions. ts, moisture_model, forcing_type)
169295 hs_tendency_uₕ = held_suarez_forcing_tendency_uₕ (hs_args... )
170296 hs_tendency_ρe_tot = held_suarez_forcing_tendency_ρe_tot (ᶜρ, hs_args... )
171297 edmf_cor_tend_uₕ = edmf_coriolis_tendency_uₕ (ᶜuₕ, edmf_coriolis)
172298 lsa_args = (ᶜρ, thermo_params, ᶜts, t, ls_adv)
173299 bc_lsa_tend_ρe_tot = large_scale_advection_tendency_ρe_tot (lsa_args... )
174300
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-
182301 # TODO : can we write this out explicitly?
183302 for (ᶜρχₜ, ᶜχ, χ_name) in matching_subfields (Yₜ. c, ᶜspecific)
184303 χ_name == :e_tot && continue
0 commit comments