#define MODAL_AERO
#define WRF_PORT
! Updated to CESM1.0.3 (CAM5.1.01) by Balwinder.Singh@pnnl.gov

module cldwat2m_micro 2,6

!---------------------------------------------------------------------------------
! Purpose:
!   CAM Interface for microphysics
!
! Author: Andrew Gettelman, Hugh Morrison.
! Contributions from: Xiaohong Liu and Steve Ghan
! December 2005-May 2010
! Description in: Morrison and Gettelman, 2008. J. Climate (MG2008)
!                 Gettelman et al., 2010 J. Geophys. Res. - Atmospheres (G2010)         
! for questions contact Hugh Morrison, Andrew Gettelman
! e-mail: morrison@ucar.edu, andrew@ucar.edu
!---------------------------------------------------------------------------------
! modification for sub-columns, HM, (orig 8/11/10)
! This is done using the logical 'sub_column' set to .true. = subcolumns
!---------------------------------------------------------------------------------

  use shr_kind_mod,  only: r8=>shr_kind_r8
#ifndef WRF_PORT
  use spmd_utils,    only: masterproc
  use ppgrid,        only: pcols, pver, pverp
#else
  use module_cam_support, only: masterproc, pcols, pver, pverp
#endif
  use physconst,     only: gravit, rair, tmelt, cpair, rh2o, rhoh2o
  use physconst,     only: latvap, latice
  use wv_saturation,  only: polysvp, epsqs 
#ifndef WRF_PORT
  use cam_history,    only: addfld, add_default, phys_decomp, outfld
  use cam_history_support, only : fillvalue
  use cam_logfile,    only: iulog
  use phys_control,   only: phys_getopts
  use cldwat2m_macro, only: rhmini
#else
  use module_cam_support, only: addfld, add_default, phys_decomp, outfld, &
       fillvalue, iulog
#endif

  implicit none
  private
  save

#ifdef WRF_PORT
  !Macrophysics is not ported yet therefore rhmini is defined here (obtained from Cam5's cldwat2_macro)-Balwinder.Singh@pnnl.gov
  real(r8), public,  parameter :: rhmini       = 0.80_r8       ! Minimum rh for ice cloud fraction > 0.
#endif
  logical, public :: liu_in = .true.   ! True = Liu et al 2007 Ice nucleation 
                                       ! False = cooper fixed ice nucleation (MG2008)

   public :: ini_micro, mmicro_pcond,gamma

!constants remaped
  real(r8), private::  g              !gravity
  real(r8), private::  r              !Dry air Gas constant
  real(r8), private::  rv             !water vapor gas contstant
  real(r8), private::  cpp            !specific heat of dry air
  real(r8), private::  rhow           !density of liquid water
  real(r8), private::  xxlv           ! latent heat of vaporization
  real(r8), private::  xlf            !latent heat of freezing
  real(r8), private::  xxls           !latent heat of sublimation

real(r8), private:: rhosn  ! bulk density snow
real(r8), private:: rhoi   ! bulk density ice

real(r8), private:: ac,bc,as,bs,ai,bi,ar,br  !fall speed parameters 
real(r8), private:: ci,di    !ice mass-diameter relation parameters
real(r8), private:: cs,ds    !snow mass-diameter relation parameters
real(r8), private:: cr,dr    !drop mass-diameter relation parameters
real(r8), private:: f1s,f2s  !ventilation param for snow
real(r8), private:: Eii      !collection efficiency aggregation of ice
real(r8), private:: Ecc      !collection efficiency
real(r8), private:: Ecr      !collection efficiency cloud droplets/rain
real(r8), private:: f1r,f2r  !ventilation param for rain
real(r8), private:: DCS      !autoconversion size threshold
real(r8), private:: qsmall   !min mixing ratio 
real(r8), private:: bimm,aimm !immersion freezing
real(r8), private:: rhosu     !typical 850mn air density
real(r8), private:: mi0       ! new crystal mass
real(r8), private:: rin       ! radius of contact nuclei
real(r8), private:: qcvar     ! 1/relative variance of sub-grid qc
real(r8), private:: pi       ! pi

! Additional constants to help speed up code

real(r8), private:: cons1
real(r8), private:: cons2
real(r8), private:: cons3
real(r8), private:: cons4
real(r8), private:: cons5
real(r8), private:: cons6
real(r8), private:: cons7
real(r8), private:: cons8
real(r8), private:: cons9
real(r8), private:: cons10
real(r8), private:: cons11
real(r8), private:: cons12
real(r8), private:: cons13
real(r8), private:: cons14
real(r8), private:: cons15
real(r8), private:: cons16
real(r8), private:: cons17
real(r8), private:: cons18
real(r8), private:: cons19
real(r8), private:: cons20
real(r8), private:: cons21
real(r8), private:: cons22
real(r8), private:: cons23
real(r8), private:: cons24
real(r8), private:: cons25
real(r8), private:: cons27
real(r8), private:: cons28

real(r8), private:: lammini
real(r8), private:: lammaxi
real(r8), private:: lamminr
real(r8), private:: lammaxr
real(r8), private:: lammins
real(r8), private:: lammaxs

! parameters for snow/rain fraction for convective clouds
real(r8), private:: tmax_fsnow ! max temperature for transition to convective snow
real(r8), private:: tmin_fsnow ! min temperature for transition to convective snow

!needed for findsp
real(r8), private:: tt0       ! Freezing temperature

real(r8), private:: csmin,csmax,minrefl,mindbz

contains

!===============================================================================


subroutine ini_micro 1,47

!----------------------------------------------------------------------- 
! 
! Purpose: 
! initialize constants for the morrison microphysics
! called from stratiform.F90
! 
! Author: Andrew Gettelman Dec 2005
! 
!-----------------------------------------------------------------------

   integer k

   integer l,m, iaer
   real(r8) surften       ! surface tension of water w/respect to air (N/m)
   real(r8) arg

   character(len=16) :: eddy_scheme = ' '
   logical           :: history_microphysics     ! output variables for microphysics diagnostics package
#ifndef WRF_PORT
   ! Query the PBL eddy scheme
   call phys_getopts(eddy_scheme_out              = eddy_scheme,           &
                     history_microphysics_out     = history_microphysics   )
#else
   history_microphysics = .FALSE.
#endif
   ! diagnostic precip
   call addfld ('QRAIN   ','kg/kg   ',pver, 'A','Diagnostic grid-mean rain mixing ratio'         ,phys_decomp)	
   call addfld ('QSNOW   ','kg/kg   ',pver, 'A','Diagnostic grid-mean snow mixing ratio'         ,phys_decomp)	
   call addfld ('NRAIN   ','m-3     ',pver, 'A','Diagnostic grid-mean rain number conc'         ,phys_decomp)	
   call addfld ('NSNOW   ','m-3     ',pver, 'A','Diagnostic grid-mean snow number conc'         ,phys_decomp)	

   ! size of precip
   call addfld ('RERCLD   ','m      ',pver, 'A','Diagnostic effective radius of Liquid Cloud and Rain' ,phys_decomp)

   call addfld ('DSNOW   ','m       ',pver, 'A','Diagnostic grid-mean snow diameter'         ,phys_decomp)	

   ! diagnostic radar reflectivity, cloud-averaged 
   call addfld ('REFL  ','DBz  ',pver, 'A','94 GHz radar reflectivity'       ,phys_decomp)
   call addfld ('AREFL  ','DBz  ',pver, 'A','Average 94 GHz radar reflectivity'       ,phys_decomp)
   call addfld ('FREFL  ','fraction  ',pver, 'A','Fractional occurance of radar reflectivity'       ,phys_decomp)
   
   call addfld ('CSRFL  ','DBz  ',pver, 'A','94 GHz radar reflectivity (CloudSat thresholds)'       ,phys_decomp)
   call addfld ('ACSRFL  ','DBz  ',pver, 'A','Average 94 GHz radar reflectivity (CloudSat thresholds)'       ,phys_decomp)
   call addfld ('FCSRFL  ','fraction  ',pver, 'A','Fractional occurance of radar reflectivity (CloudSat thresholds)' &
	,phys_decomp)
 
   call addfld ('AREFLZ ','mm^6/m^3 ',pver, 'A','Average 94 GHz radar reflectivity'       ,phys_decomp)

   ! Aerosol information
    call addfld ('NCAL    ','#/m3   ',pver, 'A','Number Concentation Activated for Liquid',phys_decomp)
    call addfld ('NCAI    ','#/m3   ',pver, 'A','Number Concentation Activated for Ice',phys_decomp)


   ! Average rain and snow mixing ratio (Q), number (N) and diameter (D), with frequency
   call addfld ('AQRAIN   ','kg/kg   ',pver, 'A','Average rain mixing ratio'         ,phys_decomp)	
   call addfld ('AQSNOW   ','kg/kg   ',pver, 'A','Average snow mixing ratio'         ,phys_decomp)	
   call addfld ('ANRAIN   ','m-3     ',pver, 'A','Average rain number conc'         ,phys_decomp)	
   call addfld ('ANSNOW   ','m-3     ',pver, 'A','Average snow number conc'         ,phys_decomp)
   call addfld ('ADRAIN   ','Micron  ',pver, 'A','Average rain effective Diameter'         ,phys_decomp)	
   call addfld ('ADSNOW   ','Micron  ',pver, 'A','Average snow effective Diameter'         ,phys_decomp)
   call addfld ('FREQR  ','fraction  ',pver, 'A','Fractional occurance of rain'       ,phys_decomp)
   call addfld ('FREQS  ','fraction  ',pver, 'A','Fractional occurance of snow'       ,phys_decomp)

   if ( history_microphysics) then
      call add_default ('AQSNOW   ', 1, ' ')
      call add_default ('FREQR    ', 1, ' ')
      call add_default ('FREQS    ', 1, ' ')
      call add_default ('AQRAIN   ', 1, ' ')
      call add_default ('AQSNOW   ', 1, ' ')
      call add_default ('ANRAIN   ', 1, ' ')
      call add_default ('ANSNOW   ', 1, ' ')
  end if

!declarations for morrison codes (transforms variable names)

   g= gravit                  !gravity
   r= rair       	      !Dry air Gas constant: note units(phys_constants are in J/K/kmol)
   rv= rh2o                   !water vapor gas contstant
   cpp = cpair                 !specific heat of dry air
   rhow = rhoh2o              !density of liquid water

! latent heats

   xxlv = latvap         ! latent heat vaporization
   xlf = latice          ! latent heat freezing
   xxls = xxlv + xlf     ! latent heat of sublimation

! parameters for snow/rain fraction for convective clouds

   tmax_fsnow = tmelt
   tmin_fsnow = tmelt-5._r8

! parameters below from Reisner et al. (1998)
! density parameters (kg/m3)

      rhosn = 250._r8    ! bulk density snow  (++ ceh)
      rhoi = 500._r8     ! bulk density ice
      rhow = 1000._r8    ! bulk density liquid


! fall speed parameters, V = aD^b
! V is in m/s

! droplets
	ac = 3.e7_r8
	bc = 2._r8

! snow
	as = 11.72_r8
	bs = 0.41_r8

! cloud ice
	ai = 700._r8
	bi = 1._r8

! rain
	ar = 841.99667_r8
	br = 0.8_r8

! particle mass-diameter relationship
! currently we assume spherical particles for cloud ice/snow
! m = cD^d

        pi= 3.1415927_r8

! cloud ice mass-diameter relationship

	ci = rhoi*pi/6._r8
	di = 3._r8

! snow mass-diameter relationship

	cs = rhosn*pi/6._r8
	ds = 3._r8

! drop mass-diameter relationship

	cr = rhow*pi/6._r8
	dr = 3._r8

! ventilation parameters for snow
! hall and prupacher

	f1s = 0.86_r8
	f2s = 0.28_r8

! collection efficiency, aggregation of cloud ice and snow

	Eii = 0.1_r8

! collection efficiency, accretion of cloud water by rain

	Ecr = 1.0_r8

! ventilation constants for rain

	f1r = 0.78_r8
	f2r = 0.32_r8

! autoconversion size threshold for cloud ice to snow (m)

       Dcs = 400.e-6_r8

! smallest mixing ratio considered in microphysics

	qsmall = 1.e-18_r8  

! immersion freezing parameters, bigg 1953

	bimm = 100._r8
	aimm = 0.66_r8

! typical air density at 850 mb

	rhosu = 85000._r8/(rair * tmelt)

! mass of new crystal due to aerosol freezing and growth (kg)

	mi0 = 4._r8/3._r8*pi*rhoi*(10.e-6_r8)*(10.e-6_r8)*(10.e-6_r8)

! radius of contact nuclei aerosol (m)

        rin = 0.1e-6_r8

! 1 / relative variance of sub-grid cloud water distribution
! see morrison and gettelman, 2007, J. Climate for details

	qcvar = 2._r8

! freezing temperature
	tt0=273.15_r8

      pi=4._r8*atan(1.0_r8)

      !Range of cloudsat reflectivities (dBz) for analytic simulator
      csmin= -30._r8
      csmax= 26._r8
      mindbz = -99._r8
      !      minrefl = 10._r8**(mindbz/10._r8)
      minrefl = 1.26e-10_r8

! Define constants to help speed up code (limit calls to gamma function)

	cons1=gamma(1._r8+di)
	cons2=gamma(qcvar+2.47_r8)
	cons3=gamma(qcvar)
	cons4=gamma(1._r8+br)
	cons5=gamma(4._r8+br)
	cons6=gamma(1._r8+ds)
	cons7=gamma(1._r8+bs)     
	cons8=gamma(4._r8+bs)     
	cons9=gamma(qcvar+2._r8)     
	cons10=gamma(qcvar+1._r8)
	cons11=gamma(3._r8+bs)
	cons12=gamma(qcvar+1.15_r8)
	cons13=gamma(5._r8/2._r8+br/2._r8)
	cons14=gamma(5._r8/2._r8+bs/2._r8)
	cons15=gamma(qcvar+bc/3._r8)
	cons16=gamma(1._r8+bi)
	cons17=gamma(4._r8+bi)
	cons18=qcvar**2.47_r8
	cons19=qcvar**2
	cons20=qcvar**1.15_r8
	cons21=qcvar**(bc/3._r8)
	cons22=(4._r8/3._r8*pi*rhow*(25.e-6_r8)**3)	
	cons23=dcs**3
	cons24=dcs**2
	cons25=dcs**bs
	cons27=xxlv**2
	cons28=xxls**2

        lammaxi = 1._r8/10.e-6_r8
        lammini = 1._r8/(2._r8*dcs)
	lammaxr = 1._r8/20.e-6_r8
	lamminr = 1._r8/500.e-6_r8
	lammaxs = 1._r8/10.e-6_r8
	lammins = 1._r8/2000.e-6_r8

   return
 end subroutine ini_micro

!===============================================================================
!microphysics routine for each timestep goes here...


subroutine mmicro_pcond ( sub_column,       & 1,36
   lchnk, ncol, deltatin, tn,               &
   qn, qc, qi,                              &
   nc, ni, p, pdel, cldn,                   &
   liqcldf, icecldf,                        &
   cldo,                                    &
   rate1ord_cw2pr_st,                       &   
   naai, npccnin, rndst,nacon,              &
   tlat, qvlat,        &
   qctend, qitend, nctend, nitend, effc,    &
   effc_fn, effi, prect, preci,             &  
   nevapr, evapsnow,      &
   prain, prodsnow, cmeout, deffi, pgamrad, &
   lamcrad,qsout,dsout, &
         rflx,sflx, qrout,reff_rain,reff_snow,  &
   qcsevap,qisevap,qvres,cmeiout, &
   vtrmc,vtrmi,qcsedten,qisedten, &
   prao,prco,mnuccco,mnuccto,msacwio,psacwso,&
   bergso,bergo,melto,homoo,qcreso,prcio,praio,qireso,&
   mnuccro,pracso,meltsdt,frzrdt,mnuccdo    &
#ifdef WRF_PORT
   , nsout, nrout                           &
#endif
                                            )

!Author: Hugh Morrison, Andrew Gettelman, NCAR
! e-mail: morrison@ucar.edu, andrew@ucar.edu

   use wv_saturation, only: vqsatd_water

   ! input arguments
   logical,  intent(in) :: sub_column  ! True = configure for sub-columns  False = use w/o sub-columns (standard)
   integer,  intent(in) :: lchnk
   integer,  intent(in) :: ncol
   real(r8), intent(in) :: deltatin             ! time step (s)
   real(r8), intent(in) :: tn(pcols,pver)       ! input temperature (K)
   real(r8), intent(in) :: qn(pcols,pver)       ! input h20 vapor mixing ratio (kg/kg)

   ! note: all input cloud variables are grid-averaged
   real(r8), intent(inout) :: qc(pcols,pver)    ! cloud water mixing ratio (kg/kg)
   real(r8), intent(inout) :: qi(pcols,pver)    ! cloud ice mixing ratio (kg/kg)
   real(r8), intent(inout) :: nc(pcols,pver)    ! cloud water number conc (1/kg)
   real(r8), intent(inout) :: ni(pcols,pver)    ! cloud ice number conc (1/kg)
   real(r8), intent(in) :: p(pcols,pver)        ! air pressure (pa)
   real(r8), intent(in) :: pdel(pcols,pver)     ! pressure difference across level (pa)
   real(r8), intent(in) :: cldn(pcols,pver)     ! cloud fraction
   real(r8), intent(in) :: icecldf(pcols,pver)  ! ice cloud fraction   
   real(r8), intent(in) :: liqcldf(pcols,pver)  ! liquid cloud fraction
   real(r8), intent(inout) :: cldo(pcols,pver)  ! old cloud fraction

   real(r8), intent(out) :: rate1ord_cw2pr_st(pcols,pver) ! 1st order rate for direct cw to precip conversion 
                                                          ! used for scavenging
! Inputs for aerosol activation
   real(r8), intent(in) :: naai(pcols,pver)      ! ice nulceation number (from microp_aero_ts) 
   real(r8), intent(in) :: npccnin(pcols,pver)   ! ccn activated number tendency (from microp_aero_ts)
   real(r8), intent(in) :: rndst(pcols,pver,4)   ! radius of 4 dust bins for contact freezing (from microp_aero_ts)
   real(r8), intent(in) :: nacon(pcols,pver,4)   ! number in 4 dust bins for contact freezing  (from microp_aero_ts)

   ! output arguments

   real(r8), intent(out) :: tlat(pcols,pver)    ! latent heating rate       (W/kg)
   real(r8), intent(out) :: qvlat(pcols,pver)   ! microphysical tendency qv (1/s)
   real(r8), intent(out) :: qctend(pcols,pver)  ! microphysical tendency qc (1/s) 
   real(r8), intent(out) :: qitend(pcols,pver)  ! microphysical tendency qi (1/s)
   real(r8), intent(out) :: nctend(pcols,pver)  ! microphysical tendency nc (1/(kg*s))
   real(r8), intent(out) :: nitend(pcols,pver)  ! microphysical tendency ni (1/(kg*s))
   real(r8), intent(out) :: effc(pcols,pver)    ! droplet effective radius (micron)
   real(r8), intent(out) :: effc_fn(pcols,pver) ! droplet effective radius, assuming nc = 1.e8 kg-1
   real(r8), intent(out) :: effi(pcols,pver)    ! cloud ice effective radius (micron)
   real(r8), intent(out) :: prect(pcols)        ! surface precip rate (m/s)
   real(r8), intent(out) :: preci(pcols)        ! cloud ice/snow precip rate (m/s)
   real(r8), intent(out) :: nevapr(pcols,pver)  ! evaporation rate of rain + snow
   real(r8), intent(out) :: evapsnow(pcols,pver)! sublimation rate of snow
   real(r8), intent(out) :: prain(pcols,pver)   ! production of rain + snow
   real(r8), intent(out) :: prodsnow(pcols,pver)! production of snow
   real(r8), intent(out) :: cmeout(pcols,pver)  ! evap/sub of cloud
   real(r8), intent(out) :: deffi(pcols,pver)   ! ice effective diameter for optics (radiation)
   real(r8), intent(out) :: pgamrad(pcols,pver) ! ice gamma parameter for optics (radiation)
   real(r8), intent(out) :: lamcrad(pcols,pver) ! slope of droplet distribution for optics (radiation)
   real(r8), intent(out) :: rflx(pcols,pver+1)  ! grid-box average rain flux (kg m^-2 s^-1)
   real(r8), intent(out) :: sflx(pcols,pver+1)  ! grid-box average snow flux (kg m^-2 s^-1)
   real(r8), intent(out) :: qcsevap(pcols,pver) ! cloud water evaporation due to sedimentation
   real(r8), intent(out) :: qisevap(pcols,pver) ! cloud ice sublimation due to sublimation
   real(r8), intent(out) :: qvres(pcols,pver) ! residual condensation term to ensure RH < 100%
   real(r8), intent(out) :: cmeiout(pcols,pver) ! grid-mean cloud ice sub/dep
   real(r8), intent(out) :: vtrmc(pcols,pver) ! mass-weighted cloud water fallspeed
   real(r8), intent(out) :: vtrmi(pcols,pver) ! mass-weighted cloud ice fallspeed
   real(r8), intent(out) :: qcsedten(pcols,pver) ! qc sedimentation tendency
   real(r8), intent(out) :: qisedten(pcols,pver) ! qi sedimentation tendency
! microphysical process rates for output (mixing ratio tendencies)
   real(r8), intent(out) :: prao(pcols,pver) ! accretion of cloud by rain 
   real(r8), intent(out) :: prco(pcols,pver) ! autoconversion of cloud to rain
   real(r8), intent(out) :: mnuccco(pcols,pver) ! mixing rat tend due to immersion freezing
   real(r8), intent(out) :: mnuccto(pcols,pver) ! mixing ratio tend due to contact freezing
   real(r8), intent(out) :: msacwio(pcols,pver) ! mixing ratio tend due to H-M splintering
   real(r8), intent(out) :: psacwso(pcols,pver) ! collection of cloud water by snow
   real(r8), intent(out) :: bergso(pcols,pver) ! bergeron process on snow
   real(r8), intent(out) :: bergo(pcols,pver) ! bergeron process on cloud ice
   real(r8), intent(out) :: melto(pcols,pver) ! melting of cloud ice
   real(r8), intent(out) :: homoo(pcols,pver) ! homogeneos freezign cloud water
   real(r8), intent(out) :: qcreso(pcols,pver) ! residual cloud condensation due to removal of excess supersat
   real(r8), intent(out) :: prcio(pcols,pver) ! autoconversion of cloud ice to snow
   real(r8), intent(out) :: praio(pcols,pver) ! accretion of cloud ice by snow
   real(r8), intent(out) :: qireso(pcols,pver) ! residual ice deposition due to removal of excess supersat
   real(r8), intent(out) :: mnuccro(pcols,pver) ! mixing ratio tendency due to heterogeneous freezing of rain to snow (1/s)
   real(r8), intent(out) :: pracso (pcols,pver) ! mixing ratio tendency due to accretion of rain by snow (1/s)
   real(r8), intent(out) :: meltsdt(pcols,pver) ! latent heating rate due to melting of snow  (W/kg)
   real(r8), intent(out) :: frzrdt (pcols,pver) ! latent heating rate due to homogeneous freezing of rain (W/kg)
   real(r8), intent(out) :: mnuccdo(pcols,pver) ! mass tendency from ice nucleation

! local workspace
! all units mks unless otherwise stated

! temporary variables for sub-stepping 
	real(r8) :: t1(pcols,pver)
	real(r8) :: q1(pcols,pver)
	real(r8) :: qc1(pcols,pver)
   	real(r8) :: qi1(pcols,pver)
   	real(r8) :: nc1(pcols,pver)
   	real(r8) :: ni1(pcols,pver)
  	real(r8) :: tlat1(pcols,pver)
   	real(r8) :: qvlat1(pcols,pver)
   	real(r8) :: qctend1(pcols,pver)
   	real(r8) :: qitend1(pcols,pver)
   	real(r8) :: nctend1(pcols,pver)
   	real(r8) :: nitend1(pcols,pver)
   	real(r8) :: prect1(pcols)
   	real(r8) :: preci1(pcols)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

   	real(r8) :: deltat        ! sub-time step (s)
        real(r8) :: omsm    ! number near unity for round-off issues
        real(r8) :: dto2    ! dt/2 (s)
        real(r8) :: mincld  ! minimum allowed cloud fraction
        real(r8) :: q(pcols,pver) ! water vapor mixing ratio (kg/kg)
        real(r8) :: t(pcols,pver) ! temperature (K)
        real(r8) :: rho(pcols,pver) ! air density (kg m-3)
        real(r8) :: dv(pcols,pver)  ! diffusivity of water vapor in air
        real(r8) :: mu(pcols,pver)  ! viscocity of air
        real(r8) :: sc(pcols,pver)  ! schmidt number
        real(r8) :: kap(pcols,pver) ! thermal conductivity of air
        real(r8) :: rhof(pcols,pver) ! air density correction factor for fallspeed
        real(r8) :: cldmax(pcols,pver) ! precip fraction assuming maximum overlap
        real(r8) :: cldm(pcols,pver)   ! cloud fraction
        real(r8) :: icldm(pcols,pver)   ! ice cloud fraction
        real(r8) :: lcldm(pcols,pver)   ! liq cloud fraction
        real(r8) :: icwc(pcols)    ! in cloud water content (liquid+ice)
        real(r8) :: calpha(pcols)  ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: cbeta(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: cbetah(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: cgamma(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: cgamah(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: rcgama(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: cmec1(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: cmec2(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: cmec3(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: cmec4(pcols) ! parameter for cond/evap (Zhang et al. 2003)
        real(r8) :: qtmp ! dummy qv 
        real(r8) :: dum  ! temporary dummy variable

        real(r8) :: cme(pcols,pver)  ! total (liquid+ice) cond/evap rate of cloud

        real(r8) :: cmei(pcols,pver) ! dep/sublimation rate of cloud ice
        real(r8) :: cwml(pcols,pver) ! cloud water mixing ratio
        real(r8) :: cwmi(pcols,pver) ! cloud ice mixing ratio
        real(r8) :: nnuccd(pver)   ! ice nucleation rate from deposition/cond.-freezing
        real(r8) :: mnuccd(pver)   ! mass tendency from ice nucleation
        real(r8) :: qcld              ! total cloud water
        real(r8) :: lcldn(pcols,pver) ! fractional coverage of new liquid cloud
        real(r8) :: lcldo(pcols,pver) ! fractional coverage of old liquid cloud
	real(r8) :: nctend_mixnuc(pcols,pver)
	real(r8) :: arg ! argument of erfc

        ! for calculation of rate1ord_cw2pr_st
        real(r8) :: qcsinksum_rate1ord(pver)   ! sum over iterations of cw to precip sink
        real(r8) :: qcsum_rate1ord(pver)    ! sum over iterations of cloud water       

        real(r8) :: alpha

        real(r8) :: dum1,dum2   !general dummy variables

        real(r8) :: npccn(pver)     ! droplet activation rate
        real(r8) :: qcic(pcols,pver) ! in-cloud cloud liquid mixing ratio
        real(r8) :: qiic(pcols,pver) ! in-cloud cloud ice mixing ratio
        real(r8) :: qniic(pcols,pver) ! in-precip snow mixing ratio
        real(r8) :: qric(pcols,pver) ! in-precip rain mixing ratio
        real(r8) :: ncic(pcols,pver) ! in-cloud droplet number conc
        real(r8) :: niic(pcols,pver) ! in-cloud cloud ice number conc
        real(r8) :: nsic(pcols,pver) ! in-precip snow number conc
        real(r8) :: nric(pcols,pver) ! in-precip rain number conc
        real(r8) :: lami(pver) ! slope of cloud ice size distr
        real(r8) :: n0i(pver) ! intercept of cloud ice size distr
        real(r8) :: lamc(pver) ! slope of cloud liquid size distr
        real(r8) :: n0c(pver) ! intercept of cloud liquid size distr
        real(r8) :: lams(pver) ! slope of snow size distr
        real(r8) :: n0s(pver) ! intercept of snow size distr
        real(r8) :: lamr(pver) ! slope of rain size distr
        real(r8) :: n0r(pver) ! intercept of rain size distr
        real(r8) :: cdist1(pver) ! size distr parameter to calculate droplet freezing
! combined size of precip & cloud drops
        real(r8) :: rercld(pcols,pver) ! effective radius calculation for rain + cloud
        real(r8) :: arcld(pcols,pver) ! averaging control flag
        real(r8) :: Actmp  !area cross section of drops
        real(r8) :: Artmp  !area cross section of rain

        real(r8) :: pgam(pver) ! spectral width parameter of droplet size distr
        real(r8) :: lammax  ! maximum allowed slope of size distr
        real(r8) :: lammin  ! minimum allowed slope of size distr
        real(r8) :: nacnt   ! number conc of contact ice nuclei
        real(r8) :: mnuccc(pver) ! mixing ratio tendency due to freezing of cloud water
        real(r8) :: nnuccc(pver) ! number conc tendency due to freezing of cloud water

        real(r8) :: mnucct(pver) ! mixing ratio tendency due to contact freezing of cloud water
        real(r8) :: nnucct(pver) ! number conc tendency due to contact freezing of cloud water
        real(r8) :: msacwi(pver) ! mixing ratio tendency due to HM ice multiplication
        real(r8) :: nsacwi(pver) ! number conc tendency due to HM ice multiplication

        real(r8) :: prc(pver) ! qc tendency due to autoconversion of cloud droplets
        real(r8) :: nprc(pver) ! number conc tendency due to autoconversion of cloud droplets
        real(r8) :: nprc1(pver) ! qr tendency due to autoconversion of cloud droplets
        real(r8) :: nsagg(pver) ! ns tendency due to self-aggregation of snow
        real(r8) :: dc0  ! mean size droplet size distr
        real(r8) :: ds0  ! mean size snow size distr (area weighted)
        real(r8) :: eci  ! collection efficiency for riming of snow by droplets
        real(r8) :: psacws(pver) ! mixing rat tendency due to collection of droplets by snow
        real(r8) :: npsacws(pver) ! number conc tendency due to collection of droplets by snow
        real(r8) :: uni ! number-weighted cloud ice fallspeed
        real(r8) :: umi ! mass-weighted cloud ice fallspeed
        real(r8) :: uns(pver) ! number-weighted snow fallspeed
        real(r8) :: ums(pver) ! mass-weighted snow fallspeed
        real(r8) :: unr(pver) ! number-weighted rain fallspeed
        real(r8) :: umr(pver) ! mass-weighted rain fallspeed
        real(r8) :: unc ! number-weighted cloud droplet fallspeed
        real(r8) :: umc ! mass-weighted cloud droplet fallspeed
        real(r8) :: pracs(pver) ! mixing rat tendency due to collection of rain	by snow
        real(r8) :: npracs(pver) ! number conc tendency due to collection of rain by snow
        real(r8) :: mnuccr(pver) ! mixing rat tendency due to freezing of rain
        real(r8) :: nnuccr(pver) ! number conc tendency due to freezing of rain
        real(r8) :: pra(pver) ! mixing rat tendnency due to accretion of droplets by rain
        real(r8) :: npra(pver) ! nc tendnency due to accretion of droplets by rain
        real(r8) :: nragg(pver) ! nr tendency due to self-collection of rain
        real(r8) :: prci(pver) ! mixing rat tendency due to autoconversion of cloud ice to snow
        real(r8) :: nprci(pver) ! number conc tendency due to autoconversion of cloud ice to snow
        real(r8) :: prai(pver) ! mixing rat tendency due to accretion of cloud ice by snow
        real(r8) :: nprai(pver) ! number conc tendency due to accretion of cloud ice by snow
        real(r8) :: qvs ! liquid saturation vapor mixing ratio
        real(r8) :: qvi ! ice saturation vapor mixing ratio
        real(r8) :: dqsdt ! change of sat vapor mixing ratio with temperature
        real(r8) :: dqsidt ! change of ice sat vapor mixing ratio with temperature
        real(r8) :: ab ! correction factor for rain evap to account for latent heat
        real(r8) :: qclr ! water vapor mixing ratio in clear air
        real(r8) :: abi ! correction factor for snow sublimation to account for latent heat
        real(r8) :: epss ! 1/ sat relaxation timescale for snow
        real(r8) :: epsr ! 1/ sat relaxation timescale for rain
        real(r8) :: pre(pver) ! rain mixing rat tendency due to evaporation
        real(r8) :: prds(pver) ! snow mixing rat tendency due to sublimation
        real(r8) :: qce ! dummy qc for conservation check
        real(r8) :: qie ! dummy qi for conservation check
        real(r8) :: nce ! dummy nc for conservation check
        real(r8) :: nie ! dummy ni for conservation check
        real(r8) :: ratio ! parameter for conservation check
        real(r8) :: dumc(pcols,pver) ! dummy in-cloud qc
        real(r8) :: dumnc(pcols,pver) ! dummy in-cloud nc
        real(r8) :: dumi(pcols,pver) ! dummy in-cloud qi
        real(r8) :: dumni(pcols,pver) ! dummy in-cloud ni
        real(r8) :: dums(pcols,pver) ! dummy in-cloud snow mixing rat
        real(r8) :: dumns(pcols,pver) ! dummy in-cloud snow number conc
        real(r8) :: dumr(pcols,pver) ! dummy in-cloud rain mixing rat
        real(r8) :: dumnr(pcols,pver) ! dummy in-cloud rain number conc
! below are parameters for cloud water and cloud ice sedimentation calculations
        real(r8) :: fr(pver)
        real(r8) :: fnr(pver)
        real(r8) :: fc(pver)
        real(r8) :: fnc(pver)
        real(r8) :: fi(pver)
        real(r8) :: fni(pver)
        real(r8) :: fs(pver)
        real(r8) :: fns(pver)
        real(r8) :: faloutr(pver)
        real(r8) :: faloutnr(pver)
        real(r8) :: faloutc(pver)
        real(r8) :: faloutnc(pver)
        real(r8) :: falouti(pver)
        real(r8) :: faloutni(pver)
        real(r8) :: falouts(pver)
        real(r8) :: faloutns(pver)
        real(r8) :: faltndr
        real(r8) :: faltndnr
        real(r8) :: faltndc
        real(r8) :: faltndnc
        real(r8) :: faltndi
        real(r8) :: faltndni
        real(r8) :: faltnds
        real(r8) :: faltndns
        real(r8) :: faltndqie
        real(r8) :: faltndqce
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        real(r8) :: relhum(pcols,pver) ! relative humidity
        real(r8) :: csigma(pcols) ! parameter for cond/evap of cloud water/ice
        real(r8) :: rgvm ! max fallspeed for all species
        real(r8) :: arn(pcols,pver) ! air density corrected rain fallspeed parameter
        real(r8) :: asn(pcols,pver) ! air density corrected snow fallspeed parameter
        real(r8) :: acn(pcols,pver) ! air density corrected cloud droplet fallspeed parameter
        real(r8) :: ain(pcols,pver) ! air density corrected cloud ice fallspeed parameter
        real(r8) :: nsubi(pver) ! evaporation of cloud ice number
        real(r8) :: nsubc(pver) ! evaporation of droplet number
        real(r8) :: nsubs(pver) ! evaporation of snow number
        real(r8) :: nsubr(pver) ! evaporation of rain number
	real(r8) :: mtime ! factor to account for droplet activation timescale
	real(r8) :: dz(pcols,pver) ! height difference across model vertical level

!fice variable
	real(r8) :: nfice(pcols,pver)

	!! add precip flux variables for sub-stepping
	real(r8) :: rflx1(pcols,pver+1)
        real(r8) :: sflx1(pcols,pver+1)

! returns from function/subroutine calls
        real(r8) :: tsp(pcols,pver)      ! saturation temp (K)
        real(r8) :: qsp(pcols,pver)      ! saturation mixing ratio (kg/kg)
        real(r8) :: qsphy(pcols,pver)      ! saturation mixing ratio (kg/kg): hybrid rh
        real(r8) :: qs(pcols)            ! liquid-ice weighted sat mixing rat (kg/kg)
        real(r8) :: es(pcols)            ! liquid-ice weighted sat vapor press (pa)
        real(r8) :: esl(pcols,pver)      ! liquid sat vapor pressure (pa)
        real(r8) :: esi(pcols,pver)      ! ice sat vapor pressure (pa)
        real(r8) :: gammas(pcols)        ! parameter for cond/evap of cloud water

! sum of source/sink terms for diagnostic precip

        real(r8) :: qnitend(pcols,pver) ! snow mixing ratio source/sink term
        real(r8) :: nstend(pcols,pver)  ! snow number concentration source/sink term
        real(r8) :: qrtend(pcols,pver) ! rain mixing ratio source/sink term
        real(r8) :: nrtend(pcols,pver)  ! rain number concentration source/sink term
	real(r8) :: qrtot ! vertically-integrated rain mixing rat source/sink term
	real(r8) :: nrtot ! vertically-integrated rain number conc source/sink term
	real(r8) :: qstot ! vertically-integrated snow mixing rat source/sink term
	real(r8) :: nstot ! vertically-integrated snow number conc source/sink term

! new terms for Bergeron process

	real(r8) :: dumnnuc ! provisional ice nucleation rate (for calculating bergeron)
	real(r8) :: ninew  ! provisional cloud ice number conc (for calculating bergeron)
	real(r8) :: qinew ! provisional cloud ice mixing ratio (for calculating bergeron)
	real(r8) :: qvl  ! liquid sat mixing ratio   
	real(r8) :: epsi ! 1/ sat relaxation timecale for cloud ice
	real(r8) :: prd ! provisional deposition rate of cloud ice at water sat 
	real(r8) :: berg(pcols,pver) ! mixing rat tendency due to bergeron process for cloud ice
	real(r8) :: bergs(pver) ! mixing rat tendency due to bergeron process for snow

!bergeron terms
        real(r8) :: bergtsf   !bergeron timescale to remove all liquid
        real(r8) :: rhin      !modified RH for vapor deposition

! diagnostic rain/snow for output to history
! values are in-precip (local) !!!!

        real(r8), intent(out) :: qrout(pcols,pver)     ! grid-box average rain mixing ratio (kg/kg)
	real(r8), intent(out) :: reff_rain(pcols,pver) ! rain effective radius (micron)
	real(r8), intent(out) :: reff_snow(pcols,pver) ! snow effective radius (micron)
	real(r8) 	      :: drout(pcols,pver)     ! rain diameter (m)
#ifndef WRF_PORT
	real(r8) :: nrout(pcols,pver) ! rain number concentration (1/m3)
	real(r8) :: nsout(pcols,pver) ! snow number concentration (1/m3)
#else
        !WRF needs nrout and nsout to be the ouput variables
        real(r8), intent(out) :: nrout(pcols,pver) ! rain number concentration (1/m3)
	real(r8), intent(out) :: nsout(pcols,pver) ! snow number concentration (1/m3)
#endif
	real(r8), intent(out) :: dsout(pcols,pver) ! snow diameter (m)
	real(r8), intent(out) :: qsout(pcols,pver) ! snow mixing ratio (kg/kg)

!averageed rain/snow for history
	real(r8) :: qrout2(pcols,pver)
	real(r8) :: qsout2(pcols,pver)
	real(r8) :: nrout2(pcols,pver)
	real(r8) :: nsout2(pcols,pver)
	real(r8) :: freqs(pcols,pver)
	real(r8) :: freqr(pcols,pver)
	real(r8) :: dumfice
	real(r8) :: drout2(pcols,pver) ! mean rain particle diameter (m)
	real(r8) :: dsout2(pcols,pver) ! mean snow particle diameter (m)

!ice nucleation, droplet activation
        real(r8) :: dum2i(pcols,pver) ! number conc of ice nuclei available (1/kg)
        real(r8) :: dum2l(pcols,pver) ! number conc of CCN (1/kg)
	real(r8) :: ncmax
	real(r8) :: nimax

!output fields for number conc
        real(r8) :: ncai(pcols,pver) ! output number conc of ice nuclei available (1/m3)
        real(r8) :: ncal(pcols,pver) ! output number conc of CCN (1/m3)

! loop array variables
         integer i,k,nstep,n, l
	 integer ii,kk, m

! loop variables for sub-step solution
	 integer iter,it,ltrue(pcols)

! used in contact freezing via dust particles
        real(r8)  tcnt, viscosity, mfp
        real(r8)  slip1, slip2, slip3, slip4
!        real(r8)  dfaer1, dfaer2, dfaer3, dfaer4
!        real(r8)  nacon1,nacon2,nacon3,nacon4
        real(r8)  ndfaer1, ndfaer2, ndfaer3, ndfaer4
        real(r8)  nslip1, nslip2, nslip3, nslip4

! used in ice effective radius
        real(r8)  bbi, cci, ak, iciwc, rvi

! used in Bergeron processe and water vapor deposition
        real(r8)  Tk, deles, Aprpr, Bprpr, Cice, qi0, Crate, qidep

! mean cloud fraction over the time step
        real(r8)  cldmw(pcols,pver)

! used in secondary ice production
        real(r8) ni_secp

! variabels to check for RH after rain evap

	real(r8) :: esn
	real(r8) :: qsn
	real(r8) :: ttmp


        real(r8) :: refl(pcols,pver)    ! analytic radar reflectivity        
        real(r8) :: rainrt(pcols,pver)  ! rain rate for reflectivity calculation
        real(r8) :: rainrt1(pcols,pver)
 	real(r8) :: csrfl(pcols,pver)	!cloudsat reflectivity 
        real(r8) :: arefl(pcols,pver)  !average reflectivity will zero points outside valid range
  	real(r8) :: acsrfl(pcols,pver) !cloudsat average
 	real(r8) :: frefl(pcols,pver)
  	real(r8) :: fcsrfl(pcols,pver)
 	real(r8) :: areflz(pcols,pver)  !average reflectivity in z.
	real(r8) :: tmp

        real(r8) dmc,ssmc,dstrn  ! variables for modal scheme.
  
      real(r8), parameter :: cdnl    = 0.e6_r8    ! cloud droplet number limiter

!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

! initialize  output fields for number conc qand ice nucleation
    ncai(1:ncol,1:pver)=0._r8 
    ncal(1:ncol,1:pver)=0._r8  

!Initialize rain size
    rercld(1:ncol,1:pver)=0._r8
    arcld(1:ncol,1:pver)=0._r8

!initialize radiation output variables
        pgamrad(1:ncol,1:pver)=0._r8 ! liquid gamma parameter for optics (radiation)
        lamcrad(1:ncol,1:pver)=0._r8 ! slope of droplet distribution for optics (radiation)
        deffi  (1:ncol,1:pver)=0._r8 ! slope of droplet distribution for optics (radiation)
!initialize radiation output variables
!initialize water vapor tendency term output
        qcsevap(1:ncol,1:pver)=0._r8 
        qisevap(1:ncol,1:pver)=0._r8 
        qvres  (1:ncol,1:pver)=0._r8 
        cmeiout (1:ncol,1:pver)=0._r8
        vtrmc (1:ncol,1:pver)=0._r8
        vtrmi (1:ncol,1:pver)=0._r8
        qcsedten (1:ncol,1:pver)=0._r8
        qisedten (1:ncol,1:pver)=0._r8    

        prao(1:ncol,1:pver)=0._r8 
        prco(1:ncol,1:pver)=0._r8 
        mnuccco(1:ncol,1:pver)=0._r8 
        mnuccto(1:ncol,1:pver)=0._r8 
        msacwio(1:ncol,1:pver)=0._r8 
        psacwso(1:ncol,1:pver)=0._r8 
        bergso(1:ncol,1:pver)=0._r8 
        bergo(1:ncol,1:pver)=0._r8 
        melto(1:ncol,1:pver)=0._r8 
        homoo(1:ncol,1:pver)=0._r8 
        qcreso(1:ncol,1:pver)=0._r8 
        prcio(1:ncol,1:pver)=0._r8 
        praio(1:ncol,1:pver)=0._r8 
        qireso(1:ncol,1:pver)=0._r8 
        mnuccro(1:ncol,1:pver)=0._r8 
        pracso (1:ncol,1:pver)=0._r8 
        meltsdt(1:ncol,1:pver)=0._r8
        frzrdt (1:ncol,1:pver)=0._r8
        mnuccdo(1:ncol,1:pver)=0._r8

! assign variable deltat for sub-stepping...
	deltat=deltatin	

! parameters for scheme

        omsm=0.99999_r8
        dto2=0.5_r8*deltat
	mincld=0.0001_r8
 
! initialize multi-level fields
        q(1:ncol,1:pver)=qn(1:ncol,1:pver)
        t(1:ncol,1:pver)=tn(1:ncol,1:pver)
	
! initialize time-varying parameters

        do k=1,pver
           do i=1,ncol
        rho(i,k)=p(i,k)/(r*t(i,k))
	dv(i,k) = 8.794E-5_r8*t(i,k)**1.81_r8/p(i,k)
	mu(i,k) = 1.496E-6_r8*t(i,k)**1.5_r8/ &
             (t(i,k)+120._r8)	
	sc(i,k) = mu(i,k)/(rho(i,k)*dv(i,k))
	kap(i,k) = 1.414e3_r8*1.496e-6_r8*t(i,k)** &
            1.5_r8/(t(i,k)+120._r8) 

! air density adjustment for fallspeed parameters
! includes air density correction factor to the
! power of 0.54 following Heymsfield and Bansemer 2007

	rhof(i,k)=(rhosu/rho(i,k))**0.54

        arn(i,k)=ar*rhof(i,k)
        asn(i,k)=as*rhof(i,k)
        acn(i,k)=ac*rhof(i,k)
        ain(i,k)=ai*rhof(i,k)

! get dz from dp and hydrostatic approx
! keep dz positive (define as layer k-1 - layer k)

        dz(i,k)= pdel(i,k)/(rho(i,k)*g)

        end do
        end do

! initialization
        t1(1:ncol,1:pver) = t(1:ncol,1:pver)
	q1(1:ncol,1:pver) = q(1:ncol,1:pver)
	qc1(1:ncol,1:pver) = qc(1:ncol,1:pver)
	qi1(1:ncol,1:pver) = qi(1:ncol,1:pver)
	nc1(1:ncol,1:pver) = nc(1:ncol,1:pver)
	ni1(1:ncol,1:pver) = ni(1:ncol,1:pver)

! initialize tendencies to zero
        tlat1(1:ncol,1:pver)=0._r8
	qvlat1(1:ncol,1:pver)=0._r8
	qctend1(1:ncol,1:pver)=0._r8
	qitend1(1:ncol,1:pver)=0._r8
	nctend1(1:ncol,1:pver)=0._r8
	nitend1(1:ncol,1:pver)=0._r8

! initialize precip output
	qrout(1:ncol,1:pver)=0._r8
	qsout(1:ncol,1:pver)=0._r8
	nrout(1:ncol,1:pver)=0._r8
	nsout(1:ncol,1:pver)=0._r8
        dsout(1:ncol,1:pver)=0._r8

        drout(1:ncol,1:pver)=0._r8
        !! initialize as fillvalue to avoid Floating Exceptions
	reff_rain(1:ncol,1:pver)=fillvalue
        reff_snow(1:ncol,1:pver)=fillvalue

! initialize variables for trop_mozart
	nevapr(1:ncol,1:pver) = 0._r8
	evapsnow(1:ncol,1:pver) = 0._r8
	prain(1:ncol,1:pver) = 0._r8
	prodsnow(1:ncol,1:pver) = 0._r8
	cmeout(1:ncol,1:pver) = 0._r8

! for refl calc
        rainrt1(1:ncol,1:pver) = 0._r8

! initialize precip fraction and output tendencies
        cldmax(1:ncol,1:pver)=mincld

!initialize aerosol number
!        naer2(1:ncol,1:pver,:)=0._r8
        dum2l(1:ncol,1:pver)=0._r8
        dum2i(1:ncol,1:pver)=0._r8

! initialize avg precip rate
	prect1(1:ncol)=0._r8
	preci1(1:ncol)=0._r8

!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
!Get humidity and saturation vapor pressures

        do k=1,pver

! find wet bulk temperature and saturation value for provisional t and q without
! condensation

        call vqsatd_water(t(1,k),p(1,k),es,qs,gammas,ncol) ! use rhw

        do i=1,ncol

	esl(i,k)=polysvp(t(i,k),0)
	esi(i,k)=polysvp(t(i,k),1)

! hm fix, make sure when above freezing that esi=esl, not active yet
	if (t(i,k).gt.tmelt)esi(i,k)=esl(i,k)

        relhum(i,k)=q(i,k)/qs(i)

! get cloud fraction, check for minimum

           cldm(i,k)=max(cldn(i,k),mincld)
           cldmw(i,k)=max(cldn(i,k),mincld)

           icldm(i,k)=max(icecldf(i,k),mincld)
           lcldm(i,k)=max(liqcldf(i,k),mincld)

! subcolumns, set cloud fraction variables to one
! if cloud water or ice is present, if not present
! set to mincld (mincld used instead of zero, to prevent
! possible division by zero errors

           if (sub_column) then

              cldm(i,k)=mincld
              cldmw(i,k)=mincld
              icldm(i,k)=mincld
              lcldm(i,k)=mincld
              
              if (qc(i,k).ge.qsmall) then
                 lcldm(i,k)=1.           
                 cldm(i,k)=1.
                 cldmw(i,k)=1.
              end if
              
              if (qi(i,k).ge.qsmall) then             
                 cldm(i,k)=1.
                 icldm(i,k)=1.
              end if
              
           end if               ! sub-columns

! calculate nfice based on liquid and ice mmr (no rain and snow mmr available yet)

        nfice(i,k)=0._r8
        dumfice=qc(i,k)+qi(i,k)
        if (dumfice.gt.qsmall .and. qi(i,k).gt.qsmall) then
           nfice(i,k)=qi(i,k)/dumfice
        endif

	if (t(i,k).lt.tmelt - 5._r8) then
           if (liu_in) then 

! if aerosols interact with ice set number of activated ice nuclei
              dum2=naai(i,k)

           else
! cooper curve (factor of 1000 is to convert from L-1 to m-3)
              dum2=0.005_r8*exp(0.304_r8*(273.15_r8-t(i,k)))*1000._r8
! put limit on number of nucleated crystals, set to number at T=-30 C
! cooper (limit to value at -35 C)
              dum2=min(dum,208.9e3_r8)/rho(i,k) ! convert from m-3 to kg-1
           endif

           dumnnuc=(dum2-ni(i,k)/icldm(i,k))/deltat*icldm(i,k)
           dumnnuc=max(dumnnuc,0._r8)
! get provisional ni and qi after nucleation in order to calculate
! Bergeron process below
           ninew=ni(i,k)+dumnnuc*deltat
           qinew=qi(i,k)+dumnnuc*deltat*mi0
!T>268
        else
           ninew=ni(i,k)
           qinew=qi(i,k)
        end if

! Initialize CME components

  cme(i,k) = 0._r8
  cmei(i,k)=0._r8


!-------------------------------------------------------------------
!Bergeron process

! make sure to initialize bergeron process to zero
       berg(i,k)=0._r8
       prd = 0._r8

!condensation loop.

! get in-cloud qi and ni after nucleation
       if (icldm(i,k) .gt. 0._r8) then 
          qiic(i,k)=qinew/icldm(i,k)
          niic(i,k)=ninew/icldm(i,k)
       else
          qiic(i,k)=0._r8
          niic(i,k)=0._r8
       endif

!if T < 0 C then bergeron.
           if (t(i,k).lt.273.15) then
!if ice exists
              if (qi(i,k).gt.qsmall) then

                 bergtsf = 0._r8 ! bergeron time scale (fraction of timestep)

                    qvi=epsqs*esi(i,k)/(p(i,k)-(1._r8-epsqs)*esi(i,k))
                    qvl=epsqs*esl(i,k)/(p(i,k)-(1._r8-epsqs)*esl(i,k))

                    dqsidt =  xxls*qvi/(rv*t(i,k)**2)
                    abi = 1._r8+dqsidt*xxls/cpp

! get ice size distribution parameters

                    if (qiic(i,k).ge.qsmall) then
                       lami(k) = (cons1*ci* &
                       niic(i,k)/qiic(i,k))**(1._r8/di)
                       n0i(k) = niic(i,k)*lami(k)

! check for slope
! adjust vars
                       if (lami(k).lt.lammini) then

                          lami(k) = lammini
                          n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
                       else if (lami(k).gt.lammaxi) then
                          lami(k) = lammaxi
                          n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
                       end if
                    
                       epsi = 2._r8*pi*n0i(k)*rho(i,k)*Dv(i,k) &
                       /(lami(k)*lami(k))

!if liquid exists  
                 if (qc(i,k).gt. qsmall) then 

!begin bergeron process
!     do bergeron (vapor deposition with RHw=1)
!     code to find berg (a rate) goes here

! calculate Bergeron process

                       prd = epsi*(qvl-qvi)/abi
                    
                    else
                       prd = 0._r8
                    end if

! multiply by cloud fraction

                    prd = prd*min(icldm(i,k),lcldm(i,k))

!     transfer of existing cloud liquid to ice

                    berg(i,k)=max(0._r8,prd)

                 end if  !end liquid exists bergeron

                 if (berg(i,k).gt.0._r8) then
                    bergtsf=max(0._r8,(qc(i,k)/berg(i,k))/deltat) 

                    if(bergtsf.lt.1._r8) berg(i,k) = max(0._r8,qc(i,k)/deltat)

                 endif

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                 if (bergtsf.lt.1._r8.or.icldm(i,k).gt.lcldm(i,k)) then

			if (qiic(i,k).ge.qsmall) then

! first case is for case when liquid water is present, but is completely depleted in time step, i.e., bergrsf > 0 but < 1

		if (qc(i,k).ge.qsmall) then
                       rhin  = (1.0_r8 + relhum(i,k)) / 2._r8
                       if ((rhin*esl(i,k)/esi(i,k)) > 1._r8) then
                          prd = epsi*(rhin*qvl-qvi)/abi

! multiply by cloud fraction assuming liquid/ice maximum overlap
                          prd = prd*min(icldm(i,k),lcldm(i,k))

! add to cmei
                          cmei(i,k) = cmei(i,k) + (prd * (1._r8- bergtsf))

	                end if ! rhin 
	        end if ! qc > qsmall

! second case is for pure ice cloud, either no liquid, or icldm > lcldm

		if (qc(i,k).lt.qsmall.or.icldm(i,k).gt.lcldm(i,k)) then

! note: for case of no liquid, need to set liquid cloud fraction to zero
! store liquid cloud fraction in 'dum'

			if (qc(i,k).lt.qsmall) then 
			dum=0._r8 
			else
			dum=lcldm(i,k)
			end if

! set RH to grid-mean value for pure ice cloud
                       rhin = relhum(i,k)

                if ((rhin*esl(i,k)/esi(i,k)) > 1._r8) then

                       prd = epsi*(rhin*qvl-qvi)/abi

! multiply by relevant cloud fraction for pure ice cloud
! assuming maximum overlap of liquid/ice
                       prd = prd*max((icldm(i,k)-dum),0._r8)
                       cmei(i,k) = cmei(i,k) + prd

		end if ! rhin
		end if ! qc or icldm > lcldm
	end if ! qiic
	end if ! bergtsf or icldm > lcldm

!     if deposition, it should not reduce grid mean rhi below 1.0
                 if(cmei(i,k) > 0.0_r8 .and. (relhum(i,k)*esl(i,k)/esi(i,k)) > 1._r8 ) &
                  cmei(i,k)=min(cmei(i,k),(q(i,k)-qs(i)*esi(i,k)/esl(i,k))/abi/deltat)

              end if            !end ice exists loop
   !this ends temperature < 0. loop

!-------------------------------------------------------------------
           end if  ! 
!..............................................................

! evaporation should not exceed available water

           if ((-berg(i,k)).lt.-qc(i,k)/deltat) &
             berg(i,k) = max(qc(i,k)/deltat,0._r8)

!sublimation process...

            if ((relhum(i,k)*esl(i,k)/esi(i,k)).lt.1._r8 .and. qiic(i,k).ge.qsmall ) then

               qvi=epsqs*esi(i,k)/(p(i,k)-(1._r8-epsqs)*esi(i,k))
               qvl=epsqs*esl(i,k)/(p(i,k)-(1._r8-epsqs)*esl(i,k))
               dqsidt =  xxls*qvi/(rv*t(i,k)**2)
               abi = 1._r8+dqsidt*xxls/cpp

! get ice size distribution parameters

               lami(k) = (cons1*ci* &
               niic(i,k)/qiic(i,k))**(1._r8/di)
               n0i(k) = niic(i,k)*lami(k)

! check for slope
! adjust vars
               if (lami(k).lt.lammini) then
                  
                  lami(k) = lammini
                  n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
               else if (lami(k).gt.lammaxi) then
                  lami(k) = lammaxi
                  n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
               end if
                    
               epsi = 2._r8*pi*n0i(k)*rho(i,k)*Dv(i,k) &
               /(lami(k)*lami(k))

! modify for ice fraction below
               prd = epsi*(relhum(i,k)*qvl-qvi)/abi * icldm(i,k)
               cmei(i,k)=min(prd,0._r8)

            endif

! sublimation should not exceed available ice
           if (cmei(i,k).lt.-qi(i,k)/deltat) &
              cmei(i,k)=-qi(i,k)/deltat

! sublimation should not increase grid mean rhi above 1.0 
           if(cmei(i,k) < 0.0_r8 .and. (relhum(i,k)*esl(i,k)/esi(i,k)) < 1._r8 ) &
              cmei(i,k)=min(0._r8,max(cmei(i,k),(q(i,k)-qs(i)*esi(i,k)/esl(i,k))/abi/deltat))

! limit cmei due for roundoff error

           cmei(i,k)=cmei(i,k)*omsm

! conditional for ice nucleation 

        if (t(i,k).lt.(tmelt - 5._r8)) then 
          if ( liu_in ) then 

! using Liu et al. (2007) ice nucleation with hooks into simulated aerosol
! ice nucleation rate (dum2) has already been calculated and read in (naai)

             dum2i(i,k)=naai(i,k)
          else

! cooper curve (factor of 1000 is to convert from L-1 to m-3)
              dum2i(i,k)=0.005_r8*exp(0.304_r8*(273.15_r8-t(i,k)))*1000._r8
! put limit on number of nucleated crystals, set to number at T=-30 C
! cooper (limit to value at -35 C)
              dum2i(i,k)=min(dum2i(i,k),208.9e3_r8)/rho(i,k) ! convert from m-3 to kg-1
           endif
        else
           dum2i(i,k)=0._r8
	end if

	end do ! i loop
	end do ! k loop

 
     cldo(:ncol,:)=cldn(:ncol,:)

!! initialize sub-step precip flux variables
	do i=1,ncol
	   !! flux is zero at top interface, so these should stay as 0.
           rflx1(i,1)=0._r8
           sflx1(i,1)=0._r8
	do k=1,pver

	   ! initialize normal and sub-step precip flux variables
           rflx1(i,k+1)=0._r8
           sflx1(i,k+1)=0._r8
	end do ! i loop
	end do ! k loop
!! initialize final precip flux variables.
	do i=1,ncol
	   !! flux is zero at top interface, so these should stay as 0.
           rflx(i,1)=0._r8
           sflx(i,1)=0._r8
	do k=1,pver
	   ! initialize normal and sub-step precip flux variables
           rflx(i,k+1)=0._r8
           sflx(i,k+1)=0._r8
	end do ! i loop
	end do ! k loop	

	do i=1,ncol
	ltrue(i)=0
	do k=1,pver
! skip microphysical calculations if no cloud water

	if (qc(i,k).ge.qsmall.or.qi(i,k).ge.qsmall.or.cmei(i,k).ge.qsmall) ltrue(i)=1
	end do
	end do

! assign number of sub-steps to iter
! use 2 sub-steps, following tests described in MG2008
	iter = 2

! get sub-step time step
	deltat=deltat/real(iter)

! since activation/nucleation processes are fast, need to take into account
! factor mtime = mixing timescale in cloud / model time step
! mixing time can be interpreted as cloud depth divided by sub-grid vertical velocity
! for now mixing timescale is assumed to be 1 timestep for modal aerosols, 20 min bulk

!        note: mtime for bulk aerosols was set to: mtime=deltat/1200._r8

        mtime=1._r8
        rate1ord_cw2pr_st(:,:)=0._r8 ! rce 2010/05/01

!!!! skip calculations if no cloud water
	do i=1,ncol
	if (ltrue(i).eq.0) then
           tlat(i,1:pver)=0._r8
           qvlat(i,1:pver)=0._r8
           qctend(i,1:pver)=0._r8
           qitend(i,1:pver)=0._r8
           qnitend(i,1:pver)=0._r8
           qrtend(i,1:pver)=0._r8
           nctend(i,1:pver)=0._r8
           nitend(i,1:pver)=0._r8
           nrtend(i,1:pver)=0._r8
           nstend(i,1:pver)=0._r8
           prect(i)=0._r8
           preci(i)=0._r8
           qniic(i,1:pver)=0._r8
           qric(i,1:pver)=0._r8
           nsic(i,1:pver)=0._r8
           nric(i,1:pver)=0._r8
           rainrt(i,1:pver)=0._r8
	goto 300
	end if

        qcsinksum_rate1ord(1:pver)=0._r8 
        qcsum_rate1ord(1:pver)=0._r8 


!!!!!!!!! begin sub-step!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!.....................................................................................................
	do it=1,iter

! initialize sub-step microphysical tendencies

	tlat(i,1:pver)=0._r8
	qvlat(i,1:pver)=0._r8
	qctend(i,1:pver)=0._r8
	qitend(i,1:pver)=0._r8
	qnitend(i,1:pver)=0._r8
	qrtend(i,1:pver)=0._r8
	nctend(i,1:pver)=0._r8
	nitend(i,1:pver)=0._r8
	nrtend(i,1:pver)=0._r8
	nstend(i,1:pver)=0._r8

! initialize diagnostic precipitation to zero

        qniic(i,1:pver)=0._r8
        qric(i,1:pver)=0._r8
        nsic(i,1:pver)=0._r8
        nric(i,1:pver)=0._r8
 
        rainrt(i,1:pver)=0._r8


! begin new i,k loop, calculate new cldmax after adjustment to cldm above

! initialize vertically-integrated rain and snow tendencies

	   qrtot = 0._r8
	   nrtot = 0._r8
	   qstot = 0._r8
	   nstot = 0._r8

! initialize precip at surface

	   prect(i)=0._r8
	   preci(i)=0._r8

	   do k=1,pver

! set cwml and cwmi to current qc and qi

	   cwml(i,k)=qc(i,k)
	   cwmi(i,k)=qi(i,k)

! initialize precip fallspeeds to zero

	   ums(k)=0._r8 
	   uns(k)=0._r8 
	   umr(k)=0._r8 
	   unr(k)=0._r8

! calculate precip fraction based on maximum overlap assumption

! for sub-columns cldm has already been set to 1 if cloud
! water or ice is present, so cldmax will be correctly set below
! and nothing extra needs to be done here

           if (k.eq.1) then
		cldmax(i,k)=cldm(i,k)
	   else
! if rain or snow mix ratio is smaller than
! threshold, then set cldmax to cloud fraction at current level
	   if (qric(i,k-1).ge.qsmall.or.qniic(i,k-1).ge.qsmall) then
                cldmax(i,k)=max(cldmax(i,k-1),cldm(i,k))
	   else
	   cldmax(i,k)=cldm(i,k)
	   end if
	   end if

! decrease in number concentration due to sublimation/evap
! divide by cloud fraction to get in-cloud decrease
! don't reduce Nc due to bergeron process

           if (cmei(i,k) < 0._r8 .and. qi(i,k) > qsmall .and. cldm(i,k) > mincld) then
              nsubi(k)=cmei(i,k)/qi(i,k)*ni(i,k)/cldm(i,k)
	   else
              nsubi(k)=0._r8
           end if
           nsubc(k)=0._r8


!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

! ice nucleation if activated nuclei exist at t<-5C AND rhmini + 5%

        if (dum2i(i,k).gt.0._r8.and.t(i,k).lt.(tmelt - 5._r8).and. &
	   relhum(i,k)*esl(i,k)/esi(i,k).gt. rhmini+0.05_r8) then

!if NCAI > 0. then set numice = ncai (as before)
!note: this is gridbox averaged

              nnuccd(k)=(dum2i(i,k)-ni(i,k)/icldm(i,k))/deltat*icldm(i,k)
              nnuccd(k)=max(nnuccd(k),0._r8)
              nimax = dum2i(i,k)*icldm(i,k)

!Calc mass of new particles using new crystal mass...
!also this will be multiplied by mtime as nnuccd is...

              mnuccd(k) = nnuccd(k) * mi0

!  add mnuccd to cmei....
              cmei(i,k)= cmei(i,k) + mnuccd(k) * mtime

!  limit cmei

               qvi=epsqs*esi(i,k)/(p(i,k)-(1._r8-epsqs)*esi(i,k))
               dqsidt =  xxls*qvi/(rv*t(i,k)**2)
               abi = 1._r8+dqsidt*xxls/cpp
              cmei(i,k)=min(cmei(i,k),(q(i,k)-qvi)/abi/deltat)

! limit for roundoff error
              cmei(i,k)=cmei(i,k)*omsm

           else
              nnuccd(k)=0._r8
	      nimax = 0._r8
              mnuccd(k) = 0._r8
           end if

!c............................................................................
!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
! obtain in-cloud values of cloud water/ice mixing ratios and number concentrations
! for microphysical process calculations
! units are kg/kg for mixing ratio, 1/kg for number conc

! limit in-cloud values to 0.005 kg/kg

           qcic(i,k)=min(cwml(i,k)/lcldm(i,k),5.e-3_r8)
           qiic(i,k)=min(cwmi(i,k)/icldm(i,k),5.e-3_r8)
           ncic(i,k)=max(nc(i,k)/lcldm(i,k),0._r8)
           niic(i,k)=max(ni(i,k)/icldm(i,k),0._r8)

           if (qc(i,k) - berg(i,k)*deltat.lt.qsmall) then
              qcic(i,k)=0._r8
              ncic(i,k)=0._r8
              if (qc(i,k)-berg(i,k)*deltat.lt.0._r8) then
                 berg(i,k)=qc(i,k)/deltat*omsm
              end if
	   end if

	   if (qi(i,k)+(cmei(i,k)+berg(i,k))*deltat.lt.qsmall) then
	   qiic(i,k)=0._r8
	   niic(i,k)=0._r8
	   if (qi(i,k)+(cmei(i,k)+berg(i,k))*deltat.lt.0._r8) then
	   cmei(i,k)=(-qi(i,k)/deltat-berg(i,k))*omsm
	   end if
	   end if

! add to cme output

           cmeout(i,k) = cmeout(i,k)+cmei(i,k)

!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
! droplet activation
! calculate potential for droplet activation if cloud water is present
! formulation from Abdul-Razzak and Ghan (2000) and Abdul-Razzak et al. (1998), AR98
! number tendency (npccnin) is read in from companion routine

! assume aerosols already activated are equal to number of existing droplets for simplicity
! multiply by cloud fraction to obtain grid-average tendency

           if (qcic(i,k).ge.qsmall) then   
              npccn(k) = max(0._r8,npccnin(i,k))  
	      dum2l(i,k)=(nc(i,k)+npccn(k)*deltat)/lcldm(i,k)
              dum2l(i,k)=max(dum2l(i,k),cdnl/rho(i,k)) ! sghan minimum in #/cm3  
	      ncmax = dum2l(i,k)*lcldm(i,k)
           else
              npccn(k)=0._r8
              dum2l(i,k)=0._r8
              ncmax = 0._r8
           end if 

!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
! get size distribution parameters based on in-cloud cloud water/ice 
! these calculations also ensure consistency between number and mixing ratio
!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

!......................................................................
! cloud ice

	if (qiic(i,k).ge.qsmall) then

! add upper limit to in-cloud number concentration to prevent numerical error
	niic(i,k)=min(niic(i,k),qiic(i,k)*1.e20_r8)

	lami(k) = (cons1*ci* &
              niic(i,k)/qiic(i,k))**(1._r8/di)
	n0i(k) = niic(i,k)*lami(k)

! check for slope
! adjust vars

	if (lami(k).lt.lammini) then

	lami(k) = lammini
	n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
	niic(i,k) = n0i(k)/lami(k)
	else if (lami(k).gt.lammaxi) then
	lami(k) = lammaxi
	n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1)
        niic(i,k) = n0i(k)/lami(k)
	end if

	else
	lami(k) = 0._r8
	n0i(k) = 0._r8
	end if

	if (qcic(i,k).ge.qsmall) then

! add upper limit to in-cloud number concentration to prevent numerical error
	ncic(i,k)=min(ncic(i,k),qcic(i,k)*1.e20_r8)

        ncic(i,k)=max(ncic(i,k),cdnl/rho(i,k)) ! sghan minimum in #/cm  

! get pgam from fit to observations of martin et al. 1994

        pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8
        pgam(k)=1._r8/(pgam(k)**2)-1._r8
        pgam(k)=max(pgam(k),2._r8)
        pgam(k)=min(pgam(k),15._r8)

! calculate lamc

	lamc(k) = (pi/6._r8*rhow*ncic(i,k)*gamma(pgam(k)+4._r8)/ &
                 (qcic(i,k)*gamma(pgam(k)+1._r8)))**(1._r8/3._r8)

! lammin, 50 micron diameter max mean size

	lammin = (pgam(k)+1._r8)/50.e-6_r8
	lammax = (pgam(k)+1._r8)/2.e-6_r8

	if (lamc(k).lt.lammin) then
	lamc(k) = lammin
	ncic(i,k) = 6._r8*lamc(k)**3*qcic(i,k)* &
                gamma(pgam(k)+1._r8)/ &
               (pi*rhow*gamma(pgam(k)+4._r8))
	else if (lamc(k).gt.lammax) then
	lamc(k) = lammax
	ncic(i,k) = 6._r8*lamc(k)**3*qcic(i,k)* &
                gamma(pgam(k)+1._r8)/ &
               (pi*rhow*gamma(pgam(k)+4._r8))
	end if

! parameter to calculate droplet freezing

        cdist1(k) = ncic(i,k)/gamma(pgam(k)+1._r8) 

	else
	lamc(k) = 0._r8
        cdist1(k) = 0._r8
	end if

!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
! begin micropysical process calculations 
!.................................................................
! autoconversion of cloud liquid water to rain
! formula from Khrouditnov and Kogan (2000), modified for sub-grid distribution of qc
! minimum qc of 1 x 10^-8 prevents floating point error

	if (qcic(i,k).ge.1.e-8_r8) then

! nprc is increase in rain number conc due to autoconversion
! nprc1 is decrease in cloud droplet conc due to autoconversion

! assume exponential sub-grid distribution of qc, resulting in additional
! factor related to qcvar below

 ! hm switch for sub-columns, don't include sub-grid qc
           if (sub_column) then
 
              prc(k) = 1350._r8*qcic(i,k)**2.47_r8* &
              (ncic(i,k)/1.e6_r8*rho(i,k))**(-1.79_r8)
              nprc(k) = prc(k)/(4._r8/3._r8*pi*rhow*(25.e-6_r8)**3)
              nprc1(k) = prc(k)/(qcic(i,k)/ncic(i,k))
 
           else

              prc(k) = cons2/(cons3*cons18)*1350._r8*qcic(i,k)**2.47_r8* &
              (ncic(i,k)/1.e6_r8*rho(i,k))**(-1.79_r8)
              nprc(k) = prc(k)/cons22
              nprc1(k) = prc(k)/(qcic(i,k)/ncic(i,k))
 
           end if               ! sub-column switch

        else
           prc(k)=0._r8
           nprc(k)=0._r8
	   nprc1(k)=0._r8
	end if
 
! add autoconversion to precip from above to get provisional rain mixing ratio
! and number concentration (qric and nric)

! 0.45 m/s is fallspeed of new rain drop (80 micron diameter)

	dum=0.45_r8
	dum1=0.45_r8

	if (k.eq.1) then
	qric(i,k)=prc(k)*lcldm(i,k)*dz(i,k)/cldmax(i,k)/dum
	nric(i,k)=nprc(k)*lcldm(i,k)*dz(i,k)/cldmax(i,k)/dum
	else
	if (qric(i,k-1).ge.qsmall) then
	dum=umr(k-1)
	dum1=unr(k-1)
	end if

! no autoconversion of rain number if rain/snow falling from above
! this assumes that new drizzle drops formed by autoconversion are rapidly collected
! by the existing rain/snow particles from above

	if (qric(i,k-1).ge.1.e-9_r8.or.qniic(i,k-1).ge.1.e-9_r8) then
	nprc(k)=0._r8
	end if

        qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)*cldmax(i,k-1)+ &
         (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))))&
                   /(dum*rho(i,k)*cldmax(i,k))
	nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)*cldmax(i,k-1)+ &
         (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))))&
                   /(dum1*rho(i,k)*cldmax(i,k))

	end if

!.......................................................................
! Autoconversion of cloud ice to snow
! similar to Ferrier (1994)

	if (t(i,k).le.273.15_r8.and.qiic(i,k).ge.qsmall) then

! note: assumes autoconversion timescale of 180 sec

           nprci(k) = n0i(k)/(lami(k)*180._r8)*exp(-lami(k)*dcs)

           prci(k) = pi*rhoi*n0i(k)/(6._r8*180._r8)* &
              (cons23/lami(k)+3._r8*cons24/lami(k)**2+ &
          6._r8*dcs/lami(k)**3+6._r8/lami(k)**4)*exp(-lami(k)*dcs)          

        else
              prci(k)=0._r8
              nprci(k)=0._r8
	end if

! add autoconversion to flux from level above to get provisional snow mixing ratio
! and number concentration (qniic and nsic)

	dum=(asn(i,k)*cons25)
	dum1=(asn(i,k)*cons25)

	if (k.eq.1) then
           qniic(i,k)=prci(k)*icldm(i,k)*dz(i,k)/cldmax(i,k)/dum
           nsic(i,k)=nprci(k)*icldm(i,k)*dz(i,k)/cldmax(i,k)/dum
	else
	if (qniic(i,k-1).ge.qsmall) then
	dum=ums(k-1)
	dum1=uns(k-1)
	end if

        qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)*cldmax(i,k-1)+ &
         (rho(i,k)*dz(i,k)*((prci(k)+prai(k-1)+psacws(k-1)+bergs(k-1))*icldm(i,k)+(prds(k-1)+ &
         pracs(k-1)+mnuccr(k-1))*cldmax(i,k))))&
                    /(dum*rho(i,k)*cldmax(i,k))

	nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)*cldmax(i,k-1)+ &
         (rho(i,k)*dz(i,k)*(nprci(k)*icldm(i,k)+(nsubs(k-1)+nsagg(k-1)+nnuccr(k-1))*cldmax(i,k))))&
                   /(dum1*rho(i,k)*cldmax(i,k))

	end if

! if precip mix ratio is zero so should number concentration

	if (qniic(i,k).lt.qsmall) then
	qniic(i,k)=0._r8
	nsic(i,k)=0._r8
	end if

	if (qric(i,k).lt.qsmall) then
	qric(i,k)=0._r8
	nric(i,k)=0._r8
	end if

! make sure number concentration is a positive number to avoid 
! taking root of negative later

	nric(i,k)=max(nric(i,k),0._r8)
	nsic(i,k)=max(nsic(i,k),0._r8)

!.......................................................................
! get size distribution parameters for precip
!......................................................................
! rain

	if (qric(i,k).ge.qsmall) then
	lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))**(1._r8/3._r8)
	n0r(k) = nric(i,k)*lamr(k)

! check for slope
! adjust vars

	if (lamr(k).lt.lamminr) then

	lamr(k) = lamminr

	n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow)
	nric(i,k) = n0r(k)/lamr(k)
	else if (lamr(k).gt.lammaxr) then
	lamr(k) = lammaxr
	n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow)
	nric(i,k) = n0r(k)/lamr(k)
	end if

! provisional rain number and mass weighted mean fallspeed (m/s)

        unr(k) = min(arn(i,k)*cons4/lamr(k)**br,9.1_r8*rhof(i,k))
        umr(k) = min(arn(i,k)*cons5/(6._r8*lamr(k)**br),9.1_r8*rhof(i,k))

	else
	lamr(k) = 0._r8
	n0r(k) = 0._r8
	umr(k) = 0._r8
	unr(k) = 0._r8
	end if

!......................................................................
! snow

	if (qniic(i,k).ge.qsmall) then
	lams(k) = (cons6*cs*nsic(i,k)/ &
            qniic(i,k))**(1._r8/ds)
	n0s(k) = nsic(i,k)*lams(k)

! check for slope
! adjust vars

	if (lams(k).lt.lammins) then
	lams(k) = lammins
	n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6)
	nsic(i,k) = n0s(k)/lams(k)

	else if (lams(k).gt.lammaxs) then
	lams(k) = lammaxs
	n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6)
	nsic(i,k) = n0s(k)/lams(k)
	end if

! provisional snow number and mass weighted mean fallspeed (m/s)

        ums(k) = min(asn(i,k)*cons8/(6._r8*lams(k)**bs),1.2_r8*rhof(i,k))
        uns(k) = min(asn(i,k)*cons7/lams(k)**bs,1.2_r8*rhof(i,k))

	else
	lams(k) = 0._r8
	n0s(k) = 0._r8
	ums(k) = 0._r8
	uns(k) = 0._r8
	end if

!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

! heterogeneous freezing of cloud water

	if (qcic(i,k).ge.qsmall .and. t(i,k).lt.269.15_r8) then

! immersion freezing (Bigg, 1953)

 
! subcolumns
           
           if (sub_column) then
 
              mnuccc(k) = &
                       pi*pi/36._r8*rhow* &
                   cdist1(k)*gamma(7._r8+pgam(k))* &
                    bimm*(exp(aimm*(273.15_r8-t(i,k)))-1._r8)/ &
                    lamc(k)**3/lamc(k)**3
 
              nnuccc(k) = &
                    pi/6._r8*cdist1(k)*gamma(pgam(k)+4._r8) &
                    *bimm* &
                    (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamc(k)**3
 
           else
 
              mnuccc(k) = cons9/(cons3*cons19)* &
                      pi*pi/36._r8*rhow* &
                  cdist1(k)*gamma(7._r8+pgam(k))* &
                   bimm*(exp(aimm*(273.15_r8-t(i,k)))-1._r8)/ &
                   lamc(k)**3/lamc(k)**3

              nnuccc(k) = cons10/(cons3*qcvar)* &
                  pi/6._r8*cdist1(k)*gamma(pgam(k)+4._r8) &
                  *bimm* &
                  (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamc(k)**3
           end if           ! sub-columns


! contact freezing (-40<T<-3 C) (Young, 1974) with hooks into simulated dust
! dust size and number in 4 bins are read in from companion routine

           tcnt=(270.16_r8-t(i,k))**1.3_r8
           viscosity=1.8e-5_r8*(t(i,k)/298.0_r8)**0.85_r8    ! Viscosity (kg/m/s)
           mfp=2.0_r8*viscosity/(p(i,k)  &                   ! Mean free path (m)
               *sqrt(8.0_r8*28.96e-3_r8/(pi*8.314409_r8*t(i,k))))           

           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
           nslip2=1.0_r8+(mfp/rndst(i,k,2))*(1.257_r8+(0.4_r8*Exp(-(1.1_r8*rndst(i,k,2)/mfp))))
           nslip3=1.0_r8+(mfp/rndst(i,k,3))*(1.257_r8+(0.4_r8*Exp(-(1.1_r8*rndst(i,k,3)/mfp))))
           nslip4=1.0_r8+(mfp/rndst(i,k,4))*(1.257_r8+(0.4_r8*Exp(-(1.1_r8*rndst(i,k,4)/mfp))))

           ndfaer1=1.381e-23_r8*t(i,k)*nslip1/(6._r8*pi*viscosity*rndst(i,k,1))  ! aerosol diffusivity (m2/s)
           ndfaer2=1.381e-23_r8*t(i,k)*nslip2/(6._r8*pi*viscosity*rndst(i,k,2))
           ndfaer3=1.381e-23_r8*t(i,k)*nslip3/(6._r8*pi*viscosity*rndst(i,k,3))
           ndfaer4=1.381e-23_r8*t(i,k)*nslip4/(6._r8*pi*viscosity*rndst(i,k,4))


           if (sub_column) then
 
               mnucct(k) = &
                        (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow* &
                        cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4
 
               nnucct(k) = (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi*  &
                        cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k)
 
           else

               mnucct(k) = gamma(qcvar+4._r8/3._r8)/(cons3*qcvar**(4._r8/3._r8))*  &
                       (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow* &
                       cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4

                nnucct(k) =  gamma(qcvar+1._r8/3._r8)/(cons3*qcvar**(1._r8/3._r8))*  &
                         (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi*  &
                       cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k)

           end if      ! sub-column switch

! make sure number of droplets frozen does not exceed available ice nuclei concentration
! this prevents 'runaway' droplet freezing

        if (nnuccc(k)*lcldm(i,k).gt.nnuccd(k)) then
        dum=(nnuccd(k)/(nnuccc(k)*lcldm(i,k)))
! scale mixing ratio of droplet freezing with limit
        mnuccc(k)=mnuccc(k)*dum
        nnuccc(k)=nnuccd(k)/lcldm(i,k)
        end if

        else
           mnuccc(k)=0._r8
           nnuccc(k)=0._r8
           mnucct(k)=0._r8
           nnucct(k)=0._r8
	end if

!.......................................................................
! snow self-aggregation from passarelli, 1978, used by reisner, 1998
! this is hard-wired for bs = 0.4 for now
! ignore self-collection of cloud ice

	if (qniic(i,k).ge.qsmall .and. t(i,k).le.273.15_r8) then
 	nsagg(k) = -1108._r8*asn(i,k)*Eii* &
             pi**((1._r8-bs)/3._r8)*rhosn**((-2._r8-bs)/3._r8)*rho(i,k)** &
            ((2._r8+bs)/3._r8)*qniic(i,k)**((2._r8+bs)/3._r8)* &
            (nsic(i,k)*rho(i,k))**((4._r8-bs)/3._r8)/ &
            (4._r8*720._r8*rho(i,k))
        else
        nsagg(k)=0._r8
	end if

!.......................................................................
! accretion of cloud droplets onto snow/graupel
! here use continuous collection equation with
! simple gravitational collection kernel
! ignore collisions between droplets/cloud ice
! since minimum size ice particle for accretion is 50 - 150 micron

! ignore collision of snow with droplets above freezing

	if (qniic(i,k).ge.qsmall .and. t(i,k).le.tmelt .and. &
            qcic(i,k).ge.qsmall) then

! put in size dependent collection efficiency
! mean diameter of snow is area-weighted, since
! accretion is function of crystal geometric area
! collection efficiency is approximation based on stoke's law (Thompson et al. 2004)

        dc0 = (pgam(k)+1._r8)/lamc(k)
        ds0 = 1._r8/lams(k)
        dum = dc0*dc0*uns(k)*rhow/(9._r8*mu(i,k)*ds0)
        eci = dum*dum/((dum+0.4_r8)*(dum+0.4_r8))

        eci = max(eci,0._r8)
        eci = min(eci,1._r8)


! no impact of sub-grid distribution of qc since psacws
! is linear in qc

	psacws(k) = pi/4._r8*asn(i,k)*qcic(i,k)*rho(i,k)* &
                  n0s(k)*Eci*cons11/ &
                  lams(k)**(bs+3._r8)	
	npsacws(k) = pi/4._r8*asn(i,k)*ncic(i,k)*rho(i,k)* &
                  n0s(k)*Eci*cons11/ &
                  lams(k)**(bs+3._r8)
        else
           psacws(k)=0._r8
           npsacws(k)=0._r8
        end if

! add secondary ice production due to accretion of droplets by snow 
! (Hallet-Mossop process) (from Cotton et al., 1986)
        if((t(i,k).lt.270.16_r8) .and. (t(i,k).ge.268.16_r8)) then
           ni_secp   = 3.5e8_r8*(270.16_r8-t(i,k))/2.0_r8*psacws(k)
           nsacwi(k) = ni_secp
           msacwi(k) = min(ni_secp*mi0,psacws(k))
        else if((t(i,k).lt.268.16_r8) .and. (t(i,k).ge.265.16_r8)) then
           ni_secp   = 3.5e8_r8*(t(i,k)-265.16_r8)/3.0_r8*psacws(k)
           nsacwi(k) = ni_secp
           msacwi(k) = min(ni_secp*mi0,psacws(k))
        else
           ni_secp   = 0.0_r8
           nsacwi(k) = 0.0_r8
           msacwi(k) = 0.0_r8
        endif
        psacws(k) = max(0.0_r8,psacws(k)-ni_secp*mi0)

!.......................................................................
! accretion of rain water by snow
! formula from ikawa and saito, 1991, used by reisner et al., 1998

	if (qric(i,k).ge.1.e-8_r8 .and. qniic(i,k).ge.1.e-8_r8 .and. & 
              t(i,k).le.273.15_r8) then

	pracs(k) = pi*pi*ecr*(((1.2_r8*umr(k)-0.95_r8*ums(k))**2+ &
                  0.08_r8*ums(k)*umr(k))**0.5_r8*rhow*rho(i,k)* &
                 n0r(k)*n0s(k)* &
                  (5._r8/(lamr(k)**6*lams(k))+ &
                  2._r8/(lamr(k)**5*lams(k)**2)+ &
                  0.5_r8/(lamr(k)**4*lams(k)**3)))

	npracs(k) = pi/2._r8*rho(i,k)*ecr*(1.7_r8*(unr(k)-uns(k))**2+ &
              0.3_r8*unr(k)*uns(k))**0.5_r8*n0r(k)*n0s(k)* &
              (1._r8/(lamr(k)**3*lams(k))+ &
              1._r8/(lamr(k)**2*lams(k)**2)+ &
              1._r8/(lamr(k)*lams(k)**3))

        else
           pracs(k)=0._r8
           npracs(k)=0._r8
	end if

!.......................................................................
! heterogeneous freezing of rain drops
! follows from Bigg (1953)

	if (t(i,k).lt.269.15_r8 .and. qric(i,k).ge.qsmall) then

	mnuccr(k) = 20._r8*pi*pi*rhow*nric(i,k)*bimm* &
                  (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamr(k)**3 &
                 /lamr(k)**3

	nnuccr(k) = pi*nric(i,k)*bimm* &
                   (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamr(k)**3
        else
           mnuccr(k)=0._r8
           nnuccr(k)=0._r8
	end if

!.......................................................................
! accretion of cloud liquid water by rain
! formula from Khrouditnov and Kogan (2000)
! gravitational collection kernel, droplet fall speed neglected

	if (qric(i,k).ge.qsmall .and. qcic(i,k).ge.qsmall) then

! include sub-grid distribution of cloud water

! add sub-column switch
 
           if (sub_column) then
 
              pra(k) = &
                       67._r8*(qcic(i,k)*qric(i,k))**1.15_r8
              npra(k) = pra(k)/(qcic(i,k)/ncic(i,k))
 
           else

              pra(k) = cons12/(cons3*cons20)* &
                      67._r8*(qcic(i,k)*qric(i,k))**1.15_r8
              npra(k) = pra(k)/(qcic(i,k)/ncic(i,k))

           end if               ! sub-column switch

         else
           pra(k)=0._r8
           npra(k)=0._r8
	end if

!.......................................................................
! Self-collection of rain drops
! from Beheng(1994)

	if (qric(i,k).ge.qsmall) then
	nragg(k) = -8._r8*nric(i,k)*qric(i,k)*rho(i,k)
        else
           nragg(k)=0._r8
	end if

!.......................................................................
! Accretion of cloud ice by snow
! For this calculation, it is assumed that the Vs >> Vi
! and Ds >> Di for continuous collection

	if (qniic(i,k).ge.qsmall.and.qiic(i,k).ge.qsmall &
            .and.t(i,k).le.273.15_r8) then
	prai(k) = pi/4._r8*asn(i,k)*qiic(i,k)*rho(i,k)* &
                  n0s(k)*Eii*cons11/ &
                  lams(k)**(bs+3._r8)	
	nprai(k) = pi/4._r8*asn(i,k)*niic(i,k)* &
                  rho(i,k)*n0s(k)*Eii*cons11/ &
                  lams(k)**(bs+3._r8)
        else
        prai(k)=0._r8
        nprai(k)=0._r8
	end if

!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
! calculate evaporation/sublimation of rain and snow
! note: evaporation/sublimation occurs only in cloud-free portion of grid cell
! in-cloud condensation/deposition of rain and snow is neglected
! except for transfer of cloud water to snow through bergeron process

! initialize evap/sub tendncies
	pre(k)=0._r8
	prds(k)=0._r8

! evaporation of rain
! only calculate if there is some precip fraction > cloud fraction

        if (qcic(i,k)+qiic(i,k).lt.1.e-6_r8.or.cldmax(i,k).gt.lcldm(i,k)) then

! set temporary cloud fraction to zero if cloud water + ice is very small
! this will ensure that evaporation/sublimation of precip occurs over
! entire grid cell, since min cloud fraction is specified otherwise
        if (qcic(i,k)+qiic(i,k).lt.1.e-6_r8) then
	dum=0._r8
	else
	dum=lcldm(i,k)
	end if

! saturation vapor pressure
        esn=polysvp(t(i,k),0)
	qsn=min(epsqs*esn/(p(i,k)-(1._r8-epsqs)*esn),1._r8)

! recalculate saturation vapor pressure for liquid and ice
	esl(i,k)=esn
	esi(i,k)=polysvp(t(i,k),1)
! hm fix, make sure when above freezing that esi=esl, not active yet
	if (t(i,k).gt.tmelt)esi(i,k)=esl(i,k)

! calculate q for out-of-cloud region
	qclr=(q(i,k)-dum*qsn)/(1._r8-dum)

	if (qric(i,k).ge.qsmall) then

        qvs=epsqs*esl(i,k)/(p(i,k)-(1._r8-epsqs)*esl(i,k))
	dqsdt = xxlv*qvs/(rv*t(i,k)**2)
        ab = 1._r8+dqsdt*xxlv/cpp
        epsr = 2._r8*pi*n0r(k)*rho(i,k)*Dv(i,k)* &
                   (f1r/(lamr(k)*lamr(k))+ &
                    f2r*(arn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* &
                    sc(i,k)**(1._r8/3._r8)*cons13/ &
                (lamr(k)**(5._r8/2._r8+br/2._r8)))

	   pre(k) = epsr*(qclr-qvs)/ab

! only evaporate in out-of-cloud region
! and distribute across cldmax
           pre(k)=min(pre(k)*(cldmax(i,k)-dum),0._r8)
           pre(k)=pre(k)/cldmax(i,k)
	end if

! sublimation of snow
	if (qniic(i,k).ge.qsmall) then
        qvi=epsqs*esi(i,k)/(p(i,k)-(1._r8-epsqs)*esi(i,k))
        dqsidt =  xxls*qvi/(rv*t(i,k)**2)
        abi = 1._r8+dqsidt*xxls/cpp
        epss = 2._r8*pi*n0s(k)*rho(i,k)*Dv(i,k)* &
                   (f1s/(lams(k)*lams(k))+ &
                    f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* &
                    sc(i,k)**(1._r8/3._r8)*cons14/ &
               (lams(k)**(5._r8/2._r8+bs/2._r8)))
	   prds(k) = epss*(qclr-qvi)/abi	

! only sublimate in out-of-cloud region and distribute over cldmax
           prds(k)=min(prds(k)*(cldmax(i,k)-dum),0._r8)
	   prds(k)=prds(k)/cldmax(i,k)
	end if

! make sure RH not pushed above 100% due to rain evaporation/snow sublimation
! get updated RH at end of time step based on cloud water/ice condensation/evap

	qtmp=q(i,k)-(cmei(i,k)+(pre(k)+prds(k))*cldmax(i,k))*deltat
	ttmp=t(i,k)+((pre(k)*cldmax(i,k))*xxlv+ &
                (cmei(i,k)+prds(k)*cldmax(i,k))*xxls)*deltat/cpp

!limit range of temperatures!
        ttmp=max(180._r8,min(ttmp,323._r8))

        esn=polysvp(ttmp,0)  ! use rhw to allow ice supersaturation
	qsn=min(epsqs*esn/(p(i,k)-(1._r8-epsqs)*esn),1._r8)

! modify precip evaporation rate if q > qsat
	if (qtmp.gt.qsn) then
	if (pre(k)+prds(k).lt.-1.e-20) then
	dum1=pre(k)/(pre(k)+prds(k))
! recalculate q and t after cloud water cond but without precip evap
	qtmp=q(i,k)-(cmei(i,k))*deltat
	ttmp=t(i,k)+(cmei(i,k)*xxls)*deltat/cpp
        esn=polysvp(ttmp,0) ! use rhw to allow ice supersaturation
	qsn=min(epsqs*esn/(p(i,k)-(1._r8-epsqs)*esn),1._r8)
	dum=(qtmp-qsn)/(1._r8 + cons27*qsn/(cpp*rv*ttmp**2))
	dum=min(dum,0._r8)

! modify rates if needed, divide by cldmax to get local (in-precip) value
	pre(k)=dum*dum1/deltat/cldmax(i,k)

! do separately using RHI for prds....
        esn=polysvp(ttmp,1) ! use rhi to allow ice supersaturation
	qsn=min(epsqs*esn/(p(i,k)-(1._r8-epsqs)*esn),1._r8)
	dum=(qtmp-qsn)/(1._r8 + cons28*qsn/(cpp*rv*ttmp**2))
	dum=min(dum,0._r8)

! modify rates if needed, divide by cldmax to get local (in-precip) value
	prds(k)=dum*(1._r8-dum1)/deltat/cldmax(i,k)
	end if
	end if

	end if

! bergeron process - evaporation of droplets and deposition onto snow

	if (qniic(i,k).ge.qsmall.and.qcic(i,k).ge.qsmall.and.t(i,k).lt.tmelt) then
        qvi=epsqs*esi(i,k)/(p(i,k)-(1._r8-epsqs)*esi(i,k))
        qvs=epsqs*esl(i,k)/(p(i,k)-(1._r8-epsqs)*esl(i,k))
        dqsidt =  xxls*qvi/(rv*t(i,k)**2)
        abi = 1._r8+dqsidt*xxls/cpp
        epss = 2._r8*pi*n0s(k)*rho(i,k)*Dv(i,k)* &
                   (f1s/(lams(k)*lams(k))+ &
                    f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* &
                    sc(i,k)**(1._r8/3._r8)*cons14/ &
               (lams(k)**(5._r8/2._r8+bs/2._r8)))
	bergs(k)=epss*(qvs-qvi)/abi
	else
	bergs(k)=0._r8
	end if

!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
! conservation to ensure no negative values of cloud water/precipitation
! in case microphysical process rates are large

! make sure and use end-of-time step values for cloud water, ice, due
! condensation/deposition

! note: for check on conservation, processes are multiplied by omsm
! to prevent problems due to round off error

! include mixing timescale  (mtime)

        qce=(qc(i,k) - berg(i,k)*deltat)
        nce=(nc(i,k)+npccn(k)*deltat*mtime)
        qie=(qi(i,k)+(cmei(i,k)+berg(i,k))*deltat)
        nie=(ni(i,k)+nnuccd(k)*deltat*mtime)

! conservation of qc

        dum = (prc(k)+pra(k)+mnuccc(k)+mnucct(k)+msacwi(k)+ &

              psacws(k)+bergs(k))*lcldm(i,k)*deltat

	if (dum.gt.qce) then
!PMA
         if (abs(prc(k)+pra(k)+mnuccc(k)+mnucct(k)+msacwi(k)+psacws(k)+bergs(k)) > 1.e-20_r8) then
          ratio = qce/deltat/lcldm(i,k)/(prc(k)+pra(k)+mnuccc(k)+mnucct(k)+msacwi(k)+psacws(k)+bergs(k))*omsm 
         else
          ratio = 0.5_r8
         end if
	prc(k) = prc(k)*ratio
	pra(k) = pra(k)*ratio
	mnuccc(k) = mnuccc(k)*ratio
        mnucct(k) = mnucct(k)*ratio  
        msacwi(k) = msacwi(k)*ratio  
	psacws(k) = psacws(k)*ratio	
	bergs(k) = bergs(k)*ratio	
        end if

! conservation of nc

        dum = (nprc1(k)+npra(k)+nnuccc(k)+nnucct(k)+ &
              npsacws(k)-nsubc(k))*lcldm(i,k)*deltat

	if (dum.gt.nce) then
!PMA
          if (abs(nprc1(k)+npra(k)+nnuccc(k)+nnucct(k)+npsacws(k)-nsubc(k)) > 1.e-20_r8) then
        ratio = nce/deltat/((nprc1(k)+npra(k)+nnuccc(k)+nnucct(k)+&
            npsacws(k)-nsubc(k))*lcldm(i,k))*omsm
          else
        ratio = 0.5_r8
          end if

	nprc1(k) = nprc1(k)*ratio
	npra(k) = npra(k)*ratio
	nnuccc(k) = nnuccc(k)*ratio
        nnucct(k) = nnucct(k)*ratio  
	npsacws(k) = npsacws(k)*ratio	
	nsubc(k)=nsubc(k)*ratio
        end if

! conservation of qi

        dum = ((-mnuccc(k)-mnucct(k)-msacwi(k))*lcldm(i,k)+(prci(k)+ &
               prai(k))*icldm(i,k))*deltat

	if (dum.gt.qie) then

!jdf
        if(abs(prci(k)+prai(k)).gt.1.0e-20) then
          ratio = (qie/deltat+(mnuccc(k)+mnucct(k)+msacwi(k))*lcldm(i,k))/((prci(k)+prai(k))*icldm(i,k))*omsm
        else
          ratio=0.5
        endif
!jdf        ratio = (qie/deltat+(mnuccc(k)+mnucct(k)+msacwi(k))*lcldm(i,k))/((prci(k)+prai(k))*icldm(i,k))*omsm 
        prci(k) = prci(k)*ratio
        prai(k) = prai(k)*ratio
        end if

! conservation of ni

        dum = ((-nnucct(k)-nsacwi(k))*lcldm(i,k)+(nprci(k)+ &
               nprai(k)-nsubi(k))*icldm(i,k))*deltat

	if (dum.gt.nie) then

           if(abs( ((nprci(k)+nprai(k)-nsubi(k))*icldm(i,k))*omsm )  .gt. 1.0e-20_r8) then
              ratio = (nie/deltat+(nnucct(k)+nsacwi(k))*lcldm(i,k))/ &  
                   ((nprci(k)+nprai(k)-nsubi(k))*icldm(i,k))*omsm
           else
              ratio = 0.5
           endif
        nprci(k) = nprci(k)*ratio
        nprai(k) = nprai(k)*ratio
	nsubi(k) = nsubi(k)*ratio
        end if

! for preciptiation conservation, use logic that vertical integral 
! of tendency from current level to top of model (i.e., qrtot) cannot be negative

! conservation of rain mixing rat

	if (((prc(k)+pra(k))*lcldm(i,k)+(-mnuccr(k)+pre(k)-pracs(k))*&
               cldmax(i,k))*dz(i,k)*rho(i,k)+qrtot.lt.0._r8) then

	if (-pre(k)+pracs(k)+mnuccr(k).ge.qsmall) then
	     
	ratio = (qrtot/(dz(i,k)*rho(i,k))+(prc(k)+pra(k))*lcldm(i,k))/&
                ((-pre(k)+pracs(k)+mnuccr(k))*cldmax(i,k))*omsm 

        pre(k) = pre(k)*ratio
        pracs(k) = pracs(k)*ratio
        mnuccr(k) = mnuccr(k)*ratio
	end if
        end if

! conservation of nr
! for now neglect evaporation of nr
       nsubr(k)=0._r8

       if ((nprc(k)*lcldm(i,k)+(-nnuccr(k)+nsubr(k)-npracs(k)&
            +nragg(k))*cldmax(i,k))*dz(i,k)*rho(i,k)+nrtot.lt.0._r8) then

	if (-nsubr(k)-nragg(k)+npracs(k)+nnuccr(k).ge.qsmall) then

	ratio = (nrtot/(dz(i,k)*rho(i,k))+nprc(k)*lcldm(i,k))/&
               ((-nsubr(k)-nragg(k)+npracs(k)+nnuccr(k))*cldmax(i,k))*omsm

        nsubr(k) = nsubr(k)*ratio
        npracs(k) = npracs(k)*ratio
        nnuccr(k) = nnuccr(k)*ratio
        nragg(k) = nragg(k)*ratio
	end if
        end if

! conservation of snow mix ratio

	if (((bergs(k)+psacws(k))*lcldm(i,k)+(prai(k)+prci(k))*icldm(i,k)+(pracs(k)+&
            mnuccr(k)+prds(k))*cldmax(i,k))*dz(i,k)*rho(i,k)+qstot.lt.0._r8) then

	if (-prds(k).ge.qsmall) then

	ratio = (qstot/(dz(i,k)*rho(i,k))+(bergs(k)+psacws(k))*lcldm(i,k)+(prai(k)+prci(k))*icldm(i,k)+&
                (pracs(k)+mnuccr(k))*cldmax(i,k))/(-prds(k)*cldmax(i,k))*omsm

        prds(k) = prds(k)*ratio
	end if
       end if

! conservation of ns

! calculate loss of number due to sublimation
! for now neglect sublimation of ns
       nsubs(k)=0._r8

       if ((nprci(k)*icldm(i,k)+(nnuccr(k)+nsubs(k)+nsagg(k))*cldmax(i,k))*&
            dz(i,k)*rho(i,k)+nstot.lt.0._r8) then

	if (-nsubs(k)-nsagg(k).ge.qsmall) then

	ratio = (nstot/(dz(i,k)*rho(i,k))+nprci(k)*icldm(i,k)+&
                nnuccr(k)*cldmax(i,k))/((-nsubs(k)-nsagg(k))*cldmax(i,k))*omsm

        nsubs(k) = nsubs(k)*ratio
        nsagg(k) = nsagg(k)*ratio
	end if
        end if

! get tendencies due to microphysical conversion processes
! note: tendencies are multiplied by appropaiate cloud/precip 
! fraction to get grid-scale values
! note: cmei is already grid-average values

	qvlat(i,k) = qvlat(i,k)- &
       (pre(k)+prds(k))*cldmax(i,k)-cmei(i,k) 

	tlat(i,k) = tlat(i,k)+((pre(k)*cldmax(i,k)) &
           *xxlv+(prds(k)*cldmax(i,k)+cmei(i,k))*xxls+ &
           ((bergs(k)+psacws(k)+mnuccc(k)+mnucct(k)+msacwi(k))*lcldm(i,k)+(mnuccr(k)+ &
               pracs(k))*cldmax(i,k)+berg(i,k))*xlf)

	qctend(i,k) = qctend(i,k)+ &
                 (-pra(k)-prc(k)-mnuccc(k)-mnucct(k)-msacwi(k)- & 
                  psacws(k)-bergs(k))*lcldm(i,k)-berg(i,k)

	qitend(i,k) = qitend(i,k)+ &
         (mnuccc(k)+mnucct(k)+msacwi(k))*lcldm(i,k)+(-prci(k)- & 
                  prai(k))*icldm(i,k)+cmei(i,k)+berg(i,k)

	qrtend(i,k) = qrtend(i,k)+ &
                 (pra(k)+prc(k))*lcldm(i,k)+(pre(k)-pracs(k)- &
                  mnuccr(k))*cldmax(i,k)

	qnitend(i,k) = qnitend(i,k)+ &
                (prai(k)+prci(k))*icldm(i,k)+(psacws(k)+bergs(k))*lcldm(i,k)+(prds(k)+ &
                   pracs(k)+mnuccr(k))*cldmax(i,k)

! add output for cmei (accumulate)
	cmeiout(i,k) = cmeiout(i,k) + cmei(i,k)

! assign variables for trop_mozart, these are grid-average
! evaporation/sublimation is stored here as positive term

	evapsnow(i,k) = evapsnow(i,k)-prds(k)*cldmax(i,k)
	nevapr(i,k) = nevapr(i,k)-pre(k)*cldmax(i,k)

! change to make sure prain is positive: do not remove snow from
! prain used for wet deposition
        	prain(i,k) = prain(i,k)+(pra(k)+prc(k))*lcldm(i,k)+(-pracs(k)- &
                          mnuccr(k))*cldmax(i,k)
	prodsnow(i,k) = prodsnow(i,k)+(prai(k)+prci(k))*icldm(i,k)+(psacws(k)+bergs(k))*lcldm(i,k)+(&
                   pracs(k)+mnuccr(k))*cldmax(i,k)

! following are used to calculate 1st order conversion rate of cloud water
!    to rain and snow (1/s), for later use in aerosol wet removal routine
! previously, wetdepa used (prain/qc) for this, and the qc in wetdepa may be smaller than the qc
!    used to calculate pra, prc, ... in this routine
! qcsinksum_rate1ord = sum over iterations{ rate of direct transfer of cloud water to rain & snow }
!                      (no cloud ice or bergeron terms)
! qcsum_rate1ord     = sum over iterations{ qc used in calculation of the transfer terms }

        qcsinksum_rate1ord(k) = qcsinksum_rate1ord(k) + (pra(k)+prc(k)+psacws(k))*lcldm(i,k) 
        qcsum_rate1ord(k) = qcsum_rate1ord(k) + qc(i,k) 

! microphysics output, note this is grid-averaged
        prao(i,k)=prao(i,k)+pra(k)*lcldm(i,k)
        prco(i,k)=prco(i,k)+prc(k)*lcldm(i,k)
        mnuccco(i,k)=mnuccco(i,k)+mnuccc(k)*lcldm(i,k)
        mnuccto(i,k)=mnuccto(i,k)+mnucct(k)*lcldm(i,k)
        mnuccdo(i,k)=mnuccdo(i,k)+mnuccd(k)*lcldm(i,k)
        msacwio(i,k)=msacwio(i,k)+msacwi(k)*lcldm(i,k)
        psacwso(i,k)=psacwso(i,k)+psacws(k)*lcldm(i,k)
        bergso(i,k)=bergso(i,k)+bergs(k)*lcldm(i,k)
        bergo(i,k)=bergo(i,k)+berg(i,k)
        prcio(i,k)=prcio(i,k)+prci(k)*icldm(i,k)
        praio(i,k)=praio(i,k)+prai(k)*icldm(i,k)
        mnuccro(i,k)=mnuccro(i,k)+mnuccr(k)*cldmax(i,k)
        pracso (i,k)=pracso (i,k)+pracs (k)*cldmax(i,k)

! multiply activation/nucleation by mtime to account for fast timescale

	nctend(i,k) = nctend(i,k)+ npccn(k)*mtime+&
                  (-nnuccc(k)-nnucct(k)-npsacws(k)+nsubc(k) & 
                  -npra(k)-nprc1(k))*lcldm(i,k)      

	nitend(i,k) = nitend(i,k)+ nnuccd(k)*mtime+ & 
                  (nnucct(k)+nsacwi(k))*lcldm(i,k)+(nsubi(k)-nprci(k)- &   
                  nprai(k))*icldm(i,k)

	nstend(i,k) = nstend(i,k)+(nsubs(k)+ &
                  nsagg(k)+nnuccr(k))*cldmax(i,k)+nprci(k)*icldm(i,k)

	nrtend(i,k) = nrtend(i,k)+ &
                  nprc(k)*lcldm(i,k)+(nsubr(k)-npracs(k)-nnuccr(k) &
                   +nragg(k))*cldmax(i,k)

! make sure that nc and ni at advanced time step do not exceed
! maximum (existing N + source terms*dt), which is possible due to
! fast nucleation timescale

	if (nctend(i,k).gt.0._r8.and.nc(i,k)+nctend(i,k)*deltat.gt.ncmax) then
	nctend(i,k)=max(0._r8,(ncmax-nc(i,k))/deltat)
	end if
	if (nitend(i,k).gt.0._r8.and.ni(i,k)+nitend(i,k)*deltat.gt.nimax) then
	nitend(i,k)=max(0._r8,(nimax-ni(i,k))/deltat)
	end if

! get final values for precipitation q and N, based on
! flux of precip from above, source/sink term, and terminal fallspeed
! see eq. 15-16 in MG2008

! rain

        if (qric(i,k).ge.qsmall) then
	if (k.eq.1) then
	qric(i,k)=qrtend(i,k)*dz(i,k)/cldmax(i,k)/umr(k)
	nric(i,k)=nrtend(i,k)*dz(i,k)/cldmax(i,k)/unr(k)
	else
        qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)*cldmax(i,k-1)+ &
         (rho(i,k)*dz(i,k)*qrtend(i,k)))/(umr(k)*rho(i,k)*cldmax(i,k))
	nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)*cldmax(i,k-1)+ &
         (rho(i,k)*dz(i,k)*nrtend(i,k)))/(unr(k)*rho(i,k)*cldmax(i,k))

	end if
	else
	qric(i,k)=0._r8
	nric(i,k)=0._r8
	end if

! snow

        if (qniic(i,k).ge.qsmall) then
	if (k.eq.1) then
	qniic(i,k)=qnitend(i,k)*dz(i,k)/cldmax(i,k)/ums(k)	
	nsic(i,k)=nstend(i,k)*dz(i,k)/cldmax(i,k)/uns(k)
	else
        qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)*cldmax(i,k-1)+ &
         (rho(i,k)*dz(i,k)*qnitend(i,k)))/(ums(k)*rho(i,k)*cldmax(i,k))
	nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)*cldmax(i,k-1)+ &
         (rho(i,k)*dz(i,k)*nstend(i,k)))/(uns(k)*rho(i,k)*cldmax(i,k))
	end if
	else
	qniic(i,k)=0._r8
	nsic(i,k)=0._r8
	end if

! calculate precipitation flux at surface
! divide by density of water to get units of m/s

	prect(i) = prect(i)+(qrtend(i,k)*dz(i,k)*rho(i,k)+&
                   qnitend(i,k)*dz(i,k)*rho(i,k))/rhow
	preci(i) = preci(i)+qnitend(i,k)*dz(i,k)*rho(i,k)/rhow

        ! convert rain rate from m/s to mm/hr
 
         rainrt(i,k)=qric(i,k)*rho(i,k)*umr(k)/rhow*3600._r8*1000._r8

! vertically-integrated precip source/sink terms (note: grid-averaged)

	qrtot = max(qrtot+qrtend(i,k)*dz(i,k)*rho(i,k),0._r8)
	qstot = max(qstot+qnitend(i,k)*dz(i,k)*rho(i,k),0._r8)
	nrtot = max(nrtot+nrtend(i,k)*dz(i,k)*rho(i,k),0._r8)
	nstot = max(nstot+nstend(i,k)*dz(i,k)*rho(i,k),0._r8)

! calculate melting and freezing of precip

! melt snow at +2 C

        if (t(i,k)+tlat(i,k)/cpp*deltat > 275.15_r8) then
           if (qstot > 0._r8) then

! make sure melting snow doesn't reduce temperature below threshold
	      dum = -xlf/cpp*qstot/(dz(i,k)*rho(i,k))
	      if (t(i,k)+tlat(i,k)/cpp*deltat+dum.lt.275.15_r8) then
	       dum = (t(i,k)+tlat(i,k)/cpp*deltat-275.15_r8)*cpp/xlf
	       dum = dum/(xlf/cpp*qstot/(dz(i,k)*rho(i,k)))
	       dum = max(0._r8,dum)
	       dum = min(1._r8,dum)
	      else
               dum = 1._r8
              end if

	      qric(i,k)=qric(i,k)+dum*qniic(i,k)
	      nric(i,k)=nric(i,k)+dum*nsic(i,k)
	      qniic(i,k)=(1._r8-dum)*qniic(i,k)
	      nsic(i,k)=(1._r8-dum)*nsic(i,k)
! heating tendency 
              tmp=-xlf*dum*qstot/(dz(i,k)*rho(i,k))
              meltsdt(i,k)=meltsdt(i,k) + tmp

	      tlat(i,k)=tlat(i,k)+tmp
	      qrtot=qrtot+dum*qstot
	      nrtot=nrtot+dum*nstot
	      qstot=(1._r8-dum)*qstot
	      nstot=(1._r8-dum)*nstot
	      preci(i)=(1._r8-dum)*preci(i)
           end if
        end if

! freeze all rain at -5C for Arctic

        if (t(i,k)+tlat(i,k)/cpp*deltat < (tmelt - 5._r8)) then

           if (qrtot > 0._r8) then

! make sure freezing rain doesn't increase temperature above threshold
          dum = xlf/cpp*qrtot/(dz(i,k)*rho(i,k))
          if (t(i,k)+tlat(i,k)/cpp*deltat+dum.gt.(tmelt - 5._r8)) then
           dum = -(t(i,k)+tlat(i,k)/cpp*deltat-(tmelt-5._r8))*cpp/xlf
           dum = dum/(xlf/cpp*qrtot/(dz(i,k)*rho(i,k)))
           dum = max(0._r8,dum)
           dum = min(1._r8,dum)
          else
             dum = 1._r8
          end if
            
	      qniic(i,k)=qniic(i,k)+dum*qric(i,k)
	      nsic(i,k)=nsic(i,k)+dum*nric(i,k)
	      qric(i,k)=(1._r8-dum)*qric(i,k)
	      nric(i,k)=(1._r8-dum)*nric(i,k)
! heating tendency 
	      tmp = xlf*dum*qrtot/(dz(i,k)*rho(i,k))
	      frzrdt(i,k)=frzrdt(i,k) + tmp

	      tlat(i,k)=tlat(i,k)+tmp
	      qstot=qstot+dum*qrtot
	      qrtot=(1._r8-dum)*qrtot
	      nstot=nstot+dum*nrtot
	      nrtot=(1._r8-dum)*nrtot
	      preci(i)=preci(i)+dum*(prect(i)-preci(i))
           end if
        end if

! if rain/snow mix ratio is zero so should number concentration

	if (qniic(i,k).lt.qsmall) then
	qniic(i,k)=0._r8
	nsic(i,k)=0._r8
	end if

	if (qric(i,k).lt.qsmall) then
	qric(i,k)=0._r8
	nric(i,k)=0._r8
	end if

! make sure number concentration is a positive number to avoid 
! taking root of negative

	nric(i,k)=max(nric(i,k),0._r8)
	nsic(i,k)=max(nsic(i,k),0._r8)

!.......................................................................
! get size distribution parameters for fallspeed calculations
!......................................................................
! rain

	if (qric(i,k).ge.qsmall) then
	lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))**(1._r8/3._r8)
	n0r(k) = nric(i,k)*lamr(k)

! check for slope
! change lammax and lammin for rain and snow
! adjust vars

	if (lamr(k).lt.lamminr) then

	lamr(k) = lamminr

	n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow)
	nric(i,k) = n0r(k)/lamr(k)
	else if (lamr(k).gt.lammaxr) then
	lamr(k) = lammaxr
	n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow)
	nric(i,k) = n0r(k)/lamr(k)
	end if


! 'final' values of number and mass weighted mean fallspeed for rain (m/s)

        unr(k) = min(arn(i,k)*cons4/lamr(k)**br,9.1_r8*rhof(i,k))
        umr(k) = min(arn(i,k)*cons5/(6._r8*lamr(k)**br),9.1_r8*rhof(i,k))

	else
	lamr(k) = 0._r8
	n0r(k) = 0._r8
	umr(k)=0._r8
	unr(k)=0._r8
	end if

!calculate mean size of combined rain and snow

        if (lamr(k).gt.0._r8) then
           Artmp = n0r(k) * pi / (2 * lamr(k)**3._r8)
        else 
           Artmp = 0._r8
        endif

        if (lamc(k).gt.0._r8) then
           Actmp = cdist1(k) * pi * gamma(pgam(k)+3._r8)/(4._r8 * lamc(k)**2._r8)
        else 
           Actmp = 0._r8
        endif

        if (Actmp.gt.0_r8.or.Artmp.gt.0) then
           rercld(i,k)=rercld(i,k) + 3._r8 *(qric(i,k) + qcic(i,k)) / (4._r8 * rhow * (Actmp + Artmp))
           arcld(i,k)=arcld(i,k)+1._r8
        endif

!......................................................................
! snow

	if (qniic(i,k).ge.qsmall) then
	lams(k) = (cons6*cs*nsic(i,k)/ &
            qniic(i,k))**(1._r8/ds)
	n0s(k) = nsic(i,k)*lams(k)

! check for slope
! adjust vars

	if (lams(k).lt.lammins) then
	lams(k) = lammins
	n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6)
	nsic(i,k) = n0s(k)/lams(k)

	else if (lams(k).gt.lammaxs) then
	lams(k) = lammaxs
	n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6)
	nsic(i,k) = n0s(k)/lams(k)
	end if

! 'final' values of number and mass weighted mean fallspeed for snow (m/s)

        ums(k) = min(asn(i,k)*cons8/(6._r8*lams(k)**bs),1.2_r8*rhof(i,k))
        uns(k) = min(asn(i,k)*cons7/lams(k)**bs,1.2_r8*rhof(i,k))

	else
	lams(k) = 0._r8
	n0s(k) = 0._r8
	ums(k) = 0._r8
	uns(k) = 0._r8
	end if

!c........................................................................
! sum over sub-step for average process rates

! convert rain/snow q and N for output to history, note, 
! output is for gridbox average

	qrout(i,k)=qrout(i,k)+qric(i,k)*cldmax(i,k)
	qsout(i,k)=qsout(i,k)+qniic(i,k)*cldmax(i,k)
	nrout(i,k)=nrout(i,k)+nric(i,k)*rho(i,k)*cldmax(i,k)
	nsout(i,k)=nsout(i,k)+nsic(i,k)*rho(i,k)*cldmax(i,k)

	tlat1(i,k)=tlat1(i,k)+tlat(i,k)
	qvlat1(i,k)=qvlat1(i,k)+qvlat(i,k)
	qctend1(i,k)=qctend1(i,k)+qctend(i,k)
	qitend1(i,k)=qitend1(i,k)+qitend(i,k)
	nctend1(i,k)=nctend1(i,k)+nctend(i,k)
	nitend1(i,k)=nitend1(i,k)+nitend(i,k)

	t(i,k)=t(i,k)+tlat(i,k)*deltat/cpp
	q(i,k)=q(i,k)+qvlat(i,k)*deltat
	qc(i,k)=qc(i,k)+qctend(i,k)*deltat
	qi(i,k)=qi(i,k)+qitend(i,k)*deltat
	nc(i,k)=nc(i,k)+nctend(i,k)*deltat
	ni(i,k)=ni(i,k)+nitend(i,k)*deltat

        rainrt1(i,k)=rainrt1(i,k)+rainrt(i,k)

!divide rain radius over substeps for average
        if (arcld(i,k) .gt. 0._r8) then
           rercld(i,k)=rercld(i,k)/arcld(i,k)
        end if

!calculate precip fluxes and adding them to summing sub-stepping variables
      !! flux is zero at top interface
      	rflx(i,1)=0.0_r8
      	sflx(i,1)=0.0_r8
	
      !! calculating the precip flux (kg/m2/s) as mixingratio(kg/kg)*airdensity(kg/m3)*massweightedfallspeed(m/s)
      	rflx(i,k+1)=qrout(i,k)*rho(i,k)*umr(k)
	sflx(i,k+1)=qsout(i,k)*rho(i,k)*ums(k)
	
      !! add to summing sub-stepping variable
	rflx1(i,k+1)=rflx1(i,k+1)+rflx(i,k+1)
	sflx1(i,k+1)=sflx1(i,k+1)+sflx(i,k+1)	

!c........................................................................

	end do ! k loop

	prect1(i)=prect1(i)+prect(i)
	preci1(i)=preci1(i)+preci(i)

	end do ! it loop, sub-step

        do k = 1, pver               
        rate1ord_cw2pr_st(i,k) = qcsinksum_rate1ord(k)/max(qcsum_rate1ord(k),1.0e-30_r8) 
        end do                       

 300    continue  ! continue if no cloud water
	end do ! i loop

! convert dt from sub-step back to full time step
	deltat=deltat*real(iter)

!c.............................................................................

        do i=1,ncol

! skip all calculations if no cloud water
	if (ltrue(i).eq.0) then

	do k=1,pver
! assign default values for effective radius
	effc(i,k)=10._r8
	effi(i,k)=25._r8
	effc_fn(i,k)=10._r8
        lamcrad(i,k)=0._r8
        pgamrad(i,k)=0._r8
        deffi(i,k)=0._r8
	end do
	goto 500
	end if

! initialize nstep for sedimentation sub-steps
	nstep = 1

! divide precip rate by number of sub-steps to get average over time step

	prect(i)=prect1(i)/real(iter)
	preci(i)=preci1(i)/real(iter)

       do k=1,pver

! assign variables back to start-of-timestep values before updating after sub-steps 

	t(i,k)=t1(i,k)
	q(i,k)=q1(i,k)
	qc(i,k)=qc1(i,k)
	qi(i,k)=qi1(i,k)
	nc(i,k)=nc1(i,k)
	ni(i,k)=ni1(i,k)

! divide microphysical tendencies by number of sub-steps to get average over time step

	tlat(i,k)=tlat1(i,k)/real(iter)
	qvlat(i,k)=qvlat1(i,k)/real(iter)
	qctend(i,k)=qctend1(i,k)/real(iter)
	qitend(i,k)=qitend1(i,k)/real(iter)
	nctend(i,k)=nctend1(i,k)/real(iter)
	nitend(i,k)=nitend1(i,k)/real(iter)
 
        rainrt(i,k)=rainrt1(i,k)/real(iter)

! divide by number of sub-steps to find final values
	rflx(i,k+1)=rflx1(i,k+1)/real(iter)
	sflx(i,k+1)=sflx1(i,k+1)/real(iter)

! divide output precip q and N by number of sub-steps to get average over time step

	qrout(i,k)=qrout(i,k)/real(iter)
	qsout(i,k)=qsout(i,k)/real(iter)
	nrout(i,k)=nrout(i,k)/real(iter)
	nsout(i,k)=nsout(i,k)/real(iter)

! divide trop_mozart variables by number of sub-steps to get average over time step 

	nevapr(i,k) = nevapr(i,k)/real(iter)
	evapsnow(i,k) = evapsnow(i,k)/real(iter)
	prain(i,k) = prain(i,k)/real(iter)
	prodsnow(i,k) = prodsnow(i,k)/real(iter)
	cmeout(i,k) = cmeout(i,k)/real(iter)

	cmeiout(i,k) = cmeiout(i,k)/real(iter)
        meltsdt(i,k) = meltsdt(i,k)/real(iter)
        frzrdt (i,k) = frzrdt (i,k)/real(iter)


! microphysics output
        prao(i,k)=prao(i,k)/real(iter)
        prco(i,k)=prco(i,k)/real(iter)
        mnuccco(i,k)=mnuccco(i,k)/real(iter)
        mnuccto(i,k)=mnuccto(i,k)/real(iter)
        msacwio(i,k)=msacwio(i,k)/real(iter)
        psacwso(i,k)=psacwso(i,k)/real(iter)
        bergso(i,k)=bergso(i,k)/real(iter)
        bergo(i,k)=bergo(i,k)/real(iter)
        prcio(i,k)=prcio(i,k)/real(iter)
        praio(i,k)=praio(i,k)/real(iter)

        mnuccro(i,k)=mnuccro(i,k)/real(iter)
        pracso (i,k)=pracso (i,k)/real(iter)

        mnuccdo(i,k)=mnuccdo(i,k)/real(iter)

! modify to include snow. in prain & evap (diagnostic here: for wet dep)
        nevapr(i,k) = nevapr(i,k) + evapsnow(i,k)
        prain(i,k) = prain(i,k) + prodsnow(i,k)

!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
! calculate sedimentation for cloud water and ice
!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

! update in-cloud cloud mixing ratio and number concentration 
! with microphysical tendencies to calculate sedimentation, assign to dummy vars
! note: these are in-cloud values***, hence we divide by cloud fraction

        dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat)/lcldm(i,k)
        dumi(i,k) = (qi(i,k)+qitend(i,k)*deltat)/icldm(i,k)
        dumnc(i,k) = max((nc(i,k)+nctend(i,k)*deltat)/lcldm(i,k),0._r8)
        dumni(i,k) = max((ni(i,k)+nitend(i,k)*deltat)/icldm(i,k),0._r8)

! obtain new slope parameter to avoid possible singularity

	if (dumi(i,k).ge.qsmall) then
! add upper limit to in-cloud number concentration to prevent numerical error
	dumni(i,k)=min(dumni(i,k),dumi(i,k)*1.e20_r8)

	lami(k) = (cons1*ci* &
              dumni(i,k)/dumi(i,k))**(1._r8/di)
        lami(k)=max(lami(k),lammini)
        lami(k)=min(lami(k),lammaxi)
        else
           lami(k)=0._r8
        end if

	if (dumc(i,k).ge.qsmall) then
! add upper limit to in-cloud number concentration to prevent numerical error
	dumnc(i,k)=min(dumnc(i,k),dumc(i,k)*1.e20_r8)
! add lower limit to in-cloud number concentration
         dumnc(i,k)=max(dumnc(i,k),cdnl/rho(i,k)) ! sghan minimum in #/cm3 
         pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8
         pgam(k)=1._r8/(pgam(k)**2)-1._r8
         pgam(k)=max(pgam(k),2._r8)
         pgam(k)=min(pgam(k),15._r8)

	lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k)+4._r8)/ &
                 (dumc(i,k)*gamma(pgam(k)+1._r8)))**(1._r8/3._r8)
	lammin = (pgam(k)+1._r8)/50.e-6_r8
	lammax = (pgam(k)+1._r8)/2.e-6_r8
        lamc(k)=max(lamc(k),lammin)
        lamc(k)=min(lamc(k),lammax)
        else
           lamc(k)=0._r8
        end if

! calculate number and mass weighted fall velocity for droplets
! include effects of sub-grid distribution of cloud water


	if (dumc(i,k).ge.qsmall) then
	unc = &
              acn(i,k)*gamma(1._r8+bc+pgam(k))/ &
               (lamc(k)**bc*gamma(pgam(k)+1._r8))
	umc = &
              acn(i,k)*gamma(4._r8+bc+pgam(k))/ &
             (lamc(k)**bc*gamma(pgam(k)+4._r8))
! fallspeed for output
	vtrmc(i,k)=umc
	else
	umc = 0._r8
	unc = 0._r8
	end if

! calculate number and mass weighted fall velocity for cloud ice

	if (dumi(i,k).ge.qsmall) then
	uni =  ain(i,k)*cons16/lami(k)**bi
	umi = ain(i,k)*cons17/(6._r8*lami(k)**bi)
        uni=min(uni,1.2_r8*rhof(i,k))
        umi=min(umi,1.2_r8*rhof(i,k))

! fallspeed
	vtrmi(i,k)=umi
	else
	umi = 0._r8
	uni = 0._r8
	end if

	fi(k) = g*rho(i,k)*umi
	fni(k) = g*rho(i,k)*uni
	fc(k) = g*rho(i,k)*umc
	fnc(k) = g*rho(i,k)*unc

! calculate number of split time steps to ensure courant stability criteria
! for sedimentation calculations

	rgvm = max(fi(k),fc(k),fni(k),fnc(k))
	nstep = max(int(rgvm*deltat/pdel(i,k)+1._r8),nstep)

! redefine dummy variables - sedimentation is calculated over grid-scale
! quantities to ensure conservation

        dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat)
        dumi(i,k) = (qi(i,k)+qitend(i,k)*deltat)
        dumnc(i,k) = max((nc(i,k)+nctend(i,k)*deltat),0._r8)
        dumni(i,k) = max((ni(i,k)+nitend(i,k)*deltat),0._r8)

	if (dumc(i,k).lt.qsmall) dumnc(i,k)=0._r8
	if (dumi(i,k).lt.qsmall) dumni(i,k)=0._r8

	end do       !!! vertical loop

	do n = 1,nstep  !! loop over sub-time step to ensure stability	
	
	do k = 1,pver
	falouti(k) = fi(k)*dumi(i,k)
	faloutni(k) = fni(k)*dumni(i,k)
	faloutc(k) = fc(k)*dumc(i,k)
	faloutnc(k) = fnc(k)*dumnc(i,k)
	end do

! top of model

	k = 1
	faltndi = falouti(k)/pdel(i,k)
	faltndni = faloutni(k)/pdel(i,k)
	faltndc = faloutc(k)/pdel(i,k)
        faltndnc = faloutnc(k)/pdel(i,k)

! add fallout terms to microphysical tendencies	

	qitend(i,k) = qitend(i,k)-faltndi/nstep
	nitend(i,k) = nitend(i,k)-faltndni/nstep
	qctend(i,k) = qctend(i,k)-faltndc/nstep
        nctend(i,k) = nctend(i,k)-faltndnc/nstep

! sedimentation tendencies for output
	qcsedten(i,k)=qcsedten(i,k)-faltndc/nstep
	qisedten(i,k)=qisedten(i,k)-faltndi/nstep

	dumi(i,k) = dumi(i,k)-faltndi*deltat/nstep
	dumni(i,k) = dumni(i,k)-faltndni*deltat/nstep
	dumc(i,k) = dumc(i,k)-faltndc*deltat/nstep
        dumnc(i,k) = dumnc(i,k)-faltndnc*deltat/nstep

	do k = 2,pver

! for cloud liquid and ice, if cloud fraction increases with height
! then add flux from above to both vapor and cloud water of current level
! this means that flux entering clear portion of cell from above evaporates
! instantly

        dum=lcldm(i,k)/lcldm(i,k-1)
	dum=min(dum,1._r8)
        dum1=icldm(i,k)/icldm(i,k-1)
	dum1=min(dum1,1._r8)

	faltndqie=(falouti(k)-falouti(k-1))/pdel(i,k)
	faltndi=(falouti(k)-dum1*falouti(k-1))/pdel(i,k)
	faltndni=(faloutni(k)-dum1*faloutni(k-1))/pdel(i,k)
	faltndqce=(faloutc(k)-faloutc(k-1))/pdel(i,k)
	faltndc=(faloutc(k)-dum*faloutc(k-1))/pdel(i,k)
	faltndnc=(faloutnc(k)-dum*faloutnc(k-1))/pdel(i,k)

! add fallout terms to eulerian tendencies

	qitend(i,k) = qitend(i,k)-faltndi/nstep
	nitend(i,k) = nitend(i,k)-faltndni/nstep
	qctend(i,k) = qctend(i,k)-faltndc/nstep
        nctend(i,k) = nctend(i,k)-faltndnc/nstep

! sedimentation tendencies for output
	qcsedten(i,k)=qcsedten(i,k)-faltndc/nstep
	qisedten(i,k)=qisedten(i,k)-faltndi/nstep
	
! add terms to to evap/sub of cloud water

        qvlat(i,k)=qvlat(i,k)-(faltndqie-faltndi)/nstep
! for output
        qisevap(i,k)=qisevap(i,k)-(faltndqie-faltndi)/nstep
        qvlat(i,k)=qvlat(i,k)-(faltndqce-faltndc)/nstep
! for output
        qcsevap(i,k)=qcsevap(i,k)-(faltndqce-faltndc)/nstep

	tlat(i,k)=tlat(i,k)+(faltndqie-faltndi)*xxls/nstep
	tlat(i,k)=tlat(i,k)+(faltndqce-faltndc)*xxlv/nstep

	dumi(i,k) = dumi(i,k)-faltndi*deltat/nstep
	dumni(i,k) = dumni(i,k)-faltndni*deltat/nstep
	dumc(i,k) = dumc(i,k)-faltndc*deltat/nstep
        dumnc(i,k) = dumnc(i,k)-faltndnc*deltat/nstep

        Fni(K)=MAX(Fni(K)/pdel(i,K),Fni(K-1)/pdel(i,K-1))*pdel(i,K)
        FI(K)=MAX(FI(K)/pdel(i,K),FI(K-1)/pdel(i,K-1))*pdel(i,K)
        fnc(k)=max(fnc(k)/pdel(i,k),fnc(k-1)/pdel(i,k-1))*pdel(i,k)
        Fc(K)=MAX(Fc(K)/pdel(i,K),Fc(K-1)/pdel(i,K-1))*pdel(i,K)

	end do   !! k loop

! units below are m/s
! cloud water/ice sedimentation flux at surface 
! is added to precip flux at surface to get total precip (cloud + precip water)
! rate

	  prect(i) = prect(i)+(faloutc(pver)+falouti(pver)) &
                     /g/nstep/1000._r8	
	  preci(i) = preci(i)+(falouti(pver)) &
                     /g/nstep/1000._r8

        end do   !! nstep loop

! end sedimentation
!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

! get new update for variables that includes sedimentation tendency
! note : here dum variables are grid-average, NOT in-cloud

  do k=1,pver	

        dumc(i,k) = max(qc(i,k)+qctend(i,k)*deltat,0._r8)
        dumi(i,k) = max(qi(i,k)+qitend(i,k)*deltat,0._r8)
        dumnc(i,k) = max(nc(i,k)+nctend(i,k)*deltat,0._r8)
        dumni(i,k) = max(ni(i,k)+nitend(i,k)*deltat,0._r8)

	if (dumc(i,k).lt.qsmall) dumnc(i,k)=0._r8
	if (dumi(i,k).lt.qsmall) dumni(i,k)=0._r8
	
! calculate instantaneous processes (melting, homogeneous freezing)

        if (t(i,k)+tlat(i,k)/cpp*deltat > tmelt) then
           if (dumi(i,k) > 0._r8) then

! limit so that melting does not push temperature below freezing
	      dum = -dumi(i,k)*xlf/cpp
	      if (t(i,k)+tlat(i,k)/cpp*deltat+dum.lt.tmelt) then
	       dum = (t(i,k)+tlat(i,k)/cpp*deltat-tmelt)*cpp/xlf
	       dum = dum/dumi(i,k)*xlf/cpp 
	       dum = max(0._r8,dum)
	       dum = min(1._r8,dum)
	      else
	       dum = 1._r8
	      end if

              qctend(i,k)=qctend(i,k)+dum*dumi(i,k)/deltat

! for output
              melto(i,k)=dum*dumi(i,k)/deltat

! assume melting ice produces droplet
! mean volume radius of 8 micron

	      nctend(i,k)=nctend(i,k)+3._r8*dum*dumi(i,k)/deltat/ &
               (4._r8*pi*5.12e-16_r8*rhow)

              qitend(i,k)=((1._r8-dum)*dumi(i,k)-qi(i,k))/deltat
              nitend(i,k)=((1._r8-dum)*dumni(i,k)-ni(i,k))/deltat
              tlat(i,k)=tlat(i,k)-xlf*dum*dumi(i,k)/deltat
           end if
        end if

! homogeneously freeze droplets at -40 C

        if (t(i,k)+tlat(i,k)/cpp*deltat < 233.15_r8) then
           if (dumc(i,k) > 0._r8) then

! limit so that freezing does not push temperature above threshold
	      dum = dumc(i,k)*xlf/cpp
	      if (t(i,k)+tlat(i,k)/cpp*deltat+dum.gt.233.15_r8) then
	       dum = -(t(i,k)+tlat(i,k)/cpp*deltat-233.15_r8)*cpp/xlf
	       dum = dum/dumc(i,k)*xlf/cpp
	       dum = max(0._r8,dum)
	       dum = min(1._r8,dum)
	      else
	       dum = 1._r8
	      end if

              qitend(i,k)=qitend(i,k)+dum*dumc(i,k)/deltat
! for output
              homoo(i,k)=dum*dumc(i,k)/deltat

! assume 25 micron mean volume radius of homogeneously frozen droplets
! consistent with size of detrained ice in stratiform.F90
	      nitend(i,k)=nitend(i,k)+dum*3._r8*dumc(i,k)/(4._r8*3.14_r8*1.563e-14_r8* &
                 500._r8)/deltat
              qctend(i,k)=((1._r8-dum)*dumc(i,k)-qc(i,k))/deltat
              nctend(i,k)=((1._r8-dum)*dumnc(i,k)-nc(i,k))/deltat
              tlat(i,k)=tlat(i,k)+xlf*dum*dumc(i,k)/deltat
           end if
        end if

! remove any excess over-saturation, which is possible due to non-linearity when adding 
! together all microphysical processes
! follow code similar to old CAM scheme

	qtmp=q(i,k)+qvlat(i,k)*deltat
	ttmp=t(i,k)+tlat(i,k)/cpp*deltat

        esn = polysvp(ttmp,0)  ! use rhw to allow ice supersaturation
	qsn = min(epsqs*esn/(p(i,k)-(1._r8-epsqs)*esn),1._r8)

	if (qtmp > qsn .and. qsn > 0) then
! expression below is approximate since there may be ice deposition
	dum = (qtmp-qsn)/(1._r8+cons27*qsn/(cpp*rv*ttmp**2))/deltat
! add to output cme
	cmeout(i,k) = cmeout(i,k)+dum
! now add to tendencies, partition between liquid and ice based on temperature
           if (ttmp > 268.15_r8) then
              dum1=0.0_r8
! now add to tendencies, partition between liquid and ice based on te
           else if (ttmp < 238.15_r8) then
              dum1=1.0_r8
           else
              dum1=(268.15_r8-ttmp)/30._r8
	   end if  

	dum = (qtmp-qsn)/(1._r8+(xxls*dum1+xxlv*(1._r8-dum1))**2 &
                     *qsn/(cpp*rv*ttmp**2))/deltat
	qctend(i,k)=qctend(i,k)+dum*(1._r8-dum1)
! for output
        qcreso(i,k)=dum*(1._r8-dum1)
	qitend(i,k)=qitend(i,k)+dum*dum1
	qireso(i,k)=dum*dum1
	qvlat(i,k)=qvlat(i,k)-dum
! for output
        qvres(i,k)=-dum
	tlat(i,k)=tlat(i,k)+dum*(1._r8-dum1)*xxlv+dum*dum1*xxls
	end if

!...............................................................................
! calculate effective radius for pass to radiation code
! if no cloud water, default value is 10 micron for droplets,
! 25 micron for cloud ice

! update cloud variables after instantaneous processes to get effective radius
! variables are in-cloud to calculate size dist parameters

        dumc(i,k) = max(qc(i,k)+qctend(i,k)*deltat,0._r8)/lcldm(i,k)
        dumi(i,k) = max(qi(i,k)+qitend(i,k)*deltat,0._r8)/icldm(i,k)
        dumnc(i,k) = max(nc(i,k)+nctend(i,k)*deltat,0._r8)/lcldm(i,k)
        dumni(i,k) = max(ni(i,k)+nitend(i,k)*deltat,0._r8)/icldm(i,k)

! limit in-cloud mixing ratio to reasonable value of 5 g kg-1

	dumc(i,k)=min(dumc(i,k),5.e-3_r8)
	dumi(i,k)=min(dumi(i,k),5.e-3_r8)

!...................
! cloud ice effective radius

	if (dumi(i,k).ge.qsmall) then
! add upper limit to in-cloud number concentration to prevent numerical error
	dumni(i,k)=min(dumni(i,k),dumi(i,k)*1.e20_r8)
	lami(k) = (cons1*ci* &
              dumni(i,k)/dumi(i,k))**(1._r8/di)

	if (lami(k).lt.lammini) then
	lami(k) = lammini
	n0i(k) = lami(k)**(di+1._r8)*dumi(i,k)/(ci*cons1)
	niic(i,k) = n0i(k)/lami(k)
! adjust number conc if needed to keep mean size in reasonable range
	nitend(i,k)=(niic(i,k)*icldm(i,k)-ni(i,k))/deltat
	else if (lami(k).gt.lammaxi) then
	lami(k) = lammaxi
	n0i(k) = lami(k)**(di+1._r8)*dumi(i,k)/(ci*cons1)
	niic(i,k) = n0i(k)/lami(k)
! adjust number conc if needed to keep mean size in reasonable range
	nitend(i,k)=(niic(i,k)*icldm(i,k)-ni(i,k))/deltat
	end if
	   effi(i,k) = 1.5_r8/lami(k)*1.e6_r8

        else
	   effi(i,k) = 25._r8
        end if

!...................
! cloud droplet effective radius

	if (dumc(i,k).ge.qsmall) then

! add upper limit to in-cloud number concentration to prevent numerical error
           dumnc(i,k)=min(dumnc(i,k),dumc(i,k)*1.e20_r8)

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! set tendency to ensure minimum droplet concentration
! after update by microphysics, except when lambda exceeds bounds on mean drop
! size or if there is no cloud water
           if (dumnc(i,k).lt.cdnl/rho(i,k)) then   
              nctend(i,k)=(cdnl/rho(i,k)*lcldm(i,k)-nc(i,k))/deltat   
           end if
           dumnc(i,k)=max(dumnc(i,k),cdnl/rho(i,k)) ! sghan minimum in #/cm3 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
           pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8
           pgam(k)=1._r8/(pgam(k)**2)-1._r8
           pgam(k)=max(pgam(k),2._r8)
           pgam(k)=min(pgam(k),15._r8)
           
           lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k)+4._r8)/ &
                     (dumc(i,k)*gamma(pgam(k)+1._r8)))**(1._r8/3._r8)
           lammin = (pgam(k)+1._r8)/50.e-6_r8
           lammax = (pgam(k)+1._r8)/2.e-6_r8
           if (lamc(k).lt.lammin) then
              lamc(k) = lammin
              ncic(i,k) = 6._r8*lamc(k)**3*dumc(i,k)* &
                   gamma(pgam(k)+1._r8)/ &
                   (pi*rhow*gamma(pgam(k)+4._r8))
! adjust number conc if needed to keep mean size in reasonable range
              nctend(i,k)=(ncic(i,k)*lcldm(i,k)-nc(i,k))/deltat

           else if (lamc(k).gt.lammax) then
              lamc(k) = lammax
              ncic(i,k) = 6._r8*lamc(k)**3*dumc(i,k)* &
                   gamma(pgam(k)+1._r8)/ &
                   (pi*rhow*gamma(pgam(k)+4._r8))
! adjust number conc if needed to keep mean size in reasonable range
              nctend(i,k)=(ncic(i,k)*lcldm(i,k)-nc(i,k))/deltat
	end if

        effc(i,k) = &
             gamma(pgam(k)+4._r8)/ &
             gamma(pgam(k)+3._r8)/lamc(k)/2._r8*1.e6_r8
!assign output fields for shape here
        lamcrad(i,k)=lamc(k)
        pgamrad(i,k)=pgam(k)

        else
           effc(i,k) = 10._r8
           lamcrad(i,k)=0._r8
           pgamrad(i,k)=0._r8
        end if

! ice effective diameter for david mitchell's optics
        deffi(i,k)=effi(i,k)*rhoi/917._r8*2._r8


!!! recalculate effective radius for constant number, in order to separate
! first and second indirect effects
! assume constant number of 10^8 kg-1

	dumnc(i,k)=1.e8

	if (dumc(i,k).ge.qsmall) then
         pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8
         pgam(k)=1._r8/(pgam(k)**2)-1._r8
         pgam(k)=max(pgam(k),2._r8)
         pgam(k)=min(pgam(k),15._r8)

	lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k)+4._r8)/ &
                 (dumc(i,k)*gamma(pgam(k)+1._r8)))**(1._r8/3._r8)
	lammin = (pgam(k)+1._r8)/50.e-6_r8
	lammax = (pgam(k)+1._r8)/2.e-6_r8
	if (lamc(k).lt.lammin) then
	lamc(k) = lammin
	else if (lamc(k).gt.lammax) then
	lamc(k) = lammax
	end if
	effc_fn(i,k) = &
             gamma(pgam(k)+4._r8)/ &
             gamma(pgam(k)+3._r8)/lamc(k)/2._r8*1.e6_r8

        else
	effc_fn(i,k) = 10._r8
        end if


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1!

	end do ! vertical k loop

 500    continue

	do k=1,pver
! if updated q (after microphysics) is zero, then ensure updated n is also zero

        if (qc(i,k)+qctend(i,k)*deltat.lt.qsmall) nctend(i,k)=-nc(i,k)/deltat
        if (qi(i,k)+qitend(i,k)*deltat.lt.qsmall) nitend(i,k)=-ni(i,k)/deltat
	end do

	end do ! i loop


! hm add rain/snow mixing ratio and number concentration as diagnostic

      call outfld('QRAIN',qrout,   pcols, lchnk)
      call outfld('QSNOW',qsout,   pcols, lchnk)
      call outfld('NRAIN',nrout,   pcols, lchnk)
      call outfld('NSNOW',nsout,   pcols, lchnk)

! add snow ouptut
      do i = 1,ncol
         do k=1,pver
            if (qsout(i,k).gt.1.e-7_r8.and.nsout(i,k).gt.0._r8) then
               dsout(i,k)=3._r8*rhosn/917._r8*(pi * rhosn * nsout(i,k)/qsout(i,k))**(-1._r8/3._r8)
            endif
         end do
      end do
      call outfld('DSNOW',dsout,   pcols, lchnk)
 
!calculate effective radius of rain and snow in microns for COSP using Eq. 9 of COSP v1.3 manual
      do i = 1,ncol
         do k=1,pver
	   !! RAIN
            if (qrout(i,k).gt.1.e-7_r8.and.nrout(i,k).gt.0._r8) then
		reff_rain(i,k)=1.5_r8*(pi * rhow * nrout(i,k)/qrout(i,k))**(-1._r8/3._r8)*1.e6_r8 
            endif
	    !! SNOW
            if (qsout(i,k).gt.1.e-7_r8.and.nsout(i,k).gt.0._r8) then
		reff_snow(i,k)=1.5_r8*(pi * rhosn * nsout(i,k)/qsout(i,k))**(-1._r8/3._r8)*1.e6_r8 

            endif
         end do
      end do

      ! analytic radar reflectivity
      ! formulas from Matthew Shupe, NOAA/CERES
      ! *****note: radar reflectivity is local (in-precip average)
      ! units of mm^6/m^3
 
      do i = 1,ncol
         do k=1,pver
            if (qc(i,k)+qctend(i,k)*deltat.ge.qsmall) then
               dum=((qc(i,k)+qctend(i,k)*deltat)/lcldm(i,k)*rho(i,k)*1000._r8)**2 &
                  /(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)
            else
               dum=0._r8
            end if
            if (qi(i,k)+qitend(i,k)*deltat.ge.qsmall) then
               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)
            else 
               dum1=0._r8
            end if
         
            if (qsout(i,k).ge.qsmall) then
               dum1=dum1+(qsout(i,k)*rho(i,k)*1000._r8/0.1_r8)**(1._r8/0.63_r8)
            end if
            
            refl(i,k)=dum+dum1
 
            ! add rain rate, but for 37 GHz formulation instead of 94 GHz
            ! formula approximated from data of Matrasov (2007)
            ! rainrt is the rain rate in mm/hr
            ! reflectivity (dum) is in DBz
 
            if (rainrt(i,k).ge.0.001) then
               dum=log10(rainrt(i,k)**6._r8)+16._r8
 
               ! convert from DBz to mm^6/m^3
 
               dum = 10._r8**(dum/10._r8)
            else
               ! don't include rain rate in R calculation for values less than 0.001 mm/hr
               dum=0.
            end if
 
            ! add to refl
 
            refl(i,k)=refl(i,k)+dum
 
            !output reflectivity in Z.
            areflz(i,k)=refl(i,k)
 
            ! convert back to DBz 
 
            if (refl(i,k).gt.minrefl) then 
               refl(i,k)=10._r8*log10(refl(i,k))
            else	
               refl(i,k)=-9999._r8
            end if
  
            !set averaging flag
            if (refl(i,k).gt.mindbz) then 
               arefl(i,k)=refl(i,k)
               frefl(i,k)=1.0_r8  
            else
               arefl(i,k)=0._r8
               areflz(i,k)=0._r8
               frefl(i,k)=0._r8
            end if
 
            ! bound cloudsat reflectivity
 
            csrfl(i,k)=min(csmax,refl(i,k))
 
            !set averaging flag
            if (csrfl(i,k).gt.csmin) then 
               acsrfl(i,k)=refl(i,k)
               fcsrfl(i,k)=1.0_r8  
            else
               acsrfl(i,k)=0._r8
               fcsrfl(i,k)=0._r8
            end if
 
         end do
      end do
       
      call outfld('REFL',refl,   pcols, lchnk)
      call outfld('AREFL',arefl,   pcols, lchnk)
      call outfld('AREFLZ',areflz,   pcols, lchnk)
      call outfld('FREFL',frefl,   pcols, lchnk)
      call outfld('CSRFL',csrfl,   pcols, lchnk)
      call outfld('ACSRFL',acsrfl,   pcols, lchnk)
      call outfld('FCSRFL',fcsrfl,   pcols, lchnk)

      call outfld('RERCLD',rercld,   pcols, lchnk)

! averaging for snow and rain number and diameter

  qrout2(:,:)=0._r8
  qsout2(:,:)=0._r8
  nrout2(:,:)=0._r8
  nsout2(:,:)=0._r8	
  drout2(:,:)=0._r8
  dsout2(:,:)=0._r8	
  freqs(:,:)=0._r8
  freqr(:,:)=0._r8
  do i = 1,ncol
     do k=1,pver
	if (qrout(i,k).gt.1.e-7_r8.and.nrout(i,k).gt.0._r8) then
 	   qrout2(i,k)=qrout(i,k)
	   nrout2(i,k)=nrout(i,k)
	   drout2(i,k)=(pi * rhow * nrout(i,k)/qrout(i,k))**(-1._r8/3._r8)
	   freqr(i,k)=1._r8
	endif
	if (qsout(i,k).gt.1.e-7_r8.and.nsout(i,k).gt.0._r8) then
 	   qsout2(i,k)=qsout(i,k)
	   nsout2(i,k)=nsout(i,k)
	   dsout2(i,k)=(pi * rhosn * nsout(i,k)/qsout(i,k))**(-1._r8/3._r8)
	   freqs(i,k)=1._r8
	endif
     end do
  end do

! output activated liquid and ice (convert from #/kg -> #/m3)
  do i = 1,ncol
     do k=1,pver
        ncai(i,k)=dum2i(i,k)*rho(i,k)
        ncal(i,k)=dum2l(i,k)*rho(i,k)
     end do
  end do
  call outfld('NCAL',ncal,    pcols,lchnk)
  call outfld('NCAI',ncai,    pcols,lchnk)

!add averaged output fields.
  call outfld('AQRAIN',qrout2,    pcols,lchnk)
  call outfld('AQSNOW',qsout2,    pcols,lchnk)
  call outfld('ANRAIN',nrout2,    pcols,lchnk)
  call outfld('ANSNOW',nsout2,    pcols,lchnk)
  call outfld('ADRAIN',drout2,    pcols,lchnk)
  call outfld('ADSNOW',dsout2,    pcols,lchnk)
  call outfld('FREQR',freqr,    pcols,lchnk)
  call outfld('FREQS',freqs,    pcols,lchnk)

!redefine fice here....
	nfice(:,:)=0._r8
	do k=1,pver
	   do i=1,ncol
        	dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat)
        	dumi(i,k) = (qi(i,k)+qitend(i,k)*deltat)
		dumfice=qsout(i,k) + qrout(i,k) + dumc(i,k) + dumi(i,k)  

                if (dumfice.gt.qsmall.and.(qsout(i,k)+dumi(i,k).gt.qsmall)) then
                  nfice(i,k)=(qsout(i,k) + dumi(i,k))/dumfice
                endif

                if (nfice(i,k).gt.1._r8) then
                   nfice(i,k)=1._r8
                endif

	   enddo
	enddo

      call outfld('FICE',nfice,   pcols, lchnk)

return
end subroutine mmicro_pcond

!
!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc


      FUNCTION GAMMA(X) 124

!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

!D    DOUBLE PRECISION FUNCTION DGAMMA(X)
!----------------------------------------------------------------------
!
! THIS ROUTINE CALCULATES THE GAMMA FUNCTION FOR A REAL ARGUMENT X.
!   COMPUTATION IS BASED ON AN ALGORITHM OUTLINED IN REFERENCE 1.
!   THE PROGRAM USES RATIONAL FUNCTIONS THAT APPROXIMATE THE GAMMA
!   FUNCTION TO AT LEAST 20 SIGNIFICANT DECIMAL DIGITS.  COEFFICIENTS
!   FOR THE APPROXIMATION OVER THE INTERVAL (1,2) ARE UNPUBLISHED.
!   THOSE FOR THE APPROXIMATION FOR X .GE. 12 ARE FROM REFERENCE 2.
!   THE ACCURACY ACHIEVED DEPENDS ON THE ARITHMETIC SYSTEM, THE
!   COMPILER, THE INTRINSIC FUNCTIONS, AND PROPER SELECTION OF THE
!   MACHINE-DEPENDENT CONSTANTS.
!
!
!*******************************************************************
!*******************************************************************
!
! EXPLANATION OF MACHINE-DEPENDENT CONSTANTS
!
! BETA   - RADIX FOR THE FLOATING-POINT REPRESENTATION
! MAXEXP - THE SMALLEST POSITIVE POWER OF BETA THAT OVERFLOWS
! XBIG   - THE LARGEST ARGUMENT FOR WHICH GAMMA(X) IS REPRESENTABLE
!          IN THE MACHINE, I.E., THE SOLUTION TO THE EQUATION
!                  GAMMA(XBIG) = BETA**MAXEXP
! XINF   - THE LARGEST MACHINE REPRESENTABLE FLOATING-POINT NUMBER;
!          APPROXIMATELY BETA**MAXEXP
! EPS    - THE SMALLEST POSITIVE FLOATING-POINT NUMBER SUCH THAT
!          1.0+EPS .GT. 1.0
! XMININ - THE SMALLEST POSITIVE FLOATING-POINT NUMBER SUCH THAT
!          1/XMININ IS MACHINE REPRESENTABLE
!
!     APPROXIMATE VALUES FOR SOME IMPORTANT MACHINES ARE:
!
!                            BETA       MAXEXP        XBIG
!
! CRAY-1         (S.P.)        2         8191        966.961
! CYBER 180/855
!   UNDER NOS    (S.P.)        2         1070        177.803
! IEEE (IBM/XT,
!   SUN, ETC.)   (S.P.)        2          128        35.040
! IEEE (IBM/XT,
!   SUN, ETC.)   (D.P.)        2         1024        171.624
! IBM 3033       (D.P.)       16           63        57.574
! VAX D-FORMAT   (D.P.)        2          127        34.844
! VAX G-FORMAT   (D.P.)        2         1023        171.489
!
!                            XINF         EPS        XMININ
!
! CRAY-1         (S.P.)   5.45E+2465   7.11E-15    1.84E-2466
! CYBER 180/855
!   UNDER NOS    (S.P.)   1.26E+322    3.55E-15    3.14E-294
! IEEE (IBM/XT,
!   SUN, ETC.)   (S.P.)   3.40E+38     1.19E-7     1.18E-38
! IEEE (IBM/XT,
!   SUN, ETC.)   (D.P.)   1.79D+308    2.22D-16    2.23D-308
! IBM 3033       (D.P.)   7.23D+75     2.22D-16    1.39D-76
! VAX D-FORMAT   (D.P.)   1.70D+38     1.39D-17    5.88D-39
! VAX G-FORMAT   (D.P.)   8.98D+307    1.11D-16    1.12D-308
!
!*******************************************************************
!*******************************************************************
!
! ERROR RETURNS
!
!  THE PROGRAM RETURNS THE VALUE XINF FOR SINGULARITIES OR
!     WHEN OVERFLOW WOULD OCCUR.  THE COMPUTATION IS BELIEVED
!     TO BE FREE OF UNDERFLOW AND OVERFLOW.
!
!
!  INTRINSIC FUNCTIONS REQUIRED ARE:
!
!     INT, DBLE, EXP, LOG, REAL, SIN
!
!
! REFERENCES:  AN OVERVIEW OF SOFTWARE DEVELOPMENT FOR SPECIAL
!              FUNCTIONS   W. J. CODY, LECTURE NOTES IN MATHEMATICS,
!              506, NUMERICAL ANALYSIS DUNDEE, 1975, G. A. WATSON
!              (ED.), SPRINGER VERLAG, BERLIN, 1976.
!
!              COMPUTER APPROXIMATIONS, HART, ET. AL., WILEY AND
!              SONS, NEW YORK, 1968.
!
!  LATEST MODIFICATION: OCTOBER 12, 1989
!
!  AUTHORS: W. J. CODY AND L. STOLTZ
!           APPLIED MATHEMATICS DIVISION
!           ARGONNE NATIONAL LABORATORY
!           ARGONNE, IL 60439
!
!----------------------------------------------------------------------
      INTEGER I,N
      LOGICAL PARITY

      real(r8) gamma
      REAL(r8) &
!D    DOUBLE PRECISION
         C,CONV,EPS,FACT,HALF,ONE,P,PI,Q,RES,SQRTPI,SUM,TWELVE, &
         TWO,X,XBIG,XDEN,XINF,XMININ,XNUM,Y,Y1,YSQ,Z,ZERO
      DIMENSION C(7),P(8),Q(8)
!----------------------------------------------------------------------
!  MATHEMATICAL CONSTANTS
!----------------------------------------------------------------------
      DATA ONE,HALF,TWELVE,TWO,ZERO/1.0E0_r8,0.5E0_r8,12.0E0_r8,2.0E0_r8,0.0E0_r8/, &
          SQRTPI/0.9189385332046727417803297E0_r8/, &
          PI/3.1415926535897932384626434E0_r8/
!D    DATA ONE,HALF,TWELVE,TWO,ZERO/1.0D0,0.5D0,12.0D0,2.0D0,0.0D0/,
!D   1     SQRTPI/0.9189385332046727417803297D0/,
!D   2     PI/3.1415926535897932384626434D0/
!----------------------------------------------------------------------
!  MACHINE DEPENDENT PARAMETERS
!----------------------------------------------------------------------
      DATA XBIG,XMININ,EPS/35.040E0_r8,1.18E-38_r8,1.19E-7_r8/, &
          XINF/3.4E38_r8/
!D    DATA XBIG,XMININ,EPS/171.624D0,2.23D-308,2.22D-16/,
!D   1     XINF/1.79D308/
!----------------------------------------------------------------------
!  NUMERATOR AND DENOMINATOR COEFFICIENTS FOR RATIONAL MINIMAX
!     APPROXIMATION OVER (1,2).
!----------------------------------------------------------------------
      DATA P/-1.71618513886549492533811E+0_r8,2.47656508055759199108314E+1_r8,&
            -3.79804256470945635097577E+2_r8,6.29331155312818442661052E+2_r8,&
            8.66966202790413211295064E+2_r8,-3.14512729688483675254357E+4_r8,&
            -3.61444134186911729807069E+4_r8,6.64561438202405440627855E+4_r8/
      DATA Q/-3.08402300119738975254353E+1_r8,3.15350626979604161529144E+2_r8,&
           -1.01515636749021914166146E+3_r8,-3.10777167157231109440444E+3_r8,&
             2.25381184209801510330112E+4_r8,4.75584627752788110767815E+3_r8,&
           -1.34659959864969306392456E+5_r8,-1.15132259675553483497211E+5_r8/
!D    DATA P/-1.71618513886549492533811D+0,2.47656508055759199108314D+1,
!D   1       -3.79804256470945635097577D+2,6.29331155312818442661052D+2,
!D   2       8.66966202790413211295064D+2,-3.14512729688483675254357D+4,
!D   3       -3.61444134186911729807069D+4,6.64561438202405440627855D+4/
!D    DATA Q/-3.08402300119738975254353D+1,3.15350626979604161529144D+2,
!D   1      -1.01515636749021914166146D+3,-3.10777167157231109440444D+3,
!D   2        2.25381184209801510330112D+4,4.75584627752788110767815D+3,
!D   3      -1.34659959864969306392456D+5,-1.15132259675553483497211D+5/
!----------------------------------------------------------------------
!  COEFFICIENTS FOR MINIMAX APPROXIMATION OVER (12, INF).
!----------------------------------------------------------------------
      DATA C/-1.910444077728E-03_r8,8.4171387781295E-04_r8, &
          -5.952379913043012E-04_r8,7.93650793500350248E-04_r8,&
          -2.777777777777681622553E-03_r8,8.333333333333333331554247E-02_r8,&
           5.7083835261E-03_r8/
!D    DATA C/-1.910444077728D-03,8.4171387781295D-04,
!D   1     -5.952379913043012D-04,7.93650793500350248D-04,
!D   2     -2.777777777777681622553D-03,8.333333333333333331554247D-02,
!D   3      5.7083835261D-03/
!----------------------------------------------------------------------
!  STATEMENT FUNCTIONS FOR CONVERSION BETWEEN INTEGER AND FLOAT
!----------------------------------------------------------------------
      CONV(I) = REAL(I,r8)
!D    CONV(I) = DBLE(I)
      PARITY=.FALSE.
      FACT=ONE
      N=0
      Y=X
      IF(Y.LE.ZERO)THEN
!----------------------------------------------------------------------
!  ARGUMENT IS NEGATIVE
!----------------------------------------------------------------------
        Y=-X
        Y1=AINT(Y)
        RES=Y-Y1
        IF(RES.NE.ZERO)THEN
          IF(Y1.NE.AINT(Y1*HALF)*TWO)PARITY=.TRUE.
          FACT=-PI/SIN(PI*RES)
          Y=Y+ONE
        ELSE
          RES=XINF
          GOTO 900
        ENDIF
      ENDIF
!----------------------------------------------------------------------
!  ARGUMENT IS POSITIVE
!----------------------------------------------------------------------
      IF(Y.LT.EPS)THEN
!----------------------------------------------------------------------
!  ARGUMENT .LT. EPS
!----------------------------------------------------------------------
        IF(Y.GE.XMININ)THEN
          RES=ONE/Y
        ELSE
          RES=XINF
          GOTO 900
        ENDIF
      ELSEIF(Y.LT.TWELVE)THEN
        Y1=Y
        IF(Y.LT.ONE)THEN
!----------------------------------------------------------------------
!  0.0 .LT. ARGUMENT .LT. 1.0
!----------------------------------------------------------------------
          Z=Y
          Y=Y+ONE
        ELSE
!----------------------------------------------------------------------
!  1.0 .LT. ARGUMENT .LT. 12.0, REDUCE ARGUMENT IF NECESSARY
!----------------------------------------------------------------------
          N=INT(Y)-1
          Y=Y-CONV(N)
          Z=Y-ONE
        ENDIF
!----------------------------------------------------------------------
!  EVALUATE APPROXIMATION FOR 1.0 .LT. ARGUMENT .LT. 2.0
!----------------------------------------------------------------------
        XNUM=ZERO
        XDEN=ONE
        DO 260 I=1,8
          XNUM=(XNUM+P(I))*Z
          XDEN=XDEN*Z+Q(I)
  260   CONTINUE
        RES=XNUM/XDEN+ONE
        IF(Y1.LT.Y)THEN
!----------------------------------------------------------------------
!  ADJUST RESULT FOR CASE  0.0 .LT. ARGUMENT .LT. 1.0
!----------------------------------------------------------------------
          RES=RES/Y1
        ELSEIF(Y1.GT.Y)THEN
!----------------------------------------------------------------------
!  ADJUST RESULT FOR CASE  2.0 .LT. ARGUMENT .LT. 12.0
!----------------------------------------------------------------------
          DO 290 I=1,N
            RES=RES*Y
            Y=Y+ONE
  290     CONTINUE
        ENDIF
      ELSE
!----------------------------------------------------------------------
!  EVALUATE FOR ARGUMENT .GE. 12.0,
!----------------------------------------------------------------------
        IF(Y.LE.XBIG)THEN
          YSQ=Y*Y
          SUM=C(7)
          DO 350 I=1,6
            SUM=SUM/YSQ+C(I)
  350     CONTINUE
          SUM=SUM/Y-Y+SQRTPI
          SUM=SUM+(Y-HALF)*LOG(Y)
          RES=EXP(SUM)
        ELSE
          RES=XINF
          GOTO 900
        ENDIF
      ENDIF
!----------------------------------------------------------------------
!  FINAL ADJUSTMENTS AND RETURN
!----------------------------------------------------------------------
      IF(PARITY)RES=-RES
      IF(FACT.NE.ONE)RES=FACT/RES
  900 GAMMA=RES
!D900 DGAMMA = RES
      RETURN
! ---------- LAST LINE OF GAMMA ----------
      END function gamma


end module cldwat2m_micro