Radiation Scheme in CCPP
radiation_aerosols.f
Go to the documentation of this file.
1 ! ========================================================== !!!!!
2 ! 'module_radiation_aerosols' description !!!!!
3 ! ========================================================== !!!!!
4 ! !
5 ! this module contains climatological atmospheric aerosol schemes for!
6 ! radiation computations. !
7 ! !
8 ! in the module, the externally callable subroutines are : !
9 ! !
10 ! 'aer_init' -- initialization !
11 ! inputs: !
12 ! ( NLAY, me ) !
13 ! outputs: !
14 ! ( none ) !
15 ! !
16 ! 'aer_update' -- updating aerosol data !
17 ! inputs: !
18 ! ( iyear, imon, me ) !
19 ! outputs: !
20 ! ( none ) !
21 ! !
22 ! 'setaer' -- mapping aeros profile, compute aeros opticals !
23 ! inputs: !
24 ! (prsi,prsl,prslk,tvly,rhlay,slmsk,tracer,xlon,xlat, !
25 ! IMAX,NLAY,NLP1, lsswr,lslwr, !
26 ! outputs: !
27 ! (aerosw,aerolw,tau_gocart) !
28 !! (aerosw,aerolw,aerodp) !
29 ! !
30 ! !
31 ! external modules referenced: !
32 ! 'module physparam' in 'physparam.f' !
33 ! 'module physcons' in 'physcons.f' !
34 ! 'module module_radsw_parameters' in 'radsw_xxxx#_param.f' !
35 ! 'module module_radlw_parameters' in 'radlw_xxxx#_param.f' !
36 ! 'module module_radlw_cntr_para' in 'radsw_xxxx#_param.f' !
37 ! !
38 ! output variable definitions: !
39 ! aerosw(IMAX,NLAY,NBDSW,1) - aerosols optical depth for sw !
40 ! aerosw(IMAX,NLAY,NBDSW,2) - aerosols single scat albedo for sw !
41 ! aerosw(IMAX,NLAY,NBDSW,3) - aerosols asymmetry parameter for sw!
42 ! !
43 ! aerolw(IMAX,NLAY,NBDLW,1) - aerosols optical depth for lw !
44 ! aerolw(IMAX,NLAY,NBDLW,2) - aerosols single scattering albedo !
45 ! aerolw(IMAX,NLAY,NBDLW,3) - aerosols asymetry parameter !
46 ! !
47 ! !
48 ! program history: !
49 ! apr 2003 --- y.-t. hou created !
50 ! nov 04, 2003 --- y.-t. hou modified version !
51 ! apr 15, 2005 --- y.-t. hou modified module structure !
52 ! jul 2006 --- y.-t. hou add volcanic forcing !
53 ! feb 2007 --- y.-t. hou add generalized spectral band !
54 ! interpolation for sw aerosol optical properties !
55 ! mar 2007 --- y.-t. hou add generalized spectral band !
56 ! interpolation for lw aerosol optical properties !
57 ! aug 2007 --- y.-t. hou change clim-aer vert domain !
58 ! from pressure reference to sigma reference !
59 ! sep 2007 --- y.-t. hou moving temporary allocatable !
60 ! module variable arrays to subroutine dynamically !
61 ! allocated arrays (eliminate deallocate calls) !
62 ! jan 2010 --- sarah lu add gocart option !
63 ! may 2010 --- sarah lu add geos4-gocart climo !
64 ! jul 2010 -- s. moorthi - merged NEMS version with new GFS !
65 ! version !
66 ! oct 23, 2010 --- Hsin-mu lin modified subr setclimaer to !
67 ! interpolate the 5 degree aerosol data to small domain based on!
68 ! the nearby 4 points instead of previous nearby assignment by !
69 ! using the 5 degree data. this process will eliminate the dsw !
70 ! jagged edges in the east conus where aerosol effect are lagre.!
71 ! dec 2010 --- y.-t. hou modified and optimized bi-linear!
72 ! horizontal interpolation in subr setclimaer. added safe guard !
73 ! measures in lat/lon indexing and added sea/land mask variable !
74 ! slmsk as input field to help aerosol profile selection. !
75 ! jan 2011 --- y.-t. hou divided the program into two !
76 ! separated interchangeable modules: a climatology aerosol !
77 ! module, and a gocart aerosol scheme module. the stratospheric !
78 ! volcanic aerosol part is still within the two driver modules, !
79 ! and may also become a separate one in the further development.!
80 ! unified in/out argument list for both clim and gocart types of!
81 ! schemes and added vertically integrated aer-opt-dep, aerodp, !
82 ! to replace tau_gocart as optional output for various species. !
83 ! aug 2012 --- y.-t. hou changed the initialization subr !
84 ! 'aerinit' into two parts: 'aer_init' is called at the start !
85 ! of run to set up module parameters; and 'aer_update' is !
86 ! called within the time loop to check and update data sets. !
87 ! nov 2012 --- y.-t. hou modified control parameters thru!
88 ! module 'physparam'. !
89 ! jan 2013 --- sarah lu and y.-t. hou reintegrate both !
90 ! opac-clim and gocart schemes into one module to make the !
91 ! program best utilize common components. added aerosol model !
92 ! scheme selection control variable iaer_mdl to the namelist. !
93 ! Aug 2013 --- s. moorthi - merge sarah's gocart changes with!
94 ! yutai's changes !
95 ! 13Feb2014 --- Sarah lu - compute aod at 550nm !
96 ! !
97 ! references for opac climatological aerosols: !
98 ! hou et al. 2002 (ncep office note 441) !
99 ! hess et al. 1998 - bams v79 831-844 !
100 ! !
101 ! references for gocart interactive aerosols: !
102 ! chin et al., 2000 - jgr, v105, 24671-24687 !
103 ! !
104 ! references for stratosperic volcanical aerosols: !
105 ! sato et al. 1993 - jgr, v98, d12, 22987-22994 !
106 ! !
107 ! !
108 !!!!! ========================================================== !!!!!
109 !!!!! end descriptions !!!!!
110 !!!!! ========================================================== !!!!!
111 
112 
115 !========================================!
117 !........................................!
118 !
119  use physparam,only : iaermdl, iaerflg, lavoflg, lalwflg, laswflg, &
120  & lalw1bd, aeros_file, ivflip, kind_phys &
121  &, kind_io4, kind_io8
122  use physcons, only : con_pi, con_rd, con_g, con_t0c, con_c, &
124 
125  use module_iounitdef, only : niaercm
126  use module_radsw_parameters, only : nbdsw, wvnsw1=>wvnum1, &
127  & nswstr, wvnsw2=>wvnum2
129 !
130  use funcphys, only : fpkap
131  use gfs_phy_tracer_config, only : gfs_phy_tracer, trcindx
132 !
133  implicit none
134 !
135  private
136 
137 ! --- version tag and last revision date
138  character(40), parameter :: &
139  & VTAGAER='NCEP-Radiation_aerosols v5.2 Jan 2013 '
140 ! & VTAGAER='NCEP-Radiation_aerosols v5.1 Nov 2012 '
141 ! & VTAGAER='NCEP-Radiation_aerosols v5.0 Aug 2012 '
142 
143 ! --- general use parameter constants:
145  integer, parameter, public :: nf_aesw = 3 ! num of output fields for sw rad
147  integer, parameter, public :: nf_aelw = 3 ! num of output fields for lw rad
149  integer, parameter, public :: nlwstr = 1 ! starting band number in ir region
151  integer, parameter, public :: nspc = 5 ! num of species for output aod (opnl)
153  integer, parameter, public :: nspc1 = nspc + 1 ! total + species
154 
155  real (kind=kind_phys), parameter :: f_zero = 0.0
156  real (kind=kind_phys), parameter :: f_one = 1.0
157 
158 ! --- module control parameters set in subroutine "aer_init"
159  integer, save :: nswbnd = nbdsw ! number of actual bands for sw aerosols
160  ! calculated according to laswflg setting
161  integer, save :: nlwbnd = nbdlw ! number of actual bands for lw aerosols
162  ! calculated according to lalwflg and lalw1bd settings
163  integer, save :: nswlwbd = nbdsw+nbdlw ! total number of bands for sw+lw aerosols
164 
165 ! --------------------------------------------------------------------- !
166 ! section-1 : module variables for spectral band interpolation !
167 ! similar to gfdl-sw treatment (2000 version) !
168 ! --------------------------------------------------------------------- !
169 
170 ! --- parameter constants:
172  integer, parameter, public :: nwvsol = 151 ! num of wvnum regions where solar
173  ! flux is constant
175  integer, parameter, public :: nwvtot = 57600 ! total num of wvnum included
177  integer, parameter, public :: nwvtir = 4000 ! total num of wvnum in ir range
178 
179 ! --- number of wavenumbers in each region where the solar flux is constant
180  integer, dimension(NWVSOL), save :: nwvns0
181 
182  data nwvns0 / 100, 11, 14, 18, 24, 33, 50, 83, 12, 12, &
183  & 13, 15, 15, 17, 18, 20, 21, 24, 26, 30, 32, 37, 42, &
184  & 47, 55, 64, 76, 91, 111, 139, 179, 238, 333, 41, 42, 45, &
185  & 46, 48, 51, 53, 55, 58, 61, 64, 68, 71, 75, 79, 84, &
186  & 89, 95, 101, 107, 115, 123, 133, 142, 154, 167, 181, 197, 217, &
187  & 238, 263, 293, 326, 368, 417, 476, 549, 641, 758, 909, 101, 103, &
188  & 105, 108, 109, 112, 115, 117, 119, 122, 125, 128, 130, 134, 137, &
189  & 140, 143, 147, 151, 154, 158, 163, 166, 171, 175, 181, 185, 190, &
190  & 196, 201, 207, 213, 219, 227, 233, 240, 248, 256, 264, 274, 282, &
191  & 292, 303, 313, 325, 337, 349, 363, 377, 392, 408, 425, 444, 462, &
192  & 483, 505, 529, 554, 580, 610, 641, 675, 711, 751, 793, 841, 891, &
193  & 947,1008,1075,1150,1231,1323,1425,1538,1667,1633,14300 /
194 
195 ! --- solar flux (w/m**2) in each wvnumb region where it is constant
196  real (kind=kind_phys), dimension(NWVSOL), save :: s0intv
197 
198  data s0intv( 1: 50) / &
199  & 1.60000e-6, 2.88000e-5, 3.60000e-5, 4.59200e-5, 6.13200e-5, &
200  & 8.55000e-5, 1.28600e-4, 2.16000e-4, 2.90580e-4, 3.10184e-4, &
201  & 3.34152e-4, 3.58722e-4, 3.88050e-4, 4.20000e-4, 4.57056e-4, &
202  & 4.96892e-4, 5.45160e-4, 6.00600e-4, 6.53600e-4, 7.25040e-4, &
203  & 7.98660e-4, 9.11200e-4, 1.03680e-3, 1.18440e-3, 1.36682e-3, &
204  & 1.57560e-3, 1.87440e-3, 2.25500e-3, 2.74500e-3, 3.39840e-3, &
205  & 4.34000e-3, 5.75400e-3, 7.74000e-3, 9.53050e-3, 9.90192e-3, &
206  & 1.02874e-2, 1.06803e-2, 1.11366e-2, 1.15830e-2, 1.21088e-2, &
207  & 1.26420e-2, 1.32250e-2, 1.38088e-2, 1.44612e-2, 1.51164e-2, &
208  & 1.58878e-2, 1.66500e-2, 1.75140e-2, 1.84450e-2, 1.94106e-2 /
209  data s0intv( 51:100) / &
210  & 2.04864e-2, 2.17248e-2, 2.30640e-2, 2.44470e-2, 2.59840e-2, &
211  & 2.75940e-2, 2.94138e-2, 3.13950e-2, 3.34800e-2, 3.57696e-2, &
212  & 3.84054e-2, 4.13490e-2, 4.46880e-2, 4.82220e-2, 5.22918e-2, &
213  & 5.70078e-2, 6.19888e-2, 6.54720e-2, 6.69060e-2, 6.81226e-2, &
214  & 6.97788e-2, 7.12668e-2, 7.27100e-2, 7.31610e-2, 7.33471e-2, &
215  & 7.34814e-2, 7.34717e-2, 7.35072e-2, 7.34939e-2, 7.35202e-2, &
216  & 7.33249e-2, 7.31713e-2, 7.35462e-2, 7.36920e-2, 7.23677e-2, &
217  & 7.25023e-2, 7.24258e-2, 7.20766e-2, 7.18284e-2, 7.32757e-2, &
218  & 7.31645e-2, 7.33277e-2, 7.36128e-2, 7.33752e-2, 7.28965e-2, &
219  & 7.24924e-2, 7.23307e-2, 7.21050e-2, 7.12620e-2, 7.10903e-2 /
220  data s0intv(101:151) / 7.12714e-2, &
221  & 7.08012e-2, 7.03752e-2, 7.00350e-2, 6.98639e-2, 6.90690e-2, &
222  & 6.87621e-2, 6.52080e-2, 6.65184e-2, 6.60038e-2, 6.47615e-2, &
223  & 6.44831e-2, 6.37206e-2, 6.24102e-2, 6.18698e-2, 6.06320e-2, &
224  & 5.83498e-2, 5.67028e-2, 5.51232e-2, 5.48645e-2, 5.12340e-2, &
225  & 4.85581e-2, 4.85010e-2, 4.79220e-2, 4.44058e-2, 4.48718e-2, &
226  & 4.29373e-2, 4.15242e-2, 3.81744e-2, 3.16342e-2, 2.99615e-2, &
227  & 2.92740e-2, 2.67484e-2, 1.76904e-2, 1.40049e-2, 1.46224e-2, &
228  & 1.39993e-2, 1.19574e-2, 1.06386e-2, 1.00980e-2, 8.63808e-3, &
229  & 6.52736e-3, 4.99410e-3, 4.39350e-3, 2.21676e-3, 1.33812e-3, &
230  & 1.12320e-3, 5.59000e-4, 3.60000e-4, 2.98080e-4, 7.46294e-5 /
231 
232 ! --------------------------------------------------------------------- !
233 ! section-2 : module variables for stratospheric volcanic aerosols !
234 ! from historical data (sato et al. 1993) !
235 ! --------------------------------------------------------------------- !
236 
237 ! --- parameter constants:
238  integer, parameter :: minvyr = 1850 ! lower lim (year) data available
239  integer, parameter :: maxvyr = 1999 ! upper lim (year) data available
240 
241 ! --- monthly, 45-deg lat-zone aerosols data set in subroutine 'aer_init'
242  integer, allocatable, save :: ivolae(:,:,:)
243 
244 ! --- static control variables:
245  integer :: kyrstr, kyrend, kyrsav, kmonsav
246 
247 ! --------------------------------------------------------------------- !
248 ! section-3 : module variables for opac climatological aerosols !
249 ! optical properties (hess et al. 1989) !
250 ! --------------------------------------------------------------------- !
251 
252 ! --- parameters and constants:
253  integer, parameter :: nxc = 5 ! num of max componets in a profile
254  integer, parameter :: nae = 7 ! num of aerosols profile structures
255  integer, parameter :: ndm = 5 ! num of atmos aerosols domains
256  integer, parameter :: imxae = 72 ! num of lon-points in glb aeros data set
257  integer, parameter :: jmxae = 37 ! num of lat-points in glb aeros data set
258  integer, parameter :: naerbnd=61 ! num of bands for clim aer data (opac)
259  integer, parameter :: nrhlev =8 ! num of rh levels for rh-dep components
260  integer, parameter :: ncm1 = 6 ! num of rh independent aeros species
261  integer, parameter :: ncm2 = 4 ! num of rh dependent aeros species
262  integer, parameter :: ncm = ncm1+ncm2
263 
264  real (kind=kind_phys), dimension(NRHLEV), save :: rhlev
265  data rhlev(:) / 0.0, 0.5, 0.7, 0.8, 0.9, 0.95, 0.98, 0.99 /
266 
267 ! --- the following arrays are for climatological data that are
268 ! allocated and read in subroutine 'clim_aerinit'.
269 ! - global aerosol distribution:
270 ! haer (NDM,NAE) - scale height of aerosols (km)
271 ! prsref(NDM,NAE) - ref pressure lev (sfc to toa) in mb (100Pa)
272 ! sigref(NDM,NAE) - ref sigma lev (sfc to toa)
273 
274  real (kind=kind_phys), save, dimension(NDM,NAE) :: haer, prsref, &
275  & sigref
276 
277 ! --- the following arrays are allocate and setup in subr 'clim_aerinit'
278 ! - for relative humidity independent aerosol optical properties:
279 ! species : insoluble (inso); soot (soot);
280 ! mineral nuc mode (minm); mineral acc mode (miam);
281 ! mineral coa mode (micm); mineral transport(mitr).
282 ! extrhi(NCM1,NSWLWBD) - extinction coefficient for sw+lw spectral band
283 ! scarhi(NCM1,NSWLWBD) - scattering coefficient for sw+lw spectral band
284 ! ssarhi(NCM1,NSWLWBD) - single scattering albedo for sw+lw spectral band
285 ! asyrhi(NCM1,NSWLWBD) - asymmetry parameter for sw+lw spectral band
286 ! - for relative humidity dependent aerosol optical properties:
287 ! species : water soluble (waso); sea salt acc mode(ssam);
288 ! sea salt coa mode(sscm); sulfate droplets (suso).
289 ! rh level: 00%, 50%, 70%, 80%, 90%, 95%, 98%, 99%
290 ! extrhd(NRHLEV,NCM2,NSWLWBD) - extinction coefficient for sw+lw band
291 ! scarhd(NRHLEV,NCM2,NSWLWBD) - scattering coefficient for sw+lw band
292 ! ssarhd(NRHLEV,NCM2,NSWLWBD) - single scattering albedo for sw+lw band
293 ! asyrhd(NRHLEV,NCM2,NSWLWBD) - asymmetry parameter for sw+lw band
294 ! - for stratospheric aerosols optical properties:
295 ! extstra(NSWLWBD) - extinction coefficient for sw+lw band
296 
297  real (kind=kind_phys), allocatable, save, dimension(:,:) :: &
298  & extrhi, scarhi, ssarhi, asyrhi
299  real (kind=kind_phys), allocatable, save, dimension(:,:,:) :: &
300  & extrhd, scarhd, ssarhd, asyrhd
301  real (kind=kind_phys), allocatable, save, dimension(:) :: &
302  & extstra
303 
304 ! --- the following arrays are calculated in subr 'clim_aerinit'
305 ! - for topospheric aerosol profile distibution:
306 ! kprfg ( IMXAE*JMXAE) - aeros profile index
307 ! idxcg (NXC*IMXAE*JMXAE) - aeros component index
308 ! cmixg (NXC*IMXAE*JMXAE) - aeros component mixing ratio
309 ! denng ( 2 *IMXAE*JMXAE) - aerosols number density
310 
311  real (kind=kind_phys), dimension(NXC,IMXAE,JMXAE), save :: cmixg
312  real (kind=kind_phys), dimension( 2 ,IMXAE,JMXAE), save :: denng
313  integer, dimension(NXC,IMXAE,JMXAE), save :: idxcg
314  integer, dimension( IMXAE,JMXAE), save :: kprfg
315 
316 ! --------------------------------------------------------------------- !
317 ! section-4 : module variables for gocart aerosol optical properties !
318 ! --------------------------------------------------------------------- !
319 
320 ! --- parameters and constants:
321 ! - KCM, KCM1, KCM2 are determined from subroutine 'set_aerspc'
322  integer, parameter :: kaerbnd=61 ! num of bands for aer data (gocart)
323  integer, parameter :: krhlev =36 ! num of rh levels for rh-dep components
324 !* integer, parameter :: KCM1 = 8 ! num of rh independent aer !species
325 !* integer, parameter :: KCM2 = 5 ! num of rh dependent aer species
326 !* integer, parameter :: KCM = KCM1 + KCM2
327  integer, save :: kcm1 = 0 ! num of rh indep aerosols (set in subr set_aerspc)
328  integer, save :: kcm2 = 0 ! num of rh dep aerosols (set in subr set_aerspc)
329  integer, save :: kcm ! =KCM1+KCM2 (set in subr set_aerspc)
330 
331  real (kind=kind_phys), dimension(KRHLEV) :: rhlev_grt &
332  data rhlev_grt (:)/ .00, .05, .10, .15, .20, .25, .30, .35, &
333  & .40, .45, .50, .55, .60, .65, .70, .75, .80, .81, .82, &
334  & .83, .84, .85, .86, .87, .88, .89, .90, .91, .92, .93, &
335  & .94, .95, .96, .97, .98, .99 /
336 
337 ! --- the following arrays are allocate and setup in subr 'gocrt_aerinit'
338 ! ------ gocart aerosol specification ------
339 ! => transported aerosol species:
340 ! DU (5-bins)
341 ! SS (4 bins for climo mode and 5 bins for fcst mode)
342 ! SU (dms, so2, so4, msa)
343 ! OC (phobic, philic) and BC (phobic, philic)
344 ! => species and lumped species for aerosol optical properties
345 ! DU (5-bins, with 4 sub-groups in the submicron bin )
346 ! SS (ssam for submicron, sscm for coarse mode)
347 ! SU (so4)
348 ! OC (phobic, philic) and BC (phobic, philic)
349 ! => specification used for aerosol optical properties luts
350 ! DU (8 bins)
351 ! SS (ssam, sscm)
352 ! SU (suso)
353 ! OC (waso) and BC (soot)
354 !
355 ! - spectral band structure:
356 ! iendwv_grt(KAERBND) - ending wavenumber (cm**-1) for each band
357 ! - relative humidity independent aerosol optical properties:
358 ! ===> species : dust (8 bins)
359 ! rhidext0_grt(KAERBND,KCM1) - extinction coefficient
360 ! rhidssa0_grt(KAERBND,KCM1) - single scattering albedo
361 ! rhidasy0_grt(KAERBND,KCM1) - asymmetry parameter
362 ! - relative humidity dependent aerosol optical properties:
363 ! ===> species : soot, suso, waso, ssam, sscm
364 ! rhdpext0_grt(KAERBND,KRHLEV,KCM2) - extinction coefficient
365 ! rhdpssa0_grt(KAERBND,KRHLEV,KCM2) - single scattering albedo
366 ! rhdpasy0_grt(KAERBND,KRHLEV,KCM2) - asymmetry parameter
367 
368  integer, allocatable, dimension(:) :: iendwv_grt
369  real (kind=kind_phys), allocatable, dimension(:,:) :: &
370  & rhidext0_grt, rhidssa0_grt, rhidasy0_grt
371  real (kind=kind_phys), allocatable, dimension(:,:,:):: &
372  & rhdpext0_grt, rhdpssa0_grt, rhdpasy0_grt
373 
374 ! - relative humidity independent aerosol optical properties:
375 ! extrhi_grt(KCM1,NSWLWBD) - extinction coefficient for sw+lw spectral band
376 ! ssarhi_grt(KCM1,NSWLWBD) - single scattering albedo for sw+lw spectral band
377 ! asyrhi_grt(KCM1,NSWLWBD) - asymmetry parameter for sw+lw spectral band
378 ! - relative humidity dependent aerosol optical properties:
379 ! extrhd_grt(KRHLEV,KCM2,NSWLWBD) - extinction coefficient for sw+lw band
380 ! ssarhd_grt(KRHLEV,KCM2,NSWLWBD) - single scattering albedo for sw+lw band
381 ! asyrhd_grt(KRHLEV,KCM2,NSWLWBD) - asymmetry parameter for sw+lw band
382 
383  real (kind=kind_phys), allocatable, save, dimension(:,:) :: &
384  & extrhi_grt, ssarhi_grt, asyrhi_grt
385  real (kind=kind_phys), allocatable, save, dimension(:,:,:) :: &
386  & extrhd_grt, ssarhd_grt, asyrhd_grt
387 
388 ! --------------------------------------------------------------------- !
389 ! section-5 : module variables for gocart aerosol climo data set !
390 ! --------------------------------------------------------------------- !
391 ! This version only supports geos3-gocart data set (Jan 2010)
392 ! Modified to support geos4-gocart data set (May 2010)
393 !
394 ! geos3-gocart vs geos4-gocart
395 ! (1) Use the same module variables
396 ! IMXG,JMXG,KMXG,NMXG,psclmg,dmclmg,geos_rlon,geos_rlat
397 ! (2) Similarity between geos3 and geos 4:
398 ! identical lat/lon grids and aerosol specification;
399 ! direction of vertical index is bottom-up (sfc to toa)
400 ! (3) Difference between geos3 and geos4
401 ! vertical coordinate (sigma for geos3/hybrid_sigma_pressure for geos4)
402 ! aerosol units (mass concentration for geos3/mixing ratio for geos4)
403 
404  integer, parameter :: imxg = 144 ! num of lon-points in geos dataset
405  integer, parameter :: jmxg = 91 ! num of lat-points in geos dataset
406  integer, parameter :: kmxg = 30 ! num of vertical layers in geos dataset
407 !* integer, parameter :: NMXG = 12 ! num of gocart aer spec for opt calc
408  integer, save :: nmxg ! to be determined by set_aerspc
409 
410  real (kind=kind_phys), parameter :: dltx = 360.0 / float(imxg)
411  real (kind=kind_phys), parameter :: dlty = 180.0 / float(jmxg-1)
412 
413 ! --- the following arrays are allocated and setup in 'rd_gocart_clim'
414 ! - geos-gocart climo data (input dataset)
415 ! psclmg - pressure in cb IMXG*JMXG*KMXG
416 ! dmclmg - aerosol dry mass in g/m3 IMXG*JMXG*KMXG*NMXG
417 ! or aerosol mixing ratio in mol/mol or Kg/Kg
418 
419  real (kind=kind_phys),allocatable, save:: psclmg(:,:,:), &
420  & dmclmg(:,:,:,:)
421 
422 ! - geos-gocart lat/lon arrays
423  real (kind=kind_phys), allocatable, save, dimension(:) :: &
424  & geos_rlon, geos_rlat
425 
426 ! - control flag for gocart climo data set
427 ! xxxx as default; ver3 for geos3; ver4 for geos4; 0000 for unknown data
428  character*4, save :: gocart_climo = 'xxxx'
429 
430 ! - molecular wght of gocart aerosol species
431  real (kind=kind_io4), allocatable :: molwgt(:)
432 
433 ! ---------------------------------------------------------------------
434 ! !
435 ! section-6 : module variables for gocart aerosol scheme options
436 ! !
437 ! ---------------------------------------------------------------------
438 ! !
439 
440 ! --- logical parameter for gocart initialization control
441  logical, save :: lgrtint = .true.
442 
443 ! --- logical parameter for gocart debug print control
444 ! logical, save :: lckprnt = .true.
445  logical, save :: lckprnt = .false.
446 
447 ! --- the following index/flag/weight are set up in 'set_aerspc'
448 
449 ! - merging coefficients for fcst/clim; determined from fdaer
450  real (kind=kind_phys), save :: ctaer = f_zero ! user specified wgt
451 
452 ! - option to get fcst or clim gocart aerosol fields
453  logical, save :: get_fcst = .true. ! option to get fcst field
454  logical, save :: get_clim = .true. ! option to get clim field
455 
456 ! ------ gocart aerosol specification ------
457 ! => transported aerosol species:
458 ! DU (5-bins)
459 ! SS (4 bins for climo mode and 5 bins for fcst mode)
460 ! SU (dms, so2, so4, msa)
461 ! OC (phobic, philic) and BC (phobic, philic)
462 ! => species and lumped species for aerosol optical properties
463 ! DU (5-bins, with 4 sub-groups in the submicron bin )
464 ! SS (ssam for submicron, sscm for coarse mode)
465 ! SU (so4)
466 ! OC (phobic, philic) and BC (phobic, philic)
467 ! => specification used for aerosol optical properties luts
468 ! DU (8 bins)
469 ! SS (ssam, sscm)
470 ! SU (suso)
471 ! OC (waso) and BC (soot)
472 !
473 
474 ! - index for rh dependent aerosol optical properties (2nd
475 ! dimension for extrhd_grt, ssarhd_grt, and asyrhd_grt)
476  integer, save :: isoot, iwaso, isuso, issam, isscm
477 
478 ! - index for rh independent aerosol optical properties (1st
479 ! dimension for extrhi_grt, ssarhi_grt, and asyrhi_grt) is
480 ! not needed ===> hardwired to 8-bin dust
481 
482 ! - index for gocart aerosol species to be included in the
483 ! calculations of aerosol optical properties (ext, ssa, asy)
485  integer :: dust1, dust2, dust3, dust4, dust5, & ! dust
486  & ssam, sscm, & ! sea salt
487  & suso, & ! sulfate
488  & waso_phobic, waso_philic, & ! oc
489  & soot_phobic, soot_philic ! bc
490  endtype
491  type(gocart_index_type), save :: dm_indx
492 
493 ! - index for gocart aerosols from prognostic tracer fields
495  integer :: du001, du002, du003, du004, du005, & ! dust
496  & ss001, ss002, ss003, ss004, ss005, & ! sea salt
497  & so4, & ! sulfate
498  & ocphobic, ocphilic, & ! oc
499  & bcphobic, bcphilic ! bc
500  endtype
502 
503 ! - grid components to be included in the aeropt calculations
504  integer, save :: num_gridcomp = 0 ! number of aerosol grid components
505  character, allocatable , save :: gridcomp(:)*2 ! aerosol grid components
506 
507 ! --- default full-package setting
508  integer, parameter :: max_num_gridcomp = 5
510  data max_gridcomp /'DU', 'BC', 'OC', 'SU', 'SS'/
511 
512 ! GOCART code modification end here (Sarah Lu)
513 ! ------------------------!
514 ! =======================================================================
515 
516 !! --- the following are for diagnostic purpose to output aerosol optical depth
517 ! aod from 10 components are grouped into 5 major different species:
518 ! 1:dust (inso,minm,miam,micm,mitr); 2:black carbon (soot)
519 ! 3:water soluble (waso); 4:sulfate (suso); 5:sea salt (ssam,sscm)
520 !
521 ! idxspc (NCM) - index conversion array
522 ! lspcaod - logical flag for aod from individual species
523 !
524  integer, dimension(NCM) :: idxspc
525  data idxspc / 1, 2, 1, 1, 1, 1, 3, 5, 5, 4 /
526 !
527 ! - wvn550 is the wavenumber (1/cm) of wavelenth 550nm for diagnostic aod output
528 ! nv_aod is the sw spectral band covering wvn550 (comp in aer_init)
529 !
530  real (kind=kind_phys), parameter :: wvn550 = 1.0e4/0.55
531  integer, save :: nv_aod = 1
532 
533 ! --- public interfaces
534 
535  public aer_init, aer_update, setaer
536 
537 
538 ! =================
539  contains
540 ! =================
541 
562 !-----------------------------------
563  subroutine aer_init &
564 !...................................
565 ! --- inputs:
566  & ( nlay, me )
567 ! --- outputs: ( to module variables )
568 
569 ! ================================================================== !
570 ! !
571 ! aer_init is the initialization program to set up necessary !
572 ! parameters and working arrays. !
573 ! !
574 ! inputs: !
575 ! NLAY - number of model vertical layers (not used) !
576 ! me - print message control flag !
577 ! !
578 ! outputs: (to module variables) !
579 ! !
580 ! external module variables: (in physparam) !
581 ! iaermdl - tropospheric aerosol model scheme flag !
582 ! =0 opac-clim; =1 gocart-clim, =2 gocart-prognostic !
583 ! lalwflg - logical lw aerosols effect control flag !
584 ! =t compute lw aerosol optical prop !
585 ! laswflg - logical sw aerosols effect control flag !
586 ! =t compute sw aerosol optical prop !
587 ! lavoflg - logical stratosphere volcanic aerosol control flag !
588 ! =t include volcanic aerosol effect !
589 ! lalw1bd = logical lw aeros propty 1 band vs multi-band cntl flag !
590 ! =t use 1 broad band optical property !
591 ! =f use multi bands optical property !
592 ! !
593 ! module constants: !
594 ! NWVSOL - num of wvnum regions where solar flux is constant !
595 ! NWVTOT - total num of wave numbers used in sw spectrum !
596 ! NWVTIR - total num of wave numbers used in the ir region !
597 ! NSWBND - total number of sw spectral bands !
598 ! NLWBND - total number of lw spectral bands !
599 ! !
600 ! usage: call aer_init !
601 ! !
602 ! subprograms called: clim_aerinit, gcrt_aerinit, !
603 ! wrt_aerlog, set_volcaer, set_spectrum, !
604 ! !
605 ! ================================================================== !
606 
607 ! --- inputs:
608  integer, intent(in) :: NLAY, me
609 
610 ! --- output: ( none )
611 
612 ! --- locals:
613  real (kind=kind_phys), dimension(NWVTOT) :: solfwv ! one wvn sol flux
614  real (kind=kind_phys), dimension(NWVTIR) :: eirfwv ! one wvn ir flux
615 !
616 !===> ... begin here
617 !
618  kyrstr = 1
619  kyrend = 1
620  kyrsav = 1
621  kmonsav = 1
622 
623 ! --- ... write aerosol parameter configuration to output logs
624 
625  if ( me == 0 ) then
626 
627  call wrt_aerlog ! write aerosol param info to log file
628 ! --- inputs: (in scope variables)
629 ! --- outputs: ( none )
630 
631  endif
632 
633  if ( iaerflg == 0 ) return ! return without any aerosol calculations
634 
635 ! --- ... in sw, aerosols optical properties are computed for each radiation
636 ! spectral band; while in lw, optical properties can be calculated
637 ! for either only one broad band or for each of the lw radiation bands
638 
639  if ( laswflg ) then
640  nswbnd = nbdsw
641  else
642  nswbnd = 0
643  endif
644 
645  if ( lalwflg ) then
646  if ( lalw1bd ) then
647  nlwbnd = 1
648  else
649  nlwbnd = nbdlw
650  endif
651  else
652  nlwbnd = 0
653  endif
654 
655  nswlwbd = nswbnd + nlwbnd
656 
657  if ( iaerflg /= 100 ) then
658 
659 ! --- ... set up spectral one wavenumber solar/ir fluxes
660 
661  call set_spectrum
662 ! --- inputs: (module constants)
663 ! --- outputs: (in-scope variables)
664 
665 ! --- ... invoke tropospheric aerosol initialization
666 
667  if ( iaermdl == 0 ) then ! opac-climatology scheme
668 
669  call clim_aerinit &
670 ! --- inputs:
671  & ( solfwv, eirfwv, me &
672 ! --- outputs:
673  & )
674 
675 ! elseif ( iaermdl == 1 ) then ! gocart-climatology scheme
676 ! elseif ( iaermdl==1 .or. iaermdl==2 ) then ! gocart-clim/prog scheme
677 
678 ! call gcrt_climinit
679 
680 ! elseif ( iaermdl == 2 ) then ! gocart-prognostic scheme
681 
682 ! call gcrt_aerinit
683 
684  else
685  if ( me == 0 ) then
686  print *,' !!! ERROR in aerosol model scheme selection', &
687  & ' iaermdl =',iaermdl
688  stop
689  endif
690  endif
691 
692  endif ! end if_iaerflg_block
693 
694 ! --- ... invoke stratosperic volcanic aerosol initialization
695 
696  if ( lavoflg ) then
697 
698  call set_volcaer
699 ! --- inputs: (module variables)
700 ! --- outputs: (module variables)
701 
702  endif ! end if_lavoflg_block
703 
704 
705 ! =================
706  contains
707 ! =================
708 
710 !--------------------------------
711  subroutine wrt_aerlog
712 !................................
713 ! --- inputs: (in scope variables)
714 ! --- outputs: ( none )
715 
716 ! ================================================================== !
717 ! !
718 ! subprogram : wrt_aerlog !
719 ! !
720 ! write aerosol parameter configuration to run log file. !
721 ! !
722 ! ==================== defination of variables =================== !
723 ! !
724 ! external module variables: (in physparam) !
725 ! iaermdl - aerosol scheme flag: 0:opac-clm; 1:gocart-clim; !
726 ! 2:gocart-prog !
727 ! iaerflg - aerosol effect control flag: 3-digits (volc,lw,sw) !
728 ! lalwflg - toposphere lw aerosol effect: =f:no; =t:yes !
729 ! laswflg - toposphere sw aerosol effect: =f:no; =t:yes !
730 ! lavoflg - stratospherer volcanic aeros effect: =f:no; =t:yes !
731 ! !
732 ! outputs: ( none ) !
733 ! !
734 ! subroutines called: none !
735 ! !
736 ! usage: call wrt_aerlog !
737 ! !
738 ! ================================================================== !
739 
740 ! --- inputs: ( none )
741 ! --- output: ( none )
742 ! --- locals:
743 
744 !
745 !===> ... begin here
746 !
747  print *, vtagaer ! print out version tag
748 
749  if ( iaermdl == 0 ) then
750  print *,' - Using OPAC-seasonal climatology for tropospheric', &
751  & ' aerosol effect'
752  elseif ( iaermdl == 1 ) then
753  print *,' - Using GOCART-climatology for tropospheric', &
754  & ' aerosol effect'
755  elseif ( iaermdl == 2 ) then
756  print *,' - Using GOCART-prognostic aerosols for tropospheric', &
757  & ' aerosol effect'
758  else
759  print *,' !!! ERROR in selection of aerosol model scheme', &
760  & ' IAER_MDL =',iaermdl
761  stop
762  endif ! end_if_iaermdl_block
763 
764  print *,' IAER=',iaerflg,' LW-trop-aer=',lalwflg, &
765  & ' SW-trop-aer=',laswflg,' Volc-aer=',lavoflg
766 
767  if ( iaerflg <= 0 ) then ! turn off all aerosol effects
768  print *,' - No tropospheric/volcanic aerosol effect included'
769  print *,' Input values of aerosol optical properties to' &
770  & ,' both SW and LW radiations are set to zeros'
771  else
772  if ( iaerflg >= 100 ) then ! incl stratospheric volcanic aerosols
773  print *,' - Include stratospheric volcanic aerosol effect'
774  else ! no stratospheric volcanic aerosols
775  print *,' - No stratospheric volcanic aerosol effect'
776  endif
777 
778  if ( laswflg ) then ! chcek for sw effect
779  print *,' - Compute multi-band aerosol optical' &
780  & ,' properties for SW input parameters'
781  else
782  print *,' - No SW radiation aerosol effect, values of' &
783  & ,' aerosol properties to SW input are set to zeros'
784  endif
785 
786  if ( lalwflg ) then ! check for lw effect
787  if ( lalw1bd ) then
788  print *,' - Compute 1 broad-band aerosol optical' &
789  & ,' properties for LW input parameters'
790  else
791  print *,' - Compute multi-band aerosol optical' &
792  & ,' properties for LW input parameters'
793  endif
794  else
795  print *,' - No LW radiation aerosol effect, values of' &
796  & ,' aerosol properties to LW input are set to zeros'
797  endif
798  endif ! end if_iaerflg_block
799 !
800  return
801 !................................
802  end subroutine wrt_aerlog
803 !--------------------------------
804 
807 !--------------------------------
808  subroutine set_spectrum
809 !................................
810 ! --- inputs: (module constants)
811 ! --- outputs: (in-scope variables)
812 
813 ! ================================================================== !
814 ! !
815 ! subprogram : set_spectrum !
816 ! !
817 ! define the one wavenumber solar fluxes based on toa solar spectral!
818 ! distrobution, and define the one wavenumber ir fluxes based on !
819 ! black-body emission distribution at a predefined temperature. !
820 ! !
821 ! ==================== defination of variables =================== !
822 ! !
823 ! inputs: (module constants) !
824 ! NWVTOT - total num of wave numbers used in sw spectrum !
825 ! NWVTIR - total num of wave numbers used in the ir region !
826 ! !
827 ! outputs: (in-scope variables) !
828 ! solfwv(NWVTOT) - solar flux for each individual wavenumber (w/m2)!
829 ! eirfwv(NWVTIR) - ir flux(273k) for each individual wavenum (w/m2)!
830 ! !
831 ! subroutines called: none !
832 ! !
833 ! usage: call set_spectrum !
834 ! !
835 ! ================================================================== !
836 
837 ! --- inputs: (module constants)
838 ! integer :: NWVTOT, NWVTIR
839 
840 ! --- output: (in-scope variables)
841 ! real (kind=kind_phys), dimension(NWVTOT) :: solfwv ! one wvn sol flux
842 ! real (kind=kind_phys), dimension(NWVTIR) :: eirfwv ! one wvn ir flux
843 
844 ! --- locals:
845  real (kind=kind_phys) :: soltot, tmp1, tmp2, tmp3
846 
847  integer :: nb, nw, nw1, nw2, nmax, nmin
848 !
849 !===> ... begin here
850 !
851 ! nmax = min( NWVTOT, nint( maxval(wvnsw2) ))
852 ! nmin = max( 1, nint( minval(wvnsw1) ))
853 
854 ! --- check print
855 ! print *,' MINWVN, MAXWVN = ',nmin, nmax
856 ! --- ... define the one wavenumber solar fluxes based on toa solar
857 ! spectral distribution
858 
859 ! soltot1 = f_zero
860 ! soltot = f_zero
861  do nb = 1, nwvsol
862  if ( nb == 1 ) then
863  nw1 = 1
864  else
865  nw1 = nw1 + nwvns0(nb-1)
866  endif
867 
868  nw2 = nw1 + nwvns0(nb) - 1
869 
870  do nw = nw1, nw2
871  solfwv(nw) = s0intv(nb)
872 ! soltot1 = soltot1 + s0intv(nb)
873 ! if ( nw >= nmin .and. nw <= nmax ) then
874 ! soltot = soltot + s0intv(nb)
875 ! endif
876  enddo
877  enddo
878 
879 ! --- ... define the one wavenumber ir fluxes based on black-body
880 ! emission distribution at a predefined temperature
881 
882  tmp1 = 2.0 * con_pi * con_plnk * (con_c**2)
883  tmp2 = con_plnk * con_c / (con_boltz * con_t0c)
884 
885  do nw = 1, nwvtir
886  tmp3 = 100.0 * nw
887  eirfwv(nw) = (tmp1 * tmp3**3) / (exp(tmp2*tmp3) - 1.0)
888  enddo
889 !
890  return
891 !................................
892  end subroutine set_spectrum
893 !--------------------------------
894 
896 !-----------------------------
897  subroutine set_volcaer
898 !.............................
899 ! --- inputs: ( none )
900 ! --- outputs: (module variables)
901 
902 ! ================================================================== !
903 ! !
904 ! subprogram : set_volcaer !
905 ! !
906 ! this is the initialization progrmam for stratospheric volcanic !
907 ! aerosols. !
908 ! !
909 ! subroutines called: none !
910 ! !
911 ! usage: call set_volcaer !
912 ! !
913 ! ================================================================== !
914 
915 ! --- inputs: (none)
916 
917 ! --- output: (module variables)
918 ! integer :: ivolae(:,:,:)
919 
920 ! --- locals:
921 !
922 !===> ... begin here
923 !
924 ! --- allocate data space
925 
926  if ( .not. allocated(ivolae) ) then
927  allocate ( ivolae(12,4,10) ) ! for 12-mon,4-lat_zone,10-year
928  endif
929 !
930  return
931 !................................
932  end subroutine set_volcaer
933 !--------------------------------
934 !
935 !...................................
936  end subroutine aer_init
937 !-----------------------------------
938 
940 !-----------------------------------
941  subroutine clim_aerinit &
942 !...................................
943 ! --- inputs:
944  & ( solfwv, eirfwv, me &
945 ! --- outputs:
946  & )
947 
948 ! ================================================================== !
949 ! !
950 ! clim_aerinit is the opac-climatology aerosol initialization program !
951 ! to set up necessary parameters and working arrays. !
952 ! !
953 ! inputs: !
954 ! solfwv(NWVTOT) - solar flux for each individual wavenumber (w/m2)!
955 ! eirfwv(NWVTIR) - ir flux(273k) for each individual wavenum (w/m2)!
956 ! me - print message control flag !
957 ! !
958 ! outputs: (to module variables) !
959 ! !
960 ! external module variables: (in physparam) !
961 ! iaerflg - abc 3-digit integer aerosol flag (abc:volc,lw,sw) !
962 ! a: =0 use background stratospheric aerosol !
963 ! =1 incl stratospheric vocanic aeros (MINVYR-MAXVYR) !
964 ! b: =0 no topospheric aerosol in lw radiation !
965 ! =1 include tropspheric aerosols for lw radiation !
966 ! c: =0 no topospheric aerosol in sw radiation !
967 ! =1 include tropspheric aerosols for sw radiation !
968 ! lalwflg - logical lw aerosols effect control flag !
969 ! =t compute lw aerosol optical prop !
970 ! laswflg - logical sw aerosols effect control flag !
971 ! =t compute sw aerosol optical prop !
972 ! lalw1bd = logical lw aeros propty 1 band vs multi-band cntl flag !
973 ! =t use 1 broad band optical property !
974 ! =f use multi bands optical property !
975 ! !
976 ! module constants: !
977 ! NWVSOL - num of wvnum regions where solar flux is constant !
978 ! NWVTOT - total num of wave numbers used in sw spectrum !
979 ! NWVTIR - total num of wave numbers used in the ir region !
980 ! NSWBND - total number of sw spectral bands !
981 ! NLWBND - total number of lw spectral bands !
982 ! NAERBND - number of bands for climatology aerosol data !
983 ! NCM1 - number of rh independent aeros species !
984 ! NCM2 - number of rh dependent aeros species !
985 ! !
986 ! usage: call clim_aerinit !
987 ! !
988 ! subprograms called: set_aercoef, optavg !
989 ! !
990 ! ================================================================== !
991 
992 ! --- inputs:
993  real (kind=kind_phys), dimension(:) :: solfwv ! one wvn sol flux
994  real (kind=kind_phys), dimension(:) :: eirfwv ! one wvn ir flux
995 
996  integer, intent(in) :: me
997 
998 ! --- output: ( none )
999 
1000 ! --- locals:
1001  real (kind=kind_phys), dimension(NAERBND,NCM1) :: &
1002  & rhidext0, rhidsca0, rhidssa0, rhidasy0
1003  real (kind=kind_phys), dimension(NAERBND,NRHLEV,NCM2):: &
1004  & rhdpext0, rhdpsca0, rhdpssa0, rhdpasy0
1005  real (kind=kind_phys), dimension(NAERBND) :: straext0
1006 
1007  real (kind=kind_phys), dimension(NSWBND,NAERBND) :: solwaer
1008  real (kind=kind_phys), dimension(NSWBND) :: solbnd
1009  real (kind=kind_phys), dimension(NLWBND,NAERBND) :: eirwaer
1010  real (kind=kind_phys), dimension(NLWBND) :: eirbnd
1011 
1012  integer, dimension(NSWBND) :: nv1, nv2
1013  integer, dimension(NLWBND) :: nr1, nr2
1014 !
1015 !===> ... begin here
1016 !
1017 ! --- ... invoke tropospheric aerosol initialization
1018 
1019  call set_aercoef
1020 ! --- inputs: (in-scope variables, module constants)
1021 ! --- outputs: (module variables)
1022 
1023 
1024 ! =================
1025  contains
1026 ! =================
1027 
1031 !--------------------------------
1032  subroutine set_aercoef
1033 !................................
1034 ! --- inputs: (in-scope variables, module constants)
1035 ! --- outputs: (module variables)
1036 
1037 ! ================================================================== !
1038 ! !
1039 ! subprogram : set_aercoef !
1040 ! !
1041 ! this is the initialization progrmam for climatological aerosols !
1042 ! !
1043 ! the program reads and maps the pre-tabulated aerosol optical !
1044 ! spectral data onto corresponding sw radiation spectral bands. !
1045 ! !
1046 ! ==================== defination of variables =================== !
1047 ! !
1048 ! inputs: (in-scope variables, module constants) !
1049 ! solfwv(:) - real, solar flux for individual wavenumber (w/m2) !
1050 ! eirfwv(:) - real, lw flux(273k) for individual wavenum (w/m2) !
1051 ! me - integer, select cpu number as print control flag !
1052 ! !
1053 ! outputs: (to the module variables) !
1054 ! !
1055 ! external module variables: (in physparam) !
1056 ! lalwflg - module control flag for lw trop-aer: =f:no; =t:yes !
1057 ! laswflg - module control flag for sw trop-aer: =f:no; =t:yes !
1058 ! aeros_file- external aerosol data file name !
1059 ! !
1060 ! internal module variables: !
1061 ! IMXAE - number of longitude points in global aeros data set !
1062 ! JMXAE - number of latitude points in global aeros data set !
1063 ! wvnsw1,wvnsw2 (NSWSTR:NSWEND) !
1064 ! - start/end wavenumbers for each of sw bands !
1065 ! wvnlw1,wvnlw2 ( 1:NBDLW) !
1066 ! - start/end wavenumbers for each of lw bands !
1067 ! NSWLWBD - total num of bands (sw+lw) for aeros optical properties!
1068 ! NSWBND - number of sw spectral bands actually invloved !
1069 ! NLWBND - number of lw spectral bands actually invloved !
1070 ! NIAERCM - unit number for reading input data set !
1071 ! extrhi - extinction coef for rh-indep aeros NCM1*NSWLWBD!
1072 ! scarhi - scattering coef for rh-indep aeros NCM1*NSWLWBD!
1073 ! ssarhi - single-scat-alb for rh-indep aeros NCM1*NSWLWBD!
1074 ! asyrhi - asymmetry factor for rh-indep aeros NCM1*NSWLWBD!
1075 ! extrhd - extinction coef for rh-dep aeros NRHLEV*NCM2*NSWLWBD!
1076 ! scarhd - scattering coef for rh-dep aeros NRHLEV*NCM2*NSWLWBD!
1077 ! ssarhd - single-scat-alb for rh-dep aeros NRHLEV*NCM2*NSWLWBD!
1078 ! asyrhd - asymmetry factor for rh-dep aeros NRHLEV*NCM2*NSWLWBD!
1079 ! !
1080 ! major local variables: !
1081 ! for handling spectral band structures !
1082 ! iendwv - ending wvnum (cm**-1) for each band NAERBND !
1083 ! for handling optical properties of rh independent species (NCM1) !
1084 ! 1. insoluble (inso); 2. soot (soot); !
1085 ! 3. mineral nuc mode (minm); 4. mineral acc mode (miam); !
1086 ! 5. mineral coa mode (micm); 6. mineral transport(mitr). !
1087 ! rhidext0 - extinction coefficient NAERBND*NCM1 !
1088 ! rhidsca0 - scattering coefficient NAERBND*NCM1 !
1089 ! rhidssa0 - single scattering albedo NAERBND*NCM1 !
1090 ! rhidasy0 - asymmetry parameter NAERBND*NCM1 !
1091 ! for handling optical properties of rh ndependent species (NCM2) !
1092 ! 1. water soluble (waso); 2. sea salt acc mode(ssam); !
1093 ! 3. sea salt coa mode(sscm); 4. sulfate droplets (suso). !
1094 ! rh level (NRHLEV): 00%, 50%, 70%, 80%, 90%, 95%, 98%, 99% !
1095 ! rhdpext0 - extinction coefficient NAERBND,NRHLEV,NCM2!
1096 ! rhdpsca0 - scattering coefficient NAERBND,NRHLEV,NCM2!
1097 ! rhdpssa0 - single scattering albedo NAERBND,NRHLEV,NCM2!
1098 ! rhdpasy0 - asymmetry parameter NAERBND,NRHLEV,NCM2!
1099 ! for handling optical properties of stratospheric bkgrnd aerosols !
1100 ! straext0 - extingction coefficients NAERBND !
1101 ! !
1102 ! usage: call set_aercoef !
1103 ! !
1104 ! subprograms called: optavg !
1105 ! !
1106 ! ================================================================== !
1107 !
1108 ! --- inputs: ( none )
1109 ! --- output: ( none )
1110 
1111 ! --- locals:
1112  integer, dimension(NAERBND) :: iendwv
1113 
1114  integer :: i, j, k, m, mb, ib, ii, id, iw, iw1, iw2
1115 
1116  real (kind=kind_phys) :: sumsol, sumir
1117 
1118  logical :: file_exist
1119  character :: cline*80
1120 !
1121 !===> ... begin here
1122 !
1123 ! --- ... reading climatological aerosols data
1124 
1125  inquire (file=aeros_file, exist=file_exist)
1126 
1127  if ( file_exist ) then
1128  close (niaercm)
1129  open (unit=niaercm,file=aeros_file,status='OLD', &
1130  & form='FORMATTED')
1131  rewind(niaercm)
1132  else
1133  print *,' Requested aerosol data file "',aeros_file, &
1134  & '" not found!'
1135  print *,' *** Stopped in subroutine aero_init !!'
1136  stop
1137  endif ! end if_file_exist_block
1138 
1139 ! --- ... skip monthly global distribution
1140 
1141  do m = 1, 12
1142  read (niaercm,12) cline
1143  12 format(a80/)
1144 
1145  do j = 1, jmxae
1146  do i = 1, imxae
1147  read(niaercm,*) id
1148  enddo
1149  enddo
1150  enddo ! end do_m_block
1151 
1152 ! --- ... aloocate and input aerosol optical data
1153 
1154  if ( .not. allocated( extrhi ) ) then
1155  allocate ( extrhi( ncm1,nswlwbd) )
1156  allocate ( scarhi( ncm1,nswlwbd) )
1157  allocate ( ssarhi( ncm1,nswlwbd) )
1158  allocate ( asyrhi( ncm1,nswlwbd) )
1159  allocate ( extrhd(nrhlev,ncm2,nswlwbd) )
1160  allocate ( scarhd(nrhlev,ncm2,nswlwbd) )
1161  allocate ( ssarhd(nrhlev,ncm2,nswlwbd) )
1162  allocate ( asyrhd(nrhlev,ncm2,nswlwbd) )
1163  allocate ( extstra( nswlwbd) )
1164  endif
1165 
1166  read(niaercm,21) cline ! ending wave num for 61 aeros spectral bands
1167  21 format(a80)
1168  read(niaercm,22) iendwv(:)
1169  22 format(13i6)
1170 
1171  read(niaercm,21) cline ! atmos scale height for 5 domains, 7 profs
1172  read(niaercm,24) haer(:,:)
1173  24 format(20f4.1)
1174 
1175  read(niaercm,21) cline ! reference pressure for 5 domains, 7 profs
1176  read(niaercm,26) prsref(:,:)
1177  26 format(10f7.2)
1178 
1179  read(niaercm,21) cline ! rh indep ext coef for 61 bands, 6 species
1180  read(niaercm,28) rhidext0(:,:)
1181  28 format(8e10.3)
1182 
1183  read(niaercm,21) cline ! rh indep sca coef for 61 bands, 6 species
1184  read(niaercm,28) rhidsca0(:,:)
1185 
1186  read(niaercm,21) cline ! rh indep ssa coef for 61 bands, 6 species
1187  read(niaercm,28) rhidssa0(:,:)
1188 
1189  read(niaercm,21) cline ! rh indep asy coef for 61 bands, 6 species
1190  read(niaercm,28) rhidasy0(:,:)
1191 
1192  read(niaercm,21) cline ! rh dep ext coef for 61 bands, 8 rh lev, 4 species
1193  read(niaercm,28) rhdpext0(:,:,:)
1194 
1195  read(niaercm,21) cline ! rh dep sca coef for 61 bands, 8 rh lev, 4 species
1196  read(niaercm,28) rhdpsca0(:,:,:)
1197 
1198  read(niaercm,21) cline ! rh dep ssa coef for 61 bands, 8 rh lev, 4 species
1199  read(niaercm,28) rhdpssa0(:,:,:)
1200 
1201  read(niaercm,21) cline ! rh dep asy coef for 61 bands, 8 rh lev, 4 species
1202  read(niaercm,28) rhdpasy0(:,:,:)
1203 
1204  read(niaercm,21) cline ! stratospheric background aeros for 61 bands
1205  read(niaercm,28) straext0(:)
1206 
1207  close (niaercm)
1208 
1209 ! --- ... convert pressure reference level (in mb) to sigma reference level
1210 ! assume an 1000mb reference surface pressure
1211 
1212  sigref(:,:) = 0.001 * prsref(:,:)
1213 
1214 ! --- ... compute solar flux weights and interval indices for mapping
1215 ! spectral bands between sw radiation and aerosol data
1216 
1217  if ( laswflg ) then
1218  solbnd(:) = f_zero
1219  solwaer(:,:) = f_zero
1220 
1221  do ib = 1, nswbnd
1222  mb = ib + nswstr - 1
1223  ii = 1
1224  iw1 = nint(wvnsw1(mb))
1225  iw2 = nint(wvnsw2(mb))
1226 
1227  if ( wvnsw2(mb)>=wvn550 .and. wvn550>=wvnsw1(mb) ) then
1228  nv_aod = ib ! sw band number covering 550nm wavelenth
1229  endif
1230 
1231  lab_swdowhile : do while ( iw1 > iendwv(ii) )
1232  if ( ii == naerbnd ) exit lab_swdowhile
1233  ii = ii + 1
1234  enddo lab_swdowhile
1235 
1236  sumsol = f_zero
1237  nv1(ib) = ii
1238 
1239  do iw = iw1, iw2
1240  solbnd(ib) = solbnd(ib) + solfwv(iw)
1241  sumsol = sumsol + solfwv(iw)
1242 
1243  if ( iw == iendwv(ii) ) then
1244  solwaer(ib,ii) = sumsol
1245 
1246  if ( ii < naerbnd ) then
1247  sumsol = f_zero
1248  ii = ii + 1
1249  endif
1250  endif
1251  enddo
1252 
1253  if ( iw2 /= iendwv(ii) ) then
1254  solwaer(ib,ii) = sumsol
1255  endif
1256 
1257  nv2(ib) = ii
1258 ! frcbnd(ib) = solbnd(ib) / soltot
1259  enddo ! end do_ib_block for sw
1260  endif ! end if_laswflg_block
1261 
1262 ! --- ... compute lw flux weights and interval indices for mapping
1263 ! spectral bands between lw radiation and aerosol data
1264 
1265  if ( lalwflg ) then
1266  eirbnd(:) = f_zero
1267  eirwaer(:,:) = f_zero
1268 
1269  do ib = 1, nlwbnd
1270  ii = 1
1271  if ( nlwbnd == 1 ) then
1272 ! iw1 = 250 ! corresponding 40 mu
1273  iw1 = 400 ! corresponding 25 mu
1274  iw2 = 2500 ! corresponding 4 mu
1275  else
1276  mb = ib + nlwstr - 1
1277  iw1 = nint(wvnlw1(mb))
1278  iw2 = nint(wvnlw2(mb))
1279  endif
1280 
1281  lab_lwdowhile : do while ( iw1 > iendwv(ii) )
1282  if ( ii == naerbnd ) exit lab_lwdowhile
1283  ii = ii + 1
1284  enddo lab_lwdowhile
1285 
1286  sumir = f_zero
1287  nr1(ib) = ii
1288 
1289  do iw = iw1, iw2
1290  eirbnd(ib) = eirbnd(ib) + eirfwv(iw)
1291  sumir = sumir + eirfwv(iw)
1292 
1293  if ( iw == iendwv(ii) ) then
1294  eirwaer(ib,ii) = sumir
1295 
1296  if ( ii < naerbnd ) then
1297  sumir = f_zero
1298  ii = ii + 1
1299  endif
1300  endif
1301  enddo
1302 
1303  if ( iw2 /= iendwv(ii) ) then
1304  eirwaer(ib,ii) = sumir
1305  endif
1306 
1307  nr2(ib) = ii
1308  enddo ! end do_ib_block for lw
1309  endif ! end if_lalwflg_block
1310 
1311 ! --- compute spectral band mean properties for each species
1312 
1313  call optavg
1314 ! --- inputs: (in-scope variables, module variables)
1315 ! --- outputs: (module variables)
1316 
1317 ! --- check print
1318 ! do ib = 1, NSWBND
1319 ! print *,' After optavg, for sw band:',ib
1320 ! print *,' extrhi:', extrhi(:,ib)
1321 ! print *,' scarhi:', scarhi(:,ib)
1322 ! print *,' ssarhi:', ssarhi(:,ib)
1323 ! print *,' asyrhi:', asyrhi(:,ib)
1324 ! mb = ib + NSWSTR - 1
1325 ! print *,' wvnsw1,wvnsw2 :',wvnsw1(mb),wvnsw2(mb)
1326 ! do i = 1, NRHLEV
1327 ! print *,' extrhd for rhlev:',i
1328 ! print *,extrhd(i,:,ib)
1329 ! print *,' scarhd for rhlev:',i
1330 ! print *,scarhd(i,:,ib)
1331 ! print *,' ssarhd for rhlev:',i
1332 ! print *,ssarhd(i,:,ib)
1333 ! print *,' asyrhd for rhlev:',i
1334 ! print *,asyrhd(i,:,ib)
1335 ! enddo
1336 ! print *,' extstra:', extstra(ib)
1337 ! enddo
1338 ! print *,' wvnlw1 :',wvnlw1
1339 ! print *,' wvnlw2 :',wvnlw2
1340 ! do ib = 1, NLWBND
1341 ! ii = NSWBND + ib
1342 ! print *,' After optavg, for lw band:',ib
1343 ! print *,' extrhi:', extrhi(:,ii)
1344 ! print *,' scarhi:', scarhi(:,ii)
1345 ! print *,' ssarhi:', ssarhi(:,ii)
1346 ! print *,' asyrhi:', asyrhi(:,ii)
1347 ! do i = 1, NRHLEV
1348 ! print *,' extrhd for rhlev:',i
1349 ! print *,extrhd(i,:,ii)
1350 ! print *,' scarhd for rhlev:',i
1351 ! print *,scarhd(i,:,ii)
1352 ! print *,' ssarhd for rhlev:',i
1353 ! print *,ssarhd(i,:,ii)
1354 ! print *,' asyrhd for rhlev:',i
1355 ! print *,asyrhd(i,:,ii)
1356 ! enddo
1357 ! print *,' extstra:', extstra(ii)
1358 ! enddo
1359 !
1360  return
1361 !................................
1362  end subroutine set_aercoef
1363 !--------------------------------
1364 
1368 !--------------------------------
1369  subroutine optavg
1370 !................................
1371 ! --- inputs: (in-scope variables, module variables
1372 ! --- outputs: (module variables)
1373 
1374 ! ==================================================================== !
1375 ! !
1376 ! subprogram: optavg !
1377 ! !
1378 ! compute mean aerosols optical properties over each sw radiation !
1379 ! spectral band for each of the species components. This program !
1380 ! follows gfdl's approach for thick cloud opertical property in !
1381 ! sw radiation scheme (2000). !
1382 ! !
1383 ! ==================== defination of variables =================== !
1384 ! !
1385 ! major input variables: !
1386 ! nv1,nv2 (NSWBND) - start/end spectral band indices of aerosol data !
1387 ! for each sw radiation spectral band !
1388 ! nr1,nr2 (NLWBND) - start/end spectral band indices of aerosol data !
1389 ! for each ir radiation spectral band !
1390 ! solwaer (NSWBND,NAERBND) !
1391 ! - solar flux weight over each sw radiation band !
1392 ! vs each aerosol data spectral band !
1393 ! eirwaer (NLWBND,NAERBND) !
1394 ! - ir flux weight over each lw radiation band !
1395 ! vs each aerosol data spectral band !
1396 ! solbnd (NSWBND) - solar flux weight over each sw radiation band !
1397 ! eirbnd (NLWBND) - ir flux weight over each lw radiation band !
1398 ! NSWBND - total number of sw spectral bands !
1399 ! NLWBND - total number of lw spectral bands !
1400 ! !
1401 ! external module variables: (in physparam) !
1402 ! laswflg - control flag for sw spectral region !
1403 ! lalwflg - control flag for lw spectral region !
1404 ! !
1405 ! output variables: (to module variables) !
1406 ! !
1407 ! ================================================================== !
1408 
1409 ! --- inputs:
1410 ! --- output:
1411 
1412 ! --- locals:
1413  real (kind=kind_phys) :: sumk, sums, sumok, sumokg, sumreft, &
1414  & sp, refb, reft, rsolbd, rirbd
1415 
1416  integer :: ib, nb, ni, nh, nc
1417 !
1418 !===> ... begin here
1419 !
1420 ! --- ... loop for each sw radiation spectral band
1421 
1422  if ( laswflg ) then
1423 
1424  do nb = 1, nswbnd
1425  rsolbd = f_one / solbnd(nb)
1426 
1427 ! --- for rh independent aerosol species
1428 
1429  do nc = 1, ncm1
1430  sumk = f_zero
1431  sums = f_zero
1432  sumok = f_zero
1433  sumokg = f_zero
1434  sumreft = f_zero
1435 
1436  do ni = nv1(nb), nv2(nb)
1437  sp = sqrt( (f_one - rhidssa0(ni,nc)) &
1438  & / (f_one - rhidssa0(ni,nc)*rhidasy0(ni,nc)) )
1439  reft = (f_one - sp) / (f_one + sp)
1440  sumreft = sumreft + reft*solwaer(nb,ni)
1441 
1442  sumk = sumk + rhidext0(ni,nc)*solwaer(nb,ni)
1443  sums = sums + rhidsca0(ni,nc)*solwaer(nb,ni)
1444  sumok = sumok + rhidssa0(ni,nc)*solwaer(nb,ni) &
1445  & * rhidext0(ni,nc)
1446  sumokg = sumokg + rhidssa0(ni,nc)*solwaer(nb,ni) &
1447  & * rhidext0(ni,nc)*rhidasy0(ni,nc)
1448  enddo
1449 
1450  refb = sumreft * rsolbd
1451 
1452  extrhi(nc,nb) = sumk * rsolbd
1453  scarhi(nc,nb) = sums * rsolbd
1454  asyrhi(nc,nb) = sumokg / (sumok + 1.0e-10)
1455  ssarhi(nc,nb) = 4.0*refb &
1456  & / ( (f_one+refb)**2 - asyrhi(nc,nb)*(f_one-refb)**2 )
1457  enddo ! end do_nc_block for rh-ind aeros
1458 
1459 ! --- for rh dependent aerosols species
1460 
1461  do nc = 1, ncm2
1462  do nh = 1, nrhlev
1463  sumk = f_zero
1464  sums = f_zero
1465  sumok = f_zero
1466  sumokg = f_zero
1467  sumreft = f_zero
1468 
1469  do ni = nv1(nb), nv2(nb)
1470  sp = sqrt( (f_one - rhdpssa0(ni,nh,nc)) &
1471  & / (f_one - rhdpssa0(ni,nh,nc)*rhdpasy0(ni,nh,nc)) )
1472  reft = (f_one - sp) / (f_one + sp)
1473  sumreft = sumreft + reft*solwaer(nb,ni)
1474 
1475  sumk = sumk + rhdpext0(ni,nh,nc)*solwaer(nb,ni)
1476  sums = sums + rhdpsca0(ni,nh,nc)*solwaer(nb,ni)
1477  sumok = sumok + rhdpssa0(ni,nh,nc)*solwaer(nb,ni) &
1478  & * rhdpext0(ni,nh,nc)
1479  sumokg = sumokg + rhdpssa0(ni,nh,nc)*solwaer(nb,ni) &
1480  & * rhdpext0(ni,nh,nc)*rhdpasy0(ni,nh,nc)
1481  enddo
1482 
1483  refb = sumreft * rsolbd
1484 
1485  extrhd(nh,nc,nb) = sumk * rsolbd
1486  scarhd(nh,nc,nb) = sums * rsolbd
1487  asyrhd(nh,nc,nb) = sumokg / (sumok + 1.0e-10)
1488  ssarhd(nh,nc,nb) = 4.0*refb &
1489  & / ( (f_one+refb)**2 - asyrhd(nh,nc,nb)*(f_one-refb)**2 )
1490  enddo ! end do_nh_block
1491  enddo ! end do_nc_block for rh-dep aeros
1492 
1493 ! --- for stratospheric background aerosols
1494 
1495  sumk = f_zero
1496  do ni = nv1(nb), nv2(nb)
1497  sumk = sumk + straext0(ni)*solwaer(nb,ni)
1498  enddo
1499 
1500  extstra(nb) = sumk * rsolbd
1501 
1502 ! --- check print
1503 ! if ( nb > 6 .and. nb < 10) then
1504 ! print *,' in optavg for sw band',nb
1505 ! print *,' nv1, nv2:',nv1(nb),nv2(nb)
1506 ! print *,' solwaer:',solwaer(nb,nv1(nb):nv2(nb))
1507 ! print *,' extrhi:', extrhi(:,nb)
1508 ! do i = 1, NRHLEV
1509 ! print *,' extrhd for rhlev:',i
1510 ! print *,extrhd(i,:,nb)
1511 ! enddo
1512 ! print *,' sumk, rsolbd, extstra:',sumk,rsolbd,extstra(nb)
1513 ! endif
1514 
1515  enddo ! end do_nb_block for sw
1516  endif ! end if_laswflg_block
1517 
1518 ! --- ... loop for each lw radiation spectral band
1519 
1520  if ( lalwflg ) then
1521 
1522  do nb = 1, nlwbnd
1523 
1524  ib = nswbnd + nb
1525  rirbd = f_one / eirbnd(nb)
1526 
1527 ! --- for rh independent aerosol species
1528 
1529  do nc = 1, ncm1
1530  sumk = f_zero
1531  sums = f_zero
1532  sumok = f_zero
1533  sumokg = f_zero
1534  sumreft = f_zero
1535 
1536  do ni = nr1(nb), nr2(nb)
1537  sp = sqrt( (f_one - rhidssa0(ni,nc)) &
1538  & / (f_one - rhidssa0(ni,nc)*rhidasy0(ni,nc)) )
1539  reft = (f_one - sp) / (f_one + sp)
1540  sumreft = sumreft + reft*eirwaer(nb,ni)
1541 
1542  sumk = sumk + rhidext0(ni,nc)*eirwaer(nb,ni)
1543  sums = sums + rhidsca0(ni,nc)*eirwaer(nb,ni)
1544  sumok = sumok + rhidssa0(ni,nc)*eirwaer(nb,ni) &
1545  & * rhidext0(ni,nc)
1546  sumokg = sumokg + rhidssa0(ni,nc)*eirwaer(nb,ni) &
1547  & * rhidext0(ni,nc)*rhidasy0(ni,nc)
1548  enddo
1549 
1550  refb = sumreft * rirbd
1551 
1552  extrhi(nc,ib) = sumk * rirbd
1553  scarhi(nc,ib) = sums * rirbd
1554  asyrhi(nc,ib) = sumokg / (sumok + 1.0e-10)
1555  ssarhi(nc,ib) = 4.0*refb &
1556  & / ( (f_one+refb)**2 - asyrhi(nc,ib)*(f_one-refb)**2 )
1557  enddo ! end do_nc_block for rh-ind aeros
1558 
1559 ! --- for rh dependent aerosols species
1560 
1561  do nc = 1, ncm2
1562  do nh = 1, nrhlev
1563  sumk = f_zero
1564  sums = f_zero
1565  sumok = f_zero
1566  sumokg = f_zero
1567  sumreft = f_zero
1568 
1569  do ni = nr1(nb), nr2(nb)
1570  sp = sqrt( (f_one - rhdpssa0(ni,nh,nc)) &
1571  & / (f_one - rhdpssa0(ni,nh,nc)*rhdpasy0(ni,nh,nc)) )
1572  reft = (f_one - sp) / (f_one + sp)
1573  sumreft = sumreft + reft*eirwaer(nb,ni)
1574 
1575  sumk = sumk + rhdpext0(ni,nh,nc)*eirwaer(nb,ni)
1576  sums = sums + rhdpsca0(ni,nh,nc)*eirwaer(nb,ni)
1577  sumok = sumok + rhdpssa0(ni,nh,nc)*eirwaer(nb,ni) &
1578  & * rhdpext0(ni,nh,nc)
1579  sumokg = sumokg + rhdpssa0(ni,nh,nc)*eirwaer(nb,ni) &
1580  & * rhdpext0(ni,nh,nc)*rhdpasy0(ni,nh,nc)
1581  enddo
1582 
1583  refb = sumreft * rirbd
1584 
1585  extrhd(nh,nc,ib) = sumk * rirbd
1586  scarhd(nh,nc,ib) = sums * rirbd
1587  asyrhd(nh,nc,ib) = sumokg / (sumok + 1.0e-10)
1588  ssarhd(nh,nc,ib) = 4.0*refb &
1589  & / ( (f_one+refb)**2 - asyrhd(nh,nc,ib)*(f_one-refb)**2 )
1590  enddo ! end do_nh_block
1591  enddo ! end do_nc_block for rh-dep aeros
1592 
1593 ! --- for stratospheric background aerosols
1594 
1595  sumk = f_zero
1596  do ni = nr1(nb), nr2(nb)
1597  sumk = sumk + straext0(ni)*eirwaer(nb,ni)
1598  enddo
1599 
1600  extstra(ib) = sumk * rirbd
1601 
1602 ! --- check print
1603 ! if ( nb >= 1 .and. nb < 5) then
1604 ! print *,' in optavg for ir band:',nb
1605 ! print *,' nr1, nr2:',nr1(nb),nr2(nb)
1606 ! print *,' eirwaer:',eirwaer(nb,nr1(nb):nr2(nb))
1607 ! print *,' extrhi:', extrhi(:,ib)
1608 ! do i = 1, NRHLEV
1609 ! print *,' extrhd for rhlev:',i
1610 ! print *,extrhd(i,:,ib)
1611 ! enddo
1612 ! print *,' sumk, rirbd, extstra:',sumk,rirbd,extstra(ib)
1613 ! endif
1614 
1615  enddo ! end do_nb_block for lw
1616  endif ! end if_lalwflg_block
1617 !
1618  return
1619 !................................
1620  end subroutine optavg
1621 !--------------------------------
1622 !
1623 !...................................
1624  end subroutine clim_aerinit
1625 !-----------------------------------
1626 
1627 
1642 !-----------------------------------
1643  subroutine aer_update &
1644 !...................................
1645 ! --- inputs:
1646  & ( iyear, imon, me )
1647 ! --- outputs: ( to module variables )
1648 
1649 ! ================================================================== !
1650 ! !
1651 ! aer_update checks and update time varying climatology aerosol !
1652 ! data sets. !
1653 ! !
1654 ! inputs: size !
1655 ! iyear - 4-digit calender year 1 !
1656 ! imon - month of the year 1 !
1657 ! me - print message control flag 1 !
1658 ! !
1659 ! outputs: ( none ) !
1660 ! !
1661 ! external module variables: (in physparam) !
1662 ! lalwflg - control flag for tropospheric lw aerosol !
1663 ! laswflg - control flag for tropospheric sw aerosol !
1664 ! lavoflg - control flag for stratospheric volcanic aerosol !
1665 ! !
1666 ! usage: call aero_update !
1667 ! !
1668 ! subprograms called: trop_update, volc_update !
1669 ! !
1670 ! ================================================================== !
1671 
1672 ! --- inputs:
1673  integer, intent(in) :: iyear, imon, me
1674 
1675 ! --- output: ( none )
1676 
1677 ! --- locals: ( none )
1678 !
1679 !===> ... begin here
1680 !
1681  if ( imon < 1 .or. imon > 12 ) then
1682  print *,' ***** ERROR in specifying requested month !!! ', &
1683  & 'imon=', imon
1684  print *,' ***** STOPPED in subroutinte aer_update !!!'
1685  stop
1686  endif
1687 
1688  if ( lalwflg .or. laswflg ) then ! update monthly tropspheric aerosol data
1689  call trop_update
1690  endif
1691 
1692  if ( lavoflg ) then ! update yearly stratospheric volcanic aerosol data
1693  call volc_update
1694  endif
1695 
1696 
1697 ! =================
1698  contains
1699 ! =================
1700 
1703 !--------------------------------
1704  subroutine trop_update
1705 !................................
1706 ! --- inputs: (in scope variables, module variables)
1707 ! --- outputs: (module variables)
1708 
1709 ! ================================================================== !
1710 ! !
1711 ! subprogram : trop_update !
1712 ! !
1713 ! updates the monthly global distribution of aerosol profiles in !
1714 ! five degree horizontal resolution. !
1715 ! !
1716 ! ==================== defination of variables =================== !
1717 ! !
1718 ! inputs: (in-scope variables, module constants) !
1719 ! imon - integer, month of the year !
1720 ! me - integer, print message control flag !
1721 ! !
1722 ! outputs: (module variables) !
1723 ! !
1724 ! external module variables: (in physparam) !
1725 ! aeros_file - external aerosol data file name !
1726 ! !
1727 ! internal module variables: !
1728 ! kprfg ( IMXAE*JMXAE) - aeros profile index !
1729 ! idxcg (NXC*IMXAE*JMXAE) - aeros component index !
1730 ! cmixg (NXC*IMXAE*JMXAE) - aeros component mixing ratio !
1731 ! denng ( 2 *IMXAE*JMXAE) - aerosols number density !
1732 ! !
1733 ! NIAERCM - unit number for input data set !
1734 ! !
1735 ! subroutines called: none !
1736 ! !
1737 ! usage: call trop_update !
1738 ! !
1739 ! ================================================================== !
1740 
1741 ! --- inputs: ( none )
1742 ! --- output: ( none )
1743 
1744 ! --- locals:
1745 ! real (kind=kind_io8) :: cmix(NXC), denn, tem
1746  real (kind=kind_phys) :: cmix(nxc), denn, tem
1747  integer :: idxc(nxc), kprf
1748 
1749  integer :: i, id, j, k, m, nc
1750  logical :: file_exist
1751 
1752  character :: cline*80, ctyp*3
1753 !
1754 !===> ... begin here
1755 !
1756 ! --- ... reading climatological aerosols data
1757 
1758  inquire (file=aeros_file, exist=file_exist)
1759 
1760  if ( file_exist ) then
1761  close(niaercm)
1762  open (unit=niaercm,file=aeros_file,status='OLD', &
1763  & form='FORMATTED')
1764  rewind(niaercm)
1765 
1766  if ( me == 0 ) then
1767  print *,' Opened aerosol data file: ',aeros_file
1768  endif
1769  else
1770  print *,' Requested aerosol data file "',aeros_file, &
1771  & '" not found!'
1772  print *,' *** Stopped in subroutine trop_update !!'
1773  stop
1774  endif ! end if_file_exist_block
1775 
1776  do j = 1, jmxae
1777  do i = 1, imxae
1778  do m = 1, nxc
1779  idxcg(m,i,j) = 0
1780  cmixg(m,i,j) = f_zero
1781  enddo
1782  enddo
1783  enddo
1784 
1785  do j = 1, jmxae
1786  do i = 1, imxae
1787  do m = 1, 2
1788  denng(m,i,j) = f_zero
1789  enddo
1790  enddo
1791  enddo
1792 
1793 ! --- ... loop over 12 month global distribution
1794 
1795  lab_do_12mon : do m = 1, 12
1796 
1797  read(niaercm,12) cline
1798  12 format(a80/)
1799 
1800  if ( m /= imon ) then
1801 ! if ( me == 0 ) print *,' *** Skipped ',cline
1802 
1803  do j = 1, jmxae
1804  do i = 1, imxae
1805  read(niaercm,*) id
1806  enddo
1807  enddo
1808  else
1809  if ( me == 0 ) print *,' --- Reading ',cline
1810 
1811  do j = 1, jmxae
1812  do i = 1, imxae
1813  read(niaercm,14) (idxc(k),cmix(k),k=1,nxc),kprf,denn,nc,ctyp
1814  14 format(5(i2,e11.4),i2,f8.2,i3,1x,a3)
1815 
1816  kprfg(i,j) = kprf
1817  denng(1,i,j) = denn ! num density of 1st layer
1818  if ( kprf >= 6 ) then
1819  denng(2,i,j) = cmix(nxc) ! num density of 2dn layer
1820  else
1821  denng(2,i,j) = f_zero
1822  endif
1823 
1824  tem = f_one
1825  do k = 1, nxc-1
1826  idxcg(k,i,j) = idxc(k) ! component index
1827  cmixg(k,i,j) = cmix(k) ! component mixing ratio
1828  tem = tem - cmix(k)
1829  enddo
1830  idxcg(nxc,i,j) = idxc(nxc)
1831  cmixg(nxc,i,j) = tem ! to make sure all add to 1.
1832  enddo
1833  enddo
1834 
1835  close (niaercm)
1836  exit lab_do_12mon
1837  endif ! end if_m_block
1838 
1839  enddo lab_do_12mon
1840 
1841 ! -- check print
1842 
1843 ! print *,' IDXCG :'
1844 ! print 16,idxcg
1845 ! 16 format(40i3)
1846 ! print *,' CMIXG :'
1847 ! print 17,cmixg
1848 ! print *,' DENNG :'
1849 ! print 17,denng
1850 ! print *,' KPRFG :'
1851 ! print 17,kprfg
1852 ! 17 format(8e16.9)
1853 !
1854  return
1855 !................................
1856  end subroutine trop_update
1857 !--------------------------------
1858 
1861 !--------------------------------
1862  subroutine volc_update
1863 !................................
1864 ! --- inputs: (in scope variables, module variables)
1865 ! --- outputs: (module variables)
1866 
1867 ! ================================================================== !
1868 ! !
1869 ! subprogram : volc_update !
1870 ! !
1871 ! searches historical volcanic data sets to find and read in !
1872 ! monthly 45-degree lat-zone band data of optical depth. !
1873 ! !
1874 ! ==================== defination of variables =================== !
1875 ! !
1876 ! inputs: (in-scope variables, module constants) !
1877 ! iyear - integer, 4-digit calender year 1 !
1878 ! imon - integer, month of the year 1 !
1879 ! me - integer, print message control flag 1 !
1880 ! NIAERCM - integer, unit number for input data set 1 !
1881 ! !
1882 ! outputs: (module variables) !
1883 ! ivolae - integer, monthly, 45-deg lat-zone volc odp 12*4*10 !
1884 ! kyrstr - integer, starting year of data in the input file !
1885 ! kyrend - integer, ending year of data in the input file !
1886 ! kyrsav - integer, the year of data in use in the input file !
1887 ! kmonsav - integer, the month of data in use in the input file !
1888 ! !
1889 ! subroutines called: none !
1890 ! !
1891 ! usage: call volc_aerinit !
1892 ! !
1893 ! ================================================================== !
1894 
1895 ! --- inputs: (in-scope variables, module constants)
1896 ! integer :: iyear, imon, me, NIAERCM
1897 
1898 ! --- output: (module variables)
1899 ! integer :: ivolae(:,:,:), kyrstr, kyrend, kyrsav, kmonsav
1900 
1901 ! --- locals:
1902  integer :: i, j, k
1903  logical :: file_exist
1904 
1905  character :: cline*80, volcano_file*32
1906  data volcano_file / 'volcanic_aerosols_1850-1859.txt ' /
1907 !
1908 !===> ... begin here
1909 !
1910  kmonsav = imon
1911 
1912  if ( kyrstr<=iyear .and. iyear<=kyrend ) then ! use previously input data
1913  kyrsav = iyear
1914  return
1915  else ! need to input new data
1916  kyrsav = iyear
1917  kyrstr = iyear - mod(iyear,10)
1918  kyrend = kyrstr + 9
1919 
1920 ! --- check print
1921 ! print *,' kyrstr, kyrend, kyrsav, kmonsav =', &
1922 ! & kyrstr,kyrend,kyrsav,kmonsav
1923 
1924  if ( iyear < minvyr .or. iyear > maxvyr ) then
1925 ! if ( .not. allocated(ivolae) ) then
1926 ! allocate ( ivolae(12,4,10) ) ! for 12-mon,4-lat_zone,10-year
1927 ! endif
1928  ivolae(:,:,:) = 1 ! set as lowest value
1929  if ( me == 0 ) then
1930  print *,' Request volcanic date out of range,', &
1931  & ' optical depth set to lowest value'
1932  endif
1933  else
1934  write(volcano_file(19:27),60) kyrstr,kyrend
1935  60 format(i4.4,'-',i4.4)
1936 
1937  inquire (file=volcano_file, exist=file_exist)
1938  if ( file_exist ) then
1939  close(niaercm)
1940  open (unit=niaercm,file=volcano_file,status='OLD', &
1941  & form='FORMATTED')
1942 
1943  read(niaercm,62) cline
1944  62 format(a80)
1945 
1946 ! --- check print
1947  if ( me == 0 ) then
1948  print *,' Opened volcanic data file: ',volcano_file
1949  print *, cline
1950  endif
1951 
1952  do k = 1, 10
1953  do j = 1, 4
1954  read(niaercm,64) (ivolae(i,j,k),i=1,12)
1955  64 format(12i5)
1956  enddo
1957  enddo
1958 
1959  close (niaercm)
1960  else
1961  print *,' Requested volcanic data file "', &
1962  & volcano_file,'" not found!'
1963  print *,' *** Stopped in subroutine VOLC_AERINIT !!'
1964  stop
1965  endif ! end if_file_exist_block
1966 
1967  endif ! end if_iyear_block
1968  endif ! end if_kyrstr_block
1969 
1970 ! --- check print
1971  if ( me == 0 ) then
1972  k = mod(kyrsav,10) + 1
1973  print *,' CHECK: Sample Volcanic data used for month, year:', &
1974  & imon, iyear
1975  print *, ivolae(kmonsav,:,k)
1976  endif
1977 !
1978  return
1979 !................................
1980  end subroutine volc_update
1981 !--------------------------------
1982 !
1983 !...................................
1984  end subroutine aer_update
1985 !-----------------------------------
1986 
1987 
2013 !-----------------------------------
2014  subroutine setaer &
2015 !...................................
2017 ! --- inputs:
2018  & ( prsi,prsl,prslk,tvly,rhlay,slmsk,tracer,xlon,xlat, &
2019  & imax,nlay,nlp1, lsswr,lslwr, &
2020 ! --- outputs:
2021  & aerosw,aerolw &
2022  &, aerodp &
2023  & )
2024 
2025 ! ================================================================== !
2026 ! !
2027 ! setaer computes aerosols optical properties !
2028 ! !
2029 ! inputs: size !
2030 ! prsi - pressure at interface mb IMAX*NLP1 !
2031 ! prsl - layer mean pressure mb IMAX*NLAY !
2032 ! prslk - exner function = (p/p0)**rocp IMAX*NLAY !
2033 ! tvly - layer virtual temperature k IMAX*NLAY !
2034 ! rhlay - layer mean relative humidity IMAX*NLAY !
2035 ! slmsk - sea/land mask (sea:0,land:1,sea-ice:2) IMAX !
2036 ! tracer - aerosol tracer concentration IMAX*NLAY*NTRAC !
2037 ! xlon - longitude of given points in radiance IMAX !
2038 ! ok for both 0->2pi or -pi->+pi ranges !
2039 ! xlat - latitude of given points in radiance IMAX !
2040 ! default to pi/2 -> -pi/2, otherwise see in-line comment!
2041 ! IMAX - horizontal dimension of arrays 1 !
2042 ! NLAY,NLP1-vertical dimensions of arrays 1 !
2043 ! lsswr,lslwr !
2044 ! - logical flags for sw/lw radiation calls 1 !
2045 ! !
2046 ! outputs: !
2047 ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW!
2048 ! (:,:,:,1): optical depth !
2049 ! (:,:,:,2): single scattering albedo !
2050 ! (:,:,:,3): asymmetry parameter !
2051 ! aerolw - aeros opt properties for lw IMAX*NLAY*NBDLW*NF_AELW!
2052 ! (:,:,:,1): optical depth !
2053 ! (:,:,:,2): single scattering albedo !
2054 ! (:,:,:,3): asymmetry parameter !
2055 ! tau_gocart - 550nm aeros opt depth IMAX*NLAY*MAX_NUM_GRIDCOMP!
2056 !! aerodp - vertically integrated optical depth IMAX*NSPC1 !
2057 ! !
2058 ! external module variable: (in physparam) !
2059 ! iaerflg - aerosol effect control flag (volc,lw,sw, 3-dig) !
2060 ! laswflg - tropospheric aerosol control flag for sw radiation !
2061 ! =f: no sw aeros calc. =t: do sw aeros calc. !
2062 ! lalwflg - tropospheric aerosol control flag for lw radiation !
2063 ! =f: no lw aeros calc. =t: do lw aeros calc. !
2064 ! lavoflg - control flag for stratospheric vocanic aerosols !
2065 ! =t: add volcanic aerosols to the background aerosols !
2066 ! ivflip - control flag for direction of vertical index !
2067 ! =0: index from toa to surface !
2068 ! =1: index from surface to toa !
2069 ! !
2070 ! internal module variable: (set by subroutine aer_init) !
2071 ! ivolae - stratosphere volcanic aerosol optical depth (fac 1.e4) !
2072 ! 12*4*10 !
2073 ! usage: call setaer !
2074 ! !
2075 ! subprograms called: aer_property !
2076 ! !
2077 ! ================================================================== !
2078 
2079 ! --- inputs:
2080  integer, intent(in) :: IMAX, NLAY, NLP1
2081 
2082  real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, &
2083  & prslk, tvly, rhlay
2084  real (kind=kind_phys), dimension(:), intent(in) :: xlon, xlat, &
2085  & slmsk
2086  real (kind=kind_phys), dimension(:,:,:),intent(in):: tracer
2087 
2088  logical, intent(in) :: lsswr, lslwr
2089 
2090 
2091 ! --- outputs:
2092  real (kind=kind_phys), dimension(:,:,:,:), intent(out) :: &
2093  & aerosw, aerolw
2094 
2095  real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp
2096 
2097 ! --- locals:
2098  real (kind=kind_phys), parameter :: psrfh = 5.0 ! ref press (mb) for upper bound
2099 
2100  real (kind=kind_phys), dimension(IMAX) :: alon,alat,volcae,rdelp
2101 ! real (kind=kind_phys), dimension(IMAX) :: sumodp
2102  real (kind=kind_phys) :: prsln(nlp1),hz(imax,nlp1),dz(imax,nlay)
2103  real (kind=kind_phys) :: tmp1, tmp2, psrfl
2104 
2105  integer :: kcutl(imax), kcuth(imax)
2106  integer :: i, i1, j, k, m, mb, kh, kl
2107 
2108  logical :: laddsw=.false., laersw=.false.
2109  logical :: laddlw=.false., laerlw=.false.
2110 
2111 ! --- conversion constants
2112  real (kind=kind_phys), parameter :: rdg = 180.0 / con_pi
2113  real (kind=kind_phys), parameter :: rovg = 0.001 * con_rd / con_g
2114 
2115 !===> ... begin here
2116 
2117  do m = 1, nf_aesw
2118  do j = 1, nbdsw
2119  do k = 1, nlay
2120  do i = 1, imax
2121  aerosw(i,k,j,m) = f_zero
2122  enddo
2123  enddo
2124  enddo
2125  enddo
2126 
2127  do m = 1, nf_aelw
2128  do j = 1, nbdlw
2129  do k = 1, nlay
2130  do i = 1, imax
2131  aerolw(i,k,j,m) = f_zero
2132  enddo
2133  enddo
2134  enddo
2135  enddo
2136 
2137 ! sumodp = f_zero
2138  do i = 1, imax
2139  do k = 1, nspc1
2140  aerodp(i,k) = f_zero
2141  enddo
2142  enddo
2143 
2144 
2145  if ( .not. (lsswr .or. lslwr) ) then
2146  return
2147  endif
2148 
2149  if ( iaerflg <= 0 ) then
2150  return
2151  endif
2152 
2153  laersw = lsswr .and. laswflg
2154  laerlw = lslwr .and. lalwflg
2155 
2157 ! --- ... convert lat/lon from radiance to degree
2158 
2159  do i = 1, imax
2160  alon(i) = xlon(i) * rdg
2161  if (alon(i) < f_zero) alon(i) = alon(i) + 360.0
2162  alat(i) = xlat(i) * rdg ! if xlat in pi/2 -> -pi/2 range
2163 ! alat(i) = 90.0 - xlat(i)*rdg ! if xlat in 0 -> pi range
2164  enddo
2165 
2167 ! --- ... compute level height and layer thickness
2168 
2169  if ( laswflg .or. lalwflg ) then
2170 
2171  lab_do_imax : do i = 1, imax
2172 
2173  lab_if_flip : if (ivflip == 1) then ! input from sfc to toa
2174 
2175  do k = 1, nlay
2176  prsln(k) = log(prsi(i,k))
2177  enddo
2178  prsln(nlp1)= log(prsl(i,nlay))
2179 
2180  do k = nlay, 1, -1
2181  dz(i,k) = rovg * (prsln(k) - prsln(k+1)) * tvly(i,k)
2182  enddo
2183  dz(i,nlay) = 2.0 * dz(i,nlay)
2184 
2185  hz(i,1) = f_zero
2186  do k = 1, nlay
2187  hz(i,k+1) = hz(i,k) + dz(i,k)
2188  enddo
2189 
2190  else lab_if_flip ! input from toa to sfc
2191 
2192  prsln(1) = log(prsl(i,1))
2193  do k = 2, nlp1
2194  prsln(k) = log(prsi(i,k))
2195  enddo
2196 
2197  do k = 1, nlay
2198  dz(i,k) = rovg * (prsln(k+1) - prsln(k)) * tvly(i,k)
2199  enddo
2200  dz(i,1) = 2.0 * dz(i,1)
2201 
2202  hz(i,nlp1) = f_zero
2203  do k = nlay, 1, -1
2204  hz(i,k) = hz(i,k+1) + dz(i,k)
2205  enddo
2206 
2207  endif lab_if_flip
2208 
2209  enddo lab_do_imax
2210 
2217 ! --- ... calculate sw aerosol optical properties for the corresponding
2218 ! frequency bands
2219 
2220 !SARAH
2221 ! if ( iaerflg == 1 ) then ! use opac aerosol climatology
2222  if ( iaermdl == 0 ) then ! use opac aerosol climatology
2223 
2224  call aer_property &
2225 ! --- inputs:
2226  & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer, &
2227  & alon,alat,slmsk, laersw,laerlw, &
2228  & imax,nlay,nlp1, &
2229 ! & IMAX,NLAY,NLP1,NSPC1, &
2230 ! --- outputs:
2231  & aerosw,aerolw,aerodp &
2232  & )
2233 
2234 ! --- check print
2235 ! do m = 1, NBDSW
2236 ! print *,' *** CHECK AEROSOLS PROPERTIES FOR SW BAND =',m, &
2237 ! & ' ***'
2238 ! do k = 1, 10
2239 ! print *,' LEVEL :',k
2240 ! print *,' TAUAER:',aerosw(:,k,m,1)
2241 ! print *,' SSAAER:',aerosw(:,k,m,2)
2242 ! print *,' ASYAER:',aerosw(:,k,m,3)
2243 ! enddo
2244 ! enddo
2245 ! print *,' *** CHECK AEROSOLS OPTICAL DEPTH FOR 550nm REGION'
2246 ! print *, aerodp(:,1)
2247 ! if ( laod_out ) then
2248 ! do m = 1, NSPC1
2249 ! print *,' *** CHECK AEROSOLS OPTICAL DEPTH FOR SPECIES:', &
2250 ! & m
2251 ! print *, aerodp(:,m)
2252 ! sumodp(:) = sumodp(:) + aerodp(:,m)
2253 ! enddo
2254 
2255 !
2256 ! print *,' *** CHECK AEROSOLS OPTICAL DEPTH FOR ALL SPECIES:'
2257 ! print *, sumodp(:)
2258 ! endif
2259 ! do m = 1, NBDLW
2260 ! print *,' *** CHECK AEROSOLS PROPERTIES FOR LW BAND =',m, &
2261 ! & ' ***'
2262 ! do k = 1, 10
2263 ! print *,' LEVEL :',k
2264 ! print *,' TAUAER:',aerolw(:,k,m,1)
2265 ! print *,' SSAAER:',aerolw(:,k,m,2)
2266 ! print *,' ASYAER:',aerolw(:,k,m,3)
2267 ! enddo
2268 ! enddo
2269 ! SARAH
2270 ! elseif ( iaerflg == 2 ) then ! use gocart aerosol scheme
2271  elseif ( iaermdl == 1 ) then ! use gocart aerosol scheme
2272 
2273  call setgocartaer &
2274 
2275 ! --- inputs:
2276  & ( alon,alat,prslk,rhlay,dz,hz,nswlwbd, &
2277  & prsl,tvly,tracer, &
2278  & imax,nlay,nlp1, ivflip, lsswr,lslwr, &
2279 ! --- outputs:
2280  & aerosw,aerolw &
2281  & )
2282 
2283  endif ! end if_iaerflg_block
2284 
2285  endif ! end if_laswflg_or_lalwflg_block
2286 
2293 ! --- ... stratosphere volcanic forcing
2294 
2295  if ( lavoflg ) then
2296 
2297  if ( iaerflg == 100 ) then
2298  laddsw = lsswr
2299  laddlw = lslwr
2300  else
2301  laddsw = lsswr .and. laswflg
2302  laddlw = lslwr .and. lalwflg
2303  endif
2304 
2305  i1 = mod(kyrsav, 10) + 1
2306 
2307 ! --- select data in 4 lat bands, interpolation at the boundaires
2308 
2309  do i = 1, imax
2310  if ( alat(i) > 46.0 ) then
2311  volcae(i) = 1.0e-4 * ivolae(kmonsav,1,i1)
2312  else if ( alat(i) > 44.0 ) then
2313  volcae(i) = 5.0e-5 &
2314  & * (ivolae(kmonsav,1,i1) + ivolae(kmonsav,2,i1))
2315  else if ( alat(i) > 1.0 ) then
2316  volcae(i) = 1.0e-4 * ivolae(kmonsav,2,i1)
2317  else if ( alat(i) > -1.0 ) then
2318  volcae(i) = 5.0e-5 &
2319  & * (ivolae(kmonsav,2,i1) + ivolae(kmonsav,3,i1))
2320  else if ( alat(i) >-44.0 ) then
2321  volcae(i) = 1.0e-4 * ivolae(kmonsav,3,i1)
2322  else if ( alat(i) >-46.0 ) then
2323  volcae(i) = 5.0e-5 &
2324  & * (ivolae(kmonsav,3,i1) + ivolae(kmonsav,4,i1))
2325  else
2326  volcae(i) = 1.0e-4 * ivolae(kmonsav,4,i1)
2327  endif
2328  enddo
2329 
2330  if ( ivflip == 0 ) then ! input data from toa to sfc
2331 
2332 
2333 ! --- find lower boundary of stratosphere
2334 
2335  do i = 1, imax
2336 
2337  tmp1 = abs( alat(i) )
2338  if ( tmp1 > 70.0 ) then ! polar, fixed at 25000pa (250mb)
2339  psrfl = 250.0
2340  elseif ( tmp1 < 20.0 ) then ! tropic, fixed at 15000pa (150mb)
2341  psrfl = 150.0
2342  else ! mid-lat, interpolation
2343  psrfl = 110.0 + 2.0*tmp1
2344  endif
2345 
2346  kcuth(i) = nlay - 1
2347  kcutl(i) = 2
2348  rdelp(i) = f_one / prsi(i,2)
2349 
2350  lab_do_kcuth0 : do k = 2, nlay-2
2351  if ( prsi(i,k) >= psrfh ) then
2352  kcuth(i) = k - 1
2353  exit lab_do_kcuth0
2354  endif
2355  enddo lab_do_kcuth0
2356 
2357  lab_do_kcutl0 : do k = 2, nlay-2
2358  if ( prsi(i,k) >= psrfl ) then
2359  kcutl(i) = k - 1
2360  rdelp(i) = f_one / (prsi(i,k) - prsi(i,kcuth(i)))
2361  exit lab_do_kcutl0
2362  endif
2363  enddo lab_do_kcutl0
2364  enddo
2365 
2366 
2367 ! --- sw: add volcanic aerosol optical depth to the background value
2368 
2369  if ( laddsw ) then
2370  do m = 1, nbdsw
2371  mb = nswstr + m - 1
2372 
2373  if ( wvnsw1(mb) > 20000 ) then ! range of wvlth < 0.5mu
2374  tmp2 = 0.74
2375  elseif ( wvnsw2(mb) < 20000 ) then ! range of wvlth > 0.5mu
2376  tmp2 = 1.14
2377  else ! range of wvlth in btwn
2378  tmp2 = 0.94
2379  endif
2380  tmp1 = (0.275e-4 * (wvnsw2(mb)+wvnsw1(mb))) ** tmp2
2381 
2382  do i = 1, imax
2383  kh = kcuth(i)
2384  kl = kcutl(i)
2385  do k = kh, kl
2386  tmp2 = tmp1 * ((prsi(i,k+1) - prsi(i,k)) * rdelp(i))
2387  aerosw(i,k,m,1) = aerosw(i,k,m,1) + tmp2*volcae(i)
2388  enddo
2389 
2390 ! --- smoothing profile at boundary if needed
2391 
2392  if ( aerosw(i,kl,m,1) > 10.*aerosw(i,kl+1,m,1) ) then
2393  tmp2 = aerosw(i,kl,m,1) + aerosw(i,kl+1,m,1)
2394  aerosw(i,kl ,m,1) = 0.8 * tmp2
2395  aerosw(i,kl+1,m,1) = 0.2 * tmp2
2396  endif
2397  enddo ! end do_i_block
2398  enddo ! end do_m_block
2399 
2400 ! --- check print
2401 ! do i = 1, IMAX
2402 ! print *,' LEV PRESS TAU FOR PROFILE:',i, &
2403 ! & ' KCUTH, KCUTL =',kcuth(i),kcutl(i)
2404 ! kh = kcuth(i) - 1
2405 ! kl = kcutl(i) + 10
2406 ! do k = kh, kl
2407 ! write(6,71) k, prsl(i,k), aerosw(i,k,1,1)
2408 ! 71 format(i3,2e11.4)
2409 ! enddo
2410 ! enddo
2411 
2412  endif ! end if_laddsw_block
2413 
2414 ! --- lw: add volcanic aerosol optical depth to the background value
2415 
2416  if ( laddlw ) then
2417  if ( nlwbnd == 1 ) then
2418 
2419  tmp1 = (0.55 / 11.0) ** 1.2
2420  do i = 1, imax
2421  kh = kcuth(i)
2422  kl = kcutl(i)
2423  do k = kh, kl
2424  tmp2 = tmp1 * ((prsi(i,k+1) - prsi(i,k)) * rdelp(i)) &
2425  & * volcae(i)
2426  do m = 1, nbdlw
2427  aerolw(i,k,m,1) = aerolw(i,k,m,1) + tmp2
2428  enddo
2429  enddo
2430  enddo ! end do_i_block
2431 
2432  else
2433 
2434  do m = 1, nbdlw
2435  tmp1 = (0.275e-4 * (wvnlw2(m) + wvnlw1(m))) ** 1.2
2436 
2437  do i = 1, imax
2438  kh = kcuth(i)
2439  kl = kcutl(i)
2440  do k = kh, kl
2441  tmp2 = tmp1 * ((prsi(i,k+1)-prsi(i,k)) * rdelp(i))
2442  aerolw(i,k,m,1) = aerolw(i,k,m,1) + tmp2*volcae(i)
2443  enddo
2444  enddo ! end do_i_block
2445  enddo ! end do_m_block
2446 
2447  endif ! end if_NLWBND_block
2448  endif ! end if_laddlw_block
2449 
2450  else ! input data from sfc to toa
2451 
2452 ! --- find lower boundary of stratosphere
2453 
2454  do i = 1, imax
2455 
2456  tmp1 = abs( alat(i) )
2457  if ( tmp1 > 70.0 ) then ! polar, fixed at 25000pa (250mb)
2458  psrfl = 250.0
2459  elseif ( tmp1 < 20.0 ) then ! tropic, fixed at 15000pa (150mb)
2460  psrfl = 150.0
2461  else ! mid-lat, interpolation
2462  psrfl = 110.0 + 2.0*tmp1
2463  endif
2464 
2465  kcuth(i) = 2
2466  kcutl(i) = nlay - 1
2467  rdelp(i) = f_one / prsi(i,nlay-1)
2468 
2469  lab_do_kcuth1 : do k = nlay-1, 2, -1
2470  if ( prsi(i,k) >= psrfh ) then
2471  kcuth(i) = k
2472  exit lab_do_kcuth1
2473  endif
2474  enddo lab_do_kcuth1
2475 
2476  lab_do_kcutl1 : do k = nlay, 2, -1
2477  if ( prsi(i,k) >= psrfl ) then
2478  kcutl(i) = k
2479  rdelp(i) = f_one / (prsi(i,k) - prsi(i,kcuth(i)+1))
2480  exit lab_do_kcutl1
2481  endif
2482  enddo lab_do_kcutl1
2483  enddo
2484 
2485 ! --- sw: add volcanic aerosol optical depth to the background value
2486 
2487  if ( laddsw ) then
2488  do m = 1, nbdsw
2489  mb = nswstr + m - 1
2490 
2491  if ( wvnsw1(mb) > 20000 ) then ! range of wvlth < 0.5mu
2492  tmp2 = 0.74
2493  elseif ( wvnsw2(mb) < 20000 ) then ! range of wvlth > 0.5mu
2494  tmp2 = 1.14
2495  else ! range of wvlth in btwn
2496  tmp2 = 0.94
2497  endif
2498  tmp1 = (0.275e-4 * (wvnsw2(mb)+wvnsw1(mb))) ** tmp2
2499 
2500  do i = 1, imax
2501  kh = kcuth(i)
2502  kl = kcutl(i)
2503  do k = kl, kh
2504  tmp2 = tmp1 * ((prsi(i,k) - prsi(i,k+1)) * rdelp(i))
2505  aerosw(i,k,m,1) = aerosw(i,k,m,1) + tmp2*volcae(i)
2506  enddo
2507 
2508 ! --- smoothing profile at boundary if needed
2509 
2510  if ( aerosw(i,kl,m,1) > 10.*aerosw(i,kl-1,m,1) ) then
2511  tmp2 = aerosw(i,kl,m,1) + aerosw(i,kl-1,m,1)
2512  aerosw(i,kl ,m,1) = 0.8 * tmp2
2513  aerosw(i,kl-1,m,1) = 0.2 * tmp2
2514  endif
2515  enddo ! end do_i_block
2516  enddo ! end do_m_block
2517 
2518 ! --- check print
2519 ! do i = 1, IMAX
2520 ! print *,' LEV PRESS TAU FOR PROFILE:',i, &
2521 ! & ' KCUTH, KCUTL =',kcuth(i),kcutl(i)
2522 ! kh = kcuth(i) + 1
2523 ! kl = kcutl(i) - 10
2524 ! do k = kh, kl, -1
2525 ! write(6,71) NLP1-k,prsl(i,k),aerosw(i,k,1,1)
2526 ! enddo
2527 ! enddo
2528 
2529  endif ! end if_laddsw_block
2530 
2531 ! --- lw: add volcanic aerosol optical depth to the background value
2532 
2533  if ( laddlw ) then
2534  if ( nlwbnd == 1 ) then
2535 
2536  tmp1 = (0.55 / 11.0) ** 1.2
2537  do i = 1, imax
2538  kh = kcuth(i)
2539  kl = kcutl(i)
2540  do k = kl, kh
2541  tmp2 = tmp1 * ((prsi(i,k) - prsi(i,k+1)) * rdelp(i)) &
2542  & * volcae(i)
2543  do m = 1, nbdlw
2544  aerolw(i,k,m,1) = aerolw(i,k,m,1) + tmp2
2545  enddo
2546  enddo
2547  enddo ! end do_i_block
2548 
2549  else
2550 
2551  do m = 1, nbdlw
2552  tmp1 = (0.275e-4 * (wvnlw2(m) + wvnlw1(m))) ** 1.2
2553 
2554  do i = 1, imax
2555  kh = kcuth(i)
2556  kl = kcutl(i)
2557  do k = kl, kh
2558  tmp2 = tmp1 * ((prsi(i,k)-prsi(i,k+1)) * rdelp(i))
2559  aerolw(i,k,m,1) = aerolw(i,k,m,1) + tmp2*volcae(i)
2560  enddo
2561  enddo ! end do_i_block
2562  enddo ! end do_m_block
2563 
2564  endif ! end if_NLWBND_block
2565  endif ! end if_laddlw_block
2566 
2567  endif ! end if_ivflip_block
2568 
2569  endif ! end if_lavoflg_block
2570 !
2571  return
2572 !...................................
2573  end subroutine setaer
2574 !-----------------------------------
2576 
2579 !-----------------------------------
2580  subroutine aer_property &
2581 !...................................
2583 ! --- inputs:
2584  & ( prsi,prsl,prslk,tvly,rhlay,dz,hz,tracer, &
2585  & alon,alat,slmsk, laersw,laerlw, &
2586  & imax,nlay,nlp1, &
2587 ! & IMAX,NLAY,NLP1,NSPC, &
2588 ! --- outputs:
2589  & aerosw,aerolw,aerodp &
2590  & )
2591 
2592 ! ================================================================== !
2593 ! !
2594 ! aer_property maps the 5 degree global climatological aerosol data !
2595 ! set onto model grids, and compute aerosol optical properties for sw !
2596 ! and lw radiations. !
2597 ! !
2598 ! inputs: !
2599 ! prsi - pressure at interface mb IMAX*NLP1 !
2600 ! prsl - layer mean pressure (not used) IMAX*NLAY !
2601 ! prslk - exner function=(p/p0)**rocp (not used) IMAX*NLAY !
2602 ! tvly - layer virtual temperature (not used) IMAX*NLAY !
2603 ! rhlay - layer mean relative humidity IMAX*NLAY !
2604 ! dz - layer thickness m IMAX*NLAY !
2605 ! hz - level high m IMAX*NLP1 !
2606 ! tracer - aer tracer concentrations (not used) IMAX*NLAY*NTRAC!
2607 ! alon, alat IMAX !
2608 ! - longitude and latitude of given points in degree !
2609 ! slmsk - sea/land mask (sea:0,land:1,sea-ice:2) IMAX !
2610 ! laersw,laerlw 1 !
2611 ! - logical flag for sw/lw aerosol calculations !
2612 ! IMAX - horizontal dimension of arrays 1 !
2613 ! NLAY,NLP1-vertical dimensions of arrays 1 !
2614 !! NSPC - num of species for optional aod output fields 1 !
2615 ! !
2616 ! outputs: !
2617 ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW!
2618 ! (:,:,:,1): optical depth !
2619 ! (:,:,:,2): single scattering albedo !
2620 ! (:,:,:,3): asymmetry parameter !
2621 ! aerolw - aeros opt properties for lw IMAX*NLAY*NBDLW*NF_AELW!
2622 ! (:,:,:,1): optical depth !
2623 ! (:,:,:,2): single scattering albedo !
2624 ! (:,:,:,3): asymmetry parameter !
2625 !! aerodp - vertically integrated aer-opt-depth IMAX*NSPC+1 !
2626 ! !
2627 ! module parameters and constants: !
2628 ! NSWBND - total number of actual sw spectral bands computed !
2629 ! NLWBND - total number of actual lw spectral bands computed !
2630 ! NSWLWBD - total number of sw+lw bands computed !
2631 ! !
2632 ! external module variables: (in physparam) !
2633 ! ivflip - control flag for direction of vertical index !
2634 ! =0: index from toa to surface !
2635 ! =1: index from surface to toa !
2636 ! !
2637 ! module variable: (set by subroutine aer_init) !
2638 ! kprfg - aerosols profile index IMXAE*JMXAE !
2639 ! 1:ant 2:arc 3:cnt 4:mar 5:des 6:marme 7:cntme !
2640 ! idxcg - aerosols component index NXC*IMXAE*JMXAE !
2641 ! 1:inso 2:soot 3:minm 4:miam 5:micm !
2642 ! 6:mitr 7:waso 8:ssam 9:sscm 10:suso !
2643 ! cmixg - aerosols component mixing ratio NXC*IMXAE*JMXAE !
2644 ! denng - aerosols number density 2 *IMXAE*JMXAE !
2645 ! 1:for domain-1 2:domain-2 (prof marme/cntme only) !
2646 ! !
2647 ! usage: call aer_property !
2648 ! !
2649 ! subprograms called: radclimaer !
2650 ! !
2651 ! ================================================================== !
2652 
2653 ! --- inputs:
2654  integer, intent(in) :: IMAX, NLAY, NLP1
2655 ! integer, intent(in) :: IMAX, NLAY, NLP1, NSPC
2656  logical, intent(in) :: laersw, laerlw
2657 
2658  real (kind=kind_phys), dimension(:,:), intent(in) :: prsi, prsl, &
2659  & prslk, tvly, rhlay, dz, hz
2660  real (kind=kind_phys), dimension(:), intent(in) :: alon, alat, &
2661  & slmsk
2662  real (kind=kind_phys), dimension(:,:,:),intent(in):: tracer
2663 
2664 ! --- outputs:
2665  real (kind=kind_phys), dimension(:,:,:,:), intent(out) :: &
2666  & aerosw, aerolw
2667  real (kind=kind_phys), dimension(:,:) , intent(out) :: aerodp
2668 
2669 ! --- locals:
2670  real (kind=kind_phys), dimension(NCM) :: cmix
2671  real (kind=kind_phys), dimension( 2) :: denn
2672  real (kind=kind_phys), dimension(NSPC) :: spcodp
2673 
2674  real (kind=kind_phys), dimension(NLAY) :: delz, rh1, dz1
2675  integer, dimension(NLAY) :: idmaer
2676 
2677  real (kind=kind_phys), dimension(NLAY,NSWLWBD):: tauae,ssaae,asyae
2678 !test real (kind=kind_phys), dimension(IMAX,NLAY) :: aersav
2679 
2680  real (kind=kind_phys) :: tmp1, tmp2, rps, dtmp, h1
2681  real (kind=kind_phys) :: wi, wj, w11, w12, w21, w22
2682 
2683  integer :: i, ii, i1, i2, i3, j1, j2, j3, k, m, m1, &
2684  & kp, kpa, kpi, kpj
2685 
2686 ! --- conversion constants
2687  real (kind=kind_phys), parameter :: dltg = 360.0 / float(imxae)
2688  real (kind=kind_phys), parameter :: hdlt = 0.5 * dltg
2689  real (kind=kind_phys), parameter :: rdlt = 1.0 / dltg
2690 
2691 !
2692 !===> ... begin here
2693 !
2694 ! --- map aerosol data to model grids
2695 
2696  i1 = 1
2697  i2 = 2
2698  j1 = 1
2699  j2 = 2
2700 
2701  lab_do_imax : do i = 1, imax
2702 
2703 ! --- map grid in longitude direction, lon from 0 to 355 deg resolution
2704 
2705 ! print *,' Seeking lon index for point i =',i
2706  i3 = i1
2707  lab_do_imxae : do while ( i3 <= imxae )
2708  tmp1 = dltg * (i3 - 1)
2709  dtmp = alon(i) - tmp1
2710 ! print *,' alon, i3, tlon, dlon =',alon(i),i3,tmp1,dtmp
2711 
2712  if ( dtmp > dltg ) then
2713  i3 = i3 + 1
2714  if ( i3 > imxae ) then
2715  print *,' ERROR! In setclimaer alon>360. ipt =',i, &
2716  & ', dltg,alon,tlon,dlon =',dltg,alon(i),tmp1,dtmp
2717  stop
2718  endif
2719  elseif ( dtmp >= f_zero ) then
2720  i1 = i3
2721  i2 = mod(i3,imxae) + 1
2722  wi = dtmp * rdlt
2723  if ( dtmp <= hdlt ) then
2724  kpi = i3
2725  else
2726  kpi = i2
2727  endif
2728 ! print *,' found i1, i2, wi =',i1,i2,wi
2729  exit lab_do_imxae
2730  else
2731  i3 = i3 - 1
2732  if ( i3 < 1 ) then
2733  print *,' ERROR! In setclimaer alon< 0. ipt =',i, &
2734  & ', dltg,alon,tlon,dlon =',dltg,alon(i),tmp1,dtmp
2735  stop
2736  endif
2737  endif
2738  enddo lab_do_imxae
2739 
2740 ! --- map grid in latitude direction, lat from 90n to 90s in 5 deg resolution
2741 
2742 ! print *,' Seeking lat index for point i =',i
2743  j3 = j1
2744  lab_do_jmxae : do while ( j3 <= jmxae )
2745  tmp2 = 90.0 - dltg * (j3 - 1)
2746  dtmp = tmp2 - alat(i)
2747 ! print *,' alat, j3, tlat, dlat =',alat(i),j3,tmp2,dtmp
2748 
2749  if ( dtmp > dltg ) then
2750  j3 = j3 + 1
2751  if ( j3 >= jmxae ) then
2752  print *,' ERROR! In setclimaer alat<-90. ipt =',i, &
2753  & ', dltg,alat,tlat,dlat =',dltg,alat(i),tmp2,dtmp
2754  stop
2755  endif
2756  elseif ( dtmp >= f_zero ) then
2757  j1 = j3
2758  j2 = j3 + 1
2759  wj = dtmp * rdlt
2760  if ( dtmp <= hdlt ) then
2761  kpj = j3
2762  else
2763  kpj = j2
2764  endif
2765 ! print *,' found j1, j2, wj =',j1,j2,wj
2766  exit lab_do_jmxae
2767  else
2768  j3 = j3 - 1
2769  if ( j3 < 1 ) then
2770  print *,' ERROR! In setclimaer alat>90. ipt =',i, &
2771  & ', dltg,alat,tlat,dlat =',dltg,alat(i),tmp2,dtmp
2772  stop
2773  endif
2774  endif
2775  enddo lab_do_jmxae
2776 
2777 ! --- determin the type of aerosol profile (kp) and scale hight for domain 1 (h1)
2778 ! to be used at this grid point
2779 
2780  kp = kprfg(kpi,kpj) ! nearest typical aeros profile as default
2781  kpa = max( kprfg(i1,j1),kprfg(i1,j2),kprfg(i2,j1),kprfg(i2,j2) )
2782  h1 = haer(1,kp)
2783  denn(2) = f_zero
2784  ii = 1
2785 
2786  if ( kp /= kpa ) then
2787  if ( kpa == 6 ) then ! if ocean prof with mineral aeros overlay
2788  ii = 2 ! need 2 types of densities
2789  if ( slmsk(i) > f_zero ) then ! but actually a land/sea-ice point
2790  kp = 7 ! reset prof index to land
2791  h1 = 0.5*(haer(1,6) + haer(1,7)) ! use a transition scale hight
2792  else
2793  kp = kpa
2794  h1 = haer(1,6)
2795  endif
2796  elseif ( kpa == 7 ) then ! if land prof with mineral aeros overlay
2797  ii = 2 ! need 2 types of densities
2798  if ( slmsk(i) <= f_zero ) then ! but actually an ocean point
2799  kp = 6 ! reset prof index to ocean
2800  h1 = 0.5*(haer(1,6) + haer(1,7)) ! use a transition scale hight
2801  else
2802  kp = kpa
2803  h1 = haer(1,7)
2804  endif
2805  else ! lower atmos without mineral aeros overlay
2806 ! h1 = 0.5*(haer(1,kp) + haer(1,kpa)) ! use a transition scale hight
2807  h1 = haer(1,kpa)
2808  kp = kpa
2809  endif
2810  endif
2811 
2812 ! --- compute horizontal bi-linear interpolation weights
2813 
2814  w11 = (f_one-wi) * (f_one-wj)
2815  w12 = (f_one-wi) * wj
2816  w21 = wi * (f_one-wj)
2817  w22 = wi * wj
2818 
2819 ! --- check print
2820 ! print *,' Grid pt', i,', alon, alat =',alon(i),alat(i), &
2821 ! & ', tlon, tlat =',tmp1,tmp2
2822 ! print *,' lon grid index i1, i2 =',i1,i2,', weight wi =',wi
2823 ! print *,' lat grid index j1, j2 =',j1,j2,', weight wj =',wj
2824 ! print *,' bi-linear weights w11,w21,w12,w22 =',w11,w21,w12,w22
2825 ! print *,' kp,kpa,slmsk,h1 =',kp,m1,slmsk(i),h1
2826 
2827 ! --- do horizontal bi-linear interpolation on aerosol partical density (denn)
2828 
2829  do m = 1, ii ! ii=1 for domain 1; =2 for domain 2.
2830  denn(m) = w11*denng(m,i1,j1) + w12*denng(m,i1,j2) &
2831  & + w21*denng(m,i2,j1) + w22*denng(m,i2,j2)
2832  enddo ! end_do_m_loop
2833 
2834 ! --- do horizontal bi-linear interpolation on mixing ratios
2835 
2836  cmix(:) = f_zero
2837  do m = 1, nxc
2838  ii = idxcg(m,i1,j1)
2839  if ( ii > 0 ) then
2840  cmix(ii) = cmix(ii) + w11*cmixg(m,i1,j1)
2841  endif
2842  ii = idxcg(m,i1,j2)
2843  if ( ii > 0 ) then
2844  cmix(ii) = cmix(ii) + w12*cmixg(m,i1,j2)
2845  endif
2846  ii = idxcg(m,i2,j1)
2847  if ( ii > 0 ) then
2848  cmix(ii) = cmix(ii) + w21*cmixg(m,i2,j1)
2849  endif
2850  ii = idxcg(m,i2,j2)
2851  if ( ii > 0 ) then
2852  cmix(ii) = cmix(ii) + w22*cmixg(m,i2,j2)
2853  endif
2854  enddo ! end_do_m_loop
2855 
2856 ! --- check print
2857 ! print *,' denn =',denn(:)
2858 ! print *,' cmix =',cmix(:)
2859 
2860 ! --- prepare to setup domain index array and effective layer thickness
2861 ! also convert pressure level to sigma level to follow the terrain
2862 
2863  do k = 1, nlay
2864  rh1(k) = rhlay(i,k)
2865  dz1(k) = dz (i,k)
2866  enddo
2867 
2868  lab_if_flip : if (ivflip == 1) then ! input from sfc to toa
2869 
2870  if ( prsi(i,1) > 100.0 ) then
2871  rps = f_one / prsi(i,1)
2872  else
2873  print *,' !!! (1) Error in subr radiation_aerosols:', &
2874  & ' unrealistic surface pressure =', i,prsi(i,1)
2875  stop
2876  endif
2877 
2878  ii = 1
2879  do k = 1, nlay
2880  if (prsi(i,k+1)*rps < sigref(ii,kp)) then
2881  ii = ii + 1
2882  if (ii == 2 .and. prsref(2,kp) == prsref(3,kp)) then
2883  ii = 3
2884  endif
2885  endif
2886  idmaer(k) = ii
2887 
2888  if ( ii > 1 ) then
2889  tmp1 = haer(ii,kp)
2890  else
2891  tmp1 = h1
2892  endif
2893 
2894  if (tmp1 > f_zero) then
2895  tmp2 = f_one / tmp1
2896  delz(k) = tmp1 * (exp(-hz(i,k)*tmp2)-exp(-hz(i,k+1)*tmp2))
2897  else
2898  delz(k) = dz1(k)
2899  endif
2900  enddo
2901 
2902  else lab_if_flip ! input from toa to sfc
2903 
2904  if ( prsi(i,nlp1) > 100.0 ) then
2905  rps = 1.0 / prsi(i,nlp1)
2906  else
2907  print *,' !!! (2) Error in subr radiation_aerosols:', &
2908  & ' unrealistic surface pressure =', i,prsi(i,nlp1)
2909  endif
2910 
2911  ii = 1
2912  do k = nlay, 1, -1
2913  if (prsi(i,k)*rps < sigref(ii,kp)) then
2914  ii = ii + 1
2915  if (ii == 2 .and. prsref(2,kp) == prsref(3,kp)) then
2916  ii = 3
2917  endif
2918  endif
2919  idmaer(k) = ii
2920 
2921  if ( ii > 1 ) then
2922  tmp1 = haer(ii,kp)
2923  else
2924  tmp1 = h1
2925  endif
2926 
2927  if (tmp1 > f_zero) then
2928  tmp2 = f_one / tmp1
2929  delz(k) = tmp1 * (exp(-hz(i,k+1)*tmp2)-exp(-hz(i,k)*tmp2))
2930  else
2931  delz(k) = dz1(k)
2932  endif
2933  enddo
2934 
2935  endif lab_if_flip
2936 
2937 ! --- check print
2938 
2939 ! print *,' in setclimaer, profile:',i
2940 ! print *,' rh :',rh1
2941 ! print *,' dz :',dz1
2942 ! print *,' delz :',delz
2943 ! print *,' idmaer:',idmaer
2944 
2945 ! --- calculate sw/lw aerosol optical properties for the
2946 ! corresponding frequency bands
2947 
2948  call radclimaer
2949 ! --- inputs: (in-scope variables)
2950 ! --- outputs: (in-scope variables)
2951 
2952  if ( laersw ) then
2953 
2954  do m = 1, nbdsw
2955  do k = 1, nlay
2956  aerosw(i,k,m,1) = tauae(k,m)
2957  aerosw(i,k,m,2) = ssaae(k,m)
2958  aerosw(i,k,m,3) = asyae(k,m)
2959  enddo
2960  enddo
2961 
2962 ! --- total aod (optional)
2963  do k = 1, nlay
2964  aerodp(i,1) = aerodp(i,1) + tauae(k,nv_aod)
2965  enddo
2966 
2967 ! --- for diagnostic output (optional)
2968 ! if ( lspcaod ) then
2969  do m = 1, nspc
2970  aerodp(i,m+1) = spcodp(m)
2971  enddo
2972 ! endif
2973 
2974  endif ! end if_larsw_block
2975 
2976  if ( laerlw ) then
2977 
2978  if ( nlwbnd == 1 ) then
2979  m1 = nswbnd + 1
2980  do m = 1, nbdlw
2981  do k = 1, nlay
2982  aerolw(i,k,m,1) = tauae(k,m1)
2983  aerolw(i,k,m,2) = ssaae(k,m1)
2984  aerolw(i,k,m,3) = asyae(k,m1)
2985  enddo
2986  enddo
2987  else
2988  do m = 1, nbdlw
2989  m1 = nswbnd + m
2990  do k = 1, nlay
2991  aerolw(i,k,m,1) = tauae(k,m1)
2992  aerolw(i,k,m,2) = ssaae(k,m1)
2993  aerolw(i,k,m,3) = asyae(k,m1)
2994  enddo
2995  enddo
2996  endif
2997 
2998  endif ! end if_laerlw_block
2999 
3000  enddo lab_do_imax
3001 
3002 ! =================
3003  contains
3004 ! =================
3005 
3009 !--------------------------------
3010  subroutine radclimaer
3011 !................................
3012 
3013 ! --- inputs: (in scope variables)
3014 ! --- outputs: (in scope variables)
3015 
3016 ! ================================================================== !
3017 ! !
3018 ! compute aerosols optical properties in NSWLWBD bands. there are !
3019 ! seven different vertical profile structures. in the troposphere, !
3020 ! aerosol distribution at each grid point is composed from up to !
3021 ! six components out of a total of ten different substances. !
3022 ! !
3023 ! ref: wmo report wcp-112 (1986) !
3024 ! !
3025 ! input variables: !
3026 ! cmix - mixing ratioes of aerosol components - NCM !
3027 ! denn - aerosol number densities - 2 !
3028 ! rh1 - relative humidity - NLAY !
3029 ! delz - effective layer thickness km NLAY !
3030 ! idmaer - aerosol domain index - NLAY !
3031 ! NXC - number of different aerosol components- 1 !
3032 ! NLAY - vertical dimensions - 1 !
3033 ! !
3034 ! output variables: !
3035 ! tauae - optical depth - NLAY*NSWLWBD!
3036 ! ssaae - single scattering albedo - NLAY*NSWLWBD!
3037 ! asyae - asymmetry parameter - NLAY*NSWLWBD!
3038 !! aerodp - vertically integrated aer-opt-depth - IMAX*NSPC+1 !
3039 ! !
3040 ! ================================================================== !
3041 !
3042  real (kind=kind_phys) :: crt1, crt2
3043  parameter(crt1=30.0, crt2=0.03333)
3044 
3045 ! --- inputs:
3046 ! --- outputs:
3047 
3048 ! --- locals:
3049  real (kind=kind_phys) :: cm, hd, hdi, sig0u, sig0l, ratio, tt0, &
3050  & ex00, sc00, ss00, as00, ex01, sc01, ss01, as01, tt1, &
3051  & ex02, sc02, ss02, as02, ex03, sc03, ss03, as03, tt2, &
3052  & ext1, sca1, ssa1, asy1, drh0, drh1, rdrh
3053 
3054  integer :: ih1, ih2, kk, idom, icmp, ib, ii, ic, ic1
3055  integer :: idx
3056 
3057 !===> ... begin here
3058 
3059  spcodp = f_zero
3060 
3061 !===> ... loop over vertical layers from top to surface
3062 
3063  lab_do_layer : do kk = 1, nlay
3064 
3065 ! --- linear interp coeffs for rh-dep species
3066 
3067  ih2 = 1
3068  do while ( rh1(kk) > rhlev(ih2) )
3069  ih2 = ih2 + 1
3070  if ( ih2 > nrhlev ) exit
3071  enddo
3072  ih1 = max( 1, ih2-1 )
3073  ih2 = min( nrhlev, ih2 )
3074 
3075  drh0 = rhlev(ih2) - rhlev(ih1)
3076  drh1 = rh1(kk) - rhlev(ih1)
3077  if ( ih1 == ih2 ) then
3078  rdrh = f_zero
3079  else
3080  rdrh = drh1 / drh0
3081  endif
3082 
3083 ! --- assign optical properties in each domain
3084 
3085  idom = idmaer(kk)
3086 
3087  lab_if_idom : if (idom == 5) then
3088 ! --- 5th domain - upper stratosphere assume no aerosol
3089 
3090  do ib = 1, nswlwbd
3091  tauae(kk,ib) = f_zero
3092  if ( ib <= nswbnd ) then
3093  ssaae(kk,ib) = 0.99
3094  asyae(kk,ib) = 0.696
3095  else
3096  ssaae(kk,ib) = 0.5
3097  asyae(kk,ib) = 0.3
3098  endif
3099  enddo
3100 
3101  elseif (idom == 4) then lab_if_idom
3102 ! --- 4th domain - stratospheric layers
3103 
3104  do ib = 1, nswlwbd
3105  tauae(kk,ib) = extstra(ib) * delz(kk)
3106  if ( ib <= nswbnd ) then
3107  ssaae(kk,ib) = 0.99
3108  asyae(kk,ib) = 0.696
3109  else
3110  ssaae(kk,ib) = 0.5
3111  asyae(kk,ib) = 0.3
3112  endif
3113  enddo
3114 
3115 ! --- compute aod from individual species' contribution (optional)
3116  idx = idxspc(10) ! for sulfate
3117  spcodp(idx) = spcodp(idx) + tauae(kk,nv_aod)
3118 
3119  elseif (idom == 3) then lab_if_idom
3120 ! --- 3rd domain - free tropospheric layers
3121 ! 1:inso 0.17e-3; 2:soot 0.4; 7:waso 0.59983; n:730
3122 
3123  do ib = 1, nswlwbd
3124  ex01 = extrhi(1,ib)
3125  sc01 = scarhi(1,ib)
3126  ss01 = ssarhi(1,ib)
3127  as01 = asyrhi(1,ib)
3128 
3129  ex02 = extrhi(2,ib)
3130  sc02 = scarhi(2,ib)
3131  ss02 = ssarhi(2,ib)
3132  as02 = asyrhi(2,ib)
3133 
3134  ex03 = extrhd(ih1,1,ib) &
3135  & + rdrh * (extrhd(ih2,1,ib) - extrhd(ih1,1,ib))
3136  sc03 = scarhd(ih1,1,ib) &
3137  & + rdrh * (scarhd(ih2,1,ib) - scarhd(ih1,1,ib))
3138  ss03 = ssarhd(ih1,1,ib) &
3139  & + rdrh * (ssarhd(ih2,1,ib) - ssarhd(ih1,1,ib))
3140  as03 = asyrhd(ih1,1,ib) &
3141  & + rdrh * (asyrhd(ih2,1,ib) - asyrhd(ih1,1,ib))
3142 
3143  ext1 = 0.17e-3*ex01 + 0.4*ex02 + 0.59983*ex03
3144  sca1 = 0.17e-3*sc01 + 0.4*sc02 + 0.59983*sc03
3145  ssa1 = 0.17e-3*ss01*ex01 + 0.4*ss02*ex02 + 0.59983*ss03*ex03
3146  asy1 = 0.17e-3*as01*sc01 + 0.4*as02*sc02 + 0.59983*as03*sc03
3147 
3148  tauae(kk,ib) = ext1 * 730.0 * delz(kk)
3149  ssaae(kk,ib) = min(f_one, ssa1/ext1)
3150  asyae(kk,ib) = min(f_one, asy1/sca1)
3151 
3152 ! --- compute aod from individual species' contribution (optional)
3153  if ( ib==nv_aod ) then
3154  spcodp(1) = spcodp(1) + 0.17e-3*ex01*730.0*delz(kk) ! dust (inso) #1
3155  spcodp(2) = spcodp(2) + 0.4 *ex02*730.0*delz(kk) ! black carbon #2
3156  spcodp(3) = spcodp(3) + 0.59983*ex03*730.0*delz(kk) ! water soluble #7
3157  endif
3158 
3159  enddo
3160 
3161  elseif (idom == 1) then lab_if_idom
3162 ! --- 1st domain - mixing layer
3163 
3164  lab_do_ib : do ib = 1, nswlwbd
3165  ext1 = f_zero
3166  sca1 = f_zero
3167  ssa1 = f_zero
3168  asy1 = f_zero
3169 
3170  lab_do_icmp : do icmp = 1, ncm
3171  ic = icmp
3172  idx = idxspc(icmp)
3173 
3174  cm = cmix(icmp)
3175  lab_if_cm : if ( cm > f_zero ) then
3176 
3177  lab_if_ic : if ( ic <= ncm1 ) then ! component withour rh dep
3178  tt0 = cm * extrhi(ic,ib)
3179  ext1 = ext1 + tt0
3180  sca1 = sca1 + cm * scarhi(ic,ib)
3181  ssa1 = ssa1 + cm * ssarhi(ic,ib) * extrhi(ic,ib)
3182  asy1 = asy1 + cm * asyrhi(ic,ib) * scarhi(ic,ib)
3183  else lab_if_ic ! component with rh dep
3184  ic1 = ic - ncm1
3185 
3186  ex00 = extrhd(ih1,ic1,ib) &
3187  & + rdrh * (extrhd(ih2,ic1,ib) - extrhd(ih1,ic1,ib))
3188  sc00 = scarhd(ih1,ic1,ib) &
3189  & + rdrh * (scarhd(ih2,ic1,ib) - scarhd(ih1,ic1,ib))
3190  ss00 = ssarhd(ih1,ic1,ib) &
3191  & + rdrh * (ssarhd(ih2,ic1,ib) - ssarhd(ih1,ic1,ib))
3192  as00 = asyrhd(ih1,ic1,ib) &
3193  & + rdrh * (asyrhd(ih2,ic1,ib) - asyrhd(ih1,ic1,ib))
3194 
3195  tt0 = cm * ex00
3196  ext1 = ext1 + tt0
3197  sca1 = sca1 + cm * sc00
3198  ssa1 = ssa1 + cm * ss00 * ex00
3199  asy1 = asy1 + cm * as00 * sc00
3200  endif lab_if_ic
3201 
3202 ! --- compute aod from individual species' contribution (optional)
3203  if ( ib==nv_aod ) then
3204  spcodp(idx) = spcodp(idx) + tt0*denn(1)*delz(kk) ! idx for dif species
3205  endif
3206 
3207  endif lab_if_cm
3208  enddo lab_do_icmp
3209 
3210  tauae(kk,ib) = ext1 * denn(1) * delz(kk)
3211  ssaae(kk,ib) = min(f_one, ssa1/ext1)
3212  asyae(kk,ib) = min(f_one, asy1/sca1)
3213  enddo lab_do_ib
3214 
3215  elseif (idom == 2) then lab_if_idom
3216 ! --- 2nd domain - mineral transport layers
3217 
3218  do ib = 1, nswlwbd
3219  tauae(kk,ib) = extrhi(6,ib) * denn(2) * delz(kk)
3220  ssaae(kk,ib) = ssarhi(6,ib)
3221  asyae(kk,ib) = asyrhi(6,ib)
3222  enddo
3223 
3224 ! --- compute aod from individual species' contribution (optional)
3225  spcodp(1) = spcodp(1) + tauae(kk,nv_aod) ! dust
3226 
3227  else lab_if_idom
3228 ! --- domain index out off range, assume no aerosol
3229 
3230  do ib = 1, nswlwbd
3231  tauae(kk,ib) = f_zero
3232  ssaae(kk,ib) = f_one
3233  asyae(kk,ib) = f_zero
3234  enddo
3235 
3236 ! write(6,19) kk,idom
3237 ! 19 format(/' *** ERROR in sub AEROS: domain index out' &
3238 ! &, ' of range! K, IDOM =',3i5,' ***')
3239 ! stop 19
3240 
3241  endif lab_if_idom
3242 
3243  enddo lab_do_layer
3244 
3245 !
3246 !===> ... smooth profile at domain boundaries
3247 !
3248  if ( ivflip == 0 ) then ! input from toa to sfc
3249 
3250  do ib = 1, nswlwbd
3251  do kk = 2, nlay
3252  if ( tauae(kk,ib) > f_zero ) then
3253  ratio = tauae(kk-1,ib) / tauae(kk,ib)
3254  else
3255  ratio = f_one
3256  endif
3257 
3258  tt0 = tauae(kk,ib) + tauae(kk-1,ib)
3259  tt1 = 0.2 * tt0
3260  tt2 = tt0 - tt1
3261 
3262  if ( ratio > crt1 ) then
3263  tauae(kk,ib) = tt1
3264  tauae(kk-1,ib) = tt2
3265  endif
3266 
3267  if ( ratio < crt2 ) then
3268  tauae(kk,ib) = tt2
3269  tauae(kk-1,ib) = tt1
3270  endif
3271  enddo ! do_kk_loop
3272  enddo ! do_ib_loop
3273 
3274  else ! input from sfc to toa
3275 
3276  do ib = 1, nswlwbd
3277  do kk = nlay-1, 1, -1
3278  if ( tauae(kk,ib) > f_zero ) then
3279  ratio = tauae(kk+1,ib) / tauae(kk,ib)
3280  else
3281  ratio = f_one
3282  endif
3283 
3284  tt0 = tauae(kk,ib) + tauae(kk+1,ib)
3285  tt1 = 0.2 * tt0
3286  tt2 = tt0 - tt1
3287 
3288  if ( ratio > crt1 ) then
3289  tauae(kk,ib) = tt1
3290  tauae(kk+1,ib) = tt2
3291  endif
3292 
3293  if ( ratio < crt2 ) then
3294  tauae(kk,ib) = tt2
3295  tauae(kk+1,ib) = tt1
3296  endif
3297  enddo ! do_kk_loop
3298  enddo ! do_ib_loop
3299 
3300  endif
3301 
3302 !
3303  return
3304 !................................
3305  end subroutine radclimaer
3306 !--------------------------------
3307 !
3308 !...................................
3309  end subroutine aer_property
3310 !-----------------------------------
3311 
3312 ! =======================================================================
3313 ! GOCART code modification starts here (Sarah lu) ---------------------!
3314 !!
3315 !! gocart_init : set_aerspc, rd_gocart_clim, rd_gocart_luts, optavg_grt
3316 !! setgocartaer: aeropt_grt, map_aermr
3317 
3322 
3323 !-----------------------------------
3324  subroutine gocart_init &
3325 !...................................
3326 ! --- inputs:
3327  & ( nwvtot,solfwv,soltot,nwvtir,eirfwv, &
3328  & nbdsw,nlwbnd,nswlwbd,imon,me,raddt,fdaer &
3329 ! --- outputs: ( none )
3330  & )
3331 
3332 ! ================================================================== !
3333 ! !
3334 ! subprogram : gocart_init !
3335 ! !
3336 ! this is the initialization program for gocart aerosols !
3337 ! !
3338 ! - determine weight and index for aerosol composition/luts !
3339 ! - read in monthly global distribution of gocart aerosols !
3340 ! - read and map the tabulated aerosol optical spectral data !
3341 ! onto corresponding sw/lw radiation spectral bands. !
3342 ! !
3343 ! ==================== defination of variables =================== !
3344 ! !
3345 ! inputs: !
3346 ! NWVTOT - total num of wave numbers used in sw spectrum !
3347 ! solfwv(NWVTOT) - solar flux for each individual wavenumber (w/m2)!
3348 ! soltot - total solar flux for the spectrual range (w/m2)!
3349 ! NWVTIR - total num of wave numbers used in the ir region !
3350 ! eirfwv(NWVTIR) - ir flux(273k) for each individual wavenum (w/m2)!
3351 ! NBDSW - num of bands calculated for sw aeros opt prop !
3352 ! NLWBND - num of bands calculated for lw aeros opt prop !
3353 ! NSWLWBD - total num of bands calc for sw+lw aeros opt prop!
3354 ! imon - month of the year !
3355 ! me - print message control flag !
3356 ! !
3357 ! outputs: (to the module variables) !
3358 ! !
3359 ! module variables: !
3360 ! NBDSW - total number of sw spectral bands !
3361 ! wvnum1,wvnum2 (NSWSTR:NSWEND) !
3362 ! - start/end wavenumbers for each of sw bands !
3363 ! NBDLW - total number of lw spectral bands !
3364 ! wvnlw1,wvnlw2 (NBDLW) !
3365 ! - start/end wavenumbers for each of lw bands !
3366 ! NSWLWBD - total number of sw+lw bands used in this version !
3367 ! extrhi_grt - extinction coef for rh-indep aeros KCM1*NSWLWBD !
3368 ! ssarhi_grt - single-scat-alb for rh-indep aeros KCM1*NSWLWBD !
3369 ! asyrhi_grt - asymmetry factor for rh-indep aeros KCM1*NSWLWBD !
3370 ! extrhd_grt - extinction coef for rh-dep aeros KRHLEV*KCM2*NSWLWBD!
3371 ! ssarhd_grt - single-scat-alb for rh-dep aeros KRHLEV*KCM2*NSWLWBD!
3372 ! asyrhd_grt - asymmetry factor for rh-dep aerosKRHLEV*KCM2*NSWLWBD!
3373 ! ctaer - merging coefficients for fcst/clim fields !
3374 ! get_fcst - option to get fcst aerosol fields !
3375 ! get_clim - option to get clim aerosol fields !
3376 ! dm_indx - index for aer spec to be included in aeropt calculations !
3377 ! dmfcs_indx - index for prognostic aerosol fields !
3378 ! psclmg - geos3/4-gocart pressure IMXG*JMXG*KMXG !
3379 ! dmclmg - geos3-gocart aerosol dry mass IMXG*JMXG*KMXG*NMXG!
3380 ! or geos4-gocart aerosol mixing ratio !
3381 ! !
3382 ! usage: call gocart_init !
3383 ! !
3384 ! subprograms called: set_aerspc, rd_gocart_clim, !
3385 ! rd_gocart_luts, optavg_grt !
3386 ! !
3387 ! ================================================================== !
3388 
3389  implicit none
3390 
3391 ! --- inputs:
3392  integer, intent(in) :: NWVTOT,NWVTIR,NBDSW,NLWBND,NSWLWBD,imon,me
3393 
3394  real (kind=kind_phys), intent(in) :: raddt, fdaer
3395 
3396  real (kind=kind_phys), intent(in) :: solfwv(:),soltot, eirfwv(:)
3397 
3398 ! --- output: ( none )
3399 
3400 ! --- locals:
3401 
3402  real (kind=kind_phys), dimension(NBDSW,KAERBND) :: solwaer
3403  real (kind=kind_phys), dimension(NBDSW) :: solbnd
3404  real (kind=kind_phys), dimension(NLWBND,KAERBND) :: eirwaer
3405  real (kind=kind_phys), dimension(NLWBND) :: eirbnd
3406  real (kind=kind_phys) :: sumsol, sumir
3407 
3408  integer, dimension(NBDSW) :: nv1, nv2
3409  integer, dimension(NLWBND) :: nr1, nr2
3410 
3411  integer :: i, mb, ib, ii, iw, iw1, iw2
3412 
3413 !===> ... begin here
3414 
3415 !--------------------------------------------------------------------------
3416 ! (1) determine aerosol specification index and merging coefficients
3417 !--------------------------------------------------------------------------
3418 
3419  if ( .not. lgrtint ) then
3420 
3421 ! --- ... already done aerspc initialization, continue
3422 
3423  continue
3424 
3425  else
3426 
3427 ! --- ... set aerosol specification index and merging coefficients
3428 
3429  call set_aerspc(raddt,fdaer)
3430 ! --- inputs: (in scope variables)
3431 ! --- outputs: (in scope variables)
3432 
3433  endif ! end if_lgrtinit_block
3434 
3435 !
3436 !--------------------------------------------------------------------------
3437 ! (2) read gocart climatological data
3438 !--------------------------------------------------------------------------
3439 
3440 ! --- ... read gocart climatological data, if needed
3441 
3442  if ( get_clim ) then
3443 
3444  call rd_gocart_clim
3445 ! --- inputs: (in scope variables)
3446 ! --- outputs: (in scope variables)
3447 
3448  endif
3449 
3450 !
3451 !--------------------------------------------------------------------------
3452 ! (3) read and map the tabulated aerosol optical spectral data
3453 ! onto corresponding radiation spectral bands
3454 !--------------------------------------------------------------------------
3455 
3456  if ( .not. lgrtint ) then
3457 
3458 ! --- ... already done optical property interpolation, exit
3459 
3460  return
3461 
3462  else
3463 
3464 ! --- ... reset lgrtint
3465 
3466  lgrtint = .false.
3467 
3468 ! --- ... read tabulated aerosol optical input data
3469  call rd_gocart_luts
3470 ! --- inputs: (in scope variables)
3471 ! --- outputs: (in scope variables)
3472 
3473 ! --- ... compute solar flux weights and interval indices for mapping
3474 ! spectral bands between sw radiation and aerosol data
3475 
3476  solbnd(:) = f_zero
3477  solwaer(:,:) = f_zero
3478 
3479  nv_aod = 1
3480 
3481  do ib = 1, nbdsw
3482  mb = ib + nswstr - 1
3483  ii = 1
3484  iw1 = nint(wvnsw1(mb))
3485  iw2 = nint(wvnsw2(mb))
3486 !
3487 ! --- locate the spectral band for 550nm (for aod diag)
3488 !
3489  if (10000./iw1 >= 0.55 .and. &
3490  & 10000./iw2 <= 0.55 ) then
3491  nv_aod = ib
3492  endif
3493 
3494  lab_swdowhile : do while ( iw1 > iendwv_grt(ii) )
3495  if ( ii == kaerbnd ) exit lab_swdowhile
3496  ii = ii + 1
3497  enddo lab_swdowhile
3498 
3499  sumsol = f_zero
3500  nv1(ib) = ii
3501 
3502  do iw = iw1, iw2
3503  solbnd(ib) = solbnd(ib) + solfwv(iw)
3504  sumsol = sumsol + solfwv(iw)
3505 
3506  if ( iw == iendwv_grt(ii) ) then
3507  solwaer(ib,ii) = sumsol
3508 
3509  if ( ii < kaerbnd ) then
3510  sumsol = f_zero
3511  ii = ii + 1
3512  endif
3513  endif
3514  enddo
3515 
3516  if ( iw2 /= iendwv_grt(ii) ) then
3517  solwaer(ib,ii) = sumsol
3518  endif
3519 
3520  nv2(ib) = ii
3521 
3522  if((me==0) .and. lckprnt) print *,'RAD-nv1,nv2:', &
3523  & ib,iw1,iw2,nv1(ib),iendwv_grt(nv1(ib)), &
3524  & nv2(ib),iendwv_grt(nv2(ib)), &
3525  & 10000./iw1, 10000./iw2
3526  enddo ! end do_ib_block for sw
3527 
3528 ! --- check the spectral range for the nv_550 band
3529  if((me==0) .and. lckprnt) then
3530  mb = nv_aod + nswstr - 1
3531  iw1 = nint(wvnsw1(mb))
3532  iw2 = nint(wvnsw2(mb))
3533  print *,'RAD-nv_aod:', &
3534  & nv_aod, iw1, iw2, 10000./iw1, 10000./iw2
3535  endif
3536 !
3537 ! --- ... compute ir flux weights and interval indices for mapping
3538 ! spectral bands between lw radiation and aerosol data
3539 
3540  eirbnd(:) = f_zero
3541  eirwaer(:,:) = f_zero
3542 
3543  do ib = 1, nlwbnd
3544  ii = 1
3545  if ( nlwbnd == 1 ) then
3546  iw1 = 400 ! corresponding 25 mu
3547  iw2 = 2500 ! corresponding 4 mu
3548  else
3549  iw1 = nint(wvnlw1(ib))
3550  iw2 = nint(wvnlw2(ib))
3551  endif
3552 
3553  lab_lwdowhile : do while ( iw1 > iendwv_grt(ii) )
3554  if ( ii == kaerbnd ) exit lab_lwdowhile
3555  ii = ii + 1
3556  enddo lab_lwdowhile
3557 
3558  sumir = f_zero
3559  nr1(ib) = ii
3560 
3561  do iw = iw1, iw2
3562  eirbnd(ib) = eirbnd(ib) + eirfwv(iw)
3563  sumir = sumir + eirfwv(iw)
3564 
3565  if ( iw == iendwv_grt(ii) ) then
3566  eirwaer(ib,ii) = sumir
3567 
3568  if ( ii < kaerbnd ) then
3569  sumir = f_zero
3570  ii = ii + 1
3571  endif
3572  endif
3573  enddo
3574 
3575  if ( iw2 /= iendwv_grt(ii) ) then
3576  eirwaer(ib,ii) = sumir
3577  endif
3578 
3579  nr2(ib) = ii
3580 
3581  if(me==0 .and. lckprnt) print *,'RAD-nr1,nr2:', &
3582  & ib,iw1,iw2,nr1(ib),iendwv_grt(nr1(ib)), &
3583  & nr2(ib),iendwv_grt(nr2(ib)), &
3584  & 10000./iw1, 10000./iw2
3585  enddo ! end do_ib_block for lw
3586 
3587 ! --- compute spectral band mean properties for each species
3588 
3589  call optavg_grt
3590 ! --- inputs: (in scope variables)
3591 ! --- outputs: (in scope variables)
3592 
3593  if(me==0 .and. lckprnt) then
3594  print *, 'RAD -After optavg_grt, sw band info'
3595  do ib = 1, nbdsw
3596  mb = ib + nswstr - 1
3597  print *,'RAD -wvnsw1,wvnsw2: ',ib,wvnsw1(mb),wvnsw2(mb)
3598  print *,'RAD -lamda1,lamda2: ',ib,10000./wvnsw1(mb), &
3599  & 10000./wvnsw2(mb)
3600  print *,'RAD -extrhi_grt:', extrhi_grt(:,ib)
3601 ! do i = 1, KRHLEV
3602  do i = 1, krhlev, 10
3603  print *, 'RAD -extrhd_grt:',i,rhlev_grt(i), &
3604  & extrhd_grt(i,:,ib)
3605  enddo
3606  enddo
3607  print *, 'RAD -After optavg_grt, lw band info'
3608  do ib = 1, nlwbnd
3609  ii = nbdsw + ib
3610  print *,'RAD -wvnlw1,wvnlw2: ',ib,wvnlw1(ib),wvnlw2(ib)
3611  print *,'RAD -lamda1,lamda2: ',ib,10000./wvnlw1(ib), &
3612  & 10000./wvnlw2(ib)
3613  print *,'RAD -extrhi_grt:', extrhi_grt(:,ii)
3614 ! do i = 1, KRHLEV
3615  do i = 1, krhlev, 10
3616  print *, 'RAD -extrhd_grt:',i,rhlev_grt(i), &
3617  & extrhd_grt(i,:,ii)
3618  enddo
3619  enddo
3620  endif
3621 
3622 ! --- ... dealoocate input data arrays no longer needed
3623  deallocate ( iendwv_grt )
3624  if ( allocated(rhidext0_grt) ) then
3625  deallocate ( rhidext0_grt )
3626  deallocate ( rhidssa0_grt )
3627  deallocate ( rhidasy0_grt )
3628  endif
3629  if ( allocated(rhdpext0_grt) ) then
3630  deallocate ( rhdpext0_grt )
3631  deallocate ( rhdpssa0_grt )
3632  deallocate ( rhdpasy0_grt )
3633  endif
3634 
3635  endif ! end if_lgrtinit_block
3636 
3637 ! =================
3638  contains
3639 ! =================
3641 !-----------------------------
3642  subroutine set_aerspc(raddt,fdaer)
3643 !.............................
3644 ! --- inputs: (in scope variables)
3645 ! --- outputs: (in scope variables)
3646 
3647 ! ==================================================================== !
3648 ! !
3649 ! subprogram: set_aerspc !
3650 ! !
3651 ! determine merging coefficients ctaer; !
3652 ! set up aerosol specification: num_gridcomp, gridcomp, dm_indx, !
3653 ! dmfcs_indx, isoot, iwaso, isuso, issam, isscm !
3654 ! !
3655 ! Aerosol optical properties (ext, ssa, asy) are determined from !
3656 ! NMGX (<=12) aerosol species !
3657 ! ==> DU: dust1 (4 sub-micron bins), dust2, dust3, dust4, dust5 !
3658 ! BC: soot_phobic, soot_philic !
3659 ! OC: waso_phobic, waso_philic !
3660 ! SU: suso (=so4) !
3661 ! SS: ssam (accumulation mode), sscm (coarse mode) !
3662 ! !
3663 ! The current version only supports prognostic aerosols (from GOCART !
3664 ! in-line calculations) and climo aerosols (from GEOS-GOCART runs) !
3665 ! !
3666 ! ================================================================== !
3667 !
3668  implicit none
3669 
3670 ! --- inputs:
3671  real (kind=kind_phys), intent(in) :: raddt, fdaer
3672 ! --- output:
3673 
3674 ! --- local:
3675 ! real (kind=kind_phys) :: raddt
3676  integer :: i, indxr
3677  character*2 :: tp, gridcomp_tmp(max_num_gridcomp)
3678 
3679 !! ===> determine ctaer (user specified weight for fcst fields)
3680 ! raddt = min(fhswr,fhlwr) / 24.
3681  if( fdaer >= 99999. ) ctaer = f_one
3682  if((fdaer>0.).and.(fdaer<99999.)) ctaer=exp(-raddt/fdaer)
3683 
3684  if(me==0 .and. lckprnt) then
3685  print *, 'RAD -raddt, fdaer,ctaer: ', raddt, fdaer, ctaer
3686  if (ctaer == f_one ) then
3687  print *, 'LU -aerosol fields determined from fcst'
3688  elseif (ctaer == f_zero) then
3689  print *, 'LU -aerosol fields determined from clim'
3690  else
3691  print *, 'LU -aerosol fields determined from fcst/clim'
3692  endif
3693  endif
3694 
3695 !! ===> determine get_fcst and get_clim
3696 !! if fcst is chosen (ctaer == f_one ), set get_clim to F
3697 !! if clim is chosen (ctaer == f_zero), set get_fcst to F
3698  if ( ctaer == f_one ) get_clim = .false.
3699  if ( ctaer == f_zero ) get_fcst = .false.
3700 
3701 !! ===> determine aerosol species to be included in the calculations
3702 !! of aerosol optical properties (ext, ssa, asy)
3703 
3704 !* If climo option is chosen, the aerosol composition is hardwired
3705 !* to full package. If not, the composition is determined from
3706 !* tracer_config on-the-fly (full package or subset)
3707  lab_if_fcst : if ( get_fcst ) then
3708 
3709 !! use tracer_config to determine num_gridcomp and gridcomp
3710  if ( gfs_phy_tracer%doing_GOCART ) then
3711  if ( gfs_phy_tracer%doing_DU ) then
3713  gridcomp_tmp(num_gridcomp) = 'DU'
3714  endif
3715  if ( gfs_phy_tracer%doing_SU ) then
3717  gridcomp_tmp(num_gridcomp) = 'SU'
3718  endif
3719  if ( gfs_phy_tracer%doing_SS ) then
3721  gridcomp_tmp(num_gridcomp) = 'SS'
3722  endif
3723  if ( gfs_phy_tracer%doing_OC ) then
3725  gridcomp_tmp(num_gridcomp) = 'OC'
3726  endif
3727  if ( gfs_phy_tracer%doing_BC ) then
3729  gridcomp_tmp(num_gridcomp) = 'BC'
3730  endif
3731 !
3732  if ( num_gridcomp > 0 ) then
3733  allocate ( gridcomp(num_gridcomp) )
3734  gridcomp(1:num_gridcomp) = gridcomp_tmp(1:num_gridcomp)
3735  else
3736  print *,'ERROR: prognostic aerosols not found,abort',me
3737  stop 1000
3738  endif
3739 
3740  else ! gfs_phy_tracer%doing_GOCART=F
3741 
3742  print *,'ERROR: prognostic aerosols option off, abort',me
3743  stop 1001
3744 
3745  endif ! end_if_gfs_phy_tracer%doing_GOCART_if_
3746 
3747  else lab_if_fcst
3748 
3749 !! set to full package (max_num_gridcomp and max_gridcomp)
3751  allocate ( gridcomp(num_gridcomp) )
3753 
3754  endif lab_if_fcst
3755 
3756 !!
3757 !! Aerosol specification is determined as such:
3758 !! A. For radiation-aerosol feedback, the specification is based on the aeropt
3759 !! routine from Mian Chin and Hongbin Yu (hydrophobic and hydrophilic for
3760 !! OC/BC; submicron and supermicron for SS, 8-bins (with 4 subgroups for the
3761 !! the submicron bin) for DU, and SO4 for SU)
3762 !! B. For transport, the specification is determined from GOCART in-line module
3763 !! C. For LUTS, (waso, soot, ssam, sscm, suso, dust) is used, based on the
3764 !! the OPAC climo aerosol scheme (implemented by Yu-Tai Hou)
3765 
3766 !!=== <A> determine dm_indx and NMXG
3767  indxr = 0
3768  dm_indx%waso_phobic = -999 ! OC
3769  dm_indx%soot_phobic = -999 ! BC
3770  dm_indx%ssam = -999 ! SS
3771  dm_indx%suso = -999 ! SU
3772  dm_indx%dust1 = -999 ! DU
3773  do i = 1, num_gridcomp
3774  tp = gridcomp(i)
3775  select case ( tp )
3776  case ( 'OC') ! consider hydrophobic and hydrophilic
3777  dm_indx%waso_phobic = indxr + 1
3778  dm_indx%waso_philic = indxr + 2
3779  indxr = indxr + 2
3780  case ( 'BC') ! consider hydrophobic and hydrophilic
3781  dm_indx%soot_phobic = indxr + 1
3782  dm_indx%soot_philic = indxr + 2
3783  indxr = indxr + 2
3784  case ( 'SS') ! consider submicron and supermicron
3785  dm_indx%ssam = indxr + 1
3786  dm_indx%sscm = indxr + 2
3787  indxr = indxr + 2
3788  case ( 'SU') ! consider SO4 only
3789  dm_indx%suso = indxr + 1
3790  indxr = indxr + 1
3791  case ( 'DU') ! consider all 5 bins
3792  dm_indx%dust1 = indxr + 1
3793  dm_indx%dust2 = indxr + 2
3794  dm_indx%dust3 = indxr + 3
3795  dm_indx%dust4 = indxr + 4
3796  dm_indx%dust5 = indxr + 5
3797  indxr = indxr + 5
3798  case default
3799  print *,'ERROR: aerosol species not supported, abort',me
3800  stop 1002
3801  end select
3802  enddo
3803 !!
3804  nmxg = indxr ! num of gocart aer spec for opt cal
3805 !!
3806 
3807 !!=== <B> determine dmfcs_indx
3808 !! SS: 5-bins are considered for transport while only two groups
3809 !! (accumulation/coarse modes) are considered for radiation
3810 !! DU: 5-bins are considered for transport while 8 bins (with the
3811 !! submicorn bin exptended to 4 bins) are considered for radiation
3812 !! SU: DMS, SO2, and MSA are not considered for radiation
3813 
3814  if ( get_fcst ) then
3815  if ( gfs_phy_tracer%doing_OC ) then
3816  dmfcs_indx%ocphobic = trcindx('ocphobic', gfs_phy_tracer)
3817  dmfcs_indx%ocphilic = trcindx('ocphilic', gfs_phy_tracer)
3818  endif
3819  if ( gfs_phy_tracer%doing_BC ) then
3820  dmfcs_indx%bcphobic = trcindx('bcphobic', gfs_phy_tracer)
3821  dmfcs_indx%bcphilic = trcindx('bcphilic', gfs_phy_tracer)
3822  endif
3823  if ( gfs_phy_tracer%doing_SS ) then
3824  dmfcs_indx%ss001 = trcindx('ss001', gfs_phy_tracer)
3825  dmfcs_indx%ss002 = trcindx('ss002', gfs_phy_tracer)
3826  dmfcs_indx%ss003 = trcindx('ss003', gfs_phy_tracer)
3827  dmfcs_indx%ss004 = trcindx('ss004', gfs_phy_tracer)
3828  dmfcs_indx%ss005 = trcindx('ss005', gfs_phy_tracer)
3829  endif
3830  if ( gfs_phy_tracer%doing_SU ) then
3831  dmfcs_indx%so4 = trcindx('so4', gfs_phy_tracer)
3832  endif
3833  if ( gfs_phy_tracer%doing_DU ) then
3834  dmfcs_indx%du001 = trcindx('du001', gfs_phy_tracer)
3835  dmfcs_indx%du002 = trcindx('du002', gfs_phy_tracer)
3836  dmfcs_indx%du003 = trcindx('du003', gfs_phy_tracer)
3837  dmfcs_indx%du004 = trcindx('du004', gfs_phy_tracer)
3838  dmfcs_indx%du005 = trcindx('du005', gfs_phy_tracer)
3839  endif
3840  endif
3841 
3842 !!
3843 !!=== <C> determin KCM, KCM1, KCM2
3844 !! DU: submicron bin (dust1) contains 4 sub-groups (e.g., hardwire
3845 !! 8 bins for aerosol optical properties luts)
3846 !! OC/BC: while hydrophobic aerosols are rh-independent, the luts
3847 !! for hydrophilic aerosols are used (e.g., use the coeff
3848 !! corresponding to rh=0)
3849 !!
3850  indxr = 1
3851  isoot = -999
3852  iwaso = -999
3853  isuso = -999
3854  issam = -999
3855  isscm = -999
3856  do i = 1, num_gridcomp
3857  tp = gridcomp(i)
3858  if ( tp /= 'DU' ) then
3859  select case ( tp )
3860  case ( 'OC ')
3861  iwaso = indxr
3862  case ( 'BC ')
3863  isoot = indxr
3864  case ( 'SU ')
3865  isuso = indxr
3866  case ( 'SS ')
3867  issam = indxr
3868  isscm = indxr + 1
3869  end select
3870  if ( tp /= 'SS' ) then
3871  indxr = indxr + 1
3872  else
3873  indxr = indxr + 2
3874  endif
3875  else
3876  kcm1 = 8 ! num of rh independent aer species
3877  endif
3878  enddo
3879  kcm2 = indxr - 1 ! num of rh dependent aer species
3880  kcm = kcm1 + kcm2 ! total num of aer species
3881 
3882 !!
3883 !! check print starts here
3884  if( me == 0 .and. lckprnt) then
3885  print *, 'RAD -num_gridcomp:', num_gridcomp
3886  print *, 'RAD -gridcomp :', gridcomp(:)
3887  print *, 'RAD -NMXG:', nmxg
3888  print *, 'RAD -dm_indx ===> '
3889  print *, 'RAD -aerspc: dust1=', dm_indx%dust1
3890  print *, 'RAD -aerspc: dust2=', dm_indx%dust2
3891  print *, 'RAD -aerspc: dust3=', dm_indx%dust3
3892  print *, 'RAD -aerspc: dust4=', dm_indx%dust4
3893  print *, 'RAD -aerspc: dust5=', dm_indx%dust5
3894  print *, 'RAD -aerspc: ssam=', dm_indx%ssam
3895  print *, 'RAD -aerspc: sscm=', dm_indx%sscm
3896  print *, 'RAD -aerspc: suso=', dm_indx%suso
3897  print *, 'RAD -aerspc: waso_phobic=',dm_indx%waso_phobic
3898  print *, 'RAD -aerspc: waso_philic=',dm_indx%waso_philic
3899  print *, 'RAD -aerspc: soot_phobic=',dm_indx%soot_phobic
3900  print *, 'RAD -aerspc: soot_philic=',dm_indx%soot_philic
3901 
3902  print *, 'RAD -KCM1 =', kcm1
3903  print *, 'RAD -KCM2 =', kcm2
3904  print *, 'RAD -KCM =', kcm
3905  if ( kcm2 > 0 ) then
3906  print *, 'RAD -aerspc: issam=', issam
3907  print *, 'RAD -aerspc: isscm=', isscm
3908  print *, 'RAD -aerspc: isuso=', isuso
3909  print *, 'RAD -aerspc: iwaso=', iwaso
3910  print *, 'RAD -aerspc: isoot=', isoot
3911  endif
3912 
3913  if ( get_fcst ) then
3914  print *, 'RAD -dmfcs_indx ===> '
3915  print *, 'RAD -trc_du001=',dmfcs_indx%du001
3916  print *, 'RAD -trc_du002=',dmfcs_indx%du002
3917  print *, 'RAD -trc_du003=',dmfcs_indx%du003
3918  print *, 'RAD -trc_du004=',dmfcs_indx%du004
3919  print *, 'RAD -trc_du005=',dmfcs_indx%du005
3920  print *, 'RAD -trc_so4 =',dmfcs_indx%so4
3921  print *, 'RAD -trc_ocphobic=',dmfcs_indx%ocphobic
3922  print *, 'RAD -trc_ocphilic=',dmfcs_indx%ocphilic
3923  print *, 'RAD -trc_bcphobic=',dmfcs_indx%bcphobic
3924  print *, 'RAD -trc_bcphilic=',dmfcs_indx%bcphilic
3925  print *, 'RAD -trc_ss001=',dmfcs_indx%ss001
3926  print *, 'RAD -trc_ss002=',dmfcs_indx%ss002
3927  print *, 'RAD -trc_ss003=',dmfcs_indx%ss003
3928  print *, 'RAD -trc_ss004=',dmfcs_indx%ss004
3929  print *, 'RAD -trc_ss005=',dmfcs_indx%ss005
3930  endif
3931  endif
3932 !! check print ends here
3933 
3934  return
3935 ! !
3936  end subroutine set_aerspc
3937 
3938 !-----------------------------------
3940 !-----------------------------
3941  subroutine rd_gocart_luts
3942 !.............................
3943 ! --- inputs: (in scope variables)
3944 ! --- outputs: (in scope variables)
3945 
3946 ! ==================================================================== !
3947 ! subprogram: rd_gocart_luts !
3948 ! read input gocart aerosol optical data from Mie code calculations !
3949 ! !
3950 ! Remarks (Quanhua (Mark) Liu, JCSDA, June 2008) !
3951 ! The LUT is for NCEP selected 61 wave numbers and 6 aerosols !
3952 ! (dust, soot, suso, waso, ssam, and sscm) and 36 aerosol effective !
3953 ! size in microns. !
3954 ! !
3955 ! The LUT is computed using Mie code with a logorithm size !
3956 ! distribution for each of 36 effective sizes. The standard deviation !
3957 ! sigma of the size, and min/max size follows Chin et al. 2000 !
3958 ! For each effective size, it corresponds a relative humidity value. !
3959 ! !
3960 ! The LUT contains the density, sigma, relative humidity, mean mode !
3961 ! radius, effective size, mass extinction coefficient, single !
3962 ! scattering albedo, asymmetry factor, and phase function !
3963 ! !
3964 ! ================================================================== !
3965 !
3966  implicit none
3967 
3968 ! --- inputs:
3969 ! --- output:
3970 
3971 ! --- locals:
3972  INTEGER, PARAMETER :: NP = 100, np2 = 2*np, nwave=100, &
3973  & naero=6, n_p=36
3974  INTEGER :: NW, NS, nH, n_bin
3975  real (kind=kind_io8), Dimension( NP2 ) :: Angle, Cos_Angle, &
3976  & Cos_Weight
3977  real (kind=kind_io8), Dimension(n_p,nAero) :: RH, rm, reff
3978  real (kind=kind_io8), Dimension(nWave,n_p,nAero) :: &
3979  & ext0, sca0, asy0
3980  real (kind=kind_io8), Dimension(NP2,n_p,nWave,nAero) :: ph0
3981  real (kind=kind_io8) :: wavelength(nwave), density(naero), &
3982  & sigma(nAero), wave,n_fac,PI,t1,s1,g1
3983  CHARACTER(len=80) :: AerosolName(naero)
3984  INTEGER :: i, j, k, l, ij
3985 
3986  character :: aerosol_file*30
3987  logical :: file_exist
3988  integer :: indx_dust(8) ! map 36 dust bins to gocart size bins
3989 
3990  data aerosol_file /"NCEP_AEROSOL.bin"/
3991  data aerosolname/ ' Dust ', ' Soot ', ' SUSO ', ' WASO ', &
3992  & ' SSAM ', ' SSCM '/
3993 
3994 !! 8 dust bins
3995 !! 1 2 3 4 5 6 7 8
3996 !! .1-.18, .18-.3, .3-.6, 0.6-1.0, 1.0-1.8, 1.8-3, 3-6, 6-10 <-- def
3997 !! 0.1399 0.2399 0.4499 0.8000 1.3994 2.3964 4.4964 7.9887 <-- reff
3998  data indx_dust/4, 8, 12, 18, 21, 24, 30, 36/
3999 
4000  pi = acos(-1.d0)
4001 
4002 ! -- allocate aerosol optical data
4003  if ( .not. allocated( iendwv_grt ) ) then
4004  allocate ( iendwv_grt(kaerbnd) )
4005  endif
4006  if (.not. allocated(rhidext0_grt) .and. kcm1 > 0 ) then
4007  allocate ( rhidext0_grt(kaerbnd,kcm1))
4008  allocate ( rhidssa0_grt(kaerbnd,kcm1))
4009  allocate ( rhidasy0_grt(kaerbnd,kcm1))
4010  endif
4011  if (.not. allocated(rhdpext0_grt) .and. kcm2 > 0 ) then
4012  allocate ( rhdpext0_grt(kaerbnd,krhlev,kcm2))
4013  allocate ( rhdpssa0_grt(kaerbnd,krhlev,kcm2))
4014  allocate ( rhdpasy0_grt(kaerbnd,krhlev,kcm2))
4015  endif
4016 
4017 ! -- read luts
4018  inquire (file = aerosol_file, exist = file_exist)
4019 
4020  if ( file_exist ) then
4021  if(me==0 .and. lckprnt) print *,'RAD -open :',aerosol_file
4022  close (niaercm)
4023  open (unit=niaercm,file=aerosol_file,status='OLD', &
4024  & form='UNFORMATTED')
4025  else
4026  print *,' Requested aerosol data file "',aerosol_file, &
4027  & '" not found!', me
4028  print *,' *** Stopped in subroutine RD_GOCART_LUTS !!'
4029  stop 1003
4030  endif ! end if_file_exist_block
4031 
4032  READ(niaercm) (cos_angle(i),i=1,np)
4033  READ(niaercm) (cos_weight(i),i=1,np)
4034  READ(niaercm)
4035  READ(niaercm)
4036  READ(niaercm) nw,ns
4037  READ(niaercm)
4038  READ(niaercm) (wavelength(i),i=1,nw)
4039 
4040 ! --- check nAero and NW
4041  if (nw /= kaerbnd) then
4042  print *, "Incorrect spectral band, abort ", nw
4043  stop 1004
4044  endif
4045 
4046 ! --- convert wavelength to wavenumber
4047  do i = 1, kaerbnd
4048  iendwv_grt(i) = 10000. / wavelength(i)
4049  if(me==0 .and. lckprnt) print *,'RAD -wn,lamda:', &
4050  & i,iendwv_grt(i),wavelength(i)
4051  enddo
4052 
4053  DO j = 1, naero
4054  if(me==0 .and. lckprnt) print *,'RAD -read LUTs:', &
4055  & j,aerosolname(j)
4056  READ(niaercm)
4057  READ(niaercm)
4058  READ(niaercm) n_bin, density(j), sigma(j)
4059  READ(niaercm)
4060  READ(niaercm) (rh(i,j),i=1, n_bin)
4061  READ(niaercm)
4062  READ(niaercm) (rm(i,j),i=1, n_bin)
4063  READ(niaercm)
4064  READ(niaercm) (reff(i,j),i=1, n_bin)
4065 
4066 ! --- check n_bin
4067  if (n_bin /= krhlev ) then
4068  print *, "Incorrect rh levels, abort ", n_bin
4069  stop 1005
4070  endif
4071 
4072 ! --- read luts
4073  DO k = 1, nw
4074  READ(niaercm) wave,(ext0(k,l,j),l=1,n_bin)
4075  READ(niaercm) (sca0(k,l,j),l=1,n_bin)
4076  READ(niaercm) (asy0(k,l,j),l=1,n_bin)
4077  READ(niaercm) (ph0(1:np2,l,k,j),l=1,n_bin)
4078  END DO
4079 
4080 ! --- map luts input to module variables
4081  if (aerosolname(j) == ' Dust ' ) then
4082  if ( kcm1 > 0) then
4083  do i = 1, kcm1
4084  rhidext0_grt(1:kaerbnd,i)=ext0(1:kaerbnd,indx_dust(i),j)
4085  rhidssa0_grt(1:kaerbnd,i)=sca0(1:kaerbnd,indx_dust(i),j)
4086  rhidasy0_grt(1:kaerbnd,i)=asy0(1:kaerbnd,indx_dust(i),j)
4087  enddo
4088  endif
4089  else
4090  if ( kcm2 > 0) then
4091  if (aerosolname(j) == ' Soot ') ij = isoot
4092  if (aerosolname(j) == ' SUSO ') ij = isuso
4093  if (aerosolname(j) == ' WASO ') ij = iwaso
4094  if (aerosolname(j) == ' SSAM ') ij = issam
4095  if (aerosolname(j) == ' SSCM ') ij = isscm
4096  if ( ij .ne. -999 ) then
4097  rhdpext0_grt(1:kaerbnd,1:krhlev,ij) = &
4098  & ext0(1:kaerbnd,1:krhlev,j)
4099  rhdpssa0_grt(1:kaerbnd,1:krhlev,ij) = &
4100  & sca0(1:kaerbnd,1:krhlev,j)
4101  rhdpasy0_grt(1:kaerbnd,1:krhlev,ij) = &
4102  & asy0(1:kaerbnd,1:krhlev,j)
4103  endif ! if_ij
4104  endif ! if_KCM2
4105  endif
4106  END DO
4107 
4108  return
4109 !...................................
4110  end subroutine rd_gocart_luts
4111 !-----------------------------------
4112 !
4116 !-----------------------------
4117  subroutine optavg_grt
4118 !.............................
4119 ! --- inputs: (in scope variables)
4120 ! --- outputs: (in scope variables)
4121 
4122 ! ==================================================================== !
4123 ! !
4124 ! subprogram: optavg_grt !
4125 ! !
4126 ! compute mean aerosols optical properties over each sw/lw radiation !
4127 ! spectral band for each of the species components. This program !
4128 ! follows gfdl's approach for thick cloud opertical property in !
4129 ! sw radiation scheme (2000). !
4130 ! !
4131 ! ==================== defination of variables =================== !
4132 ! !
4133 ! input arguments: !
4134 ! nv1,nv2 (NBDSW) - start/end spectral band indices of aerosol data !
4135 ! for each sw radiation spectral band !
4136 ! nr1,nr2 (NLWBND) - start/end spectral band indices of aerosol data !
4137 ! for each ir radiation spectral band !
4138 ! solwaer (NBDSW,KAERBND) !
4139 ! - solar flux weight over each sw radiation band !
4140 ! vs each aerosol data spectral band !
4141 ! eirwaer (NLWBND,KAERBND) !
4142 ! - ir flux weight over each lw radiation band !
4143 ! vs each aerosol data spectral band !
4144 ! solbnd (NBDSW) - solar flux weight over each sw radiation band !
4145 ! eirbnd (NLWBND) - ir flux weight over each lw radiation band !
4146 ! NBDSW - total number of sw spectral bands !
4147 ! NLWBND - total number of lw spectral bands !
4148 ! NSWLWBD - total number of sw+lw spectral bands !
4149 ! !
4150 ! output arguments: (to module variables) !
4151 ! !
4152 ! ================================================================== !
4153 !
4154  implicit none
4155 
4156 ! --- inputs:
4157 ! --- output:
4158 
4159 ! --- locals:
4160  real (kind=kind_phys) :: sumk, sumok, sumokg, sumreft, &
4161  & sp, refb, reft, rsolbd, rirbd
4162 
4163  integer :: ib, nb, ni, nh, nc
4164 !
4165 !===> ... begin here
4166 
4167 ! --- ... allocate aerosol optical data
4168  if (.not. allocated(extrhd_grt) .and. kcm2 > 0 ) then
4169  allocate ( extrhd_grt(krhlev,kcm2,nswlwbd) )
4170  allocate ( ssarhd_grt(krhlev,kcm2,nswlwbd) )
4171  allocate ( asyrhd_grt(krhlev,kcm2,nswlwbd) )
4172  endif
4173  if (.not. allocated(extrhi_grt) .and. kcm1 > 0 ) then
4174  allocate ( extrhi_grt(kcm1,nswlwbd) )
4175  allocate ( ssarhi_grt(kcm1,nswlwbd) )
4176  allocate ( asyrhi_grt(kcm1,nswlwbd) )
4177  endif
4178 !
4179 ! --- ... loop for each sw radiation spectral band
4180 
4181  do nb = 1, nbdsw
4182  rsolbd = f_one / solbnd(nb)
4183 
4184 ! --- for rh independent aerosol species
4185 
4186  lab_rhi: if (kcm1 > 0 ) then
4187  do nc = 1, kcm1
4188  sumk = f_zero
4189  sumok = f_zero
4190  sumokg = f_zero
4191  sumreft = f_zero
4192 
4193  do ni = nv1(nb), nv2(nb)
4194  sp = sqrt( (f_one - rhidssa0_grt(ni,nc)) &
4195  & / (f_one - rhidssa0_grt(ni,nc)*rhidasy0_grt(ni,nc)) )
4196  reft = (f_one - sp) / (f_one + sp)
4197  sumreft = sumreft + reft*solwaer(nb,ni)
4198 
4199  sumk = sumk + rhidext0_grt(ni,nc)*solwaer(nb,ni)
4200  sumok = sumok + rhidssa0_grt(ni,nc)*solwaer(nb,ni) &
4201  & * rhidext0_grt(ni,nc)
4202  sumokg = sumokg + rhidssa0_grt(ni,nc)*solwaer(nb,ni) &
4203  & * rhidext0_grt(ni,nc)*rhidasy0_grt(ni,nc)
4204  enddo
4205 
4206  refb = sumreft * rsolbd
4207 
4208  extrhi_grt(nc,nb) = sumk * rsolbd
4209  asyrhi_grt(nc,nb) = sumokg / (sumok + 1.0e-10)
4210  ssarhi_grt(nc,nb) = 4.0*refb &
4211  & / ( (f_one+refb)**2 - asyrhi_grt(nc,nb)*(f_one-refb)**2 )
4212 
4213  enddo ! end do_nc_block for rh-ind aeros
4214  endif lab_rhi
4215 
4216 ! --- for rh dependent aerosols species
4217 
4218  lab_rhd: if (kcm2 > 0 ) then
4219  do nc = 1, kcm2
4220  do nh = 1, krhlev
4221  sumk = f_zero
4222  sumok = f_zero
4223  sumokg = f_zero
4224  sumreft = f_zero
4225 
4226  do ni = nv1(nb), nv2(nb)
4227  sp = sqrt( (f_one - rhdpssa0_grt(ni,nh,nc)) &
4228  & /(f_one-rhdpssa0_grt(ni,nh,nc)*rhdpasy0_grt(ni,nh,nc)))
4229  reft = (f_one - sp) / (f_one + sp)
4230  sumreft = sumreft + reft*solwaer(nb,ni)
4231 
4232  sumk = sumk + rhdpext0_grt(ni,nh,nc)*solwaer(nb,ni)
4233  sumok = sumok + rhdpssa0_grt(ni,nh,nc)*solwaer(nb,ni) &
4234  & * rhdpext0_grt(ni,nh,nc)
4235  sumokg = sumokg + rhdpssa0_grt(ni,nh,nc)*solwaer(nb,ni) &
4236  & * rhdpext0_grt(ni,nh,nc)*rhdpasy0_grt(ni,nh,nc)
4237  enddo
4238 
4239  refb = sumreft * rsolbd
4240 
4241  extrhd_grt(nh,nc,nb) = sumk * rsolbd
4242  asyrhd_grt(nh,nc,nb) = sumokg / (sumok + 1.0e-10)
4243  ssarhd_grt(nh,nc,nb) = 4.0*refb &
4244  & /((f_one+refb)**2 - asyrhd_grt(nh,nc,nb)*(f_one-refb)**2)
4245  enddo ! end do_nh_block
4246  enddo ! end do_nc_block for rh-dep aeros
4247  endif lab_rhd
4248 
4249  enddo ! end do_nb_block for sw
4250 
4251 ! --- ... loop for each lw radiation spectral band
4252 
4253  do nb = 1, nlwbnd
4254 
4255  ib = nbdsw + nb
4256  rirbd = f_one / eirbnd(nb)
4257 
4258 ! --- for rh independent aerosol species
4259 
4260  lab_rhi_lw: if (kcm1 > 0 ) then
4261  do nc = 1, kcm1
4262  sumk = f_zero
4263  sumok = f_zero
4264  sumokg = f_zero
4265  sumreft = f_zero
4266 
4267  do ni = nr1(nb), nr2(nb)
4268  sp = sqrt( (f_one - rhidssa0_grt(ni,nc)) &
4269  & / (f_one - rhidssa0_grt(ni,nc)*rhidasy0_grt(ni,nc)) )
4270  reft = (f_one - sp) / (f_one + sp)
4271  sumreft = sumreft + reft*eirwaer(nb,ni)
4272 
4273  sumk = sumk + rhidext0_grt(ni,nc)*eirwaer(nb,ni)
4274  sumok = sumok + rhidssa0_grt(ni,nc)*eirwaer(nb,ni) &
4275  & * rhidext0_grt(ni,nc)
4276  sumokg = sumokg + rhidssa0_grt(ni,nc)*eirwaer(nb,ni) &
4277  & * rhidext0_grt(ni,nc)*rhidasy0_grt(ni,nc)
4278  enddo
4279 
4280  refb = sumreft * rirbd
4281 
4282  extrhi_grt(nc,ib) = sumk * rirbd
4283  asyrhi_grt(nc,ib) = sumokg / (sumok + 1.0e-10)
4284  ssarhi_grt(nc,ib) = 4.0*refb &
4285  & / ( (f_one+refb)**2 - asyrhi_grt(nc,ib)*(f_one-refb)**2 )
4286  enddo ! end do_nc_block for rh-ind aeros
4287  endif lab_rhi_lw
4288 
4289 ! --- for rh dependent aerosols species
4290 
4291  lab_rhd_lw: if (kcm2 > 0 ) then
4292  do nc = 1, kcm2
4293  do nh = 1, krhlev
4294  sumk = f_zero
4295  sumok = f_zero
4296  sumokg = f_zero
4297  sumreft = f_zero
4298 
4299  do ni = nr1(nb), nr2(nb)
4300  sp = sqrt( (f_one - rhdpssa0_grt(ni,nh,nc)) &
4301  & /(f_one - rhdpssa0_grt(ni,nh,nc)*rhdpasy0_grt(ni,nh,nc)) )
4302  reft = (f_one - sp) / (f_one + sp)
4303  sumreft = sumreft + reft*eirwaer(nb,ni)
4304 
4305  sumk = sumk + rhdpext0_grt(ni,nh,nc)*eirwaer(nb,ni)
4306  sumok = sumok + rhdpssa0_grt(ni,nh,nc)*eirwaer(nb,ni) &
4307  & * rhdpext0_grt(ni,nh,nc)
4308  sumokg = sumokg+ rhdpssa0_grt(ni,nh,nc)*eirwaer(nb,ni) &
4309  & * rhdpext0_grt(ni,nh,nc)*rhdpasy0_grt(ni,nh,nc)
4310  enddo
4311 
4312  refb = sumreft * rirbd
4313 
4314  extrhd_grt(nh,nc,ib) = sumk * rirbd
4315  asyrhd_grt(nh,nc,ib) = sumokg / (sumok + 1.0e-10)
4316  ssarhd_grt(nh,nc,ib) = 4.0*refb &
4317  & /((f_one+refb)**2 - asyrhd_grt(nh,nc,ib)*(f_one-refb)**2 )
4318  enddo ! end do_nh_block
4319  enddo ! end do_nc_block for rh-dep aeros
4320  endif lab_rhd_lw
4321 
4322  enddo ! end do_nb_block for lw
4323 
4324 !
4325  return
4326 !................................
4327  end subroutine optavg_grt
4328 !--------------------------------
4329 !
4334 !-----------------------------------
4335  subroutine rd_gocart_clim
4336 !...................................
4337 ! --- inputs: (in scope variables)
4338 ! --- outputs: (in scope variables)
4339 
4340 ! ================================================================== !
4341 ! !
4342 ! subprogram: rd_gocart_clim !
4343 ! !
4344 ! 1. read in aerosol dry mass and surface pressure from GEOS3-GOCART !
4345 ! C3.1 2000 monthly data set !
4346 ! or aerosol mixing ratio and surface pressure from GEOS4-GOCART !
4347 ! 2000-2007 averaged monthly data set !
4348 ! 2. compute goes lat/lon array (for horizontal mapping) !
4349 ! !
4350 ! ==================== defination of variables =================== !
4351 ! !
4352 ! inputs arguments: !
4353 ! imon - month of the year !
4354 ! me - print message control flag !
4355 ! !
4356 ! outputs arguments: (to the module variables) !
4357 ! psclmg - pressure (sfc to toa) cb IMXG*JMXG*KMXG !
4358 ! dmclmg - aerosol dry mass/mixing ratio IMXG*JMXG*KMXG*NMXG !
4359 ! geos_rlon - goes longitude deg IMXG !
4360 ! geos_rlat - goes latitude deg JMXG !
4361 ! !
4362 ! usage: call rd_gocart_clim !
4363 ! !
4364 ! program history: !
4365 ! 05/18/2010 --- Lu Add the option to read GEOS4-GOCART climo !
4366 ! ================================================================== !
4367 !
4368  implicit none
4369 
4370 ! --- inputs:
4371 ! --- output:
4372 
4373 ! --- locals:
4374  integer, parameter :: MAXSPC = 5
4375  real (kind=kind_io4), parameter :: PINT = 0.01
4376  real (kind=kind_io4), parameter :: EPSQ = 0.0
4377 
4378  integer :: i, j, k, numspci, ii
4379  integer :: icmp, nrecl, nt1, nt2, nn(maxspc)
4380  character :: ymd*6, yr*4, mn*2, tp*2, &
4381  & fname*30, fin*30, aerosol_file*40
4382  logical :: file_exist
4383 
4384  real (kind=kind_io4), dimension(KMXG) :: sig
4385  real (kind=kind_io4), dimension(IMXG,JMXG) :: ps
4386  real (kind=kind_io4), dimension(IMXG,JMXG,KMXG) :: temp
4387  real (kind=kind_io4), dimension(IMXG,JMXG,KMXG,MAXSPC):: buff
4388  real (kind=kind_phys) :: pstmp
4389 
4390 ! Add the following variables for GEOS4-GOCART
4391  real (kind=kind_io4), dimension(KMXG):: hyam, hybm
4392  real (kind=kind_io4) :: p0
4393 
4394  data yr /'2000'/ !!<=== use 2000 as the climo proxy
4395 
4396 !* sigma_coordinate for GEOS3-GOCART
4397 !* P(i,j,k) = PINT + SIG(k) * (PS(i,j) - PINT)
4398  data sig / &
4399  & 9.98547e-01,9.94147e-01,9.86350e-01,9.74300e-01,9.56950e-01, &
4400  & 9.33150e-01,9.01750e-01,8.61500e-01,8.11000e-01,7.50600e-01, &
4401  & 6.82900e-01,6.10850e-01,5.37050e-01,4.63900e-01,3.93650e-01, &
4402  & 3.28275e-01,2.69500e-01,2.18295e-01,1.74820e-01,1.38840e-01, &
4403  & 1.09790e-01,8.66900e-02,6.84150e-02,5.39800e-02,4.25750e-02, &
4404  & 3.35700e-02,2.39900e-02,1.36775e-02,5.01750e-03,5.30000e-04 /
4405 
4406 !* hybrid_sigma_pressure_coordinate for GEOS4-GOCART
4407 !* p(i,j,k) = a(k)*p0 + b(k)*ps(i,j)
4408  data hyam/ &
4409  & 0, 0.0062694, 0.02377049, 0.05011813, 0.08278809, 0.1186361, &
4410  & 0.1540329, 0.1836373, 0.2043698, 0.2167788, 0.221193, &
4411  & 0.217729, 0.2062951, 0.1865887, 0.1615213, 0.1372958, &
4412  & 0.1167039, 0.09920014, 0.08432171, 0.06656809, 0.04765031, &
4413  & 0.03382346, 0.0237648, 0.01435208, 0.00659734, 0.002826232, &
4414  & 0.001118959, 0.0004086494, 0.0001368611, 3.750308e-05/
4415 
4416  data hybm / &
4417  & 0.992555, 0.9642, 0.90556, 0.816375, 0.703815, 0.576585, &
4418  & 0.44445, 0.324385, 0.226815, 0.149165, 0.089375, &
4419  & 0.045865, 0.017485, 0.00348, 0, 0, 0, 0, 0, &
4420  & 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /
4421 
4422  data p0 /1013.25 /
4423 
4424 !===> ... begin here
4425 
4426 ! --- allocate and initialize gocart climatological data
4427  if ( .not. allocated (dmclmg) ) then
4428  allocate ( dmclmg(imxg,jmxg,kmxg,nmxg) )
4429  allocate ( psclmg(imxg,jmxg,kmxg) )
4430  allocate ( molwgt(nmxg) )
4431  endif
4432 
4433  dmclmg(:,:,:,:) = f_zero
4434  psclmg(:,:,:) = f_zero
4435  molwgt(:) = f_zero
4436 
4437 ! --- allocate and initialize geos lat and lon arrays
4438  if ( .not. allocated ( geos_rlon )) then
4439  allocate (geos_rlon(imxg))
4440  allocate (geos_rlat(jmxg))
4441  endif
4442 
4443  geos_rlon(:) = f_zero
4444  geos_rlat(:) = f_zero
4445 
4446 ! --- compute geos lat and lon arrays
4447  do i = 1, imxg
4448  geos_rlon(i) = -180. + (i-1)* dltx
4449  end do
4450  do j = 2, jmxg-1
4451  geos_rlat(j) = -90. + (j-1)* dlty
4452  end do
4453  geos_rlat(1) = -89.5
4454  geos_rlat(jmxg) = 89.5
4455 
4456 ! --- determine whether GEOS3 or GEOS4 data set is provided
4457  if ( gocart_climo == 'xxxx' ) then
4458  gocart_climo='0000'
4459 ! check geos3-gocart climo
4460  aerosol_file = '200001.PS.avg'
4461  inquire (file = aerosol_file, exist = file_exist)
4462  if ( file_exist ) gocart_climo='ver3'
4463 ! check geos4-gocart climo
4464  aerosol_file = 'gocart_climo_2000x2007_ps_01.bin'
4465  inquire (file = aerosol_file, exist = file_exist)
4466  if ( file_exist ) gocart_climo='ver4'
4467  endif
4468 !
4469 !
4470 ! --- read ps (sfc pressure) and compute 3d pressure field (psclmg)
4471 !
4472  write(mn,'(i2.2)') imon
4473  ymd = yr//mn
4474  aerosol_file = 'null'
4475  if ( gocart_climo == 'ver3' ) then
4476  aerosol_file = ymd//'.PS.avg'
4477  elseif ( gocart_climo == 'ver4' ) then
4478  aerosol_file = 'gocart_climo_2000x2007_ps_'//mn//'.bin'
4479  endif
4480 !
4481  inquire (file = aerosol_file, exist = file_exist)
4482  lab_if_ps : if ( file_exist ) then
4483 
4484  close(niaercm)
4485  if ( gocart_climo == 'ver3' ) then
4486  nrecl = 4 * (imxg * jmxg)
4487  open(niaercm, file=trim(aerosol_file), &
4488  & access='direct',recl=nrecl)
4489  read(niaercm, rec=1) ps
4490  do j = 1, jmxg
4491  do i = 1, imxg
4492  do k = 1, kmxg
4493  pstmp = pint + sig(k) * (ps(i,j) - pint)
4494  psclmg(i,j,k) = 0.1 * pstmp ! convert mb to cb
4495  enddo
4496  enddo
4497  enddo
4498 
4499  elseif ( gocart_climo == 'ver4' ) then
4500  open(niaercm, file=trim(aerosol_file), &
4501  & status='old', form='unformatted')
4502  read(niaercm) ps(:,:)
4503  do j = 1, jmxg
4504  do i = 1, imxg
4505  do k = 1, kmxg
4506  pstmp = hyam(k)*p0 + hybm(k)*ps(i,j)
4507  psclmg(i,j,k) = 0.1 * pstmp ! convert mb to cb
4508  enddo
4509  enddo
4510  enddo
4511 
4512  endif ! ---- end if_gocart_climo
4513 
4514  else lab_if_ps
4515 
4516  print *,' *** Requested aerosol data file "', &
4517  & trim(aerosol_file), '" not found!'
4518  print *,' *** Stopped in RD_GOCART_CLIM ! ', me
4519  stop 1006
4520  endif lab_if_ps
4521 !
4522 ! --- read aerosol dry mass (g/m3) or mixing ratios (mol/mol,kg/kg)
4523 !
4524  lab_do_icmp : do icmp = 1, num_gridcomp
4525 
4526  tp = gridcomp(icmp)
4527 
4528 ! determine aerosol_file
4529  aerosol_file = 'null'
4530  if ( gocart_climo == 'ver3' ) then
4531  if(tp == 'DU') fname='.DU.STD.tv20.g.avg'
4532  if(tp == 'SS') fname='.SS.STD.tv17.g.avg'
4533  if(tp == 'SU') fname='.SU.STD.tv15.g.avg'
4534  if(tp == 'OC') fname='.CC.STD.tv15.g.avg'
4535  if(tp == 'BC') fname='.CC.STD.tv15.g.avg'
4536  aerosol_file=ymd//trim(fname)
4537  elseif ( gocart_climo == 'ver4' ) then
4538  fin = 'gocart_climo_2000x2007_'
4539  if(tp == 'DU') fname=trim(fin)//'du_'
4540  if(tp == 'SS') fname=trim(fin)//'ss_'
4541  if(tp == 'SU') fname=trim(fin)//'su_'
4542  if(tp == 'OC') fname=trim(fin)//'cc_'
4543  if(tp == 'BC') fname=trim(fin)//'cc_'
4544  aerosol_file=trim(fname)//mn//'.bin'
4545  endif
4546 
4547  numspci = 4
4548  if(tp == 'DU') numspci = 5
4549  inquire (file=trim(aerosol_file), exist = file_exist)
4550  lab_if_aer: if ( file_exist ) then
4551 !
4552  close(niaercm)
4553  if ( gocart_climo == 'ver3' ) then
4554  nrecl = 4 * numspci * (imxg * jmxg * kmxg + 3)
4555  open (niaercm, file=trim(aerosol_file), &
4556  & access='direct', recl=nrecl)
4557  read(niaercm,rec=1)(nt1,nt2,nn(i),buff(:,:,:,i),i=1,numspci)
4558 
4559  elseif ( gocart_climo == 'ver4' ) then
4560  open (niaercm, file=trim(aerosol_file), &
4561  & status='old', form='unformatted')
4562  do i = 1, numspci
4563  do k = 1, kmxg
4564  read(niaercm) temp(:,:,k)
4565  buff(:,:,k,i) = temp(:,:,k)
4566  enddo
4567  enddo
4568  endif
4569 
4570 !!===> fill dmclmg with working array buff
4571  select case ( tp )
4572 
4573 ! fill in DU from DU: du1, du2, du3, du4, du5
4574  case ('DU' )
4575  if ( dm_indx%dust1 /= -999) then
4576  do ii = 1, 5
4577  dmclmg(:,:,:,dm_indx%dust1+ii-1) = buff(:,:,:,ii)
4578  enddo
4579  else
4580  print *, 'ERROR: invalid DU index, abort! ',me
4581  stop 1007
4582  endif
4583 
4584 ! fill in BC from CC: bc_phobic, oc_phobic, bc_philic, oc_philic
4585  case ('BC' )
4586  if ( dm_indx%soot_phobic /= -999) then
4587  dmclmg(:,:,:,dm_indx%soot_phobic)=buff(:,:,:,1)
4588  dmclmg(:,:,:,dm_indx%soot_philic)=buff(:,:,:,3)
4589  molwgt(dm_indx%soot_phobic) = 12.
4590  molwgt(dm_indx%soot_philic) = 12.
4591  else
4592  print *, 'ERROR: invalid BC index, abort! ',me
4593  stop 1008
4594  endif
4595 
4596 ! fill in SU from SU: dms, so2, so4, msa
4597  case ('SU' )
4598  if ( dm_indx%suso /= -999) then
4599  dmclmg(:,:,:,dm_indx%suso) = buff(:,:,:,3)
4600  molwgt(dm_indx%suso) = 96.
4601  else
4602  print *, 'ERROR: invalid SU index, abort! ',me
4603  stop 1009
4604  endif
4605 
4606 ! fill in OC from CC: bc_phobic, oc_phobic, bc_philic, oc_philic
4607  case ('OC' )
4608  if ( dm_indx%waso_phobic /= -999) then
4609  dmclmg(:,:,:,dm_indx%waso_phobic) = 1.4*buff(:,:,:,2)
4610  dmclmg(:,:,:,dm_indx%waso_philic) = 1.4*buff(:,:,:,4)
4611  molwgt(dm_indx%waso_phobic) = 12.
4612  molwgt(dm_indx%waso_philic) = 12.
4613  else
4614  print *, 'ERROR: invalid OC index, abort! ',me
4615  stop 1010
4616  endif
4617 
4618 ! fill in SS from SS: ss1, ss2, ss3, ss4
4619  case ('SS' )
4620  if ( dm_indx%ssam /= -999) then
4621  dmclmg(:,:,:,dm_indx%ssam) = buff(:,:,:,1)
4622  dmclmg(:,:,:,dm_indx%sscm) = buff(:,:,:,2) + &
4623  & buff(:,:,:,3)+buff(:,:,:,4)
4624  else
4625  print *, 'ERROR: invalid SS index, abort! ',me
4626  stop 1011
4627  endif
4628 
4629  case default
4630 
4631  print *, 'ERROR: invalid aerosol species, abort ',tp
4632  stop 1012
4633 
4634  end select
4635 
4636  else lab_if_aer
4637  print *,' *** Requested aerosol data file "',aerosol_file, &
4638  & '" not found!'
4639  print *,' *** Stopped in RD_GOCART_CLIM ! ', me
4640  stop 1013
4641  endif lab_if_aer
4642 
4643  enddo lab_do_icmp
4644 
4645  return
4646 !...................................
4647  end subroutine rd_gocart_clim
4648 !-----------------------------------
4649 !
4650 !...................................
4651  end subroutine gocart_init
4652 !-----------------------------------
4653 
4655 !-----------------------------------
4656  subroutine setgocartaer &
4657 !...................................
4659 ! --- inputs:
4660  & ( alon,alat,prslk,rhlay,dz,hz,nswlwbd, &
4661  & prsl,tvly,trcly, &
4662  & imax,nlay,nlp1, ivflip, lsswr,lslwr, &
4663 ! --- outputs:
4664  & aerosw,aerolw &
4665  & )
4666 
4667 
4668 ! ================================================================== !
4669 ! !
4670 ! setgocartaer computes sw + lw aerosol optical properties for gocart !
4671 ! aerosol species (merged from fcst and clim fields) !
4672 ! !
4673 ! inputs: !
4674 ! alon, alat IMAX !
4675 ! - longitude and latitude of given points in degree !
4676 ! prslk - pressure cb IMAX*NLAY !
4677 ! rhlay - layer mean relative humidity IMAX*NLAY !
4678 ! dz - layer thickness m IMAX*NLAY !
4679 ! hz - level high m IMAX*NLP1 !
4680 ! NSWLWBD - total number of sw+ir bands for aeros opt prop 1 !
4681 ! prsl - layer mean pressure mb IMAX*NLAY !
4682 ! tvly - layer mean virtual temperature k IMAX*NLAY !
4683 ! trcly - layer mean specific tracer g/g IMAX*NLAY*NTRAC!
4684 ! IMAX - horizontal dimension of arrays 1 !
4685 ! NLAY,NLP1-vertical dimensions of arrays 1 !
4686 ! ivflip - control flag for direction of vertical index 1 !
4687 ! =0: index from toa to surface !
4688 ! =1: index from surface to toa !
4689 ! lsswr,lslwr !
4690 ! - logical flag for sw/lw radiation calls 1 !
4691 ! !
4692 ! outputs: !
4693 ! aerosw - aeros opt properties for sw IMAX*NLAY*NBDSW*NF_AESW!
4694 ! (:,:,:,1): optical depth !
4695 ! (:,:,:,2): single scattering albedo !
4696 ! (:,:,:,3): asymmetry parameter !
4697 ! aerolw - aeros opt properties for lw IMAX*NLAY*NBDLW*NF_AELW!
4698 ! (:,:,:,1): optical depth !
4699 ! (:,:,:,2): single scattering albedo !
4700 ! (:,:,:,3): asymmetry parameter !
4701 ! tau_gocart - 550nm aeros opt depth IMAX*NLAY*MAX_NUM_GRIDCOMP!
4702 ! !
4703 ! module parameters and constants: !
4704 ! NBDSW - total number of sw bands for aeros opt prop 1 !
4705 ! NLWBND - total number of ir bands for aeros opt prop 1 !
4706 ! !
4707 ! module variable: (set by subroutine gocart_init) !
4708 ! dmclmg - aerosols dry mass/mixing ratios IMXG*JMXG*KMXG*NMXG !
4709 ! psclmg - pressure cb IMXG*JMXG*KMXG !
4710 ! !
4711 ! usage: call setgocartaer !
4712 ! !
4713 ! subprograms called: map_aermr, aeropt_grt !
4714 ! !
4715 ! ================================================================== !
4716 !
4717  implicit none
4718 
4719 ! --- inputs:
4720  integer, intent(in) :: IMAX,NLAY,NLP1,ivflip,NSWLWBD
4721  logical, intent(in) :: lsswr, lslwr
4722 
4723  real (kind=kind_phys), dimension(:,:), intent(in) :: prslk, &
4724  & prsl, rhlay, tvly, dz, hz
4725  real (kind=kind_phys), dimension(:), intent(in) :: alon, alat
4726  real (kind=kind_phys), dimension(:,:,:), intent(in) :: trcly
4727 
4728 ! --- outputs:
4729  real (kind=kind_phys), dimension(:,:,:,:), intent(out) :: &
4730  & aerosw, aerolw
4731 
4732 ! --- locals:
4733  real (kind=kind_phys), dimension(NLAY) :: rh1, dz1
4734  real (kind=kind_phys), dimension(NLAY,NSWLWBD)::tauae,ssaae,asyae
4735  real (kind=kind_phys), dimension(NLAY,max_num_gridcomp) :: &
4736  & tauae_gocart
4737 
4738  real (kind=kind_phys) :: tmp1, tmp2
4739 
4740  integer :: i, i1, i2, j1, j2, k, m, m1, kp
4741 
4742 ! prognostic aerosols on gfs grids
4743  real (kind=kind_phys), dimension(:,:,:),allocatable:: aermr,dmfcs
4744 
4745 ! aerosol (dry mass) on gfs grids/levels
4746  real (kind=kind_phys), dimension(:,:), allocatable :: dmanl,dmclm, &
4747  & dmclmx
4748  real (kind=kind_phys), dimension(KMXG) :: pstmp, pkstr
4749  real (kind=kind_phys) :: ptop, psfc, tem, plv, tv, rho
4750 
4751 ! --- conversion constants
4752  real (kind=kind_phys), parameter :: hdltx = 0.5 * dltx
4753  real (kind=kind_phys), parameter :: hdlty = 0.5 * dlty
4754 
4755 !===> ... begin here
4756 !
4757  if ( .not. allocated(dmanl) ) then
4758  allocate ( dmclmx(kmxg,nmxg) )
4759  allocate ( dmanl(nlay,nmxg) )
4760  allocate ( dmclm(nlay,nmxg) )
4761 
4762  allocate ( aermr(imax,nlay,nmxg) )
4763  allocate ( dmfcs(imax,nlay,nmxg) )
4764  endif
4765 !
4766 ! -- map input tracer array (trcly) to local tracer array (aermr)
4767 !
4768  dmfcs(:,:,:) = f_zero
4769  lab_if_fcst : if ( get_fcst ) then
4770 
4771  call map_aermr
4772 ! --- inputs: (in scope variables)
4773 ! --- outputs: (in scope variables)
4774 
4775  endif lab_if_fcst
4776 !
4777 ! -- map geos-gocart climo (dmclmg) to gfs grids (dmclm)
4778 !
4779  lab_do_imax : do i = 1, imax
4780 
4781  dmclm(:,:) = f_zero
4782 
4783  lab_if_clim : if ( get_clim ) then
4784 ! --- map grid in longitude direction
4785  i2 = 1
4786  j2 = 1
4787  tmp1 = alon(i)
4788  if (tmp1 > 180.) tmp1 = tmp1 - 360.0
4789  lab_do_imxg : do i1 = 1, imxg
4790  tmp2 = geos_rlon(i1)
4791  if (tmp2 > 180.) tmp2 = tmp2 - 360.0
4792  if (abs(tmp1-tmp2) <= hdltx) then
4793  i2 = i1
4794  exit lab_do_imxg
4795  endif
4796  enddo lab_do_imxg
4797 
4798 ! --- map grid in latitude direction
4799  lab_do_jmxg : do j1 = 1, jmxg
4800  if (abs(alat(i)-geos_rlat(j1)) <= hdlty) then
4801  j2 = j1
4802  exit lab_do_jmxg
4803  endif
4804  enddo lab_do_jmxg
4805 
4806 ! --- update local arrays pstmp and dmclmx
4807  pstmp(:)= psclmg(i2,j2,:)*1000.0 ! cb to Pa
4808  dmclmx(:,:) = dmclmg(i2,j2,:,:)
4809 
4810 ! --- map geos-gocart climo (dmclmx) to gfs level (dmclm)
4811  pkstr(:)=fpkap(pstmp(:))
4812  psfc = pkstr(1) ! pressure at sfc
4813  ptop = pkstr(kmxg) ! pressure at toa
4814 
4815 ! --- map grid in verical direction (follow how ozone is mapped
4816 ! in radiation_gases routine)
4817  do k = 1, nlay
4818  kp = k ! from sfc to toa
4819  if(ivflip==0) kp = nlay - k + 1 ! from toa to sfc
4820  tmp1 = prslk(i,kp)
4821 
4822  do m1 = 1, kmxg - 1 ! from sfc to toa
4823  if(tmp1 > pkstr(m1+1) .and. tmp1 <= pkstr(m1)) then
4824  tmp2 = f_one / (pkstr(m1)-pkstr(m1+1))
4825  tem = (pkstr(m1) - tmp1) * tmp2
4826  dmclm(kp,:) = tem * dmclmx(m1+1,:)+ &
4827  & (f_one-tem) * dmclmx(m1,:)
4828  endif
4829  enddo
4830 
4831 !* if(tmp1 > psfc) dmclm(kp,:) = dmclmx(1,:)
4832 !* if(tmp1 < ptop) dmclm(kp,:) = dmclmx(KMXG,:)
4833 
4834  enddo
4835  endif lab_if_clim
4836 !
4837 ! --- compute fcst/clim merged aerosol loading (dmanl) and the
4838 ! radiation optical properties (aerosw, aerolw)
4839 !
4840  do k = 1, nlay
4841 
4842 ! --- map global to local arrays (rh1 and dz1)
4843  rh1(k) = rhlay(i,k)
4844  dz1(k) = dz (i,k)
4845 
4846 ! --- convert from mixing ratio to dry mass (g/m3)
4847  plv = 100. * prsl(i,k) ! convert pressure from mb to Pa
4848  tv = tvly(i,k) ! virtual temp in K
4849  rho = plv / (con_rd * tv) ! air density in kg/m3
4850  if ( get_fcst ) then
4851  do m = 1, nmxg ! mixing ratio (g/g)
4852  dmfcs(i,k,m) = max(1000.*(rho*aermr(i,k,m)),f_zero)
4853  enddo ! m_do_loop
4854  endif
4855  if ( get_clim .and. (gocart_climo == 'ver4') ) then
4856  do m = 1, nmxg
4857  dmclm(k,m)=1000.*dmclm(k,m)*rho !mixing ratio (g/g)
4858  if ( molwgt(m) /= 0. ) then !mixing ratio (mol/mol)
4859  dmclm(k,m)=dmclm(k,m) * (molwgt(m)/con_amd)
4860  endif
4861  enddo ! m_do_loop
4862  endif
4863 
4864 
4865 ! --- determine dmanl from dmclm and dmfcs
4866  do m = 1, nmxg
4867  dmanl(k,m)= ctaer*dmfcs(i,k,m) + &
4868  & ( f_one-ctaer)*dmclm(k,m)
4869  enddo
4870  enddo
4871 
4872 ! --- calculate sw/lw aerosol optical properties for the
4873 ! corresponding frequency bands
4874 
4875  call aeropt_grt
4876 ! --- inputs: (in scope variables)
4877 ! --- outputs: (in scope variables)
4878 
4879  if ( lsswr ) then
4880 
4881  if ( laswflg ) then
4882 
4883  do m = 1, nbdsw
4884  do k = 1, nlay
4885  aerosw(i,k,m,1) = tauae(k,m)
4886  aerosw(i,k,m,2) = ssaae(k,m)
4887  aerosw(i,k,m,3) = asyae(k,m)
4888  enddo
4889  enddo
4890 
4891  else
4892 
4893  aerosw(:,:,:,:) = f_zero
4894 
4895  endif
4896 
4897  endif ! end if_lsswr_block
4898 
4899  if ( lslwr ) then
4900 
4901  if ( lalwflg ) then
4902 
4903  if ( nlwbnd == 1 ) then
4904  m1 = nbdsw + 1
4905  do m = 1, nbdlw
4906  do k = 1, nlay
4907  aerolw(i,k,m,1) = tauae(k,m1)
4908  aerolw(i,k,m,2) = ssaae(k,m1)
4909  aerolw(i,k,m,3) = asyae(k,m1)
4910  enddo
4911  enddo
4912  else
4913  do m = 1, nbdlw
4914  m1 = nbdsw + m
4915  do k = 1, nlay
4916  aerolw(i,k,m,1) = tauae(k,m1)
4917  aerolw(i,k,m,2) = ssaae(k,m1)
4918  aerolw(i,k,m,3) = asyae(k,m1)
4919  enddo
4920  enddo
4921  endif
4922 
4923  else
4924 
4925  aerolw(:,:,:,:) = f_zero
4926 
4927  endif
4928  endif ! end if_lslwr_block
4929 
4930  enddo lab_do_imax
4931 
4932 ! =================
4933  contains
4934 ! =================
4935 
4937 !-----------------------------
4938  subroutine map_aermr
4939 !.............................
4940 ! --- inputs: (in scope variables)
4941 ! --- outputs: (in scope variables)
4942 
4943 ! ==================================================================== !
4944 ! !
4945 ! subprogram: map_aermr !
4946 ! !
4947 ! map input tracer fields (trcly) to local tracer array (aermr) !
4948 ! !
4949 ! ==================== defination of variables =================== !
4950 ! !
4951 ! input arguments: !
4952 ! IMAX - horizontal dimension of arrays 1 !
4953 ! NLAY - vertical dimensions of arrays 1 !
4954 ! trcly - layer tracer mass mixing ratio g/g IMAX*NLAY*NTRAC!
4955 ! output arguments: (to module variables) !
4956 ! aermr - layer aerosol mass mixing ratio g/g IMAX*NLAY*NMXG !
4957 ! !
4958 ! note: !
4959 ! NTRAC is the number of tracers excluding water vapor !
4960 ! NMXG is the number of prognostic aerosol species !
4961 ! ================================================================== !
4962 !
4963  implicit none
4964 
4965 ! --- inputs:
4966 ! --- output:
4967 
4968 ! --- local:
4969  integer :: i, indx, ii
4970  character :: tp*2
4971 
4972 ! initialize
4973  aermr(:,:,:) = f_zero
4974  ii = 1 !! <---- trcly does not contain q
4975 
4976 ! ==> DU: du1 (submicron bins), du2, du3, du4, du5
4977  if( gfs_phy_tracer%doing_DU ) then
4978  aermr(:,:,dm_indx%dust1) = trcly(:,:,dmfcs_indx%du001-ii)
4979  aermr(:,:,dm_indx%dust2) = trcly(:,:,dmfcs_indx%du002-ii)
4980  aermr(:,:,dm_indx%dust3) = trcly(:,:,dmfcs_indx%du003-ii)
4981  aermr(:,:,dm_indx%dust4) = trcly(:,:,dmfcs_indx%du004-ii)
4982  aermr(:,:,dm_indx%dust5) = trcly(:,:,dmfcs_indx%du005-ii)
4983  endif
4984 
4985 ! ==> OC: oc_phobic, oc_philic
4986  if( gfs_phy_tracer%doing_OC ) then
4987  aermr(:,:,dm_indx%waso_phobic) = &
4988  & trcly(:,:,dmfcs_indx%ocphobic-ii)
4989  aermr(:,:,dm_indx%waso_philic) = &
4990  & trcly(:,:,dmfcs_indx%ocphilic-ii)
4991  endif
4992 
4993 ! ==> BC: bc_phobic, bc_philic
4994  if( gfs_phy_tracer%doing_BC ) then
4995  aermr(:,:,dm_indx%soot_phobic) = &
4996  & trcly(:,:,dmfcs_indx%bcphobic-ii)
4997  aermr(:,:,dm_indx%soot_philic) = &
4998  & trcly(:,:,dmfcs_indx%bcphilic-ii)
4999  endif
5000 
5001 ! ==> SS: ss1, ss2 (submicron bins), ss3, ss4, ss5
5002  if( gfs_phy_tracer%doing_SS ) then
5003  aermr(:,:,dm_indx%ssam) = trcly(:,:,dmfcs_indx%ss001-ii) &
5004  & + trcly(:,:,dmfcs_indx%ss002-ii)
5005  aermr(:,:,dm_indx%sscm) = trcly(:,:,dmfcs_indx%ss003-ii) &
5006  & + trcly(:,:,dmfcs_indx%ss004-ii) &
5007  & + trcly(:,:,dmfcs_indx%ss005-ii)
5008  endif
5009 
5010 ! ==> SU: so4
5011  if( gfs_phy_tracer%doing_SU ) then
5012  aermr(:,:,dm_indx%suso) = trcly(:,:,dmfcs_indx%so4-ii)
5013  endif
5014 
5015  return
5016 !...................................
5017  end subroutine map_aermr
5018 !-----------------------------------
5019 
5023 !-----------------------------------
5024  subroutine aeropt_grt
5025 !...................................
5026 ! --- inputs: (in scope variables)
5027 ! --- outputs: (in scope variables)
5028 
5029 ! ================================================================== !
5030 ! !
5031 ! subprogram: aeropt_grt !
5032 ! !
5033 ! compute aerosols optical properties in NSWLWBD sw/lw bands. !
5034 ! Aerosol distribution at each grid point is composed from up to !
5035 ! NMXG aerosol species (from NUM_GRIDCOMP components). !
5036 ! !
5037 ! input variables: !
5038 ! dmanl - aerosol dry mass g/m3 NLAY*NMXG !
5039 ! rh1 - relative humidity % NLAY !
5040 ! dz1 - layer thickness km NLAY !
5041 ! NLAY - vertical dimensions - 1 !
5042 ! ivflip - control flag for direction of vertical index !
5043 ! =0: index from toa to surface !
5044 ! =1: index from surface to toa !
5045 ! !
5046 ! output variables: !
5047 ! tauae - aerosol optical depth - NLAY*NSWLWBD !
5048 ! ssaae - aerosol single scattering albedo - NLAY*NSWLWBD !
5049 ! asyae - aerosol asymmetry parameter - NLAY*NSWLWBD !
5050 ! !
5051 ! ================================================================== !
5052 !
5053  implicit none
5054 
5055 ! --- inputs:
5056 ! --- outputs:
5057 
5058 ! --- locals:
5059  real (kind=kind_phys) :: aerdm
5060  real (kind=kind_phys) :: ext1, ssa1, asy1, ex00, ss00, as00, &
5061  & ex01, ss01, as01, exint
5062  real (kind=kind_phys) :: tau, ssa, asy, &
5063  & sum_tau, sum_ssa, sum_asy
5064 
5065 ! --- subgroups for sub-micron dust
5066 ! --- corresponds to 0.1-0.18, 0.18-0.3, 0.3-0.6, 0.6-1.0 micron
5067 
5068  real (kind=kind_phys) :: fd(4)
5069  data fd / 0.01053,0.08421,0.25263,0.65263 /
5070 
5071  character :: tp*2
5072  integer :: icmp, n, kk, ib, ih2, ih1, ii, ij, ijk
5073  real (kind=kind_phys) :: drh0, drh1, rdrh
5074 
5075  real (kind=kind_phys) :: qmin
5076  data qmin / 1.e-20 /
5077 
5078 !===> ... begin here
5079 
5080 ! --- initialize (assume no aerosols)
5081  tauae = f_zero
5082  ssaae = f_one
5083  asyae = f_zero
5084 
5085  tauae_gocart = f_zero
5086 
5087 !===> ... loop over vertical layers
5088 !
5089  lab_do_layer : do kk = 1, nlay
5090 
5091 ! --- linear interp coeffs for rh-dep species
5092 
5093  ih2 = 1
5094  do while ( rh1(kk) > rhlev_grt(ih2) )
5095  ih2 = ih2 + 1
5096  if ( ih2 > krhlev ) exit
5097  enddo
5098  ih1 = max( 1, ih2-1 )
5099  ih2 = min( krhlev, ih2 )
5100 
5101  drh0 = rhlev_grt(ih2) - rhlev_grt(ih1)
5102  drh1 = rh1(kk) - rhlev_grt(ih1)
5103  if ( ih1 == ih2 ) then
5104  rdrh = f_zero
5105  else
5106  rdrh = drh1 / drh0
5107  endif
5108 
5109 ! --- loop through sw/lw spectral bands
5110 
5111  lab_do_ib : do ib = 1, nswlwbd
5112  sum_tau = f_zero
5113  sum_ssa = f_zero
5114  sum_asy = f_zero
5115 
5116 ! --- loop through aerosol grid components
5117  lab_do_icmp : do icmp = 1, num_gridcomp
5118  ext1 = f_zero
5119  ssa1 = f_zero
5120  asy1 = f_zero
5121 
5122  tp = gridcomp(icmp)
5123 
5124  select case ( tp )
5125 
5126 ! -- dust aerosols: no humidification effect
5127  case ( 'DU')
5128  do n = 1, kcm1
5129 
5130  if (n <= 4) then
5131  aerdm = dmanl(kk,dm_indx%dust1) * fd(n)
5132  else
5133  aerdm = dmanl(kk,dm_indx%dust1+n-4 )
5134  endif
5135 
5136  if (aerdm < qmin) aerdm = f_zero
5137  ex00 = extrhi_grt(n,ib)*(1000.*dz1(kk))*aerdm
5138  ss00 = ssarhi_grt(n,ib)
5139  as00 = asyrhi_grt(n,ib)
5140  ext1 = ext1 + ex00
5141  ssa1 = ssa1 + ex00 * ss00
5142  asy1 = asy1 + ex00 * ss00 * as00
5143 
5144  enddo
5145 
5146 ! -- suso aerosols: with humidification effect
5147  case ( 'SU')
5148  ij = isuso
5149  exint = extrhd_grt(ih1,ij,ib) &
5150  & + rdrh*(extrhd_grt(ih2,ij,ib) - extrhd_grt(ih1,ij,ib))
5151  ss00 = ssarhd_grt(ih1,ij,ib) &
5152  & + rdrh*(ssarhd_grt(ih2,ij,ib) - ssarhd_grt(ih1,ij,ib))
5153  as00 = asyrhd_grt(ih1,ij,ib) &
5154  & + rdrh*(asyrhd_grt(ih2,ij,ib) - asyrhd_grt(ih1,ij,ib))
5155 
5156  aerdm = dmanl(kk, dm_indx%suso)
5157  if (aerdm < qmin) aerdm = f_zero
5158  ex00 = exint*(1000.*dz1(kk))*aerdm
5159  ext1 = ex00
5160  ssa1 = ex00 * ss00
5161  asy1 = ex00 * ss00 * as00
5162 
5163 ! -- seasalt aerosols: with humidification effect
5164  case ( 'SS')
5165  do n = 1, 2
5166  ij = issam + (n-1)
5167  exint = extrhd_grt(ih1,ij,ib) &
5168  & + rdrh*(extrhd_grt(ih2,ij,ib) - extrhd_grt(ih1,ij,ib))
5169  ss00 = ssarhd_grt(ih1,ij,ib) &
5170  & + rdrh*(ssarhd_grt(ih2,ij,ib) - ssarhd_grt(ih1,ij,ib))
5171  as00 = asyrhd_grt(ih1,ij,ib) &
5172  & + rdrh*(asyrhd_grt(ih2,ij,ib) - asyrhd_grt(ih1,ij,ib))
5173 
5174  aerdm = dmanl(kk, dm_indx%ssam+n-1)
5175  if (aerdm < qmin) aerdm = f_zero
5176  ex00 = exint*(1000.*dz1(kk))*aerdm
5177  ext1 = ext1 + ex00
5178  ssa1 = ssa1 + ex00 * ss00
5179  asy1 = asy1 + ex00 * ss00 * as00
5180 
5181  enddo
5182 
5183 ! -- organic carbon/black carbon:
5184 ! using 'waso' and 'soot' for hydrophilic OC and BC
5185 ! using 'waso' and 'soot' at RH=0 for hydrophobic OC and BC
5186  case ( 'OC', 'BC')
5187  if(tp == 'OC') then
5188  ii = dm_indx%waso_phobic
5189  ij = iwaso
5190  else
5191  ii = dm_indx%soot_phobic
5192  ij = isoot
5193  endif
5194 
5195 ! --- hydrophobic
5196  aerdm = dmanl(kk, ii)
5197  if (aerdm < qmin) aerdm = f_zero
5198  ex00 = extrhd_grt(1,ij,ib)*(1000.*dz1(kk))*aerdm
5199  ss00 = ssarhd_grt(1,ij,ib)
5200  as00 = asyrhd_grt(1,ij,ib)
5201 ! --- hydrophilic
5202  aerdm = dmanl(kk, ii+1)
5203  if (aerdm < qmin) aerdm = f_zero
5204  exint = extrhd_grt(ih1,ij,ib) &
5205  & + rdrh*(extrhd_grt(ih2,ij,ib) - extrhd_grt(ih1,ij,ib))
5206  ex01 = exint*(1000.*dz1(kk))*aerdm
5207  ss01 = ssarhd_grt(ih1,ij,ib) &
5208  & + rdrh*(ssarhd_grt(ih2,ij,ib) - ssarhd_grt(ih1,ij,ib))
5209  as01 = asyrhd_grt(ih1,ij,ib) &
5210  & + rdrh*(asyrhd_grt(ih2,ij,ib) - asyrhd_grt(ih1,ij,ib))
5211 
5212  ext1 = ex00 + ex01
5213  ssa1 = (ex00 * ss00) + (ex01 * ss01)
5214  asy1 = (ex00 * ss00 * as00) + (ex01 * ss01 * as01)
5215 
5216  end select
5217 
5218 ! --- determine tau, ssa, asy for each grid component
5219  tau = ext1
5220  if (ext1 > f_zero) ssa=min(f_one,ssa1/ext1)
5221  if (ssa1 > f_zero) asy=min(f_one,asy1/ssa1)
5222 
5223 ! --- save tau at 550 nm for each grid component
5224  if ( ib == nv_aod ) then
5225  do ijk = 1, max_num_gridcomp
5226  if ( tp == max_gridcomp(ijk) ) then
5227  tauae_gocart(kk,ijk) = tau
5228  endif
5229  enddo
5230  endif
5231 
5232 ! --- update sum_tau, sum_ssa, sum_asy
5233  sum_tau = sum_tau + tau
5234  sum_ssa = sum_ssa + tau * ssa
5235  sum_asy = sum_asy + tau * ssa * asy
5236 
5237  enddo lab_do_icmp
5238 
5239 
5240 ! --- determine total tau, ssa, asy for aerosol mixture
5241  tauae(kk,ib) = sum_tau
5242  if (sum_tau > f_zero) ssaae(kk,ib) = sum_ssa / sum_tau
5243  if (sum_ssa > f_zero) asyae(kk,ib) = sum_asy / sum_ssa
5244 
5245  enddo lab_do_ib
5246 
5247  enddo lab_do_layer
5248 
5249 !
5250  return
5251 !...................................
5252  end subroutine aeropt_grt
5253 !--------------------------------
5254 
5255 !................................
5256  end subroutine setgocartaer
5257 !--------------------------------
5258 !
5259 ! GOCART code modification end here (Sarah Lu) ------------------------!
5260 ! =======================================================================
5261 
5262 !..........................................!
5263  end module module_radiation_aerosols !
5264 !==========================================!
real(kind=kind_phys), dimension(nwvsol), save s0intv
real(kind=kind_phys), dimension(ndm, nae), save haer
real(kind=kind_phys), dimension(:,:,:), allocatable, save extrhd_grt
subroutine aer_property
This subroutine maps the 5 degree global climatological aerosol data set onto model grids...
real(kind=kind_phys), dimension(:,:), allocatable rhidssa0_grt
integer, dimension(:,:,:), allocatable, save ivolae
subroutine wrt_aerlog
This subroutine writes aerosol parameter configuration to run log file.
real(kind=kind_phys), dimension(:), allocatable, save geos_rlon
real(kind=kind_phys), parameter f_one
subroutine setgocartaer
This subroutine computes SW + LW aerosol optical properties for gocart aerosol species (merged from f...
real(kind=kind_phys), parameter wvn550
integer, save iaerflg
aerosol effect control flag
Definition: physparam.f:155
real(kind=kind_phys), dimension(krhlev) data
integer, dimension(:), allocatable iendwv_grt
real(kind=kind_phys), parameter con_t0c
temp at 0C (K)
Definition: physcons.f:89
type(gocart_index_type), save dm_indx
real(kind=kind_phys), dimension(:,:), allocatable, save scarhi
integer, save iaermdl
aerosol model scheme control flag
Definition: physparam.f:153
character(40), parameter vtagaer
integer, parameter, public nlwstr
starting band number in ir region
real(kind=kind_phys), dimension(:,:), allocatable, save asyrhi
real(kind=kind_phys), dimension(:,:,:,:), allocatable, save dmclmg
subroutine set_spectrum
This subroutine defines the one wavenumber solar fluxes based on toa solar spectral distribution...
real(kind=kind_phys), dimension(:,:,:), allocatable rhdpasy0_grt
real(kind=kind_phys), dimension(nbands) wvnum1
Definition: radsw_param.f:188
subroutine aeropt_grt
This subroutine computes aerosols optical properties in NSWLWBD SW/LW bands. Aerosol distribution at ...
This module contains some the most frequently used math and physics constants for gcm models...
Definition: physcons.f:29
real(kind=kind_phys), dimension(:,:,:), allocatable, save asyrhd_grt
real(kind=kind_phys), parameter con_boltz
boltzmann constant (J/K)
Definition: physcons.f:121
real(kind=kind_phys), dimension(:,:), allocatable rhidasy0_grt
real(kind=kind_phys), dimension(:), allocatable, save geos_rlat
integer, parameter, public nwvsol
num of wvnum regions where solar flux is constant
real(kind=kind_phys), dimension(2,imxae, jmxae), save denng
integer, parameter nbdlw
Definition: radlw_param.f:122
real(kind=kind_phys), dimension(nbands) wvnlw2
Definition: radlw_param.f:144
subroutine trop_update
update the monthly global distribution of aerosol profiles in five degree horizontal resolution...
subroutine rd_gocart_luts
This subroutine reads input gocart aerosol optical data from Mie code calculations.
integer, parameter nbdsw
Definition: radsw_param.f:144
real(kind=kind_phys), dimension(:), allocatable, save extstra
real(kind=kind_phys), dimension(nbands) wvnum2
Definition: radsw_param.f:188
real(kind=kind_phys), dimension(ndm, nae), save prsref
integer, parameter, public nf_aelw
num of output fields for lw rad
real(kind=kind_phys), dimension(:,:), allocatable, save ssarhi_grt
subroutine volc_update
search historical volcanic data sets to find and read in monthly 45-degree lat-zone band of optical d...
real(kind=kind_phys), dimension(nxc, imxae, jmxae), save cmixg
This module defines commonly used control variables/parameters in physics related programs...
Definition: physparam.f:27
real(kind=kind_phys), dimension(ndm, nae), save sigref
real(kind=kind_phys), dimension(:,:,:), allocatable rhdpssa0_grt
integer, parameter nswstr
Definition: radsw_param.f:142
This module contains SW band parameters set up.
Definition: radsw_param.f:58
real(kind=kind_phys), dimension(:,:,:), allocatable, save ssarhd_grt
integer, parameter max_num_gridcomp
real(kind=kind_phys), parameter con_rd
gas constant air (J/kg/K)
Definition: physcons.f:69
subroutine optavg_grt
This subroutine computes mean aerosols optical properties over each SW/LW radiation spectral band for...
real(kind=kind_io4), dimension(:), allocatable molwgt
real(kind=kind_phys), dimension(:,:), allocatable rhidext0_grt
real(kind=kind_phys), save ctaer
This module contains climatological atmospheric aerosol schemes for radiation computations.
integer, parameter, public nwvtir
total num of wvnum in ir range
integer, save ivflip
vertical profile indexing flag
Definition: physparam.f:224
integer, dimension(nwvsol), save nwvns0
real(kind=kind_phys), dimension(nbands) wvnlw1
Definition: radlw_param.f:144
character *2, dimension(max_num_gridcomp) max_gridcomp
logical, save lalwflg
lw aerosols effect control flag
Definition: physparam.f:157
subroutine gocart_init
the initialization program for gocart aerosols
real(kind=kind_phys), parameter dlty
subroutine, public aer_init
The initialization program to set up necessary parameters and working arrays.
This module contains LW band parameters set up.
Definition: radlw_param.f:58
real(kind=kind_phys), parameter con_plnk
planck constant (J/s)
Definition: physcons.f:119
real(kind=kind_phys), dimension(:,:,:), allocatable, save scarhd
character, dimension(:), allocatable, save gridcomp
integer, dimension( imxae, jmxae), save kprfg
real(kind=kind_phys), dimension(:,:), allocatable, save asyrhi_grt
real(kind=kind_phys), parameter dltx
real(kind=kind_phys), parameter con_amd
molecular wght of dry air (g/mol)
Definition: physcons.f:130
real(kind=kind_phys), dimension(:,:,:), allocatable, save ssarhd
logical, parameter lalw1bd
control flag for lw aerosol property =t: use 1 broad-band lw aeros properties =f: use multi bands...
Definition: physparam.f:127
integer, parameter, public nspc
num of species for output aod (opnl)
character, save aeros_file
external aerosols data file
Definition: physparam.f:163
real(kind=kind_phys), dimension(:,:), allocatable, save extrhi
real(kind=kind_phys), parameter con_g
gravity (m/s2)
Definition: physcons.f:52
real(kind=kind_phys), parameter con_pi
Definition: physcons.f:41
subroutine map_aermr
This subroutine maps input tracer fields (trcly) to local tracer array (aermr).
integer, parameter, public nwvtot
total num of wvnum included
real(kind=kind_phys), dimension(:,:), allocatable, save extrhi_grt
real(kind=kind_phys), parameter con_c
Definition: physcons.f:117
real(kind=kind_phys), dimension(nrhlev), save rhlev
subroutine set_aerspc(raddt, fdaer)
determine merging coefficients ctaer; setup aerosol specification.
subroutine clim_aerinit
the opac-climatology aerosol initialization program to set up necessary parameters and working arrays...
integer, parameter, public nf_aesw
num of output fields for sw rad
character *4, save gocart_climo
type(tracer_index_type), save dmfcs_indx
subroutine set_aercoef
the initialization program for climatological aerosols. the program reads and maps the pre-tabulated ...
real(kind=kind_phys), dimension(:,:,:), allocatable, save extrhd
integer, dimension(nxc, imxae, jmxae), save idxcg
subroutine set_volcaer
The initialization program for stratospheric volcanic aerosols.
logical, save lavoflg
stratospheric volcanic effect flag
Definition: physparam.f:161
real(kind=kind_phys), dimension(:,:,:), allocatable, save asyrhd
subroutine optavg
compute mean aerosols optical properties over each SW radiation spectral band for each of the species...
subroutine radclimaer
This subroutine computes aerosols optical properties in NSWLWBD bands. there are seven different vert...
integer, dimension(ncm) idxspc
subroutine rd_gocart_clim
This subroutine:
real(kind=kind_phys), dimension(:,:,:), allocatable rhdpext0_grt
real(kind=kind_phys), parameter f_zero
integer, parameter, public nspc1
total+species
logical, save laswflg
sw aerosols effect control flag
Definition: physparam.f:159
subroutine, public setaer
This subroutine computes aerosols optical properties.
real(kind=kind_phys), dimension(:,:), allocatable, save ssarhi
real(kind=kind_phys), dimension(:,:,:), allocatable, save psclmg
subroutine, public aer_update
This subroutine checks and updates time varying climatology aerosol data sets.
real(kind=kind_phys), dimension(:) rhlev_grt