Skip to content

Commit 4f935ca

Browse files
authored
Bring in RRTMGP tricking mods to rrtmgp_inputs (ESCOMP#299)
Originator(s): JulioTBacmeister Description (include issue title and the keyword ['closes', 'fixes', 'resolves'] and issue number): Addresses ESCOMP/CAM#1382 List all namelist files that were added or changed: n/a List all files eliminated and why: n/a List all files added and what they do: n/a List all existing files that have been modified, and describe the changes: (Helpful git command: `git diff --name-status development...<your_branch_name>`) M schemes/rrtmgp/rrtmgp_inputs.F90 - bring in mods to rrtmgp_inputs_run interface and logic to enable vertical grid trickery List all automated tests that failed, as well as an explanation for why they weren't fixed: n/a Is this an answer-changing PR? If so, is it a new physics package, algorithm change, tuning change, etc? no. If yes to the above question, describe how this code was validated with the new/modified features:
1 parent 9dd83ad commit 4f935ca

1 file changed

Lines changed: 64 additions & 20 deletions

File tree

schemes/rrtmgp/rrtmgp_inputs.F90

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ module rrtmgp_inputs
1111
!! \htmlinclude rrtmgp_inputs_run.html
1212
!!
1313
subroutine rrtmgp_inputs_run(dosw, dolw, snow_associated, graupel_associated, &
14-
pmid, pint, t, nday, idxday, cldfprime, &
15-
coszrs, kdist_sw, t_sfc, emis_sfc, t_rad, pmid_rad, &
16-
pint_rad, t_day, pmid_day, pint_day, coszrs_day, &
14+
is_root, iulog, is_mpas, pmid, pint, t, nday, idxday, &
15+
cldfprime, coszrs, kdist_sw, t_sfc, emis_sfc, t_rad, &
16+
pmid_rad, pint_rad, t_day, pmid_day, pint_day, coszrs_day, &
1717
alb_dir, alb_dif, lwup, stebol, ncol, ktopcam, ktoprad, &
1818
nswbands, asdir, asdif, sw_low_bounds, sw_high_bounds, &
1919
aldir, aldif, nlay, pverp, pver, cld, cldfsnow, &
@@ -27,6 +27,7 @@ subroutine rrtmgp_inputs_run(dosw, dolw, snow_associated, graupel_associated, &
2727
use ccpp_gas_concentrations, only: ty_gas_concs_ccpp
2828
use ccpp_source_functions, only: ty_source_func_lw_ccpp
2929
use atmos_phys_rad_utils, only: is_visible
30+
3031
! Inputs
3132
logical, intent(in) :: graupel_in_rad ! Flag to include graupel in radiation calculation
3233
integer, intent(in) :: ncol ! Number of columns
@@ -42,6 +43,9 @@ subroutine rrtmgp_inputs_run(dosw, dolw, snow_associated, graupel_associated, &
4243
logical, intent(in) :: dolw ! Flag for performing the longwave calculation
4344
logical, intent(in) :: snow_associated ! Flag for whether the cloud snow fraction argument should be used
4445
logical, intent(in) :: graupel_associated ! Flag for whether the cloud graupel fraction argument should be used
46+
logical, intent(in) :: is_root
47+
logical, intent(in) :: is_mpas
48+
integer, intent(in) :: iulog
4549
integer, dimension(:), intent(in) :: idxday ! Indices of daylight columns
4650
real(kind_phys), dimension(:,:), intent(in) :: pmid ! Air pressure at midpoint (Pa)
4751
real(kind_phys), dimension(:,:), intent(in) :: pint ! Air pressure at interface (Pa)
@@ -89,6 +93,7 @@ subroutine rrtmgp_inputs_run(dosw, dolw, snow_associated, graupel_associated, &
8993
real(kind_phys) :: tref_min
9094
real(kind_phys) :: tref_max
9195
integer :: idx, kdx, iband
96+
logical :: ltrick_rrtmgp
9297

9398
! Set error variables
9499
errmsg = ''
@@ -98,6 +103,37 @@ subroutine rrtmgp_inputs_run(dosw, dolw, snow_associated, graupel_associated, &
98103
return
99104
end if
100105

106+
!------------------------------------------------------------------------------
107+
! Compile logic to determine whether it is necessary AND possible to 'trick'
108+
! rrtmgp to violate its own validity limits by hacking its vertical grid.
109+
! Conditions:
110+
! 1) top CAM interface (k=1) is above 1 Pa
111+
! 2) next interface (k=2) is below 1 Pa
112+
! 3) RRTMGP is asked to active over ALL CAM layers
113+
! (nlay=pverp, e.g., set by spec p_top_for_equil_rad=0.)
114+
! 4) dycore is NOT MPAS
115+
!
116+
! These conditions are generally only satisfied in a non-MPAS MT configuration
117+
!------------------------------------------------------------------------------
118+
if (( .not. is_mpas ) .and. &
119+
(nlay==pverp) .and. &
120+
(minval(pint(:,1)) < 1._kind_phys) .and. &
121+
(minval(pint(:,2)) > 1._kind_phys) ) then
122+
! we can and need to trick rrtmgp
123+
ltrick_rrtmgp = .true.
124+
else
125+
! we cannot or don't need to trick rrtmgp
126+
ltrick_rrtmgp = .false.
127+
end if
128+
129+
if (is_root) then
130+
if (ltrick_rrtmgp) then
131+
write(iulog,*) ' *** TRICKING RRTMGP INTO GOING AN EXTRA LEVEL ',nlay,pverp
132+
else
133+
write(iulog,*) ' *** CANT or WONT trick RRTMGP ',nlay,pverp
134+
end if
135+
end if
136+
101137
! RRTMGP set state
102138
t_sfc = sqrt(sqrt(lwup(:)/stebol)) ! Surface temp set based on longwave up flux.
103139

@@ -110,16 +146,16 @@ subroutine rrtmgp_inputs_run(dosw, dolw, snow_associated, graupel_associated, &
110146

111147
!-------------------------------------------------------------------------
112148
! RRTMGP enforces P > 1 Pa for validity.
113-
! In radiation.F90 we count layers based on P_ref > 10 Pa to safely account
114-
! for possible situations in MPAS (z-based vert. coordinate) in which
115-
! full 3D pressure could be significanlty below min(P_ref).
149+
! Actual range of RRTMGP in CAM is set with namelist variable p_top_for_equil_rad.
150+
! In rrtmg_inputs_setup.F90, active layers for RRTMGP are counted based on
151+
! the logical P_ref > p_top_for_equil_rad. Returned as nlay.
116152
!
117153
! If
118-
! 1) entire vertical domain has P_ref> 10Pa (e.g. CAM7 LT) then
154+
! 1) entire vertical domain has P_ref> p_top_for_equil_rad then
119155
! nlay = pverp
120156
! ktoprad = 2
121157
! ktopcam = 1
122-
! 2) min(P_ref) < 10Pa (e.g. CAM7 MT) then
158+
! 2) min(P_ref) < p_top_for_equil_rad (e.g. MPAS MT) then
123159
! nlay < pverp
124160
! ktoprad = 1
125161
! ktopcam = pver - nlay + 1
@@ -134,23 +170,31 @@ subroutine rrtmgp_inputs_run(dosw, dolw, snow_associated, graupel_associated, &
134170

135171
! Deal with vertical grid for RRTMGP
136172
if (nlay == pverp) then
137-
! This case is the CAM7 LT situation, i.e., all model layers are
138-
! within RRTMGP's range of valid pressures - (Case 1 above)
173+
! All model layers are within RRTMGP's range of valid pressures
174+
! as specified by p_top_for_equil_rad - (Case 1 above)
139175
t_rad(:,1) = t(:,1)
140-
! The top reference pressure from the RRTMGP coefficients datasets is 1.005183574463 Pa
141-
! Set the top of the extra layer just below that.
142-
pint_rad(:,1) = 1.01_kind_phys
143-
! set the highest pmid (in the "extra layer") to the midpoint (guarantees > 1Pa)
144-
pmid_rad(:,1) = pint_rad(:,1) + 0.5_kind_phys * (pint_rad(:,2) - pint_rad(:,1))
176+
if (ltrick_rrtmgp) then
177+
! The top reference pressure from the RRTMGP coefficients datasets is 1.005183574463 Pa
178+
! Set the top of the extra layer just below that.
179+
pint_rad(:,1) = 1.01_kind_phys
180+
pint_rad(:,2) = 1.02_kind_phys
181+
! set the highest pmid (in the "extra layer") to the midpoint (guarantees > 1Pa)
182+
pmid_rad(:,1) = 1.015_kind_phys ! pint_rad(:,1) + 0.5_kind_phys * (pint_rad(:,2) - pint_rad(:,1))
183+
pmid_rad(:,2) = 0.5*(pint_rad(:,2) + pint_rad(:,3))
184+
else
185+
! The top reference pressure from the RRTMGP coefficients datasets is 1.005183574463 Pa
186+
! Set the top of the extra layer just below that.
187+
pint_rad(:,1) = 1.01_kind_phys
188+
! set the highest pmid (in the "extra layer") to the midpoint (guarantees > 1Pa)
189+
pmid_rad(:,1) = pint_rad(:,1) + 0.5_kind_phys * (pint_rad(:,2) - pint_rad(:,1))
190+
end if
145191
else
146192
! nlay < pverp : model min(pref) < p_top_for_rrtmgp (Case 2 above)
147-
! min(pref) could be 9.999 or 0.0999
148-
! Assuming the top interface of this layer is at a pressure < 1 Pa, we need to adjust
149-
! so that it is within the valid pressure range of RRTMGP (otherwise RRTMGP issues
150-
! an error). Then we set the midpoint pressure halfway between the interfaces.
193+
! Not sure why is this needed since pint_rad should have been specified
194+
! at RRTMGP valid values above. But this is the way it was done in
195+
! original RRTMG implementation.
151196
pint_rad(:,1) = 1.01_kind_phys
152197
! The following *should* work since pint_rad is all in valid range.
153-
! Need to think about possible edge cases ... (jtb 07/31/25)
154198
pmid_rad(:,1) = 0.5_kind_phys * (pint_rad(:,1) + pint_rad(:,2))
155199
end if
156200

0 commit comments

Comments
 (0)