diff --git a/.buildkite/Manifest-v1.11.toml b/.buildkite/Manifest-v1.11.toml index d88a3bd902..2998c7df4c 100644 --- a/.buildkite/Manifest-v1.11.toml +++ b/.buildkite/Manifest-v1.11.toml @@ -381,7 +381,9 @@ weakdeps = ["CUDA", "MPI"] [[deps.ClimaCore]] deps = ["Adapt", "BandedMatrices", "BlockArrays", "ClimaComms", "CubedSphere", "DataStructures", "ForwardDiff", "GaussQuadrature", "GilbertCurves", "HDF5", "InteractiveUtils", "IntervalSets", "KrylovKit", "LazyBroadcast", "LinearAlgebra", "MultiBroadcastFusion", "NVTX", "PkgVersion", "RecursiveArrayTools", "RootSolvers", "SparseArrays", "StaticArrays", "Statistics", "UnrolledUtilities"] -git-tree-sha1 = "c6ab151ea66f3756566abc039c76ae767e490446" +git-tree-sha1 = "4085d9d00635b3780533539e12d2e2af5ffc6cb2" +repo-rev = "ck/fixes" +repo-url = "https://github.com/CliMA/ClimaCore.jl.git" uuid = "d414da3d-4745-48bb-8d80-42e94e092884" version = "0.14.34" weakdeps = ["CUDA", "Krylov"] diff --git a/.buildkite/ci_driver.jl b/.buildkite/ci_driver.jl index 3207bcd3a0..23d4db12b9 100644 --- a/.buildkite/ci_driver.jl +++ b/.buildkite/ci_driver.jl @@ -11,6 +11,8 @@ redirect_stderr(IOContext(stderr, :stacktrace_types_limited => Ref(false))) # and run `using PrecompileTools; PrecompileTools.verbose[] = true; include(".buildkite/PrecompileCI/src/PrecompileCI.jl")` using PrecompileCI import ClimaComms +import ClimaCore +ClimaCore.Fields.error_mismatched_spaces(::Type, ::Type) = nothing # causes unsupported dynamic function invocation ClimaComms.@import_required_backends import ClimaAtmos as CA import Random diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 997026e384..7ac2d86542 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -328,6 +328,8 @@ steps: artifact_paths: "baroclinic_wave_equil/output_active/*" agents: slurm_constraint: icelake|cascadelake|skylake|epyc + # slurm_mem: 20GB # columnwise! insufficient mem + slurm_mem: 60GB # columnwise! - label: ":computer: held suarez" key: held_suarez @@ -904,7 +906,7 @@ steps: CLIMACOMMS_DEVICE: "CUDA" agents: slurm_gpus: 1 - slurm_mem: 16GB + slurm_mem: 60GB - label: "GPU: compare BW with CPU" command: > diff --git a/src/cache/precipitation_precomputed_quantities.jl b/src/cache/precipitation_precomputed_quantities.jl index ca172846d6..09eb38e219 100644 --- a/src/cache/precipitation_precomputed_quantities.jl +++ b/src/cache/precipitation_precomputed_quantities.jl @@ -29,6 +29,76 @@ function Kin(ᶜw_precip, ᶜu_air) ) end +function compute_precip_velocities(ᶜY, ᶠY, p, t) + cmc = CAP.microphysics_cloud_params(p.params) + cmp = CAP.microphysics_1m_params(p.params) + + # compute the precipitation terminal velocity [m/s] + ᶜwᵣ = @. lazy(CM1.terminal_velocity( + cmp.pr, + cmp.tv.rain, + ᶜY.ρ, + max(zero(ᶜY.ρ), ᶜY.ρq_rai / ᶜY.ρ), + )) + ᶜwₛ = @. lazy(CM1.terminal_velocity( + cmp.ps, + cmp.tv.snow, + ᶜY.ρ, + max(zero(ᶜY.ρ), ᶜY.ρq_sno / ᶜY.ρ), + )) + # compute sedimentation velocity for cloud condensate [m/s] + ᶜwₗ = @. lazy(CMNe.terminal_velocity( + cmc.liquid, + cmc.Ch2022.rain, + ᶜY.ρ, + max(zero(ᶜY.ρ), ᶜY.ρq_liq / ᶜY.ρ), + )) + ᶜwᵢ = @. lazy(CMNe.terminal_velocity( + cmc.ice, + cmc.Ch2022.small_ice, + ᶜY.ρ, + max(zero(ᶜY.ρ), ᶜY.ρq_ice / ᶜY.ρ), + )) + return (ᶜwᵣ, ᶜwₛ, ᶜwₗ, ᶜwᵢ) +end + + +compute_ᶜwₜqₜ(ᶜY, ᶠY, p, t) = + compute_ᶜwₜqₜ(ᶜY, ᶠY, p, t, p.atmos.moisture_model, p.atmos.precip_model) +compute_ᶜwₜqₜ(ᶜY, ᶠY, p, t, moisture_model, precip_model) = zero(eltype(ᶜY.ρ)) + +function compute_ᶜwₜqₜ(ᶜY, ᶠY, p, t, + ::NonEquilMoistModel, + ::Microphysics1Moment, +) + (ᶜwᵣ, ᶜwₛ, ᶜwₗ, ᶜwᵢ) = compute_precip_velocities(ᶜY, ᶠY, p, t) + # compute their contributions to energy and total water advection + return @. lazy(Geometry.WVector( + ᶜwₗ * ᶜY.ρq_liq + + ᶜwᵢ * ᶜY.ρq_ice + + ᶜwᵣ * ᶜY.ρq_rai + + ᶜwₛ * ᶜY.ρq_sno, + ) / ᶜY.ρ) +end + +compute_ᶜwₕhₜ(ᶜY, ᶠY, p, t) = + compute_ᶜwₕhₜ(ᶜY, ᶠY, p, t, p.atmos.moisture_model, p.atmos.precip_model) + +compute_ᶜwₕhₜ(ᶜY, ᶠY, p, t, moisture_model, precip_model) = zero(eltype(ᶜY.ρ)) + +function compute_ᶜwₕhₜ(ᶜY, ᶠY, p, t, ::NonEquilMoistModel, ::Microphysics1Moment) + thp = CAP.thermodynamics_params(p.params) + ᶜts = compute_ᶜts(ᶜY, ᶠY, p, t) + (ᶜwᵣ, ᶜwₛ, ᶜwₗ, ᶜwᵢ) = compute_precip_velocities(ᶜY, ᶠY, p, t) + # compute their contributions to energy and total water advection + return @. lazy(Geometry.WVector( + ᶜwₗ * ᶜY.ρq_liq * (Iₗ(thp, ᶜts) + ᶜΦ + $(Kin(ᶜwₗ, ᶜY.ᶜu))) + + ᶜwᵢ * ᶜY.ρq_ice * (Iᵢ(thp, ᶜts) + ᶜΦ + $(Kin(ᶜwᵢ, ᶜY.ᶜu))) + + ᶜwᵣ * ᶜY.ρq_rai * (Iₗ(thp, ᶜts) + ᶜΦ + $(Kin(ᶜwᵣ, ᶜY.ᶜu))) + + ᶜwₛ * ᶜY.ρq_sno * (Iᵢ(thp, ᶜts) + ᶜΦ + $(Kin(ᶜwₛ, ᶜY.ᶜu))), + ) / ᶜY.ρ) +end + """ set_precipitation_velocities!(Y, p, moisture_model, precip_model) diff --git a/src/parameterized_tendencies/sponge/rayleigh_sponge.jl b/src/parameterized_tendencies/sponge/rayleigh_sponge.jl index ae69849958..defdd71325 100644 --- a/src/parameterized_tendencies/sponge/rayleigh_sponge.jl +++ b/src/parameterized_tendencies/sponge/rayleigh_sponge.jl @@ -14,7 +14,13 @@ import ClimaCore.Fields as Fields function rayleigh_sponge_tendency_uₕ(ᶜuₕ, s) s isa Nothing && return NullBroadcasted() - (; ᶜz, ᶠz) = z_coordinate_fields(axes(ᶜuₕ)) + ᶜz = Fields.coordinate_field(Spaces.center_space(axes(ᶜuₕ))).z + ᶠz = Fields.coordinate_field(Spaces.face_space(axes(ᶜuₕ))).z zmax = z_max(axes(ᶠz)) + return rayleigh_sponge_tendency_uₕ(ᶜuₕ, s, ᶜz, ᶠz, zmax) +end + +function rayleigh_sponge_tendency_uₕ(ᶜuₕ, s, ᶜz, ᶠz, zmax) + s isa Nothing && return NullBroadcasted() return @. lazy(-β_rayleigh_uₕ(s, ᶜz, zmax) * ᶜuₕ) end diff --git a/src/prognostic_equations/advection.jl b/src/prognostic_equations/advection.jl index 304a048869..09d85c15a8 100644 --- a/src/prognostic_equations/advection.jl +++ b/src/prognostic_equations/advection.jl @@ -139,19 +139,6 @@ NVTX.@annotate function explicit_vertical_advection_tendency!(Yₜ, Y, p, t) end # ... and upwinding correction of energy and total water. # (The central advection of energy and total water is done implicitly.) - if energy_upwinding != Val(:none) - (; ᶜh_tot) = p.precomputed - vtt = vertical_transport(ᶜρ, ᶠu³, ᶜh_tot, float(dt), energy_upwinding) - vtt_central = vertical_transport(ᶜρ, ᶠu³, ᶜh_tot, float(dt), Val(:none)) - @. Yₜ.c.ρe_tot += vtt - vtt_central - end - - if !(p.atmos.moisture_model isa DryModel) && tracer_upwinding != Val(:none) - ᶜq_tot = ᶜspecific.q_tot - vtt = vertical_transport(ᶜρ, ᶠu³, ᶜq_tot, float(dt), tracer_upwinding) - vtt_central = vertical_transport(ᶜρ, ᶠu³, ᶜq_tot, float(dt), Val(:none)) - @. Yₜ.c.ρq_tot += vtt - vtt_central - end if isnothing(ᶠf¹²) # shallow atmosphere diff --git a/src/prognostic_equations/remaining_tendency.jl b/src/prognostic_equations/remaining_tendency.jl index a8929739a3..c0fab53a90 100644 --- a/src/prognostic_equations/remaining_tendency.jl +++ b/src/prognostic_equations/remaining_tendency.jl @@ -10,15 +10,280 @@ NVTX.@annotate function hyperdiffusion_tendency!(Yₜ, Yₜ_lim, Y, p, t) apply_hyperdiffusion_tendency!(Yₜ, Y, p, t) end +@generated function sorted_nt(::Val{snames}, ::Val{unames}, vals...) where {snames,unames} + svals_exprs = [] + for sn in snames + i = findfirst(un -> un == sn, unames)::Int + push!(svals_exprs, :(getfield(vals, $i))) + end + return quote + NamedTuple{snames}(($(svals_exprs...),)) + end +end + +prognostic_nt(::Val{names}, ::Val{K}, vals...) where {names, K} = + sorted_nt(Val(names), Val(K), vals...) + +@generated function construct_tends(::Val{names}, f, ᶜY, ᶠY, p, t) where {names} + calls = [] + for name in names + push!(calls, :(f(Val($(QuoteNode(name))), ᶜY, ᶠY, p, t))) + end + return quote + ($(calls...),) + end +end + +function ᶜremaining_tendency(ᶜY, ᶠY, p, t) + names = propertynames(ᶜY) + tends = construct_tends(Val(names), ᶜremaining_tendency, ᶜY, ᶠY, p, t) + return lazy.(foo.(Val(names), tends...)) +end +foo(::Val{names}, tends...) where {names} = NamedTuple{names}(tends) + +function ᶠremaining_tendency(ᶜY, ᶠY, p, t) + names = propertynames(ᶠY) + tends = construct_tends(Val(names), ᶠremaining_tendency, ᶜY, ᶠY, p, t) + return lazy.(foo.(Val(names), tends...)) +end +using ClimaCore.RecursiveApply: rzero +function ᶜremaining_tendency(::Val{:ρ}, ᶜY, ᶠY, p, t) + :ρ in propertynames(ᶜY) || return () + ∑tendencies = zero(eltype(ᶜY.ρ)) + ᶜJ = Fields.local_geometry_field(ᶜY).J + ᶠJ = Fields.local_geometry_field(ᶠY).J + ᶜρ = ᶜY.ρ + + if !(p.atmos.moisture_model isa DryModel) + ᶜwₜqₜ = compute_ᶜwₜqₜ(ᶜY, ᶠY, p, t) + ∑tendencies = sub_tend(∑tendencies, water_adv(ᶜρ, ᶜJ, ᶠJ, ᶜwₜqₜ)) + end + return ∑tendencies +end + +add_tend(∑tends, t) = lazy.(∑tends .+ t) +add_tend(∑tends, ::NullBroadcasted) = ∑tends +sub_tend(∑tends, ::NullBroadcasted) = ∑tends +sub_tend(∑tends, t) = lazy.(∑tends .- t) + +function ᶜremaining_tendency(::Val{:uₕ}, ᶜY, ᶠY, p, t) + :uₕ in propertynames(ᶜY) || return () + ∑tendencies = zero(eltype(ᶜY.uₕ)) + (; zmax) = p + (; viscous_sponge, rayleigh_sponge) = p.atmos + ᶜz = Fields.coordinate_field(ᶜY).z + ᶠz = Fields.coordinate_field(ᶠY).z + ᶜuₕ = ᶜY.uₕ + ∑tendencies = add_tend(∑tendencies, viscous_sponge_tendency_uₕ(ᶜuₕ, viscous_sponge)) + ∑tendencies = add_tend(∑tendencies, rayleigh_sponge_tendency_uₕ(ᶜuₕ, rayleigh_sponge, ᶜz, ᶠz, zmax)) + + return ∑tendencies +end +function ᶜremaining_tendency(::Val{:ρe_tot}, ᶜY, ᶠY, p, t) + :ρe_tot in propertynames(ᶜY) || return () + ∑tendencies = zero(eltype(ᶜY.ρe_tot)) + + (; moisture_model, viscous_sponge, precip_model) = p.atmos + (; energy_upwinding) = p.atmos.numerics + thermo_params = CAP.thermodynamics_params(p.params) + thermo_args = (thermo_params, moisture_model, precip_model) + ᶜz = Fields.coordinate_field(ᶜY).z + ᶜJ = Fields.local_geometry_field(ᶜY).J + ᶠJ = Fields.local_geometry_field(ᶠY).J + ᶜρ = ᶜY.ρ + ᶜuₕ = ᶜY.uₕ + ᶜρe_tot = ᶜY.ρe_tot + ᶜts = compute_ᶜts(ᶜY, ᶠY, p, t) + ᶜp = @. lazy(TD.air_pressure(thermo_params, ᶜts)) + ᶜe_tot = @. lazy(ᶜρe_tot / ᶜρ) + ᶜh_tot = @. lazy(TD.total_specific_enthalpy(thermo_params, ᶜts, ᶜe_tot)) + + if !(p.atmos.moisture_model isa DryModel) + ᶜwₕhₜ = compute_ᶜwₕhₜ(ᶜY, ᶠY, p, t) + ∑tendencies = sub_tend(∑tendencies, water_adv(ᶜρ, ᶜJ, ᶠJ, ᶜwₕhₜ)) + end + if energy_upwinding != Val(:none) + (; dt) = p + ᶠu³ = compute_ᶠu³(ᶜY, ᶠY) + vtt = vertical_transport(ᶜρ, ᶠu³, ᶜh_tot, float(dt), energy_upwinding) + ∑tendencies = add_tend(∑tendencies, vtt) + vtt_central = vertical_transport(ᶜρ, ᶠu³, ᶜh_tot, float(dt), Val(:none)) + # need to improve NullBroadcast support for this. + ∑tendencies = sub_tend(∑tendencies, vtt_central) + end + + ∑tendencies = add_tend(∑tendencies, viscous_sponge_tendency_ρe_tot(ᶜρ, ᶜh_tot, viscous_sponge)) + return ∑tendencies +end +function ᶜremaining_tendency(::Val{:ρq_tot}, ᶜY, ᶠY, p, t) + :ρq_tot in propertynames(ᶜY) || return () + ∑tendencies = zero(eltype(ᶜY.ρq_tot)) + ᶜJ = Fields.local_geometry_field(ᶜY).J + ᶠJ = Fields.local_geometry_field(ᶠY).J + ᶜρ = ᶜY.ρ + if !(p.atmos.moisture_model isa DryModel) + ᶜwₜqₜ = compute_ᶜwₜqₜ(ᶜY, ᶠY, p, t) + cmc = CAP.microphysics_cloud_params(p.params) + cmp = CAP.microphysics_1m_params(p.params) + thp = CAP.thermodynamics_params(p.params) + ∑tendencies = sub_tend(∑tendencies, water_adv(ᶜρ, ᶜJ, ᶠJ, ᶜwₜqₜ)) + end + (; tracer_upwinding) = p.atmos.numerics + if !(p.atmos.moisture_model isa DryModel) && tracer_upwinding != Val(:none) + (; dt) = p + ᶜq_tot = @. lazy(ᶜY.ρq_tot / ᶜY.ρ) + ᶠu³ = compute_ᶠu³(ᶜY, ᶠY) + vtt = vertical_transport(ᶜρ, ᶠu³, ᶜq_tot, float(dt), tracer_upwinding) + vtt_central = vertical_transport(ᶜρ, ᶠu³, ᶜq_tot, float(dt), Val(:none)) + ∑tendencies = add_tend(∑tendencies, vtt) + ∑tendencies = sub_tend(∑tendencies, vtt_central) + end + + return ∑tendencies +end +function ᶜremaining_tendency(::Val{:ρq_liq}, ᶜY, ᶠY, p, t) + :ρq_liq in propertynames(ᶜY) || return () + ∑tendencies = zero(eltype(ᶜY.ρq_liq)) + return ∑tendencies +end +function ᶜremaining_tendency(::Val{:ρq_ice}, ᶜY, ᶠY, p, t) + :ρq_ice in propertynames(ᶜY) || return () + ∑tendencies = zero(eltype(ᶜY.ρq_ice)) + return ∑tendencies +end +function ᶜremaining_tendency(::Val{:ρq_rai}, ᶜY, ᶠY, p, t) + :ρq_rai in propertynames(ᶜY) || return () + ∑tendencies = zero(eltype(ᶜY.ρq_rai)) + return ∑tendencies +end +function ᶜremaining_tendency(::Val{:ρq_sno}, ᶜY, ᶠY, p, t) + :ρq_sno in propertynames(ᶜY) || return () + ∑tendencies = zero(eltype(ᶜY.ρq_sno)) + return ∑tendencies +end +function ᶜremaining_tendency(::Val{:sgsʲs}, ᶜY, ᶠY, p, t) + :sgsʲs in propertynames(ᶜY) || return () + ∑tendencies = rzero(eltype(ᶜY.sgsʲs)) + return ∑tendencies +end +function ᶜremaining_tendency(::Val{:sgs⁰}, ᶜY, ᶠY, p, t) + :sgs⁰ in propertynames(ᶜY) || return () + ∑tendencies = rzero(eltype(ᶜY.sgs⁰)) + return ∑tendencies +end +function ᶠremaining_tendency(::Val{:u₃}, ᶜY, ᶠY, p, t) + :u₃ in propertynames(ᶠY) || return () + ∑tendencies = zero(eltype(ᶠY.u₃)) + (; viscous_sponge) = p.atmos + ᶜρ = ᶜY.ρ + ᶜuₕ = ᶜY.uₕ + ᶠuₕ³ = compute_ᶠuₕ³(ᶜuₕ, ᶜρ) + ᶠu₃ = compute_ᶠu₃_with_bcs(ᶠY.u₃, ᶠuₕ³) + ∑tendencies = add_tend(∑tendencies, viscous_sponge_tendency_u₃(ᶠu₃, viscous_sponge)) + return ∑tendencies +end +function ᶠremaining_tendency(::Val{:sgsʲs}, ᶜY, ᶠY, p, t) + :sgsʲs in propertynames(ᶠY) || return () + ∑tendencies = rzero(eltype(ᶠY.sgsʲs)) + return ∑tendencies +end + + +water_adv(ᶜρ, ᶜJ, ᶠJ, ᶜχ::Real) = zero(eltype(ᶜρ)) +water_adv(ᶜρ, ᶜJ, ᶠJ, ᶜχ) = # only valid when ᶜχ is a field + @. lazy(ᶜprecipdivᵥ(ᶠinterp(ᶜρ * ᶜJ) / ᶠJ * ᶠright_bias(-(ᶜχ)))) + +function surface_velocity_full(ᶠu₃, ᶠuₕ³) + assert_eltype(ᶠuₕ³, Geometry.Contravariant3Vector) + assert_eltype(ᶠu₃, Geometry.Covariant3Vector) + ᶠlg = Fields.local_geometry_field(axes(ᶠu₃)) + sfc_u₃ = ᶠu₃ # Fields.level(ᶠu₃.components.data.:1, half) + sfc_uₕ³ = ᶠuₕ³ # Fields.level(ᶠuₕ³.components.data.:1, half) + sfc_g³³ = g³³_field(axes(sfc_u₃)) + w₃ = @. lazy(- C3(sfc_uₕ³ / sfc_g³³, ᶠlg)) # u³ = uₕ³ + w³ = uₕ³ + w₃ * g³³ + assert_eltype(w₃, Geometry.Covariant3Vector) + return w₃ +end + +function compute_ᶜts(ᶜY, ᶠY, p, t) + (; moisture_model, precip_model) = p.atmos + thermo_params = CAP.thermodynamics_params(p.params) + thermo_args = (thermo_params, moisture_model, precip_model) + ᶜz = Fields.coordinate_field(ᶜY).z + FT = Spaces.undertype(axes(ᶜY)) + grav = FT(CAP.grav(p.params)) + ᶜΦ = @. lazy(grav * ᶜz) + + ᶜρ = ᶜY.ρ + ᶜuₕ = ᶜY.uₕ + ᶠuₕ³ = compute_ᶠuₕ³(ᶜuₕ, ᶜρ) + ᶠu₃ = compute_ᶠu₃_with_bcs(ᶠY.u₃, ᶠuₕ³) + ᶜK = compute_kinetic(ᶜuₕ, ᶠu₃) + ᶜspecific = @. lazy(specific_gs(ᶜY)) + return @. lazy(ts_gs(thermo_args..., ᶜspecific, ᶜK, ᶜΦ, ᶜρ)) +end + +assert_eltype(bc::Base.AbstractBroadcasted, ::Type{T}) where {T} = + assert_eltype(eltype(bc), T) +assert_eltype(f::Fields.Field, ::Type{T}) where {T} = + assert_eltype(Fields.field_values(f), T) +assert_eltype(data::DataLayouts.AbstractData, ::Type{T}) where {T} = + assert_eltype(eltype(data), T) +assert_eltype(::Type{S}, ::Type{T}) where {S, T} = + @assert S <: T "Type $S should be a subtype of $T" + +function compute_ᶠu₃_with_bcs(ᶠu₃, ᶠuₕ³) + assert_eltype(ᶠu₃, Geometry.Covariant3Vector) + assert_eltype(ᶠuₕ³, Geometry.Contravariant3Vector) + ᶠz = Fields.coordinate_field(axes(ᶠu₃)).z + sfc_u₃ = surface_velocity_full(ᶠu₃, ᶠuₕ³) + # todo: generalize this with z_min + return @. lazy(ifelse(iszero(ᶠz), sfc_u₃, ᶠu₃)) +end +function compute_ᶠu³(ᶜY, ᶠY) + ᶜρ = ᶜY.ρ + ᶜuₕ = ᶜY.uₕ + ᶠuₕ³ = compute_ᶠuₕ³(ᶜuₕ, ᶜρ) + ᶠu₃ = compute_ᶠu₃_with_bcs(ᶠY.u₃, ᶠuₕ³) + return @. lazy(ᶠuₕ³ + CT3(ᶠu₃)) +end + NVTX.@annotate function remaining_tendency!(Yₜ, Yₜ_lim, Y, p, t) Yₜ_lim .= zero(eltype(Yₜ_lim)) - Yₜ .= zero(eltype(Yₜ)) + device = ClimaComms.device(axes(Y.c)) + (localmem_lg, localmem_state) = if device isa ClimaComms.CUDADevice + Val(false), Val(true) + else + Val(false), Val(false) + end + (; moisture_model, viscous_sponge, precip_model) = p.atmos + p_kernel = (; + zmax = Spaces.z_max(axes(Y.f)), + atmos = p.atmos, + params = p.params, + dt = p.dt, + ) + if :sfc in propertynames(Y) # columnwise! does not yet handle .sfc + parent(Yₜ.sfc) .= zero(Spaces.undertype(axes(Y.c))) + end + Operators.columnwise!( + device, + ᶜremaining_tendency, + ᶠremaining_tendency, + Yₜ.c, + Yₜ.f, + Y.c, + Y.f, + p_kernel, + t, + localmem_lg, + localmem_state, + ) horizontal_tracer_advection_tendency!(Yₜ_lim, Y, p, t) fill_with_nans!(p) horizontal_advection_tendency!(Yₜ, Y, p, t) hyperdiffusion_tendency!(Yₜ, Yₜ_lim, Y, p, t) explicit_vertical_advection_tendency!(Yₜ, Y, p, t) - vertical_advection_of_water_tendency!(Yₜ, Y, p, t) additional_tendency!(Yₜ, Y, p, t) return Yₜ end @@ -46,10 +311,6 @@ NVTX.@annotate function additional_tendency!(Yₜ, Y, p, t) thermo_params = CAP.thermodynamics_params(params) (; ᶜp, sfc_conditions, ᶜts) = p.precomputed - vst_uₕ = viscous_sponge_tendency_uₕ(ᶜuₕ, viscous_sponge) - vst_u₃ = viscous_sponge_tendency_u₃(ᶠu₃, viscous_sponge) - vst_ρe_tot = viscous_sponge_tendency_ρe_tot(ᶜρ, ᶜh_tot, viscous_sponge) - rst_uₕ = rayleigh_sponge_tendency_uₕ(ᶜuₕ, rayleigh_sponge) hs_args = (ᶜuₕ, ᶜp, params, sfc_conditions.ts, moisture_model, forcing_type) hs_tendency_uₕ = held_suarez_forcing_tendency_uₕ(hs_args...) hs_tendency_ρe_tot = held_suarez_forcing_tendency_ρe_tot(ᶜρ, hs_args...) @@ -57,13 +318,6 @@ NVTX.@annotate function additional_tendency!(Yₜ, Y, p, t) lsa_args = (ᶜρ, thermo_params, ᶜts, t, ls_adv) bc_lsa_tend_ρe_tot = large_scale_advection_tendency_ρe_tot(lsa_args...) - # TODO: fuse, once we fix - # https://github.com/CliMA/ClimaCore.jl/issues/2165 - @. Yₜ.c.uₕ += vst_uₕ - @. Yₜ.c.uₕ += rst_uₕ - @. Yₜ.f.u₃.components.data.:1 += vst_u₃ - @. Yₜ.c.ρe_tot += vst_ρe_tot - # TODO: can we write this out explicitly? for (ᶜρχₜ, ᶜχ, χ_name) in matching_subfields(Yₜ.c, ᶜspecific) χ_name == :e_tot && continue diff --git a/src/prognostic_equations/water_advection.jl b/src/prognostic_equations/water_advection.jl index 1ce7f6504b..735dd1f6ce 100644 --- a/src/prognostic_equations/water_advection.jl +++ b/src/prognostic_equations/water_advection.jl @@ -1,18 +1,2 @@ import ClimaCore: Fields -function vertical_advection_of_water_tendency!(Yₜ, Y, p, t) - - ᶜJ = Fields.local_geometry_field(Y.c).J - ᶠJ = Fields.local_geometry_field(Y.f).J - (; ᶜwₜqₜ, ᶜwₕhₜ) = p.precomputed - - if !(p.atmos.moisture_model isa DryModel) - @. Yₜ.c.ρ -= - ᶜprecipdivᵥ(ᶠinterp(Y.c.ρ * ᶜJ) / ᶠJ * ᶠright_bias(-(ᶜwₜqₜ))) - @. Yₜ.c.ρe_tot -= - ᶜprecipdivᵥ(ᶠinterp(Y.c.ρ * ᶜJ) / ᶠJ * ᶠright_bias(-(ᶜwₕhₜ))) - @. Yₜ.c.ρq_tot -= - ᶜprecipdivᵥ(ᶠinterp(Y.c.ρ * ᶜJ) / ᶠJ * ᶠright_bias(-(ᶜwₜqₜ))) - end - return nothing -end