2 MODULE module_mozcart_wetscav
5 USE module_state_description
10 public :: wetscav_mozcart_init
11 public :: wetscav_mozcart
15 real, parameter :: zero = 0.
16 real, parameter :: one = 1.
17 real, parameter :: four = 4.
18 real(8), parameter :: oner8 = 1._8
19 real(8), parameter :: fourr8 = 4._8
20 real, parameter :: adj_factor = one + 10.*epsilon( one )
21 real, parameter :: TICE = 273.
22 real, parameter :: TMIX = 258.
23 integer, parameter :: idiag = 0
24 integer, parameter :: jdiag = 0
25 integer, parameter :: kdiag = 18
28 integer :: hno3_ndx = 0
29 integer, allocatable :: wrf2tab(:)
30 REAL, allocatable :: mol_wght(:)
31 logical, allocatable :: ice_uptake(:)
34 character(len=12) :: name
42 type(wet_scav), allocatable :: wet_scav_tab(:)
44 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
48 subroutine wetscav_mozcart_init( id, numgas, config_flags )
49 !----------------------------------------------------------------------
50 ! Initialize the mozart, mozcart wet scavenging module
51 !----------------------------------------------------------------------
52 use module_scalar_tables, only : chem_dname_table
53 use module_chem_utilities, only : upcase
54 use module_HLawConst, only : nHLC, HLC
56 !----------------------------------------------------------------------
58 !----------------------------------------------------------------------
59 integer, intent(in) :: id
60 integer, intent(in) :: numgas
61 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
63 !----------------------------------------------------------------------
65 !----------------------------------------------------------------------
68 character(len=12) :: wrf_spc_name
69 character(len=64) :: HL_tbl_name
70 character(len=256) :: message
73 if( .not. allocated( wet_scav_tab ) ) then
74 call wrf_message( ' ' )
75 call wrf_message( 'wetscav_mozcart_init: species names' )
76 do m = param_first_scalar,numgas,6
77 write(message,'(6a12)') chem_dname_table(id,m:min(m+5,numgas))
78 call wrf_message( trim(message) )
80 call wrf_message( ' ' )
81 !----------------------------------------------------------------------
82 ! scan HLawConst table for match with chem_opt scheme gas phase species
83 ! first just count matches
84 !----------------------------------------------------------------------
87 HL_tbl_name = HLC(m)%name
88 call upcase( HL_tbl_name )
89 do m1 = param_first_scalar,numgas
90 wrf_spc_name = chem_dname_table(id,m1)
91 call upcase( wrf_spc_name )
92 if( trim(HL_tbl_name) == trim(wrf_spc_name) ) then
100 allocate( wet_scav_tab(hetcnt),stat=astat )
101 if( astat /= 0 ) then
102 call wrf_error_fatal("mozcart_wetscav_init: failed to allocate wet_scav_tab")
105 call wrf_message( ' ' )
106 call wrf_message( 'wetscav_mozcart_init: There are no wet scavenging mozcart species' )
107 call wrf_message( ' ' )
111 !----------------------------------------------------------------------
112 ! now put matches in local table
113 !----------------------------------------------------------------------
116 HL_tbl_name = HLC(m)%name
117 call upcase( HL_tbl_name )
118 do m1 = param_first_scalar,numgas
119 wrf_spc_name = chem_dname_table(id,m1)
120 call upcase( wrf_spc_name )
121 if( trim(HL_tbl_name) == trim(wrf_spc_name) ) then
123 wet_scav_tab(m2)%name = chem_dname_table(id,m1)
124 wet_scav_tab(m2)%p_ndx = m1
125 wet_scav_tab(m2)%molecw = HLC(m)%mw
126 wet_scav_tab(m2)%heff(1:6) = HLC(m)%hcnst(1:6)
132 wet_scav_tab(:)%ice_uptake = .false.
133 wet_scav_tab(:)%reteff = 0.
135 if( wet_scav_tab(m)%p_ndx == p_h2o2 ) then
136 wet_scav_tab(m)%ice_uptake = .true.
137 wet_scav_tab(m)%reteff = .64
138 elseif( wet_scav_tab(m)%p_ndx == p_hno3 ) then
139 wet_scav_tab(m)%ice_uptake = .true.
140 wet_scav_tab(m)%reteff = 1.
142 elseif( wet_scav_tab(m)%p_ndx == p_hcooh ) then
143 wet_scav_tab(m)%ice_uptake = .true.
144 wet_scav_tab(m)%reteff = .64
145 elseif( wet_scav_tab(m)%p_ndx == p_ch3ooh ) then
146 wet_scav_tab(m)%ice_uptake = .true.
147 wet_scav_tab(m)%reteff = .02
148 elseif( wet_scav_tab(m)%p_ndx == p_so2 ) then
149 wet_scav_tab(m)%ice_uptake = .true.
150 wet_scav_tab(m)%reteff = .02
151 elseif( wet_scav_tab(m)%p_ndx == p_hcooh ) then
152 wet_scav_tab(m)%ice_uptake = .true.
153 wet_scav_tab(m)%reteff = .68
157 allocate( wrf2tab(hetcnt),mol_wght(hetcnt),ice_uptake(hetcnt),stat=astat )
158 if( astat /= 0 ) then
159 call wrf_error_fatal("mozcart_wetscav_init: failed to allocate wrf2tab,mol_wght,ice_uptake")
163 mol_wght(m) = wet_scav_tab(m)%molecw
164 ice_uptake(m) = wet_scav_tab(m)%ice_uptake
167 call wrf_message( 'wetscav_mozcart_init: Wet scavenging mozcart species' )
169 write(message,*) m,wrf2tab(m),trim(wet_scav_tab(wrf2tab(m))%name),mol_wght(m),ice_uptake(m)
170 call wrf_message( trim(message) )
173 if( wrf_dm_on_monitor() ) then
174 call wrf_debug( 100,' ' )
175 write(message,*) 'wetscav_mozcart_init: hetcnt = ',hetcnt
176 call wrf_debug( 100, trim(message) )
177 write(message,*) 'wetscav_mozcart_init: hno3_ndx = ',hno3_ndx
178 call wrf_debug( 100, trim(message) )
179 call wrf_debug( 100,' ' )
183 end subroutine wetscav_mozcart_init
185 subroutine wetscav_mozcart( id, ktau, dtstep, ktauc, config_flags, &
186 dtstepc, t_phy, p8w, t8w, p_phy, &
187 chem, rho_phy, cldfra, rainprod, evapprod, &
188 qv_b4mp, qc_b4mp, qi_b4mp, qs_b4mp, &
189 gas_aqfrac, numgas_aqfrac, dz8w, dx, dy, &
191 ! 20131125 acd_ck_washout start
194 ! 20131125 acd_ck_washout end
195 ids,ide, jds,jde, kds,kde, &
196 ims,ime, jms,jme, kms,kme, &
197 its,ite, jts,jte, kts,kte )
199 USE module_configure, only: grid_config_rec_type
200 USE module_state_description
201 USE module_model_constants, only: g, mwdry
203 !----------------------------------------------------------------------
205 !----------------------------------------------------------------------
206 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
208 INTEGER, INTENT(IN ) :: &
209 ids,ide, jds,jde, kds,kde, &
210 ims,ime, jms,jme, kms,kme, &
211 its,ite, jts,jte, kts,kte, &
212 id, ktau, ktauc, numgas_aqfrac
213 REAL, INTENT(IN ) :: dtstep, dtstepc
214 REAL, INTENT(IN ) :: dx, dy
215 !----------------------------------------------------------------------
216 ! all advected chemical species
217 !----------------------------------------------------------------------
218 REAL, DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ), &
219 INTENT(INOUT ) :: chem
220 !----------------------------------------------------------------------
221 ! fraction of gas species in cloud water
222 !----------------------------------------------------------------------
223 REAL, DIMENSION( ims:ime, kms:kme, jms:jme, numgas_aqfrac ), &
224 INTENT(IN ) :: gas_aqfrac
225 !----------------------------------------------------------------------
226 ! input from meteorology
227 !----------------------------------------------------------------------
228 REAL, DIMENSION( ims:ime , kms:kme , jms:jme ) , &
237 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ) :: &
242 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ) :: &
245 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ) :: &
251 REAL, DIMENSION( ims:ime , kms:kme , jms:jme ) , &
252 INTENT(INOUT ) :: cldfra
254 ! 20131125 acd_ck_washout start
255 ! REAL, DIMENSION( ims:ime , jms:jme ) , &
256 ! INTENT(INOUT ) :: hno3_col_mdel
258 REAL, DIMENSION( ims:ime , jms:jme, num_chem ) , &
259 INTENT(OUT ) :: delta_mass_col
260 ! 20131125 acd_ck_washout end
262 !----------------------------------------------------------------------
264 !----------------------------------------------------------------------
265 real, parameter :: t0 = 298.
266 ! real, parameter :: ph = 1.e-5
267 ! real, parameter :: hp_inv = 1./ph
268 real, parameter :: hion = 1.e-5
269 real, parameter :: hion_inv = 1./hion
270 real, parameter :: henry_thres = 1.e4
272 integer :: i, j, k, ktem1, m, m1
274 integer :: cld_col_cnt
275 integer :: precip_col_cnt
276 integer :: max_ndx(3)
277 integer :: wrk_ndx(3)
281 REAL :: percent_precip
283 REAL :: layer_mass(kts:kte)
284 REAL :: delp(kts:kte)
288 REAL :: evaprate(kts:kte)
289 REAL :: totprec(kts:kte)
290 REAL :: totevap(kts:kte)
292 REAL :: tfac(kts:kte)
293 REAL :: dk1s(kts:kte)
294 REAL :: dk2s(kts:kte)
296 REAL :: diff(its:ite,kts:kte,jts:jte)
297 REAL :: hno3(kts:kte)
298 REAL :: wrk_mass(hetcnt)
299 REAL :: trc_mass(kts:kte,hetcnt)
300 REAL :: heff(kts:kte,hetcnt)
303 logical :: tckaqb(hetcnt)
306 REAL :: reteff(hetcnt)
309 character(len=128) :: message
312 if( hetcnt > 0 ) then
313 !----------------------------------------------------------------------
314 ! form cloud fraction
315 !----------------------------------------------------------------------
316 CALL cal_cldfra3( CLDFRA, qc_b4mp, qi_b4mp, qs_b4mp, &
317 ids,ide, jds,jde, kds,kde, &
318 ims,ime, jms,jme, kms,kme, &
319 its,ite, jts,jte, kts,kte )
321 !----------------------------------------------------------------------
322 ! washout soluble species
323 !----------------------------------------------------------------------
329 ! 20131125 acd_ck_washout start
330 ! hno3_col_mdel(:,:) = 0.
331 delta_mass_col(:,:,:) = 0.
332 ! 20131125 acd_ck_washout end
338 t(kts:kte) = t_phy(i,kts:kte,j)
339 tfac(kts:ktem1) = (t0 - t(kts:ktem1))/(t0*t(kts:ktem1))
340 p(kts:kte) = p_phy(i,kts:kte,j)*.01
341 delp(kts:ktem1) = p8w(i,kts:ktem1,j) - p8w(i,kts+1:kte,j)
342 layer_mass(kts:ktem1) = area*delp(kts:ktem1)/g
343 totprec(kts:ktem1) = rainprod(i,kts:ktem1,j)*layer_mass(kts:ktem1)
344 totevap(kts:ktem1) = evapprod(i,kts:ktem1,j)*layer_mass(kts:ktem1)
348 rls(k) = max( 0.,totprec(k)-totevap(k)+rls(k+1) )
349 evaprate(k) = min( 1.,totevap(k)/(rls(k+1)+1.e-20) )
351 column_has_precip : &
352 if( any( rls(kts:ktem1) > 0. ) ) then
353 if( maxval(rls(kts:ktem1)) >= max_rls ) then
354 max_rls = max( max_rls,maxval(rls(kts:ktem1)) )
355 max_ndx(3:3) = maxloc(rls(kts:ktem1))
356 max_ndx(1:2) = (/ i,j /)
357 if( max_ndx(3) /= kts ) then
358 write(message,'(''wetscav: max rls not at srf; time,i,j,k = '',4i6)') ktau,max_ndx(:)
359 call wrf_debug( 100,trim(message) )
362 precip_col_cnt = precip_col_cnt + 1
366 pndx = wet_scav_tab(m1)%p_ndx
367 if( pndx == p_hno3 ) then
368 hno3(kts:kte) = chem(i,kts:kte,j,p_hno3)
370 wrk(kts:ktem1) = 1.e-6*mol_wght(m)*chem(i,kts:ktem1,j,pndx)/mwdry
371 trc_mass(kts:ktem1,m) = wrk(kts:ktem1)*layer_mass(kts:ktem1)
372 wrk_mass(m) = sum( trc_mass(kts:ktem1,m) )
373 e298 = wet_scav_tab(m1)%heff(1)
374 dhr = wet_scav_tab(m1)%heff(2)
375 kh(kts:ktem1) = e298 * exp( dhr*tfac(kts:ktem1) )
376 e298 = wet_scav_tab(m1)%heff(3)
377 dhr = wet_scav_tab(m1)%heff(4)
378 if( e298 /= 0. ) then
379 dk1s(kts:ktem1) = e298*exp( dhr*tfac(kts:ktem1) )
383 e298 = wet_scav_tab(m1)%heff(5)
384 dhr = wet_scav_tab(m1)%heff(6)
385 if( e298 /= 0. ) then
386 dk2s(kts:ktem1) = e298*exp( dhr*tfac(kts:ktem1) )
390 if( pndx /= p_nh3 ) then
391 heff(kts:ktem1,m) = kh(kts:ktem1)*(1. + dk1s(kts:ktem1)*hion_inv*(1. + dk2s(kts:ktem1)*hion_inv))
393 !----------------------------------------------------------------------
394 ! special handling for nh3
395 !----------------------------------------------------------------------
396 heff(kts:ktem1,m) = kh(kts:ktem1)*(1. + dk1s(kts:ktem1)*hion/dk2s(kts:ktem1))
398 tckaqb(m) = any( heff(kts:ktem1,m) > henry_thres )
400 reteff(m) = wet_scav_tab(m1)%reteff
404 !----------------------------------------------------------------------
406 !----------------------------------------------------------------------
407 CALL washout( kte-kts+1, hetcnt, dtstep, trc_mass, layer_mass, &
408 p, dz8w(i,kts:kte,j), rls, qc_b4mp(i,kts:kte,j), qi_b4mp(i,kts:kte,j), &
409 cldfra(i,kts:kte,j), t, evaprate, area, heff, &
411 ! mol_wght, tckaqb, ice_uptake, i, j )
412 mol_wght, tckaqb, ice_uptake, i, j, reteff )
418 pndx = wet_scav_tab(m1)%p_ndx
419 is_hno3 = pndx == p_hno3
420 ! 20131125 acd_ck_washout start
422 ! hno3_col_mdel(i,j) = sum( trc_mass(kts:ktem1,m) ) - wrk_mass(m)
424 delta_mass_col(i,j,pndx) = sum( trc_mass(kts:ktem1,m) ) - wrk_mass(m)
425 ! 20131125 acd_ck_washout end
427 wrk(kts:ktem1) = 1.e6*mwdry*trc_mass(kts:ktem1,m)/mol_wght(m)
428 chem(i,kts:ktem1,j,pndx) = wrk(kts:ktem1)/layer_mass(kts:ktem1)
430 diff(i,kts:ktem1,j) = 100.*(chem(i,kts:ktem1,j,p_hno3) - hno3(kts:ktem1))/hno3(kts:ktem1)
433 endif column_has_precip
437 write(message,'(''washout: max rls @ (i,j,k) '',3i4,'' = '',1pg15.7)') max_ndx(:),max_rls
438 call wrf_debug( 100,trim(message) )
440 percent_precip = 100.*real(precip_col_cnt)/real((ite-its+1)*(jte-jts+1))
441 write(*,*) 'wetscav_mozcart: percent columns with precip = ',percent_precip,'%'
444 end subroutine wetscav_mozcart
446 SUBROUTINE cal_cldfra( CLDFRA,QC,QI, &
447 ids,ide, jds,jde, kds,kde, &
448 ims,ime, jms,jme, kms,kme, &
449 its,ite, jts,jte, kts,kte )
450 !---------------------------------------------------------------------
452 ! Compute cloud fraction from input ice and cloud water fields
455 ! Whether QI or QC is active or not is determined from the indices of
456 ! the fields into the 4D scalar arrays in WRF. These indices are
457 ! P_QI and P_QC, respectively, and they are passed in to the routine
458 ! to enable testing to see if QI and QC represent active fields in
459 ! the moisture 4D scalar array carried by WRF.
461 ! If a field is active its index will have a value greater than or
462 ! equal to PARAM_FIRST_SCALAR, which is also an input argument to
465 !---------------------------------------------------------------------
469 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, &
470 ims,ime, jms,jme, kms,kme, &
471 its,ite, jts,jte, kts,kte
473 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(OUT ) :: &
476 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ) :: &
479 !----------------------------------------------------------------------
481 !----------------------------------------------------------------------
482 ! REAL, parameter :: thresh = 1.e-6
483 REAL, parameter :: thresh = 1.e-9
489 where( (qc(its:ite,k,j) + qi(its:ite,k,j)) > thresh )
490 cldfra(its:ite,k,j) = one
492 cldfra(its:ite,k,j) = zero
497 END SUBROUTINE cal_cldfra
499 SUBROUTINE cal_cldfra3( CLDFRA,QC,QI, QS, &
500 ids,ide, jds,jde, kds,kde, &
501 ims,ime, jms,jme, kms,kme, &
502 its,ite, jts,jte, kts,kte )
503 !---------------------------------------------------------------------
505 ! Compute cloud fraction from input ice and cloud water fields
508 ! Whether QI or QC is active or not is determined from the indices of
509 ! the fields into the 4D scalar arrays in WRF. These indices are
510 ! P_QI and P_QC, respectively, and they are passed in to the routine
511 ! to enable testing to see if QI and QC represent active fields in
512 ! the moisture 4D scalar array carried by WRF.
514 ! If a field is active its index will have a value greater than or
515 ! equal to PARAM_FIRST_SCALAR, which is also an input argument to
518 !---------------------------------------------------------------------
522 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, &
523 ims,ime, jms,jme, kms,kme, &
524 its,ite, jts,jte, kts,kte
526 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(OUT ) :: &
529 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ) :: &
533 !----------------------------------------------------------------------
535 !----------------------------------------------------------------------
536 REAL, parameter :: thresh = 1.e-9
541 where( (qc(its:ite,kts:kte,j) + qi(its:ite,kts:kte,j) + qs(its:ite,kts:kte,j)) > thresh )
542 cldfra(its:ite,kts:kte,j) = one
544 cldfra(its:ite,kts:kte,j) = zero
548 END SUBROUTINE cal_cldfra3
550 SUBROUTINE cal_cldfra2( CLDFRA, QV, QC, QI, QS, &
552 ids,ide, jds,jde, kds,kde, &
553 ims,ime, jms,jme, kms,kme, &
554 its,ite, jts,jte, kts,kte )
556 !----------------------------------------------------------------------
558 !----------------------------------------------------------------------
559 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, &
560 ims,ime, jms,jme, kms,kme, &
561 its,ite, jts,jte, kts,kte
563 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(OUT ) :: &
566 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN ) :: &
575 !----------------------------------------------------------------------
577 !----------------------------------------------------------------------
578 integer, parameter :: idbg = 144, kdbg = 15, jdbg = 147
579 REAL , PARAMETER :: ALPHA0 = 100.
580 REAL , PARAMETER :: GAMMA = 0.49
581 REAL , PARAMETER :: QCLDMIN = 1.E-12
582 REAL , PARAMETER :: PEXP = 0.25
583 REAL , PARAMETER :: RHGRID =1.0
584 REAL , PARAMETER :: SVP1 = 0.61078
585 REAL , PARAMETER :: SVP2 = 17.2693882
586 REAL , PARAMETER :: SVPI2 = 21.8745584
587 REAL , PARAMETER :: SVP3 = 35.86
588 REAL , PARAMETER :: SVPI3 = 7.66
589 REAL , PARAMETER :: SVPT0 = 273.15
590 REAL , PARAMETER :: r_d = 287.
591 REAL , PARAMETER :: r_v = 461.6
592 REAL , PARAMETER :: ep_2 = r_d/r_v
595 INTEGER :: imax, jmax, kmax
596 REAL :: RHUM, tc, esw, esi, weight, qvsw, qvsi, qvs_weight
597 REAL :: QCLD, DENOM, ARG, SUBSAT, wrk
598 REAL :: relhum_max, wrk_max
602 !----------------------------------------------------------------------
603 ! Compute cloud fraction from input ice and cloud water fields
606 ! Whether QI or QC is active or not is determined from the indices of
607 ! the fields into the 4D scalar arrays in WRF. These indices are
608 ! P_QI and P_QC, respectively, and they are passed in to the routine
609 ! to enable testing to see if QI and QC represent active fields in
610 ! the moisture 4D scalar array carried by WRF.
612 ! If a field is active its index will have a value greater than or
613 ! equal to PARAM_FIRST_SCALAR, which is also an input argument to
615 !----------------------------------------------------------------------
619 !-----------------------------------------------------------------------
620 ! COMPUTE GRID-SCALE CLOUD COVER FOR RADIATION
621 ! (modified by Ferrier, Feb '02)
623 ! Cloud fraction parameterization follows Randall, 1994
624 ! (see Hong et al., 1998)
625 !-----------------------------------------------------------------------
626 ! Note: ep_2=287./461.6 Rd/Rv
629 ! Alternative calculation for critical RH for grid saturation
630 ! RHGRID=0.90+.08*((100.-DX)/95.)**.5
632 ! Calculate saturation mixing ratio weighted according to the fractions of
635 ! Murray, F.W. 1966. ``On the computation of Saturation Vapor Pressure'' J. Appl. Meteor. 6 p.204
636 ! es (in mb) = 6.1078 . exp[ a . (T-273.16)/ (T-b) ]
638 ! over ice over water
639 ! a = 21.8745584 17.2693882
641 !---------------------------------------------------------------------
643 CLDFRA(its:ite,kts:kte,jts:jte) = 0.
646 imax = 0; kmax = 0; jmax = 0
651 !---------------------------------------------------------------------
652 ! Determine cloud fraction (modified from original algorithm)
653 !---------------------------------------------------------------------
654 QCLD = QI(i,k,j) + QC(i,k,j) + QS(i,k,j)
656 IF( QCLD >= QCLDMIN ) THEN
657 tc = t_phy(i,k,j) - SVPT0
658 esw = 1000.0 * SVP1 * EXP( SVP2 * tc / ( t_phy(i,k,j) - SVP3 ) )
659 esi = 1000.0 * SVP1 * EXP( SVPI2 * tc / ( t_phy(i,k,j) - SVPI3 ) )
660 QVSW = EP_2 * esw / ( p_phy(i,k,j) - esw )
661 QVSI = EP_2 * esi / ( p_phy(i,k,j) - esi )
663 weight = (QI(i,k,j) + QS(i,k,j)) / QCLD
664 QVS_WEIGHT = (1. - weight)*QVSW + weight*QVSI
665 RHUM = QV(i,k,j)/QVS_WEIGHT !--- Relative humidity
666 !---------------------------------------------------------------------
667 ! Assume zero cloud fraction if there is no cloud mixing ratio
668 !---------------------------------------------------------------------
669 IF( RHUM >= RHGRID )THEN
670 !---------------------------------------------------------------------
671 ! Assume cloud fraction of unity if near saturation and the cloud
672 ! mixing ratio is at or above the minimum threshold
673 !---------------------------------------------------------------------
676 !---------------------------------------------------------------------
677 ! Adaptation of original algorithm (Randall, 1994; Zhao, 1995)
678 ! modified based on assumed grid-scale saturation at RH=RHgrid.
679 !---------------------------------------------------------------------
680 SUBSAT = MAX( 1.E-10,RHGRID*QVS_WEIGHT - QV(i,k,j) )
681 DENOM = SUBSAT**GAMMA
682 ARG = MAX( -6.9,-ALPHA0*QCLD/DENOM ) ! <-- EXP(-6.9)=.001
683 !---------------------------------------------------------------------
684 ! prevent negative values (new)
685 !---------------------------------------------------------------------
686 RHUM = MAX( 1.E-10, RHUM )
687 wrk = (RHUM/RHGRID)**PEXP*(1. - EXP( ARG ))
688 if( rhum >= relhum_max ) then
694 IF( wrk >= .01 ) then
696 if( wrk >= wrk_max ) then
706 END SUBROUTINE cal_cldfra2
708 subroutine WASHOUT( LPAR, NTRACE, DTSCAV, QTTJFL, QM, &
709 POFL, DELZ, RLS, CLWC, CIWC, &
710 CFR, TEM, EVAPRATE, GAREA, HSTAR, &
712 ! TCMASS, TCKAQB, TCNION, ii, jj )
713 TCMASS, TCKAQB, TCNION, ii, jj, RETEFF )
715 !-----------------------------------------------------------------------
716 !---p-conde 5.4 (2007) -----called from main-----
717 !---called from pmain to calculate rainout and washout of tracers
718 !---revised by JNEU 8/2007
720 !-LAER has been removed - no scavenging for aerosols
721 !-LAER could be used as LWASHTYP
722 !---WILL THIS WORK FOR T42->T21???????????
723 !-----------------------------------------------------------------------
725 !-----------------------------------------------------------------------
727 !-----------------------------------------------------------------------
728 integer, intent(in) :: LPAR
729 integer, intent(in) :: NTRACE
730 integer, intent(in) :: ii, jj
731 real, intent(in) :: DTSCAV
732 real, intent(in) :: GAREA
733 real, intent(in) :: QM(LPAR)
734 real, intent(in) :: POFL(LPAR)
735 real, intent(in) :: DELZ(LPAR)
736 real, intent(in) :: RLS(LPAR)
737 real, intent(in) :: CLWC(LPAR)
738 real, intent(in) :: CIWC(LPAR)
739 real, intent(in) :: CFR(LPAR)
740 real, intent(in) :: TEM(LPAR)
741 real, intent(in) :: EVAPRATE(LPAR)
742 real, intent(in) :: TCMASS(NTRACE)
743 real, intent(in) :: HSTAR(LPAR,NTRACE)
744 real, intent(inout) :: QTTJFL(LPAR,NTRACE)
745 logical, intent(in) :: TCKAQB(NTRACE)
746 logical, intent(in) :: TCNION(NTRACE)
748 real, intent(in) :: RETEFF(NTRACE)
751 !-----------------------------------------------------------------------
753 !-----------------------------------------------------------------------
754 integer :: I, J, L, LE, LM1, N
755 integer :: LWASHTYP, LICETYP
757 real :: WRK, RNEW_TST
759 real :: RNEW, RPRECIP, DELTARIMEMASS, DELTARIME, RAMPCT
761 real :: DOR, DNEW, DEMP, COLEFFSNOW, RHOSNOW
762 real :: WEMP, REMP, RRAIN, RWASH
763 real :: QTPRECIP, QTRAIN, QTCXA, QTAX
765 real :: FAMA, RAMA, DAMA, FCA, RCA, DCA
766 real :: FAX, RAX, DAX, FCXA, RCXA, DCXA, FCXB, RCXB, DCXB
767 real :: RAXADJ, FAXADJ, RAXADJF
768 real :: QTDISCF, QTDISRIME, QTDISCXA
769 real :: QTEVAPAXP, QTEVAPAXW, QTEVAPAX
771 real :: QTEVAPCXAP, QTEVAPCXAW, QTEVAPCXA
772 real :: QTWASHCXA, QTRIMECXA
773 real :: QTRAINCXA, QTRAINCXB
774 real :: QTTOPCA, QTTOPAA, QTTOPCAX, QTTOPAAX
776 real :: AMPCT, AMCLPCT, CLNEWPCT, CLNEWAMPCT, CLOLDPCT, CLOLDAMPCT
777 real :: RAXLOC, RCXALOC, RCXBLOC, RCALOC, RAMALOC, RCXPCT
779 real :: QTNETLCXA, QTNETLCXB, QTNETLAX, QTNETL
785 real :: rls_wrk(lpar)
786 real :: rnew_wrk(lpar)
787 real :: rca_wrk(lpar)
788 real :: fca_wrk(lpar)
789 real :: rcxa_wrk(lpar)
790 real :: fcxa_wrk(lpar)
791 real :: rcxb_wrk(lpar)
792 real :: fcxb_wrk(lpar)
793 real :: rax_wrk(lpar,2)
794 real :: fax_wrk(lpar,2)
795 real :: rama_wrk(lpar)
796 real :: fama_wrk(lpar)
797 real :: deltarime_wrk(lpar)
798 real :: clwx_wrk(lpar)
803 logical :: rls_flag(lpar)
804 logical :: rnew_flag(lpar)
805 logical :: cf_trigger(lpar)
806 logical :: freezing(lpar)
808 character(len=132) :: message
811 real, parameter :: TFROZ = 240.
812 real, parameter :: CFMIN = 1.0
813 real, parameter :: CWMIN = 1.0e-9
814 real, parameter :: DMIN = 1.0e-1 !mm
815 real, parameter :: VOLPOW = 1./3.
816 real, parameter :: RHORAIN = 1.0e3 !kg/m3
817 real, parameter :: RHOSNOWFIX = 1.0e2 !kg/m3
818 real, parameter :: COLEFFRAIN = 0.7
819 real, parameter :: COLEFFAER = 0.05
821 !-----------------------------------------------------------------------
822 ! Note: LE must be less than LPAR
823 !-----------------------------------------------------------------------
825 rls_flag(1:le) = rls(1:le) > zero
826 freezing(1:le) = tem(1:le) < tice
827 rlsog(1:le) = rls(1:le)/garea
831 QTT(:lpar) = QTTJFL(:lpar,N)
832 QTTNEW(:lpar) = QTTJFL(:lpar,N)
833 is_hno3 = n == hno3_ndx
835 rca_wrk(:lpar) = zero
836 fca_wrk(:lpar) = zero
837 rcxa_wrk(:lpar) = zero
838 fcxa_wrk(:lpar) = zero
839 rcxb_wrk(:lpar) = zero
840 fcxb_wrk(:lpar) = zero
841 rls_wrk(:lpar) = zero
842 rnew_wrk(:lpar) = zero
843 cf_trigger(:lpar) = .false.
844 clwx_wrk(:lpar) = -9999.
845 deltarime_wrk(:lpar) = -9999.
846 rax_wrk(:lpar,:) = zero
847 fax_wrk(:lpar,:) = zero
849 !-----------------------------------------------------------------------
850 ! calculate scavenging by large-scale stratiform precipitation
851 ! check whether mass-limited or henry's law
852 !-----------------------------------------------------------------------
858 !-----------------------------------------------------------------------
859 ! check whether soluble in ice
860 !-----------------------------------------------------------------------
867 !-----------------------------------------------------------------------
869 !-----------------------------------------------------------------------
886 !-----------------------------------------------------------------------
887 ! Check whether precip in top layer - if so, require CF ge 0.2
888 !-----------------------------------------------------------------------
889 if( RLS(LE) > zero ) then
890 CFXX(LE) = max( CFMIN,CFR(LE) )
895 rnew_flag(1:le) = .false.
946 if( rls_flag(l) ) then
947 !-----------------------------------------------------------------------
948 !-----Evaporate ambient precip and decrease area-------------------------
949 !-----If ice, diam=diam falling from above If rain, diam=4mm (not used)
950 !-----Evaporate tracer contained in evaporated precip
951 !-----Can't evaporate more than we start with-----------------------------
952 !-----Don't do washout until we adjust ambient precip to match Rbot if needed
953 !------(after RNEW if statements)
954 !-----------------------------------------------------------------------
955 FAX = max( zero,FAMA*(one - evaprate(l)) )
957 if( FAMA > zero ) then
958 if( freezing(l) ) then
961 DAX = four !mm - not necessary
967 if( RAMA > zero ) then
968 QTEVAPAXP = min( QTTOPAA,EVAPRATE(L)*QTTOPAA )
978 !-----------------------------------------------------------------------
979 ! Determine how much the in-cloud precip rate has increased------
980 !-----------------------------------------------------------------------
981 WRK = RAX*FAX + RCA*FCA
983 RNEW_TST = RLS(L)/(GAREA * WRK)
987 RNEW = RLSOG(L) - (RAX*FAX + RCA*FCA) !GBA*CF
988 rnew_wrk(l) = rnew_tst
989 !-----------------------------------------------------------------------
990 ! if RNEW>0, there is growth and/or new precip formation
991 !-----------------------------------------------------------------------
992 has_rnew: if( rlsog(l) > adj_factor*(rax*fax + rca*fca) ) then
993 !-----------------------------------------------------------------------
994 ! Min cloudwater requirement for cloud with new precip
995 ! Min CF is set at top for LE, at end for other levels
996 ! CWMIN is only needed for new precip formation - do not need for RNEW<0
997 !-----------------------------------------------------------------------
998 if( cfxx(l) == zero ) then
999 write(*,*) 'offline inputs'
1000 write(*,*) qttjfl(:,n)
1009 write(*,*) evaprate(:)
1010 write(*,*) hstar(:,n)
1011 write(message,'('' washout: cloud fraction == 0 @ i,j,l,n = '',4i4)') ii,jj,l,n
1012 call wrf_debug( 15, trim(message) )
1013 QTTJFL(:lpar,N) = QTT(:lpar)
1016 rnew_flag(l) = .true.
1017 CLWX = max( CLWC(L)+CIWC(L),CWMIN*CFXX(L) )
1021 !-----------------------------------------------------------------------
1022 ! Area of old cloud and new cloud
1023 !-----------------------------------------------------------------------
1025 FCXB = max( zero,CFXX(L)-FCXA )
1026 !-----------------------------------------------------------------------
1028 ! For ice and mixed phase, grow precip in old cloud by riming
1029 ! Use only portion of cloudwater in old cloud fraction
1030 ! and rain above old cloud fraction
1031 ! COLEFF from Lohmann and Roeckner (1996), Loss rate from Rotstayn (1997)
1032 !-----------------------------------------------------------------------
1034 if( freezing(l) ) then
1035 COLEFFSNOW = exp( 2.5e-2*(TEM(L) - TICE) )
1036 if( TEM(L) <= TFROZ ) then
1037 RHOSNOW = RHOSNOWFIX
1039 RHOSNOW = 0.303*(TEM(L) - TFROZ)*RHOSNOWFIX
1041 if( FCXA > zero ) then
1042 if( DCA > zero ) then
1043 DELTARIMEMASS = CLWX*QM(L)*(FCXA/CFXX(L))* &
1044 (one - exp( (-COLEFFSNOW/(DCA*1.e-3))*((RCA)/(2.*RHOSNOW))*DTSCAV )) !uses GBA R
1046 DELTARIMEMASS = zero
1049 DELTARIMEMASS = zero
1051 !-----------------------------------------------------------------------
1052 ! Increase in precip rate due to riming (kg/m2/s):
1053 ! Limit to total increase in R in cloud
1054 !-----------------------------------------------------------------------
1055 if( FCXA > zero ) then
1056 DELTARIME = min( RNEW/FCXA,DELTARIMEMASS/(FCXA*GAREA*DTSCAV) ) !GBA
1061 deltarime_wrk(l) = deltarime
1063 !-----------------------------------------------------------------------
1064 ! Find diameter of rimed precip, must be at least .1mm
1065 !-----------------------------------------------------------------------
1066 if( RCA > zero ) then
1067 DOR = max( DMIN,(((RCA+DELTARIME)/RCA)**VOLPOW)*DCA )
1071 !-----------------------------------------------------------------------
1072 ! If there is some in-cloud precip left, we have new precip formation
1073 ! Will be spread over whole cloud fraction
1074 !-----------------------------------------------------------------------
1075 ! Calculate precip rate in old and new cloud fractions
1076 !-----------------------------------------------------------------------
1077 RPRECIP = (RNEW-(DELTARIME*FCXA))/CFXX(L) !kg/m2/s !GBA
1078 !-----------------------------------------------------------------------
1079 ! Calculate precip rate in old and new cloud fractions
1080 !-----------------------------------------------------------------------
1081 RCXA = RCA + DELTARIME + RPRECIP !kg/m2/s GBA
1082 RCXB = RPRECIP !kg/m2/s GBA
1084 !-----------------------------------------------------------------------
1085 ! Find diameter of new precip from empirical relation using Rprecip
1086 ! in given area of box- use density of water, not snow, to convert kg/s
1087 ! to mm/s -> as given in Field and Heymsfield
1088 ! Also calculate diameter of mixed precip,DCXA, from empirical relation
1089 ! using total R in FCXA - this will give larger particles than averaging DOR and
1090 ! DNEW in the next level
1091 ! DNEW and DCXA must be at least .1mm
1092 !-----------------------------------------------------------------------
1093 if( RPRECIP > zero ) then
1094 WEMP = (CLWX*QM(L))/(GAREA*CFXX(L)*DELZ(L)) !kg/m3
1095 REMP = RPRECIP/((RHORAIN/1.e3)) !mm/s local
1096 DNEW = DEMPIRICAL( WEMP, REMP )
1097 DNEW = max( DMIN,DNEW )
1098 if( FCXB > zero ) then
1107 if( FCXA > zero ) then
1108 WEMP = (CLWX*QM(L)*(FCXA/CFXX(L)))/(GAREA*FCXA*DELZ(L)) !kg/m3
1109 REMP = RCXA/((RHORAIN/1.e3)) !mm/s local
1110 DEMP = DEMPIRICAL( WEMP, REMP )
1111 DCXA = ((RCA+DELTARIME)/RCXA)*DOR + (RPRECIP/RCXA)*DNEW
1112 DCXA = max( DEMP,DCXA )
1113 DCXA = max( DMIN,DCXA )
1118 if( QTT(L) > zero ) then
1119 !-----------------------------------------------------------------------
1121 !-----------------------------------------------------------------------
1122 ! For ice, rainout only hno3/aerosols using new precip
1123 ! Tracer dissolved given by Kaercher and Voigt (2006) for T<258K
1124 ! For T>258K, use Henry's Law with Retention coefficient
1125 ! Rain out in whole CF
1126 !-----------------------------------------------------------------------
1127 if( RPRECIP > zero ) then
1128 if( LICETYP == 1 ) then
1129 RRAIN = RPRECIP*GAREA !kg/s local
1130 call DISGAS( CLWX, CFXX(L), TCMASS(N), HSTAR(L,N), &
1131 TEM(L),POFL(L),QM(L), &
1133 ! QTT(L)*CFXX(L),QTDISCF )
1134 QTT(L)*CFXX(L),QTDISCF, is_hno3, RETEFF(N) )
1136 call RAINGAS( RRAIN, DTSCAV, CLWX, CFXX(L), &
1137 QM(L), QTT(L), QTDISCF, QTRAIN )
1138 WRK = QTRAIN/CFXX(L)
1139 QTRAINCXA = FCXA*WRK
1140 QTRAINCXB = FCXB*WRK
1141 elseif( LICETYP == 2 ) then
1146 !-----------------------------------------------------------------------
1147 ! For ice, accretion removal for hno3 and aerosols is propotional to riming,
1148 ! no accretion removal for gases
1149 ! remove only in mixed portion of cloud
1150 ! Limit DELTARIMEMASS to RNEW*DTSCAV for ice - evaporation of rimed ice to match
1151 ! RNEW precip rate would result in HNO3 escaping from ice (no trapping)
1152 !-----------------------------------------------------------------------
1153 if( DELTARIME > zero ) then
1154 if( LICETYP == 1 ) then
1155 if( TEM(L) <= TFROZ ) then
1156 RHOSNOW = RHOSNOWFIX
1158 RHOSNOW = 0.303*(TEM(L) - TFROZ)*RHOSNOWFIX
1161 call DISGAS( CLWX*(FCXA/CFXX(L)), FCXA, TCMASS(N), &
1162 HSTAR(L,N), TEM(L), POFL(L), &
1164 ! QM(L), QTCXA, QTDISRIME )
1165 QM(L), QTCXA, QTDISRIME, is_hno3, RETEFF(N) )
1167 QTDISSTAR = (QTDISRIME*QTCXA)/(QTDISRIME + QTCXA)
1168 QTRIMECXA = QTCXA* &
1169 (one - exp((-COLEFFSNOW/(DCA*1.e-3))* &
1170 (RCA/(2.*RHOSNOW))* & !uses GBA R
1171 (QTDISSTAR/QTCXA)*DTSCAV))
1172 QTRIMECXA = min( QTRIMECXA, &
1173 ((RNEW*GAREA*DTSCAV)/(CLWX*QM(L)*(FCXA/CFXX(L))))*QTDISSTAR)
1174 elseif( LICETYP == 2 ) then
1183 !-----------------------------------------------------------------------
1184 ! For ice, no washout in interstitial cloud air
1185 !-----------------------------------------------------------------------
1189 !-----------------------------------------------------------------------
1191 ! For rain, accretion increases rain rate but diameter remains constant
1192 ! Diameter is 4mm (not used)
1193 !-----------------------------------------------------------------------
1195 if( FCXA > zero ) then
1196 DELTARIMEMASS = (CLWX*QM(L))*(FCXA/CFXX(L))* &
1197 (one - exp( -0.24*COLEFFRAIN*((RCA)**0.75)*DTSCAV )) !local
1199 DELTARIMEMASS = zero
1201 !-----------------------------------------------------------------------
1202 ! Increase in precip rate due to riming (kg/m2/s):
1203 ! Limit to total increase in R in cloud
1204 !-----------------------------------------------------------------------
1205 if( FCXA > zero ) then
1206 DELTARIME = min( RNEW/FCXA,DELTARIMEMASS/(FCXA*GAREA*DTSCAV) ) !GBA
1210 !-----------------------------------------------------------------------
1211 ! If there is some in-cloud precip left, we have new precip formation
1212 !-----------------------------------------------------------------------
1213 RPRECIP = (RNEW-(DELTARIME*FCXA))/CFXX(L) !GBA
1215 RCXA = RCA + DELTARIME + RPRECIP !kg/m2/s GBA
1216 RCXB = RPRECIP !kg/m2/s GBA
1218 if( FCXB > zero ) then
1223 !-----------------------------------------------------------------------
1225 ! For rain, rainout both hno3/aerosols and gases using new precip
1226 !-----------------------------------------------------------------------
1227 if( QTT(L) > zero ) then
1228 if( RPRECIP > zero ) then
1229 RRAIN = (RPRECIP*GAREA) !kg/s local
1230 call DISGAS( CLWX, CFXX(L), TCMASS(N), HSTAR(L,N), &
1231 TEM(L), POFL(L), QM(L), &
1233 ! QTT(L)*CFXX(L), QTDISCF )
1234 QTT(L)*CFXX(L), QTDISCF, is_hno3, RETEFF(N) )
1236 call RAINGAS( RRAIN, DTSCAV, CLWX, CFXX(L), &
1237 QM(L), QTT(L), QTDISCF, QTRAIN )
1238 WRK = QTRAIN/CFXX(L)
1239 QTRAINCXA = FCXA*WRK
1240 QTRAINCXB = FCXB*WRK
1242 !-----------------------------------------------------------------------
1243 ! For rain, accretion removal is propotional to riming
1244 ! caclulate for hno3/aerosols and gases
1245 ! Remove only in mixed portion of cloud
1246 ! Limit DELTARIMEMASS to RNEW*DTSCAV
1247 !-----------------------------------------------------------------------
1248 if( DELTARIME > zero ) then
1250 call DISGAS( CLWX*(FCXA/CFXX(L)), FCXA, TCMASS(N), &
1251 HSTAR(L,N), TEM(L), POFL(L), &
1253 ! QM(L), QTCXA, QTDISRIME )
1254 QM(L), QTCXA, QTDISRIME, is_hno3, RETEFF(N) )
1256 QTDISSTAR = (QTDISRIME*QTCXA)/(QTDISRIME + QTCXA)
1257 QTRIMECXA = QTCXA* &
1258 (one - exp(-0.24*COLEFFRAIN* &
1259 ((RCA)**0.75)* & !local
1260 (QTDISSTAR/QTCXA)*DTSCAV))
1261 QTRIMECXA = min( QTRIMECXA, &
1262 ((RNEW*GAREA*DTSCAV)/(CLWX*QM(L)*(FCXA/CFXX(L))))*QTDISSTAR)
1271 !-----------------------------------------------------------------------
1272 ! For rain, washout gases and HNO3/aerosols using rain from above old cloud
1273 ! Washout for HNO3/aerosols is only on non-dissolved portion, impaction-style
1274 ! Washout for gases is on non-dissolved portion, limited by QTTOP+QTRIME
1275 !-----------------------------------------------------------------------
1276 if( RCA > zero ) then
1277 QTPRECIP = FCXA*QTT(L) - QTDISRIME
1278 if( LWASHTYP == 1 ) then
1279 if( QTPRECIP > zero ) then
1280 QTWASHCXA = QTPRECIP*(one - exp( -0.24*COLEFFAER*((RCA)**0.75)*DTSCAV )) !local
1285 elseif( LWASHTYP == 2 ) then
1286 RWASH = RCA*GAREA !kg/s local
1287 if( QTPRECIP > zero ) then
1288 call WASHGAS( RWASH, FCA, DTSCAV, QTTOPCA+QTRIMECXA, &
1289 HSTAR(L,N), TEM(L), POFL(L), &
1290 QM(L), QTPRECIP, QTWASHCXA, QTEVAPCXA )
1298 !-----------------------------------------------------------------------
1299 ! If RNEW<O, confine precip to area of cloud above
1300 ! FCXA does not require a minimum (could be zero if R(L).le.what
1301 ! evaporated in ambient)
1302 !-----------------------------------------------------------------------
1304 CLWX = CLWC(L) + CIWC(L)
1309 FCXB = max( zero,CFXX(L)-FCXA )
1316 !-----------------------------------------------------------------------
1317 ! Put rain into cloud up to RCA so that we evaporate
1318 ! from ambient first
1319 ! Adjust ambient to try to match RLS(L)
1320 ! If no cloud, RAX=R(L)
1321 !-----------------------------------------------------------------------
1322 if( FCXA > zero ) then
1323 RCXA = min( RCA,RLS(L)/(GAREA*FCXA) ) !kg/m2/s GBA
1324 if( FAX > zero .and. ((RCXA+1.e-12) < RLS(L)/(GAREA*FCXA)) ) then
1325 RAXADJF = RLS(L)/GAREA - RCXA*FCXA
1326 RAMPCT = RAXADJF/(RAX*FAX)
1328 if( FAXADJ > zero ) then
1329 RAXADJ = RAXADJF/FAXADJ
1340 if( FAX > zero ) then
1341 RAXADJF = RLS(L)/GAREA
1342 RAMPCT = RAXADJF/(RAX*FAX)
1344 if( FAXADJ > zero ) then
1345 RAXADJ = RAXADJF/FAXADJ
1356 QTEVAPAXP = min( QTTOPAA,QTTOPAA - (RAMPCT*(QTTOPAA-QTEVAPAXP)) )
1360 !-----------------------------------------------------------------------
1361 ! IN-CLOUD EVAPORATION/WASHOUT
1362 ! If precip out the bottom of the cloud is 0, evaporate everything
1363 ! If there is no cloud, QTTOPCA=0, so nothing happens
1364 !-----------------------------------------------------------------------
1365 if( RCXA <= zero ) then
1370 !-----------------------------------------------------------------------
1371 ! If rain out the bottom of the cloud is >0 (but .le. RCA):
1372 ! For ice, decrease particle size,
1374 ! no evap for non-ice gases (b/c there is nothing in ice)
1375 ! T<Tmix,release hno3& aerosols
1376 ! release is amount dissolved in ice mass released
1377 ! T>Tmix, hno3&aerosols are incorporated into ice structure:
1379 ! For rain, assume full evaporation of some raindrops
1380 ! proportional evaporation for all species
1381 ! washout for gases using Rbot
1382 ! impact washout for hno3/aerosol portion in gas phase
1383 !-----------------------------------------------------------------------
1384 ! if (TEM(L) < TICE ) then
1386 if( freezing(l) ) then
1388 DCXA = ((RCXA/RCA)**VOLPOW)*DCA
1389 if( LICETYP == 1 ) then
1390 if( TEM(L) <= TMIX ) then
1391 MASSLOSS = (RCA-RCXA)*FCXA*GAREA*DTSCAV
1392 !-----------------------------------------------------------------------
1393 ! note-QTT doesn't matter b/c T<258K
1394 !-----------------------------------------------------------------------
1395 call DISGAS( (MASSLOSS/QM(L)), FCXA, TCMASS(N), &
1396 HSTAR(L,N), TEM(L), POFL(L), &
1398 ! QM(L), QTT(L), QTEVAPCXA )
1399 QM(L), QTT(L), QTEVAPCXA, is_hno3, RETEFF(N) )
1401 QTEVAPCXA = min( QTTOPCA,QTEVAPCXA )
1405 elseif( LICETYP == 2 ) then
1409 QTEVAPCXAP = (RCA - RCXA)/RCA*QTTOPCA
1412 if( LWASHTYP == 1 ) then
1413 if( QTT(L) > zero ) then
1414 call DISGAS( CLWX*(FCXA/CFXX(L)), FCXA, TCMASS(N), &
1415 HSTAR(L,N), TEM(L), POFL(L), &
1417 ! QM(L), QTCXA, QTDISCXA )
1418 QM(L), QTCXA, QTDISCXA, is_hno3, RETEFF(N) )
1420 if( QTCXA > QTDISCXA ) then
1421 QTWASHCXA = (QTCXA - QTDISCXA)*(one - exp( -0.24*COLEFFAER*((RCXA)**0.75)*DTSCAV )) !local
1430 elseif (LWASHTYP == 2 ) then
1431 RWASH = RCXA*GAREA !kg/s local
1432 call WASHGAS( RWASH, FCXA, DTSCAV, QTTOPCA, HSTAR(L,N), &
1433 TEM(L), POFL(L), QM(L), &
1434 QTCXA-QTDISCXA, QTWASHCXA, QTEVAPCXAW )
1436 QTEVAPCXA = QTEVAPCXAP + QTEVAPCXAW
1441 !-----------------------------------------------------------------------
1443 ! Ambient precip is finalized - if it is rain, washout
1444 ! no ambient washout for ice, since gases are in vapor phase
1445 !-----------------------------------------------------------------------
1446 if( RAX > zero ) then
1447 ! if( TEM(L) >= TICE ) then
1448 if( .not. freezing(l) ) then
1450 if( LWASHTYP == 1 ) then
1452 (one - exp(-0.24*COLEFFAER* &
1453 ((RAX)**0.75)*DTSCAV)) !local
1455 elseif( LWASHTYP == 2 ) then
1456 RWASH = RAX*GAREA !kg/s local
1457 call WASHGAS( RWASH, FAX, DTSCAV, QTTOPAA, HSTAR(L,N), &
1458 TEM(L), POFL(L), QM(L), QTAX, &
1459 QTWASHAX, QTEVAPAXW )
1469 QTEVAPAX = QTEVAPAXP + QTEVAPAXW
1471 !-----------------------------------------------------------------------
1473 ! Require CF if our ambient evaporation rate would give less
1474 ! precip than R from model.
1475 !-----------------------------------------------------------------------
1477 rls_wrk(l) = rls(l)/garea
1489 FAMA = max( FCXA + FCXB + FAX - CFR(LM1),zero )
1490 if( FAX > zero ) then
1495 if( FCXA > zero ) then
1500 if( FCXB > zero ) then
1506 if( CFR(LM1) >= CFMIN ) then
1507 CFXX(LM1) = CFR(LM1)
1509 if( adj_factor*RLSOG(LM1) >= (RCXA*FCXA + RCXB*FCXB + RAX*FAX)*(one - EVAPRATE(LM1)) ) then
1511 cf_trigger(lm1) = .true.
1513 CFXX(LM1) = CFR(LM1)
1516 !-----------------------------------------------------------------------
1517 ! Figure out what will go into ambient and cloud below
1518 ! Don't do for lowest level
1519 !-----------------------------------------------------------------------
1520 if( FAX > zero ) then
1522 AMPCT = max( zero,min( one,(CFXX(L) + FAX - CFXX(LM1))/FAX ) )
1523 AMCLPCT = one - AMPCT
1529 if( FCXB > zero ) then
1531 CLNEWPCT = max( zero,min( (CFXX(LM1) - FCXA)/FCXB,one ) )
1532 CLNEWAMPCT = one - CLNEWPCT
1538 if( FCXA > zero ) then
1540 CLOLDPCT = max( zero,min( CFXX(LM1)/FCXA,one ) )
1541 CLOLDAMPCT = one - CLOLDPCT
1547 !-----------------------------------------------------------------------
1548 ! Remix everything for the next level
1549 !-----------------------------------------------------------------------
1550 FCA = min( CFXX(LM1),FCXA*CLOLDPCT + CLNEWPCT*FCXB + AMCLPCT*FAX )
1551 if( FCA > zero ) then
1552 !-----------------------------------------------------------------------
1553 ! Maintain cloud core by reducing NC and AM area going into cloud below
1554 !-----------------------------------------------------------------------
1555 RCA = (RCXA*FCXA*CLOLDPCT + RCXB*FCXB*CLNEWPCT + RAX*FAX*AMCLPCT)/FCA
1556 if( RCA > zero ) then
1557 DCA = (RCXA*FCXA*CLOLDPCT)/(RCA*FCA)*DCXA + &
1558 (RCXB*FCXB*CLNEWPCT)/(RCA*FCA)*DCXB + &
1559 (RAX*FAX*AMCLPCT)/(RCA*FCA)*DAX
1569 FAMA = FCXA + FCXB + FAX - CFXX(LM1)
1570 if( FAMA > zero ) then
1571 RAMA = (RCXA*FCXA*CLOLDAMPCT + RCXB*FCXB*CLNEWAMPCT + RAX*FAX*AMPCT)/FAMA
1572 if( RAMA > zero ) then
1573 DAMA = (RCXA*FCXA*CLOLDAMPCT)/(RAMA*FAMA)*DCXA + &
1574 (RCXB*FCXB*CLNEWAMPCT)/(RAMA*FAMA)*DCXB + &
1575 (RAX*FAX*AMPCT)/(RAMA*FAMA)*DAX
1598 if( RLS(LM1) > zero ) then
1599 CFXX(LM1) = max( CFMIN,CFR(LM1) )
1600 ! if( CFR(LM1) >= CFMIN ) then
1601 ! CFXX(LM1) = CFR(LM1)
1606 CFXX(LM1) = CFR(LM1)
1627 !-----------------------------------------------------------------------
1628 ! Net loss can not exceed QTT in each region
1629 !-----------------------------------------------------------------------
1630 QTNETLCXA = QTRAINCXA + QTRIMECXA + QTWASHCXA - QTEVAPCXA
1631 QTNETLCXA = min( QTT(L)*FCXA,QTNETLCXA )
1633 QTNETLCXB =QTRAINCXB
1634 QTNETLCXB = min( QTT(L)*FCXB,QTNETLCXB )
1636 QTNETLAX = QTWASHAX - QTEVAPAX
1637 QTNETLAX = min( QTT(L)*FAX,QTNETLAX )
1639 QTTNEW(L) = QTT(L) - (QTNETLCXA + QTNETLCXB + QTNETLAX)
1642 QTTOPCAX = (QTTOPCA + QTNETLCXA)*CLOLDPCT + QTNETLCXB*CLNEWPCT + (QTTOPAA + QTNETLAX)*AMCLPCT
1643 QTTOPAAX = (QTTOPCA + QTNETLCXA)*CLOLDAMPCT + QTNETLCXB*CLNEWAMPCT + (QTTOPAA + QTNETLAX)*AMPCT
1648 !-----------------------------------------------------------------------
1649 ! reload new tracer mass and rescale moments: check upper limits (LE)
1650 !-----------------------------------------------------------------------
1651 QTTJFL(:le,N) = QTTNEW(:le)
1654 end subroutine WASHOUT
1656 subroutine DISGAS( CLWX, CFX, MOLMASS, HSTAR, &
1660 QT, QTDIS, is_hno3, RETEFF )
1663 !-----------------------------------------------------------------------
1665 !-----------------------------------------------------------------------
1666 real, intent(in) :: CLWX,CFX !cloud water,cloud fraction
1667 real, intent(in) :: MOLMASS !molecular mass of tracer
1668 real, intent(in) :: HSTAR !Henry's Law coeffs A*exp(-B/T)
1669 real, intent(in) :: TM !temperature of box (K)
1670 real, intent(in) :: PR !pressure of box (hPa)
1671 real, intent(in) :: QM !air mass in box (kg)
1672 real, intent(in) :: QT !tracer in box (kg)
1673 real, intent(out) :: QTDIS !tracer dissolved in aqueous phase
1676 logical, intent(in) :: is_hno3
1677 real, intent(in) :: RETEFF !Ice retention parameter
1680 !-----------------------------------------------------------------------
1682 !-----------------------------------------------------------------------
1685 ! real, parameter :: RETEFF = 0.5
1686 ! real, parameter :: RETEFF = 1.0
1691 !-----------------------------------------------------------------------
1692 ! calculate rate of uptake of tracer
1693 !-----------------------------------------------------------------------
1695 !-----------------------------------------------------------------------
1696 ! effective Henry's Law constant: H* = moles-T / liter-precip / press(atm-T)
1697 ! p(atm of tracer-T) = (QT/QM) * (.029/MolWt-T) * pressr(hPa)/1000
1698 ! limit temperature effects to T above freezing
1699 ! MU from fit to Kaercher and Voigt (2006)
1700 !-----------------------------------------------------------------------
1701 if( TM >= TICE ) then
1702 QTDIS = (HSTAR*(QT/(QM*CFX))*0.029*(PR/1.0e3))*(CLWX*QM)
1704 ! elseif( TM <= TMIX ) then
1705 elseif( TM <= TMIX .and. is_hno3 ) then
1707 MUEMP = exp( -14.2252 + TM*(1.55704e-1 - 7.1929e-4*TM) )
1708 QTDIS = MUEMP*(MOLMASS/18.)*(CLWX*QM)
1710 QTDIS = RETEFF*((HSTAR*(QT/(QM*CFX))*0.029*(PR/1.0e3))*(CLWX*QM))
1713 end subroutine DISGAS
1715 subroutine RAINGAS( RRAIN, DTSCAV, CLWX, CFX, QM, QT, QTDIS, QTRAIN )
1716 !-----------------------------------------------------------------------
1717 !---New trace-gas rainout from large-scale precip with two time scales,
1718 !---one based on precip formation from cloud water and one based on
1719 !---Henry's Law solubility: correct limit for delta-t
1721 !---NB this code does not consider the aqueous dissociation (eg, C-q)
1722 !--- that makes uptake of HNO3 and H2SO4 so complete. To do so would
1723 !--- require that we keep track of the pH of the falling rain.
1724 !---THUS the Henry's Law coefficient KHA needs to be enhanced to incldue this!
1725 !---ALSO the possible formation of other soluble species from, eg, CH2O, H2O2
1726 !--- can be considered with enhanced values of KHA.
1728 !---Does NOT now use RMC (moist conv rain) but could, assuming 30% coverage
1729 !-----------------------------------------------------------------------
1731 !-----------------------------------------------------------------------
1733 !-----------------------------------------------------------------------
1734 real, intent(in) :: RRAIN !new rain formation in box (kg/s)
1735 real, intent(in) :: DTSCAV !time step (s)
1736 real, intent(in) :: CLWX,CFX !cloud water and cloud fraction
1737 real, intent(in) :: QM !air mass in box (kg)
1738 real, intent(in) :: QT !tracer in box (kg)
1739 real, intent(in) :: QTDIS !tracer in aqueous phase (kg)
1740 real, intent(out) :: QTRAIN !tracer picked up by new rain
1742 !-----------------------------------------------------------------------
1744 !-----------------------------------------------------------------------
1745 real :: QTLF, QTDISSTAR
1747 QTDISSTAR = (QTDIS*(QT*CFX))/(QTDIS+(QT*CFX))
1749 !-----------------------------------------------------------------------
1750 ! Tracer Loss frequency (1/s) within cloud fraction:
1751 !-----------------------------------------------------------------------
1752 QTLF = (RRAIN*QTDISSTAR)/(CLWX*QM*QT*CFX)
1754 !-----------------------------------------------------------------------
1755 ! in time = DTSCAV, the amount of QTT scavenged is calculated
1756 ! from CF*AMOUNT OF UPTAKE
1757 !-----------------------------------------------------------------------
1758 QTRAIN = QT*CFX*(one - exp( -DTSCAV*QTLF ))
1760 end subroutine RAINGAS
1762 subroutine WASHGAS( RWASH, BOXF, DTSCAV, QTRTOP, HSTAR, TM, PR, QM, &
1763 QT, QTWASH, QTEVAP )
1764 !-----------------------------------------------------------------------
1765 !---for most gases below-cloud washout assume Henry-Law equilib with precip
1766 !---assumes that precip is liquid, if frozen, do not call this sub
1767 !---since solubility is moderate, fraction of box with rain does not matter
1768 !---NB this code does not consider the aqueous dissociation (eg, C-q)
1769 !--- that makes uptake of HNO3 and H2SO4 so complete. To do so would
1770 !--- require that we keep track of the pH of the falling rain.
1771 !---THUS the Henry's Law coefficient KHA needs to be enhanced to incldue this!
1772 !---ALSO the possible formation of other soluble species from, eg, CH2O, H2O2
1773 !--- can be considered with enhanced values of KHA.
1774 !-----------------------------------------------------------------------
1776 !-----------------------------------------------------------------------
1778 !-----------------------------------------------------------------------
1779 real, intent(in) :: RWASH ! precip leaving bottom of box (kg/s)
1780 real, intent(in) :: BOXF ! fraction of box with washout
1781 real, intent(in) :: DTSCAV ! time step (s)
1782 real, intent(in) :: QTRTOP ! tracer-T in rain entering top of box over time step (kg)
1783 real, intent(in) :: HSTAR ! Henry's Law coeffs A*exp(-B/T)
1784 real, intent(in) :: TM ! temperature of box (K)
1785 real, intent(in) :: PR ! pressure of box (hPa)
1786 real, intent(in) :: QT ! tracer in box (kg)
1787 real, intent(in) :: QM ! air mass in box (kg)
1788 real, intent(out) :: QTWASH ! tracer picked up by precip (kg)
1789 real, intent(out) :: QTEVAP ! tracer evaporated from precip (kg)
1791 !-----------------------------------------------------------------------
1793 !-----------------------------------------------------------------------
1794 real :: FWASH, QTMAX, QTDIF
1796 !-----------------------------------------------------------------------
1797 ! effective Henry's Law constant: H* = moles-T / liter-precip / press(atm-T)
1798 ! p(atm of tracer-T) = (QT/QM) * (.029/MolWt-T) * pressr(hPa)/1000
1799 ! limit temperature effects to T above freezing
1800 !-----------------------------------------------------------------------
1802 !-----------------------------------------------------------------------
1803 ! effective washout frequency (1/s):
1804 !-----------------------------------------------------------------------
1805 FWASH = (RWASH*HSTAR*29.e-6*PR)/(QM*BOXF)
1806 !-----------------------------------------------------------------------
1807 ! equilib amount of T (kg) in rain thru bottom of box over time step
1808 !-----------------------------------------------------------------------
1809 QTMAX = QT*FWASH*DTSCAV
1810 if( QTMAX > QTRTOP ) then
1811 !-----------------------------------------------------------------------
1812 ! more of tracer T can go into rain
1813 !-----------------------------------------------------------------------
1814 QTDIF = min( QT,QTMAX-QTRTOP )
1815 QTWASH = QTDIF * (one - exp( -DTSCAV*FWASH ))
1818 !-----------------------------------------------------------------------
1819 ! too much of T in rain, must degas/evap T
1820 !-----------------------------------------------------------------------
1822 QTEVAP = QTRTOP - QTMAX
1825 end subroutine WASHGAS
1827 function DEMPIRICAL( CWATER, RRATE )
1829 !-----------------------------------------------------------------------
1831 !-----------------------------------------------------------------------
1832 real, intent(in) :: CWATER
1833 real, intent(in) :: RRATE
1835 !-----------------------------------------------------------------------
1837 !-----------------------------------------------------------------------
1838 real(8), parameter :: big_diameter = 100._8 ! mm
1839 real(8), parameter :: const0 = .638_8
1840 real(8), parameter :: const1 = oner8 + const0
1842 real(8) :: RRATEX, WX, THETA, PHI, ETA, BETA, ALPHA, BEE
1843 real(8) :: GAMTHETA, GAMBETA
1844 real(8) :: numer, denom
1845 real(8) :: diameter ! mm
1849 if( cwater > 0._8 ) then
1850 RRATEX = real(RRATE,kind=8)*3600._8 !mm/hr
1851 WX = real(CWATER,kind=8)*1.0e3_8 !g/m3
1853 if( RRATEX > 0.04_8 ) then
1854 THETA = exp( -1.43_8*log10( 7._8*RRATEX ) ) + 2.8_8
1859 PHI = RRATEX/(3600._8*10._8) !cgs units
1860 ETA = exp( 3.01_8*THETA - 10.5_8 )
1862 ALPHA = exp( FOURR8*(BETA - 3.5_8) )
1863 BEE = const0*BETA - ONER8
1864 GAMTHETA = real( GAMMA( real(THETA,kind=4) ),kind=8 )
1865 GAMBETA = real( GAMMA( real(BETA + ONER8,kind=4) ),kind=8 )
1867 numer = WX*ETA*GAMTHETA
1868 denom = 1.0e6_8*ALPHA*PHI*GAMBETA
1869 diameter = ((numer/denom)**(-oner8/BEE))*10._8
1870 diameter = min( big_diameter,diameter )
1871 DEMPIRICAL = real( diameter )
1872 ! DEMPIRICAL = (((WX*ETA*GAMTHETA)/(1.0e6*ALPHA*PHI*GAMBETA))** (-one/BEE))*10. ! in mm (wx/1e6 for cgs)
1877 end function DEMPIRICAL
1880 !-----------------------------------------------------------------------
1881 ! Purpose: Compute the gamma function Ahat(x)
1882 ! Input : x --- Argument of Ahat(x)
1883 ! ( x is not equal to 0,-1,-2, ... )
1884 ! Output: GA --- Ahat(x)
1885 !-----------------------------------------------------------------------
1887 !-----------------------------------------------------------------------
1889 !-----------------------------------------------------------------------
1890 real, intent(in) :: X
1892 !-----------------------------------------------------------------------
1894 !-----------------------------------------------------------------------
1895 real, parameter :: PI = 3.141592653589793e0
1901 !-----------------------------------------------------------------------
1902 ! function definition
1903 !-----------------------------------------------------------------------
1906 DATA G/1.0e0,0.5772156649015329, &
1907 -0.6558780715202538e0, -0.420026350340952e-1, &
1908 0.1665386113822915e0,-.421977345555443e-1, &
1909 -.96219715278770e-2, .72189432466630e-2, &
1910 -.11651675918591e-2, -.2152416741149e-3, &
1911 .1280502823882e-3, -.201348547807e-4, &
1912 -.12504934821e-5, .11330272320e-5, &
1913 -.2056338417e-6, .61160950e-8, &
1914 .50020075e-8, -.11812746e-8, &
1915 .1043427e-9, .77823e-11, &
1916 -.36968e-11, .51e-12, &
1917 -.206e-13, -.54e-14, .14e-14, .1e-15/
1920 IF( x == real( int(x) ) ) then
1925 GAMMA = GAMMA*real(K)
1931 IF( ABS(X) > ONE ) THEN
1947 IF( ABS(X) > ONE ) THEN
1950 GAMMA = -PI/(X*GAMMA*SIN( PI*X ))
1957 END MODULE module_mozcart_wetscav