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
|