LCOV - code coverage report
Current view: | top level - physics/rrtmgp - radiation.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 950 | 1061 | 89.5 %
Date: | 2024-12-17 17:57:11 |  | Functions: | 23 | 24 | 95.8 %

              Line data    Source code
           1             : module radiation
           2             :
           3             : !---------------------------------------------------------------------------------
           4             : !
           5             : ! CAM interface to RRTMGP radiation parameterization.
           6             : !
           7             : !---------------------------------------------------------------------------------
           8             :
           9             : use shr_kind_mod,        only: r8=>shr_kind_r8, cl=>shr_kind_cl
          10             : use spmd_utils,          only: masterproc
          11             : use ppgrid,              only: pcols, pver, pverp, begchunk, endchunk
          12             : use ref_pres,            only: pref_edge
          13             : use physics_types,       only: physics_state, physics_ptend
          14             : use phys_control,        only: phys_getopts
          15             : use physics_buffer,      only: physics_buffer_desc, pbuf_add_field, dtype_r8, pbuf_get_index, &
          16             :                                pbuf_set_field, pbuf_get_field, pbuf_old_tim_idx
          17             : use camsrfexch,          only: cam_out_t, cam_in_t
          18             : use physconst,           only: cappa, cpair, gravit
          19             : use solar_irrad_data,    only: sol_tsi
          20             :
          21             : use time_manager,        only: get_nstep, is_first_step, is_first_restart_step, &
          22             :                                get_curr_calday, get_step_size
          23             :
          24             : use rad_constituents,    only: N_DIAG, rad_cnst_get_call_list, rad_cnst_get_gas, rad_cnst_out
          25             :
          26             : use rrtmgp_inputs,       only: rrtmgp_inputs_init
          27             :
          28             : use radconstants,        only: nradgas, gasnamelength, gaslist, nswbands, nlwbands, &
          29             :                                nswgpts, set_wavenumber_bands
          30             :
          31             : use cloud_rad_props,     only: cloud_rad_props_init
          32             :
          33             : use cospsimulator_intr,  only: docosp, cospsimulator_intr_init, &
          34             :                                cospsimulator_intr_run, cosp_nradsteps
          35             :
          36             : use scamMod,             only: scm_crm_mode, single_column, have_cld, cldobs
          37             :
          38             : use cam_history,         only: addfld, add_default, horiz_only, outfld, hist_fld_active
          39             :
          40             : use radiation_data,      only: rad_data_register, rad_data_init
          41             :
          42             : use ioFileMod,           only: getfil
          43             : use cam_pio_utils,       only: cam_pio_openfile
          44             : use pio,                 only: file_desc_t, var_desc_t,                       &
          45             :                                pio_int, pio_double, PIO_NOERR,                &
          46             :                                pio_seterrorhandling, PIO_BCAST_ERROR,         &
          47             :                                pio_inq_dimlen, pio_inq_dimid, pio_inq_varid,  &
          48             :                                pio_def_var, pio_put_var, pio_get_var,         &
          49             :                                pio_put_att, PIO_NOWRITE, pio_closefile
          50             :
          51             : use mo_gas_concentrations, only: ty_gas_concs
          52             : use mo_gas_optics_rrtmgp,  only: ty_gas_optics_rrtmgp
          53             : use mo_optical_props,      only: ty_optical_props_1scl, ty_optical_props_2str
          54             : use mo_source_functions,   only: ty_source_func_lw
          55             : use mo_fluxes,             only: ty_fluxes_broadband
          56             : use mo_fluxes_byband,      only: ty_fluxes_byband
          57             :
          58             : use string_utils,        only: to_lower
          59             : use cam_abortutils,      only: endrun, handle_allocate_error
          60             : use cam_logfile,         only: iulog
          61             :
          62             :
          63             : implicit none
          64             : private
          65             : save
          66             :
          67             : public :: &
          68             :    radiation_readnl,         &! read namelist variables
          69             :    radiation_register,       &! registers radiation physics buffer fields
          70             :    radiation_do,             &! query which radiation calcs are done this timestep
          71             :    radiation_init,           &! initialization
          72             :    radiation_define_restart, &! define variables for restart
          73             :    radiation_write_restart,  &! write variables to restart
          74             :    radiation_read_restart,   &! read variables from restart
          75             :    radiation_tend,           &! compute heating rates and fluxes
          76             :    rad_out_t                  ! type for diagnostic outputs
          77             :
          78             : integer,public, allocatable :: cosp_cnt(:)       ! counter for cosp
          79             : integer,public              :: cosp_cnt_init = 0 !initial value for cosp counter
          80             :
          81             : real(r8), public, protected :: nextsw_cday       ! future radiation calday for surface models
          82             :
          83             : type rad_out_t
          84             :    real(r8) :: solin(pcols)         ! Solar incident flux
          85             :
          86             :    real(r8) :: qrsc(pcols,pver)
          87             :
          88             :    real(r8) :: fsnsc(pcols)         ! Clear sky surface abs solar flux
          89             :    real(r8) :: fsntc(pcols)         ! Clear sky total column abs solar flux
          90             :    real(r8) :: fsdsc(pcols)         ! Clear sky surface downwelling solar flux
          91             :
          92             :    real(r8) :: fsntoa(pcols)        ! Net solar flux at TOA
          93             :    real(r8) :: fsntoac(pcols)       ! Clear sky net solar flux at TOA
          94             :    real(r8) :: fsutoa(pcols)        ! upwelling solar flux at TOA
          95             :
          96             :    real(r8) :: fsnirt(pcols)        ! Near-IR flux absorbed at toa
          97             :    real(r8) :: fsnrtc(pcols)        ! Clear sky near-IR flux absorbed at toa
          98             :    real(r8) :: fsnirtsq(pcols)      ! Near-IR flux absorbed at toa >= 0.7 microns
          99             :
         100             :    real(r8) :: fsn200(pcols)        ! Net SW flux interpolated to 200 mb
         101             :    real(r8) :: fsn200c(pcols)       ! Net clear-sky SW flux interpolated to 200 mb
         102             :    real(r8) :: fsnr(pcols)          ! Net SW flux interpolated to tropopause
         103             :
         104             :    real(r8) :: flux_sw_up(pcols,pverp)     ! upward shortwave flux on interfaces
         105             :    real(r8) :: flux_sw_clr_up(pcols,pverp) ! upward shortwave clearsky flux
         106             :    real(r8) :: flux_sw_dn(pcols,pverp)     ! downward flux
         107             :    real(r8) :: flux_sw_clr_dn(pcols,pverp) ! downward clearsky flux
         108             :
         109             :    real(r8) :: flux_lw_up(pcols,pverp)     ! upward longwave flux on interfaces
         110             :    real(r8) :: flux_lw_clr_up(pcols,pverp) ! upward longwave clearsky flux
         111             :    real(r8) :: flux_lw_dn(pcols,pverp)     ! downward flux
         112             :    real(r8) :: flux_lw_clr_dn(pcols,pverp) ! downward clearsky flux
         113             :
         114             :    real(r8) :: qrlc(pcols,pver)
         115             :
         116             :    real(r8) :: flntc(pcols)         ! Clear sky lw flux at model top
         117             :    real(r8) :: flut(pcols)          ! Upward flux at top of model
         118             :    real(r8) :: flutc(pcols)         ! Upward Clear Sky flux at top of model
         119             :    real(r8) :: lwcf(pcols)          ! longwave cloud forcing
         120             :
         121             :    real(r8) :: fln200(pcols)        ! net longwave flux interpolated to 200 mb
         122             :    real(r8) :: fln200c(pcols)       ! net clearsky longwave flux interpolated to 200 mb
         123             :    real(r8) :: flnr(pcols)          ! net longwave flux interpolated to tropopause
         124             :
         125             :    real(r8) :: flnsc(pcols)         ! Clear sky lw flux at srf (up-down)
         126             :    real(r8) :: fldsc(pcols)         ! Clear sky lw flux at srf (down)
         127             :
         128             :    real(r8) :: tot_cld_vistau(pcols,pver)   ! gbx water+ice cloud optical depth (only during day, night = fillvalue)
         129             :    real(r8) :: tot_icld_vistau(pcols,pver)  ! in-cld water+ice cloud optical depth (only during day, night = fillvalue)
         130             :    real(r8) :: liq_icld_vistau(pcols,pver)  ! in-cld liq cloud optical depth (only during day, night = fillvalue)
         131             :    real(r8) :: ice_icld_vistau(pcols,pver)  ! in-cld ice cloud optical depth (only during day, night = fillvalue)
         132             :    real(r8) :: snow_icld_vistau(pcols,pver) ! snow in-cloud visible sw optical depth for output on history files
         133             :    real(r8) :: grau_icld_vistau(pcols,pver) ! Graupel in-cloud visible sw optical depth for output on history files
         134             : end type rad_out_t
         135             :
         136             : ! Control variables set via namelist
         137             : character(len=cl) :: coefs_lw_file ! filepath for lw coefficients
         138             : character(len=cl) :: coefs_sw_file ! filepath for sw coefficients
         139             :
         140             : integer :: iradsw = -1     ! freq. of shortwave radiation calc in time steps (positive)
         141             :                            ! or hours (negative).
         142             : integer :: iradlw = -1     ! frequency of longwave rad. calc. in time steps (positive)
         143             :                            ! or hours (negative).
         144             :
         145             : integer :: irad_always = 0 ! Specifies length of time in timesteps (positive)
         146             :                            ! or hours (negative) SW/LW radiation will be
         147             :                            ! run continuously from the start of an
         148             :                            ! initial or restart run
         149             : logical :: use_rad_dt_cosz  = .false. ! if true, use radiation dt for all cosz calculations
         150             : logical :: spectralflux     = .false. ! calculate fluxes (up and down) per band.
         151             : logical :: graupel_in_rad   = .false. ! graupel in radiation code
         152             : logical :: use_rad_uniform_angle = .false. ! if true, use the namelist rad_uniform_angle for the coszrs calculation
         153             :
         154             : ! active_calls is set by a rad_constituents method after parsing namelist input
         155             : ! for the rad_climate and rad_diag_N entries.
         156             : logical :: active_calls(0:N_DIAG)
         157             :
         158             : ! Physics buffer indices
         159             : integer :: qrs_idx      = 0
         160             : integer :: qrl_idx      = 0
         161             : integer :: su_idx       = 0
         162             : integer :: sd_idx       = 0
         163             : integer :: lu_idx       = 0
         164             : integer :: ld_idx       = 0
         165             : integer :: fsds_idx     = 0
         166             : integer :: fsns_idx     = 0
         167             : integer :: fsnt_idx     = 0
         168             : integer :: flns_idx     = 0
         169             : integer :: flnt_idx     = 0
         170             : integer :: cld_idx      = 0
         171             : integer :: cldfsnow_idx = 0
         172             : integer :: cldfgrau_idx = 0
         173             :
         174             : character(len=4) :: diag(0:N_DIAG) =(/'    ','_d1 ','_d2 ','_d3 ','_d4 ','_d5 ',&
         175             :                                       '_d6 ','_d7 ','_d8 ','_d9 ','_d10'/)
         176             :
         177             : ! averaging time interval for zenith angle
         178             : real(r8) :: dt_avg = 0._r8
         179             : real(r8) :: rad_uniform_angle = -99._r8
         180             :
         181             : ! Number of layers in radiation calculations.
         182             : integer :: nlay
         183             :
         184             : ! Number of CAM layers in radiation calculations.  Is either equal to nlay, or is
         185             : ! 1 less than nlay if "extra layer" is used in the radiation calculations.
         186             : integer :: nlaycam
         187             :
         188             : ! Indices for copying data between CAM/WACCM and RRTMGP arrays.  Since RRTMGP is
         189             : ! vertical order agnostic we can send data using the top to bottom order used
         190             : ! in CAM/WACCM.  But the number of layers that RRTMGP does computations for
         191             : ! may not match the number of layers in CAM/WACCM for two reasons:
         192             : ! 1. If the CAM model top is below 1 Pa, then RRTMGP does calculations for an
         193             : !    extra layer that is added between 1 Pa and the model top.
         194             : ! 2. If the WACCM model top is above 1 Pa, then RRMTGP only does calculations
         195             : !    for those model layers that are below 1 Pa.
         196             : integer :: ktopcam ! Index in CAM arrays of top level (layer or interface) at which
         197             :                    ! RRTMGP is active.
         198             : integer :: ktoprad ! Index in RRTMGP arrays of the layer or interface corresponding
         199             :                    ! to CAM's top layer or interface.
         200             :                    ! Note: for CAM's top to bottom indexing, the index of a given layer
         201             :                    ! (midpoint) and the upper interface of that layer, are the same.
         202             :
         203             : ! Gas optics objects contain the data read from the coefficients files.
         204             : type(ty_gas_optics_rrtmgp) :: kdist_sw
         205             : type(ty_gas_optics_rrtmgp) :: kdist_lw
         206             :
         207             : ! lower case version of gaslist for RRTMGP
         208             : character(len=gasnamelength) :: gaslist_lc(nradgas)
         209             :
         210             : type(var_desc_t) :: cospcnt_desc  ! cosp
         211             : type(var_desc_t) :: nextsw_cday_desc
         212             :
         213             : !=========================================================================================
         214             : contains
         215             : !=========================================================================================
         216             :
         217        1536 : subroutine radiation_readnl(nlfile)
         218             :
         219             :    ! Read radiation_nl namelist group.
         220             :
         221             :    use namelist_utils,  only: find_group_name
         222             :    use spmd_utils,      only: mpicom, mstrid=>masterprocid, mpi_integer, mpi_logical, &
         223             :                               mpi_character, mpi_real8
         224             :
         225             :    character(len=*), intent(in) :: nlfile  ! filepath for file containing namelist input
         226             :
         227             :    ! Local variables
         228             :    integer :: unitn, ierr
         229             :    integer :: dtime      ! timestep size
         230             :    character(len=32) :: errmsg
         231             :    character(len=*), parameter :: sub = 'radiation_readnl'
         232             :
         233             :    character(len=cl) :: rrtmgp_coefs_lw_file, rrtmgp_coefs_sw_file
         234             :
         235             :    namelist /radiation_nl/ &
         236             :       rrtmgp_coefs_lw_file, rrtmgp_coefs_sw_file, iradsw, iradlw,        &
         237             :       irad_always, use_rad_dt_cosz, spectralflux, use_rad_uniform_angle, &
         238             :       rad_uniform_angle, graupel_in_rad
         239             :    !-----------------------------------------------------------------------------
         240             :
         241        1536 :    if (masterproc) then
         242           2 :       open( newunit=unitn, file=trim(nlfile), status='old' )
         243           2 :       call find_group_name(unitn, 'radiation_nl', status=ierr)
         244           2 :       if (ierr == 0) then
         245           2 :          read(unitn, radiation_nl, iostat=ierr)
         246           2 :          if (ierr /= 0) then
         247           0 :             write(errmsg,'(a,i5)') 'iostat =', ierr
         248           0 :             call endrun(sub//': ERROR reading namelist: '//trim(errmsg))
         249             :          end if
         250             :       end if
         251           2 :       close(unitn)
         252             :    end if
         253             :
         254             :    ! Broadcast namelist variables
         255        1536 :    call mpi_bcast(rrtmgp_coefs_lw_file, cl, mpi_character, mstrid, mpicom, ierr)
         256        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: rrtmgp_coefs_lw_file")
         257        1536 :    call mpi_bcast(rrtmgp_coefs_sw_file, cl, mpi_character, mstrid, mpicom, ierr)
         258        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: rrtmgp_coefs_sw_file")
         259        1536 :    call mpi_bcast(iradsw, 1, mpi_integer, mstrid, mpicom, ierr)
         260        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: iradsw")
         261        1536 :    call mpi_bcast(iradlw, 1, mpi_integer, mstrid, mpicom, ierr)
         262        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: iradlw")
         263        1536 :    call mpi_bcast(irad_always, 1, mpi_integer, mstrid, mpicom, ierr)
         264        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: irad_always")
         265        1536 :    call mpi_bcast(use_rad_dt_cosz, 1, mpi_logical, mstrid, mpicom, ierr)
         266        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: use_rad_dt_cosz")
         267        1536 :    call mpi_bcast(spectralflux, 1, mpi_logical, mstrid, mpicom, ierr)
         268        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: spectralflux")
         269        1536 :    call mpi_bcast(use_rad_uniform_angle, 1, mpi_logical, mstrid, mpicom, ierr)
         270        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: use_rad_uniform_angle")
         271        1536 :    call mpi_bcast(rad_uniform_angle, 1, mpi_real8, mstrid, mpicom, ierr)
         272        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: rad_uniform_angle")
         273        1536 :    call mpi_bcast(graupel_in_rad, 1, mpi_logical, mstrid, mpicom, ierr)
         274        1536 :    if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: graupel_in_rad")
         275             :
         276        1536 :    if (use_rad_uniform_angle .and. rad_uniform_angle == -99._r8) then
         277             :       call endrun(sub//': ERROR - use_rad_uniform_angle is set to .true,' &
         278           0 :                      //' but rad_uniform_angle is not set ')
         279             :    end if
         280             :
         281             :    ! Set module data
         282        1536 :    coefs_lw_file   = rrtmgp_coefs_lw_file
         283        1536 :    coefs_sw_file   = rrtmgp_coefs_sw_file
         284             :
         285             :    ! Convert iradsw, iradlw and irad_always from hours to timesteps if necessary
         286        1536 :    dtime  = get_step_size()
         287        1536 :    if (iradsw      < 0) iradsw      = nint((-iradsw     *3600._r8)/dtime)
         288        1536 :    if (iradlw      < 0) iradlw      = nint((-iradlw     *3600._r8)/dtime)
         289        1536 :    if (irad_always < 0) irad_always = nint((-irad_always*3600._r8)/dtime)
         290             :
         291             :    !-----------------------------------------------------------------------
         292             :    ! Print runtime options to log.
         293             :    !-----------------------------------------------------------------------
         294             :
         295        1536 :    if (masterproc) then
         296           2 :       write(iulog,*) 'RRTMGP radiation scheme parameters:'
         297           2 :       write(iulog,10) trim(coefs_lw_file), trim(coefs_sw_file), nlwbands, nswbands, &
         298           4 :          iradsw, iradlw, irad_always, use_rad_dt_cosz, spectralflux, graupel_in_rad
         299             :    end if
         300             :
         301             : 10 format('  LW coefficents file: ',                                a/, &
         302             :           '  SW coefficents file: ',                                a/, &
         303             :           '  Number of LW bands:                                 ',i5/, &
         304             :           '  Number of SW bands:                                 ',i5/, &
         305             :           '  Frequency (timesteps) of Shortwave Radiation calc:  ',i5/, &
         306             :           '  Frequency (timesteps) of Longwave Radiation calc:   ',i5/, &
         307             :           '  SW/LW calc done every timestep for first N steps. N=',i5/, &
         308             :           '  Use average zenith angle:                           ',l5/, &
         309             :           '  Output spectrally resolved fluxes:                  ',l5/, &
         310             :           '  Graupel in Radiation Code:                          ',l5/)
         311             :
         312        1536 : end subroutine radiation_readnl
         313             :
         314             : !================================================================================================
         315             :
         316        1536 : subroutine radiation_register
         317             :
         318             :    ! Register radiation fields in the physics buffer
         319             :
         320        1536 :    call pbuf_add_field('QRS' , 'global',dtype_r8,(/pcols,pver/), qrs_idx) ! shortwave radiative heating rate
         321        1536 :    call pbuf_add_field('QRL' , 'global',dtype_r8,(/pcols,pver/), qrl_idx) ! longwave  radiative heating rate
         322             :
         323        1536 :    call pbuf_add_field('FSDS' , 'global',dtype_r8,(/pcols/), fsds_idx) ! Surface solar downward flux
         324        1536 :    call pbuf_add_field('FSNS' , 'global',dtype_r8,(/pcols/), fsns_idx) ! Surface net shortwave flux
         325        1536 :    call pbuf_add_field('FSNT' , 'global',dtype_r8,(/pcols/), fsnt_idx) ! Top-of-model net shortwave flux
         326             :
         327        1536 :    call pbuf_add_field('FLNS' , 'global',dtype_r8,(/pcols/), flns_idx) ! Surface net longwave flux
         328        1536 :    call pbuf_add_field('FLNT' , 'global',dtype_r8,(/pcols/), flnt_idx) ! Top-of-model net longwave flux
         329             :
         330             :    ! If the namelist has been configured for preserving the spectral fluxes, then create
         331             :    ! physics buffer variables to store the results.  This data is accessed by CARMA.
         332        1536 :    if (spectralflux) then
         333           0 :       call pbuf_add_field('SU'  , 'global',dtype_r8,(/pcols,pverp,nswbands/), su_idx) ! shortwave upward flux (per band)
         334           0 :       call pbuf_add_field('SD'  , 'global',dtype_r8,(/pcols,pverp,nswbands/), sd_idx) ! shortwave downward flux (per band)
         335           0 :       call pbuf_add_field('LU'  , 'global',dtype_r8,(/pcols,pverp,nlwbands/), lu_idx) ! longwave upward flux (per band)
         336           0 :       call pbuf_add_field('LD'  , 'global',dtype_r8,(/pcols,pverp,nlwbands/), ld_idx) ! longwave downward flux (per band)
         337             :    end if
         338             :
         339             :    ! Register fields for offline radiation driver.
         340        1536 :    call rad_data_register()
         341             :
         342        1536 : end subroutine radiation_register
         343             :
         344             : !================================================================================================
         345             :
         346     5232240 : function radiation_do(op, timestep)
         347             :
         348             :    ! Return true if the specified operation is done this timestep.
         349             :
         350             :    character(len=*), intent(in) :: op             ! name of operation
         351             :    integer, intent(in), optional:: timestep
         352             :    logical                      :: radiation_do   ! return value
         353             :
         354             :    ! Local variables
         355             :    integer :: nstep             ! current timestep number
         356             :    !-----------------------------------------------------------------------
         357             :
         358     5232240 :    if (present(timestep)) then
         359     5232240 :       nstep = timestep
         360             :    else
         361           0 :       nstep = get_nstep()
         362             :    end if
         363             :
         364     3739968 :    select case (op)
         365             :       case ('sw') ! do a shortwave heating calc this timestep?
         366             :          radiation_do = nstep == 0  .or.  iradsw == 1                     &
         367             :                      .or. (mod(nstep-1,iradsw) == 0  .and.  nstep /= 1)   &
         368     3739968 :                      .or. nstep <= irad_always
         369             :       case ('lw') ! do a longwave heating calc this timestep?
         370             :          radiation_do = nstep == 0  .or.  iradlw == 1                     &
         371             :                      .or. (mod(nstep-1,iradlw) == 0  .and.  nstep /= 1)   &
         372     1492272 :                      .or. nstep <= irad_always
         373             :       case default
         374     5232240 :          call endrun('radiation_do: unknown operation:'//op)
         375             :    end select
         376             :
         377     5232240 : end function radiation_do
         378             :
         379             : !================================================================================================
         380             :
         381     1492272 : real(r8) function radiation_nextsw_cday()
         382             :
         383             :    ! If a SW radiation calculation will be done on the next time-step, then return
         384             :    ! the calendar day of that time-step.  Otherwise return -1.0
         385             :
         386             :    ! Local variables
         387             :    integer :: nstep      ! timestep counter
         388             :    logical :: dosw       ! true => do shosrtwave calc
         389             :    integer :: offset     ! offset for calendar day calculation
         390             :    integer :: dtime      ! integer timestep size
         391             :    real(r8):: caldayp1   ! calendar day of next time-step
         392             :
         393             :    !-----------------------------------------------------------------------
         394             :
         395     1492272 :    radiation_nextsw_cday = -1._r8
         396     1492272 :    dosw   = .false.
         397     1492272 :    nstep  = get_nstep()
         398     1492272 :    dtime  = get_step_size()
         399     1492272 :    offset = 0
         400             :    do while (.not. dosw)
         401     2247696 :       nstep = nstep + 1
         402     2247696 :       offset = offset + dtime
         403     2247696 :       if (radiation_do('sw', nstep)) then
         404     1492272 :          radiation_nextsw_cday = get_curr_calday(offset=offset)
         405             :          dosw = .true.
         406             :       end if
         407             :    end do
         408     1492272 :    if(radiation_nextsw_cday == -1._r8) then
         409           0 :       call endrun('error in radiation_nextsw_cday')
         410             :    end if
         411             :
         412             :    ! determine if next radiation time-step not equal to next time-step
         413     1492272 :    if (get_nstep() >= 1) then
         414     1486080 :       caldayp1 = get_curr_calday(offset=int(dtime))
         415     1486080 :       if (caldayp1 /= radiation_nextsw_cday) radiation_nextsw_cday = -1._r8
         416             :    end if
         417             :
         418     1492272 : end function radiation_nextsw_cday
         419             :
         420             : !================================================================================================
         421             :
         422        1536 : subroutine radiation_init(pbuf2d)
         423             :
         424             :    ! Initialize the radiation and cloud optics.
         425             :    ! Add fields to the history buffer.
         426             :
         427             :    ! arguments
         428             :    type(physics_buffer_desc), pointer :: pbuf2d(:,:)
         429             :
         430             :    ! local variables
         431             :    character(len=128) :: errmsg
         432             :
         433             :    ! names of gases that are available in the model
         434             :    ! -- needed for the kdist initialization routines
         435        1536 :    type(ty_gas_concs) :: available_gases
         436             :
         437             :    integer :: i, icall
         438             :    integer :: nstep                       ! current timestep number
         439             :    logical :: history_amwg                ! output the variables used by the AMWG diag package
         440             :    logical :: history_vdiag               ! output the variables used by the AMWG variability diag package
         441             :    logical :: history_budget              ! output tendencies and state variables for CAM4
         442             :                                           ! temperature, water vapor, cloud ice and cloud
         443             :                                           ! liquid budgets.
         444             :    integer :: history_budget_histfile_num ! history file number for budget fields
         445             :    integer :: ierr, istat
         446             :
         447             :    integer :: dtime
         448             :
         449             :    character(len=*), parameter :: sub = 'radiation_init'
         450             :    !-----------------------------------------------------------------------
         451             :
         452             :    ! Number of layers in radiation calculation is capped by the number of
         453             :    ! pressure interfaces below 1 Pa.  When the entire model atmosphere is
         454             :    ! below 1 Pa then an extra layer is added to the top of the model for
         455             :    ! the purpose of the radiation calculation.
         456             :
         457      145920 :    nlay = count( pref_edge(:) > 1._r8 ) ! pascals (0.01 mbar)
         458             :
         459        1536 :    if (nlay == pverp) then
         460             :       ! Top model interface is below 1 Pa.  RRTMGP is active in all model layers plus
         461             :       ! 1 extra layer between model top and 1 Pa.
         462           0 :       ktopcam = 1
         463           0 :       ktoprad = 2
         464           0 :       nlaycam = pver
         465        1536 :    else if (nlay == (pverp-1)) then
         466             :       ! Special case nlay == (pverp-1) -- topmost interface outside bounds (CAM MT config), treat as if it is ok.
         467        1536 :       ktopcam = 1
         468        1536 :       ktoprad = 2
         469        1536 :       nlaycam = pver
         470        1536 :       nlay = nlay+1 ! reassign the value so later code understands to treat this case like nlay==pverp
         471        1536 :       write(iulog,*) 'RADIATION_INIT: Special case of 1 model interface at p < 1Pa. Top layer will be INCLUDED in radiation calculation.'
         472        1536 :       write(iulog,*) 'RADIATION_INIT: nlay = ',nlay, ' same as pverp: ',nlay==pverp
         473             :    else
         474             :       ! nlay < pverp.  nlay layers are used in radiation calcs, and they are
         475             :       ! all CAM layers.
         476           0 :       ktopcam = pver - nlay + 1
         477           0 :       ktoprad = 1
         478           0 :       nlaycam = nlay
         479             :    end if
         480             :
         481             :    ! Create lowercase version of the gaslist for RRTMGP.  The ty_gas_concs objects
         482             :    ! work with CAM's uppercase names, but other objects that get input from the gas
         483             :    ! concs objects don't work.
         484       13824 :    do i = 1, nradgas
         485       13824 :       gaslist_lc(i) = to_lower(gaslist(i))
         486             :    end do
         487             :
         488        1536 :    errmsg = available_gases%init(gaslist_lc)
         489        1536 :    call stop_on_err(errmsg, sub, 'available_gases%init')
         490             :
         491             :    ! Read RRTMGP coefficients files and initialize kdist objects.
         492        1536 :    call coefs_init(coefs_sw_file, available_gases, kdist_sw)
         493        1536 :    call coefs_init(coefs_lw_file, available_gases, kdist_lw)
         494             :
         495             :    ! Set the sw/lw band boundaries in radconstants.  Also sets
         496             :    ! indicies of specific bands for diagnostic output and COSP input.
         497        1536 :    call set_wavenumber_bands(kdist_sw, kdist_lw)
         498             :
         499             :    ! The spectral band boundaries need to be set before this init is called.
         500        1536 :    call rrtmgp_inputs_init(ktopcam, ktoprad)
         501             :
         502             :    ! initialize output fields for offline driver
         503        1536 :    call rad_data_init(pbuf2d)
         504             :
         505        1536 :    call cloud_rad_props_init()
         506             :
         507        1536 :    cld_idx      = pbuf_get_index('CLD')
         508        1536 :    cldfsnow_idx = pbuf_get_index('CLDFSNOW', errcode=ierr)
         509        1536 :    cldfgrau_idx = pbuf_get_index('CLDFGRAU', errcode=ierr)
         510             :
         511        1536 :    if (is_first_step()) then
         512         768 :       call pbuf_set_field(pbuf2d, qrl_idx, 0._r8)
         513             :    end if
         514             :
         515             :    ! Set the radiation timestep for cosz calculations if requested using
         516             :    ! the adjusted iradsw value from radiation
         517        1536 :    if (use_rad_dt_cosz)  then
         518           0 :       dtime  = get_step_size()
         519           0 :       dt_avg = iradsw*dtime
         520             :    end if
         521             :
         522             :    ! Surface components to get radiation computed today
         523        1536 :    if (.not. is_first_restart_step()) then
         524         768 :       nextsw_cday = get_curr_calday()
         525             :    end if
         526             :
         527             :    call phys_getopts(history_amwg_out   = history_amwg,    &
         528             :                      history_vdiag_out  = history_vdiag,   &
         529             :                      history_budget_out = history_budget,  &
         530        1536 :                      history_budget_histfile_num_out = history_budget_histfile_num)
         531             :
         532             :    ! "irad_always" is number of time steps to execute radiation continuously from
         533             :    ! start of initial OR restart run
         534        1536 :    nstep = get_nstep()
         535        1536 :    if (irad_always > 0) then
         536           0 :       irad_always = irad_always + nstep
         537             :    end if
         538             :
         539        1536 :    if (docosp) call cospsimulator_intr_init()
         540             :
         541        4608 :    allocate(cosp_cnt(begchunk:endchunk), stat=istat)
         542        1536 :    call handle_allocate_error(istat, sub, 'cosp_cnt')
         543        1536 :    if (is_first_restart_step()) then
         544        3864 :       cosp_cnt(begchunk:endchunk) = cosp_cnt_init
         545             :    else
         546        3864 :       cosp_cnt(begchunk:endchunk) = 0
         547             :    end if
         548             :
         549             :    ! Add fields to history buffer
         550             :
         551             :    call addfld('TOT_CLD_VISTAU',  (/ 'lev' /), 'A',   '1',             &
         552             :                'Total gbx cloud extinction visible sw optical depth',  &
         553        3072 :                sampling_seq='rad_lwsw', flag_xyfill=.true.)
         554             :    call addfld('TOT_ICLD_VISTAU', (/ 'lev' /), 'A',  '1',              &
         555             :                'Total in-cloud extinction visible sw optical depth',   &
         556        3072 :                sampling_seq='rad_lwsw', flag_xyfill=.true.)
         557             :    call addfld('LIQ_ICLD_VISTAU', (/ 'lev' /), 'A',  '1', &
         558             :                'Liquid in-cloud extinction visible sw optical depth',  &
         559        3072 :                sampling_seq='rad_lwsw', flag_xyfill=.true.)
         560             :    call addfld('ICE_ICLD_VISTAU', (/ 'lev' /), 'A',  '1',              &
         561             :                'Ice in-cloud extinction visible sw optical depth',     &
         562        3072 :                sampling_seq='rad_lwsw', flag_xyfill=.true.)
         563             :
         564        1536 :    if (cldfsnow_idx > 0) then
         565             :       call addfld('SNOW_ICLD_VISTAU', (/ 'lev' /), 'A', '1',           &
         566             :                   'Snow in-cloud extinction visible sw optical depth', &
         567        3072 :                   sampling_seq='rad_lwsw', flag_xyfill=.true.)
         568             :    end if
         569        1536 :    if (cldfgrau_idx > 0 .and. graupel_in_rad) then
         570             :       call addfld('GRAU_ICLD_VISTAU', (/ 'lev' /), 'A', '1',           &
         571             :                   'Graupel in-cloud extinction visible sw optical depth', &
         572           0 :                   sampling_seq='rad_lwsw', flag_xyfill=.true.)
         573             :    endif
         574             :
         575             :    ! get list of active radiation calls
         576        1536 :    call rad_cnst_get_call_list(active_calls)
         577             :
         578             :    ! Add shortwave radiation fields to history master field list.
         579             :
         580       18432 :    do icall = 0, N_DIAG
         581             :
         582       18432 :       if (active_calls(icall)) then
         583             :
         584             :          call addfld('SOLIN'//diag(icall),    horiz_only,   'A', 'W/m2', &
         585        1536 :                      'Solar insolation', sampling_seq='rad_lwsw')
         586             :          call addfld('QRS'//diag(icall),      (/ 'lev' /),  'A', 'K/s',  &
         587        3072 :                      'Solar heating rate', sampling_seq='rad_lwsw')
         588             :          call addfld('QRSC'//diag(icall),     (/ 'lev' /),  'A', 'K/s',  &
         589        3072 :                      'Clearsky solar heating rate', sampling_seq='rad_lwsw')
         590             :          call addfld('FSNT'//diag(icall),     horiz_only,   'A', 'W/m2', &
         591        1536 :                      'Net solar flux at top of model', sampling_seq='rad_lwsw')
         592             :          call addfld('FSNTC'//diag(icall),    horiz_only,   'A', 'W/m2', &
         593        1536 :                      'Clearsky net solar flux at top of model', sampling_seq='rad_lwsw')
         594             :          call addfld('FSNTOA'//diag(icall),   horiz_only,   'A', 'W/m2', &
         595        1536 :                      'Net solar flux at top of atmosphere', sampling_seq='rad_lwsw')
         596             :          call addfld('FSNTOAC'//diag(icall),  horiz_only,   'A', 'W/m2', &
         597        1536 :                      'Clearsky net solar flux at top of atmosphere', sampling_seq='rad_lwsw')
         598             :          call addfld('SWCF'//diag(icall),     horiz_only,   'A', 'W/m2', &
         599        1536 :                      'Shortwave cloud forcing', sampling_seq='rad_lwsw')
         600             :          call addfld('FSUTOA'//diag(icall),   horiz_only,   'A', 'W/m2', &
         601        1536 :                      'Upwelling solar flux at top of atmosphere', sampling_seq='rad_lwsw')
         602             :          call addfld('FSNIRTOA'//diag(icall), horiz_only,   'A', 'W/m2', &
         603        1536 :                      'Net near-infrared flux (Nimbus-7 WFOV) at top of atmosphere', sampling_seq='rad_lwsw')
         604             :          call addfld('FSNRTOAC'//diag(icall), horiz_only,   'A', 'W/m2', &
         605        1536 :                       'Clearsky net near-infrared flux (Nimbus-7 WFOV) at top of atmosphere', sampling_seq='rad_lwsw')
         606             :          call addfld('FSNRTOAS'//diag(icall), horiz_only,   'A', 'W/m2', &
         607        1536 :                      'Net near-infrared flux (>= 0.7 microns) at top of atmosphere', sampling_seq='rad_lwsw')
         608             :          call addfld('FSN200'//diag(icall),   horiz_only,   'A', 'W/m2', &
         609        1536 :                      'Net shortwave flux at 200 mb', sampling_seq='rad_lwsw')
         610             :          call addfld('FSN200C'//diag(icall),  horiz_only,   'A', 'W/m2', &
         611        1536 :                      'Clearsky net shortwave flux at 200 mb', sampling_seq='rad_lwsw')
         612             :          call addfld('FSNR'//diag(icall),     horiz_only,   'A', 'W/m2', &
         613        1536 :                      'Net solar flux at tropopause', sampling_seq='rad_lwsw')
         614             :          call addfld('SOLL'//diag(icall),     horiz_only,   'A', 'W/m2', &
         615        1536 :                      'Solar downward near infrared direct  to surface', sampling_seq='rad_lwsw')
         616             :          call addfld('SOLS'//diag(icall),     horiz_only,   'A', 'W/m2', &
         617        1536 :                      'Solar downward visible direct  to surface', sampling_seq='rad_lwsw')
         618             :          call addfld('SOLLD'//diag(icall),    horiz_only,   'A', 'W/m2', &
         619        1536 :                      'Solar downward near infrared diffuse to surface', sampling_seq='rad_lwsw')
         620             :          call addfld('SOLSD'//diag(icall),    horiz_only,   'A', 'W/m2', &
         621        1536 :                      'Solar downward visible diffuse to surface', sampling_seq='rad_lwsw')
         622             :          call addfld('FSNS'//diag(icall),     horiz_only,   'A', 'W/m2', &
         623        1536 :                      'Net solar flux at surface', sampling_seq='rad_lwsw')
         624             :          call addfld('FSNSC'//diag(icall),    horiz_only,   'A', 'W/m2', &
         625        1536 :                      'Clearsky net solar flux at surface', sampling_seq='rad_lwsw')
         626             :          call addfld('FSDS'//diag(icall),     horiz_only,   'A', 'W/m2', &
         627        1536 :                      'Downwelling solar flux at surface', sampling_seq='rad_lwsw')
         628             :          call addfld('FSDSC'//diag(icall),    horiz_only,   'A', 'W/m2', &
         629        1536 :                      'Clearsky downwelling solar flux at surface', sampling_seq='rad_lwsw')
         630             :
         631             :          ! Fluxes on CAM grid
         632             :          call addfld('FUS'//diag(icall),      (/ 'ilev' /), 'I', 'W/m2', &
         633        3072 :                      'Shortwave upward flux', sampling_seq='rad_lwsw')
         634             :          call addfld('FDS'//diag(icall),      (/ 'ilev' /), 'I', 'W/m2', &
         635        3072 :                      'Shortwave downward flux', sampling_seq='rad_lwsw')
         636             :          call addfld('FUSC'//diag(icall),     (/ 'ilev' /), 'I', 'W/m2', &
         637        3072 :                      'Shortwave clear-sky upward flux', sampling_seq='rad_lwsw')
         638             :          call addfld('FDSC'//diag(icall),     (/ 'ilev' /), 'I', 'W/m2', &
         639        3072 :                      'Shortwave clear-sky downward flux', sampling_seq='rad_lwsw')
         640             :
         641        1536 :          if (history_amwg) then
         642        1536 :             call add_default('SOLIN'//diag(icall),   1, ' ')
         643        1536 :             call add_default('QRS'//diag(icall),     1, ' ')
         644        1536 :             call add_default('FSNT'//diag(icall),    1, ' ')
         645        1536 :             call add_default('FSNTC'//diag(icall),   1, ' ')
         646        1536 :             call add_default('FSNTOA'//diag(icall),  1, ' ')
         647        1536 :             call add_default('FSNTOAC'//diag(icall), 1, ' ')
         648        1536 :             call add_default('SWCF'//diag(icall),    1, ' ')
         649        1536 :             call add_default('FSNS'//diag(icall),    1, ' ')
         650        1536 :             call add_default('FSNSC'//diag(icall),   1, ' ')
         651        1536 :             call add_default('FSUTOA'//diag(icall),  1, ' ')
         652        1536 :             call add_default('FSDSC'//diag(icall),   1, ' ')
         653        1536 :             call add_default('FSDS'//diag(icall),    1, ' ')
         654             :          endif
         655             :
         656             :       end if
         657             :    end do
         658             :
         659        1536 :    if (scm_crm_mode) then
         660           0 :       call add_default('FUS     ', 1, ' ')
         661           0 :       call add_default('FUSC    ', 1, ' ')
         662           0 :       call add_default('FDS     ', 1, ' ')
         663           0 :       call add_default('FDSC    ', 1, ' ')
         664             :    endif
         665             :
         666             :    ! Add longwave radiation fields to history master field list.
         667             :
         668       18432 :    do icall = 0, N_DIAG
         669             :
         670       18432 :       if (active_calls(icall)) then
         671             :          call addfld('QRL'//diag(icall),     (/ 'lev' /), 'A', 'K/s',  &
         672        3072 :                      'Longwave heating rate', sampling_seq='rad_lwsw')
         673             :          call addfld('QRLC'//diag(icall),    (/ 'lev' /), 'A', 'K/s',  &
         674        3072 :                      'Clearsky longwave heating rate', sampling_seq='rad_lwsw')
         675             :          call addfld('FLNT'//diag(icall),    horiz_only,  'A', 'W/m2', &
         676        1536 :                      'Net longwave flux at top of model', sampling_seq='rad_lwsw')
         677             :          call addfld('FLNTC'//diag(icall),   horiz_only,  'A', 'W/m2', &
         678        1536 :                      'Clearsky net longwave flux at top of model', sampling_seq='rad_lwsw')
         679             :          call addfld('FLUT'//diag(icall),    horiz_only,  'A', 'W/m2', &
         680        1536 :                      'Upwelling longwave flux at top of model', sampling_seq='rad_lwsw')
         681             :          call addfld('FLUTC'//diag(icall),   horiz_only,  'A', 'W/m2', &
         682        1536 :                      'Clearsky upwelling longwave flux at top of model', sampling_seq='rad_lwsw')
         683             :          call addfld('LWCF'//diag(icall),    horiz_only,  'A', 'W/m2', &
         684        1536 :                      'Longwave cloud forcing', sampling_seq='rad_lwsw')
         685             :          call addfld('FLN200'//diag(icall),  horiz_only,  'A', 'W/m2', &
         686        1536 :                      'Net longwave flux at 200 mb', sampling_seq='rad_lwsw')
         687             :          call addfld('FLN200C'//diag(icall), horiz_only,  'A', 'W/m2', &
         688        1536 :                      'Clearsky net longwave flux at 200 mb', sampling_seq='rad_lwsw')
         689             :          call addfld('FLNR'//diag(icall),    horiz_only,  'A', 'W/m2', &
         690        1536 :                      'Net longwave flux at tropopause', sampling_seq='rad_lwsw')
         691             :          call addfld('FLNS'//diag(icall),    horiz_only,  'A', 'W/m2', &
         692        1536 :                      'Net longwave flux at surface', sampling_seq='rad_lwsw')
         693             :          call addfld('FLNSC'//diag(icall),   horiz_only,  'A', 'W/m2', &
         694        1536 :                      'Clearsky net longwave flux at surface', sampling_seq='rad_lwsw')
         695             :          call addfld('FLDS'//diag(icall),    horiz_only,  'A', 'W/m2', &
         696        1536 :                      'Downwelling longwave flux at surface', sampling_seq='rad_lwsw')
         697             :          call addfld('FLDSC'//diag(icall),   horiz_only,  'A', 'W/m2', &
         698        1536 :                      'Clearsky Downwelling longwave flux at surface', sampling_seq='rad_lwsw')
         699             :
         700             :          ! Fluxes on CAM grid
         701             :          call addfld('FUL'//diag(icall),    (/ 'ilev' /), 'I', 'W/m2', &
         702        3072 :                      'Longwave upward flux', sampling_seq='rad_lwsw')
         703             :          call addfld('FDL'//diag(icall),    (/ 'ilev' /), 'I', 'W/m2', &
         704        3072 :                      'Longwave downward flux', sampling_seq='rad_lwsw')
         705             :          call addfld('FULC'//diag(icall),   (/ 'ilev' /), 'I', 'W/m2', &
         706        3072 :                      'Longwave clear-sky upward flux', sampling_seq='rad_lwsw')
         707             :          call addfld('FDLC'//diag(icall),   (/ 'ilev' /), 'I', 'W/m2', &
         708        3072 :                      'Longwave clear-sky downward flux', sampling_seq='rad_lwsw')
         709             :
         710        1536 :          if (history_amwg) then
         711        1536 :             call add_default('QRL'//diag(icall),   1, ' ')
         712        1536 :             call add_default('FLNT'//diag(icall),  1, ' ')
         713        1536 :             call add_default('FLNTC'//diag(icall), 1, ' ')
         714        1536 :             call add_default('FLUT'//diag(icall),  1, ' ')
         715        1536 :             call add_default('FLUTC'//diag(icall), 1, ' ')
         716        1536 :             call add_default('LWCF'//diag(icall),  1, ' ')
         717        1536 :             call add_default('FLNS'//diag(icall),  1, ' ')
         718        1536 :             call add_default('FLNSC'//diag(icall), 1, ' ')
         719        1536 :             call add_default('FLDS'//diag(icall),  1, ' ')
         720             :          end if
         721             :
         722             :       end if
         723             :    end do
         724             :
         725        3072 :    call addfld('EMIS', (/ 'lev' /), 'A', '1', 'Cloud longwave emissivity')
         726             :
         727        1536 :    if (scm_crm_mode) then
         728           0 :       call add_default ('FUL     ', 1, ' ')
         729           0 :       call add_default ('FULC    ', 1, ' ')
         730           0 :       call add_default ('FDL     ', 1, ' ')
         731           0 :       call add_default ('FDLC    ', 1, ' ')
         732             :    endif
         733             :
         734             :    ! Heating rate needed for d(theta)/dt computation
         735        3072 :    call addfld ('HR',(/ 'lev' /), 'A','K/s','Heating rate needed for d(theta)/dt computation')
         736             :
         737        1536 :    if ( history_budget .and. history_budget_histfile_num > 1 ) then
         738           0 :       call add_default ('QRL     ', history_budget_histfile_num, ' ')
         739           0 :       call add_default ('QRS     ', history_budget_histfile_num, ' ')
         740             :    end if
         741             :
         742        1536 :    if (history_vdiag) then
         743           0 :       call add_default('FLUT', 2, ' ')
         744           0 :       call add_default('FLUT', 3, ' ')
         745             :    end if
         746             :
         747        3072 : end subroutine radiation_init
         748             :
         749             : !===============================================================================
         750             :
         751        1536 : subroutine radiation_define_restart(file)
         752             :
         753             :    ! define variables to be written to restart file
         754             :
         755             :    ! arguments
         756             :    type(file_desc_t), intent(inout) :: file
         757             :
         758             :    ! local variables
         759             :    integer :: ierr
         760             :    !----------------------------------------------------------------------------
         761             :
         762        1536 :    call pio_seterrorhandling(file, PIO_BCAST_ERROR)
         763             :
         764        1536 :    ierr = pio_def_var(file, 'nextsw_cday', pio_double, nextsw_cday_desc)
         765        1536 :    ierr = pio_put_att(file, nextsw_cday_desc, 'long_name', 'future radiation calday for surface models')
         766        1536 :    if (docosp) then
         767           0 :       ierr = pio_def_var(File, 'cosp_cnt_init', pio_int, cospcnt_desc)
         768             :    end if
         769             :
         770        1536 : end subroutine radiation_define_restart
         771             :
         772             : !===============================================================================
         773             :
         774        1536 : subroutine radiation_write_restart(file)
         775             :
         776             :    ! write variables to restart file
         777             :
         778             :    ! arguments
         779             :    type(file_desc_t), intent(inout) :: file
         780             :
         781             :    ! local variables
         782             :    integer :: ierr
         783             :    !----------------------------------------------------------------------------
         784        3072 :    ierr = pio_put_var(File, nextsw_cday_desc, (/ nextsw_cday /))
         785        1536 :    if (docosp) then
         786           0 :       ierr = pio_put_var(File, cospcnt_desc, (/cosp_cnt(begchunk)/))
         787             :    end if
         788             :
         789        1536 : end subroutine radiation_write_restart
         790             :
         791             : !===============================================================================
         792             :
         793         768 : subroutine radiation_read_restart(file)
         794             :
         795             :    ! read variables from restart file
         796             :
         797             :    ! arguments
         798             :    type(file_desc_t), intent(inout) :: file
         799             :
         800             :    ! local variables
         801             :    integer :: ierr
         802             :    type(var_desc_t) :: vardesc
         803             :    integer :: err_handling
         804             :
         805             :    !----------------------------------------------------------------------------
         806         768 :    if (docosp) then
         807           0 :       call pio_seterrorhandling(File, PIO_BCAST_ERROR, err_handling)
         808           0 :       ierr = pio_inq_varid(File, 'cosp_cnt_init', vardesc)
         809           0 :       call pio_seterrorhandling(File, err_handling)
         810           0 :       if (ierr /= PIO_NOERR) then
         811           0 :          cosp_cnt_init = 0
         812             :       else
         813           0 :          ierr = pio_get_var(File, vardesc, cosp_cnt_init)
         814             :       end if
         815             :    end if
         816             :
         817         768 :    ierr = pio_inq_varid(file, 'nextsw_cday', vardesc)
         818         768 :    ierr = pio_get_var(file, vardesc, nextsw_cday)
         819             :
         820             :
         821         768 : end subroutine radiation_read_restart
         822             :
         823             : !===============================================================================
         824             :
         825    17907264 : subroutine radiation_tend( &
         826             :    state, ptend, pbuf, cam_out, cam_in, net_flx, rd_out)
         827             :
         828             :    !-----------------------------------------------------------------------
         829             :    !
         830             :    ! CAM driver for radiation computation.
         831             :    !
         832             :    !-----------------------------------------------------------------------
         833             :
         834             :    ! Location/Orbital Parameters for cosine zenith angle
         835             :    use phys_grid,          only: get_rlat_all_p, get_rlon_all_p
         836             :    use cam_control_mod,    only: eccen, mvelpp, lambm0, obliqr
         837             :    use shr_orb_mod,        only: shr_orb_decl, shr_orb_cosz
         838             :
         839             :    use rrtmgp_inputs,      only: rrtmgp_set_state, rrtmgp_set_gases_lw, rrtmgp_set_cloud_lw, &
         840             :                                  rrtmgp_set_aer_lw, rrtmgp_set_gases_sw, rrtmgp_set_cloud_sw, &
         841             :                                  rrtmgp_set_aer_sw
         842             :
         843             :    ! RRTMGP drivers for flux calculations.
         844             :    use mo_rte_lw,          only: rte_lw
         845             :    use mo_rte_sw,          only: rte_sw
         846             :
         847             :    use radheat,            only: radheat_tend
         848             :
         849             :    use radiation_data,     only: rad_data_write
         850             :
         851             :    use interpolate_data,   only: vertinterp
         852             :    use tropopause,         only: tropopause_find_cam, TROP_ALG_HYBSTOB, TROP_ALG_CLIMATE
         853             :    use cospsimulator_intr, only: docosp, cospsimulator_intr_run, cosp_nradsteps
         854             :
         855             :
         856             :    ! Arguments
         857             :    type(physics_state), intent(in), target :: state
         858             :    type(physics_ptend), intent(out)        :: ptend
         859             :    type(physics_buffer_desc), pointer      :: pbuf(:)
         860             :    type(cam_out_t),     intent(inout)      :: cam_out
         861             :    type(cam_in_t),      intent(in)         :: cam_in
         862             :    real(r8),            intent(out)        :: net_flx(pcols)
         863             :
         864             :    type(rad_out_t), target, optional, intent(out) :: rd_out
         865             :
         866             :
         867             :    ! Local variables
         868             :    type(rad_out_t), pointer :: rd  ! allow rd_out to be optional by allocating a local object
         869             :                                    ! if the argument is not present
         870             :    logical  :: write_output
         871             :
         872             :    integer  :: i, k, istat
         873             :    integer  :: lchnk, ncol
         874             :    logical  :: dosw, dolw
         875             :    integer  :: icall           ! loop index for climate/diagnostic radiation calls
         876             :
         877             :    real(r8) :: calday          ! current calendar day
         878             :    real(r8) :: delta           ! Solar declination angle  in radians
         879             :    real(r8) :: eccf            ! Earth orbit eccentricity factor
         880             :    real(r8) :: clat(pcols)     ! current latitudes(radians)
         881             :    real(r8) :: clon(pcols)     ! current longitudes(radians)
         882             :    real(r8) :: coszrs(pcols)   ! Cosine solar zenith angle
         883             :
         884             :    ! Gathered indices of day and night columns
         885             :    !  chunk_column_index = IdxDay(daylight_column_index)
         886             :    integer :: Nday           ! Number of daylight columns
         887             :    integer :: Nnite          ! Number of night columns
         888             :    integer :: IdxDay(pcols)  ! chunk indices of daylight columns
         889             :    integer :: IdxNite(pcols) ! chunk indices of night columns
         890             :
         891             :    integer :: itim_old
         892             :
         893     1492272 :    real(r8), pointer :: cld(:,:)      ! cloud fraction
         894     1492272 :    real(r8), pointer :: cldfsnow(:,:) ! cloud fraction of just "snow clouds"
         895     1492272 :    real(r8), pointer :: cldfgrau(:,:) ! cloud fraction of just "graupel clouds"
         896             :    real(r8)          :: cldfprime(pcols,pver)   ! combined cloud fraction
         897     1492272 :    real(r8), pointer :: qrs(:,:) ! shortwave radiative heating rate
         898     1492272 :    real(r8), pointer :: qrl(:,:) ! longwave  radiative heating rate
         899     1492272 :    real(r8), pointer :: fsds(:)  ! Surface solar down flux
         900     1492272 :    real(r8), pointer :: fsns(:)  ! Surface solar absorbed flux
         901     1492272 :    real(r8), pointer :: fsnt(:)  ! Net column abs solar flux at model top
         902     1492272 :    real(r8), pointer :: flns(:)  ! Srf longwave cooling (up-down) flux
         903     1492272 :    real(r8), pointer :: flnt(:)  ! Net outgoing lw flux at model top
         904             :
         905             :    real(r8), pointer, dimension(:,:,:) :: su => NULL()  ! shortwave spectral flux up
         906             :    real(r8), pointer, dimension(:,:,:) :: sd => NULL()  ! shortwave spectral flux down
         907             :    real(r8), pointer, dimension(:,:,:) :: lu => NULL()  ! longwave  spectral flux up
         908             :    real(r8), pointer, dimension(:,:,:) :: ld => NULL()  ! longwave  spectral flux down
         909             :
         910             :    ! tropopause diagnostic
         911             :    integer  :: troplev(pcols)
         912             :    real(r8) :: p_trop(pcols)
         913             :
         914             :    ! state data passed to radiation calc
         915     1492272 :    real(r8), allocatable :: t_sfc(:)
         916     1492272 :    real(r8), allocatable :: emis_sfc(:,:)
         917     1492272 :    real(r8), allocatable :: t_rad(:,:)
         918     1492272 :    real(r8), allocatable :: pmid_rad(:,:)
         919     1492272 :    real(r8), allocatable :: pint_rad(:,:)
         920     1492272 :    real(r8), allocatable :: t_day(:,:)
         921     1492272 :    real(r8), allocatable :: pmid_day(:,:)
         922     1492272 :    real(r8), allocatable :: pint_day(:,:)
         923     1492272 :    real(r8), allocatable :: coszrs_day(:)
         924     1492272 :    real(r8), allocatable :: alb_dir(:,:)
         925     1492272 :    real(r8), allocatable :: alb_dif(:,:)
         926             :
         927             :    ! in-cloud optical depths for COSP
         928             :    real(r8) :: cld_tau_cloudsim(pcols,pver)    ! liq + ice
         929             :    real(r8) :: snow_tau_cloudsim(pcols,pver)   ! snow
         930             :    real(r8) :: grau_tau_cloudsim(pcols,pver)   ! graupel
         931             :    real(r8) :: cld_lw_abs_cloudsim(pcols,pver) ! liq + ice
         932             :    real(r8) :: snow_lw_abs_cloudsim(pcols,pver)! snow
         933             :    real(r8) :: grau_lw_abs_cloudsim(pcols,pver)! graupel
         934             :
         935             :    ! Set vertical indexing in RRTMGP to be the same as CAM (top to bottom).
         936             :    logical, parameter :: top_at_1 = .true.
         937             :
         938             :    ! TOA solar flux on RRTMGP g-points
         939     1492272 :    real(r8), allocatable :: toa_flux(:,:)
         940             :    ! TSI from RRTMGP data (from sum over g-point representation)
         941             :    real(r8) :: tsi_ref
         942             :
         943             :    ! Planck sources for LW.
         944     1492272 :    type(ty_source_func_lw) :: sources_lw
         945             :
         946             :    ! Gas volume mixing ratios.  Use separate objects for LW and SW because SW only does
         947             :    ! calculations for daylight columns.
         948             :    ! These objects have a final method which deallocates the internal memory when they
         949             :    ! go out of scope (i.e., when radiation_tend returns), so no need for explicit deallocation.
         950     1492272 :    type(ty_gas_concs) :: gas_concs_lw
         951     1492272 :    type(ty_gas_concs) :: gas_concs_sw
         952             :
         953             :    ! Atmosphere optics.  This object is initialized with gas optics, then is incremented
         954             :    ! by the aerosol optics for the clear-sky radiative flux calculations, and then
         955             :    ! incremented again by the cloud optics for the all-sky radiative flux calculations.
         956     1492272 :    type(ty_optical_props_1scl) :: atm_optics_lw
         957     1492272 :    type(ty_optical_props_2str) :: atm_optics_sw
         958             :
         959             :    ! Cloud optical properties objects (McICA sampling of cloud optical properties).
         960     1492272 :    type(ty_optical_props_1scl) :: cloud_lw
         961     1492272 :    type(ty_optical_props_2str) :: cloud_sw
         962             :
         963             :    ! Aerosol optical properties objects.
         964     1492272 :    type(ty_optical_props_1scl) :: aer_lw
         965     1492272 :    type(ty_optical_props_2str) :: aer_sw
         966             :
         967             :    ! Flux objects contain all fluxes computed by RRTMGP.
         968             :    ! SW allsky fluxes always include spectrally resolved fluxes needed for surface models.
         969             :    type(ty_fluxes_byband) :: fsw
         970             :    ! LW allsky fluxes only need spectrally resolved fluxes when spectralflux=.true.
         971             :    type(ty_fluxes_byband) :: flw
         972             :    ! Only broadband fluxes needed for clear sky (diagnostics).
         973             :    type(ty_fluxes_broadband) :: fswc, flwc
         974             :
         975             :    ! Arrays for output diagnostics on CAM grid.
         976             :    real(r8) :: fns(pcols,pverp)     ! net shortwave flux
         977             :    real(r8) :: fcns(pcols,pverp)    ! net clear-sky shortwave flux
         978             :    real(r8) :: fnl(pcols,pverp)     ! net longwave flux
         979             :    real(r8) :: fcnl(pcols,pverp)    ! net clear-sky longwave flux
         980             :
         981             :    ! for COSP
         982             :    real(r8) :: emis(pcols,pver)        ! Cloud longwave emissivity
         983             :    real(r8) :: gb_snow_tau(pcols,pver) ! grid-box mean snow_tau
         984             :    real(r8) :: gb_snow_lw(pcols,pver)  ! grid-box mean LW snow optical depth
         985             :
         986             :    real(r8) :: ftem(pcols,pver)        ! Temporary workspace for outfld variables
         987             :
         988             :    character(len=128) :: errmsg
         989             :    character(len=*), parameter :: sub = 'radiation_tend'
         990             :    !--------------------------------------------------------------------------------------
         991             :
         992     1492272 :    lchnk = state%lchnk
         993     1492272 :    ncol = state%ncol
         994             :
         995     1492272 :    if (present(rd_out)) then
         996           0 :       rd => rd_out
         997           0 :       write_output = .false.
         998             :    else
         999     1492272 :       allocate(rd, stat=istat)
        1000     1492272 :       call handle_allocate_error(istat, sub, 'rd')
        1001     1492272 :       write_output = .true.
        1002             :    end if
        1003             :
        1004     1492272 :    dosw = radiation_do('sw', get_nstep())      ! do shortwave radiation calc this timestep?
        1005     1492272 :    dolw = radiation_do('lw', get_nstep())      ! do longwave radiation calc this timestep?
        1006             :
        1007             :    ! Cosine solar zenith angle for current time step
        1008     1492272 :    calday = get_curr_calday()
        1009     1492272 :    call get_rlat_all_p(lchnk, ncol, clat)
        1010     1492272 :    call get_rlon_all_p(lchnk, ncol, clon)
        1011             :
        1012             :    call shr_orb_decl(calday, eccen, mvelpp, lambm0, obliqr, &
        1013     1492272 :                      delta, eccf)
        1014             :
        1015     1492272 :    if (use_rad_uniform_angle) then
        1016           0 :       do i = 1, ncol
        1017           0 :          coszrs(i) = shr_orb_cosz(calday, clat(i), clon(i), delta, dt_avg, &
        1018           0 :                                   uniform_angle=rad_uniform_angle)
        1019             :       end do
        1020             :    else
        1021    24917472 :       do i = 1, ncol
        1022             :          ! if dt_avg /= 0, it triggers using avg coszrs
        1023    24917472 :          coszrs(i) = shr_orb_cosz(calday, clat(i), clon(i), delta, dt_avg)
        1024             :       end do
        1025             :    end if
        1026             :
        1027             :    ! Gather night/day column indices.
        1028     1492272 :    Nday = 0
        1029     1492272 :    Nnite = 0
        1030    24917472 :    do i = 1, ncol
        1031    24917472 :       if ( coszrs(i) > 0.0_r8 ) then
        1032    11712600 :          Nday = Nday + 1
        1033    11712600 :          IdxDay(Nday) = i
        1034             :       else
        1035    11712600 :          Nnite = Nnite + 1
        1036    11712600 :          IdxNite(Nnite) = i
        1037             :       end if
        1038             :    end do
        1039             :
        1040             :    ! Associate pointers to physics buffer fields
        1041     1492272 :    itim_old = pbuf_old_tim_idx()
        1042     1492272 :    nullify(cldfsnow)
        1043     1492272 :    if (cldfsnow_idx > 0) then
        1044     5969088 :       call pbuf_get_field(pbuf, cldfsnow_idx, cldfsnow, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
        1045             :    end if
        1046     1492272 :    nullify(cldfgrau)
        1047     1492272 :    if (cldfgrau_idx > 0 .and. graupel_in_rad) then
        1048           0 :       call pbuf_get_field(pbuf, cldfgrau_idx, cldfgrau, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
        1049             :    endif
        1050             :
        1051     5969088 :    call pbuf_get_field(pbuf, cld_idx, cld, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
        1052             :
        1053     1492272 :    call pbuf_get_field(pbuf, qrs_idx, qrs)
        1054     1492272 :    call pbuf_get_field(pbuf, qrl_idx, qrl)
        1055             :
        1056     1492272 :    call pbuf_get_field(pbuf, fsns_idx, fsns)
        1057     1492272 :    call pbuf_get_field(pbuf, fsnt_idx, fsnt)
        1058     1492272 :    call pbuf_get_field(pbuf, fsds_idx, fsds)
        1059     1492272 :    call pbuf_get_field(pbuf, flns_idx, flns)
        1060     1492272 :    call pbuf_get_field(pbuf, flnt_idx, flnt)
        1061             :
        1062     1492272 :    if (spectralflux) then
        1063           0 :       call pbuf_get_field(pbuf, su_idx, su)
        1064           0 :       call pbuf_get_field(pbuf, sd_idx, sd)
        1065           0 :       call pbuf_get_field(pbuf, lu_idx, lu)
        1066           0 :       call pbuf_get_field(pbuf, ld_idx, ld)
        1067             :    end if
        1068             :
        1069             :    ! Allocate the flux arrays and init to zero.
        1070     1492272 :    call initialize_rrtmgp_fluxes(nday, nlay+1, nswbands, fsw, do_direct=.true.)
        1071     1492272 :    call initialize_rrtmgp_fluxes(nday, nlay+1, nswbands, fswc, do_direct=.true.)
        1072     1492272 :    call initialize_rrtmgp_fluxes(ncol, nlay+1, nlwbands, flw)
        1073     1492272 :    call initialize_rrtmgp_fluxes(ncol, nlay+1, nlwbands, flwc)
        1074             :
        1075             :    !  For CRM, make cloud equal to input observations:
        1076     1492272 :    if (scm_crm_mode .and. have_cld) then
        1077           0 :       do k = 1, pver
        1078           0 :          cld(:ncol,k)= cldobs(k)
        1079             :       end do
        1080             :    end if
        1081             :
        1082             :    ! Find tropopause height if needed for diagnostic output
        1083     1492272 :    if (hist_fld_active('FSNR') .or. hist_fld_active('FLNR')) then
        1084             :       !REMOVECAM - no longer need this when CAM is retired and pcols no longer exists
        1085           0 :       troplev(:) = 0
        1086           0 :       p_trop(:) = 0._r8
        1087             :       !REMOVECAM_END
        1088             :       call tropopause_find_cam(state, troplev, tropP=p_trop, primary=TROP_ALG_HYBSTOB, &
        1089           0 :                            backup=TROP_ALG_CLIMATE)
        1090             :    end if
        1091             :
        1092             :    ! Get time of next radiation calculation - albedos will need to be
        1093             :    ! calculated by each surface model at this time
        1094     1492272 :    nextsw_cday = radiation_nextsw_cday()
        1095             :
        1096     1492272 :    if (dosw .or. dolw) then
        1097             :
        1098             :       allocate( &
        1099             :          t_sfc(ncol), emis_sfc(nlwbands,ncol), toa_flux(nday,nswgpts),     &
        1100             :          t_rad(ncol,nlay), pmid_rad(ncol,nlay), pint_rad(ncol,nlay+1),     &
        1101             :          t_day(nday,nlay), pmid_day(nday,nlay), pint_day(nday,nlay+1),     &
        1102             :          coszrs_day(nday), alb_dir(nswbands,nday), alb_dif(nswbands,nday), &
        1103    19139833 :          stat=istat)
        1104      746136 :       call handle_allocate_error(istat, sub, 't_sfc,..,alb_dif')
        1105             :
        1106             :       ! Prepares state variables, daylit columns, albedos for RRTMGP
        1107             :       call rrtmgp_set_state( &
        1108             :          state, cam_in, ncol, nlay, nday,             &
        1109             :          idxday, coszrs, kdist_sw, t_sfc, emis_sfc,   &
        1110             :          t_rad, pmid_rad, pint_rad, t_day, pmid_day,  &
        1111      746136 :          pint_day, coszrs_day, alb_dir, alb_dif)
        1112             :
        1113             :       ! Output the mass per layer, and total column burdens for gas and aerosol
        1114             :       ! constituents in the climate list.
        1115      746136 :       call rad_cnst_out(0, state, pbuf)
        1116             :
        1117             :       ! Modified cloud fraction accounts for radiatively active snow and/or graupel
        1118      746136 :       call modified_cloud_fraction(ncol, cld, cldfsnow, cldfgrau, cldfprime)
        1119             :
        1120             :       !========================!
        1121             :       ! SHORTWAVE calculations !
        1122             :       !========================!
        1123             :
        1124      746136 :       if (dosw) then
        1125             :
        1126             :          ! Set cloud optical properties in cloud_sw object.
        1127             :          call rrtmgp_set_cloud_sw( &
        1128             :             state, pbuf, nlay, nday, idxday,                              &
        1129             :             nnite, idxnite, pmid_day, cld, cldfsnow,                      &
        1130             :             cldfgrau, cldfprime, graupel_in_rad, kdist_sw, cloud_sw,      &
        1131             :             rd%tot_cld_vistau, rd%tot_icld_vistau, rd%liq_icld_vistau,    &
        1132             :             rd%ice_icld_vistau, rd%snow_icld_vistau, rd%grau_icld_vistau, &
        1133      746136 :             cld_tau_cloudsim, snow_tau_cloudsim, grau_tau_cloudsim )
        1134             :
        1135      746136 :          if (write_output) then
        1136      746136 :             call radiation_output_cld(lchnk, rd)
        1137             :          end if
        1138             :
        1139             :          ! If no daylight columns, can't create empty RRTMGP objects
        1140      746136 :          if (nday > 0) then
        1141             :
        1142             :             ! Initialize object for gas concentrations.
        1143      389263 :             errmsg = gas_concs_sw%init(gaslist_lc)
        1144      389263 :             call stop_on_err(errmsg, sub, 'gas_concs_sw%init')
        1145             :
        1146             :             ! Initialize object for combined gas + aerosol + cloud optics.
        1147             :             ! Allocates arrays for properties represented on g-points.
        1148      389263 :             errmsg = atm_optics_sw%alloc_2str(nday, nlay, kdist_sw)
        1149      389263 :             call stop_on_err(errmsg, sub, 'atm_optics_sw%alloc_2str')
        1150             :
        1151             :             ! Initialize object for SW aerosol optics.  Allocates arrays
        1152             :             ! for properties represented by band.
        1153      389263 :             errmsg = aer_sw%alloc_2str(nday, nlay, kdist_sw%get_band_lims_wavenumber())
        1154      389263 :             call stop_on_err(errmsg, sub, 'aer_sw%alloc_2str')
        1155             :
        1156             :          end if
        1157             :
        1158             :          ! The climate (icall==0) calculation must occur last.
        1159     8953632 :          do icall = N_DIAG, 0, -1
        1160     8953632 :             if (active_calls(icall)) then
        1161             :
        1162      746136 :                if (nday > 0) then
        1163             :
        1164             :                   ! Set gas volume mixing ratios for this call in gas_concs_sw.
        1165             :                   call rrtmgp_set_gases_sw( &
        1166             :                      icall, state, pbuf, nlay, nday, &
        1167      389263 :                      idxday, gas_concs_sw)
        1168             :
        1169             :                   ! Compute the gas optics (stored in atm_optics_sw).
        1170             :                   ! toa_flux is the reference solar source from RRTMGP data.
        1171             :                   errmsg = kdist_sw%gas_optics( &
        1172             :                      pmid_day, pint_day, t_day, gas_concs_sw, atm_optics_sw, &
        1173      389263 :                      toa_flux)
        1174      389263 :                   call stop_on_err(errmsg, sub, 'kdist_sw%gas_optics')
        1175             :
        1176             :                   ! Scale the solar source
        1177    43986719 :                   tsi_ref = sum(toa_flux(1,:))
        1178   699892319 :                   toa_flux = toa_flux * sol_tsi * eccf / tsi_ref
        1179             :
        1180             :                end if
        1181             :
        1182             :                ! Set SW aerosol optical properties in the aer_sw object.
        1183             :                ! This call made even when no daylight columns because it does some
        1184             :                ! diagnostic aerosol output.
        1185             :                call rrtmgp_set_aer_sw( &
        1186      746136 :                   icall, state, pbuf, nday, idxday, nnite, idxnite, aer_sw)
        1187             :
        1188      746136 :                if (nday > 0) then
        1189             :
        1190             :                   ! Increment the gas optics (in atm_optics_sw) by the aerosol optics in aer_sw.
        1191      389263 :                   errmsg = aer_sw%increment(atm_optics_sw)
        1192      389263 :                   call stop_on_err(errmsg, sub, 'aer_sw%increment')
        1193             :
        1194             :                   ! Compute clear-sky fluxes.
        1195             :                   errmsg = rte_sw(&
        1196             :                      atm_optics_sw, top_at_1, coszrs_day, toa_flux, &
        1197      389263 :                      alb_dir, alb_dif, fswc)
        1198      389263 :                   call stop_on_err(errmsg, sub, 'clear-sky rte_sw')
        1199             :
        1200             :                   ! Increment the aerosol+gas optics (in atm_optics_sw) by the cloud optics in cloud_sw.
        1201      389263 :                   errmsg = cloud_sw%increment(atm_optics_sw)
        1202      389263 :                   call stop_on_err(errmsg, sub, 'cloud_sw%increment')
        1203             :
        1204             :                   ! Compute all-sky fluxes.
        1205             :                   errmsg = rte_sw(&
        1206             :                      atm_optics_sw, top_at_1, coszrs_day, toa_flux, &
        1207      389263 :                      alb_dir, alb_dif, fsw)
        1208      389263 :                   call stop_on_err(errmsg, sub, 'all-sky rte_sw')
        1209             :
        1210             :                end if
        1211             :
        1212             :                ! Transform RRTMGP outputs to CAM outputs and compute heating rates.
        1213      746136 :                call set_sw_diags()
        1214             :
        1215      746136 :                if (write_output) then
        1216      746136 :                   call radiation_output_sw(lchnk, ncol, icall, rd, pbuf, cam_out)
        1217             :                end if
        1218             :
        1219             :             end if ! (active_calls(icall))
        1220             :          end do    ! loop over diagnostic calcs (icall)
        1221             :
        1222             :       else
        1223             :          ! SW calc not done.  pbuf carries Q*dp across timesteps.
        1224             :          ! Convert to Q before calling radheat_tend.
        1225           0 :          qrs(:ncol,:) = qrs(:ncol,:) / state%pdel(:ncol,:)
        1226             :       end if  ! if (dosw)
        1227             :
        1228             :       !=======================!
        1229             :       ! LONGWAVE calculations !
        1230             :       !=======================!
        1231             :
        1232      746136 :       if (dolw) then
        1233             :
        1234             :          ! Initialize object for Planck sources.
        1235      746136 :          errmsg = sources_lw%alloc(ncol, nlay, kdist_lw)
        1236      746136 :          call stop_on_err(errmsg, sub, 'sources_lw%alloc')
        1237             :
        1238             :          ! Set cloud optical properties in cloud_lw object.
        1239             :          call rrtmgp_set_cloud_lw( &
        1240             :             state, pbuf, ncol, nlay, nlaycam, &
        1241             :             cld, cldfsnow, cldfgrau, cldfprime, graupel_in_rad, &
        1242      746136 :             kdist_lw, cloud_lw, cld_lw_abs_cloudsim, snow_lw_abs_cloudsim, grau_lw_abs_cloudsim)
        1243             :
        1244             :          ! Initialize object for gas concentrations
        1245      746136 :          errmsg = gas_concs_lw%init(gaslist_lc)
        1246      746136 :          call stop_on_err(errmsg, sub, 'gas_concs_lw%init')
        1247             :
        1248             :          ! Initialize object for combined gas + aerosol + cloud optics.
        1249      746136 :          errmsg = atm_optics_lw%alloc_1scl(ncol, nlay, kdist_lw)
        1250      746136 :          call stop_on_err(errmsg, sub, 'atm_optics_lw%alloc_1scl')
        1251             :
        1252             :          ! Initialize object for LW aerosol optics.
        1253      746136 :          errmsg = aer_lw%alloc_1scl(ncol, nlay, kdist_lw%get_band_lims_wavenumber())
        1254      746136 :          call stop_on_err(errmsg, sub, 'aer_lw%alloc_1scl')
        1255             :
        1256             :          ! The climate (icall==0) calculation must occur last.
        1257     8953632 :          do icall = N_DIAG, 0, -1
        1258             :
        1259     8953632 :             if (active_calls(icall)) then
        1260             :
        1261             :                ! Set gas volume mixing ratios for this call in gas_concs_lw.
        1262      746136 :                call rrtmgp_set_gases_lw(icall, state, pbuf, nlay, gas_concs_lw)
        1263             :
        1264             :                ! Compute the gas optics and Planck sources.
        1265             :                errmsg = kdist_lw%gas_optics( &
        1266             :                   pmid_rad, pint_rad, t_rad, t_sfc, gas_concs_lw, &
        1267      746136 :                   atm_optics_lw, sources_lw)
        1268      746136 :                call stop_on_err(errmsg, sub, 'kdist_lw%gas_optics')
        1269             :
        1270             :                ! Set LW aerosol optical properties in the aer_lw object.
        1271      746136 :                call rrtmgp_set_aer_lw(icall, state, pbuf, aer_lw)
        1272             :
        1273             :                ! Increment the gas optics by the aerosol optics.
        1274      746136 :                errmsg = aer_lw%increment(atm_optics_lw)
        1275      746136 :                call stop_on_err(errmsg, sub, 'aer_lw%increment')
        1276             :
        1277             :                ! Compute clear-sky LW fluxes
        1278      746136 :                errmsg = rte_lw(atm_optics_lw, top_at_1, sources_lw, emis_sfc, flwc)
        1279      746136 :                call stop_on_err(errmsg, sub, 'clear-sky rte_lw')
        1280             :
        1281             :                ! Increment the gas+aerosol optics by the cloud optics.
        1282      746136 :                errmsg = cloud_lw%increment(atm_optics_lw)
        1283      746136 :                call stop_on_err(errmsg, sub, 'cloud_lw%increment')
        1284             :
        1285             :                ! Compute all-sky LW fluxes
        1286      746136 :                errmsg = rte_lw(atm_optics_lw, top_at_1, sources_lw, emis_sfc, flw)
        1287      746136 :                call stop_on_err(errmsg, sub, 'all-sky rte_lw')
        1288             :
        1289             :                ! Transform RRTMGP outputs to CAM outputs and compute heating rates.
        1290      746136 :                call set_lw_diags()
        1291             :
        1292      746136 :                if (write_output) then
        1293      746136 :                   call radiation_output_lw(lchnk, ncol, icall, rd, pbuf, cam_out)
        1294             :                end if
        1295             :
        1296             :             end if ! (active_calls(icall))
        1297             :          end do    ! loop over diagnostic calcs (icall)
        1298             :
        1299             :       else
        1300             :          ! LW calc not done.  pbuf carries Q*dp across timesteps.
        1301             :          ! Convert to Q before calling radheat_tend.
        1302           0 :         qrl(:ncol,:) = qrl(:ncol,:) / state%pdel(:ncol,:)
        1303             :       end if  ! if (dolw)
        1304             :
        1305           0 :       deallocate( &
        1306           0 :          t_sfc, emis_sfc, toa_flux, t_rad, pmid_rad, pint_rad,  &
        1307      746136 :          t_day, pmid_day, pint_day, coszrs_day, alb_dir, alb_dif)
        1308             :
        1309             :       !================!
        1310             :       ! COSP simulator !
        1311             :       !================!
        1312             :
        1313      746136 :       if (docosp) then
        1314             :
        1315           0 :          emis(:,:) = 0._r8
        1316           0 :          emis(:ncol,:) = 1._r8 - exp(-cld_lw_abs_cloudsim(:ncol,:))
        1317           0 :          call outfld('EMIS', emis, pcols, lchnk)
        1318             :
        1319             :          ! compute grid-box mean SW and LW snow optical depth for use by COSP
        1320           0 :          gb_snow_tau(:,:) = 0._r8
        1321           0 :          gb_snow_lw(:,:)  = 0._r8
        1322           0 :          if (cldfsnow_idx > 0) then
        1323           0 :             do i = 1, ncol
        1324           0 :                do k = 1, pver
        1325           0 :                   if (cldfsnow(i,k) > 0._r8) then
        1326             :
        1327             :                      ! Add graupel to snow tau for cosp
        1328           0 :                      if (cldfgrau_idx > 0 .and. graupel_in_rad) then
        1329           0 :                         gb_snow_tau(i,k) = snow_tau_cloudsim(i,k)*cldfsnow(i,k) + &
        1330           0 :                                            grau_tau_cloudsim(i,k)*cldfgrau(i,k)
        1331             :                         gb_snow_lw(i,k)  = snow_lw_abs_cloudsim(i,k)*cldfsnow(i,k) + &
        1332           0 :                                            grau_lw_abs_cloudsim(i,k)*cldfgrau(i,k)
        1333             :                      else
        1334           0 :                         gb_snow_tau(i,k) = snow_tau_cloudsim(i,k)*cldfsnow(i,k)
        1335           0 :                         gb_snow_lw(i,k)  = snow_lw_abs_cloudsim(i,k)*cldfsnow(i,k)
        1336             :                      end if
        1337             :                   end if
        1338             :                end do
        1339             :             end do
        1340             :          end if
        1341             :
        1342             :          ! advance counter for this timestep (chunk dimension required for thread safety)
        1343           0 :          cosp_cnt(lchnk) = cosp_cnt(lchnk) + 1
        1344             :
        1345             :          ! if counter is the same as cosp_nradsteps, run cosp and reset counter
        1346           0 :          if (cosp_nradsteps .eq. cosp_cnt(lchnk)) then
        1347             :
        1348             :             ! N.B.: For snow optical properties, the GRID-BOX MEAN shortwave and longwave
        1349             :             !       optical depths are passed.
        1350             :             call cospsimulator_intr_run( &
        1351             :                state,  pbuf, cam_in, emis, coszrs,                     &
        1352             :                cld_swtau_in=cld_tau_cloudsim, snow_tau_in=gb_snow_tau, &
        1353           0 :                snow_emis_in=gb_snow_lw)
        1354           0 :             cosp_cnt(lchnk) = 0
        1355             :          end if
        1356             :       end if   ! docosp
        1357             :
        1358             :    else
        1359             :       ! Radiative flux calculations not done.  The quantity Q*dp is carried by the
        1360             :       ! physics buffer across timesteps.  It must be converted to Q (dry static energy
        1361             :       ! tendency) before being passed to radheat_tend.
        1362  1159408584 :       qrs(:ncol,:) = qrs(:ncol,:) / state%pdel(:ncol,:)
        1363  1159408584 :       qrl(:ncol,:) = qrl(:ncol,:) / state%pdel(:ncol,:)
        1364             :
        1365             :    end if   ! if (dosw .or. dolw) then
        1366             :
        1367             :    ! Output for PORT: Parallel Offline Radiative Transport
        1368     1492272 :    call rad_data_write(pbuf, state, cam_in, coszrs)
        1369             :
        1370             :    ! Compute net radiative heating tendency.  Note that the WACCM version
        1371             :    ! of radheat_tend merges upper atmosphere heating rates with those calculated
        1372             :    ! by RRTMGP.
        1373             :    call radheat_tend(state, pbuf,  ptend, qrl, qrs, fsns, &
        1374     1492272 :                      fsnt, flns, flnt, cam_in%asdir, net_flx)
        1375             :
        1376     1492272 :    if (write_output) then
        1377             :       ! Compute heating rate for dtheta/dt
        1378   140273568 :       do k = 1, pver
        1379  2318817168 :          do i = 1, ncol
        1380  2317324896 :             ftem(i,k) = (qrs(i,k) + qrl(i,k))/cpair * (1.e5_r8/state%pmid(i,k))**cappa
        1381             :          end do
        1382             :       end do
        1383     1492272 :       call outfld('HR', ftem, pcols, lchnk)
        1384             :    end if
        1385             :
        1386             :    ! The radiative heating rates are carried in the physics buffer across timesteps
        1387             :    ! as Q*dp (for energy conservation).
        1388  2318817168 :    qrs(:ncol,:) = qrs(:ncol,:) * state%pdel(:ncol,:)
        1389  2318817168 :    qrl(:ncol,:) = qrl(:ncol,:) * state%pdel(:ncol,:)
        1390             :
        1391     1492272 :    if (.not. present(rd_out)) then
        1392     1492272 :       deallocate(rd)
        1393             :    end if
        1394     1492272 :    call free_optics_sw(atm_optics_sw)
        1395     1492272 :    call free_optics_sw(cloud_sw)
        1396     1492272 :    call free_optics_sw(aer_sw)
        1397     1492272 :    call free_fluxes(fsw)
        1398     1492272 :    call free_fluxes(fswc)
        1399             :
        1400     1492272 :    call sources_lw%finalize()
        1401     1492272 :    call free_optics_lw(cloud_lw)
        1402     1492272 :    call free_optics_lw(aer_lw)
        1403     1492272 :    call free_fluxes(flw)
        1404     2984544 :    call free_fluxes(flwc)
        1405             :
        1406             :    !-------------------------------------------------------------------------------
        1407             :    contains
        1408             :    !-------------------------------------------------------------------------------
        1409             :
        1410      746136 :    subroutine set_sw_diags()
        1411             :
        1412             :       ! Transform RRTMGP output for CAM and compute heating rates.
        1413             :       ! SW fluxes from RRTMGP are on daylight columns only, so expand to
        1414             :       ! full chunks for output to CAM history.
        1415             :
        1416             :       integer :: i
        1417             :       real(r8), dimension(size(fsw%bnd_flux_dn,1), &
        1418             :                           size(fsw%bnd_flux_dn,2), &
        1419     1492272 :                           size(fsw%bnd_flux_dn,3)) :: flux_dn_diffuse
        1420             :       !-------------------------------------------------------------------------
        1421             :
        1422             :       ! Initialize to provide 0.0 values for night columns.
        1423      746136 :       fns               = 0._r8 ! net sw flux
        1424      746136 :       fcns              = 0._r8 ! net sw clearsky flux
        1425    12684312 :       fsds              = 0._r8 ! downward sw flux at surface
        1426    12684312 :       rd%fsdsc          = 0._r8 ! downward sw clearsky flux at surface
        1427    12684312 :       rd%fsutoa         = 0._r8 ! upward sw flux at TOA
        1428    12684312 :       rd%fsntoa         = 0._r8 ! net sw at TOA
        1429    12684312 :       rd%fsntoac        = 0._r8 ! net sw clearsky flux at TOA
        1430    12684312 :       rd%solin          = 0._r8 ! solar irradiance at TOA
        1431  1193071464 :       rd%flux_sw_up     = 0._r8
        1432  1193071464 :       rd%flux_sw_dn     = 0._r8
        1433  1193071464 :       rd%flux_sw_clr_up = 0._r8
        1434  1193071464 :       rd%flux_sw_clr_dn = 0._r8
        1435             :
        1436  1180387152 :       qrs      = 0._r8
        1437    12684312 :       fsns     = 0._r8
        1438    12684312 :       fsnt     = 0._r8
        1439  1180387152 :       rd%qrsc  = 0._r8
        1440    12684312 :       rd%fsnsc = 0._r8
        1441    12684312 :       rd%fsntc = 0._r8
        1442             :
        1443     6602436 :       do i = 1, nday
        1444   556348500 :          fns(idxday(i),ktopcam:)  = fsw%flux_net(i, ktoprad:)
        1445   556348500 :          fcns(idxday(i),ktopcam:) = fswc%flux_net(i,ktoprad:)
        1446     5856300 :          fsds(idxday(i))          = fsw%flux_dn(i, nlay+1)
        1447     5856300 :          rd%fsdsc(idxday(i))      = fswc%flux_dn(i, nlay+1)
        1448     5856300 :          rd%fsutoa(idxday(i))     = fsw%flux_up(i, 1)
        1449     5856300 :          rd%fsntoa(idxday(i))     = fsw%flux_net(i, 1)
        1450     5856300 :          rd%fsntoac(idxday(i))    = fswc%flux_net(i, 1)
        1451     5856300 :          rd%solin(idxday(i))      = fswc%flux_dn(i, 1)
        1452   556348500 :          rd%flux_sw_up(idxday(i),ktopcam:)     = fsw%flux_up(i,ktoprad:)
        1453   556348500 :          rd%flux_sw_dn(idxday(i),ktopcam:)     = fsw%flux_dn(i,ktoprad:)
        1454   556348500 :          rd%flux_sw_clr_up(idxday(i),ktopcam:) = fswc%flux_up(i,ktoprad:)
        1455   557094636 :          rd%flux_sw_clr_dn(idxday(i),ktopcam:) = fswc%flux_dn(i,ktoprad:)
        1456             :       end do
        1457             :
        1458             :       ! Compute heating rate as a dry static energy tendency.
        1459      746136 :       call heating_rate('SW', ncol, fns, qrs)
        1460      746136 :       call heating_rate('SW', ncol, fcns, rd%qrsc)
        1461             :
        1462    12458736 :       fsns(:ncol)     = fns(:ncol,pverp)    ! net sw flux at surface
        1463    12458736 :       fsnt(:ncol)     = fns(:ncol,ktopcam)  ! net sw flux at top-of-model (w/o extra layer)
        1464    13204872 :       rd%fsnsc(:ncol) = fcns(:ncol,pverp)   ! net sw clearsky flux at surface
        1465    13204872 :       rd%fsntc(:ncol) = fcns(:ncol,ktopcam) ! net sw clearsky flux at top
        1466             :
        1467    12458736 :       cam_out%netsw(:ncol) = fsns(:ncol)
        1468             :
        1469             :       ! Output fluxes at 200 mb
        1470      746136 :       call vertinterp(ncol, pcols, pverp, state%pint, 20000._r8, fns,  rd%fsn200)
        1471      746136 :       call vertinterp(ncol, pcols, pverp, state%pint, 20000._r8, fcns, rd%fsn200c)
        1472      746136 :       if (hist_fld_active('FSNR')) then
        1473           0 :          do i = 1,ncol
        1474           0 :             call vertinterp(1, 1, pverp, state%pint(i,:), p_trop(i), fns(i,:), rd%fsnr(i))
        1475             :          end do
        1476             :       end if
        1477             :
        1478      746136 :       if (spectralflux) then
        1479           0 :          su  = 0._r8
        1480           0 :          sd  = 0._r8
        1481           0 :          do i = 1, nday
        1482           0 :             su(idxday(i),ktopcam:,:) = fsw%bnd_flux_up(i,ktoprad:,:)
        1483           0 :             sd(idxday(i),ktopcam:,:) = fsw%bnd_flux_dn(i,ktoprad:,:)
        1484             :          end do
        1485             :       end if
        1486             :
        1487             :       ! Export surface fluxes
        1488             :       ! sols(pcols)      Direct solar rad on surface (< 0.7)
        1489             :       ! soll(pcols)      Direct solar rad on surface (>= 0.7)
        1490             :       ! RRTMGP: Near-IR bands (1-10), 820-16000 cm-1, 0.625-12.195 microns
        1491             :       ! Put half of band 10 in each of the UV/visible and near-IR values,
        1492             :       ! since this band straddles 0.7 microns:
        1493             :       ! UV/visible bands 10-13, 16000-50000 cm-1, 0.200-0.625 micron
        1494             :
        1495             :       ! reset fluxes
        1496    12684312 :       cam_out%sols  = 0.0_r8
        1497    12684312 :       cam_out%soll  = 0.0_r8
        1498    12684312 :       cam_out%solsd = 0.0_r8
        1499    12684312 :       cam_out%solld = 0.0_r8
        1500             :
        1501             :       ! Calculate diffuse flux from total and direct
        1502  8792431920 :       flux_dn_diffuse = fsw%bnd_flux_dn - fsw%bnd_flux_dn_dir
        1503             :
        1504     6602436 :       do i = 1, nday
        1505    17568900 :          cam_out%soll(idxday(i)) = sum(fsw%bnd_flux_dn_dir(i,nlay+1,1:9))      &
        1506    76131900 :                                    + 0.5_r8 * fsw%bnd_flux_dn_dir(i,nlay+1,10)
        1507             :
        1508     5856300 :          cam_out%sols(idxday(i)) = 0.5_r8 * fsw%bnd_flux_dn_dir(i,nlay+1,10)   &
        1509    35137800 :                                    + sum(fsw%bnd_flux_dn_dir(i,nlay+1,11:14))
        1510             :
        1511    11712600 :          cam_out%solld(idxday(i)) = sum(flux_dn_diffuse(i,nlay+1,1:9))         &
        1512    70275600 :                                     + 0.5_r8 * flux_dn_diffuse(i,nlay+1,10)
        1513             :
        1514     5856300 :          cam_out%solsd(idxday(i)) = 0.5_r8 * flux_dn_diffuse(i, nlay+1, 10)    &
        1515    41740236 :                                     + sum(flux_dn_diffuse(i,nlay+1,11:14))
        1516             :       end do
        1517             :
        1518     1492272 :    end subroutine set_sw_diags
        1519             :
        1520             :    !-------------------------------------------------------------------------------
        1521             :
        1522      746136 :    subroutine set_lw_diags()
        1523             :
        1524             :       ! Set CAM LW diagnostics
        1525             :       !----------------------------------------------------------------------------
        1526             :
        1527      746136 :       fnl = 0._r8
        1528      746136 :       fcnl = 0._r8
        1529             :
        1530             :       ! RTE-RRTMGP convention for net is (down - up) **CAM assumes (up - down) !!
        1531  1171867320 :       fnl(:ncol,ktopcam:)  = -1._r8 * flw%flux_net(    :, ktoprad:)
        1532  1171867320 :       fcnl(:ncol,ktopcam:) = -1._r8 * flwc%flux_net(   :, ktoprad:)
        1533             :
        1534  1171867320 :       rd%flux_lw_up(:ncol,ktopcam:)     = flw%flux_up( :, ktoprad:)
        1535  1171867320 :       rd%flux_lw_clr_up(:ncol,ktopcam:) = flwc%flux_up(:, ktoprad:)
        1536  1171867320 :       rd%flux_lw_dn(:ncol,ktopcam:)     = flw%flux_dn( :, ktoprad:)
        1537  1171867320 :       rd%flux_lw_clr_dn(:ncol,ktopcam:) = flwc%flux_dn(:, ktoprad:)
        1538             :
        1539      746136 :       call heating_rate('LW', ncol, fnl, qrl)
        1540      746136 :       call heating_rate('LW', ncol, fcnl, rd%qrlc)
        1541             :
        1542    12458736 :       flns(:ncol) = fnl(:ncol, pverp)
        1543    12458736 :       flnt(:ncol) = fnl(:ncol, ktopcam)
        1544             :
        1545    13204872 :       rd%flnsc(:ncol) = fcnl(:ncol, pverp)
        1546    13204872 :       rd%flntc(:ncol) = fcnl(:ncol, ktopcam)    ! net lw flux at top-of-model
        1547             :
        1548    12458736 :       cam_out%flwds(:ncol) = flw%flux_dn(:, nlay+1)
        1549    12458736 :       rd%fldsc(:ncol)      = flwc%flux_dn(:, nlay+1)
        1550             :
        1551    12458736 :       rd%flut(:ncol)  = flw%flux_up(:, ktoprad)
        1552    12458736 :       rd%flutc(:ncol) = flwc%flux_up(:, ktoprad)
        1553             :
        1554             :       ! Output fluxes at 200 mb
        1555      746136 :       call vertinterp(ncol, pcols, pverp, state%pint, 20000._r8, fnl,  rd%fln200)
        1556      746136 :       call vertinterp(ncol, pcols, pverp, state%pint, 20000._r8, fcnl, rd%fln200c)
        1557      746136 :       if (hist_fld_active('FLNR')) then
        1558           0 :          do i = 1,ncol
        1559           0 :             call vertinterp(1, 1, pverp, state%pint(i,:), p_trop(i), fnl(i,:), rd%flnr(i))
        1560             :          end do
        1561             :       end if
        1562             :
        1563      746136 :       if (spectralflux) then
        1564           0 :          lu  = 0._r8
        1565           0 :          ld  = 0._r8
        1566           0 :          lu(:ncol, ktopcam:, :)  = flw%bnd_flux_up(:, ktoprad:, :)
        1567           0 :          ld(:ncol, ktopcam:, :)  = flw%bnd_flux_dn(:, ktoprad:, :)
        1568             :       end if
        1569             :
        1570      746136 :    end subroutine set_lw_diags
        1571             :
        1572             :    !-------------------------------------------------------------------------------
        1573             :
        1574     2984544 :    subroutine heating_rate(type, ncol, flux_net, hrate)
        1575             :
        1576             :       ! Compute heating rate as a dry static energy tendency
        1577             :
        1578             :       ! arguments
        1579             :       character(2), intent(in)  :: type ! either LW or SW
        1580             :       integer,      intent(in)  :: ncol
        1581             :       real(r8),     intent(in)  :: flux_net(pcols,pverp)  ! W/m^2
        1582             :       real(r8),     intent(out) :: hrate(pcols,pver)      ! J/kg/s
        1583             :
        1584             :       ! local vars
        1585             :       integer :: k
        1586             :
        1587             :       ! Initialize for layers where RRTMGP is not providing fluxes.
        1588     2984544 :       hrate = 0.0_r8
        1589             :
        1590     1492272 :       select case (type)
        1591             :       case ('LW')
        1592             :
        1593   140273568 :          do k = ktopcam, pver
        1594             :             ! (flux divergence as bottom-MINUS-top) * g/dp
        1595   277562592 :             hrate(:ncol,k) = (flux_net(:ncol,k+1) - flux_net(:ncol,k)) * &
        1596  2596379760 :                           gravit * state%rpdel(:ncol,k)
        1597             :          end do
        1598             :
        1599             :       case ('SW')
        1600             :
        1601   141765840 :          do k = ktopcam, pver
        1602             :             ! top - bottom
        1603   277562592 :             hrate(:ncol,k) = (flux_net(:ncol,k) - flux_net(:ncol,k+1)) * &
        1604  2596379760 :                           gravit * state%rpdel(:ncol,k)
        1605             :          end do
        1606             :
        1607             :       end select
        1608             :
        1609     2984544 :    end subroutine heating_rate
        1610             :
        1611             :    !----------------------------------------------------------------------------
        1612             :    !            -- end contains statement of radiation_tend --
        1613             :    !----------------------------------------------------------------------------
        1614             : end subroutine radiation_tend
        1615             :
        1616             : !===============================================================================
        1617             :
        1618      746136 : subroutine radiation_output_sw(lchnk, ncol, icall, rd, pbuf, cam_out)
        1619             :
        1620             :    ! Dump shortwave radiation information to history buffer.
        1621             :
        1622             :    integer ,               intent(in) :: lchnk
        1623             :    integer,                intent(in) :: ncol
        1624             :    integer,                intent(in) :: icall
        1625             :    type(rad_out_t),        intent(in) :: rd
        1626             :    type(physics_buffer_desc), pointer :: pbuf(:)
        1627             :    type(cam_out_t),        intent(in) :: cam_out
        1628             :
        1629             :    ! local variables
        1630      746136 :    real(r8), pointer :: qrs(:,:)
        1631      746136 :    real(r8), pointer :: fsnt(:)
        1632      746136 :    real(r8), pointer :: fsns(:)
        1633      746136 :    real(r8), pointer :: fsds(:)
        1634             :
        1635             :    real(r8) :: ftem(pcols)
        1636             :    !----------------------------------------------------------------------------
        1637             :
        1638      746136 :    call pbuf_get_field(pbuf, qrs_idx,  qrs)
        1639      746136 :    call pbuf_get_field(pbuf, fsnt_idx, fsnt)
        1640      746136 :    call pbuf_get_field(pbuf, fsns_idx, fsns)
        1641      746136 :    call pbuf_get_field(pbuf, fsds_idx, fsds)
        1642             :
        1643      746136 :    call outfld('SOLIN'//diag(icall),    rd%solin,      pcols, lchnk)
        1644             :
        1645             :    ! QRS is output as temperature tendency.
        1646  1159408584 :    call outfld('QRS'//diag(icall),      qrs(:ncol,:)/cpair,     ncol, lchnk)
        1647  1159408584 :    call outfld('QRSC'//diag(icall),     rd%qrsc(:ncol,:)/cpair, ncol, lchnk)
        1648             :
        1649      746136 :    call outfld('FSNT'//diag(icall),    fsnt,               pcols, lchnk)
        1650      746136 :    call outfld('FSNTC'//diag(icall),   rd%fsntc,           pcols, lchnk)
        1651      746136 :    call outfld('FSNTOA'//diag(icall),  rd%fsntoa,          pcols, lchnk)
        1652      746136 :    call outfld('FSNTOAC'//diag(icall), rd%fsntoac,         pcols, lchnk)
        1653             :
        1654    12458736 :    ftem(:ncol) = rd%fsntoa(:ncol) - rd%fsntoac(:ncol)
        1655      746136 :    call outfld('SWCF'//diag(icall),     ftem,          pcols, lchnk)
        1656             :
        1657      746136 :    call outfld('FSUTOA'//diag(icall),   rd%fsutoa,     pcols, lchnk)
        1658             :
        1659      746136 :    call outfld('FSNIRTOA'//diag(icall), rd%fsnirt,     pcols, lchnk)
        1660      746136 :    call outfld('FSNRTOAC'//diag(icall), rd%fsnrtc,     pcols, lchnk)
        1661      746136 :    call outfld('FSNRTOAS'//diag(icall), rd%fsnirtsq,   pcols, lchnk)
        1662             :
        1663      746136 :    call outfld('FSN200'//diag(icall),   rd%fsn200,     pcols, lchnk)
        1664      746136 :    call outfld('FSN200C'//diag(icall),  rd%fsn200c,    pcols, lchnk)
        1665             :
        1666      746136 :    call outfld('FSNR'//diag(icall),     rd%fsnr,       pcols, lchnk)
        1667             :
        1668      746136 :    call outfld('SOLS'//diag(icall),     cam_out%sols,  pcols, lchnk)
        1669      746136 :    call outfld('SOLL'//diag(icall),     cam_out%soll,  pcols, lchnk)
        1670      746136 :    call outfld('SOLSD'//diag(icall),    cam_out%solsd, pcols, lchnk)
        1671      746136 :    call outfld('SOLLD'//diag(icall),    cam_out%solld, pcols, lchnk)
        1672             :
        1673      746136 :    call outfld('FSNS'//diag(icall),     fsns,          pcols, lchnk)
        1674      746136 :    call outfld('FSNSC'//diag(icall),    rd%fsnsc,      pcols, lchnk)
        1675             :
        1676      746136 :    call outfld('FSDS'//diag(icall),     fsds,          pcols, lchnk)
        1677      746136 :    call outfld('FSDSC'//diag(icall),    rd%fsdsc,      pcols, lchnk)
        1678             :
        1679      746136 :    call outfld('FUS'//diag(icall),  rd%flux_sw_up,     pcols, lchnk)
        1680      746136 :    call outfld('FUSC'//diag(icall), rd%flux_sw_clr_up, pcols, lchnk)
        1681      746136 :    call outfld('FDS'//diag(icall),  rd%flux_sw_dn,     pcols, lchnk)
        1682      746136 :    call outfld('FDSC'//diag(icall), rd%flux_sw_clr_dn, pcols, lchnk)
        1683             :
        1684      746136 : end subroutine radiation_output_sw
        1685             :
        1686             : !===============================================================================
        1687             :
        1688      746136 : subroutine radiation_output_cld(lchnk, rd)
        1689             :
        1690             :    ! Dump shortwave cloud optics information to history buffer.
        1691             :
        1692             :    integer ,        intent(in) :: lchnk
        1693             :    type(rad_out_t), intent(in) :: rd
        1694             :    !----------------------------------------------------------------------------
        1695             :
        1696      746136 :    call outfld('TOT_CLD_VISTAU',  rd%tot_cld_vistau,  pcols, lchnk)
        1697      746136 :    call outfld('TOT_ICLD_VISTAU', rd%tot_icld_vistau, pcols, lchnk)
        1698      746136 :    call outfld('LIQ_ICLD_VISTAU', rd%liq_icld_vistau, pcols, lchnk)
        1699      746136 :    call outfld('ICE_ICLD_VISTAU', rd%ice_icld_vistau, pcols, lchnk)
        1700      746136 :    if (cldfsnow_idx > 0) then
        1701      746136 :       call outfld('SNOW_ICLD_VISTAU', rd%snow_icld_vistau, pcols, lchnk)
        1702             :    endif
        1703      746136 :    if (cldfgrau_idx > 0 .and. graupel_in_rad) then
        1704           0 :       call outfld('GRAU_ICLD_VISTAU', rd%grau_icld_vistau , pcols, lchnk)
        1705             :    endif
        1706             :
        1707      746136 : end subroutine radiation_output_cld
        1708             :
        1709             : !===============================================================================
        1710             :
        1711      746136 : subroutine radiation_output_lw(lchnk, ncol, icall, rd, pbuf, cam_out)
        1712             :
        1713             :    ! Dump longwave radiation information to history buffer
        1714             :
        1715             :    integer,                intent(in) :: lchnk
        1716             :    integer,                intent(in) :: ncol
        1717             :    integer,                intent(in) :: icall  ! icall=0 for climate diagnostics
        1718             :    type(rad_out_t),        intent(in) :: rd
        1719             :    type(physics_buffer_desc), pointer :: pbuf(:)
        1720             :    type(cam_out_t),        intent(in) :: cam_out
        1721             :
        1722             :    ! local variables
        1723      746136 :    real(r8), pointer :: qrl(:,:)
        1724      746136 :    real(r8), pointer :: flnt(:)
        1725      746136 :    real(r8), pointer :: flns(:)
        1726             :
        1727             :    real(r8) :: ftem(pcols)
        1728             :    !----------------------------------------------------------------------------
        1729             :
        1730      746136 :    call pbuf_get_field(pbuf, qrl_idx,  qrl)
        1731      746136 :    call pbuf_get_field(pbuf, flnt_idx, flnt)
        1732      746136 :    call pbuf_get_field(pbuf, flns_idx, flns)
        1733             :
        1734  1159408584 :    call outfld('QRL'//diag(icall),     qrl(:ncol,:)/cpair,     ncol, lchnk)
        1735  1159408584 :    call outfld('QRLC'//diag(icall),    rd%qrlc(:ncol,:)/cpair, ncol, lchnk)
        1736             :
        1737      746136 :    call outfld('FLNT'//diag(icall),    flnt,          pcols, lchnk)
        1738      746136 :    call outfld('FLNTC'//diag(icall),   rd%flntc,      pcols, lchnk)
        1739             :
        1740      746136 :    call outfld('FLUT'//diag(icall),    rd%flut,       pcols, lchnk)
        1741      746136 :    call outfld('FLUTC'//diag(icall),   rd%flutc,      pcols, lchnk)
        1742             :
        1743    12458736 :    ftem(:ncol) = rd%flutc(:ncol) - rd%flut(:ncol)
        1744      746136 :    call outfld('LWCF'//diag(icall),    ftem,          pcols, lchnk)
        1745             :
        1746      746136 :    call outfld('FLN200'//diag(icall),  rd%fln200,     pcols, lchnk)
        1747      746136 :    call outfld('FLN200C'//diag(icall), rd%fln200c,    pcols, lchnk)
        1748             :
        1749      746136 :    call outfld('FLNR'//diag(icall),    rd%flnr,       pcols, lchnk)
        1750             :
        1751      746136 :    call outfld('FLNS'//diag(icall),    flns,          pcols, lchnk)
        1752      746136 :    call outfld('FLNSC'//diag(icall),   rd%flnsc,      pcols, lchnk)
        1753             :
        1754      746136 :    call outfld('FLDS'//diag(icall),    cam_out%flwds, pcols, lchnk)
        1755      746136 :    call outfld('FLDSC'//diag(icall),   rd%fldsc,      pcols, lchnk)
        1756             :
        1757      746136 :    call outfld('FDL'//diag(icall),  rd%flux_lw_dn,     pcols, lchnk)
        1758      746136 :    call outfld('FDLC'//diag(icall), rd%flux_lw_clr_dn, pcols, lchnk)
        1759      746136 :    call outfld('FUL'//diag(icall),  rd%flux_lw_up,     pcols, lchnk)
        1760      746136 :    call outfld('FULC'//diag(icall), rd%flux_lw_clr_up, pcols, lchnk)
        1761             :
        1762      746136 : end subroutine radiation_output_lw
        1763             :
        1764             : !===============================================================================
        1765             :
        1766        3072 : subroutine coefs_init(coefs_file, available_gases, kdist)
        1767             :
        1768             :    ! Read data from coefficients file.  Initialize the kdist object.
        1769             :    ! available_gases object provides the gas names that CAM provides.
        1770             :
        1771             :    ! arguments
        1772             :    character(len=*),                  intent(in)  :: coefs_file
        1773             :    class(ty_gas_concs),               intent(in)  :: available_gases
        1774             :    class(ty_gas_optics_rrtmgp),       intent(out) :: kdist
        1775             :
        1776             :    ! local variables
        1777             :    type(file_desc_t) :: fh    ! pio file handle
        1778             :    character(len=cl) :: locfn ! path to file on local storage
        1779             :
        1780             :    ! File dimensions
        1781             :    integer ::            &
        1782             :       absorber,          &
        1783             :       atmos_layer,       &
        1784             :       bnd,               &
        1785             :       pressure,          &
        1786             :       temperature,       &
        1787             :       absorber_ext,      &
        1788             :       pressure_interp,   &
        1789             :       mixing_fraction,   &
        1790             :       gpt,               &
        1791             :       temperature_Planck
        1792             :
        1793             :    integer :: i
        1794             :    integer :: did, vid
        1795             :    integer :: ierr, istat
        1796             :
        1797        3072 :    character(32), dimension(:),  allocatable :: gas_names
        1798        3072 :    integer,  dimension(:,:,:),   allocatable :: key_species
        1799        3072 :    integer,  dimension(:,:),     allocatable :: band2gpt
        1800        3072 :    real(r8), dimension(:,:),     allocatable :: band_lims_wavenum
        1801        3072 :    real(r8), dimension(:),       allocatable :: press_ref, temp_ref
        1802             :    real(r8)                                  :: press_ref_trop, temp_ref_t, temp_ref_p
        1803        3072 :    real(r8), dimension(:,:,:),   allocatable :: vmr_ref
        1804        3072 :    real(r8), dimension(:,:,:,:), allocatable :: kmajor
        1805        3072 :    real(r8), dimension(:,:,:),   allocatable :: kminor_lower, kminor_upper
        1806        3072 :    real(r8), dimension(:,:),     allocatable :: totplnk
        1807        3072 :    real(r8), dimension(:,:,:,:), allocatable :: planck_frac
        1808        3072 :    real(r8), dimension(:),       allocatable :: solar_src_quiet, solar_src_facular, solar_src_sunspot
        1809             :    real(r8)                                  :: tsi_default
        1810        3072 :    real(r8), dimension(:,:,:),   allocatable :: rayl_lower, rayl_upper
        1811        3072 :    character(len=32), dimension(:),  allocatable :: gas_minor,         &
        1812        3072 :                                                     identifier_minor,  &
        1813        3072 :                                                     minor_gases_lower, &
        1814        3072 :                                                     minor_gases_upper, &
        1815        3072 :                                                     scaling_gas_lower, &
        1816        3072 :                                                     scaling_gas_upper
        1817        3072 :    integer, dimension(:,:),          allocatable :: minor_limits_gpt_lower, &
        1818        3072 :                                                     minor_limits_gpt_upper
        1819             :    ! Send these to RRTMGP as logicals,
        1820             :    ! but they have to be read from the netCDF as integers
        1821        3072 :    logical, dimension(:),            allocatable :: minor_scales_with_density_lower, &
        1822        3072 :                                                     minor_scales_with_density_upper
        1823        3072 :    logical, dimension(:),            allocatable :: scale_by_complement_lower, &
        1824        3072 :                                                     scale_by_complement_upper
        1825        3072 :    integer, dimension(:), allocatable :: int2log   ! use this to convert integer-to-logical.
        1826        3072 :    integer, dimension(:),            allocatable :: kminor_start_lower, kminor_start_upper
        1827        3072 :    real(r8), dimension(:,:),         allocatable :: optimal_angle_fit
        1828             :    real(r8)                                      :: mg_default, sb_default
        1829             :
        1830             :    integer :: pairs, &
        1831             :               minorabsorbers, &
        1832             :               minor_absorber_intervals_lower, &
        1833             :               minor_absorber_intervals_upper, &
        1834             :               contributors_lower, &
        1835             :               contributors_upper, &
        1836             :               fit_coeffs
        1837             :
        1838             :    character(len=128) :: error_msg
        1839             :    character(len=*), parameter :: sub = 'coefs_init'
        1840             :    !----------------------------------------------------------------------------
        1841             :
        1842             :    ! Open file
        1843        3072 :    call getfil(coefs_file, locfn, 0)
        1844        3072 :    call cam_pio_openfile(fh, locfn, PIO_NOWRITE)
        1845             :
        1846        3072 :    call pio_seterrorhandling(fh, PIO_BCAST_ERROR)
        1847             :
        1848             :    ! Get dimensions
        1849             :
        1850        3072 :    ierr = pio_inq_dimid(fh, 'absorber', did)
        1851        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': absorber not found')
        1852        3072 :    ierr = pio_inq_dimlen(fh, did, absorber)
        1853             :
        1854        3072 :    ierr = pio_inq_dimid(fh, 'atmos_layer', did)
        1855        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': atmos_layer not found')
        1856        3072 :    ierr = pio_inq_dimlen(fh, did, atmos_layer)
        1857             :
        1858        3072 :    ierr = pio_inq_dimid(fh, 'bnd', did)
        1859        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': bnd not found')
        1860        3072 :    ierr = pio_inq_dimlen(fh, did, bnd)
        1861             :
        1862        3072 :    ierr = pio_inq_dimid(fh, 'pressure', did)
        1863        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': pressure not found')
        1864        3072 :    ierr = pio_inq_dimlen(fh, did, pressure)
        1865             :
        1866        3072 :    ierr = pio_inq_dimid(fh, 'temperature', did)
        1867        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': temperature not found')
        1868        3072 :    ierr = pio_inq_dimlen(fh, did, temperature)
        1869             :
        1870        3072 :    ierr = pio_inq_dimid(fh, 'absorber_ext', did)
        1871        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': absorber_ext not found')
        1872        3072 :    ierr = pio_inq_dimlen(fh, did, absorber_ext)
        1873             :
        1874        3072 :    ierr = pio_inq_dimid(fh, 'pressure_interp', did)
        1875        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': pressure_interp not found')
        1876        3072 :    ierr = pio_inq_dimlen(fh, did, pressure_interp)
        1877             :
        1878        3072 :    ierr = pio_inq_dimid(fh, 'mixing_fraction', did)
        1879        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': mixing_fraction not found')
        1880        3072 :    ierr = pio_inq_dimlen(fh, did, mixing_fraction)
        1881             :
        1882        3072 :    ierr = pio_inq_dimid(fh, 'gpt', did)
        1883        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': gpt not found')
        1884        3072 :    ierr = pio_inq_dimlen(fh, did, gpt)
        1885             :
        1886        3072 :    temperature_Planck = 0
        1887        3072 :    ierr = pio_inq_dimid(fh, 'temperature_Planck', did)
        1888        3072 :    if (ierr == PIO_NOERR) then
        1889        1536 :       ierr = pio_inq_dimlen(fh, did, temperature_Planck)
        1890             :    end if
        1891        3072 :    ierr = pio_inq_dimid(fh, 'pair', did)
        1892        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': pair not found')
        1893        3072 :    ierr = pio_inq_dimlen(fh, did, pairs)
        1894        3072 :    ierr = pio_inq_dimid(fh, 'minor_absorber', did)
        1895        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_absorber not found')
        1896        3072 :    ierr = pio_inq_dimlen(fh, did, minorabsorbers)
        1897        3072 :    ierr = pio_inq_dimid(fh, 'minor_absorber_intervals_lower', did)
        1898        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_absorber_intervals_lower not found')
        1899        3072 :    ierr = pio_inq_dimlen(fh, did, minor_absorber_intervals_lower)
        1900        3072 :    ierr = pio_inq_dimid(fh, 'minor_absorber_intervals_upper', did)
        1901        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_absorber_intervals_upper not found')
        1902        3072 :    ierr = pio_inq_dimlen(fh, did, minor_absorber_intervals_upper)
        1903        3072 :    ierr = pio_inq_dimid(fh, 'contributors_lower', did)
        1904        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': contributors_lower not found')
        1905        3072 :    ierr = pio_inq_dimlen(fh, did, contributors_lower)
        1906        3072 :    ierr = pio_inq_dimid(fh, 'contributors_upper', did)
        1907        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': contributors_upper not found')
        1908        3072 :    ierr = pio_inq_dimlen(fh, did, contributors_upper)
        1909             :
        1910        3072 :    ierr = pio_inq_dimid(fh, 'fit_coeffs', did)
        1911        3072 :    if (ierr == PIO_NOERR) then
        1912        1536 :       ierr = pio_inq_dimlen(fh, did, fit_coeffs)
        1913             :    end if
        1914             :
        1915             :    ! Get variables
        1916             :
        1917             :    ! names of absorbing gases
        1918        9216 :    allocate(gas_names(absorber), stat=istat)
        1919        3072 :    call handle_allocate_error(istat, sub, 'gas_names')
        1920        3072 :    ierr = pio_inq_varid(fh, 'gas_names', vid)
        1921        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': gas_names not found')
        1922        3072 :    ierr = pio_get_var(fh, vid, gas_names)
        1923        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading gas_names')
        1924             :
        1925             :    ! key species pair for each band
        1926       12288 :    allocate(key_species(2,atmos_layer,bnd), stat=istat)
        1927        3072 :    call handle_allocate_error(istat, sub, 'key_species')
        1928        3072 :    ierr = pio_inq_varid(fh, 'key_species', vid)
        1929        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': key_species not found')
        1930        3072 :    ierr = pio_get_var(fh, vid, key_species)
        1931        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading key_species')
        1932             :
        1933             :    ! beginning and ending gpoint for each band
        1934        9216 :    allocate(band2gpt(2,bnd), stat=istat)
        1935        3072 :    call handle_allocate_error(istat, sub, 'band2gpt')
        1936        3072 :    ierr = pio_inq_varid(fh, 'bnd_limits_gpt', vid)
        1937        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': bnd_limits_gpt not found')
        1938        3072 :    ierr = pio_get_var(fh, vid, band2gpt)
        1939        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading bnd_limits_gpt')
        1940             :
        1941             :    ! beginning and ending wavenumber for each band
        1942        9216 :    allocate(band_lims_wavenum(2,bnd), stat=istat)
        1943        3072 :    call handle_allocate_error(istat, sub, 'band_lims_wavenum')
        1944        3072 :    ierr = pio_inq_varid(fh, 'bnd_limits_wavenumber', vid)
        1945        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': bnd_limits_wavenumber not found')
        1946        3072 :    ierr = pio_get_var(fh, vid, band_lims_wavenum)
        1947        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading bnd_limits_wavenumber')
        1948             :
        1949             :    ! pressures [hPa] for reference atmosphere; press_ref(# reference layers)
        1950        9216 :    allocate(press_ref(pressure), stat=istat)
        1951        3072 :    call handle_allocate_error(istat, sub, 'press_ref')
        1952        3072 :    ierr = pio_inq_varid(fh, 'press_ref', vid)
        1953        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': press_ref not found')
        1954        3072 :    ierr = pio_get_var(fh, vid, press_ref)
        1955        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading press_ref')
        1956             :
        1957             :    ! reference pressure separating the lower and upper atmosphere
        1958        3072 :    ierr = pio_inq_varid(fh, 'press_ref_trop', vid)
        1959        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': press_ref_trop not found')
        1960        3072 :    ierr = pio_get_var(fh, vid, press_ref_trop)
        1961        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading press_ref_trop')
        1962             :
        1963             :    ! temperatures [K] for reference atmosphere; temp_ref(# reference layers)
        1964        9216 :    allocate(temp_ref(temperature), stat=istat)
        1965        3072 :    call handle_allocate_error(istat, sub, 'temp_ref')
        1966        3072 :    ierr = pio_inq_varid(fh, 'temp_ref', vid)
        1967        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': temp_ref not found')
        1968        3072 :    ierr = pio_get_var(fh, vid, temp_ref)
        1969        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading temp_ref')
        1970             :
        1971             :    ! standard spectroscopic reference temperature [K]
        1972        3072 :    ierr = pio_inq_varid(fh, 'absorption_coefficient_ref_T', vid)
        1973        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': absorption_coefficient_ref_T not found')
        1974        3072 :    ierr = pio_get_var(fh, vid, temp_ref_t)
        1975        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading absorption_coefficient_ref_T')
        1976             :
        1977             :    ! standard spectroscopic reference pressure [hPa]
        1978        3072 :    ierr = pio_inq_varid(fh, 'absorption_coefficient_ref_P', vid)
        1979        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': absorption_coefficient_ref_P not found')
        1980        3072 :    ierr = pio_get_var(fh, vid, temp_ref_p)
        1981        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading absorption_coefficient_ref_P')
        1982             :
        1983             :    ! volume mixing ratios for reference atmosphere
        1984       15360 :    allocate(vmr_ref(atmos_layer, absorber_ext, temperature), stat=istat)
        1985        3072 :    call handle_allocate_error(istat, sub, 'vmr_ref')
        1986        3072 :    ierr = pio_inq_varid(fh, 'vmr_ref', vid)
        1987        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': vmr_ref not found')
        1988        3072 :    ierr = pio_get_var(fh, vid, vmr_ref)
        1989        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading vmr_ref')
        1990             :
        1991             :    ! absorption coefficients due to major absorbing gases
        1992       18432 :    allocate(kmajor(gpt,mixing_fraction,pressure_interp,temperature), stat=istat)
        1993        3072 :    call handle_allocate_error(istat, sub, 'kmajor')
        1994        3072 :    ierr = pio_inq_varid(fh, 'kmajor', vid)
        1995        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': kmajor not found')
        1996        3072 :    ierr = pio_get_var(fh, vid, kmajor)
        1997        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading kmajor')
        1998             :
        1999             :    ! absorption coefficients due to minor absorbing gases in lower part of atmosphere
        2000       15360 :    allocate(kminor_lower(contributors_lower, mixing_fraction, temperature), stat=istat)
        2001        3072 :    call handle_allocate_error(istat, sub, 'kminor_lower')
        2002        3072 :    ierr = pio_inq_varid(fh, 'kminor_lower', vid)
        2003        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': kminor_lower not found')
        2004        3072 :    ierr = pio_get_var(fh, vid, kminor_lower)
        2005        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading kminor_lower')
        2006             :
        2007             :    ! absorption coefficients due to minor absorbing gases in upper part of atmosphere
        2008       15360 :    allocate(kminor_upper(contributors_upper, mixing_fraction, temperature), stat=istat)
        2009        3072 :    call handle_allocate_error(istat, sub, 'kminor_upper')
        2010        3072 :    ierr = pio_inq_varid(fh, 'kminor_upper', vid)
        2011        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': kminor_upper not found')
        2012        3072 :    ierr = pio_get_var(fh, vid, kminor_upper)
        2013        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading kminor_upper')
        2014             :
        2015             :    ! integrated Planck function by band
        2016        3072 :    ierr = pio_inq_varid(fh, 'totplnk', vid)
        2017        3072 :    if (ierr == PIO_NOERR) then
        2018        6144 :       allocate(totplnk(temperature_Planck,bnd), stat=istat)
        2019        1536 :       call handle_allocate_error(istat, sub, 'totplnk')
        2020        1536 :       ierr = pio_get_var(fh, vid, totplnk)
        2021        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading totplnk')
        2022             :    end if
        2023             :
        2024             :    ! Planck fractions
        2025        3072 :    ierr = pio_inq_varid(fh, 'plank_fraction', vid)
        2026        3072 :    if (ierr == PIO_NOERR) then
        2027        9216 :       allocate(planck_frac(gpt,mixing_fraction,pressure_interp,temperature), stat=istat)
        2028        1536 :       call handle_allocate_error(istat, sub, 'planck_frac')
        2029        1536 :       ierr = pio_get_var(fh, vid, planck_frac)
        2030        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading plank_fraction')
        2031             :    end if
        2032             :
        2033        3072 :    ierr = pio_inq_varid(fh, 'optimal_angle_fit', vid)
        2034        3072 :    if (ierr == PIO_NOERR) then
        2035        6144 :       allocate(optimal_angle_fit(fit_coeffs, bnd), stat=istat)
        2036        1536 :       call handle_allocate_error(istat, sub, 'optiman_angle_fit')
        2037        1536 :       ierr = pio_get_var(fh, vid, optimal_angle_fit)
        2038        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading optimal_angle_fit')
        2039             :    end if
        2040             :
        2041        3072 :    ierr = pio_inq_varid(fh, 'solar_source_quiet', vid)
        2042        3072 :    if (ierr == PIO_NOERR) then
        2043        4608 :       allocate(solar_src_quiet(gpt), stat=istat)
        2044        1536 :       call handle_allocate_error(istat, sub, 'solar_src_quiet')
        2045        1536 :       ierr = pio_get_var(fh, vid, solar_src_quiet)
        2046        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading solar_source_quiet')
        2047             :    end if
        2048             :
        2049        3072 :    ierr = pio_inq_varid(fh, 'solar_source_facular', vid)
        2050        3072 :    if (ierr == PIO_NOERR) then
        2051        4608 :       allocate(solar_src_facular(gpt), stat=istat)
        2052        1536 :       call handle_allocate_error(istat, sub, 'solar_src_facular')
        2053        1536 :       ierr = pio_get_var(fh, vid, solar_src_facular)
        2054        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading solar_source_facular')
        2055             :    end if
        2056             :
        2057        3072 :    ierr = pio_inq_varid(fh, 'solar_source_sunspot', vid)
        2058        3072 :    if (ierr == PIO_NOERR) then
        2059        4608 :       allocate(solar_src_sunspot(gpt), stat=istat)
        2060        1536 :       call handle_allocate_error(istat, sub, 'solar_src_sunspot')
        2061        1536 :       ierr = pio_get_var(fh, vid, solar_src_sunspot)
        2062        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading solar_source_sunspot')
        2063             :    end if
        2064             :
        2065        3072 :    ierr = pio_inq_varid(fh, 'tsi_default', vid)
        2066        3072 :    if (ierr == PIO_NOERR) then
        2067        1536 :       ierr = pio_get_var(fh, vid, tsi_default)
        2068        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading tsi_default')
        2069             :    end if
        2070             :
        2071        3072 :    ierr = pio_inq_varid(fh, 'mg_default', vid)
        2072        3072 :    if (ierr == PIO_NOERR) then
        2073        1536 :       ierr = pio_get_var(fh, vid, mg_default)
        2074        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading mg_default')
        2075             :    end if
        2076             :
        2077        3072 :    ierr = pio_inq_varid(fh, 'sb_default', vid)
        2078        3072 :    if (ierr == PIO_NOERR) then
        2079        1536 :       ierr = pio_get_var(fh, vid, sb_default)
        2080        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading sb_default')
        2081             :    end if
        2082             :
        2083             :    ! rayleigh scattering contribution in lower part of atmosphere
        2084        3072 :    ierr = pio_inq_varid(fh, 'rayl_lower', vid)
        2085        3072 :    if (ierr == PIO_NOERR) then
        2086        7680 :       allocate(rayl_lower(gpt,mixing_fraction,temperature), stat=istat)
        2087        1536 :       call handle_allocate_error(istat, sub, 'rayl_lower')
        2088        1536 :       ierr = pio_get_var(fh, vid, rayl_lower)
        2089        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading rayl_lower')
        2090             :    end if
        2091             :
        2092             :    ! rayleigh scattering contribution in upper part of atmosphere
        2093        3072 :    ierr = pio_inq_varid(fh, 'rayl_upper', vid)
        2094        3072 :    if (ierr == PIO_NOERR) then
        2095        7680 :       allocate(rayl_upper(gpt,mixing_fraction,temperature), stat=istat)
        2096        1536 :       call handle_allocate_error(istat, sub, 'rayl_upper')
        2097        1536 :       ierr = pio_get_var(fh, vid, rayl_upper)
        2098        1536 :       if (ierr /= PIO_NOERR) call endrun(sub//': error reading rayl_upper')
        2099             :    end if
        2100             :
        2101        9216 :    allocate(gas_minor(minorabsorbers), stat=istat)
        2102        3072 :    call handle_allocate_error(istat, sub, 'gas_minor')
        2103        3072 :    ierr = pio_inq_varid(fh, 'gas_minor', vid)
        2104        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': gas_minor not found')
        2105        3072 :    ierr = pio_get_var(fh, vid, gas_minor)
        2106        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading gas_minor')
        2107             :
        2108        9216 :    allocate(identifier_minor(minorabsorbers), stat=istat)
        2109        3072 :    call handle_allocate_error(istat, sub, 'identifier_minor')
        2110        3072 :    ierr = pio_inq_varid(fh, 'identifier_minor', vid)
        2111        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': identifier_minor not found')
        2112        3072 :    ierr = pio_get_var(fh, vid, identifier_minor)
        2113        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading identifier_minor')
        2114             :
        2115        9216 :    allocate(minor_gases_lower(minor_absorber_intervals_lower), stat=istat)
        2116        3072 :    call handle_allocate_error(istat, sub, 'minor_gases_lower')
        2117        3072 :    ierr = pio_inq_varid(fh, 'minor_gases_lower', vid)
        2118        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_gases_lower not found')
        2119        3072 :    ierr = pio_get_var(fh, vid, minor_gases_lower)
        2120        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading minor_gases_lower')
        2121             :
        2122        9216 :    allocate(minor_gases_upper(minor_absorber_intervals_upper), stat=istat)
        2123        3072 :    call handle_allocate_error(istat, sub, 'minor_gases_upper')
        2124        3072 :    ierr = pio_inq_varid(fh, 'minor_gases_upper', vid)
        2125        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_gases_upper not found')
        2126        3072 :    ierr = pio_get_var(fh, vid, minor_gases_upper)
        2127        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading minor_gases_upper')
        2128             :
        2129       12288 :    allocate(minor_limits_gpt_lower(pairs,minor_absorber_intervals_lower), stat=istat)
        2130        3072 :    call handle_allocate_error(istat, sub, 'minor_limits_gpt_lower')
        2131        3072 :    ierr = pio_inq_varid(fh, 'minor_limits_gpt_lower', vid)
        2132        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_limits_gpt_lower not found')
        2133        3072 :    ierr = pio_get_var(fh, vid, minor_limits_gpt_lower)
        2134        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading minor_limits_gpt_lower')
        2135             :
        2136       12288 :    allocate(minor_limits_gpt_upper(pairs,minor_absorber_intervals_upper), stat=istat)
        2137        3072 :    call handle_allocate_error(istat, sub, 'minor_limits_gpt_upper')
        2138        3072 :    ierr = pio_inq_varid(fh, 'minor_limits_gpt_upper', vid)
        2139        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_limits_gpt_upper not found')
        2140        3072 :    ierr = pio_get_var(fh, vid, minor_limits_gpt_upper)
        2141        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading minor_limits_gpt_upper')
        2142             :
        2143             :    ! Read as integer and convert to logical
        2144        9216 :    allocate(int2log(minor_absorber_intervals_lower), stat=istat)
        2145        3072 :    call handle_allocate_error(istat, sub, 'int2log for lower')
        2146             :
        2147        9216 :    allocate(minor_scales_with_density_lower(minor_absorber_intervals_lower), stat=istat)
        2148        3072 :    call handle_allocate_error(istat, sub, 'minor_scales_with_density_lower')
        2149        3072 :    ierr = pio_inq_varid(fh, 'minor_scales_with_density_lower', vid)
        2150        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_scales_with_density_lower not found')
        2151        3072 :    ierr = pio_get_var(fh, vid, int2log)
        2152        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading minor_scales_with_density_lower')
        2153      147456 :    do i = 1,minor_absorber_intervals_lower
        2154      147456 :       if (int2log(i) .eq. 0) then
        2155       53760 :          minor_scales_with_density_lower(i) = .false.
        2156             :       else
        2157       90624 :          minor_scales_with_density_lower(i) = .true.
        2158             :       end if
        2159             :    end do
        2160             :
        2161        9216 :    allocate(scale_by_complement_lower(minor_absorber_intervals_lower), stat=istat)
        2162        3072 :    call handle_allocate_error(istat, sub, 'scale_by_complement_lower')
        2163        3072 :    ierr = pio_inq_varid(fh, 'scale_by_complement_lower', vid)
        2164        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': scale_by_complement_lower not found')
        2165        3072 :    ierr = pio_get_var(fh, vid, int2log)
        2166        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading scale_by_complement_lower')
        2167      147456 :    do i = 1,minor_absorber_intervals_lower
        2168      147456 :       if (int2log(i) .eq. 0) then
        2169      104448 :          scale_by_complement_lower(i) = .false.
        2170             :       else
        2171       39936 :          scale_by_complement_lower(i) = .true.
        2172             :       end if
        2173             :    end do
        2174             :
        2175        3072 :    deallocate(int2log)
        2176             :
        2177             :    ! Read as integer and convert to logical
        2178        9216 :    allocate(int2log(minor_absorber_intervals_upper), stat=istat)
        2179        3072 :    call handle_allocate_error(istat, sub, 'int2log for upper')
        2180             :
        2181        9216 :    allocate(minor_scales_with_density_upper(minor_absorber_intervals_upper), stat=istat)
        2182        3072 :    call handle_allocate_error(istat, sub, 'minor_scales_with_density_upper')
        2183        3072 :    ierr = pio_inq_varid(fh, 'minor_scales_with_density_upper', vid)
        2184        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': minor_scales_with_density_upper not found')
        2185        3072 :    ierr = pio_get_var(fh, vid, int2log)
        2186        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading minor_scales_with_density_upper')
        2187       92160 :    do i = 1,minor_absorber_intervals_upper
        2188       92160 :       if (int2log(i) .eq. 0) then
        2189       46080 :          minor_scales_with_density_upper(i) = .false.
        2190             :       else
        2191       43008 :          minor_scales_with_density_upper(i) = .true.
        2192             :       end if
        2193             :    end do
        2194             :
        2195        9216 :    allocate(scale_by_complement_upper(minor_absorber_intervals_upper), stat=istat)
        2196        3072 :    call handle_allocate_error(istat, sub, 'scale_by_complement_upper')
        2197        3072 :    ierr = pio_inq_varid(fh, 'scale_by_complement_upper', vid)
        2198        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': scale_by_complement_upper not found')
        2199        3072 :    ierr = pio_get_var(fh, vid, int2log)
        2200        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading scale_by_complement_upper')
        2201       92160 :    do i = 1,minor_absorber_intervals_upper
        2202       92160 :       if (int2log(i) .eq. 0) then
        2203       70656 :          scale_by_complement_upper(i) = .false.
        2204             :       else
        2205       18432 :          scale_by_complement_upper(i) = .true.
        2206             :       end if
        2207             :    end do
        2208             :
        2209        3072 :    deallocate(int2log)
        2210             :
        2211        9216 :    allocate(scaling_gas_lower(minor_absorber_intervals_lower), stat=istat)
        2212        3072 :    call handle_allocate_error(istat, sub, 'scaling_gas_lower')
        2213        3072 :    ierr = pio_inq_varid(fh, 'scaling_gas_lower', vid)
        2214        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': scaling_gas_lower not found')
        2215        3072 :    ierr = pio_get_var(fh, vid, scaling_gas_lower)
        2216        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading scaling_gas_lower')
        2217             :
        2218        9216 :    allocate(scaling_gas_upper(minor_absorber_intervals_upper), stat=istat)
        2219        3072 :    call handle_allocate_error(istat, sub, 'scaling_gas_upper')
        2220        3072 :    ierr = pio_inq_varid(fh, 'scaling_gas_upper', vid)
        2221        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': scaling_gas_upper not found')
        2222        3072 :    ierr = pio_get_var(fh, vid, scaling_gas_upper)
        2223        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading scaling_gas_upper')
        2224             :
        2225        9216 :    allocate(kminor_start_lower(minor_absorber_intervals_lower), stat=istat)
        2226        3072 :    call handle_allocate_error(istat, sub, 'kminor_start_lower')
        2227        3072 :    ierr = pio_inq_varid(fh, 'kminor_start_lower', vid)
        2228        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': kminor_start_lower not found')
        2229        3072 :    ierr = pio_get_var(fh, vid, kminor_start_lower)
        2230        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading kminor_start_lower')
        2231             :
        2232        9216 :    allocate(kminor_start_upper(minor_absorber_intervals_upper), stat=istat)
        2233        3072 :    call handle_allocate_error(istat, sub, 'kminor_start_upper')
        2234        3072 :    ierr = pio_inq_varid(fh, 'kminor_start_upper', vid)
        2235        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': kminor_start_upper not found')
        2236        3072 :    ierr = pio_get_var(fh, vid, kminor_start_upper)
        2237        3072 :    if (ierr /= PIO_NOERR) call endrun(sub//': error reading kminor_start_upper')
        2238             :
        2239             :    ! Close file
        2240        3072 :    call pio_closefile(fh)
        2241             :
        2242             :    ! Initialize the gas optics object with data. The calls are slightly different depending
        2243             :    ! on whether the radiation sources are internal to the atmosphere (longwave) or external (shortwave)
        2244             :
        2245        3072 :    if (allocated(totplnk) .and. allocated(planck_frac)) then
        2246             :       error_msg = kdist%load( &
        2247             :          available_gases, gas_names, key_species,              &
        2248             :          band2gpt, band_lims_wavenum,                          &
        2249             :          press_ref, press_ref_trop, temp_ref,                  &
        2250             :          temp_ref_p, temp_ref_t, vmr_ref,                      &
        2251             :          kmajor, kminor_lower, kminor_upper,                   &
        2252             :          gas_minor, identifier_minor,                          &
        2253             :          minor_gases_lower, minor_gases_upper,                 &
        2254             :          minor_limits_gpt_lower, minor_limits_gpt_upper,       &
        2255             :          minor_scales_with_density_lower,                      &
        2256             :          minor_scales_with_density_upper,                      &
        2257             :          scaling_gas_lower, scaling_gas_upper,                 &
        2258             :          scale_by_complement_lower, scale_by_complement_upper, &
        2259             :          kminor_start_lower, kminor_start_upper,               &
        2260             :          totplnk, planck_frac, rayl_lower, rayl_upper,         &
        2261        1536 :          optimal_angle_fit)
        2262        1536 :    else if (allocated(solar_src_quiet)) then
        2263             :       error_msg = kdist%load( &
        2264             :          available_gases, gas_names, key_species,               &
        2265             :          band2gpt, band_lims_wavenum,                           &
        2266             :          press_ref, press_ref_trop, temp_ref,                   &
        2267             :          temp_ref_p, temp_ref_t, vmr_ref,                       &
        2268             :          kmajor, kminor_lower, kminor_upper,                    &
        2269             :          gas_minor, identifier_minor,                           &
        2270             :          minor_gases_lower, minor_gases_upper,                  &
        2271             :          minor_limits_gpt_lower, minor_limits_gpt_upper,        &
        2272             :          minor_scales_with_density_lower,                       &
        2273             :          minor_scales_with_density_upper,                       &
        2274             :          scaling_gas_lower, scaling_gas_upper,                  &
        2275             :          scale_by_complement_lower,                             &
        2276             :          scale_by_complement_upper,                             &
        2277             :          kminor_start_lower,                                    &
        2278             :          kminor_start_upper,                                    &
        2279             :          solar_src_quiet, solar_src_facular, solar_src_sunspot, &
        2280             :          tsi_default, mg_default, sb_default,                   &
        2281        1536 :          rayl_lower, rayl_upper)
        2282             :    else
        2283           0 :       error_msg = 'must supply either totplnk and planck_frac, or solar_src_[*]'
        2284             :    end if
        2285             :
        2286        3072 :    call stop_on_err(error_msg, sub, 'kdist%load')
        2287             :
        2288           0 :    deallocate( &
        2289           0 :       gas_names, key_species,               &
        2290           0 :       band2gpt, band_lims_wavenum,          &
        2291           0 :       press_ref, temp_ref, vmr_ref,         &
        2292           0 :       kmajor, kminor_lower, kminor_upper,   &
        2293           0 :       gas_minor, identifier_minor,          &
        2294           0 :       minor_gases_lower, minor_gases_upper, &
        2295           0 :       minor_limits_gpt_lower,               &
        2296           0 :       minor_limits_gpt_upper,               &
        2297           0 :       minor_scales_with_density_lower,      &
        2298           0 :       minor_scales_with_density_upper,      &
        2299           0 :       scale_by_complement_lower,            &
        2300           0 :       scale_by_complement_upper,            &
        2301           0 :       scaling_gas_lower, scaling_gas_upper, &
        2302        3072 :       kminor_start_lower, kminor_start_upper)
        2303             :
        2304        3072 :    if (allocated(totplnk))           deallocate(totplnk)
        2305        3072 :    if (allocated(planck_frac))       deallocate(planck_frac)
        2306        3072 :    if (allocated(optimal_angle_fit)) deallocate(optimal_angle_fit)
        2307        3072 :    if (allocated(solar_src_quiet))   deallocate(solar_src_quiet)
        2308        3072 :    if (allocated(solar_src_facular)) deallocate(solar_src_facular)
        2309        3072 :    if (allocated(solar_src_sunspot)) deallocate(solar_src_sunspot)
        2310        3072 :    if (allocated(rayl_lower))        deallocate(rayl_lower)
        2311        3072 :    if (allocated(rayl_upper))        deallocate(rayl_upper)
        2312             :
        2313        6144 : end subroutine coefs_init
        2314             :
        2315             : !=========================================================================================
        2316             :
        2317     5969088 : subroutine initialize_rrtmgp_fluxes(ncol, nlevels, nbands, fluxes, do_direct)
        2318             :
        2319             :    ! Allocate flux arrays and set values to zero.
        2320             :
        2321             :    ! Arguments
        2322             :    integer,                    intent(in)    :: ncol, nlevels, nbands
        2323             :    class(ty_fluxes_broadband), intent(inout) :: fluxes
        2324             :    logical, optional,          intent(in)    :: do_direct
        2325             :
        2326             :    ! Local variables
        2327             :    logical :: do_direct_local
        2328             :    integer :: istat
        2329             :    character(len=*), parameter :: sub = 'initialize_rrtmgp_fluxes'
        2330             :    !----------------------------------------------------------------------------
        2331             :
        2332     5969088 :    if (present(do_direct)) then
        2333             :       do_direct_local = .true.
        2334             :    else
        2335     2984544 :       do_direct_local = .false.
        2336             :    end if
        2337             :
        2338             :    ! Broadband fluxes
        2339    22448964 :    allocate(fluxes%flux_up(ncol, nlevels), stat=istat)
        2340     5969088 :    call handle_allocate_error(istat, sub, 'fluxes%flux_up')
        2341    16479876 :    allocate(fluxes%flux_dn(ncol, nlevels), stat=istat)
        2342     5969088 :    call handle_allocate_error(istat, sub, 'fluxes%flux_dn')
        2343    16479876 :    allocate(fluxes%flux_net(ncol, nlevels), stat=istat)
        2344     5969088 :    call handle_allocate_error(istat, sub, 'fluxes%flux_net')
        2345     5969088 :    if (do_direct_local) then
        2346     7526244 :       allocate(fluxes%flux_dn_dir(ncol, nlevels), stat=istat)
        2347     2984544 :       call handle_allocate_error(istat, sub, 'fluxes%flux_dn_dir')
        2348             :    end if
        2349             :
        2350             :    select type (fluxes)
        2351             :    type is (ty_fluxes_byband)
        2352             :       ! Fluxes by band always needed for SW.  Only allocate for LW
        2353             :       ! when spectralflux is true.
        2354     2984544 :       if (nbands == nswbands .or. spectralflux) then
        2355     6747666 :          allocate(fluxes%bnd_flux_up(ncol, nlevels, nbands), stat=istat)
        2356     1492272 :          call handle_allocate_error(istat, sub, 'fluxes%bnd_flux_up')
        2357     5255394 :          allocate(fluxes%bnd_flux_dn(ncol, nlevels, nbands), stat=istat)
        2358     1492272 :          call handle_allocate_error(istat, sub, 'fluxes%bnd_flux_dn')
        2359     5255394 :          allocate(fluxes%bnd_flux_net(ncol, nlevels, nbands), stat=istat)
        2360     1492272 :          call handle_allocate_error(istat, sub, 'fluxes%bnd_flux_net')
        2361     1492272 :          if (do_direct_local) then
        2362     5255394 :             allocate(fluxes%bnd_flux_dn_dir(ncol, nlevels, nbands), stat=istat)
        2363     1492272 :             call handle_allocate_error(istat, sub, 'fluxes%bnd_flux_dn_dir')
        2364             :          end if
        2365             :       end if
        2366             :    end select
        2367             :
        2368             :    ! Initialize
        2369     5969088 :    call reset_fluxes(fluxes)
        2370             :
        2371     5969088 : end subroutine initialize_rrtmgp_fluxes
        2372             :
        2373             : !=========================================================================================
        2374             :
        2375     5969088 : subroutine reset_fluxes(fluxes)
        2376             :
        2377             :    ! Reset flux arrays to zero.
        2378             :
        2379             :    class(ty_fluxes_broadband), intent(inout) :: fluxes
        2380             :    !----------------------------------------------------------------------------
        2381             :
        2382             :    ! Reset broadband fluxes
        2383  7249214448 :    fluxes%flux_up(:,:) = 0._r8
        2384  7249214448 :    fluxes%flux_dn(:,:) = 0._r8
        2385  7249214448 :    fluxes%flux_net(:,:) = 0._r8
        2386  2514894768 :    if (associated(fluxes%flux_dn_dir)) fluxes%flux_dn_dir(:,:) = 0._r8
        2387             :
        2388             :    select type (fluxes)
        2389             :    type is (ty_fluxes_byband)
        2390             :       ! Reset band-by-band fluxes
        2391 17584863840 :       if (associated(fluxes%bnd_flux_up)) fluxes%bnd_flux_up(:,:,:) = 0._r8
        2392 17586356112 :       if (associated(fluxes%bnd_flux_dn)) fluxes%bnd_flux_dn(:,:,:) = 0._r8
        2393 17586356112 :       if (associated(fluxes%bnd_flux_net)) fluxes%bnd_flux_net(:,:,:) = 0._r8
        2394 17589340656 :       if (associated(fluxes%bnd_flux_dn_dir)) fluxes%bnd_flux_dn_dir(:,:,:) = 0._r8
        2395             :    end select
        2396             :
        2397     5969088 : end subroutine reset_fluxes
        2398             :
        2399             : !=========================================================================================
        2400             :
        2401     4476816 : subroutine free_optics_sw(optics)
        2402             :
        2403             :    type(ty_optical_props_2str), intent(inout) :: optics
        2404             :
        2405     4476816 :    if (allocated(optics%tau)) deallocate(optics%tau)
        2406     4476816 :    if (allocated(optics%ssa)) deallocate(optics%ssa)
        2407     4476816 :    if (allocated(optics%g)) deallocate(optics%g)
        2408     4476816 :    call optics%finalize()
        2409             :
        2410     4476816 : end subroutine free_optics_sw
        2411             :
        2412             : !=========================================================================================
        2413             :
        2414     2984544 : subroutine free_optics_lw(optics)
        2415             :
        2416             :    type(ty_optical_props_1scl), intent(inout) :: optics
        2417             :
        2418     2984544 :    if (allocated(optics%tau)) deallocate(optics%tau)
        2419     2984544 :    call optics%finalize()
        2420             :
        2421     2984544 : end subroutine free_optics_lw
        2422             :
        2423             : !=========================================================================================
        2424             :
        2425     5969088 : subroutine free_fluxes(fluxes)
        2426             :
        2427             :    class(ty_fluxes_broadband), intent(inout) :: fluxes
        2428             :
        2429     5969088 :    if (associated(fluxes%flux_up)) deallocate(fluxes%flux_up)
        2430     5969088 :    if (associated(fluxes%flux_dn)) deallocate(fluxes%flux_dn)
        2431     5969088 :    if (associated(fluxes%flux_net)) deallocate(fluxes%flux_net)
        2432     5969088 :    if (associated(fluxes%flux_dn_dir)) deallocate(fluxes%flux_dn_dir)
        2433             :
        2434             :    select type (fluxes)
        2435             :    type is (ty_fluxes_byband)
        2436     1492272 :       if (associated(fluxes%bnd_flux_up)) deallocate(fluxes%bnd_flux_up)
        2437     2984544 :       if (associated(fluxes%bnd_flux_dn)) deallocate(fluxes%bnd_flux_dn)
        2438     2984544 :       if (associated(fluxes%bnd_flux_net)) deallocate(fluxes%bnd_flux_net)
        2439     5969088 :       if (associated(fluxes%bnd_flux_dn_dir)) deallocate(fluxes%bnd_flux_dn_dir)
        2440             :    end select
        2441             :
        2442     5969088 : end subroutine free_fluxes
        2443             :
        2444             : !=========================================================================================
        2445             :
        2446      746136 : subroutine modified_cloud_fraction(ncol, cld, cldfsnow, cldfgrau, cldfprime)
        2447             :
        2448             :    ! Compute modified cloud fraction, cldfprime.
        2449             :    ! 1. initialize as cld
        2450             :    ! 2. modify for snow if cldfsnow is available. use max(cld, cldfsnow)
        2451             :    ! 3. modify for graupel if cldfgrau is available and graupel_in_rad is true.
        2452             :    !    use max(cldfprime, cldfgrau)
        2453             :
        2454             :    ! Arguments
        2455             :    integer,  intent(in)  :: ncol
        2456             :    real(r8), pointer     :: cld(:,:)       ! cloud fraction
        2457             :    real(r8), pointer     :: cldfsnow(:,:)  ! cloud fraction of just "snow clouds"
        2458             :    real(r8), pointer     :: cldfgrau(:,:)  ! cloud fraction of just "graupel clouds"
        2459             :    real(r8), intent(out) :: cldfprime(:,:) ! modified cloud fraction
        2460             :
        2461             :    ! Local variables
        2462             :    integer :: i, k
        2463             :    !----------------------------------------------------------------------------
        2464             :
        2465      746136 :    if (associated(cldfsnow)) then
        2466    70136784 :       do k = 1, pver
        2467  1159408584 :          do i = 1, ncol
        2468  1158662448 :             cldfprime(i,k) = max(cld(i,k), cldfsnow(i,k))
        2469             :          end do
        2470             :       end do
        2471             :    else
        2472           0 :       cldfprime(:ncol,:) = cld(:ncol,:)
        2473             :    end if
        2474             :
        2475      746136 :    if (associated(cldfgrau) .and. graupel_in_rad) then
        2476           0 :       do k = 1, pver
        2477           0 :          do i = 1, ncol
        2478           0 :             cldfprime(i,k) = max(cldfprime(i,k), cldfgrau(i,k))
        2479             :          end do
        2480             :       end do
        2481             :    end if
        2482             :
        2483      746136 : end subroutine modified_cloud_fraction
        2484             :
        2485             : !=========================================================================================
        2486             :
        2487     9833936 : subroutine stop_on_err(errmsg, sub, info)
        2488             :
        2489             : ! call endrun if RRTMGP function returns non-empty error message.
        2490             :
        2491             :    character(len=*), intent(in) :: errmsg    ! return message from RRTMGP function
        2492             :    character(len=*), intent(in) :: sub       ! name of calling subroutine
        2493             :    character(len=*), intent(in) :: info      ! name of called function
        2494             :
        2495     9833936 :    if (len_trim(errmsg) > 0) then
        2496           0 :       call endrun(trim(sub)//': ERROR: '//trim(info)//': '//trim(errmsg))
        2497             :    end if
        2498             :
        2499     9833936 : end subroutine stop_on_err
        2500             :
        2501             : !=========================================================================================
        2502             :
        2503    17907264 : end module radiation
        2504             :

Generated by: LCOV version 1.14