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