1 module module_ftuv_driver
3 use module_wave_data, only : nw
9 integer, parameter :: dp = selected_real_kind(14,300)
10 !----------------------------------------------------
12 !----------------------------------------------------
13 integer, private, parameter :: nref = 51
14 real(dp), private, parameter :: m2s = 60._dp
15 real(dp), private, parameter :: Pa2hPa = .01_dp
17 integer, private :: nz, kcon
18 integer, private :: next, last
19 integer, private :: curjulday = 0
21 !++alma 2012-12-01 modis landuse from sw
22 integer, private, allocatable :: luse2usgs(:)
25 real(dp), private :: esfact = 1.0_dp
26 real(dp), private :: dobson
28 real(dp), private :: dels
30 real(dp), private :: zref(nref), tref(nref), airref(nref), o3ref(nref)
31 real(dp), private :: albedo(nw-1,2)
34 integer :: ncoldens_levs
35 integer :: ndays_of_year
36 real(dp), pointer :: col_levs(:)
37 real(dp), pointer :: day_of_year(:)
38 real(dp), pointer :: o3_col_dens(:,:,:,:)
39 real(dp), pointer :: o2_col_dens(:,:,:,:)
40 logical :: is_allocated
41 end type column_density
43 type(column_density), private, allocatable :: col_dens(:)
44 logical, private :: photo_inti_initialized = .false.
47 data zref/ 00.0, 01.0, 02.0, 03.0, 04.0, 05.0, 06.0, 07.0, 08.0, 09.0, &
48 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, &
49 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, &
50 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, &
51 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, &
54 data tref/ 288.150, 281.651, 275.154, 268.659, 262.166, 255.676, 249.187, &
55 242.700, 236.215, 229.733, 223.252, 216.774, 216.650, 216.650, &
56 216.650, 216.650, 216.650, 216.650, 216.650, 216.650, 216.650, &
57 217.581, 218.574, 219.567, 220.560, 221.552, 222.544, 223.536, &
58 224.527, 225.518, 226.509, 227.500, 228.490, 230.973, 233.743, &
59 236.513, 239.282, 242.050, 244.818, 247.584, 250.350, 253.114, &
60 255.878, 258.641, 261.403, 264.164, 266.925, 269.684, 270.650, &
63 data airref/ 2.55E+19, 2.31E+19, 2.09E+19, 1.89E+19, 1.70E+19, 1.53E+19, &
64 1.37E+19, 1.23E+19, 1.09E+19, 9.71E+18, 8.60E+18, 7.59E+18, &
65 6.49E+18, 5.54E+18, 4.74E+18, 4.05E+18, 3.46E+18, 2.96E+18, &
66 2.53E+18, 2.16E+18, 1.85E+18, 1.57E+18, 1.34E+18, 1.14E+18, &
67 9.76E+17, 8.33E+17, 7.12E+17, 6.09E+17, 5.21E+17, 4.47E+17, &
68 3.83E+17, 3.28E+17, 2.82E+17, 2.41E+17, 2.06E+17, 1.76E+17, &
69 1.51E+17, 1.30E+17, 1.12E+17, 9.62E+16, 8.31E+16, 7.19E+16, &
70 6.23E+16, 5.40E+16, 4.70E+16, 4.09E+16, 3.56E+16, 3.11E+16, &
71 2.74E+16, 2.42E+16, 2.14E+16 /
73 data o3ref/ 8.00E+11, 7.39E+11, 6.90E+11, 6.22E+11, 5.80E+11, 5.67E+11, &
74 5.70E+11, 5.86E+11, 6.50E+11, 8.23E+11, 1.13E+12, 1.57E+12, &
75 2.02E+12, 2.24E+12, 2.35E+12, 2.57E+12, 2.95E+12, 3.47E+12, &
76 4.04E+12, 4.49E+12, 4.77E+12, 4.88E+12, 4.86E+12, 4.73E+12, &
77 4.54E+12, 4.32E+12, 4.03E+12, 3.65E+12, 3.24E+12, 2.85E+12, &
78 2.52E+12, 2.26E+12, 2.03E+12, 1.80E+12, 1.58E+12, 1.40E+12, &
79 1.22E+12, 1.04E+12, 8.73E+11, 7.31E+11, 6.07E+11, 4.95E+11, &
80 3.98E+11, 3.18E+11, 2.54E+11, 2.03E+11, 1.62E+11, 1.30E+11, &
81 1.04E+11, 8.27E+10, 6.61E+10/
84 !----------------------------------------------------
86 !----------------------------------------------------
87 integer, private, parameter :: pid_no2 = 4
88 integer, private, parameter :: pid_n2o = 9
89 integer, private, parameter :: pid_n2o5 = 8
90 integer, private, parameter :: pid_o31d = 2
91 integer, private, parameter :: pid_o33p = 3
92 integer, private, parameter :: pid_hono = 12
93 integer, private, parameter :: pid_hno3 = 13
94 integer, private, parameter :: pid_hno4 = 14
95 integer, private, parameter :: pid_no3o2 = 5
96 integer, private, parameter :: pid_no3o = 6
97 integer, private, parameter :: pid_h2o2 = 11
98 integer, private, parameter :: pid_ch2om = 16
99 integer, private, parameter :: pid_ch2or = 15
100 integer, private, parameter :: pid_ald = 17
101 integer, private, parameter :: pid_ch3choa = 17
102 integer, private, parameter :: pid_ch3chob = 18
103 integer, private, parameter :: pid_ch3choc = 19
104 integer, private, parameter :: pid_op1 = 24
105 integer, private, parameter :: pid_op2 = 1 ! unknown
106 integer, private, parameter :: pid_paa = 16
107 integer, private, parameter :: pid_ket = 23
108 integer, private, parameter :: pid_glya = 21
109 integer, private, parameter :: pid_glyb = 21
110 integer, private, parameter :: pid_mgly = 22
111 integer, private, parameter :: pid_dcb = 1 ! unknown
112 integer, private, parameter :: pid_onit = 25
113 integer, private, parameter :: pid_pan = 26
114 integer, private, parameter :: pid_mvk = 27
115 integer, private, parameter :: pid_macr = 28
116 integer, private, parameter :: pid_hyac = 29
117 integer, private, parameter :: pid_glyald= 30
120 ! These numbers are referred to from module_wave_data.F (sjref(ii,XX))
121 integer, private, parameter :: pid_cl2 = 56
122 integer, private, parameter :: pid_hocl = 57
123 integer, private, parameter :: pid_fmcl = 58
127 subroutine ftuv_driver( id, curr_secs, dtstep, config_flags, &
129 p_phy, t_phy, rho_phy, p8w, t8w, &
130 xlat, xlong, z_at_w, &
131 moist, chem,gd_cloud,gd_cloud2, &
132 ph_no2,ph_o31d,ph_o33p,ph_hono, &
133 ph_hno3,ph_hno4,ph_no3o2,ph_no3o, &
134 ph_h2o2,ph_ch2om,ph_ch2or,ph_ald, &
135 ph_op1,ph_op2,ph_paa,ph_ket,ph_glya, &
136 ph_glyb,ph_mgly,ph_dcb,ph_onit, &
137 ph_macr,ph_ch3coc2h5,ph_n2o, &
138 ph_pan,ph_mpan,ph_acetol,ph_gly, &
139 ph_bigald,ph_mek,ph_c2h5ooh,ph_c3h7ooh, &
140 ph_pooh,ph_rooh,ph_xooh,ph_isopooh, &
141 ph_alkooh,ph_mekooh,ph_tolooh, &
142 ph_terpooh,ph_n2o5,ph_mvk,ph_glyald, &
144 ph_cl2,ph_hocl,ph_fmcl, &
146 ntuv_lev, ntuv_bin, ntuv_pht, &
147 ph_radfld, ph_adjcoe, ph_prate, &
149 tauaer1, tauaer2, tauaer3, tauaer4, & !rajesh
150 waer1, waer2, waer3, waer4, & !rajesh
151 gaer1, gaer2, gaer3, gaer4, & !rajesh
152 ids,ide, jds,jde, kds,kde, &
153 ims,ime, jms,jme, kms,kme, &
154 its,ite, jts,jte, kts,kte )
157 use module_state_description
158 use module_model_constants
159 use module_data_sorgam, only : mw_so4_aer
161 use module_wave_data, only : tuv_jmax, nw, wc
162 use module_ftuv_subs, only : calc_zenith
166 !----------------------------------------------------
168 !----------------------------------------------------
169 integer, intent(in ) :: id, julday, &
170 ids,ide, jds,jde, kds,kde, &
171 ims,ime, jms,jme, kms,kme, &
172 its,ite, jts,jte, kts,kte
173 integer, intent(in ) :: ntuv_lev, ntuv_bin, ntuv_pht
174 integer, intent(in) :: ivgtyp(ims:ime,jms:jme)
176 real, intent(in ) :: dtstep, gmt
177 real(dp), intent(in ) :: curr_secs
179 type(grid_config_rec_type), intent(in ) :: config_flags
181 real, intent(in ) :: p_phy(ims:ime,kms:kme,jms:jme), &
182 t_phy(ims:ime,kms:kme,jms:jme), &
183 rho_phy(ims:ime,kms:kme,jms:jme), &
184 p8w(ims:ime,kms:kme,jms:jme), &
185 t8w(ims:ime,kms:kme,jms:jme), &
186 z_at_w(ims:ime,kms:kme,jms:jme)
188 !----------------------------------------------------
189 ! these arrays are for cloudwater/ice coming from
190 ! grell convection, optional
191 !----------------------------------------------------
193 intent(in ) :: gd_cloud(ims:ime,kms:kme,jms:jme), &
194 gd_cloud2(ims:ime,kms:kme,jms:jme)
195 real, intent(in ) :: xlat(ims:ime,jms:jme), &
196 xlong(ims:ime,jms:jme)
197 real, intent(in ) :: moist(ims:ime,kms:kme,jms:jme,num_moist)
198 real, intent(in ) :: chem(ims:ime,kms:kme,jms:jme,num_chem)
199 !rajesh: add arrays for aerosol optical properties
200 real, dimension( ims:ime, kms:kme, jms:jme ), &
201 intent(in ) :: tauaer1, tauaer2, tauaer3, tauaer4, &
202 waer1, waer2, waer3, waer4, &
203 gaer1, gaer2, gaer3, gaer4
205 !----------------------------------------------------
207 !----------------------------------------------------
208 real, dimension( ims:ime, kms:kme, jms:jme ), &
209 intent(out ) :: ph_no2, ph_o31d, ph_o33p, ph_hono, &
210 ph_hno3, ph_hno4, ph_no3o2, ph_no3o, &
211 ph_h2o2, ph_ch2om, ph_ch2or, ph_ald, &
212 ph_op1, ph_op2, ph_paa, ph_ket, ph_glya, &
213 ph_glyb, ph_mgly, ph_dcb, &
214 ph_onit, ph_macr, ph_ch3coc2h5, ph_n2o, &
215 ph_pan, ph_mpan, ph_acetol, ph_gly, &
216 ph_bigald, ph_mek, ph_c2h5ooh, ph_c3h7ooh,&
217 ph_pooh,ph_rooh,ph_xooh,ph_isopooh, &
218 ph_alkooh,ph_mekooh,ph_tolooh,ph_terpooh, &
219 ph_n2o5,ph_mvk,ph_glyald,ph_hyac, &
220 ph_cl2,ph_hocl,ph_fmcl
222 real, dimension( ims:ime, ntuv_lev, jms:jme, ntuv_bin ), &
223 intent(out ) :: ph_radfld
224 real, dimension( ims:ime, ntuv_lev, jms:jme, ntuv_pht ), &
225 intent(out ) :: ph_adjcoe
226 real, dimension( ims:ime, ntuv_lev, jms:jme, ntuv_pht ), &
227 intent(out ) :: ph_prate
228 real, dimension(ntuv_bin), &
230 real, dimension(ntuv_lev), &
231 intent(out ) :: zref_x
233 !----------------------------------------------------
235 !----------------------------------------------------
236 real(dp), parameter :: xair_kg = 1.0e3_dp/28.97_dp*6.023e23_dp*1.0e-6_dp
237 real(dp), parameter :: ph_no3o_factor = 1.1236_dp
238 real(dp), parameter :: kg_per_amu = 1.65979e-27_dp
240 !----------------------------------------------------
242 !----------------------------------------------------
243 integer :: i, j, k, kp1, m
244 integer :: astat, istat
247 real(dp) :: xtime, xhour, xmin, gmtp
248 real(dp) :: wrk, qs, es
249 real(dp) :: alat, along, azim, zen
252 real(dp) :: atm_mass_den
253 logical :: chm_is_mozart
255 !----------------------------------------------------
257 !----------------------------------------------------
258 real(dp) :: zen_angle(its:ite,jts:jte)
259 real(dp) :: temp(kts:kte+1), o3(kts:kte+1), air(kts:kte+1)
260 real(dp) :: zh(kts:kte+1), rh(kts:kte+1), xlwc(kts:kte+1)
262 real(dp) :: acb1(kts:kte+1), acb2(kts:kte+1), aoc1(kts:kte+1), aoc2(kts:kte+1)
263 real(dp) :: aant(kts:kte+1), aso4(kts:kte+1), asal(kts:kte+1)
265 real(dp) :: tauaer300(kts:kte), tauaer400(kts:kte+1), &
266 tauaer600(kts:kte), tauaer999(kts:kte+1)
267 real(dp) :: waer300(kts:kte), waer400(kts:kte), &
268 waer600(kts:kte), waer999(kts:kte)
269 real(dp) :: gaer300(kts:kte), gaer400(kts:kte), &
270 gaer600(kts:kte), gaer999(kts:kte)
272 real(dp) :: p_jtop(its:ite,jts:jte)
273 real(dp) :: o2_exo_col(its:ite,jts:jte)
274 real(dp) :: o3_exo_col(its:ite,jts:jte)
275 real(dp) :: prate(kts:kte+1,tuv_jmax)
276 real(dp) :: radfld(nz,nw-1)
277 real(dp) :: adjcoe(nz,tuv_jmax)
278 real(dp) :: prate0(nz,tuv_jmax)
280 chm_is_mozart = config_flags%chem_opt == MOZART_KPP .or. &
281 config_flags%chem_opt == MOZCART_KPP .or. &
282 config_flags%chem_opt == T1_MOZCART_KPP .or. &
283 config_flags%chem_opt == MOZART_MOSAIC_4BIN_KPP .or. &
284 config_flags%chem_opt == MOZART_MOSAIC_4BIN_AQ_KPP
285 !----------------------------------------------------
286 ! set o3,o2 column densities at model top
287 !----------------------------------------------------
288 if( chm_is_mozart ) then
289 p_jtop(its:ite,jts:jte) = Pa2hPa * p_phy(its:ite,kte,jts:jte)
290 call p_interp( o2_exo_col, o3_exo_col, p_jtop, &
291 id, its, ite, jts, jte )
293 o2top = 3.60906e+21_dp
294 o3top = 2.97450e+16_dp
298 aer_select: SELECT CASE(config_flags%chem_opt)
299 CASE (RADM2SORG,RADM2SORG_KPP,RACMSORG_KPP,RADM2SORG_AQCHEM,RACM_ESRLSORG_KPP,RACMSORG_AQ,RACMSORG_AQCHEM_KPP, &
300 RACM_ESRLSORG_AQCHEM_KPP,CBMZSORG,CBMZSORG_AQ, &
301 CB05_SORG_AQ_KPP,CB05_SORG_VBS_AQ_KPP)
303 CALL wrf_debug(15,'SORGAM aerosols initialization ')
304 CASE (MOZART_MOSAIC_4BIN_KPP, MOZART_MOSAIC_4BIN_AQ_KPP)
305 CALL wrf_debug(15,'MOZART_MOSAIC_4BIN_KPP, MOZART_MOSAIC_4BIN_AQ_KPP aerosols initialization ')
307 CALL wrf_debug(15,'no aerosols initialization yet')
308 CALL wrf_message('no aerosols initialization yet')
309 END SELECT aer_select
311 !----------------------------------------------------
313 !----------------------------------------------------
314 xtime = curr_secs/60._dp
315 xhour = real( int(gmt + .01_dp) + int(xtime/m2s),kind=dp )
316 xmin = m2s*gmt + ( xtime - xhour*m2s )
317 gmtp = mod( xhour, 24.0_dp )
318 gmtp = gmtp + xmin/m2s
320 xlwc(:) = 0._dp !initialize in case no cloud water is present
322 !----------------------------------------------------
323 ! set photolysis rates
324 !----------------------------------------------------
325 J_TILE_LOOP : do j = jts, jte
326 I_TILE_LOOP : do i = its, ite
328 !----------------------------------------------------
330 !----------------------------------------------------
331 if( chm_is_mozart ) then
332 !++alma 2012-12-01 modis landuse from sw
333 ! if( ivgtyp(i,j) /= 16 ) then
334 if( luse2usgs( ivgtyp(i,j) ) /= 16 ) then
345 if( chm_is_mozart ) then
346 o3top = o3_exo_col(i,j)
347 o2top = o2_exo_col(i,j)
353 temp(kp1) = t_phy(i,k,j) ! temperature(K)
354 air(kp1) = xair_kg*rho_phy(i,k,j) ! air num.(molecules/cm^3)
355 o3(kp1) = chem(i,k,j,p_o3)*1.0e-6_dp ! ozone(VMR)
357 wrk = t_phy(i,k,j) - 273._dp
358 es = 6.11_dp*10.0_dp**(7.63_dp*wrk/(241.9_dp + wrk)) ! Magnus EQ
359 qs = 0.622_dp*es/(p_phy(i,k,j)*0.01_dp) ! sat mass mix (H2O)
360 wrk = moist(i,k,j,p_qv)/qs
361 rh(kp1) = max( 0.0_dp, min( 1.0_dp, wrk) ) ! relative huminity
364 xlwc(kp1) = 1.0e3_dp*moist(i,k,j,p_qc)*rho_phy(i,k,j) ! cloud water(g/m^3)
366 if( xlwc(kp1) < 1.0e-6_dp ) then
370 zh(kp1) = .5_dp*(z_at_w(i,kp1,j)+z_at_w(i,k,j))*0.001_dp - z_at_w(i,kts,j)*0.001_dp ! height(km)
371 ! zh(k+1) = z(i,k,j)*0.001 - z_at_w(i,1,j)*0.001 ! height(km)
373 !===============================================================================
375 ! ADD the aerosol effect on J
376 ! chem is in the unit of ug/m3
379 ! oc1 = p_orgpaj ( Primary organic conc. Aitken mode)
380 ! + p_p25aj ( Unknown PM25 conc. Acc. mode )
381 ! ant = p_no3aj ( Nitrate conc. Acc. mode )
382 ! + p_nh4aj ( Ammonium conc. Acc. mode )
383 ! so4 = p_so4aj ( Sulfate conc. Acc. mode )
384 ! sa1 = p_seas ( Coarse soil-derived aero sols )
386 !=======================================================
395 ! rajesh: initialize aerosol optical properties to zero
409 if( isorg == 1 ) then
410 acb1(kp1) = chem(i,k,j,p_ecj)
412 ! aoc1(kp1) = chem(i,k,j,p_orgpaj) + chem(i,k,j,p_orgbaj) + chem(i,k,j,p_orgaj)
414 if(config_flags%chem_opt == CB05_SORG_VBS_AQ_KPP) then
415 aoc1(kp1) = chem(i,k,j,p_orgpaj)+chem(i,k,j,p_asoa1j)+chem(i,k,j,p_asoa2j) &
416 + chem(i,k,j,p_asoa3j)+chem(i,k,j,p_asoa4j) &
417 + chem(i,k,j,p_bsoa1j)+chem(i,k,j,p_bsoa2j) &
418 + chem(i,k,j,p_bsoa3j)+chem(i,k,j,p_bsoa4j)
420 aoc1(kp1) = chem(i,k,j,p_orgpaj)
422 ! aoc1(kp1) = chem(i,k,j,p_orgpaj)
424 aant(kp1) = chem(i,k,j,p_no3aj) + chem(i,k,j,p_nh4aj)
425 aso4(kp1) = chem(i,k,j,p_so4aj)
426 ! asal(kp1) = chem(i,k,j,p_seas)
427 asal(kp1) = chem(i,k,j,p_seas) + chem(i,k,j,p_naaj) + chem(i,k,j,p_claj)
428 elseif( config_flags%chem_opt == MOZART_KPP .or. &
429 config_flags%chem_opt == MOZCART_KPP .or. &
430 config_flags%chem_opt == T1_MOZCART_KPP ) then
431 aso4(kp1) = chem(i,k,j,p_sulf)*air(kp1)*real(mw_so4_aer,kind=dp)*kg_per_amu*1.e-9_dp
432 if( config_flags%chem_opt == MOZCART_KPP .or. &
433 config_flags%chem_opt == T1_MOZCART_KPP ) then
434 atm_mass_den = rho_phy(i,k,j)
435 acb1(kp1) = chem(i,k,j,p_bc1)*atm_mass_den
436 acb2(kp1) = chem(i,k,j,p_bc2)*atm_mass_den
437 aoc1(kp1) = chem(i,k,j,p_oc1)*atm_mass_den
438 aoc2(kp1) = chem(i,k,j,p_oc2)*atm_mass_den
440 asal(kp1) = (chem(i,k,j,p_seas_1) + chem(i,k,j,p_seas_2) &
441 + chem(i,k,j,p_seas_3) + chem(i,k,j,p_seas_4))*atm_mass_den
444 ! rajesh: Extract column of aerosol optical properties
445 if(config_flags%aer_ra_feedback == 1) then
446 tauaer300(k) = tauaer1(i,k,j)
447 tauaer400(k) = tauaer2(i,k,j)
448 tauaer600(k) = tauaer3(i,k,j)
449 tauaer999(k) = tauaer4(i,k,j)
450 waer300(k) = waer1(i,k,j)
451 waer400(k) = waer2(i,k,j)
452 waer600(k) = waer3(i,k,j)
453 waer999(k) = waer4(i,k,j)
454 gaer300(k) = gaer1(i,k,j)
455 gaer400(k) = gaer2(i,k,j)
456 gaer600(k) = gaer3(i,k,j)
457 gaer999(k) = gaer4(i,k,j)
469 temp(1) = t8w(i,kts,j)
470 air(1) = xair_kg*( p8w(i,kts,j)/t8w(i,kts,j)/r_d )
483 ! tauaer300(1) = tauaer300(2)
484 ! tauaer400(1) = tauaer400(2)
485 ! tauaer600(1) = tauaer600(2)
486 ! tauaer999(1) = tauaer999(2)
487 ! waer300(1) = waer300(2)
488 ! waer400(1) = waer400(2)
489 ! waer600(1) = waer600(2)
490 ! waer999(1) = waer999(2)
491 ! gaer300(1) = gaer300(2)
492 ! gaer400(1) = gaer400(2)
493 ! gaer600(1) = gaer600(2)
494 ! gaer999(1) = gaer999(2)
496 !----------------------------------------------------
497 ! smooth air density ...
498 !----------------------------------------------------
500 air(k) = .5_dp*air(k) + .25_dp*( air(k-1) + air(k+1) )
503 alat = real(xlat(i,j),kind=dp)
504 along = -real(xlong(i,j),kind=dp)
505 call calc_zenith( alat, along, julday, gmtp, azim, zen )
508 call photo( config_flags%chem_opt,&
514 o3top, o2top, dobson, &
529 ! rajesh: Add aerosol optical property columns as arguments
530 tauaer300, tauaer400, &
531 tauaer600, tauaer999, &
536 config_flags%aer_ra_feedback, &
543 ph_no2(i,k,j) = max( 0._dp,prate(k,pid_no2)*m2s )
544 ph_o31d(i,k,j) = max( 0._dp,prate(k,pid_o31d)*m2s )
545 ph_o33p(i,k,j) = max( 0._dp,prate(k,pid_o33p)*m2s )
546 ph_hono(i,k,j) = max( 0._dp,prate(k,pid_hono)*m2s )
547 ph_hno3(i,k,j) = max( 0._dp,prate(k,pid_hno3)*m2s )
548 ph_hno4(i,k,j) = max( 0._dp,prate(k,pid_hno4)*m2s )
549 ph_no3o2(i,k,j) = max( 0._dp,prate(k,pid_no3o2)*m2s )
550 ph_no3o(i,k,j) = max( 0._dp,prate(k,pid_no3o)*m2s*ph_no3o_factor )
551 ph_h2o2(i,k,j) = max( 0._dp,prate(k,pid_h2o2)*m2s )
552 ph_ch2om(i,k,j) = max( 0._dp,prate(k,pid_ch2om)*m2s )
553 ph_ch2or(i,k,j) = max( 0._dp,prate(k,pid_ch2or)*m2s )
554 ph_ald(i,k,j) = max( 0._dp,prate(k,pid_ald)*m2s )
555 ph_op1(i,k,j) = max( 0._dp,prate(k,pid_op1)*m2s )
556 ph_op2(i,k,j) = max( 0._dp,prate(k,pid_op2)*m2s )
557 ph_paa(i,k,j) = max( 0._dp,prate(k,pid_paa)*m2s )
558 ph_ket(i,k,j) = max( 0._dp,prate(k,pid_ket)*m2s )
559 ph_glya(i,k,j) = max( 0._dp,prate(k,pid_glya)*m2s )
560 ph_glyb(i,k,j) = max( 0._dp,prate(k,pid_glyb)*m2s )
561 ph_mgly(i,k,j) = max( 0._dp,prate(k,pid_mgly)*m2s )
562 ph_dcb(i,k,j) = max( 0._dp,prate(k,pid_dcb)*m2s )
563 ph_onit(i,k,j) = max( 0._dp,prate(k,pid_onit)*m2s )
564 ph_macr(i,k,j) = max( 0._dp,prate(k,pid_macr) *m2s )
565 ph_ch3coc2h5(i,k,j) = max( 0._dp,prate(k,23)*m2s )
566 ph_cl2(i,k,j) = max( 0._dp,prate(k,pid_cl2)*m2s )
567 ph_hocl(i,k,j) = max( 0._dp,prate(k,pid_hocl)*m2s )
568 ph_fmcl(i,k,j) = max( 0._dp,prate(k,pid_fmcl)*m2s )
569 ph_pan(i,k,j) = max( 0._dp,prate(k,pid_pan)*m2s )
570 ph_n2o5(i,k,j) = max( 0._dp,prate(k,pid_n2o5)*m2s )
573 wc_x(1:min(ntuv_bin,nw-1)) = wc(1:min(ntuv_bin,nw-1))
574 zref_x(1:min(nz,ntuv_lev)) = zref(1:min(nz,ntuv_lev))
576 if( chm_is_mozart ) then
578 ph_n2o(i,k,j) = max( 0._dp,prate(k,pid_n2o)*m2s )
579 ph_n2o5(i,k,j) = max( 0._dp,prate(k,pid_n2o5)*m2s )
580 ph_mvk(i,k,j) = max( 0._dp,prate(k,pid_mvk)*m2s )
581 ph_pan(i,k,j) = max( 0._dp,prate(k,pid_pan)*m2s )
582 ph_ald(i,k,j) = max( 0._dp,(prate(k,pid_ch3choa)+prate(k,pid_ch3chob)+prate(k,pid_ch3choc))*m2s )
583 ph_gly(i,k,j) = ph_mgly(i,k,j)
584 ph_mek(i,k,j) = ph_ket(i,k,j)
585 ph_acetol(i,k,j) = ph_op1(i,k,j)
586 ph_pooh(i,k,j) = ph_op1(i,k,j)
587 ph_glyald(i,k,j) = max( 0._dp,prate(k,pid_glyald) *m2s )
588 ph_hyac(i,k,j) = max( 0._dp,2._dp*prate(k,pid_hyac) *m2s )
589 ph_hno4(i,k,j) = ph_hno4(i,k,j) + 1.e-5_dp*m2s
596 end subroutine ftuv_driver
598 !++alma 2012-12-01 modis landse from
599 ! subroutine ftuv_init( id,ips, ipe, jps, jpe, kte, &
600 ! ide, jde, config_flags )
601 subroutine ftuv_init( id,ips, ipe, jps, jpe, kte, &
602 ide, jde, config_flags, num_land_cat, mminlu_loc)
605 !---------------------------------------------------------------------
606 ! ... new initialization routine for ftuv
607 !---------------------------------------------------------------------
609 use module_state_description, only : mozart_kpp, mozcart_kpp, &
611 mozart_mosaic_4bin_kpp,&
612 mozart_mosaic_4bin_aq_kpp
613 use module_ftuv_subs, only : aer_init
614 use module_configure, only : grid_config_rec_type
618 !---------------------------------------------------------------------
619 ! ... dummy arguments
620 !---------------------------------------------------------------------
621 integer, intent(in) :: id
622 integer, intent(in) :: ips, ipe, jps, jpe, kte
623 integer, intent(in) :: ide, jde
625 !++alma 2012-12-01 modis landuse from sw
626 integer, intent(in) :: num_land_cat
627 character(len=*), intent(in) :: mminlu_loc
628 type(grid_config_rec_type), intent(in ) :: config_flags
632 !---------------------------------------------------------------------
633 ! ... local variables
634 !---------------------------------------------------------------------
641 integer :: iend, jend
642 integer :: lon_e, lat_e
643 integer :: ncoldens_levs
644 integer :: ndays_of_year
646 real, allocatable :: coldens(:,:,:,:)
647 character(len=128) :: err_msg
648 character(len=64) :: filename
649 character(len=3) :: id_num
651 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
655 #define DM_BCAST_MACRO(A) CALL wrf_dm_bcast_bytes ( A , size ( A ) * DWORDSIZE )
657 if( config_flags%chem_opt == MOZART_KPP .or. &
658 config_flags%chem_opt == MOZCART_KPP .or. &
659 config_flags%chem_opt == T1_MOZCART_KPP .or. &
660 config_flags%chem_opt == MOZART_MOSAIC_4BIN_KPP .or. &
661 config_flags%chem_opt == MOZART_MOSAIC_4BIN_AQ_KPP ) then
662 call wrf_message( 'ftuv_init: mozart,mozcart,mozart_mosaic_* chem option requires netcdf' )
667 !---------------------------------------------------------------------
668 ! ... general initializer
669 !---------------------------------------------------------------------
670 if( id == 1 .and. .not. photo_inti_initialized ) then
671 write(err_msg,*) 'ftuv_init: calling photo_inti for id = ',id
672 call wrf_message( trim(err_msg) )
673 call photo_inti( config_flags%chem_opt, kte, 20._dp )
677 if( config_flags%chem_opt == MOZART_KPP .or. &
678 config_flags%chem_opt == MOZCART_KPP .or. &
679 config_flags%chem_opt == T1_MOZCART_KPP .or. &
680 config_flags%chem_opt == MOZART_MOSAIC_4BIN_KPP .or. &
681 config_flags%chem_opt == MOZART_MOSAIC_4BIN_AQ_KPP ) then
682 !---------------------------------------------------------------------
683 ! ... allocate column_density type
684 !---------------------------------------------------------------------
685 if( id == 1 .and. .not. allocated(col_dens) ) then
686 CALL nl_get_max_dom( 1,max_dom )
687 allocate( col_dens(max_dom),stat=astat )
688 if( astat /= 0 ) then
689 CALL wrf_message( 'ftuv_init: failed to allocate column_density type col_dens' )
692 write(err_msg,*) 'ftuv_init: intializing ',max_dom,' domains'
693 call wrf_message( trim(err_msg) )
694 col_dens(:)%is_allocated = .false.
696 !---------------------------------------------------------------------
697 ! ... open column density netcdf file
698 !---------------------------------------------------------------------
699 col_dens_allocated : &
700 if( .not. col_dens(id)%is_allocated ) then
701 if( wrf_dm_on_monitor() ) then
702 cpos = index( config_flags%exo_coldens_inname, '<domain>' )
704 write(id_num,'(i3)') 100+id
705 filename = config_flags%exo_coldens_inname(:cpos-1) // 'd' // id_num(2:3)
707 filename = trim( config_flags%exo_coldens_inname )
709 err_msg = 'ftuv_init: intializing domain ' // id_num(2:3)
710 call wrf_message( trim(err_msg) )
711 err_msg = 'ftuv_init: failed to open file ' // trim(filename)
712 call handle_ncerr( nf_open( trim(filename), nf_noclobber, ncid ), trim(err_msg) )
713 !---------------------------------------------------------------------
715 !---------------------------------------------------------------------
716 err_msg = 'ftuv_init: failed to get col_dens levels id'
717 call handle_ncerr( nf_inq_dimid( ncid, 'coldens_levs', dimid ), trim(err_msg) )
718 err_msg = 'ftuv_init: failed to get col_dens levels'
719 call handle_ncerr( nf_inq_dimlen( ncid, dimid, ncoldens_levs ), trim(err_msg) )
720 err_msg = 'ftuv_init: failed to get number of days in year id'
721 call handle_ncerr( nf_inq_dimid( ncid, 'ndays_of_year', dimid ), trim(err_msg) )
722 err_msg = 'ftuv_init: failed to get number of days in year'
723 call handle_ncerr( nf_inq_dimlen( ncid, dimid, ndays_of_year ), trim(err_msg) )
724 err_msg = 'ftuv_init: failed to get west_east id'
725 call handle_ncerr( nf_inq_dimid( ncid, 'west_east', dimid ), trim(err_msg) )
726 err_msg = 'ftuv_init: failed to get west_east'
727 call handle_ncerr( nf_inq_dimlen( ncid, dimid, lon_e ), trim(err_msg) )
728 err_msg = 'ftuv_init: failed to get south_north id'
729 call handle_ncerr( nf_inq_dimid( ncid, 'south_north', dimid ), trim(err_msg) )
730 err_msg = 'ftuv_init: failed to get south_north'
731 call handle_ncerr( nf_inq_dimlen( ncid, dimid, lat_e ), trim(err_msg) )
733 !---------------------------------------------------------------------
734 ! ... bcast the dimensions
735 !---------------------------------------------------------------------
736 CALL wrf_dm_bcast_bytes ( ncoldens_levs , IWORDSIZE )
737 CALL wrf_dm_bcast_bytes ( ndays_of_year , IWORDSIZE )
738 CALL wrf_dm_bcast_bytes ( lon_e , IWORDSIZE )
739 CALL wrf_dm_bcast_bytes ( lat_e , IWORDSIZE )
740 !---------------------------------------------------------------------
741 ! ... allocate local arrays
742 !---------------------------------------------------------------------
743 iend = min( ipe,ide-1 )
744 jend = min( jpe,jde-1 )
745 allocate( coldens(lon_e,lat_e,ncoldens_levs,ndays_of_year), stat=astat )
746 if( astat /= 0 ) then
747 call wrf_message( 'ftuv_init: failed to allocate coldens' )
750 !---------------------------------------------------------------------
751 ! ... allocate column_density type component arrays
752 !---------------------------------------------------------------------
753 col_dens(id)%ncoldens_levs = ncoldens_levs
754 col_dens(id)%ndays_of_year = ndays_of_year
755 allocate( col_dens(id)%col_levs(ncoldens_levs), &
756 col_dens(id)%day_of_year(ndays_of_year), stat=astat )
757 if( astat /= 0 ) then
758 call wrf_message( 'ftuv_init: failed to allocate col_levs,day_of_year' )
761 allocate( col_dens(id)%o3_col_dens(ips:iend,jps:jend,ncoldens_levs,ndays_of_year), &
762 col_dens(id)%o2_col_dens(ips:iend,jps:jend,ncoldens_levs,ndays_of_year), stat=astat )
763 if( astat /= 0 ) then
764 call wrf_message( 'ftuv_init: failed to allocate o3_col_dens,o2_col_dens' )
767 col_dens(id)%is_allocated = .true.
768 !---------------------------------------------------------------------
770 !---------------------------------------------------------------------
771 IF ( wrf_dm_on_monitor() ) THEN
772 err_msg = 'ftuv_init: failed to get col_levs variable id'
773 call handle_ncerr( nf_inq_varid( ncid, 'coldens_levs', varid ), trim(err_msg) )
774 err_msg = 'ftuv_init: failed to read col_levs variable'
775 call handle_ncerr( nf_get_var_double( ncid, varid, col_dens(id)%col_levs ), trim(err_msg) )
776 err_msg = 'ftuv_init: failed to get days_of_year variable id'
777 call handle_ncerr( nf_inq_varid( ncid, 'days_of_year', varid ), trim(err_msg) )
778 err_msg = 'ftuv_init: failed to read days_of_year variable'
779 call handle_ncerr( nf_get_var_double( ncid, varid, col_dens(id)%day_of_year ), trim(err_msg) )
780 err_msg = 'ftuv_init: failed to col_dens variable id'
781 call handle_ncerr( nf_inq_varid( ncid, 'o3_column_density', varid ), trim(err_msg) )
782 err_msg = 'ftuv_init: failed to read col_dens variable'
783 call handle_ncerr( nf_get_var_real( ncid, varid, coldens ), trim(err_msg) )
786 DM_BCAST_MACRO(col_dens(id)%col_levs)
787 write(*,*) 'ftuv_init: bcast col_levs'
788 DM_BCAST_MACRO(col_dens(id)%day_of_year)
789 write(*,*) 'ftuv_init: bcast day_of_year'
790 CALL wrf_dm_bcast_bytes ( coldens, size(coldens)*RWORDSIZE )
791 write(*,*) 'ftuv_init: bcast o3_col_dens'
793 col_dens(id)%o3_col_dens(ips:iend,jps:jend,:ncoldens_levs,:ndays_of_year) = &
794 coldens(ips:iend,jps:jend,:ncoldens_levs,:ndays_of_year)
796 IF ( wrf_dm_on_monitor() ) THEN
797 err_msg = 'ftuv_init: failed to col_dens variable id'
798 call handle_ncerr( nf_inq_varid( ncid, 'o2_column_density', varid ), trim(err_msg) )
799 err_msg = 'ftuv_init: failed to read col_dens variable'
800 call handle_ncerr( nf_get_var_real( ncid, varid, coldens ), trim(err_msg) )
801 !---------------------------------------------------------------------
802 ! ... close column density netcdf file
803 !---------------------------------------------------------------------
804 err_msg = 'ftuv_init: failed to close file ' // trim(filename)
805 call handle_ncerr( nf_close( ncid ), trim(err_msg) )
808 CALL wrf_dm_bcast_bytes ( coldens, size(coldens)*RWORDSIZE )
809 write(*,*) 'ftuv_init: bcast o2_col_dens'
811 col_dens(id)%o2_col_dens(ips:iend,jps:jend,:ncoldens_levs,:ndays_of_year) = &
812 coldens(ips:iend,jps:jend,:ncoldens_levs,:ndays_of_year)
814 deallocate( coldens )
817 write(*,*) 'ftuv_init: coldens variables for domain ',id
818 write(*,*) 'ftuv_init: days_of_year'
819 write(*,'(1p,5g15.7)') col_dens(id)%day_of_year(:)
820 write(*,*) 'ftuv_init: coldens levels'
821 write(*,'(1p,5g15.7)') col_dens(id)%col_levs(:)
823 endif col_dens_allocated
825 !++alma 2012-12-01 modis landuse from sw
827 if( id == 1 .and. .not. allocated(luse2usgs) ) then
828 !allocate( luse2usgs(config_flags%num_land_cat),stat=astat )
829 print*,"num_land_cat: ", num_land_cat
830 allocate( luse2usgs(num_land_cat),stat=astat )
831 if( astat /= 0 ) then
832 CALL wrf_message( 'ftuv_init: failed to allocate luse2usgs')
835 if( trim(mminlu_loc) == 'USGS' ) then
836 !luse2usgs(:) = (/ (i,i=1,config_flags%num_land_cat) /)
837 luse2usgs(:) = (/ (i,i=1,num_land_cat) /)
838 elseif( trim(mminlu_loc) == 'MODIFIED_IGBP_MODIS_NOAH' ) then
839 luse2usgs(:) = (/ 14,13,12,11,15,8,9,10,10,7, &
840 17,4,1,5,24,19,16,21,22,23 /)
848 !---------------------------------------------------------------------
849 ! ... initialize aerosol routine
850 !---------------------------------------------------------------------
851 if( id == 1 .and. .not. photo_inti_initialized ) then
852 write(*,*) 'ftuv_init: initializing aerosol routine'
854 write(*,*) 'ftuv_init: finished'
855 photo_inti_initialized = .true.
858 end subroutine ftuv_init
861 subroutine handle_ncerr( ret, mes )
862 !---------------------------------------------------------------------
863 ! ... netcdf error handling routine
864 !---------------------------------------------------------------------
868 !---------------------------------------------------------------------
869 ! ... dummy arguments
870 !---------------------------------------------------------------------
871 integer, intent(in) :: ret
872 character(len=*), intent(in) :: mes
876 if( ret /= nf_noerr ) then
877 call wrf_message( trim(mes) )
878 call wrf_message( trim(nf_strerror(ret)) )
882 end subroutine handle_ncerr
885 subroutine photo_inti( chem_opt, nlev, ztopin )
887 use module_wave_data, only : nw, wl, wave_data_inti
888 use module_ftuv_subs, only : nwint, wlint, schu_inti, inter_inti
889 use module_state_description, only : mozart_kpp, mozcart_kpp, &
891 mozart_mosaic_4bin_kpp,&
892 mozart_mosaic_4bin_aq_kpp
896 !---------------------------------------------------------------------
898 !---------------------------------------------------------------------
899 integer, intent(in) :: chem_opt
900 integer, intent(in) :: nlev
901 real(dp), intent(in) :: ztopin
903 !---------------------------------------------------------------------
905 !---------------------------------------------------------------------
906 integer :: k, kdis, nabv, iw
909 if( chem_opt /= MOZART_KPP .and. &
910 chem_opt /= MOZCART_KPP .and. &
911 chem_opt /= T1_MOZCART_KPP .and. &
912 chem_opt /= MOZART_MOSAIC_4BIN_KPP .and. &
913 chem_opt /= MOZART_MOSAIC_4BIN_AQ_KPP ) then
914 !---------------------------------------------------------------------
915 ! change unit from m to km
916 !---------------------------------------------------------------------
918 !---------------------------------------------------------------------
919 ! set the top exo model level
920 !---------------------------------------------------------------------
922 if( ztop < zref(k) ) then
926 if( k == 1 .or. k > nref ) then
927 call wrf_message( 'photo_inti: ztop is not in zref range' )
934 if( mod(kdis,2) /= 0 ) then
938 write(*,*) '******************************************'
939 write(*,*) 'photo_inti: kcon,kdis,nabv,nlev,nz = ',kcon,kdis,nabv,nlev,nz
940 write(*,*) '******************************************'
947 !---------------------------------------------------------------------
948 ! set albedo for land
949 !---------------------------------------------------------------------
951 if( wl(iw)<400.0_dp ) then
952 albedo(iw,1) = 0.05_dp
953 else if( (wl(iw)>=400.0_dp ) .and. (wl(iw)<450.0_dp) ) then
954 albedo(iw,1) = 0.06_dp
955 else if( (wl(iw)>=450.0_dp ) .and. (wl(iw)<500.0_dp) ) then
956 albedo(iw,1) = 0.08_dp
957 else if( (wl(iw)>=500.0_dp ) .and. (wl(iw)<550.0_dp) ) then
958 albedo(iw,1) = 0.10_dp
959 else if( (wl(iw)>=550.0_dp ) .and. (wl(iw)<600.0_dp) ) then
960 albedo(iw,1) = 0.11_dp
961 else if( (wl(iw)>=600.0_dp ) .and. (wl(iw)<640.0_dp) ) then
962 albedo(iw,1) = 0.12_dp
963 else if( (wl(iw)>=640.0_dp ) .and. (wl(iw)<660.0_dp) ) then
964 albedo(iw,1) = 0.135_dp
965 else if( wl(iw)>=660.0_dp ) then
966 albedo(iw,1) = 0.15_dp
970 !---------------------------------------------------------------------
971 ! set albedo for sea water
973 ! For mozart_kpp these are interpolated from reflectance values
974 ! for IGBP type 17 (ocean water). Source: NASA LARC
975 ! (http://www-surf.larc.nasa.gov/surf/pages/explan.html)
976 !---------------------------------------------------------------------
977 if( chem_opt == MOZART_KPP .or. &
978 chem_opt == MOZCART_KPP .or. &
979 chem_opt == T1_MOZCART_KPP .or. &
980 chem_opt == MOZART_MOSAIC_4BIN_KPP .or. &
981 chem_opt == MOZART_MOSAIC_4BIN_AQ_KPP) then
982 albedo(1:17,2) = (/ 0.0747_dp, 0.0755_dp, 0.0767_dp, 0.0783_dp, 0.0802_dp, &
983 0.0825_dp, 0.0852_dp, 0.0882_dp, 0.0914_dp, 0.0908_dp, &
984 0.0763_dp, 0.0725_dp, 0.0689_dp, 0.0632_dp, 0.0570_dp, &
985 0.0585_dp, 0.0535_dp /)
987 albedo(1:17,2) = (/ 0.8228_dp, 0.8140_dp, 0.8000_dp, 0.7820_dp, 0.7600_dp, &
988 0.7340_dp, 0.7040_dp, 0.6700_dp, 0.6340_dp, 0.4782_dp, &
989 0.3492_dp, 0.3000_dp, 0.2700_dp, 0.2400_dp, 0.1700_dp, &
990 0.0800_dp, 0.0600_dp /)
993 !---------------------------------------------------------------------
994 ! intialize other modules
995 !---------------------------------------------------------------------
997 call wave_data_inti( nz )
998 call inter_inti( nw, wl, nwint, wlint )
1000 end subroutine photo_inti
1002 subroutine photo( chem_opt, nlev, njout, julday, gmtp, alat, &
1003 along, o3top, o2top, o3toms, lu, zin, tlevin, &
1004 airlevin, rhin, xlwcin, o3in, acb1in, &
1005 acb2in, aoc1in, aoc2in, aantin, aso4in, &
1006 asalin, tauaer300in,tauaer400in,tauaer600in,tauaer999in, &
1007 waer300in, waer400in, waer600in, waer999in, &
1008 gaer300in, gaer400in, gaer600in, gaer999in, &
1009 aer_ra_feedback, prate, radfld, adjcoe, prate0 )
1011 use module_ftuv_subs, only : calc_zenith, photoin
1015 !----------------------------------------------------
1017 !----------------------------------------------------
1018 integer, intent(in) :: chem_opt
1019 integer, intent(in) :: lu
1020 integer, intent(in) :: nlev, njout
1021 integer, intent(in) :: julday
1022 real(dp), intent(in) :: gmtp
1023 real(dp), intent(in) :: alat, along
1024 real(dp), intent(in) :: o3toms
1025 real(dp), intent(in) :: o3top
1026 real(dp), intent(in) :: o2top
1028 real(dp), intent(in) :: zin(nlev)
1029 real(dp), intent(in) :: tlevin(nlev)
1030 real(dp), intent(in) :: airlevin(nlev)
1031 real(dp), intent(in) :: rhin(nlev)
1032 real(dp), intent(in) :: xlwcin(nlev)
1033 real(dp), intent(in) :: o3in(nlev)
1034 real(dp), intent(in) :: acb1in(nlev)
1035 real(dp), intent(in) :: acb2in(nlev)
1036 real(dp), intent(in) :: aoc1in(nlev)
1037 real(dp), intent(in) :: aoc2in(nlev)
1038 real(dp), intent(in) :: aantin(nlev)
1039 real(dp), intent(in) :: aso4in(nlev)
1040 real(dp), intent(in) :: asalin(nlev)
1042 ! rajesh: declare dust variables
1043 real(dp), intent(in) :: tauaer300in(nlev-1)
1044 real(dp), intent(in) :: tauaer400in(nlev-1)
1045 real(dp), intent(in) :: tauaer600in(nlev-1)
1046 real(dp), intent(in) :: tauaer999in(nlev-1)
1047 real(dp), intent(in) :: waer300in(nlev-1)
1048 real(dp), intent(in) :: waer400in(nlev-1)
1049 real(dp), intent(in) :: waer600in(nlev-1)
1050 real(dp), intent(in) :: waer999in(nlev-1)
1051 real(dp), intent(in) :: gaer300in(nlev-1)
1052 real(dp), intent(in) :: gaer400in(nlev-1)
1053 real(dp), intent(in) :: gaer600in(nlev-1)
1054 real(dp), intent(in) :: gaer999in(nlev-1)
1055 INTEGER, INTENT(IN) :: aer_ra_feedback
1057 !----------------------------------------------------
1059 !----------------------------------------------------
1060 real(dp), intent(out) :: prate(nlev,njout)
1061 real(dp), intent(out) :: radfld(nz,nw-1)
1062 real(dp), intent(out) :: adjcoe(nz,njout)
1063 real(dp), intent(out) :: prate0(nz,njout)
1065 !----------------------------------------------------
1067 !----------------------------------------------------
1068 integer :: astat, istat
1070 real(dp) :: azim, zen
1071 real(dp), allocatable :: z_ph(:), tlev_ph(:), tlay_ph(:), airlev_ph(:)
1072 real(dp), allocatable :: rh_ph(:), xlwc_ph(:)
1073 real(dp), allocatable :: o3_ph(:)
1074 real(dp), allocatable :: acb1_ph(:), acb2_ph(:)
1075 real(dp), allocatable :: aoc1_ph(:), aoc2_ph(:)
1076 real(dp), allocatable :: aant_ph(:), aso4_ph(:), asal_ph(:)
1078 ! rajesh: declare allocatable variables for aerosol optical properties
1079 real(dp), allocatable :: tauaer300_ph(:), tauaer400_ph(:), &
1080 tauaer600_ph(:), tauaer999_ph(:), &
1081 waer300_ph(:), waer400_ph(:), &
1082 waer600_ph(:), waer999_ph(:), &
1083 gaer300_ph(:), gaer400_ph(:), &
1084 gaer600_ph(:), gaer999_ph(:)
1085 real(dp), allocatable :: ftuv(:,:)
1087 !-----------------------------------------------------------------------------
1088 ! Now xx-ftuv only considers the following 28 photolysis reactions ...
1089 !-----------------------------------------------------------------------------
1090 ! 1 o2 + hv -> o + o
1091 ! 2 o3 -> o2 + o(1d)
1092 ! 3 o3 -> o2 + o(3p)
1093 ! 4 no2 -> no + o(3p)
1095 ! 6 no3 -> no2 + o(3p)
1096 ! 7 n2o5 -> no3 + no + o(3p)
1097 ! 8 n2o5 -> no3 + no2
1098 ! 9 n2o + hv -> n2 + o(1d)
1099 ! 10 ho2 + hv -> oh + o
1101 ! 12 hno2 -> oh + no
1102 ! 13 hno3 -> oh + no2
1103 ! 14 hno4 -> ho2 + no2
1104 ! 15 ch2o -> h + hco
1105 ! 16 ch2o -> h2 + co
1106 ! 17 ch3cho -> ch3 + hco
1107 ! 18 ch3cho -> ch4 + co
1108 ! 19 ch3cho -> ch3co + h
1109 ! 20 c2h5cho -> c2h5 + hco
1110 ! 21 chocho -> products
1111 ! 22 ch3cocho -> products
1113 ! 24 ch3ooh -> ch3o + oh
1114 ! 25 ch3ono2 -> ch3o+no2
1115 ! 26 pan + hv -> products
1116 ! 27 mvk + hv -> products
1117 ! 28 macr + hv -> products
1118 ! 29 hyac + hv -> products
1119 ! 30 glyald + hv -> products
1120 !-----------------------------------------------------------------------------
1122 !-----------------------------------------------------------------------------
1123 ! solar zenith angle calculation
1124 !-----------------------------------------------------------------------------
1125 call calc_zenith( alat, along, julday, gmtp, azim, zen )
1126 if( zen == 90.0_dp ) then
1128 elseif( zen >= 95.0_dp ) then
1133 !---------------------------------------------------------------------
1134 ! allocate memory space
1135 !---------------------------------------------------------------------
1137 allocate( ftuv(nz,njout), stat=istat )
1138 astat = astat + istat
1139 allocate( z_ph(nz), tlev_ph(nz), tlay_ph(nz-1), airlev_ph(nz), stat=istat )
1140 astat = astat + istat
1141 allocate( rh_ph(nz), xlwc_ph(nz), stat=istat )
1142 astat = astat + istat
1143 allocate( o3_ph(nz), stat=istat )
1144 astat = astat + istat
1145 allocate( acb1_ph(nz), acb2_ph(nz), aoc1_ph(nz), aoc2_ph(nz), stat=istat )
1146 astat = astat + istat
1147 allocate( aant_ph(nz), aso4_ph(nz), asal_ph(nz), stat=istat )
1148 astat = astat + istat
1150 ! rajesh: allocate memory space to aerosol optical property variables
1151 allocate( tauaer300_ph(nz-1), tauaer400_ph(nz-1), tauaer600_ph(nz-1), &
1152 tauaer999_ph(nz-1), stat=istat)
1153 astat = astat + istat
1154 allocate( waer300_ph(nz-1), waer400_ph(nz-1), waer600_ph(nz-1), &
1155 waer999_ph(nz-1), stat=istat)
1156 astat = astat + istat
1157 allocate( gaer300_ph(nz-1), gaer400_ph(nz-1), gaer600_ph(nz-1), &
1158 gaer999_ph(nz-1), stat=istat)
1159 astat = astat + istat
1161 if( astat /= 0 ) then
1162 call wrf_message( 'ftuv_driver: failed to allocate _ph arrays' )
1176 ! rajesh: Initialize variables to zero
1177 tauaer300_ph(:) = 0.0_dp
1178 tauaer400_ph(:) = 0.0_dp
1179 tauaer600_ph(:) = 0.0_dp
1180 tauaer999_ph(:) = 0.0_dp
1181 waer300_ph(:) = 0.0_dp
1182 waer400_ph(:) = 0.0_dp
1183 waer600_ph(:) = 0.0_dp
1184 waer999_ph(:) = 0.0_dp
1185 gaer300_ph(:) = 0.0_dp
1186 gaer400_ph(:) = 0.0_dp
1187 gaer600_ph(:) = 0.0_dp
1188 gaer999_ph(:) = 0.0_dp
1190 !----------------------------------------------------
1191 ! assgin vertical profiles
1192 ! model levels first
1193 !----------------------------------------------------
1194 z_ph(1:nlev) = zin(1:nlev)
1195 tlev_ph(1:nlev) = tlevin(1:nlev)
1196 airlev_ph(1:nlev) = airlevin(1:nlev)
1197 rh_ph(1:nlev) = rhin(1:nlev)
1198 xlwc_ph(1:nlev) = xlwcin(1:nlev)
1199 o3_ph(1:nlev) = o3in(1:nlev)
1200 acb1_ph(1:nlev) = acb1in(1:nlev)
1201 acb2_ph(1:nlev) = acb2in(1:nlev)
1202 aoc1_ph(1:nlev) = aoc1in(1:nlev)
1203 aoc2_ph(1:nlev) = aoc2in(1:nlev)
1204 aant_ph(1:nlev) = aantin(1:nlev)
1205 aso4_ph(1:nlev) = aso4in(1:nlev)
1206 asal_ph(1:nlev) = asalin(1:nlev)
1209 tauaer300_ph(1:nlev-1) = tauaer300in(1:nlev-1)
1210 tauaer400_ph(1:nlev-1) = tauaer400in(1:nlev-1)
1211 tauaer600_ph(1:nlev-1) = tauaer600in(1:nlev-1)
1212 tauaer999_ph(1:nlev-1) = tauaer999in(1:nlev-1)
1213 waer300_ph(1:nlev-1) = waer300in(1:nlev-1)
1214 waer400_ph(1:nlev-1) = waer400in(1:nlev-1)
1215 waer600_ph(1:nlev-1) = waer600in(1:nlev-1)
1216 waer999_ph(1:nlev-1) = waer999in(1:nlev-1)
1217 gaer300_ph(1:nlev-1) = gaer300in(1:nlev-1)
1218 gaer400_ph(1:nlev-1) = gaer400in(1:nlev-1)
1219 gaer600_ph(1:nlev-1) = gaer600in(1:nlev-1)
1220 gaer999_ph(1:nlev-1) = gaer999in(1:nlev-1)
1222 tlay_ph(1:nlev-1) = 0.5_dp*(tlev_ph(1:nlev-1) + tlev_ph(2:nlev))
1224 !----------------------------------------------------
1226 !----------------------------------------------------
1227 if( nz > nlev ) then
1228 z_ph(nlev+1:nz-1) = zref(kcon:nref:2)
1229 tlev_ph(nlev+1:nz-1) = tref(kcon:nref:2)
1230 airlev_ph(nlev+1:nz-1) = airref(kcon:nref:2)
1231 o3_ph(nlev+1:nz-1) = o3ref(kcon:nref:2)/airref(kcon:nref:2) ! Changed to vmr
1233 z_ph(nz) = zref(nref)
1234 tlev_ph(nz) = tref(nref)
1235 airlev_ph(nz) = airref(nref)
1236 o3_ph(nz) = o3ref(nref)/airref(nref)
1237 tlay_ph(nlev) = 0.5_dp*(tlev_ph(nlev) + tref(kcon))
1238 tlay_ph(nlev+1:) = 0.5_dp*( tlev_ph(nlev+1:nz-1) + tlev_ph(nlev+2:) )
1242 call photoin( chem_opt, nz, zen, o3toms, esfact, &
1243 o3top, o2top, albedo(:,lu), z_ph, tlev_ph, &
1244 tlay_ph, airlev_ph, rh_ph, xlwc_ph, o3_ph, &
1245 acb1_ph, acb2_ph, aoc1_ph, aoc2_ph, aant_ph, &
1247 tauaer300_ph, tauaer400_ph, tauaer600_ph, &
1248 tauaer999_ph, waer300_ph, waer400_ph, &
1249 waer600_ph, waer999_ph, gaer300_ph, &
1250 gaer400_ph, gaer600_ph, gaer999_ph, &
1251 aer_ra_feedback, ftuv, adjcoe, radfld )
1254 prate(1:nlev-1,n) = ftuv(2:nlev,n)
1255 prate0(1:nz,n) = ftuv(1:nz,n)
1258 deallocate( ftuv, z_ph, tlev_ph, tlay_ph, airlev_ph, rh_ph, xlwc_ph, &
1259 o3_ph, acb1_ph, acb2_ph, aoc1_ph, aoc2_ph, aant_ph, aso4_ph, &
1260 asal_ph, tauaer300_ph, tauaer400_ph,tauaer600_ph, tauaer999_ph, &
1261 waer300_ph, waer400_ph, waer600_ph, waer999_ph, &
1262 gaer300_ph, gaer400_ph, gaer600_ph, gaer999_ph )
1264 end subroutine photo
1266 subroutine ftuv_timestep_init( id, julday )
1267 !-----------------------------------------------------------------------------
1268 ! ... setup the time interpolation
1269 !-----------------------------------------------------------------------------
1271 use module_ftuv_subs, only : sundis
1275 !-----------------------------------------------------------------------------
1276 ! ... dummy arguments
1277 !-----------------------------------------------------------------------------
1278 integer, intent(in) :: id ! domain id
1279 integer, intent(in) :: julday ! day of year at present time step
1281 !-----------------------------------------------------------------------------
1282 ! ... local variables
1283 !-----------------------------------------------------------------------------
1287 calday = real( julday,kind=dp)
1288 if( calday < col_dens(id)%day_of_year(1) ) then
1291 dels = (365._dp + calday - col_dens(id)%day_of_year(12)) &
1292 / (365._dp + col_dens(id)%day_of_year(1) - col_dens(id)%day_of_year(12))
1293 else if( calday >= col_dens(id)%day_of_year(12) ) then
1296 dels = (calday - col_dens(id)%day_of_year(12)) &
1297 / (365. + col_dens(id)%day_of_year(1) - col_dens(id)%day_of_year(12))
1300 if( calday >= col_dens(id)%day_of_year(m) ) then
1306 dels = (calday - col_dens(id)%day_of_year(m)) / (col_dens(id)%day_of_year(m+1) - col_dens(id)%day_of_year(m))
1308 !-----------------------------------------------------------------------------
1309 ! set solar distance factor
1310 !-----------------------------------------------------------------------------
1311 if( curjulday /= julday ) then
1313 call sundis( curjulday, esfact )
1316 end subroutine ftuv_timestep_init
1318 subroutine p_interp( o2_exo_col, o3_exo_col, ptop, &
1319 id, its, ite, jts, jte )
1320 !---------------------------------------------------------------
1321 ! ... pressure interpolation for exo col density
1322 !---------------------------------------------------------------
1326 !---------------------------------------------------------------
1327 ! ... dummy arguments
1328 !---------------------------------------------------------------
1329 integer, intent(in) :: id
1330 integer, intent(in) :: its, ite
1331 integer, intent(in) :: jts, jte
1332 real(dp), intent(in) :: ptop(its:ite,jts:jte) ! pressure at photolysis top (hPa)
1333 real(dp), intent(out) :: o2_exo_col(its:ite,jts:jte) ! exo model o2 column density (molecules/cm^2)
1334 real(dp), intent(out) :: o3_exo_col(its:ite,jts:jte) ! exo model o3 column density (molecules/cm^2)
1336 !---------------------------------------------------------------
1337 ! ... local variables
1338 !---------------------------------------------------------------
1339 integer :: i, j, k, ku, kl
1342 real(dp) :: tint_vals(2)
1349 if( pinterp < col_dens(id)%col_levs(1) ) then
1354 do ku = 2,col_dens(id)%ncoldens_levs
1355 if( pinterp <= col_dens(id)%col_levs(ku) ) then
1357 delp = log( pinterp/col_dens(id)%col_levs(kl) )/log( col_dens(id)%col_levs(ku)/col_dens(id)%col_levs(kl) )
1362 tint_vals(1) = col_dens(id)%o2_col_dens(i,j,kl,last) &
1363 + delp * (col_dens(id)%o2_col_dens(i,j,ku,last) &
1364 - col_dens(id)%o2_col_dens(i,j,kl,last))
1365 tint_vals(2) = col_dens(id)%o2_col_dens(i,j,kl,next) &
1366 + delp * (col_dens(id)%o2_col_dens(i,j,ku,next) &
1367 - col_dens(id)%o2_col_dens(i,j,kl,next))
1368 o2_exo_col(i,j) = tint_vals(1) + dels * (tint_vals(2) - tint_vals(1))
1369 tint_vals(1) = col_dens(id)%o3_col_dens(i,j,kl,last) &
1370 + delp * (col_dens(id)%o3_col_dens(i,j,ku,last) &
1371 - col_dens(id)%o3_col_dens(i,j,kl,last))
1372 tint_vals(2) = col_dens(id)%o3_col_dens(i,j,kl,next) &
1373 + delp * (col_dens(id)%o3_col_dens(i,j,ku,next) &
1374 - col_dens(id)%o3_col_dens(i,j,kl,next))
1375 o3_exo_col(i,j) = tint_vals(1) + dels * (tint_vals(2) - tint_vals(1))
1379 end subroutine p_interp
1381 end module module_ftuv_driver