Skip to content

Commit 554c13c

Browse files
committed
wip: interface shaping up for gray radiation model
1 parent d5e2c86 commit 554c13c

File tree

7 files changed

+272
-217
lines changed

7 files changed

+272
-217
lines changed

src/Radiation/gray_breezy.jl

Lines changed: 0 additions & 87 deletions
This file was deleted.

src/Radiation/radiation_model.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
abstract type AbstractRadiationModel end
22

3-
function update_radative_fluxes!(model::AbstractRadiationModel)
4-
throw("Not implemented for $(typeof(model)).")
3+
"""
4+
update_radative_fluxes!(model)
5+
6+
Update radiative fluxes for the given `GrayRadiationModel` by running the
7+
longwave and shortwave two-stream solvers with the current atmospheric state
8+
and boundary conditions.
9+
"""
10+
function update_radative_fluxes!(model::AbstractRadiationModel)
11+
solve_lw!(model.slv_lw, model.atmospheric_state)
12+
solve_sw!(model.slv_sw, model.atmospheric_state)
513
end

src/Radiation/radiation_model_gray.jl

Lines changed: 86 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -7,116 +7,121 @@ using Oceananigans
77
using Oceananigans: field
88
using Oceananigans.Architectures: array_type
99
using Oceananigans: RectilinearGrid
10+
1011

11-
mutable struct GrayRadiationModel{FT, DA, SLVLW, SLVSW, AS, OTP} <: AbstractRadiationModel
12+
"""
13+
GrayRadiationModel stores state and solver handles for a gray-band radiative
14+
transfer setup.
15+
16+
Field conventions (array shapes):
17+
- cos_zenith_angle: (Nx, Ny) — cos of zenith angle on the horizontal grid
18+
- sfc_emissivity: (Nbnd, Nx, Ny) — surface emissivity per band
19+
- sfc_albedo_direct: (Nbnd, Nx, Ny) — direct-beam surface albedo per band
20+
- 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
24+
"""
25+
mutable struct GrayRadiationModel{FT, AS, SLVLW, SLVSW, OTP} <: AbstractRadiationModel
1226
atmospheric_state :: AS
1327
slv_lw :: SLVLW
1428
slv_sw :: SLVSW
1529
optical_properties :: OTP
16-
cos_zenith_angle :: DA{FT}
17-
sfc_emissivity :: DA{FT}
18-
sfc_albedo_direct :: DA{FT}
19-
sfc_albedo_diffuse :: DA{FT}
20-
sw_toa_flux_inc :: DA{FT}
21-
sw_inc_flux_diffuse :: Union{Nothing, DA{FT}}
22-
lw_toa_inc_flux :: Union{Nothing, DA{FT}}
30+
cos_zenith_angle :: AbstractArray{FT}
31+
sfc_emissivity :: AbstractArray{FT}
32+
sfc_albedo_direct :: AbstractArray{FT}
33+
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}}
2337
end
2438

39+
"""
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)
46+
47+
Construct a gray-band model using a precomputed atmospheric state.
48+
Inputs may be scalars or arrays and are normalized to device arrays.
49+
"""
2550
function GrayRadiationModel(
26-
grid;
27-
temperature,
51+
grid;
52+
temperature,
2853
pressure,
29-
cos_zenith_angle,
54+
zenith_angle,
3055
sfc_emissivity,
3156
sfc_albedo_direct,
3257
sfc_albedo_diffuse,
3358
sw_flux_inc_toa,
34-
sw_flux_inc_toa_diffusive,
35-
lw_flux_inc_toa,
59+
sw_flux_inc_toa_diffusive=nothing,
60+
lw_flux_inc_toa=nothing,
3661
optical_properties=GrayOpticalThicknessSchneider2004(FT),
37-
lat_center=0
38-
)
39-
# We assemble objects required for RRTMGP to work.
62+
lat_center=0,
63+
)
64+
DA = array_type(grid.architecture)
65+
FT = eltype(grid)
66+
Nx, Ny = grid.Nx, grid.Ny
67+
Nbnd = 1
68+
69+
# Create atmospheric state from provided Fields (generic library behavior)
4070
atmospheric_state = GrayAtmosphericState(
41-
grid;
42-
temperature,
43-
pressure,
44-
otp=optical_properties,
45-
lat_center=lat_center
71+
grid;
72+
temperature,
73+
pressure,
74+
otp=optical_properties,
75+
lat_center=lat_center,
4676
)
77+
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)
4798
SLVLW = TwoStreamLWRTE
4899
SLVSW = TwoStreamSWRTE
49100
lw_params = (
50-
sfc_emission = sfc_emissivity,
51-
lw_inc_flux = lw_flux_inc_toa,
101+
sfc_emission = sfc_emission,
102+
lw_inc_flux = lw_toa_inc_flux,
52103
)
53104
sw_params = (
54-
cos_zenith = cos_zenith_angle,
55-
toa_flux = sw_flux_inc_toa,
56-
sfc_alb_direct = sfc_albedo_diffuse,
57-
inc_flux_diffuse = sw_flux_inc_toa_diffusive,
58-
sfc_alb_diffuse = sfc_albedo_diffuse,
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,
59110
)
60111
slv_lw = SLVLW(grid; lw_params...)
61112
slv_sw = SLVSW(grid; sw_params...)
62-
63-
if sfc_emissivity isa DA
64-
65-
elseif sfc_emissivity isa AbstractFloat
66-
67-
end
68113

69114
return GrayRadiationModel(
70115
atmospheric_state,
71-
slv_lw,
116+
slv_lw,
72117
slv_sw,
73118
optical_properties,
74-
cos_zenith_angle,
119+
cos_zenith,
75120
sfc_emission,
76-
sfc_albedo_direct,
77-
sfc_albedo_diffuse,
78-
sw_flux_inc_toa,
79-
sw_flux_inc_toa_diffusive,
80-
lw_flux_inc_toa,
121+
sfc_alb_direct,
122+
sfc_alb_diffuse,
123+
toa_flux,
124+
inc_flux_diffuse,
125+
lw_toa_inc_flux,
81126
)
82127
end
83-
84-
function GrayRadiationModel(
85-
grid;
86-
temperature :: Field,
87-
pressure :: Field,
88-
zenith_angle :: FT,
89-
sfc_emissivity :: FT,
90-
sfc_albedo_direct :: FT,
91-
sfc_albedo_diffuse :: FT,
92-
sw_flux_inc_toa :: FT,
93-
sw_flux_inc_toa_diffusive :: Union{Nothing, FT},
94-
lw_flux_inc_toa :: Union{Nothing, FT},
95-
optical_properties=GrayOpticalThicknessSchneider2004(FT),
96-
lat_center=0
97-
)
98-
FT = eltype(grid)
99-
DA = device_array(grid.architecture)
100-
Nx, Ny, Nz = grid.Nx, grid.Ny, grid.Nz
101-
Nbnd = 1
102-
103-
104-
sfc_emission = DA{FT}(undef, Nbnd, Nx, Ny)
105-
sfc_alb_direct = DA{FT}(undef, Nbnd, Nx, Ny)
106-
sfc_alb_diffuse = DA{FT}(undef, Nbnd, Nx, Ny)
107-
cos_zenith = DA{FT}(undef, Nx, Ny)
108-
toa_flux = DA{FT}(undef, Nx, Ny)
109-
lw_toa_inc_flux = nothing
110-
inc_flux_diffuse = nothing
111-
fill!(sfc_emission, FT(sfc_emissivity))
112-
fill!(sfc_alb_direct, FT(albedo_direct))
113-
fill!(sfc_alb_diffuse, FT(albedo_diffuse))
114-
fill!(cos_zenith, FT(cos(deg2rad * zenith_angle)))
115-
fill!(toa_flux, FT(sw_inc_flux))
116-
end
117-
118-
function (rad::GrayRadiationModel)(::Val{:ρe}, temperature, pressure)
119-
update_atmospheric_state(rad, temperature, pressure)
120-
solve_lw!(rad.slv_lw, rad.atmospheric_state)
121-
solve_sw!(rad.slv_sw, rad.atmospheric_state)
122-
end

src/Radiation/radiation_model_utils.jl

Whitespace-only changes.

0 commit comments

Comments
 (0)