LCOV - code coverage report
Current view: top level - physics/pumas-frozen - micro_mg1_0.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1509 0.0 %
Date: 2025-01-13 21:54:50 Functions: 0 3 0.0 %

          Line data    Source code
       1             : module micro_mg1_0
       2             : 
       3             : !---------------------------------------------------------------------------------
       4             : ! Purpose:
       5             : !   MG microphysics
       6             : !
       7             : ! Author: Andrew Gettelman, Hugh Morrison.
       8             : ! Contributions from: Xiaohong Liu and Steve Ghan
       9             : ! December 2005-May 2010
      10             : ! Description in: Morrison and Gettelman, 2008. J. Climate (MG2008)
      11             : !                 Gettelman et al., 2010 J. Geophys. Res. - Atmospheres (G2010)         
      12             : ! for questions contact Hugh Morrison, Andrew Gettelman
      13             : ! e-mail: morrison@ucar.edu, andrew@ucar.edu
      14             : !
      15             : ! NOTE: Modified to allow other microphysics packages (e.g. CARMA) to do ice
      16             : ! microphysics in cooperation with the MG liquid microphysics. This is
      17             : ! controlled by the do_cldice variable.
      18             : !
      19             : ! NOTE: If do_cldice is false, then MG microphysics should not update CLDICE
      20             : ! or NUMICE; however, it is assumed that the other microphysics scheme will have
      21             : ! updated CLDICE and NUMICE. The other microphysics should handle the following
      22             : ! processes that would have been done by MG:
      23             : !   - Detrainment (liquid and ice)
      24             : !   - Homogeneous ice nucleation
      25             : !   - Heterogeneous ice nucleation
      26             : !   - Bergeron process
      27             : !   - Melting of ice
      28             : !   - Freezing of cloud drops
      29             : !   - Autoconversion (ice -> snow)
      30             : !   - Growth/Sublimation of ice
      31             : !   - Sedimentation of ice
      32             : !---------------------------------------------------------------------------------
      33             : ! modification for sub-columns, HM, (orig 8/11/10)
      34             : ! This is done using the logical 'microp_uniform' set to .true. = uniform for subcolumns
      35             : !---------------------------------------------------------------------------------
      36             : 
      37             : ! Procedures required:
      38             : ! 1) An implementation of the gamma function (if not intrinsic).
      39             : ! 2) saturation vapor pressure to specific humidity formula
      40             : ! 3) svp over water
      41             : ! 4) svp over ice
      42             : 
      43             : #ifndef HAVE_GAMMA_INTRINSICS
      44             : use shr_spfn_mod, only: gamma => shr_spfn_gamma
      45             : #endif
      46             : 
      47             :   use wv_sat_methods, only: &
      48             :        svp_water => wv_sat_svp_water, &
      49             :        svp_ice => wv_sat_svp_ice, &
      50             :        svp_to_qsat => wv_sat_svp_to_qsat
      51             : 
      52             :   use phys_control, only: phys_getopts
      53             : 
      54             : implicit none
      55             : private
      56             : save
      57             : 
      58             : ! Note: The liu_in option has been removed, as there was a serious bug with this
      59             : ! option being set to false. The code now behaves as if the default liu_in=.true.
      60             : ! is always on. Addition/reinstatement of ice nucleation options will likely be
      61             : ! done outside of this module.
      62             : 
      63             : public :: &
      64             :      micro_mg_init, &
      65             :      micro_mg_get_cols, &
      66             :      micro_mg_tend
      67             : 
      68             : integer, parameter :: r8 = selected_real_kind(12)      ! 8 byte real
      69             : 
      70             : real(r8) :: g              !gravity
      71             : real(r8) :: r              !Dry air Gas constant
      72             : real(r8) :: rv             !water vapor gas contstant
      73             : real(r8) :: cpp            !specific heat of dry air
      74             : real(r8) :: rhow           !density of liquid water
      75             : real(r8) :: tmelt          ! Freezing point of water (K)
      76             : real(r8) :: xxlv           ! latent heat of vaporization
      77             : real(r8) :: xlf            !latent heat of freezing
      78             : real(r8) :: xxls           !latent heat of sublimation
      79             : 
      80             : real(r8) :: rhosn  ! bulk density snow
      81             : real(r8) :: rhoi   ! bulk density ice
      82             : 
      83             : real(r8) :: ac,bc,as,bs,ai,bi,ar,br  !fall speed parameters 
      84             : real(r8) :: ci,di    !ice mass-diameter relation parameters
      85             : real(r8) :: cs,ds    !snow mass-diameter relation parameters
      86             : real(r8) :: cr,dr    !drop mass-diameter relation parameters
      87             : real(r8) :: f1s,f2s  !ventilation param for snow
      88             : real(r8) :: Eii      !collection efficiency aggregation of ice
      89             : real(r8) :: Ecr      !collection efficiency cloud droplets/rain
      90             : real(r8) :: f1r,f2r  !ventilation param for rain
      91             : real(r8) :: DCS      !autoconversion size threshold
      92             : real(r8) :: qsmall   !min mixing ratio 
      93             : real(r8) :: bimm,aimm !immersion freezing
      94             : real(r8) :: rhosu     !typical 850mn air density
      95             : real(r8) :: mi0       ! new crystal mass
      96             : real(r8) :: rin       ! radius of contact nuclei
      97             : real(r8) :: pi       ! pi
      98             : 
      99             : ! Additional constants to help speed up code
     100             : 
     101             : real(r8) :: cons1
     102             : real(r8) :: cons4
     103             : real(r8) :: cons5
     104             : real(r8) :: cons6
     105             : real(r8) :: cons7
     106             : real(r8) :: cons8
     107             : real(r8) :: cons11
     108             : real(r8) :: cons13
     109             : real(r8) :: cons14
     110             : real(r8) :: cons16
     111             : real(r8) :: cons17
     112             : real(r8) :: cons22
     113             : real(r8) :: cons23
     114             : real(r8) :: cons24
     115             : real(r8) :: cons25
     116             : real(r8) :: cons27
     117             : real(r8) :: cons28
     118             : 
     119             : real(r8) :: lammini
     120             : real(r8) :: lammaxi
     121             : real(r8) :: lamminr
     122             : real(r8) :: lammaxr
     123             : real(r8) :: lammins
     124             : real(r8) :: lammaxs
     125             : 
     126             : ! parameters for snow/rain fraction for convective clouds
     127             : real(r8) :: tmax_fsnow ! max temperature for transition to convective snow
     128             : real(r8) :: tmin_fsnow ! min temperature for transition to convective snow
     129             : 
     130             : !needed for findsp
     131             : real(r8) :: tt0       ! Freezing temperature
     132             : 
     133             : real(r8) :: csmin,csmax,minrefl,mindbz
     134             : 
     135             : real(r8) :: rhmini     ! Minimum rh for ice cloud fraction > 0.
     136             : 
     137             : logical :: use_hetfrz_classnuc ! option to use heterogeneous freezing
     138             : 
     139             : character(len=16)  :: micro_mg_precip_frac_method  ! type of precipitation fraction method
     140             : real(r8)           :: micro_mg_berg_eff_factor     ! berg efficiency factor
     141             : 
     142             : ! Switches for specification rather than prediction of droplet and crystal number
     143             : ! note: number will be adjusted as needed to keep mean size within bounds,
     144             : ! even when specified droplet or ice number is used
     145             : !
     146             : ! If constant cloud ice number is set (nicons = .true.),
     147             : ! then all microphysical processes except mass transfer due to ice nucleation
     148             : ! (mnuccd) are based on the fixed cloud ice number. Calculation of
     149             : ! mnuccd follows from the prognosed ice crystal number ni.
     150             : logical :: nccons ! nccons=.true. to specify constant cloud droplet number
     151             : logical :: nicons ! nicons=.true. to specify constant cloud ice number
     152             : 
     153             : ! parameters for specified ice and droplet number concentration
     154             : ! note: these are local in-cloud values, not grid-mean
     155             : real(r8) :: ncnst ! droplet num concentration when nccons=.true. (m-3)
     156             : real(r8) :: ninst ! ice num concentration when nicons=.true. (m-3)
     157             : 
     158             : !===============================================================================
     159             : contains
     160             : !===============================================================================
     161             : 
     162           0 : subroutine micro_mg_init( &
     163             :      kind, gravit, rair, rh2o, cpair,  &
     164             :      rhoh2o, tmelt_in, latvap, latice, &
     165             :      rhmini_in, micro_mg_dcs, use_hetfrz_classnuc_in, &
     166           0 :      micro_mg_precip_frac_method_in, micro_mg_berg_eff_factor_in, &
     167           0 :      nccons_in, nicons_in, ncnst_in, ninst_in, errstring)
     168             : 
     169             : !----------------------------------------------------------------------- 
     170             : ! 
     171             : ! Purpose: 
     172             : ! initialize constants for the morrison microphysics
     173             : ! 
     174             : ! Author: Andrew Gettelman Dec 2005
     175             : ! 
     176             : !-----------------------------------------------------------------------
     177             : 
     178             : integer,          intent(in)  :: kind            ! Kind used for reals
     179             : real(r8),         intent(in)  :: gravit
     180             : real(r8),         intent(in)  :: rair
     181             : real(r8),         intent(in)  :: rh2o
     182             : real(r8),         intent(in)  :: cpair
     183             : real(r8),         intent(in)  :: rhoh2o
     184             : real(r8),         intent(in)  :: tmelt_in        ! Freezing point of water (K)
     185             : real(r8),         intent(in)  :: latvap
     186             : real(r8),         intent(in)  :: latice
     187             : real(r8),         intent(in)  :: rhmini_in       ! Minimum rh for ice cloud fraction > 0.
     188             : real(r8),         intent(in)  :: micro_mg_dcs
     189             : logical,          intent(in)  :: use_hetfrz_classnuc_in
     190             : character(len=16),intent(in)  :: micro_mg_precip_frac_method_in  ! type of precipitation fraction method
     191             : real(r8),         intent(in)  :: micro_mg_berg_eff_factor_in     ! berg efficiency factor
     192             : logical,          intent(in)  :: nccons_in
     193             : logical,          intent(in)  :: nicons_in
     194             : real(r8),         intent(in)  :: ncnst_in
     195             : real(r8),         intent(in)  :: ninst_in
     196             : 
     197             : character(128),   intent(out) :: errstring       ! Output status (non-blank for error return)
     198             : 
     199             : integer k
     200             : 
     201             : integer l,m, iaer
     202             : real(r8) surften       ! surface tension of water w/respect to air (N/m)
     203             : real(r8) arg
     204             : !-----------------------------------------------------------------------
     205             : 
     206           0 : errstring = ' '
     207             : 
     208           0 : if( kind .ne. r8 ) then
     209           0 :    errstring = 'micro_mg_init: KIND of reals does not match'
     210           0 :    return
     211             : end if
     212             : 
     213             : !declarations for morrison codes (transforms variable names)
     214             : 
     215           0 : g= gravit                  !gravity
     216           0 : r= rair                    !Dry air Gas constant: note units(phys_constants are in J/K/kmol)
     217           0 : rv= rh2o                   !water vapor gas contstant
     218           0 : cpp = cpair                !specific heat of dry air
     219           0 : rhow = rhoh2o              !density of liquid water
     220           0 : tmelt = tmelt_in
     221           0 : rhmini = rhmini_in
     222           0 : micro_mg_precip_frac_method = micro_mg_precip_frac_method_in
     223           0 : micro_mg_berg_eff_factor    = micro_mg_berg_eff_factor_in
     224             : 
     225           0 : nccons = nccons_in
     226           0 : nicons = nicons_in
     227           0 : ncnst  = ncnst_in
     228           0 : ninst  = ninst_in
     229             : 
     230             : ! latent heats
     231             : 
     232           0 : xxlv = latvap         ! latent heat vaporization
     233           0 : xlf = latice          ! latent heat freezing
     234           0 : xxls = xxlv + xlf     ! latent heat of sublimation
     235             : 
     236             : ! flags
     237           0 : use_hetfrz_classnuc = use_hetfrz_classnuc_in
     238             : 
     239             : ! parameters for snow/rain fraction for convective clouds
     240             : 
     241           0 : tmax_fsnow = tmelt
     242           0 : tmin_fsnow = tmelt-5._r8
     243             : 
     244             : ! parameters below from Reisner et al. (1998)
     245             : ! density parameters (kg/m3)
     246             : 
     247           0 : rhosn = 250._r8    ! bulk density snow  (++ ceh)
     248           0 : rhoi = 500._r8     ! bulk density ice
     249           0 : rhow = 1000._r8    ! bulk density liquid
     250             : 
     251             : 
     252             : ! fall speed parameters, V = aD^b
     253             : ! V is in m/s
     254             : 
     255             : ! droplets
     256           0 : ac = 3.e7_r8
     257           0 : bc = 2._r8
     258             : 
     259             : ! snow
     260           0 : as = 11.72_r8
     261           0 : bs = 0.41_r8
     262             : 
     263             : ! cloud ice
     264           0 : ai = 700._r8
     265           0 : bi = 1._r8
     266             : 
     267             : ! rain
     268           0 : ar = 841.99667_r8
     269           0 : br = 0.8_r8
     270             : 
     271             : ! particle mass-diameter relationship
     272             : ! currently we assume spherical particles for cloud ice/snow
     273             : ! m = cD^d
     274             : 
     275           0 : pi= 3.1415927_r8
     276             : 
     277             : ! cloud ice mass-diameter relationship
     278             : 
     279           0 : ci = rhoi*pi/6._r8
     280           0 : di = 3._r8
     281             : 
     282             : ! snow mass-diameter relationship
     283             : 
     284           0 : cs = rhosn*pi/6._r8
     285           0 : ds = 3._r8
     286             : 
     287             : ! drop mass-diameter relationship
     288             : 
     289           0 : cr = rhow*pi/6._r8
     290           0 : dr = 3._r8
     291             : 
     292             : ! ventilation parameters for snow
     293             : ! hall and prupacher
     294             : 
     295           0 : f1s = 0.86_r8
     296           0 : f2s = 0.28_r8
     297             : 
     298             : ! collection efficiency, aggregation of cloud ice and snow
     299             : 
     300           0 : Eii = 0.1_r8
     301             : 
     302             : ! collection efficiency, accretion of cloud water by rain
     303             : 
     304           0 : Ecr = 1.0_r8
     305             : 
     306             : ! ventilation constants for rain
     307             : 
     308           0 : f1r = 0.78_r8
     309           0 : f2r = 0.32_r8
     310             : 
     311             : ! autoconversion size threshold for cloud ice to snow (m)
     312             : 
     313           0 : Dcs = micro_mg_dcs
     314             : 
     315             : ! smallest mixing ratio considered in microphysics
     316             : 
     317           0 : qsmall = 1.e-18_r8  
     318             : 
     319             : ! immersion freezing parameters, bigg 1953
     320             : 
     321           0 : bimm = 100._r8
     322           0 : aimm = 0.66_r8
     323             : 
     324             : ! typical air density at 850 mb
     325             : 
     326           0 : rhosu = 85000._r8/(rair * tmelt)
     327             : 
     328             : ! mass of new crystal due to aerosol freezing and growth (kg)
     329             : 
     330           0 : mi0 = 4._r8/3._r8*pi*rhoi*(10.e-6_r8)*(10.e-6_r8)*(10.e-6_r8)
     331             : 
     332             : ! radius of contact nuclei aerosol (m)
     333             : 
     334           0 : rin = 0.1e-6_r8
     335             : 
     336             : ! freezing temperature
     337           0 : tt0=273.15_r8
     338             : 
     339           0 : pi=4._r8*atan(1.0_r8)
     340             : 
     341             : !Range of cloudsat reflectivities (dBz) for analytic simulator
     342           0 : csmin= -30._r8
     343           0 : csmax= 26._r8
     344           0 : mindbz = -99._r8
     345             : !      minrefl = 10._r8**(mindbz/10._r8)
     346           0 : minrefl = 1.26e-10_r8
     347             : 
     348             : ! Define constants to help speed up code (limit calls to gamma function)
     349             : 
     350           0 : cons1=gamma(1._r8+di)
     351           0 : cons4=gamma(1._r8+br)
     352           0 : cons5=gamma(4._r8+br)
     353           0 : cons6=gamma(1._r8+ds)
     354           0 : cons7=gamma(1._r8+bs)     
     355           0 : cons8=gamma(4._r8+bs)     
     356           0 : cons11=gamma(3._r8+bs)
     357           0 : cons13=gamma(5._r8/2._r8+br/2._r8)
     358           0 : cons14=gamma(5._r8/2._r8+bs/2._r8)
     359           0 : cons16=gamma(1._r8+bi)
     360           0 : cons17=gamma(4._r8+bi)
     361           0 : cons22=(4._r8/3._r8*pi*rhow*(25.e-6_r8)**3)
     362           0 : cons23=dcs**3
     363           0 : cons24=dcs**2
     364           0 : cons25=dcs**bs
     365           0 : cons27=xxlv**2
     366           0 : cons28=xxls**2
     367             : 
     368           0 : lammaxi = 1._r8/10.e-6_r8
     369           0 : lammini = 1._r8/(2._r8*dcs)
     370           0 : lammaxr = 1._r8/20.e-6_r8
     371           0 : lamminr = 1._r8/500.e-6_r8
     372           0 : lammaxs = 1._r8/10.e-6_r8
     373           0 : lammins = 1._r8/2000.e-6_r8
     374             : 
     375             : end subroutine micro_mg_init
     376             : 
     377             : !===============================================================================
     378             : !microphysics routine for each timestep goes here...
     379             : 
     380           0 : subroutine micro_mg_tend ( &
     381             :      microp_uniform, pcols, pver, ncol, top_lev, deltatin,&
     382           0 :      tn, qn, qc, qi, nc,                              &
     383           0 :      ni, p, pdel, cldn, liqcldf,                      &
     384           0 :      relvar, accre_enhan,                             &
     385           0 :      icecldf, rate1ord_cw2pr_st, naai, npccnin,       &
     386           0 :      rndst, nacon, tlat, qvlat, qctend,               &
     387           0 :      qitend, nctend, nitend, effc, effc_fn,           &
     388           0 :      effi, prect, preci, nevapr, evapsnow, am_evp_st, &
     389           0 :      prain, prodsnow, cmeout, deffi, pgamrad,         &
     390           0 :      lamcrad, qsout, dsout, rflx, sflx,               &
     391           0 :      qrout, reff_rain, reff_snow, qcsevap, qisevap,   &
     392           0 :      qvres, cmeiout, vtrmc, vtrmi, qcsedten,          &
     393           0 :      qisedten, prao, prco, mnuccco, mnuccto,          &
     394           0 :      msacwio, psacwso, bergso, bergo, melto,          &
     395           0 :      homoo, qcreso, prcio, praio, qireso,             &
     396           0 :      mnuccro, pracso, meltsdt, frzrdt, mnuccdo,       &
     397           0 :      nrout, nsout, refl, arefl, areflz,               &
     398           0 :      frefl, csrfl, acsrfl, fcsrfl, rercld,            &
     399           0 :      ncai, ncal, qrout2, qsout2, nrout2,              &
     400           0 :      nsout2, drout2, dsout2, freqs, freqr,            &
     401           0 :      nfice, prer_evap, do_cldice, errstring,          &
     402           0 :      tnd_qsnow, tnd_nsnow, re_ice,                    &
     403           0 :      frzimm, frzcnt, frzdep)
     404             : 
     405             : ! input arguments
     406             : logical,  intent(in) :: microp_uniform  ! True = configure uniform for sub-columns  False = use w/o sub-columns (standard)
     407             : integer,  intent(in) :: pcols                ! size of column (first) index
     408             : integer,  intent(in) :: pver                 ! number of layers in columns
     409             : integer,  intent(in) :: ncol                 ! number of columns
     410             : integer,  intent(in) :: top_lev              ! top level microphys is applied
     411             : real(r8), intent(in) :: deltatin             ! time step (s)
     412             : real(r8), intent(in) :: tn(pcols,pver)       ! input temperature (K)
     413             : real(r8), intent(in) :: qn(pcols,pver)       ! input h20 vapor mixing ratio (kg/kg)
     414             : real(r8), intent(in) :: relvar(pcols,pver)   ! relative variance of cloud water (-)
     415             : real(r8), intent(in) :: accre_enhan(pcols,pver) ! optional accretion enhancement factor (-)
     416             : 
     417             : ! note: all input cloud variables are grid-averaged
     418             : real(r8), intent(inout) :: qc(pcols,pver)    ! cloud water mixing ratio (kg/kg)
     419             : real(r8), intent(inout) :: qi(pcols,pver)    ! cloud ice mixing ratio (kg/kg)
     420             : real(r8), intent(inout) :: nc(pcols,pver)    ! cloud water number conc (1/kg)
     421             : real(r8), intent(inout) :: ni(pcols,pver)    ! cloud ice number conc (1/kg)
     422             : real(r8), intent(in) :: p(pcols,pver)        ! air pressure (pa)
     423             : real(r8), intent(in) :: pdel(pcols,pver)     ! pressure difference across level (pa)
     424             : real(r8), intent(in) :: cldn(pcols,pver)     ! cloud fraction
     425             : real(r8), intent(in) :: icecldf(pcols,pver)  ! ice cloud fraction   
     426             : real(r8), intent(in) :: liqcldf(pcols,pver)  ! liquid cloud fraction
     427             :           
     428             : real(r8), intent(out) :: rate1ord_cw2pr_st(pcols,pver) ! 1st order rate for direct cw to precip conversion 
     429             : ! used for scavenging
     430             : ! Inputs for aerosol activation
     431             : real(r8), intent(in) :: naai(pcols,pver)      ! ice nulceation number (from microp_aero_ts) 
     432             : real(r8), intent(in) :: npccnin(pcols,pver)   ! ccn activated number tendency (from microp_aero_ts)
     433             : real(r8), intent(in) :: rndst(pcols,pver,4)   ! radius of 4 dust bins for contact freezing (from microp_aero_ts)
     434             : real(r8), intent(in) :: nacon(pcols,pver,4)   ! number in 4 dust bins for contact freezing  (from microp_aero_ts)
     435             : 
     436             : ! Used with CARMA cirrus microphysics
     437             : ! (or similar external microphysics model)
     438             : logical,  intent(in) :: do_cldice             ! Prognosing cldice
     439             : 
     440             : ! output arguments
     441             : 
     442             : real(r8), intent(out) :: tlat(pcols,pver)    ! latent heating rate       (W/kg)
     443             : real(r8), intent(out) :: qvlat(pcols,pver)   ! microphysical tendency qv (1/s)
     444             : real(r8), intent(out) :: qctend(pcols,pver)  ! microphysical tendency qc (1/s) 
     445             : real(r8), intent(out) :: qitend(pcols,pver)  ! microphysical tendency qi (1/s)
     446             : real(r8), intent(out) :: nctend(pcols,pver)  ! microphysical tendency nc (1/(kg*s))
     447             : real(r8), intent(out) :: nitend(pcols,pver)  ! microphysical tendency ni (1/(kg*s))
     448             : real(r8), intent(out) :: effc(pcols,pver)    ! droplet effective radius (micron)
     449             : real(r8), intent(out) :: effc_fn(pcols,pver) ! droplet effective radius, assuming nc = 1.e8 kg-1
     450             : real(r8), intent(out) :: effi(pcols,pver)    ! cloud ice effective radius (micron)
     451             : real(r8), intent(out) :: prect(pcols)        ! surface precip rate (m/s)
     452             : real(r8), intent(out) :: preci(pcols)        ! cloud ice/snow precip rate (m/s)
     453             : real(r8), intent(out) :: nevapr(pcols,pver)  ! evaporation rate of rain + snow
     454             : real(r8), intent(out) :: evapsnow(pcols,pver)! sublimation rate of snow
     455             : real(r8), intent(out) :: am_evp_st(pcols,pver)! stratiform evaporation area
     456             : real(r8), intent(out) :: prain(pcols,pver)   ! production of rain + snow
     457             : real(r8), intent(out) :: prodsnow(pcols,pver)! production of snow
     458             : real(r8), intent(out) :: cmeout(pcols,pver)  ! evap/sub of cloud
     459             : real(r8), intent(out) :: deffi(pcols,pver)   ! ice effective diameter for optics (radiation)
     460             : real(r8), intent(out) :: pgamrad(pcols,pver) ! ice gamma parameter for optics (radiation)
     461             : real(r8), intent(out) :: lamcrad(pcols,pver) ! slope of droplet distribution for optics (radiation)
     462             : real(r8), intent(out) :: qsout(pcols,pver)   ! snow mixing ratio (kg/kg)
     463             : real(r8), intent(out) :: dsout(pcols,pver)   ! snow diameter (m)
     464             : real(r8), intent(out) :: rflx(pcols,pver+1)  ! grid-box average rain flux (kg m^-2 s^-1)
     465             : real(r8), intent(out) :: sflx(pcols,pver+1)  ! grid-box average snow flux (kg m^-2 s^-1)
     466             : real(r8), intent(out) :: qrout(pcols,pver)     ! grid-box average rain mixing ratio (kg/kg)
     467             : real(r8), intent(inout) :: reff_rain(pcols,pver) ! rain effective radius (micron)
     468             : real(r8), intent(inout) :: reff_snow(pcols,pver) ! snow effective radius (micron)
     469             : real(r8), intent(out) :: qcsevap(pcols,pver) ! cloud water evaporation due to sedimentation
     470             : real(r8), intent(out) :: qisevap(pcols,pver) ! cloud ice sublimation due to sublimation
     471             : real(r8), intent(out) :: qvres(pcols,pver) ! residual condensation term to ensure RH < 100%
     472             : real(r8), intent(out) :: cmeiout(pcols,pver) ! grid-mean cloud ice sub/dep
     473             : real(r8), intent(out) :: vtrmc(pcols,pver) ! mass-weighted cloud water fallspeed
     474             : real(r8), intent(out) :: vtrmi(pcols,pver) ! mass-weighted cloud ice fallspeed
     475             : real(r8), intent(out) :: qcsedten(pcols,pver) ! qc sedimentation tendency
     476             : real(r8), intent(out) :: qisedten(pcols,pver) ! qi sedimentation tendency
     477             : ! microphysical process rates for output (mixing ratio tendencies)
     478             : real(r8), intent(out) :: prao(pcols,pver) ! accretion of cloud by rain 
     479             : real(r8), intent(out) :: prco(pcols,pver) ! autoconversion of cloud to rain
     480             : real(r8), intent(out) :: mnuccco(pcols,pver) ! mixing rat tend due to immersion freezing
     481             : real(r8), intent(out) :: mnuccto(pcols,pver) ! mixing ratio tend due to contact freezing
     482             : real(r8), intent(out) :: msacwio(pcols,pver) ! mixing ratio tend due to H-M splintering
     483             : real(r8), intent(out) :: psacwso(pcols,pver) ! collection of cloud water by snow
     484             : real(r8), intent(out) :: bergso(pcols,pver) ! bergeron process on snow
     485             : real(r8), intent(out) :: bergo(pcols,pver) ! bergeron process on cloud ice
     486             : real(r8), intent(out) :: melto(pcols,pver) ! melting of cloud ice
     487             : real(r8), intent(out) :: homoo(pcols,pver) ! homogeneos freezign cloud water
     488             : real(r8), intent(out) :: qcreso(pcols,pver) ! residual cloud condensation due to removal of excess supersat
     489             : real(r8), intent(out) :: prcio(pcols,pver) ! autoconversion of cloud ice to snow
     490             : real(r8), intent(out) :: praio(pcols,pver) ! accretion of cloud ice by snow
     491             : real(r8), intent(out) :: qireso(pcols,pver) ! residual ice deposition due to removal of excess supersat
     492             : real(r8), intent(out) :: mnuccro(pcols,pver) ! mixing ratio tendency due to heterogeneous freezing of rain to snow (1/s)
     493             : real(r8), intent(out) :: pracso (pcols,pver) ! mixing ratio tendency due to accretion of rain by snow (1/s)
     494             : real(r8), intent(out) :: meltsdt(pcols,pver) ! latent heating rate due to melting of snow  (W/kg)
     495             : real(r8), intent(out) :: frzrdt (pcols,pver) ! latent heating rate due to homogeneous freezing of rain (W/kg)
     496             : real(r8), intent(out) :: mnuccdo(pcols,pver) ! mass tendency from ice nucleation
     497             : real(r8), intent(out) :: nrout(pcols,pver) ! rain number concentration (1/m3)
     498             : real(r8), intent(out) :: nsout(pcols,pver) ! snow number concentration (1/m3)
     499             : real(r8), intent(out) :: refl(pcols,pver)    ! analytic radar reflectivity        
     500             : real(r8), intent(out) :: arefl(pcols,pver)  !average reflectivity will zero points outside valid range
     501             : real(r8), intent(out) :: areflz(pcols,pver)  !average reflectivity in z.
     502             : real(r8), intent(out) :: frefl(pcols,pver)
     503             : real(r8), intent(out) :: csrfl(pcols,pver)   !cloudsat reflectivity 
     504             : real(r8), intent(out) :: acsrfl(pcols,pver)  !cloudsat average
     505             : real(r8), intent(out) :: fcsrfl(pcols,pver)
     506             : real(r8), intent(out) :: rercld(pcols,pver) ! effective radius calculation for rain + cloud
     507             : real(r8), intent(out) :: ncai(pcols,pver) ! output number conc of ice nuclei available (1/m3)
     508             : real(r8), intent(out) :: ncal(pcols,pver) ! output number conc of CCN (1/m3)
     509             : real(r8), intent(out) :: qrout2(pcols,pver)
     510             : real(r8), intent(out) :: qsout2(pcols,pver)
     511             : real(r8), intent(out) :: nrout2(pcols,pver)
     512             : real(r8), intent(out) :: nsout2(pcols,pver)
     513             : real(r8), intent(out) :: drout2(pcols,pver) ! mean rain particle diameter (m)
     514             : real(r8), intent(out) :: dsout2(pcols,pver) ! mean snow particle diameter (m)
     515             : real(r8), intent(out) :: freqs(pcols,pver)
     516             : real(r8), intent(out) :: freqr(pcols,pver)
     517             : real(r8), intent(out) :: nfice(pcols,pver)
     518             : real(r8), intent(out) :: prer_evap(pcols,pver)
     519             : 
     520           0 : real(r8) :: nevapr2(pcols,pver)
     521             : 
     522             : character(128),   intent(out) :: errstring       ! Output status (non-blank for error return)
     523             : 
     524             : ! Tendencies calculated by external schemes that can replace MG's native
     525             : ! process tendencies.
     526             : 
     527             : ! Used with CARMA cirrus microphysics
     528             : ! (or similar external microphysics model)
     529             : real(r8), intent(in) :: tnd_qsnow(:,:) ! snow mass tendency (kg/kg/s)
     530             : real(r8), intent(in) :: tnd_nsnow(:,:) ! snow number tendency (#/kg/s)
     531             : real(r8), intent(in) :: re_ice(:,:)    ! ice effective radius (m)
     532             : 
     533             : ! From external ice nucleation.
     534             : real(r8), intent(in) :: frzimm(:,:) ! Number tendency due to immersion freezing (1/cm3)
     535             : real(r8), intent(in) :: frzcnt(:,:) ! Number tendency due to contact freezing (1/cm3)
     536             : real(r8), intent(in) :: frzdep(:,:) ! Number tendency due to deposition nucleation (1/cm3)
     537             : 
     538             : ! local workspace
     539             : ! all units mks unless otherwise stated
     540             : 
     541             : ! Additional constants to help speed up code
     542             : real(r8) :: cons2
     543             : real(r8) :: cons3
     544             : real(r8) :: cons9
     545             : real(r8) :: cons10
     546             : real(r8) :: cons12
     547             : real(r8) :: cons15
     548             : real(r8) :: cons18
     549             : real(r8) :: cons19
     550             : real(r8) :: cons20
     551             : 
     552             : ! temporary variables for sub-stepping 
     553           0 : real(r8) :: t1(pcols,pver)
     554           0 : real(r8) :: q1(pcols,pver)
     555           0 : real(r8) :: qc1(pcols,pver)
     556           0 : real(r8) :: qi1(pcols,pver)
     557           0 : real(r8) :: nc1(pcols,pver)
     558           0 : real(r8) :: ni1(pcols,pver)
     559           0 : real(r8) :: tlat1(pcols,pver)
     560           0 : real(r8) :: qvlat1(pcols,pver)
     561           0 : real(r8) :: qctend1(pcols,pver)
     562           0 : real(r8) :: qitend1(pcols,pver)
     563           0 : real(r8) :: nctend1(pcols,pver)
     564           0 : real(r8) :: nitend1(pcols,pver)
     565           0 : real(r8) :: prect1(pcols)
     566           0 : real(r8) :: preci1(pcols)
     567             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     568             : 
     569             : real(r8) :: deltat        ! sub-time step (s)
     570             : real(r8) :: omsm    ! number near unity for round-off issues
     571             : real(r8) :: dto2    ! dt/2 (s)
     572             : real(r8) :: mincld  ! minimum allowed cloud fraction
     573           0 : real(r8) :: q(pcols,pver) ! water vapor mixing ratio (kg/kg)
     574           0 : real(r8) :: t(pcols,pver) ! temperature (K)
     575           0 : real(r8) :: rho(pcols,pver) ! air density (kg m-3)
     576           0 : real(r8) :: dv(pcols,pver)  ! diffusivity of water vapor in air
     577           0 : real(r8) :: mu(pcols,pver)  ! viscocity of air
     578           0 : real(r8) :: sc(pcols,pver)  ! schmidt number
     579           0 : real(r8) :: kap(pcols,pver) ! thermal conductivity of air
     580           0 : real(r8) :: rhof(pcols,pver) ! air density correction factor for fallspeed
     581           0 : real(r8) :: cldmax(pcols,pver) ! precip fraction assuming maximum overlap
     582           0 : real(r8) :: cldm(pcols,pver)   ! cloud fraction
     583           0 : real(r8) :: icldm(pcols,pver)   ! ice cloud fraction
     584           0 : real(r8) :: lcldm(pcols,pver)   ! liq cloud fraction
     585             : real(r8) :: icwc(pcols)    ! in cloud water content (liquid+ice)
     586             : real(r8) :: calpha(pcols)  ! parameter for cond/evap (Zhang et al. 2003)
     587             : real(r8) :: cbeta(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     588             : real(r8) :: cbetah(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     589             : real(r8) :: cgamma(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     590             : real(r8) :: cgamah(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     591             : real(r8) :: rcgama(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     592             : real(r8) :: cmec1(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     593             : real(r8) :: cmec2(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     594             : real(r8) :: cmec3(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     595             : real(r8) :: cmec4(pcols) ! parameter for cond/evap (Zhang et al. 2003)
     596             : real(r8) :: qtmp ! dummy qv 
     597             : real(r8) :: dum  ! temporary dummy variable
     598             : 
     599           0 : real(r8) :: cme(pcols,pver)  ! total (liquid+ice) cond/evap rate of cloud
     600             : 
     601           0 : real(r8) :: cmei(pcols,pver) ! dep/sublimation rate of cloud ice
     602           0 : real(r8) :: cwml(pcols,pver) ! cloud water mixing ratio
     603           0 : real(r8) :: cwmi(pcols,pver) ! cloud ice mixing ratio
     604           0 : real(r8) :: nnuccd(pver)   ! ice nucleation rate from deposition/cond.-freezing
     605           0 : real(r8) :: mnuccd(pver)   ! mass tendency from ice nucleation
     606             : real(r8) :: qcld              ! total cloud water
     607             : real(r8) :: lcldn(pcols,pver) ! fractional coverage of new liquid cloud
     608             : real(r8) :: lcldo(pcols,pver) ! fractional coverage of old liquid cloud
     609             : real(r8) :: nctend_mixnuc(pcols,pver)
     610             : real(r8) :: arg ! argument of erfc
     611             : 
     612             : ! for calculation of rate1ord_cw2pr_st
     613           0 : real(r8) :: qcsinksum_rate1ord(pver)   ! sum over iterations of cw to precip sink
     614           0 : real(r8) :: qcsum_rate1ord(pver)    ! sum over iterations of cloud water       
     615             : 
     616             : real(r8) :: alpha
     617             : 
     618             : real(r8) :: dum1,dum2   !general dummy variables
     619             : 
     620           0 : real(r8) :: npccn(pver)     ! droplet activation rate
     621           0 : real(r8) :: qcic(pcols,pver) ! in-cloud cloud liquid mixing ratio
     622           0 : real(r8) :: qiic(pcols,pver) ! in-cloud cloud ice mixing ratio
     623           0 : real(r8) :: qniic(pcols,pver) ! in-precip snow mixing ratio
     624           0 : real(r8) :: qric(pcols,pver) ! in-precip rain mixing ratio
     625           0 : real(r8) :: ncic(pcols,pver) ! in-cloud droplet number conc
     626           0 : real(r8) :: niic(pcols,pver) ! in-cloud cloud ice number conc
     627           0 : real(r8) :: nsic(pcols,pver) ! in-precip snow number conc
     628           0 : real(r8) :: nric(pcols,pver) ! in-precip rain number conc
     629           0 : real(r8) :: lami(pver) ! slope of cloud ice size distr
     630           0 : real(r8) :: n0i(pver) ! intercept of cloud ice size distr
     631           0 : real(r8) :: lamc(pver) ! slope of cloud liquid size distr
     632             : real(r8) :: n0c(pver) ! intercept of cloud liquid size distr
     633           0 : real(r8) :: lams(pver) ! slope of snow size distr
     634           0 : real(r8) :: n0s(pver) ! intercept of snow size distr
     635           0 : real(r8) :: lamr(pver) ! slope of rain size distr
     636           0 : real(r8) :: n0r(pver) ! intercept of rain size distr
     637           0 : real(r8) :: cdist1(pver) ! size distr parameter to calculate droplet freezing
     638             : ! combined size of precip & cloud drops
     639           0 : real(r8) :: arcld(pcols,pver) ! averaging control flag
     640             : real(r8) :: Actmp  !area cross section of drops
     641             : real(r8) :: Artmp  !area cross section of rain
     642             : 
     643           0 : real(r8) :: pgam(pver) ! spectral width parameter of droplet size distr
     644             : real(r8) :: lammax  ! maximum allowed slope of size distr
     645             : real(r8) :: lammin  ! minimum allowed slope of size distr
     646             : real(r8) :: nacnt   ! number conc of contact ice nuclei
     647           0 : real(r8) :: mnuccc(pver) ! mixing ratio tendency due to freezing of cloud water
     648           0 : real(r8) :: nnuccc(pver) ! number conc tendency due to freezing of cloud water
     649             : 
     650           0 : real(r8) :: mnucct(pver) ! mixing ratio tendency due to contact freezing of cloud water
     651           0 : real(r8) :: nnucct(pver) ! number conc tendency due to contact freezing of cloud water
     652           0 : real(r8) :: msacwi(pver) ! mixing ratio tendency due to HM ice multiplication
     653           0 : real(r8) :: nsacwi(pver) ! number conc tendency due to HM ice multiplication
     654             : 
     655           0 : real(r8) :: prc(pver) ! qc tendency due to autoconversion of cloud droplets
     656           0 : real(r8) :: nprc(pver) ! number conc tendency due to autoconversion of cloud droplets
     657           0 : real(r8) :: nprc1(pver) ! qr tendency due to autoconversion of cloud droplets
     658           0 : real(r8) :: nsagg(pver) ! ns tendency due to self-aggregation of snow
     659             : real(r8) :: dc0  ! mean size droplet size distr
     660             : real(r8) :: ds0  ! mean size snow size distr (area weighted)
     661             : real(r8) :: eci  ! collection efficiency for riming of snow by droplets
     662           0 : real(r8) :: psacws(pver) ! mixing rat tendency due to collection of droplets by snow
     663           0 : real(r8) :: npsacws(pver) ! number conc tendency due to collection of droplets by snow
     664             : real(r8) :: uni ! number-weighted cloud ice fallspeed
     665             : real(r8) :: umi ! mass-weighted cloud ice fallspeed
     666           0 : real(r8) :: uns(pver) ! number-weighted snow fallspeed
     667           0 : real(r8) :: ums(pver) ! mass-weighted snow fallspeed
     668           0 : real(r8) :: unr(pver) ! number-weighted rain fallspeed
     669           0 : real(r8) :: umr(pver) ! mass-weighted rain fallspeed
     670             : real(r8) :: unc ! number-weighted cloud droplet fallspeed
     671             : real(r8) :: umc ! mass-weighted cloud droplet fallspeed
     672           0 : real(r8) :: pracs(pver) ! mixing rat tendency due to collection of rain by snow
     673           0 : real(r8) :: npracs(pver) ! number conc tendency due to collection of rain by snow
     674           0 : real(r8) :: mnuccr(pver) ! mixing rat tendency due to freezing of rain
     675           0 : real(r8) :: nnuccr(pver) ! number conc tendency due to freezing of rain
     676           0 : real(r8) :: pra(pver) ! mixing rat tendnency due to accretion of droplets by rain
     677           0 : real(r8) :: npra(pver) ! nc tendnency due to accretion of droplets by rain
     678           0 : real(r8) :: nragg(pver) ! nr tendency due to self-collection of rain
     679           0 : real(r8) :: prci(pver) ! mixing rat tendency due to autoconversion of cloud ice to snow
     680           0 : real(r8) :: nprci(pver) ! number conc tendency due to autoconversion of cloud ice to snow
     681           0 : real(r8) :: prai(pver) ! mixing rat tendency due to accretion of cloud ice by snow
     682           0 : real(r8) :: nprai(pver) ! number conc tendency due to accretion of cloud ice by snow
     683             : real(r8) :: qvs ! liquid saturation vapor mixing ratio
     684             : real(r8) :: qvi ! ice saturation vapor mixing ratio
     685             : real(r8) :: dqsdt ! change of sat vapor mixing ratio with temperature
     686             : real(r8) :: dqsidt ! change of ice sat vapor mixing ratio with temperature
     687             : real(r8) :: ab ! correction factor for rain evap to account for latent heat
     688             : real(r8) :: qclr ! water vapor mixing ratio in clear air
     689             : real(r8) :: abi ! correction factor for snow sublimation to account for latent heat
     690             : real(r8) :: epss ! 1/ sat relaxation timescale for snow
     691             : real(r8) :: epsr ! 1/ sat relaxation timescale for rain
     692           0 : real(r8) :: pre(pver) ! rain mixing rat tendency due to evaporation
     693           0 : real(r8) :: prds(pver) ! snow mixing rat tendency due to sublimation
     694             : real(r8) :: qce ! dummy qc for conservation check
     695             : real(r8) :: qie ! dummy qi for conservation check
     696             : real(r8) :: nce ! dummy nc for conservation check
     697             : real(r8) :: nie ! dummy ni for conservation check
     698             : real(r8) :: ratio ! parameter for conservation check
     699           0 : real(r8) :: dumc(pcols,pver) ! dummy in-cloud qc
     700           0 : real(r8) :: dumnc(pcols,pver) ! dummy in-cloud nc
     701           0 : real(r8) :: dumi(pcols,pver) ! dummy in-cloud qi
     702           0 : real(r8) :: dumni(pcols,pver) ! dummy in-cloud ni
     703             : real(r8) :: dums(pcols,pver) ! dummy in-cloud snow mixing rat
     704             : real(r8) :: dumns(pcols,pver) ! dummy in-cloud snow number conc
     705             : real(r8) :: dumr(pcols,pver) ! dummy in-cloud rain mixing rat
     706             : real(r8) :: dumnr(pcols,pver) ! dummy in-cloud rain number conc
     707             : ! below are parameters for cloud water and cloud ice sedimentation calculations
     708             : real(r8) :: fr(pver)
     709             : real(r8) :: fnr(pver)
     710           0 : real(r8) :: fc(pver)
     711           0 : real(r8) :: fnc(pver)
     712           0 : real(r8) :: fi(pver)
     713           0 : real(r8) :: fni(pver)
     714             : real(r8) :: fs(pver)
     715             : real(r8) :: fns(pver)
     716             : real(r8) :: faloutr(pver)
     717             : real(r8) :: faloutnr(pver)
     718           0 : real(r8) :: faloutc(pver)
     719           0 : real(r8) :: faloutnc(pver)
     720           0 : real(r8) :: falouti(pver)
     721           0 : real(r8) :: faloutni(pver)
     722             : real(r8) :: falouts(pver)
     723             : real(r8) :: faloutns(pver)
     724             : real(r8) :: faltndr
     725             : real(r8) :: faltndnr
     726             : real(r8) :: faltndc
     727             : real(r8) :: faltndnc
     728             : real(r8) :: faltndi
     729             : real(r8) :: faltndni
     730             : real(r8) :: faltnds
     731             : real(r8) :: faltndns
     732             : real(r8) :: faltndqie
     733             : real(r8) :: faltndqce
     734             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     735           0 : real(r8) :: relhum(pcols,pver) ! relative humidity
     736             : real(r8) :: csigma(pcols) ! parameter for cond/evap of cloud water/ice
     737             : real(r8) :: rgvm ! max fallspeed for all species
     738           0 : real(r8) :: arn(pcols,pver) ! air density corrected rain fallspeed parameter
     739           0 : real(r8) :: asn(pcols,pver) ! air density corrected snow fallspeed parameter
     740           0 : real(r8) :: acn(pcols,pver) ! air density corrected cloud droplet fallspeed parameter
     741           0 : real(r8) :: ain(pcols,pver) ! air density corrected cloud ice fallspeed parameter
     742           0 : real(r8) :: nsubi(pver) ! evaporation of cloud ice number
     743           0 : real(r8) :: nsubc(pver) ! evaporation of droplet number
     744           0 : real(r8) :: nsubs(pver) ! evaporation of snow number
     745           0 : real(r8) :: nsubr(pver) ! evaporation of rain number
     746             : real(r8) :: mtime ! factor to account for droplet activation timescale
     747           0 : real(r8) :: dz(pcols,pver) ! height difference across model vertical level
     748             : 
     749             : 
     750             : !! add precip flux variables for sub-stepping
     751           0 : real(r8) :: rflx1(pcols,pver+1)
     752           0 : real(r8) :: sflx1(pcols,pver+1)
     753             : 
     754             : ! returns from function/subroutine calls
     755             : real(r8) :: tsp(pcols,pver)      ! saturation temp (K)
     756             : real(r8) :: qsp(pcols,pver)      ! saturation mixing ratio (kg/kg)
     757             : real(r8) :: qsphy(pcols,pver)      ! saturation mixing ratio (kg/kg): hybrid rh
     758           0 : real(r8) :: qs(pcols)            ! liquid-ice weighted sat mixing rat (kg/kg)
     759           0 : real(r8) :: es(pcols)            ! liquid-ice weighted sat vapor press (pa)
     760           0 : real(r8) :: esl(pcols,pver)      ! liquid sat vapor pressure (pa)
     761           0 : real(r8) :: esi(pcols,pver)      ! ice sat vapor pressure (pa)
     762             : 
     763             : ! sum of source/sink terms for diagnostic precip
     764             : 
     765           0 : real(r8) :: qnitend(pcols,pver) ! snow mixing ratio source/sink term
     766           0 : real(r8) :: nstend(pcols,pver)  ! snow number concentration source/sink term
     767           0 : real(r8) :: qrtend(pcols,pver) ! rain mixing ratio source/sink term
     768           0 : real(r8) :: nrtend(pcols,pver)  ! rain number concentration source/sink term
     769             : real(r8) :: qrtot ! vertically-integrated rain mixing rat source/sink term
     770             : real(r8) :: nrtot ! vertically-integrated rain number conc source/sink term
     771             : real(r8) :: qstot ! vertically-integrated snow mixing rat source/sink term
     772             : real(r8) :: nstot ! vertically-integrated snow number conc source/sink term
     773             : 
     774             : ! new terms for Bergeron process
     775             : 
     776             : real(r8) :: dumnnuc ! provisional ice nucleation rate (for calculating bergeron)
     777             : real(r8) :: ninew  ! provisional cloud ice number conc (for calculating bergeron)
     778             : real(r8) :: qinew ! provisional cloud ice mixing ratio (for calculating bergeron)
     779             : real(r8) :: qvl  ! liquid sat mixing ratio   
     780             : real(r8) :: epsi ! 1/ sat relaxation timecale for cloud ice
     781             : real(r8) :: prd ! provisional deposition rate of cloud ice at water sat 
     782           0 : real(r8) :: berg(pcols,pver) ! mixing rat tendency due to bergeron process for cloud ice
     783           0 : real(r8) :: bergs(pver) ! mixing rat tendency due to bergeron process for snow
     784             : 
     785             : !bergeron terms
     786             : real(r8) :: bergtsf   !bergeron timescale to remove all liquid
     787             : real(r8) :: rhin      !modified RH for vapor deposition
     788             : 
     789             : ! diagnostic rain/snow for output to history
     790             : ! values are in-precip (local) !!!!
     791             : 
     792           0 : real(r8) :: drout(pcols,pver)     ! rain diameter (m)
     793             : 
     794             : !averageed rain/snow for history
     795             : real(r8) :: dumfice
     796             : 
     797             : !ice nucleation, droplet activation
     798           0 : real(r8) :: dum2i(pcols,pver) ! number conc of ice nuclei available (1/kg)
     799           0 : real(r8) :: dum2l(pcols,pver) ! number conc of CCN (1/kg)
     800             : real(r8) :: ncmax
     801             : real(r8) :: nimax
     802             : 
     803             : real(r8) :: qcvar     ! 1/relative variance of sub-grid qc
     804             : 
     805             : ! loop array variables
     806             : integer i,k,nstep,n, l
     807             : integer ii,kk, m
     808             : 
     809             : ! loop variables for sub-step solution
     810           0 : integer iter,it,ltrue(pcols)
     811             : 
     812             : ! used in contact freezing via dust particles
     813             : real(r8)  tcnt, viscosity, mfp
     814             : real(r8)  slip1, slip2, slip3, slip4
     815             : !        real(r8)  dfaer1, dfaer2, dfaer3, dfaer4
     816             : !        real(r8)  nacon1,nacon2,nacon3,nacon4
     817             : real(r8)  ndfaer1, ndfaer2, ndfaer3, ndfaer4
     818             : real(r8)  nslip1, nslip2, nslip3, nslip4
     819             : 
     820             : ! used in ice effective radius
     821             : real(r8)  bbi, cci, ak, iciwc, rvi
     822             : 
     823             : ! used in Bergeron processe and water vapor deposition
     824             : real(r8)  Tk, deles, Aprpr, Bprpr, Cice, qi0, Crate, qidep
     825             : 
     826             : ! mean cloud fraction over the time step
     827           0 : real(r8)  cldmw(pcols,pver)
     828             : 
     829             : ! used in secondary ice production
     830             : real(r8) ni_secp
     831             : 
     832             : ! variabels to check for RH after rain evap
     833             : 
     834             : real(r8) :: esn
     835             : real(r8) :: qsn
     836             : real(r8) :: ttmp
     837             : 
     838             : 
     839             : 
     840           0 : real(r8) :: rainrt(pcols,pver)  ! rain rate for reflectivity calculation
     841           0 : real(r8) :: rainrt1(pcols,pver)
     842             : real(r8) :: tmp
     843             : 
     844             : real(r8) dmc,ssmc,dstrn  ! variables for modal scheme.
     845             : 
     846             : real(r8), parameter :: cdnl    = 0.e6_r8    ! cloud droplet number limiter
     847             : 
     848             : ! heterogeneous freezing
     849           0 : real(r8) :: mnudep(pver) ! mixing ratio tendency due to deposition of water vapor
     850           0 : real(r8) :: nnudep(pver) ! number conc tendency due to deposition of water vapor
     851             : real(r8) :: con1 ! work cnstant
     852             : real(r8) :: r3lx ! Mean volume radius (m)
     853             : real(r8) :: mi0l
     854             : real(r8) :: frztmp
     855             : 
     856             : logical  :: do_clubb_sgs
     857             : 
     858             : !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
     859             : 
     860             : ! Return error message
     861           0 : errstring = ' '
     862             : 
     863           0 : call phys_getopts(do_clubb_sgs_out = do_clubb_sgs)
     864             : 
     865             : ! initialize  output fields for number conc qand ice nucleation
     866           0 : ncai(1:ncol,1:pver)=0._r8 
     867           0 : ncal(1:ncol,1:pver)=0._r8  
     868             : 
     869             : !Initialize rain size
     870           0 : rercld(1:ncol,1:pver)=0._r8
     871           0 : arcld(1:ncol,1:pver)=0._r8
     872             : 
     873             : !initialize radiation output variables
     874           0 : pgamrad(1:ncol,1:pver)=0._r8 ! liquid gamma parameter for optics (radiation)
     875           0 : lamcrad(1:ncol,1:pver)=0._r8 ! slope of droplet distribution for optics (radiation)
     876           0 : deffi  (1:ncol,1:pver)=0._r8 ! slope of droplet distribution for optics (radiation)
     877             : !initialize radiation output variables
     878             : !initialize water vapor tendency term output
     879           0 : qcsevap(1:ncol,1:pver)=0._r8 
     880           0 : qisevap(1:ncol,1:pver)=0._r8 
     881           0 : qvres  (1:ncol,1:pver)=0._r8 
     882           0 : cmeiout (1:ncol,1:pver)=0._r8
     883           0 : vtrmc (1:ncol,1:pver)=0._r8
     884           0 : vtrmi (1:ncol,1:pver)=0._r8
     885           0 : qcsedten (1:ncol,1:pver)=0._r8
     886           0 : qisedten (1:ncol,1:pver)=0._r8    
     887             : 
     888           0 : prao(1:ncol,1:pver)=0._r8 
     889           0 : prco(1:ncol,1:pver)=0._r8 
     890           0 : mnuccco(1:ncol,1:pver)=0._r8 
     891           0 : mnuccto(1:ncol,1:pver)=0._r8 
     892           0 : msacwio(1:ncol,1:pver)=0._r8 
     893           0 : psacwso(1:ncol,1:pver)=0._r8 
     894           0 : bergso(1:ncol,1:pver)=0._r8 
     895           0 : bergo(1:ncol,1:pver)=0._r8 
     896           0 : melto(1:ncol,1:pver)=0._r8 
     897           0 : homoo(1:ncol,1:pver)=0._r8 
     898           0 : qcreso(1:ncol,1:pver)=0._r8 
     899           0 : prcio(1:ncol,1:pver)=0._r8 
     900           0 : praio(1:ncol,1:pver)=0._r8 
     901           0 : qireso(1:ncol,1:pver)=0._r8 
     902           0 : mnuccro(1:ncol,1:pver)=0._r8 
     903           0 : pracso (1:ncol,1:pver)=0._r8 
     904           0 : meltsdt(1:ncol,1:pver)=0._r8
     905           0 : frzrdt (1:ncol,1:pver)=0._r8
     906           0 : mnuccdo(1:ncol,1:pver)=0._r8
     907             : 
     908           0 : rflx(:,:)=0._r8
     909           0 : sflx(:,:)=0._r8
     910           0 : effc(:,:)=0._r8
     911           0 : effc_fn(:,:)=0._r8
     912           0 : effi(:,:)=0._r8
     913             : 
     914             : ! assign variable deltat for sub-stepping...
     915           0 : deltat=deltatin
     916             : 
     917             : ! parameters for scheme
     918             : 
     919           0 : omsm=0.99999_r8
     920           0 : dto2=0.5_r8*deltat
     921           0 : mincld=0.0001_r8
     922             : 
     923             : ! initialize multi-level fields
     924           0 : q(1:ncol,1:pver)=qn(1:ncol,1:pver)
     925           0 : t(1:ncol,1:pver)=tn(1:ncol,1:pver)
     926             : 
     927             : ! initialize time-varying parameters
     928             : 
     929           0 : do k=1,pver
     930           0 :    do i=1,ncol
     931           0 :       rho(i,k)=p(i,k)/(r*t(i,k))
     932           0 :       dv(i,k) = 8.794E-5_r8*t(i,k)**1.81_r8/p(i,k)
     933           0 :       mu(i,k) = 1.496E-6_r8*t(i,k)**1.5_r8/(t(i,k)+120._r8) 
     934           0 :       sc(i,k) = mu(i,k)/(rho(i,k)*dv(i,k))
     935           0 :       kap(i,k) = 1.414e3_r8*1.496e-6_r8*t(i,k)**1.5_r8/(t(i,k)+120._r8) 
     936             : 
     937             :       ! air density adjustment for fallspeed parameters
     938             :       ! includes air density correction factor to the
     939             :       ! power of 0.54 following Heymsfield and Bansemer 2007
     940             : 
     941           0 :       rhof(i,k)=(rhosu/rho(i,k))**0.54_r8
     942             : 
     943           0 :       arn(i,k)=ar*rhof(i,k)
     944           0 :       asn(i,k)=as*rhof(i,k)
     945           0 :       acn(i,k)=ac*rhof(i,k)
     946           0 :       ain(i,k)=ai*rhof(i,k)
     947             : 
     948             :       ! get dz from dp and hydrostatic approx
     949             :       ! keep dz positive (define as layer k-1 - layer k)
     950             : 
     951           0 :       dz(i,k)= pdel(i,k)/(rho(i,k)*g)
     952             : 
     953             :    end do
     954             : end do
     955             : 
     956             : ! initialization
     957           0 : qc(1:ncol,1:top_lev-1) = 0._r8
     958           0 : qi(1:ncol,1:top_lev-1) = 0._r8
     959           0 : nc(1:ncol,1:top_lev-1) = 0._r8
     960           0 : ni(1:ncol,1:top_lev-1) = 0._r8
     961           0 : t1(1:ncol,1:pver) = t(1:ncol,1:pver)
     962           0 : q1(1:ncol,1:pver) = q(1:ncol,1:pver)
     963           0 : qc1(1:ncol,1:pver) = qc(1:ncol,1:pver)
     964           0 : qi1(1:ncol,1:pver) = qi(1:ncol,1:pver)
     965           0 : nc1(1:ncol,1:pver) = nc(1:ncol,1:pver)
     966           0 : ni1(1:ncol,1:pver) = ni(1:ncol,1:pver)
     967             : 
     968             : ! initialize tendencies to zero
     969           0 : tlat1(1:ncol,1:pver)=0._r8
     970           0 : qvlat1(1:ncol,1:pver)=0._r8
     971           0 : qctend1(1:ncol,1:pver)=0._r8
     972           0 : qitend1(1:ncol,1:pver)=0._r8
     973           0 : nctend1(1:ncol,1:pver)=0._r8
     974           0 : nitend1(1:ncol,1:pver)=0._r8
     975             : 
     976             : ! initialize precip output
     977           0 : qrout(1:ncol,1:pver)=0._r8
     978           0 : qsout(1:ncol,1:pver)=0._r8
     979           0 : nrout(1:ncol,1:pver)=0._r8
     980           0 : nsout(1:ncol,1:pver)=0._r8
     981           0 : dsout(1:ncol,1:pver)=0._r8
     982             : 
     983           0 : drout(1:ncol,1:pver)=0._r8
     984             : 
     985           0 : reff_rain(1:ncol,1:pver)=0._r8
     986           0 : reff_snow(1:ncol,1:pver)=0._r8
     987             : 
     988             : ! initialize variables for trop_mozart
     989           0 : nevapr(1:ncol,1:pver) = 0._r8
     990           0 : nevapr2(1:ncol,1:pver) = 0._r8
     991           0 : evapsnow(1:ncol,1:pver) = 0._r8
     992           0 : prain(1:ncol,1:pver) = 0._r8
     993           0 : prodsnow(1:ncol,1:pver) = 0._r8
     994           0 : cmeout(1:ncol,1:pver) = 0._r8
     995             : 
     996           0 : am_evp_st(1:ncol,1:pver) = 0._r8
     997             : 
     998             : ! for refl calc
     999           0 : rainrt1(1:ncol,1:pver) = 0._r8
    1000             : 
    1001             : ! initialize precip fraction and output tendencies
    1002           0 : cldmax(1:ncol,1:pver)=mincld
    1003             : 
    1004             : !initialize aerosol number
    1005             : !        naer2(1:ncol,1:pver,:)=0._r8
    1006           0 : dum2l(1:ncol,1:pver)=0._r8
    1007           0 : dum2i(1:ncol,1:pver)=0._r8
    1008             : 
    1009             : ! initialize avg precip rate
    1010           0 : prect1(1:ncol)=0._r8
    1011           0 : preci1(1:ncol)=0._r8
    1012             : 
    1013             : !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1014             : !Get humidity and saturation vapor pressures
    1015             : 
    1016           0 : do k=top_lev,pver
    1017             : 
    1018           0 :    do i=1,ncol
    1019             : 
    1020             :       ! find wet bulk temperature and saturation value for provisional t and q without
    1021             :       ! condensation
    1022             :       
    1023           0 :       es(i) = svp_water(t(i,k))
    1024           0 :       qs(i) = svp_to_qsat(es(i), p(i,k))
    1025             : 
    1026             :       ! Prevents negative values.
    1027           0 :       if (qs(i) < 0.0_r8) then
    1028           0 :          qs(i) = 1.0_r8
    1029           0 :          es(i) = p(i,k)
    1030             :       end if
    1031             : 
    1032           0 :       esl(i,k)=svp_water(t(i,k))
    1033           0 :       esi(i,k)=svp_ice(t(i,k))
    1034             : 
    1035             :       ! hm fix, make sure when above freezing that esi=esl, not active yet
    1036           0 :       if (t(i,k).gt.tmelt)esi(i,k)=esl(i,k)
    1037             : 
    1038           0 :       relhum(i,k)=q(i,k)/qs(i)
    1039             : 
    1040             :       ! get cloud fraction, check for minimum
    1041             : 
    1042           0 :       cldm(i,k)=max(cldn(i,k),mincld)
    1043           0 :       cldmw(i,k)=max(cldn(i,k),mincld)
    1044             : 
    1045           0 :       icldm(i,k)=max(icecldf(i,k),mincld)
    1046           0 :       lcldm(i,k)=max(liqcldf(i,k),mincld)
    1047             : 
    1048             :       ! subcolumns, set cloud fraction variables to one
    1049             :       ! if cloud water or ice is present, if not present
    1050             :       ! set to mincld (mincld used instead of zero, to prevent
    1051             :       ! possible division by zero errors
    1052             : 
    1053           0 :       if (microp_uniform) then
    1054             : 
    1055           0 :          cldm(i,k)=mincld
    1056           0 :          cldmw(i,k)=mincld
    1057           0 :          icldm(i,k)=mincld
    1058           0 :          lcldm(i,k)=mincld
    1059             : 
    1060           0 :          if (qc(i,k).ge.qsmall) then
    1061           0 :             lcldm(i,k)=1._r8           
    1062           0 :             cldm(i,k)=1._r8
    1063           0 :             cldmw(i,k)=1._r8
    1064             :          end if
    1065             : 
    1066           0 :          if (qi(i,k).ge.qsmall) then             
    1067           0 :             cldm(i,k)=1._r8
    1068           0 :             icldm(i,k)=1._r8
    1069             :          end if
    1070             : 
    1071             :       end if               ! sub-columns
    1072             : 
    1073             :       ! calculate nfice based on liquid and ice mmr (no rain and snow mmr available yet)
    1074             : 
    1075           0 :       nfice(i,k)=0._r8
    1076           0 :       dumfice=qc(i,k)+qi(i,k)
    1077           0 :       if (dumfice.gt.qsmall .and. qi(i,k).gt.qsmall) then
    1078           0 :          nfice(i,k)=qi(i,k)/dumfice
    1079             :       endif
    1080             : 
    1081           0 :       if (do_cldice .and. (t(i,k).lt.tmelt - 5._r8)) then
    1082             : 
    1083             :          ! if aerosols interact with ice set number of activated ice nuclei
    1084           0 :          dum2=naai(i,k)
    1085             : 
    1086           0 :          dumnnuc=(dum2-ni(i,k)/icldm(i,k))/deltat*icldm(i,k)
    1087           0 :          dumnnuc=max(dumnnuc,0._r8)
    1088             :          ! get provisional ni and qi after nucleation in order to calculate
    1089             :          ! Bergeron process below
    1090           0 :          ninew=ni(i,k)+dumnnuc*deltat
    1091           0 :          qinew=qi(i,k)+dumnnuc*deltat*mi0
    1092             : 
    1093             :          !T>268
    1094             :       else
    1095           0 :          ninew=ni(i,k)
    1096           0 :          qinew=qi(i,k)
    1097             :       end if
    1098             : 
    1099             :       ! Initialize CME components
    1100             : 
    1101           0 :       cme(i,k) = 0._r8
    1102           0 :       cmei(i,k)=0._r8
    1103             : 
    1104             : 
    1105             :       !-------------------------------------------------------------------
    1106             :       !Bergeron process
    1107             : 
    1108             :       ! make sure to initialize bergeron process to zero
    1109           0 :       berg(i,k)=0._r8
    1110           0 :       prd = 0._r8
    1111             : 
    1112             :       !condensation loop.
    1113             : 
    1114             :       ! get in-cloud qi and ni after nucleation
    1115           0 :       if (icldm(i,k) .gt. 0._r8) then 
    1116           0 :          qiic(i,k)=qinew/icldm(i,k)
    1117           0 :          niic(i,k)=ninew/icldm(i,k)
    1118             :       else
    1119           0 :          qiic(i,k)=0._r8
    1120           0 :          niic(i,k)=0._r8
    1121             :       endif
    1122             : 
    1123           0 :       if (nicons) then
    1124           0 :         niic(i,k) = ninst/rho(i,k)
    1125             :       end if
    1126             : 
    1127             :       !if T < 0 C then bergeron.
    1128           0 :       if (do_cldice .and. (t(i,k).lt.273.15_r8)) then
    1129             : 
    1130             :          !if ice exists
    1131           0 :          if (qi(i,k).gt.qsmall) then
    1132             : 
    1133           0 :             bergtsf = 0._r8 ! bergeron time scale (fraction of timestep)
    1134             : 
    1135           0 :             qvi = svp_to_qsat(esi(i,k), p(i,k))
    1136           0 :             qvl = svp_to_qsat(esl(i,k), p(i,k))
    1137             : 
    1138           0 :             dqsidt =  xxls*qvi/(rv*t(i,k)**2)
    1139           0 :             abi = 1._r8+dqsidt*xxls/cpp
    1140             : 
    1141             :             ! get ice size distribution parameters
    1142             : 
    1143           0 :             if (qiic(i,k).ge.qsmall) then
    1144             :                lami(k) = (cons1*ci* &
    1145           0 :                     niic(i,k)/qiic(i,k))**(1._r8/di)
    1146           0 :                n0i(k) = niic(i,k)*lami(k)
    1147             : 
    1148             :                ! check for slope
    1149             :                ! adjust vars
    1150           0 :                if (lami(k).lt.lammini) then
    1151             : 
    1152           0 :                   lami(k) = lammini
    1153           0 :                   n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
    1154           0 :                else if (lami(k).gt.lammaxi) then
    1155           0 :                   lami(k) = lammaxi
    1156           0 :                   n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
    1157             :                end if
    1158             : 
    1159           0 :                epsi = 2._r8*pi*n0i(k)*rho(i,k)*Dv(i,k)/(lami(k)*lami(k))
    1160             : 
    1161             :                !if liquid exists  
    1162           0 :                if (qc(i,k).gt. qsmall) then 
    1163             : 
    1164             :                   !begin bergeron process
    1165             :                   !     do bergeron (vapor deposition with RHw=1)
    1166             :                   !     code to find berg (a rate) goes here
    1167             : 
    1168             :                   ! calculate Bergeron process
    1169             : 
    1170           0 :                   prd = epsi*(qvl-qvi)/abi
    1171             : 
    1172             :                else
    1173             :                   prd = 0._r8
    1174             :                end if
    1175             : 
    1176             :                ! multiply by cloud fraction
    1177             : 
    1178           0 :                prd = prd*min(icldm(i,k),lcldm(i,k))
    1179             : 
    1180             :                !     transfer of existing cloud liquid to ice
    1181             : 
    1182           0 :                berg(i,k)=max(0._r8,prd)
    1183             : 
    1184             :             end if  !end liquid exists bergeron
    1185             : 
    1186           0 :             if (berg(i,k).gt.0._r8) then
    1187           0 :                bergtsf=max(0._r8,(qc(i,k)/berg(i,k))/deltat) 
    1188             : 
    1189           0 :                if(bergtsf.lt.1._r8) berg(i,k) = max(0._r8,qc(i,k)/deltat)
    1190             : 
    1191             :             endif
    1192             : 
    1193             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1194             : 
    1195           0 :             if (bergtsf.lt.1._r8.or.icldm(i,k).gt.lcldm(i,k)) then
    1196             : 
    1197           0 :                if (qiic(i,k).ge.qsmall) then
    1198             : 
    1199             :                   ! first case is for case when liquid water is present, but is completely depleted 
    1200             :                   ! in time step, i.e., bergrsf > 0 but < 1
    1201             : 
    1202           0 :                   if (qc(i,k).ge.qsmall) then
    1203           0 :                      rhin  = (1.0_r8 + relhum(i,k)) / 2._r8
    1204           0 :                      if ((rhin*esl(i,k)/esi(i,k)) > 1._r8) then
    1205           0 :                         prd = epsi*(rhin*qvl-qvi)/abi
    1206             : 
    1207             :                         ! multiply by cloud fraction assuming liquid/ice maximum overlap
    1208           0 :                         prd = prd*min(icldm(i,k),lcldm(i,k))
    1209             : 
    1210             :                         ! add to cmei
    1211           0 :                         cmei(i,k) = cmei(i,k) + (prd * (1._r8- bergtsf))
    1212             : 
    1213             :                      end if ! rhin 
    1214             :                   end if ! qc > qsmall
    1215             : 
    1216             :                   ! second case is for pure ice cloud, either no liquid, or icldm > lcldm
    1217             : 
    1218           0 :                   if (qc(i,k).lt.qsmall.or.icldm(i,k).gt.lcldm(i,k)) then
    1219             : 
    1220             :                      ! note: for case of no liquid, need to set liquid cloud fraction to zero
    1221             :                      ! store liquid cloud fraction in 'dum'
    1222             : 
    1223           0 :                      if (qc(i,k).lt.qsmall) then 
    1224             :                         dum=0._r8 
    1225             :                      else
    1226           0 :                         dum=lcldm(i,k)
    1227             :                      end if
    1228             : 
    1229             :                      ! set RH to grid-mean value for pure ice cloud
    1230           0 :                      rhin = relhum(i,k)
    1231             : 
    1232           0 :                      if ((rhin*esl(i,k)/esi(i,k)) > 1._r8) then
    1233             : 
    1234           0 :                         prd = epsi*(rhin*qvl-qvi)/abi
    1235             : 
    1236             :                         ! multiply by relevant cloud fraction for pure ice cloud
    1237             :                         ! assuming maximum overlap of liquid/ice
    1238           0 :                         prd = prd*max((icldm(i,k)-dum),0._r8)
    1239           0 :                         cmei(i,k) = cmei(i,k) + prd
    1240             : 
    1241             :                      end if ! rhin
    1242             :                   end if ! qc or icldm > lcldm
    1243             :                end if ! qiic
    1244             :             end if ! bergtsf or icldm > lcldm
    1245             : 
    1246             :             !     if deposition, it should not reduce grid mean rhi below 1.0
    1247           0 :             if(cmei(i,k) > 0.0_r8 .and. (relhum(i,k)*esl(i,k)/esi(i,k)) > 1._r8 ) &
    1248           0 :                  cmei(i,k)=min(cmei(i,k),(q(i,k)-qs(i)*esi(i,k)/esl(i,k))/abi/deltat)
    1249             : 
    1250             :          end if            !end ice exists loop
    1251             :          !this ends temperature < 0. loop
    1252             : 
    1253             :          !-------------------------------------------------------------------
    1254             :       end if  ! 
    1255             :       !..............................................................
    1256             : 
    1257             :       ! evaporation should not exceed available water
    1258             : 
    1259           0 :       if ((-berg(i,k)).lt.-qc(i,k)/deltat) berg(i,k) = max(qc(i,k)/deltat,0._r8)
    1260             : 
    1261             :       !sublimation process...
    1262           0 :       if (do_cldice .and. ((relhum(i,k)*esl(i,k)/esi(i,k)).lt.1._r8 .and. qiic(i,k).ge.qsmall )) then
    1263             : 
    1264           0 :          qvi = svp_to_qsat(esi(i,k), p(i,k))
    1265           0 :          qvl = svp_to_qsat(esl(i,k), p(i,k))
    1266           0 :          dqsidt =  xxls*qvi/(rv*t(i,k)**2)
    1267           0 :          abi = 1._r8+dqsidt*xxls/cpp
    1268             : 
    1269             :          ! get ice size distribution parameters
    1270             : 
    1271             :          lami(k) = (cons1*ci* &
    1272           0 :               niic(i,k)/qiic(i,k))**(1._r8/di)
    1273           0 :          n0i(k) = niic(i,k)*lami(k)
    1274             : 
    1275             :          ! check for slope
    1276             :          ! adjust vars
    1277           0 :          if (lami(k).lt.lammini) then
    1278             : 
    1279           0 :             lami(k) = lammini
    1280           0 :             n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
    1281           0 :          else if (lami(k).gt.lammaxi) then
    1282           0 :             lami(k) = lammaxi
    1283           0 :             n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
    1284             :          end if
    1285             : 
    1286           0 :          epsi = 2._r8*pi*n0i(k)*rho(i,k)*Dv(i,k)/(lami(k)*lami(k))
    1287             : 
    1288             :          ! modify for ice fraction below
    1289           0 :          prd = epsi*(relhum(i,k)*qvl-qvi)/abi * icldm(i,k)
    1290           0 :          cmei(i,k)=min(prd,0._r8)
    1291             : 
    1292             :       endif
    1293             : 
    1294             :       ! sublimation should not exceed available ice
    1295           0 :       if (cmei(i,k).lt.-qi(i,k)/deltat) cmei(i,k)=-qi(i,k)/deltat
    1296             : 
    1297             :       ! sublimation should not increase grid mean rhi above 1.0 
    1298           0 :       if(cmei(i,k) < 0.0_r8 .and. (relhum(i,k)*esl(i,k)/esi(i,k)) < 1._r8 ) &
    1299           0 :            cmei(i,k)=min(0._r8,max(cmei(i,k),(q(i,k)-qs(i)*esi(i,k)/esl(i,k))/abi/deltat))
    1300             : 
    1301             :       ! limit cmei due for roundoff error
    1302             : 
    1303           0 :       cmei(i,k)=cmei(i,k)*omsm
    1304             : 
    1305             :       ! conditional for ice nucleation 
    1306           0 :       if (do_cldice .and. (t(i,k).lt.(tmelt - 5._r8))) then 
    1307             : 
    1308             :          ! using Liu et al. (2007) ice nucleation with hooks into simulated aerosol
    1309             :          ! ice nucleation rate (dum2) has already been calculated and read in (naai)
    1310             : 
    1311           0 :          dum2i(i,k)=naai(i,k)
    1312             :       else
    1313           0 :          dum2i(i,k)=0._r8
    1314             :       end if
    1315             : 
    1316             :    end do ! i loop
    1317             : end do ! k loop
    1318             : 
    1319             : 
    1320             : !! initialize sub-step precip flux variables
    1321           0 : do i=1,ncol
    1322             :    !! flux is zero at top interface, so these should stay as 0.
    1323           0 :    rflx1(i,1)=0._r8
    1324           0 :    sflx1(i,1)=0._r8
    1325           0 :    do k=top_lev,pver
    1326             : 
    1327             :       ! initialize normal and sub-step precip flux variables
    1328           0 :       rflx1(i,k+1)=0._r8
    1329           0 :       sflx1(i,k+1)=0._r8
    1330             :    end do ! i loop
    1331             : end do ! k loop
    1332             : !! initialize final precip flux variables.
    1333           0 : do i=1,ncol
    1334             :    !! flux is zero at top interface, so these should stay as 0.
    1335           0 :    rflx(i,1)=0._r8
    1336           0 :    sflx(i,1)=0._r8
    1337           0 :    do k=top_lev,pver
    1338             :       ! initialize normal and sub-step precip flux variables
    1339           0 :       rflx(i,k+1)=0._r8
    1340           0 :       sflx(i,k+1)=0._r8
    1341             :    end do ! i loop
    1342             : end do ! k loop
    1343             : 
    1344           0 : do i=1,ncol
    1345           0 :    ltrue(i)=0
    1346           0 :    do k=top_lev,pver
    1347             :       ! skip microphysical calculations if no cloud water
    1348             : 
    1349           0 :       if (qc(i,k).ge.qsmall.or.qi(i,k).ge.qsmall.or.cmei(i,k).ge.qsmall) ltrue(i)=1
    1350             :    end do
    1351             : end do
    1352             : 
    1353             : ! assign number of sub-steps to iter
    1354             : ! use 2 sub-steps, following tests described in MG2008
    1355             : iter = 2
    1356             : 
    1357             : ! get sub-step time step
    1358           0 : deltat=deltat/real(iter)
    1359             : 
    1360             : ! since activation/nucleation processes are fast, need to take into account
    1361             : ! factor mtime = mixing timescale in cloud / model time step
    1362             : ! mixing time can be interpreted as cloud depth divided by sub-grid vertical velocity
    1363             : ! for now mixing timescale is assumed to be 1 timestep for modal aerosols, 20 min bulk
    1364             : 
    1365             : !        note: mtime for bulk aerosols was set to: mtime=deltat/1200._r8
    1366             : 
    1367             : mtime=1._r8
    1368           0 : rate1ord_cw2pr_st(:,:)=0._r8 ! rce 2010/05/01
    1369             : 
    1370             : !!!! skip calculations if no cloud water
    1371           0 : do i=1,ncol
    1372           0 :    if (ltrue(i).eq.0) then
    1373           0 :       tlat(i,1:pver)=0._r8
    1374           0 :       qvlat(i,1:pver)=0._r8
    1375           0 :       qctend(i,1:pver)=0._r8
    1376           0 :       qitend(i,1:pver)=0._r8
    1377           0 :       qnitend(i,1:pver)=0._r8
    1378           0 :       qrtend(i,1:pver)=0._r8
    1379           0 :       nctend(i,1:pver)=0._r8
    1380           0 :       nitend(i,1:pver)=0._r8
    1381           0 :       nrtend(i,1:pver)=0._r8
    1382           0 :       nstend(i,1:pver)=0._r8
    1383           0 :       prect(i)=0._r8
    1384           0 :       preci(i)=0._r8
    1385           0 :       rflx(i,1:pver+1)=0._r8
    1386           0 :       sflx(i,1:pver+1)=0._r8
    1387           0 :       qniic(i,1:pver)=0._r8
    1388           0 :       qric(i,1:pver)=0._r8
    1389           0 :       nsic(i,1:pver)=0._r8
    1390           0 :       nric(i,1:pver)=0._r8
    1391           0 :       rainrt(i,1:pver)=0._r8
    1392             :       goto 300
    1393             :    end if
    1394             : 
    1395           0 :    qcsinksum_rate1ord(1:pver)=0._r8 
    1396           0 :    qcsum_rate1ord(1:pver)=0._r8 
    1397             : 
    1398             : 
    1399             : !!!!!!!!! begin sub-step!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1400             :    !.....................................................................................................
    1401           0 :    do it=1,iter
    1402             : 
    1403             :       ! initialize sub-step microphysical tendencies
    1404             : 
    1405           0 :       tlat(i,1:pver)=0._r8
    1406           0 :       qvlat(i,1:pver)=0._r8
    1407           0 :       qctend(i,1:pver)=0._r8
    1408           0 :       qitend(i,1:pver)=0._r8
    1409           0 :       qnitend(i,1:pver)=0._r8
    1410           0 :       qrtend(i,1:pver)=0._r8
    1411           0 :       nctend(i,1:pver)=0._r8
    1412           0 :       nitend(i,1:pver)=0._r8
    1413           0 :       nrtend(i,1:pver)=0._r8
    1414           0 :       nstend(i,1:pver)=0._r8
    1415             : 
    1416             :       ! initialize diagnostic precipitation to zero
    1417             : 
    1418           0 :       qniic(i,1:pver)=0._r8
    1419           0 :       qric(i,1:pver)=0._r8
    1420           0 :       nsic(i,1:pver)=0._r8
    1421           0 :       nric(i,1:pver)=0._r8
    1422             : 
    1423           0 :       rainrt(i,1:pver)=0._r8
    1424             : 
    1425             : 
    1426             :       ! begin new i,k loop, calculate new cldmax after adjustment to cldm above
    1427             : 
    1428             :       ! initialize vertically-integrated rain and snow tendencies
    1429             : 
    1430           0 :       qrtot = 0._r8
    1431           0 :       nrtot = 0._r8
    1432           0 :       qstot = 0._r8
    1433           0 :       nstot = 0._r8
    1434             : 
    1435             :       ! initialize precip at surface
    1436             : 
    1437           0 :       prect(i)=0._r8
    1438           0 :       preci(i)=0._r8
    1439             : 
    1440             :       ! initialize fluxes
    1441           0 :       rflx(i,1:pver+1)=0._r8
    1442           0 :       sflx(i,1:pver+1)=0._r8
    1443             : 
    1444           0 :       do k=top_lev,pver
    1445             :       
    1446           0 :          qcvar=relvar(i,k)
    1447           0 :          cons2=gamma(qcvar+2.47_r8)
    1448           0 :          cons3=gamma(qcvar)
    1449           0 :          cons9=gamma(qcvar+2._r8)
    1450           0 :          cons10=gamma(qcvar+1._r8)
    1451           0 :          cons12=gamma(qcvar+1.15_r8) 
    1452           0 :          cons15=gamma(qcvar+bc/3._r8)
    1453           0 :          cons18=qcvar**2.47_r8
    1454           0 :          cons19=qcvar**2
    1455           0 :          cons20=qcvar**1.15_r8
    1456             : 
    1457             :          ! set cwml and cwmi to current qc and qi
    1458             : 
    1459           0 :          cwml(i,k)=qc(i,k)
    1460           0 :          cwmi(i,k)=qi(i,k)
    1461             : 
    1462             :          ! initialize precip fallspeeds to zero
    1463             : 
    1464           0 :          ums(k)=0._r8 
    1465           0 :          uns(k)=0._r8 
    1466           0 :          umr(k)=0._r8 
    1467           0 :          unr(k)=0._r8
    1468             : 
    1469             :          ! calculate precip fraction based on maximum overlap assumption
    1470             : 
    1471             :          ! for sub-columns cldm has already been set to 1 if cloud
    1472             :          ! water or ice is present, so cldmax will be correctly set below
    1473             :          ! and nothing extra needs to be done here
    1474             : 
    1475           0 :          if (k.eq.top_lev) then
    1476           0 :             cldmax(i,k)=cldm(i,k)
    1477             :          else
    1478             :             ! if rain or snow mix ratio is smaller than
    1479             :             ! threshold, then set cldmax to cloud fraction at current level
    1480             : 
    1481           0 :             if (do_clubb_sgs) then
    1482           0 :                if (qc(i,k).ge.qsmall.or.qi(i,k).ge.qsmall) then
    1483           0 :                   cldmax(i,k)=cldm(i,k)
    1484             :                else
    1485           0 :                   cldmax(i,k)=cldmax(i,k-1)
    1486             :                end if
    1487             :             else
    1488             : 
    1489           0 :                if (qric(i,k-1).ge.qsmall.or.qniic(i,k-1).ge.qsmall) then
    1490           0 :                   cldmax(i,k)=max(cldmax(i,k-1),cldm(i,k))
    1491             :                else
    1492           0 :                   cldmax(i,k)=cldm(i,k)
    1493             :                end if
    1494             :             endif
    1495             :          end if
    1496             : 
    1497             :          ! decrease in number concentration due to sublimation/evap
    1498             :          ! divide by cloud fraction to get in-cloud decrease
    1499             :          ! don't reduce Nc due to bergeron process
    1500             : 
    1501           0 :          if (cmei(i,k) < 0._r8 .and. qi(i,k) > qsmall .and. cldm(i,k) > mincld) then
    1502           0 :             nsubi(k)=cmei(i,k)/qi(i,k)*ni(i,k)/cldm(i,k)
    1503             :          else
    1504           0 :             nsubi(k)=0._r8
    1505             :          end if
    1506           0 :          nsubc(k)=0._r8
    1507             : 
    1508             : 
    1509             :          !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1510             :          !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1511             : 
    1512             :          ! ice nucleation if activated nuclei exist at t<-5C AND rhmini + 5%
    1513             : 
    1514           0 :          if (do_cldice .and. dum2i(i,k).gt.0._r8.and.t(i,k).lt.(tmelt - 5._r8).and. &
    1515             :               relhum(i,k)*esl(i,k)/esi(i,k).gt. rhmini+0.05_r8) then
    1516             : 
    1517             :             !if NCAI > 0. then set numice = ncai (as before)
    1518             :             !note: this is gridbox averaged
    1519             : 
    1520           0 :             nnuccd(k)=(dum2i(i,k)-ni(i,k)/icldm(i,k))/deltat*icldm(i,k)
    1521           0 :             nnuccd(k)=max(nnuccd(k),0._r8)
    1522           0 :             nimax = dum2i(i,k)*icldm(i,k)
    1523             : 
    1524             :             !Calc mass of new particles using new crystal mass...
    1525             :             !also this will be multiplied by mtime as nnuccd is...
    1526             : 
    1527           0 :             mnuccd(k) = nnuccd(k) * mi0
    1528             : 
    1529             :             !  add mnuccd to cmei....
    1530           0 :             cmei(i,k)= cmei(i,k) + mnuccd(k) * mtime
    1531             : 
    1532             :             !  limit cmei
    1533             : 
    1534           0 :             qvi = svp_to_qsat(esi(i,k), p(i,k))
    1535           0 :             dqsidt =  xxls*qvi/(rv*t(i,k)**2)
    1536           0 :             abi = 1._r8+dqsidt*xxls/cpp
    1537           0 :             cmei(i,k)=min(cmei(i,k),(q(i,k)-qvi)/abi/deltat)
    1538             : 
    1539             :             ! limit for roundoff error
    1540           0 :             cmei(i,k)=cmei(i,k)*omsm
    1541             : 
    1542             :          else
    1543           0 :             nnuccd(k)=0._r8
    1544           0 :             nimax = 0._r8
    1545           0 :             mnuccd(k) = 0._r8
    1546             :          end if
    1547             : 
    1548             :          !c............................................................................
    1549             :          !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1550             :          ! obtain in-cloud values of cloud water/ice mixing ratios and number concentrations
    1551             :          ! for microphysical process calculations
    1552             :          ! units are kg/kg for mixing ratio, 1/kg for number conc
    1553             : 
    1554             :          ! limit in-cloud values to 0.005 kg/kg
    1555             : 
    1556           0 :          qcic(i,k)=min(cwml(i,k)/lcldm(i,k),5.e-3_r8)
    1557           0 :          qiic(i,k)=min(cwmi(i,k)/icldm(i,k),5.e-3_r8)
    1558           0 :          ncic(i,k)=max(nc(i,k)/lcldm(i,k),0._r8)
    1559           0 :          niic(i,k)=max(ni(i,k)/icldm(i,k),0._r8)
    1560             : 
    1561           0 :          if (nccons) then
    1562           0 :            ncic(i,k) = ncnst/rho(i,k)
    1563             :          end if
    1564           0 :          if (nicons) then
    1565           0 :            niic(i,k) = ninst/rho(i,k)
    1566             :          end if 
    1567             : 
    1568           0 :          if (qc(i,k) - berg(i,k)*deltat.lt.qsmall) then
    1569           0 :             qcic(i,k)=0._r8
    1570           0 :             ncic(i,k)=0._r8
    1571           0 :             if (qc(i,k)-berg(i,k)*deltat.lt.0._r8) then
    1572           0 :                berg(i,k)=qc(i,k)/deltat*omsm
    1573             :             end if
    1574             :          end if
    1575             : 
    1576           0 :          if (do_cldice .and. qi(i,k)+(cmei(i,k)+berg(i,k))*deltat.lt.qsmall) then
    1577           0 :             qiic(i,k)=0._r8
    1578           0 :             niic(i,k)=0._r8
    1579           0 :             if (qi(i,k)+(cmei(i,k)+berg(i,k))*deltat.lt.0._r8) then
    1580           0 :                cmei(i,k)=(-qi(i,k)/deltat-berg(i,k))*omsm
    1581             :             end if
    1582             :          end if
    1583             : 
    1584             :          ! add to cme output
    1585             : 
    1586           0 :          cmeout(i,k) = cmeout(i,k)+cmei(i,k)
    1587             : 
    1588             :          !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1589             :          ! droplet activation
    1590             :          ! calculate potential for droplet activation if cloud water is present
    1591             :          ! formulation from Abdul-Razzak and Ghan (2000) and Abdul-Razzak et al. (1998), AR98
    1592             :          ! number tendency (npccnin) is read in from companion routine
    1593             : 
    1594             :          ! assume aerosols already activated are equal to number of existing droplets for simplicity
    1595             :          ! multiply by cloud fraction to obtain grid-average tendency
    1596             : 
    1597           0 :          if (qcic(i,k).ge.qsmall) then   
    1598           0 :             npccn(k) = max(0._r8,npccnin(i,k))  
    1599           0 :             dum2l(i,k)=(nc(i,k)+npccn(k)*deltat)/lcldm(i,k)
    1600           0 :             dum2l(i,k)=max(dum2l(i,k),cdnl/rho(i,k)) ! sghan minimum in #/cm3  
    1601           0 :             ncmax = dum2l(i,k)*lcldm(i,k)
    1602             :          else
    1603           0 :             npccn(k)=0._r8
    1604           0 :             dum2l(i,k)=0._r8
    1605           0 :             ncmax = 0._r8
    1606             :          end if
    1607             : 
    1608             :          !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1609             :          ! get size distribution parameters based on in-cloud cloud water/ice 
    1610             :          ! these calculations also ensure consistency between number and mixing ratio
    1611             :          !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1612             : 
    1613             :          !......................................................................
    1614             :          ! cloud ice
    1615             : 
    1616           0 :          if (qiic(i,k).ge.qsmall) then
    1617             : 
    1618             :             ! add upper limit to in-cloud number concentration to prevent numerical error
    1619           0 :             niic(i,k)=min(niic(i,k),qiic(i,k)*1.e20_r8)
    1620             : 
    1621           0 :             lami(k) = (cons1*ci*niic(i,k)/qiic(i,k))**(1._r8/di)
    1622           0 :             n0i(k) = niic(i,k)*lami(k)
    1623             : 
    1624             :             ! check for slope
    1625             :             ! adjust vars
    1626             : 
    1627           0 :             if (lami(k).lt.lammini) then
    1628             : 
    1629           0 :                lami(k) = lammini
    1630           0 :                n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
    1631           0 :                niic(i,k) = n0i(k)/lami(k)
    1632           0 :             else if (lami(k).gt.lammaxi) then
    1633           0 :                lami(k) = lammaxi
    1634           0 :                n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
    1635           0 :                niic(i,k) = n0i(k)/lami(k)
    1636             :             end if
    1637             : 
    1638             :          else
    1639           0 :             lami(k) = 0._r8
    1640           0 :             n0i(k) = 0._r8
    1641             :          end if
    1642             : 
    1643           0 :          if (qcic(i,k).ge.qsmall) then
    1644             : 
    1645             :             ! add upper limit to in-cloud number concentration to prevent numerical error
    1646           0 :             ncic(i,k)=min(ncic(i,k),qcic(i,k)*1.e20_r8)
    1647             : 
    1648           0 :             ncic(i,k)=max(ncic(i,k),cdnl/rho(i,k)) ! sghan minimum in #/cm  
    1649             : 
    1650             :             ! get pgam from fit to observations of martin et al. 1994
    1651             : 
    1652           0 :             pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8
    1653           0 :             pgam(k)=1._r8/(pgam(k)**2)-1._r8
    1654           0 :             pgam(k)=max(pgam(k),2._r8)
    1655           0 :             pgam(k)=min(pgam(k),15._r8)
    1656             : 
    1657             :             ! calculate lamc
    1658             : 
    1659             :             lamc(k) = (pi/6._r8*rhow*ncic(i,k)*gamma(pgam(k)+4._r8)/ &
    1660           0 :                  (qcic(i,k)*gamma(pgam(k)+1._r8)))**(1._r8/3._r8)
    1661             : 
    1662             :             ! lammin, 50 micron diameter max mean size
    1663             : 
    1664           0 :             lammin = (pgam(k)+1._r8)/50.e-6_r8
    1665           0 :             lammax = (pgam(k)+1._r8)/2.e-6_r8
    1666             : 
    1667           0 :             if (lamc(k).lt.lammin) then
    1668           0 :                lamc(k) = lammin
    1669             :                ncic(i,k) = 6._r8*lamc(k)**3*qcic(i,k)* &
    1670           0 :                     gamma(pgam(k)+1._r8)/(pi*rhow*gamma(pgam(k)+4._r8))
    1671           0 :             else if (lamc(k).gt.lammax) then
    1672           0 :                lamc(k) = lammax
    1673             :                ncic(i,k) = 6._r8*lamc(k)**3*qcic(i,k)* &
    1674           0 :                     gamma(pgam(k)+1._r8)/(pi*rhow*gamma(pgam(k)+4._r8))
    1675             :             end if
    1676             : 
    1677             :             ! parameter to calculate droplet freezing
    1678             : 
    1679           0 :             cdist1(k) = ncic(i,k)/gamma(pgam(k)+1._r8) 
    1680             : 
    1681             :          else
    1682           0 :             lamc(k) = 0._r8
    1683           0 :             cdist1(k) = 0._r8
    1684             :          end if
    1685             : 
    1686             :          !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1687             :          !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1688             :          ! begin micropysical process calculations 
    1689             :          !.................................................................
    1690             :          ! autoconversion of cloud liquid water to rain
    1691             :          ! formula from Khrouditnov and Kogan (2000), modified for sub-grid distribution of qc
    1692             :          ! minimum qc of 1 x 10^-8 prevents floating point error
    1693             : 
    1694           0 :          if (qcic(i,k).ge.1.e-8_r8) then
    1695             : 
    1696             :             ! nprc is increase in rain number conc due to autoconversion
    1697             :             ! nprc1 is decrease in cloud droplet conc due to autoconversion
    1698             : 
    1699             :             ! assume exponential sub-grid distribution of qc, resulting in additional
    1700             :             ! factor related to qcvar below
    1701             : 
    1702             :             ! hm switch for sub-columns, don't include sub-grid qc
    1703           0 :             if (microp_uniform) then
    1704             : 
    1705             :                prc(k) = 1350._r8*qcic(i,k)**2.47_r8* &
    1706           0 :                     (ncic(i,k)/1.e6_r8*rho(i,k))**(-1.79_r8)
    1707           0 :                nprc(k) = prc(k)/(4._r8/3._r8*pi*rhow*(25.e-6_r8)**3)
    1708           0 :                nprc1(k) = prc(k)/(qcic(i,k)/ncic(i,k))
    1709             : 
    1710             :             else
    1711             : 
    1712             :                prc(k) = cons2/(cons3*cons18)*1350._r8*qcic(i,k)**2.47_r8* &
    1713           0 :                     (ncic(i,k)/1.e6_r8*rho(i,k))**(-1.79_r8)
    1714           0 :                nprc(k) = prc(k)/cons22
    1715           0 :                nprc1(k) = prc(k)/(qcic(i,k)/ncic(i,k))
    1716             : 
    1717             :             end if               ! sub-column switch
    1718             : 
    1719             :          else
    1720           0 :             prc(k)=0._r8
    1721           0 :             nprc(k)=0._r8
    1722           0 :             nprc1(k)=0._r8
    1723             :          end if
    1724             : 
    1725             :          ! add autoconversion to precip from above to get provisional rain mixing ratio
    1726             :          ! and number concentration (qric and nric)
    1727             : 
    1728             :          ! 0.45 m/s is fallspeed of new rain drop (80 micron diameter)
    1729             : 
    1730           0 :          dum=0.45_r8
    1731           0 :          dum1=0.45_r8
    1732             : 
    1733           0 :          if (k.eq.top_lev) then
    1734           0 :             qric(i,k)=prc(k)*lcldm(i,k)*dz(i,k)/cldmax(i,k)/dum
    1735           0 :             nric(i,k)=nprc(k)*lcldm(i,k)*dz(i,k)/cldmax(i,k)/dum
    1736             :          else
    1737           0 :             if (qric(i,k-1).ge.qsmall) then
    1738           0 :                dum=umr(k-1)
    1739           0 :                dum1=unr(k-1)
    1740             :             end if
    1741             : 
    1742             :             ! no autoconversion of rain number if rain/snow falling from above
    1743             :             ! this assumes that new drizzle drops formed by autoconversion are rapidly collected
    1744             :             ! by the existing rain/snow particles from above
    1745             : 
    1746           0 :             if (qric(i,k-1).ge.1.e-9_r8.or.qniic(i,k-1).ge.1.e-9_r8) then
    1747           0 :                nprc(k)=0._r8
    1748             :             end if
    1749             : 
    1750             :             qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)*cldmax(i,k-1)+ &
    1751             :                  (rho(i,k)*dz(i,k)*((pra(k-1)+prc(k))*lcldm(i,k)+(pre(k-1)-pracs(k-1)-mnuccr(k-1))*cldmax(i,k))))&
    1752           0 :                  /(dum*rho(i,k)*cldmax(i,k))
    1753             :             nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)*cldmax(i,k-1)+ &
    1754             :                  (rho(i,k)*dz(i,k)*(nprc(k)*lcldm(i,k)+(nsubr(k-1)-npracs(k-1)-nnuccr(k-1)+nragg(k-1))*cldmax(i,k))))&
    1755           0 :                  /(dum1*rho(i,k)*cldmax(i,k))
    1756             : 
    1757             :          end if
    1758             : 
    1759             :          !.......................................................................
    1760             :          ! Autoconversion of cloud ice to snow
    1761             :          ! similar to Ferrier (1994)
    1762             : 
    1763           0 :          if (do_cldice) then
    1764           0 :             if (t(i,k).le.273.15_r8.and.qiic(i,k).ge.qsmall) then
    1765             : 
    1766             :                ! note: assumes autoconversion timescale of 180 sec
    1767             :                
    1768           0 :                nprci(k) = n0i(k)/(lami(k)*180._r8)*exp(-lami(k)*dcs)
    1769             : 
    1770             :                prci(k) = pi*rhoi*n0i(k)/(6._r8*180._r8)* &
    1771             :                     (cons23/lami(k)+3._r8*cons24/lami(k)**2+ &
    1772           0 :                     6._r8*dcs/lami(k)**3+6._r8/lami(k)**4)*exp(-lami(k)*dcs)
    1773             :             else
    1774           0 :                prci(k)=0._r8
    1775           0 :                nprci(k)=0._r8
    1776             :             end if
    1777             :          else
    1778             :             ! Add in the particles that we have already converted to snow, and
    1779             :             ! don't do any further autoconversion of ice.
    1780           0 :             prci(k)  = tnd_qsnow(i, k) / cldm(i,k)
    1781           0 :             nprci(k) = tnd_nsnow(i, k) / cldm(i,k)
    1782             :          end if
    1783             : 
    1784             :          ! add autoconversion to flux from level above to get provisional snow mixing ratio
    1785             :          ! and number concentration (qniic and nsic)
    1786             : 
    1787           0 :          dum=(asn(i,k)*cons25)
    1788           0 :          dum1=(asn(i,k)*cons25)
    1789             : 
    1790           0 :          if (k.eq.top_lev) then
    1791           0 :             qniic(i,k)=prci(k)*icldm(i,k)*dz(i,k)/cldmax(i,k)/dum
    1792           0 :             nsic(i,k)=nprci(k)*icldm(i,k)*dz(i,k)/cldmax(i,k)/dum
    1793             :          else
    1794           0 :             if (qniic(i,k-1).ge.qsmall) then
    1795           0 :                dum=ums(k-1)
    1796           0 :                dum1=uns(k-1)
    1797             :             end if
    1798             : 
    1799             :             qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)*cldmax(i,k-1)+ &
    1800             :                  (rho(i,k)*dz(i,k)*((prci(k)+prai(k-1)+psacws(k-1)+bergs(k-1))*icldm(i,k)+(prds(k-1)+ &
    1801             :                  pracs(k-1)+mnuccr(k-1))*cldmax(i,k))))&
    1802           0 :                  /(dum*rho(i,k)*cldmax(i,k))
    1803             : 
    1804             :             nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)*cldmax(i,k-1)+ &
    1805             :                  (rho(i,k)*dz(i,k)*(nprci(k)*icldm(i,k)+(nsubs(k-1)+nsagg(k-1)+nnuccr(k-1))*cldmax(i,k))))&
    1806           0 :                  /(dum1*rho(i,k)*cldmax(i,k))
    1807             : 
    1808             :          end if
    1809             : 
    1810             :          ! if precip mix ratio is zero so should number concentration
    1811             : 
    1812           0 :          if (qniic(i,k).lt.qsmall) then
    1813           0 :             qniic(i,k)=0._r8
    1814           0 :             nsic(i,k)=0._r8
    1815             :          end if
    1816             : 
    1817           0 :          if (qric(i,k).lt.qsmall) then
    1818           0 :             qric(i,k)=0._r8
    1819           0 :             nric(i,k)=0._r8
    1820             :          end if
    1821             : 
    1822             :          ! make sure number concentration is a positive number to avoid 
    1823             :          ! taking root of negative later
    1824             : 
    1825           0 :          nric(i,k)=max(nric(i,k),0._r8)
    1826           0 :          nsic(i,k)=max(nsic(i,k),0._r8)
    1827             : 
    1828             :          !.......................................................................
    1829             :          ! get size distribution parameters for precip
    1830             :          !......................................................................
    1831             :          ! rain
    1832             : 
    1833           0 :          if (qric(i,k).ge.qsmall) then
    1834           0 :             lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))**(1._r8/3._r8)
    1835           0 :             n0r(k) = nric(i,k)*lamr(k)
    1836             : 
    1837             :             ! check for slope
    1838             :             ! adjust vars
    1839             : 
    1840           0 :             if (lamr(k).lt.lamminr) then
    1841             : 
    1842           0 :                lamr(k) = lamminr
    1843             : 
    1844           0 :                n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow)
    1845           0 :                nric(i,k) = n0r(k)/lamr(k)
    1846           0 :             else if (lamr(k).gt.lammaxr) then
    1847           0 :                lamr(k) = lammaxr
    1848           0 :                n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow)
    1849           0 :                nric(i,k) = n0r(k)/lamr(k)
    1850             :             end if
    1851             : 
    1852             :             ! provisional rain number and mass weighted mean fallspeed (m/s)
    1853             : 
    1854           0 :             unr(k) = min(arn(i,k)*cons4/lamr(k)**br,9.1_r8*rhof(i,k))
    1855           0 :             umr(k) = min(arn(i,k)*cons5/(6._r8*lamr(k)**br),9.1_r8*rhof(i,k))
    1856             : 
    1857             :          else
    1858           0 :             lamr(k) = 0._r8
    1859           0 :             n0r(k) = 0._r8
    1860           0 :             umr(k) = 0._r8
    1861           0 :             unr(k) = 0._r8
    1862             :          end if
    1863             : 
    1864             :          !......................................................................
    1865             :          ! snow
    1866             : 
    1867           0 :          if (qniic(i,k).ge.qsmall) then
    1868           0 :             lams(k) = (cons6*cs*nsic(i,k)/qniic(i,k))**(1._r8/ds)
    1869           0 :             n0s(k) = nsic(i,k)*lams(k)
    1870             : 
    1871             :             ! check for slope
    1872             :             ! adjust vars
    1873             : 
    1874           0 :             if (lams(k).lt.lammins) then
    1875           0 :                lams(k) = lammins
    1876           0 :                n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6)
    1877           0 :                nsic(i,k) = n0s(k)/lams(k)
    1878             : 
    1879           0 :             else if (lams(k).gt.lammaxs) then
    1880           0 :                lams(k) = lammaxs
    1881           0 :                n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6)
    1882           0 :                nsic(i,k) = n0s(k)/lams(k)
    1883             :             end if
    1884             : 
    1885             :             ! provisional snow number and mass weighted mean fallspeed (m/s)
    1886             : 
    1887           0 :             ums(k) = min(asn(i,k)*cons8/(6._r8*lams(k)**bs),1.2_r8*rhof(i,k))
    1888           0 :             uns(k) = min(asn(i,k)*cons7/lams(k)**bs,1.2_r8*rhof(i,k))
    1889             : 
    1890             :          else
    1891           0 :             lams(k) = 0._r8
    1892           0 :             n0s(k) = 0._r8
    1893           0 :             ums(k) = 0._r8
    1894           0 :             uns(k) = 0._r8
    1895             :          end if
    1896             : 
    1897             :          !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1898             : 
    1899             :          ! heterogeneous freezing of cloud water
    1900             : 
    1901           0 :          if (.not. use_hetfrz_classnuc) then
    1902             : 
    1903           0 :             if (do_cldice .and. qcic(i,k).ge.qsmall .and. t(i,k).lt.269.15_r8) then
    1904             : 
    1905             :                ! immersion freezing (Bigg, 1953)
    1906             : 
    1907             : 
    1908             :                ! subcolumns
    1909             : 
    1910           0 :                if (microp_uniform) then
    1911             : 
    1912             :                   mnuccc(k) = &
    1913             :                      pi*pi/36._r8*rhow* &
    1914             :                      cdist1(k)*gamma(7._r8+pgam(k))* &
    1915             :                      bimm*(exp(aimm*(273.15_r8-t(i,k)))-1._r8)/ &
    1916           0 :                      lamc(k)**3/lamc(k)**3
    1917             : 
    1918             :                   nnuccc(k) = &
    1919             :                      pi/6._r8*cdist1(k)*gamma(pgam(k)+4._r8) &
    1920             :                      *bimm* &
    1921           0 :                      (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamc(k)**3
    1922             : 
    1923             :                else
    1924             : 
    1925             :                   mnuccc(k) = cons9/(cons3*cons19)* &
    1926             :                      pi*pi/36._r8*rhow* &
    1927             :                      cdist1(k)*gamma(7._r8+pgam(k))* &
    1928             :                      bimm*(exp(aimm*(273.15_r8-t(i,k)))-1._r8)/ &
    1929           0 :                      lamc(k)**3/lamc(k)**3
    1930             : 
    1931             :                   nnuccc(k) = cons10/(cons3*qcvar)* &
    1932             :                      pi/6._r8*cdist1(k)*gamma(pgam(k)+4._r8) &
    1933             :                      *bimm* &
    1934           0 :                      (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamc(k)**3
    1935             :                end if           ! sub-columns
    1936             : 
    1937             : 
    1938             :                ! contact freezing (-40<T<-3 C) (Young, 1974) with hooks into simulated dust
    1939             :                ! dust size and number in 4 bins are read in from companion routine
    1940             : 
    1941           0 :                tcnt=(270.16_r8-t(i,k))**1.3_r8
    1942           0 :                viscosity=1.8e-5_r8*(t(i,k)/298.0_r8)**0.85_r8    ! Viscosity (kg/m/s)
    1943             :                mfp=2.0_r8*viscosity/(p(i,k)  &                   ! Mean free path (m)
    1944           0 :                   *sqrt(8.0_r8*28.96e-3_r8/(pi*8.314409_r8*t(i,k))))           
    1945             : 
    1946           0 :                nslip1=1.0_r8+(mfp/rndst(i,k,1))*(1.257_r8+(0.4_r8*Exp(-(1.1_r8*rndst(i,k,1)/mfp))))! Slip correction factor
    1947           0 :                nslip2=1.0_r8+(mfp/rndst(i,k,2))*(1.257_r8+(0.4_r8*Exp(-(1.1_r8*rndst(i,k,2)/mfp))))
    1948           0 :                nslip3=1.0_r8+(mfp/rndst(i,k,3))*(1.257_r8+(0.4_r8*Exp(-(1.1_r8*rndst(i,k,3)/mfp))))
    1949           0 :                nslip4=1.0_r8+(mfp/rndst(i,k,4))*(1.257_r8+(0.4_r8*Exp(-(1.1_r8*rndst(i,k,4)/mfp))))
    1950             : 
    1951           0 :                ndfaer1=1.381e-23_r8*t(i,k)*nslip1/(6._r8*pi*viscosity*rndst(i,k,1))  ! aerosol diffusivity (m2/s)
    1952           0 :                ndfaer2=1.381e-23_r8*t(i,k)*nslip2/(6._r8*pi*viscosity*rndst(i,k,2))
    1953           0 :                ndfaer3=1.381e-23_r8*t(i,k)*nslip3/(6._r8*pi*viscosity*rndst(i,k,3))
    1954           0 :                ndfaer4=1.381e-23_r8*t(i,k)*nslip4/(6._r8*pi*viscosity*rndst(i,k,4))
    1955             : 
    1956             : 
    1957           0 :                if (microp_uniform) then
    1958             : 
    1959             :                   mnucct(k) = &
    1960             :                      (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ &
    1961             :                      ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow* &
    1962           0 :                      cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4
    1963             : 
    1964             :                   nnucct(k) = (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ &
    1965             :                      ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi*  &
    1966           0 :                      cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k)
    1967             : 
    1968             :                else
    1969             : 
    1970             :                   mnucct(k) = gamma(qcvar+4._r8/3._r8)/(cons3*qcvar**(4._r8/3._r8))*  &
    1971             :                      (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ &
    1972             :                      ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow* &
    1973           0 :                      cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4
    1974             : 
    1975             :                   nnucct(k) =  gamma(qcvar+1._r8/3._r8)/(cons3*qcvar**(1._r8/3._r8))*  &
    1976             :                      (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ &
    1977             :                      ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi*  &
    1978           0 :                      cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k)
    1979             : 
    1980             :                end if      ! sub-column switch
    1981             : 
    1982             :                ! make sure number of droplets frozen does not exceed available ice nuclei concentration
    1983             :                ! this prevents 'runaway' droplet freezing
    1984             : 
    1985           0 :                if (nnuccc(k)*lcldm(i,k).gt.nnuccd(k)) then
    1986           0 :                   dum=(nnuccd(k)/(nnuccc(k)*lcldm(i,k)))
    1987             :                   ! scale mixing ratio of droplet freezing with limit
    1988           0 :                   mnuccc(k)=mnuccc(k)*dum
    1989           0 :                   nnuccc(k)=nnuccd(k)/lcldm(i,k)
    1990             :                end if
    1991             : 
    1992             :             else
    1993           0 :                mnuccc(k)=0._r8
    1994           0 :                nnuccc(k)=0._r8
    1995           0 :                mnucct(k)=0._r8
    1996           0 :                nnucct(k)=0._r8
    1997             :             end if
    1998             : 
    1999             :          else
    2000           0 :             if (do_cldice .and. qcic(i,k) >= qsmall) then
    2001           0 :                con1 = 1._r8/(1.333_r8*pi)**0.333_r8
    2002           0 :                r3lx = con1*(rho(i,k)*qcic(i,k)/(rhow*max(ncic(i,k)*rho(i,k), 1.0e6_r8)))**0.333_r8 ! in m
    2003           0 :                r3lx = max(4.e-6_r8, r3lx)
    2004           0 :                mi0l = 4._r8/3._r8*pi*rhow*r3lx**3_r8
    2005             :                 
    2006           0 :                nnuccc(k) = frzimm(i,k)*1.0e6_r8/rho(i,k)
    2007           0 :                mnuccc(k) = nnuccc(k)*mi0l 
    2008             : 
    2009           0 :                nnucct(k) = frzcnt(i,k)*1.0e6_r8/rho(i,k)
    2010           0 :                mnucct(k) = nnucct(k)*mi0l 
    2011             : 
    2012           0 :                nnudep(k) = frzdep(i,k)*1.0e6_r8/rho(i,k)
    2013           0 :                mnudep(k) = nnudep(k)*mi0
    2014             :             else
    2015           0 :                nnuccc(k) = 0._r8
    2016           0 :                mnuccc(k) = 0._r8
    2017             : 
    2018           0 :                nnucct(k) = 0._r8
    2019           0 :                mnucct(k) = 0._r8
    2020             : 
    2021           0 :                nnudep(k) = 0._r8
    2022           0 :                mnudep(k) = 0._r8
    2023             :             end if
    2024             :          endif
    2025             : 
    2026             : 
    2027             :          !.......................................................................
    2028             :          ! snow self-aggregation from passarelli, 1978, used by reisner, 1998
    2029             :          ! this is hard-wired for bs = 0.4 for now
    2030             :          ! ignore self-collection of cloud ice
    2031             : 
    2032           0 :          if (qniic(i,k).ge.qsmall .and. t(i,k).le.273.15_r8) then
    2033             :             nsagg(k) = -1108._r8*asn(i,k)*Eii* &
    2034             :                  pi**((1._r8-bs)/3._r8)*rhosn**((-2._r8-bs)/3._r8)*rho(i,k)** &
    2035             :                  ((2._r8+bs)/3._r8)*qniic(i,k)**((2._r8+bs)/3._r8)* &
    2036             :                  (nsic(i,k)*rho(i,k))**((4._r8-bs)/3._r8)/ &
    2037           0 :                  (4._r8*720._r8*rho(i,k))
    2038             :          else
    2039           0 :             nsagg(k)=0._r8
    2040             :          end if
    2041             : 
    2042             :          !.......................................................................
    2043             :          ! accretion of cloud droplets onto snow/graupel
    2044             :          ! here use continuous collection equation with
    2045             :          ! simple gravitational collection kernel
    2046             :          ! ignore collisions between droplets/cloud ice
    2047             :          ! since minimum size ice particle for accretion is 50 - 150 micron
    2048             : 
    2049             :          ! ignore collision of snow with droplets above freezing
    2050             : 
    2051           0 :          if (qniic(i,k).ge.qsmall .and. t(i,k).le.tmelt .and. &
    2052             :               qcic(i,k).ge.qsmall) then
    2053             : 
    2054             :             ! put in size dependent collection efficiency
    2055             :             ! mean diameter of snow is area-weighted, since
    2056             :             ! accretion is function of crystal geometric area
    2057             :             ! collection efficiency is approximation based on stoke's law (Thompson et al. 2004)
    2058             : 
    2059           0 :             dc0 = (pgam(k)+1._r8)/lamc(k)
    2060           0 :             ds0 = 1._r8/lams(k)
    2061           0 :             dum = dc0*dc0*uns(k)*rhow/(9._r8*mu(i,k)*ds0)
    2062           0 :             eci = dum*dum/((dum+0.4_r8)*(dum+0.4_r8))
    2063             : 
    2064           0 :             eci = max(eci,0._r8)
    2065           0 :             eci = min(eci,1._r8)
    2066             : 
    2067             : 
    2068             :             ! no impact of sub-grid distribution of qc since psacws
    2069             :             ! is linear in qc
    2070             : 
    2071             :             psacws(k) = pi/4._r8*asn(i,k)*qcic(i,k)*rho(i,k)* &
    2072             :                  n0s(k)*Eci*cons11/ &
    2073           0 :                  lams(k)**(bs+3._r8)
    2074             :             npsacws(k) = pi/4._r8*asn(i,k)*ncic(i,k)*rho(i,k)* &
    2075             :                  n0s(k)*Eci*cons11/ &
    2076           0 :                  lams(k)**(bs+3._r8)
    2077             :          else
    2078           0 :             psacws(k)=0._r8
    2079           0 :             npsacws(k)=0._r8
    2080             :          end if
    2081             : 
    2082             :          ! add secondary ice production due to accretion of droplets by snow 
    2083             :          ! (Hallet-Mossop process) (from Cotton et al., 1986)
    2084             : 
    2085           0 :          if (.not. do_cldice) then
    2086           0 :             ni_secp   = 0.0_r8
    2087           0 :             nsacwi(k) = 0.0_r8
    2088           0 :             msacwi(k) = 0.0_r8
    2089           0 :          else if((t(i,k).lt.270.16_r8) .and. (t(i,k).ge.268.16_r8)) then
    2090           0 :             ni_secp   = 3.5e8_r8*(270.16_r8-t(i,k))/2.0_r8*psacws(k)
    2091           0 :             nsacwi(k) = ni_secp
    2092           0 :             msacwi(k) = min(ni_secp*mi0,psacws(k))
    2093           0 :          else if((t(i,k).lt.268.16_r8) .and. (t(i,k).ge.265.16_r8)) then
    2094           0 :             ni_secp   = 3.5e8_r8*(t(i,k)-265.16_r8)/3.0_r8*psacws(k)
    2095           0 :             nsacwi(k) = ni_secp
    2096           0 :             msacwi(k) = min(ni_secp*mi0,psacws(k))
    2097             :          else
    2098           0 :             ni_secp   = 0.0_r8
    2099           0 :             nsacwi(k) = 0.0_r8
    2100           0 :             msacwi(k) = 0.0_r8
    2101             :          endif
    2102           0 :          psacws(k) = max(0.0_r8,psacws(k)-ni_secp*mi0)
    2103             : 
    2104             :          !.......................................................................
    2105             :          ! accretion of rain water by snow
    2106             :          ! formula from ikawa and saito, 1991, used by reisner et al., 1998
    2107             : 
    2108           0 :          if (qric(i,k).ge.1.e-8_r8 .and. qniic(i,k).ge.1.e-8_r8 .and. & 
    2109             :               t(i,k).le.273.15_r8) then
    2110             : 
    2111             :             pracs(k) = pi*pi*ecr*(((1.2_r8*umr(k)-0.95_r8*ums(k))**2+ &
    2112             :                  0.08_r8*ums(k)*umr(k))**0.5_r8*rhow*rho(i,k)* &
    2113             :                  n0r(k)*n0s(k)* &
    2114             :                  (5._r8/(lamr(k)**6*lams(k))+ &
    2115             :                  2._r8/(lamr(k)**5*lams(k)**2)+ &
    2116           0 :                  0.5_r8/(lamr(k)**4*lams(k)**3)))
    2117             : 
    2118             :             npracs(k) = pi/2._r8*rho(i,k)*ecr*(1.7_r8*(unr(k)-uns(k))**2+ &
    2119             :                  0.3_r8*unr(k)*uns(k))**0.5_r8*n0r(k)*n0s(k)* &
    2120             :                  (1._r8/(lamr(k)**3*lams(k))+ &
    2121             :                  1._r8/(lamr(k)**2*lams(k)**2)+ &
    2122           0 :                  1._r8/(lamr(k)*lams(k)**3))
    2123             : 
    2124             :          else
    2125           0 :             pracs(k)=0._r8
    2126           0 :             npracs(k)=0._r8
    2127             :          end if
    2128             : 
    2129             :          !.......................................................................
    2130             :          ! heterogeneous freezing of rain drops
    2131             :          ! follows from Bigg (1953)
    2132             : 
    2133           0 :          if (t(i,k).lt.269.15_r8 .and. qric(i,k).ge.qsmall) then
    2134             : 
    2135             :             mnuccr(k) = 20._r8*pi*pi*rhow*nric(i,k)*bimm* &
    2136             :                  (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamr(k)**3 &
    2137           0 :                  /lamr(k)**3
    2138             : 
    2139             :             nnuccr(k) = pi*nric(i,k)*bimm* &
    2140           0 :                  (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamr(k)**3
    2141             :          else
    2142           0 :             mnuccr(k)=0._r8
    2143           0 :             nnuccr(k)=0._r8
    2144             :          end if
    2145             : 
    2146             :          !.......................................................................
    2147             :          ! accretion of cloud liquid water by rain
    2148             :          ! formula from Khrouditnov and Kogan (2000)
    2149             :          ! gravitational collection kernel, droplet fall speed neglected
    2150             : 
    2151           0 :          if (qric(i,k).ge.qsmall .and. qcic(i,k).ge.qsmall) then
    2152             : 
    2153             :             ! include sub-grid distribution of cloud water
    2154             : 
    2155             :             ! add sub-column switch
    2156             : 
    2157           0 :             if (microp_uniform) then
    2158             : 
    2159           0 :                pra(k) = 67._r8*(qcic(i,k)*qric(i,k))**1.15_r8
    2160           0 :                npra(k) = pra(k)/(qcic(i,k)/ncic(i,k))
    2161             : 
    2162             :             else
    2163             : 
    2164           0 :                pra(k) = accre_enhan(i,k)*(cons12/(cons3*cons20)*67._r8*(qcic(i,k)*qric(i,k))**1.15_r8)
    2165           0 :                npra(k) = pra(k)/(qcic(i,k)/ncic(i,k))
    2166             : 
    2167             :             end if               ! sub-column switch
    2168             : 
    2169             :          else
    2170           0 :             pra(k)=0._r8
    2171           0 :             npra(k)=0._r8
    2172             :          end if
    2173             : 
    2174             :          !.......................................................................
    2175             :          ! Self-collection of rain drops
    2176             :          ! from Beheng(1994)
    2177             : 
    2178           0 :          if (qric(i,k).ge.qsmall) then
    2179           0 :             nragg(k) = -8._r8*nric(i,k)*qric(i,k)*rho(i,k)
    2180             :          else
    2181           0 :             nragg(k)=0._r8
    2182             :          end if
    2183             : 
    2184             :          !.......................................................................
    2185             :          ! Accretion of cloud ice by snow
    2186             :          ! For this calculation, it is assumed that the Vs >> Vi
    2187             :          ! and Ds >> Di for continuous collection
    2188             : 
    2189             :          if (do_cldice .and. qniic(i,k).ge.qsmall.and.qiic(i,k).ge.qsmall &
    2190           0 :               .and.t(i,k).le.273.15_r8) then
    2191             : 
    2192             :             prai(k) = pi/4._r8*asn(i,k)*qiic(i,k)*rho(i,k)* &
    2193             :                  n0s(k)*Eii*cons11/ &
    2194           0 :                  lams(k)**(bs+3._r8)
    2195             :             nprai(k) = pi/4._r8*asn(i,k)*niic(i,k)* &
    2196             :                  rho(i,k)*n0s(k)*Eii*cons11/ &
    2197           0 :                  lams(k)**(bs+3._r8)
    2198             :          else
    2199           0 :             prai(k)=0._r8
    2200           0 :             nprai(k)=0._r8
    2201             :          end if
    2202             : 
    2203             :          !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    2204             :          ! calculate evaporation/sublimation of rain and snow
    2205             :          ! note: evaporation/sublimation occurs only in cloud-free portion of grid cell
    2206             :          ! in-cloud condensation/deposition of rain and snow is neglected
    2207             :          ! except for transfer of cloud water to snow through bergeron process
    2208             : 
    2209             :          ! initialize evap/sub tendncies
    2210           0 :          pre(k)=0._r8
    2211           0 :          prds(k)=0._r8
    2212             : 
    2213             :          ! evaporation of rain
    2214             :          ! only calculate if there is some precip fraction > cloud fraction
    2215             : 
    2216           0 :          if (qcic(i,k)+qiic(i,k).lt.1.e-6_r8.or.cldmax(i,k).gt.lcldm(i,k)) then
    2217             : 
    2218             :             ! set temporary cloud fraction to zero if cloud water + ice is very small
    2219             :             ! this will ensure that evaporation/sublimation of precip occurs over
    2220             :             ! entire grid cell, since min cloud fraction is specified otherwise
    2221           0 :             if (qcic(i,k)+qiic(i,k).lt.1.e-6_r8) then
    2222             :                dum=0._r8
    2223             :             else
    2224           0 :                dum=lcldm(i,k)
    2225             :             end if
    2226             : 
    2227             :             ! saturation vapor pressure
    2228           0 :             esn=svp_water(t(i,k))
    2229           0 :             qsn=svp_to_qsat(esn, p(i,k))
    2230             : 
    2231             :             ! recalculate saturation vapor pressure for liquid and ice
    2232           0 :             esl(i,k)=esn
    2233           0 :             esi(i,k)=svp_ice(t(i,k))
    2234             :             ! hm fix, make sure when above freezing that esi=esl, not active yet
    2235           0 :             if (t(i,k).gt.tmelt)esi(i,k)=esl(i,k)
    2236             : 
    2237             :             ! calculate q for out-of-cloud region
    2238           0 :             qclr=(q(i,k)-dum*qsn)/(1._r8-dum)
    2239             : 
    2240           0 :             if (qric(i,k).ge.qsmall) then
    2241             : 
    2242           0 :                qvs=svp_to_qsat(esl(i,k), p(i,k))
    2243           0 :                dqsdt = xxlv*qvs/(rv*t(i,k)**2)
    2244           0 :                ab = 1._r8+dqsdt*xxlv/cpp
    2245             :                epsr = 2._r8*pi*n0r(k)*rho(i,k)*Dv(i,k)* &
    2246             :                     (f1r/(lamr(k)*lamr(k))+ &
    2247             :                     f2r*(arn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* &
    2248             :                     sc(i,k)**(1._r8/3._r8)*cons13/ &
    2249           0 :                     (lamr(k)**(5._r8/2._r8+br/2._r8)))
    2250             : 
    2251           0 :                pre(k) = epsr*(qclr-qvs)/ab
    2252             : 
    2253             :                ! only evaporate in out-of-cloud region
    2254             :                ! and distribute across cldmax
    2255           0 :                pre(k)=min(pre(k)*(cldmax(i,k)-dum),0._r8)
    2256           0 :                pre(k)=pre(k)/cldmax(i,k)
    2257           0 :                am_evp_st(i,k) = max(cldmax(i,k)-dum, 0._r8)
    2258             :             end if
    2259             : 
    2260             :             ! sublimation of snow
    2261           0 :             if (qniic(i,k).ge.qsmall) then
    2262           0 :                qvi=svp_to_qsat(esi(i,k), p(i,k))
    2263           0 :                dqsidt =  xxls*qvi/(rv*t(i,k)**2)
    2264           0 :                abi = 1._r8+dqsidt*xxls/cpp
    2265             :                epss = 2._r8*pi*n0s(k)*rho(i,k)*Dv(i,k)* &
    2266             :                     (f1s/(lams(k)*lams(k))+ &
    2267             :                     f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* &
    2268             :                     sc(i,k)**(1._r8/3._r8)*cons14/ &
    2269           0 :                     (lams(k)**(5._r8/2._r8+bs/2._r8)))
    2270           0 :                prds(k) = epss*(qclr-qvi)/abi
    2271             : 
    2272             :                ! only sublimate in out-of-cloud region and distribute over cldmax
    2273           0 :                prds(k)=min(prds(k)*(cldmax(i,k)-dum),0._r8)
    2274           0 :                prds(k)=prds(k)/cldmax(i,k)
    2275           0 :                am_evp_st(i,k) = max(cldmax(i,k)-dum, 0._r8)
    2276             :             end if
    2277             : 
    2278             :             ! make sure RH not pushed above 100% due to rain evaporation/snow sublimation
    2279             :             ! get updated RH at end of time step based on cloud water/ice condensation/evap
    2280             : 
    2281           0 :             qtmp=q(i,k)-(cmei(i,k)+(pre(k)+prds(k))*cldmax(i,k))*deltat
    2282             :             ttmp=t(i,k)+((pre(k)*cldmax(i,k))*xxlv+ &
    2283           0 :                  (cmei(i,k)+prds(k)*cldmax(i,k))*xxls)*deltat/cpp
    2284             : 
    2285             :             !limit range of temperatures!
    2286           0 :             ttmp=max(180._r8,min(ttmp,323._r8))
    2287             : 
    2288           0 :             esn=svp_water(ttmp)  ! use rhw to allow ice supersaturation
    2289           0 :             qsn=svp_to_qsat(esn, p(i,k))
    2290             : 
    2291             :             ! modify precip evaporation rate if q > qsat
    2292           0 :             if (qtmp.gt.qsn) then
    2293           0 :                if (pre(k)+prds(k).lt.-1.e-20_r8) then
    2294           0 :                   dum1=pre(k)/(pre(k)+prds(k))
    2295             :                   ! recalculate q and t after cloud water cond but without precip evap
    2296           0 :                   qtmp=q(i,k)-(cmei(i,k))*deltat
    2297           0 :                   ttmp=t(i,k)+(cmei(i,k)*xxls)*deltat/cpp
    2298           0 :                   esn=svp_water(ttmp) ! use rhw to allow ice supersaturation
    2299           0 :                   qsn=svp_to_qsat(esn, p(i,k))
    2300           0 :                   dum=(qtmp-qsn)/(1._r8 + cons27*qsn/(cpp*rv*ttmp**2))
    2301           0 :                   dum=min(dum,0._r8)
    2302             : 
    2303             :                   ! modify rates if needed, divide by cldmax to get local (in-precip) value
    2304           0 :                   pre(k)=dum*dum1/deltat/cldmax(i,k)
    2305             : 
    2306             :                   ! do separately using RHI for prds....
    2307           0 :                   esn=svp_ice(ttmp) ! use rhi to allow ice supersaturation
    2308           0 :                   qsn=svp_to_qsat(esn, p(i,k))
    2309           0 :                   dum=(qtmp-qsn)/(1._r8 + cons28*qsn/(cpp*rv*ttmp**2))
    2310           0 :                   dum=min(dum,0._r8)
    2311             : 
    2312             :                   ! modify rates if needed, divide by cldmax to get local (in-precip) value
    2313           0 :                   prds(k)=dum*(1._r8-dum1)/deltat/cldmax(i,k)
    2314             :                end if
    2315             :             end if
    2316             :          end if
    2317             : 
    2318             :          ! bergeron process - evaporation of droplets and deposition onto snow
    2319             : 
    2320           0 :          if (qniic(i,k).ge.qsmall.and.qcic(i,k).ge.qsmall.and.t(i,k).lt.tmelt) then
    2321           0 :             qvi=svp_to_qsat(esi(i,k), p(i,k))
    2322           0 :             qvs=svp_to_qsat(esl(i,k), p(i,k))
    2323           0 :             dqsidt =  xxls*qvi/(rv*t(i,k)**2)
    2324           0 :             abi = 1._r8+dqsidt*xxls/cpp
    2325             :             epss = 2._r8*pi*n0s(k)*rho(i,k)*Dv(i,k)* &
    2326             :                  (f1s/(lams(k)*lams(k))+ &
    2327             :                  f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* &
    2328             :                  sc(i,k)**(1._r8/3._r8)*cons14/ &
    2329           0 :                  (lams(k)**(5._r8/2._r8+bs/2._r8)))
    2330           0 :             bergs(k)=epss*(qvs-qvi)/abi
    2331             :          else
    2332           0 :             bergs(k)=0._r8
    2333             :          end if
    2334             : 
    2335             :          !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    2336             :          ! conservation to ensure no negative values of cloud water/precipitation
    2337             :          ! in case microphysical process rates are large
    2338             : 
    2339             :          ! make sure and use end-of-time step values for cloud water, ice, due
    2340             :          ! condensation/deposition
    2341             : 
    2342             :          ! note: for check on conservation, processes are multiplied by omsm
    2343             :          ! to prevent problems due to round off error
    2344             : 
    2345             :          ! include mixing timescale  (mtime)
    2346             : 
    2347           0 :          qce=(qc(i,k) - berg(i,k)*deltat)
    2348           0 :          nce=(nc(i,k)+npccn(k)*deltat*mtime)
    2349           0 :          qie=(qi(i,k)+(cmei(i,k)+berg(i,k))*deltat)
    2350           0 :          nie=(ni(i,k)+nnuccd(k)*deltat*mtime)
    2351             : 
    2352             :          ! conservation of qc
    2353             : 
    2354             :          dum = (prc(k)+pra(k)+mnuccc(k)+mnucct(k)+msacwi(k)+ &
    2355           0 :               psacws(k)+bergs(k))*lcldm(i,k)*deltat
    2356             : 
    2357           0 :          if (dum.gt.qce) then
    2358           0 :             ratio = qce/deltat/lcldm(i,k)/(prc(k)+pra(k)+mnuccc(k)+mnucct(k)+msacwi(k)+psacws(k)+bergs(k))*omsm 
    2359             : 
    2360           0 :             prc(k) = prc(k)*ratio
    2361           0 :             pra(k) = pra(k)*ratio
    2362           0 :             mnuccc(k) = mnuccc(k)*ratio
    2363           0 :             mnucct(k) = mnucct(k)*ratio  
    2364           0 :             msacwi(k) = msacwi(k)*ratio  
    2365           0 :             psacws(k) = psacws(k)*ratio
    2366           0 :             bergs(k) = bergs(k)*ratio
    2367             :          end if
    2368             : 
    2369             :          ! conservation of nc
    2370             : 
    2371             :          dum = (nprc1(k)+npra(k)+nnuccc(k)+nnucct(k)+ &
    2372           0 :               npsacws(k)-nsubc(k))*lcldm(i,k)*deltat
    2373             : 
    2374           0 :          if (dum.gt.nce) then
    2375             :             ratio = nce/deltat/((nprc1(k)+npra(k)+nnuccc(k)+nnucct(k)+&
    2376           0 :                  npsacws(k)-nsubc(k))*lcldm(i,k))*omsm
    2377             : 
    2378           0 :             nprc1(k) = nprc1(k)*ratio
    2379           0 :             npra(k) = npra(k)*ratio
    2380           0 :             nnuccc(k) = nnuccc(k)*ratio
    2381           0 :             nnucct(k) = nnucct(k)*ratio  
    2382           0 :             npsacws(k) = npsacws(k)*ratio
    2383           0 :             nsubc(k)=nsubc(k)*ratio
    2384             :          end if
    2385             : 
    2386             :          ! conservation of qi
    2387             : 
    2388           0 :          if (do_cldice) then
    2389             : 
    2390           0 :             frztmp = -mnuccc(k) - mnucct(k) - msacwi(k)
    2391           0 :             if (use_hetfrz_classnuc) frztmp = -mnuccc(k)-mnucct(k)-mnudep(k)-msacwi(k)
    2392           0 :             dum = ( frztmp*lcldm(i,k) + (prci(k)+prai(k))*icldm(i,k) )*deltat
    2393             : 
    2394           0 :             if (dum.gt.qie) then
    2395             : 
    2396           0 :                frztmp = mnuccc(k) + mnucct(k) + msacwi(k)
    2397           0 :                if (use_hetfrz_classnuc) frztmp = mnuccc(k) + mnucct(k) + mnudep(k) + msacwi(k)
    2398           0 :                ratio = (qie/deltat + frztmp*lcldm(i,k))/((prci(k)+prai(k))*icldm(i,k))*omsm 
    2399           0 :                prci(k) = prci(k)*ratio
    2400           0 :                prai(k) = prai(k)*ratio
    2401             :             end if
    2402             : 
    2403             :             ! conservation of ni
    2404           0 :             frztmp = -nnucct(k) - nsacwi(k)
    2405           0 :             if (use_hetfrz_classnuc) frztmp = -nnucct(k) - nnuccc(k) - nnudep(k) - nsacwi(k)
    2406           0 :             dum = ( frztmp*lcldm(i,k) + (nprci(k)+nprai(k)-nsubi(k))*icldm(i,k) )*deltat
    2407             : 
    2408           0 :             if (dum.gt.nie) then
    2409             : 
    2410           0 :                frztmp = nnucct(k) + nsacwi(k)
    2411           0 :                if (use_hetfrz_classnuc) frztmp = nnucct(k) + nnuccc(k) + nnudep(k) + nsacwi(k)
    2412             :                ratio = (nie/deltat + frztmp*lcldm(i,k))/ &  
    2413           0 :                      ((nprci(k)+nprai(k)-nsubi(k))*icldm(i,k))*omsm
    2414           0 :                nprci(k) = nprci(k)*ratio
    2415           0 :                nprai(k) = nprai(k)*ratio
    2416           0 :                nsubi(k) = nsubi(k)*ratio
    2417             :             end if
    2418             :          end if
    2419             : 
    2420             :          ! for precipitation conservation, use logic that vertical integral 
    2421             :          ! of tendency from current level to top of model (i.e., qrtot) cannot be negative
    2422             : 
    2423             :          ! conservation of rain mixing rat
    2424             : 
    2425           0 :          if (((prc(k)+pra(k))*lcldm(i,k)+(-mnuccr(k)+pre(k)-pracs(k))*&
    2426             :               cldmax(i,k))*dz(i,k)*rho(i,k)+qrtot.lt.0._r8) then
    2427             : 
    2428           0 :             if (-pre(k)+pracs(k)+mnuccr(k).ge.qsmall) then
    2429             : 
    2430             :                ratio = (qrtot/(dz(i,k)*rho(i,k))+(prc(k)+pra(k))*lcldm(i,k))/&
    2431           0 :                     ((-pre(k)+pracs(k)+mnuccr(k))*cldmax(i,k))*omsm 
    2432             : 
    2433           0 :                pre(k) = pre(k)*ratio
    2434           0 :                pracs(k) = pracs(k)*ratio
    2435           0 :                mnuccr(k) = mnuccr(k)*ratio
    2436             :             end if
    2437             :          end if
    2438             : 
    2439             :          ! conservation of nr
    2440             :          ! for now neglect evaporation of nr
    2441           0 :          nsubr(k)=0._r8
    2442             : 
    2443           0 :          if ((nprc(k)*lcldm(i,k)+(-nnuccr(k)+nsubr(k)-npracs(k)&
    2444             :               +nragg(k))*cldmax(i,k))*dz(i,k)*rho(i,k)+nrtot.lt.0._r8) then
    2445             : 
    2446           0 :             if (-nsubr(k)-nragg(k)+npracs(k)+nnuccr(k).ge.qsmall) then
    2447             : 
    2448             :                ratio = (nrtot/(dz(i,k)*rho(i,k))+nprc(k)*lcldm(i,k))/&
    2449           0 :                     ((-nsubr(k)-nragg(k)+npracs(k)+nnuccr(k))*cldmax(i,k))*omsm
    2450             : 
    2451           0 :                nsubr(k) = nsubr(k)*ratio
    2452           0 :                npracs(k) = npracs(k)*ratio
    2453           0 :                nnuccr(k) = nnuccr(k)*ratio
    2454           0 :                nragg(k) = nragg(k)*ratio
    2455             :             end if
    2456             :          end if
    2457             : 
    2458             :          ! conservation of snow mix ratio
    2459             : 
    2460           0 :          if (((bergs(k)+psacws(k))*lcldm(i,k)+(prai(k)+prci(k))*icldm(i,k)+(pracs(k)+&
    2461             :               mnuccr(k)+prds(k))*cldmax(i,k))*dz(i,k)*rho(i,k)+qstot.lt.0._r8) then
    2462             : 
    2463           0 :             if (-prds(k).ge.qsmall) then
    2464             : 
    2465             :                ratio = (qstot/(dz(i,k)*rho(i,k))+(bergs(k)+psacws(k))*lcldm(i,k)+(prai(k)+prci(k))*icldm(i,k)+&
    2466           0 :                     (pracs(k)+mnuccr(k))*cldmax(i,k))/(-prds(k)*cldmax(i,k))*omsm
    2467             : 
    2468           0 :                prds(k) = prds(k)*ratio
    2469             :             end if
    2470             :          end if
    2471             : 
    2472             :          ! conservation of ns
    2473             : 
    2474             :          ! calculate loss of number due to sublimation
    2475             :          ! for now neglect sublimation of ns
    2476           0 :          nsubs(k)=0._r8
    2477             : 
    2478           0 :          if ((nprci(k)*icldm(i,k)+(nnuccr(k)+nsubs(k)+nsagg(k))*cldmax(i,k))*&
    2479             :               dz(i,k)*rho(i,k)+nstot.lt.0._r8) then
    2480             : 
    2481           0 :             if (-nsubs(k)-nsagg(k).ge.qsmall) then
    2482             : 
    2483             :                ratio = (nstot/(dz(i,k)*rho(i,k))+nprci(k)*icldm(i,k)+&
    2484           0 :                     nnuccr(k)*cldmax(i,k))/((-nsubs(k)-nsagg(k))*cldmax(i,k))*omsm
    2485             : 
    2486           0 :                nsubs(k) = nsubs(k)*ratio
    2487           0 :                nsagg(k) = nsagg(k)*ratio
    2488             :             end if
    2489             :          end if
    2490             : 
    2491             :          ! get tendencies due to microphysical conversion processes
    2492             :          ! note: tendencies are multiplied by appropaiate cloud/precip 
    2493             :          ! fraction to get grid-scale values
    2494             :          ! note: cmei is already grid-average values
    2495             : 
    2496           0 :          qvlat(i,k) = qvlat(i,k)-(pre(k)+prds(k))*cldmax(i,k)-cmei(i,k) 
    2497             : 
    2498             :          tlat(i,k) = tlat(i,k)+((pre(k)*cldmax(i,k)) &
    2499             :               *xxlv+(prds(k)*cldmax(i,k)+cmei(i,k))*xxls+ &
    2500             :               ((bergs(k)+psacws(k)+mnuccc(k)+mnucct(k)+msacwi(k))*lcldm(i,k)+(mnuccr(k)+ &
    2501           0 :               pracs(k))*cldmax(i,k)+berg(i,k))*xlf)
    2502             : 
    2503             :          qctend(i,k) = qctend(i,k)+ &
    2504             :               (-pra(k)-prc(k)-mnuccc(k)-mnucct(k)-msacwi(k)- & 
    2505           0 :               psacws(k)-bergs(k))*lcldm(i,k)-berg(i,k)
    2506             : 
    2507           0 :          if (do_cldice) then
    2508             : 
    2509           0 :             frztmp = mnuccc(k) + mnucct(k) + msacwi(k)
    2510           0 :             if (use_hetfrz_classnuc) frztmp = mnuccc(k) + mnucct(k) + mnudep(k) + msacwi(k)
    2511             :             qitend(i,k) = qitend(i,k) + frztmp*lcldm(i,k) + &
    2512           0 :                (-prci(k)-prai(k))*icldm(i,k) + cmei(i,k) + berg(i,k)
    2513             : 
    2514             :          end if
    2515             : 
    2516             :          qrtend(i,k) = qrtend(i,k)+ &
    2517             :               (pra(k)+prc(k))*lcldm(i,k)+(pre(k)-pracs(k)- &
    2518           0 :               mnuccr(k))*cldmax(i,k)
    2519             : 
    2520             :          qnitend(i,k) = qnitend(i,k)+ &
    2521             :               (prai(k)+prci(k))*icldm(i,k)+(psacws(k)+bergs(k))*lcldm(i,k)+(prds(k)+ &
    2522           0 :               pracs(k)+mnuccr(k))*cldmax(i,k)
    2523             : 
    2524             :          ! add output for cmei (accumulate)
    2525           0 :          cmeiout(i,k) = cmeiout(i,k) + cmei(i,k)
    2526             : 
    2527             :          ! assign variables for trop_mozart, these are grid-average
    2528             :          ! evaporation/sublimation is stored here as positive term
    2529             : 
    2530           0 :          evapsnow(i,k) = evapsnow(i,k)-prds(k)*cldmax(i,k)
    2531           0 :          nevapr(i,k) = nevapr(i,k)-pre(k)*cldmax(i,k)
    2532           0 :          nevapr2(i,k) = nevapr2(i,k)-pre(k)*cldmax(i,k)
    2533             : 
    2534             :          ! change to make sure prain is positive: do not remove snow from
    2535             :          ! prain used for wet deposition
    2536             :          prain(i,k) = prain(i,k)+(pra(k)+prc(k))*lcldm(i,k)+(-pracs(k)- &
    2537           0 :               mnuccr(k))*cldmax(i,k)
    2538             :          prodsnow(i,k) = prodsnow(i,k)+(prai(k)+prci(k))*icldm(i,k)+(psacws(k)+bergs(k))*lcldm(i,k)+(&
    2539           0 :               pracs(k)+mnuccr(k))*cldmax(i,k)
    2540             : 
    2541             :          ! following are used to calculate 1st order conversion rate of cloud water
    2542             :          !    to rain and snow (1/s), for later use in aerosol wet removal routine
    2543             :          ! previously, wetdepa used (prain/qc) for this, and the qc in wetdepa may be smaller than the qc
    2544             :          !    used to calculate pra, prc, ... in this routine
    2545             :          ! qcsinksum_rate1ord = sum over iterations{ rate of direct transfer of cloud water to rain & snow }
    2546             :          !                      (no cloud ice or bergeron terms)
    2547             :          ! qcsum_rate1ord     = sum over iterations{ qc used in calculation of the transfer terms }
    2548             : 
    2549           0 :          qcsinksum_rate1ord(k) = qcsinksum_rate1ord(k) + (pra(k)+prc(k)+psacws(k))*lcldm(i,k) 
    2550           0 :          qcsum_rate1ord(k) = qcsum_rate1ord(k) + qc(i,k) 
    2551             : 
    2552             :          ! microphysics output, note this is grid-averaged
    2553           0 :          prao(i,k)=prao(i,k)+pra(k)*lcldm(i,k)
    2554           0 :          prco(i,k)=prco(i,k)+prc(k)*lcldm(i,k)
    2555           0 :          mnuccco(i,k)=mnuccco(i,k)+mnuccc(k)*lcldm(i,k)
    2556           0 :          mnuccto(i,k)=mnuccto(i,k)+mnucct(k)*lcldm(i,k)
    2557           0 :          mnuccdo(i,k)=mnuccdo(i,k)+mnuccd(k)*lcldm(i,k)
    2558           0 :          msacwio(i,k)=msacwio(i,k)+msacwi(k)*lcldm(i,k)
    2559           0 :          psacwso(i,k)=psacwso(i,k)+psacws(k)*lcldm(i,k)
    2560           0 :          bergso(i,k)=bergso(i,k)+bergs(k)*lcldm(i,k)
    2561           0 :          bergo(i,k)=bergo(i,k)+berg(i,k)
    2562           0 :          prcio(i,k)=prcio(i,k)+prci(k)*icldm(i,k)
    2563           0 :          praio(i,k)=praio(i,k)+prai(k)*icldm(i,k)
    2564           0 :          mnuccro(i,k)=mnuccro(i,k)+mnuccr(k)*cldmax(i,k)
    2565           0 :          pracso (i,k)=pracso (i,k)+pracs (k)*cldmax(i,k)
    2566             : 
    2567             :          ! multiply activation/nucleation by mtime to account for fast timescale
    2568             : 
    2569             :          nctend(i,k) = nctend(i,k)+ npccn(k)*mtime+&
    2570             :               (-nnuccc(k)-nnucct(k)-npsacws(k)+nsubc(k) & 
    2571           0 :               -npra(k)-nprc1(k))*lcldm(i,k)      
    2572             : 
    2573           0 :          if (do_cldice) then
    2574             : 
    2575           0 :             frztmp = nnucct(k) + nsacwi(k)
    2576           0 :             if (use_hetfrz_classnuc) frztmp = nnucct(k) + nnuccc(k) + nnudep(k) + nsacwi(k)
    2577             :             nitend(i,k) = nitend(i,k) + nnuccd(k)*mtime + & 
    2578           0 :                   frztmp*lcldm(i,k) + (nsubi(k)-nprci(k)-nprai(k))*icldm(i,k)
    2579             : 
    2580             :          end if
    2581             : 
    2582             :          nstend(i,k) = nstend(i,k)+(nsubs(k)+ &
    2583           0 :               nsagg(k)+nnuccr(k))*cldmax(i,k)+nprci(k)*icldm(i,k)
    2584             : 
    2585             :          nrtend(i,k) = nrtend(i,k)+ &
    2586             :               nprc(k)*lcldm(i,k)+(nsubr(k)-npracs(k)-nnuccr(k) &
    2587           0 :               +nragg(k))*cldmax(i,k)
    2588             : 
    2589             :          ! make sure that nc and ni at advanced time step do not exceed
    2590             :          ! maximum (existing N + source terms*dt), which is possible due to
    2591             :          ! fast nucleation timescale
    2592             : 
    2593           0 :          if (nctend(i,k).gt.0._r8.and.nc(i,k)+nctend(i,k)*deltat.gt.ncmax) then
    2594           0 :             nctend(i,k)=max(0._r8,(ncmax-nc(i,k))/deltat)
    2595             :          end if
    2596             : 
    2597           0 :          if (do_cldice .and. nitend(i,k).gt.0._r8.and.ni(i,k)+nitend(i,k)*deltat.gt.nimax) then
    2598           0 :             nitend(i,k)=max(0._r8,(nimax-ni(i,k))/deltat)
    2599             :          end if
    2600             : 
    2601             :          ! get final values for precipitation q and N, based on
    2602             :          ! flux of precip from above, source/sink term, and terminal fallspeed
    2603             :          ! see eq. 15-16 in MG2008
    2604             : 
    2605             :          ! rain
    2606             : 
    2607           0 :          if (qric(i,k).ge.qsmall) then
    2608           0 :             if (k.eq.top_lev) then
    2609           0 :                qric(i,k)=qrtend(i,k)*dz(i,k)/cldmax(i,k)/umr(k)
    2610           0 :                nric(i,k)=nrtend(i,k)*dz(i,k)/cldmax(i,k)/unr(k)
    2611             :             else
    2612           0 :                qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)*cldmax(i,k-1)+ &
    2613           0 :                     (rho(i,k)*dz(i,k)*qrtend(i,k)))/(umr(k)*rho(i,k)*cldmax(i,k))
    2614             :                nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)*cldmax(i,k-1)+ &
    2615           0 :                     (rho(i,k)*dz(i,k)*nrtend(i,k)))/(unr(k)*rho(i,k)*cldmax(i,k))
    2616             : 
    2617             :             end if
    2618             :          else
    2619           0 :             qric(i,k)=0._r8
    2620           0 :             nric(i,k)=0._r8
    2621             :          end if
    2622             : 
    2623             :          ! snow
    2624             : 
    2625           0 :          if (qniic(i,k).ge.qsmall) then
    2626           0 :             if (k.eq.top_lev) then
    2627           0 :                qniic(i,k)=qnitend(i,k)*dz(i,k)/cldmax(i,k)/ums(k)
    2628           0 :                nsic(i,k)=nstend(i,k)*dz(i,k)/cldmax(i,k)/uns(k)
    2629             :             else
    2630           0 :                qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)*cldmax(i,k-1)+ &
    2631           0 :                     (rho(i,k)*dz(i,k)*qnitend(i,k)))/(ums(k)*rho(i,k)*cldmax(i,k))
    2632             :                nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)*cldmax(i,k-1)+ &
    2633           0 :                     (rho(i,k)*dz(i,k)*nstend(i,k)))/(uns(k)*rho(i,k)*cldmax(i,k))
    2634             :             end if
    2635             :          else
    2636           0 :             qniic(i,k)=0._r8
    2637           0 :             nsic(i,k)=0._r8
    2638             :          end if
    2639             : 
    2640             :          ! calculate precipitation flux at surface
    2641             :          ! divide by density of water to get units of m/s
    2642             : 
    2643             :          prect(i) = prect(i)+(qrtend(i,k)*dz(i,k)*rho(i,k)+&
    2644           0 :               qnitend(i,k)*dz(i,k)*rho(i,k))/rhow
    2645           0 :          preci(i) = preci(i)+qnitend(i,k)*dz(i,k)*rho(i,k)/rhow
    2646             : 
    2647             :          ! convert rain rate from m/s to mm/hr
    2648             : 
    2649           0 :          rainrt(i,k)=qric(i,k)*rho(i,k)*umr(k)/rhow*3600._r8*1000._r8
    2650             : 
    2651             :          ! vertically-integrated precip source/sink terms (note: grid-averaged)
    2652             : 
    2653           0 :          qrtot = max(qrtot+qrtend(i,k)*dz(i,k)*rho(i,k),0._r8)
    2654           0 :          qstot = max(qstot+qnitend(i,k)*dz(i,k)*rho(i,k),0._r8)
    2655           0 :          nrtot = max(nrtot+nrtend(i,k)*dz(i,k)*rho(i,k),0._r8)
    2656           0 :          nstot = max(nstot+nstend(i,k)*dz(i,k)*rho(i,k),0._r8)
    2657             : 
    2658             :          ! calculate melting and freezing of precip
    2659             : 
    2660             :          ! melt snow at +2 C
    2661             : 
    2662           0 :          if (t(i,k)+tlat(i,k)/cpp*deltat > 275.15_r8) then
    2663           0 :             if (qstot > 0._r8) then
    2664             : 
    2665             :                ! make sure melting snow doesn't reduce temperature below threshold
    2666           0 :                dum = -xlf/cpp*qstot/(dz(i,k)*rho(i,k))
    2667           0 :                if (t(i,k)+tlat(i,k)/cpp*deltat+dum.lt.275.15_r8) then
    2668           0 :                   dum = (t(i,k)+tlat(i,k)/cpp*deltat-275.15_r8)*cpp/xlf
    2669           0 :                   dum = dum/(xlf/cpp*qstot/(dz(i,k)*rho(i,k)))
    2670           0 :                   dum = max(0._r8,dum)
    2671           0 :                   dum = min(1._r8,dum)
    2672             :                else
    2673             :                   dum = 1._r8
    2674             :                end if
    2675             : 
    2676           0 :                qric(i,k)=qric(i,k)+dum*qniic(i,k)
    2677           0 :                nric(i,k)=nric(i,k)+dum*nsic(i,k)
    2678           0 :                qniic(i,k)=(1._r8-dum)*qniic(i,k)
    2679           0 :                nsic(i,k)=(1._r8-dum)*nsic(i,k)
    2680             :                ! heating tendency 
    2681           0 :                tmp=-xlf*dum*qstot/(dz(i,k)*rho(i,k))
    2682           0 :                meltsdt(i,k)=meltsdt(i,k) + tmp
    2683             : 
    2684           0 :                tlat(i,k)=tlat(i,k)+tmp
    2685           0 :                qrtot=qrtot+dum*qstot
    2686           0 :                nrtot=nrtot+dum*nstot
    2687           0 :                qstot=(1._r8-dum)*qstot
    2688           0 :                nstot=(1._r8-dum)*nstot
    2689           0 :                preci(i)=(1._r8-dum)*preci(i)
    2690             :             end if
    2691             :          end if
    2692             : 
    2693             :          ! freeze all rain at -5C for Arctic
    2694             : 
    2695           0 :          if (t(i,k)+tlat(i,k)/cpp*deltat < (tmelt - 5._r8)) then
    2696             : 
    2697           0 :             if (qrtot > 0._r8) then
    2698             : 
    2699             :                ! make sure freezing rain doesn't increase temperature above threshold
    2700           0 :                dum = xlf/cpp*qrtot/(dz(i,k)*rho(i,k))
    2701           0 :                if (t(i,k)+tlat(i,k)/cpp*deltat+dum.gt.(tmelt - 5._r8)) then
    2702           0 :                   dum = -(t(i,k)+tlat(i,k)/cpp*deltat-(tmelt-5._r8))*cpp/xlf
    2703           0 :                   dum = dum/(xlf/cpp*qrtot/(dz(i,k)*rho(i,k)))
    2704           0 :                   dum = max(0._r8,dum)
    2705           0 :                   dum = min(1._r8,dum)
    2706             :                else
    2707             :                   dum = 1._r8
    2708             :                end if
    2709             : 
    2710           0 :                qniic(i,k)=qniic(i,k)+dum*qric(i,k)
    2711           0 :                nsic(i,k)=nsic(i,k)+dum*nric(i,k)
    2712           0 :                qric(i,k)=(1._r8-dum)*qric(i,k)
    2713           0 :                nric(i,k)=(1._r8-dum)*nric(i,k)
    2714             :                ! heating tendency 
    2715           0 :                tmp = xlf*dum*qrtot/(dz(i,k)*rho(i,k))
    2716           0 :                frzrdt(i,k)=frzrdt(i,k) + tmp
    2717             : 
    2718           0 :                tlat(i,k)=tlat(i,k)+tmp
    2719           0 :                qstot=qstot+dum*qrtot
    2720           0 :                qrtot=(1._r8-dum)*qrtot
    2721           0 :                nstot=nstot+dum*nrtot
    2722           0 :                nrtot=(1._r8-dum)*nrtot
    2723           0 :                preci(i)=preci(i)+dum*(prect(i)-preci(i))
    2724             :             end if
    2725             :          end if
    2726             : 
    2727             :          ! Precip Flux Calculation (Diagnostic)
    2728           0 :          rflx(i,k+1)=(prect(i)-preci(i)) * rhow
    2729           0 :          sflx(i,k+1)=preci(i) * rhow
    2730             : 
    2731             :          ! if rain/snow mix ratio is zero so should number concentration
    2732             : 
    2733           0 :          if (qniic(i,k).lt.qsmall) then
    2734           0 :             qniic(i,k)=0._r8
    2735           0 :             nsic(i,k)=0._r8
    2736             :          end if
    2737             : 
    2738           0 :          if (qric(i,k).lt.qsmall) then
    2739           0 :             qric(i,k)=0._r8
    2740           0 :             nric(i,k)=0._r8
    2741             :          end if
    2742             : 
    2743             :          ! make sure number concentration is a positive number to avoid 
    2744             :          ! taking root of negative
    2745             : 
    2746           0 :          nric(i,k)=max(nric(i,k),0._r8)
    2747           0 :          nsic(i,k)=max(nsic(i,k),0._r8)
    2748             : 
    2749             :          !.......................................................................
    2750             :          ! get size distribution parameters for fallspeed calculations
    2751             :          !......................................................................
    2752             :          ! rain
    2753             : 
    2754           0 :          if (qric(i,k).ge.qsmall) then
    2755           0 :             lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))**(1._r8/3._r8)
    2756           0 :             n0r(k) = nric(i,k)*lamr(k)
    2757             : 
    2758             :             ! check for slope
    2759             :             ! change lammax and lammin for rain and snow
    2760             :             ! adjust vars
    2761             : 
    2762           0 :             if (lamr(k).lt.lamminr) then
    2763             : 
    2764           0 :                lamr(k) = lamminr
    2765             : 
    2766           0 :                n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow)
    2767           0 :                nric(i,k) = n0r(k)/lamr(k)
    2768           0 :             else if (lamr(k).gt.lammaxr) then
    2769           0 :                lamr(k) = lammaxr
    2770           0 :                n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow)
    2771           0 :                nric(i,k) = n0r(k)/lamr(k)
    2772             :             end if
    2773             : 
    2774             : 
    2775             :             ! 'final' values of number and mass weighted mean fallspeed for rain (m/s)
    2776             : 
    2777           0 :             unr(k) = min(arn(i,k)*cons4/lamr(k)**br,9.1_r8*rhof(i,k))
    2778           0 :             umr(k) = min(arn(i,k)*cons5/(6._r8*lamr(k)**br),9.1_r8*rhof(i,k))
    2779             : 
    2780             :          else
    2781           0 :             lamr(k) = 0._r8
    2782           0 :             n0r(k) = 0._r8
    2783           0 :             umr(k)=0._r8
    2784           0 :             unr(k)=0._r8
    2785             :          end if
    2786             : 
    2787             :          !calculate mean size of combined rain and snow
    2788             : 
    2789           0 :          if (lamr(k).gt.0._r8) then
    2790           0 :             Artmp = n0r(k) * pi / (2._r8 * lamr(k)**3._r8)
    2791             :          else 
    2792             :             Artmp = 0._r8
    2793             :          endif
    2794             : 
    2795           0 :          if (lamc(k).gt.0._r8) then
    2796           0 :             Actmp = cdist1(k) * pi * gamma(pgam(k)+3._r8)/(4._r8 * lamc(k)**2._r8)
    2797             :          else 
    2798             :             Actmp = 0._r8
    2799             :          endif
    2800             : 
    2801           0 :          if (Actmp.gt.0_r8.or.Artmp.gt.0) then
    2802           0 :             rercld(i,k)=rercld(i,k) + 3._r8 *(qric(i,k) + qcic(i,k)) / (4._r8 * rhow * (Actmp + Artmp))
    2803           0 :             arcld(i,k)=arcld(i,k)+1._r8
    2804             :          endif
    2805             : 
    2806             :          !......................................................................
    2807             :          ! snow
    2808             : 
    2809           0 :          if (qniic(i,k).ge.qsmall) then
    2810             :             lams(k) = (cons6*cs*nsic(i,k)/ &
    2811           0 :                  qniic(i,k))**(1._r8/ds)
    2812           0 :             n0s(k) = nsic(i,k)*lams(k)
    2813             : 
    2814             :             ! check for slope
    2815             :             ! adjust vars
    2816             : 
    2817           0 :             if (lams(k).lt.lammins) then
    2818           0 :                lams(k) = lammins
    2819           0 :                n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6)
    2820           0 :                nsic(i,k) = n0s(k)/lams(k)
    2821             : 
    2822           0 :             else if (lams(k).gt.lammaxs) then
    2823           0 :                lams(k) = lammaxs
    2824           0 :                n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6)
    2825           0 :                nsic(i,k) = n0s(k)/lams(k)
    2826             :             end if
    2827             : 
    2828             :             ! 'final' values of number and mass weighted mean fallspeed for snow (m/s)
    2829             : 
    2830           0 :             ums(k) = min(asn(i,k)*cons8/(6._r8*lams(k)**bs),1.2_r8*rhof(i,k))
    2831           0 :             uns(k) = min(asn(i,k)*cons7/lams(k)**bs,1.2_r8*rhof(i,k))
    2832             : 
    2833             :          else
    2834           0 :             lams(k) = 0._r8
    2835           0 :             n0s(k) = 0._r8
    2836           0 :             ums(k) = 0._r8
    2837           0 :             uns(k) = 0._r8
    2838             :          end if
    2839             : 
    2840             :          !c........................................................................
    2841             :          ! sum over sub-step for average process rates
    2842             : 
    2843             :          ! convert rain/snow q and N for output to history, note, 
    2844             :          ! output is for gridbox average
    2845             : 
    2846           0 :          qrout(i,k)=qrout(i,k)+qric(i,k)*cldmax(i,k)
    2847           0 :          qsout(i,k)=qsout(i,k)+qniic(i,k)*cldmax(i,k)
    2848           0 :          nrout(i,k)=nrout(i,k)+nric(i,k)*rho(i,k)*cldmax(i,k)
    2849           0 :          nsout(i,k)=nsout(i,k)+nsic(i,k)*rho(i,k)*cldmax(i,k)
    2850             : 
    2851           0 :          tlat1(i,k)=tlat1(i,k)+tlat(i,k)
    2852           0 :          qvlat1(i,k)=qvlat1(i,k)+qvlat(i,k)
    2853           0 :          qctend1(i,k)=qctend1(i,k)+qctend(i,k)
    2854           0 :          qitend1(i,k)=qitend1(i,k)+qitend(i,k)
    2855           0 :          nctend1(i,k)=nctend1(i,k)+nctend(i,k)
    2856           0 :          nitend1(i,k)=nitend1(i,k)+nitend(i,k)
    2857             : 
    2858           0 :          t(i,k)=t(i,k)+tlat(i,k)*deltat/cpp
    2859           0 :          q(i,k)=q(i,k)+qvlat(i,k)*deltat
    2860           0 :          qc(i,k)=qc(i,k)+qctend(i,k)*deltat
    2861           0 :          qi(i,k)=qi(i,k)+qitend(i,k)*deltat
    2862           0 :          nc(i,k)=nc(i,k)+nctend(i,k)*deltat
    2863           0 :          ni(i,k)=ni(i,k)+nitend(i,k)*deltat
    2864             : 
    2865           0 :          rainrt1(i,k)=rainrt1(i,k)+rainrt(i,k)
    2866             : 
    2867             :          !divide rain radius over substeps for average
    2868           0 :          if (arcld(i,k) .gt. 0._r8) then
    2869           0 :             rercld(i,k)=rercld(i,k)/arcld(i,k)
    2870             :          end if
    2871             : 
    2872             :          !! add to summing sub-stepping variable
    2873           0 :          rflx1(i,k+1)=rflx1(i,k+1)+rflx(i,k+1)
    2874           0 :          sflx1(i,k+1)=sflx1(i,k+1)+sflx(i,k+1)
    2875             : 
    2876             :          !c........................................................................
    2877             : 
    2878             :       end do ! k loop
    2879             : 
    2880           0 :       prect1(i)=prect1(i)+prect(i)
    2881           0 :       preci1(i)=preci1(i)+preci(i)
    2882             : 
    2883             :    end do ! it loop, sub-step
    2884             : 
    2885           0 :    do k = top_lev, pver
    2886           0 :       rate1ord_cw2pr_st(i,k) = qcsinksum_rate1ord(k)/max(qcsum_rate1ord(k),1.0e-30_r8) 
    2887             :    end do
    2888             : 
    2889           0 : 300 continue  ! continue if no cloud water
    2890             : end do ! i loop
    2891             : 
    2892             : ! convert dt from sub-step back to full time step
    2893           0 : deltat=deltat*real(iter)
    2894             : 
    2895             : !c.............................................................................
    2896             : 
    2897           0 : do i=1,ncol
    2898             : 
    2899             :    ! skip all calculations if no cloud water
    2900           0 :    if (ltrue(i).eq.0) then
    2901             : 
    2902           0 :       do k=1,top_lev-1
    2903             :          ! assign zero values for effective radius above 1 mbar
    2904           0 :          effc(i,k)=0._r8
    2905           0 :          effi(i,k)=0._r8
    2906           0 :          effc_fn(i,k)=0._r8
    2907           0 :          lamcrad(i,k)=0._r8
    2908           0 :          pgamrad(i,k)=0._r8
    2909           0 :          deffi(i,k)=0._r8
    2910             :       end do
    2911             : 
    2912           0 :       do k=top_lev,pver
    2913             :          ! assign default values for effective radius
    2914           0 :          effc(i,k)=10._r8
    2915           0 :          effi(i,k)=25._r8
    2916           0 :          effc_fn(i,k)=10._r8
    2917           0 :          lamcrad(i,k)=0._r8
    2918           0 :          pgamrad(i,k)=0._r8
    2919           0 :          deffi(i,k)=0._r8
    2920             :       end do
    2921             :       goto 500
    2922             :    end if
    2923             : 
    2924             :    ! initialize nstep for sedimentation sub-steps
    2925           0 :    nstep = 1
    2926             : 
    2927             :    ! divide precip rate by number of sub-steps to get average over time step
    2928             : 
    2929           0 :    prect(i)=prect1(i)/real(iter)
    2930           0 :    preci(i)=preci1(i)/real(iter)
    2931             : 
    2932           0 :    do k=top_lev,pver
    2933             : 
    2934             :       ! assign variables back to start-of-timestep values before updating after sub-steps 
    2935             : 
    2936           0 :       t(i,k)=t1(i,k)
    2937           0 :       q(i,k)=q1(i,k)
    2938           0 :       qc(i,k)=qc1(i,k)
    2939           0 :       qi(i,k)=qi1(i,k)
    2940           0 :       nc(i,k)=nc1(i,k)
    2941           0 :       ni(i,k)=ni1(i,k)
    2942             : 
    2943             :       ! divide microphysical tendencies by number of sub-steps to get average over time step
    2944             : 
    2945           0 :       tlat(i,k)=tlat1(i,k)/real(iter)
    2946           0 :       qvlat(i,k)=qvlat1(i,k)/real(iter)
    2947           0 :       qctend(i,k)=qctend1(i,k)/real(iter)
    2948           0 :       qitend(i,k)=qitend1(i,k)/real(iter)
    2949           0 :       nctend(i,k)=nctend1(i,k)/real(iter)
    2950           0 :       nitend(i,k)=nitend1(i,k)/real(iter)
    2951             : 
    2952           0 :       rainrt(i,k)=rainrt1(i,k)/real(iter)
    2953             : 
    2954             :       ! divide by number of sub-steps to find final values
    2955           0 :       rflx(i,k+1)=rflx1(i,k+1)/real(iter)
    2956           0 :       sflx(i,k+1)=sflx1(i,k+1)/real(iter)
    2957             : 
    2958             :       ! divide output precip q and N by number of sub-steps to get average over time step
    2959             : 
    2960           0 :       qrout(i,k)=qrout(i,k)/real(iter)
    2961           0 :       qsout(i,k)=qsout(i,k)/real(iter)
    2962           0 :       nrout(i,k)=nrout(i,k)/real(iter)
    2963           0 :       nsout(i,k)=nsout(i,k)/real(iter)
    2964             : 
    2965             :       ! divide trop_mozart variables by number of sub-steps to get average over time step 
    2966             : 
    2967           0 :       nevapr(i,k) = nevapr(i,k)/real(iter)
    2968           0 :       nevapr2(i,k) = nevapr2(i,k)/real(iter)
    2969           0 :       evapsnow(i,k) = evapsnow(i,k)/real(iter)
    2970           0 :       prain(i,k) = prain(i,k)/real(iter)
    2971           0 :       prodsnow(i,k) = prodsnow(i,k)/real(iter)
    2972           0 :       cmeout(i,k) = cmeout(i,k)/real(iter)
    2973             : 
    2974           0 :       cmeiout(i,k) = cmeiout(i,k)/real(iter)
    2975           0 :       meltsdt(i,k) = meltsdt(i,k)/real(iter)
    2976           0 :       frzrdt (i,k) = frzrdt (i,k)/real(iter)
    2977             : 
    2978             : 
    2979             :       ! microphysics output
    2980           0 :       prao(i,k)=prao(i,k)/real(iter)
    2981           0 :       prco(i,k)=prco(i,k)/real(iter)
    2982           0 :       mnuccco(i,k)=mnuccco(i,k)/real(iter)
    2983           0 :       mnuccto(i,k)=mnuccto(i,k)/real(iter)
    2984           0 :       msacwio(i,k)=msacwio(i,k)/real(iter)
    2985           0 :       psacwso(i,k)=psacwso(i,k)/real(iter)
    2986           0 :       bergso(i,k)=bergso(i,k)/real(iter)
    2987           0 :       bergo(i,k)=bergo(i,k)/real(iter)
    2988           0 :       prcio(i,k)=prcio(i,k)/real(iter)
    2989           0 :       praio(i,k)=praio(i,k)/real(iter)
    2990             : 
    2991           0 :       mnuccro(i,k)=mnuccro(i,k)/real(iter)
    2992           0 :       pracso (i,k)=pracso (i,k)/real(iter)
    2993             : 
    2994           0 :       mnuccdo(i,k)=mnuccdo(i,k)/real(iter)
    2995             : 
    2996             :       ! modify to include snow. in prain & evap (diagnostic here: for wet dep)
    2997           0 :       nevapr(i,k) = nevapr(i,k) + evapsnow(i,k)
    2998           0 :       prer_evap(i,k) = nevapr2(i,k)
    2999           0 :       prain(i,k) = prain(i,k) + prodsnow(i,k)
    3000             : 
    3001             :       !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    3002             :       ! calculate sedimentation for cloud water and ice
    3003             :       !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    3004             : 
    3005             :       ! update in-cloud cloud mixing ratio and number concentration 
    3006             :       ! with microphysical tendencies to calculate sedimentation, assign to dummy vars
    3007             :       ! note: these are in-cloud values***, hence we divide by cloud fraction
    3008             : 
    3009           0 :       dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat)/lcldm(i,k)
    3010           0 :       dumi(i,k) = (qi(i,k)+qitend(i,k)*deltat)/icldm(i,k)
    3011           0 :       dumnc(i,k) = max((nc(i,k)+nctend(i,k)*deltat)/lcldm(i,k),0._r8)
    3012           0 :       dumni(i,k) = max((ni(i,k)+nitend(i,k)*deltat)/icldm(i,k),0._r8)
    3013             : 
    3014           0 :       if (nccons) then
    3015           0 :         dumnc(i,k) = ncnst/rho(i,k)
    3016             :       end if
    3017           0 :       if (nicons) then
    3018           0 :         dumni(i,k) = ninst/rho(i,k)   
    3019             :       end if
    3020             : 
    3021             :       ! obtain new slope parameter to avoid possible singularity
    3022             : 
    3023           0 :       if (dumi(i,k).ge.qsmall) then
    3024             :          ! add upper limit to in-cloud number concentration to prevent numerical error
    3025           0 :          dumni(i,k)=min(dumni(i,k),dumi(i,k)*1.e20_r8)
    3026             : 
    3027             :          lami(k) = (cons1*ci* &
    3028           0 :               dumni(i,k)/dumi(i,k))**(1._r8/di)
    3029           0 :          lami(k)=max(lami(k),lammini)
    3030           0 :          lami(k)=min(lami(k),lammaxi)
    3031             :       else
    3032           0 :          lami(k)=0._r8
    3033             :       end if
    3034             : 
    3035           0 :       if (dumc(i,k).ge.qsmall) then
    3036             :          ! add upper limit to in-cloud number concentration to prevent numerical error
    3037           0 :          dumnc(i,k)=min(dumnc(i,k),dumc(i,k)*1.e20_r8)
    3038             :          ! add lower limit to in-cloud number concentration
    3039           0 :          dumnc(i,k)=max(dumnc(i,k),cdnl/rho(i,k)) ! sghan minimum in #/cm3 
    3040           0 :          pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8
    3041           0 :          pgam(k)=1._r8/(pgam(k)**2)-1._r8
    3042           0 :          pgam(k)=max(pgam(k),2._r8)
    3043           0 :          pgam(k)=min(pgam(k),15._r8)
    3044             : 
    3045             :          lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k)+4._r8)/ &
    3046           0 :               (dumc(i,k)*gamma(pgam(k)+1._r8)))**(1._r8/3._r8)
    3047           0 :          lammin = (pgam(k)+1._r8)/50.e-6_r8
    3048           0 :          lammax = (pgam(k)+1._r8)/2.e-6_r8
    3049           0 :          lamc(k)=max(lamc(k),lammin)
    3050           0 :          lamc(k)=min(lamc(k),lammax)
    3051             :       else
    3052           0 :          lamc(k)=0._r8
    3053             :       end if
    3054             : 
    3055             :       ! calculate number and mass weighted fall velocity for droplets
    3056             :       ! include effects of sub-grid distribution of cloud water
    3057             : 
    3058             : 
    3059           0 :       if (dumc(i,k).ge.qsmall) then
    3060           0 :          unc = acn(i,k)*gamma(1._r8+bc+pgam(k))/(lamc(k)**bc*gamma(pgam(k)+1._r8))
    3061           0 :          umc = acn(i,k)*gamma(4._r8+bc+pgam(k))/(lamc(k)**bc*gamma(pgam(k)+4._r8))
    3062             :          ! fallspeed for output
    3063           0 :          vtrmc(i,k)=umc
    3064             :       else
    3065             :          umc = 0._r8
    3066             :          unc = 0._r8
    3067             :       end if
    3068             : 
    3069             :       ! calculate number and mass weighted fall velocity for cloud ice
    3070             : 
    3071           0 :       if (dumi(i,k).ge.qsmall) then
    3072           0 :          uni =  ain(i,k)*cons16/lami(k)**bi
    3073           0 :          umi = ain(i,k)*cons17/(6._r8*lami(k)**bi)
    3074           0 :          uni=min(uni,1.2_r8*rhof(i,k))
    3075           0 :          umi=min(umi,1.2_r8*rhof(i,k))
    3076             : 
    3077             :          ! fallspeed
    3078           0 :          vtrmi(i,k)=umi
    3079             :       else
    3080             :          umi = 0._r8
    3081             :          uni = 0._r8
    3082             :       end if
    3083             : 
    3084           0 :       fi(k) = g*rho(i,k)*umi
    3085           0 :       fni(k) = g*rho(i,k)*uni
    3086           0 :       fc(k) = g*rho(i,k)*umc
    3087           0 :       fnc(k) = g*rho(i,k)*unc
    3088             : 
    3089             :       ! calculate number of split time steps to ensure courant stability criteria
    3090             :       ! for sedimentation calculations
    3091             : 
    3092           0 :       rgvm = max(fi(k),fc(k),fni(k),fnc(k))
    3093           0 :       nstep = max(int(rgvm*deltat/pdel(i,k)+1._r8),nstep)
    3094             : 
    3095             :       ! redefine dummy variables - sedimentation is calculated over grid-scale
    3096             :       ! quantities to ensure conservation
    3097             : 
    3098           0 :       dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat)
    3099           0 :       dumi(i,k) = (qi(i,k)+qitend(i,k)*deltat)
    3100           0 :       dumnc(i,k) = max((nc(i,k)+nctend(i,k)*deltat),0._r8)
    3101           0 :       dumni(i,k) = max((ni(i,k)+nitend(i,k)*deltat),0._r8)
    3102             : 
    3103           0 :       if (dumc(i,k).lt.qsmall) dumnc(i,k)=0._r8
    3104           0 :       if (dumi(i,k).lt.qsmall) dumni(i,k)=0._r8
    3105             : 
    3106             :    end do       !!! vertical loop
    3107           0 :    do n = 1,nstep  !! loop over sub-time step to ensure stability
    3108             : 
    3109           0 :       do k = top_lev,pver
    3110           0 :          if (do_cldice) then
    3111           0 :             falouti(k) = fi(k)*dumi(i,k)
    3112           0 :             faloutni(k) = fni(k)*dumni(i,k)
    3113             :          else
    3114           0 :             falouti(k)  = 0._r8
    3115           0 :             faloutni(k) = 0._r8
    3116             :          end if
    3117             : 
    3118           0 :          faloutc(k) = fc(k)*dumc(i,k)
    3119           0 :          faloutnc(k) = fnc(k)*dumnc(i,k)
    3120             :       end do
    3121             : 
    3122             :       ! top of model
    3123             : 
    3124           0 :       k = top_lev
    3125           0 :       faltndi = falouti(k)/pdel(i,k)
    3126           0 :       faltndni = faloutni(k)/pdel(i,k)
    3127           0 :       faltndc = faloutc(k)/pdel(i,k)
    3128           0 :       faltndnc = faloutnc(k)/pdel(i,k)
    3129             : 
    3130             :       ! add fallout terms to microphysical tendencies
    3131             : 
    3132           0 :       qitend(i,k) = qitend(i,k)-faltndi/nstep
    3133           0 :       nitend(i,k) = nitend(i,k)-faltndni/nstep
    3134           0 :       qctend(i,k) = qctend(i,k)-faltndc/nstep
    3135           0 :       nctend(i,k) = nctend(i,k)-faltndnc/nstep
    3136             : 
    3137             :       ! sedimentation tendencies for output
    3138           0 :       qcsedten(i,k)=qcsedten(i,k)-faltndc/nstep
    3139           0 :       qisedten(i,k)=qisedten(i,k)-faltndi/nstep
    3140             : 
    3141           0 :       dumi(i,k) = dumi(i,k)-faltndi*deltat/nstep
    3142           0 :       dumni(i,k) = dumni(i,k)-faltndni*deltat/nstep
    3143           0 :       dumc(i,k) = dumc(i,k)-faltndc*deltat/nstep
    3144           0 :       dumnc(i,k) = dumnc(i,k)-faltndnc*deltat/nstep
    3145             : 
    3146           0 :       do k = top_lev+1,pver
    3147             : 
    3148             :          ! for cloud liquid and ice, if cloud fraction increases with height
    3149             :          ! then add flux from above to both vapor and cloud water of current level
    3150             :          ! this means that flux entering clear portion of cell from above evaporates
    3151             :          ! instantly
    3152             : 
    3153           0 :          dum=lcldm(i,k)/lcldm(i,k-1)
    3154           0 :          dum=min(dum,1._r8)
    3155           0 :          dum1=icldm(i,k)/icldm(i,k-1)
    3156           0 :          dum1=min(dum1,1._r8)
    3157             : 
    3158           0 :          faltndqie=(falouti(k)-falouti(k-1))/pdel(i,k)
    3159           0 :          faltndi=(falouti(k)-dum1*falouti(k-1))/pdel(i,k)
    3160           0 :          faltndni=(faloutni(k)-dum1*faloutni(k-1))/pdel(i,k)
    3161           0 :          faltndqce=(faloutc(k)-faloutc(k-1))/pdel(i,k)
    3162           0 :          faltndc=(faloutc(k)-dum*faloutc(k-1))/pdel(i,k)
    3163           0 :          faltndnc=(faloutnc(k)-dum*faloutnc(k-1))/pdel(i,k)
    3164             : 
    3165             :          ! add fallout terms to eulerian tendencies
    3166             : 
    3167           0 :          qitend(i,k) = qitend(i,k)-faltndi/nstep
    3168           0 :          nitend(i,k) = nitend(i,k)-faltndni/nstep
    3169           0 :          qctend(i,k) = qctend(i,k)-faltndc/nstep
    3170           0 :          nctend(i,k) = nctend(i,k)-faltndnc/nstep
    3171             : 
    3172             :          ! sedimentation tendencies for output
    3173           0 :          qcsedten(i,k)=qcsedten(i,k)-faltndc/nstep
    3174           0 :          qisedten(i,k)=qisedten(i,k)-faltndi/nstep
    3175             : 
    3176             :          ! add terms to to evap/sub of cloud water
    3177             : 
    3178           0 :          qvlat(i,k)=qvlat(i,k)-(faltndqie-faltndi)/nstep
    3179             :          ! for output
    3180           0 :          qisevap(i,k)=qisevap(i,k)-(faltndqie-faltndi)/nstep
    3181           0 :          qvlat(i,k)=qvlat(i,k)-(faltndqce-faltndc)/nstep
    3182             :          ! for output
    3183           0 :          qcsevap(i,k)=qcsevap(i,k)-(faltndqce-faltndc)/nstep
    3184             : 
    3185           0 :          tlat(i,k)=tlat(i,k)+(faltndqie-faltndi)*xxls/nstep
    3186           0 :          tlat(i,k)=tlat(i,k)+(faltndqce-faltndc)*xxlv/nstep
    3187             : 
    3188           0 :          dumi(i,k) = dumi(i,k)-faltndi*deltat/nstep
    3189           0 :          dumni(i,k) = dumni(i,k)-faltndni*deltat/nstep
    3190           0 :          dumc(i,k) = dumc(i,k)-faltndc*deltat/nstep
    3191           0 :          dumnc(i,k) = dumnc(i,k)-faltndnc*deltat/nstep
    3192             : 
    3193           0 :          Fni(K)=MAX(Fni(K)/pdel(i,K),Fni(K-1)/pdel(i,K-1))*pdel(i,K)
    3194           0 :          FI(K)=MAX(FI(K)/pdel(i,K),FI(K-1)/pdel(i,K-1))*pdel(i,K)
    3195           0 :          fnc(k)=max(fnc(k)/pdel(i,k),fnc(k-1)/pdel(i,k-1))*pdel(i,k)
    3196           0 :          Fc(K)=MAX(Fc(K)/pdel(i,K),Fc(K-1)/pdel(i,K-1))*pdel(i,K)
    3197             : 
    3198             :       end do   !! k loop
    3199             : 
    3200             :       ! units below are m/s
    3201             :       ! cloud water/ice sedimentation flux at surface 
    3202             :       ! is added to precip flux at surface to get total precip (cloud + precip water)
    3203             :       ! rate
    3204             : 
    3205           0 :       prect(i) = prect(i)+(faloutc(pver)+falouti(pver))/g/nstep/1000._r8  
    3206           0 :       preci(i) = preci(i)+(falouti(pver))/g/nstep/1000._r8
    3207             : 
    3208             :       ! Add fallout to Precip Flux: note unit change m/s *kg/m3 = kg/m2
    3209           0 :       do k = top_lev,pver
    3210           0 :          rflx(i,k+1)=rflx(i,k+1)+(faloutc(k))/g/nstep/1000._r8 * rhow
    3211           0 :          sflx(i,k+1)=sflx(i,k+1)+(falouti(k))/g/nstep/1000._r8 * rhow
    3212             :       end do
    3213             : 
    3214             :    end do   !! nstep loop
    3215             : 
    3216             :    ! end sedimentation
    3217             :    !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    3218             : 
    3219             :    ! get new update for variables that includes sedimentation tendency
    3220             :    ! note : here dum variables are grid-average, NOT in-cloud
    3221             : 
    3222           0 :    do k=top_lev,pver
    3223             : 
    3224           0 :       dumc(i,k) = max(qc(i,k)+qctend(i,k)*deltat,0._r8)
    3225           0 :       dumi(i,k) = max(qi(i,k)+qitend(i,k)*deltat,0._r8)
    3226           0 :       dumnc(i,k) = max(nc(i,k)+nctend(i,k)*deltat,0._r8)
    3227           0 :       dumni(i,k) = max(ni(i,k)+nitend(i,k)*deltat,0._r8)
    3228             : 
    3229           0 :       if (nccons) then
    3230           0 :         dumnc(i,k) = ncnst/rho(i,k)*lcldm(i,k)
    3231             :       end if
    3232           0 :       if (nicons) then
    3233           0 :         dumni(i,k) = ninst/rho(i,k)*icldm(i,k)
    3234             :       end if
    3235             : 
    3236           0 :       if (dumc(i,k).lt.qsmall) dumnc(i,k)=0._r8
    3237           0 :       if (dumi(i,k).lt.qsmall) dumni(i,k)=0._r8
    3238             : 
    3239             :       ! calculate instantaneous processes (melting, homogeneous freezing)
    3240           0 :       if (do_cldice) then
    3241             : 
    3242           0 :          if (t(i,k)+tlat(i,k)/cpp*deltat > tmelt) then
    3243           0 :             if (dumi(i,k) > 0._r8) then
    3244             : 
    3245             :                ! limit so that melting does not push temperature below freezing
    3246           0 :                dum = -dumi(i,k)*xlf/cpp
    3247           0 :                if (t(i,k)+tlat(i,k)/cpp*deltat+dum.lt.tmelt) then
    3248           0 :                   dum = (t(i,k)+tlat(i,k)/cpp*deltat-tmelt)*cpp/xlf
    3249           0 :                   dum = dum/dumi(i,k)*xlf/cpp 
    3250           0 :                   dum = max(0._r8,dum)
    3251           0 :                   dum = min(1._r8,dum)
    3252             :                else
    3253             :                   dum = 1._r8
    3254             :                end if
    3255             : 
    3256           0 :                qctend(i,k)=qctend(i,k)+dum*dumi(i,k)/deltat
    3257             : 
    3258             :                ! for output
    3259           0 :                melto(i,k)=dum*dumi(i,k)/deltat
    3260             : 
    3261             :                ! assume melting ice produces droplet
    3262             :                ! mean volume radius of 8 micron
    3263             : 
    3264             :                nctend(i,k)=nctend(i,k)+3._r8*dum*dumi(i,k)/deltat/ &
    3265           0 :                     (4._r8*pi*5.12e-16_r8*rhow)
    3266             : 
    3267           0 :                qitend(i,k)=((1._r8-dum)*dumi(i,k)-qi(i,k))/deltat
    3268           0 :                nitend(i,k)=((1._r8-dum)*dumni(i,k)-ni(i,k))/deltat
    3269           0 :                tlat(i,k)=tlat(i,k)-xlf*dum*dumi(i,k)/deltat
    3270             :             end if
    3271             :          end if
    3272             : 
    3273             :          ! homogeneously freeze droplets at -40 C
    3274             : 
    3275           0 :          if (t(i,k)+tlat(i,k)/cpp*deltat < 233.15_r8) then
    3276           0 :             if (dumc(i,k) > 0._r8) then
    3277             : 
    3278             :                ! limit so that freezing does not push temperature above threshold
    3279           0 :                dum = dumc(i,k)*xlf/cpp
    3280           0 :                if (t(i,k)+tlat(i,k)/cpp*deltat+dum.gt.233.15_r8) then
    3281           0 :                   dum = -(t(i,k)+tlat(i,k)/cpp*deltat-233.15_r8)*cpp/xlf
    3282           0 :                   dum = dum/dumc(i,k)*xlf/cpp
    3283           0 :                   dum = max(0._r8,dum)
    3284           0 :                   dum = min(1._r8,dum)
    3285             :                else
    3286             :                   dum = 1._r8
    3287             :                end if
    3288             : 
    3289           0 :                qitend(i,k)=qitend(i,k)+dum*dumc(i,k)/deltat
    3290             :                ! for output
    3291           0 :                homoo(i,k)=dum*dumc(i,k)/deltat
    3292             : 
    3293             :                ! assume 25 micron mean volume radius of homogeneously frozen droplets
    3294             :                ! consistent with size of detrained ice in stratiform.F90
    3295             :                nitend(i,k)=nitend(i,k)+dum*3._r8*dumc(i,k)/(4._r8*3.14_r8*1.563e-14_r8* &
    3296           0 :                     500._r8)/deltat
    3297           0 :                qctend(i,k)=((1._r8-dum)*dumc(i,k)-qc(i,k))/deltat
    3298           0 :                nctend(i,k)=((1._r8-dum)*dumnc(i,k)-nc(i,k))/deltat
    3299           0 :                tlat(i,k)=tlat(i,k)+xlf*dum*dumc(i,k)/deltat
    3300             :             end if
    3301             :          end if
    3302             : 
    3303             :          ! remove any excess over-saturation, which is possible due to non-linearity when adding 
    3304             :          ! together all microphysical processes
    3305             :          ! follow code similar to old CAM scheme
    3306             : 
    3307           0 :          qtmp=q(i,k)+qvlat(i,k)*deltat
    3308           0 :          ttmp=t(i,k)+tlat(i,k)/cpp*deltat
    3309             : 
    3310           0 :          esn = svp_water(ttmp)  ! use rhw to allow ice supersaturation
    3311           0 :          qsn = svp_to_qsat(esn, p(i,k))
    3312             : 
    3313           0 :          if (qtmp > qsn .and. qsn > 0) then
    3314             :             ! expression below is approximate since there may be ice deposition
    3315           0 :             dum = (qtmp-qsn)/(1._r8+cons27*qsn/(cpp*rv*ttmp**2))/deltat
    3316             :             ! add to output cme
    3317           0 :             cmeout(i,k) = cmeout(i,k)+dum
    3318             :             ! now add to tendencies, partition between liquid and ice based on temperature
    3319           0 :             if (ttmp > 268.15_r8) then
    3320             :                dum1=0.0_r8
    3321             :                ! now add to tendencies, partition between liquid and ice based on te
    3322           0 :             else if (ttmp < 238.15_r8) then
    3323             :                dum1=1.0_r8
    3324             :             else
    3325           0 :                dum1=(268.15_r8-ttmp)/30._r8
    3326             :             end if
    3327             : 
    3328             :             dum = (qtmp-qsn)/(1._r8+(xxls*dum1+xxlv*(1._r8-dum1))**2 &
    3329           0 :                  *qsn/(cpp*rv*ttmp**2))/deltat
    3330           0 :             qctend(i,k)=qctend(i,k)+dum*(1._r8-dum1)
    3331             :             ! for output
    3332           0 :             qcreso(i,k)=dum*(1._r8-dum1)
    3333           0 :             qitend(i,k)=qitend(i,k)+dum*dum1
    3334           0 :             qireso(i,k)=dum*dum1
    3335           0 :             qvlat(i,k)=qvlat(i,k)-dum
    3336             :             ! for output
    3337           0 :             qvres(i,k)=-dum
    3338           0 :             tlat(i,k)=tlat(i,k)+dum*(1._r8-dum1)*xxlv+dum*dum1*xxls
    3339             :          end if
    3340             :       end if
    3341             : 
    3342             :       !...............................................................................
    3343             :       ! calculate effective radius for pass to radiation code
    3344             :       ! if no cloud water, default value is 10 micron for droplets,
    3345             :       ! 25 micron for cloud ice
    3346             : 
    3347             :       ! update cloud variables after instantaneous processes to get effective radius
    3348             :       ! variables are in-cloud to calculate size dist parameters
    3349             : 
    3350           0 :       dumc(i,k) = max(qc(i,k)+qctend(i,k)*deltat,0._r8)/lcldm(i,k)
    3351           0 :       dumi(i,k) = max(qi(i,k)+qitend(i,k)*deltat,0._r8)/icldm(i,k)
    3352           0 :       dumnc(i,k) = max(nc(i,k)+nctend(i,k)*deltat,0._r8)/lcldm(i,k)
    3353           0 :       dumni(i,k) = max(ni(i,k)+nitend(i,k)*deltat,0._r8)/icldm(i,k)
    3354             : 
    3355           0 :       if (nccons) then
    3356           0 :         dumnc(i,k) = ncnst/rho(i,k)
    3357             :       end if
    3358           0 :       if (nicons) then
    3359           0 :         dumni(i,k) = ninst/rho(i,k)
    3360             :       end if
    3361             : 
    3362             :       ! limit in-cloud mixing ratio to reasonable value of 5 g kg-1
    3363             : 
    3364           0 :       dumc(i,k)=min(dumc(i,k),5.e-3_r8)
    3365           0 :       dumi(i,k)=min(dumi(i,k),5.e-3_r8)
    3366             : 
    3367             :       !...................
    3368             :       ! cloud ice effective radius
    3369             : 
    3370           0 :       if (dumi(i,k).ge.qsmall) then
    3371             : 
    3372           0 :          if (nicons) then
    3373             :            ! make sure ni is consistent with the constant N by adjusting
    3374             :            ! tendency, need to multiply by cloud fraction
    3375             :            ! note that nitend may be further adjusted below if mean crystal
    3376             :            ! size is out of bounds
    3377           0 :            nitend(i,k) = (ninst/rho(i,k)*icldm(i,k) - ni(i,k))/deltat
    3378             :          end if
    3379             : 
    3380             :          ! add upper limit to in-cloud number concentration to prevent numerical error
    3381           0 :          dumni(i,k)=min(dumni(i,k),dumi(i,k)*1.e20_r8)
    3382           0 :          lami(k) = (cons1*ci*dumni(i,k)/dumi(i,k))**(1._r8/di)
    3383             : 
    3384           0 :          if (lami(k).lt.lammini) then
    3385           0 :             lami(k) = lammini
    3386           0 :             n0i(k) = lami(k)**(di+1._r8)*dumi(i,k)/(ci*cons1)
    3387           0 :             niic(i,k) = n0i(k)/lami(k)
    3388             :             ! adjust number conc if needed to keep mean size in reasonable range
    3389           0 :             if (do_cldice) nitend(i,k)=(niic(i,k)*icldm(i,k)-ni(i,k))/deltat
    3390             : 
    3391           0 :          else if (lami(k).gt.lammaxi) then
    3392           0 :             lami(k) = lammaxi
    3393           0 :             n0i(k) = lami(k)**(di+1._r8)*dumi(i,k)/(ci*cons1)
    3394           0 :             niic(i,k) = n0i(k)/lami(k)
    3395             :             ! adjust number conc if needed to keep mean size in reasonable range
    3396           0 :             if (do_cldice) nitend(i,k)=(niic(i,k)*icldm(i,k)-ni(i,k))/deltat
    3397             :          end if
    3398           0 :          effi(i,k) = 1.5_r8/lami(k)*1.e6_r8
    3399             : 
    3400             :       else
    3401           0 :          effi(i,k) = 25._r8
    3402             :       end if
    3403             : 
    3404             :       ! NOTE: If CARMA is doing the ice microphysics, then the ice effective
    3405             :       ! radius has already been determined from the size distribution.
    3406           0 :       if (.not. do_cldice) then
    3407           0 :          effi(i,k) = re_ice(i,k) * 1e6_r8      ! m -> um
    3408             :       end if
    3409             : 
    3410             :       !...................
    3411             :       ! cloud droplet effective radius
    3412             : 
    3413           0 :       if (dumc(i,k).ge.qsmall) then
    3414             : 
    3415           0 :          if (nccons) then
    3416             :            ! make sure nc is consistent with the constant N by adjusting
    3417             :            ! tendency, need to multiply by cloud fraction
    3418             :            ! note that nctend may be further adjusted below if mean droplet
    3419             :            ! size is out of bounds
    3420           0 :            nctend(i,k) = (ncnst/rho(i,k)*lcldm(i,k) - nc(i,k))/deltat
    3421             :          end if
    3422             : 
    3423             :          ! add upper limit to in-cloud number concentration to prevent numerical error
    3424           0 :          dumnc(i,k)=min(dumnc(i,k),dumc(i,k)*1.e20_r8)
    3425             : 
    3426             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    3427             :          ! set tendency to ensure minimum droplet concentration
    3428             :          ! after update by microphysics, except when lambda exceeds bounds on mean drop
    3429             :          ! size or if there is no cloud water
    3430           0 :          if (dumnc(i,k).lt.cdnl/rho(i,k)) then   
    3431           0 :             nctend(i,k)=(cdnl/rho(i,k)*lcldm(i,k)-nc(i,k))/deltat   
    3432             :          end if
    3433           0 :          dumnc(i,k)=max(dumnc(i,k),cdnl/rho(i,k)) ! sghan minimum in #/cm3 
    3434             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    3435           0 :          pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8
    3436           0 :          pgam(k)=1._r8/(pgam(k)**2)-1._r8
    3437           0 :          pgam(k)=max(pgam(k),2._r8)
    3438           0 :          pgam(k)=min(pgam(k),15._r8)
    3439             : 
    3440             :          lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k)+4._r8)/ &
    3441           0 :               (dumc(i,k)*gamma(pgam(k)+1._r8)))**(1._r8/3._r8)
    3442           0 :          lammin = (pgam(k)+1._r8)/50.e-6_r8
    3443             :          ! Multiply by omsm to fit within RRTMG's table.
    3444           0 :          lammax = (pgam(k)+1._r8)*omsm/2.e-6_r8
    3445           0 :          if (lamc(k).lt.lammin) then
    3446           0 :             lamc(k) = lammin
    3447             :             ncic(i,k) = 6._r8*lamc(k)**3*dumc(i,k)* &
    3448             :                  gamma(pgam(k)+1._r8)/ &
    3449           0 :                  (pi*rhow*gamma(pgam(k)+4._r8))
    3450             :             ! adjust number conc if needed to keep mean size in reasonable range
    3451           0 :             nctend(i,k)=(ncic(i,k)*lcldm(i,k)-nc(i,k))/deltat
    3452             : 
    3453           0 :          else if (lamc(k).gt.lammax) then
    3454           0 :             lamc(k) = lammax
    3455             :             ncic(i,k) = 6._r8*lamc(k)**3*dumc(i,k)* &
    3456             :                  gamma(pgam(k)+1._r8)/ &
    3457           0 :                  (pi*rhow*gamma(pgam(k)+4._r8))
    3458             :             ! adjust number conc if needed to keep mean size in reasonable range
    3459           0 :             nctend(i,k)=(ncic(i,k)*lcldm(i,k)-nc(i,k))/deltat
    3460             :          end if
    3461             : 
    3462             :          effc(i,k) = &
    3463             :               gamma(pgam(k)+4._r8)/ &
    3464           0 :               gamma(pgam(k)+3._r8)/lamc(k)/2._r8*1.e6_r8
    3465             :          !assign output fields for shape here
    3466           0 :          lamcrad(i,k)=lamc(k)
    3467           0 :          pgamrad(i,k)=pgam(k)
    3468             : 
    3469             :       else
    3470           0 :          effc(i,k) = 10._r8
    3471           0 :          lamcrad(i,k)=0._r8
    3472           0 :          pgamrad(i,k)=0._r8
    3473             :       end if
    3474             : 
    3475             :       ! ice effective diameter for david mitchell's optics
    3476           0 :       if (do_cldice) then
    3477           0 :          deffi(i,k)=effi(i,k)*rhoi/917._r8*2._r8
    3478             :       else
    3479           0 :          deffi(i,k)=effi(i,k) * 2._r8
    3480             :       end if
    3481             : 
    3482             : 
    3483             : !!! recalculate effective radius for constant number, in order to separate
    3484             :       ! first and second indirect effects
    3485             :       ! assume constant number of 10^8 kg-1
    3486             : 
    3487           0 :       dumnc(i,k)=1.e8_r8
    3488             : 
    3489           0 :       if (dumc(i,k).ge.qsmall) then
    3490           0 :          pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8
    3491           0 :          pgam(k)=1._r8/(pgam(k)**2)-1._r8
    3492           0 :          pgam(k)=max(pgam(k),2._r8)
    3493           0 :          pgam(k)=min(pgam(k),15._r8)
    3494             : 
    3495             :          lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k)+4._r8)/ &
    3496           0 :               (dumc(i,k)*gamma(pgam(k)+1._r8)))**(1._r8/3._r8)
    3497           0 :          lammin = (pgam(k)+1._r8)/50.e-6_r8
    3498           0 :          lammax = (pgam(k)+1._r8)/2.e-6_r8
    3499           0 :          if (lamc(k).lt.lammin) then
    3500           0 :             lamc(k) = lammin
    3501           0 :          else if (lamc(k).gt.lammax) then
    3502           0 :             lamc(k) = lammax
    3503             :          end if
    3504             :          effc_fn(i,k) = &
    3505             :               gamma(pgam(k)+4._r8)/ &
    3506           0 :               gamma(pgam(k)+3._r8)/lamc(k)/2._r8*1.e6_r8
    3507             : 
    3508             :       else
    3509           0 :          effc_fn(i,k) = 10._r8
    3510             :       end if
    3511             : 
    3512             : 
    3513             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1!
    3514             : 
    3515             :    end do ! vertical k loop
    3516             : 
    3517             : 500 continue
    3518             : 
    3519           0 :    do k=top_lev,pver
    3520             :       ! if updated q (after microphysics) is zero, then ensure updated n is also zero
    3521             : 
    3522           0 :       if (qc(i,k)+qctend(i,k)*deltat.lt.qsmall) nctend(i,k)=-nc(i,k)/deltat
    3523           0 :       if (do_cldice .and. qi(i,k)+qitend(i,k)*deltat.lt.qsmall) nitend(i,k)=-ni(i,k)/deltat
    3524             :    end do
    3525             : 
    3526             : end do ! i loop
    3527             : 
    3528             : ! add snow ouptut
    3529           0 : do i = 1,ncol
    3530           0 :    do k=top_lev,pver
    3531           0 :       if (qsout(i,k).gt.1.e-7_r8.and.nsout(i,k).gt.0._r8) then
    3532           0 :          dsout(i,k)=3._r8*rhosn/917._r8*(pi * rhosn * nsout(i,k)/qsout(i,k))**(-1._r8/3._r8)
    3533             :       endif
    3534             :    end do
    3535             : end do
    3536             : 
    3537             : !calculate effective radius of rain and snow in microns for COSP using Eq. 9 of COSP v1.3 manual
    3538           0 : do i = 1,ncol
    3539           0 :    do k=top_lev,pver
    3540             :       !! RAIN
    3541           0 :       if (qrout(i,k).gt.1.e-7_r8.and.nrout(i,k).gt.0._r8) then
    3542           0 :          reff_rain(i,k)=1.5_r8*(pi * rhow * nrout(i,k)/qrout(i,k))**(-1._r8/3._r8)*1.e6_r8
    3543             :       endif
    3544             :       !! SNOW
    3545           0 :       if (qsout(i,k).gt.1.e-7_r8.and.nsout(i,k).gt.0._r8) then
    3546           0 :          reff_snow(i,k)=1.5_r8*(pi * rhosn * nsout(i,k)/qsout(i,k))**(-1._r8/3._r8)*1.e6_r8
    3547             :       end if
    3548             :    end do
    3549             : end do
    3550             : 
    3551             : ! analytic radar reflectivity
    3552             : ! formulas from Matthew Shupe, NOAA/CERES
    3553             : ! *****note: radar reflectivity is local (in-precip average)
    3554             : ! units of mm^6/m^3
    3555             : 
    3556           0 : do i = 1,ncol
    3557           0 :    do k=top_lev,pver
    3558           0 :       if (qc(i,k)+qctend(i,k)*deltat.ge.qsmall .and. nc(i,k)+nctend(i,k)*deltat.gt.10._r8) then
    3559             :          dum=((qc(i,k)+qctend(i,k)*deltat)/lcldm(i,k)*rho(i,k)*1000._r8)**2 &
    3560           0 :               /(0.109_r8*(nc(i,k)+nctend(i,k)*deltat)/lcldm(i,k)*rho(i,k)/1.e6_r8)*lcldm(i,k)/cldmax(i,k)
    3561             :       else
    3562             :          dum=0._r8
    3563             :       end if
    3564           0 :       if (qi(i,k)+qitend(i,k)*deltat.ge.qsmall) then
    3565           0 :          dum1=((qi(i,k)+qitend(i,k)*deltat)*rho(i,k)/icldm(i,k)*1000._r8/0.1_r8)**(1._r8/0.63_r8)*icldm(i,k)/cldmax(i,k)
    3566             :       else 
    3567             :          dum1=0._r8
    3568             :       end if
    3569             : 
    3570           0 :       if (qsout(i,k).ge.qsmall) then
    3571           0 :          dum1=dum1+(qsout(i,k)*rho(i,k)*1000._r8/0.1_r8)**(1._r8/0.63_r8)
    3572             :       end if
    3573             : 
    3574           0 :       refl(i,k)=dum+dum1
    3575             : 
    3576             :       ! add rain rate, but for 37 GHz formulation instead of 94 GHz
    3577             :       ! formula approximated from data of Matrasov (2007)
    3578             :       ! rainrt is the rain rate in mm/hr
    3579             :       ! reflectivity (dum) is in DBz
    3580             : 
    3581           0 :       if (rainrt(i,k).ge.0.001_r8) then
    3582           0 :          dum=log10(rainrt(i,k)**6._r8)+16._r8
    3583             : 
    3584             :          ! convert from DBz to mm^6/m^3
    3585             : 
    3586           0 :          dum = 10._r8**(dum/10._r8)
    3587             :       else
    3588             :          ! don't include rain rate in R calculation for values less than 0.001 mm/hr
    3589             :          dum=0._r8
    3590             :       end if
    3591             : 
    3592             :       ! add to refl
    3593             : 
    3594           0 :       refl(i,k)=refl(i,k)+dum
    3595             : 
    3596             :       !output reflectivity in Z.
    3597           0 :       areflz(i,k)=refl(i,k)
    3598             : 
    3599             :       ! convert back to DBz 
    3600             : 
    3601           0 :       if (refl(i,k).gt.minrefl) then 
    3602           0 :          refl(i,k)=10._r8*log10(refl(i,k))
    3603             :       else
    3604           0 :          refl(i,k)=-9999._r8
    3605             :       end if
    3606             : 
    3607             :       !set averaging flag
    3608           0 :       if (refl(i,k).gt.mindbz) then 
    3609           0 :          arefl(i,k)=refl(i,k)
    3610           0 :          frefl(i,k)=1.0_r8  
    3611             :       else
    3612           0 :          arefl(i,k)=0._r8
    3613           0 :          areflz(i,k)=0._r8
    3614           0 :          frefl(i,k)=0._r8
    3615             :       end if
    3616             : 
    3617             :       ! bound cloudsat reflectivity
    3618             : 
    3619           0 :       csrfl(i,k)=min(csmax,refl(i,k))
    3620             : 
    3621             :       !set averaging flag
    3622           0 :       if (csrfl(i,k).gt.csmin) then 
    3623           0 :          acsrfl(i,k)=refl(i,k)
    3624           0 :          fcsrfl(i,k)=1.0_r8  
    3625             :       else
    3626           0 :          acsrfl(i,k)=0._r8
    3627           0 :          fcsrfl(i,k)=0._r8
    3628             :       end if
    3629             : 
    3630             :    end do
    3631             : end do
    3632             : 
    3633             : 
    3634             : ! averaging for snow and rain number and diameter
    3635             : 
    3636           0 : qrout2(:,:)=0._r8
    3637           0 : qsout2(:,:)=0._r8
    3638           0 : nrout2(:,:)=0._r8
    3639           0 : nsout2(:,:)=0._r8
    3640           0 : drout2(:,:)=0._r8
    3641           0 : dsout2(:,:)=0._r8
    3642           0 : freqs(:,:)=0._r8
    3643           0 : freqr(:,:)=0._r8
    3644           0 : do i = 1,ncol
    3645           0 :    do k=top_lev,pver
    3646           0 :       if (qrout(i,k).gt.1.e-7_r8.and.nrout(i,k).gt.0._r8) then
    3647           0 :          qrout2(i,k)=qrout(i,k)
    3648           0 :          nrout2(i,k)=nrout(i,k)
    3649           0 :          drout2(i,k)=(pi * rhow * nrout(i,k)/qrout(i,k))**(-1._r8/3._r8)
    3650           0 :          freqr(i,k)=1._r8
    3651             :       endif
    3652           0 :       if (qsout(i,k).gt.1.e-7_r8.and.nsout(i,k).gt.0._r8) then
    3653           0 :          qsout2(i,k)=qsout(i,k)
    3654           0 :          nsout2(i,k)=nsout(i,k)
    3655           0 :          dsout2(i,k)=(pi * rhosn * nsout(i,k)/qsout(i,k))**(-1._r8/3._r8)
    3656           0 :          freqs(i,k)=1._r8
    3657             :       endif
    3658             :    end do
    3659             : end do
    3660             : 
    3661             : ! output activated liquid and ice (convert from #/kg -> #/m3)
    3662           0 : do i = 1,ncol
    3663           0 :    do k=top_lev,pver
    3664           0 :       ncai(i,k)=dum2i(i,k)*rho(i,k)
    3665           0 :       ncal(i,k)=dum2l(i,k)*rho(i,k)
    3666             :    end do
    3667             : end do
    3668             : 
    3669             : 
    3670             : !redefine fice here....
    3671           0 : nfice(:,:)=0._r8
    3672           0 : do k=top_lev,pver
    3673           0 :    do i=1,ncol
    3674           0 :       dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat)
    3675           0 :       dumi(i,k) = (qi(i,k)+qitend(i,k)*deltat)
    3676           0 :       dumfice=qsout(i,k) + qrout(i,k) + dumc(i,k) + dumi(i,k)  
    3677             : 
    3678           0 :       if (dumfice.gt.qsmall.and.(qsout(i,k)+dumi(i,k).gt.qsmall)) then
    3679           0 :          nfice(i,k)=(qsout(i,k) + dumi(i,k))/dumfice
    3680             :       endif
    3681             : 
    3682           0 :       if (nfice(i,k).gt.1._r8) then
    3683           0 :          nfice(i,k)=1._r8
    3684             :       endif
    3685             : 
    3686             :    enddo
    3687             : enddo
    3688             : 
    3689             : 
    3690           0 : end subroutine micro_mg_tend
    3691             : 
    3692             : !========================================================================
    3693             : !UTILITIES
    3694             : !========================================================================
    3695             : 
    3696           0 : pure subroutine micro_mg_get_cols(ncol, nlev, top_lev, qcn, qin, &
    3697             :      mgncol, mgcols)
    3698             : 
    3699             :   ! Determines which columns microphysics should operate over by
    3700             :   ! checking for non-zero cloud water/ice.
    3701             : 
    3702             :   integer, intent(in) :: ncol      ! Number of columns with meaningful data
    3703             :   integer, intent(in) :: nlev      ! Number of levels to use
    3704             :   integer, intent(in) :: top_lev   ! Top level for microphysics
    3705             : 
    3706             :   real(r8), intent(in) :: qcn(:,:) ! cloud water mixing ratio (kg/kg)
    3707             :   real(r8), intent(in) :: qin(:,:) ! cloud ice mixing ratio (kg/kg)
    3708             : 
    3709             :   integer, intent(out) :: mgncol   ! Number of columns MG will use
    3710             :   integer, allocatable, intent(out) :: mgcols(:) ! column indices
    3711             : 
    3712             :   integer :: lev_offset  ! top_lev - 1 (defined here for consistency)
    3713           0 :   logical :: ltrue(ncol) ! store tests for each column
    3714             : 
    3715             :   integer :: i, ii ! column indices
    3716             : 
    3717           0 :   if (allocated(mgcols)) deallocate(mgcols)
    3718             : 
    3719           0 :   lev_offset = top_lev - 1
    3720             : 
    3721             :   ! Using "any" along dimension 2 collapses across levels, but
    3722             :   ! not columns, so we know if water is present at any level
    3723             :   ! in each column.
    3724             : 
    3725           0 :   ltrue = any(qcn(:ncol,top_lev:(nlev+lev_offset)) >= qsmall, 2)
    3726           0 :   ltrue = ltrue .or. any(qin(:ncol,top_lev:(nlev+lev_offset)) >= qsmall, 2)
    3727             : 
    3728             :   ! Scan for true values to get a usable list of indices.
    3729             : 
    3730           0 :   mgncol = count(ltrue)
    3731           0 :   allocate(mgcols(mgncol))
    3732           0 :   i = 0
    3733           0 :   do ii = 1,ncol
    3734           0 :      if (ltrue(ii)) then
    3735           0 :         i = i + 1
    3736           0 :         mgcols(i) = ii
    3737             :      end if
    3738             :   end do
    3739             : 
    3740           0 : end subroutine micro_mg_get_cols
    3741             : 
    3742             : end module micro_mg1_0

Generated by: LCOV version 1.14