Skip to content

Commit 97fbb29

Browse files
committed
Add SCMSetup, remove Forcing/Advection
1 parent 05d5aa3 commit 97fbb29

File tree

4 files changed

+50
-61
lines changed

4 files changed

+50
-61
lines changed

src/prognostic_equations/remaining_tendency.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ NVTX.@annotate function additional_tendency!(Yₜ, Y, p, t)
141141
ᶜuₕ = Y.c.uₕ
142142
ᶠu₃ = Y.f.u₃
143143
ᶜρ = Y.c.ρ
144-
(; forcing_type, moisture_model, rayleigh_sponge, viscous_sponge) = p.atmos
144+
(; radiation_mode, moisture_model, rayleigh_sponge, viscous_sponge) = p.atmos
145145
(; ls_adv, scm_coriolis) = p.atmos
146146
(; params) = p
147147
thermo_params = CAP.thermodynamics_params(params)
@@ -151,7 +151,9 @@ NVTX.@annotate function additional_tendency!(Yₜ, Y, p, t)
151151
vst_u₃ = viscous_sponge_tendency_u₃(ᶠu₃, viscous_sponge)
152152
vst_ρe_tot = viscous_sponge_tendency_ρe_tot(ᶜρ, ᶜh_tot, viscous_sponge)
153153
rst_uₕ = rayleigh_sponge_tendency_uₕ(ᶜuₕ, rayleigh_sponge)
154-
hs_args = (ᶜuₕ, ᶜp, params, sfc_conditions.ts, moisture_model, forcing_type)
154+
# For HeldSuarezForcing, the radiation_mode is used as the forcing parameter
155+
forcing = radiation_mode isa HeldSuarezForcing ? radiation_mode : nothing
156+
hs_args = (ᶜuₕ, ᶜp, params, sfc_conditions.ts, moisture_model, forcing)
155157
hs_tendency_uₕ = held_suarez_forcing_tendency_uₕ(hs_args...)
156158
hs_tendency_ρe_tot = held_suarez_forcing_tendency_ρe_tot(ᶜρ, hs_args...)
157159
edmf_cor_tend_uₕ = scm_coriolis_tendency_uₕ(ᶜuₕ, scm_coriolis)

src/solver/type_getters.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,23 +94,21 @@ function get_atmos(config::AtmosConfig, params)
9494
Implicit() : Explicit(),
9595
call_cloud_diagnostics_per_stage,
9696

97-
# AtmosForcing
98-
forcing_type,
97+
# SCMSetup - Single-Column Model components
9998
subsidence = get_subsidence_model(parsed_args, radiation_mode, FT),
10099
external_forcing = get_external_forcing_model(parsed_args, FT),
101-
102-
# AtmosAdvection
103100
ls_adv = get_large_scale_advection_model(parsed_args, FT),
104101
advection_test,
102+
scm_coriolis = get_scm_coriolis(parsed_args, FT),
105103

106104
# AtmosRadiation
107105
radiation_mode,
108106
ozone,
109107
co2,
110108
insolation = get_insolation_form(parsed_args),
109+
held_suarez_forcing = forcing_type,
111110

112111
# AtmosTurbconv - Turbulence & Convection
113-
scm_coriolis = get_scm_coriolis(parsed_args, FT),
114112
edmfx_model,
115113
turbconv_model = get_turbconv_model(FT, parsed_args, turbconv_params),
116114
sgs_adv_mode = implicit_sgs_advection ? Implicit() : Explicit(),

src/solver/types.jl

Lines changed: 40 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,22 @@ end
519519

520520
# Grouped structs to reduce AtmosModel type parameters
521521

522+
"""
523+
SCMSetup
524+
525+
Groups Single-Column Model and Large-Eddy Simulation specific forcing, advection, and setup models.
526+
527+
These components are primarily used internally for testing, calibration, and research purposes
528+
with single-column model setups. Most external users will not need these components.
529+
"""
530+
Base.@kwdef struct SCMSetup{S, EF, LA, AT, SC}
531+
subsidence::S = nothing
532+
external_forcing::EF = nothing
533+
ls_adv::LA = nothing
534+
advection_test::AT = nothing
535+
scm_coriolis::SC = nothing
536+
end
537+
522538
"""
523539
AtmosWater
524540
@@ -532,46 +548,25 @@ Base.@kwdef struct AtmosWater{MM, PM, CM, NCFM, CCDPS}
532548
call_cloud_diagnostics_per_stage::CCDPS = nothing
533549
end
534550

535-
"""
536-
AtmosForcing
537-
538-
Groups forcing-related models and types.
539-
"""
540-
Base.@kwdef struct AtmosForcing{F, S, EXTFORCING}
541-
forcing_type::F = nothing
542-
subsidence::S = nothing
543-
external_forcing::EXTFORCING = nothing
544-
end
545-
546551
"""
547552
AtmosRadiation
548553
549554
Groups radiation-related models and types.
550555
"""
551-
Base.@kwdef struct AtmosRadiation{RM, OZ, CO2, IN}
556+
Base.@kwdef struct AtmosRadiation{RM, OZ, CO2, IN, HS}
552557
radiation_mode::RM = nothing
553558
ozone::OZ = nothing
554559
co2::CO2 = nothing
555560
insolation::IN = nothing
556-
end
557-
558-
"""
559-
AtmosAdvection
560-
561-
Groups advection-related models and types.
562-
"""
563-
Base.@kwdef struct AtmosAdvection{LA, AT}
564-
ls_adv::LA = nothing
565-
advection_test::AT = nothing
561+
held_suarez_forcing::HS = nothing
566562
end
567563

568564
"""
569565
AtmosTurbconv
570566
571567
Groups turbulence convection-related models and types.
572568
"""
573-
Base.@kwdef struct AtmosTurbconv{EC, EDMFX, TCM, SAM, SEDM, SNPM, SMM, SL}
574-
scm_coriolis::EC = nothing
569+
Base.@kwdef struct AtmosTurbconv{EDMFX, TCM, SAM, SEDM, SNPM, SMM, SL}
575570
edmfx_model::EDMFX = nothing
576571
turbconv_model::TCM = nothing
577572
sgs_adv_mode::SAM = nothing
@@ -613,20 +608,18 @@ Base.@kwdef struct AtmosSurface{ST, SM, SA}
613608
end
614609

615610
# Add broadcastable for the new grouped types
611+
Base.broadcastable(x::SCMSetup) = tuple(x)
616612
Base.broadcastable(x::AtmosWater) = tuple(x)
617-
Base.broadcastable(x::AtmosForcing) = tuple(x)
618613
Base.broadcastable(x::AtmosRadiation) = tuple(x)
619-
Base.broadcastable(x::AtmosAdvection) = tuple(x)
620614
Base.broadcastable(x::AtmosTurbconv) = tuple(x)
621615
Base.broadcastable(x::AtmosGravityWave) = tuple(x)
622616
Base.broadcastable(x::AtmosSponge) = tuple(x)
623617
Base.broadcastable(x::AtmosSurface) = tuple(x)
624618

625-
struct AtmosModel{H, F, R, A, TC, GW, HD, VD, SP, SU, NU}
619+
struct AtmosModel{H, SCM, R, TC, GW, HD, VD, SP, SU, NU}
626620
hydrology::H
627-
forcing::F
621+
scm_setup::SCM
628622
radiation::R
629-
advection::A
630623
turbconv::TC
631624
gravity_wave::GW
632625
hyperdiff::HD
@@ -642,14 +635,13 @@ end
642635
# Map grouped struct types to their names in AtmosModel struct
643636
const ATMOS_MODEL_GROUPS = (
644637
(AtmosWater, :hydrology),
645-
(AtmosForcing, :forcing),
646638
(AtmosRadiation, :radiation),
647-
(AtmosAdvection, :advection),
648639
(AtmosTurbconv, :turbconv),
649640
(AtmosGravityWave, :gravity_wave),
650641
(AtmosSponge, :sponge),
651642
(AtmosSurface, :surface),
652643
(AtmosNumerics, :numerics),
644+
(SCMSetup, :scm_setup),
653645
)
654646

655647
# Auto-generate map from property_name to group_field
@@ -724,9 +716,8 @@ This constructor provides sensible defaults for a minimal dry atmospheric model
724716
All model components are automatically organized into appropriate grouped sub-structs
725717
internally:
726718
- [`AtmosWater`](@ref)
727-
- [`AtmosForcing`](@ref)
719+
- [`SCMSetup`](@ref)
728720
- [`AtmosRadiation`](@ref)
729-
- [`AtmosAdvection`](@ref)
730721
- [`AtmosTurbconv`](@ref)
731722
- [`AtmosGravityWave`](@ref)
732723
- [`AtmosSponge`](@ref)
@@ -742,7 +733,6 @@ model = AtmosModel() # Creates a basic dry atmospheric model
742733
# Example: Basic dry model with forcing
743734
```julia
744735
model = AtmosModel(;
745-
forcing_type = HeldSuarezForcing(),
746736
hyperdiff = ClimaHyperdiffusion(;
747737
ν₄_vorticity_coeff = 1e15,
748738
ν₄_scalar_coeff = 1e15,
@@ -780,23 +770,22 @@ The default AtmosModel provides:
780770
- `noneq_cloud_formation_mode`: Explicit(), Implicit()
781771
- `call_cloud_diagnostics_per_stage`: nothing or CallCloudDiagnosticsPerStage()
782772
773+
## SCMSetup (Single-Column Model & LES specific - accessed via model.subsidence, model.external_forcing, etc.)
774+
Internal testing and calibration components for single-column setups:
775+
- `subsidence`: nothing or Subsidence() instances (Bomex, Rico, DYCOMS, ISDAC, etc.)
776+
- `external_forcing`: nothing or external forcing objects (GCMForcing, ExternalDrivenTVForcing, ISDACForcing)
777+
- `ls_adv`: nothing or LargeScaleAdvection() instances
778+
- `advection_test`: nothing or boolean
779+
- `scm_coriolis`: nothing or SCMCoriolis() instances
780+
783781
## AtmosRadiation
784782
- `radiation_mode`: RRTMGPI.ClearSkyRadiation(), RRTMGPI.AllSkyRadiation(), etc.
785783
- `ozone`: IdealizedOzone(), PrescribedOzone()
786784
- `co2`: FixedCO2(), MaunaLoaCO2()
787785
- `insolation`: IdealizedInsolation(), TimeVaryingInsolation(), etc.
788-
789-
## AtmosForcing
790-
- `forcing_type`: nothing, HeldSuarezForcing()
791-
- `subsidence`: nothing or Subsidence() instances
792-
- `external_forcing`: nothing or external forcing objects
793-
794-
## AtmosAdvection
795-
- `ls_adv`: nothing or LargeScaleAdvection() instances
796-
- `advection_test`: nothing or boolean
786+
- `held_suarez_forcing`: nothing, HeldSuarezForcing() (atmospheric dynamics forcing)
797787
798788
## AtmosTurbconv
799-
- `scm_coriolis`: nothing or SCMCoriolis() instances
800789
- `edmfx_model`: EDMFXModel() instances
801790
- `turbconv_model`: nothing, PrognosticEDMFX(), DiagnosticEDMFX(), EDOnlyEDMFX()
802791
- `sgs_adv_mode`, `sgs_entr_detr_mode`, `sgs_nh_pressure_mode`, `sgs_mf_mode`: Explicit(), Implicit()
@@ -831,9 +820,11 @@ function AtmosModel(; kwargs...)
831820
group_kwargs, atmos_model_kwargs = _partition_atmos_model_kwargs(kwargs)
832821

833822
moisture = AtmosWater(; group_kwargs[:hydrology]...)
834-
forcing = AtmosForcing(; group_kwargs[:forcing]...)
823+
824+
# Create SCM forcing directly
825+
scm_setup = SCMSetup(; group_kwargs[:scm_setup]...)
826+
835827
radiation = AtmosRadiation(; group_kwargs[:radiation]...)
836-
advection = AtmosAdvection(; group_kwargs[:advection]...)
837828
turbconv = AtmosTurbconv(; group_kwargs[:turbconv]...)
838829
gravity_wave = AtmosGravityWave(; group_kwargs[:gravity_wave]...)
839830
sponge = AtmosSponge(; group_kwargs[:sponge]...)
@@ -847,9 +838,8 @@ function AtmosModel(; kwargs...)
847838

848839
return AtmosModel{
849840
typeof(moisture),
850-
typeof(forcing),
841+
typeof(scm_setup),
851842
typeof(radiation),
852-
typeof(advection),
853843
typeof(turbconv),
854844
typeof(gravity_wave),
855845
typeof(hyperdiff),
@@ -859,9 +849,8 @@ function AtmosModel(; kwargs...)
859849
typeof(numerics),
860850
}(
861851
moisture,
862-
forcing,
852+
scm_setup,
863853
radiation,
864-
advection,
865854
turbconv,
866855
gravity_wave,
867856
hyperdiff,
@@ -966,7 +955,7 @@ Create a dry atmospheric model with sensible defaults for dry simulations.
966955
```julia
967956
model = DryAtmosModel(;
968957
radiation_mode = RRTMGPI.GrayRadiation(false, false),
969-
forcing_type = HeldSuarezForcing(),
958+
held_suarez_forcing = HeldSuarezForcing(),
970959
hyperdiff = ClimaHyperdiffusion(; ν₄_vorticity_coeff = 1e15, ν₄_scalar_coeff = 1e15, divergence_damping_factor = 1.0)
971960
)
972961
```

test/solver/atmos_model_constructor.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ end
4747
:radiation_mode => nothing,
4848
:ozone => nothing,
4949
:co2 => nothing,
50-
:forcing_type => nothing,
50+
:held_suarez_forcing => nothing,
5151
:turbconv_model => nothing,
5252
:non_orographic_gravity_wave => nothing,
5353
:orographic_gravity_wave => nothing,
@@ -78,7 +78,7 @@ end
7878
),
7979
ozone = CA.IdealizedOzone(),
8080
co2 = CA.FixedCO2(),
81-
forcing_type = CA.HeldSuarezForcing(),
81+
held_suarez_forcing = CA.HeldSuarezForcing(),
8282
hyperdiff = CA.ClimaHyperdiffusion(;
8383
ν₄_vorticity_coeff = 1e15,
8484
ν₄_scalar_coeff = 1e15,
@@ -94,7 +94,7 @@ end
9494
@test model.radiation_mode isa RRTMGPI.ClearSkyRadiation
9595
@test model.ozone isa CA.IdealizedOzone
9696
@test model.co2 isa CA.FixedCO2
97-
@test model.forcing_type isa CA.HeldSuarezForcing
97+
@test model.held_suarez_forcing isa CA.HeldSuarezForcing
9898
@test model.hyperdiff isa CA.ClimaHyperdiffusion
9999
@test model.disable_surface_flux_tendency == true
100100

0 commit comments

Comments
 (0)