519
519
520
520
# Grouped structs to reduce AtmosModel type parameters
521
521
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
+
522
538
"""
523
539
AtmosWater
524
540
@@ -532,46 +548,25 @@ Base.@kwdef struct AtmosWater{MM, PM, CM, NCFM, CCDPS}
532
548
call_cloud_diagnostics_per_stage:: CCDPS = nothing
533
549
end
534
550
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
-
546
551
"""
547
552
AtmosRadiation
548
553
549
554
Groups radiation-related models and types.
550
555
"""
551
- Base. @kwdef struct AtmosRadiation{RM, OZ, CO2, IN}
556
+ Base. @kwdef struct AtmosRadiation{RM, OZ, CO2, IN, HS }
552
557
radiation_mode:: RM = nothing
553
558
ozone:: OZ = nothing
554
559
co2:: CO2 = nothing
555
560
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
566
562
end
567
563
568
564
"""
569
565
AtmosTurbconv
570
566
571
567
Groups turbulence convection-related models and types.
572
568
"""
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}
575
570
edmfx_model:: EDMFX = nothing
576
571
turbconv_model:: TCM = nothing
577
572
sgs_adv_mode:: SAM = nothing
@@ -613,20 +608,18 @@ Base.@kwdef struct AtmosSurface{ST, SM, SA}
613
608
end
614
609
615
610
# Add broadcastable for the new grouped types
611
+ Base. broadcastable (x:: SCMSetup ) = tuple (x)
616
612
Base. broadcastable (x:: AtmosWater ) = tuple (x)
617
- Base. broadcastable (x:: AtmosForcing ) = tuple (x)
618
613
Base. broadcastable (x:: AtmosRadiation ) = tuple (x)
619
- Base. broadcastable (x:: AtmosAdvection ) = tuple (x)
620
614
Base. broadcastable (x:: AtmosTurbconv ) = tuple (x)
621
615
Base. broadcastable (x:: AtmosGravityWave ) = tuple (x)
622
616
Base. broadcastable (x:: AtmosSponge ) = tuple (x)
623
617
Base. broadcastable (x:: AtmosSurface ) = tuple (x)
624
618
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}
626
620
hydrology:: H
627
- forcing :: F
621
+ scm_setup :: SCM
628
622
radiation:: R
629
- advection:: A
630
623
turbconv:: TC
631
624
gravity_wave:: GW
632
625
hyperdiff:: HD
@@ -642,14 +635,13 @@ end
642
635
# Map grouped struct types to their names in AtmosModel struct
643
636
const ATMOS_MODEL_GROUPS = (
644
637
(AtmosWater, :hydrology ),
645
- (AtmosForcing, :forcing ),
646
638
(AtmosRadiation, :radiation ),
647
- (AtmosAdvection, :advection ),
648
639
(AtmosTurbconv, :turbconv ),
649
640
(AtmosGravityWave, :gravity_wave ),
650
641
(AtmosSponge, :sponge ),
651
642
(AtmosSurface, :surface ),
652
643
(AtmosNumerics, :numerics ),
644
+ (SCMSetup, :scm_setup ),
653
645
)
654
646
655
647
# Auto-generate map from property_name to group_field
@@ -724,9 +716,8 @@ This constructor provides sensible defaults for a minimal dry atmospheric model
724
716
All model components are automatically organized into appropriate grouped sub-structs
725
717
internally:
726
718
- [`AtmosWater`](@ref)
727
- - [`AtmosForcing `](@ref)
719
+ - [`SCMSetup `](@ref)
728
720
- [`AtmosRadiation`](@ref)
729
- - [`AtmosAdvection`](@ref)
730
721
- [`AtmosTurbconv`](@ref)
731
722
- [`AtmosGravityWave`](@ref)
732
723
- [`AtmosSponge`](@ref)
@@ -742,7 +733,6 @@ model = AtmosModel() # Creates a basic dry atmospheric model
742
733
# Example: Basic dry model with forcing
743
734
```julia
744
735
model = AtmosModel(;
745
- forcing_type = HeldSuarezForcing(),
746
736
hyperdiff = ClimaHyperdiffusion(;
747
737
ν₄_vorticity_coeff = 1e15,
748
738
ν₄_scalar_coeff = 1e15,
@@ -780,23 +770,22 @@ The default AtmosModel provides:
780
770
- `noneq_cloud_formation_mode`: Explicit(), Implicit()
781
771
- `call_cloud_diagnostics_per_stage`: nothing or CallCloudDiagnosticsPerStage()
782
772
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
+
783
781
## AtmosRadiation
784
782
- `radiation_mode`: RRTMGPI.ClearSkyRadiation(), RRTMGPI.AllSkyRadiation(), etc.
785
783
- `ozone`: IdealizedOzone(), PrescribedOzone()
786
784
- `co2`: FixedCO2(), MaunaLoaCO2()
787
785
- `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)
797
787
798
788
## AtmosTurbconv
799
- - `scm_coriolis`: nothing or SCMCoriolis() instances
800
789
- `edmfx_model`: EDMFXModel() instances
801
790
- `turbconv_model`: nothing, PrognosticEDMFX(), DiagnosticEDMFX(), EDOnlyEDMFX()
802
791
- `sgs_adv_mode`, `sgs_entr_detr_mode`, `sgs_nh_pressure_mode`, `sgs_mf_mode`: Explicit(), Implicit()
@@ -831,9 +820,11 @@ function AtmosModel(; kwargs...)
831
820
group_kwargs, atmos_model_kwargs = _partition_atmos_model_kwargs (kwargs)
832
821
833
822
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
+
835
827
radiation = AtmosRadiation (; group_kwargs[:radiation ]. .. )
836
- advection = AtmosAdvection (; group_kwargs[:advection ]. .. )
837
828
turbconv = AtmosTurbconv (; group_kwargs[:turbconv ]. .. )
838
829
gravity_wave = AtmosGravityWave (; group_kwargs[:gravity_wave ]. .. )
839
830
sponge = AtmosSponge (; group_kwargs[:sponge ]. .. )
@@ -847,9 +838,8 @@ function AtmosModel(; kwargs...)
847
838
848
839
return AtmosModel{
849
840
typeof (moisture),
850
- typeof (forcing ),
841
+ typeof (scm_setup ),
851
842
typeof (radiation),
852
- typeof (advection),
853
843
typeof (turbconv),
854
844
typeof (gravity_wave),
855
845
typeof (hyperdiff),
@@ -859,9 +849,8 @@ function AtmosModel(; kwargs...)
859
849
typeof (numerics),
860
850
}(
861
851
moisture,
862
- forcing ,
852
+ scm_setup ,
863
853
radiation,
864
- advection,
865
854
turbconv,
866
855
gravity_wave,
867
856
hyperdiff,
@@ -966,7 +955,7 @@ Create a dry atmospheric model with sensible defaults for dry simulations.
966
955
```julia
967
956
model = DryAtmosModel(;
968
957
radiation_mode = RRTMGPI.GrayRadiation(false, false),
969
- forcing_type = HeldSuarezForcing(),
958
+ held_suarez_forcing = HeldSuarezForcing(),
970
959
hyperdiff = ClimaHyperdiffusion(; ν₄_vorticity_coeff = 1e15, ν₄_scalar_coeff = 1e15, divergence_damping_factor = 1.0)
971
960
)
972
961
```
0 commit comments