1- using RRTMGP. Optics: GrayOpticalThicknessSchneider2004
21using RRTMGP. AtmosphericStates: GrayAtmosphericState
32using RRTMGP. RTE: TwoStreamLWRTE, TwoStreamSWRTE
43using RRTMGP. RTESolver: solve_lw!, solve_sw!
@@ -8,7 +7,6 @@ using Oceananigans: field
87using Oceananigans. Architectures: array_type
98using Oceananigans: RectilinearGrid
109
11-
1210"""
1311GrayRadiationModel stores state and solver handles for a gray-band radiative
1412transfer setup.
@@ -18,110 +16,87 @@ Field conventions (array shapes):
1816- sfc_emissivity: (Nbnd, Nx, Ny) — surface emissivity per band
1917- sfc_albedo_direct: (Nbnd, Nx, Ny) — direct-beam surface albedo per band
2018- sfc_albedo_diffuse: (Nbnd, Nx, Ny) — diffuse surface albedo per band
21- - sw_toa_flux_inc: (Nx, Ny) — incoming shortwave flux at TOA
22- - sw_inc_flux_diffuse: (Nx, Ny) or nothing — optional diffuse SW incoming flux
23- - lw_toa_inc_flux: (Nx, Ny) or nothing — optional incoming LW flux at TOA
19+ - toa_sw_flux_inc: (Nx, Ny) — incoming shortwave flux at TOA
2420"""
25- mutable struct GrayRadiationModel{FT, AS, SLVLW, SLVSW, OTP } <: AbstractRadiationModel
21+ struct GrayRadiationModel{FT, AS, SLVLW, SLVSW} <: AbstractRadiationModel
2622 atmospheric_state :: AS
27- slv_lw :: SLVLW
28- slv_sw :: SLVSW
29- optical_properties :: OTP
3023 cos_zenith_angle :: AbstractArray{FT}
3124 sfc_emissivity :: AbstractArray{FT}
3225 sfc_albedo_direct :: AbstractArray{FT}
3326 sfc_albedo_diffuse :: AbstractArray{FT}
34- sw_toa_flux_inc :: AbstractArray{FT}
35- sw_inc_flux_diffuse :: Union{Nothing, AbstractArray{FT}}
36- lw_toa_inc_flux :: Union{Nothing, AbstractArray{FT}}
27+ toa_sw_toa_flux :: AbstractArray{FT}
28+ solver_lw :: SLVLW
29+ solver_sw :: SLVSW
3730end
3831
3932"""
40- GrayRadiationModel(grid; atmospheric_state,
41- zenith_angle, sfc_emissivity, sfc_albedo_direct,
42- sfc_albedo_diffuse, sw_flux_inc_toa;
43- sw_flux_inc_toa_diffusive=nothing,
44- lw_flux_inc_toa=nothing,
45- optical_properties=nothing)
33+ GrayRadiationModel(grid;
34+ temperature,
35+ pressure,
36+ zenith_angle,
37+ sfc_emissivity,
38+ sfc_albedo_direct,
39+ sfc_albedo_diffuse,
40+ toa_sw_flux_inc)
4641
4742Construct a gray-band model using a precomputed atmospheric state.
4843Inputs may be scalars or arrays and are normalized to device arrays.
4944"""
5045function GrayRadiationModel (
5146 grid;
52- temperature,
53- pressure,
47+ temperature :: Field ,
48+ pressure :: Field ,
5449 zenith_angle,
5550 sfc_emissivity,
5651 sfc_albedo_direct,
5752 sfc_albedo_diffuse,
58- sw_flux_inc_toa,
59- sw_flux_inc_toa_diffusive= nothing ,
60- lw_flux_inc_toa= nothing ,
61- optical_properties= GrayOpticalThicknessSchneider2004 (FT),
62- lat_center= 0 ,
53+ toa_sw_flux_inc,
54+ latitude,
55+ isothermal_boundary_layer= false ,
6356)
6457 DA = array_type (grid. architecture)
6558 FT = eltype (grid)
66- Nx, Ny = grid. Nx, grid. Ny
67- Nbnd = 1
6859
6960 # Create atmospheric state from provided Fields (generic library behavior)
7061 atmospheric_state = GrayAtmosphericState (
7162 grid;
72- temperature,
73- pressure,
74- otp= optical_properties,
75- lat_center= lat_center,
63+ temperature= temperature,
64+ pressure= pressure,
65+ latitude= latitude,
7666 )
7767
78- # Helper functions
79- to_grid_array (val) = val isa AbstractArray ? DA (val) : (A = DA {FT} (undef, Nx, Ny); fill! (A, FT (val)))
80- to_banded_array (val) = val isa AbstractArray ? DA (val) : (A = DA {FT} (undef, Nbnd, Nx, Ny); fill! (A, FT (val)))
81- to_optional_grid_array (val) = val === nothing ? nothing : to_grid_array (val)
82-
83- # Bring arrays to the correct shape for RRTMGP.jl interface
84- cos_zenith = if zenith_angle isa AbstractArray
85- DA (cos .(FT (π / 180 ) .* zenith_angle))
86- else
87- A = DA {FT} (undef, Nx, Ny)
88- fill! (A, FT (cos (FT (π / 180 ) * zenith_angle)))
89- end
90- sfc_emission = to_banded_array (sfc_emissivity)
91- sfc_alb_direct = to_banded_array (sfc_albedo_direct)
92- sfc_alb_diffuse = to_banded_array (sfc_albedo_diffuse)
93- toa_flux = to_grid_array (sw_flux_inc_toa)
94- inc_flux_diffuse = to_optional_grid_array (sw_flux_inc_toa_diffusive)
95- lw_toa_inc_flux = to_optional_grid_array (lw_flux_inc_toa)
96-
97- # Build solvers using the high-level wrappers (they reshape internally)
68+ # Build solvers using the high-level wrappers (they reshape internally for RRTMGP.jl compatibility)
9869 SLVLW = TwoStreamLWRTE
9970 SLVSW = TwoStreamSWRTE
10071 lw_params = (
101- sfc_emission = sfc_emission,
102- lw_inc_flux = lw_toa_inc_flux,
72+ sfc_emission = DA (sfc_emissivity),
73+ lw_inc_flux = nothing ,
74+ isothermal_boundary_layer = isothermal_boundary_layer,
10375 )
10476 sw_params = (
105- cos_zenith = cos_zenith,
106- toa_flux = toa_flux,
107- sfc_alb_direct = sfc_alb_direct,
108- inc_flux_diffuse = inc_flux_diffuse,
109- sfc_alb_diffuse = sfc_alb_diffuse,
77+ cos_zenith = DA (cos .(FT (π / 180 ) .* zenith_angle)),
78+ toa_flux = DA (toa_sw_flux_inc),
79+ sfc_alb_direct = DA (sfc_albedo_direct),
80+ inc_flux_diffuse = nothing ,
81+ sfc_alb_diffuse = DA (sfc_albedo_diffuse),
82+ isothermal_boundary_layer = isothermal_boundary_layer,
11083 )
111- slv_lw = SLVLW (grid; lw_params... )
112- slv_sw = SLVSW (grid; sw_params... )
84+ solver_lw = SLVLW (grid; lw_params... )
85+ solver_sw = SLVSW (grid; sw_params... )
11386
11487 return GrayRadiationModel (
11588 atmospheric_state,
116- slv_lw,
117- slv_sw,
118- optical_properties,
119- cos_zenith,
120- sfc_emission,
121- sfc_alb_direct,
122- sfc_alb_diffuse,
123- toa_flux,
124- inc_flux_diffuse,
125- lw_toa_inc_flux,
89+ sw_params. cos_zenith,
90+ lw_params. sfc_emission,
91+ sw_params. sfc_alb_direct,
92+ sw_params. sfc_alb_diffuse,
93+ sw_params. toa_flux,
94+ solver_lw,
95+ solver_sw,
12696 )
12797end
98+
99+ function update_radative_fluxes! (model:: GrayRadiationModel )
100+ solve_lw! (model. solver_lw, model. atmospheric_state)
101+ solve_sw! (model. solver_sw, model. atmospheric_state)
102+ end
0 commit comments