Skip to content

Commit 9ee01d5

Browse files
authored
Merge pull request #1194 from brian-eaton/ssi-scale
cam6_4_057: Restore spectral scaling to RRTMGP
2 parents ea101b3 + 552bd23 commit 9ee01d5

File tree

5 files changed

+276
-12
lines changed

5 files changed

+276
-12
lines changed

bld/build-namelist

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -760,11 +760,9 @@ if ($rad_pkg =~ /rrtmg/ or $chem =~ /waccm/) {
760760
# use solar data file as the default for rrtmg and waccm_ma
761761
add_default($nl, 'solar_irrad_data_file');
762762

763-
# This option only used by camrt and rrtmg radiation schemes.
764-
# The solar spectral scaling is done internal to RRTMGP code.
765-
if ($rad_pkg ne 'rrtmgp') {
766-
add_default($nl, 'solar_htng_spctrl_scl', 'val'=>'.true.');
767-
}
763+
# The solar spectral scaling is done based on the distribution from
764+
# the solar_irrad_data_file.
765+
add_default($nl, 'solar_htng_spctrl_scl', 'val'=>'.true.');
768766

769767
}
770768
elsif (!$simple_phys) {

doc/ChangeLog

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,115 @@
11
===============================================================
22

3+
Tag name: cam6_4_057
4+
Originator(s): brianpm, eaton, nusbaume
5+
Date: Jan 29 2025
6+
One-line Summary: Restore spectral scaling to RRTMGP
7+
Github PR URL: https://github.com/ESCOMP/CAM/pull/1194
8+
9+
Purpose of changes (include the issue number and title text for each relevant GitHub issue):
10+
11+
resolve issue #1193 - Restore spectral scaling to RRTMGP
12+
13+
Describe any changes made to build system: none
14+
15+
Describe any changes made to the namelist: none
16+
17+
List any changes to the defaults for the boundary datasets: none
18+
19+
Describe any substantial timing or memory changes: not evaluated
20+
21+
Code reviewed by: peverwhee
22+
23+
List all files eliminated: none
24+
25+
List all files added and what they do:
26+
27+
src/physics/rrtmgp/rad_solar_var.F90
28+
. compute scale factors for solar irradiance based on input dataset
29+
30+
List all existing files that have been modified, and describe the changes:
31+
32+
bld/build-namelist
33+
. change default setting of solar_htng_spctrl_scl to true for rrtmgp
34+
35+
src/physics/rrtmgp/radconstants.F90
36+
. add module data band2gpt_sw and set using kdist_sw%get_band_lims_gpoint()
37+
38+
src/physics/rrtmgp/radiation.F90
39+
. radiation_init
40+
- add call to rad_solar_var_init
41+
. radiation_tend
42+
- replace code that scales the solar source based on internal RRTMGP
43+
spectral distribution by a scaling based on distribution from the
44+
solar_irrad_data_file.
45+
46+
If there were any failures reported from running test_driver.sh on any test
47+
platform, and checkin with these failures has been OK'd by the gatekeeper,
48+
then copy the lines from the td.*.status files for the failed tests to the
49+
appropriate machine below. All failed tests must be justified.
50+
51+
derecho/intel/aux_cam:
52+
53+
ERP_D_Ln9.ne30pg3_ne30pg3_mg17.FLTHIST.derecho_intel.cam-outfrq9s (Overall: DIFF)
54+
ERP_D_Ln9.ne30pg3_ne30pg3_mg17.QPLT.derecho_intel.cam-outfrq3s_cosp (Overall: DIFF)
55+
ERP_D_Ln9.ne30pg3_ne30pg3_mg17.QPMT.derecho_intel.cam-outfrq9s (Overall: DIFF)
56+
ERP_Ld3.ne30pg3_ne30pg3_mg17.FHISTC_MTt4s.derecho_intel.cam-outfrq1d_aoa (Overall: DIFF)
57+
SMS_D_Ln9.ne30pg3_ne30pg3_mg17.FMTHIST.derecho_intel.cam-outfrq9s (Overall: DIFF)
58+
SMS_D_Ln9_P1280x1.ne30pg3_ne30pg3_mg17.FHISTC_MTt1s.derecho_intel.cam-outfrq9s_Leung_dust (Overall: DIFF)
59+
SMS_Ln9.ne30pg3_ne30pg3_mg17.FW2000climo.derecho_intel.cam-outfrq9s_rrtmgp (Overall: DIFF)
60+
- expected NLCOMP (solar_htng_spctrl_scl) and baseline answer changes due to restored RRTMGP spectral scaling.
61+
62+
63+
ERP_Ln9.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq9s (Overall: FAIL)
64+
SMS_Ld1.f09_f09_mg17.FCHIST_GC.derecho_intel.cam-outfrq1d (Overall: DIFF)
65+
- pre-existing failure due to HEMCO not having reproducible results issues #1018 and #856
66+
67+
SMS_D_Ln9.f19_f19_mg17.FXHIST.derecho_intel.cam-outfrq9s_amie (Overall: FAIL)
68+
SMS_D_Ln9_P1280x1.ne0CONUSne30x8_ne0CONUSne30x8_mt12.FCHIST.derecho_intel.cam-outfrq9s (Overall: FAIL)
69+
- pre-existing failures due to build-namelist error requiring CLM/CTSM external update
70+
71+
derecho/nvhpc/aux_cam:
72+
73+
ERS_Ln9.ne30pg3_ne30pg3_mg17.F2000dev.derecho_nvhpc.cam-outfrq9s_gpu_default (Overall: FAIL)
74+
- pre-existing failure -- issue #1220
75+
76+
izumi/nag/aux_cam: ALL PASS
77+
78+
izumi/gnu/aux_cam:
79+
80+
ERP_D_Ln9.ne3pg3_ne3pg3_mg37.FLTHIST.izumi_gnu.cam-outfrq9s (Overall: DIFF)
81+
ERP_D_Ln9.ne3pg3_ne3pg3_mg37.QPLT.izumi_gnu.cam-outfrq9s (Overall: DIFF)
82+
ERP_D_Ln9.ne3pg3_ne3pg3_mg37.QPMT.izumi_gnu.cam-outfrq9s (Overall: DIFF)
83+
SMS_Ld5.f09_f09_mg17.PC6.izumi_gnu.cam-cam6_port_f09_rrtmgp (Overall: DIFF)
84+
- expected NLCOMP (solar_htng_spctrl_scl) and baseline answer changes due to restored RRTMGP spectral scaling.
85+
86+
CAM tag used for the baseline comparison tests if different than previous
87+
tag:
88+
89+
Summarize any changes to answers, i.e.,
90+
- what code configurations:
91+
- what platforms/compilers:
92+
- nature of change (roundoff; larger than roundoff but same climate; new
93+
climate):
94+
95+
If bitwise differences were observed, how did you show they were no worse
96+
than roundoff?
97+
98+
If this tag changes climate describe the run(s) done to evaluate the new
99+
climate in enough detail that it(they) could be reproduced, i.e.,
100+
- source tag (all code used must be in the repository):
101+
- platform/compilers:
102+
- configure commandline:
103+
- build-namelist command (or complete namelist):
104+
- MSS location of output:
105+
106+
MSS location of control simulations used to validate new climate:
107+
108+
URL for AMWG diagnostics output used to validate new climate:
109+
110+
===============================================================
111+
===============================================================
112+
3113
Tag name: cam6_4_056
4114
Originator(s): fvitt
5115
Date: 16 Jan 2025
@@ -1143,7 +1253,6 @@ Summarize any changes to answers: none
11431253

11441254
===============================================================
11451255

1146-
>>>>>>> upstream/cam_development
11471256
Tag name: cam6_4_048
11481257
Originator(s): jedwards4b, peverwhee
11491258
Date: 20 December 2024
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
!-------------------------------------------------------------------------------
2+
! This module uses the solar irradiance data
3+
! to provide a spectral scaling factor
4+
! to approximate the spectral distribution of irradiance
5+
! when the radiation scheme might use a different solar source function
6+
!-------------------------------------------------------------------------------
7+
module rad_solar_var
8+
9+
use shr_kind_mod , only : r8 => shr_kind_r8
10+
use radconstants, only : nswbands, get_sw_spectral_boundaries, band2gpt_sw
11+
use solar_irrad_data, only : sol_irrad, we, nbins, has_spectrum, sol_tsi
12+
use solar_irrad_data, only : do_spctrl_scaling
13+
use cam_abortutils, only : endrun
14+
use error_messages, only : alloc_err
15+
16+
implicit none
17+
save
18+
19+
private
20+
public :: rad_solar_var_init
21+
public :: get_variability
22+
23+
real(r8), allocatable :: irrad(:) ! solar irradiance at model timestep in each band
24+
25+
real(r8), allocatable :: radbinmax(:)
26+
real(r8), allocatable :: radbinmin(:)
27+
28+
!-------------------------------------------------------------------------------
29+
contains
30+
!-------------------------------------------------------------------------------
31+
32+
subroutine rad_solar_var_init( )
33+
34+
integer :: ierr
35+
integer :: radmax_loc
36+
37+
if ( do_spctrl_scaling ) then
38+
39+
if ( .not.has_spectrum ) then
40+
call endrun('rad_solar_var_init: solar input file must have irradiance spectrum')
41+
endif
42+
43+
allocate (radbinmax(nswbands),stat=ierr)
44+
if (ierr /= 0) then
45+
call endrun('rad_solar_var_init: Error allocating space for radbinmax')
46+
end if
47+
48+
allocate (radbinmin(nswbands),stat=ierr)
49+
if (ierr /= 0) then
50+
call endrun('rad_solar_var_init: Error allocating space for radbinmin')
51+
end if
52+
53+
allocate (irrad(nswbands), stat=ierr)
54+
if (ierr /= 0) then
55+
call endrun('rad_solar_var_init: Error allocating space for irrad')
56+
end if
57+
58+
call get_sw_spectral_boundaries(radbinmin, radbinmax, 'nm')
59+
60+
! Make sure that the far-IR is included, even if radiation grid does not
61+
! extend that far down. 10^5 nm corresponds to a wavenumber of
62+
! 100 cm^-1.
63+
radmax_loc = maxloc(radbinmax,1)
64+
radbinmax(radmax_loc) = max(100000._r8,radbinmax(radmax_loc))
65+
66+
endif
67+
68+
end subroutine rad_solar_var_init
69+
70+
!-------------------------------------------------------------------------------
71+
!-------------------------------------------------------------------------------
72+
73+
subroutine get_variability(toa_flux, sfac)
74+
75+
! Arguments
76+
real(r8), intent(in) :: toa_flux(:,:) ! TOA flux to be scaled (columns,gpts)
77+
real(r8), intent(out) :: sfac(:,:) ! scaling factors (columns,gpts)
78+
79+
! Local variables
80+
integer :: i, j, istat, gpt_start, gpt_end, ncols
81+
real(r8), allocatable :: scale(:)
82+
character(len=*), parameter :: sub = 'get_variability'
83+
84+
if (do_spctrl_scaling) then
85+
86+
! Determine target irradiance for each band
87+
call integrate_spectrum(nbins, nswbands, we, radbinmin, radbinmax, sol_irrad, irrad)
88+
89+
ncols = size(toa_flux, 1)
90+
allocate(scale(ncols), stat=istat)
91+
call alloc_err(istat, sub, 'scale', ncols)
92+
93+
do i = 1, nswbands
94+
gpt_start = band2gpt_sw(1,i)
95+
gpt_end = band2gpt_sw(2,i)
96+
scale = spread(irrad(i), 1, ncols) / sum(toa_flux(:, gpt_start:gpt_end), dim=2)
97+
do j = gpt_start, gpt_end
98+
sfac(:,j) = scale
99+
end do
100+
end do
101+
102+
else
103+
sfac(:,:) = sol_tsi / spread(sum(toa_flux, 2), 2, size(toa_flux, 2))
104+
end if
105+
end subroutine get_variability
106+
107+
108+
!-------------------------------------------------------------------------------
109+
! private method.........
110+
!-------------------------------------------------------------------------------
111+
112+
subroutine integrate_spectrum( nsrc, ntrg, src_x, min_trg, max_trg, src, trg )
113+
114+
use mo_util, only : rebin
115+
116+
implicit none
117+
118+
!---------------------------------------------------------------
119+
! ... dummy arguments
120+
!---------------------------------------------------------------
121+
integer, intent(in) :: nsrc ! dimension source array
122+
integer, intent(in) :: ntrg ! dimension target array
123+
real(r8), intent(in) :: src_x(nsrc+1) ! source coordinates
124+
real(r8), intent(in) :: max_trg(ntrg) ! target coordinates
125+
real(r8), intent(in) :: min_trg(ntrg) ! target coordinates
126+
real(r8), intent(in) :: src(nsrc) ! source array
127+
real(r8), intent(out) :: trg(ntrg) ! target array
128+
129+
!---------------------------------------------------------------
130+
! ... local variables
131+
!---------------------------------------------------------------
132+
real(r8) :: trg_x(2), targ(1) ! target coordinates
133+
integer :: i
134+
135+
do i = 1, ntrg
136+
137+
trg_x(1) = min_trg(i)
138+
trg_x(2) = max_trg(i)
139+
140+
call rebin( nsrc, 1, src_x, trg_x, src(1:nsrc), targ(:) )
141+
! W/m2/nm --> W/m2
142+
trg( i ) = targ(1)*(trg_x(2)-trg_x(1))
143+
144+
enddo
145+
146+
147+
end subroutine integrate_spectrum
148+
149+
end module rad_solar_var

src/physics/rrtmgp/radconstants.F90

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ module radconstants
2626

2727
logical :: wavenumber_boundaries_set = .false.
2828

29+
! First and last g-point for each band.
30+
integer, public, protected :: band2gpt_sw(2,nswbands)
31+
2932
integer, public, protected :: nswgpts ! number of SW g-points
3033
integer, public, protected :: nlwgpts ! number of LW g-points
3134

@@ -104,6 +107,9 @@ subroutine set_wavenumber_bands(kdist_sw, kdist_lw)
104107
wavenumber_low_shortwave = values(1,:)
105108
wavenumber_high_shortwave = values(2,:)
106109

110+
! First and last g-point for each SW band:
111+
band2gpt_sw = kdist_sw%get_band_lims_gpoint()
112+
107113
! Indices into specific bands
108114
idx_sw_diag = get_band_index_by_value('sw', 500.0_r8, 'nm')
109115
idx_nir_diag = get_band_index_by_value('sw', 1000.0_r8, 'nm')

src/physics/rrtmgp/radiation.F90

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ module radiation
1616
pbuf_set_field, pbuf_get_field, pbuf_old_tim_idx
1717
use camsrfexch, only: cam_out_t, cam_in_t
1818
use physconst, only: cappa, cpair, gravit
19-
use solar_irrad_data, only: sol_tsi
2019

2120
use time_manager, only: get_nstep, is_first_step, is_first_restart_step, &
2221
get_curr_calday, get_step_size
@@ -27,6 +26,7 @@ module radiation
2726

2827
use radconstants, only: nradgas, gasnamelength, gaslist, nswbands, nlwbands, &
2928
nswgpts, set_wavenumber_bands
29+
use rad_solar_var, only: rad_solar_var_init, get_variability
3030

3131
use cloud_rad_props, only: cloud_rad_props_init
3232

@@ -495,6 +495,7 @@ subroutine radiation_init(pbuf2d)
495495
! Set the sw/lw band boundaries in radconstants. Also sets
496496
! indicies of specific bands for diagnostic output and COSP input.
497497
call set_wavenumber_bands(kdist_sw, kdist_lw)
498+
call rad_solar_var_init()
498499

499500
! The spectral band boundaries need to be set before this init is called.
500501
call rrtmgp_inputs_init(ktopcam, ktoprad)
@@ -937,8 +938,8 @@ subroutine radiation_tend( &
937938

938939
! TOA solar flux on RRTMGP g-points
939940
real(r8), allocatable :: toa_flux(:,:)
940-
! TSI from RRTMGP data (from sum over g-point representation)
941-
real(r8) :: tsi_ref
941+
! Scale factors based on spectral distribution from input irradiance dataset
942+
real(r8), allocatable :: sfac(:,:)
942943

943944
! Planck sources for LW.
944945
type(ty_source_func_lw) :: sources_lw
@@ -1097,6 +1098,7 @@ subroutine radiation_tend( &
10971098

10981099
allocate( &
10991100
t_sfc(ncol), emis_sfc(nlwbands,ncol), toa_flux(nday,nswgpts), &
1101+
sfac(nday,nswgpts), &
11001102
t_rad(ncol,nlay), pmid_rad(ncol,nlay), pint_rad(ncol,nlay+1), &
11011103
t_day(nday,nlay), pmid_day(nday,nlay), pint_day(nday,nlay+1), &
11021104
coszrs_day(nday), alb_dir(nswbands,nday), alb_dif(nswbands,nday), &
@@ -1174,8 +1176,8 @@ subroutine radiation_tend( &
11741176
call stop_on_err(errmsg, sub, 'kdist_sw%gas_optics')
11751177

11761178
! Scale the solar source
1177-
tsi_ref = sum(toa_flux(1,:))
1178-
toa_flux = toa_flux * sol_tsi * eccf / tsi_ref
1179+
call get_variability(toa_flux, sfac)
1180+
toa_flux = toa_flux * sfac * eccf
11791181

11801182
end if
11811183

@@ -1303,7 +1305,7 @@ subroutine radiation_tend( &
13031305
end if ! if (dolw)
13041306

13051307
deallocate( &
1306-
t_sfc, emis_sfc, toa_flux, t_rad, pmid_rad, pint_rad, &
1308+
t_sfc, emis_sfc, toa_flux, sfac, t_rad, pmid_rad, pint_rad, &
13071309
t_day, pmid_day, pint_day, coszrs_day, alb_dir, alb_dif)
13081310

13091311
!================!

0 commit comments

Comments
 (0)