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

          Line data    Source code
       1             : module micro_pumas_v1
       2             : !---------------------------------------------------------------------------------
       3             : ! Purpose:
       4             : !   MG microphysics version 3.0 - Update of MG microphysics with
       5             : !                                 prognostic hail OR graupel.
       6             : !
       7             : ! Author: Andrew Gettelman, Hugh Morrison
       8             : !
       9             : ! Version 3 history: Sep 2016: development begun for hail, graupel 
      10             : !
      11             : ! Version 2 history: Sep 2011: Development begun.
      12             : !                    Feb 2013: Added of prognostic precipitation.
      13             : !                    Aug 2015: Published and released version
      14             : ! Contributions from:  Sean Santos, Peter Caldwell, Xiaohong Liu and Steve Ghan
      15             : !
      16             : ! invoked in CAM by specifying -microphys=mg3
      17             : !
      18             : ! References: 
      19             : !
      20             : !           Gettelman, A. and H. Morrison, Advanced Two-Moment Microphysics for Global Models. 
      21             : !
      22             : !           Part I: Off line tests and comparisons with other schemes. 
      23             : !
      24             : !           J. Climate, 28, 1268-1287. doi: 10.1175/JCLI-D-14-00102.1, 2015. 
      25             : !
      26             : !
      27             : !
      28             : !           Gettelman, A., H. Morrison, S. Santos, P. Bogenschutz and P. H. Caldwell 
      29             : !
      30             : !           Advanced Two-Moment Microphysics for Global Models. 
      31             : !
      32             : !           Part II: Global model solutions and Aerosol-Cloud Interactions. 
      33             : !
      34             : !           J. Climate, 28, 1288-1307. doi:10.1175/JCLI-D-14-00103.1 , 2015. 
      35             : !
      36             : ! for questions contact Hugh Morrison, Andrew Gettelman
      37             : ! e-mail: morrison@ucar.edu, andrew@ucar.edu
      38             : !---------------------------------------------------------------------------------
      39             : !
      40             : ! NOTE: Modified to allow other microphysics packages (e.g. CARMA) to do ice
      41             : ! microphysics in cooperation with the MG liquid microphysics. This is
      42             : ! controlled by the do_cldice variable.
      43             : !
      44             : ! If do_cldice is false, then MG microphysics should not update CLDICE or
      45             : ! NUMICE; it is assumed that the other microphysics scheme will have updated
      46             : ! CLDICE and NUMICE. The other microphysics should handle the following
      47             : ! processes that would have been done by MG:
      48             : !   - Detrainment (liquid and ice)
      49             : !   - Homogeneous ice nucleation
      50             : !   - Heterogeneous ice nucleation
      51             : !   - Bergeron process
      52             : !   - Melting of ice
      53             : !   - Freezing of cloud drops
      54             : !   - Autoconversion (ice -> snow)
      55             : !   - Growth/Sublimation of ice
      56             : !   - Sedimentation of ice
      57             : !
      58             : ! This option has not been updated since the introduction of prognostic
      59             : ! precipitation, and probably should be adjusted to cover snow as well.
      60             : !
      61             : !---------------------------------------------------------------------------------
      62             : ! Version 3.O based on micro_mg2_0.F90 and WRF3.8.1 module_mp_morr_two_moment.F
      63             : !---------------------------------------------------------------------------------
      64             : ! Based on micro_mg (restructuring of former cldwat2m_micro)
      65             : ! Author: Andrew Gettelman, Hugh Morrison.
      66             : ! Contributions from: Xiaohong Liu and Steve Ghan
      67             : ! December 2005-May 2010
      68             : ! Description in: Morrison and Gettelman, 2008. J. Climate (MG2008)
      69             : !                 Gettelman et al., 2010 J. Geophys. Res. - Atmospheres (G2010)
      70             : ! for questions contact Hugh Morrison, Andrew Gettelman
      71             : ! e-mail: morrison@ucar.edu, andrew@ucar.edu
      72             : !---------------------------------------------------------------------------------
      73             : ! Code comments added by HM, 093011
      74             : ! General code structure:
      75             : !
      76             : ! Code is divided into two main subroutines:
      77             : !   subroutine micro_pumas_init --> initializes microphysics routine, should be called
      78             : !                                  once at start of simulation
      79             : !   subroutine micro_pumas_tend --> main microphysics routine to be called each time step
      80             : !                                this also calls several smaller subroutines to calculate
      81             : !                                microphysical processes and other utilities
      82             : !
      83             : ! List of external functions:
      84             : !   qsat_water --> for calculating saturation vapor pressure with respect to liquid water
      85             : !   qsat_ice --> for calculating saturation vapor pressure with respect to ice
      86             : !   gamma   --> standard mathematical gamma function
      87             : ! .........................................................................
      88             : ! List of inputs through use statement in fortran90:
      89             : ! Variable Name                      Description                Units
      90             : ! .........................................................................
      91             : ! gravit          acceleration due to gravity                    m s-2
      92             : ! rair            dry air gas constant for air                  J kg-1 K-1
      93             : ! tmelt           temperature of melting point for water          K
      94             : ! cpair           specific heat at constant pressure for dry air J kg-1 K-1
      95             : ! rh2o            gas constant for water vapor                  J kg-1 K-1
      96             : ! latvap          latent heat of vaporization                   J kg-1
      97             : ! latice          latent heat of fusion                         J kg-1
      98             : ! qsat_water      external function for calculating liquid water
      99             : !                 saturation vapor pressure/humidity              -
     100             : ! qsat_ice        external function for calculating ice
     101             : !                 saturation vapor pressure/humidity              pa
     102             : ! rhmini          relative humidity threshold parameter for
     103             : !                 nucleating ice                                  -
     104             : ! .........................................................................
     105             : ! NOTE: List of all inputs/outputs passed through the call/subroutine statement
     106             : !       for micro_pumas_tend is given below at the start of subroutine micro_pumas_tend.
     107             : !---------------------------------------------------------------------------------
     108             : 
     109             : ! Procedures required:
     110             : ! 1) An implementation of the gamma function (if not intrinsic).
     111             : ! 2) saturation vapor pressure and specific humidity over water
     112             : ! 3) svp over ice
     113             : 
     114             : #ifndef HAVE_GAMMA_INTRINSICS
     115             : use shr_spfn_mod, only: gamma => shr_spfn_gamma
     116             : #endif
     117             : 
     118             : use wv_sat_methods, only: &
     119             :      qsat_water => wv_sat_qsat_water_vect, &
     120             :      qsat_ice => wv_sat_qsat_ice_vect
     121             : 
     122             : ! Parameters from the utilities module.
     123             : use micro_pumas_utils, only: &
     124             :      r8, &
     125             :      pi, &
     126             :      omsm, &
     127             :      qsmall, &
     128             :      mincld, &
     129             :      rhosn, &
     130             :      rhoi, &
     131             :      rhow, &
     132             :      rhows, &
     133             :      ac, bc, &
     134             :      ai, bi, &
     135             :      aj, bj, &
     136             :      ar, br, &
     137             :      as, bs, &
     138             :      ag, bg, &
     139             :      ah, bh, &
     140             :      rhog,rhoh, &
     141             :      mi0, &
     142             :      rising_factorial
     143             : 
     144             : implicit none
     145             : private
     146             : save
     147             : 
     148             : public :: &
     149             :      micro_pumas_init, &
     150             :      micro_pumas_get_cols, &
     151             :      micro_pumas_tend
     152             : 
     153             : ! Switches for specification rather than prediction of droplet and crystal number
     154             : ! note: number will be adjusted as needed to keep mean size within bounds,
     155             : ! even when specified droplet or ice number is used
     156             : !
     157             : ! If constant cloud ice number is set (nicons = .true.),
     158             : ! then all microphysical processes except mass transfer due to ice nucleation
     159             : ! (mnuccd) are based on the fixed cloud ice number. Calculation of
     160             : ! mnuccd follows from the prognosed ice crystal number ni.
     161             : 
     162             : logical :: nccons ! nccons = .true. to specify constant cloud droplet number
     163             : logical :: nicons ! nicons = .true. to specify constant cloud ice number
     164             : logical :: ngcons ! ngcons = .true. to specify constant graupel number
     165             : logical :: nrcons ! constant rain number
     166             : logical :: nscons ! constant snow number
     167             : 
     168             : ! specified ice and droplet number concentrations
     169             : ! note: these are local in-cloud values, not grid-mean
     170             : real(r8) :: ncnst  ! droplet num concentration when nccons=.true. (m-3)
     171             : real(r8) :: ninst  ! ice num concentration when nicons=.true. (m-3)
     172             : real(r8) :: ngnst   ! graupel num concentration when ngcons=.true. (m-3)
     173             : real(r8) :: nrnst
     174             : real(r8) :: nsnst
     175             : 
     176             : ! IFS Switches....
     177             : ! Switch to turn off evaporation of sedimenting condensate 
     178             : ! Found to interact badly in some models with diagnostic cloud fraction
     179             : logical :: evap_sed_off 
     180             : 
     181             : ! Remove RH conditional from ice nucleation
     182             : logical :: icenuc_rh_off
     183             : 
     184             : ! Internally: Meyers Ice Nucleation 
     185             : logical :: icenuc_use_meyers
     186             : 
     187             : ! Scale evaporation as IFS does (*0.3)
     188             : logical :: evap_scl_ifs
     189             : 
     190             : ! Evap RH threhold following ifs
     191             : logical :: evap_rhthrsh_ifs
     192             : 
     193             : ! Rain freezing at 0C following ifs
     194             : 
     195             : logical :: rainfreeze_ifs
     196             : 
     197             : ! Snow sedimentation = 1 m/s
     198             : 
     199             : logical :: ifs_sed
     200             : 
     201             : ! Precipitation fall speed, prevent zero velocity if precip above
     202             : 
     203             : logical :: precip_fall_corr
     204             : 
     205             : !--ag
     206             : 
     207             : !=========================================================
     208             : ! Private module parameters
     209             : !=========================================================
     210             : 
     211             : !Range of cloudsat reflectivities (dBz) for analytic simulator
     212             : real(r8), parameter :: csmin = -30._r8
     213             : real(r8), parameter :: csmax = 26._r8
     214             : real(r8), parameter :: mindbz = -99._r8
     215             : real(r8), parameter :: minrefl = 1.26e-10_r8    ! minrefl = 10._r8**(mindbz/10._r8)
     216             : 
     217             : integer, parameter  :: MG_PRECIP_FRAC_INCLOUD = 101
     218             : integer, parameter  :: MG_PRECIP_FRAC_OVERLAP = 102
     219             : 
     220             : ! autoconversion size threshold for cloud ice to snow (m)
     221             : real(r8) :: dcs
     222             : 
     223             : ! minimum mass of new crystal due to freezing of cloud droplets done
     224             : ! externally (kg)
     225             : real(r8), parameter :: mi0l_min = 4._r8/3._r8*pi*rhow*(4.e-6_r8)**3
     226             : 
     227             : ! Ice number sublimation parameter. Assume some decrease in ice number with sublimation if non-zero. Else, no decrease in number with sublimation. 
     228             : real(r8), parameter :: sublim_factor =0.0_r8      !number sublimation factor. 
     229             : 
     230             : integer, parameter :: VLENS = 128  ! vector length of a GPU compute kernel
     231             : 
     232             : !=========================================================
     233             : ! Constants set in initialization
     234             : !=========================================================
     235             : 
     236             : ! Set using arguments to micro_pumas_init
     237             : real(r8) :: g           ! gravity
     238             : real(r8) :: r           ! dry air gas constant
     239             : real(r8) :: rv          ! water vapor gas constant
     240             : real(r8) :: cpp         ! specific heat of dry air
     241             : real(r8) :: tmelt       ! freezing point of water (K)
     242             : 
     243             : ! latent heats of:
     244             : real(r8) :: xxlv        ! vaporization
     245             : real(r8) :: xlf         ! freezing
     246             : real(r8) :: xxls        ! sublimation
     247             : 
     248             : real(r8) :: rhmini      ! Minimum rh for ice cloud fraction > 0.
     249             : 
     250             : ! flags
     251             : logical :: microp_uniform
     252             : logical :: do_cldice
     253             : logical :: use_hetfrz_classnuc
     254             : logical :: do_hail
     255             : logical :: do_graupel
     256             : 
     257             : real(r8) :: rhosu       ! typical 850mn air density
     258             : 
     259             : real(r8) :: icenuct     ! ice nucleation temperature: currently -5 degrees C
     260             : 
     261             : real(r8) :: snowmelt    ! what temp to melt all snow: currently 2 degrees C
     262             : real(r8) :: rainfrze    ! what temp to freeze all rain: currently -5 degrees C
     263             : 
     264             : ! additional constants to help speed up code
     265             : real(r8) :: gamma_br_plus1
     266             : real(r8) :: gamma_br_plus4
     267             : real(r8) :: gamma_bs_plus1
     268             : real(r8) :: gamma_bs_plus4
     269             : real(r8) :: gamma_bi_plus1
     270             : real(r8) :: gamma_bi_plus4
     271             : real(r8) :: gamma_bj_plus1
     272             : real(r8) :: gamma_bj_plus4
     273             : real(r8) :: gamma_bg_plus1
     274             : real(r8) :: gamma_bg_plus4
     275             : real(r8) :: xxlv_squared
     276             : real(r8) :: xxls_squared
     277             : 
     278             : character(len=16)  :: micro_mg_precip_frac_method  ! type of precipitation fraction method
     279             : real(r8)           :: micro_mg_berg_eff_factor     ! berg efficiency factor
     280             : 
     281             : real(r8)           :: micro_mg_accre_enhan_fact     ! accretion enhancment factor
     282             : real(r8)           :: micro_mg_autocon_fact     ! autoconversion prefactor
     283             : real(r8)           :: micro_mg_autocon_nd_exp     ! autoconversion Nd exponent factor
     284             : real(r8)           :: micro_mg_autocon_lwp_exp  !autoconversion LWP exponent
     285             : real(r8)           :: micro_mg_homog_size ! size of freezing homogeneous ice
     286             : real(r8)           :: micro_mg_vtrmi_factor
     287             : real(r8)           :: micro_mg_effi_factor
     288             : real(r8)           :: micro_mg_iaccr_factor
     289             : real(r8)           :: micro_mg_max_nicons
     290             : 
     291             : logical  :: remove_supersat ! If true, remove supersaturation after sedimentation loop
     292             : logical  :: do_sb_physics ! do SB 2001 autoconversion or accretion physics
     293             : 
     294             : !$acc declare create (nccons,nicons,ngcons,nrcons,nscons,ncnst,ninst,ngnst,   &
     295             : !$acc                 nrnst,nsnst,evap_sed_off,icenuc_rh_off,evap_scl_ifs,    &
     296             : !$acc                 icenuc_use_meyers,evap_rhthrsh_ifs,rainfreeze_ifs,      &
     297             : !$acc                 ifs_sed,precip_fall_corr,dcs,                           &
     298             : !$acc                 g,r,rv,cpp,tmelt,xxlv,xlf,xxls,rhmini,microp_uniform,   &
     299             : !$acc                 do_cldice,use_hetfrz_classnuc,do_hail,do_graupel,rhosu, &
     300             : !$acc                 icenuct,snowmelt,rainfrze,xxlv_squared,xxls_squared,    &
     301             : !$acc                 gamma_br_plus1,gamma_br_plus4,gamma_bs_plus1,           &
     302             : !$acc                 gamma_bs_plus4,gamma_bi_plus1,gamma_bi_plus4,           &
     303             : !$acc                 gamma_bj_plus1,gamma_bj_plus4,gamma_bg_plus1,           &
     304             : !$acc                 gamma_bg_plus4,micro_mg_berg_eff_factor,                &
     305             : !$acc                 remove_supersat,do_sb_physics)
     306             : 
     307             : !===============================================================================
     308             : contains
     309             : !===============================================================================
     310             : 
     311           0 : subroutine micro_pumas_init( &
     312             :      kind, gravit, rair, rh2o, cpair,    &
     313             :      tmelt_in, latvap, latice,           &
     314             :      rhmini_in, micro_mg_dcs,            &
     315             :      micro_mg_do_hail_in,micro_mg_do_graupel_in, &
     316             :      microp_uniform_in, do_cldice_in, use_hetfrz_classnuc_in, &
     317           0 :      micro_mg_precip_frac_method_in, micro_mg_berg_eff_factor_in, &
     318             :      micro_mg_accre_enhan_fact_in, micro_mg_autocon_fact_in, & 
     319             :      micro_mg_autocon_nd_exp_in, micro_mg_autocon_lwp_exp_in, micro_mg_homog_size_in, &
     320             :      micro_mg_vtrmi_factor_in, micro_mg_effi_factor_in,  micro_mg_iaccr_factor_in,&
     321             :      micro_mg_max_nicons_in, &
     322             :      remove_supersat_in, do_sb_physics_in, &
     323             :      micro_mg_evap_sed_off_in, micro_mg_icenuc_rh_off_in, micro_mg_icenuc_use_meyers_in, &
     324             :      micro_mg_evap_scl_ifs_in, micro_mg_evap_rhthrsh_ifs_in, &
     325             :      micro_mg_rainfreeze_ifs_in,  micro_mg_ifs_sed_in, micro_mg_precip_fall_corr, &
     326             :      nccons_in, nicons_in, ncnst_in, ninst_in, ngcons_in, ngnst_in, & 
     327             :      nrcons_in, nrnst_in, nscons_in, nsnst_in, &
     328           0 :      errstring)
     329             : 
     330             :   use micro_pumas_utils, only: micro_pumas_utils_init
     331             : 
     332             :   !-----------------------------------------------------------------------
     333             :   !
     334             :   ! Purpose:
     335             :   ! initialize constants for MG microphysics
     336             :   !
     337             :   ! Author: Andrew Gettelman Dec 2005
     338             :   !
     339             :   !-----------------------------------------------------------------------
     340             : 
     341             :   integer,  intent(in)  :: kind         ! Kind used for reals
     342             :   real(r8), intent(in)  :: gravit
     343             :   real(r8), intent(in)  :: rair
     344             :   real(r8), intent(in)  :: rh2o
     345             :   real(r8), intent(in)  :: cpair
     346             :   real(r8), intent(in)  :: tmelt_in     ! Freezing point of water (K)
     347             :   real(r8), intent(in)  :: latvap
     348             :   real(r8), intent(in)  :: latice
     349             :   real(r8), intent(in)  :: rhmini_in    ! Minimum rh for ice cloud fraction > 0.
     350             :   real(r8), intent(in)  :: micro_mg_dcs
     351             : 
     352             : !MG3 dense precipitating ice. Note, only 1 can be true, or both false.
     353             :   logical,  intent(in)  :: micro_mg_do_graupel_in    ! .true. = configure with graupel
     354             :                                                    ! .false. = no graupel (hail possible)
     355             :   logical,  intent(in)  :: micro_mg_do_hail_in    ! .true. = configure with hail
     356             :                                                    ! .false. = no hail (graupel possible)
     357             :   logical,  intent(in)  :: microp_uniform_in    ! .true. = configure uniform for sub-columns
     358             :                                             ! .false. = use w/o sub-columns (standard)
     359             :   logical,  intent(in)  :: do_cldice_in     ! .true. = do all processes (standard)
     360             :                                             ! .false. = skip all processes affecting
     361             :                                             !           cloud ice
     362             :   logical,  intent(in)  :: use_hetfrz_classnuc_in ! use heterogeneous freezing
     363             : 
     364             :   character(len=16),intent(in)  :: micro_mg_precip_frac_method_in  ! type of precipitation fraction method
     365             :   real(r8),         intent(in)  :: micro_mg_berg_eff_factor_in     ! berg efficiency factor
     366             :   real(r8),         intent(in)  :: micro_mg_accre_enhan_fact_in     !accretion enhancment factor
     367             :   real(r8),         intent(in) ::  micro_mg_autocon_fact_in    !autconversion prefactor
     368             :   real(r8),         intent(in) ::  micro_mg_autocon_nd_exp_in !autconversion exponent factor
     369             :   real(r8),         intent(in) ::  micro_mg_autocon_lwp_exp_in    !autconversion exponent factor      
     370             :   real(r8),         intent(in) ::  micro_mg_homog_size_in  ! size of homoegenous freezing ice
     371             :   real(r8),         intent(in)  :: micro_mg_vtrmi_factor_in    !factor for ice fall velocity
     372             :   real(r8),         intent(in)  :: micro_mg_effi_factor_in    !factor for ice effective radius
     373             :   real(r8),         intent(in)  :: micro_mg_iaccr_factor_in  ! ice accretion factor
     374             :   real(r8),         intent(in)  :: micro_mg_max_nicons_in ! maximum number ice crystal allowed 
     375             : 
     376             :   logical,  intent(in)  ::  remove_supersat_in ! If true, remove supersaturation after sedimentation loop
     377             :   logical,  intent(in)  ::  do_sb_physics_in ! do SB autoconversion and accretion physics
     378             : 
     379             : ! IFS-like Switches
     380             : 
     381             :   logical, intent(in) :: micro_mg_evap_sed_off_in ! Turn off evaporation/sublimation based on cloud fraction for sedimenting condensate
     382             : 
     383             :   logical, intent(in) :: micro_mg_icenuc_rh_off_in ! Remove RH conditional from ice nucleation
     384             :   logical, intent(in) :: micro_mg_icenuc_use_meyers_in ! Internally: Meyers Ice Nucleation
     385             :   logical, intent(in) :: micro_mg_evap_scl_ifs_in ! Scale evaporation as IFS does (*0.3)
     386             :   logical, intent(in) :: micro_mg_evap_rhthrsh_ifs_in ! Evap RH threhold following ifs
     387             :   logical, intent(in) :: micro_mg_rainfreeze_ifs_in ! Rain freezing temp following ifs
     388             :   logical, intent(in) :: micro_mg_ifs_sed_in ! snow sedimentation = 1m/s following ifs
     389             :   logical, intent(in) :: micro_mg_precip_fall_corr ! ensure rain fall speed non-zero if rain above in column
     390             : 
     391             :   logical, intent(in)   :: nccons_in
     392             :   logical, intent(in)   :: nicons_in
     393             :   real(r8), intent(in)  :: ncnst_in
     394             :   real(r8), intent(in)  :: ninst_in
     395             : 
     396             :   logical, intent(in)   :: ngcons_in
     397             :   real(r8), intent(in)  :: ngnst_in
     398             :   logical, intent(in)   :: nrcons_in
     399             :   real(r8), intent(in)  :: nrnst_in
     400             :   logical, intent(in)   :: nscons_in
     401             :   real(r8), intent(in)  :: nsnst_in
     402             : 
     403             :   character(128), intent(out) :: errstring    ! Output status (non-blank for error return)
     404             : 
     405             :   !-----------------------------------------------------------------------
     406             : 
     407           0 :   dcs = micro_mg_dcs
     408             : 
     409             :   ! Initialize subordinate utilities module.
     410             :   call micro_pumas_utils_init(kind, rair, rh2o, cpair, tmelt_in, latvap, latice, &
     411           0 :        dcs, errstring)
     412             : 
     413           0 :   if (trim(errstring) /= "") return
     414             : 
     415             :   ! declarations for MG code (transforms variable names)
     416             : 
     417           0 :   g= gravit                 ! gravity
     418           0 :   r= rair                   ! dry air gas constant: note units(phys_constants are in J/K/kmol)
     419           0 :   rv= rh2o                  ! water vapor gas constant
     420           0 :   cpp = cpair               ! specific heat of dry air
     421           0 :   tmelt = tmelt_in
     422           0 :   rhmini = rhmini_in
     423           0 :   micro_mg_precip_frac_method = micro_mg_precip_frac_method_in
     424           0 :   micro_mg_berg_eff_factor    = micro_mg_berg_eff_factor_in
     425           0 :   micro_mg_accre_enhan_fact   =  micro_mg_accre_enhan_fact_in
     426           0 :   micro_mg_autocon_fact  = micro_mg_autocon_fact_in
     427           0 :   micro_mg_autocon_nd_exp = micro_mg_autocon_nd_exp_in
     428           0 :   micro_mg_autocon_lwp_exp = micro_mg_autocon_lwp_exp_in
     429           0 :   micro_mg_homog_size   = micro_mg_homog_size_in
     430           0 :   micro_mg_vtrmi_factor = micro_mg_vtrmi_factor_in
     431           0 :   micro_mg_effi_factor = micro_mg_effi_factor_in
     432           0 :   micro_mg_iaccr_factor = micro_mg_iaccr_factor_in
     433           0 :   micro_mg_max_nicons = micro_mg_max_nicons_in
     434           0 :   remove_supersat          = remove_supersat_in
     435           0 :   do_sb_physics               = do_sb_physics_in
     436             : 
     437           0 :   nccons = nccons_in
     438           0 :   nicons = nicons_in
     439           0 :   ncnst  = ncnst_in
     440           0 :   ninst  = ninst_in
     441           0 :   ngcons = ngcons_in
     442           0 :   ngnst  = ngnst_in
     443           0 :   nscons = nscons_in
     444           0 :   nsnst  = nsnst_in
     445           0 :   nrcons = nrcons_in
     446           0 :   nrnst  = nrnst_in
     447             : 
     448             :   ! latent heats
     449             : 
     450           0 :   xxlv = latvap         ! latent heat vaporization
     451           0 :   xlf  = latice         ! latent heat freezing
     452           0 :   xxls = xxlv + xlf     ! latent heat of sublimation
     453             : 
     454             :   ! flags
     455           0 :   microp_uniform = microp_uniform_in
     456           0 :   do_cldice  = do_cldice_in
     457           0 :   use_hetfrz_classnuc = use_hetfrz_classnuc_in
     458           0 :   do_hail = micro_mg_do_hail_in
     459           0 :   do_graupel = micro_mg_do_graupel_in
     460           0 :   evap_sed_off = micro_mg_evap_sed_off_in
     461           0 :   icenuc_rh_off = micro_mg_icenuc_rh_off_in
     462           0 :   icenuc_use_meyers = micro_mg_icenuc_use_meyers_in
     463           0 :   evap_scl_ifs = micro_mg_evap_scl_ifs_in
     464           0 :   evap_rhthrsh_ifs = micro_mg_evap_rhthrsh_ifs_in
     465           0 :   rainfreeze_ifs = micro_mg_rainfreeze_ifs_in
     466           0 :   ifs_sed = micro_mg_ifs_sed_in 
     467           0 :   precip_fall_corr = micro_mg_precip_fall_corr
     468             :   ! typical air density at 850 mb
     469             : 
     470           0 :   rhosu = 85000._r8/(rair * tmelt)
     471             : 
     472             :   ! Maximum temperature at which snow is allowed to exist
     473           0 :   snowmelt = tmelt + 2._r8
     474             :   ! Minimum temperature at which rain is allowed to exist
     475           0 :    if (rainfreeze_ifs) then
     476           0 :       rainfrze = tmelt
     477             :    else
     478           0 :       rainfrze = tmelt - 40._r8
     479             :    end if
     480             : 
     481             : 
     482             :   ! Ice nucleation temperature
     483           0 :   icenuct  = tmelt - 5._r8
     484             : 
     485             :   ! Define constants to help speed up code (this limits calls to gamma function)
     486           0 :   gamma_br_plus1=gamma(1._r8+br)
     487           0 :   gamma_br_plus4=gamma(4._r8+br)
     488           0 :   gamma_bs_plus1=gamma(1._r8+bs)
     489           0 :   gamma_bs_plus4=gamma(4._r8+bs)
     490           0 :   gamma_bi_plus1=gamma(1._r8+bi)
     491           0 :   gamma_bi_plus4=gamma(4._r8+bi)
     492           0 :   gamma_bj_plus1=gamma(1._r8+bj)
     493           0 :   gamma_bj_plus4=gamma(4._r8+bj)
     494           0 :   gamma_bg_plus1=gamma(1._r8)
     495           0 :   gamma_bg_plus4=gamma(4._r8)
     496           0 :   if (do_hail) then
     497           0 :      gamma_bg_plus1 = gamma(1._r8+bh)
     498           0 :      gamma_bg_plus4 = gamma(4._r8+bh)
     499             :   end if
     500           0 :   if (do_graupel) then
     501           0 :      gamma_bg_plus1 = gamma(1._r8+bg)
     502           0 :      gamma_bg_plus4 = gamma(4._r8+bg)
     503             :   end if
     504             : 
     505           0 :   xxlv_squared=xxlv**2
     506           0 :   xxls_squared=xxls**2
     507             : 
     508             :   !$acc update device (nccons,nicons,ngcons,nrcons,nscons,ncnst,ninst,ngnst,   &
     509             :   !$acc                nrnst,nsnst,evap_sed_off,icenuc_rh_off,evap_scl_ifs,    &
     510             :   !$acc                icenuc_use_meyers,evap_rhthrsh_ifs,rainfreeze_ifs,      &
     511             :   !$acc                ifs_sed,precip_fall_corr,dcs,                           &
     512             :   !$acc                g,r,rv,cpp,tmelt,xxlv,xlf,xxls,rhmini,microp_uniform,   &
     513             :   !$acc                do_cldice,use_hetfrz_classnuc,do_hail,do_graupel,rhosu, &
     514             :   !$acc                icenuct,snowmelt,rainfrze,xxlv_squared,xxls_squared,    &
     515             :   !$acc                gamma_br_plus1,gamma_br_plus4,gamma_bs_plus1,           &
     516             :   !$acc                gamma_bs_plus4,gamma_bi_plus1,gamma_bi_plus4,           &
     517             :   !$acc                gamma_bj_plus1,gamma_bj_plus4,gamma_bg_plus1,           &
     518             :   !$acc                gamma_bg_plus4,micro_mg_berg_eff_factor,                &
     519             :   !$acc                remove_supersat,do_sb_physics)
     520             : 
     521             : end subroutine micro_pumas_init
     522             : 
     523             : !===============================================================================
     524             : !microphysics routine for each timestep goes here...
     525             : 
     526           0 : subroutine micro_pumas_tend ( &
     527             :      mgncol,             nlev,               deltatin,           &
     528           0 :      t,                            q,                            &
     529           0 :      qcn,                          qin,                          &
     530           0 :      ncn,                          nin,                          &
     531           0 :      qrn,                          qsn,                          &
     532           0 :      nrn,                          nsn,                          &
     533           0 :      qgr,                          ngr,                          &
     534           0 :      relvar,                       accre_enhan,                  &
     535           0 :      p,                            pdel,                         &
     536           0 :      cldn,    liqcldf,        icecldf,       qsatfac,            &
     537           0 :      qcsinksum_rate1ord,                                         &
     538           0 :      naai,                         npccn,                        &
     539           0 :      rndst,                        nacon,                        &
     540           0 :      tlat,                         qvlat,                        &
     541           0 :      qctend,                       qitend,                       &
     542           0 :      nctend,                       nitend,                       &
     543           0 :      qrtend,                       qstend,                       &
     544           0 :      nrtend,                       nstend,                       &
     545           0 :      qgtend,                       ngtend,                       &
     546           0 :      effc,               effc_fn,            effi,               &
     547           0 :      sadice,                       sadsnow,                      &
     548           0 :      prect,                        preci,                        &
     549           0 :      nevapr,                       evapsnow,                     &
     550           0 :      am_evp_st,                                                  &
     551           0 :      prain,                        prodsnow,                     &
     552           0 :      cmeout,                       deffi,                        &
     553           0 :      pgamrad,                      lamcrad,                      &
     554           0 :      qsout,                        dsout,                        &
     555           0 :      qgout,     ngout,             dgout,                        &
     556           0 :      lflx,               iflx,                                   &
     557           0 :      gflx,                                                       &
     558           0 :      rflx,               sflx,               qrout,              &
     559           0 :      reff_rain,          reff_snow,          reff_grau,          &
     560           0 :      qcsevap,            qisevap,            qvres,              &
     561           0 :      cmeitot,            vtrmc,              vtrmi,              &
     562           0 :      umr,                          ums,                          &
     563           0 :      umg,                qgsedten,                               &
     564           0 :      qcsedten,                     qisedten,                     &
     565           0 :      qrsedten,                     qssedten,                     &
     566           0 :      pratot,                       prctot,                       &
     567           0 :      mnuccctot,          mnuccttot,          msacwitot,          &
     568           0 :      psacwstot,          bergstot,           bergtot,            &
     569           0 :      melttot,    meltstot,   meltgtot,       homotot,            &
     570           0 :      qcrestot,           prcitot,            praitot,            &
     571           0 :      qirestot,           mnuccrtot,    mnudeptot,       mnuccritot, pracstot,           &
     572           0 :      meltsdttot,         frzrdttot,          mnuccdtot,          &
     573           0 :      pracgtot,           psacwgtot,          pgsacwtot,          &
     574           0 :      pgracstot,          prdgtot,           &
     575           0 :      qmultgtot,          qmultrgtot,         psacrtot,           &
     576           0 :      npracgtot,          nscngtot,           ngracstot,          &
     577           0 :      nmultgtot,          nmultrgtot,         npsacwgtot,         & 
     578           0 :      nrout,                        nsout,                        &
     579           0 :      refl,               arefl,              areflz,             &
     580           0 :      frefl,              csrfl,              acsrfl,             &
     581           0 :      fcsrfl,                       rercld,                       &
     582           0 :      ncai,                         ncal,                         &
     583           0 :      qrout2,                       qsout2,                       &
     584           0 :      nrout2,                       nsout2,                       &
     585           0 :      drout2,                       dsout2,                       &
     586           0 :      qgout2,        ngout2,        dgout2,    freqg,                   &
     587           0 :      freqs,                        freqr,                        &
     588           0 :      nfice,                        qcrat,                        &
     589           0 :      errstring, & ! Below arguments are "optional" (pass null pointers to omit).
     590           0 :      tnd_qsnow,          tnd_nsnow,          re_ice,             &
     591           0 :      prer_evap,                                                      &
     592           0 :      frzimm,             frzcnt,             frzdep)
     593             : 
     594             :   ! Constituent properties.
     595             :   use micro_pumas_utils, only: &
     596             :        mg_liq_props, &
     597             :        mg_ice_props, &
     598             :        mg_rain_props, &
     599             :        mg_graupel_props, &
     600             :        mg_hail_props, &
     601             :        mg_snow_props
     602             : 
     603             :   ! Size calculation functions.
     604             :   use micro_pumas_utils, only: &
     605             :        size_dist_param_liq, &
     606             :        size_dist_param_basic, &
     607             :        avg_diameter, &
     608             :        avg_diameter_vec
     609             : 
     610             :   ! Microphysical processes.
     611             :   use micro_pumas_utils, only: &
     612             :        ice_deposition_sublimation, &
     613             :        sb2001v2_liq_autoconversion,&
     614             :        sb2001v2_accre_cld_water_rain,&       
     615             :        kk2000_liq_autoconversion, &
     616             :        ice_autoconversion, &
     617             :        immersion_freezing, &
     618             :        contact_freezing, &
     619             :        snow_self_aggregation, &
     620             :        accrete_cloud_water_snow, &
     621             :        secondary_ice_production, &
     622             :        accrete_rain_snow, &
     623             :        heterogeneous_rain_freezing, &
     624             :        accrete_cloud_water_rain, &
     625             :        self_collection_rain, &
     626             :        accrete_cloud_ice_snow, &
     627             :        evaporate_sublimate_precip, &
     628             :        bergeron_process_snow, &
     629             :        graupel_collecting_snow, &
     630             :        graupel_collecting_rain, &
     631             :        graupel_collecting_cld_water, &
     632             :        graupel_riming_liquid_snow, &
     633             :        graupel_rain_riming_snow, &
     634             :        graupel_rime_splintering, &
     635             :        evaporate_sublimate_precip_graupel
     636             : 
     637             :   !Authors: Hugh Morrison, Andrew Gettelman, NCAR, Peter Caldwell, LLNL
     638             :   ! e-mail: morrison@ucar.edu, andrew@ucar.edu
     639             : 
     640             :   ! input arguments
     641             :   integer,  intent(in) :: mgncol         ! number of microphysics columns
     642             :   integer,  intent(in) :: nlev           ! number of layers
     643             :   real(r8), intent(in) :: deltatin       ! time step (s)
     644             :   real(r8), intent(in) :: t(mgncol,nlev) ! input temperature (K)
     645             :   real(r8), intent(in) :: q(mgncol,nlev) ! input h20 vapor mixing ratio (kg/kg)
     646             : 
     647             :   ! note: all input cloud variables are grid-averaged
     648             :   real(r8), intent(in) :: qcn(mgncol,nlev)       ! cloud water mixing ratio (kg/kg)
     649             :   real(r8), intent(in) :: qin(mgncol,nlev)       ! cloud ice mixing ratio (kg/kg)
     650             :   real(r8), intent(in) :: ncn(mgncol,nlev)       ! cloud water number conc (1/kg)
     651             :   real(r8), intent(in) :: nin(mgncol,nlev)       ! cloud ice number conc (1/kg)
     652             : 
     653             :   real(r8), intent(in) :: qrn(mgncol,nlev)       ! rain mixing ratio (kg/kg)
     654             :   real(r8), intent(in) :: qsn(mgncol,nlev)       ! snow mixing ratio (kg/kg)
     655             :   real(r8), intent(in) :: nrn(mgncol,nlev)       ! rain number conc (1/kg)
     656             :   real(r8), intent(in) :: nsn(mgncol,nlev)       ! snow number conc (1/kg)
     657             :   real(r8), intent(in) :: qgr(mgncol,nlev)       ! graupel/hail mixing ratio (kg/kg)
     658             :   real(r8), intent(in) :: ngr(mgncol,nlev)       ! graupel/hail number conc (1/kg)
     659             : 
     660             :   real(r8), intent(in) :: relvar(mgncol,nlev)      ! cloud water relative variance (-)
     661             :   real(r8), intent(in) :: accre_enhan(mgncol,nlev) ! optional accretion
     662             :                                              ! enhancement factor (-)
     663             : 
     664             :   real(r8), intent(in) :: p(mgncol,nlev)        ! air pressure (pa)
     665             :   real(r8), intent(in) :: pdel(mgncol,nlev)     ! pressure difference across level (pa)
     666             : 
     667             :   real(r8), intent(in) :: cldn(mgncol,nlev)      ! cloud fraction (no units)
     668             :   real(r8), intent(in) :: liqcldf(mgncol,nlev)   ! liquid cloud fraction (no units)
     669             :   real(r8), intent(in) :: icecldf(mgncol,nlev)   ! ice cloud fraction (no units)
     670             :   real(r8), intent(in) :: qsatfac(mgncol,nlev)   ! subgrid cloud water saturation scaling factor (no units)
     671             : 
     672             :   ! used for scavenging
     673             :   ! Inputs for aerosol activation
     674             :   real(r8), intent(in) :: naai(mgncol,nlev)     ! ice nucleation number (from microp_aero_ts) (1/kg)
     675             :   real(r8), intent(in) :: npccn(mgncol,nlev)   ! ccn activated number tendency (from microp_aero_ts) (1/kg*s)
     676             : 
     677             :   ! Note that for these variables, the dust bin is assumed to be the last index.
     678             :   ! (For example, in CAM, the last dimension is always size 4.)
     679             :   real(r8), intent(in) :: rndst(:,:,:)  ! radius of each dust bin, for contact freezing (from microp_aero_ts) (m)
     680             :   real(r8), intent(in) :: nacon(:,:,:) ! number in each dust bin, for contact freezing  (from microp_aero_ts) (1/m^3)
     681             :   
     682             :   ! output arguments
     683             : 
     684             :   real(r8), intent(out) :: qcsinksum_rate1ord(mgncol,nlev) ! 1st order rate for
     685             :   ! direct cw to precip conversion
     686             :   real(r8), intent(out) :: tlat(mgncol,nlev)         ! latent heating rate       (W/kg)
     687             :   real(r8), intent(out) :: qvlat(mgncol,nlev)        ! microphysical tendency qv (1/s)
     688             :   real(r8), intent(out) :: qctend(mgncol,nlev)       ! microphysical tendency qc (1/s)
     689             :   real(r8), intent(out) :: qitend(mgncol,nlev)       ! microphysical tendency qi (1/s)
     690             :   real(r8), intent(out) :: nctend(mgncol,nlev)       ! microphysical tendency nc (1/(kg*s))
     691             :   real(r8), intent(out) :: nitend(mgncol,nlev)       ! microphysical tendency ni (1/(kg*s))
     692             : 
     693             :   real(r8), intent(out) :: qrtend(mgncol,nlev)       ! microphysical tendency qr (1/s)
     694             :   real(r8), intent(out) :: qstend(mgncol,nlev)       ! microphysical tendency qs (1/s)
     695             :   real(r8), intent(out) :: nrtend(mgncol,nlev)       ! microphysical tendency nr (1/(kg*s))
     696             :   real(r8), intent(out) :: nstend(mgncol,nlev)       ! microphysical tendency ns (1/(kg*s))
     697             :   real(r8), intent(out) :: qgtend(mgncol,nlev)       ! microphysical tendency qg (1/s)
     698             :   real(r8), intent(out) :: ngtend(mgncol,nlev)       ! microphysical tendency ng (1/(kg*s))
     699             : 
     700             :   real(r8), intent(out) :: effc(mgncol,nlev)         ! droplet effective radius (micron)
     701             :   real(r8), intent(out) :: effc_fn(mgncol,nlev)      ! droplet effective radius, assuming nc = 1.e8 kg-1
     702             :   real(r8), intent(out) :: effi(mgncol,nlev)         ! cloud ice effective radius (micron)
     703             :   real(r8), intent(out) :: sadice(mgncol,nlev)       ! cloud ice surface area density (cm2/cm3)
     704             :   real(r8), intent(out) :: sadsnow(mgncol,nlev)      ! cloud snow surface area density (cm2/cm3)
     705             :   real(r8), intent(out) :: prect(mgncol)             ! surface precip rate (m/s)
     706             :   real(r8), intent(out) :: preci(mgncol)             ! cloud ice/snow precip rate (m/s)
     707             :   real(r8), intent(out) :: nevapr(mgncol,nlev)       ! evaporation rate of rain + snow (1/s)
     708             :   real(r8), intent(out) :: evapsnow(mgncol,nlev)     ! sublimation rate of snow (1/s)
     709             :   real(r8), intent(out) :: am_evp_st(mgncol,nlev)    ! stratiform evaporation area (frac)
     710             :   real(r8), intent(out) :: prain(mgncol,nlev)        ! production of rain + snow (1/s)
     711             :   real(r8), intent(out) :: prodsnow(mgncol,nlev)     ! production of snow (1/s)
     712             :   real(r8), intent(out) :: cmeout(mgncol,nlev)       ! evap/sub of cloud (1/s)
     713             :   real(r8), intent(out) :: deffi(mgncol,nlev)        ! ice effective diameter for optics (radiation) (micron)
     714             :   real(r8), intent(out) :: pgamrad(mgncol,nlev)      ! ice gamma parameter for optics (radiation) (no units)
     715             :   real(r8), intent(out) :: lamcrad(mgncol,nlev)      ! slope of droplet distribution for optics (radiation) (1/m)
     716             :   real(r8), intent(out) :: qsout(mgncol,nlev)        ! snow mixing ratio (kg/kg)
     717             :   real(r8), intent(out) :: dsout(mgncol,nlev)        ! snow diameter (m)
     718             :   real(r8), intent(out) :: lflx(mgncol,nlev+1)       ! grid-box average liquid condensate flux (kg m^-2 s^-1)
     719             :   real(r8), intent(out) :: iflx(mgncol,nlev+1)       ! grid-box average ice condensate flux (kg m^-2 s^-1)
     720             :   real(r8), intent(out) :: rflx(mgncol,nlev+1)       ! grid-box average rain flux (kg m^-2 s^-1)
     721             :   real(r8), intent(out) :: sflx(mgncol,nlev+1)       ! grid-box average snow flux (kg m^-2 s^-1)
     722             :   real(r8), intent(out) :: gflx(mgncol,nlev+1)       ! grid-box average graupel/hail flux (kg m^-2 s^-1)
     723             : 
     724             :   real(r8), intent(out) :: qrout(mgncol,nlev)        ! grid-box average rain mixing ratio (kg/kg)
     725             :   real(r8), intent(out) :: reff_rain(mgncol,nlev)    ! rain effective radius (micron)
     726             :   real(r8), intent(out) :: reff_snow(mgncol,nlev)    ! snow effective radius (micron)
     727             :   real(r8), intent(out) :: reff_grau(mgncol,nlev)    ! graupel effective radius (micron)
     728             :   real(r8), intent(out) :: qcsevap(mgncol,nlev)      ! cloud water evaporation due to sedimentation (1/s)
     729             :   real(r8), intent(out) :: qisevap(mgncol,nlev)      ! cloud ice sublimation due to sublimation (1/s)
     730             :   real(r8), intent(out) :: qvres(mgncol,nlev)        ! residual condensation term to ensure RH < 100% (1/s)
     731             :   real(r8), intent(out) :: cmeitot(mgncol,nlev)      ! grid-mean cloud ice sub/dep (1/s)
     732             :   real(r8), intent(out) :: vtrmc(mgncol,nlev)        ! mass-weighted cloud water fallspeed (m/s)
     733             :   real(r8), intent(out) :: vtrmi(mgncol,nlev)        ! mass-weighted cloud ice fallspeed (m/s)
     734             :   real(r8), intent(out) :: umr(mgncol,nlev)          ! mass weighted rain fallspeed (m/s)
     735             :   real(r8), intent(out) :: ums(mgncol,nlev)          ! mass weighted snow fallspeed (m/s)
     736             :   real(r8), intent(out) :: umg(mgncol,nlev)          ! mass weighted graupel/hail fallspeed (m/s)
     737             :   real(r8), intent(out) :: qgsedten(mgncol,nlev)     ! qg sedimentation tendency (1/s)
     738             :   real(r8), intent(out) :: qcsedten(mgncol,nlev)     ! qc sedimentation tendency (1/s)
     739             :   real(r8), intent(out) :: qisedten(mgncol,nlev)     ! qi sedimentation tendency (1/s)
     740             :   real(r8), intent(out) :: qrsedten(mgncol,nlev)     ! qr sedimentation tendency (1/s)
     741             :   real(r8), intent(out) :: qssedten(mgncol,nlev)     ! qs sedimentation tendency (1/s)
     742             : 
     743             :   ! microphysical process rates for output (mixing ratio tendencies) (all have units of 1/s)
     744             :   real(r8), intent(out) :: pratot(mgncol,nlev)          ! accretion of cloud by rain
     745             :   real(r8), intent(out) :: prctot(mgncol,nlev)          ! autoconversion of cloud to rain
     746             :   real(r8), intent(out) :: mnuccctot(mgncol,nlev)       ! mixing ratio tend due to immersion freezing
     747             :   real(r8), intent(out) :: mnuccttot(mgncol,nlev)       ! mixing ratio tend due to contact freezing
     748             :   real(r8), intent(out) :: msacwitot(mgncol,nlev)       ! mixing ratio tend due to H-M splintering
     749             :   real(r8), intent(out) :: psacwstot(mgncol,nlev)       ! collection of cloud water by snow
     750             :   real(r8), intent(out) :: bergstot(mgncol,nlev)        ! bergeron process on snow
     751             :   real(r8), intent(out) :: bergtot(mgncol,nlev)         ! bergeron process on cloud ice
     752             :   real(r8), intent(out) :: melttot(mgncol,nlev)         ! melting of cloud ice
     753             :   real(r8), intent(out) :: meltstot(mgncol,nlev)         ! melting of snow
     754             :   real(r8), intent(out) :: meltgtot(mgncol,nlev)         ! melting of graupel
     755             :   real(r8), intent(out) :: mnudeptot(mgncol,nlev)       ! deposition nucleation to ice 
     756             :   real(r8), intent(out) :: homotot(mgncol,nlev)         ! homogeneous freezing cloud water
     757             :   real(r8), intent(out) :: qcrestot(mgncol,nlev)        ! residual cloud condensation due to removal of excess supersat
     758             :   real(r8), intent(out) :: prcitot(mgncol,nlev)         ! autoconversion of cloud ice to snow
     759             :   real(r8), intent(out) :: praitot(mgncol,nlev)         ! accretion of cloud ice by snow
     760             :   real(r8), intent(out) :: qirestot(mgncol,nlev)        ! residual ice deposition due to removal of excess supersat
     761             :   real(r8), intent(out) :: mnuccrtot(mgncol,nlev)       ! mixing ratio tendency due to heterogeneous freezing of rain to snow (1/s)
     762             :   real(r8), intent(out) :: mnuccritot(mgncol,nlev)      ! mixing ratio tendency due to heterogeneous freezing of rain to ice (1/s)
     763             :   real(r8), intent(out) :: pracstot(mgncol,nlev)        ! mixing ratio tendency due to accretion of rain by snow (1/s)
     764             :   real(r8), intent(out) :: meltsdttot(mgncol,nlev)      ! latent heating rate due to melting of snow  (W/kg)
     765             :   real(r8), intent(out) :: frzrdttot(mgncol,nlev)       ! latent heating rate due to homogeneous freezing of rain (W/kg)
     766             :   real(r8), intent(out) :: mnuccdtot(mgncol,nlev)       ! mass tendency from ice nucleation
     767             :   real(r8), intent(out) :: pracgtot(mgncol,nlev)        ! change in q collection rain by graupel  (precipf)
     768             :   real(r8), intent(out) :: psacwgtot(mgncol,nlev)       ! change in q collection droplets by graupel (lcldm)
     769             :   real(r8), intent(out) :: pgsacwtot(mgncol,nlev)       ! conversion q to graupel due to collection droplets by snow  (lcldm)
     770             :   real(r8), intent(out) :: pgracstot(mgncol,nlev)       ! conversion q to graupel due to collection rain by snow (precipf)
     771             :   real(r8), intent(out) :: prdgtot(mgncol,nlev)         ! dep of graupel (precipf)
     772             :   real(r8), intent(out) :: qmultgtot(mgncol,nlev)       ! change q due to ice mult droplets/graupel  (lcldm)
     773             :   real(r8), intent(out) :: qmultrgtot(mgncol,nlev)      ! change q due to ice mult rain/graupel (precipf)
     774             :   real(r8), intent(out) :: psacrtot(mgncol,nlev)        ! conversion due to coll of snow by rain (precipf)
     775             :   real(r8), intent(out) :: npracgtot(mgncol,nlev)       ! change n collection rain by graupel  (precipf)
     776             :   real(r8), intent(out) :: nscngtot(mgncol,nlev)        ! change n conversion to graupel due to collection droplets by snow (lcldm)
     777             :   real(r8), intent(out) :: ngracstot(mgncol,nlev)       ! change n conversion to graupel due to collection rain by snow (precipf)
     778             :   real(r8), intent(out) :: nmultgtot(mgncol,nlev)       ! ice mult due to acc droplets by graupel  (lcldm)
     779             :   real(r8), intent(out) :: nmultrgtot(mgncol,nlev)      ! ice mult due to acc rain by graupel  (precipf)
     780             :   real(r8), intent(out) :: npsacwgtot(mgncol,nlev)      ! change n collection droplets by graupel (lcldm?)
     781             :   real(r8), intent(out) :: nrout(mgncol,nlev)        ! rain number concentration (1/m3)
     782             :   real(r8), intent(out) :: nsout(mgncol,nlev)        ! snow number concentration (1/m3)
     783             :   real(r8), intent(out) :: refl(mgncol,nlev)         ! analytic radar reflectivity
     784             :   real(r8), intent(out) :: arefl(mgncol,nlev)        ! average reflectivity will zero points outside valid range
     785             :   real(r8), intent(out) :: areflz(mgncol,nlev)       ! average reflectivity in z.
     786             :   real(r8), intent(out) :: frefl(mgncol,nlev)        ! fractional occurrence of radar reflectivity
     787             :   real(r8), intent(out) :: csrfl(mgncol,nlev)        ! cloudsat reflectivity
     788             :   real(r8), intent(out) :: acsrfl(mgncol,nlev)       ! cloudsat average
     789             :   real(r8), intent(out) :: fcsrfl(mgncol,nlev)       ! cloudsat fractional occurrence of radar reflectivity
     790             :   real(r8), intent(out) :: rercld(mgncol,nlev)       ! effective radius calculation for rain + cloud
     791             :   real(r8), intent(out) :: ncai(mgncol,nlev)         ! output number conc of ice nuclei available (1/m3)
     792             :   real(r8), intent(out) :: ncal(mgncol,nlev)         ! output number conc of CCN (1/m3)
     793             :   real(r8), intent(out) :: qrout2(mgncol,nlev)       ! copy of qrout as used to compute drout2
     794             :   real(r8), intent(out) :: qsout2(mgncol,nlev)       ! copy of qsout as used to compute dsout2
     795             :   real(r8), intent(out) :: nrout2(mgncol,nlev)       ! copy of nrout as used to compute drout2
     796             :   real(r8), intent(out) :: nsout2(mgncol,nlev)       ! copy of nsout as used to compute dsout2
     797             :   real(r8), intent(out) :: drout2(mgncol,nlev)       ! mean rain particle diameter (m)
     798             :   real(r8), intent(out) :: dsout2(mgncol,nlev)       ! mean snow particle diameter (m)
     799             :   real(r8), intent(out) :: freqs(mgncol,nlev)        ! fractional occurrence of snow
     800             :   real(r8), intent(out) :: freqr(mgncol,nlev)        ! fractional occurrence of rain
     801             :   real(r8), intent(out) :: nfice(mgncol,nlev)        ! fractional occurrence of ice
     802             :   real(r8), intent(out) :: qcrat(mgncol,nlev)        ! limiter for qc process rates (1=no limit --> 0. no qc)
     803             :   real(r8), intent(out) :: qgout(mgncol,nlev)        ! graupel/hail mixing ratio (kg/kg)
     804             :   real(r8), intent(out) :: dgout(mgncol,nlev)        ! graupel/hail diameter (m)
     805             :   real(r8), intent(out) :: ngout(mgncol,nlev)        ! graupel/hail number concentration (1/m3)
     806             :   real(r8), intent(out) :: qgout2(mgncol,nlev)       ! copy of qgout as used to compute dgout2
     807             :   real(r8), intent(out) :: ngout2(mgncol,nlev)       ! copy of ngout as used to compute dgout2
     808             :   real(r8), intent(out) :: dgout2(mgncol,nlev)       ! mean graupel/hail particle diameter (m)
     809             :   real(r8), intent(out) :: freqg(mgncol,nlev)        ! fractional occurrence of graupel  
     810             : 
     811             :   real(r8), intent(out) :: prer_evap(mgncol,nlev)
     812             : 
     813             :   character(128),   intent(out) :: errstring  ! output status (non-blank for error return)
     814             : 
     815             :   ! Tendencies calculated by external schemes that can replace MG's native
     816             :   ! process tendencies.
     817             : 
     818             :   ! Used with CARMA cirrus microphysics
     819             :   ! (or similar external microphysics model)
     820             :   real(r8), intent(in) :: tnd_qsnow(:,:) ! snow mass tendency (kg/kg/s)
     821             :   real(r8), intent(in) :: tnd_nsnow(:,:) ! snow number tendency (#/kg/s)
     822             :   real(r8), intent(in) :: re_ice(:,:)    ! ice effective radius (m)
     823             : 
     824             :   ! From external ice nucleation.
     825             :   real(r8), intent(in) :: frzimm(:,:) ! Number tendency due to immersion freezing (1/cm3)
     826             :   real(r8), intent(in) :: frzcnt(:,:) ! Number tendency due to contact freezing (1/cm3)
     827             :   real(r8), intent(in) :: frzdep(:,:) ! Number tendency due to deposition nucleation (1/cm3)
     828             : 
     829             :   ! local workspace
     830             :   ! all units mks unless otherwise stated
     831             : 
     832             :   ! local copies of input variables
     833           0 :   real(r8) :: qc(mgncol,nlev)      ! cloud liquid mixing ratio (kg/kg)
     834           0 :   real(r8) :: qi(mgncol,nlev)      ! cloud ice mixing ratio (kg/kg)
     835           0 :   real(r8) :: nc(mgncol,nlev)      ! cloud liquid number concentration (1/kg)
     836           0 :   real(r8) :: ni(mgncol,nlev)      ! cloud liquid number concentration (1/kg)
     837           0 :   real(r8) :: qr(mgncol,nlev)      ! rain mixing ratio (kg/kg)
     838           0 :   real(r8) :: qs(mgncol,nlev)      ! snow mixing ratio (kg/kg)
     839           0 :   real(r8) :: nr(mgncol,nlev)      ! rain number concentration (1/kg)
     840           0 :   real(r8) :: ns(mgncol,nlev)      ! snow number concentration (1/kg)
     841           0 :   real(r8) :: qg(mgncol,nlev)      ! graupel mixing ratio (kg/kg)
     842           0 :   real(r8) :: ng(mgncol,nlev)      ! graupel number concentration (1/kg)
     843             :   real(r8) :: rhogtmp              ! hail or graupel density (kg m-3)
     844             : 
     845             :   ! general purpose variables
     846             :   real(r8) :: deltat            ! sub-time step (s)
     847             :   real(r8) :: mtime             ! the assumed ice nucleation timescale
     848             :   real(r8) :: rdeltat           ! reciprocal of sub-time step (1/s)
     849             : 
     850             :   ! physical properties of the air at a given point
     851           0 :   real(r8) :: rho(mgncol,nlev)    ! density (kg m-3)
     852           0 :   real(r8) :: dv(mgncol,nlev)     ! diffusivity of water vapor
     853           0 :   real(r8) :: mu(mgncol,nlev)     ! viscosity
     854           0 :   real(r8) :: sc(mgncol,nlev)     ! schmidt number
     855           0 :   real(r8) :: rhof(mgncol,nlev)   ! density correction factor for fallspeed
     856             : 
     857             :   ! cloud fractions
     858           0 :   real(r8) :: precip_frac(mgncol,nlev) ! precip fraction assuming maximum overlap
     859           0 :   real(r8) :: cldm(mgncol,nlev)   ! cloud fraction
     860           0 :   real(r8) :: icldm(mgncol,nlev)  ! ice cloud fraction
     861           0 :   real(r8) :: lcldm(mgncol,nlev)  ! liq cloud fraction
     862           0 :   real(r8) :: qsfm(mgncol,nlev)   ! subgrid cloud water saturation scaling factor
     863             : 
     864             :   ! mass mixing ratios
     865           0 :   real(r8) :: qcic(mgncol,nlev)   ! in-cloud cloud liquid
     866           0 :   real(r8) :: qiic(mgncol,nlev)   ! in-cloud cloud ice
     867           0 :   real(r8) :: qsic(mgncol,nlev)   ! in-precip snow
     868           0 :   real(r8) :: qric(mgncol,nlev)   ! in-precip rain
     869           0 :   real(r8) :: qgic(mgncol,nlev)   ! in-precip graupel/hail
     870             : 
     871             :   ! number concentrations
     872           0 :   real(r8) :: ncic(mgncol,nlev)   ! in-cloud droplet
     873           0 :   real(r8) :: niic(mgncol,nlev)   ! in-cloud cloud ice
     874           0 :   real(r8) :: nsic(mgncol,nlev)   ! in-precip snow
     875           0 :   real(r8) :: nric(mgncol,nlev)   ! in-precip rain
     876           0 :   real(r8) :: ngic(mgncol,nlev)   ! in-precip graupel/hail
     877             : 
     878             :   ! maximum allowed ni value
     879           0 :   real(r8) :: nimax(mgncol,nlev)
     880             : 
     881             :   ! Size distribution parameters for:
     882             :   ! cloud ice
     883           0 :   real(r8) :: lami(mgncol,nlev)   ! slope
     884           0 :   real(r8) :: n0i(mgncol,nlev)    ! intercept
     885             :   ! cloud liquid
     886           0 :   real(r8) :: lamc(mgncol,nlev)   ! slope
     887           0 :   real(r8) :: pgam(mgncol,nlev)   ! spectral width parameter
     888             :   ! snow
     889           0 :   real(r8) :: lams(mgncol,nlev)   ! slope
     890           0 :   real(r8) :: n0s(mgncol,nlev)    ! intercept
     891             :   ! rain
     892           0 :   real(r8) :: lamr(mgncol,nlev)   ! slope
     893           0 :   real(r8) :: n0r(mgncol,nlev)    ! intercept 
     894             :   ! graupel/hail
     895           0 :   real(r8) :: lamg(mgncol,nlev)   ! slope
     896           0 :   real(r8) :: n0g(mgncol,nlev)    ! intercept
     897             :   real(r8) :: bgtmp               ! tmp fall speed parameter
     898             : 
     899             :   ! Rates/tendencies due to:
     900             : 
     901             :   ! Instantaneous snow melting
     902           0 :   real(r8) :: minstsm(mgncol,nlev)    ! mass mixing ratio
     903           0 :   real(r8) :: ninstsm(mgncol,nlev)    ! number concentration
     904             :   ! Instantaneous graupel melting
     905           0 :   real(r8) :: minstgm(mgncol,nlev)    ! mass mixing ratio
     906           0 :   real(r8) :: ninstgm(mgncol,nlev)    ! number concentration
     907             : 
     908             :   ! Instantaneous rain freezing
     909           0 :   real(r8) :: minstrf(mgncol,nlev)    ! mass mixing ratio
     910           0 :   real(r8) :: ninstrf(mgncol,nlev)    ! number concentration
     911             : 
     912             :   ! deposition of cloud ice
     913           0 :   real(r8) :: vap_dep(mgncol,nlev)    ! deposition from vapor to ice PMC 12/3/12
     914             :   ! sublimation of cloud ice
     915           0 :   real(r8) :: ice_sublim(mgncol,nlev) ! sublimation from ice to vapor PMC 12/3/12
     916             :   ! ice nucleation
     917           0 :   real(r8) :: nnuccd(mgncol,nlev) ! number rate from deposition/cond.-freezing
     918           0 :   real(r8) :: mnuccd(mgncol,nlev) ! mass mixing ratio
     919             :   ! freezing of cloud water
     920           0 :   real(r8) :: mnuccc(mgncol,nlev) ! mass mixing ratio
     921           0 :   real(r8) :: nnuccc(mgncol,nlev) ! number concentration
     922             :   ! contact freezing of cloud water
     923           0 :   real(r8) :: mnucct(mgncol,nlev) ! mass mixing ratio
     924           0 :   real(r8) :: nnucct(mgncol,nlev) ! number concentration
     925             :   ! deposition nucleation in mixed-phase clouds (from external scheme)
     926           0 :   real(r8) :: mnudep(mgncol,nlev) ! mass mixing ratio
     927           0 :   real(r8) :: nnudep(mgncol,nlev) ! number concentration
     928             :   ! ice multiplication
     929           0 :   real(r8) :: msacwi(mgncol,nlev) ! mass mixing ratio
     930           0 :   real(r8) :: nsacwi(mgncol,nlev) ! number concentration
     931             :   ! autoconversion of cloud droplets
     932           0 :   real(r8) :: prc(mgncol,nlev)    ! mass mixing ratio
     933           0 :   real(r8) :: nprc(mgncol,nlev)   ! number concentration (rain)
     934           0 :   real(r8) :: nprc1(mgncol,nlev)  ! number concentration (cloud droplets)
     935             :   ! self-aggregation of snow
     936           0 :   real(r8) :: nsagg(mgncol,nlev)  ! number concentration
     937             :   ! self-collection of rain
     938           0 :   real(r8) :: nragg(mgncol,nlev)  ! number concentration
     939             :   ! collection of droplets by snow
     940           0 :   real(r8) :: psacws(mgncol,nlev)     ! mass mixing ratio
     941           0 :   real(r8) :: npsacws(mgncol,nlev)    ! number concentration
     942             :   ! collection of rain by snow
     943           0 :   real(r8) :: pracs(mgncol,nlev)  ! mass mixing ratio
     944           0 :   real(r8) :: npracs(mgncol,nlev) ! number concentration
     945             :   ! freezing of rain
     946           0 :   real(r8) :: mnuccr(mgncol,nlev) ! mass mixing ratio
     947           0 :   real(r8) :: nnuccr(mgncol,nlev) ! number concentration
     948             :   ! freezing of rain to form ice (mg add 4/26/13)
     949           0 :   real(r8) :: mnuccri(mgncol,nlev)    ! mass mixing ratio
     950           0 :   real(r8) :: nnuccri(mgncol,nlev)    ! number concentration
     951             :   ! accretion of droplets by rain
     952           0 :   real(r8) :: pra(mgncol,nlev)    ! mass mixing ratio
     953           0 :   real(r8) :: npra(mgncol,nlev)   ! number concentration
     954             :   ! autoconversion of cloud ice to snow
     955           0 :   real(r8) :: prci(mgncol,nlev)   ! mass mixing ratio
     956           0 :   real(r8) :: nprci(mgncol,nlev)  ! number concentration
     957             :   ! accretion of cloud ice by snow
     958           0 :   real(r8) :: prai(mgncol,nlev)   ! mass mixing ratio
     959           0 :   real(r8) :: nprai(mgncol,nlev)  ! number concentration
     960             :   ! evaporation of rain
     961           0 :   real(r8) :: pre(mgncol,nlev)    ! mass mixing ratio
     962             :   ! sublimation of snow
     963           0 :   real(r8) :: prds(mgncol,nlev)   ! mass mixing ratio
     964             :   ! number evaporation
     965           0 :   real(r8) :: nsubi(mgncol,nlev)  ! cloud ice
     966           0 :   real(r8) :: nsubc(mgncol,nlev)  ! droplet
     967           0 :   real(r8) :: nsubs(mgncol,nlev)  ! snow
     968           0 :   real(r8) :: nsubr(mgncol,nlev)  ! rain
     969             :   ! bergeron process
     970           0 :   real(r8) :: berg(mgncol,nlev)   ! mass mixing ratio (cloud ice)
     971           0 :   real(r8) :: bergs(mgncol,nlev)  ! mass mixing ratio (snow)
     972             : 
     973             :   !graupel/hail processes
     974           0 :   real(r8) :: npracg(mgncol,nlev)  ! change n collection rain by graupel  (precipf)
     975           0 :   real(r8) :: nscng(mgncol,nlev)   ! change n conversion to graupel due to collection droplets by snow (lcldm)
     976           0 :   real(r8) :: ngracs(mgncol,nlev)  ! change n conversion to graupel due to collection rain by snow (precipf)
     977           0 :   real(r8) :: nmultg(mgncol,nlev)  ! ice mult due to acc droplets by graupel  (lcldm)
     978           0 :   real(r8) :: nmultrg(mgncol,nlev) ! ice mult due to acc rain by graupel  (precipf)
     979           0 :   real(r8) :: npsacwg(mgncol,nlev) ! change n collection droplets by graupel (lcldm)
     980             : 
     981           0 :   real(r8) :: psacr(mgncol,nlev)   ! conversion due to coll of snow by rain (precipf)
     982           0 :   real(r8) :: pracg(mgncol,nlev)   ! change in q collection rain by graupel  (precipf)
     983           0 :   real(r8) :: psacwg(mgncol,nlev)  ! change in q collection droplets by graupel (lcldm)
     984           0 :   real(r8) :: pgsacw(mgncol,nlev)  ! conversion q to graupel due to collection droplets by snow  (lcldm)
     985           0 :   real(r8) :: pgracs(mgncol,nlev)  ! conversion q to graupel due to collection rain by snow (precipf)
     986           0 :   real(r8) :: prdg(mgncol,nlev)    ! dep of graupel (precipf)
     987           0 :   real(r8) :: qmultg(mgncol,nlev)  ! change q due to ice mult droplets/graupel  (lcldm)
     988           0 :   real(r8) :: qmultrg(mgncol,nlev) ! change q due to ice mult rain/graupel (precipf)
     989             : 
     990             : 
     991             :   ! fallspeeds
     992             :   ! number-weighted
     993           0 :   real(r8) :: uns(mgncol,nlev)    ! snow
     994           0 :   real(r8) :: unr(mgncol,nlev)    ! rain
     995           0 :   real(r8) :: ung(mgncol,nlev)    ! graupel/hail
     996             : 
     997             :   ! air density corrected fallspeed parameters
     998           0 :   real(r8) :: arn(mgncol,nlev)    ! rain
     999           0 :   real(r8) :: asn(mgncol,nlev)    ! snow
    1000           0 :   real(r8) :: agn(mgncol,nlev)    ! graupel
    1001           0 :   real(r8) :: acn(mgncol,nlev)    ! cloud droplet
    1002           0 :   real(r8) :: ain(mgncol,nlev)    ! cloud ice
    1003           0 :   real(r8) :: ajn(mgncol,nlev)    ! cloud small ice
    1004             : 
    1005             :   ! Mass of liquid droplets used with external heterogeneous freezing.
    1006           0 :   real(r8) :: mi0l(mgncol,nlev)
    1007             : 
    1008             :   ! saturation vapor pressures
    1009           0 :   real(r8) :: esl(mgncol,nlev)    ! liquid
    1010           0 :   real(r8) :: esi(mgncol,nlev)    ! ice
    1011           0 :   real(r8) :: esnA(mgncol,nlev)   ! checking for RH after rain evap
    1012             : 
    1013             :   ! saturation vapor mixing ratios
    1014           0 :   real(r8) :: qvl(mgncol,nlev)    ! liquid
    1015           0 :   real(r8) :: qvi(mgncol,nlev)    ! ice
    1016           0 :   real(r8) :: qvnA(mgncol,nlev), qvnAI(mgncol,nlev) ! checking for RH after rain evap
    1017             : 
    1018             :   ! relative humidity
    1019           0 :   real(r8) :: relhum(mgncol,nlev)
    1020             : 
    1021             :   ! parameters for cloud water and cloud ice sedimentation calculations
    1022           0 :   real(r8) :: fc(mgncol,nlev)
    1023           0 :   real(r8) :: fnc(mgncol,nlev)
    1024           0 :   real(r8) :: fi(mgncol,nlev)
    1025           0 :   real(r8) :: fni(mgncol,nlev)
    1026           0 :   real(r8) :: fg(mgncol,nlev)
    1027           0 :   real(r8) :: fng(mgncol,nlev)
    1028           0 :   real(r8) :: fr(mgncol,nlev)
    1029           0 :   real(r8) :: fnr(mgncol,nlev)
    1030           0 :   real(r8) :: fs(mgncol,nlev)
    1031           0 :   real(r8) :: fns(mgncol,nlev)
    1032             : 
    1033             :   real(r8) :: faloutc(nlev)
    1034             :   real(r8) :: faloutnc(nlev)
    1035             :   real(r8) :: falouti(nlev)
    1036             :   real(r8) :: faloutni(nlev)
    1037             : 
    1038             :   real(r8) :: faloutr(nlev)
    1039             :   real(r8) :: faloutnr(nlev)
    1040             :   real(r8) :: falouts(nlev)
    1041             :   real(r8) :: faloutns(nlev)
    1042             : 
    1043           0 :   real(r8) :: rainrt(mgncol,nlev)     ! rain rate for reflectivity calculation
    1044             : 
    1045             :   ! dummy variables
    1046             :   real(r8) :: dum, dum1, dum2, dum3, dum4, qtmp
    1047           0 :   real(r8) :: dum1A(mgncol,nlev), dum2A(mgncol,nlev), dum3A(mgncol,nlev)
    1048           0 :   real(r8) :: dumni0, dumni0A2D(mgncol,nlev)
    1049           0 :   real(r8) :: dumns0, dumns0A2D(mgncol,nlev)
    1050             :   ! dummies for checking RH
    1051           0 :   real(r8) :: ttmpA(mgncol,nlev), qtmpAI(mgncol,nlev)
    1052             :   ! dummies for conservation check
    1053             :   real(r8) :: ratio
    1054             :   real(r8) :: tmpfrz
    1055             :   ! dummies for in-cloud variables
    1056           0 :   real(r8) :: dumc(mgncol,nlev)   ! qc
    1057           0 :   real(r8) :: dumnc(mgncol,nlev)  ! nc
    1058           0 :   real(r8) :: dumi(mgncol,nlev)   ! qi
    1059           0 :   real(r8) :: dumni(mgncol,nlev)  ! ni
    1060           0 :   real(r8) :: dumr(mgncol,nlev)   ! rain mixing ratio
    1061           0 :   real(r8) :: dumnr(mgncol,nlev)  ! rain number concentration
    1062           0 :   real(r8) :: dums(mgncol,nlev)   ! snow mixing ratio
    1063           0 :   real(r8) :: dumns(mgncol,nlev)  ! snow number concentration
    1064           0 :   real(r8) :: dumg(mgncol,nlev)   ! graupel mixing ratio
    1065           0 :   real(r8) :: dumng(mgncol,nlev)  ! graupel number concentration
    1066             :   ! Array dummy variable
    1067           0 :   real(r8) :: dum_2D(mgncol,nlev)
    1068           0 :   real(r8) :: pdel_inv(mgncol,nlev)
    1069             : 
    1070             :   ! loop array variables
    1071             :   ! "i" and "k" are column/level iterators for internal (MG) variables
    1072             :   ! "n" is used for other looping (currently just sedimentation)
    1073             :   integer i, k, n
    1074             : 
    1075             :   ! number of sub-steps for loops over "n" (for sedimentation)
    1076             :   integer nstep
    1077             :   integer mdust
    1078             :   integer :: precip_frac_method
    1079             : 
    1080             :   ! Varaibles to scale fall velocity between small and regular ice regimes.
    1081             :   real(r8) :: irad
    1082             :   real(r8) :: ifrac
    1083             : 
    1084             :   real(r8) :: nimey  !meyers ice nucleation
    1085           0 :   real(r8) :: niact(mgncol,nlev) ! dummy for modified activation
    1086             : 
    1087             :   !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1088             : 
    1089             :   ! Return error message
    1090           0 :   errstring = ' '
    1091             : 
    1092             :   ! Process inputs
    1093             : 
    1094             :   ! assign variable deltat to deltatin
    1095           0 :   deltat  = deltatin
    1096           0 :   rdeltat = 1._r8 / deltat
    1097             : 
    1098           0 :   if (trim(micro_mg_precip_frac_method) == 'in_cloud') then
    1099             :      precip_frac_method = MG_PRECIP_FRAC_INCLOUD
    1100           0 :   else if(trim(micro_mg_precip_frac_method) == 'max_overlap') then
    1101             :      precip_frac_method = MG_PRECIP_FRAC_OVERLAP
    1102             :   endif
    1103             : 
    1104             :   !===============================================
    1105             :   ! Set ice nucleation timescale to deltat before microphysics loop 
    1106           0 :   mtime=deltat
    1107             : 
    1108             :   !......................................................................
    1109             :   !       graupel/hail density set (Hail = 400, Graupel = 500 from M2005)
    1110           0 :   bgtmp=0._r8
    1111           0 :   rhogtmp=0._r8
    1112           0 :   if (do_hail) then
    1113           0 :      bgtmp = bh
    1114           0 :      rhogtmp = rhoh
    1115             :   end if
    1116           0 :   if (do_graupel) then
    1117           0 :      bgtmp = bg
    1118           0 :      rhogtmp = rhog
    1119             :   end if
    1120             : 
    1121             :   ! set mdust as the number of dust bins for use later in contact freezing subroutine
    1122           0 :   mdust = size(rndst,3)
    1123             : 
    1124             :   !$acc data copyin  (t,q,qcn,qin,ncn,nin,qrn,qsn,nrn,nsn,qgr,ngr,relvar, &
    1125             :   !$acc               accre_enhan,p,pdel,cldn,liqcldf,icecldf,qsatfac,    &
    1126             :   !$acc               naai,npccn,rndst,nacon,tnd_qsnow,tnd_nsnow,re_ice,  &
    1127             :   !$acc               frzimm,frzcnt,frzdep,mg_liq_props,mg_ice_props,     &
    1128             :   !$acc               mg_rain_props,mg_graupel_props,mg_hail_props,       &
    1129             :   !$acc               mg_snow_props)                                      &
    1130             :   !$acc      copyout (qcsinksum_rate1ord,tlat,qvlat,qctend,qitend,nctend, &
    1131             :   !$acc               nitend,qrtend,qstend,nrtend,nstend,qgtend,ngtend,   &
    1132             :   !$acc               effc,effc_fn,effi,sadice,sadsnow,prect,preci,       &
    1133             :   !$acc               nevapr,evapsnow,am_evp_st,prain,prodsnow,cmeout,    &
    1134             :   !$acc               deffi,pgamrad,lamcrad,qsout,dsout,lflx,iflx,rflx,   &
    1135             :   !$acc               sflx,gflx,qrout,reff_rain,reff_snow,reff_grau,      &
    1136             :   !$acc               qcsevap,qisevap,qvres,cmeitot,vtrmc,vtrmi,umr,ums,  &
    1137             :   !$acc               umg,qgsedten,qcsedten,qisedten,qrsedten,qssedten,   &
    1138             :   !$acc               pratot,prctot,mnuccctot,mnuccttot,msacwitot,        &
    1139             :   !$acc               psacwstot,bergstot,bergtot,melttot,meltstot,        &
    1140             :   !$acc               meltgtot,mnudeptot,homotot,qcrestot,prcitot,        &
    1141             :   !$acc               praitot,qirestot,mnuccrtot,mnuccritot,pracstot,     &
    1142             :   !$acc               meltsdttot,frzrdttot,mnuccdtot,pracgtot,psacwgtot,  &
    1143             :   !$acc               pgsacwtot,pgracstot,prdgtot,qmultgtot,qmultrgtot,   &
    1144             :   !$acc               psacrtot,npracgtot,nscngtot,ngracstot,nmultgtot,    &
    1145             :   !$acc               nmultrgtot,npsacwgtot,nrout,nsout,refl,arefl,       &
    1146             :   !$acc               areflz,frefl,csrfl,acsrfl,fcsrfl,rercld,ncai,ncal,  &
    1147             :   !$acc               qrout2,qsout2,nrout2,nsout2,drout2,dsout2,freqs,    &
    1148             :   !$acc               freqr,nfice,qcrat,qgout,dgout,ngout,qgout2,ngout2,  &
    1149             :   !$acc               dgout2,freqg,prer_evap)                             &
    1150             :   !$acc      create  (qc,qi,nc,ni,qr,qs,nr,ns,qg,ng,rho,dv,mu,sc,rhof,    &
    1151             :   !$acc               precip_frac,cldm,icldm,lcldm,qsfm,qcic,qiic,qsic,   &
    1152             :   !$acc               qric,qgic,ncic,niic,nsic,nric,ngic,nimax,lami,n0i,  &
    1153             :   !$acc               lamc,pgam,lams,n0s,lamr,n0r,lamg,n0g,minstsm,       &
    1154             :   !$acc               ninstsm,minstgm,ninstgm,minstrf,ninstrf,vap_dep,    &
    1155             :   !$acc               ice_sublim,nnuccd,mnuccd,mnuccc,nnuccc,mnucct,      &
    1156             :   !$acc               nnucct,mnudep,nnudep,msacwi,nsacwi,prc,nprc,nprc1,  &
    1157             :   !$acc               nsagg,nragg,psacws,npsacws,pracs,npracs,mnuccr,     &
    1158             :   !$acc               nnuccr,mnuccri,nnuccri,pra,npra,prci,nprci,prai,    &
    1159             :   !$acc               nprai,pre,prds,nsubi,nsubc,nsubs,nsubr,berg,bergs,  &
    1160             :   !$acc               npracg,nscng,ngracs,nmultg,nmultrg,npsacwg,psacr,   &
    1161             :   !$acc               pracg,psacwg,pgsacw,pgracs,prdg,qmultg,qmultrg,uns, &
    1162             :   !$acc               unr,ung,arn,asn,agn,acn,ain,ajn,mi0l,esl,esi,esnA,  &
    1163             :   !$acc               qvl,qvi,qvnA,qvnAI,relhum,fc,fnc,fi,fni,fg,fng,fr,  &
    1164             :   !$acc               fnr,fs,fns,faloutc,faloutnc,falouti,faloutni,       &
    1165             :   !$acc               faloutr,faloutnr,falouts,faloutns,rainrt,dum1A,     &
    1166             :   !$acc               dum2A,dum3A,dumni0A2D,dumns0A2D,ttmpA,qtmpAI,dumc,  &
    1167             :   !$acc               dumnc,dumi,dumni,dumr,dumnr,dums,dumns,dumg,dumng,  &
    1168             :   !$acc               dum_2D,pdel_inv,niact)    
    1169             : 
    1170             :   ! Copies of input concentrations that may be changed internally.
    1171             : 
    1172             :   !$acc parallel vector_length(VLENS) default(present)
    1173             :   !$acc loop gang vector collapse(2)
    1174           0 :   do k = 1,nlev
    1175           0 :      do i = 1,mgncol
    1176           0 :         qc(i,k) = qcn(i,k)
    1177           0 :         nc(i,k) = ncn(i,k)
    1178           0 :         qi(i,k) = qin(i,k)
    1179           0 :         ni(i,k) = nin(i,k)
    1180           0 :         qr(i,k) = qrn(i,k)
    1181           0 :         nr(i,k) = nrn(i,k)
    1182           0 :         qs(i,k) = qsn(i,k)
    1183           0 :         ns(i,k) = nsn(i,k)
    1184           0 :         qg(i,k) = qgr(i,k)
    1185           0 :         ng(i,k) = ngr(i,k)
    1186             :      end do
    1187             :   end do
    1188             : 
    1189             :   ! cldn: used to set cldm, unused for subcolumns
    1190             :   ! liqcldf: used to set lcldm, unused for subcolumns
    1191             :   ! icecldf: used to set icldm, unused for subcolumns
    1192             : 
    1193           0 :   if (microp_uniform) then
    1194             :      ! subcolumns, set cloud fraction variables to one
    1195             :      ! if cloud water or ice is present, if not present
    1196             :      ! set to mincld (mincld used instead of zero, to prevent
    1197             :      ! possible division by zero errors).
    1198             : 
    1199             :      !$acc loop gang vector collapse(2)
    1200           0 :      do k=1,nlev
    1201           0 :        do i=1,mgncol
    1202           0 :           if (qc(i,k) >= qsmall) then
    1203           0 :              lcldm(i,k) = 1._r8
    1204             :           else
    1205           0 :              lcldm(i,k) = mincld
    1206             :           end if
    1207             : 
    1208           0 :           if (qi(i,k) >= qsmall) then
    1209           0 :              icldm(i,k) = 1._r8
    1210             :           else
    1211           0 :              icldm(i,k) = mincld
    1212             :           end if
    1213             : 
    1214           0 :           cldm(i,k) = max(icldm(i,k), lcldm(i,k))
    1215           0 :           qsfm(i,k) = 1._r8
    1216             :         end do
    1217             :      end do
    1218             :   else
    1219             :      ! get cloud fraction, check for minimum
    1220             : 
    1221             :      !$acc loop gang vector collapse(2)
    1222           0 :      do k=1,nlev
    1223           0 :         do i=1,mgncol
    1224           0 :           cldm(i,k) = max(cldn(i,k),mincld)
    1225           0 :           lcldm(i,k) = max(liqcldf(i,k),mincld)
    1226           0 :           icldm(i,k) = max(icecldf(i,k),mincld)
    1227           0 :           qsfm(i,k) = qsatfac(i,k)
    1228             :         end do
    1229             :      end do
    1230             :   end if
    1231             : 
    1232             :   ! Initialize local variables
    1233             : 
    1234             :   ! local physical properties
    1235             : 
    1236             :   !$acc loop gang vector collapse(2)
    1237           0 :   do k=1,nlev
    1238           0 :      do i=1,mgncol
    1239           0 :         rho(i,k) = p(i,k)/(r*t(i,k))
    1240           0 :         dv(i,k) = 8.794E-5_r8 * t(i,k)**1.81_r8 / p(i,k)
    1241           0 :         mu(i,k) = 1.496E-6_r8 * t(i,k)**1.5_r8 / (t(i,k) + 120._r8)
    1242           0 :         sc(i,k) = mu(i,k)/(rho(i,k)*dv(i,k))
    1243             : 
    1244             :         ! air density adjustment for fallspeed parameters
    1245             :         ! includes air density correction factor to the
    1246             :         ! power of 0.54 following Heymsfield and Bansemer 2007
    1247             :      
    1248           0 :         rhof(i,k)=(rhosu/rho(i,k))**0.54_r8
    1249             :      
    1250           0 :         arn(i,k)=ar*rhof(i,k)
    1251           0 :         asn(i,k)=as*rhof(i,k)
    1252             :         ! Hail use ah*rhof graupel use ag*rhof
    1253             :         ! Note that do_hail and do_graupel can't both be true
    1254           0 :         if (do_hail) then
    1255           0 :            agn(i,k) = ah*rhof(i,k)
    1256             :         end if
    1257           0 :         if (do_graupel) then
    1258           0 :            agn(i,k) = ag*rhof(i,k)
    1259             :         end if
    1260           0 :         acn(i,k)=g*rhow/(18._r8*mu(i,k))
    1261           0 :         ain(i,k)=ai*(rhosu/rho(i,k))**0.35_r8
    1262           0 :         ajn(i,k)=aj*(rhosu/rho(i,k))**0.35_r8
    1263             :      end do
    1264             :   end do
    1265             :   !$acc end parallel
    1266             : 
    1267             :   !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1268             :   ! Get humidity and saturation vapor pressures
    1269             : 
    1270           0 :   call qsat_water(t, p, esl, qvl, mgncol*nlev)
    1271           0 :   call qsat_ice(t, p, esi, qvi, mgncol*nlev)
    1272             : 
    1273             :   !$acc parallel vector_length(VLENS) default(present)
    1274             :   !$acc loop gang vector collapse(2)
    1275           0 :   do k=1,nlev
    1276           0 :      do i=1,mgncol
    1277             :         ! make sure when above freezing that esi=esl, not active yet
    1278           0 :         if (t(i,k) >= tmelt) then
    1279           0 :            esi(i,k)=esl(i,k)
    1280           0 :            qvi(i,k)=qvl(i,k)
    1281             :         else
    1282             :            ! Scale the water saturation values to reflect subgrid scale
    1283             :            ! ice cloud fraction, where ice clouds begin forming at a
    1284             :            ! gridbox average relative humidity of rhmini (not 1).
    1285             :            !
    1286             :            ! NOTE: For subcolumns and other non-subgrid clouds, qsfm willi
    1287             :            ! be 1.
    1288           0 :            qvi(i,k) = qsfm(i,k) * qvi(i,k)
    1289           0 :            esi(i,k) = qsfm(i,k) * esi(i,k)
    1290           0 :            qvl(i,k) = qsfm(i,k) * qvl(i,k)
    1291           0 :            esl(i,k) = qsfm(i,k) * esl(i,k)
    1292             :         end if
    1293           0 :         relhum(i,k) = q(i,k) / max(qvl(i,k), qsmall)
    1294             : 
    1295             : !  Adjust NAAI with meyers ice nucleation for 0 > T > -37
    1296           0 :         if ((t(i,k).gt.tmelt-37._r8.and.t(i,k).lt.tmelt).and.icenuc_use_meyers) then
    1297           0 :            nimey=1.e3_r8*exp(12.96_r8*(esl(i,k)-esi(i,k))/esi(i,k) - 0.639_r8) 
    1298           0 :            niact(i,k)=max(naai(i,k),nimey/rho(i,k))
    1299             :         else
    1300           0 :            niact(i,k)=naai(i,k)
    1301             :         end if
    1302             : 
    1303             :      end do
    1304             :   end do
    1305             : 
    1306             :   ! initialize microphysics output
    1307             : 
    1308             :   !$acc loop gang vector collapse(2)
    1309           0 :   do k=1,nlev
    1310           0 :      do i=1,mgncol
    1311           0 :         qcsevap(i,k)            = 0._r8
    1312           0 :         qisevap(i,k)            = 0._r8
    1313           0 :         qvres(i,k)              = 0._r8
    1314           0 :         cmeitot(i,k)            = 0._r8
    1315           0 :         vtrmc(i,k)              = 0._r8
    1316           0 :         vtrmi(i,k)              = 0._r8
    1317           0 :         qcsedten(i,k)           = 0._r8
    1318           0 :         qisedten(i,k)           = 0._r8
    1319           0 :         qrsedten(i,k)           = 0._r8
    1320           0 :         qssedten(i,k)           = 0._r8
    1321           0 :         qgsedten(i,k)           = 0._r8
    1322             :       
    1323           0 :         pratot(i,k)             = 0._r8
    1324           0 :         prctot(i,k)             = 0._r8
    1325           0 :         mnuccctot(i,k)          = 0._r8
    1326           0 :         mnuccttot(i,k)          = 0._r8
    1327           0 :         msacwitot(i,k)          = 0._r8
    1328           0 :         psacwstot(i,k)          = 0._r8
    1329           0 :         bergstot(i,k)           = 0._r8
    1330           0 :         bergtot(i,k)            = 0._r8
    1331           0 :         melttot(i,k)            = 0._r8
    1332             : 
    1333           0 :         mnudeptot(i,k)          = 0._r8
    1334           0 :         meltstot(i,k)           = 0._r8
    1335           0 :         meltgtot(i,k)           = 0._r8
    1336           0 :         homotot(i,k)            = 0._r8
    1337           0 :         qcrestot(i,k)           = 0._r8
    1338           0 :         prcitot(i,k)            = 0._r8
    1339           0 :         praitot(i,k)            = 0._r8
    1340           0 :         qirestot(i,k)           = 0._r8
    1341           0 :         mnuccrtot(i,k)          = 0._r8
    1342           0 :         mnuccritot(i,k)         = 0._r8
    1343           0 :         pracstot(i,k)           = 0._r8
    1344           0 :         meltsdttot(i,k)         = 0._r8
    1345           0 :         frzrdttot(i,k)          = 0._r8
    1346           0 :         mnuccdtot(i,k)          = 0._r8
    1347           0 :         psacrtot(i,k)           = 0._r8
    1348           0 :         pracgtot(i,k)           = 0._r8
    1349           0 :         psacwgtot(i,k)          = 0._r8
    1350           0 :         pgsacwtot(i,k)          = 0._r8
    1351           0 :         pgracstot(i,k)          = 0._r8
    1352           0 :         prdgtot(i,k)            = 0._r8
    1353           0 :         qmultgtot(i,k)          = 0._r8
    1354           0 :         qmultrgtot(i,k)         = 0._r8
    1355           0 :         npracgtot(i,k)          = 0._r8
    1356           0 :         nscngtot(i,k)           = 0._r8
    1357           0 :         ngracstot(i,k)          = 0._r8
    1358           0 :         nmultgtot(i,k)          = 0._r8
    1359           0 :         nmultrgtot(i,k)         = 0._r8
    1360           0 :         npsacwgtot(i,k)         = 0._r8
    1361             : 
    1362             : !need to zero these out to be totally switchable (for conservation)
    1363           0 :         psacr(i,k)              = 0._r8
    1364           0 :         pracg(i,k)              = 0._r8
    1365           0 :         psacwg(i,k)             = 0._r8
    1366           0 :         pgsacw(i,k)             = 0._r8
    1367           0 :         pgracs(i,k)             = 0._r8
    1368           0 :         prdg(i,k)               = 0._r8
    1369           0 :         qmultg(i,k)             = 0._r8
    1370           0 :         qmultrg(i,k)            = 0._r8
    1371           0 :         npracg(i,k)             = 0._r8
    1372           0 :         nscng(i,k)              = 0._r8
    1373           0 :         ngracs(i,k)             = 0._r8
    1374           0 :         nmultg(i,k)             = 0._r8
    1375           0 :         nmultrg(i,k)            = 0._r8
    1376           0 :         npsacwg(i,k)            = 0._r8
    1377             :      end do
    1378             :   end do
    1379             : 
    1380             :   !$acc loop gang vector collapse(2)
    1381           0 :   do k=1,nlev+1
    1382           0 :      do i=1,mgncol
    1383           0 :         rflx(i,k)               = 0._r8
    1384           0 :         sflx(i,k)               = 0._r8
    1385           0 :         lflx(i,k)               = 0._r8
    1386           0 :         iflx(i,k)               = 0._r8
    1387           0 :         gflx(i,k)               = 0._r8
    1388             :      end do
    1389             :   end do
    1390             : 
    1391             :   !$acc loop gang vector collapse(2)
    1392           0 :   do k=1,nlev
    1393           0 :      do i=1,mgncol
    1394             :         ! initialize precip output
    1395           0 :         qrout(i,k)              = 0._r8
    1396           0 :         qsout(i,k)              = 0._r8
    1397           0 :         nrout(i,k)              = 0._r8
    1398           0 :         nsout(i,k)              = 0._r8
    1399           0 :         qgout(i,k)              = 0._r8
    1400           0 :         ngout(i,k)              = 0._r8
    1401             : 
    1402             :         ! for refl calc
    1403           0 :         rainrt(i,k)             = 0._r8
    1404             :       
    1405             :         ! initialize rain size
    1406           0 :         rercld(i,k)             = 0._r8
    1407             :       
    1408           0 :         qcsinksum_rate1ord(i,k) = 0._r8
    1409             :       
    1410             :         ! initialize variables for trop_mozart
    1411           0 :         nevapr(i,k)             = 0._r8
    1412           0 :         prer_evap(i,k)          = 0._r8
    1413           0 :         evapsnow(i,k)           = 0._r8
    1414           0 :         am_evp_st(i,k)          = 0._r8
    1415           0 :         prain(i,k)              = 0._r8
    1416           0 :         prodsnow(i,k)           = 0._r8
    1417           0 :         cmeout(i,k)             = 0._r8
    1418             :       
    1419           0 :         precip_frac(i,k)        = mincld
    1420           0 :         lamc(i,k)               = 0._r8
    1421           0 :         lamg(i,k)               = 0._r8
    1422             :       
    1423             :         ! initialize microphysical tendencies
    1424           0 :         tlat(i,k)               = 0._r8
    1425           0 :         qvlat(i,k)              = 0._r8
    1426           0 :         qctend(i,k)             = 0._r8
    1427           0 :         qitend(i,k)             = 0._r8
    1428           0 :         qstend(i,k)             = 0._r8
    1429           0 :         qrtend(i,k)             = 0._r8
    1430           0 :         nctend(i,k)             = 0._r8
    1431           0 :         nitend(i,k)             = 0._r8
    1432           0 :         nrtend(i,k)             = 0._r8
    1433           0 :         nstend(i,k)             = 0._r8
    1434           0 :         qgtend(i,k)             = 0._r8
    1435           0 :         ngtend(i,k)             = 0._r8
    1436             :       
    1437             :         ! initialize in-cloud and in-precip quantities to zero
    1438           0 :         qcic(i,k)               = 0._r8
    1439           0 :         qiic(i,k)               = 0._r8
    1440           0 :         qsic(i,k)               = 0._r8
    1441           0 :         qric(i,k)               = 0._r8
    1442           0 :         qgic(i,k)               = 0._r8
    1443             :       
    1444           0 :         ncic(i,k)               = 0._r8
    1445           0 :         niic(i,k)               = 0._r8
    1446           0 :         nsic(i,k)               = 0._r8
    1447           0 :         nric(i,k)               = 0._r8
    1448           0 :         ngic(i,k)               = 0._r8
    1449             :      end do
    1450             :   end do
    1451             : 
    1452             :   ! initialize precip at surface
    1453             : 
    1454             :   !$acc loop gang vector
    1455           0 :   do i=1,mgncol
    1456           0 :      prect(i)                   = 0._r8
    1457           0 :      preci(i)                   = 0._r8
    1458             :   end do
    1459             : 
    1460             :   !$acc loop gang vector collapse(2)
    1461           0 :   do k=1,nlev
    1462           0 :      do i=1,mgncol
    1463             :         ! initialize precip fallspeeds to zero
    1464           0 :         ums(i,k)                = 0._r8
    1465           0 :         uns(i,k)                = 0._r8
    1466           0 :         umr(i,k)                = 0._r8
    1467           0 :         unr(i,k)                = 0._r8
    1468           0 :         umg(i,k)                = 0._r8
    1469           0 :         ung(i,k)                = 0._r8
    1470             :       
    1471             :         ! initialize limiter for output
    1472           0 :         qcrat(i,k)              = 1._r8
    1473             :       
    1474             :         ! Many outputs have to be initialized here at the top to work around
    1475             :         ! ifort problems, even if they are always overwritten later.
    1476           0 :         effc(i,k)               = 10._r8
    1477           0 :         lamcrad(i,k)            = 0._r8
    1478           0 :         pgamrad(i,k)            = 0._r8
    1479           0 :         effc_fn(i,k)            = 10._r8
    1480           0 :         effi(i,k)               = 25._r8
    1481           0 :         effi(i,k) = effi(i,k)*micro_mg_effi_factor
    1482           0 :         sadice(i,k)             = 0._r8
    1483           0 :         sadsnow(i,k)            = 0._r8
    1484           0 :         deffi(i,k)              = 50._r8
    1485             :       
    1486           0 :         qrout2(i,k)             = 0._r8
    1487           0 :         nrout2(i,k)             = 0._r8
    1488           0 :         drout2(i,k)             = 0._r8
    1489           0 :         qsout2(i,k)             = 0._r8
    1490           0 :         nsout2(i,k)             = 0._r8
    1491           0 :         dsout(i,k)              = 0._r8
    1492           0 :         dsout2(i,k)             = 0._r8
    1493           0 :         qgout2(i,k)             = 0._r8
    1494           0 :         ngout2(i,k)             = 0._r8
    1495           0 :         freqg(i,k)              = 0._r8
    1496           0 :         freqr(i,k)              = 0._r8
    1497           0 :         freqs(i,k)              = 0._r8
    1498             :       
    1499           0 :         reff_rain(i,k)          = 0._r8
    1500           0 :         reff_snow(i,k)          = 0._r8
    1501           0 :         reff_grau(i,k)          = 0._r8
    1502             :       
    1503           0 :         refl(i,k)               = -9999._r8
    1504           0 :         arefl(i,k)              = 0._r8
    1505           0 :         areflz(i,k)             = 0._r8
    1506           0 :         frefl(i,k)              = 0._r8
    1507           0 :         csrfl(i,k)              = 0._r8
    1508           0 :         acsrfl(i,k)             = 0._r8
    1509           0 :         fcsrfl(i,k)             = 0._r8
    1510             :       
    1511           0 :         ncal(i,k)               = 0._r8
    1512           0 :         ncai(i,k)               = 0._r8
    1513           0 :         nfice(i,k)              = 0._r8
    1514             :      end do
    1515             :   end do
    1516             : 
    1517             :   !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1518             :   ! droplet activation
    1519             :   ! get provisional droplet number after activation. This is used for
    1520             :   ! all microphysical process calculations, for consistency with update of
    1521             :   ! droplet mass before microphysics
    1522             : 
    1523             :   ! calculate potential for droplet activation if cloud water is present
    1524             :   ! tendency from activation (npccn) is read in from companion routine
    1525             : 
    1526             :   ! output activated liquid and ice (convert from #/kg -> #/m3)
    1527             :   !--------------------------------------------------
    1528             : 
    1529             :   !$acc loop gang vector collapse(2)
    1530           0 :   do k=1,nlev
    1531           0 :      do i=1,mgncol
    1532           0 :         if (qc(i,k) >= qsmall) then
    1533           0 :            nc(i,k) = max(nc(i,k) + npccn(i,k)*deltat, 0._r8)
    1534           0 :            ncal(i,k) = nc(i,k)*rho(i,k)/lcldm(i,k) ! sghan minimum in #/cm3
    1535             :         else
    1536           0 :            ncal(i,k) = 0._r8
    1537             :         end if
    1538             : 
    1539           0 :         if (t(i,k) < icenuct) then
    1540           0 :            ncai(i,k) = naai(i,k)*rho(i,k)
    1541             :         else
    1542           0 :            ncai(i,k) = 0._r8
    1543             :         end if 
    1544             :     end do
    1545             :   end do
    1546             : 
    1547             :   !===============================================
    1548             : 
    1549             :   ! ice nucleation if activated nuclei exist at t<-5C AND rhmini + 5%
    1550             :   !
    1551             :   ! NOTE: If using gridbox average values, condensation will not occur until rh=1,
    1552             :   ! so the threshold seems like it should be 1.05 and not rhmini + 0.05. For subgrid
    1553             :   ! clouds (using rhmini and qsfacm), the relhum has already been adjusted, and thus
    1554             :   ! the nucleation threshold should also be 1.05 and not rhmini + 0.05.
    1555             :   !-------------------------------------------------------
    1556             : 
    1557           0 :   if (do_cldice) then
    1558           0 :      if (icenuc_rh_off) then 
    1559             :         !$acc loop gang vector collapse(2)
    1560           0 :         do k=1,nlev
    1561           0 :            do i=1,mgncol
    1562           0 :               if (niact(i,k) > 0._r8 .and. t(i,k) < icenuct) then
    1563             :                  !if NAAI > 0. then set numice = naai (as before)
    1564             :                  !note: this is gridbox averaged
    1565           0 :                  nnuccd(i,k) = (niact(i,k)-ni(i,k)/icldm(i,k))/mtime*icldm(i,k)
    1566           0 :                  nnuccd(i,k) = max(nnuccd(i,k),0._r8)
    1567           0 :                  nimax(i,k) = naai(i,k)*icldm(i,k)
    1568             :             
    1569             :                  !Calc mass of new particles using new crystal mass...
    1570             :                  !also this will be multiplied by mtime as nnuccd is...
    1571           0 :                  mnuccd(i,k) = nnuccd(i,k) * mi0
    1572             :               else
    1573           0 :                  nnuccd(i,k) = 0._r8
    1574           0 :                  nimax(i,k)  = 0._r8
    1575           0 :                  mnuccd(i,k) = 0._r8
    1576             :               end if
    1577             :            end do
    1578             :         end do
    1579             :      else
    1580             :         !$acc loop gang vector collapse(2)
    1581           0 :         do k=1,nlev
    1582           0 :            do i=1,mgncol
    1583           0 :               if (naai(i,k) > 0._r8 .and. t(i,k) < icenuct .and. &
    1584           0 :                  relhum(i,k)*esl(i,k)/esi(i,k) > 1.05_r8) then
    1585             :                  !if NAAI > 0. then set numice = naai (as before)
    1586             :                  !note: this is gridbox averaged
    1587           0 :                  nnuccd(i,k) = (naai(i,k)-ni(i,k)/icldm(i,k))/mtime*icldm(i,k)
    1588           0 :                  nnuccd(i,k) = max(nnuccd(i,k),0._r8)
    1589           0 :                  nimax(i,k) = naai(i,k)*icldm(i,k)
    1590             : 
    1591             :                  !Calc mass of new particles using new crystal mass...
    1592             :                  !also this will be multiplied by mtime as nnuccd is...
    1593           0 :                  mnuccd(i,k) = nnuccd(i,k) * mi0
    1594             :               else
    1595           0 :                  nnuccd(i,k) = 0._r8
    1596           0 :                  nimax(i,k)  = 0._r8
    1597           0 :                  mnuccd(i,k) = 0._r8
    1598             :               end if
    1599             :            end do
    1600             :         end do
    1601             :     end if
    1602             : !--ag
    1603             :   end if
    1604             : 
    1605             :   !=============================================================================
    1606             :   !$acc loop gang vector collapse(2) private(dum,dum1)
    1607           0 :   do k=1,nlev
    1608           0 :      do i=1,mgncol
    1609             :         ! calculate instantaneous precip processes (melting and homogeneous freezing)
    1610             :         ! melting of snow at +2 C
    1611           0 :         if (t(i,k) > snowmelt) then
    1612           0 :            if (qs(i,k) > 0._r8) then
    1613             :               ! make sure melting snow doesn't reduce temperature below threshold
    1614           0 :               dum = -xlf/cpp*qs(i,k)
    1615           0 :               if (t(i,k)+dum < snowmelt) then
    1616           0 :                  dum = (t(i,k)-snowmelt)*cpp/xlf
    1617           0 :                  dum = dum/qs(i,k)
    1618           0 :                  dum = max(0._r8,dum)
    1619           0 :                  dum = min(1._r8,dum)
    1620             :               else
    1621             :                  dum = 1._r8
    1622             :               end if
    1623             : 
    1624           0 :               minstsm(i,k) = dum*qs(i,k)
    1625           0 :               ninstsm(i,k) = dum*ns(i,k)
    1626             : 
    1627           0 :               dum1=-xlf*minstsm(i,k)*rdeltat
    1628           0 :               tlat(i,k)=tlat(i,k)+dum1
    1629           0 :               meltsdttot(i,k)=meltsdttot(i,k) + dum1
    1630           0 :               meltstot(i,k)=minstsm(i,k)*rdeltat
    1631             : 
    1632           0 :               qs(i,k) = max(qs(i,k) - minstsm(i,k), 0._r8)
    1633           0 :               ns(i,k) = max(ns(i,k) - ninstsm(i,k), 0._r8)
    1634           0 :               qr(i,k) = max(qr(i,k) + minstsm(i,k), 0._r8)
    1635           0 :               nr(i,k) = max(nr(i,k) + ninstsm(i,k), 0._r8)
    1636             :            end if
    1637             :         end if
    1638             : 
    1639             :      end do
    1640             :   end do 
    1641             : 
    1642             :   ! melting of graupel at +2 C
    1643             : 
    1644             :   !$acc loop gang vector collapse(2) private(dum,dum1)
    1645           0 :   do k=1,nlev
    1646           0 :      do i=1,mgncol
    1647             : 
    1648           0 :         if (t(i,k) > snowmelt) then
    1649           0 :            if (qg(i,k) > 0._r8) then
    1650             : 
    1651             :               ! make sure melting graupel doesn't reduce temperature below threshold
    1652           0 :               dum = -xlf/cpp*qg(i,k)
    1653           0 :               if (t(i,k)+dum < snowmelt) then
    1654           0 :                  dum = (t(i,k)-snowmelt)*cpp/xlf
    1655           0 :                  dum = dum/qg(i,k)
    1656           0 :                  dum = max(0._r8,dum)
    1657           0 :                  dum = min(1._r8,dum)
    1658             :               else
    1659             :                  dum = 1._r8
    1660             :               end if
    1661             : 
    1662           0 :               minstgm(i,k) = dum*qg(i,k)
    1663           0 :               ninstgm(i,k) = dum*ng(i,k)
    1664             : 
    1665           0 :               dum1=-xlf*minstgm(i,k)*rdeltat
    1666           0 :               tlat(i,k)=tlat(i,k)+dum1
    1667           0 :               meltsdttot(i,k)=meltsdttot(i,k) + dum1
    1668           0 :               meltgtot(i,k)=minstgm(i,k)*rdeltat
    1669             : 
    1670           0 :               qg(i,k) = max(qg(i,k) - minstgm(i,k), 0._r8)
    1671           0 :               ng(i,k) = max(ng(i,k) - ninstgm(i,k), 0._r8)
    1672           0 :               qr(i,k) = max(qr(i,k) + minstgm(i,k), 0._r8)
    1673           0 :               nr(i,k) = max(nr(i,k) + ninstgm(i,k), 0._r8)
    1674             :            end if
    1675             :         end if
    1676             : 
    1677             :      end do
    1678             :   end do 
    1679             : 
    1680             :   !$acc loop gang vector collapse(2) private(dum,dum1)
    1681           0 :   do k=1,nlev
    1682           0 :     do i=1,mgncol
    1683             :         ! freezing of rain at -5 C
    1684             : 
    1685           0 :         if (t(i,k) < rainfrze) then
    1686             : 
    1687           0 :            if (qr(i,k) > 0._r8) then
    1688             : 
    1689             :               ! make sure freezing rain doesn't increase temperature above threshold
    1690           0 :               dum = xlf/cpp*qr(i,k)
    1691           0 :               if (t(i,k)+dum > rainfrze) then
    1692           0 :                  dum = -(t(i,k)-rainfrze)*cpp/xlf
    1693           0 :                  dum = dum/qr(i,k)
    1694           0 :                  dum = max(0._r8,dum)
    1695           0 :                  dum = min(1._r8,dum)
    1696             :               else
    1697             :                  dum = 1._r8
    1698             :               end if
    1699             : 
    1700           0 :               minstrf(i,k) = dum*qr(i,k)
    1701           0 :               ninstrf(i,k) = dum*nr(i,k)
    1702             : 
    1703             :               ! heating tendency
    1704           0 :               dum1 = xlf*minstrf(i,k)*rdeltat
    1705           0 :               tlat(i,k)=tlat(i,k)+dum1
    1706           0 :               frzrdttot(i,k)=frzrdttot(i,k) + dum1                                                                                   
    1707             : 
    1708           0 :               qr(i,k) = max(qr(i,k) - minstrf(i,k), 0._r8)
    1709           0 :               nr(i,k) = max(nr(i,k) - ninstrf(i,k), 0._r8)
    1710             : 
    1711             :               ! freeze rain to graupel not snow.
    1712           0 :               if(do_hail.or.do_graupel) then
    1713           0 :                  qg(i,k) = max(qg(i,k) + minstrf(i,k), 0._r8)
    1714           0 :                  ng(i,k) = max(ng(i,k) + ninstrf(i,k), 0._r8)
    1715             :               else
    1716           0 :                  qs(i,k) = max(qs(i,k) + minstrf(i,k), 0._r8)
    1717           0 :                  ns(i,k) = max(ns(i,k) + ninstrf(i,k), 0._r8)
    1718             :               end if
    1719             :            end if
    1720             :         end if
    1721             :      end do
    1722             :   end do 
    1723             : 
    1724             :   !$acc loop gang vector collapse(2)
    1725           0 :   do k=1,nlev
    1726           0 :     do i=1,mgncol
    1727             :         ! obtain in-cloud values of cloud water/ice mixing ratios and number concentrations
    1728             :         !-------------------------------------------------------
    1729             :         ! for microphysical process calculations
    1730             :         ! units are kg/kg for mixing ratio, 1/kg for number conc
    1731             : 
    1732           0 :         if (qc(i,k).ge.qsmall) then
    1733             :            ! limit in-cloud values to 0.005 kg/kg
    1734           0 :            qcic(i,k)=min(qc(i,k)/lcldm(i,k),5.e-3_r8)
    1735           0 :            ncic(i,k)=max(nc(i,k)/lcldm(i,k),0._r8)
    1736             : 
    1737             :            ! specify droplet concentration
    1738           0 :            if (nccons) then
    1739           0 :               ncic(i,k)=ncnst/rho(i,k)
    1740             :            end if
    1741             :         else
    1742           0 :            qcic(i,k)=0._r8
    1743           0 :            ncic(i,k)=0._r8
    1744             :         end if
    1745             : 
    1746           0 :         if (qi(i,k).ge.qsmall) then
    1747             :            ! limit in-cloud values to 0.005 kg/kg
    1748           0 :            qiic(i,k)=min(qi(i,k)/icldm(i,k),5.e-3_r8)
    1749           0 :            niic(i,k)=max(ni(i,k)/icldm(i,k),0._r8)
    1750             : 
    1751             :            ! switch for specification of cloud ice number
    1752           0 :            if (nicons) then
    1753           0 :               niic(i,k)=ninst/rho(i,k)
    1754             :            end if
    1755             :         else
    1756           0 :            qiic(i,k)=0._r8
    1757           0 :            niic(i,k)=0._r8
    1758             :         end if
    1759             : 
    1760             :      end do
    1761             :   end do
    1762             : 
    1763             :   !========================================================================
    1764             : 
    1765             :   ! for sub-columns cldm has already been set to 1 if cloud
    1766             :   ! water or ice is present, so precip_frac will be correctly set below
    1767             :   ! and nothing extra needs to be done here
    1768             : 
    1769             :   !$acc loop gang vector collapse(2)
    1770           0 :   do k=1,nlev
    1771           0 :      do i=1,mgncol
    1772           0 :         precip_frac(i,k) = cldm(i,k)
    1773             :      end do
    1774             :   end do
    1775             :   !$acc end parallel
    1776             : 
    1777             :   !$acc parallel vector_length(VLENS) default(present)
    1778           0 :   if (precip_frac_method == MG_PRECIP_FRAC_INCLOUD) then
    1779             :      !$acc loop seq
    1780           0 :      do k=2,nlev
    1781             :         !$acc loop gang vector
    1782           0 :         do i=1,mgncol
    1783           0 :            if (qc(i,k) < qsmall .and. qi(i,k) < qsmall) then
    1784           0 :               precip_frac(i,k) = precip_frac(i,k-1)
    1785             :            end if
    1786             :        end do
    1787             :      end do
    1788           0 :   else if (precip_frac_method == MG_PRECIP_FRAC_OVERLAP) then
    1789             :      ! calculate precip fraction based on maximum overlap assumption
    1790             : 
    1791             :      ! if rain or snow mix ratios are smaller than threshold,
    1792             :      ! then leave precip_frac as cloud fraction at current level
    1793             : 
    1794             :      !$acc loop seq
    1795           0 :      do k=2,nlev
    1796             :         !$acc loop gang vector
    1797           0 :         do i=1,mgncol
    1798           0 :            if (qr(i,k-1) >= qsmall .or. qs(i,k-1) >= qsmall .or. qg(i,k-1) >= qsmall) then
    1799           0 :               precip_frac(i,k)=max(precip_frac(i,k-1),precip_frac(i,k))
    1800             :            end if
    1801             :         end do
    1802             :      end do
    1803             : 
    1804             :   end if
    1805             :   !$acc end parallel
    1806             : 
    1807             :   !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1808             :   ! get size distribution parameters based on in-cloud cloud water
    1809             :   ! these calculations also ensure consistency between number and mixing ratio
    1810             :   !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    1811             : 
    1812             :   ! cloud liquid
    1813             :   !-------------------------------------------
    1814           0 :   call size_dist_param_liq(mg_liq_props, qcic, ncic, rho, pgam, lamc, mgncol, nlev)
    1815             : 
    1816             :   !========================================================================
    1817             :   ! autoconversion of cloud liquid water to rain
    1818             :   ! formula from Khrouditnov and Kogan (2000), modified for sub-grid distribution of qc
    1819             :   ! minimum qc of 1 x 10^-8 prevents floating point error
    1820             : 
    1821           0 :   if (.not. do_sb_physics) then
    1822           0 :     call kk2000_liq_autoconversion(microp_uniform, qcic, ncic, rho, relvar, prc, nprc, nprc1, micro_mg_autocon_fact, micro_mg_autocon_nd_exp, micro_mg_autocon_lwp_exp, mgncol*nlev)
    1823             :   end if
    1824             : 
    1825             :   !$acc parallel vector_length(VLENS) default(present)
    1826             :   !$acc loop gang vector collapse(2)
    1827           0 :   do k=1,nlev
    1828           0 :      do i=1,mgncol
    1829             :         ! assign qric based on prognostic qr, using assumed precip fraction
    1830             :         ! note: this could be moved above for consistency with qcic and qiic calculations
    1831           0 :         qric(i,k) = qr(i,k)/precip_frac(i,k)
    1832           0 :         nric(i,k) = nr(i,k)/precip_frac(i,k)
    1833             : 
    1834             :         ! limit in-precip mixing ratios to 10 g/kg
    1835           0 :         qric(i,k)=min(qric(i,k),0.01_r8)
    1836             : 
    1837             :         ! add autoconversion to precip from above to get provisional rain mixing ratio
    1838             :         ! and number concentration (qric and nric)
    1839             : 
    1840           0 :         if (qric(i,k).lt.qsmall) then
    1841           0 :            qric(i,k)=0._r8
    1842           0 :            nric(i,k)=0._r8
    1843             :         end if
    1844             : 
    1845             :         ! make sure number concentration is a positive number to avoid
    1846             :         ! taking root of negative later
    1847             : 
    1848           0 :         nric(i,k)=max(nric(i,k),0._r8)
    1849             :      end do
    1850             :   end do
    1851             :   !$acc end parallel
    1852             : 
    1853             :   ! Get size distribution parameters for cloud ice
    1854           0 :   call size_dist_param_basic(mg_ice_props, qiic, niic, lami, mgncol, nlev, n0=n0i)
    1855             : 
    1856             :   ! Alternative autoconversion 
    1857           0 :   if (do_sb_physics) then
    1858           0 :      call sb2001v2_liq_autoconversion(pgam, qcic, ncic, qric, rho, relvar, prc, nprc, nprc1, mgncol*nlev) 
    1859             :   end if
    1860             : 
    1861             :   !.......................................................................
    1862             :   ! Autoconversion of cloud ice to snow
    1863             :   ! similar to Ferrier (1994)
    1864           0 :   if (do_cldice) then
    1865           0 :      call ice_autoconversion(t, qiic, lami, n0i, dcs, prci, nprci, mgncol*nlev)
    1866             :   else
    1867             :      ! Add in the particles that we have already converted to snow, and
    1868             :      ! don't do any further autoconversion of ice.
    1869             : 
    1870             :      !$acc parallel vector_length(VLENS) default(present)
    1871             :      !$acc loop gang vector collapse(2)
    1872           0 :      do k=1,nlev
    1873           0 :         do i=1,mgncol
    1874           0 :            prci(i,k)  = tnd_qsnow(i,k) / cldm(i,k)
    1875           0 :            nprci(i,k) = tnd_nsnow(i,k) / cldm(i,k)
    1876             :         end do
    1877             :      end do
    1878             :      !$acc end parallel
    1879             :   end if
    1880             : 
    1881             :   ! note, currently we don't have this
    1882             :   ! inside the do_cldice block, should be changed later
    1883             :   ! assign qsic based on prognostic qs, using assumed precip fraction
    1884             : 
    1885             :   !$acc parallel vector_length(VLENS) default(present)
    1886             :   !$acc loop gang vector collapse(2)
    1887           0 :   do k=1,nlev
    1888           0 :      do i=1,mgncol
    1889           0 :         qsic(i,k) = qs(i,k)/precip_frac(i,k)
    1890           0 :         nsic(i,k) = ns(i,k)/precip_frac(i,k)
    1891             : 
    1892             :         ! limit in-precip mixing ratios to 10 g/kg
    1893           0 :         qsic(i,k)=min(qsic(i,k),0.01_r8)
    1894             : 
    1895             :         ! if precip mix ratio is zero so should number concentration
    1896           0 :         if (qsic(i,k) < qsmall) then
    1897           0 :            qsic(i,k)=0._r8
    1898           0 :            nsic(i,k)=0._r8
    1899             :         end if
    1900             : 
    1901             :         ! make sure number concentration is a positive number to avoid
    1902             :         ! taking root of negative later
    1903           0 :         nsic(i,k)=max(nsic(i,k),0._r8)
    1904             : 
    1905             :         ! also do this for graupel, which is assumed to be 'precip_frac'
    1906           0 :         qgic(i,k) = qg(i,k)/precip_frac(i,k)
    1907           0 :         ngic(i,k) = ng(i,k)/precip_frac(i,k)
    1908             : 
    1909             :         ! limit in-precip mixing ratios to 10 g/kg
    1910           0 :         qgic(i,k)=min(qgic(i,k),0.01_r8)
    1911             : 
    1912             :         ! if precip mix ratio is zero so should number concentration
    1913           0 :         if (qgic(i,k) < qsmall) then
    1914           0 :            qgic(i,k)=0._r8
    1915           0 :            ngic(i,k)=0._r8
    1916             :         end if
    1917             : 
    1918             :         ! make sure number concentration is a positive number to avoid
    1919             :         ! taking root of negative later
    1920           0 :         ngic(i,k)=max(ngic(i,k),0._r8)    
    1921             :      end do
    1922             :   end do
    1923             :   !$acc end parallel
    1924             : 
    1925             :   !.......................................................................
    1926             :   ! get size distribution parameters for precip
    1927             :   !......................................................................
    1928             :   ! rain
    1929           0 :   call size_dist_param_basic(mg_rain_props, qric, nric, lamr, mgncol, nlev, n0=n0r)
    1930             : 
    1931             :   !$acc parallel vector_length(VLENS) default(present)
    1932             :   !$acc loop gang vector collapse(2)
    1933           0 :   do k=1,nlev
    1934           0 :      do i=1,mgncol
    1935           0 :         if (lamr(i,k) >= qsmall) then
    1936           0 :            dum_2D(i,k)= lamr(i,k)**br
    1937             :            ! provisional rain number and mass weighted mean fallspeed (m/s)
    1938           0 :            unr(i,k) = min(arn(i,k)*gamma_br_plus1/dum_2D(i,k),9.1_r8*rhof(i,k))
    1939           0 :            umr(i,k) = min(arn(i,k)*gamma_br_plus4/(6._r8*dum_2D(i,k)),9.1_r8*rhof(i,k))
    1940             :         else
    1941           0 :            umr(i,k) = 0._r8
    1942           0 :            unr(i,k) = 0._r8
    1943             :         end if
    1944             :      end do
    1945             :   end do
    1946             :   !$acc end parallel
    1947             : 
    1948             :   !......................................................................
    1949             :   ! snow
    1950           0 :   call size_dist_param_basic(mg_snow_props, qsic, nsic, lams, mgncol, nlev, n0=n0s)
    1951             : 
    1952             :   !$acc parallel vector_length(VLENS) default(present)
    1953             :   !$acc loop gang vector collapse(2)
    1954           0 :   do k=1,nlev
    1955           0 :      do i=1,mgncol
    1956           0 :         if (ifs_sed) then
    1957           0 :            if (lams(i,k) > 0._r8) then
    1958           0 :               ums(i,k) = 1._r8
    1959           0 :               uns(i,k) = 1._r8
    1960             :            else
    1961           0 :               ums(i,k) = 0._r8
    1962           0 :               uns(i,k) = 0._r8
    1963             :            end if
    1964             :         else
    1965           0 :            if (lams(i,k) > 0._r8) then
    1966           0 :               dum_2D(i,k) = lams(i,k)**bs
    1967             :               ! provisional snow number and mass weighted mean fallspeed (m/s)
    1968           0 :               ums(i,k) = min(asn(i,k)*gamma_bs_plus4/(6._r8*dum_2D(i,k)),1.2_r8*rhof(i,k))
    1969           0 :               ums(i,k) = ums(i,k)*micro_mg_vtrmi_factor
    1970           0 :               uns(i,k) = min(asn(i,k)*gamma_bs_plus1/dum_2D(i,k),1.2_r8*rhof(i,k))
    1971             :            else
    1972           0 :               ums(i,k) = 0._r8
    1973           0 :               uns(i,k) = 0._r8
    1974             :            end if
    1975             :         end if
    1976             :      end do
    1977             :   end do
    1978             :   !$acc end parallel
    1979             : 
    1980             :   !  graupel/hail size distributions and properties
    1981             : 
    1982           0 :   if (do_hail) then
    1983           0 :      call size_dist_param_basic(mg_hail_props, qgic, ngic, lamg, mgncol, nlev, n0=n0g)
    1984             :   end if
    1985           0 :   if (do_graupel) then
    1986           0 :      call size_dist_param_basic(mg_graupel_props, qgic, ngic, lamg, mgncol, nlev, n0=n0g)
    1987             :   end if
    1988             : 
    1989             :   !$acc parallel vector_length(VLENS) default(present)
    1990             :   !$acc loop gang vector collapse(2)  
    1991           0 :   do k=1,nlev
    1992           0 :      do i=1,mgncol
    1993           0 :         if (lamg(i,k) > 0._r8) then
    1994           0 :            dum_2D(i,k) = lamg(i,k)**bgtmp
    1995             :            ! provisional graupel/hail number and mass weighted mean fallspeed (m/s)
    1996           0 :            umg(i,k) = min(agn(i,k)*gamma_bg_plus4/(6._r8*dum_2D(i,k)),20._r8*rhof(i,k))
    1997           0 :            ung(i,k) = min(agn(i,k)*gamma_bg_plus1/dum_2D(i,k),20._r8*rhof(i,k))
    1998             :         else
    1999           0 :            umg(i,k) = 0._r8
    2000           0 :            ung(i,k) = 0._r8
    2001             :         end if
    2002             :      end do
    2003             :   end do
    2004             :   !$acc end parallel
    2005             :  
    2006           0 :   if (do_cldice) then
    2007           0 :      if (.not. use_hetfrz_classnuc) then
    2008             :         ! heterogeneous freezing of cloud water
    2009             :         !----------------------------------------------
    2010           0 :         call immersion_freezing(microp_uniform, t, pgam, lamc, qcic, ncic, relvar, mnuccc, nnuccc, mgncol*nlev)
    2011             : 
    2012             :         ! make sure number of droplets frozen does not exceed available ice nuclei concentration
    2013             :         ! this prevents 'runaway' droplet freezing
    2014             : 
    2015             :         !$acc parallel vector_length(VLENS) default(present)
    2016             :         !$acc loop gang vector collapse(2)
    2017           0 :         do k=1,nlev
    2018           0 :            do i=1,mgncol
    2019           0 :               if (qcic(i,k).ge.qsmall .and. t(i,k).lt.269.15_r8 .and. &
    2020             :                   nnuccc(i,k)*lcldm(i,k).gt.nnuccd(i,k)) then
    2021             :                   ! scale mixing ratio of droplet freezing with limit
    2022           0 :                   mnuccc(i,k)=mnuccc(i,k)*(nnuccd(i,k)/(nnuccc(i,k)*lcldm(i,k)))
    2023           0 :                   nnuccc(i,k)=nnuccd(i,k)/lcldm(i,k)
    2024             :               end if
    2025           0 :               mnudep(i,k)=0._r8
    2026           0 :               nnudep(i,k)=0._r8
    2027             :            end do
    2028             :         end do
    2029             :         !$acc end parallel
    2030             : 
    2031             :         call contact_freezing(microp_uniform, t, p, rndst, nacon, pgam, lamc, qcic, ncic, &
    2032           0 :                               relvar, mnucct, nnucct, mgncol*nlev, mdust)
    2033             :      else
    2034             :         ! Mass of droplets frozen is the average droplet mass, except
    2035             :         ! with two limiters: concentration must be at least 1/cm^3, and
    2036             :         ! mass must be at least the minimum defined above.
    2037             : 
    2038             :         !$acc parallel vector_length(VLENS) default(present)
    2039             :         !$acc loop gang vector collapse(2)
    2040           0 :         do k=1,nlev
    2041           0 :            do i=1,mgncol
    2042           0 :               mi0l(i,k) = qcic(i,k)/max(ncic(i,k), 1.0e6_r8/rho(i,k))
    2043           0 :               mi0l(i,k) = max(mi0l_min, mi0l(i,k))
    2044           0 :               if (qcic(i,k) >= qsmall) then
    2045           0 :                  nnuccc(i,k) = frzimm(i,k)*1.0e6_r8/rho(i,k)
    2046           0 :                  mnuccc(i,k) = nnuccc(i,k)*mi0l(i,k)
    2047           0 :                  nnucct(i,k) = frzcnt(i,k)*1.0e6_r8/rho(i,k)
    2048           0 :                  mnucct(i,k) = nnucct(i,k)*mi0l(i,k)
    2049           0 :                  nnudep(i,k) = frzdep(i,k)*1.0e6_r8/rho(i,k)
    2050           0 :                  mnudep(i,k) = nnudep(i,k)*mi0
    2051             :               else
    2052           0 :                  nnuccc(i,k) = 0._r8
    2053           0 :                  mnuccc(i,k) = 0._r8
    2054           0 :                  nnucct(i,k) = 0._r8
    2055           0 :                  mnucct(i,k) = 0._r8
    2056           0 :                  nnudep(i,k) = 0._r8
    2057           0 :                  mnudep(i,k) = 0._r8
    2058             :               end if
    2059             :            end do
    2060             :         end do
    2061             :         !$acc end parallel
    2062             :      end if
    2063             :   else
    2064             :      !$acc parallel vector_length(VLENS) default(present)
    2065             :      !$acc loop gang vector collapse(2)
    2066           0 :      do k=1,nlev
    2067           0 :         do i=1,mgncol
    2068           0 :            mnuccc(i,k)=0._r8
    2069           0 :            nnuccc(i,k)=0._r8
    2070           0 :            mnucct(i,k)=0._r8
    2071           0 :            nnucct(i,k)=0._r8
    2072           0 :            mnudep(i,k)=0._r8
    2073           0 :            nnudep(i,k)=0._r8
    2074             :         end do
    2075             :      end do
    2076             :      !$acc end parallel
    2077             :   end if
    2078             : 
    2079           0 :   call snow_self_aggregation(t, rho, asn, rhosn, qsic, nsic, nsagg, mgncol*nlev)
    2080             : 
    2081             :   call accrete_cloud_water_snow(t, rho, asn, uns, mu, qcic, ncic, qsic, pgam, &
    2082           0 :                                 lamc, lams, n0s, psacws, npsacws, mgncol*nlev)
    2083             : 
    2084           0 :   psacws = psacws*micro_mg_iaccr_factor
    2085           0 :   npsacws = npsacws*micro_mg_iaccr_factor
    2086           0 :   if (do_cldice) then
    2087           0 :      call secondary_ice_production(t, psacws, msacwi, nsacwi, mgncol*nlev)
    2088             :   else
    2089             :      !$acc parallel vector_length(VLENS) default(present)
    2090             :      !$acc loop gang vector collapse(2)
    2091           0 :      do k=1,nlev
    2092           0 :         do i=1,mgncol
    2093           0 :            nsacwi(i,k) = 0.0_r8
    2094           0 :            msacwi(i,k) = 0.0_r8
    2095             :         end do
    2096             :      end do
    2097             :      !$acc end parallel
    2098             :   end if
    2099             : 
    2100             :   call accrete_rain_snow(t, rho, umr, ums, unr, uns, qric, qsic, lamr, &
    2101           0 :                          n0r, lams, n0s, pracs, npracs, mgncol*nlev)
    2102             : 
    2103           0 :   call heterogeneous_rain_freezing(t, qric, nric, lamr, mnuccr, nnuccr, mgncol*nlev)
    2104             : 
    2105           0 :   if (do_sb_physics) then
    2106           0 :      call sb2001v2_accre_cld_water_rain(qcic, ncic, qric, rho, relvar, pra, npra, mgncol*nlev)     
    2107             :   else
    2108           0 :      call accrete_cloud_water_rain(microp_uniform, qric, qcic, ncic, relvar, accre_enhan, pra, npra, mgncol*nlev)
    2109             :   endif
    2110             : 
    2111           0 :   pra = pra*micro_mg_accre_enhan_fact
    2112           0 :   npra = npra*micro_mg_accre_enhan_fact
    2113             : 
    2114           0 :   call self_collection_rain(rho, qric, nric, nragg, mgncol*nlev)
    2115             : 
    2116           0 :   if (do_cldice) then
    2117           0 :      call accrete_cloud_ice_snow(t, rho, asn, qiic, niic, qsic, lams, n0s, prai, nprai, mgncol*nlev)
    2118             :   else
    2119             :      !$acc parallel vector_length(VLENS) default(present)
    2120             :      !$acc loop gang vector collapse(2)
    2121           0 :      do k=1,nlev
    2122           0 :         do i=1,mgncol
    2123           0 :            prai(i,k) = 0._r8
    2124           0 :            nprai(i,k) = 0._r8
    2125             :         end do
    2126             :      end do
    2127             :      !$acc end parallel
    2128             :   end if
    2129             : 
    2130           0 :   call bergeron_process_snow(t, rho, dv, mu, sc, qvl, qvi, asn, qcic, qsic, lams, n0s, bergs, mgncol*nlev)
    2131             :   !$acc parallel vector_length(VLENS) default(present)
    2132             :   !$acc loop gang vector collapse(2)
    2133           0 :   do k=1,nlev
    2134           0 :      do i=1,mgncol
    2135           0 :         bergs(i,k)=bergs(i,k)*micro_mg_berg_eff_factor
    2136             :      end do
    2137             :   end do
    2138             :   !$acc end parallel
    2139             : 
    2140           0 :   if (do_cldice) then
    2141             :      call ice_deposition_sublimation(t, q, qi, ni, icldm, rho, dv, qvl, qvi, &
    2142           0 :                                      berg, vap_dep, ice_sublim, mgncol*nlev)
    2143             :      !$acc parallel vector_length(VLENS) default(present)
    2144             :      !$acc loop gang vector collapse(2)
    2145           0 :      do k=1,nlev
    2146           0 :         do i=1,mgncol
    2147           0 :            berg(i,k)=berg(i,k)*micro_mg_berg_eff_factor
    2148           0 :            if (ice_sublim(i,k) < 0._r8 .and. qi(i,k) > qsmall .and. icldm(i,k) > mincld) then
    2149           0 :               nsubi(i,k) = sublim_factor*ice_sublim(i,k) / qi(i,k) * ni(i,k) / icldm(i,k)
    2150             :            else
    2151           0 :               nsubi(i,k) = 0._r8
    2152             :            end if
    2153             : 
    2154             :            ! bergeron process should not reduce nc unless
    2155             :            ! all ql is removed (which is handled elsewhere)
    2156             :            !in fact, nothing in this entire file makes nsubc nonzero.
    2157           0 :            nsubc(i,k) = 0._r8
    2158             : 
    2159             :         end do
    2160             :      end do
    2161             :      !$acc end parallel
    2162             :   end if !do_cldice
    2163             : 
    2164             : ! Process rate calls for graupel   
    2165             : !===================================================================
    2166             : 
    2167           0 :   if (do_hail.or.do_graupel) then
    2168           0 :      call graupel_collecting_snow(qsic, qric, umr, ums, rho, lamr, n0r, lams, n0s, psacr, mgncol*nlev)
    2169             : 
    2170           0 :      call graupel_collecting_cld_water(qgic, qcic, ncic, rho, n0g, lamg, bgtmp, agn, psacwg, npsacwg, mgncol*nlev)
    2171             : 
    2172           0 :      psacwg = psacwg*micro_mg_iaccr_factor
    2173           0 :      npsacwg = npsacwg*micro_mg_iaccr_factor
    2174             :      
    2175             :      call graupel_riming_liquid_snow(psacws, qsic, qcic, nsic, rho, rhosn, rhogtmp, asn, &
    2176           0 :                                      lams, n0s, deltat, pgsacw, nscng, mgncol*nlev)
    2177             : 
    2178             :      call graupel_collecting_rain(qric, qgic, umg, umr, ung, unr, rho, n0r, &
    2179           0 :                                   lamr, n0g, lamg, pracg, npracg, mgncol*nlev)
    2180             : 
    2181           0 :      pracg = pracg*micro_mg_iaccr_factor
    2182           0 :      npracg = npracg*micro_mg_iaccr_factor
    2183             : 
    2184             : !AG note: Graupel rain riming snow changes  
    2185             : !    pracs, npracs, (accretion of rain by snow)  psacr (collection of snow by rain)
    2186             : 
    2187             :      call graupel_rain_riming_snow(pracs, npracs, psacr, qsic, qric, nric, nsic, &
    2188           0 :                                    n0s, lams, n0r, lamr, deltat, pgracs, ngracs, mgncol*nlev)
    2189             :    
    2190           0 :      call graupel_rime_splintering(t, qcic, qric, qgic, psacwg, pracg, qmultg, nmultg, qmultrg, nmultrg,mgncol*nlev)
    2191             : 
    2192             : 
    2193             :      call evaporate_sublimate_precip_graupel(t, rho, dv, mu, sc, q, qvl, qvi, lcldm, precip_frac, arn, asn, agn, &
    2194             :                                              bgtmp, qcic, qiic, qric, qsic, qgic, lamr, n0r, lams, n0s, lamg, n0g, &
    2195           0 :                                              pre, prds, prdg, am_evp_st, mgncol*nlev, evap_rhthrsh_ifs) 
    2196             :   else
    2197             :      ! Routine without Graupel (original)        
    2198             :      call evaporate_sublimate_precip(t, rho, dv, mu, sc, q, qvl, qvi, lcldm, precip_frac, arn, asn, qcic, qiic, &
    2199           0 :                                      qric, qsic, lamr, n0r, lams, n0s, pre, prds, am_evp_st, mgncol*nlev, evap_rhthrsh_ifs)
    2200             :   end if ! end do_graupel/hail loop
    2201             : 
    2202             : ! scale precip evaporation to match IFS 'new' version (option 2)
    2203           0 :   if (evap_scl_ifs) then
    2204             :      !$acc parallel vector_length(VLENS) default(present)
    2205             :      !$acc loop gang vector collapse(2)
    2206           0 :      do k=1,nlev
    2207           0 :         do i=1,mgncol
    2208           0 :            pre(i,k)= 0.15_r8 * pre(i,k)
    2209             :         end do
    2210             :      end do
    2211             :      !$acc end parallel
    2212             :   end if
    2213             : 
    2214             :   !$acc parallel vector_length(VLENS) default(present)
    2215             :   !$acc loop gang vector collapse(2) private(dum,ratio)
    2216           0 :   do k=1,nlev
    2217           0 :      do i=1,mgncol
    2218             :         ! conservation to ensure no negative values of cloud water/precipitation
    2219             :         ! in case microphysical process rates are large
    2220             :         !===================================================================
    2221             : 
    2222             :         ! note: for check on conservation, processes are multiplied by omsm
    2223             :         ! to prevent problems due to round off error
    2224             : 
    2225             :         ! conservation of qc
    2226             :         !-------------------------------------------------------------------
    2227           0 :         dum = ((prc(i,k)+pra(i,k)+mnuccc(i,k)+mnucct(i,k)+msacwi(i,k)+ &
    2228             :              psacws(i,k)+bergs(i,k)+qmultg(i,k)+psacwg(i,k)+pgsacw(i,k))*lcldm(i,k)+ &
    2229           0 :              berg(i,k))*deltat 
    2230           0 :         if (dum.gt.qc(i,k)) then
    2231             :            ratio = qc(i,k)*rdeltat/((prc(i,k)+pra(i,k)+mnuccc(i,k)+mnucct(i,k)+ &
    2232             :                 msacwi(i,k)+psacws(i,k)+bergs(i,k)+qmultg(i,k)+psacwg(i,k)+pgsacw(i,k))*lcldm(i,k)+&
    2233           0 :                 berg(i,k))*omsm
    2234           0 :            qmultg(i,k)=qmultg(i,k)*ratio
    2235           0 :            psacwg(i,k)=psacwg(i,k)*ratio
    2236           0 :            pgsacw(i,k)=pgsacw(i,k)*ratio
    2237           0 :            prc(i,k) = prc(i,k)*ratio
    2238           0 :            pra(i,k) = pra(i,k)*ratio
    2239           0 :            mnuccc(i,k) = mnuccc(i,k)*ratio
    2240           0 :            mnucct(i,k) = mnucct(i,k)*ratio
    2241           0 :            msacwi(i,k) = msacwi(i,k)*ratio
    2242           0 :            psacws(i,k) = psacws(i,k)*ratio
    2243           0 :            bergs(i,k) = bergs(i,k)*ratio
    2244           0 :            berg(i,k) = berg(i,k)*ratio
    2245           0 :            qcrat(i,k) = ratio
    2246             :         else
    2247           0 :            qcrat(i,k) = 1._r8
    2248             :         end if
    2249             :         !PMC 12/3/12: ratio is also frac of step w/ liquid.
    2250             :         !thus we apply berg for "ratio" of timestep and vapor
    2251             :         !deposition for the remaining frac of the timestep.
    2252           0 :         if (qc(i,k) >= qsmall) then
    2253           0 :            vap_dep(i,k) = vap_dep(i,k)*(1._r8-qcrat(i,k))
    2254             :         end if
    2255             :      end do
    2256             :   end do
    2257             : 
    2258             :   !$acc loop gang vector collapse(2) private(dum,dum1)
    2259           0 :   do k=1,nlev
    2260           0 :      do i=1,mgncol
    2261             :         !=================================================================
    2262             :         ! apply limiter to ensure that ice/snow sublimation and rain evap
    2263             :         ! don't push conditions into supersaturation, and ice deposition/nucleation don't
    2264             :         ! push conditions into sub-saturation
    2265             :         ! note this is done after qc conservation since we don't know how large
    2266             :         ! vap_dep is before then
    2267             :         ! estimates are only approximate since other process terms haven't been limited
    2268             :         ! for conservation yet
    2269             : 
    2270             :         ! first limit ice deposition/nucleation vap_dep + mnuccd
    2271           0 :         dum1 = vap_dep(i,k) + mnuccd(i,k)
    2272           0 :         if (dum1 > 1.e-20_r8) then
    2273           0 :            dum = (q(i,k)-qvi(i,k))/(1._r8 + xxls_squared*qvi(i,k)/(cpp*rv*t(i,k)**2))*rdeltat
    2274           0 :            dum = max(dum,0._r8)
    2275           0 :            if (dum1 > dum) then
    2276             :               ! Allocate the limited "dum" tendency to mnuccd and vap_dep
    2277             :               ! processes. Don't divide by cloud fraction; these are grid-
    2278             :               ! mean rates.
    2279           0 :               dum1 = mnuccd(i,k) / (vap_dep(i,k)+mnuccd(i,k))
    2280           0 :               mnuccd(i,k) = dum*dum1
    2281           0 :               vap_dep(i,k) = dum - mnuccd(i,k)
    2282             :            end if
    2283             :         end if
    2284             :      end do
    2285             :   end do
    2286             : 
    2287             :   !$acc loop gang vector collapse(2) private(dum,ratio)
    2288           0 :   do k=1,nlev
    2289           0 :      do i=1,mgncol
    2290             :         !===================================================================
    2291             :         ! conservation of nc
    2292             :         !-------------------------------------------------------------------
    2293           0 :         dum = (nprc1(i,k)+npra(i,k)+nnuccc(i,k)+nnucct(i,k)+ &
    2294           0 :                npsacws(i,k)-nsubc(i,k)+npsacwg(i,k))*lcldm(i,k)*deltat
    2295           0 :         if (dum.gt.nc(i,k)) then
    2296             :            ratio = nc(i,k)*rdeltat/((nprc1(i,k)+npra(i,k)+nnuccc(i,k)+nnucct(i,k)+&
    2297           0 :                    npsacws(i,k)-nsubc(i,k)+npsacwg(i,k))*lcldm(i,k))*omsm
    2298           0 :            npsacwg(i,k) = npsacwg(i,k)*ratio
    2299           0 :            nprc1(i,k)   = nprc1(i,k)*ratio
    2300           0 :            npra(i,k)    = npra(i,k)*ratio
    2301           0 :            nnuccc(i,k)  = nnuccc(i,k)*ratio
    2302           0 :            nnucct(i,k)  = nnucct(i,k)*ratio
    2303           0 :            npsacws(i,k) = npsacws(i,k)*ratio
    2304           0 :            nsubc(i,k)   = nsubc(i,k)*ratio
    2305             :         end if
    2306           0 :         mnuccri(i,k)=0._r8
    2307           0 :         nnuccri(i,k)=0._r8
    2308             : 
    2309           0 :         if (do_cldice) then
    2310             :            ! freezing of rain to produce ice if mean rain size is smaller than Dcs
    2311           0 :            if (lamr(i,k) > qsmall) then
    2312           0 :               if (1._r8/lamr(i,k) < Dcs) then
    2313           0 :                  mnuccri(i,k)=mnuccr(i,k)
    2314           0 :                  nnuccri(i,k)=nnuccr(i,k)
    2315           0 :                  mnuccr(i,k)=0._r8
    2316           0 :                  nnuccr(i,k)=0._r8
    2317             :               end if
    2318             :            end if
    2319             :         end if
    2320             :      end do
    2321             :   end do
    2322             : 
    2323             :   !$acc loop gang vector collapse(2) private(dum,ratio)
    2324           0 :   do k=1,nlev
    2325           0 :      do i=1,mgncol
    2326             :         ! conservation of rain mixing ratio
    2327             :         !-------------------------------------------------------------------
    2328           0 :         dum = ((-pre(i,k)+pracs(i,k)+mnuccr(i,k)+mnuccri(i,k) &
    2329             :              +qmultrg(i,k)+pracg(i,k)+pgracs(i,k))*precip_frac(i,k)- &
    2330           0 :              (pra(i,k)+prc(i,k))*lcldm(i,k))*deltat
    2331             :         ! note that qrtend is included below because of instantaneous freezing/melt
    2332           0 :         if (dum.gt.qr(i,k).and. &
    2333           0 :              (-pre(i,k)+pracs(i,k)+mnuccr(i,k)+mnuccri(i,k)+qmultrg(i,k)+pracg(i,k)+pgracs(i,k)).ge.qsmall) then
    2334             :            ratio = (qr(i,k)*rdeltat+(pra(i,k)+prc(i,k))*lcldm(i,k))/   &
    2335             :                 precip_frac(i,k)/(-pre(i,k)+pracs(i,k)+mnuccr(i,k)+mnuccri(i,k) &
    2336           0 :                 +qmultrg(i,k)+pracg(i,k)+pgracs(i,k))*omsm
    2337           0 :            qmultrg(i,k)= qmultrg(i,k)*ratio
    2338           0 :            pracg(i,k)=pracg(i,k)*ratio
    2339           0 :            pgracs(i,k)=pgracs(i,k)*ratio
    2340           0 :            pre(i,k)=pre(i,k)*ratio
    2341           0 :            pracs(i,k)=pracs(i,k)*ratio
    2342           0 :            mnuccr(i,k)=mnuccr(i,k)*ratio
    2343           0 :            mnuccri(i,k)=mnuccri(i,k)*ratio
    2344             :         end if
    2345             :      end do
    2346             :   end do
    2347             : 
    2348             :   !$acc loop gang vector collapse(2)
    2349           0 :   do k=1,nlev
    2350           0 :      do i=1,mgncol
    2351             :         ! conservation of rain number
    2352             :         !-------------------------------------------------------------------
    2353             :         ! Add evaporation of rain number.
    2354           0 :         if (pre(i,k) < 0._r8) then
    2355           0 :            nsubr(i,k) = pre(i,k)*nr(i,k)/qr(i,k)
    2356             :         else
    2357           0 :            nsubr(i,k) = 0._r8
    2358             :         end if
    2359             :      end do
    2360             :   end do
    2361             : 
    2362             :   !$acc loop gang vector collapse(2) private(dum,ratio)
    2363           0 :   do k=1,nlev
    2364           0 :      do i=1,mgncol
    2365           0 :         dum = ((-nsubr(i,k)+npracs(i,k)+nnuccr(i,k)+nnuccri(i,k)-nragg(i,k)+npracg(i,k)+ngracs(i,k)) &
    2366           0 :              *precip_frac(i,k)- nprc(i,k)*lcldm(i,k))*deltat
    2367           0 :         if (dum.gt.nr(i,k)) then
    2368             :            ratio = (nr(i,k)*rdeltat+nprc(i,k)*lcldm(i,k))/precip_frac(i,k)/ &
    2369           0 :                 (-nsubr(i,k)+npracs(i,k)+nnuccr(i,k)+nnuccri(i,k)-nragg(i,k)+npracg(i,k)+ngracs(i,k))*omsm
    2370           0 :            npracg(i,k)=npracg(i,k)*ratio
    2371           0 :            ngracs(i,k)=ngracs(i,k)*ratio
    2372           0 :            nragg(i,k)=nragg(i,k)*ratio
    2373           0 :            npracs(i,k)=npracs(i,k)*ratio
    2374           0 :            nnuccr(i,k)=nnuccr(i,k)*ratio
    2375           0 :            nsubr(i,k)=nsubr(i,k)*ratio
    2376           0 :            nnuccri(i,k)=nnuccri(i,k)*ratio
    2377             :         end if
    2378             :      end do
    2379             :   end do
    2380             : 
    2381           0 :   if (do_cldice) then
    2382             :      !$acc loop gang vector collapse(2) private(dum,ratio)
    2383           0 :      do k=1,nlev
    2384           0 :         do i=1,mgncol
    2385             :            ! conservation of qi
    2386             :            !-------------------------------------------------------------------
    2387           0 :            dum = ((-mnuccc(i,k)-mnucct(i,k)-mnudep(i,k)-msacwi(i,k)-qmultg(i,k))*lcldm(i,k)+(prci(i,k)+ &
    2388             :                 prai(i,k))*icldm(i,k)+(-qmultrg(i,k)-mnuccri(i,k))*precip_frac(i,k) &
    2389           0 :                 -ice_sublim(i,k)-vap_dep(i,k)-berg(i,k)-mnuccd(i,k))*deltat
    2390           0 :            if (dum.gt.qi(i,k)) then
    2391             :               ratio = (qi(i,k)*rdeltat+vap_dep(i,k)+berg(i,k)+mnuccd(i,k)+ &
    2392             :                    (mnuccc(i,k)+mnucct(i,k)+mnudep(i,k)+msacwi(i,k)+qmultg(i,k))*lcldm(i,k)+ &
    2393             :                    (qmultrg(i,k)+mnuccri(i,k))*precip_frac(i,k))/ &
    2394           0 :                    ((prci(i,k)+prai(i,k))*icldm(i,k)-ice_sublim(i,k))*omsm
    2395           0 :               prci(i,k) = prci(i,k)*ratio
    2396           0 :               prai(i,k) = prai(i,k)*ratio
    2397           0 :               ice_sublim(i,k) = ice_sublim(i,k)*ratio
    2398             :            end if
    2399             :         end do
    2400             :      end do
    2401             :   end if
    2402             : 
    2403           0 :   if (do_cldice) then
    2404             :      !$acc loop gang vector collapse(2) private(dum,ratio,tmpfrz)
    2405           0 :      do k=1,nlev
    2406           0 :         do i=1,mgncol
    2407             :            ! conservation of ni
    2408             :            !-------------------------------------------------------------------
    2409           0 :            if (use_hetfrz_classnuc) then
    2410           0 :               tmpfrz = nnuccc(i,k)
    2411             :            else
    2412             :               tmpfrz = 0._r8
    2413             :            end if
    2414           0 :            dum = ((-nnucct(i,k)-tmpfrz-nnudep(i,k)-nsacwi(i,k)-nmultg(i,k))*lcldm(i,k)+(nprci(i,k)+ &
    2415             :                 nprai(i,k)-nsubi(i,k))*icldm(i,k)+(-nmultrg(i,k)-nnuccri(i,k))*precip_frac(i,k)- &
    2416           0 :                 nnuccd(i,k))*deltat
    2417           0 :            if (dum.gt.ni(i,k)) then
    2418             :               ratio = (ni(i,k)*rdeltat+nnuccd(i,k)+ &
    2419             :                  (nnucct(i,k)+tmpfrz+nnudep(i,k)+nsacwi(i,k)+nmultg(i,k))*lcldm(i,k)+ &
    2420             :                  (nnuccri(i,k)+nmultrg(i,k))*precip_frac(i,k))/ &
    2421           0 :                  ((nprci(i,k)+nprai(i,k)-nsubi(i,k))*icldm(i,k))*omsm
    2422           0 :               nprci(i,k) = nprci(i,k)*ratio
    2423           0 :               nprai(i,k) = nprai(i,k)*ratio
    2424           0 :               nsubi(i,k) = nsubi(i,k)*ratio
    2425             :            end if
    2426             :         end do
    2427             :      end do
    2428             :   end if
    2429             : 
    2430             :   !$acc loop gang vector collapse(2) private(dum,ratio)
    2431           0 :   do k=1,nlev
    2432           0 :      do i=1,mgncol
    2433             :         ! conservation of snow mixing ratio
    2434             :         !-------------------------------------------------------------------
    2435           0 :         if (do_hail .or. do_graupel) then
    2436             :         ! NOTE: mnuccr is moved to graupel when active
    2437             :         ! psacr is a positive value, but a loss for snow
    2438             :         !HM: psacr is positive in dum (two negatives)
    2439           0 :            dum = (-(prds(i,k)+pracs(i,k)-psacr(i,k))*precip_frac(i,k)-(prai(i,k)+prci(i,k))*icldm(i,k) &
    2440           0 :              -(bergs(i,k)+psacws(i,k))*lcldm(i,k))*deltat
    2441             :         else
    2442           0 :            dum = (-(prds(i,k)+pracs(i,k)+mnuccr(i,k))*precip_frac(i,k)-(prai(i,k)+prci(i,k))*icldm(i,k) &
    2443           0 :              -(bergs(i,k)+psacws(i,k))*lcldm(i,k))*deltat
    2444             :         end if 
    2445           0 :         if (dum.gt.qs(i,k).and.(psacr(i,k)-prds(i,k)).ge.qsmall) then
    2446           0 :            if (do_hail .or. do_graupel) then        
    2447             :               ratio = (qs(i,k)*rdeltat+(prai(i,k)+prci(i,k))*icldm(i,k)+ &
    2448             :                    (bergs(i,k)+psacws(i,k))*lcldm(i,k)+pracs(i,k)*precip_frac(i,k))/ &
    2449           0 :                    precip_frac(i,k)/(psacr(i,k)-prds(i,k))*omsm
    2450           0 :               psacr(i,k)=psacr(i,k)*ratio
    2451             :            else 
    2452             :               ratio = (qs(i,k)*rdeltat+(prai(i,k)+prci(i,k))*icldm(i,k)+ &
    2453             :                    (bergs(i,k)+psacws(i,k))*lcldm(i,k)+(pracs(i,k)+mnuccr(i,k))*precip_frac(i,k))/ &
    2454           0 :                    precip_frac(i,k)/(-prds(i,k))*omsm
    2455             :            end if
    2456           0 :            prds(i,k)=prds(i,k)*ratio
    2457             :         end if
    2458             :      end do
    2459             :   end do
    2460             : 
    2461             :   !$acc loop gang vector collapse(2) private(dum,ratio)
    2462           0 :   do k=1,nlev
    2463           0 :      do i=1,mgncol
    2464             :         ! conservation of snow number
    2465             :         !-------------------------------------------------------------------
    2466             :         ! calculate loss of number due to sublimation
    2467             :         ! for now neglect sublimation of ns
    2468           0 :         nsubs(i,k)=0._r8
    2469           0 :         if (do_hail .or. do_graupel) then        
    2470           0 :            dum = ((-nsagg(i,k)-nsubs(i,k)+ngracs(i,k))*precip_frac(i,k)-nprci(i,k)*icldm(i,k)+nscng(i,k)*lcldm(i,k))*deltat
    2471             :         else
    2472           0 :            dum = ((-nsagg(i,k)-nsubs(i,k)-nnuccr(i,k))*precip_frac(i,k)-nprci(i,k)*icldm(i,k))*deltat
    2473             :         end if
    2474           0 :         if (dum.gt.ns(i,k)) then
    2475           0 :            if (do_hail .or. do_graupel) then        
    2476             :               ratio = (ns(i,k)*rdeltat+nprci(i,k)*icldm(i,k))/precip_frac(i,k)/ &
    2477           0 :                    (-nsubs(i,k)-nsagg(i,k)+ngracs(i,k)+lcldm(i,k)/precip_frac(i,k)*nscng(i,k))*omsm
    2478           0 :               nscng(i,k)=nscng(i,k)*ratio
    2479           0 :               ngracs(i,k)=ngracs(i,k)*ratio
    2480             :            else
    2481             :               ratio = (ns(i,k)*rdeltat+nnuccr(i,k)* &
    2482             :                    precip_frac(i,k)+nprci(i,k)*icldm(i,k))/precip_frac(i,k)/ &
    2483           0 :                    (-nsubs(i,k)-nsagg(i,k))*omsm
    2484             :            endif
    2485           0 :            nsubs(i,k)=nsubs(i,k)*ratio
    2486           0 :            nsagg(i,k)=nsagg(i,k)*ratio
    2487             :         end if
    2488             :      end do
    2489             :   end do
    2490             : 
    2491             : ! Graupel Conservation Checks
    2492             : !-------------------------------------------------------------------
    2493             : 
    2494           0 :   if (do_hail.or.do_graupel) then
    2495             :      ! conservation of graupel mass
    2496             :      !-------------------------------------------------------------------
    2497             : 
    2498             :      !$acc loop gang vector collapse(2) private(dum,ratio)
    2499           0 :      do k=1,nlev
    2500           0 :         do i=1,mgncol
    2501           0 :            dum= ((-pracg(i,k)-pgracs(i,k)-prdg(i,k)-psacr(i,k)-mnuccr(i,k))*precip_frac(i,k) &
    2502           0 :                 + (-psacwg(i,k)-pgsacw(i,k))*lcldm(i,k))*deltat
    2503           0 :            if (dum.gt.qg(i,k)) then
    2504             :               ! note: prdg is always negative (like prds), so it needs to be subtracted in ratio
    2505             :               ratio = (qg(i,k)*rdeltat + (pracg(i,k)+pgracs(i,k)+psacr(i,k)+mnuccr(i,k))*precip_frac(i,k) &
    2506           0 :                        + (psacwg(i,k)+pgsacw(i,k))*lcldm(i,k)) / ((-prdg(i,k))*precip_frac(i,k)) * omsm
    2507           0 :               prdg(i,k)= prdg(i,k)*ratio
    2508             :            end if
    2509             :         end do
    2510             :      end do
    2511             :      ! conservation of graupel number: not needed, no sinks
    2512             :      !-------------------------------------------------------------------
    2513             :   end if
    2514             : 
    2515             :   !$acc loop gang vector collapse(2)
    2516           0 :   do k=1,nlev
    2517           0 :      do i=1,mgncol
    2518             :         ! next limit ice and snow sublimation and rain evaporation
    2519             :         ! get estimate of q and t at end of time step
    2520             :         ! don't include other microphysical processes since they haven't
    2521             :         ! been limited via conservation checks yet
    2522           0 :         qtmpAI(i,k)=q(i,k)-(ice_sublim(i,k)+vap_dep(i,k)+mnuccd(i,k)+ &
    2523           0 :                 (pre(i,k)+prds(i,k)+prdg(i,k))*precip_frac(i,k))*deltat
    2524             :         ttmpA(i,k)=t(i,k)+((pre(i,k)*precip_frac(i,k))*xxlv+ &
    2525           0 :              ((prds(i,k)+prdg(i,k))*precip_frac(i,k)+vap_dep(i,k)+ice_sublim(i,k)+mnuccd(i,k))*xxls)*deltat/cpp
    2526             :      end do
    2527             :   end do
    2528             :   !$acc end parallel
    2529             : 
    2530             :   ! use rhw to allow ice supersaturation
    2531           0 :   call qsat_water(ttmpA, p, esnA, qvnAI, mgncol*nlev)
    2532             : 
    2533             :   !$acc parallel vector_length(VLENS) default(present)
    2534             :   !$acc loop gang vector collapse(2)
    2535           0 :   do k=1,nlev
    2536           0 :      do i=1,mgncol
    2537           0 :         if ((pre(i,k)+prds(i,k)+prdg(i,k))*precip_frac(i,k)+ice_sublim(i,k) < -1.e-20_r8) then
    2538             :            ! modify ice/precip evaporation rate if q > qsat
    2539           0 :            if (qtmpAI(i,k) > qvnAI(i,k)) then
    2540           0 :               dum1A(i,k)=pre(i,k)*precip_frac(i,k)/((pre(i,k)+prds(i,k)+prdg(i,k))*precip_frac(i,k)+ice_sublim(i,k))
    2541           0 :               dum2A(i,k)=prds(i,k)*precip_frac(i,k)/((pre(i,k)+prds(i,k)+prdg(i,k))*precip_frac(i,k)+ice_sublim(i,k))
    2542           0 :               dum3A(i,k)=prdg(i,k)*precip_frac(i,k)/((pre(i,k)+prds(i,k)+prdg(i,k))*precip_frac(i,k)+ice_sublim(i,k))
    2543             :               ! recalculate q and t after vap_dep and mnuccd but without evap or sublim
    2544           0 :               ttmpA(i,k)=t(i,k)+((vap_dep(i,k)+mnuccd(i,k))*xxls)*deltat/cpp
    2545           0 :               dum_2D(i,k)=q(i,k)-(vap_dep(i,k)+mnuccd(i,k))*deltat
    2546             :            end if
    2547             :         end if
    2548             :      end do
    2549             :   end do
    2550             :   !$acc end parallel
    2551             : 
    2552             :   ! use rhw to allow ice supersaturation
    2553           0 :   call qsat_water(ttmpA, p, esnA, qvnA, mgncol*nlev)
    2554             : 
    2555             :   !$acc parallel vector_length(VLENS) default(present)
    2556             :   !$acc loop gang vector collapse(2) private(dum)
    2557           0 :   do k=1,nlev
    2558           0 :      do i=1,mgncol
    2559           0 :         if ((pre(i,k)+prds(i,k)+prdg(i,k))*precip_frac(i,k)+ice_sublim(i,k) < -1.e-20_r8) then
    2560             :            ! modify ice/precip evaporation rate if q > qsat
    2561           0 :            if (qtmpAI(i,k) > qvnAI(i,k)) then
    2562           0 :               dum=(dum_2D(i,k)-qvnA(i,k))/(1._r8 + xxlv_squared*qvnA(i,k)/(cpp*rv*ttmpA(i,k)**2))
    2563           0 :               dum=min(dum,0._r8)
    2564             :               ! modify rates if needed, divide by precip_frac to get local (in-precip) value
    2565           0 :               pre(i,k)=dum*dum1A(i,k)*rdeltat/precip_frac(i,k)
    2566             :            end if
    2567             :         end if
    2568             :      end do
    2569             :   end do
    2570             :   !$acc end parallel
    2571             : 
    2572             :   ! do separately using RHI for prds and ice_sublim
    2573           0 :   call qsat_ice(ttmpA, p, esnA, qvnA, mgncol*nlev)
    2574             : 
    2575             :   !$acc parallel vector_length(VLENS) default(present)
    2576             :   !$acc loop gang vector collapse(2) private(dum)
    2577           0 :   do k=1,nlev
    2578           0 :      do i=1,mgncol
    2579           0 :         if ((pre(i,k)+prds(i,k)+prdg(i,k))*precip_frac(i,k)+ice_sublim(i,k) < -1.e-20_r8) then
    2580             :            ! modify ice/precip evaporation rate if q > qsat
    2581           0 :            if (qtmpAI(i,k) > qvnAI(i,k)) then
    2582           0 :               dum=(dum_2D(i,k)-qvnA(i,k))/(1._r8 + xxls_squared*qvnA(i,k)/(cpp*rv*ttmpA(i,k)**2))
    2583           0 :               dum=min(dum,0._r8)
    2584             :               ! modify rates if needed, divide by precip_frac to get local (in-precip) value
    2585           0 :               prds(i,k) = dum*dum2A(i,k)*rdeltat/precip_frac(i,k)
    2586           0 :               prdg(i,k) = dum*dum3A(i,k)*rdeltat/precip_frac(i,k)
    2587             :               ! don't divide ice_sublim by cloud fraction since it is grid-averaged
    2588           0 :               dum1A(i,k) = (1._r8-dum1A(i,k)-dum2A(i,k)-dum3A(i,k))
    2589           0 :               ice_sublim(i,k) = dum*dum1A(i,k)*rdeltat
    2590             :            end if
    2591             :         end if
    2592             :      end do
    2593             :   end do
    2594             : 
    2595             :   ! Big "administration" loop enforces conservation, updates variables
    2596             :   ! that accumulate over substeps, and sets output variables.
    2597             : 
    2598             :   !$acc loop gang vector collapse(2)
    2599           0 :   do k=1,nlev
    2600           0 :      do i=1,mgncol
    2601             :         ! get tendencies due to microphysical conversion processes
    2602             :         !==========================================================
    2603             :         ! note: tendencies are multiplied by appropriate cloud/precip
    2604             :         ! fraction to get grid-scale values
    2605             :         ! note: vap_dep is already grid-average values
    2606             : 
    2607             :         ! The net tendencies need to be added to rather than overwritten,
    2608             :         ! because they may have a value already set for instantaneous
    2609             :         ! melting/freezing.
    2610           0 :         qvlat(i,k) = qvlat(i,k)-(pre(i,k)+prds(i,k))*precip_frac(i,k)-&
    2611             :              vap_dep(i,k)-ice_sublim(i,k)-mnuccd(i,k)-mnudep(i,k)*lcldm(i,k) &
    2612           0 :              -prdg(i,k)*precip_frac(i,k) 
    2613             :         tlat(i,k) = tlat(i,k)+((pre(i,k)*precip_frac(i,k))*xxlv+ &
    2614             :              ((prds(i,k)+prdg(i,k))*precip_frac(i,k)+vap_dep(i,k)+ice_sublim(i,k)+ &
    2615             :                  mnuccd(i,k)+mnudep(i,k)*lcldm(i,k))*xxls+ &
    2616             :              ((bergs(i,k)+psacws(i,k)+mnuccc(i,k)+mnucct(i,k)+msacwi(i,k)+psacwg(i,k)+ &
    2617             :                   qmultg(i,k)+pgsacw(i,k))*lcldm(i,k)+ &
    2618             :              (mnuccr(i,k)+pracs(i,k)+mnuccri(i,k)+pracg(i,k)+pgracs(i,k)+qmultrg(i,k))*precip_frac(i,k)+ &
    2619           0 :                   berg(i,k))*xlf)  
    2620             :         qctend(i,k) = qctend(i,k)+ &
    2621             :              (-pra(i,k)-prc(i,k)-mnuccc(i,k)-mnucct(i,k)-msacwi(i,k)- &
    2622           0 :              psacws(i,k)-bergs(i,k)-qmultg(i,k)-psacwg(i,k)-pgsacw(i,k))*lcldm(i,k)-berg(i,k)
    2623             : 
    2624           0 :         if (do_cldice) then
    2625             :            qitend(i,k) = qitend(i,k)+ &
    2626             :               (mnuccc(i,k)+mnucct(i,k)+mnudep(i,k)+msacwi(i,k)+qmultg(i,k))*lcldm(i,k)+(-prci(i,k)- &
    2627             :               prai(i,k))*icldm(i,k)+vap_dep(i,k)+berg(i,k)+ice_sublim(i,k)+ &
    2628           0 :               mnuccd(i,k)+(mnuccri(i,k)+qmultrg(i,k))*precip_frac(i,k)
    2629             :         end if
    2630             : 
    2631             :         qrtend(i,k) = qrtend(i,k)+ &
    2632             :              (pra(i,k)+prc(i,k))*lcldm(i,k)+(pre(i,k)-pracs(i,k)- &
    2633           0 :              mnuccr(i,k)-mnuccri(i,k)-qmultrg(i,k)-pracg(i,k)-pgracs(i,k))*precip_frac(i,k)
    2634             : 
    2635           0 :         if (do_hail.or.do_graupel) then
    2636             :            qgtend(i,k) = qgtend(i,k) + (pracg(i,k)+pgracs(i,k)+prdg(i,k)+psacr(i,k)+mnuccr(i,k))*precip_frac(i,k) &
    2637           0 :                 + (psacwg(i,k)+pgsacw(i,k))*lcldm(i,k)
    2638             :            qstend(i,k) = qstend(i,k)+ &
    2639             :                 (prai(i,k)+prci(i,k))*icldm(i,k)+(psacws(i,k)+bergs(i,k))*lcldm(i,k)+(prds(i,k)+ &
    2640           0 :                 pracs(i,k)-psacr(i,k))*precip_frac(i,k)
    2641             :         else
    2642             :            !necessary since mnuccr moved to graupel
    2643             :            qstend(i,k) = qstend(i,k)+ &
    2644             :                 (prai(i,k)+prci(i,k))*icldm(i,k)+(psacws(i,k)+bergs(i,k))*lcldm(i,k)+(prds(i,k)+ &
    2645           0 :                 pracs(i,k)+mnuccr(i,k))*precip_frac(i,k)
    2646             :         end if
    2647             :      end do
    2648             :   end do
    2649             : 
    2650             :   !$acc loop gang vector collapse(2)
    2651           0 :   do k=1,nlev
    2652           0 :      do i=1,mgncol
    2653           0 :         cmeout(i,k) = vap_dep(i,k) + ice_sublim(i,k) + mnuccd(i,k)
    2654             :         ! add output for cmei (accumulate)
    2655           0 :         cmeitot(i,k) = vap_dep(i,k) + ice_sublim(i,k) + mnuccd(i,k)
    2656             :         !-------------------------------------------------------------------
    2657             :         ! evaporation/sublimation is stored here as positive term
    2658             :         ! Add to evapsnow via prdg
    2659           0 :         evapsnow(i,k) = (-prds(i,k)-prdg(i,k))*precip_frac(i,k)
    2660           0 :         nevapr(i,k) = -pre(i,k)*precip_frac(i,k)
    2661           0 :         prer_evap(i,k) = -pre(i,k)*precip_frac(i,k)
    2662             :         ! change to make sure prain is positive: do not remove snow from
    2663             :         ! prain used for wet deposition
    2664             :         prain(i,k) = (pra(i,k)+prc(i,k))*lcldm(i,k)+(-pracs(i,k)- &
    2665           0 :              mnuccr(i,k)-mnuccri(i,k))*precip_frac(i,k)
    2666           0 :         if (do_hail .or. do_graupel) then
    2667             :            prodsnow(i,k) = (prai(i,k)+prci(i,k))*icldm(i,k)+(psacws(i,k)+bergs(i,k))*lcldm(i,k)+(&
    2668           0 :                 pracs(i,k))*precip_frac(i,k)
    2669             :         else
    2670             :            prodsnow(i,k) = (prai(i,k)+prci(i,k))*icldm(i,k)+(psacws(i,k)+bergs(i,k))*lcldm(i,k)+(&
    2671           0 :                 pracs(i,k)+mnuccr(i,k))*precip_frac(i,k)
    2672             :         end if
    2673             :         ! following are used to calculate 1st order conversion rate of cloud water
    2674             :         !    to rain and snow (1/s), for later use in aerosol wet removal routine
    2675             :         ! previously, wetdepa used (prain/qc) for this, and the qc in wetdepa may be smaller than the qc
    2676             :         !    used to calculate pra, prc, ... in this routine
    2677             :         ! qcsinksum_rate1ord = { rate of direct transfer of cloud water to rain & snow }
    2678             :         !                      (no cloud ice or bergeron terms)
    2679           0 :         qcsinksum_rate1ord(i,k) = (pra(i,k)+prc(i,k)+psacws(i,k)+psacwg(i,k)+pgsacw(i,k))*lcldm(i,k) 
    2680             :         ! Avoid zero/near-zero division.
    2681             :         qcsinksum_rate1ord(i,k) = qcsinksum_rate1ord(i,k) / &
    2682           0 :              max(qc(i,k),1.0e-30_r8)
    2683             :      end do
    2684             :   end do
    2685             : 
    2686             :   !$acc loop gang vector collapse(2)
    2687           0 :   do k=1,nlev
    2688           0 :      do i=1,mgncol
    2689             :         ! microphysics output, note this is grid-averaged
    2690           0 :         pratot(i,k)     = pra(i,k)*lcldm(i,k)
    2691           0 :         prctot(i,k)     = prc(i,k)*lcldm(i,k)
    2692           0 :         mnuccctot(i,k)  = mnuccc(i,k)*lcldm(i,k)
    2693           0 :         mnudeptot(i,k)  = mnudep(i,k)*lcldm(i,k)
    2694           0 :         mnuccttot(i,k)  = mnucct(i,k)*lcldm(i,k)
    2695           0 :         msacwitot(i,k)  = msacwi(i,k)*lcldm(i,k)
    2696           0 :         psacwstot(i,k)  = psacws(i,k)*lcldm(i,k)
    2697           0 :         bergstot(i,k)   = bergs(i,k)*lcldm(i,k)
    2698           0 :         bergtot(i,k)    = berg(i,k)
    2699           0 :         prcitot(i,k)    = prci(i,k)*icldm(i,k)
    2700           0 :         praitot(i,k)    = prai(i,k)*icldm(i,k)
    2701           0 :         mnuccdtot(i,k)  = mnuccd(i,k)*icldm(i,k)
    2702           0 :         pracstot(i,k)   = pracs(i,k)*precip_frac(i,k)
    2703           0 :         mnuccrtot(i,k)  = mnuccr(i,k)*precip_frac(i,k)
    2704           0 :         mnuccritot(i,k) = mnuccri(i,k)*precip_frac(i,k)
    2705             :      end do
    2706             :   end do
    2707             :         
    2708             :   !$acc loop gang vector collapse(2)
    2709           0 :   do k=1,nlev
    2710           0 :      do i=1,mgncol
    2711           0 :         psacrtot(i,k)   = psacr(i,k)*precip_frac(i,k)
    2712           0 :         pracgtot(i,k)   = pracg(i,k)*precip_frac(i,k)
    2713           0 :         psacwgtot(i,k)  = psacwg(i,k)*lcldm(i,k)
    2714           0 :         pgsacwtot(i,k)  = pgsacw(i,k)*lcldm(i,k)
    2715           0 :         pgracstot(i,k)  = pgracs(i,k)*precip_frac(i,k)
    2716           0 :         prdgtot(i,k)    = prdg(i,k)*precip_frac(i,k)
    2717           0 :         qmultgtot(i,k)  = qmultg(i,k)*lcldm(i,k)
    2718           0 :         qmultrgtot(i,k) = qmultrg(i,k)*precip_frac(i,k)
    2719           0 :         npracgtot(i,k)  = npracg(i,k)*precip_frac(i,k) 
    2720           0 :         nscngtot(i,k)   = nscng(i,k)*lcldm(i,k) 
    2721           0 :         ngracstot(i,k)  = ngracs(i,k)*precip_frac(i,k)
    2722           0 :         nmultgtot(i,k)  = nmultg(i,k)*lcldm(i,k)
    2723           0 :         nmultrgtot(i,k) = nmultrg(i,k)*precip_frac(i,k)
    2724           0 :         npsacwgtot(i,k) = npsacwg(i,k)*lcldm(i,k)
    2725             :      end do
    2726             :   end do
    2727             : 
    2728             :   !$acc loop gang vector collapse(2) private(tmpfrz)
    2729           0 :   do k=1,nlev
    2730           0 :      do i=1,mgncol
    2731           0 :         nctend(i,k) = nctend(i,k)+&
    2732             :              (-nnuccc(i,k)-nnucct(i,k)-npsacws(i,k)+nsubc(i,k) &
    2733           0 :              -npra(i,k)-nprc1(i,k)-npsacwg(i,k))*lcldm(i,k)
    2734             : 
    2735           0 :         if (do_cldice) then
    2736           0 :            if (use_hetfrz_classnuc) then
    2737           0 :               tmpfrz = nnuccc(i,k)
    2738             :            else
    2739             :               tmpfrz = 0._r8
    2740             :            end if
    2741             :            nitend(i,k) = nitend(i,k)+ nnuccd(i,k)+ &
    2742             :                 (nnucct(i,k)+tmpfrz+nnudep(i,k)+nsacwi(i,k)+nmultg(i,k))*lcldm(i,k)+(nsubi(i,k)-nprci(i,k)- &
    2743           0 :                 nprai(i,k))*icldm(i,k)+(nnuccri(i,k)+nmultrg(i,k))*precip_frac(i,k)
    2744             :         end if
    2745             : 
    2746           0 :         if(do_graupel.or.do_hail) then
    2747             :            nstend(i,k) = nstend(i,k)+(nsubs(i,k)+ &
    2748           0 :                 nsagg(i,k)-ngracs(i,k))*precip_frac(i,k)+nprci(i,k)*icldm(i,k)-nscng(i,k)*lcldm(i,k)
    2749           0 :            ngtend(i,k) = ngtend(i,k)+nscng(i,k)*lcldm(i,k)+(ngracs(i,k)+nnuccr(i,k))*precip_frac(i,k)
    2750             :         else
    2751             :            !necessary since mnuccr moved to graupel
    2752             :            nstend(i,k) = nstend(i,k)+(nsubs(i,k)+ &
    2753           0 :                 nsagg(i,k)+nnuccr(i,k))*precip_frac(i,k)+nprci(i,k)*icldm(i,k)
    2754             :         end if
    2755             : 
    2756             :         nrtend(i,k) = nrtend(i,k)+ &
    2757             :              nprc(i,k)*lcldm(i,k)+(nsubr(i,k)-npracs(i,k)-nnuccr(i,k) &
    2758           0 :              -nnuccri(i,k)+nragg(i,k)-npracg(i,k)-ngracs(i,k))*precip_frac(i,k)
    2759             : 
    2760             :         ! make sure that ni at advanced time step does not exceed
    2761             :         ! maximum (existing N + source terms*dt), which is possible if mtime < deltat
    2762             :         ! note that currently mtime = deltat
    2763             :         !================================================================
    2764           0 :         if (do_cldice .and. nitend(i,k).gt.0._r8.and.ni(i,k)+nitend(i,k)*deltat.gt.nimax(i,k)) then
    2765           0 :            nitend(i,k)=max(0._r8,(nimax(i,k)-ni(i,k))*rdeltat)
    2766             :         end if
    2767             :      end do
    2768             :   end do ! end k loop
    2769             :   ! End of "administration" loop
    2770             : 
    2771             :   !-----------------------------------------------------
    2772             :   ! convert rain/snow q and N for output to history, note,
    2773             :   ! output is for gridbox average
    2774             : 
    2775             :   !$acc loop gang vector collapse(2)
    2776           0 :   do k=1,nlev
    2777           0 :      do i=1,mgncol
    2778           0 :         qrout(i,k) = qr(i,k)
    2779           0 :         nrout(i,k) = nr(i,k) * rho(i,k)
    2780           0 :         qsout(i,k) = qs(i,k)
    2781           0 :         nsout(i,k) = ns(i,k) * rho(i,k)
    2782           0 :         qgout(i,k) = qg(i,k)
    2783           0 :         ngout(i,k) = ng(i,k) * rho(i,k)
    2784             :      end do
    2785             :   end do
    2786             :   !$acc end parallel
    2787             : 
    2788             :   ! calculate n0r and lamr from rain mass and number
    2789             :   ! divide by precip fraction to get in-precip (local) values of
    2790             :   ! rain mass and number, divide by rhow to get rain number in kg^-1
    2791           0 :   call size_dist_param_basic(mg_rain_props, qric, nric, lamr, mgncol, nlev, n0=n0r)
    2792             : 
    2793             :   ! Calculate rercld
    2794             :   ! calculate mean size of combined rain and cloud water
    2795           0 :   call calc_rercld(lamr, n0r, lamc, pgam, qric, qcic, ncic, rercld, mgncol*nlev)
    2796             : 
    2797             :   ! Assign variables back to start-of-timestep values
    2798             :   ! Some state variables are changed before the main microphysics loop
    2799             :   ! to make "instantaneous" adjustments. Afterward, we must move those changes
    2800             :   ! back into the tendencies.
    2801             :   ! These processes:
    2802             :   !  - Droplet activation (npccn, impacts nc)
    2803             :   !  - Instantaneous snow melting  (minstsm/ninstsm, impacts qr/qs/nr/ns)
    2804             :   !  - Instantaneous rain freezing (minstfr/ninstrf, impacts qr/qs/nr/ns)
    2805             :   !================================================================================
    2806             :   ! Re-apply droplet activation tendency
    2807             : 
    2808             :   !$acc parallel vector_length(VLENS) default(present)
    2809             :   !$acc loop gang vector collapse(2)
    2810           0 :   do k=1,nlev
    2811           0 :      do i=1,mgncol
    2812           0 :         nc(i,k) = ncn(i,k)
    2813           0 :         nctend(i,k) = nctend(i,k) + npccn(i,k)
    2814             :         ! Re-apply rain freezing and snow melting.
    2815           0 :         dum_2D(i,k) = qs(i,k)
    2816           0 :         qs(i,k)     = qsn(i,k)
    2817           0 :         qstend(i,k) = qstend(i,k) + (dum_2D(i,k)-qs(i,k))*rdeltat
    2818             :       
    2819           0 :         dum_2D(i,k) = ns(i,k)
    2820           0 :         ns(i,k)     = nsn(i,k)
    2821           0 :         nstend(i,k) = nstend(i,k) + (dum_2D(i,k)-ns(i,k))*rdeltat
    2822             :       
    2823           0 :         dum_2D(i,k) = qr(i,k)
    2824           0 :         qr(i,k)     = qrn(i,k)
    2825           0 :         qrtend(i,k) = qrtend(i,k) + (dum_2D(i,k)-qr(i,k))*rdeltat
    2826             :       
    2827           0 :         dum_2D(i,k) = nr(i,k)
    2828           0 :         nr(i,k)     = nrn(i,k)
    2829           0 :         nrtend(i,k) = nrtend(i,k) + (dum_2D(i,k)-nr(i,k))*rdeltat
    2830             : 
    2831             :         ! Re-apply graupel freezing/melting
    2832           0 :         dum_2D(i,k) = qg(i,k)
    2833           0 :         qg(i,k)     = qgr(i,k)
    2834           0 :         qgtend(i,k) = qgtend(i,k) + (dum_2D(i,k)-qg(i,k))*rdeltat
    2835             :       
    2836           0 :         dum_2D(i,k) = ng(i,k)
    2837           0 :         ng(i,k)     = ngr(i,k)
    2838           0 :         ngtend(i,k) = ngtend(i,k) + (dum_2D(i,k)-ng(i,k))*rdeltat
    2839             :         !.............................................................................
    2840             :         !================================================================================
    2841             :         ! modify to include snow. in prain & evap (diagnostic here: for wet dep)
    2842           0 :         nevapr(i,k) = nevapr(i,k) + evapsnow(i,k)
    2843           0 :         prain(i,k) = prain(i,k) + prodsnow(i,k)
    2844             :      end do
    2845             :   end do
    2846             : 
    2847             :   !$acc loop gang vector collapse(2)
    2848           0 :   do k=1,nlev
    2849           0 :      do i=1,mgncol
    2850             :         ! calculate sedimentation for cloud water and ice
    2851             :         ! and Graupel (mg3)
    2852             :         !================================================================================
    2853             :         ! update in-cloud cloud mixing ratio and number concentration
    2854             :         ! with microphysical tendencies to calculate sedimentation, assign to dummy vars
    2855             :         ! note: these are in-cloud values***, hence we divide by cloud fraction
    2856           0 :         dumc(i,k)  = (qc(i,k)+qctend(i,k)*deltat)/lcldm(i,k)
    2857           0 :         dumi(i,k)  = (qi(i,k)+qitend(i,k)*deltat)/icldm(i,k)
    2858           0 :         dumnc(i,k) = max((nc(i,k)+nctend(i,k)*deltat)/lcldm(i,k),0._r8)
    2859           0 :         dumni(i,k) = max((ni(i,k)+nitend(i,k)*deltat)/icldm(i,k),0._r8)
    2860             : 
    2861           0 :         dumr(i,k)  = (qr(i,k)+qrtend(i,k)*deltat)/precip_frac(i,k)
    2862           0 :         dumnr(i,k) = max((nr(i,k)+nrtend(i,k)*deltat)/precip_frac(i,k),0._r8)
    2863           0 :         dums(i,k)  = (qs(i,k)+qstend(i,k)*deltat)/precip_frac(i,k)
    2864           0 :         dumns(i,k) = max((ns(i,k)+nstend(i,k)*deltat)/precip_frac(i,k),0._r8)
    2865             : 
    2866           0 :         dumg(i,k)  = (qg(i,k)+qgtend(i,k)*deltat)/precip_frac(i,k)
    2867           0 :         dumng(i,k) = max((ng(i,k)+ngtend(i,k)*deltat)/precip_frac(i,k),0._r8)
    2868             : 
    2869             :         ! switch for specification of droplet and crystal number
    2870           0 :         if (ngcons) then
    2871           0 :            dumng(i,k)=ngnst/rho(i,k)
    2872             :         end if
    2873             : 
    2874             :         ! switch for specification of droplet and crystal number
    2875           0 :         if (nccons) then
    2876           0 :            dumnc(i,k)=ncnst/rho(i,k)
    2877             :         end if
    2878             : 
    2879             :         ! switch for specification of cloud ice number
    2880           0 :         if (nicons) then
    2881           0 :            dumni(i,k)=ninst/rho(i,k)
    2882             :         end if
    2883             : 
    2884             :         ! switch for specification of constant number        
    2885           0 :         if (nscons) then
    2886           0 :             dumns(i,k)=nsnst/rho(i,k)
    2887             :         end if
    2888             : 
    2889             :         ! switch for specification of constant number                
    2890           0 :         if (nrcons) then
    2891           0 :             dumnr(i,k)=nrnst/rho(i,k)
    2892             :         end if
    2893             :      end do
    2894             :   end do
    2895             :   !$acc end parallel
    2896             : 
    2897             :   ! obtain new slope parameter to avoid possible singularity
    2898           0 :   call size_dist_param_basic(mg_ice_props, dumi, dumni, lami, mgncol, nlev)
    2899           0 :   call size_dist_param_liq(mg_liq_props, dumc, dumnc, rho, pgam, lamc, mgncol, nlev)
    2900             : 
    2901             :   !$acc parallel vector_length(VLENS) default(present)
    2902             :   !$acc loop gang vector collapse(2) private(dum1,dum2,dum3,dum4)
    2903           0 :   do k=1,nlev
    2904           0 :      do i=1,mgncol
    2905             :         ! calculate number and mass weighted fall velocity for droplets and cloud ice
    2906             :         !-------------------------------------------------------------------
    2907           0 :         if (dumc(i,k).ge.qsmall) then
    2908           0 :            dum1 = 4._r8+bc+pgam(i,k)
    2909           0 :            dum2 = pgam(i,k)+4._r8
    2910           0 :            vtrmc(i,k)=acn(i,k)*gamma(dum1)/(lamc(i,k)**bc*gamma(dum2))
    2911             :            ! Following ifs, no condensate sedimentation
    2912           0 :            if (ifs_sed) then
    2913           0 :               fc(i,k)  = 0._r8
    2914           0 :               fnc(i,k) = 0._r8
    2915             :            else
    2916           0 :               dum3     = 1._r8+bc+pgam(i,k)
    2917           0 :               dum4     = pgam(i,k)+1._r8
    2918           0 :               fc(i,k)  = g*rho(i,k)*vtrmc(i,k)
    2919             :               fnc(i,k) = g*rho(i,k)* &
    2920             :                    acn(i,k)*gamma(dum3)/ &
    2921           0 :                    (lamc(i,k)**bc*gamma(dum4))
    2922             :            end if
    2923             :         else
    2924           0 :            fc(i,k) = 0._r8
    2925           0 :            fnc(i,k)= 0._r8
    2926             :         end if
    2927             :      end do
    2928             :   end do
    2929             : 
    2930             :   !$acc loop gang vector collapse(2) private(irad,ifrac)
    2931           0 :   do k=1,nlev
    2932           0 :      do i=1,mgncol        
    2933             :         ! calculate number and mass weighted fall velocity for cloud ice
    2934           0 :         if (dumi(i,k).ge.qsmall) then
    2935             :            vtrmi(i,k)=min(ain(i,k)*gamma_bi_plus4/(6._r8*lami(i,k)**bi), &
    2936           0 :                 1.2_r8*rhof(i,k))
    2937           0 :            vtrmi(i,k)=vtrmi(i,k)*micro_mg_vtrmi_factor
    2938             : 
    2939           0 :            fi(i,k) = g*rho(i,k)*vtrmi(i,k)
    2940             :            fni(i,k) = g*rho(i,k)* &
    2941           0 :                 min(ain(i,k)*gamma_bi_plus1/lami(i,k)**bi,1.2_r8*rhof(i,k))
    2942             : 
    2943             :            ! adjust the ice fall velocity for smaller (r < 20 um) ice
    2944             :            ! particles (blend over 8-20 um)
    2945           0 :            irad = 1.5_r8 / lami(i,k) * 1e6_r8
    2946           0 :            ifrac = min(1._r8, max(0._r8, (irad - 18._r8) / 2._r8))
    2947             :  
    2948           0 :            if (ifrac .lt. 1._r8) then
    2949             :               vtrmi(i,k) = ifrac * vtrmi(i,k) + & 
    2950             :                  (1._r8 - ifrac) * &
    2951             :                  min(ajn(i,k)*gamma_bj_plus4/(6._r8*lami(i,k)**bj), &
    2952           0 :                  1.2_r8*rhof(i,k))
    2953           0 :               vtrmi(i,k)=vtrmi(i,k)*micro_mg_vtrmi_factor     
    2954             : 
    2955           0 :               fi(i,k)  = g*rho(i,k)*vtrmi(i,k)
    2956             :               fni(i,k) = ifrac * fni(i,k) + & 
    2957             :                  (1._r8 - ifrac) * &
    2958             :                  g*rho(i,k)* &
    2959           0 :                  min(ajn(i,k)*gamma_bj_plus1/lami(i,k)**bj,1.2_r8*rhof(i,k))
    2960             :            end if
    2961             : 
    2962             :            ! Fix ice fall speed following IFS microphysics
    2963           0 :            if (ifs_sed) then
    2964           0 :               fi(i,k)=g*rho(i,k)*0.1_r8
    2965           0 :               fni(i,k)=g*rho(i,k)*0.1_r8
    2966             :            end if
    2967             :         else
    2968           0 :            fi(i,k) = 0._r8
    2969           0 :            fni(i,k)= 0._r8
    2970             :         end if
    2971             :      end do
    2972             :   end do
    2973             :   !$acc end parallel
    2974             : 
    2975             :   ! fallspeed for rain
    2976           0 :   call size_dist_param_basic(mg_rain_props, dumr, dumnr, lamr, mgncol, nlev)
    2977             :   ! fallspeed for snow
    2978           0 :   call size_dist_param_basic(mg_snow_props, dums, dumns, lams, mgncol, nlev)
    2979             :   ! fallspeed for graupel
    2980           0 :   if (do_hail) then
    2981           0 :      call size_dist_param_basic(mg_hail_props, dumg, dumng, lamg, mgncol, nlev)
    2982             :   end if
    2983           0 :   if (do_graupel) then
    2984           0 :      call size_dist_param_basic(mg_graupel_props, dumg, dumng, lamg, mgncol, nlev)
    2985             :   end if
    2986             : 
    2987             :   !$acc parallel vector_length(VLENS) default(present)
    2988             :   !$acc loop gang vector collapse(2) private(qtmp)
    2989           0 :   do k=1,nlev
    2990           0 :      do i=1,mgncol
    2991           0 :         if (lamr(i,k).ge.qsmall) then
    2992           0 :            qtmp = lamr(i,k)**br
    2993             :            ! 'final' values of number and mass weighted mean fallspeed for rain (m/s)
    2994           0 :            unr(i,k) = min(arn(i,k)*gamma_br_plus1/qtmp,9.1_r8*rhof(i,k))
    2995           0 :            fnr(i,k) = g*rho(i,k)*unr(i,k)
    2996           0 :            umr(i,k) = min(arn(i,k)*gamma_br_plus4/(6._r8*qtmp),9.1_r8*rhof(i,k))
    2997           0 :            fr(i,k) = g*rho(i,k)*umr(i,k)
    2998             :         else
    2999           0 :            fr(i,k)=0._r8
    3000           0 :            fnr(i,k)=0._r8
    3001             :         end if
    3002             : 
    3003             :         ! Fallspeed correction to ensure non-zero if rain in the column
    3004             :         ! from updated Morrison (WRFv3.3) and P3 schemes
    3005             :         ! If fallspeed exists at a higher level, apply it below to eliminate    
    3006           0 :         if (precip_fall_corr) then 
    3007           0 :            if (k.gt.2) then
    3008           0 :               if (fr(i,k).lt.1.e-10_r8) then
    3009           0 :                  fr(i,k)=fr(i,k-1)
    3010           0 :                  fnr(i,k)=fnr(i,k-1)
    3011             :               end if
    3012             :            end if
    3013             :         end if
    3014             : 
    3015           0 :         if (lams(i,k).ge.qsmall) then
    3016           0 :            qtmp = lams(i,k)**bs
    3017             :            ! 'final' values of number and mass weighted mean fallspeed for snow (m/s)
    3018           0 :            ums(i,k) = min(asn(i,k)*gamma_bs_plus4/(6._r8*qtmp),1.2_r8*rhof(i,k))
    3019           0 :            ums(:,k)=ums(:,k)*micro_mg_vtrmi_factor       
    3020             : 
    3021           0 :            fs(i,k)  = g*rho(i,k)*ums(i,k)
    3022           0 :            uns(i,k) = min(asn(i,k)*gamma_bs_plus1/qtmp,1.2_r8*rhof(i,k))
    3023           0 :            fns(i,k) = g*rho(i,k)*uns(i,k)
    3024             :            ! Fix fallspeed for snow
    3025           0 :            if (ifs_sed) then
    3026           0 :               ums(i,k) = 1._r8
    3027           0 :               uns(i,k) = 1._r8
    3028             :             end if
    3029             :         else
    3030           0 :            fs(i,k)=0._r8
    3031           0 :            fns(i,k)=0._r8
    3032             :         end if
    3033             : 
    3034           0 :         if (precip_fall_corr) then
    3035           0 :            if (k.gt.2) then
    3036           0 :               if (fs(i,k).lt.1.e-10_r8) then
    3037           0 :                  fs(i,k)=fs(i,k-1)
    3038           0 :                  fns(i,k)=fns(i,k-1)
    3039             :               end if
    3040             :            end if
    3041             :         end if
    3042             : 
    3043           0 :         if (lamg(i,k).ge.qsmall) then
    3044           0 :            qtmp = lamg(i,k)**bgtmp
    3045             :            ! 'final' values of number and mass weighted mean fallspeed for graupel (m/s)
    3046           0 :            umg(i,k) = min(agn(i,k)*gamma_bg_plus4/(6._r8*qtmp),20._r8*rhof(i,k))
    3047           0 :            fg(i,k) = g*rho(i,k)*umg(i,k)
    3048           0 :            ung(i,k) = min(agn(i,k)*gamma_bg_plus1/qtmp,20._r8*rhof(i,k))
    3049           0 :            fng(i,k) = g*rho(i,k)*ung(i,k)
    3050             :         else
    3051           0 :            fg(i,k)=0._r8
    3052           0 :            fng(i,k)=0._r8
    3053             :         end if
    3054             : 
    3055           0 :         if (precip_fall_corr) then
    3056           0 :            if (k.gt.2) then
    3057           0 :               if (fg(i,k).lt.1.e-10_r8) then
    3058           0 :                  fg(i,k)=fg(i,k-1)
    3059           0 :                  fng(i,k)=fng(i,k-1)
    3060             :               end if
    3061             :            end if
    3062             :         end if
    3063           0 :         pdel_inv(i,k) = 1._r8/pdel(i,k)
    3064             :      end do
    3065             :   end do
    3066             : 
    3067             :   !$acc loop gang vector collapse(2)
    3068           0 :   do k=1,nlev
    3069           0 :      do i=1,mgncol
    3070             :         ! redefine dummy variables - sedimentation is calculated over grid-scale
    3071             :         ! quantities to ensure conservation
    3072           0 :         dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat)
    3073           0 :         dumnc(i,k) = max((nc(i,k)+nctend(i,k)*deltat),0._r8)
    3074           0 :         dumi(i,k) = (qi(i,k)+qitend(i,k)*deltat)
    3075           0 :         dumni(i,k) = max((ni(i,k)+nitend(i,k)*deltat),0._r8)
    3076           0 :         dumr(i,k) = (qr(i,k)+qrtend(i,k)*deltat)
    3077           0 :         dumnr(i,k) = max((nr(i,k)+nrtend(i,k)*deltat),0._r8)
    3078           0 :         dums(i,k) = (qs(i,k)+qstend(i,k)*deltat)
    3079           0 :         dumns(i,k) = max((ns(i,k)+nstend(i,k)*deltat),0._r8)
    3080           0 :         dumg(i,k) = (qg(i,k)+qgtend(i,k)*deltat)
    3081           0 :         dumng(i,k) = max((ng(i,k)+ngtend(i,k)*deltat),0._r8)
    3082           0 :         if (dumc(i,k).lt.qsmall) dumnc(i,k)=0._r8
    3083           0 :         if (dumi(i,k).lt.qsmall) dumni(i,k)=0._r8
    3084           0 :         if (dumr(i,k).lt.qsmall) dumnr(i,k)=0._r8
    3085           0 :         if (dums(i,k).lt.qsmall) dumns(i,k)=0._r8
    3086           0 :         if (dumg(i,k).lt.qsmall) dumng(i,k)=0._r8
    3087             :      end do
    3088             :   end do
    3089             :   !$acc end parallel
    3090             : 
    3091             :   ! begin sedimentation
    3092             :   ! ice
    3093             :   call Sedimentation(mgncol,nlev,do_cldice,deltat,fi,fni,pdel_inv, &
    3094             :                        qitend,nitend,qisedten,dumi,dumni,prect,iflx, &
    3095             :                        xxlx=xxls,qxsevap=qisevap,tlat=tlat,qvlat=qvlat, &
    3096           0 :                        xcldm=icldm,preci=preci)
    3097             :   ! liq
    3098             :   call Sedimentation(mgncol,nlev,.TRUE.,deltat,fc,fnc,pdel_inv, &
    3099             :                        qctend,nctend,qcsedten,dumc,dumnc,prect,lflx, &
    3100           0 :                        xxlx=xxlv,qxsevap=qcsevap,tlat=tlat,qvlat=qvlat,xcldm=lcldm)
    3101             :   ! rain
    3102             :   call Sedimentation(mgncol,nlev,.TRUE.,deltat,fr,fnr,pdel_inv, &
    3103           0 :                        qrtend,nrtend,qrsedten,dumr,dumnr,prect,rflx)
    3104             :   ! snow
    3105             :   call Sedimentation(mgncol,nlev,.TRUE.,deltat,fs,fns,pdel_inv, &
    3106           0 :                        qstend,nstend,qssedten,dums,dumns,prect,sflx,preci=preci)
    3107             :   ! graupel
    3108             :   call Sedimentation(mgncol,nlev,.TRUE.,deltat,fg,fng,pdel_inv, &
    3109           0 :                        qgtend,ngtend,qgsedten,dumg,dumng,prect,gflx,preci=preci)
    3110             :   ! end sedimentation
    3111             : 
    3112             :   !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    3113             : 
    3114             :   ! get new update for variables that includes sedimentation tendency
    3115             :   ! note : here dum variables are grid-average, NOT in-cloud
    3116             : 
    3117             :   !$acc parallel vector_length(VLENS) default(present)
    3118             :   !$acc loop gang vector collapse(2)
    3119           0 :   do k=1,nlev
    3120           0 :      do i=1,mgncol
    3121           0 :         dumc(i,k)  = max(qc(i,k)+qctend(i,k)*deltat,0._r8)
    3122           0 :         dumi(i,k)  = max(qi(i,k)+qitend(i,k)*deltat,0._r8)
    3123           0 :         dumnc(i,k) = max(nc(i,k)+nctend(i,k)*deltat,0._r8)
    3124           0 :         dumni(i,k) = max(ni(i,k)+nitend(i,k)*deltat,0._r8)
    3125             : 
    3126           0 :         dumr(i,k)  = max(qr(i,k)+qrtend(i,k)*deltat,0._r8)
    3127           0 :         dumnr(i,k) = max(nr(i,k)+nrtend(i,k)*deltat,0._r8)
    3128           0 :         dums(i,k)  = max(qs(i,k)+qstend(i,k)*deltat,0._r8)
    3129           0 :         dumns(i,k) = max(ns(i,k)+nstend(i,k)*deltat,0._r8)
    3130           0 :         dumg(i,k)  = max(qg(i,k)+qgtend(i,k)*deltat,0._r8)
    3131           0 :         dumng(i,k) = max(ng(i,k)+ngtend(i,k)*deltat,0._r8)
    3132             : 
    3133             :         ! switch for specification of droplet and crystal number
    3134           0 :         if (nccons) then
    3135           0 :            dumnc(i,k)=ncnst/rho(i,k)*lcldm(i,k)
    3136             :         end if
    3137             : 
    3138             :         ! switch for specification of cloud ice number
    3139           0 :         if (nicons) then
    3140           0 :            dumni(i,k)=ninst/rho(i,k)*icldm(i,k)
    3141             :         end if
    3142             :         
    3143             :         ! switch for specification of graupel number
    3144           0 :         if (ngcons) then
    3145           0 :            dumng(i,k)=ngnst/rho(i,k)*precip_frac(i,k)
    3146             :         end if
    3147             : 
    3148             :         ! switch for specification of constant snow number                 
    3149           0 :         if (nscons) then
    3150           0 :             dumns(i,k)=nsnst/rho(i,k)
    3151             :         end if
    3152             : 
    3153             :         ! switch for specification of constant rain number         
    3154           0 :         if (nrcons) then
    3155           0 :             dumnr(i,k)=nrnst/rho(i,k)
    3156             :         end if
    3157             : 
    3158           0 :         if (dumc(i,k).lt.qsmall) dumnc(i,k)=0._r8
    3159           0 :         if (dumi(i,k).lt.qsmall) dumni(i,k)=0._r8
    3160           0 :         if (dumr(i,k).lt.qsmall) dumnr(i,k)=0._r8
    3161           0 :         if (dums(i,k).lt.qsmall) dumns(i,k)=0._r8
    3162           0 :         if (dumg(i,k).lt.qsmall) dumng(i,k)=0._r8
    3163             :      end do
    3164             :   end do
    3165             : 
    3166             :   ! calculate instantaneous processes (melting, homogeneous freezing)
    3167             :   !====================================================================
    3168             :   ! melting of snow at +2 C
    3169             : 
    3170             :   !$acc loop gang vector collapse(2) private(dum,dum1)
    3171           0 :   do k=1,nlev
    3172           0 :      do i=1,mgncol
    3173           0 :         if (t(i,k)+tlat(i,k)/cpp*deltat > snowmelt) then
    3174           0 :            if (dums(i,k) > 0._r8) then
    3175             :               ! make sure melting snow doesn't reduce temperature below threshold
    3176           0 :               dum = -xlf/cpp*dums(i,k)
    3177           0 :               if (t(i,k)+tlat(i,k)/cpp*deltat+dum.lt. snowmelt) then
    3178           0 :                  dum = (t(i,k)+tlat(i,k)/cpp*deltat-snowmelt)*cpp/xlf
    3179           0 :                  dum = dum/dums(i,k)
    3180           0 :                  dum = max(0._r8,dum)
    3181           0 :                  dum = min(1._r8,dum)
    3182             :               else
    3183             :                  dum = 1._r8
    3184             :               end if
    3185             : 
    3186           0 :               qstend(i,k)=qstend(i,k)-dum*dums(i,k)*rdeltat
    3187           0 :               nstend(i,k)=nstend(i,k)-dum*dumns(i,k)*rdeltat
    3188           0 :               qrtend(i,k)=qrtend(i,k)+dum*dums(i,k)*rdeltat
    3189           0 :               nrtend(i,k)=nrtend(i,k)+dum*dumns(i,k)*rdeltat
    3190             : 
    3191           0 :               dum1=-xlf*dum*dums(i,k)*rdeltat
    3192           0 :               tlat(i,k)=tlat(i,k)+dum1
    3193           0 :               meltsdttot(i,k)=meltsdttot(i,k) + dum1
    3194             : 
    3195             : !STOPPED FIX FOR SNOW NUMBER
    3196             : !ensure that snow... number does not go negative with constant number set
    3197             : !necessary because dumng is updated above.                               
    3198           0 :               if (nscons .and. ((ns(i,k)+nstend(i,k)*deltat) .lt. 0._r8)) then
    3199           0 :                  nstend(i,k)=-ns(i,k)*rdeltat
    3200             :               end if
    3201             :            end if
    3202             :         end if
    3203             :      end do
    3204             :   end do
    3205             : 
    3206             :   ! melting of graupel at +2 C
    3207             : 
    3208             :   !$acc loop gang vector collapse(2) private(dum,dum1)
    3209           0 :   do k=1,nlev
    3210           0 :      do i=1,mgncol
    3211           0 :         if (t(i,k)+tlat(i,k)/cpp*deltat > snowmelt) then
    3212           0 :            if (dumg(i,k) > 0._r8) then
    3213             :               ! make sure melting graupel doesn't reduce temperature below threshold
    3214           0 :               dum = -xlf/cpp*dumg(i,k)
    3215           0 :               if (t(i,k)+tlat(i,k)/cpp*deltat+dum .lt. snowmelt) then
    3216           0 :                  dum = (t(i,k)+tlat(i,k)/cpp*deltat-snowmelt)*cpp/xlf
    3217           0 :                  dum = dum/dumg(i,k)
    3218           0 :                  dum = max(0._r8,dum)
    3219           0 :                  dum = min(1._r8,dum)
    3220             :               else
    3221             :                  dum = 1._r8
    3222             :               end if
    3223             : 
    3224           0 :               qgtend(i,k)=qgtend(i,k)-dum*dumg(i,k)*rdeltat
    3225           0 :               ngtend(i,k)=ngtend(i,k)-dum*dumng(i,k)*rdeltat
    3226           0 :               qrtend(i,k)=qrtend(i,k)+dum*dumg(i,k)*rdeltat
    3227           0 :               nrtend(i,k)=nrtend(i,k)+dum*dumng(i,k)*rdeltat
    3228             : 
    3229           0 :               dum1=-xlf*dum*dumg(i,k)*rdeltat
    3230           0 :               tlat(i,k)=tlat(i,k)+dum1
    3231           0 :               meltsdttot(i,k)=meltsdttot(i,k) + dum1
    3232             : 
    3233             : !ensure that graupel number does not go negative with constant number set
    3234             : !necessary because dumng is updated above.                               
    3235           0 :               if (ngcons .and. ((ng(i,k)+ngtend(i,k)*deltat) .lt. 0._r8)) then
    3236           0 :                  ngtend(i,k)=-ng(i,k)*rdeltat
    3237             :               end if
    3238             :            end if
    3239             :         end if
    3240             :      end do
    3241             :   end do
    3242             :   !$acc end parallel
    3243             : 
    3244             :   ! get mean size of rain = 1/lamr, add frozen rain to either snow or cloud ice
    3245             :   ! depending on mean rain size
    3246             :   ! add to graupel if using that option....
    3247           0 :   call size_dist_param_basic(mg_rain_props, dumr, dumnr, lamr, mgncol, nlev)
    3248             : 
    3249             :   !$acc parallel vector_length(VLENS) default(present)
    3250             :   !$acc loop gang vector collapse(2) private(dum,dum1)
    3251           0 :   do k=1,nlev
    3252           0 :      do i=1,mgncol
    3253             :         ! freezing of rain at -5 C
    3254           0 :         if (t(i,k)+tlat(i,k)/cpp*deltat < rainfrze) then
    3255           0 :            if (dumr(i,k) > 0._r8) then
    3256             :               ! make sure freezing rain doesn't increase temperature above threshold
    3257           0 :               dum = xlf/cpp*dumr(i,k)
    3258           0 :               if (t(i,k)+tlat(i,k)/cpp*deltat+dum.gt.rainfrze) then
    3259           0 :                  dum = -(t(i,k)+tlat(i,k)/cpp*deltat-rainfrze)*cpp/xlf
    3260           0 :                  dum = dum/dumr(i,k)
    3261           0 :                  dum = max(0._r8,dum)
    3262           0 :                  dum = min(1._r8,dum)
    3263             :               else
    3264             :                  dum = 1._r8
    3265             :               end if
    3266             : 
    3267           0 :               qrtend(i,k)=qrtend(i,k)-dum*dumr(i,k)*rdeltat
    3268           0 :               nrtend(i,k)=nrtend(i,k)-dum*dumnr(i,k)*rdeltat
    3269             : 
    3270           0 :               if (lamr(i,k) < 1._r8/Dcs) then
    3271           0 :                  if (do_hail.or.do_graupel) then
    3272           0 :                     qgtend(i,k)=qgtend(i,k)+dum*dumr(i,k)*rdeltat
    3273           0 :                     ngtend(i,k)=ngtend(i,k)+dum*dumnr(i,k)*rdeltat
    3274             :                  else
    3275           0 :                     qstend(i,k)=qstend(i,k)+dum*dumr(i,k)*rdeltat
    3276           0 :                     nstend(i,k)=nstend(i,k)+dum*dumnr(i,k)*rdeltat
    3277             :                  end if
    3278             :               else
    3279           0 :                  qitend(i,k)=qitend(i,k)+dum*dumr(i,k)*rdeltat
    3280           0 :                  nitend(i,k)=nitend(i,k)+dum*dumnr(i,k)*rdeltat
    3281             :               end if
    3282             : 
    3283             :               ! heating tendency
    3284           0 :               dum1 = xlf*dum*dumr(i,k)*rdeltat
    3285           0 :               frzrdttot(i,k)=frzrdttot(i,k) + dum1
    3286           0 :               tlat(i,k)=tlat(i,k)+dum1
    3287             :            end if
    3288             :         end if
    3289             :       end do
    3290             :    end do
    3291             :    !$acc end parallel
    3292             : 
    3293           0 :    if (do_cldice) then
    3294             :       !$acc parallel vector_length(VLENS) default(present)
    3295             :       !$acc loop gang vector collapse(2) private(dum)
    3296           0 :       do k=1,nlev
    3297           0 :         do i=1,mgncol
    3298           0 :            if (t(i,k)+tlat(i,k)/cpp*deltat > tmelt) then
    3299           0 :               if (dumi(i,k) > 0._r8) then
    3300             :                  ! limit so that melting does not push temperature below freezing
    3301             :                  !-----------------------------------------------------------------
    3302           0 :                  dum = -dumi(i,k)*xlf/cpp
    3303           0 :                  if (t(i,k)+tlat(i,k)/cpp*deltat+dum.lt.tmelt) then
    3304           0 :                     dum = (t(i,k)+tlat(i,k)/cpp*deltat-tmelt)*cpp/xlf
    3305           0 :                     dum = dum/dumi(i,k)
    3306           0 :                     dum = max(0._r8,dum)
    3307           0 :                     dum = min(1._r8,dum)
    3308             :                  else
    3309             :                     dum = 1._r8
    3310             :                  end if
    3311             : 
    3312           0 :                  qctend(i,k)=qctend(i,k)+dum*dumi(i,k)*rdeltat
    3313             : 
    3314             :                  ! for output
    3315           0 :                  melttot(i,k)=dum*dumi(i,k)*rdeltat
    3316             : 
    3317             :                  ! assume melting ice produces droplet
    3318             :                  ! mean volume radius of 8 micron
    3319             :                  nctend(i,k)=nctend(i,k)+3._r8*dum*dumi(i,k)*rdeltat/ &
    3320           0 :                       (4._r8*pi*5.12e-16_r8*rhow)
    3321             : 
    3322           0 :                  qitend(i,k)=((1._r8-dum)*dumi(i,k)-qi(i,k))*rdeltat
    3323           0 :                  nitend(i,k)=((1._r8-dum)*dumni(i,k)-ni(i,k))*rdeltat
    3324           0 :                  tlat(i,k)=tlat(i,k)-xlf*dum*dumi(i,k)*rdeltat
    3325             :               end if
    3326             :            end if
    3327             :         end do
    3328             :      end do
    3329             : 
    3330             :      ! homogeneously freeze droplets at -40 C
    3331             :      !-----------------------------------------------------------------
    3332             : 
    3333             :      !$acc loop gang vector collapse(2) private(dum)
    3334           0 :      do k=1,nlev
    3335           0 :         do i=1,mgncol
    3336           0 :            if (t(i,k)+tlat(i,k)/cpp*deltat < 233.15_r8) then
    3337           0 :               if (dumc(i,k) > 0._r8) then
    3338             :                  ! limit so that freezing does not push temperature above threshold
    3339           0 :                  dum = dumc(i,k)*xlf/cpp
    3340           0 :                  if (t(i,k)+tlat(i,k)/cpp*deltat+dum.gt.233.15_r8) then
    3341           0 :                     dum = -(t(i,k)+tlat(i,k)/cpp*deltat-233.15_r8)*cpp/xlf
    3342           0 :                     dum = dum/dumc(i,k)
    3343           0 :                     dum = max(0._r8,dum)
    3344           0 :                     dum = min(1._r8,dum)
    3345             :                  else
    3346             :                     dum = 1._r8
    3347             :                  end if
    3348             : 
    3349           0 :                  qitend(i,k)=qitend(i,k)+dum*dumc(i,k)*rdeltat
    3350             :                  ! for output
    3351           0 :                  homotot(i,k)=dum*dumc(i,k)*rdeltat
    3352             : 
    3353             :                  ! assume 25 micron mean volume radius of homogeneously frozen droplets
    3354             :                  ! consistent with size of detrained ice in stratiform.F90
    3355           0 :                  nitend(i,k)=nitend(i,k)+dum*3._r8*dumc(i,k)/(4._r8*3.14_r8*micro_mg_homog_size**3._r8*500._r8)*rdeltat
    3356             : 
    3357           0 :                  qctend(i,k)=((1._r8-dum)*dumc(i,k)-qc(i,k))*rdeltat
    3358           0 :                  nctend(i,k)=((1._r8-dum)*dumnc(i,k)-nc(i,k))*rdeltat
    3359           0 :                  tlat(i,k)=tlat(i,k)+xlf*dum*dumc(i,k)*rdeltat
    3360             :               end if
    3361             :            end if
    3362             :         end do 
    3363             :      end do 
    3364             : 
    3365             :      ! ice number limiter                      
    3366           0 :      do k=1,nlev
    3367           0 :         do i=1,mgncol
    3368           0 :             if (do_cldice .and. nitend(i,k).gt.0._r8.and.ni(i,k)+nitend(i,k)*deltat.gt.micro_mg_max_nicons/rho(i,k)) then
    3369           0 :                nitend(i,k)=max(0._r8,(micro_mg_max_nicons/rho(i,k)-ni(i,k))/deltat)
    3370             :             end if
    3371             :         end do
    3372             :      end do
    3373             : 
    3374             :      ! remove any excess over-saturation, which is possible due to non-linearity when adding
    3375             :      ! together all microphysical processes
    3376             :      !-----------------------------------------------------------------
    3377             :      ! follow code similar to old CAM scheme
    3378             : 
    3379             :      !$acc loop gang vector collapse(2)
    3380           0 :      do k=1,nlev
    3381           0 :         do i=1,mgncol
    3382           0 :            dum_2D(i,k)=q(i,k)+qvlat(i,k)*deltat
    3383           0 :            ttmpA(i,k)=t(i,k)+tlat(i,k)/cpp*deltat
    3384             :         end do
    3385             :      end do
    3386             :      !$acc end parallel
    3387             : 
    3388             :      ! use rhw to allow ice supersaturation
    3389           0 :      call qsat_water(ttmpA, p, esnA, qvnA, mgncol*nlev)
    3390             : 
    3391             :      !$acc parallel vector_length(VLENS) default(present)
    3392             :      !$acc loop gang vector collapse(2) private(dum,dum1)
    3393           0 :      do k=1,nlev
    3394           0 :         do i=1,mgncol
    3395           0 :            if (dum_2D(i,k) > qvnA(i,k) .and. qvnA(i,k) > 0 .and. remove_supersat) then
    3396             :               ! expression below is approximate since there may be ice deposition
    3397           0 :               dum = (dum_2D(i,k)-qvnA(i,k))/(1._r8+xxlv_squared*qvnA(i,k)/(cpp*rv*ttmpA(i,k)**2))*rdeltat
    3398             :               ! add to output cme
    3399           0 :               cmeout(i,k) = cmeout(i,k)+dum
    3400             :               ! now add to tendencies, partition between liquid and ice based on temperature
    3401           0 :               if (ttmpA(i,k) > 268.15_r8) then
    3402           0 :                  dum1=0.0_r8
    3403             :                  ! now add to tendencies, partition between liquid and ice based on te
    3404             :                  !-------------------------------------------------------
    3405           0 :               else if (ttmpA(i,k) < 238.15_r8) then
    3406           0 :                  dum1=1.0_r8
    3407             :               else
    3408           0 :                  dum1=(268.15_r8-ttmpA(i,k))/30._r8
    3409             :               end if
    3410             :               dum = (dum_2D(i,k)-qvnA(i,k))/(1._r8+(xxls*dum1+xxlv*(1._r8-dum1))**2 &
    3411           0 :                     *qvnA(i,k)/(cpp*rv*ttmpA(i,k)**2))*rdeltat
    3412           0 :               qctend(i,k)=qctend(i,k)+dum*(1._r8-dum1)
    3413             :               ! for output
    3414           0 :               qcrestot(i,k)=dum*(1._r8-dum1)
    3415           0 :               qitend(i,k)=qitend(i,k)+dum*dum1
    3416           0 :               qirestot(i,k)=dum*dum1
    3417           0 :               qvlat(i,k)=qvlat(i,k)-dum
    3418             :               ! for output
    3419           0 :               qvres(i,k)=-dum
    3420           0 :               tlat(i,k)=tlat(i,k)+dum*(1._r8-dum1)*xxlv+dum*dum1*xxls
    3421             :            end if
    3422             :         end do 
    3423             :      end do 
    3424             :      !$acc end parallel
    3425             :   end if
    3426             : 
    3427             :   ! calculate effective radius for pass to radiation code
    3428             :   !=========================================================
    3429             :   ! if no cloud water, default value is 10 micron for droplets,
    3430             :   ! 25 micron for cloud ice
    3431             : 
    3432             :   ! update cloud variables after instantaneous processes to get effective radius
    3433             :   ! variables are in-cloud to calculate size dist parameters
    3434             : 
    3435             :   !$acc parallel vector_length(VLENS) default(present)
    3436             :   !$acc loop gang vector collapse(2)
    3437           0 :   do k=1,nlev
    3438           0 :      do i=1,mgncol
    3439           0 :         dumc(i,k) = max(qc(i,k)+qctend(i,k)*deltat,0._r8)/lcldm(i,k)
    3440           0 :         dumi(i,k) = max(qi(i,k)+qitend(i,k)*deltat,0._r8)/icldm(i,k)
    3441           0 :         dumnc(i,k) = max(nc(i,k)+nctend(i,k)*deltat,0._r8)/lcldm(i,k)
    3442           0 :         dumni(i,k) = max(ni(i,k)+nitend(i,k)*deltat,0._r8)/icldm(i,k)
    3443             : 
    3444           0 :         dumr(i,k) = max(qr(i,k)+qrtend(i,k)*deltat,0._r8)/precip_frac(i,k)
    3445           0 :         dumnr(i,k) = max(nr(i,k)+nrtend(i,k)*deltat,0._r8)/precip_frac(i,k)
    3446           0 :         dums(i,k) = max(qs(i,k)+qstend(i,k)*deltat,0._r8)/precip_frac(i,k)
    3447           0 :         dumns(i,k) = max(ns(i,k)+nstend(i,k)*deltat,0._r8)/precip_frac(i,k)
    3448           0 :         dumg(i,k) = max(qg(i,k)+qgtend(i,k)*deltat,0._r8)
    3449           0 :         dumng(i,k) = max(ng(i,k)+ngtend(i,k)*deltat,0._r8)
    3450             : 
    3451             :         ! switch for specification of droplet and crystal number
    3452           0 :         if (nccons) then
    3453           0 :            dumnc(i,k)=ncnst/rho(i,k)
    3454             :         end if
    3455             : 
    3456             :         ! switch for specification of cloud ice number
    3457           0 :         if (nicons) then
    3458           0 :            dumni(i,k)=ninst/rho(i,k)
    3459             :         end if
    3460             : 
    3461             :         ! switch for specification of graupel number
    3462           0 :         if (ngcons) then
    3463           0 :            dumng(i,k)=ngnst/rho(i,k)*precip_frac(i,k)
    3464             :         end if
    3465             : 
    3466             :         ! switch for specification of constant snow number    
    3467           0 :         if (nscons) then
    3468           0 :             dumns(i,k)=nsnst/rho(i,k)
    3469             :         end if   
    3470             : 
    3471             :         ! switch for specification of constant rain number 
    3472           0 :         if (nrcons) then
    3473           0 :             dumnr(i,k)=nrnst/rho(i,k)
    3474             :         end if
    3475             : 
    3476             :         ! limit in-cloud mixing ratio to reasonable value of 5 g kg-1
    3477           0 :         dumc(i,k)=min(dumc(i,k),5.e-3_r8)
    3478           0 :         dumi(i,k)=min(dumi(i,k),5.e-3_r8)
    3479             :         ! limit in-precip mixing ratios
    3480           0 :         dumr(i,k)=min(dumr(i,k),10.e-3_r8)
    3481           0 :         dums(i,k)=min(dums(i,k),10.e-3_r8)
    3482           0 :         dumg(i,k)=min(dumg(i,k),10.e-3_r8)
    3483             :      end do
    3484             :   end do
    3485             :   !$acc end parallel
    3486             : 
    3487             :   ! cloud ice effective radius
    3488             :   !-----------------------------------------------------------------
    3489           0 :   if (do_cldice) then
    3490             :      !$acc parallel vector_length(VLENS) default(present)
    3491             :      !$acc loop gang vector collapse(2)
    3492           0 :      do k=1,nlev
    3493           0 :         do i=1,mgncol
    3494           0 :            dum_2D(i,k) = dumni(i,k)
    3495             :         end do
    3496             :      end do
    3497             :      !$acc end parallel
    3498             : 
    3499           0 :      call size_dist_param_basic(mg_ice_props, dumi, dumni, lami, mgncol, nlev, n0=dumni0A2D)
    3500             : 
    3501             :      !$acc parallel vector_length(VLENS) default(present)
    3502             :      !$acc loop gang vector collapse(2)
    3503           0 :      do k=1,nlev
    3504           0 :         do i=1,mgncol
    3505           0 :            if (dumi(i,k).ge.qsmall) then
    3506           0 :               if (dumni(i,k) /=dum_2D(i,k)) then
    3507             :                  ! adjust number conc if needed to keep mean size in reasonable range
    3508           0 :                  nitend(i,k)=(dumni(i,k)*icldm(i,k)-ni(i,k))*rdeltat
    3509             :               end if
    3510           0 :               effi(i,k)   = 1.5_r8/lami(i,k)*1.e6_r8
    3511           0 :               effi(i,k) = effi(i,k)*micro_mg_effi_factor      
    3512             : 
    3513           0 :               sadice(i,k) = 2._r8*pi*(lami(i,k)**(-3))*dumni0A2D(i,k)*rho(i,k)*1.e-2_r8  ! m2/m3 -> cm2/cm3
    3514             :            else
    3515           0 :               effi(i,k)   = 25._r8
    3516           0 :               effi(i,k) = effi(i,k)*micro_mg_effi_factor      
    3517             : 
    3518           0 :               sadice(i,k) = 0._r8
    3519             :            end if
    3520             :            ! ice effective diameter for david mitchell's optics
    3521           0 :            deffi(i,k)=effi(i,k)*rhoi/rhows*2._r8
    3522             :         end do
    3523             :      end do
    3524             :      !$acc end parallel
    3525             :   else
    3526             :      !$acc parallel vector_length(VLENS) default(present)
    3527             :      !acc loop gang vector collapse(2)
    3528           0 :      do k=1,nlev
    3529           0 :         do i=1,mgncol
    3530             :            ! NOTE: If CARMA is doing the ice microphysics, then the ice effective
    3531             :            ! radius has already been determined from the size distribution.
    3532           0 :            effi(i,k)   = re_ice(i,k) * 1.e6_r8      ! m -> um
    3533           0 :            effi(i,k) = effi(i,k)*micro_mg_effi_factor      
    3534             : 
    3535           0 :            deffi(i,k)  = effi(i,k) * 2._r8
    3536           0 :            sadice(i,k) = 4._r8*pi*(effi(i,k)**2)*ni(i,k)*rho(i,k)*1e-2_r8
    3537             :         end do
    3538             :      end do
    3539             :      !$acc end parallel
    3540             :   end if
    3541             : 
    3542             :   ! cloud droplet effective radius
    3543             :   !-----------------------------------------------------------------
    3544             : 
    3545             :   !$acc parallel vector_length(VLENS) default(present)
    3546             :   !$acc loop gang vector collapse(2)
    3547           0 :   do k=1,nlev
    3548           0 :      do i=1,mgncol
    3549           0 :         dum_2D(i,k) = dumnc(i,k)
    3550             :      end do
    3551             :   end do
    3552             :   !$acc end parallel
    3553             : 
    3554           0 :   call size_dist_param_liq(mg_liq_props, dumc, dumnc, rho, pgam, lamc, mgncol, nlev)
    3555             : 
    3556             :   !$acc parallel vector_length(VLENS) default(present)
    3557             :   !$acc loop gang vector collapse(2)
    3558           0 :   do k=1,nlev
    3559           0 :      do i=1,mgncol
    3560           0 :         if (dumc(i,k).ge.qsmall) then
    3561             :            ! switch for specification of droplet and crystal number
    3562           0 :            if (nccons) then
    3563             :               ! make sure nc is consistence with the constant N by adjusting tendency, need
    3564             :               ! to multiply by cloud fraction
    3565             :               ! note that nctend may be further adjusted below if mean droplet size is
    3566             :               ! out of bounds
    3567           0 :               nctend(i,k)=(ncnst/rho(i,k)*lcldm(i,k)-nc(i,k))*rdeltat
    3568             :            end if
    3569           0 :            if (dum_2D(i,k) /= dumnc(i,k)) then
    3570             :               ! adjust number conc if needed to keep mean size in reasonable range
    3571           0 :               nctend(i,k)=(dumnc(i,k)*lcldm(i,k)-nc(i,k))*rdeltat
    3572             :            end if
    3573             : 
    3574           0 :            effc(i,k) = (pgam(i,k)+3._r8)/lamc(i,k)/2._r8*1.e6_r8
    3575             :            !assign output fields for shape here
    3576           0 :            lamcrad(i,k)=lamc(i,k)
    3577           0 :            pgamrad(i,k)=pgam(i,k)
    3578             : 
    3579             :            ! recalculate effective radius for constant number, in order to separate
    3580             :            ! first and second indirect effects
    3581             :            !======================================
    3582             :            ! assume constant number of 10^8 kg-1
    3583           0 :            dumnc(i,k)=1.e8_r8
    3584             :         end if
    3585             :      end do
    3586             :   end do
    3587             :   !$acc end parallel
    3588             : 
    3589             :   ! Pass in "false" adjust flag to prevent number from being changed within
    3590             :   ! size distribution subroutine.
    3591           0 :   call size_dist_param_liq(mg_liq_props, dumc, dumnc, rho, pgam, lamc, mgncol, nlev)
    3592             : 
    3593             :   !$acc parallel vector_length(VLENS) default(present)
    3594             :   !$acc loop gang vector collapse(2)
    3595           0 :   do k =1,nlev
    3596           0 :      do i=1,mgncol
    3597           0 :         if (dumc(i,k).ge.qsmall) then
    3598           0 :            effc_fn(i,k) = (pgam(i,k)+3._r8)/lamc(i,k)/2._r8*1.e6_r8
    3599             :         else
    3600           0 :            effc(i,k) = 10._r8
    3601           0 :            lamcrad(i,k)=0._r8
    3602           0 :            pgamrad(i,k)=0._r8
    3603           0 :            effc_fn(i,k) = 10._r8
    3604             :         end if
    3605             :      end do
    3606             :   end do
    3607             : 
    3608             :   ! recalculate 'final' rain size distribution parameters
    3609             :   ! to ensure that rain size is in bounds, adjust rain number if needed
    3610             : 
    3611             :   !$acc loop gang vector collapse(2)
    3612           0 :   do k=1,nlev
    3613           0 :      do i=1,mgncol
    3614           0 :         dum_2D(i,k) = dumnr(i,k)
    3615             :      end do
    3616             :   end do
    3617             :   !$acc end parallel
    3618             : 
    3619           0 :   call size_dist_param_basic(mg_rain_props, dumr, dumnr, lamr, mgncol, nlev)
    3620             : 
    3621             :   !$acc parallel vector_length(VLENS) default(present)
    3622             :   !$acc loop gang vector collapse(2)
    3623           0 :   do k=1,nlev
    3624           0 :      do i=1,mgncol
    3625           0 :         if (dumr(i,k).ge.qsmall) then
    3626           0 :            if (dum_2D(i,k) /= dumnr(i,k)) then
    3627             :               ! adjust number conc if needed to keep mean size in reasonable range
    3628           0 :               nrtend(i,k)=(dumnr(i,k)*precip_frac(i,k)-nr(i,k))*rdeltat
    3629             :            end if
    3630             : 
    3631             :         end if
    3632             :      end do
    3633             :   end do
    3634             : 
    3635             :   ! recalculate 'final' snow size distribution parameters
    3636             :   ! to ensure that snow size is in bounds, adjust snow number if needed
    3637             : 
    3638             :   !$acc loop gang vector collapse(2)
    3639           0 :   do k=1,nlev
    3640           0 :      do i=1,mgncol
    3641           0 :         dum_2D(i,k) = dumns(i,k)
    3642             :      end do
    3643             :   end do
    3644             :   !$acc end parallel
    3645             : 
    3646           0 :   call size_dist_param_basic(mg_snow_props, dums, dumns, lams, mgncol, nlev, n0=dumns0A2D)
    3647             : 
    3648             :   !$acc parallel vector_length(VLENS) default(present)
    3649             :   !$acc loop gang vector collapse(2)
    3650           0 :   do k=1,nlev
    3651           0 :      do i=1,mgncol
    3652           0 :         if (dums(i,k).ge.qsmall) then
    3653             : 
    3654           0 :            if (dum_2D(i,k) /= dumns(i,k)) then
    3655             :               ! adjust number conc if needed to keep mean size in reasonable range
    3656           0 :               nstend(i,k)=(dumns(i,k)*precip_frac(i,k)-ns(i,k))*rdeltat
    3657             :            end if
    3658             : 
    3659           0 :            sadsnow(i,k) = 2._r8*pi*(lams(i,k)**(-3))*dumns0A2D(i,k)*rho(i,k)*1.e-2_r8  ! m2/m3 -> cm2/cm3
    3660             : 
    3661             :         end if
    3662             :      end do
    3663             :   end do
    3664             : 
    3665             :   ! recalculate 'final' graupel size distribution parameters
    3666             :   ! to ensure that  size is in bounds, addjust number if needed
    3667             : 
    3668             :   !$acc loop gang vector collapse(2)
    3669           0 :   do k=1,nlev
    3670           0 :      do i=1,mgncol
    3671           0 :         dum_2D(i,k) = dumng(i,k)
    3672             :      end do
    3673             :   end do
    3674             :   !$acc end parallel
    3675             : 
    3676           0 :   if (do_hail) then
    3677           0 :      call size_dist_param_basic(mg_hail_props, dumg, dumng, lamg, mgncol, nlev)
    3678             :   end if
    3679           0 :   if (do_graupel) then
    3680           0 :      call size_dist_param_basic(mg_graupel_props, dumg, dumng, lamg, mgncol, nlev)
    3681             :   end if
    3682             : 
    3683             :   !$acc parallel vector_length(VLENS) default(present)
    3684             :   !$acc loop gang vector collapse(2)
    3685           0 :   do k=1,nlev
    3686           0 :      do i=1,mgncol
    3687           0 :         if (dumg(i,k).ge.qsmall) then
    3688           0 :            if (dum_2D(i,k) /= dumng(i,k)) then
    3689             :               ! adjust number conc if needed to keep mean size in reasonable range
    3690           0 :               ngtend(i,k)=(dumng(i,k)*precip_frac(i,k)-ng(i,k))*rdeltat
    3691             :            end if
    3692             :         end if
    3693             :      end do
    3694             :   end do
    3695             : 
    3696             :   !$acc loop gang vector collapse(2)
    3697           0 :   do k=1,nlev
    3698           0 :      do i=1,mgncol
    3699             :         ! if updated q (after microphysics) is zero, then ensure updated n is also zero
    3700             :         !=================================================================================
    3701           0 :         if (qc(i,k)+qctend(i,k)*deltat.lt.qsmall) nctend(i,k)=-nc(i,k)*rdeltat
    3702           0 :         if (do_cldice .and. qi(i,k)+qitend(i,k)*deltat.lt.qsmall) nitend(i,k)=-ni(i,k)*rdeltat
    3703           0 :         if (qr(i,k)+qrtend(i,k)*deltat.lt.qsmall) nrtend(i,k)=-nr(i,k)*rdeltat
    3704           0 :         if (qs(i,k)+qstend(i,k)*deltat.lt.qsmall) nstend(i,k)=-ns(i,k)*rdeltat
    3705           0 :         if (qg(i,k)+qgtend(i,k)*deltat.lt.qsmall) ngtend(i,k)=-ng(i,k)*rdeltat
    3706             :      end do
    3707             :   end do
    3708             : 
    3709             :   ! DO STUFF FOR OUTPUT:
    3710             :   !==================================================
    3711             :   ! qc and qi are only used for output calculations past here,
    3712             :   ! so add qctend and qitend back in one more time
    3713             : 
    3714             :   !$acc loop gang vector collapse(2)
    3715           0 :   do k=1,nlev
    3716           0 :      do i=1,mgncol
    3717           0 :         qc(i,k) = qc(i,k) + qctend(i,k)*deltat
    3718           0 :         qi(i,k) = qi(i,k) + qitend(i,k)*deltat
    3719             :      end do
    3720             :   end do
    3721             : 
    3722             :   ! averaging for snow and rain number and diameter
    3723             :   !--------------------------------------------------
    3724             : 
    3725             :   ! drout2/dsout2:
    3726             :   ! diameter of rain and snow
    3727             :   ! dsout:
    3728             :   ! scaled diameter of snow (passed to radiation in CAM)
    3729             :   ! reff_rain/reff_snow:
    3730             :   ! calculate effective radius of rain and snow in microns for COSP using Eq. 9 of COSP v1.3 manual
    3731             : 
    3732             :   ! avoid divide by zero in avg_diameter_vec
    3733             : 
    3734             :   !$acc loop gang vector collapse(2)
    3735           0 :   do k=1,nlev
    3736           0 :      do i=1,mgncol
    3737           0 :         if (nrout(i,k) .eq. 0._r8) nrout(i,k)=1.e-34_r8
    3738             :      end do
    3739             :   end do
    3740             :   !$acc end parallel
    3741             : 
    3742             :   ! The avg_diameter_vec call does the actual calculation; other diameter
    3743             :   ! outputs are just drout2 times constants.
    3744           0 :   call avg_diameter_vec(qrout,nrout,rho,rhow,drout2,mgncol*nlev)
    3745             : 
    3746             :   !$acc parallel vector_length(VLENS) default(present)
    3747             :   !$acc loop gang vector collapse(2)
    3748           0 :   do k=1,nlev
    3749           0 :      do i=1,mgncol
    3750           0 :         if (qrout(i,k) .gt. 1.e-7_r8 .and. nrout(i,k) .gt. 0._r8) then
    3751           0 :            qrout2(i,k) = qrout(i,k) * precip_frac(i,k)
    3752           0 :            nrout2(i,k) = nrout(i,k) * precip_frac(i,k)
    3753           0 :            freqr(i,k) = precip_frac(i,k)
    3754           0 :            reff_rain(i,k)=1.5_r8*drout2(i,k)*1.e6_r8
    3755             :         else
    3756           0 :            qrout2(i,k) = 0._r8
    3757           0 :            nrout2(i,k) = 0._r8
    3758           0 :            drout2(i,k) = 0._r8
    3759           0 :            freqr(i,k) = 0._r8
    3760           0 :            reff_rain(i,k) = 0._r8
    3761             :         end if
    3762             :      end do
    3763             :   end do
    3764             : 
    3765             :   ! avoid divide by zero in avg_diameter_vec
    3766             : 
    3767             :   !$acc loop gang vector collapse(2)
    3768           0 :   do k=1,nlev
    3769           0 :      do i=1,mgncol
    3770           0 :         if (nsout(i,k) .eq. 0._r8) nsout(i,k) = 1.e-34_r8
    3771             :      end do
    3772             :   end do
    3773             :   !$acc end parallel
    3774             : 
    3775             :   ! The avg_diameter_vec call does the actual calculation; other diameter
    3776             :   ! outputs are just dsout2 times constants.
    3777           0 :   call avg_diameter_vec(qsout, nsout, rho, rhosn,dsout2,mgncol*nlev)
    3778             : 
    3779             :   !$acc parallel vector_length(VLENS) default(present)
    3780             :   !$acc loop gang vector collapse(2)
    3781           0 :   do k=1,nlev
    3782           0 :      do i=1,mgncol
    3783           0 :         if (qsout(i,k) .gt. 1.e-7_r8 .and. nsout(i,k) .gt. 0._r8) then
    3784           0 :            qsout2(i,k) = qsout(i,k) * precip_frac(i,k)
    3785           0 :            nsout2(i,k) = nsout(i,k) * precip_frac(i,k)
    3786           0 :            freqs(i,k) = precip_frac(i,k)      
    3787           0 :            dsout(i,k)=3._r8*rhosn/rhows*dsout2(i,k)
    3788           0 :            reff_snow(i,k)=1.5_r8*dsout2(i,k)*1.e6_r8
    3789             :         else
    3790           0 :            dsout(i,k)  = 0._r8
    3791           0 :            qsout2(i,k) = 0._r8
    3792           0 :            nsout2(i,k) = 0._r8
    3793           0 :            dsout2(i,k) = 0._r8
    3794           0 :            freqs(i,k)  = 0._r8
    3795           0 :            reff_snow(i,k)=0._r8
    3796             :         end if 
    3797             :      end do
    3798             :   end do
    3799             : 
    3800             :   ! avoid divide by zero in avg_diameter_vec
    3801             : 
    3802             :   !$acc loop gang vector collapse(2)
    3803           0 :   do k=1,nlev
    3804           0 :      do i=1,mgncol
    3805           0 :         if (ngout(i,k) .eq. 0._r8) ngout(i,k) = 1.e-34_r8
    3806             :      end do
    3807             :   end do
    3808             :   !$acc end parallel
    3809             : 
    3810             :   ! The avg_diameter_vec call does the actual calculation; other diameter
    3811             :   ! outputs are just dgout2 times constants.
    3812           0 :   if (do_hail .or. do_graupel) then
    3813           0 :      call avg_diameter_vec(qgout, ngout, rho, rhogtmp, dgout2, mgncol*nlev)
    3814             :   else
    3815             :      ! need this if statement for MG2, where rhogtmp = 0
    3816             : 
    3817             :      !$acc parallel vector_length(VLENS) default(present)
    3818             :      !$acc loop gang vector collapse(2)
    3819           0 :      do k=1,nlev
    3820           0 :         do i=1,mgncol
    3821           0 :            dgout2(i,k) = 0._r8
    3822             :         end do
    3823             :      end do
    3824             :      !$acc end parallel
    3825             :   end if
    3826             : 
    3827             :   !$acc parallel vector_length(VLENS) default(present)
    3828             :   !$acc loop gang vector collapse(2)
    3829           0 :   do k=1,nlev
    3830           0 :      do i=1,mgncol
    3831           0 :         if (qgout(i,k) .gt. 1.e-7_r8 .and. ngout(i,k) .gt. 0._r8) then
    3832           0 :            qgout2(i,k) = qgout(i,k) * precip_frac(i,k)
    3833           0 :            ngout2(i,k) = ngout(i,k) * precip_frac(i,k)
    3834           0 :            freqg(i,k) = precip_frac(i,k)
    3835           0 :            dgout(i,k)=3._r8*rhogtmp/rhows*dgout2(i,k)
    3836           0 :            reff_grau(i,k)=1.5_r8*dgout2(i,k)*1.e6_r8
    3837             :         else
    3838           0 :            dgout(i,k)  = 0._r8
    3839           0 :            qgout2(i,k) = 0._r8
    3840           0 :            ngout2(i,k) = 0._r8
    3841           0 :            dgout2(i,k) = 0._r8
    3842           0 :            freqg(i,k)  = 0._r8
    3843           0 :            reff_grau(i,k)=0._r8
    3844             :         end if 
    3845             :      end do
    3846             :   end do
    3847             : 
    3848             :   ! analytic radar reflectivity
    3849             :   !--------------------------------------------------
    3850             :   ! formulas from Matthew Shupe, NOAA/CERES
    3851             :   ! *****note: radar reflectivity is local (in-precip average)
    3852             :   ! units of mm^6/m^3
    3853             : 
    3854             :   !$acc loop gang vector collapse(2) private(dum,dum1)
    3855           0 :   do k=1,nlev
    3856           0 :      do i=1,mgncol
    3857           0 :         if (qc(i,k).ge.qsmall .and. (nc(i,k)+nctend(i,k)*deltat).gt.10._r8) then
    3858             :            dum=(qc(i,k)/lcldm(i,k)*rho(i,k)*1000._r8)**2 &
    3859           0 :                 /(0.109_r8*(nc(i,k)+nctend(i,k)*deltat)/lcldm(i,k)*rho(i,k)/1.e6_r8)*lcldm(i,k)/precip_frac(i,k)
    3860             :         else
    3861             :            dum=0._r8
    3862             :         end if
    3863           0 :         if (qi(i,k).ge.qsmall) then
    3864           0 :            dum1=(qi(i,k)*rho(i,k)/icldm(i,k)*1000._r8/0.1_r8)**(1._r8/0.63_r8)*icldm(i,k)/precip_frac(i,k)
    3865             :         else
    3866           0 :            dum1=0._r8
    3867             :         end if
    3868           0 :         if (qsout(i,k).ge.qsmall) then
    3869           0 :            dum1=dum1+(qsout(i,k)*rho(i,k)*1000._r8/0.1_r8)**(1._r8/0.63_r8)
    3870             :         end if
    3871           0 :         refl(i,k)=dum+dum1
    3872             : 
    3873             :         ! add rain rate, but for 37 GHz formulation instead of 94 GHz
    3874             :         ! formula approximated from data of Matrasov (2007)
    3875             :         ! rainrt is the rain rate in mm/hr
    3876             :         ! reflectivity (dum) is in DBz
    3877           0 :         if (rainrt(i,k).ge.0.001_r8) then
    3878           0 :            dum=log10(rainrt(i,k)**6._r8)+16._r8
    3879             :            ! convert from DBz to mm^6/m^3
    3880           0 :            dum = 10._r8**(dum/10._r8)
    3881             :         else
    3882             :            ! don't include rain rate in R calculation for values less than 0.001 mm/hr
    3883             :            dum=0._r8
    3884             :         end if
    3885             : 
    3886             :         ! add to refl
    3887           0 :         refl(i,k)=refl(i,k)+dum
    3888             : 
    3889             :         !output reflectivity in Z.
    3890           0 :         areflz(i,k)=refl(i,k) * precip_frac(i,k)
    3891             : 
    3892             :         ! convert back to DBz
    3893           0 :         if (refl(i,k).gt.minrefl) then
    3894           0 :            refl(i,k)=10._r8*log10(refl(i,k))
    3895             :         else
    3896           0 :            refl(i,k)=-9999._r8
    3897             :         end if
    3898             : 
    3899             :         !set averaging flag
    3900           0 :         if (refl(i,k).gt.mindbz) then
    3901           0 :            arefl(i,k)=refl(i,k) * precip_frac(i,k)
    3902           0 :            frefl(i,k)=precip_frac(i,k)
    3903             :         else
    3904           0 :            arefl(i,k)=0._r8
    3905           0 :            areflz(i,k)=0._r8
    3906           0 :            frefl(i,k)=0._r8
    3907             :         end if
    3908             : 
    3909             :         ! bound cloudsat reflectivity
    3910           0 :         csrfl(i,k)=min(csmax,refl(i,k))
    3911             : 
    3912             :         !set averaging flag
    3913           0 :         if (csrfl(i,k).gt.csmin) then
    3914           0 :            acsrfl(i,k)=refl(i,k) * precip_frac(i,k)
    3915           0 :            fcsrfl(i,k)=precip_frac(i,k)
    3916             :         else
    3917           0 :            acsrfl(i,k)=0._r8
    3918           0 :            fcsrfl(i,k)=0._r8
    3919             :         end if
    3920             :      end do
    3921             :   end do
    3922             : 
    3923             :   !redefine fice here....
    3924             : 
    3925             :   !$acc loop gang vector collapse(2)
    3926           0 :   do k=1,nlev
    3927           0 :      do i=1,mgncol
    3928           0 :         dum_2D(i,k) = qsout(i,k) + qrout(i,k) + qc(i,k) + qi(i,k)
    3929           0 :         dumi(i,k)   = qsout(i,k) + qi(i,k)
    3930           0 :         if (dumi(i,k) .gt. qsmall .and. dum_2D(i,k) .gt. qsmall) then
    3931           0 :            nfice(i,k) = min(dumi(i,k)/dum_2D(i,k),1._r8)
    3932             :         else
    3933           0 :            nfice(i,k) = 0._r8
    3934             :         end if
    3935             :      end do
    3936             :   end do
    3937             :   !$acc end parallel
    3938             : 
    3939             :   !$acc end data
    3940             : 
    3941           0 : end subroutine micro_pumas_tend
    3942             : 
    3943             : !========================================================================
    3944             : !OUTPUT CALCULATIONS
    3945             : !========================================================================
    3946             : 
    3947           0 : subroutine calc_rercld(lamr, n0r, lamc, pgam, qric, qcic, ncic, rercld, vlen)
    3948             :   integer,                   intent(in) :: vlen 
    3949             :   real(r8), dimension(vlen), intent(in) :: lamr          ! rain size parameter (slope)
    3950             :   real(r8), dimension(vlen), intent(in) :: n0r           ! rain size parameter (intercept)
    3951             :   real(r8), dimension(vlen), intent(in) :: lamc          ! size distribution parameter (slope)
    3952             :   real(r8), dimension(vlen), intent(in) :: pgam          ! droplet size parameter
    3953             :   real(r8), dimension(vlen), intent(in) :: qric          ! in-cloud rain mass mixing ratio
    3954             :   real(r8), dimension(vlen), intent(in) :: qcic          ! in-cloud cloud liquid
    3955             :   real(r8), dimension(vlen), intent(in) :: ncic          ! in-cloud droplet number concentration
    3956             : 
    3957             :   real(r8), dimension(vlen), intent(inout) :: rercld     ! effective radius calculation for rain + cloud
    3958             : 
    3959             :   ! combined size of precip & cloud drops
    3960           0 :   real(r8) :: Atmp,tmp(vlen), pgamp1(vlen) 
    3961             : 
    3962             :   integer :: i
    3963             : 
    3964             :   !$acc data present (rercld,lamr,n0r,lamc,pgam,qric,qcic,ncic) &
    3965             :   !$acc      create  (Atmp,tmp,pgamp1)
    3966             : 
    3967             :   !$acc parallel vector_length(VLENS) default(present)
    3968             :   !$acc loop gang vector
    3969           0 :   do i=1,vlen
    3970           0 :      pgamp1(i) = pgam(i)+1._r8
    3971             :   end do
    3972             :   !$acc end parallel
    3973             : 
    3974           0 :   call rising_factorial(pgamp1, 2, tmp, vlen)
    3975             : 
    3976             :   !$acc parallel vector_length(VLENS) default(present)
    3977             :   !$acc loop gang vector private(Atmp)
    3978           0 :   do i=1,vlen
    3979             :      ! Rain drops
    3980           0 :      if (lamr(i) > 0._r8) then
    3981           0 :         Atmp = n0r(i) * pi / (2._r8 * lamr(i)**3._r8)
    3982             :      else
    3983             :         Atmp = 0._r8
    3984             :      end if
    3985             :      ! Add cloud drops
    3986           0 :      if (lamc(i) > 0._r8) then
    3987             :         Atmp = Atmp + &
    3988           0 :              ncic(i) * pi * tmp(i) / (4._r8 * lamc(i)**2._r8)
    3989             :      end if
    3990           0 :      if (Atmp > 0._r8) then
    3991           0 :         rercld(i) = rercld(i) + 3._r8 *(qric(i) + qcic(i)) / (4._r8 * rhow * Atmp)
    3992             :      end if
    3993             :   end do
    3994             :   !$acc end parallel
    3995             : 
    3996             :   !$acc end data
    3997           0 : end subroutine calc_rercld
    3998             : 
    3999             : !========================================================================
    4000             : !2020-09-15: Follow John Dennis's version to generate a new interface 
    4001             : !            to update tendency in the sedimentation loop
    4002             : !========================================================================
    4003           0 : subroutine Sedimentation(mgncol,nlev,do_cldice,deltat,fx,fnx,pdel_inv,qxtend,nxtend, &
    4004           0 :                             qxsedten,dumx,dumnx,prect,xflx,xxlx,qxsevap,xcldm,tlat,qvlat,preci)
    4005             : 
    4006             :    integer, intent(in)               :: mgncol,nlev
    4007             :    logical, intent(in)               :: do_cldice
    4008             :    real(r8),intent(in)               :: deltat
    4009             :    real(r8), intent(in)              :: fx(mgncol,nlev)
    4010             :    real(r8), intent(in)              :: fnx(mgncol,nlev)
    4011             :    real(r8), intent(in)              :: pdel_inv(mgncol,nlev)
    4012             :    real(r8), intent(inout)           :: qxtend(mgncol,nlev)
    4013             :    real(r8), intent(inout)           :: nxtend(mgncol,nlev)
    4014             :    real(r8), intent(inout)           :: qxsedten(mgncol,nlev)
    4015             :    real(r8), intent(inout)           :: dumx(mgncol,nlev)
    4016             :    real(r8), intent(inout)           :: dumnx(mgncol,nlev)
    4017             :    real(r8), intent(inout)           :: prect(mgncol)
    4018             :    real(r8), intent(inout)           :: xflx(mgncol,nlev+1)
    4019             :    real(r8), intent(in)   , optional :: xxlx
    4020             :    real(r8), intent(inout), optional :: qxsevap(mgncol,nlev)
    4021             :    real(r8), intent(in)   , optional :: xcldm(mgncol,nlev)
    4022             :    real(r8), intent(inout), optional :: tlat(mgncol,nlev)
    4023             :    real(r8), intent(inout), optional :: qvlat(mgncol,nlev)
    4024             :    real(r8), intent(inout), optional :: preci(mgncol)
    4025             :    integer  :: i,k,n,nstep
    4026             :    real(r8) :: faltndx,faltndnx,rnstep,faltndqxe
    4027           0 :    real(r8) :: dum1(mgncol,nlev),faloutx(mgncol,0:nlev),faloutnx(mgncol,0:nlev)
    4028             :    logical  :: present_tlat,present_qvlat, present_xcldm,present_qxsevap, present_preci
    4029             : 
    4030           0 :    present_tlat    = present(tlat)
    4031           0 :    present_qvlat   = present(qvlat)
    4032           0 :    present_xcldm   = present(xcldm)
    4033           0 :    present_qxsevap = present(qxsevap)
    4034           0 :    present_preci   = present(preci)
    4035             : 
    4036             :    ! loop over sedimentation sub-time step to ensure stability
    4037             :    !==============================================================
    4038             : 
    4039             :    !$acc data present (fx,fnx,pdel_inv,qxtend,nxtend,qxsedten,dumx,dumnx) &
    4040             :    !$acc      present (prect,xflx,xxlx,qxsevap,xcldm,tlat,qvlat,preci) &
    4041             :    !$acc      create  (faloutx,faloutnx,dum1)
    4042             : 
    4043             :    !$acc parallel vector_length(VLENS) default(present)
    4044             :    !$acc loop gang vector private(faltndx,faltndnx,faltndqxe,nstep,rnstep)
    4045           0 :    do i = 1,mgncol
    4046           0 :       nstep   = 1 + int( max( maxval( fx(i,:)*pdel_inv(i,:) ), &
    4047             :                               maxval( fnx(i,:)*pdel_inv(i,:) ) ) &
    4048           0 :                               * deltat )
    4049           0 :       rnstep  = 1._r8/real(nstep)
    4050             : 
    4051           0 :       dum1(i,1) = 0._r8
    4052           0 :       if (present_xcldm) then
    4053             :          !$acc loop vector 
    4054           0 :          do k = 2,nlev
    4055           0 :             dum1(i,k) = xcldm(i,k)/xcldm(i,k-1)
    4056           0 :             dum1(i,k) = min(dum1(i,k),1._r8)
    4057             :          end do
    4058             :       else
    4059             :          !$acc loop vector
    4060           0 :          do k=2,nlev
    4061           0 :             dum1(i,k) = 1._r8
    4062             :          end do
    4063             :       end if
    4064             : 
    4065             :       !$acc loop seq
    4066           0 :       do n = 1,nstep
    4067           0 :          faloutx(i,0)  = 0._r8
    4068           0 :          faloutnx(i,0) = 0._r8
    4069           0 :          if (do_cldice) then
    4070             :             !$acc loop vector
    4071           0 :             do k=1,nlev
    4072           0 :                faloutx(i,k)  = fx(i,k)  * dumx(i,k)
    4073           0 :                faloutnx(i,k) = fnx(i,k) * dumnx(i,k)
    4074             :             end do
    4075             :          else
    4076             :             !$acc loop vector
    4077           0 :             do k=1,nlev
    4078           0 :                faloutx(i,k)  = 0._r8
    4079           0 :                faloutnx(i,k) = 0._r8
    4080             :             end do
    4081             :          end if
    4082             : 
    4083             :          !$acc loop vector
    4084           0 :          do k = 1,nlev
    4085             :             ! for cloud liquid and ice, if cloud fraction increases with height
    4086             :             ! then add flux from above to both vapor and cloud water of current level
    4087             :             ! this means that flux entering clear portion of cell from above evaporates
    4088             :             ! instantly
    4089             :             ! note: this is not an issue with precip, since we assume max overlap
    4090           0 :             faltndx       = (faloutx(i,k)  - dum1(i,k)*faloutx(i,k-1))*pdel_inv(i,k)
    4091           0 :             faltndnx      = (faloutnx(i,k) - dum1(i,k)*faloutnx(i,k-1))*pdel_inv(i,k)
    4092             :             ! add fallout terms to eulerian tendencies
    4093           0 :             qxtend(i,k)   = qxtend(i,k)-faltndx*rnstep
    4094           0 :             nxtend(i,k)   = nxtend(i,k)-faltndnx*rnstep
    4095             :             ! sedimentation tendency for output
    4096           0 :             qxsedten(i,k) = qxsedten(i,k)-faltndx*rnstep
    4097             :             ! add terms to to evap/sub of cloud water
    4098           0 :             dumx(i,k)     = dumx(i,k)  - faltndx*deltat*rnstep
    4099           0 :             dumnx(i,k)    = dumnx(i,k) - faltndnx*deltat*rnstep
    4100             :    
    4101           0 :             if (k>1) then
    4102           0 :                faltndqxe     = (faloutx(i,k)-faloutx(i,k-1))*pdel_inv(i,k)
    4103             :                ! for output
    4104           0 :                if(present_qxsevap) qxsevap(i,k)= qxsevap(i,k) - (faltndqxe-faltndx)*rnstep
    4105           0 :                if(present_qvlat)   qvlat(i,k)  = qvlat(i,k) - (faltndqxe-faltndx)*rnstep
    4106           0 :                if(present_tlat)    tlat(i,k)   = tlat(i,k) + (faltndqxe-faltndx)*xxlx*rnstep
    4107             :             end if 
    4108             :    
    4109           0 :             xflx(i,k+1) = xflx(i,k+1) + faloutx(i,k) / g * rnstep
    4110             :          end do
    4111             : 
    4112             :          ! units below are m/s
    4113             :          ! sedimentation flux at surface is added to precip flux at surface
    4114             :          ! to get total precip (cloud + precip water) rate
    4115           0 :          prect(i) = prect(i)+faloutx(i,nlev)/g*rnstep/1000._r8
    4116           0 :          if(present_preci) preci(i) = preci(i)+faloutx(i,nlev)/g*rnstep/1000._r8
    4117             :       end do  ! n loop of 1, nstep
    4118             :    end do  ! i loop of 1, mgncol
    4119             :    !$acc end parallel
    4120             : 
    4121             :    !$acc end data
    4122           0 : end subroutine Sedimentation
    4123             : 
    4124             : !========================================================================
    4125             : !UTILITIES
    4126             : !========================================================================
    4127             : 
    4128             : 
    4129           0 : pure subroutine micro_pumas_get_cols(ncol, nlev, top_lev, mgncol, mgcols, &
    4130           0 :      qcn, qin, qrn, qsn, qgr)
    4131             : 
    4132             :   ! Determines which columns microphysics should operate over by
    4133             :   ! checking for non-zero cloud water/ice.
    4134             : 
    4135             :   integer, intent(in) :: ncol      ! Number of columns with meaningful data
    4136             :   integer, intent(in) :: nlev      ! Number of levels to use
    4137             :   integer, intent(in) :: top_lev   ! Top level for microphysics
    4138             :   integer, intent(out) :: mgncol   ! Number of columns MG will use
    4139             :   integer, allocatable, intent(out) :: mgcols(:) ! column indices
    4140             : 
    4141             :   real(r8), intent(in) :: qcn(:,:) ! cloud water mixing ratio (kg/kg)
    4142             :   real(r8), intent(in) :: qin(:,:) ! cloud ice mixing ratio (kg/kg)
    4143             :   real(r8), intent(in) :: qrn(:,:) ! rain mixing ratio (kg/kg)
    4144             :   real(r8), intent(in) :: qsn(:,:) ! snow mixing ratio (kg/kg)
    4145             :   real(r8), optional, intent(in) :: qgr(:,:) ! graupel mixing ratio (kg/kg)
    4146             : 
    4147             :   integer :: lev_offset  ! top_lev - 1 (defined here for consistency)
    4148           0 :   logical :: ltrue(ncol) ! store tests for each column
    4149             : 
    4150             :   integer :: i, ii ! column indices
    4151             : 
    4152           0 :   if (allocated(mgcols)) deallocate(mgcols)
    4153             : 
    4154           0 :   lev_offset = top_lev - 1
    4155             : 
    4156             :   ! Using "any" along dimension 2 collapses across levels, but
    4157             :   ! not columns, so we know if water is present at any level
    4158             :   ! in each column.
    4159             : 
    4160           0 :   ltrue = any(qcn(:ncol,top_lev:(nlev+lev_offset)) >= qsmall, 2)
    4161           0 :   ltrue = ltrue .or. any(qin(:ncol,top_lev:(nlev+lev_offset)) >= qsmall, 2)
    4162           0 :   ltrue = ltrue .or. any(qrn(:ncol,top_lev:(nlev+lev_offset)) >= qsmall, 2)
    4163           0 :   ltrue = ltrue .or. any(qsn(:ncol,top_lev:(nlev+lev_offset)) >= qsmall, 2)
    4164             : 
    4165           0 :   if(present(qgr)) ltrue = ltrue .or. any(qgr(:ncol,top_lev:(nlev+lev_offset)) >= qsmall, 2)
    4166             : 
    4167             :   ! Scan for true values to get a usable list of indices.
    4168             : 
    4169           0 :   mgncol = count(ltrue)
    4170           0 :   allocate(mgcols(mgncol))
    4171           0 :   i = 0
    4172           0 :   do ii = 1,ncol
    4173           0 :      if (ltrue(ii)) then
    4174           0 :         i = i + 1
    4175           0 :         mgcols(i) = ii
    4176             :      end if
    4177             :   end do
    4178             : 
    4179           0 : end subroutine micro_pumas_get_cols
    4180             :       
    4181             : end module micro_pumas_v1

Generated by: LCOV version 1.14