@@ -13,7 +13,8 @@ module rrtmgp_inputs
1313 subroutine rrtmgp_inputs_init (ktopcam , ktoprad , nlaycam , sw_low_bounds , sw_high_bounds , nswbands , &
1414 pref_edge , nlay , pver , pverp , kdist_sw , kdist_lw , qrl , is_first_step , use_rad_dt_cosz , &
1515 timestep_size , nstep , iradsw , dt_avg , irad_always , is_first_restart_step , is_root , &
16- nlwbands , nradgas , gasnamelength , iulog , idx_sw_diag , idx_nir_diag , idx_uv_diag , &
16+ p_top_for_rrtmgp , &
17+ nlwbands , nradgas , gasnamelength , idx_sw_diag , idx_nir_diag , idx_uv_diag , &
1718 idx_sw_cloudsim , idx_lw_diag , idx_lw_cloudsim , nswgpts , nlwgpts , nlayp , &
1819 nextsw_cday , current_cal_day , band2gpt_sw , errmsg , errflg )
1920 use ccpp_kinds, only: kind_phys
@@ -26,10 +27,10 @@ subroutine rrtmgp_inputs_init(ktopcam, ktoprad, nlaycam, sw_low_bounds, sw_high_
2627 integer , intent (in ) :: nradgas ! Number of radiatively active gases
2728 integer , intent (in ) :: pverp ! Number of vertical interfaces
2829 integer , intent (in ) :: pver ! Number of vertical layers
29- integer , intent (in ) :: iradsw ! Freq. of shortwave radiation calc in time steps (positive) or hours (negative).
30+ integer , intent (in ) :: iradsw ! Freq. of shortwave radiation calc in time steps
31+ ! (positive) or hours (negative).
3032 integer , intent (in ) :: timestep_size ! Timestep size (s)
3133 integer , intent (in ) :: nstep ! Current timestep number
32- integer , intent (in ) :: iulog ! Logging unit
3334 integer , intent (in ) :: gasnamelength ! Length of all of the gas_list entries
3435 real (kind_phys), intent (in ) :: current_cal_day ! Current calendar day
3536 real (kind_phys), dimension (:), intent (in ) :: pref_edge ! Reference pressures (interfaces) (Pa)
@@ -39,6 +40,7 @@ subroutine rrtmgp_inputs_init(ktopcam, ktoprad, nlaycam, sw_low_bounds, sw_high_
3940 logical , intent (in ) :: is_first_restart_step ! Flag for whether this is the first restart step (.true. = yes)
4041 logical , intent (in ) :: use_rad_dt_cosz ! Use adjusted radiation timestep for cosz calculation
4142 logical , intent (in ) :: is_root ! Flag for whether this is the root task
43+ real (kind_phys), intent (in ) :: p_top_for_rrtmgp ! Top pressure to use for RRTMGP
4244
4345 ! Outputs
4446 integer , intent (out ) :: ktopcam ! Index in CAM arrays of top level (layer or interface) at which RRTMGP is active
@@ -81,7 +83,7 @@ subroutine rrtmgp_inputs_init(ktopcam, ktoprad, nlaycam, sw_low_bounds, sw_high_
8183 ! pressure interfaces below 1 Pa. When the entire model atmosphere is
8284 ! below 1 Pa then an extra layer is added to the top of the model for
8385 ! the purpose of the radiation calculation.
84- nlay = count ( pref_edge(:) > 1._kind_phys ) ! pascals (0.01 mbar )
86+ nlay = count ( pref_edge(:) > p_top_for_rrtmgp )
8587 nlayp = nlay + 1
8688
8789 if (nlay == pverp) then
@@ -90,16 +92,6 @@ subroutine rrtmgp_inputs_init(ktopcam, ktoprad, nlaycam, sw_low_bounds, sw_high_
9092 ktopcam = 1
9193 ktoprad = 2
9294 nlaycam = pver
93- else if (nlay == (pverp-1 )) then
94- ! Special case nlay == (pverp-1) -- topmost interface outside bounds (CAM MT config), treat as if it is ok.
95- ktopcam = 1
96- ktoprad = 2
97- nlaycam = pver
98- nlay = nlay+1 ! reassign the value so later code understands to treat this case like nlay==pverp
99- if (is_root) then
100- write (iulog,* ) ' RADIATION_INIT: Special case of 1 model interface at p < 1Pa. Top layer will be INCLUDED in radiation calculation.'
101- write (iulog,* ) ' RADIATION_INIT: nlay = ' ,nlay, ' same as pverp: ' ,nlay== pverp
102- end if
10395 else
10496 ! nlay < pverp. nlay layers are used in radiation calcs, and they are
10597 ! all CAM layers.
@@ -254,33 +246,49 @@ subroutine rrtmgp_inputs_run(dosw, dolw, snow_associated, graupel_associated, &
254246 ! to be consistent with t_sfc.
255247 emis_sfc(:,:) = 1._kind_phys
256248
249+ !- ------------------------------------------------------------------------
250+ ! RRTMGP enforces P > 1 Pa for validity.
251+ ! In radiation.F90 we count layers based on P_ref > 10 Pa to safely account
252+ ! for possible situations in MPAS (z-based vert. coordinate) in which
253+ ! full 3D pressure could be significanlty below min(P_ref).
254+ !
255+ ! If
256+ ! 1) entire vertical domain has P_ref> 10Pa (e.g. CAM7 LT) then
257+ ! nlay = pverp
258+ ! ktoprad = 2
259+ ! ktopcam = 1
260+ ! 2) min(P_ref) < 10Pa (e.g. CAM7 MT) then
261+ ! nlay < pverp
262+ ! ktoprad = 1
263+ ! ktopcam = pver - nlay + 1
264+ !
257265 ! Level ordering is the same for both CAM and RRTMGP (top to bottom)
266+ ! Note in Case 2, tops of {t,pint,pmid}_rad start at a 'valid' level,
267+ ! i.e. pref > p_top_for_rrtmgp
268+ !- ------------------------------------------------------
258269 t_rad(:,ktoprad:) = t(:,ktopcam:)
259270 pmid_rad(:,ktoprad:) = pmid(:,ktopcam:)
260271 pint_rad(:,ktoprad:) = pint(:,ktopcam:)
261272
262- ! Add extra layer values if needed.
273+ ! Deal with vertical grid for RRTMGP
263274 if (nlay == pverp) then
264- t_rad(:,1 ) = t(:,1 )
275+ ! This case is the CAM7 LT situation, i.e., all model layers are
276+ ! within RRTMGP's range of valid pressures - (Case 1 above)
277+ t_rad(:,1 ) = t(:,1 )
265278 ! The top reference pressure from the RRTMGP coefficients datasets is 1.005183574463 Pa
266279 ! Set the top of the extra layer just below that.
267280 pint_rad(:,1 ) = 1.01_kind_phys
268-
269- ! next interface down in LT will always be > 1Pa
270- ! but in MT we apply adjustment to have it be 1.02 Pa if it was too high
271- where (pint_rad(:,2 ) <= pint_rad(:,1 )) pint_rad(:,2 ) = pint_rad(:,1 )+ 0.01_kind_phys
272-
273- ! set the highest pmid (in the "extra layer") to the midpoint (guarantees > 1Pa)
281+ ! set the highest pmid (in the "extra layer") to the midpoint (guarantees > 1Pa)
274282 pmid_rad(:,1 ) = pint_rad(:,1 ) + 0.5_kind_phys * (pint_rad(:,2 ) - pint_rad(:,1 ))
275-
276- ! For case of CAM MT, also ensure pint_rad(:,2) > pint_rad(:,1) & pmid_rad(:,2) > max(pmid_rad(:,1), min_pressure)
277- where (pmid_rad(:,2 ) <= kdist_sw% gas_props% get_press_min()) pmid_rad(:,2 ) = pint_rad(:,2 ) + 0.01_kind_phys
278283 else
279- ! nlay < pverp, thus the 1 Pa level is within a CAM layer. Assuming the top interface of
280- ! this layer is at a pressure < 1 Pa, we need to adjust the top of this layer so that it
281- ! is within the valid pressure range of RRTMGP (otherwise RRTMGP issues an error). Then
282- ! set the midpoint pressure halfway between the interfaces.
284+ ! nlay < pverp : model min(pref) < p_top_for_rrtmgp (Case 2 above)
285+ ! min(pref) could be 9.999 or 0.0999
286+ ! Assuming the top interface of this layer is at a pressure < 1 Pa, we need to adjust
287+ ! so that it is within the valid pressure range of RRTMGP (otherwise RRTMGP issues
288+ ! an error). Then we set the midpoint pressure halfway between the interfaces.
283289 pint_rad(:,1 ) = 1.01_kind_phys
290+ ! The following *should* work since pint_rad is all in valid range.
291+ ! Need to think about possible edge cases ... (jtb 07/31/25)
284292 pmid_rad(:,1 ) = 0.5_kind_phys * (pint_rad(:,1 ) + pint_rad(:,2 ))
285293 end if
286294
0 commit comments