Line data Source code
1 : module mo_drydep
2 :
3 : !---------------------------------------------------------------------
4 : ! ... Dry deposition
5 : !---------------------------------------------------------------------
6 :
7 : use shr_kind_mod, only : r8 => shr_kind_r8, shr_kind_cl
8 : use chem_mods, only : gas_pcnst
9 : use pmgrid, only : plev
10 : use spmd_utils, only : masterproc
11 : use ppgrid, only : pcols, begchunk, endchunk
12 : use mo_tracname, only : solsym
13 : use cam_abortutils, only : endrun
14 : use ioFileMod, only : getfil
15 : use pio
16 : use cam_pio_utils, only : cam_pio_openfile, cam_pio_closefile
17 : use cam_logfile, only : iulog
18 : use dyn_grid, only : get_dyn_grid_parm, get_horiz_grid_d
19 : use scamMod, only : single_column
20 :
21 : use shr_drydep_mod, only : nddvels => n_drydep, drydep_list, mapping
22 : use physconst, only : karman
23 :
24 : use infnan, only : nan, assignment(=)
25 :
26 : implicit none
27 :
28 : save
29 :
30 : interface drydep_inti
31 : module procedure dvel_inti_xactive
32 : end interface
33 :
34 : interface drydep
35 : module procedure drydep_fromlnd
36 : end interface
37 :
38 : private
39 :
40 : public :: drydep_inti, drydep, has_drydep
41 : public :: drydep_update
42 : public :: n_land_type, fraction_landuse, drydep_srf_file
43 :
44 : integer :: pan_ndx, mpan_ndx, o3_ndx, ch4_ndx, co_ndx, h2_ndx, ch3cooh_ndx
45 : integer :: sogm_ndx, sogi_ndx, sogt_ndx, sogb_ndx, sogx_ndx
46 :
47 : integer :: so2_ndx, ch3cn_ndx, hcn_ndx, hcooh_ndx
48 :
49 : integer :: o3a_ndx,xpan_ndx,xmpan_ndx
50 :
51 : integer :: cohc_ndx=-1, come_ndx=-1
52 : integer, parameter :: NTAGS = 50
53 : integer :: cotag_ndx(NTAGS)
54 : integer :: tag_cnt
55 :
56 : real(r8), parameter :: small_value = 1.e-36_r8
57 : real(r8), parameter :: large_value = 1.e36_r8
58 : real(r8), parameter :: diffm = 1.789e-5_r8
59 : real(r8), parameter :: diffk = 1.461e-5_r8
60 : real(r8), parameter :: difft = 2.060e-5_r8
61 : real(r8), parameter :: vonkar = karman
62 : real(r8), parameter :: ric = 0.2_r8
63 : real(r8), parameter :: r = 287.04_r8
64 : real(r8), parameter :: cp = 1004._r8
65 : real(r8), parameter :: grav = 9.81_r8
66 : real(r8), parameter :: p00 = 100000._r8
67 : real(r8), parameter :: wh2o = 18.0153_r8
68 : real(r8), parameter :: ph = 1.e-5_r8
69 : real(r8), parameter :: ph_inv = 1._r8/ph
70 : real(r8), parameter :: rovcp = r/cp
71 :
72 : logical, public :: has_dvel(gas_pcnst) = .false.
73 : integer :: map_dvel(gas_pcnst) = 0
74 :
75 : real(r8), protected, allocatable :: fraction_landuse(:,:,:)
76 : real(r8), allocatable, dimension(:,:,:) :: dep_ra ! [s/m] aerodynamic resistance
77 : real(r8), allocatable, dimension(:,:,:) :: dep_rb ! [s/m] resistance across sublayer
78 : integer, parameter :: n_land_type = 11
79 :
80 : integer, allocatable :: spc_ndx(:) ! nddvels
81 : real(r8), public :: crb
82 :
83 : type lnd_dvel_type
84 : real(r8), pointer :: dvel(:,:) ! deposition velocity over land (cm/s)
85 : end type lnd_dvel_type
86 :
87 : type(lnd_dvel_type), allocatable :: lnd(:)
88 : character(len=SHR_KIND_CL) :: drydep_srf_file
89 :
90 : contains
91 :
92 : !---------------------------------------------------------------------------
93 : !---------------------------------------------------------------------------
94 1536 : subroutine dvel_inti_fromlnd
95 : use mo_chem_utls, only : get_spc_ndx
96 : use cam_abortutils, only : endrun
97 :
98 : integer :: ispc
99 :
100 4608 : allocate(spc_ndx(nddvels))
101 4608 : allocate( lnd(begchunk:endchunk) )
102 :
103 156672 : do ispc = 1,nddvels
104 :
105 155136 : spc_ndx(ispc) = get_spc_ndx(drydep_list(ispc))
106 156672 : if (spc_ndx(ispc) < 1) then
107 0 : write(*,*) 'drydep_inti: '//trim(drydep_list(ispc))//' is not included in species set'
108 0 : call endrun('drydep_init: invalid dry deposition species')
109 : endif
110 :
111 : enddo
112 :
113 1536 : crb = (difft/diffm)**(2._r8/3._r8) !.666666_r8
114 :
115 1536 : endsubroutine dvel_inti_fromlnd
116 :
117 : !-------------------------------------------------------------------------------------
118 : !-------------------------------------------------------------------------------------
119 72960 : subroutine drydep_update( state, cam_in )
120 : use physics_types, only : physics_state
121 : use camsrfexch, only : cam_in_t
122 :
123 : type(physics_state), intent(in) :: state ! Physics state variables
124 : type(cam_in_t), intent(in) :: cam_in
125 :
126 72960 : if (nddvels<1) return
127 :
128 72960 : lnd(state%lchnk)%dvel => cam_in%depvel
129 :
130 72960 : end subroutine drydep_update
131 :
132 : !-------------------------------------------------------------------------------------
133 : !-------------------------------------------------------------------------------------
134 72960 : subroutine drydep_fromlnd( ocnfrac, icefrac, sfc_temp, pressure_sfc, &
135 : wind_speed, spec_hum, air_temp, pressure_10m, rain, &
136 72960 : snow, solar_flux, dvelocity, dflx, mmr, &
137 : tv, ncol, lchnk )
138 :
139 : !-------------------------------------------------------------------------------------
140 : ! combines the deposition velocities provided by the land model with deposition
141 : ! velocities over ocean and sea ice
142 : !-------------------------------------------------------------------------------------
143 :
144 72960 : use ppgrid, only : pcols
145 : use chem_mods, only : gas_pcnst
146 :
147 : #if (defined OFFLINE_DYN)
148 : use metdata, only: get_met_fields
149 : #endif
150 :
151 : !-------------------------------------------------------------------------------------
152 : ! ... dummy arguments
153 : !-------------------------------------------------------------------------------------
154 :
155 : real(r8), intent(in) :: icefrac(pcols)
156 : real(r8), intent(in) :: ocnfrac(pcols)
157 : integer, intent(in) :: ncol
158 : integer, intent(in) :: lchnk ! chunk number
159 : real(r8), intent(in) :: sfc_temp(pcols) ! surface temperature (K)
160 : real(r8), intent(in) :: pressure_sfc(pcols) ! surface pressure (Pa)
161 : real(r8), intent(in) :: wind_speed(pcols) ! 10 meter wind speed (m/s)
162 : real(r8), intent(in) :: spec_hum(pcols) ! specific humidity (kg/kg)
163 : real(r8), intent(in) :: air_temp(pcols) ! surface air temperature (K)
164 : real(r8), intent(in) :: pressure_10m(pcols) ! 10 meter pressure (Pa)
165 : real(r8), intent(in) :: rain(pcols)
166 : real(r8), intent(in) :: snow(pcols) ! snow height (m)
167 : real(r8), intent(in) :: solar_flux(pcols) ! direct shortwave radiation at surface (W/m^2)
168 : real(r8), intent(in) :: tv(pcols) ! potential temperature
169 : real(r8), intent(in) :: mmr(pcols,plev,gas_pcnst) ! constituent concentration (kg/kg)
170 : real(r8), intent(out) :: dvelocity(ncol,gas_pcnst) ! deposition velocity (cm/s)
171 : real(r8), intent(inout) :: dflx(pcols,gas_pcnst) ! deposition flux (/cm^2/s)
172 :
173 : !-------------------------------------------------------------------------------------
174 : ! ... local variables
175 : !-------------------------------------------------------------------------------------
176 145920 : real(r8) :: ocnice_dvel(ncol,gas_pcnst)
177 : real(r8) :: ocnice_dflx(pcols,gas_pcnst)
178 :
179 145920 : real(r8), dimension(ncol) :: term ! work array
180 : integer :: ispec
181 : real(r8) :: lndfrac(pcols)
182 : #if (defined OFFLINE_DYN)
183 : real(r8) :: met_ocnfrac(pcols)
184 : real(r8) :: met_icefrac(pcols)
185 : #endif
186 : integer :: i
187 :
188 1196544 : lndfrac(:ncol) = 1._r8 - ocnfrac(:ncol) - icefrac(:ncol)
189 :
190 1123584 : where( lndfrac(:ncol) < 0._r8 )
191 : lndfrac(:ncol) = 0._r8
192 : endwhere
193 :
194 : #if (defined OFFLINE_DYN)
195 : call get_met_fields(lndfrac, met_ocnfrac, met_icefrac, lchnk, ncol)
196 : #endif
197 :
198 : !-------------------------------------------------------------------------------------
199 : ! ... initialize
200 : !-------------------------------------------------------------------------------------
201 227036928 : dvelocity(:,:) = 0._r8
202 :
203 : !-------------------------------------------------------------------------------------
204 : ! ... compute the dep velocities over ocean and sea ice
205 : ! land type 7 is used for ocean
206 : ! land type 8 is used for sea ice
207 : !-------------------------------------------------------------------------------------
208 : call drydep_xactive( sfc_temp, pressure_sfc, &
209 : wind_speed, spec_hum, air_temp, pressure_10m, rain, &
210 : snow, solar_flux, ocnice_dvel, ocnice_dflx, mmr, &
211 : tv, ncol, lchnk, &
212 : #if (defined OFFLINE_DYN)
213 : ocnfrc=met_ocnfrac,icefrc=met_icefrac, beglandtype=7, endlandtype=8 )
214 : #else
215 72960 : ocnfrc=ocnfrac,icefrc=icefrac, beglandtype=7, endlandtype=8 )
216 : #endif
217 1123584 : term(:ncol) = 1.e-2_r8 * pressure_10m(:ncol) / (r*tv(:ncol))
218 :
219 7441920 : do ispec = 1,nddvels
220 : !-------------------------------------------------------------------------------------
221 : ! ... merge the land component with the non-land component
222 : ! ocn and ice already have fractions factored in
223 : !-------------------------------------------------------------------------------------
224 0 : dvelocity(:ncol,spc_ndx(ispec)) = lnd(lchnk)%dvel(:ncol,ispec)*lndfrac(:ncol) &
225 113554944 : + ocnice_dvel(:ncol,spc_ndx(ispec))
226 : enddo
227 :
228 : !-------------------------------------------------------------------------------------
229 : ! ... special adjustments
230 : !-------------------------------------------------------------------------------------
231 72960 : if( mpan_ndx>0 ) then
232 1123584 : dvelocity(:ncol,mpan_ndx) = dvelocity(:ncol,mpan_ndx)/3._r8
233 : endif
234 72960 : if( xmpan_ndx>0 ) then
235 0 : dvelocity(:ncol,xmpan_ndx) = dvelocity(:ncol,xmpan_ndx)/3._r8
236 : endif
237 72960 : if( hcn_ndx>0 ) then
238 1123584 : dvelocity(:ncol,hcn_ndx) = ocnice_dvel(:ncol,hcn_ndx) ! should be zero over land
239 : endif
240 72960 : if( ch3cn_ndx>0 ) then
241 1123584 : dvelocity(:ncol,ch3cn_ndx) = ocnice_dvel(:ncol,ch3cn_ndx) ! should be zero over land
242 : endif
243 :
244 : ! HCOOH, use CH3COOH dep.vel
245 72960 : if( hcooh_ndx > 0 .and. ch3cooh_ndx > 0 ) then
246 0 : if( has_dvel(hcooh_ndx) ) then
247 0 : dvelocity(:ncol,hcooh_ndx) = dvelocity(:ncol,ch3cooh_ndx)
248 : end if
249 : end if
250 :
251 : !-------------------------------------------------------------------------------------
252 : ! ... assign CO tags to CO
253 : ! put this kludge in for now ...
254 : ! -- should be able to set all these via the table mapping in shr_drydep_mod
255 : !-------------------------------------------------------------------------------------
256 72960 : if( cohc_ndx>0 .and. co_ndx>0 ) then
257 0 : dvelocity(:ncol,cohc_ndx) = dvelocity(:ncol,co_ndx)
258 0 : dflx(:ncol,cohc_ndx) = dvelocity(:ncol,co_ndx) * term(:ncol) * mmr(:ncol,plev,cohc_ndx)
259 : endif
260 72960 : if( come_ndx>0 .and. co_ndx>0 ) then
261 0 : dvelocity(:ncol,come_ndx) = dvelocity(:ncol,co_ndx)
262 0 : dflx(:ncol,come_ndx) = dvelocity(:ncol,co_ndx) * term(:ncol) * mmr(:ncol,plev,come_ndx)
263 : endif
264 :
265 72960 : if ( co_ndx>0 ) then
266 72960 : do i=1,tag_cnt
267 0 : dvelocity(:ncol,cotag_ndx(i)) = dvelocity(:ncol,co_ndx)
268 72960 : dflx(:ncol,cotag_ndx(i)) = dvelocity(:ncol,co_ndx) * term(:ncol) * mmr(:ncol,plev,cotag_ndx(i))
269 : enddo
270 : endif
271 :
272 7441920 : do ispec = 1,nddvels
273 : !-------------------------------------------------------------------------------------
274 : ! ... compute the deposition flux
275 : !-------------------------------------------------------------------------------------
276 113554944 : dflx(:ncol,spc_ndx(ispec)) = dvelocity(:ncol,spc_ndx(ispec)) * term(:ncol) * mmr(:ncol,plev,spc_ndx(ispec))
277 : end do
278 :
279 72960 : end subroutine drydep_fromlnd
280 :
281 : !-------------------------------------------------------------------------------------
282 : !-------------------------------------------------------------------------------------
283 1536 : subroutine dvel_inti_xactive( depvel_lnd_file )
284 : !-------------------------------------------------------------------------------------
285 : ! ... intialize interactive drydep
286 : !-------------------------------------------------------------------------------------
287 : use dycore, only : dycore_is
288 : use mo_chem_utls, only : get_spc_ndx
289 : use phys_control, only : phys_getopts
290 :
291 : !-------------------------------------------------------------------------------------
292 : ! ... dummy arguments
293 : !-------------------------------------------------------------------------------------
294 : character(len=*), intent(in) :: depvel_lnd_file
295 :
296 : !-------------------------------------------------------------------------------------
297 : ! ... local variables
298 : !-------------------------------------------------------------------------------------
299 : integer :: i
300 : integer :: nlon_veg, nlat_veg, npft_veg
301 : integer :: dimid
302 : integer :: m
303 : integer :: astat
304 : integer :: plon, plat
305 : integer :: ierr, ndx
306 :
307 1536 : real(r8), allocatable :: vegetation_map(:,:,:)
308 1536 : real(r8), allocatable :: work(:,:)
309 1536 : real(r8), allocatable :: landmask(:,:)
310 1536 : real(r8), allocatable :: urban(:,:)
311 1536 : real(r8), allocatable :: lake(:,:)
312 1536 : real(r8), allocatable :: wetland(:,:)
313 1536 : real(r8), allocatable :: lon_veg_edge(:)
314 1536 : real(r8), allocatable :: lat_veg_edge(:)
315 :
316 : character(len=32) :: test_name
317 : character(len=4) :: tag_name
318 : type(file_desc_t) :: piofile
319 : type(var_desc_t) :: vid
320 :
321 : character(len=shr_kind_cl) :: locfn
322 : logical :: prog_modal_aero
323 :
324 : ! determine if modal aerosols are active so that fraction_landuse array is initialized for modal aerosal dry dep
325 1536 : call phys_getopts(prog_modal_aero_out=prog_modal_aero)
326 :
327 1536 : call dvel_inti_fromlnd()
328 :
329 1536 : if( masterproc ) then
330 2 : write(iulog,*) 'drydep_inti: following species have dry deposition'
331 204 : do i=1,nddvels
332 204 : if( len_trim(drydep_list(i)) > 0 ) then
333 202 : write(iulog,*) 'drydep_inti: '//trim(drydep_list(i))//' is requested to have dry dep'
334 : endif
335 : enddo
336 2 : write(iulog,*) 'drydep_inti:'
337 : endif
338 :
339 : !-------------------------------------------------------------------------------------
340 : ! ... get species indices
341 : !-------------------------------------------------------------------------------------
342 1536 : xpan_ndx = get_spc_ndx( 'XPAN' )
343 1536 : xmpan_ndx = get_spc_ndx( 'XMPAN' )
344 1536 : o3a_ndx = get_spc_ndx( 'O3A' )
345 :
346 1536 : ch4_ndx = get_spc_ndx( 'CH4' )
347 1536 : h2_ndx = get_spc_ndx( 'H2' )
348 1536 : co_ndx = get_spc_ndx( 'CO' )
349 1536 : pan_ndx = get_spc_ndx( 'PAN' )
350 1536 : mpan_ndx = get_spc_ndx( 'MPAN' )
351 1536 : o3_ndx = get_spc_ndx( 'OX' )
352 1536 : if( o3_ndx < 0 ) then
353 1536 : o3_ndx = get_spc_ndx( 'O3' )
354 : end if
355 1536 : so2_ndx = get_spc_ndx( 'SO2' )
356 1536 : ch3cooh_ndx = get_spc_ndx( 'CH3COOH')
357 :
358 1536 : sogm_ndx = get_spc_ndx( 'SOGM' )
359 1536 : sogi_ndx = get_spc_ndx( 'SOGI' )
360 1536 : sogt_ndx = get_spc_ndx( 'SOGT' )
361 1536 : sogb_ndx = get_spc_ndx( 'SOGB' )
362 1536 : sogx_ndx = get_spc_ndx( 'SOGX' )
363 :
364 1536 : hcn_ndx = get_spc_ndx( 'HCN')
365 1536 : ch3cn_ndx = get_spc_ndx( 'CH3CN')
366 :
367 1536 : cohc_ndx = get_spc_ndx( 'COhc' )
368 1536 : come_ndx = get_spc_ndx( 'COme' )
369 :
370 1536 : tag_cnt=0
371 78336 : cotag_ndx(:)=-1
372 78336 : do i = 1,NTAGS
373 76800 : write(tag_name,'(a2,i2.2)') 'CO',i
374 76800 : ndx = get_spc_ndx(tag_name)
375 78336 : if (ndx>0) then
376 0 : tag_cnt = tag_cnt+1
377 0 : cotag_ndx(tag_cnt) = ndx
378 : endif
379 : enddo
380 :
381 156672 : do i=1,nddvels
382 156672 : if ( mapping(i) > 0 ) then
383 155136 : test_name = drydep_list(i)
384 155136 : m = get_spc_ndx( test_name )
385 155136 : has_dvel(m) = .true.
386 155136 : map_dvel(m) = i
387 : endif
388 : enddo
389 :
390 1536 : if( all( .not. has_dvel(:) ) ) then
391 : return
392 : end if
393 :
394 : !---------------------------------------------------------------------------
395 : ! ... allocate module variables
396 : !---------------------------------------------------------------------------
397 4608 : allocate( dep_ra(pcols,n_land_type,begchunk:endchunk),stat=astat )
398 1536 : if( astat /= 0 ) then
399 0 : write(iulog,*) 'dvel_inti: failed to allocate dep_ra; error = ',astat
400 0 : call endrun('dvel_inti: failed to allocate dep_ra')
401 : end if
402 4608 : allocate( dep_rb(pcols,n_land_type,begchunk:endchunk),stat=astat )
403 1536 : if( astat /= 0 ) then
404 0 : write(iulog,*) 'dvel_inti: failed to allocate dep_rb; error = ',astat
405 0 : call endrun('dvel_inti: failed to allocate dep_rb')
406 : end if
407 :
408 1536 : if (.not.prog_modal_aero) then
409 : return
410 : endif
411 :
412 0 : allocate( fraction_landuse(pcols,n_land_type, begchunk:endchunk),stat=astat )
413 0 : if( astat /= 0 ) then
414 0 : write(iulog,*) 'dvel_inti: failed to allocate fraction_landuse; error = ',astat
415 0 : call endrun('dvel_inti: failed to allocate fraction_landuse')
416 : end if
417 0 : fraction_landuse = nan
418 :
419 0 : plon = get_dyn_grid_parm('plon')
420 0 : plat = get_dyn_grid_parm('plat')
421 :
422 0 : if(dycore_is('UNSTRUCTURED') ) then
423 0 : call get_landuse_and_soilw_from_file()
424 : else
425 : !---------------------------------------------------------------------------
426 : ! ... read landuse map
427 : !---------------------------------------------------------------------------
428 0 : call getfil (depvel_lnd_file, locfn, 0)
429 0 : call cam_pio_openfile (piofile, trim(locfn), PIO_NOWRITE)
430 : !---------------------------------------------------------------------------
431 : ! ... get the dimensions
432 : !---------------------------------------------------------------------------
433 0 : ierr = pio_inq_dimid( piofile, 'lon', dimid )
434 0 : ierr = pio_inq_dimlen( piofile, dimid, nlon_veg )
435 0 : ierr = pio_inq_dimid( piofile, 'lat', dimid )
436 0 : ierr = pio_inq_dimlen( piofile, dimid, nlat_veg )
437 0 : ierr = pio_inq_dimid( piofile, 'pft', dimid )
438 0 : ierr = pio_inq_dimlen( piofile, dimid, npft_veg )
439 : !---------------------------------------------------------------------------
440 : ! ... allocate arrays
441 : !---------------------------------------------------------------------------
442 0 : allocate( vegetation_map(nlon_veg,nlat_veg,npft_veg), work(nlon_veg,nlat_veg), stat=astat )
443 0 : if( astat /= 0 ) then
444 0 : write(iulog,*) 'dvel_inti: failed to allocate vegetation_map; error = ',astat
445 0 : call endrun('dvel_inti: failed to allocate vegetation_map')
446 : end if
447 : allocate( urban(nlon_veg,nlat_veg), lake(nlon_veg,nlat_veg), &
448 0 : landmask(nlon_veg,nlat_veg), wetland(nlon_veg,nlat_veg), stat=astat )
449 0 : if( astat /= 0 ) then
450 0 : write(iulog,*) 'dvel_inti: failed to allocate vegetation_map; error = ',astat
451 0 : call endrun('dvel_inti: failed to allocate vegetation_map')
452 : end if
453 0 : allocate( lon_veg_edge(nlon_veg+1), lat_veg_edge(nlat_veg+1), stat=astat )
454 0 : if( astat /= 0 ) then
455 0 : write(iulog,*) 'dvel_inti: failed to allocate vegetation lon, lat arrays; error = ',astat
456 0 : call endrun('dvel_inti: failed to allocate vegetation lon, lat arrays')
457 : end if
458 : !---------------------------------------------------------------------------
459 : ! ... read the vegetation map and landmask
460 : !---------------------------------------------------------------------------
461 0 : ierr = pio_inq_varid( piofile, 'PCT_PFT', vid )
462 0 : ierr = pio_get_var( piofile, vid, vegetation_map )
463 :
464 0 : ierr = pio_inq_varid( piofile, 'LANDMASK', vid )
465 0 : ierr = pio_get_var( piofile, vid, landmask )
466 :
467 0 : ierr = pio_inq_varid( piofile, 'PCT_URBAN', vid )
468 0 : ierr = pio_get_var( piofile, vid, urban )
469 :
470 0 : ierr = pio_inq_varid( piofile, 'PCT_LAKE', vid )
471 0 : ierr = pio_get_var( piofile, vid, lake )
472 :
473 0 : ierr = pio_inq_varid( piofile, 'PCT_WETLAND', vid )
474 0 : ierr = pio_get_var( piofile, vid, wetland )
475 :
476 0 : call cam_pio_closefile( piofile )
477 :
478 : !---------------------------------------------------------------------------
479 : ! scale vegetation, urban, lake, and wetland to fraction
480 : !---------------------------------------------------------------------------
481 0 : vegetation_map(:,:,:) = .01_r8 * vegetation_map(:,:,:)
482 0 : wetland(:,:) = .01_r8 * wetland(:,:)
483 0 : lake(:,:) = .01_r8 * lake(:,:)
484 0 : urban(:,:) = .01_r8 * urban(:,:)
485 : #ifdef DEBUG
486 0 : if(masterproc) then
487 0 : write(iulog,*) 'minmax vegetation_map ',minval(vegetation_map),maxval(vegetation_map)
488 0 : write(iulog,*) 'minmax wetland ',minval(wetland),maxval(wetland)
489 0 : write(iulog,*) 'minmax landmask ',minval(landmask),maxval(landmask)
490 : end if
491 : #endif
492 : !---------------------------------------------------------------------------
493 : ! ... define lat-lon of vegetation map (1x1)
494 : !---------------------------------------------------------------------------
495 0 : lat_veg_edge(:) = (/ (-90.0_r8 + (i-1),i=1,nlat_veg+1) /)
496 0 : lon_veg_edge(:) = (/ ( 0.0_r8 + (i-1),i=1,nlon_veg+1) /)
497 :
498 : !---------------------------------------------------------------------------
499 : ! ... regrid to model grid
500 : !---------------------------------------------------------------------------
501 : call interp_map( plon, plat, nlon_veg, nlat_veg, npft_veg, lat_veg_edge, &
502 : lon_veg_edge, landmask, urban, lake, &
503 0 : wetland, vegetation_map )
504 :
505 0 : deallocate( vegetation_map, work, stat=astat )
506 0 : deallocate( lon_veg_edge, lat_veg_edge, stat=astat )
507 0 : deallocate( landmask, urban, lake, wetland, stat=astat )
508 : endif ! Unstructured grid
509 :
510 3072 : end subroutine dvel_inti_xactive
511 :
512 : !-------------------------------------------------------------------------------------
513 0 : subroutine get_landuse_and_soilw_from_file()
514 : use ncdio_atm, only : infld
515 :
516 : logical :: readvar
517 :
518 : type(file_desc_t) :: piofile
519 : character(len=shr_kind_cl) :: locfn
520 : logical :: lexist
521 :
522 0 : if (len_trim(drydep_srf_file) == 0) then
523 0 : if (masterproc) then
524 0 : write(iulog,*)'**************************************'
525 0 : write(iulog,*)' get_landuse_and_soilw_from_file: INFO:'
526 0 : write(iulog,*)' drydep_srf_file not set:'
527 0 : write(iulog,*)' setting fraction_landuse to zero'
528 0 : write(iulog,*)'**************************************'
529 : end if
530 0 : fraction_landuse = 0._r8
531 : return
532 : end if
533 :
534 0 : call getfil (drydep_srf_file, locfn, 1, lexist)
535 0 : if(lexist) then
536 0 : call cam_pio_openfile(piofile, locfn, PIO_NOWRITE)
537 :
538 : call infld('fraction_landuse', piofile, 'ncol','class',1,pcols,1,n_land_type, begchunk,endchunk, &
539 0 : fraction_landuse, readvar, gridname='physgrid')
540 0 : if (.not. readvar) then
541 0 : if (masterproc) then
542 0 : write(iulog,*)'**************************************'
543 0 : write(iulog,*)'get_landuse_and_soilw_from_file: INFO:'
544 0 : write(iulog,*)' fraction_landuse not read from file: '
545 0 : write(iulog,*)' ', trim(locfn)
546 0 : write(iulog,*)' setting all values to zero'
547 0 : write(iulog,*)'**************************************'
548 : end if
549 0 : fraction_landuse = 0._r8
550 : end if
551 :
552 0 : call cam_pio_closefile(piofile)
553 : else
554 0 : call endrun('Unstructured grids require drydep_srf_file ')
555 : end if
556 :
557 :
558 0 : end subroutine get_landuse_and_soilw_from_file
559 :
560 : !-------------------------------------------------------------------------------------
561 0 : subroutine interp_map( plon, plat, nlon_veg, nlat_veg, npft_veg, lat_veg_edge, &
562 0 : lon_veg_edge, landmask, urban, lake, &
563 0 : wetland, vegetation_map )
564 :
565 0 : use mo_constants, only : r2d
566 : use scamMod, only : latiop,loniop,scmlat,scmlon,scm_cambfb_mode
567 : use shr_scam_mod , only: shr_scam_getCloseLatLon ! Standardized system subroutines
568 : use cam_initfiles, only: initial_file_get_id
569 : use dycore, only : dycore_is
570 : use phys_grid, only : get_rlat_all_p, get_rlon_all_p, get_ncols_p
571 :
572 : !-------------------------------------------------------------------------------------
573 : ! ... dummy arguments
574 : !-------------------------------------------------------------------------------------
575 : integer, intent(in) :: plon, plat, nlon_veg, nlat_veg, npft_veg
576 : real(r8), intent(in) :: landmask(nlon_veg,nlat_veg)
577 : real(r8), intent(in) :: urban(nlon_veg,nlat_veg)
578 : real(r8), intent(in) :: lake(nlon_veg,nlat_veg)
579 : real(r8), intent(in) :: wetland(nlon_veg,nlat_veg)
580 : real(r8), intent(in) :: vegetation_map(nlon_veg,nlat_veg,npft_veg)
581 : real(r8), intent(in) :: lon_veg_edge(nlon_veg+1)
582 : real(r8), intent(in) :: lat_veg_edge(nlat_veg+1)
583 :
584 : !-------------------------------------------------------------------------------------
585 : ! ... local variables
586 : !-------------------------------------------------------------------------------------
587 : real(r8) :: closelat,closelon
588 : integer :: latidx,lonidx
589 :
590 : integer, parameter :: veg_ext = 20
591 : type(file_desc_t), pointer :: piofile
592 : integer :: i, j, ii, jj, i_ndx, n
593 0 : integer, dimension(plon+1) :: ind_lon
594 0 : integer, dimension(plat+1) :: ind_lat
595 : real(r8) :: total_land
596 0 : real(r8), dimension(plon+1) :: lon_edge
597 0 : real(r8), dimension(plat+1) :: lat_edge
598 : real(r8) :: lat1, lon1
599 : real(r8) :: x1, x2, y1, y2, dx, dy
600 : real(r8) :: area, total_area
601 0 : real(r8), dimension(npft_veg+3) :: fraction
602 0 : real(r8), dimension(-veg_ext:nlon_veg+veg_ext) :: lon_veg_edge_ext
603 0 : integer, dimension(-veg_ext:nlon_veg+veg_ext) :: mapping_ext
604 :
605 0 : real(r8), allocatable :: lam(:), phi(:)
606 :
607 : logical, parameter :: has_npole = .true.
608 : integer :: ploniop,platiop
609 0 : real(r8) :: tmp_frac_lu(plon,n_land_type,plat)
610 :
611 : real(r8):: rlats(pcols), rlons(pcols)
612 : integer :: lchnk, ncol, icol
613 : logical :: found
614 :
615 0 : if(dycore_is('UNSTRUCTURED') ) then
616 0 : call endrun('mo_drydep::interp_map called for UNSTRUCTURED grid')
617 : endif
618 :
619 0 : allocate(lam(plon), phi(plat))
620 0 : call get_horiz_grid_d(plat, clat_d_out=phi)
621 0 : call get_horiz_grid_d(plon, clon_d_out=lam)
622 :
623 0 : if (single_column) then
624 0 : if (scm_cambfb_mode) then
625 0 : piofile => initial_file_get_id()
626 0 : call shr_scam_getCloseLatLon(piofile,scmlat,scmlon,closelat,closelon,latidx,lonidx)
627 0 : ploniop=size(loniop)
628 0 : platiop=size(latiop)
629 : else
630 0 : latidx=1
631 0 : lonidx=1
632 0 : ploniop=1
633 0 : platiop=1
634 : end if
635 :
636 0 : lon_edge(1) = loniop(lonidx) * r2d - .5_r8*(loniop(2) - loniop(1)) * r2d
637 :
638 0 : if (lonidx.lt.ploniop) then
639 0 : lon_edge(2) = loniop(lonidx+1) * r2d - .5_r8*(loniop(2) - loniop(1)) * r2d
640 : else
641 0 : lon_edge(2) = lon_edge(1) + (loniop(2) - loniop(1)) * r2d
642 : end if
643 :
644 0 : lat_edge(1) = latiop(latidx) * r2d - .5_r8*(latiop(2) - latiop(1)) * r2d
645 :
646 0 : if (latidx.lt.platiop) then
647 0 : lat_edge(2) = latiop(latidx+1) * r2d - .5_r8*(latiop(2) - latiop(1)) * r2d
648 : else
649 0 : lat_edge(2) = lat_edge(1) + (latiop(2) - latiop(1)) * r2d
650 : end if
651 : else
652 0 : do i = 1,plon
653 0 : lon_edge(i) = lam(i) * r2d - .5_r8*(lam(2) - lam(1)) * r2d
654 : end do
655 0 : lon_edge(plon+1) = lon_edge(plon) + (lam(2) - lam(1)) * r2d
656 : if( .not. has_npole ) then
657 : do j = 1,plat+1
658 : lat_edge(j) = phi(j) * r2d - .5_r8*(phi(2) - phi(1)) * r2d
659 : end do
660 : else
661 0 : do j = 1,plat
662 0 : lat_edge(j) = phi(j) * r2d - .5_r8*(phi(2) - phi(1)) * r2d
663 : end do
664 0 : lat_edge(plat+1) = lat_edge(plat) + (phi(2) - phi(1)) * r2d
665 : end if
666 : end if
667 0 : do j = 1,plat+1
668 0 : lat_edge(j) = min( lat_edge(j), 90._r8 )
669 0 : lat_edge(j) = max( lat_edge(j),-90._r8 )
670 : end do
671 :
672 : !-------------------------------------------------------------------------------------
673 : ! wrap around the longitudes
674 : !-------------------------------------------------------------------------------------
675 0 : do i = -veg_ext,0
676 0 : lon_veg_edge_ext(i) = lon_veg_edge(nlon_veg+i) - 360._r8
677 0 : mapping_ext (i) = nlon_veg+i
678 : end do
679 0 : do i = 1,nlon_veg
680 0 : lon_veg_edge_ext(i) = lon_veg_edge(i)
681 0 : mapping_ext (i) = i
682 : end do
683 0 : do i = nlon_veg+1,nlon_veg+veg_ext
684 0 : lon_veg_edge_ext(i) = lon_veg_edge(i-nlon_veg) + 360._r8
685 0 : mapping_ext (i) = i-nlon_veg
686 : end do
687 : #ifdef DEBUG
688 0 : write(iulog,*) 'interp_map : lon_edge ',lon_edge
689 0 : write(iulog,*) 'interp_map : lat_edge ',lat_edge
690 0 : write(iulog,*) 'interp_map : mapping_ext ',mapping_ext
691 : #endif
692 0 : do j = 1,plon+1
693 0 : lon1 = lon_edge(j)
694 0 : do i = -veg_ext,nlon_veg+veg_ext
695 0 : dx = lon_veg_edge_ext(i ) - lon1
696 0 : dy = lon_veg_edge_ext(i+1) - lon1
697 0 : if( dx*dy <= 0._r8 ) then
698 0 : ind_lon(j) = i
699 0 : exit
700 : end if
701 : end do
702 : end do
703 :
704 0 : do j = 1,plat+1
705 0 : lat1 = lat_edge(j)
706 0 : do i = 1,nlat_veg
707 0 : dx = lat_veg_edge(i ) - lat1
708 0 : dy = lat_veg_edge(i+1) - lat1
709 0 : if( dx*dy <= 0._r8 ) then
710 0 : ind_lat(j) = i
711 0 : exit
712 : end if
713 : end do
714 : end do
715 : #ifdef DEBUG
716 0 : write(iulog,*) 'interp_map : ind_lon ',ind_lon
717 0 : write(iulog,*) 'interp_map : ind_lat ',ind_lat
718 : #endif
719 0 : lat_loop : do j = 1,plat
720 0 : lon_loop : do i = 1,plon
721 0 : total_area = 0._r8
722 0 : fraction = 0._r8
723 0 : do jj = ind_lat(j),ind_lat(j+1)
724 0 : y1 = max( lat_edge(j),lat_veg_edge(jj) )
725 0 : y2 = min( lat_edge(j+1),lat_veg_edge(jj+1) )
726 0 : dy = (y2 - y1)/(lat_veg_edge(jj+1) - lat_veg_edge(jj))
727 0 : do ii =ind_lon(i),ind_lon(i+1)
728 0 : i_ndx = mapping_ext(ii)
729 0 : x1 = max( lon_edge(i),lon_veg_edge_ext(ii) )
730 0 : x2 = min( lon_edge(i+1),lon_veg_edge_ext(ii+1) )
731 0 : dx = (x2 - x1)/(lon_veg_edge_ext(ii+1) - lon_veg_edge_ext(ii))
732 0 : area = dx * dy
733 0 : total_area = total_area + area
734 : !-----------------------------------------------------------------
735 : ! ... special case for ocean grid point
736 : !-----------------------------------------------------------------
737 0 : if( nint(landmask(i_ndx,jj)) == 0 ) then
738 0 : fraction(npft_veg+1) = fraction(npft_veg+1) + area
739 : else
740 0 : do n = 1,npft_veg
741 0 : fraction(n) = fraction(n) + vegetation_map(i_ndx,jj,n) * area
742 : end do
743 0 : fraction(npft_veg+1) = fraction(npft_veg+1) + area * lake (i_ndx,jj)
744 0 : fraction(npft_veg+2) = fraction(npft_veg+2) + area * wetland(i_ndx,jj)
745 0 : fraction(npft_veg+3) = fraction(npft_veg+3) + area * urban (i_ndx,jj)
746 : !-----------------------------------------------------------------
747 : ! ... check if land accounts for the whole area.
748 : ! If not, the remaining area is in the ocean
749 : !-----------------------------------------------------------------
750 : total_land = sum(vegetation_map(i_ndx,jj,:)) &
751 : + urban (i_ndx,jj) &
752 : + lake (i_ndx,jj) &
753 0 : + wetland(i_ndx,jj)
754 0 : if( total_land < 1._r8 ) then
755 0 : fraction(npft_veg+1) = fraction(npft_veg+1) + (1._r8 - total_land) * area
756 : end if
757 : end if
758 : end do
759 : end do
760 : !-------------------------------------------------------------------------------------
761 : ! ... divide by total area of grid box
762 : !-------------------------------------------------------------------------------------
763 0 : fraction(:) = fraction(:)/total_area
764 : !-------------------------------------------------------------------------------------
765 : ! ... make sure we don't have too much or too little
766 : !-------------------------------------------------------------------------------------
767 0 : if( abs( sum(fraction) - 1._r8) > .001_r8 ) then
768 0 : fraction(:) = fraction(:)/sum(fraction)
769 : end if
770 : !-------------------------------------------------------------------------------------
771 : ! ... map to Wesely land classification
772 : !-------------------------------------------------------------------------------------
773 0 : tmp_frac_lu(i, 1, j) = fraction(20)
774 0 : tmp_frac_lu(i, 2, j) = sum(fraction(16:17))
775 0 : tmp_frac_lu(i, 3, j) = sum(fraction(13:15))
776 0 : tmp_frac_lu(i, 4, j) = sum(fraction( 5: 9))
777 0 : tmp_frac_lu(i, 5, j) = sum(fraction( 2: 4))
778 0 : tmp_frac_lu(i, 6, j) = fraction(19)
779 0 : tmp_frac_lu(i, 7, j) = fraction(18)
780 0 : tmp_frac_lu(i, 8, j) = fraction( 1)
781 0 : tmp_frac_lu(i, 9, j) = 0._r8
782 0 : tmp_frac_lu(i,10, j) = 0._r8
783 0 : tmp_frac_lu(i,11, j) = sum(fraction(10:12))
784 : end do lon_loop
785 : end do lat_loop
786 :
787 0 : do lchnk = begchunk, endchunk
788 0 : ncol = get_ncols_p(lchnk)
789 0 : call get_rlat_all_p(lchnk, ncol, rlats(:ncol))
790 0 : call get_rlon_all_p(lchnk, ncol, rlons(:ncol))
791 0 : do icol= 1,ncol
792 0 : found=.false.
793 0 : find_col: do j = 1,plat
794 0 : do i = 1,plon
795 0 : if (rlats(icol)==phi(j) .and. rlons(icol)==lam(i)) then
796 : found=.true.
797 : exit find_col
798 : endif
799 : enddo
800 : enddo find_col
801 :
802 0 : if (.not.found) call endrun('mo_drydep::interp_map not able find physics column coordinate')
803 0 : fraction_landuse(icol,1:n_land_type,lchnk) = tmp_frac_lu(i,1:n_land_type,j)
804 :
805 : end do
806 :
807 : !-------------------------------------------------------------------------------------
808 : ! ... make sure there are no out of range values
809 : !-------------------------------------------------------------------------------------
810 0 : where (fraction_landuse(:ncol,:n_land_type,lchnk) < 0._r8) fraction_landuse(:ncol,:n_land_type,lchnk) = 0._r8
811 0 : where (fraction_landuse(:ncol,:n_land_type,lchnk) > 1._r8) fraction_landuse(:ncol,:n_land_type,lchnk) = 1._r8
812 : end do
813 :
814 0 : end subroutine interp_map
815 :
816 : !-------------------------------------------------------------------------------------
817 : !-------------------------------------------------------------------------------------
818 72960 : subroutine drydep_xactive( sfc_temp, pressure_sfc, &
819 : wind_speed, spec_hum, air_temp, pressure_10m, rain, &
820 72960 : snow, solar_flux, dvel, dflx, mmr, &
821 : tv, ncol, lchnk, &
822 : ocnfrc, icefrc, beglandtype, endlandtype )
823 : !-------------------------------------------------------------------------------------
824 : ! code based on wesely (atmospheric environment, 1989, vol 23, p. 1293-1304) for
825 : ! calculation of r_c, and on walcek et. al. (atmospheric enviroment, 1986,
826 : ! vol. 20, p. 949-964) for calculation of r_a and r_b
827 : !
828 : ! as suggested in walcek (u_i)(u*_i) = (u_a)(u*_a)
829 : ! is kept constant where i represents a subgrid environment and a the
830 : ! grid average environment. thus the calculation proceeds as follows:
831 : ! va the grid averaged wind is calculated on dots
832 : ! z0(i) the grid averaged roughness coefficient is calculated
833 : ! ri(i) the grid averaged richardson number is calculated
834 : ! --> the grid averaged (u_a)(u*_a) is calculated
835 : ! --> subgrid scale u*_i is calculated assuming (u_i) given as above
836 : ! --> final deposotion velocity is weighted average of subgrid scale velocities
837 : !
838 : ! code written by P. Hess, rewritten in fortran 90 by JFL (August 2000)
839 : ! modified by JFL to be used in MOZART-2 (October 2002)
840 : !-------------------------------------------------------------------------------------
841 :
842 0 : use shr_drydep_mod, only: z0, rgso, rgss, ri, rclo, rcls, rlu, rac
843 : use shr_drydep_mod, only: shr_drydep_setHCoeff, foxd, drat
844 : use physconst, only: tmelt
845 :
846 : !-------------------------------------------------------------------------------------
847 : ! ... dummy arguments
848 : !-------------------------------------------------------------------------------------
849 : integer, intent(in) :: ncol
850 : real(r8), intent(in) :: sfc_temp(pcols) ! surface temperature (K)
851 : real(r8), intent(in) :: pressure_sfc(pcols) ! surface pressure (Pa)
852 : real(r8), intent(in) :: wind_speed(pcols) ! 10 meter wind speed (m/s)
853 : real(r8), intent(in) :: spec_hum(pcols) ! specific humidity (kg/kg)
854 : real(r8), intent(in) :: air_temp(pcols) ! surface air temperature (K)
855 : real(r8), intent(in) :: pressure_10m(pcols) ! 10 meter pressure (Pa)
856 : real(r8), intent(in) :: rain(pcols)
857 : real(r8), intent(in) :: snow(pcols) ! snow height (m)
858 :
859 : real(r8), intent(in) :: solar_flux(pcols) ! direct shortwave radiation at surface (W/m^2)
860 : real(r8), intent(in) :: tv(pcols) ! potential temperature
861 : real(r8), intent(in) :: mmr(pcols,plev,gas_pcnst) ! constituent concentration (kg/kg)
862 : real(r8), intent(out) :: dvel(ncol,gas_pcnst) ! deposition velocity (cm/s)
863 : real(r8), intent(inout) :: dflx(pcols,gas_pcnst) ! deposition flux (/cm^2/s)
864 :
865 : integer, intent(in) :: lchnk ! chunk number
866 :
867 : integer, intent(in), optional :: beglandtype
868 : integer, intent(in), optional :: endlandtype
869 :
870 : real(r8), intent(in), optional :: ocnfrc(pcols)
871 : real(r8), intent(in), optional :: icefrc(pcols)
872 :
873 : !-------------------------------------------------------------------------------------
874 : ! ... local variables
875 : !-------------------------------------------------------------------------------------
876 : real(r8), parameter :: scaling_to_cm_per_s = 100._r8
877 : real(r8), parameter :: rain_threshold = 1.e-7_r8 ! of the order of 1cm/day expressed in m/s
878 :
879 : integer :: i, ispec, lt, m
880 : integer :: sndx
881 :
882 : real(r8) :: slope = 0._r8
883 : real(r8) :: z0water ! revised z0 over water
884 : real(r8) :: p ! pressure at midpoint first layer
885 : real(r8) :: pg ! surface pressure
886 : real(r8) :: es ! saturation vapor pressure
887 : real(r8) :: ws ! saturation mixing ratio
888 : real(r8) :: hvar ! constant to compute xmol
889 : real(r8) :: h ! constant to compute xmol
890 : real(r8) :: psih ! stability correction factor
891 : real(r8) :: rs ! constant for calculating rsmx
892 : real(r8) :: rmx ! resistance by vegetation
893 : real(r8) :: zovl ! ratio of z to m-o length
894 : real(r8) :: cvarb ! cvar averaged over landtypes
895 : real(r8) :: bb ! b averaged over landtypes
896 : real(r8) :: ustarb ! ustar averaged over landtypes
897 145920 : real(r8) :: tc(ncol) ! temperature in celsius
898 145920 : real(r8) :: cts(ncol) ! correction to rlu rcl and rgs for frost
899 :
900 : !-------------------------------------------------------------------------------------
901 : ! local arrays: dependent on location and species
902 : !-------------------------------------------------------------------------------------
903 145920 : real(r8), dimension(ncol,nddvels) :: heff
904 :
905 : !-------------------------------------------------------------------------------------
906 : ! local arrays: dependent on location only
907 : !-------------------------------------------------------------------------------------
908 145920 : integer :: index_season(ncol,n_land_type)
909 145920 : real(r8), dimension(ncol) :: tha ! atmospheric virtual potential temperature
910 145920 : real(r8), dimension(ncol) :: thg ! ground virtual potential temperature
911 145920 : real(r8), dimension(ncol) :: z ! height of lowest level
912 145920 : real(r8), dimension(ncol) :: va ! magnitude of v on cross points
913 145920 : real(r8), dimension(ncol) :: ribn ! richardson number
914 145920 : real(r8), dimension(ncol) :: qs ! saturation specific humidity
915 145920 : real(r8), dimension(ncol) :: crs ! multiplier to calculate crs
916 145920 : real(r8), dimension(ncol) :: rdc ! part of lower canopy resistance
917 145920 : real(r8), dimension(ncol) :: uustar ! u*ustar (assumed constant over grid)
918 145920 : real(r8), dimension(ncol) :: z0b ! average roughness length over grid
919 145920 : real(r8), dimension(ncol) :: wrk ! work array
920 145920 : real(r8), dimension(ncol) :: term ! work array
921 145920 : real(r8), dimension(ncol) :: resc ! work array
922 145920 : real(r8), dimension(ncol) :: lnd_frc ! work array
923 145920 : logical, dimension(ncol) :: unstable
924 145920 : logical, dimension(ncol) :: has_rain
925 145920 : logical, dimension(ncol) :: has_dew
926 :
927 : !-------------------------------------------------------------------------------------
928 : ! local arrays: dependent on location and landtype
929 : !-------------------------------------------------------------------------------------
930 145920 : real(r8), dimension(ncol,n_land_type) :: rds ! resistance for deposition of sulfate
931 145920 : real(r8), dimension(ncol,n_land_type) :: b ! buoyancy parameter for unstable conditions
932 145920 : real(r8), dimension(ncol,n_land_type) :: cvar ! height parameter
933 145920 : real(r8), dimension(ncol,n_land_type) :: ustar ! friction velocity
934 145920 : real(r8), dimension(ncol,n_land_type) :: xmol ! monin-obukhov length
935 :
936 : !-------------------------------------------------------------------------------------
937 : ! local arrays: dependent on location, landtype and species
938 : !-------------------------------------------------------------------------------------
939 145920 : real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rsmx ! vegetative resistance (plant mesophyll)
940 145920 : real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rclx ! lower canopy resistance
941 145920 : real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rlux ! vegetative resistance (upper canopy)
942 145920 : real(r8), dimension(ncol,n_land_type) :: rlux_o3 ! vegetative resistance (upper canopy)
943 145920 : real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rgsx ! ground resistance
944 : real(r8) :: vds
945 145920 : logical :: fr_lnduse(ncol,n_land_type) ! wrking array
946 : real(r8) :: dewm ! multiplier for rs when dew occurs
947 :
948 145920 : real(r8) :: lcl_frc_landuse(ncol,n_land_type)
949 :
950 : integer :: beglt, endlt
951 :
952 : !-------------------------------------------------------------------------------------
953 : ! jfl : mods for PAN
954 : !-------------------------------------------------------------------------------------
955 : real(r8) :: dv_pan
956 : real(r8) :: c0_pan(11) = (/ 0.000_r8, 0.006_r8, 0.002_r8, 0.009_r8, 0.015_r8, &
957 : 0.006_r8, 0.000_r8, 0.000_r8, 0.000_r8, 0.002_r8, 0.002_r8 /)
958 : real(r8) :: k_pan (11) = (/ 0.000_r8, 0.010_r8, 0.005_r8, 0.004_r8, 0.003_r8, &
959 : 0.005_r8, 0.000_r8, 0.000_r8, 0.000_r8, 0.075_r8, 0.002_r8 /)
960 :
961 72960 : if (present( beglandtype)) then
962 72960 : beglt = beglandtype
963 : else
964 : beglt = 1
965 : endif
966 72960 : if (present( endlandtype)) then
967 72960 : endlt = endlandtype
968 : else
969 : endlt = n_land_type
970 : endif
971 :
972 : !-------------------------------------------------------------------------------------
973 : ! initialize
974 : !-------------------------------------------------------------------------------------
975 14810880 : do m = 1,gas_pcnst
976 227036928 : dvel(:,m) = 0._r8
977 : end do
978 :
979 72960 : if( all( .not. has_dvel(:) ) ) then
980 : return
981 : end if
982 :
983 : !-------------------------------------------------------------------------------------
984 : ! define species-dependent parameters (temperature dependent)
985 : !-------------------------------------------------------------------------------------
986 72960 : call shr_drydep_setHCoeff( ncol, sfc_temp, heff )
987 :
988 875520 : do lt = 1,n_land_type
989 13643520 : dep_ra (:,lt,lchnk) = 0._r8
990 13643520 : dep_rb (:,lt,lchnk) = 0._r8
991 12432384 : rds(:,lt) = 0._r8
992 : end do
993 :
994 : !-------------------------------------------------------------------------------------
995 : ! season index only for ocn and sea ice
996 : !-------------------------------------------------------------------------------------
997 12432384 : index_season = 4
998 : !-------------------------------------------------------------------------------------
999 : ! special case for snow covered terrain
1000 : !-------------------------------------------------------------------------------------
1001 1123584 : do i = 1,ncol
1002 1123584 : if( snow(i) > .01_r8 ) then
1003 2948400 : index_season(i,:) = 4
1004 : end if
1005 : end do
1006 : !-------------------------------------------------------------------------------------
1007 : ! scale rain and define logical arrays
1008 : !-------------------------------------------------------------------------------------
1009 1123584 : has_rain(:ncol) = rain(:ncol) > rain_threshold
1010 :
1011 : !-------------------------------------------------------------------------------------
1012 : ! loop over longitude points
1013 : !-------------------------------------------------------------------------------------
1014 1123584 : col_loop : do i = 1,ncol
1015 1050624 : p = pressure_10m(i)
1016 1050624 : pg = pressure_sfc(i)
1017 : !-------------------------------------------------------------------------------------
1018 : ! potential temperature
1019 : !-------------------------------------------------------------------------------------
1020 1050624 : tha(i) = air_temp(i) * (p00/p )**rovcp * (1._r8 + .61_r8*spec_hum(i))
1021 1050624 : thg(i) = sfc_temp(i) * (p00/pg)**rovcp * (1._r8 + .61_r8*spec_hum(i))
1022 : !-------------------------------------------------------------------------------------
1023 : ! height of 1st level
1024 : !-------------------------------------------------------------------------------------
1025 1050624 : z(i) = - r/grav * air_temp(i) * (1._r8 + .61_r8*spec_hum(i)) * log(p/pg)
1026 : !-------------------------------------------------------------------------------------
1027 : ! wind speed
1028 : !-------------------------------------------------------------------------------------
1029 1050624 : va(i) = max( .01_r8,wind_speed(i) )
1030 : !-------------------------------------------------------------------------------------
1031 : ! Richardson number
1032 : !-------------------------------------------------------------------------------------
1033 1050624 : ribn(i) = z(i) * grav * (tha(i) - thg(i))/thg(i) / (va(i)*va(i))
1034 1050624 : ribn(i) = min( ribn(i),ric )
1035 1050624 : unstable(i) = ribn(i) < 0._r8
1036 : !-------------------------------------------------------------------------------------
1037 : ! saturation vapor pressure (Pascals)
1038 : ! saturation mixing ratio
1039 : ! saturation specific humidity
1040 : !-------------------------------------------------------------------------------------
1041 1050624 : es = 611._r8*exp( 5414.77_r8*(sfc_temp(i) - tmelt)/(tmelt*sfc_temp(i)) )
1042 1050624 : ws = .622_r8*es/(pg - es)
1043 1050624 : qs(i) = ws/(1._r8 + ws)
1044 1050624 : has_dew(i) = .false.
1045 1050624 : if( qs(i) <= spec_hum(i) ) then
1046 106298 : has_dew(i) = .true.
1047 : end if
1048 1050624 : if( sfc_temp(i) < tmelt ) then
1049 378597 : has_dew(i) = .false.
1050 : end if
1051 : !-------------------------------------------------------------------------------------
1052 : ! constant in determining rs
1053 : !-------------------------------------------------------------------------------------
1054 1050624 : tc(i) = sfc_temp(i) - tmelt
1055 1050624 : if( sfc_temp(i) > tmelt .and. sfc_temp(i) < 313.15_r8 ) then
1056 666874 : crs(i) = (1._r8 + (200._r8/(solar_flux(i) + .1_r8))**2) * (400._r8/(tc(i)*(40._r8 - tc(i))))
1057 : else
1058 383750 : crs(i) = large_value
1059 : end if
1060 : !-------------------------------------------------------------------------------------
1061 : ! rdc (lower canopy res)
1062 : !-------------------------------------------------------------------------------------
1063 1123584 : rdc(i) = 100._r8*(1._r8 + 1000._r8/(solar_flux(i) + 10._r8))/(1._r8 + 1000._r8*slope)
1064 : end do col_loop
1065 :
1066 : !-------------------------------------------------------------------------------------
1067 : ! ... form working arrays
1068 : !-------------------------------------------------------------------------------------
1069 12432384 : lcl_frc_landuse(:,:) = 0._r8
1070 :
1071 72960 : if ( present(ocnfrc) .and. present(icefrc) ) then
1072 1123584 : do i=1,ncol
1073 : ! land type 7 is used for ocean
1074 : ! land type 8 is used for sea ice
1075 1050624 : lcl_frc_landuse(i,7) = ocnfrc(i)
1076 1123584 : lcl_frc_landuse(i,8) = icefrc(i)
1077 : enddo
1078 : endif
1079 875520 : do lt = 1,n_land_type
1080 12432384 : do i=1,ncol
1081 12359424 : fr_lnduse(i,lt) = lcl_frc_landuse(i,lt) > 0._r8
1082 : enddo
1083 : end do
1084 :
1085 : !-------------------------------------------------------------------------------------
1086 : ! find grid averaged z0: z0bar (the roughness length) z_o=exp[S(f_i*ln(z_oi))]
1087 : ! this is calculated so as to find u_i, assuming u*u=u_i*u_i
1088 : !-------------------------------------------------------------------------------------
1089 1123584 : z0b(:) = 0._r8
1090 875520 : do lt = 1,n_land_type
1091 12432384 : do i = 1,ncol
1092 12359424 : if( fr_lnduse(i,lt) ) then
1093 852463 : z0b(i) = z0b(i) + lcl_frc_landuse(i,lt) * log( z0(index_season(i,lt),lt) )
1094 : end if
1095 : end do
1096 : end do
1097 :
1098 : !-------------------------------------------------------------------------------------
1099 : ! find the constant velocity uu*=(u_i)(u*_i)
1100 : !-------------------------------------------------------------------------------------
1101 1123584 : do i = 1,ncol
1102 1050624 : z0b(i) = exp( z0b(i) )
1103 1050624 : cvarb = vonkar/log( z(i)/z0b(i) )
1104 : !-------------------------------------------------------------------------------------
1105 : ! unstable and stable cases
1106 : !-------------------------------------------------------------------------------------
1107 1050624 : if( unstable(i) ) then
1108 663448 : bb = 9.4_r8*(cvarb**2)*sqrt( abs(ribn(i))*z(i)/z0b(i) )
1109 663448 : ustarb = cvarb * va(i) * sqrt( 1._r8 - (9.4_r8*ribn(i)/(1._r8 + 7.4_r8*bb)) )
1110 : else
1111 387176 : ustarb = cvarb * va(i)/(1._r8 + 4.7_r8*ribn(i))
1112 : end if
1113 1123584 : uustar(i) = va(i)*ustarb
1114 : end do
1115 :
1116 : !-------------------------------------------------------------------------------------
1117 : ! calculate the friction velocity for each land type u_i=uustar/u*_i
1118 : !-------------------------------------------------------------------------------------
1119 218880 : do lt = beglt,endlt
1120 2320128 : do i = 1,ncol
1121 2247168 : if( fr_lnduse(i,lt) ) then
1122 852463 : if( unstable(i) ) then
1123 594778 : cvar(i,lt) = vonkar/log( z(i)/z0(index_season(i,lt),lt) )
1124 594778 : b(i,lt) = 9.4_r8*(cvar(i,lt)**2)* sqrt( abs(ribn(i))*z(i)/z0(index_season(i,lt),lt) )
1125 594778 : ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)*sqrt( 1._r8 - (9.4_r8*ribn(i)/(1._r8 + 7.4_r8*b(i,lt))) ) )
1126 : else
1127 257685 : cvar(i,lt) = vonkar/log( z(i)/z0(index_season(i,lt),lt) )
1128 257685 : ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)/(1._r8 + 4.7_r8*ribn(i)) )
1129 : end if
1130 : end if
1131 : end do
1132 : end do
1133 :
1134 : !-------------------------------------------------------------------------------------
1135 : ! revise calculation of friction velocity and z0 over water
1136 : !-------------------------------------------------------------------------------------
1137 1123584 : lt = 7
1138 1123584 : do i = 1,ncol
1139 1123584 : if( fr_lnduse(i,lt) ) then
1140 704075 : if( unstable(i) ) then
1141 530246 : z0water = (.016_r8*(ustar(i,lt)**2)/grav) + diffk/(9.1_r8*ustar(i,lt))
1142 530246 : cvar(i,lt) = vonkar/(log( z(i)/z0water ))
1143 530246 : b(i,lt) = 9.4_r8*(cvar(i,lt)**2)*sqrt( abs(ribn(i))*z(i)/z0water )
1144 530246 : ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)* sqrt( 1._r8 - (9.4_r8*ribn(i)/(1._r8+ 7.4_r8*b(i,lt))) ) )
1145 : else
1146 173829 : z0water = (.016_r8*(ustar(i,lt)**2)/grav) + diffk/(9.1_r8*ustar(i,lt))
1147 173829 : cvar(i,lt) = vonkar/(log(z(i)/z0water))
1148 173829 : ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)/(1._r8 + 4.7_r8*ribn(i)) )
1149 : end if
1150 : end if
1151 : end do
1152 :
1153 : !-------------------------------------------------------------------------------------
1154 : ! compute monin-obukhov length for unstable and stable conditions/ sublayer resistance
1155 : !-------------------------------------------------------------------------------------
1156 218880 : do lt = beglt,endlt
1157 2320128 : do i = 1,ncol
1158 2247168 : if( fr_lnduse(i,lt) ) then
1159 852463 : hvar = (va(i)/0.74_r8) * (tha(i) - thg(i)) * (cvar(i,lt)**2)
1160 852463 : if( unstable(i) ) then ! unstable
1161 594778 : h = hvar*(1._r8 - (9.4_r8*ribn(i)/(1._r8 + 5.3_r8*b(i,lt))))
1162 : else
1163 257685 : h = hvar/((1._r8+4.7_r8*ribn(i))**2)
1164 : end if
1165 852463 : xmol(i,lt) = thg(i) * ustar(i,lt) * ustar(i,lt) / (vonkar * grav * h)
1166 : end if
1167 : end do
1168 : end do
1169 :
1170 : !-------------------------------------------------------------------------------------
1171 : ! psih
1172 : !-------------------------------------------------------------------------------------
1173 218880 : do lt = beglt,endlt
1174 2320128 : do i = 1,ncol
1175 2247168 : if( fr_lnduse(i,lt) ) then
1176 852463 : if( xmol(i,lt) < 0._r8 ) then
1177 594778 : zovl = z(i)/xmol(i,lt)
1178 594778 : zovl = max( -1._r8,zovl )
1179 594778 : psih = exp( .598_r8 + .39_r8*log( -zovl ) - .09_r8*(log( -zovl ))**2 )
1180 594778 : vds = 2.e-3_r8*ustar(i,lt) * (1._r8 + (300/(-xmol(i,lt)))**0.666_r8)
1181 : else
1182 257685 : zovl = z(i)/xmol(i,lt)
1183 257685 : zovl = min( 1._r8,zovl )
1184 257685 : psih = -5._r8 * zovl
1185 257685 : vds = 2.e-3_r8*ustar(i,lt)
1186 : end if
1187 852463 : dep_ra (i,lt,lchnk) = (vonkar - psih*cvar(i,lt))/(ustar(i,lt)*vonkar*cvar(i,lt))
1188 852463 : dep_rb (i,lt,lchnk) = (2._r8/(vonkar*ustar(i,lt))) * crb
1189 852463 : rds(i,lt) = 1._r8/vds
1190 : end if
1191 : end do
1192 : end do
1193 :
1194 : !-------------------------------------------------------------------------------------
1195 : ! surface resistance : depends on both land type and species
1196 : ! land types are computed seperately, then resistance is computed as average of values
1197 : ! following wesely rc=(1/(rs+rm) + 1/rlu +1/(rdc+rcl) + 1/(rac+rgs))**-1
1198 : !
1199 : ! compute rsmx = 1/(rs+rm) : multiply by 3 if surface is wet
1200 : !-------------------------------------------------------------------------------------
1201 14810880 : species_loop1 : do ispec = 1,gas_pcnst
1202 14810880 : if( has_dvel(ispec) ) then
1203 7368960 : m = map_dvel(ispec)
1204 22106880 : do lt = beglt,endlt
1205 234332928 : do i = 1,ncol
1206 226963968 : if( fr_lnduse(i,lt) ) then
1207 86098763 : sndx = index_season(i,lt)
1208 86098763 : if( ispec == o3_ndx .or. ispec == o3a_ndx .or. ispec == so2_ndx ) then
1209 : rmx = 0._r8
1210 : else
1211 84393837 : rmx = 1._r8/(heff(i,m)/3000._r8 + 100._r8*foxd(m))
1212 : end if
1213 86098763 : cts(i) = 1000._r8*exp( - tc(i) - 4._r8 ) ! correction for frost
1214 86098763 : rgsx(i,lt,ispec) = cts(i) + 1._r8/((heff(i,m)/(1.e5_r8*rgss(sndx,lt))) + (foxd(m)/rgso(sndx,lt)))
1215 : !-------------------------------------------------------------------------------------
1216 : ! special case for H2 and CO;; CH4 is set ot a fraction of dv(H2)
1217 : !-------------------------------------------------------------------------------------
1218 86098763 : if( ispec == h2_ndx .or. ispec == co_ndx .or. ispec == ch4_ndx ) then
1219 : !-------------------------------------------------------------------------------------
1220 : ! no deposition on snow, ice, desert, and water
1221 : !-------------------------------------------------------------------------------------
1222 852463 : if( lt == 1 .or. lt == 7 .or. lt == 8 .or. sndx == 4 ) then
1223 852463 : rgsx(i,lt,ispec) = large_value
1224 : end if
1225 : end if
1226 86098763 : if( lt == 7 ) then
1227 71111575 : rclx(i,lt,ispec) = large_value
1228 71111575 : rsmx(i,lt,ispec) = large_value
1229 71111575 : rlux(i,lt,ispec) = large_value
1230 : else
1231 14987188 : rs = ri(sndx,lt)*crs(i)
1232 14987188 : if ( has_dew(i) .or. has_rain(i) ) then
1233 : dewm = 3._r8
1234 : else
1235 14731759 : dewm = 1._r8
1236 : end if
1237 14987188 : rsmx(i,lt,ispec) = (dewm*rs*drat(m) + rmx)
1238 : !-------------------------------------------------------------------------------------
1239 : ! jfl : special case for PAN
1240 : !-------------------------------------------------------------------------------------
1241 14987188 : if( ispec == pan_ndx .or. ispec == xpan_ndx ) then
1242 148388 : dv_pan = c0_pan(lt) * (1._r8 - exp( -k_pan(lt)*(dewm*rs*drat(m))*1.e-2_r8 ))
1243 148388 : if( dv_pan > 0._r8 .and. sndx /= 4 ) then
1244 0 : rsmx(i,lt,ispec) = ( 1._r8/dv_pan )
1245 : end if
1246 : end if
1247 14987188 : rclx(i,lt,ispec) = cts(i) + 1._r8/((heff(i,m)/(1.e5_r8*rcls(sndx,lt))) + (foxd(m)/rclo(sndx,lt)))
1248 14987188 : rlux(i,lt,ispec) = cts(i) + rlu(sndx,lt)/(1.e-5_r8*heff(i,m) + foxd(m))
1249 : end if
1250 : end if
1251 : end do
1252 : end do
1253 : end if
1254 : end do species_loop1
1255 :
1256 218880 : do lt = beglt,endlt
1257 218880 : if( lt /= 7 ) then
1258 1123584 : do i = 1,ncol
1259 1123584 : if( fr_lnduse(i,lt) ) then
1260 148388 : sndx = index_season(i,lt)
1261 : !-------------------------------------------------------------------------------------
1262 : ! ... no effect if sfc_temp < O C
1263 : !-------------------------------------------------------------------------------------
1264 148388 : if( sfc_temp(i) > tmelt ) then
1265 4561 : if( has_dew(i) ) then
1266 745 : rlux_o3(i,lt) = 3000._r8*rlu(sndx,lt)/(1000._r8 + rlu(sndx,lt))
1267 745 : if( o3_ndx > 0 ) then
1268 745 : rlux(i,lt,o3_ndx) = rlux_o3(i,lt)
1269 : endif
1270 745 : if( o3a_ndx > 0 ) then
1271 0 : rlux(i,lt,o3a_ndx) = rlux_o3(i,lt)
1272 : endif
1273 : end if
1274 4561 : if( has_rain(i) ) then
1275 : ! rlux(i,lt,o3_ndx) = 1./(1.e-3 + (1./(3.*rlu(sndx,lt))))
1276 504 : rlux_o3(i,lt) = 3000._r8*rlu(sndx,lt)/(1000._r8 + 3._r8*rlu(sndx,lt))
1277 504 : if( o3_ndx > 0 ) then
1278 504 : rlux(i,lt,o3_ndx) = rlux_o3(i,lt)
1279 : endif
1280 504 : if( o3a_ndx > 0 ) then
1281 0 : rlux(i,lt,o3a_ndx) = rlux_o3(i,lt)
1282 : endif
1283 : end if
1284 : end if
1285 :
1286 148388 : if ( o3_ndx > 0 ) then
1287 148388 : rclx(i,lt,o3_ndx) = cts(i) + rclo(index_season(i,lt),lt)
1288 148388 : rlux(i,lt,o3_ndx) = cts(i) + rlux(i,lt,o3_ndx)
1289 : end if
1290 148388 : if ( o3a_ndx > 0 ) then
1291 0 : rclx(i,lt,o3a_ndx) = cts(i) + rclo(index_season(i,lt),lt)
1292 0 : rlux(i,lt,o3a_ndx) = cts(i) + rlux(i,lt,o3a_ndx)
1293 : end if
1294 :
1295 : end if
1296 : end do
1297 : end if
1298 : end do
1299 :
1300 14810880 : species_loop2 : do ispec = 1,gas_pcnst
1301 14737920 : m = map_dvel(ispec)
1302 14810880 : if( has_dvel(ispec) ) then
1303 7368960 : if( ispec /= o3_ndx .and. ispec /= o3a_ndx .and. ispec /= so2_ndx ) then
1304 21669120 : do lt = beglt,endlt
1305 21669120 : if( lt /= 7 ) then
1306 111234816 : do i = 1,ncol
1307 111234816 : if( fr_lnduse(i,lt) ) then
1308 : !-------------------------------------------------------------------------------------
1309 : ! no effect if sfc_temp < O C
1310 : !-------------------------------------------------------------------------------------
1311 14690412 : if( sfc_temp(i) > tmelt ) then
1312 451539 : if( has_dew(i) ) then
1313 : rlux(i,lt,ispec) = 1._r8/((1._r8/(3._r8*rlux(i,lt,ispec))) &
1314 73755 : + 1.e-7_r8*heff(i,m) + foxd(m)/rlux_o3(i,lt))
1315 : end if
1316 : end if
1317 :
1318 : end if
1319 : end do
1320 : end if
1321 : end do
1322 145920 : else if( ispec == so2_ndx ) then
1323 218880 : do lt = beglt,endlt
1324 218880 : if( lt /= 7 ) then
1325 1123584 : do i = 1,ncol
1326 1123584 : if( fr_lnduse(i,lt) ) then
1327 : !-------------------------------------------------------------------------------------
1328 : ! no effect if sfc_temp < O C
1329 : !-------------------------------------------------------------------------------------
1330 148388 : if( sfc_temp(i) > tmelt ) then
1331 4561 : if( qs(i) <= spec_hum(i) ) then
1332 745 : rlux(i,lt,ispec) = 100._r8
1333 : end if
1334 4561 : if( has_rain(i) ) then
1335 : ! rlux(i,lt,ispec) = 1./(2.e-4 + (1./(3.*rlu(index_season(i,lt),lt))))
1336 504 : rlux(i,lt,ispec) = 15._r8*rlu(index_season(i,lt),lt)/(5._r8 + 3.e-3_r8*rlu(index_season(i,lt),lt))
1337 : end if
1338 : end if
1339 148388 : rclx(i,lt,ispec) = cts(i) + rcls(index_season(i,lt),lt)
1340 148388 : rlux(i,lt,ispec) = cts(i) + rlux(i,lt,ispec)
1341 :
1342 : end if
1343 : end do
1344 : end if
1345 : end do
1346 1123584 : do i = 1,ncol
1347 1123584 : if( fr_lnduse(i,1) .and. (has_dew(i) .or. has_rain(i)) ) then
1348 0 : rlux(i,1,ispec) = 50._r8
1349 : end if
1350 : end do
1351 : end if
1352 : end if
1353 : end do species_loop2
1354 :
1355 : !-------------------------------------------------------------------------------------
1356 : ! compute rc
1357 : !-------------------------------------------------------------------------------------
1358 1123584 : term(:ncol) = 1.e-2_r8 * pressure_10m(:ncol) / (r*tv(:ncol))
1359 14810880 : species_loop3 : do ispec = 1,gas_pcnst
1360 14810880 : if( has_dvel(ispec) ) then
1361 113481984 : wrk(:) = 0._r8
1362 22106880 : lt_loop: do lt = beglt,endlt
1363 226963968 : do i = 1,ncol
1364 226963968 : if (fr_lnduse(i,lt)) then
1365 : resc(i) = 1._r8/( 1._r8/rsmx(i,lt,ispec) + 1._r8/rlux(i,lt,ispec) &
1366 : + 1._r8/(rdc(i) + rclx(i,lt,ispec)) &
1367 86098763 : + 1._r8/(rac(index_season(i,lt),lt) + rgsx(i,lt,ispec)))
1368 :
1369 86098763 : resc(i) = max( 10._r8,resc(i) )
1370 :
1371 86098763 : lnd_frc(i) = lcl_frc_landuse(i,lt)
1372 : endif
1373 : enddo
1374 : !-------------------------------------------------------------------------------------
1375 : ! ... compute average deposition velocity
1376 : !-------------------------------------------------------------------------------------
1377 7368960 : select case( solsym(ispec) )
1378 : case( 'SO2' )
1379 145920 : if( lt == 7 ) then
1380 1123584 : where( fr_lnduse(:ncol,lt) )
1381 : ! assume no surface resistance for SO2 over water`
1382 72960 : wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk))
1383 : endwhere
1384 : else
1385 1123584 : where( fr_lnduse(:ncol,lt) )
1386 72960 : wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk) + resc(:))
1387 : endwhere
1388 : end if
1389 :
1390 : ! JFL - increase in dry deposition of SO2 to improve bias over US/Europe
1391 2247168 : wrk(:) = wrk(:) * 2._r8
1392 :
1393 : case( 'SO4' )
1394 0 : where( fr_lnduse(:ncol,lt) )
1395 0 : wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + rds(:,lt))
1396 : endwhere
1397 : case( 'NH4', 'NH4NO3', 'XNH4NO3' )
1398 2247168 : where( fr_lnduse(:ncol,lt) )
1399 145920 : wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + 0.5_r8*rds(:,lt))
1400 : endwhere
1401 :
1402 : !-------------------------------------------------------------------------------------
1403 : ! ... special case for Pb (for consistency with offline code)
1404 : !-------------------------------------------------------------------------------------
1405 : case( 'Pb' )
1406 0 : if( lt == 7 ) then
1407 0 : where( fr_lnduse(:ncol,lt) )
1408 : wrk(:) = wrk(:) + lnd_frc(:) * 0.05e-2_r8
1409 : endwhere
1410 : else
1411 0 : where( fr_lnduse(:ncol,lt) )
1412 : wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.2e-2_r8
1413 : endwhere
1414 : end if
1415 :
1416 : !-------------------------------------------------------------------------------------
1417 : ! ... special case for carbon aerosols
1418 : !-------------------------------------------------------------------------------------
1419 : case( 'CB1', 'CB2', 'OC1', 'OC2', 'SOAM', 'SOAI', 'SOAT', 'SOAB','SOAX' )
1420 0 : where( fr_lnduse(:ncol,lt) )
1421 : wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.10e-2_r8
1422 : endwhere
1423 :
1424 : !-------------------------------------------------------------------------------------
1425 : ! deposition over ocean for HCN, CH3CN
1426 : ! velocity estimated from aircraft measurements (E.Apel, INTEX-B)
1427 : !-------------------------------------------------------------------------------------
1428 : case( 'HCN','CH3CN' )
1429 291840 : if( lt == 7 ) then ! over ocean only
1430 2247168 : where( fr_lnduse(:ncol,lt) .and. snow(:ncol) < 0.01_r8 )
1431 : wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.2e-2_r8
1432 : endwhere
1433 : end if
1434 : case default
1435 232713216 : where( fr_lnduse(:ncol,lt) )
1436 14154240 : wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk) + resc(:ncol))
1437 : endwhere
1438 : end select
1439 : end do lt_loop
1440 113481984 : dvel(:ncol,ispec) = wrk(:ncol) * scaling_to_cm_per_s
1441 113481984 : dflx(:ncol,ispec) = term(:ncol) * dvel(:ncol,ispec) * mmr(:ncol,plev,ispec)
1442 : end if
1443 :
1444 : end do species_loop3
1445 :
1446 72960 : if ( beglt > 1 ) return
1447 :
1448 : !-------------------------------------------------------------------------------------
1449 : ! ... special adjustments
1450 : !-------------------------------------------------------------------------------------
1451 0 : if( mpan_ndx > 0 ) then
1452 0 : if( has_dvel(mpan_ndx) ) then
1453 0 : dvel(:ncol,mpan_ndx) = dvel(:ncol,mpan_ndx)/3._r8
1454 0 : dflx(:ncol,mpan_ndx) = term(:ncol) * dvel(:ncol,mpan_ndx) * mmr(:ncol,plev,mpan_ndx)
1455 : end if
1456 : end if
1457 0 : if( xmpan_ndx > 0 ) then
1458 0 : if( has_dvel(xmpan_ndx) ) then
1459 0 : dvel(:ncol,xmpan_ndx) = dvel(:ncol,xmpan_ndx)/3._r8
1460 0 : dflx(:ncol,xmpan_ndx) = term(:ncol) * dvel(:ncol,xmpan_ndx) * mmr(:ncol,plev,xmpan_ndx)
1461 : end if
1462 : end if
1463 :
1464 : ! HCOOH, use CH3COOH dep.vel
1465 0 : if( hcooh_ndx > 0) then
1466 0 : if( has_dvel(hcooh_ndx) ) then
1467 0 : dvel(:ncol,hcooh_ndx) = dvel(:ncol,ch3cooh_ndx)
1468 0 : dflx(:ncol,hcooh_ndx) = term(:ncol) * dvel(:ncol,hcooh_ndx) * mmr(:ncol,plev,hcooh_ndx)
1469 : end if
1470 : end if
1471 : !
1472 : ! SOG species
1473 : !
1474 0 : if( sogm_ndx > 0) then
1475 0 : if( has_dvel(sogm_ndx) ) then
1476 0 : dvel(:ncol,sogm_ndx) = dvel(:ncol,ch3cooh_ndx)
1477 0 : dflx(:ncol,sogm_ndx) = term(:ncol) * dvel(:ncol,sogm_ndx) * mmr(:ncol,plev,sogm_ndx)
1478 : end if
1479 : end if
1480 0 : if( sogi_ndx > 0) then
1481 0 : if( has_dvel(sogi_ndx) ) then
1482 0 : dvel(:ncol,sogi_ndx) = dvel(:ncol,ch3cooh_ndx)
1483 0 : dflx(:ncol,sogi_ndx) = term(:ncol) * dvel(:ncol,sogi_ndx) * mmr(:ncol,plev,sogi_ndx)
1484 : end if
1485 : end if
1486 0 : if( sogt_ndx > 0) then
1487 0 : if( has_dvel(sogt_ndx) ) then
1488 0 : dvel(:ncol,sogt_ndx) = dvel(:ncol,ch3cooh_ndx)
1489 0 : dflx(:ncol,sogt_ndx) = term(:ncol) * dvel(:ncol,sogt_ndx) * mmr(:ncol,plev,sogt_ndx)
1490 : end if
1491 : end if
1492 0 : if( sogb_ndx > 0) then
1493 0 : if( has_dvel(sogb_ndx) ) then
1494 0 : dvel(:ncol,sogb_ndx) = dvel(:ncol,ch3cooh_ndx)
1495 0 : dflx(:ncol,sogb_ndx) = term(:ncol) * dvel(:ncol,sogb_ndx) * mmr(:ncol,plev,sogb_ndx)
1496 : end if
1497 : end if
1498 0 : if( sogx_ndx > 0) then
1499 0 : if( has_dvel(sogx_ndx) ) then
1500 0 : dvel(:ncol,sogx_ndx) = dvel(:ncol,ch3cooh_ndx)
1501 0 : dflx(:ncol,sogx_ndx) = term(:ncol) * dvel(:ncol,sogx_ndx) * mmr(:ncol,plev,sogx_ndx)
1502 : end if
1503 : end if
1504 :
1505 72960 : end subroutine drydep_xactive
1506 :
1507 : !-------------------------------------------------------------------------------------
1508 : !-------------------------------------------------------------------------------------
1509 15048192 : function has_drydep( name )
1510 :
1511 : character(len=*), intent(in) :: name
1512 :
1513 : logical :: has_drydep
1514 : integer :: i
1515 :
1516 15048192 : has_drydep = .false.
1517 :
1518 1151186688 : do i=1,nddvels
1519 1151186688 : if ( trim(name) == trim(drydep_list(i)) ) then
1520 7524096 : has_drydep = .true.
1521 7524096 : exit
1522 : endif
1523 : enddo
1524 :
1525 72960 : endfunction has_drydep
1526 :
1527 0 : end module mo_drydep
|