LCOV - code coverage report
Current view: top level - physics/rrtmg - radconstants.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 26 49 53.1 %
Date: 2025-03-14 01:23:43 Functions: 6 7 85.7 %

          Line data    Source code
       1             : module radconstants
       2             : 
       3             : ! This module contains constants that are specific to the radiative transfer
       4             : ! code used in the RRTMG model.
       5             : 
       6             : use shr_kind_mod,   only: r8 => shr_kind_r8
       7             : use cam_abortutils, only: endrun
       8             : 
       9             : implicit none
      10             : private
      11             : save
      12             : 
      13             : ! SHORTWAVE DATA
      14             : 
      15             : ! number of shorwave spectral intervals
      16             : integer, parameter, public :: nswbands = 14
      17             : integer, parameter, public :: nbndsw = 14
      18             : 
      19             : ! Wavenumbers of band boundaries
      20             : !
      21             : ! Note: Currently rad_solar_var extends the lowest band down to
      22             : ! 100 cm^-1 if it is too high to cover the far-IR. Any changes meant
      23             : ! to affect IR solar variability should take note of this.
      24             : 
      25             : real(r8),parameter :: wavenum_low(nbndsw) = & ! in cm^-1
      26             :   (/2600._r8, 3250._r8, 4000._r8, 4650._r8, 5150._r8, 6150._r8, 7700._r8, &
      27             :     8050._r8,12850._r8,16000._r8,22650._r8,29000._r8,38000._r8,  820._r8/)
      28             : real(r8),parameter :: wavenum_high(nbndsw) = & ! in cm^-1
      29             :   (/3250._r8, 4000._r8, 4650._r8, 5150._r8, 6150._r8, 7700._r8, 8050._r8, &
      30             :    12850._r8,16000._r8,22650._r8,29000._r8,38000._r8,50000._r8, 2600._r8/)
      31             : 
      32             : ! Solar irradiance at 1 A.U. in W/m^2 assumed by radiation code
      33             : ! Rescaled so that sum is precisely 1368.22 and fractional amounts sum to 1.0
      34             : real(r8), parameter :: solar_ref_band_irradiance(nbndsw) = & 
      35             :    (/ &
      36             :     12.11_r8,  20.3600000000001_r8, 23.73_r8, &
      37             :     22.43_r8,  55.63_r8, 102.93_r8, 24.29_r8, &
      38             :    345.74_r8, 218.19_r8, 347.20_r8, &
      39             :    129.49_r8,  50.15_r8,   3.08_r8, 12.89_r8 &
      40             :    /)
      41             : 
      42             : ! None of the following comment appears to be the case any more? This
      43             : ! should be reevalutated and/or removed.
      44             : 
      45             : ! rrtmg (coarse) reference solar flux in rrtmg is initialized as the following
      46             : ! reference data inside rrtmg seems to indicate 1366.44 instead
      47             : !  This data references 1366.442114152342
      48             : !real(r8), parameter :: solar_ref_band_irradiance(nbndsw) = & 
      49             : !   (/ &
      50             : !   12.10956827000000_r8, 20.36508467999999_r8, 23.72973826333333_r8, &
      51             : !   22.42769644333333_r8, 55.62661262000000_r8, 102.9314315544444_r8, 24.29361887666667_r8, &
      52             : !   345.7425138000000_r8, 218.1870300666667_r8, 347.1923147000001_r8, &
      53             : !   129.4950181200000_r8, 48.37217043000000_r8, 3.079938997898001_r8, 12.88937733000000_r8 &
      54             : !   /)
      55             : !  Kurucz (fine) reference would seem to imply the following but the above values are from rrtmg_sw_init
      56             : !  (/12.109559, 20.365097, 23.729752, 22.427697, 55.626622, 102.93142, 24.293593, &
      57             : !    345.73655, 218.18416, 347.18406, 129.49407, 50.147238, 3.1197130, 12.793834 /)
      58             : 
      59             : ! These are indices to the band for diagnostic output
      60             : integer, parameter, public :: idx_sw_diag = 10 ! index to sw visible band
      61             : integer, parameter, public :: idx_nir_diag = 8 ! index to sw near infrared (778-1240 nm) band
      62             : integer, parameter, public :: idx_uv_diag = 11 ! index to sw uv (345-441 nm) band
      63             : 
      64             : integer, parameter, public :: rrtmg_sw_cloudsim_band = 9  ! rrtmg band for .67 micron
      65             : 
      66             : ! LONGWAVE DATA
      67             : 
      68             : ! These are indices to the band for diagnostic output
      69             : integer, parameter, public :: idx_lw_diag = 7 ! index to (H20 window) LW band
      70             : 
      71             : integer, parameter, public :: rrtmg_lw_cloudsim_band = 6  ! rrtmg band for 10.5 micron
      72             : 
      73             : ! number of lw bands
      74             : integer, parameter, public :: nlwbands = 16
      75             : integer, parameter, public :: nbndlw = 16
      76             : 
      77             : real(r8), parameter :: wavenumber1_longwave(nlwbands) = &! Longwave spectral band limits (cm-1)
      78             :     (/   10._r8,  350._r8, 500._r8,   630._r8,  700._r8,  820._r8,  980._r8, 1080._r8, &
      79             :        1180._r8, 1390._r8, 1480._r8, 1800._r8, 2080._r8, 2250._r8, 2390._r8, 2600._r8 /)
      80             : 
      81             : real(r8), parameter :: wavenumber2_longwave(nlwbands) = &! Longwave spectral band limits (cm-1)
      82             :     (/  350._r8,  500._r8,  630._r8,  700._r8,  820._r8,  980._r8, 1080._r8, 1180._r8, &
      83             :        1390._r8, 1480._r8, 1800._r8, 2080._r8, 2250._r8, 2390._r8, 2600._r8, 3250._r8 /)
      84             : 
      85             : !These can go away when old camrt disappears
      86             : ! Index of volc. abs., H2O non-window
      87             : integer, public, parameter :: idx_LW_H2O_NONWND=1
      88             : ! Index of volc. abs., H2O window
      89             : integer, public, parameter :: idx_LW_H2O_WINDOW=2
      90             : ! Index of volc. cnt. abs. 0500--0650 cm-1
      91             : integer, public, parameter :: idx_LW_0500_0650=3
      92             : ! Index of volc. cnt. abs. 0650--0800 cm-1
      93             : integer, public, parameter :: idx_LW_0650_0800=4
      94             : ! Index of volc. cnt. abs. 0800--1000 cm-1
      95             : integer, public, parameter :: idx_LW_0800_1000=5
      96             : ! Index of volc. cnt. abs. 1000--1200 cm-1
      97             : integer, public, parameter :: idx_LW_1000_1200=6
      98             : ! Index of volc. cnt. abs. 1200--2000 cm-1
      99             : integer, public, parameter :: idx_LW_1200_2000=7
     100             : 
     101             : ! GASES TREATED BY RADIATION (line spectrae)
     102             : 
     103             : ! gasses required by radiation
     104             : integer, public, parameter :: gasnamelength = 5
     105             : integer, public, parameter :: nradgas = 8
     106             : character(len=gasnamelength), public, parameter :: gaslist(nradgas) &
     107             :    = (/'H2O  ','O3   ', 'O2   ', 'CO2  ', 'N2O  ', 'CH4  ', 'CFC11', 'CFC12'/)
     108             : 
     109             : ! what is the minimum mass mixing ratio that can be supported by radiation implementation?
     110             : real(r8), public, parameter :: minmmr(nradgas) &
     111             :    = epsilon(1._r8)
     112             : 
     113             : public :: rad_gas_index
     114             : 
     115             : public :: get_number_sw_bands, &
     116             :           get_sw_spectral_boundaries, &
     117             :           get_lw_spectral_boundaries, &
     118             :           get_ref_solar_band_irrad, &
     119             :           get_ref_total_solar_irrad, &
     120             :           get_solar_band_fraction_irrad
     121             : 
     122             : contains
     123             : !------------------------------------------------------------------------------
     124        1536 : subroutine get_solar_band_fraction_irrad(fractional_irradiance)
     125             :    ! provide Solar Irradiance for each band in RRTMG
     126             : 
     127             :    ! fraction of solar irradiance in each band
     128             :    real(r8), intent(out) :: fractional_irradiance(1:nswbands)
     129             :    real(r8) :: tsi ! total solar irradiance
     130             : 
     131        1536 :    tsi = sum(solar_ref_band_irradiance)
     132       23040 :    fractional_irradiance = solar_ref_band_irradiance / tsi
     133             : 
     134        1536 : end subroutine get_solar_band_fraction_irrad
     135             : !------------------------------------------------------------------------------
     136           0 : subroutine get_ref_total_solar_irrad(tsi)
     137             :    ! provide Total Solar Irradiance assumed by RRTMG
     138             : 
     139             :    real(r8), intent(out) :: tsi
     140             : 
     141           0 :    tsi = sum(solar_ref_band_irradiance)
     142             : 
     143           0 : end subroutine get_ref_total_solar_irrad
     144             : !------------------------------------------------------------------------------
     145        3072 : subroutine get_ref_solar_band_irrad( band_irrad )
     146             : 
     147             :    ! solar irradiance in each band (W/m^2)
     148             :    real(r8), intent(out) :: band_irrad(nswbands)
     149             :  
     150        3072 :    band_irrad = solar_ref_band_irradiance
     151             : 
     152        3072 : end subroutine get_ref_solar_band_irrad
     153             : !------------------------------------------------------------------------------
     154        1536 : subroutine get_number_sw_bands(number_of_bands)
     155             : 
     156             :    ! number of solar (shortwave) bands in the rrtmg code
     157             :    integer, intent(out) :: number_of_bands
     158             : 
     159        1536 :    number_of_bands = nswbands
     160             : 
     161        1536 : end subroutine get_number_sw_bands
     162             : 
     163             : !------------------------------------------------------------------------------
     164        1536 : subroutine get_lw_spectral_boundaries(low_boundaries, high_boundaries, units)
     165             :    ! provide spectral boundaries of each longwave band
     166             : 
     167             :    real(r8), intent(out) :: low_boundaries(nlwbands), high_boundaries(nlwbands)
     168             :    character(*), intent(in) :: units ! requested units
     169             : 
     170           0 :    select case (units)
     171             :    case ('inv_cm','cm^-1','cm-1')
     172           0 :       low_boundaries  = wavenumber1_longwave
     173           0 :       high_boundaries = wavenumber2_longwave
     174             :    case('m','meter','meters')
     175           0 :       low_boundaries  = 1.e-2_r8/wavenumber2_longwave
     176           0 :       high_boundaries = 1.e-2_r8/wavenumber1_longwave
     177             :    case('nm','nanometer','nanometers')
     178           0 :       low_boundaries  = 1.e7_r8/wavenumber2_longwave
     179           0 :       high_boundaries = 1.e7_r8/wavenumber1_longwave
     180             :    case('um','micrometer','micrometers','micron','microns')
     181        1536 :       low_boundaries  = 1.e4_r8/wavenumber2_longwave
     182        1536 :       high_boundaries = 1.e4_r8/wavenumber1_longwave
     183             :    case('cm','centimeter','centimeters')
     184           0 :       low_boundaries  = 1._r8/wavenumber2_longwave
     185           0 :       high_boundaries = 1._r8/wavenumber1_longwave
     186             :    case default
     187        1536 :       call endrun('get_lw_spectral_boundaries: spectral units not acceptable'//units)
     188             :    end select
     189             : 
     190        1536 : end subroutine get_lw_spectral_boundaries
     191             : 
     192             : !------------------------------------------------------------------------------
     193        1536 : subroutine get_sw_spectral_boundaries(low_boundaries, high_boundaries, units)
     194             :    ! provide spectral boundaries of each shortwave band
     195             : 
     196             :    real(r8), intent(out) :: low_boundaries(nswbands), high_boundaries(nswbands)
     197             :    character(*), intent(in) :: units ! requested units
     198             : 
     199           0 :    select case (units)
     200             :    case ('inv_cm','cm^-1','cm-1')
     201           0 :       low_boundaries = wavenum_low
     202           0 :       high_boundaries = wavenum_high
     203             :    case('m','meter','meters')
     204           0 :       low_boundaries = 1.e-2_r8/wavenum_high
     205           0 :       high_boundaries = 1.e-2_r8/wavenum_low
     206             :    case('nm','nanometer','nanometers')
     207        1536 :       low_boundaries = 1.e7_r8/wavenum_high
     208        1536 :       high_boundaries = 1.e7_r8/wavenum_low
     209             :    case('um','micrometer','micrometers','micron','microns')
     210           0 :       low_boundaries = 1.e4_r8/wavenum_high
     211           0 :       high_boundaries = 1.e4_r8/wavenum_low
     212             :    case('cm','centimeter','centimeters')
     213           0 :       low_boundaries  = 1._r8/wavenum_high
     214           0 :       high_boundaries = 1._r8/wavenum_low
     215             :    case default
     216        1536 :       call endrun('rad_constants.F90: spectral units not acceptable'//units)
     217             :    end select
     218             : 
     219        1536 : end subroutine get_sw_spectral_boundaries
     220             : 
     221             : !------------------------------------------------------------------------------
     222      708864 : integer function rad_gas_index(gasname)
     223             : 
     224             :    ! return the index in the gaslist array of the specified gasname
     225             : 
     226             :    character(len=*),intent(in) :: gasname
     227             :    integer :: igas
     228             : 
     229      708864 :    rad_gas_index = -1
     230     2984448 :    do igas = 1, nradgas
     231     2984448 :       if (trim(gaslist(igas)).eq.trim(gasname)) then
     232      708864 :          rad_gas_index = igas
     233      708864 :          return
     234             :       endif
     235             :    enddo
     236           0 :    call endrun ("rad_gas_index: can not find gas with name "//gasname)
     237           0 : end function rad_gas_index
     238             : 
     239             : end module radconstants

Generated by: LCOV version 1.14