Skip to content

Commit e21ed29

Browse files
committed
wip
1 parent d953685 commit e21ed29

File tree

3 files changed

+141
-115
lines changed

3 files changed

+141
-115
lines changed

src/Radiation/gray_breezy.jl

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,64 @@
1+
using RRTMGP.Optics: GrayOpticalThicknessSchneider2004
2+
using RRTMGP.Parameters: RRTMGPParameters
3+
using RRTMGP.AtmosphericStates: GrayAtmosphericState
4+
using RRTMGP.RTE: TwoStreamLWRTE
5+
using RRTMGP.RTESolver: solve_lw!
6+
17
using Oceananigans
28
using Oceananigans: field
39
using Oceananigans.Architectures: array_type
410
using Oceananigans: RectilinearGrid
511

6-
arch = CPU()
12+
include("rrtmgp_interface.jl")
13+
14+
FT = Float64
15+
architecture = CPU()
16+
DA = array_type(architecture)
17+
Nx, Ny, Nz = 1, 1, 64
18+
Lx, Ly, Lz = 1, 20_000_000, 1_000 # domain size in meters
19+
Nbnd, Ngpt = 1, 1 # gray model
20+
lw_inc_flux = nothing # no incoming longwave flux
21+
sfc_emissivity = 1
22+
planet_radius = 6_371_000
23+
p_surface = 100_000 # surface pressure (Pa)
24+
p_top = 9_000 # top of atmosphere pressure / emission level (Pa)
25+
lat_center = 0
26+
optical_properties = GrayOpticalThicknessSchneider2004(FT)
27+
28+
# Grid setup, we also need to say where on the planet our box is located
729
grid = RectilinearGrid(
8-
CPU(),
9-
size=(1, 1, 64),
10-
x=(0, 2π),
11-
y=(0, 2π),
12-
z=(0, 1),
30+
architecture,
31+
FT,
32+
size=(Nx, Ny, Nz,),
33+
x=(-Lx/2, Lx/2),
34+
y=(-Ly/2, Ly/2),
35+
z=(0, Lz),
1336
topology=(Periodic, Periodic, Bounded)
1437
)
1538

39+
# Set up temperature and pressure profiles for the atmosphere
40+
if grid.Nx > 1
41+
throw("Grid must not be wider than 1 point in the x direction")
42+
else
43+
# assumes only 1 point in the x direction
44+
pressure, temperature = gray_test_t_p_profiles(grid; p0=p_surface, pe=p_top)
45+
end
1646

47+
# Set up atmospheric state
48+
atmospheric_state = GrayAtmosphericState(
49+
grid;
50+
temperature,
51+
pressure,
52+
otp=optical_properties,
53+
lat_center=lat_center
54+
)
1755

18-
function t_p_profiles(grid::RectilinearGrid; lat, p0, pe, otp)
19-
20-
context = context_from_arch(grid.architecture)
21-
nlay = grid.Nz
22-
param_set = RRTMGPParameters(eltype(grid))
23-
DA = array_type(grid.architecture)
24-
gray_as = setup_gray_as_pr_grid(context, nlay, lat, p0, pe, otp, param_set, DA)
56+
# Set up radiation model
57+
sfc_emission = DA{FT}(undef, Nbnd, Nx, Ny)
58+
fill!(sfc_emission, FT(sfc_emissivity))
59+
SLVLW = TwoStreamLWRTE
60+
slv_lw = SLVLW(grid; sfc_emission, lw_inc_flux)
2561

26-
pressure = field((Center(), Center(), Face()), gray_as.p_lay, grid)
27-
temperature = field((Center(), Center(), Face()), gray_as.t_lay, grid)
62+
# solve the radiation model
63+
solve_lw!(slv_lw, atmospheric_state)
2864

29-
return pressure, temperature
30-
end

src/Radiation/proposed_design.jl

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

src/Radiation/rrtmgp_interface.jl

Lines changed: 90 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,84 @@ using RRTMGP: RRTMGPGridParams
33
using RRTMGP.AngularDiscretizations
44
using RRTMGP.Fluxes
55
using RRTMGP.Optics
6-
using RRTMGP.GrayUtils
6+
using RRTMGP.GrayUtils: setup_gray_as_pr_grid
77
using RRTMGP.Sources
88
using RRTMGP.BCs
9+
using RRTMGP.Parameters: RRTMGPParameters
10+
using RRTMGP.Optics: GrayOpticalThicknessSchneider2004
11+
12+
using Oceananigans
13+
using Oceananigans: RectilinearGrid
14+
using Oceananigans: field
915
using ClimaParams
16+
using ClimaComms
1017

1118
import RRTMGP.Parameters.RRTMGPParameters
1219
import RRTMGP.AtmosphericStates
1320
import RRTMGP.RTE: NoScatLWRTE, TwoStreamLWRTE, NoScatSWRTE, TwoStreamSWRTE
1421

22+
function latitude(grid::RectilinearGrid; lat_center=0, planet_radius=6_371_000, unit=:degrees)
23+
FT = eltype(grid)
24+
DA = array_type(grid.architecture)
25+
Nx = grid.Nx
26+
27+
y = ynodes(grid, Center())
28+
lat = lat_center .+ y / planet_radius * (unit == :degrees ? 180/π : 1)
29+
lat = DA{FT}(repeat(lat', Nx, 1))
30+
31+
return lat
32+
end
33+
1534
function RRTMGP.RRTMGPGridParams(grid::RectilinearGrid; isothermal_boundary_layer::Bool = false)
16-
nlay = grid.Nz
17-
ncols = grid.Nx * grid.Ny
35+
FT = eltype(grid)
36+
Nx, Ny, Nz = grid.Nx, grid.Ny, grid.Nz
37+
Ncols = Nz * Ny
1838
context = context_from_arch(grid.architecture)
19-
return RRTMGPGridParams(context, nlay, ncols, isothermal_boundary_layer)
39+
return RRTMGPGridParams{FT, typeof(context)}(context, Nz, Ncols, isothermal_boundary_layer)
2040
end
2141

2242
function RRTMGP.AtmosphericStates.GrayAtmosphericState(
2343
grid::RectilinearGrid;
2444
temperature::Field,
2545
pressure::Field,
26-
lat::Field,
2746
otp,
47+
lat_center=0,
48+
planet_radius=6_371_000,
2849
)
29-
lat = grid.lat
30-
nlay = grid.Nz
31-
ncols = grid.Nx * grid.Ny
32-
p_lay = reshape(interior(pressure), nlay, ncols)
33-
p_lev = reshape(interior(Field(@at (Center, Center, Face) pressure)), nlay + 1, ncols)
34-
t_lay = reshape(interior(temperature), nlay, ncols)
35-
t_lev = reshape(interior(Field(@at (Center, Center, Face) temperature)), nlay + 1, ncols)
36-
z_lev = znodes(grid, Face())
50+
FT = eltype(grid)
51+
Nx, Ny, Nz = grid.Nx, grid.Ny, grid.Nz
52+
Ncols = Nx * Ny
53+
lat = reshape(latitude(grid; lat_center, planet_radius), Ncols)
54+
p_lay = reshape(interior(pressure), Nz, Ncols)
55+
p_lev = reshape(interior(Field(@at (Center, Center, Face) pressure)), Nz + 1, Ncols)
56+
t_lay = reshape(interior(temperature), Nz, Ncols)
57+
t_lev = reshape(interior(Field(@at (Center, Center, Face) temperature)), Nz + 1, Ncols)
58+
z_lev = reshape(view(repeat(znodes(grid, Face()), Nx, Ny, 1), :, :, :), Nz + 1, Ncols)
3759
t_sfc = t_lev[1, :]
38-
otp = otp
3960

40-
return GrayAtmosphericState(lat, p_lay, p_lev, t_lay, t_lev, z_lev, t_sfc, otp)
61+
return GrayAtmosphericState{FT, AbstractVector{FT}, AbstractMatrix{FT}, typeof(otp)}(
62+
lat,
63+
p_lay,
64+
p_lev,
65+
t_lay,
66+
t_lev,
67+
z_lev,
68+
t_sfc,
69+
otp
70+
)
4171
end
4272

4373
function RRTMGP.RTE.NoScatLWRTE(
4474
grid::RectilinearGrid;
45-
sfc_emis,
46-
inc_flux
75+
sfc_emission,
76+
lw_inc_flux
4777
)
4878
grid_params = RRTMGPGridParams(grid)
4979
params = RRTMGPParameters(eltype(grid))
5080
(; context) = grid_params
5181
op = OneScalar(grid_params)
5282
src = SourceLWNoScat(grid_params; params)
53-
bcs = LwBCs(sfc_emis, inc_flux)
83+
bcs = LwBCs(sfc_emission, lw_inc_flux)
5484
fluxb = FluxLW(grid_params)
5585
flux = FluxLW(grid_params)
5686
ad = AngularDiscretization(grid_params, 1)
@@ -59,15 +89,21 @@ end
5989

6090
function RRTMGP.RTE.TwoStreamLWRTE(
6191
grid::RectilinearGrid;
62-
sfc_emis,
63-
inc_flux
92+
sfc_emission,
93+
lw_inc_flux
6494
)
95+
FT = eltype(grid)
96+
Nx, Ny = grid.Nx, grid.Ny
97+
Ncols = Nx * Ny
6598
grid_params = RRTMGPGridParams(grid)
6699
params = RRTMGPParameters(eltype(grid))
67100
(; context) = grid_params
68101
op = TwoStream(grid_params)
69102
src = SourceLW2Str(grid_params; params)
70-
bcs = LwBCs(sfc_emis, inc_flux)
103+
if lw_inc_flux !== nothing
104+
lw_inc_flux = reshape(lw_inc_flux, 1, Ncols)
105+
end
106+
bcs = LwBCs(reshape(sfc_emission, 1, Ncols), lw_inc_flux)
71107
fluxb = FluxLW(grid_params)
72108
flux = FluxLW(grid_params)
73109
return TwoStreamLWRTE(context, op, src, bcs, fluxb, flux)
@@ -118,3 +154,36 @@ function context_from_arch(arch)
118154
return ClimaComms.context(ClimaComms.CUDADevice())
119155
end
120156
end
157+
158+
function gray_test_t_p_profiles(grid::RectilinearGrid; p0, pe)
159+
# get data types and context from grid
160+
FT = eltype(grid)
161+
context = context_from_arch(grid.architecture)
162+
DA = array_type(grid.architecture)
163+
164+
# derive latitude from grid
165+
Nx, Ny, Nz = grid.Nx, grid.Ny, grid.Nz
166+
ncol = grid.Nx * grid.Ny
167+
if ncol == 1
168+
lat = DA{FT}([0])
169+
else
170+
lat = DA{FT}(range(FT(-90), FT(90), length = ncol))
171+
end
172+
173+
# get test case temperature and pressure profiles
174+
param_set = RRTMGPParameters(FT)
175+
otp = GrayOpticalThicknessSchneider2004(FT)
176+
gray_as = setup_gray_as_pr_grid(context, Nz, lat, FT(p0), FT(pe), otp, param_set, DA)
177+
p_lay_as_array = reshape(gray_as.p_lay', Nx, Ny, Nz)
178+
t_lay_as_array = reshape(gray_as.t_lay', Nx, Ny, Nz)
179+
180+
# create Fields from test case temperature and pressure profiles
181+
pressure = CenterField(grid)
182+
temperature = CenterField(grid)
183+
set!(pressure, p_lay_as_array)
184+
set!(temperature, t_lay_as_array)
185+
186+
return pressure, temperature
187+
end
188+
189+

0 commit comments

Comments
 (0)