@@ -514,85 +514,193 @@ Base.@kwdef struct EDMFXModel{
514
514
scale_blending_method:: SBM
515
515
end
516
516
517
- Base. @kwdef struct AtmosModel{
518
- MM,
519
- PM,
520
- CM,
521
- NCFM,
522
- CCDPS,
523
- F,
524
- S,
525
- OZ,
526
- CO2,
527
- RM,
528
- LA,
529
- EXTFORCING,
530
- EC,
531
- AT,
532
- EDMFX,
533
- TCM,
534
- NOGW,
535
- OGW,
536
- HD,
537
- VD,
538
- DM,
539
- SAM,
540
- SEDM,
541
- SNPM,
542
- SMM,
543
- VS,
544
- SL,
545
- RS,
546
- ST,
547
- IN,
548
- SM,
549
- SA,
550
- NUM,
551
- }
517
+ # Grouped structures to reduce AtmosModel type parameters
518
+
519
+ """
520
+ AtmosMoistureModel
521
+
522
+ Groups moisture-related models and parameters.
523
+ """
524
+ Base. @kwdef struct AtmosMoistureModel{MM, PM, CM, NCFM, CCDPS}
552
525
moisture_model:: MM = nothing
553
526
precip_model:: PM = nothing
554
527
cloud_model:: CM = nothing
555
528
noneq_cloud_formation_mode:: NCFM = nothing
556
529
call_cloud_diagnostics_per_stage:: CCDPS = nothing
530
+ end
531
+
532
+ """
533
+ AtmosForcing
534
+
535
+ Groups forcing-related models and parameters.
536
+ """
537
+ Base. @kwdef struct AtmosForcing{F, S, EXTFORCING}
557
538
forcing_type:: F = nothing
558
539
subsidence:: S = nothing
540
+ external_forcing:: EXTFORCING = nothing
541
+ end
542
+
543
+ """
544
+ AtmosRadiation
559
545
560
- # Currently only relevant for RRTMGP, but will hopefully become standalone
561
- # in the future
562
- """ What to do with ozone for radiation (when using RRTMGP)"""
546
+ Groups radiation-related models and parameters.
547
+ """
548
+ Base. @kwdef struct AtmosRadiation{RM, OZ, CO2, IN}
549
+ radiation_mode:: RM = nothing
563
550
ozone:: OZ = nothing
564
- """ What to do with co2 for radiation (when using RRTMGP)"""
565
551
co2:: CO2 = nothing
552
+ insolation:: IN = nothing
553
+ end
566
554
567
- radiation_mode:: RM = nothing
555
+ """
556
+ AtmosAdvection
557
+
558
+ Groups advection-related models and parameters.
559
+ """
560
+ Base. @kwdef struct AtmosAdvection{LA, AT}
568
561
ls_adv:: LA = nothing
569
- external_forcing:: EXTFORCING = nothing
570
- scm_coriolis:: EC = nothing
571
562
advection_test:: AT = nothing
563
+ end
564
+
565
+ """
566
+ AtmosTurbconv
567
+
568
+ Groups turbulence convection-related models and parameters.
569
+ """
570
+ Base. @kwdef struct AtmosTurbconv{EC, EDMFX, TCM, SAM, SEDM, SNPM, SMM, SL}
571
+ scm_coriolis:: EC = nothing
572
572
edmfx_model:: EDMFX = nothing
573
573
turbconv_model:: TCM = nothing
574
- non_orographic_gravity_wave:: NOGW = nothing
575
- orographic_gravity_wave:: OGW = nothing
576
- hyperdiff:: HD = nothing
577
- vert_diff:: VD = nothing
578
- diff_mode:: DM = nothing
579
574
sgs_adv_mode:: SAM = nothing
580
- """ sgs_entr_detr_mode == Implicit() only works if sgs_adv_mode == Implicit()"""
581
575
sgs_entr_detr_mode:: SEDM = nothing
582
- """ sgs_nh_pressure_mode == Implicit() only works if sgs_adv_mode == Implicit()"""
583
576
sgs_nh_pressure_mode:: SNPM = nothing
584
- """ sgs_mf_mode == Implicit() only works if sgs_adv_mode == Implicit() and diff_mode == Implicit()"""
585
577
sgs_mf_mode:: SMM = nothing
586
- viscous_sponge:: VS = nothing
587
578
smagorinsky_lilly:: SL = nothing
579
+ end
580
+
581
+ """
582
+ AtmosGravityWave
583
+
584
+ Groups gravity wave-related models and parameters.
585
+ """
586
+ Base. @kwdef struct AtmosGravityWave{NOGW, OGW}
587
+ non_orographic_gravity_wave:: NOGW = nothing
588
+ orographic_gravity_wave:: OGW = nothing
589
+ end
590
+
591
+ """
592
+ AtmosVertDiff
593
+
594
+ Groups vertical diffusion-related models and parameters.
595
+ """
596
+ Base. @kwdef struct AtmosVertDiff{VD, DM}
597
+ vert_diff:: VD = nothing
598
+ diff_mode:: DM = nothing
599
+ end
600
+
601
+ """
602
+ AtmosSponge
603
+
604
+ Groups sponge-related models and parameters.
605
+ """
606
+ Base. @kwdef struct AtmosSponge{VS, RS}
607
+ viscous_sponge:: VS = nothing
588
608
rayleigh_sponge:: RS = nothing
609
+ end
610
+
611
+ """
612
+ AtmosSurface
613
+
614
+ Groups surface-related models and parameters.
615
+ """
616
+ Base. @kwdef struct AtmosSurface{ST, SM, SA}
589
617
sfc_temperature:: ST = nothing
590
- insolation:: IN = nothing
591
- """ Whether to apply surface flux tendency (independent of surface conditions)"""
592
- disable_surface_flux_tendency:: Bool = false
593
618
surface_model:: SM = nothing
594
619
surface_albedo:: SA = nothing
620
+ end
621
+
622
+ # Add broadcastable for the new grouped types
623
+ Base. broadcastable (x:: AtmosMoistureModel ) = tuple (x)
624
+ Base. broadcastable (x:: AtmosForcing ) = tuple (x)
625
+ Base. broadcastable (x:: AtmosRadiation ) = tuple (x)
626
+ Base. broadcastable (x:: AtmosAdvection ) = tuple (x)
627
+ Base. broadcastable (x:: AtmosTurbconv ) = tuple (x)
628
+ Base. broadcastable (x:: AtmosGravityWave ) = tuple (x)
629
+ Base. broadcastable (x:: AtmosVertDiff ) = tuple (x)
630
+ Base. broadcastable (x:: AtmosSponge ) = tuple (x)
631
+ Base. broadcastable (x:: AtmosSurface ) = tuple (x)
632
+
633
+ Base. @kwdef struct AtmosModel{
634
+ MOISTURE,
635
+ FORCING,
636
+ RADIATION,
637
+ ADVECTION,
638
+ TURBCONV,
639
+ GRAVITY_WAVE,
640
+ HD,
641
+ VERT_DIFF,
642
+ SPONGE,
643
+ SURFACE,
644
+ NUM,
645
+ }
646
+ moisture:: MOISTURE = AtmosMoistureModel ()
647
+ forcing:: FORCING = AtmosForcing ()
648
+ radiation:: RADIATION = AtmosRadiation ()
649
+ advection:: ADVECTION = AtmosAdvection ()
650
+ turbconv:: TURBCONV = AtmosTurbconv ()
651
+ gravity_wave:: GRAVITY_WAVE = AtmosGravityWave ()
652
+ hyperdiff:: HD = nothing
653
+ vert_diff:: VERT_DIFF = AtmosVertDiff ()
654
+ sponge:: SPONGE = AtmosSponge ()
655
+ surface:: SURFACE = AtmosSurface ()
595
656
numerics:: NUM = nothing
657
+
658
+ """ Whether to apply surface flux tendency (independent of surface conditions)"""
659
+ disable_surface_flux_tendency:: Bool = false
660
+ end
661
+
662
+ # ============================================================================
663
+ # BACKWARD COMPATIBILITY FOR AtmosModel PROPERTY ACCESS
664
+ # ============================================================================
665
+ # We reduced AtmosModel type parameters from ~33 to ~11 by grouping related fields.
666
+ # Old: atmos.moisture_model → New: atmos.moisture.moisture_model
667
+ #
668
+ # This automatically forwards old property access to the new grouped structure,
669
+ # so existing code continues to work without changes.
670
+
671
+ # Map grouped struct types to their AtmosModel field names
672
+ const ATMOS_MODEL_GROUPS = (
673
+ (AtmosMoistureModel, :moisture ),
674
+ (AtmosForcing, :forcing ),
675
+ (AtmosRadiation, :radiation ),
676
+ (AtmosAdvection, :advection ),
677
+ (AtmosTurbconv, :turbconv ),
678
+ (AtmosGravityWave, :gravity_wave ),
679
+ (AtmosVertDiff, :vert_diff ),
680
+ (AtmosSponge, :sponge ),
681
+ (AtmosSurface, :surface ),
682
+ )
683
+
684
+ # Auto-generate lookup: property_name => group_field
685
+ const GROUPED_PROPERTY_MAP = let
686
+ property_map = Dict {Symbol, Symbol} ()
687
+ for (group_type, group_field) in ATMOS_MODEL_GROUPS
688
+ for property in fieldnames (group_type)
689
+ property_map[property] = group_field
690
+ end
691
+ end
692
+ property_map
693
+ end
694
+
695
+ # Forward property access: atmos.moisture_model → atmos.moisture.moisture_model
696
+ function Base. getproperty (atmos:: AtmosModel , property_name:: Symbol )
697
+ if haskey (GROUPED_PROPERTY_MAP, property_name)
698
+ group_field = GROUPED_PROPERTY_MAP[property_name]
699
+ group = getfield (atmos, group_field)
700
+ return getfield (group, property_name)
701
+ else
702
+ return getfield (atmos, property_name)
703
+ end
596
704
end
597
705
598
706
Base. broadcastable (x:: AtmosModel ) = tuple (x)
0 commit comments