Skip to content

Commit 5f0c9c1

Browse files
Use columnwise for setting tendencies to zero
1 parent 1f3398d commit 5f0c9c1

File tree

2 files changed

+184
-1
lines changed

2 files changed

+184
-1
lines changed

src/prognostic_equations/remaining_tendency.jl

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,103 @@ NVTX.@annotate function hyperdiffusion_tendency!(Yₜ, Yₜ_lim, Y, p, t)
3737
apply_hyperdiffusion_tendency!(Yₜ, Y, p, t)
3838
end
3939

40+
using ClimaCore.RecursiveApply: rzero
41+
42+
#####
43+
##### Cell center tendencies
44+
#####
45+
function ᶜremaining_tendency(ᶜY, ᶠY, p, t)
46+
names = propertynames(ᶜY)
47+
tends = construct_tendencies(Val(names), ᶜremaining_tendency, ᶜY, ᶠY, p, t)
48+
# We cannot broadcast over a NamedTuple, so we need to check that edge case
49+
# first.
50+
if all(t -> !(t isa Base.Broadcast.Broadcasted), tends)
51+
return make_named_tuple(Val(names), tends...)
52+
else
53+
return lazy.(make_named_tuple.(Val(names), tends...))
54+
end
55+
end
56+
57+
#####
58+
##### Cell face tendencies
59+
#####
60+
function ᶠremaining_tendency(ᶜY, ᶠY, p, t)
61+
names = propertynames(ᶠY)
62+
tends = construct_tendencies(Val(names), ᶠremaining_tendency, ᶜY, ᶠY, p, t)
63+
# We cannot broadcast over a NamedTuple, so we need to check that edge case
64+
# first.
65+
if all(t -> !(t isa Base.Broadcast.Broadcasted), tends)
66+
return make_named_tuple(Val(names), tends...)
67+
else
68+
return lazy.(make_named_tuple.(Val(names), tends...))
69+
end
70+
end
71+
72+
#####
73+
##### Individual tendencies
74+
#####
75+
76+
function ᶜremaining_tendency(::Val{:ρ}, ᶜY, ᶠY, p, t)
77+
in propertynames(ᶜY) || return ()
78+
∑tendencies = zero(eltype(ᶜY.ρ))
79+
return ∑tendencies
80+
end
81+
function ᶜremaining_tendency(::Val{:uₕ}, ᶜY, ᶠY, p, t)
82+
:uₕ in propertynames(ᶜY) || return ()
83+
∑tendencies = zero(eltype(ᶜY.uₕ))
84+
return ∑tendencies
85+
end
86+
function ᶜremaining_tendency(::Val{:ρe_tot}, ᶜY, ᶠY, p, t)
87+
:ρe_tot in propertynames(ᶜY) || return ()
88+
∑tendencies = zero(eltype(ᶜY.ρe_tot))
89+
return ∑tendencies
90+
end
91+
function ᶜremaining_tendency(::Val{:ρq_tot}, ᶜY, ᶠY, p, t)
92+
:ρq_tot in propertynames(ᶜY) || return ()
93+
∑tendencies = zero(eltype(ᶜY.ρq_tot))
94+
return ∑tendencies
95+
end
96+
function ᶜremaining_tendency(::Val{:ρq_liq}, ᶜY, ᶠY, p, t)
97+
:ρq_liq in propertynames(ᶜY) || return ()
98+
∑tendencies = zero(eltype(ᶜY.ρq_liq))
99+
return ∑tendencies
100+
end
101+
function ᶜremaining_tendency(::Val{:ρq_ice}, ᶜY, ᶠY, p, t)
102+
:ρq_ice in propertynames(ᶜY) || return ()
103+
∑tendencies = zero(eltype(ᶜY.ρq_ice))
104+
return ∑tendencies
105+
end
106+
function ᶜremaining_tendency(::Val{:ρq_rai}, ᶜY, ᶠY, p, t)
107+
:ρq_rai in propertynames(ᶜY) || return ()
108+
∑tendencies = zero(eltype(ᶜY.ρq_rai))
109+
return ∑tendencies
110+
end
111+
function ᶜremaining_tendency(::Val{:ρq_sno}, ᶜY, ᶠY, p, t)
112+
:ρq_sno in propertynames(ᶜY) || return ()
113+
∑tendencies = zero(eltype(ᶜY.ρq_sno))
114+
return ∑tendencies
115+
end
116+
function ᶜremaining_tendency(::Val{:sgsʲs}, ᶜY, ᶠY, p, t)
117+
:sgsʲs in propertynames(ᶜY) || return ()
118+
∑tendencies = rzero(eltype(ᶜY.sgsʲs))
119+
return ∑tendencies
120+
end
121+
function ᶜremaining_tendency(::Val{:sgs⁰}, ᶜY, ᶠY, p, t)
122+
:sgs⁰ in propertynames(ᶜY) || return ()
123+
∑tendencies = rzero(eltype(ᶜY.sgs⁰))
124+
return ∑tendencies
125+
end
126+
function ᶠremaining_tendency(::Val{:u₃}, ᶜY, ᶠY, p, t)
127+
:u₃ in propertynames(ᶠY) || return ()
128+
∑tendencies = zero(eltype(ᶠY.u₃))
129+
return ∑tendencies
130+
end
131+
function ᶠremaining_tendency(::Val{:sgsʲs}, ᶜY, ᶠY, p, t)
132+
:sgsʲs in propertynames(ᶠY) || return ()
133+
∑tendencies = rzero(eltype(ᶠY.sgsʲs))
134+
return ∑tendencies
135+
end
136+
40137
"""
41138
remaining_tendency!(Yₜ, Yₜ_lim, Y, p, t)
42139
@@ -64,7 +161,27 @@ Returns:
64161
"""
65162
NVTX.@annotate function remaining_tendency!(Yₜ, Yₜ_lim, Y, p, t)
66163
Yₜ_lim .= zero(eltype(Yₜ_lim))
67-
Yₜ .= zero(eltype(Yₜ))
164+
device = ClimaComms.device(axes(Y.c))
165+
p_kernel = (;
166+
zmax = Spaces.z_max(axes(Y.f)),
167+
atmos = p.atmos,
168+
params = p.params,
169+
dt = p.dt,
170+
)
171+
if :sfc in propertynames(Y) # columnwise! does not yet handle .sfc
172+
parent(Yₜ.sfc) .= zero(Spaces.undertype(axes(Y.c)))
173+
end
174+
Operators.columnwise!(
175+
device,
176+
ᶜremaining_tendency,
177+
ᶠremaining_tendency,
178+
Yₜ.c,
179+
Yₜ.f,
180+
Y.c,
181+
Y.f,
182+
p_kernel,
183+
t,
184+
)
68185
horizontal_tracer_advection_tendency!(Yₜ_lim, Y, p, t)
69186
fill_with_nans!(p) # TODO: would be better to limit this to debug mode (e.g., if p.debug_mode...)
70187
horizontal_dynamics_tendency!(Yₜ, Y, p, t)

src/utils/utilities.jl

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,3 +496,69 @@ function issphere(space)
496496
return Meshes.domain(Spaces.topology(Spaces.horizontal_space(space))) isa
497497
Domains.SphereDomain
498498
end
499+
500+
501+
"""
502+
construct_tendencies(::Val{names}, f, ᶜY, ᶠY, p, t)
503+
504+
Return a tuple of calls to
505+
506+
```
507+
f(Val(name), ᶜY, ᶠY, p, t)
508+
```
509+
for all names in `names`.
510+
511+
For example, `f(Val((:a, :b)), ᶜY, ᶠY, p, t)` will return:
512+
513+
```
514+
(
515+
f(Val(:a), ᶜY, ᶠY, p, t),
516+
f(Val(:b), ᶜY, ᶠY, p, t),
517+
)
518+
```
519+
"""
520+
@generated function construct_tendencies(
521+
::Val{names},
522+
f,
523+
ᶜY,
524+
ᶠY,
525+
p,
526+
t,
527+
) where {names}
528+
calls = []
529+
for name in names
530+
push!(calls, :(f(Val($(QuoteNode(name))), ᶜY, ᶠY, p, t)))
531+
end
532+
return quote
533+
($(calls...),)
534+
end
535+
end
536+
537+
"""
538+
make_named_tuple(::Val{names}, vals...) where {names}
539+
540+
Construct a NamedTuple given the names `names` and values `vals`.
541+
"""
542+
make_named_tuple(::Val{names}, vals...) where {names} = NamedTuple{names}(vals)
543+
544+
"""
545+
add_tend(∑tendencies, tendency)
546+
547+
A helper function which returns `∑tendencies` when `tendency` is a
548+
`NullBroadcasted` and `lazy.(∑tendencies + tendency)` when `tendency` is not a
549+
`NullBroadcasted`.
550+
"""
551+
function add_tend end
552+
add_tend(∑tends, t) = lazy.(∑tends .+ t)
553+
add_tend(∑tends, ::NullBroadcasted) = ∑tends
554+
555+
"""
556+
sub_tend(∑tendencies, tendency)
557+
558+
A helper function which returns `∑tendencies` when `tendency` is a
559+
`NullBroadcasted` and `lazy.(∑tendencies - tendency)` when `tendency` is not a
560+
`NullBroadcasted`.
561+
"""
562+
function sub_tend end
563+
sub_tend(∑tends, ::NullBroadcasted) = ∑tends
564+
sub_tend(∑tends, t) = lazy.(∑tends .- t)

0 commit comments

Comments
 (0)