LCOV - code coverage report
Current view: top level - physics/cam - subcol_SILHS.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 479 0.0 %
Date: 2025-03-13 18:42:46 Functions: 0 11 0.0 %

          Line data    Source code
       1             : module subcol_SILHS
       2             :    !---------------------------------------------------------------------------
       3             :    ! Purpose:
       4             :    !
       5             :    ! Implement a subcolumn scheme based on the Subgrid Importance Latin Hypercube 
       6             :    ! Sampling (SILHS) functionality of the CLUBB moist turbulence parameterization.
       7             :    !
       8             :    !---------------------------------------------------------------------------
       9             : 
      10             :    use shr_kind_mod,     only: r8=>shr_kind_r8, r4=>shr_kind_r4, i4=>shr_kind_i4
      11             :    use physics_types,    only: physics_state, physics_tend, physics_ptend
      12             :    use ppgrid,           only: pcols, psubcols, pver, pverp, begchunk, endchunk
      13             :    use constituents,     only: pcnst, cnst_get_ind
      14             :    use cam_abortutils,   only: endrun
      15             :    use cam_logfile,      only: iulog
      16             :    use cam_history,      only: addfld, add_default, outfld, horiz_only
      17             :    use ref_pres,         only: top_lev => trop_cloud_top_lev
      18             : #ifdef CLUBB_SGS
      19             : #ifdef SILHS
      20             :   use clubb_intr, only: &
      21             :         clubb_config_flags, &
      22             :         clubb_params, &
      23             :         stats_metadata, &
      24             :         stats_zt, stats_zm, stats_sfc, &
      25             :         pdf_params_chnk
      26             :         
      27             :    use clubb_api_module, only: &
      28             :         hmp2_ip_on_hmm2_ip_slope_type, &
      29             :         hmp2_ip_on_hmm2_ip_intrcpt_type, &
      30             :         precipitation_fractions, &
      31             :         stats
      32             : 
      33             :    use silhs_api_module, only: &
      34             :         silhs_config_flags_type
      35             : #endif
      36             : #endif
      37             :    use physconst,     only: cpair, gravit, latvap, latice, rair, rga, cappa
      38             : 
      39             :    implicit none
      40             :    private
      41             :    save
      42             : 
      43             :    public :: subcol_register_SILHS  ! 
      44             :    public :: subcol_init_SILHS      ! Initialize 
      45             :    public :: subcol_gen_SILHS       ! Generate subcolumn fields by calling SILHS 
      46             :    public :: subcol_readnl_SILHS    ! SILHS namelist reader
      47             :    public :: subcol_ptend_avg_SILHS
      48             :    public :: subcol_SILHS_var_covar_driver
      49             :    public :: subcol_SILHS_fill_holes_conserv
      50             :    public :: subcol_SILHS_hydromet_conc_tend_lim
      51             :    public :: init_state_subcol
      52             :    private :: fill_holes_sedimentation
      53             :    private :: fill_holes_same_phase_vert
      54             : #ifdef SILHS
      55             :    ! Calc subcol mean ! Calc subcol variance
      56             :    private :: meansc
      57             :    private :: stdsc
      58             :    
      59             :    type (stats), target :: stats_lh_zt,   &
      60             :                            stats_lh_sfc
      61             :    !$omp threadprivate(stats_lh_zt, stats_lh_sfc)
      62             : #endif
      63             : 
      64             :    !-----
      65             :    ! Private module vars
      66             :    !-----
      67             : 
      68             :    ! constituent indicies
      69             :    integer :: &
      70             :       ixq      = 0, &
      71             :       ixcldliq = 0, &
      72             :       ixnumliq = 0, &
      73             :       ixcldice = 0, &
      74             :       ixnumice = 0, &
      75             :       ixrain   = 0, &
      76             :       ixnumrain= 0, &
      77             :       ixsnow   = 0, &
      78             :       ixnumsnow= 0
      79             :    
      80             :    ! Pbuf indicies
      81             :    integer :: thlm_idx, rtm_idx, ice_supersat_idx, &
      82             :               alst_idx, cld_idx, qrain_idx, qsnow_idx, &
      83             :               nrain_idx, nsnow_idx, ztodt_idx, tke_idx, kvh_idx, &
      84             :               prec_pcw_idx, snow_pcw_idx, prec_str_idx, snow_str_idx, &
      85             :               qcsedten_idx, qrsedten_idx, qisedten_idx, qssedten_idx, &
      86             :               vtrmc_idx, umr_idx, vtrmi_idx, ums_idx, qcsevap_idx, qisevap_idx
      87             : 
      88             :    logical :: subcol_SILHS_weight  ! if set, sets up weights for averaging subcolumns for SILHS
      89             :    integer :: subcol_SILHS_numsubcol ! number of subcolumns for this run
      90             :    logical :: docldfracscaling = .false. ! Weight tendencies by cloud fraction
      91             : 
      92             :    character(len=256) :: subcol_SILHS_corr_file_path
      93             :    character(len=16)  :: subcol_SILHS_corr_file_name
      94             : 
      95             :    logical :: subcol_SILHS_q_to_micro, &
      96             :               subcol_SILHS_n_to_micro, &
      97             :               subcol_SILHS_use_clear_col, &
      98             :               subcol_SILHS_meanice, &
      99             :               subcol_SILHS_constrainmn
     100             : 
     101             :    logical :: subcol_SILHS_var_covar_src
     102             : 
     103             :    real(r8) :: subcol_SILHS_ncnp2_on_ncnm2
     104             : 
     105             :    ! There may or may not be a better place to put this.
     106             :    real(r8), parameter :: p0_clubb = 100000._r8
     107             : 
     108             : 
     109             : !   real(r8) :: subcol_SILHS_c6rt, subcol_SILHS_c7, subcol_SILHS_c8, subcol_SILHS_c11, &
     110             : !               subcol_SILHS_c11b, subcol_SILHS_gamma_coef, &
     111             : !               subcol_SILHS_mult_coef, subcol_SILHS_mu
     112             : 
     113             :    real(r8) :: ztodt  ! model timestep
     114             : #ifdef CLUBB_SGS
     115             : #ifdef SILHS
     116             :     type(hmp2_ip_on_hmm2_ip_slope_type) :: subcol_SILHS_hmp2_ip_on_hmm2_ip_slope    
     117             :     type(hmp2_ip_on_hmm2_ip_intrcpt_type) :: subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt
     118             : 
     119             :     type(silhs_config_flags_type) :: silhs_config_flags
     120             : #endif
     121             : #endif
     122             : 
     123             : contains
     124             : 
     125           0 :    subroutine subcol_register_SILHS()
     126             : 
     127             :       !--------------------------------
     128             :       ! Register fields needed by SILHS in the physics buffer
     129             :       ! Currently, most fields needed by SILHS but calculated by CLUBB are registered
     130             :       ! by clubb in clubb_intr.F90.
     131             :       ! 
     132             :       !--------------------------------
     133             : #ifdef CLUBB_SGS
     134             : #ifdef SILHS
     135             : #endif
     136             : #endif
     137           0 :    end subroutine subcol_register_SILHS
     138             : 
     139             : 
     140           0 :    subroutine subcol_readnl_SILHS(nlfile)
     141             : #ifdef CLUBB_SGS
     142             : #ifdef SILHS
     143             :       use namelist_utils,   only: find_group_name
     144             :       use spmd_utils,       only: masterproc, masterprocid, mpicom
     145             :       use spmd_utils,       only: mpi_integer, mpi_logical, mpi_character, mpir8, iam
     146             :       use clubb_api_module, only: core_rknd
     147             :       use silhs_api_module, only: set_default_silhs_config_flags_api, &
     148             :                                   initialize_silhs_config_flags_type_api, &
     149             :                                   print_silhs_config_flags_api
     150             : #endif
     151             : #endif
     152             :       character(len=*), intent(in) :: nlfile  ! filepath for file containing namelist input
     153             : 
     154             :       ! Local variables
     155             :       integer :: unitn, ierr
     156             : #ifdef CLUBB_SGS
     157             : #ifdef SILHS
     158             : 
     159             :       integer :: &
     160             :           cluster_allocation_strategy
     161             : 
     162             :       logical :: &
     163             :           subcol_silhs_l_lh_importance_sampling, &
     164             :           subcol_silhs_l_Lscale_vert_avg, &
     165             :           subcol_silhs_l_lh_straight_mc, &
     166             :           subcol_silhs_l_lh_clustered_sampling, &
     167             :           subcol_silhs_l_rcm_in_cloud_k_lh_start, &
     168             :           subcol_silhs_l_random_k_lh_start, &
     169             :           subcol_silhs_l_max_overlap_in_cloud, &
     170             :           subcol_silhs_l_lh_instant_var_covar_src, &
     171             :           subcol_silhs_l_lh_limit_weights, &
     172             :           subcol_silhs_l_lh_var_frac, &
     173             :           subcol_silhs_l_lh_normalize_weights
     174             : 
     175             :       namelist /subcol_SILHS_nl/ subcol_SILHS_weight, &
     176             :                                  subcol_SILHS_numsubcol, &
     177             :                                  subcol_SILHS_corr_file_path, &
     178             :                                  subcol_SILHS_corr_file_name, &
     179             :                                  subcol_SILHS_q_to_micro, &
     180             :                                  subcol_SILHS_n_to_micro, &
     181             :                                  subcol_SILHS_ncnp2_on_ncnm2, &
     182             :                                  subcol_SILHS_hmp2_ip_on_hmm2_ip_slope, &
     183             :                                  subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt, &
     184             :                                  subcol_SILHS_meanice, &
     185             :                                  subcol_SILHS_use_clear_col, &
     186             :                                  subcol_SILHS_constrainmn, &
     187             :                                  subcol_SILHS_var_covar_src
     188             : !                                 subcol_SILHS_c6rt, subcol_SILHS_c7, &
     189             : !                                 subcol_SILHS_c8, subcol_SILHS_c11, subcol_SILHS_c11b, &
     190             : !                                 subcol_SILHS_gamma_coef, subcol_SILHS_mult_coef, subcol_SILHS_mu
     191             : 
     192             :      namelist /silhs_config_flags_nl/ subcol_silhs_l_lh_importance_sampling, &
     193             :                                       subcol_silhs_l_Lscale_vert_avg, &
     194             :                                       subcol_silhs_l_lh_straight_mc, &
     195             :                                       subcol_silhs_l_lh_clustered_sampling, &
     196             :                                       subcol_silhs_l_rcm_in_cloud_k_lh_start, &
     197             :                                       subcol_silhs_l_random_k_lh_start, &
     198             :                                       subcol_silhs_l_max_overlap_in_cloud, &
     199             :                                       subcol_silhs_l_lh_instant_var_covar_src, &
     200             :                                       subcol_silhs_l_lh_limit_weights, &
     201             :                                       subcol_silhs_l_lh_var_frac, &
     202             :                                       subcol_silhs_l_lh_normalize_weights
     203             : 
     204             :       !-----------------------------------------------------------------------------
     205             :       ! Set defaults
     206             : 
     207             :       ! Eric Raut changed a default.
     208             :       subcol_SILHS_hmp2_ip_on_hmm2_ip_slope%Ni = 0.0_core_rknd
     209             :       subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt%Ni = 0.5_core_rknd
     210             : 
     211             :       if (masterproc) then
     212             :          open( newunit=unitn, file=trim(nlfile), status='old' )
     213             :          call find_group_name(unitn, 'subcol_SILHS_nl', status=ierr)
     214             :          if (ierr == 0) then
     215             :             read(unitn, subcol_SILHS_nl, iostat=ierr)
     216             :             if (ierr /= 0) then
     217             :                call endrun('subcol_readnl_SILHS: ERROR reading namelist')
     218             :             end if
     219             :          end if
     220             :          close(unitn)
     221             :       end if
     222             : 
     223             :       ! Set default silhs_config_flags entires
     224             :       call set_default_silhs_config_flags_api( cluster_allocation_strategy, &
     225             :                                                subcol_silhs_l_lh_importance_sampling, &
     226             :                                                subcol_silhs_l_Lscale_vert_avg, &
     227             :                                                subcol_silhs_l_lh_straight_mc, &
     228             :                                                subcol_silhs_l_lh_clustered_sampling, &
     229             :                                                subcol_silhs_l_rcm_in_cloud_k_lh_start, &
     230             :                                                subcol_silhs_l_random_k_lh_start, &
     231             :                                                subcol_silhs_l_max_overlap_in_cloud, &
     232             :                                                subcol_silhs_l_lh_instant_var_covar_src, &
     233             :                                                subcol_silhs_l_lh_limit_weights, &
     234             :                                                subcol_silhs_l_lh_var_frac, &
     235             :                                                subcol_silhs_l_lh_normalize_weights )
     236             : 
     237             :       ! Get silhs_config_flags entries from namelist
     238             :       if (masterproc) then
     239             :         open( newunit=unitn, file=trim(nlfile), status='old' )
     240             :         call find_group_name(unitn, 'silhs_config_flags_nl', status=ierr)
     241             :         if (ierr == 0) then
     242             :           read(unitn, silhs_config_flags_nl, iostat=ierr)
     243             :           if (ierr /= 0) then
     244             :             call endrun('silhs_config_flags_nl: ERROR reading namelist')
     245             :           end if
     246             :         end if
     247             :         close(unitn)
     248             :       end if
     249             : 
     250             :       ! Save silhs_config_flags entries into module variable silhs_config_flags
     251             :       call initialize_silhs_config_flags_type_api( cluster_allocation_strategy, &
     252             :                                                    subcol_silhs_l_lh_importance_sampling, &
     253             :                                                    subcol_silhs_l_Lscale_vert_avg, &
     254             :                                                    subcol_silhs_l_lh_straight_mc, &
     255             :                                                    subcol_silhs_l_lh_clustered_sampling, &
     256             :                                                    subcol_silhs_l_rcm_in_cloud_k_lh_start, &
     257             :                                                    subcol_silhs_l_random_k_lh_start, &
     258             :                                                    subcol_silhs_l_max_overlap_in_cloud, &
     259             :                                                    subcol_silhs_l_lh_instant_var_covar_src, &
     260             :                                                    subcol_silhs_l_lh_limit_weights, &
     261             :                                                    subcol_silhs_l_lh_var_frac, &
     262             :                                                    subcol_silhs_l_lh_normalize_weights, &
     263             :                                                    silhs_config_flags )
     264             : 
     265             :       ! Print the SILHS configurable flags
     266             :       call print_silhs_config_flags_api( iulog, silhs_config_flags ) ! Intent(in)
     267             : 
     268             : #ifdef SPMD
     269             :       ! Broadcast namelist variables
     270             :       call mpi_bcast(subcol_SILHS_weight,    1, mpi_logical, masterprocid, mpicom, ierr)
     271             :       call mpi_bcast(subcol_SILHS_numsubcol, 1, mpi_integer, masterprocid, mpicom, ierr)
     272             :       call mpi_bcast(subcol_SILHS_corr_file_path, len(subcol_SILHS_corr_file_path), &
     273             :                      mpi_character, masterprocid, mpicom, ierr)
     274             :       call mpi_bcast(subcol_SILHS_corr_file_name, len(subcol_SILHS_corr_file_name), &
     275             :                      mpi_character, masterprocid, mpicom, ierr)
     276             :       call mpi_bcast(subcol_SILHS_use_clear_col, 1, mpi_logical, masterprocid, mpicom, ierr)
     277             :       call mpi_bcast(subcol_SILHS_constrainmn, 1, mpi_logical, masterprocid, mpicom, ierr)
     278             :       call mpi_bcast(subcol_SILHS_meanice, 1, mpi_logical, masterprocid, mpicom, ierr)
     279             :       call mpi_bcast(subcol_SILHS_q_to_micro, 1, mpi_logical, masterprocid, mpicom, ierr)
     280             :       call mpi_bcast(subcol_SILHS_n_to_micro, 1, mpi_logical, masterprocid, mpicom, ierr)
     281             :       call mpi_bcast(subcol_SILHS_var_covar_src,1,mpi_logical,masterprocid, mpicom, ierr)
     282             :       call mpi_bcast(subcol_SILHS_ncnp2_on_ncnm2, 1, mpir8, masterprocid, mpicom, ierr)
     283             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_slope%rr, 1, mpir8, masterprocid, mpicom, ierr)
     284             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_slope%Nr, 1, mpir8, masterprocid, mpicom, ierr)
     285             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_slope%ri, 1, mpir8, masterprocid, mpicom, ierr)
     286             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_slope%Ni, 1, mpir8, masterprocid, mpicom, ierr)
     287             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_slope%rs, 1, mpir8, masterprocid, mpicom, ierr)
     288             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_slope%Ns, 1, mpir8, masterprocid, mpicom, ierr)
     289             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt%rr, 1, mpir8, masterprocid, mpicom, ierr)
     290             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt%Nr, 1, mpir8, masterprocid, mpicom, ierr)
     291             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt%ri, 1, mpir8, masterprocid, mpicom, ierr)
     292             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt%Ni, 1, mpir8, masterprocid, mpicom, ierr)
     293             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt%rs, 1, mpir8, masterprocid, mpicom, ierr)
     294             :       call mpi_bcast(subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt%Ns, 1, mpir8, masterprocid, mpicom, ierr)
     295             : !      call mpi_bcast(subcol_SILHS_c6rt, 1, mpir8, masterprocid, mpicom, ierr)
     296             : !      call mpi_bcast(subcol_SILHS_c7, 1, mpir8, masterprocid, mpicom, ierr)
     297             : !      call mpi_bcast(subcol_SILHS_c8, 1, mpir8, masterprocid, mpicom, ierr)
     298             : !      call mpi_bcast(subcol_SILHS_c11, 1, mpir8, masterprocid, mpicom, ierr)
     299             : !      call mpi_bcast(subcol_SILHS_c11b, 1, mpir8, masterprocid, mpicom, ierr)
     300             : !      call mpi_bcast(subcol_SILHS_gamma_coef, 1, mpir8, masterprocid, mpicom, ierr)
     301             : !      call mpi_bcast(subcol_SILHS_mult_coef, 1, mpir8, masterprocid, mpicom, ierr)
     302             : !      call mpi_bcast(subcol_SILHS_mu, 1, mpir8, masterprocid, mpicom, ierr)
     303             :       call mpi_bcast(silhs_config_flags%l_lh_importance_sampling, 1, mpi_logical, masterprocid, mpicom, ierr)
     304             :       call mpi_bcast(silhs_config_flags%l_Lscale_vert_avg, 1, mpi_logical, masterprocid, mpicom, ierr)
     305             :       call mpi_bcast(silhs_config_flags%l_lh_straight_mc, 1, mpi_logical, masterprocid, mpicom, ierr)
     306             :       call mpi_bcast(silhs_config_flags%l_lh_clustered_sampling, 1, mpi_logical, masterprocid, mpicom, ierr)
     307             :       call mpi_bcast(silhs_config_flags%l_rcm_in_cloud_k_lh_start, 1, mpi_logical, masterprocid, mpicom, ierr)
     308             :       call mpi_bcast(silhs_config_flags%l_random_k_lh_start, 1, mpi_logical, masterprocid, mpicom, ierr)
     309             :       call mpi_bcast(silhs_config_flags%l_max_overlap_in_cloud, 1, mpi_logical, masterprocid, mpicom, ierr)
     310             :       call mpi_bcast(silhs_config_flags%l_lh_instant_var_covar_src, 1, mpi_logical, masterprocid, mpicom, ierr)
     311             :       call mpi_bcast(silhs_config_flags%l_lh_limit_weights, 1, mpi_logical, masterprocid, mpicom, ierr)
     312             :       call mpi_bcast(silhs_config_flags%l_lh_var_frac, 1, mpi_logical, masterprocid, mpicom, ierr)
     313             :       call mpi_bcast(silhs_config_flags%l_lh_normalize_weights, 1, mpi_logical, masterprocid, mpicom, ierr)
     314             : 
     315             : ! SPMD
     316             : #endif
     317             : ! SILHS
     318             : #endif
     319             : ! CLUBB_SGS
     320             : #endif
     321           0 :    end subroutine subcol_readnl_SILHS
     322             : 
     323             : 
     324           0 :    subroutine subcol_init_SILHS(pbuf2d)
     325             : 
     326             :       !--------------------------------
     327             :       ! Read in parameters and initialize SILHS PDF fields.
     328             :       ! Set up indexes into Pbuf fields.
     329             :       ! Register history outputs.
     330             :       !--------------------------------
     331             : 
     332             :       use physics_buffer,          only: physics_buffer_desc, pbuf_get_field, &
     333             :                                          dtype_r8, pbuf_get_index
     334             : #ifdef CLUBB_SGS
     335             : #ifdef SILHS
     336             :       use clubb_api_module,        only: core_rknd, &
     337             :                                          pdf_dim, &
     338             :                                          setup_corr_varnce_array_api, &
     339             :                                          init_pdf_hydromet_arrays_api, &
     340             :                                          Ncnp2_on_Ncnm2, &
     341             :                                          set_clubb_debug_level_api
     342             : 
     343             : #endif
     344             : #endif
     345             : 
     346             :       type(physics_buffer_desc), pointer :: pbuf2d(:,:)
     347             : 
     348             : #ifdef CLUBB_SGS
     349             : #ifdef SILHS
     350             : 
     351             :       integer :: iunit = 501 ! Default value, will get iunit from CAM 
     352             :       !character(len=*), parameter :: default_corr_case = "arm_97"
     353             :       character(len=*), parameter :: &
     354             :             cloud_file_ext  = "_corr_array_cloud.in", & ! File extensions for corr files
     355             :             below_file_ext  = "_corr_array_below.in"
     356             :       character(len=256) :: corr_file_path_cloud, corr_file_path_below
     357             : 
     358             :       ! To set up CLUBB hydromet indices
     359             :       integer :: &
     360             :           hydromet_dim, & ! Number of enabled hydrometeors
     361             :           iirr,         & ! Hydrometeor array index for rain water mixing ratio, rr
     362             :           iirs,         & ! Hydrometeor array index for snow mixing ratio, rs
     363             :           iiri,         & ! Hydrometeor array index for ice mixing ratio, ri
     364             :           iirg,         & ! Hydrometeor array index for graupel mixing ratio, rg
     365             :           iiNr,         & ! Hydrometeor array index for rain drop concentration, Nr
     366             :           iiNs,         & ! Hydrometeor array index for snow concentration, Ns
     367             :           iiNi,         & ! Hydrometeor array index for ice concentration, Ni
     368             :           iiNg            ! Hydrometeor array index for graupel concentration, Ng
     369             : 
     370             :       integer :: l  ! Loop variable
     371             : 
     372             :       ! Set CLUBB's debug level
     373             :       ! This is called in module clubb_intr; no need to do it here.
     374             : !      call set_clubb_debug_level_api( 0 )
     375             : 
     376             :       !-------------------------------
     377             :       ! CLUBB-SILHS Parameters (global module variables)
     378             :       !-------------------------------
     379             :       clubb_config_flags%l_fix_w_chi_eta_correlations = .true.
     380             :       clubb_config_flags%l_diagnose_correlations = .false.
     381             :       clubb_config_flags%l_calc_w_corr = .false.
     382             : !      l_prescribed_avg_deltaz = .false.
     383             :       clubb_config_flags%l_use_cloud_cover = .false.
     384             :       clubb_config_flags%l_const_Nc_in_cloud = .true.
     385             : 
     386             :       ! Values from the namelist
     387             :       docldfracscaling = subcol_SILHS_use_clear_col
     388             : 
     389             :       ! Namelist "tuning" or set correlations
     390             :       ! KTC Todo: Move these to a tuning "in" file or into the namelist
     391             :       ! JHTODO: we might want these on CLUBB's API and ultimatively on a namelist for tuning
     392             : !      C6rt = subcol_SILHS_c6rt
     393             : !      C7 = subcol_SILHS_c7                                      ! to all ice clouds
     394             : !      C8 = subcol_SILHS_c8
     395             : !      C11 = subcol_SILHS_c11
     396             : !      C11b = subcol_SILHS_c11b
     397             : !      gamma_coef = subcol_SILHS_gamma_coef
     398             : !      mult_coef = subcol_SILHS_mult_coef
     399             : !      mu = subcol_SILHS_mu
     400             : 
     401             :       !call set_clubb_debug_level( 0 )  !#KTCtodo: Add a namelist variable to set debug level
     402             : 
     403             :       ! Get constituent indices
     404             :       call cnst_get_ind('Q', ixq)
     405             :       call cnst_get_ind('CLDLIQ', ixcldliq)
     406             :       call cnst_get_ind('NUMLIQ', ixnumliq)
     407             :       call cnst_get_ind('CLDICE', ixcldice)
     408             :       call cnst_get_ind('NUMICE', ixnumice)
     409             :       call cnst_get_ind('RAINQM', ixrain, abort=.false.)
     410             :       call cnst_get_ind('NUMRAI', ixnumrain, abort=.false.)
     411             :       call cnst_get_ind('SNOWQM', ixsnow, abort=.false.)
     412             :       call cnst_get_ind('NUMSNO', ixnumsnow, abort=.false.)
     413             : 
     414             :       ! Get physics buffer indexes
     415             :       thlm_idx = pbuf_get_index('THLM')
     416             :       rtm_idx = pbuf_get_index('RTM')
     417             :       cld_idx = pbuf_get_index('CLD')
     418             :       alst_idx = pbuf_get_index('ALST')  ! SILHS expects clubb's cloud_frac liq stratus fraction
     419             :       ztodt_idx = pbuf_get_index('ZTODT')
     420             :       ice_supersat_idx = pbuf_get_index('ISS_FRAC')
     421             :       tke_idx = pbuf_get_index('tke')
     422             :       kvh_idx = pbuf_get_index('kvh')
     423             :       prec_pcw_idx = pbuf_get_index('PREC_PCW')
     424             :       snow_pcw_idx = pbuf_get_index('SNOW_PCW')
     425             :       prec_str_idx = pbuf_get_index('PREC_STR')
     426             :       snow_str_idx = pbuf_get_index('SNOW_STR')
     427             :       qcsedten_idx = pbuf_get_index('QCSEDTEN')
     428             :       qrsedten_idx = pbuf_get_index('QRSEDTEN')
     429             :       qisedten_idx = pbuf_get_index('QISEDTEN')
     430             :       qssedten_idx = pbuf_get_index('QSSEDTEN')
     431             :       vtrmc_idx = pbuf_get_index('VTRMC')
     432             :       umr_idx = pbuf_get_index('UMR')
     433             :       vtrmi_idx = pbuf_get_index('VTRMI')
     434             :       ums_idx = pbuf_get_index('UMS')
     435             :       qcsevap_idx = pbuf_get_index('QCSEVAP')
     436             :       qisevap_idx = pbuf_get_index('QISEVAP')
     437             :       qrain_idx = pbuf_get_index('QRAIN')
     438             :       qsnow_idx = pbuf_get_index('QSNOW')
     439             :       nrain_idx = pbuf_get_index('NRAIN')
     440             :       nsnow_idx = pbuf_get_index('NSNOW')
     441             :      
     442             :       !-------------------------------
     443             :       ! Set up SILHS hydrometeors #KTCtodo: move microphys specification to config time,
     444             :       !        Steve wants to set up a microphysics query so I can ask the microphysics
     445             :       !        scheme which hydrometeors to use. For the future.
     446             :       !-------------------------------
     447             :       iirr = 1
     448             :       iirs = 3
     449             :       iiri  = 5
     450             :       iirg = -1
     451             : 
     452             :       iiNr    = 2
     453             :       iiNs = 4
     454             :       iiNi    = 6
     455             :       iiNg = -1
     456             : 
     457             :       hydromet_dim = 6
     458             : 
     459             :  
     460             :       ! Set up pdf indices, hydromet indicies, hydromet arrays, and hydromet variance ratios
     461             :       call init_pdf_hydromet_arrays_api( 1.0_core_rknd, 1.0_core_rknd,  & ! intent(in)
     462             :                                          hydromet_dim,                  & ! intent(in)
     463             :                                          iirr, iiri, iirs, iirg,        & ! intent(in)
     464             :                                          iiNr, iiNi, iiNs, iiNg,        & ! intent(in)
     465             :                                          subcol_SILHS_hmp2_ip_on_hmm2_ip_slope,      & ! optional(in)
     466             :                                          subcol_SILHS_hmp2_ip_on_hmm2_ip_intrcpt )     ! optional(in)
     467             : 
     468             :       Ncnp2_on_Ncnm2 = subcol_SILHS_ncnp2_on_ncnm2
     469             : 
     470             :       !-------------------------------
     471             :       ! Set up hydrometeors and correlation arrays for SILHS
     472             :       !-------------------------------
     473             :       corr_file_path_cloud = trim( subcol_SILHS_corr_file_path )//trim( subcol_SILHS_corr_file_name )//cloud_file_ext
     474             :       corr_file_path_below = trim( subcol_SILHS_corr_file_path )//trim( subcol_SILHS_corr_file_name )//below_file_ext
     475             : 
     476             :       call setup_corr_varnce_array_api( corr_file_path_cloud, corr_file_path_below, &
     477             :                                         newunit(iunit), &
     478             :                                         clubb_config_flags%l_fix_w_chi_eta_correlations )
     479             : 
     480             :       !-------------------------------
     481             :       ! Register output fields from SILHS
     482             :       !-------------------------------
     483             :       call addfld('SILHS_NCLD_SCOL', (/'psubcols', 'ilev    '/), 'I', 'm^-3', &
     484             :            'Subcolumn Cloud Number Concentration', flag_xyfill=.true., fill_value=1.e30_r8)
     485             :       call addfld('SILHS_NRAIN_SCOL', (/'psubcols', 'ilev    '/), 'I', 'm^-3', &
     486             :            'Subcolumn Number Concentration of Rain from SILHS', flag_xyfill=.true., fill_value=1.e30_r8)
     487             :       call addfld('SILHS_OMEGA_SCOL', (/'psubcols', 'ilev    '/), 'I', 'Pa/s', &
     488             :            'Subcolumn vertical pressure velocity', flag_xyfill=.true., fill_value=1.e30_r8)
     489             :       call addfld('SILHS_RCM_SCOL', (/'psubcols', 'ilev    '/), 'I', 'kg/kg', &
     490             :            'Subcolumn Cloud Liquid Water from SILHS', flag_xyfill=.true., fill_value=1.e30_r8)
     491             :       call addfld('SILHS_RICLD_SCOL', (/'psubcols', 'ilev    '/), 'I', 'kg/kg', &
     492             :            'Subcolumn Cloud Ice Water from SILHS', flag_xyfill=.true., fill_value=1.e30_r8)
     493             :       call addfld('SILHS_NICLD_SCOL', (/'psubcols', 'ilev    '/), 'I', 'kg/kg', &
     494             :            'Subcolumn Cloud Ice Number Conc from SILHS', flag_xyfill=.true., fill_value=1.e30_r8)
     495             :       call addfld('SILHS_RRAIN_SCOL', (/'psubcols', 'ilev    '/), 'I', 'kg/kg', &
     496             :            'Subcolumn Precipitating Liquid Water from SILHS', flag_xyfill=.true., fill_value=1.e30_r8)
     497             :       call addfld('SILHS_RT_SCOL', (/'psubcols', 'ilev    '/), 'I', 'kg/kg ', &
     498             :            'Subcolumn Total Water from SILHS', flag_xyfill=.true., fill_value=1.e30_r8)
     499             :       call addfld('SILHS_THLM_SCOL', (/'psubcols', 'ilev    '/), 'I', 'K', &
     500             :            'Subcolumn liquid water pot temperature', flag_xyfill=.true., fill_value=1.e30_r8)
     501             :       call addfld('SILHS_WEIGHT_SCOL', (/'psubcols'/), 'I', 'frac', &
     502             :            'Weights for each subcolumn', flag_xyfill=.true., fill_value=1.e30_r8)
     503             :       call addfld('SILHS_WM_SCOL', (/'psubcols', 'ilev    '/), 'I', 'm/s', &
     504             :            'Subcolumn vertical velocity from SILHS', flag_xyfill=.true., fill_value=1.e30_r8)
     505             : 
     506             :       call addfld('NR_IN_LH', (/ 'lev' /), 'I', 'm^-3', &
     507             :                   'Num Rain Conc as input to SILHS')
     508             :      call addfld('SILHS_RTM', (/ 'ilev' /), 'I', 'kg/kg', &
     509             :                   'Input total water mixing ratio')
     510             :      call addfld('SILHS_THLM', (/ 'ilev' /), 'I', 'K', &
     511             :                   'Input liquid water potential temperature')
     512             :      call addfld('SILHS_QC_IN', (/ 'lev' /), 'I', 'kg/kg', &
     513             :                   'Input cloud water mixing ratio')
     514             :      call addfld('SILHS_QI_IN', (/ 'lev' /), 'I', 'kg/kg', &
     515             :                   'Input cloud ice mixing ratio')
     516             :      call addfld('SILHS_NC_IN', (/ 'lev' /), 'I', '#/kg', &
     517             :                   'Input cloud water number concentration')
     518             :      call addfld('SILHS_NI_IN', (/ 'lev' /), 'I', '#/kg', &
     519             :                   'Input cloud ice number concentration')
     520             :      call addfld('AKM_CLUBB', (/ 'ilev' /), 'I', '(kg/kg)/s', &
     521             :                   'Exact Kessler autoconversion')
     522             :      call addfld('AKM_LH_CLUBB', (/ 'ilev' /), 'I', '(kg/kg)/s', &
     523             :                   'Monte Carlo estimate of Kessler autoconversion')
     524             :      call addfld('INVS_EXNER', (/ 'lev' /), 'I', 'none', &
     525             :                   'inverse EXNER function from state in subcol_SILHS')
     526             :      call addfld('SILHS_ZTODT', horiz_only, 'I', 's', & 
     527             :                   'Length of Physics timestep (for debugging)')
     528             :      if ( subcol_SILHS_constrainmn ) then
     529             :         call addfld('SILHS_MSC_CLDICE', (/ 'lev' /), 'A', 'kg/kg', &
     530             :                     'Mean Cloud Ice across subcolumns')
     531             :         call addfld('SILHS_STDSC_CLDICE', (/ 'lev' /), 'A', 'kg/kg', &
     532             :                     'Standard deviation of Ice across subcolumns')
     533             :         if ( ixsnow > 0 ) then
     534             :            call addfld('SILHS_MSC_CLDLIQ', (/ 'lev' /), 'A', 'kg/kg', &
     535             :                        'Mean Cloud Liquid across subcolumns')
     536             :            call addfld('SILHS_STDSC_CLDLIQ', (/ 'lev' /), 'A', 'kg/kg', &
     537             :                        'Standard deviation of Liquid across subcolumns')
     538             :            call addfld('SILHS_MSC_Q', (/ 'lev' /), 'A', 'kg/kg', &
     539             :                        'Mean water vapor across subcolumns')
     540             :            call addfld('SILHS_STDSC_Q', (/ 'lev' /), 'A', 'kg/kg', &
     541             :                        'Standard deviation of water vapor across subcolumns')
     542             :         endif ! ixsnow > 0
     543             :      endif ! subcol_SILHS_constrainmn
     544             :      call addfld('SILHS_EFF_CLDFRAC', (/ 'lev' /), 'A', 'frac', &
     545             :                   'Calculated cloud fraction from subcolumn liq or ice') 
     546             : 
     547             :      call addfld('SILHS_CLUBB_PRECIP_FRAC', (/ 'lev' /), 'A', 'frac', &
     548             :                   'Precipitation fraction from CLUBB (set_up_pdf_params_incl_hydromet)')
     549             :      call addfld('SILHS_CLUBB_ICE_SS_FRAC', (/ 'lev' /), 'A', 'frac', &
     550             :                   'Ice supersaturation fraction from CLUBB')
     551             : 
     552             :      call addfld ('QVHFTEN', (/ 'lev' /), 'A', 'kg/kg/s', 'Water vapor mixing ratio tendency from hole filling')
     553             :      call addfld ('QCHFTEN', (/ 'lev' /), 'A', 'kg/kg/s', 'Cloud water mixing ratio tendency from hole filling')
     554             :      call addfld ('QRHFTEN', (/ 'lev' /), 'A', 'kg/kg/s', 'Rain water mixing ratio tendency from hole filling')
     555             :      call addfld ('QIHFTEN', (/ 'lev' /), 'A', 'kg/kg/s', 'Cloud ice mixing ratio tendency from hole filling')
     556             :      call addfld ('QSHFTEN', (/ 'lev' /), 'A', 'kg/kg/s', 'Snow mixing ratio tendency from hole filling')
     557             :      call addfld ('THFTEN', (/ 'lev' /), 'A', 'K/s', 'Temperature tendency from hole filling')
     558             : 
     559             : #endif
     560             : #endif
     561           0 :    end subroutine subcol_init_SILHS
     562             : !==============================================================!
     563           0 :    subroutine init_state_subcol(state, tend, state_sc, tend_sc)
     564             :      
     565           0 :      use ppgrid,                 only : pver, pverp, pcols
     566             :      
     567             :      use subcol_utils,           only : subcol_set_subcols
     568             :      
     569             :      implicit none
     570             :      
     571             :      type(physics_state), intent(inout) :: state
     572             :      type(physics_tend),  intent(inout) :: tend
     573             :      type(physics_state), intent(inout) :: state_sc        ! sub-column state
     574             :      type(physics_tend),  intent(inout) :: tend_sc         ! sub-column tend
     575             :      
     576             :      integer, dimension(pcols) :: numsubcol_arr ! To set up the state struct
     577             :      
     578           0 :      numsubcol_arr(:) = 0  ! Start over each chunk
     579           0 :      numsubcol_arr(:state%ngrdcol) = subcol_SILHS_numsubcol ! Only set for valid grid columns
     580           0 :      call subcol_set_subcols(state, tend, numsubcol_arr, state_sc, tend_sc)
     581             :      
     582           0 :    end subroutine init_state_subcol
     583             : !==================================================================!
     584           0 :    subroutine subcol_gen_SILHS(state, tend, state_sc, tend_sc, pbuf)
     585             :       !-------------------------------
     586             :       ! This is where the subcolumns are created, and the call to
     587             :       !      generate_silhs_sample_mod_api
     588             :       !    goes out. Variables needed to make this call are pulled from the 
     589             :       !    pbuf, from module data, and calculated based on the CAM state.
     590             :       !-------------------------------
     591             : 
     592           0 :       use physics_buffer,         only : physics_buffer_desc, pbuf_get_index, &
     593             :                                          pbuf_get_field
     594             :       use time_manager,           only : get_nstep
     595             :       use subcol_utils,           only : subcol_set_subcols, subcol_set_weight
     596             :       use subcol_pack_mod,        only : subcol_pack
     597             :       use phys_control,           only : phys_getopts
     598             :       use spmd_utils,             only : masterproc
     599             :       use shr_const_mod,          only : SHR_CONST_PI, SHR_CONST_RHOFW
     600             : 
     601             : #ifdef CLUBB_SGS
     602             : #ifdef SILHS
     603             :       use clubb_api_module,       only : hydromet_dim, &
     604             : 
     605             :                                          setup_pdf_parameters_api, &
     606             : 
     607             :                                          hydromet_pdf_parameter, &
     608             : 
     609             :                                          zm2zt_api, setup_grid_heights_api, &
     610             : 
     611             :                                          iirr, iiNr, iirs, iiri, &
     612             :                                          iirg, iiNs, &
     613             :                                          iiNi, iiNg, &
     614             : 
     615             :                                          core_rknd, &
     616             : 
     617             :                                          w_tol_sqd, zero_threshold, &
     618             :                                          em_min, cloud_frac_min, & ! rc_tol, &
     619             : 
     620             :                                          pdf_dim, &
     621             :                                          corr_array_n_cloud, &
     622             :                                          corr_array_n_below, &
     623             :                                          iiPDF_chi, iiPDF_rr, &
     624             :                                          iiPDF_w, iiPDF_Nr, &
     625             :                                          iiPDF_ri, iiPDF_Ni, &
     626             :                                          iiPDF_Ncn, iiPDF_rs, iiPDF_Ns, &
     627             : 
     628             :                                          genrand_intg, genrand_init_api, &
     629             : 
     630             :                                          nparams, ic_K, &
     631             :                                          read_parameters_api, &
     632             :                                          Cp, Lv, &
     633             :                                          grid, setup_grid_api, &
     634             :                                          init_precip_fracs_api
     635             :    
     636             :       use silhs_api_module, only :       generate_silhs_sample_api, & ! Ncn_to_Nc, &
     637             :                                          clip_transform_silhs_output_api, &
     638             :                                          est_kessler_microphys_api, &
     639             :                                          vert_decorr_coef
     640             : 
     641             : #endif
     642             : #endif
     643             :       
     644             :       ! CAM data structures
     645             :       type(physics_state), intent(inout) :: state
     646             :       type(physics_tend),  intent(inout) :: tend
     647             :       type(physics_state), intent(inout) :: state_sc        ! sub-column state
     648             :       type(physics_tend),  intent(inout) :: tend_sc         ! sub-column tend
     649             :       type(physics_buffer_desc), pointer :: pbuf(:)
     650             : 
     651             : #ifdef CLUBB_SGS
     652             : #ifdef SILHS
     653             :       !----------------
     654             :       ! Local variables
     655             :       !----------------
     656             :       logical, parameter :: &
     657             :                  l_implemented = .true.   ! Implemented in a host model
     658             :       logical, parameter :: rx_Nc = .false. ! Use NC calculated based on grid mean effective radius
     659             :       integer, parameter :: &
     660             :                  grid_type = 3            ! The 3 grid centered on momentum levels
     661             :       real(r8), parameter :: cldmin = 0.001_r8 ! To use when cld frac = 0.0 to be consistant with micro_mg
     662             :       real(r8), parameter :: min_num_conc = 1.0e-12_r8
     663             :       real(r8), parameter :: qsmall = 1.0e-18_r8  ! Microphysics cut-off for cloud
     664             : 
     665             :       integer :: i, j, k, ngrdcol, ncol, lchnk, stncol
     666             :       real(r8) :: sfc_elevation(state%ngrdcol)  ! Surface elevation
     667             :       
     668             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: zt_g, zi_g ! Thermo & Momentum grids for clubb
     669             :       
     670             :       real(r8), dimension(pverp) :: scfrac     ! cloud fraction based on sc distributions
     671             :       real(r8) :: msc, std, maxcldfrac, maxsccldfrac
     672             :       real(r8) :: scale = 1.0_r8
     673             : 
     674             :       real(r8) :: c_K ! CLUBB parameter c_K (for eddy diffusivity)
     675             : 
     676             :       integer( kind = genrand_intg ) :: &
     677             :         lh_seed    ! Seed used in random number generator that will be different
     678             :                    ! for each column, yet reproducible for a restart run
     679             : 
     680             :       !----------------
     681             :       ! Required for set_up_pdf_params_incl_hydromet
     682             :       !----------------
     683             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: cld_frac_in  ! Cloud fraction
     684             :                                     
     685             :       real(r8), dimension(state%ngrdcol, pverp-top_lev+1, pdf_dim, pdf_dim) :: &       
     686             :                           corr_array_1, corr_array_2  ! Correlation matrix for pdf components
     687             :                                     
     688             :       real(r8), dimension(state%ngrdcol, pverp-top_lev+1, pdf_dim) :: &
     689             :                           mu_x_1, mu_x_2, &    ! Mean array for PDF components
     690             :                           sigma_x_1, sigma_x_2 ! Std dev arr for PDF components
     691             :                                     
     692             :       real(r8), dimension(state%ngrdcol, pverp-top_lev+1, pdf_dim, pdf_dim) :: &       
     693             :                           corr_cholesky_mtx_1, corr_cholesky_mtx_2  ! Transposed corr cholesky mtx
     694             :                                     
     695             :       real(r8), dimension(state%ngrdcol, pverp-top_lev+1) :: Nc_in_cloud
     696             :       real(r8), dimension(state%ngrdcol, pverp-top_lev+1) :: ice_supersat_frac_in
     697             :       real(r8), dimension(state%ngrdcol, pverp-top_lev+1, hydromet_dim) :: hydrometp2
     698             : 
     699             : 
     700             :       !----------------
     701             :       ! Input to generate_silhs_sample
     702             :       !----------------
     703             :       integer :: iter                            ! CLUBB iteration 
     704             :       integer :: num_subcols                     ! Number of subcolumns
     705             :       integer, parameter :: sequence_length = 1  ! Number of timesteps btn subcol calls
     706             :       
     707             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: rho_ds_zt    ! Dry static density (kg/m^3) on thermo levs
     708             :       real(r8), dimension(state%ngrdcol,pver)  :: dz_g         ! thickness of layer
     709             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: delta_zm     ! Difference in u wind altitudes
     710             :       
     711             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1,hydromet_dim) :: hydromet  ! Hydrometeor species
     712             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1,hydromet_dim) :: wphydrometp  ! Hydrometeor flux
     713             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1)              :: Ncm ! Mean cloud droplet concentration, <N_c>
     714             : 
     715             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: tke       ! TKE
     716             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: khzm      ! Eddy diffusivity coef
     717             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: Lscale_zm ! CLUBB's length scale on momentum (zm) levels
     718             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: Lscale    ! CLUBB's length scale
     719             : 
     720             :       logical, parameter :: &  
     721             :          l_calc_weights_all_levs = .false. ! .false. if all time steps use the same
     722             :                                           !   weights at all vertical grid levels 
     723             :       logical :: & 
     724             :         l_calc_weights_all_levs_itime, & ! .true. if we calculate sample weights separately at all 
     725             :                                          !    grid levels at the current time step   
     726             :         l_rad_itime                      ! .true. if we calculate radiation at the current time step  
     727             : 
     728             :       !---------------
     729             :       !Output from generate_silhs_sample
     730             :       !--------------
     731             :       real(r8), dimension(state%ngrdcol,subcol_SILHS_numsubcol,pverp-top_lev+1,pdf_dim) :: X_nl_all_levs ! Sample transformed to normal-lognormal
     732             :       real(r8), dimension(state%ngrdcol,subcol_SILHS_numsubcol,pverp-top_lev+1)   :: lh_sample_point_weights ! Subcolumn weights
     733             :       integer, dimension(state%ngrdcol,subcol_SILHS_numsubcol,pverp-top_lev+1)    :: X_mixt_comp_all_levs ! Which Mixture Component
     734             : 
     735             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1, subcol_SILHS_numsubcol) :: &
     736             :                   rc_all_points, & ! Calculate RCM from LH output
     737             :                   rain_all_pts,  & ! Calculate Rain from LH output
     738             :                   nrain_all_pts, & ! Calculate Rain Conc from LH
     739             :                   snow_all_pts,  & ! Calculate Snow from LH output
     740             :                   nsnow_all_pts, & ! Calculate Snow Conc from LH
     741             :                   w_all_points,  & ! Calculate W from LH output
     742             :                   ice_all_pts,   & ! Calculate Cld Ice from LH output
     743             :                   nice_all_pts,  & ! Calculate Num cld ice from LH
     744             :                   nclw_all_pts     ! Calculate Num cld wat from LH
     745             : 
     746             :       !----------------
     747             :       ! Output from clip_transform_silhs_output_api
     748             :       !----------------
     749             :       real( kind = core_rknd ), dimension(state%ngrdcol,subcol_SILHS_numsubcol,pverp-top_lev+1) :: &
     750             :         lh_rt_clipped,  & ! rt generated from silhs sample points
     751             :         lh_thl_clipped, & ! thl generated from silhs sample points
     752             :         lh_rc_clipped,  & ! rc generated from silhs sample points
     753             :         lh_rv_clipped,  & ! rv generated from silhs sample points
     754             :         lh_Nc_clipped     ! Nc generated from silhs sample points
     755             : 
     756             :       logical, parameter :: &
     757             :         l_use_Ncn_to_Nc = .true.  ! Whether to call Ncn_to_Nc (.true.) or not (.false.);
     758             :                                   ! Ncn_to_Nc might cause problems with the MG microphysics 
     759             :                                   ! since the changes made here (Nc-tendency) are not fed into 
     760             :                                   ! the microphysics
     761             :         
     762             : 
     763             :       !----------------
     764             :       ! Output to history
     765             :       !----------------
     766             :       ! V. Larson note: These variables are on the zt (full) levels: why do they
     767             :       ! have dimension pverp?  The pverp level corresponds to the CLUBB
     768             :       ! below-ground level.
     769             :       ! The variables in this paragraph are oriented like CAM variables (k=1 is
     770             :       ! the model top).
     771             :       ! They are flipped versions of CLUBB variables, for the entire chunk.
     772             :       real(r8), dimension(pcols*psubcols, pverp) :: RT_lh_out
     773             :       real(r8), dimension(pcols*psubcols, pverp) :: THL_lh_out
     774             :       real(r8), dimension(pcols*psubcols, pverp) :: OMEGA_lh_out
     775             :       real(r8), dimension(pcols*psubcols, pverp) :: WM_lh_out
     776             :       real(r8), dimension(pcols*psubcols, pverp) :: RVM_lh_out
     777             :       real(r8), dimension(pcols*psubcols, pverp) :: RCM_lh_out
     778             :       real(r8), dimension(pcols*psubcols, pverp) :: NCLW_lh_out
     779             :       real(r8), dimension(pcols*psubcols, pverp) :: ICE_lh_out
     780             :       real(r8), dimension(pcols*psubcols, pverp) :: NICE_lh_out
     781             :       real(r8), dimension(pcols*psubcols, pverp) :: RAIN_lh_out
     782             :       real(r8), dimension(pcols*psubcols, pverp) :: NRAIN_lh_out
     783             :       real(r8), dimension(pcols*psubcols, pverp) :: SNOW_lh_out
     784             :       real(r8), dimension(pcols*psubcols, pverp) :: NSNOW_lh_out
     785             : 
     786             :       real(r8), dimension(state_sc%psetcols) :: weights ! Subcol weights
     787             : 
     788             :       real(r8), dimension(pcols, pver) :: meansc_ice
     789             :       real(r8), dimension(pcols, pver) :: stdsc_ice
     790             : 
     791             :       real(r8), dimension(pcols, pver) :: meansc_liq
     792             :       real(r8), dimension(pcols, pver) :: stdsc_liq
     793             : 
     794             :       real(r8), dimension(pcols, pver) :: meansc_vap
     795             :       real(r8), dimension(pcols, pver) :: stdsc_vap
     796             :       real(r8), dimension(pcols, pver) :: grmn_eff_rad
     797             :       real(r8), dimension(pcols, pver) :: eff_cldfrac
     798             :       real(r8), dimension(pcols, pver) :: precip_frac_out
     799             : 
     800             :       real(r8) :: tmp_mean, diff_mean, rcubed
     801             : 
     802             :       !----------------
     803             :       ! Output from Est_Kessler_microphys
     804             :       !----------------
     805             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: lh_Akm     ! Monte Carlo estimate of Kessler Autoconversion
     806             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: AKm        ! Exact Kessler autoconversion
     807             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: AKstd      ! Exact Stdev of gba Kessler
     808             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: AKstd_cld  ! Exact w/in cloud stdev of gba Kessler
     809             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: AKm_rcm    ! Exact local gba Kessler auto based on rcm
     810             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: AKm_rcc    ! Exact local gba Kessler based on w/in cloud rc
     811             :       real(r8), dimension(state%ngrdcol,pverp-top_lev+1) :: lh_rcm_avg ! LH estimate of grid box avg liquid water
     812             :       real(r8), dimension(pcols,pverp) :: lh_AKm_out, AKm_out
     813             : 
     814             :       !----------------
     815             :       ! Needed to update State
     816             :       !----------------
     817             :       real(r8), dimension(pver)  :: Temp_prof  ! Subcolumn LWPT converted to Abs Temp
     818             :       real(r8), dimension(pver)  :: SE_prof    ! Static Energy calculated from Abs Temp
     819             :       real(r8), dimension(pver)  :: No_cloud = 0.0_r8     ! Clear air condensate profile
     820             :       real(r8), dimension(pcols, pver)  :: invs_exner  ! inverse exner sent to conversion codw
     821             :                                                        ! pcols for output to history
     822             :       real(r8) :: eff_rad_coef = 1.0_r8/(4.0_r8/3.0_r8*SHR_CONST_RHOFW*SHR_CONST_PI)
     823             :      
     824             :       !----------------
     825             :       ! Pointers
     826             :       !----------------
     827             :       real(r8), pointer, dimension(:) :: ztodt_ptr
     828             :       real(r8), pointer, dimension(:,:) :: thlm      ! Mean temperature
     829             :       real(r8), pointer, dimension(:,:) :: ice_supersat_frac ! ice cloud fraction
     830             :       real(r8), pointer, dimension(:,:) :: rtm       ! mean moisture mixing ratio
     831             :       real(r8), pointer, dimension(:,:) :: cld       ! CAM cloud fraction
     832             :       real(r8), pointer, dimension(:,:) :: alst      ! CLUBB liq cloud fraction
     833             :       real(r8), pointer, dimension(:,:) :: qrain     ! micro_mg rain from previous step
     834             :       real(r8), pointer, dimension(:,:) :: qsnow     
     835             :       real(r8), pointer, dimension(:,:) :: nrain     ! micro_mg rain num conc 
     836             :       real(r8), pointer, dimension(:,:) :: nsnow
     837             : 
     838             :       real(r8), pointer, dimension(:,:) :: tke_in    ! TKE
     839             :       real(r8), pointer, dimension(:,:) :: khzm_in   ! Eddy diffusivity coef
     840             :       
     841             :       logical, parameter :: l_est_kessler_microphys = .false.
     842             :       logical, parameter :: l_outfld_subcol         = .false.
     843             :       
     844             :       type(grid) :: gr
     845             :       
     846             :       type(precipitation_fractions) :: precip_fracs      
     847             :       
     848             :       !------------------------------------------------
     849             :       !                     Begin Code
     850             :       !------------------------------------------------
     851             :       
     852             : #ifdef SILHS_OPENACC
     853             :       if ( l_est_kessler_microphys ) then
     854             :         call endrun('subcol_gen error: compilation with OpenACC requires l_est_kessler_microphys = .false.')
     855             :       end if
     856             :       
     857             :       if ( subcol_SILHS_constrainmn ) then
     858             :         call endrun('subcol_gen error: compilation with OpenACC requires subcol_SILHS_constrainmn = .false.')
     859             :       end if
     860             :       
     861             :       if ( subcol_SILHS_weight ) then
     862             :         call endrun('subcol_gen error: Importance sampling is not enabled for SILHS when using OpenACC. Set subcol_SILHS_weight to false.')
     863             :       end if
     864             : #endif
     865             : 
     866             :       if (.not. allocated(state_sc%lat)) then
     867             :          call endrun('subcol_gen error: state_sc must be allocated before calling subcol_gen')
     868             :       end if
     869             :       
     870             :       if( rx_Nc ) then
     871             :          call endrun('subcol_gen_SILHS: rx_Nc not enabled')
     872             :       endif
     873             :       
     874             :       if (subcol_SILHS_meanice) then
     875             :         call endrun('subcol_gen_SILHS: subcol_SILHS_meanice = T not currently available')
     876             :       end if
     877             : 
     878             :       ! Determine num of columns and which chunk we're working on and what timestep
     879             :       ngrdcol = state%ngrdcol
     880             :       ncol = state%ncol
     881             :       lchnk = state%lchnk
     882             :       iter = get_nstep() ! #KTCtodo: The model iteration is passed into SILHS without taking
     883             :                          !           substepping into account. I may need to change this in 
     884             :                          !           the future. Also, why does SILHS need an iter, but CLUBB
     885             :                          !           does not?
     886             :                          ! #ERDBG:   The model iteration number is not used in SILHS unless
     887             :                          !           sequence_length > 1, but nobody runs with that option.
     888             :       !----------------
     889             :       ! Establish associations between pointers and physics buffer fields
     890             :       !----------------
     891             :       call pbuf_get_field(pbuf, thlm_idx, thlm)
     892             :       call pbuf_get_field(pbuf, ztodt_idx, ztodt_ptr)
     893             :       call pbuf_get_field(pbuf, ice_supersat_idx, ice_supersat_frac)
     894             :       call pbuf_get_field(pbuf, rtm_idx, rtm)
     895             :       call pbuf_get_field(pbuf, alst_idx, alst)
     896             :       call pbuf_get_field(pbuf, cld_idx, cld)
     897             :       call pbuf_get_field(pbuf, qrain_idx, qrain)
     898             :       call pbuf_get_field(pbuf, qsnow_idx, qsnow)
     899             :       call pbuf_get_field(pbuf, nrain_idx, nrain)
     900             :       call pbuf_get_field(pbuf, nsnow_idx, nsnow)
     901             :       call pbuf_get_field(pbuf, tke_idx, tke_in)
     902             :       call pbuf_get_field(pbuf, kvh_idx, khzm_in)
     903             : 
     904             :       ! Pull c_K from clubb parameters.
     905             :       c_K = clubb_params(ic_K)
     906             : 
     907             :       !----------------
     908             :       ! Copy state and populate numbers and values of sub-columns
     909             :       !----------------
     910             :       ztodt = ztodt_ptr(1)
     911             :       num_subcols = subcol_SILHS_numsubcol
     912             : 
     913             :       ! The number of vertical grid levels used in CLUBB is pverp, which is originally
     914             :       ! set in the call to setup_clubb_core_api from subroutine clubb_ini_cam.  This
     915             :       ! is stored in CLUBB in the object gr%nz.  This isn't changed in CLUBB.
     916             :       ! However, when SILHS is used, SILHS only uses pverp - top_lev + 1 vertical grid
     917             :       ! levels and also uses the gr%nz object.  The value of gr%nz needs to be reset
     918             :       ! for SILHS here and then set again for CLUBB in subroutine clubb_tend_cam.
     919             :       gr%nz = pverp - top_lev + 1
     920             :       
     921             :       ! Calculate sample weights separately at all grid levels when
     922             :       ! radiation is not called  
     923             :       l_calc_weights_all_levs_itime = .false. ! subcol_utils cannot compute weighted avgs
     924             :                                               !   when the weights vary with height.   
     925             :                                               !   Don't set to true until this is fixed!!
     926             : 
     927             :          
     928             :       ! Setup the CLUBB vertical grid object. This must be done for each
     929             :       ! column as the z-distance between hybrid pressure levels can 
     930             :       ! change easily.
     931             :       ! Define the CLUBB momentum grid (in height, units of m)
     932             :       do k = 1, pverp-top_lev+1
     933             :         do i = 1, ngrdcol
     934             :           zi_g(i,k) = state%zi(i,pverp-k+1)-state%zi(i,pverp)
     935             :         end do
     936             :       end do
     937             :         
     938             :       
     939             :       ! Define the CLUBB thermodynamic grid (in units of m)
     940             :       do k = 1, pver-top_lev+1
     941             :         do i = 1, ngrdcol
     942             :           zt_g(i,k+1) = state%zm(i,pver-k+1)-state%zi(i,pverp)
     943             :           
     944             :           ! Thermodynamic ghost point is below surface
     945             :           zt_g(i,1) = -1._r8*zt_g(i,2)
     946             :         end do
     947             :       end do
     948             :       
     949             :       do i=1, ncol
     950             :         !  Set the elevation of the surface
     951             :         sfc_elevation(i) = state%zi(i,pver+1)
     952             :       end do
     953             :       
     954             :       !  Heights need to be set at each timestep.
     955             :       call setup_grid_api( pverp+1-top_lev, ncol, sfc_elevation(1:ncol), l_implemented,  & ! intent(in)
     956             :                            grid_type, zi_g(1:ncol,2), zi_g(1:ncol,1), zi_g(1:ncol,pverp+1-top_lev),   & ! intent(in)
     957             :                            zi_g(1:ncol,:), zt_g(1:ncol,:),                              & ! intent(in)
     958             :                            gr )        
     959             :          
     960             :       ! Calculate the distance between grid levels on the host model grid,
     961             :       ! using host model grid indices.
     962             :       do k = top_lev, pver
     963             :         do i = 1, ngrdcol
     964             :           dz_g(i,k) = state%zi(i,k)-state%zi(i,k+1)
     965             :         end do
     966             :       end do
     967             :         
     968             :       ! Inverse delta_zm is required for the 3-level L-scale averaging
     969             :       do k = 1, pver-top_lev+1
     970             :         do i = 1, ngrdcol
     971             :           delta_zm(i,k+1) = state%zi(i,pverp-k)-state%zi(i,pverp-k+1)
     972             :           
     973             :           ! Handle CLUBB sub-sfc ghost point as done in clubb grid_class.F90
     974             :           delta_zm(i,1) = delta_zm(i,2) 
     975             :         end do
     976             :       end do
     977             :        
     978             :       ! Compute dry static density on CLUBB vertical grid
     979             :       do k = 1, pver-top_lev+1
     980             :         do i = 1, ngrdcol
     981             :           rho_ds_zt(i,k+1) = (rga)*state%pdel(i,pverp-k)/dz_g(i,pverp-k)
     982             :           
     983             :           ! CLUBB ghost point under the surface
     984             :           rho_ds_zt(i,1) = rho_ds_zt(i,2)
     985             :         end do
     986             :       end do
     987             :        
     988             :       ! Set up hydromet array, flipped from CAM vert grid to CLUBB
     989             :       if ( iirr > 0 ) then
     990             :         ! If ixrain and family are greater than zero, then MG2 is
     991             :         ! being used, and rain and snow are part of state. Otherwise,
     992             :         ! diagnostic rain and snow from MG1 are used in hydromet.
     993             :         if (ixrain > 0) then
     994             :           do k = 1, pver-top_lev+1
     995             :             do i = 1, ngrdcol
     996             :               hydromet(i,k+1,iirr) = state%q(i,pver-k+1,ixrain)
     997             :             end do
     998             :           end do
     999             :         else
    1000             :           do k = 1, pver-top_lev+1
    1001             :             do i = 1, ngrdcol
    1002             :               hydromet(i,k+1,iirr) = qrain(i,pver-k+1)
    1003             :             end do
    1004             :           end do
    1005             :         endif
    1006             :       endif
    1007             :       
    1008             :       if ( iiNr > 0 ) then
    1009             :         if (ixnumrain > 0) then
    1010             :           do k = 1, pver-top_lev+1
    1011             :             do i = 1, ngrdcol
    1012             :               hydromet(i,k+1,iiNr) = state%q(i,pver-k+1,ixnumrain)
    1013             :             end do
    1014             :           end do
    1015             :         else
    1016             :           do k = 1, pver-top_lev+1
    1017             :             do i = 1, ngrdcol
    1018             :               hydromet(i,k+1,iiNr) = nrain(i,pver-k+1)
    1019             :             end do
    1020             :           end do
    1021             :         endif
    1022             :       endif
    1023             :           
    1024             :       if ( iirs > 0 ) then
    1025             :         if (ixsnow > 0) then
    1026             :           do k = 1, pver-top_lev+1
    1027             :             do i = 1, ngrdcol
    1028             :               hydromet(i,k+1,iirs) = state%q(i,pver-k+1,ixsnow)
    1029             :             end do
    1030             :           end do
    1031             :         else
    1032             :           do k = 1, pver-top_lev+1
    1033             :             do i = 1, ngrdcol
    1034             :               hydromet(i,k+1,iirs) = qsnow(i,pver-k+1)
    1035             :             end do
    1036             :           end do
    1037             :         endif
    1038             :       endif
    1039             :           
    1040             :       if ( iiNs > 0 ) then
    1041             :         if (ixnumsnow > 0) then
    1042             :           do k = 1, pver-top_lev+1
    1043             :             do i = 1, ngrdcol
    1044             :               hydromet(i,k+1,iiNs) = state%q(i,pver-k+1,ixnumsnow)
    1045             :             end do
    1046             :           end do
    1047             :         else
    1048             :           do k = 1, pver-top_lev+1
    1049             :             do i = 1, ngrdcol
    1050             :               hydromet(i,k+1,iiNs) = nsnow(i,pver-k+1)
    1051             :             end do
    1052             :           end do
    1053             :         endif
    1054             :       endif
    1055             :           
    1056             :       if ( iiri > 0 ) then
    1057             :         do k = 1, pver-top_lev+1
    1058             :           do i = 1, ngrdcol
    1059             :             hydromet(i,k+1,iiri) = state%q(i,pver-k+1,ixcldice)
    1060             :           end do
    1061             :         end do
    1062             :       endif
    1063             :           
    1064             :       if ( iiNi > 0 ) then
    1065             :         do k = 1, pver-top_lev+1
    1066             :           do i = 1, ngrdcol
    1067             :             hydromet(i,k+1,iiNi) = state%q(i,pver-k+1,ixnumice)
    1068             :           end do
    1069             :         end do
    1070             :       endif
    1071             :       
    1072             :       do k = 1, hydromet_dim ! ghost point below the surface
    1073             :         do i = 1, ngrdcol
    1074             :           hydromet(i,1,k) = hydromet(i,2,k)                  
    1075             :         end do
    1076             :       end do
    1077             :    
    1078             :       do k = 1, pver-top_lev+1
    1079             :         do i = 1, ngrdcol
    1080             :           Ncm(i,k+1) = state%q(i,pver-k+1,ixnumliq)
    1081             :           Ncm(i,1) = Ncm(i,2)
    1082             :        end do
    1083             :       end do
    1084             :        
    1085             :       ! Convert from CAM vertical grid to CLUBB
    1086             :       do k = 1, pverp-top_lev+1 
    1087             :         do i = 1, ngrdcol
    1088             :           ice_supersat_frac_in(i,k) = ice_supersat_frac(i,pverp-k+1)
    1089             :         end do
    1090             :       end do
    1091             :         
    1092             :       
    1093             :       do k = 1, pver-top_lev+1
    1094             :         do i = 1, ngrdcol
    1095             :           cld_frac_in(i,k+1) = alst(i,pver-k+1)
    1096             :           cld_frac_in(i,1) = cld_frac_in(i,2) ! Ghost pt below surface
    1097             :         end do
    1098             :       end do
    1099             :         
    1100             :       ! Calculate a clubb-specific exner function
    1101             :       ! (This is grid mean, as pressure levels do not change in 
    1102             :       !  the subcolumn state)
    1103             :       do k = 1, pver-top_lev+1
    1104             :         do i = 1, ngrdcol
    1105             :           invs_exner(i,k) = ((state%pmid(i,k)/p0_clubb)**(cappa))
    1106             :         end do
    1107             :       end do
    1108             :      
    1109             :       ! Call setup_pdf_parameters to get the CLUBB PDF ready for SILHS
    1110             :       ! Compute Num concentration of cloud nuclei
    1111             :       do k = 1, pverp-top_lev+1 
    1112             :         do i = 1, ngrdcol
    1113             :           Nc_in_cloud(i,k) = Ncm(i,k) / max( cld_frac_in(i,k), cloud_frac_min )
    1114             :         end do
    1115             :       end do
    1116             : 
    1117             :       ! The variable wphydrometp is only used when l_calc_w_corr is enabled.
    1118             :       ! The l_calc_w_corr flag is turned off by default, so wphydrometp will
    1119             :       ! simply be set to 0 to simplify matters.
    1120             :       wphydrometp = 0.0_r8
    1121             : 
    1122             :       do k = 1, pverp-top_lev+1
    1123             :         do i = 1, ngrdcol
    1124             :           khzm(i,k) = khzm_in(i,pverp-k+1)
    1125             :         end do
    1126             :       end do
    1127             :       
    1128             :       ! Allocate 2D arrays in precip_fracs for all grid columns and vertical levels
    1129             :       call init_precip_fracs_api( pverp-top_lev+1, ngrdcol, &
    1130             :                                   precip_fracs )
    1131             :        
    1132             :       call setup_pdf_parameters_api( gr, pverp-top_lev+1, ngrdcol, pdf_dim, ztodt, &    ! In
    1133             :                                      Nc_in_cloud, cld_frac_in, khzm, &                  ! In
    1134             :                                      ice_supersat_frac_in, hydromet, wphydrometp, &     ! In
    1135             :                                      corr_array_n_cloud, corr_array_n_below, &          ! In
    1136             :                                      pdf_params_chnk(lchnk), &                          ! In
    1137             :                                      clubb_params, &                                    ! In
    1138             :                                      clubb_config_flags%iiPDF_type, &                   ! In
    1139             :                                      clubb_config_flags%l_use_precip_frac, &            ! In
    1140             :                                      clubb_config_flags%l_predict_upwp_vpwp, &          ! In
    1141             :                                      clubb_config_flags%l_diagnose_correlations, &      ! In
    1142             :                                      clubb_config_flags%l_calc_w_corr, &                ! In
    1143             :                                      clubb_config_flags%l_const_Nc_in_cloud, &          ! In
    1144             :                                      clubb_config_flags%l_fix_w_chi_eta_correlations, & ! In
    1145             :                                      stats_metadata, &                                  ! In
    1146             :                                      stats_zt, stats_zm, stats_sfc, &                   ! In
    1147             :                                      hydrometp2, &                                      ! Inout
    1148             :                                      mu_x_1, mu_x_2, &                                  ! Out
    1149             :                                      sigma_x_1, sigma_x_2, &                            ! Out
    1150             :                                      corr_array_1, corr_array_2, &                      ! Out
    1151             :                                      corr_cholesky_mtx_1, corr_cholesky_mtx_2, &        ! Out
    1152             :                                      precip_fracs )                                     ! Inout
    1153             :       
    1154             :       ! In order for Lscale to be used properly, it needs to be passed out of
    1155             :       ! advance_clubb_core, saved to the pbuf, and then pulled out of the
    1156             :       ! pbuf for use here.  The profile of Lscale is passed into subroutine
    1157             :       ! generate_silhs_sample_api for use in calculating the vertical
    1158             :       ! correlation coefficient.  Rather than output Lscale directly, its
    1159             :       ! value can be calculated from other fields that are already output to
    1160             :       ! pbuf.  The equation relating Lscale to eddy diffusivity is:
    1161             :       !
    1162             :       ! Kh = c_K * Lscale * sqrt( TKE ).
    1163             :       !
    1164             :       ! Both Kh and TKE are written to the pbuf, and c_K is easily extracted
    1165             :       ! from CLUBB's tunable parameters.  The equation for Lscale is:
    1166             :       !
    1167             :       ! Lscale = Kh / ( c_K * sqrt( TKE ) ).
    1168             :       !
    1169             :       ! Since Kh and TKE are output on momentum (interface) grid levels, the
    1170             :       ! resulting calculation of Lscale is also found on momentum levels.  It
    1171             :       ! needs to be interpolated back to thermodynamic (midpoint) grid levels
    1172             :       ! for further use.
    1173             :       do k = 1, pverp-top_lev+1
    1174             :         do i = 1, ngrdcol
    1175             :           tke(i,k) = tke_in(i,pverp-k+1)
    1176             :         end do
    1177             :       end do
    1178             :       
    1179             :       do k = 1, pverp-top_lev+1
    1180             :         do i = 1, ngrdcol
    1181             :           Lscale_zm(i,k) = khzm(i,k) / ( c_K * sqrt( max( tke(i,k), em_min ) ) )
    1182             :         end do
    1183             :       end do
    1184             : 
    1185             :       do i = 1, ngrdcol
    1186             :         Lscale(i,1) = Lscale_zm(i,1) + ( Lscale_zm(i,2) - Lscale_zm(i,1) ) &
    1187             :                                      * ( zt_g(i,1) - zi_g(i,1) ) / ( zi_g(i,2) - zi_g(i,1) )
    1188             :       end do
    1189             :      
    1190             :       do k = 2, pverp-top_lev+1
    1191             :         do i = 1, ngrdcol
    1192             :           Lscale(i,k) = Lscale_zm(i,k-1) + ( Lscale_zm(i,k) - Lscale_zm(i,k-1) ) &
    1193             :                                          * ( zt_g(i,k) - zi_g(i,k-1) ) / ( zi_g(i,k) - zi_g(i,k-1) )
    1194             :         end do
    1195             :       end do
    1196             :      
    1197             :       do k = 2, pverp-top_lev+1
    1198             :         do i = 1, ngrdcol
    1199             :           Lscale(i,:) = max( Lscale(i,:), 0.01_r8 )
    1200             :         end do
    1201             :       end do
    1202             :       
    1203             :       !$acc data create( X_mixt_comp_all_levs, X_nl_all_levs, lh_rc_clipped, lh_Nc_clipped, &
    1204             :       !$acc&             lh_sample_point_weights, lh_rt_clipped, lh_rt_clipped, &
    1205             :       !$acc&             lh_rv_clipped, lh_thl_clipped, THL_lh_out, &
    1206             :       !$acc&             RT_lh_out, RCM_lh_out, NCLW_lh_out, ICE_lh_out, &
    1207             :       !$acc&             NICE_lh_out, RVM_lh_out, THL_lh_out, RAIN_lh_out, &
    1208             :       !$acc&             NRAIN_lh_out, SNOW_lh_out, NSNOW_lh_out, WM_lh_out, &
    1209             :       !$acc&             OMEGA_lh_out ) &
    1210             :       !$acc&     copyin( state, state%zm, state%phis, rho_ds_zt, invs_exner ) &
    1211             :       !$acc&     copyout( state%t, state%s, state%omega, state_sc%q )
    1212             :       !$acc& async(1)
    1213             :       
    1214             :       ! Set the seed to the random number generator based on a quantity that
    1215             :       ! will be reproducible for restarts.
    1216             :       lh_seed = int( 1.0e4_r8 * rtm(1,pver), kind = genrand_intg )
    1217             :       
    1218             :       ! Let's generate some subcolumns!!!!!
    1219             :       call generate_silhs_sample_api( &
    1220             :                     iter, pdf_dim, num_subcols, sequence_length, pverp-top_lev+1, ngrdcol, & ! In
    1221             :                     l_calc_weights_all_levs_itime, &                      ! In 
    1222             :                     pdf_params_chnk(lchnk), delta_zm, Lscale, &           ! In
    1223             :                     lh_seed, &                                            ! In
    1224             :                     rho_ds_zt, &                                          ! In 
    1225             :                     mu_x_1, mu_x_2, sigma_x_1, sigma_x_2, &               ! In 
    1226             :                     corr_cholesky_mtx_1, corr_cholesky_mtx_2, &           ! In
    1227             :                     precip_fracs, silhs_config_flags, &                   ! In
    1228             :                     clubb_params, &                                       ! In
    1229             :                     clubb_config_flags%l_uv_nudge, &                      ! In
    1230             :                     clubb_config_flags%l_tke_aniso, &                     ! In
    1231             :                     clubb_config_flags%l_standard_term_ta, &              ! In
    1232             :                     vert_decorr_coef, &                                   ! In
    1233             :                     stats_metadata, &                                     ! In
    1234             :                     stats_lh_zt, stats_lh_sfc, &                          ! InOut
    1235             :                     X_nl_all_levs, X_mixt_comp_all_levs, &                ! Out
    1236             :                     lh_sample_point_weights)                              ! Out
    1237             : 
    1238             :       ! Extract clipped variables from subcolumns
    1239             :       call clip_transform_silhs_output_api( gr, pverp-top_lev+1, ngrdcol, num_subcols, &   ! In
    1240             :                                             pdf_dim, hydromet_dim, & ! In
    1241             :                                             X_mixt_comp_all_levs, & ! In
    1242             :                                             X_nl_all_levs, &        ! In
    1243             :                                             pdf_params_chnk(lchnk), & ! In
    1244             :                                             l_use_Ncn_to_Nc, & ! In
    1245             :                                             lh_rt_clipped, lh_thl_clipped, & ! Out
    1246             :                                             lh_rc_clipped, lh_rv_clipped, & ! Out
    1247             :                                             lh_Nc_clipped ) ! Out
    1248             :       !$acc wait
    1249             :        
    1250             :       if ( l_est_kessler_microphys ) then
    1251             :         call endrun('subcol_SILHS: l_est_kessler_microphys = T is not currently supported')
    1252             :       end if
    1253             : 
    1254             :       !-------------------------------------------------------------------------
    1255             :       !            Convert from CLUBB vertical grid to CAM grid
    1256             :       !------------------------------------------------------------------------
    1257             :       ! This kernel is executed in stream 1:
    1258             :       !$acc parallel loop collapse(3) default(present) async(1)
    1259             :       do k = top_lev, pverp
    1260             :         do j = 1, num_subcols
    1261             :           do i = 1, ngrdcol
    1262             :             RT_lh_out(   num_subcols*(i-1)+j,k ) = lh_rt_clipped(i,j,pverp-k+1)
    1263             :             RCM_lh_out(  num_subcols*(i-1)+j,k ) = lh_rc_clipped(i,j,pverp-k+1)
    1264             :             NCLW_lh_out( num_subcols*(i-1)+j,k ) = lh_Nc_clipped(i,j,pverp-k+1)
    1265             :             RVM_lh_out(  num_subcols*(i-1)+j,k ) = lh_rv_clipped(i,j,pverp-k+1)
    1266             :             THL_lh_out(  num_subcols*(i-1)+j,k ) = lh_thl_clipped(i,j,pverp-k+1)
    1267             :           end do          
    1268             :         end do
    1269             :       end do
    1270             :        
    1271             :       ! This kernel is executed in stream 2:
    1272             :       !$acc parallel loop collapse(3) default(present) async(2)
    1273             :       do k = top_lev, pverp
    1274             :         do j = 1, num_subcols
    1275             :           do i = 1, ngrdcol
    1276             :             ICE_lh_out(   num_subcols*(i-1)+j,k ) = X_nl_all_levs(i,j,pverp-k+1,iiPDF_ri)
    1277             :             NICE_lh_out(  num_subcols*(i-1)+j,k ) = X_nl_all_levs(i,j,pverp-k+1,iiPDF_Ni)
    1278             :             RAIN_lh_out(  num_subcols*(i-1)+j,k ) = X_nl_all_levs(i,j,pverp-k+1,iiPDF_rr)
    1279             :             NRAIN_lh_out( num_subcols*(i-1)+j,k ) = X_nl_all_levs(i,j,pverp-k+1,iiPDF_Nr)
    1280             :             SNOW_lh_out(  num_subcols*(i-1)+j,k ) = X_nl_all_levs(i,j,pverp-k+1,iiPDF_rs)
    1281             :             NSNOW_lh_out( num_subcols*(i-1)+j,k ) = X_nl_all_levs(i,j,pverp-k+1,iiPDF_Ns)
    1282             :             WM_lh_out(    num_subcols*(i-1)+j,k ) = X_nl_all_levs(i,j,pverp-k+1,iiPDF_w)
    1283             :           end do          
    1284             :         end do
    1285             :       end do
    1286             :      
    1287             :       ! This kernel is executed in stream 2 because WM_lh_out comes from stream 2:
    1288             :       !$acc parallel loop collapse(3) default(present) async(2)
    1289             :       do k = top_lev, pverp
    1290             :         do j = 1, num_subcols
    1291             :           do i = 1, ngrdcol
    1292             :             OMEGA_lh_out( num_subcols*(i-1)+j,k ) = -1._r8 * WM_lh_out(num_subcols*(i-1)+j,k) &
    1293             :                                                            * rho_ds_zt(i,pverp-k+1) * gravit
    1294             :           end do
    1295             :         end do
    1296             :       end do
    1297             :      
    1298             :       if ( l_est_kessler_microphys ) then
    1299             :         do k = top_lev, pverp
    1300             :           do j = 1, num_subcols
    1301             :             do i = 1, ngrdcol
    1302             :               AKm_out(i,k) = AKm(i,pverp-k+1)
    1303             :               lh_AKm_out(i,k) = lh_AKm(i,pverp-k+1)
    1304             :             end do
    1305             :           end do
    1306             :         end do
    1307             :       end if
    1308             : 
    1309             :       ! Pack up weights
    1310             :       ! Using grid level 2 always won't work if weights vary with height.
    1311             :       call subcol_pack(lchnk, lh_sample_point_weights(:,:,2), weights )
    1312             :       call subcol_set_weight(lchnk, weights)
    1313             :       
    1314             :       ! Constrain the sample distribution of cloud water and ice to the same mean
    1315             :       ! as the grid to prevent negative condensate errors
    1316             :       if(subcol_SILHS_constrainmn) then
    1317             :          
    1318             :         do i = 1, ngrdcol
    1319             :          
    1320             :           stncol = num_subcols*(i-1)
    1321             :            
    1322             :           call subcol_constrainmn( num_subcols, ICE_lh_out(stncol+1:stncol+num_subcols,:), &
    1323             :                                    weights(stncol+1:stncol+num_subcols), &
    1324             :                                    state%q(i,:,ixcldice), meansc_ice(i,:), stdsc_ice(i,:) )
    1325             :           if ( ixrain > 0 ) &
    1326             :           call subcol_constrainmn( num_subcols, RAIN_lh_out(stncol+1:stncol+num_subcols,:), &
    1327             :                                    weights(stncol+1:stncol+num_subcols), &
    1328             :                                    state%q(i,:,ixrain) )
    1329             :           if ( ixsnow > 0 ) &
    1330             :           call subcol_constrainmn( num_subcols, SNOW_lh_out(stncol+1:stncol+num_subcols,:), &
    1331             :                                    weights(stncol+1:stncol+num_subcols), &
    1332             :                                    state%q(i,:,ixsnow) )
    1333             :           call subcol_constrainmn( num_subcols, RCM_lh_out(stncol+1:stncol+num_subcols,:), &
    1334             :                                    weights(stncol+1:stncol+num_subcols), &
    1335             :                                    state%q(i,:,ixcldliq), meansc_liq(i,:), stdsc_liq(i,:) )
    1336             :           call subcol_constrainmn( num_subcols, RVM_lh_out(stncol+1:stncol+num_subcols,:), &
    1337             :                                    weights(stncol+1:stncol+num_subcols), &
    1338             :                                    state%q(i,:,ixq), meansc_vap(i,:), stdsc_vap(i,:) )
    1339             :           call subcol_constrainmn( num_subcols, NICE_lh_out(stncol+1:stncol+num_subcols,:), &
    1340             :                                    weights(stncol+1:stncol+num_subcols), &
    1341             :                                    state%q(i,:,ixnumice) )
    1342             :           if ( ixnumrain > 0 ) &
    1343             :           call subcol_constrainmn( num_subcols, NRAIN_lh_out(stncol+1:stncol+num_subcols,:), &
    1344             :                                    weights(stncol+1:stncol+num_subcols), &
    1345             :                                    state%q(i,:,ixnumrain) )
    1346             :           if ( ixnumsnow > 0 ) &
    1347             :           call subcol_constrainmn( num_subcols, NSNOW_lh_out(stncol+1:stncol+num_subcols,:), &
    1348             :                                    weights(stncol+1:stncol+num_subcols), &
    1349             :                                    state%q(i,:,ixnumsnow) )
    1350             :           call subcol_constrainmn( num_subcols, NCLW_lh_out(stncol+1:stncol+num_subcols,:), &
    1351             :                                    weights(stncol+1:stncol+num_subcols), &
    1352             :                                    state%q(i,:,ixnumliq) )
    1353             :           do k = top_lev, pver
    1354             :             ! Look for exceptionally large values of condensate
    1355             :             if(ANY(ICE_lh_out(stncol+1:stncol+num_subcols,k) .gt. 0.01_r8)) then
    1356             :               ! Clip the large values
    1357             :               where(ICE_lh_out(stncol+1:stncol+num_subcols,k) .gt. 0.01_r8)
    1358             :                  ICE_lh_out(stncol+1:stncol+num_subcols,k) = 0.01_r8
    1359             :                  NICE_lh_out(stncol+1:stncol+num_subcols,k) = 1.5e+7_r8
    1360             :               end where
    1361             :               ! Recalculate the weighted subcolumn mean
    1362             :               tmp_mean = meansc( ICE_lh_out( stncol+1:stncol+num_subcols, k ), & 
    1363             :                                      weights(stncol+1:stncol+num_subcols), &
    1364             :                                      real(num_subcols,r8) )
    1365             :               ! Calculate the difference between the weighted mean and grid mean
    1366             :               diff_mean = state%q(i,k,ixcldice)-tmp_mean
    1367             :               ! Add the difference to each subcolumn
    1368             :               ICE_lh_out(stncol+1:stncol+num_subcols,k) = &
    1369             :                  ICE_lh_out(stncol+1:stncol+num_subcols,k)+diff_mean
    1370             :               ! Recalculate the weight subcolumn mean for ice num conc
    1371             :               tmp_mean = meansc( NICE_lh_out( stncol+1:stncol+num_subcols, k ), & 
    1372             :                                      weights(stncol+1:stncol+num_subcols), &
    1373             :                                      real(num_subcols,r8) )
    1374             :               ! Calculate the difference between the weighted mean and grid mean
    1375             :               diff_mean = state%q(i,k,ixnumice)-tmp_mean
    1376             :               ! Add the difference to each subcolumn
    1377             :               if(diff_mean.gt.0.0_r8) then
    1378             :                  NICE_lh_out(stncol+1:stncol+num_subcols,k) = &
    1379             :                      NICE_lh_out(stncol+1:stncol+num_subcols,k)+diff_mean
    1380             :               else ! just use the grid mean in each subcolumn
    1381             :                  NICE_lh_out(stncol+1:stncol+num_subcols,k) = &
    1382             :                      state%q(i,k,ixnumice)
    1383             :               end if
    1384             :               ! Test adjusted means for debugging
    1385             :               tmp_mean = meansc( ICE_lh_out( stncol+1:stncol+num_subcols, k ), & 
    1386             :                                      weights(stncol+1:stncol+num_subcols), &
    1387             :                                      real(num_subcols,r8) )
    1388             :               diff_mean = state%q(i,k,ixcldice)-tmp_mean
    1389             :               tmp_mean = meansc( NICE_lh_out( stncol+1:stncol+num_subcols, k ), & 
    1390             :                                      weights(stncol+1:stncol+num_subcols), &
    1391             :                                      real(num_subcols,r8) )
    1392             :               diff_mean = state%q(i,k,ixnumice)-tmp_mean
    1393             :             endif
    1394             :           end do ! k = top_lev, pver
    1395             :         end do
    1396             :       endif ! subcol_silhs_constrainm
    1397             :       
    1398             :       
    1399             :       !---------------------------------------------------
    1400             :       !            Updating state variables
    1401             :       !---------------------------------------------------
    1402             :       ! Code to update the state variables for interactive runs
    1403             :       ! This kernel is executed in stream 3, but waits for stream 1
    1404             :       ! because THL_lh_out and RCM_lh_out come from stream 1:
    1405             :       !$acc parallel loop collapse(3) default(present) wait(1) async(3)
    1406             :       do k = 1, pver-top_lev+1
    1407             :         do j = 1, num_subcols
    1408             :           do i = 1, ngrdcol
    1409             :               
    1410             :             state_sc%t(num_subcols*(i-1)+j,k) = THL_lh_out(num_subcols*(i-1)+j,k) * invs_exner(i,k) &
    1411             :                                                 + Lv * RCM_lh_out(num_subcols*(i-1)+j,k) / Cp
    1412             :             
    1413             :             state_sc%s(num_subcols*(i-1)+j,k) = cpair * state_sc%t(num_subcols*(i-1)+j,k) &
    1414             :                                                 + gravit * state%zm(i,k) + state%phis(i)
    1415             :           end do
    1416             :         end do
    1417             :       end do
    1418             :       
    1419             :       ! This kernel is executed in stream 4, but waits for stream 1 and 2
    1420             :       ! because RVM_lh_out is from stream 1 and OMEGA_lh_out is from stream 2:
    1421             :       !$acc parallel loop collapse(3) default(present) wait(1,2) async(4)
    1422             :       do k = 1, pver-top_lev+1
    1423             :         do j = 1, num_subcols
    1424             :           do i = 1, ngrdcol
    1425             :             ! Vertical Velocity is not part of the energy conservation checks, but
    1426             :             ! we need to be careful here, because the SILHS output VV is noisy.
    1427             :             state_sc%omega(num_subcols*(i-1)+j,k) = OMEGA_lh_out(num_subcols*(i-1)+j,k)
    1428             :             state_sc%q(num_subcols*(i-1)+j,k,ixq) = RVM_lh_out(num_subcols*(i-1)+j,k) 
    1429             :           end do
    1430             :         end do
    1431             :       end do
    1432             : 
    1433             :         
    1434             :       if (subcol_SILHS_q_to_micro) then ! Send SILHS predicted constituents to microp
    1435             :          
    1436             :         ! This kernel is executed in stream 5, but waits for stream 1 and 2
    1437             :         ! because RCM_lh_out is from stream 1 and ICE_lh_out is from stream 2:
    1438             :         !$acc parallel loop collapse(3) default(present) wait(1,2) async(5)
    1439             :         do k = 1, pver-top_lev+1
    1440             :           do j = 1, num_subcols
    1441             :             do i = 1, ngrdcol
    1442             :               state_sc%q(num_subcols*(i-1)+j,k,ixcldliq) = RCM_lh_out(num_subcols*(i-1)+j,k)
    1443             :               state_sc%q(num_subcols*(i-1)+j,k,ixcldice) = ICE_lh_out(num_subcols*(i-1)+j,k)
    1444             :             end do
    1445             :           end do
    1446             :         end do
    1447             :         
    1448             :         if (ixrain > 0) then
    1449             :           ! This kernel is executed in stream 6, but waits for stream 2
    1450             :           ! because RAIN_lh_out is from stream 2:
    1451             :           !$acc parallel loop collapse(3) default(present) wait(2) async(6)
    1452             :           do k = 1, pver-top_lev+1
    1453             :             do j = 1, num_subcols
    1454             :               do i = 1, ngrdcol
    1455             :                 state_sc%q(num_subcols*(i-1)+j,k,ixrain) = RAIN_lh_out(num_subcols*(i-1)+j,k)
    1456             :               end do
    1457             :             end do
    1458             :           end do
    1459             :         end if
    1460             :         
    1461             :         if (ixsnow > 0) then
    1462             :           ! This kernel is executed in stream 7, but waits for stream 2
    1463             :           ! because SNOW_lh_out is from stream 2:
    1464             :           !$acc parallel loop collapse(3) default(present) wait(2) async(7)
    1465             :           do k = 1, pver-top_lev+1
    1466             :             do j = 1, num_subcols
    1467             :               do i = 1, ngrdcol
    1468             :                 state_sc%q(num_subcols*(i-1)+j,k,ixsnow) = SNOW_lh_out(num_subcols*(i-1)+j,k)
    1469             :               end do
    1470             :             end do
    1471             :           end do
    1472             :         end if
    1473             :           
    1474             :       else   
    1475             :          
    1476             :         do k = 1, pver-top_lev+1
    1477             :           do j = 1, num_subcols
    1478             :             do i = 1, ngrdcol
    1479             :               state_sc%q(num_subcols*(i-1)+j,k,ixcldliq) = state%q(i,k,ixcldliq)
    1480             :               state_sc%q(num_subcols*(i-1)+j,k,ixcldice) = state%q(i,k,ixcldice)
    1481             :               if (ixrain > 0) then
    1482             :                  state_sc%q(num_subcols*(i-1)+j,k,ixrain) = state%q(i,k,ixrain)
    1483             :               end if
    1484             :               if (ixsnow > 0) then
    1485             :                  state_sc%q(num_subcols*(i-1)+j,k,ixsnow) = state%q(i,k,ixsnow)
    1486             :               end if
    1487             :             end do
    1488             :           end do
    1489             :         end do
    1490             :        
    1491             :       endif
    1492             :        
    1493             :       if (subcol_SILHS_n_to_micro) then ! Send SILHS predicted number conc to microp
    1494             :         
    1495             :         ! This kernel is executed in stream 8, but waits for stream 1 and 2
    1496             :         ! because NCLW_lh_out is from stream 1 and NICE_lh_out is from stream 2:
    1497             :         !$acc parallel loop collapse(3) default(present) wait(1,2) async(8)
    1498             :         do k = 1, pver-top_lev+1
    1499             :           do j = 1, num_subcols
    1500             :             do i = 1, ngrdcol
    1501             :               state_sc%q(num_subcols*(i-1)+j,k,ixnumice) = NICE_lh_out(num_subcols*(i-1)+j,k)
    1502             :               state_sc%q(num_subcols*(i-1)+j,k,ixnumliq) = NCLW_lh_out(num_subcols*(i-1)+j,k)
    1503             :             end do
    1504             :           end do
    1505             :         end do
    1506             :         
    1507             :         if (ixnumrain > 0) then
    1508             :           ! This kernel is executed in stream 9, but waits for stream 2
    1509             :           ! because NRAIN_lh_out is from stream 2:
    1510             :           !$acc parallel loop collapse(3) default(present) wait(2) async(9)
    1511             :           do k = 1, pver-top_lev+1
    1512             :             do j = 1, num_subcols
    1513             :               do i = 1, ngrdcol
    1514             :                 state_sc%q(num_subcols*(i-1)+j,k,ixnumrain) = NRAIN_lh_out(num_subcols*(i-1)+j,k)
    1515             :               end do
    1516             :             end do
    1517             :           end do
    1518             :         end if
    1519             :         
    1520             :         if (ixnumsnow > 0) then
    1521             :           ! This kernel is executed in stream 10, but waits for stream 2
    1522             :           ! because NSNOW_lh_out is from stream 2:
    1523             :           !$acc parallel loop collapse(3) default(present) wait(2) async(10)
    1524             :           do k = 1, pver-top_lev+1
    1525             :             do j = 1, num_subcols
    1526             :               do i = 1, ngrdcol
    1527             :                 state_sc%q(num_subcols*(i-1)+j,k,ixnumsnow) = NSNOW_lh_out(num_subcols*(i-1)+j,k)
    1528             :               end do
    1529             :             end do
    1530             :           end do
    1531             :         end if
    1532             :        
    1533             :       else     
    1534             :        
    1535             :         do k = 1, pver-top_lev+1
    1536             :           do j = 1, num_subcols
    1537             :             do i = 1, ngrdcol
    1538             :               state_sc%q(num_subcols*(i-1)+j,k,ixnumliq) = state%q(i,k,ixnumliq)
    1539             :               state_sc%q(num_subcols*(i-1)+j,k,ixnumice) = state%q(i,k,ixnumice)
    1540             :               if (ixnumrain > 0) then
    1541             :                  state_sc%q(num_subcols*(i-1)+j,k,ixnumrain) = state%q(i,k,ixnumrain)
    1542             :               end if
    1543             :               if (ixnumsnow > 0) then
    1544             :                  state_sc%q(num_subcols*(i-1)+j,k,ixnumsnow) = state%q(i,k,ixnumsnow)
    1545             :               end if
    1546             :             end do
    1547             :           end do
    1548             :         end do
    1549             :          
    1550             :       endif
    1551             :       
    1552             :       ! This kernel is executed in stream 8, because state_sc%q(:,:,ixnumliq) and
    1553             :       !  state_sc%q(:,:,ixnumice) are from stream 8
    1554             :       !$acc parallel loop collapse(3) default(present) async(8)
    1555             :       do k = 1, pver-top_lev+1
    1556             :         do j = 1, num_subcols
    1557             :           do i = 1, ngrdcol
    1558             :             ! Change liq and ice (and rain and snow) num conc zeros to min values (1e-12)
    1559             :             if (state_sc%q(num_subcols*(i-1)+j,k,ixnumliq) .lt. min_num_conc) then
    1560             :                 state_sc%q(num_subcols*(i-1)+j,k,ixnumliq) = min_num_conc
    1561             :             end if
    1562             :             
    1563             :             if (state_sc%q(num_subcols*(i-1)+j,k,ixnumice) .lt. min_num_conc) then
    1564             :                 state_sc%q(num_subcols*(i-1)+j,k,ixnumice) = min_num_conc
    1565             :             end if
    1566             :           end do
    1567             :         end do
    1568             :       end do
    1569             :         
    1570             :       if (ixnumrain > 0) then
    1571             :         ! This kernel is executed in stream 9, because state_sc%q(:,:,ixnumrain) is
    1572             :         ! from stream 9
    1573             :         !$acc parallel loop collapse(3) default(present) async(9)
    1574             :         do k = 1, pver-top_lev+1
    1575             :           do j = 1, num_subcols   
    1576             :             do i = 1, ngrdcol   
    1577             :                if(state_sc%q(num_subcols*(i-1)+j,k,ixnumrain) .lt. min_num_conc) then
    1578             :                   state_sc%q(num_subcols*(i-1)+j,k,ixnumrain) = min_num_conc
    1579             :                end if
    1580             :             end do
    1581             :           end do
    1582             :         end do
    1583             :       endif
    1584             :         
    1585             :       if (ixnumsnow > 0) then
    1586             :         ! This kernel is executed in stream 10, because state_sc%q(:,:,ixnumsnow) is
    1587             :         ! from stream 10
    1588             :         !$acc parallel loop collapse(3) default(present) async(10)
    1589             :         do k = 1, pver-top_lev+1
    1590             :           do j = 1, num_subcols     
    1591             :             do i = 1, ngrdcol
    1592             :               if(state_sc%q(num_subcols*(i-1)+j,k,ixnumsnow) .lt. min_num_conc) then
    1593             :                  state_sc%q(num_subcols*(i-1)+j,k,ixnumsnow) = min_num_conc
    1594             :               end if
    1595             :             end do
    1596             :           end do
    1597             :         end do
    1598             :       endif
    1599             : 
    1600             :       if ( l_outfld_subcol ) then
    1601             :         
    1602             :         do k = 1, pver-top_lev+1
    1603             :           do i = 1, ngrdcol
    1604             :             do j = 1, num_subcols
    1605             :                
    1606             :               ! Calc effective cloud fraction for testing
    1607             :               if ( ( lh_rc_clipped(i,j,pverp-k+1) .gt. qsmall ) &
    1608             :                      .or. ( X_nl_all_levs(i,j,pverp-k+1,iiPDF_ri) .gt. qsmall ) ) then
    1609             :                  eff_cldfrac(i,k) = eff_cldfrac(i,k) + lh_sample_point_weights(i,j,pverp-k+1)
    1610             :               else 
    1611             :                 eff_cldfrac(i,k) = 0.0_r8
    1612             :               endif
    1613             :                 
    1614             :              end do 
    1615             :              
    1616             :              eff_cldfrac(i,k) = eff_cldfrac(i,k)/real(num_subcols, kind=r8)
    1617             :              
    1618             :           end do
    1619             :         end do
    1620             :         
    1621             :         ! Pack precip_frac for output
    1622             :         do k = 2, pverp-top_lev+1
    1623             :           do i = 1, ngrdcol
    1624             :             precip_frac_out(i,pver-k+2) = precip_fracs%precip_frac(i,k)
    1625             :           end do
    1626             :         end do
    1627             :         
    1628             :         call outfld( 'SILHS_THLM_SCOL', THL_lh_out, pcols*psubcols, lchnk )
    1629             :         call outfld( 'SILHS_RT_SCOL', RT_lh_out, pcols*psubcols, lchnk )
    1630             :         call outfld( 'SILHS_OMEGA_SCOL', OMEGA_lh_out, pcols*psubcols, lchnk )
    1631             :         call outfld( 'SILHS_WM_SCOL', WM_lh_out, pcols*psubcols, lchnk )
    1632             :         call outfld( 'SILHS_RCM_SCOL', RCM_lh_out, pcols*psubcols, lchnk )
    1633             :         call outfld( 'SILHS_RICLD_SCOL', ICE_lh_out, pcols*psubcols, lchnk )
    1634             :         call outfld( 'SILHS_NICLD_SCOL', NICE_lh_out, pcols*psubcols, lchnk )
    1635             :         call outfld( 'SILHS_NCLD_SCOL', NCLW_lh_out, pcols*psubcols, lchnk )
    1636             :         call outfld( 'SILHS_RRAIN_SCOL', RAIN_lh_out, pcols*psubcols, lchnk )
    1637             :         call outfld( 'SILHS_NRAIN_SCOL', NRAIN_lh_out, pcols*psubcols, lchnk )
    1638             :         call outfld( 'SILHS_WEIGHT_SCOL', weights, pcols*psubcols, lchnk )
    1639             :         call outfld( 'NR_IN_LH', nrain, pcols, lchnk )
    1640             :         call outfld( 'SILHS_RTM', rtm, pcols, lchnk )
    1641             :         call outfld( 'SILHS_THLM', thlm, pcols, lchnk )
    1642             :         call outfld( 'SILHS_QC_IN', state%q(:,:,ixcldliq), pcols, lchnk )
    1643             :         call outfld( 'SILHS_QI_IN', state%q(:,:,ixcldice), pcols, lchnk )
    1644             :         call outfld( 'SILHS_NC_IN', state%q(:,:,ixnumliq), pcols, lchnk )
    1645             :         call outfld( 'SILHS_NI_IN', state%q(:,:,ixnumice), pcols, lchnk )
    1646             :         if ( l_est_kessler_microphys ) then
    1647             :           call outfld( 'AKM_CLUBB', AKm_out, pcols, lchnk )
    1648             :           call outfld( 'AKM_LH_CLUBB', lh_AKm_out, pcols, lchnk )
    1649             :         end if
    1650             :         call outfld( 'INVS_EXNER', invs_exner, pcols, lchnk )
    1651             :         call outfld( 'SILHS_ZTODT', ztodt_ptr, pcols, lchnk )
    1652             :         if ( subcol_SILHS_constrainmn ) then
    1653             :           call outfld( 'SILHS_MSC_CLDICE', meansc_ice, pcols, lchnk )
    1654             :           call outfld( 'SILHS_STDSC_CLDICE', stdsc_ice, pcols, lchnk )
    1655             :           if ( ixsnow > 0 ) then
    1656             :             call outfld( 'SILHS_MSC_CLDLIQ', meansc_liq, pcols, lchnk )
    1657             :             call outfld( 'SILHS_STDSC_CLDLIQ', stdsc_liq, pcols, lchnk )
    1658             :             call outfld( 'SILHS_MSC_Q', meansc_vap, pcols, lchnk )
    1659             :             call outfld( 'SILHS_STDSC_Q', stdsc_vap, pcols, lchnk )
    1660             :           endif ! ixsnow > 0
    1661             :         endif ! subcol_SILHS_constrainmn
    1662             :         call outfld( 'SILHS_EFF_CLDFRAC', eff_cldfrac, pcols, lchnk )
    1663             :         call outfld( 'SILHS_CLUBB_PRECIP_FRAC', precip_frac_out, pcols, lchnk )
    1664             :         call outfld( 'SILHS_CLUBB_ICE_SS_FRAC', ice_supersat_frac, pcols, lchnk )
    1665             :       end if
    1666             :       
    1667             :       !$acc end data
    1668             :       !$acc wait
    1669             : 
    1670             : #endif
    1671             : #endif
    1672           0 :    end subroutine subcol_gen_SILHS
    1673             : 
    1674           0 :    subroutine subcol_ptend_avg_SILHS(ptend_sc, ngrdcol, lchnk, ptend)
    1675           0 :       use physics_buffer,   only: physics_buffer_desc
    1676             :       use subcol_utils,     only: subcol_ptend_get_firstsubcol, subcol_ptend_avg_shr, &
    1677             :                                   subcol_get_weight, subcol_get_filter, &
    1678             :                                   is_filter_set, is_weight_set
    1679             : 
    1680             :       !-----------------------------------
    1681             :       ! Average the subcolumns dimension (pcols*psubcols) to the grid dimension (pcols)
    1682             :       !-----------------------------------
    1683             : 
    1684             :       type(physics_ptend), intent(in)             :: ptend_sc        ! intent in
    1685             :       integer,  intent(in)                        :: ngrdcol       ! # grid cols
    1686             :       integer,  intent(in)                        :: lchnk         ! chunk index
    1687             :       type(physics_ptend), intent(inout)          :: ptend
    1688             :       ! Because we can't get a state passed in here, we might have to use values from the 
    1689             :       ! subcolumn generation. This would make any conservation checks invalid if this
    1690             :       ! function is called after another parameterization... hmm.
    1691             : 
    1692           0 :        call subcol_ptend_avg_shr(ptend_sc, ngrdcol, lchnk, ptend, is_filter_set(), is_weight_set())
    1693             : 
    1694           0 :    end subroutine subcol_ptend_avg_SILHS
    1695             : 
    1696           0 :    subroutine subcol_SILHS_var_covar_driver &
    1697             :               ( ztodt, state_sc, ptend_sc, &
    1698             :                 pbuf )
    1699             : 
    1700             :      ! This subroutine calculates microphysical effects on five variances and
    1701             :      ! covariances: rtp2, thlp2, wprtp, wpthlp, and rtpthlp.
    1702             :      !
    1703             :      ! This code is experimental!!
    1704             : 
    1705           0 :      use physics_buffer,          only: physics_buffer_desc, pbuf_get_index, pbuf_get_field
    1706             : #ifdef CLUBB_SGS
    1707             : #ifdef SILHS
    1708             :      use subcol_utils,            only: subcol_get_weight
    1709             :      use subcol_pack_mod,         only: subcol_unpack, subcol_get_nsubcol
    1710             :      use clubb_api_module,        only: T_in_K2thlm_api, &
    1711             :                                         init_pdf_params_api, &
    1712             :                                         copy_multi_pdf_params_to_single,&
    1713             :                                         pdf_parameter
    1714             :      use silhs_api_module,        only: lh_microphys_var_covar_driver_api
    1715             : #endif
    1716             : #endif
    1717             : 
    1718             :      implicit none
    1719             : 
    1720             :      ! Parameters
    1721             :      !  This fill value is set to catch errors; it should not be read.
    1722             :      real(r8), parameter                   :: fillvalue = -999._r8
    1723             : 
    1724             :      ! Input Variables
    1725             :      real(r8), intent(in)                  :: ztodt        ! model time increment
    1726             :      type(physics_state), intent(in)       :: state_sc     ! state for sub-columns
    1727             :      type(physics_ptend), intent(in)       :: ptend_sc     ! ptend for sub-columns
    1728             : 
    1729             :      ! Pointers
    1730             :      type(physics_buffer_desc), pointer    :: pbuf(:)
    1731             : 
    1732             : #ifdef CLUBB_SGS
    1733             : #ifdef SILHS
    1734             :      ! Local Variables
    1735             :      integer :: lchnk, ngrdcol, igrdcol, isubcol, ns, k
    1736             :      integer, dimension(pcols) :: nsubcol
    1737             :      real(r8), dimension(pcols*psubcols)       :: weights_packed
    1738             :      real(r8), dimension(pcols,psubcols)       :: weights
    1739             :      real(r8), dimension(pcols,psubcols,pverp) :: rc_all, rv_all, rt_all, w_all, thl_all
    1740             :      real(r8), dimension(pcols,psubcols,pver ) :: s_all, t_all, zm_all, omega_all, pmid_all
    1741             :      real(r8), dimension(pcols,psubcols)       :: phis_all
    1742             :      real(r8), dimension(pcols,psubcols,pver ) :: stend, ttend
    1743             :      real(r8), dimension(pcols,psubcols,pverp) :: thltend, qctend, qvtend
    1744             : 
    1745             :      real(r8), dimension(pcols,psubcols,pver)  :: dz_g, pdel_all, rho
    1746             :      real(r8), dimension(pcols,psubcols,pverp) :: zi_all
    1747             :  
    1748             :      real(r8), dimension(pcols,psubcols,pver ) :: exner
    1749             : 
    1750             :      ! Inputs to lh_microphys_var_covar_driver
    1751             :      real(r8), dimension(pcols,psubcols,pverp) :: rt_all_clubb, thl_all_clubb, w_all_clubb, &
    1752             :                                                   qctend_clubb, qvtend_clubb, thltend_clubb
    1753             :      real(r8), dimension(pcols,psubcols,pverp-top_lev+1) :: height_depndt_weights
    1754             : 
    1755             :      ! Outputs from lh_microphys_var_covar_driver
    1756             :      real(r8), dimension(:,:), pointer :: rtp2_mc_zt, thlp2_mc_zt, wprtp_mc_zt, &
    1757             :                                           wpthlp_mc_zt, rtpthlp_mc_zt
    1758             : 
    1759             :      ! pbuf indices
    1760             :      integer :: &
    1761             :        rtp2_mc_zt_idx,    &
    1762             :        thlp2_mc_zt_idx,   &
    1763             :        wprtp_mc_zt_idx,   &
    1764             :        wpthlp_mc_zt_idx,  &
    1765             :        rtpthlp_mc_zt_idx
    1766             :        
    1767             :      type(pdf_parameter) :: pdf_params_single_col
    1768             : 
    1769             :      !----- Begin Code -----
    1770             :      
    1771             :      call init_pdf_params_api( pverp+1-top_lev, 1, pdf_params_single_col )
    1772             : 
    1773             :      ! Don't do anything if this option isn't enabled.
    1774             :      if ( .not. subcol_SILHS_var_covar_src ) return
    1775             : 
    1776             :      lchnk = state_sc%lchnk
    1777             :      ngrdcol  = state_sc%ngrdcol
    1778             : 
    1779             :      ! Obtain indices
    1780             :      rtp2_mc_zt_idx = pbuf_get_index('rtp2_mc_zt')
    1781             :      thlp2_mc_zt_idx = pbuf_get_index('thlp2_mc_zt')
    1782             :      wprtp_mc_zt_idx = pbuf_get_index('wprtp_mc_zt')
    1783             :      wpthlp_mc_zt_idx = pbuf_get_index('wpthlp_mc_zt')
    1784             :      rtpthlp_mc_zt_idx = pbuf_get_index('rtpthlp_mc_zt')
    1785             : 
    1786             :      ! Obtain pbuf fields for output
    1787             :      call pbuf_get_field(pbuf, rtp2_mc_zt_idx, rtp2_mc_zt)
    1788             :      call pbuf_get_field(pbuf, thlp2_mc_zt_idx, thlp2_mc_zt)
    1789             :      call pbuf_get_field(pbuf, wprtp_mc_zt_idx, wprtp_mc_zt)
    1790             :      call pbuf_get_field(pbuf, wpthlp_mc_zt_idx, wpthlp_mc_zt)
    1791             :      call pbuf_get_field(pbuf, rtpthlp_mc_zt_idx, rtpthlp_mc_zt)
    1792             : 
    1793             :      ! Unpack needed tendencies from subcolumn ptends
    1794             :      call subcol_unpack(lchnk, ptend_sc%s(:,:), stend, fillvalue)
    1795             :      call subcol_unpack(lchnk, ptend_sc%q(:,:,ixcldliq), qctend(:,:,1:pver), fillvalue)
    1796             :      call subcol_unpack(lchnk, ptend_sc%q(:,:,ixq), qvtend(:,:,1:pver), fillvalue)
    1797             : 
    1798             :      ! Unpack sample point values from subcolumn states
    1799             :      call subcol_unpack(lchnk, state_sc%q(:,:,ixcldliq), rc_all(:,:,1:pver), fillvalue)
    1800             :      call subcol_unpack(lchnk, state_sc%q(:,:,ixq),      rv_all(:,:,1:pver), fillvalue)
    1801             :      call subcol_unpack(lchnk, state_sc%omega(:,:),      omega_all (:,:,:),  fillvalue)
    1802             :      call subcol_unpack(lchnk, state_sc%s(:,:),          s_all,              fillvalue)
    1803             :      call subcol_unpack(lchnk, state_sc%zm,              zm_all,             fillvalue)
    1804             :      call subcol_unpack(lchnk, state_sc%phis,            phis_all,           fillvalue)
    1805             :      call subcol_unpack(lchnk, state_sc%zi,              zi_all,             fillvalue)
    1806             :      call subcol_unpack(lchnk, state_sc%pdel,            pdel_all,           fillvalue)
    1807             :      call subcol_unpack(lchnk, state_sc%pmid,            pmid_all,           fillvalue)
    1808             : 
    1809             :      ! Initialize fields to fillvalue.
    1810             :      rt_all  = fillvalue
    1811             :      thl_all = fillvalue
    1812             :      w_all   = fillvalue
    1813             :      qctend  = fillvalue
    1814             :      qvtend  = fillvalue
    1815             :      thltend = fillvalue
    1816             : 
    1817             :      ! How many subcolumns in each column?
    1818             :      call subcol_get_nsubcol(lchnk, nsubcol)
    1819             : 
    1820             :      do igrdcol = 1, ngrdcol
    1821             :         do isubcol = 1, nsubcol(igrdcol)
    1822             : 
    1823             :            rt_all(igrdcol,isubcol,top_lev:pver) = rc_all(igrdcol,isubcol,top_lev:pver) &
    1824             :                                                   + rv_all(igrdcol,isubcol,top_lev:pver)
    1825             : 
    1826             :            ! Compute dry static density on CLUBB vertical grid
    1827             :            do k = top_lev, pver
    1828             :               dz_g(igrdcol,isubcol,k) = zi_all(igrdcol,isubcol,k) - zi_all(igrdcol,isubcol,k+1) ! thickness
    1829             :               rho(igrdcol,isubcol,k) = (rga)*pdel_all(igrdcol,isubcol,k)/dz_g(igrdcol,isubcol,k)
    1830             :            end do
    1831             : 
    1832             :            ! Compute w from omega
    1833             :            w_all(igrdcol,isubcol,top_lev:pver) = -omega_all(igrdcol,isubcol,top_lev:pver) &
    1834             :                                                   / ( rho(igrdcol,isubcol,top_lev:pver) * gravit )
    1835             : 
    1836             :            ! Convert stend and s_all to ttend and t_all
    1837             :            !  Note 1: With subcolumns, cpair is truly a constant (I think).
    1838             :            !  Note 2: For tendencies, the extra terns zm and phis should
    1839             :            !          not be included in the calculation.
    1840             :            ttend(igrdcol,isubcol,top_lev:pver) = stend(igrdcol,isubcol,top_lev:pver) / cpair
    1841             : 
    1842             :            do k = top_lev, pver
    1843             :               t_all(igrdcol,isubcol,k) = ( s_all(igrdcol,isubcol,k) &
    1844             :                                            - gravit * zm_all(igrdcol,isubcol,k) &
    1845             :                                            - phis_all(igrdcol,isubcol) ) / cpair
    1846             :            end do ! k = 1, pver
    1847             : 
    1848             :            ! This formula is taken from earlier in this file.
    1849             :            exner(igrdcol,isubcol,top_lev:pver) &
    1850             :            = ( pmid_all(igrdcol,isubcol,top_lev:pver) / p0_clubb )**(rair/cpair)
    1851             : 
    1852             :            ! Note: all tendencies or all means should be used in the call to
    1853             :            !       T_in_K2thlm_api (with the exception of exner)
    1854             :            do k = top_lev, pver
    1855             :               thltend(igrdcol,isubcol,k) &
    1856             :               = T_in_K2thlm_api( ttend(igrdcol,isubcol,k), exner(igrdcol,isubcol,k), &
    1857             :                                  qctend(igrdcol,isubcol,k) )
    1858             :               thl_all(igrdcol,isubcol,k) &
    1859             :               = T_in_K2thlm_api( t_all(igrdcol,isubcol,k), exner(igrdcol,isubcol,k), &
    1860             :                                  rc_all(igrdcol,isubcol,k) )
    1861             :            end do ! k = 1, pver
    1862             : 
    1863             :            ! Add ghost points
    1864             :            rt_all (igrdcol,isubcol,pverp) = rt_all (igrdcol,isubcol,pver)
    1865             :            thl_all(igrdcol,isubcol,pverp) = thl_all(igrdcol,isubcol,pver)
    1866             :            w_all  (igrdcol,isubcol,pverp) = w_all  (igrdcol,isubcol,pver)
    1867             :            qctend (igrdcol,isubcol,pverp) = qctend (igrdcol,isubcol,pver)
    1868             :            qvtend (igrdcol,isubcol,pverp) = qvtend (igrdcol,isubcol,pver)
    1869             :            thltend(igrdcol,isubcol,pverp) = thltend(igrdcol,isubcol,pver)
    1870             : 
    1871             :            ! Flip inputs to CLUBB's grid. Note the dimension ordering change.
    1872             :            rt_all_clubb(igrdcol,isubcol,1:pverp) = clubb_flip_grid( rt_all(igrdcol,isubcol,1:pverp) )
    1873             :            thl_all_clubb(igrdcol,isubcol,1:pverp) = clubb_flip_grid( thl_all(igrdcol,isubcol,1:pverp) )
    1874             :            w_all_clubb(igrdcol,isubcol,1:pverp) = clubb_flip_grid( w_all(igrdcol,isubcol,1:pverp) )
    1875             :            qctend_clubb(igrdcol,isubcol,1:pverp) = clubb_flip_grid( qctend(igrdcol,isubcol,1:pverp) )
    1876             :            qvtend_clubb(igrdcol,isubcol,1:pverp) = clubb_flip_grid( qvtend(igrdcol,isubcol,1:pverp) )
    1877             :            thltend_clubb(igrdcol,isubcol,1:pverp) = clubb_flip_grid( thltend(igrdcol,isubcol,1:pverp) )
    1878             : 
    1879             :         end do ! isubcol = 1, nsubcol(igrdcol)
    1880             :      end do ! igrdcol = 1, ngrdcol
    1881             : 
    1882             :      ! Obtain weights
    1883             :      call subcol_get_weight(lchnk, weights_packed)
    1884             :      call subcol_unpack(lchnk, weights_packed, weights, fillvalue)
    1885             : 
    1886             :      ! Call lh_microphys_var_covar_driver for each column
    1887             :      do igrdcol=1, ngrdcol
    1888             :        ns = nsubcol(igrdcol)
    1889             : 
    1890             :        ! This code assumes that the weights are height independent.
    1891             :        ! It will have to change once the weights vary with altitude!
    1892             :        ! I'm not sure whether the grid will need to be flipped.
    1893             :        do k = 1, pverp-top_lev+1
    1894             :           height_depndt_weights(igrdcol,1:ns,k) = weights(igrdcol,1:ns)
    1895             :        end do
    1896             : 
    1897             :        ! Copy the igrdcol column from the multicolumn pdf_params_chnk to the single column 
    1898             :        ! version of pdf_params_single_col since lh_microphys_var_covar_driver_api only
    1899             :        ! works over 1 column currently
    1900             :        call copy_multi_pdf_params_to_single( pdf_params_chnk(lchnk), igrdcol, &
    1901             :                                              pdf_params_single_col )
    1902             : 
    1903             :        ! Make the call!!!!!
    1904             :        call lh_microphys_var_covar_driver_api &
    1905             :             ( pverp-top_lev+1, ns, ztodt, height_depndt_weights(igrdcol,1:ns,1:pverp-top_lev+1), &
    1906             :               pdf_params_single_col, &
    1907             :               rt_all_clubb(igrdcol,1:ns,1:pverp-top_lev+1), thl_all_clubb(igrdcol,1:ns,1:pverp-top_lev+1), &
    1908             :               w_all_clubb(igrdcol,1:ns,1:pverp-top_lev+1), qctend_clubb(igrdcol,1:ns,1:pverp-top_lev+1), &
    1909             :               qvtend_clubb(igrdcol,1:ns,1:pverp-top_lev+1), thltend_clubb(igrdcol,1:ns,1:pverp-top_lev+1), &
    1910             :               silhs_config_flags%l_lh_instant_var_covar_src, &
    1911             :               rtp2_mc_zt(igrdcol,1:pverp-top_lev+1), thlp2_mc_zt(igrdcol,1:pverp-top_lev+1), &
    1912             :               wprtp_mc_zt(igrdcol,1:pverp-top_lev+1), wpthlp_mc_zt(igrdcol,1:pverp-top_lev+1), &
    1913             :               rtpthlp_mc_zt(igrdcol,1:pverp-top_lev+1) )
    1914             : 
    1915             :        ! The *_mc_zt microphysics tendencies are passed out of SILHS and back
    1916             :        ! to CLUBB without being used at all in the rest of the host model code.
    1917             :        ! The arrays aren't flipped for the *_mc_zt microphysics tendencies, and
    1918             :        ! they don't need to be.
    1919             : 
    1920             :        ! CLUBB used pverp vertical levels, but SILHS only uses
    1921             :        ! pverp - top_lev + 1 vertical levels.
    1922             :        ! Fill the upper levels with 0s when necessary.
    1923             :        if ( pverp > pverp-top_lev+1 ) then
    1924             :           rtp2_mc_zt(igrdcol,pverp-top_lev+2:pverp) = 0.0_r8
    1925             :           thlp2_mc_zt(igrdcol,pverp-top_lev+2:pverp) = 0.0_r8
    1926             :           wprtp_mc_zt(igrdcol,pverp-top_lev+2:pverp) = 0.0_r8
    1927             :           wpthlp_mc_zt(igrdcol,pverp-top_lev+2:pverp) = 0.0_r8
    1928             :           rtpthlp_mc_zt(igrdcol,pverp-top_lev+2:pverp) = 0.0_r8
    1929             :        endif ! pverp > pverp-top_lev+1
    1930             : 
    1931             :      end do ! igrdcol = 1, ngrdcol
    1932             : #endif
    1933             : #endif
    1934             : 
    1935           0 :      return
    1936           0 :    end subroutine subcol_SILHS_var_covar_driver
    1937             : #ifdef SILHS
    1938             :    real(r8) function meansc(arr_in, w_in, ns) result(val)
    1939             :       real(r8), intent(in) :: ns                         ! Length of Array
    1940             :       real(r8), dimension(int(ns)), intent(in) :: arr_in      ! Input array
    1941             :       real(r8), dimension(int(ns)), intent(in) :: w_in        ! Weights
    1942             :       real(r8) :: acc  ! accumulator
    1943             :       integer :: i
    1944             :       acc = 0
    1945             :       val = 0
    1946             :       do i=1,ns
    1947             :          acc = acc + arr_in(i)*w_in(i)
    1948             :       end do
    1949             :       val = acc/ns
    1950             :    end function
    1951             : 
    1952             :    real(r8) function stdsc(arr_in, w_in, mn_in, ns) result(val)
    1953             :       real(r8), intent(in) :: ns  ! Number of elements (subcolumns)
    1954             :       real(r8), dimension(int(ns)), intent(in) :: arr_in, w_in  !Input array and weights
    1955             :       real(r8), intent(in) :: mn_in   ! The mean of arr_in
    1956             :       real(r8) :: accvar, var
    1957             :       integer :: i
    1958             :       accvar = 0
    1959             :       do i=1,ns
    1960             :          accvar = accvar + ((arr_in(i)-mn_in)**2)*w_in(i)
    1961             :       end do
    1962             :       var = accvar/ns
    1963             :       val = sqrt(var)
    1964             :    end function
    1965             : 
    1966             :    subroutine THL_profile(nz, ABST_prof, ex_prof, rcm_prof, THL_prof)
    1967             : 
    1968             :       use clubb_api_module,              only : T_in_K2thlm_api
    1969             : 
    1970             :       integer,                 intent(in)  :: nz         ! Num vert levels
    1971             :       real(r8), dimension(nz), intent(in)  :: ABST_prof  ! Abs Temp prof
    1972             :       real(r8), dimension(nz), intent(in)  :: ex_prof    ! Profile of Exner func
    1973             :       real(r8), dimension(nz), intent(in)  :: rcm_prof   ! Profile of Cld Wat MR
    1974             :       real(r8), dimension(nz), intent(out) :: THL_prof  ! LWPT prof
    1975             :       integer :: i
    1976             :  
    1977             :       do i=1,nz
    1978             :          THL_prof(i) = T_in_K2thlm_api(ABST_prof(i), ex_prof(i), rcm_prof(i))
    1979             :       end do
    1980             :       
    1981             :    end subroutine
    1982             : 
    1983             :    subroutine subcol_constrainmn( num_subcols, samples, weights, grid_mean, mean_sc, std_sc )
    1984             : 
    1985             :       ! Input/Output Variables
    1986             :       integer, intent(in) :: num_subcols
    1987             :       real(r8), dimension(num_subcols, pverp), intent(inout) :: samples
    1988             :       real(r8), dimension(num_subcols), intent(in) :: weights
    1989             :       real(r8), dimension(pverp), intent(in) :: grid_mean
    1990             :       real(r8), dimension(pver), intent(out), optional :: mean_sc, std_sc
    1991             : 
    1992             :       ! Local Variables
    1993             :       real(r8) :: meansc_loc, adj_rat
    1994             :       integer :: k
    1995             :    !------------------------------------------------------------------
    1996             :       !----- Begin Code -----
    1997             :       do k=1, pver
    1998             :          meansc_loc = meansc( samples(:,k), weights(:), real(num_subcols, r8) )
    1999             : 
    2000             :          if (present(mean_sc)) &
    2001             :             mean_sc(k) = meansc_loc
    2002             :          if (present(std_sc)) &
    2003             :             std_sc(k) = stdsc( samples(:,k), weights(:), meansc_loc, &
    2004             :                                real(num_subcols, r8) )
    2005             : 
    2006             :          if ( meansc_loc > 0.0_r8 ) then
    2007             :             adj_rat = grid_mean(k)/meansc_loc
    2008             :          else 
    2009             :             ! If the mean is zero, then zero out all subcolumns to avoid
    2010             :             ! negative samples
    2011             :             adj_rat = 0.0_r8
    2012             :          end if
    2013             :          samples(:,k) = samples(:,k) * adj_rat
    2014             :       end do
    2015             :    end subroutine subcol_constrainmn
    2016             : 
    2017             :    ! =============================================================================== !
    2018             :    !                                                                                 !
    2019             :    ! =============================================================================== !
    2020             :    function clubb_flip_grid ( profile ) result( profile_flipped )
    2021             : 
    2022             :      ! Description:
    2023             :      !   Swaps the elements in profile so they are in reverse order. CAM and
    2024             :      !   CLUBB's grids are flipped with respect to each other.
    2025             :      !
    2026             :      !   Usage:
    2027             :      !     clubb_var = clubb_flip_grid( cam_var )
    2028             :      !     cam_var   = clubb_flip_grid( clubb_var )
    2029             : 
    2030             :      implicit none
    2031             : 
    2032             :      ! Input Variable
    2033             :      real(r8), dimension(pverp), intent(in) :: profile
    2034             : 
    2035             :      ! Output Variable
    2036             :      real(r8), dimension(pverp) :: profile_flipped
    2037             : 
    2038             :      ! Local Variable
    2039             :      integer :: k
    2040             : 
    2041             :      do k=1, pverp
    2042             :        profile_flipped(k) = profile(pverp-k+1)
    2043             :      end do ! k=1, pverp
    2044             : 
    2045             :      return
    2046             :    end function clubb_flip_grid
    2047             :    ! =============================================================================== !
    2048             :    !                                                                                 !
    2049             :    ! =============================================================================== !
    2050             : #endif
    2051             :    !============================================================================
    2052           0 :    subroutine subcol_SILHS_fill_holes_conserv( state, dt, ptend, pbuf )
    2053             : 
    2054             :      ! The William F. Buckley Jr. Conservative Hole Filler.
    2055             : 
    2056             :      ! Description:
    2057             :      ! Stops holes from forming in a hydrometeor mixing ratio by reducing the
    2058             :      ! microphysics tendency of that hydrometeor mixing ratio which would
    2059             :      ! otherwise cause that hydrometeor mixing ratio to have a negative value
    2060             :      ! once the microphysics tendency is applied.  This code is used to prevent
    2061             :      ! holes in water mass, not number concentration.
    2062             :      !
    2063             :      ! This subroutine is called after microphysics has completed and after
    2064             :      ! microphysics fields from subcolumns have been averaged back to grid
    2065             :      ! columns, but before the grid-column microphysics tendencies have been
    2066             :      ! applied in physics_update.  This code is meant for use with the SILHS
    2067             :      ! subcolumn approach.  This code needs to be applied to grid columns, not
    2068             :      ! subcolumns.
    2069             :      !
    2070             :      ! This code adjusts the tendencies (ptend) before they are used to update
    2071             :      ! the grid mean fields (state variables).
    2072             :      !
    2073             :      ! The column-integrated total water needs to be conserved during
    2074             :      ! microphysics.  The conserved amount includes the amount of water that
    2075             :      ! precipitated to the ground from sedimentation during microphysics.
    2076             :      ! The conservation equation for each grid column is:
    2077             :      !
    2078             :      ! SUM(k=top_lev:pver) ( rv_start(k) + rc_start(k) + rr_start(k)
    2079             :      !                       + ri_start(k) + rs_start(k) ) * pdel(k) / g
    2080             :      ! = SUM(k=top_lev:pver) ( rv(k) + rc(k) + rr(k) + ri(k) + rs(k) )
    2081             :      !                       * pdel(k) / g
    2082             :      !   + prect * dt * 1000;
    2083             :      !
    2084             :      ! where rv_start, rc_start, rr_start, ri_start, and rs_start are water
    2085             :      ! vapor, cloud water, rain water, cloud ice, and snow mixing ratios before
    2086             :      ! microphysics is called; rv, rc, rr, ri, and rs are water vapor, cloud
    2087             :      ! water, rain water, cloud ice, and snow mixing ratios after being updated
    2088             :      ! by microphysics; pdel is the pressure difference between vertical levels,
    2089             :      ! g is gravity, and prect * dt * 1000 is the total amount of water (from
    2090             :      ! all precipitating hydrometeors) that sedimented to the ground during
    2091             :      ! microphysics (dt is the timestep used for microphysics).  The units of
    2092             :      ! column-integrated total water are kg (water) / m^2.
    2093             :      !
    2094             :      ! All the updated hydrometeor fields are related to the hydrometeor fields
    2095             :      ! at the start by:
    2096             :      !
    2097             :      ! rv(k) = rv_start(k) + rv_tend(k) * dt;
    2098             :      ! rc(k) = rc_start(k) + rc_tend(k) * dt;
    2099             :      ! rr(k) = rr_start(k) + rr_tend(k) * dt;
    2100             :      ! ri(k) = ri_start(k) + ri_tend(k) * dt; and
    2101             :      ! rs(k) = rs_start(k) + rs_tend(k) * dt;
    2102             :      !
    2103             :      ! where rv_tend, rc_tend, rr_tend, ri_tend, and rs_tend are water vapor,
    2104             :      ! cloud water, rain water, cloud ice, and snow mixing ratio tendencies
    2105             :      ! from microphysics, which includes the sum of microphysics process rates
    2106             :      ! and sedimentation.  When these equations are applied to the equation
    2107             :      ! for column-integrated total water, that equation becomes:
    2108             :      !
    2109             :      ! SUM(k=top_lev:pver) ( rv_tend(k) + rc_tend(k) + rr_tend(k)
    2110             :      !                       + ri_tend(k) + rs_tend(k) ) * dt * pdel(k) / g
    2111             :      ! + prect * dt * 1000 = 0.
    2112             :      !
    2113             :      ! As stated above, the hydrometeor tendencies are the sum of tendencies
    2114             :      ! from microphysics process rates and tendencies from sedimentation:
    2115             :      !
    2116             :      ! rv_tend(k) = rv_mc_tend(k);
    2117             :      ! rc_tend(k) = rc_mc_tend(k) + rc_sed_tend(k);
    2118             :      ! rr_tend(k) = rr_mc_tend(k) + rr_sed_tend(k);
    2119             :      ! ri_tend(k) = ri_mc_tend(k) + ri_sed_tend(k); and
    2120             :      ! rs_tend(k) = rs_mc_tend(k) + rs_sed_tend(k);
    2121             :      !
    2122             :      ! where rv_mc_tend, rc_mc_tend, rr_mc_tend, ri_mc_tend, and rs_mc_tend are
    2123             :      ! the tendencies of water vapor, cloud water, rain water, cloud ice, and
    2124             :      ! snow from microphysics process rates, and rc_sed_tend, rr_sed_tend,
    2125             :      ! ri_sed_tend, and rs_sed_tend are the tendencies of cloud water,
    2126             :      ! rain water, cloud ice, and snow from sedimentation.  When these equations
    2127             :      ! are applied to the equation for column-integrated total water, that
    2128             :      ! equation becomes:
    2129             :      !
    2130             :      ! SUM(k=top_lev:pver) ( rv_mc_tend(k) + rc_mc_tend(k) + rr_mc_tend(k)
    2131             :      !                       + ri_mc_tend(k) + rs_mc_tend(k) )
    2132             :      !                     * dt * pdel(k) / g
    2133             :      ! + SUM(k=top_lev:pver) ( rc_sed_tend(k) + rr_sed_tend(k) + ri_sed_tend(k)
    2134             :      !                         + rs_sed_tend(k) ) * dt * pdel(k) / g
    2135             :      ! + prect * dt * 1000 = 0.
    2136             :      !
    2137             :      ! At any vertical level, the tendencies from microphysics process rates
    2138             :      ! (mc_tend variables) must balance:
    2139             :      !
    2140             :      ! rv_mc_tend(k) + rc_mc_tend(k) + rr_mc_tend(k)
    2141             :      ! + ri_mc_tend(k) + rs_mc_tend(k) = 0; for all k from top_lev to pver.
    2142             :      !
    2143             :      ! The column-integrated total water equation can be applied to
    2144             :      ! sedimentation:
    2145             :      !
    2146             :      ! SUM(k=top_lev:pver) ( rc_sed_tend(k) + rr_sed_tend(k) + ri_sed_tend(k)
    2147             :      !                       + rs_sed_tend(k) ) * dt * pdel(k) / g
    2148             :      ! + prect * dt * 1000 = 0.
    2149             :      !
    2150             :      ! The total precipitation rate, prect, can be split into liquid
    2151             :      ! precipitation rate, precl, and frozen precipitation rate, preci:
    2152             :      !
    2153             :      ! prect = precl + preci.
    2154             :      !
    2155             :      ! The microphysics code outputs prect and preci, so precl can be calculated
    2156             :      ! by precl = prect - preci.  The column-integrated total water equation can
    2157             :      ! be split into:
    2158             :      !
    2159             :      ! SUM(k=top_lev:pver) ( rc_sed_tend(k) + rr_sed_tend(k) )
    2160             :      !                     * dt * pdel(k) / g
    2161             :      ! + precl * dt * 1000 = 0; and
    2162             :      !
    2163             :      ! SUM(k=top_lev:pver) ( ri_sed_tend(k) + rs_sed_tend(k) )
    2164             :      !                     * dt * pdel(k) / g
    2165             :      ! + preci * dt * 1000 = 0.
    2166             :      !
    2167             :      ! Overall, the conservation methods used in this subroutine are:
    2168             :      !
    2169             :      ! 1) When adjusting the tendencies from microphysics process rates,
    2170             :      !    conserve:
    2171             :      !
    2172             :      !    rv_mc_tend(k) + rc_mc_tend(k) + rr_mc_tend(k)
    2173             :      !    + ri_mc_tend(k) + rs_mc_tend(k) = 0; for all k from top_lev to pver.
    2174             :      !
    2175             :      ! 2) When adjusting the tendencies from microphysics process rates, adjust
    2176             :      !    dry static energy appropriately.  The change in dry static energy
    2177             :      !    is necessary because of phase changes.  This "puts back" the extra dry
    2178             :      !    static energy that was "taken out" when an excessive phase-changing
    2179             :      !    process rate was produced by microphysics.
    2180             :      !
    2181             :      ! 3) When adjusting the hydrometeor tendency from sedimentation of a
    2182             :      !    liquid hydrometeor (cloud water or rain water), conserve:
    2183             :      !
    2184             :      !    SUM(k=top_lev:pver) ( rc_sed_tend(k) + rr_sed_tend(k) )
    2185             :      !                        * dt * pdel(k) / g
    2186             :      !    + precl * dt * 1000 = 0.
    2187             :      !
    2188             :      ! 4) When adjusting the hydrometeor tendency from sedimentation of a
    2189             :      !    frozen hydrometeor (cloud ice or snow), conserve:
    2190             :      !
    2191             :      !    SUM(k=top_lev:pver) ( ri_sed_tend(k) + rs_sed_tend(k) )
    2192             :      !                        * dt * pdel(k) / g
    2193             :      !    + preci * dt * 1000 = 0.
    2194             :      !
    2195             :      ! The conservative hole filler works as follows.  The total microphysics
    2196             :      ! tendency for each hydrometeor is provided in ptend.  This is the sum of
    2197             :      ! the microphysics process rate tendency and sedimentation tendency for
    2198             :      ! each hydrometeor.  The sedimentation tendency is provided in pbuf.  The
    2199             :      ! sedimentation tendency is subtracted off the total microphysics tendency
    2200             :      ! to produce the microphysics process rate tendency for each hydrometeor.
    2201             :      ! The microphysics process rate tendency is adjusted when necessary so that
    2202             :      ! holes in the hydrometeor are not produced by microphysics process rates.
    2203             :      ! When a hydrometeor's negative microphysics process rate tendency needs to
    2204             :      ! be made smaller in magnitude to avoid a hole, all hydrometeor tendencies
    2205             :      ! that are positive at that grid level are also decreased proportionately
    2206             :      ! to maintain a balance.  Dry static energy tendency is also adjusted
    2207             :      ! appropriately when necessary.  After this, the vertical integral of each
    2208             :      ! hydrometeor species is greater than or equal to 0.
    2209             :      !
    2210             :      ! The sedimentation tendency is then added back onto the new microphysics
    2211             :      ! process rate tendency to produce a new total microphysics tendency for
    2212             :      ! each hydrometeor.  Since the sedimentation tendency was based on the old
    2213             :      ! value of hydrometeor, before the hole-filling adjustment, it is possible
    2214             :      ! that the new total microphysics tendency may produce holes.  When this
    2215             :      ! happens, sedimentation hole filling fills holes in the vertical profile
    2216             :      ! of each hydrometeor.  Holes are filled using mass from other vertical
    2217             :      ! levels for the same hydrometeor (or from a same-phase hydrometeor when
    2218             :      ! necessary).  Since the vertical integral of sedimentation tendency
    2219             :      ! (including surface precipitation rate) is 0, the vertical integral of the
    2220             :      ! hydrometeor must be greater than or equal to 0, which means that all
    2221             :      ! holes can be filled.  The result is that all holes in any hydrometeor
    2222             :      ! mixing ratio are filled completely and conservatively.  The value of
    2223             :      ! ptend is updated appropriately so that it can be applied later in
    2224             :      ! physics_update.
    2225             : 
    2226             :      !----------------------------------------------------------------------
    2227             : 
    2228           0 :      use physics_buffer, only: &
    2229             :          physics_buffer_desc, &
    2230             :          pbuf_get_field
    2231             : 
    2232             :      use ppgrid, only: &
    2233             :          pcols
    2234             : 
    2235             :      use constituents, only: &
    2236             :          qmin
    2237             : 
    2238             :      use ref_pres, only: &
    2239             :          top_lev => trop_cloud_top_lev
    2240             : 
    2241             :      implicit none
    2242             : 
    2243             :      ! Input Variables
    2244             :      type(physics_state), intent(in) :: state     ! Physics state variables
    2245             :      real(r8), intent(in) :: dt                   ! Time step duration
    2246             : 
    2247             :      ! Input/Output Variables
    2248             :      type(physics_ptend),  intent(inout) :: ptend  ! Parameterization tendencies
    2249             :      type(physics_buffer_desc), pointer :: pbuf(:) ! Physics buffer
    2250             : 
    2251             :      ! Local Variables
    2252             :      real(r8), dimension(pcols,pver) :: &
    2253             :        rv_start, & ! Water vapor mixing ratio at start of microphysics  [kg/kg]
    2254             :        rc_start, & ! Cloud water mixing ratio at start of microphysics  [kg/kg]
    2255             :        rr_start, & ! Rain water mixing ratio at start of microphysics   [kg/kg]
    2256             :        ri_start, & ! Cloud ice mixing ratio at start of microphysics    [kg/kg]
    2257             :        rs_start    ! Snow mixing ratio at start of microphysics         [kg/kg]
    2258             : 
    2259             :      real(r8), dimension(pcols,pver) :: &
    2260             :        rv_tend, & ! Water vapor mixing ratio tendency  [kg/kg/s]
    2261             :        rc_tend, & ! Cloud water mixing ratio tendency  [kg/kg/s]
    2262             :        rr_tend, & ! Rain water mixing ratio tendency   [kg/kg/s]
    2263             :        ri_tend, & ! Cloud ice mixing ratio tendency    [kg/kg/s]
    2264             :        rs_tend, & ! Snow mixing ratio tendency         [kg/kg/s]
    2265             :        stend      ! Dry static energy tendency         [J/kg/s]
    2266             : 
    2267             :      real(r8), dimension(:), pointer :: &
    2268           0 :        prect,    & ! Total microphysics precipitation rate (surface)      [m/s]
    2269           0 :        preci,    & ! Ice-phase microphysics precipitation rate (surface)  [m/s]
    2270           0 :        prec_str, & ! Total surface precipitation rate from stratoform     [m/s]
    2271           0 :        snow_str    ! Snow surface precipitation rate from stratoform      [m/s]
    2272             : 
    2273             :      real(r8), dimension(:,:), pointer :: &
    2274           0 :        rc_sed_tend, & ! Mean cloud water sedimentation tendency        [kg/kg/s]
    2275           0 :        rr_sed_tend, & ! Mean rain water sedimentation tendency         [kg/kg/s]
    2276           0 :        ri_sed_tend, & ! Mean cloud ice sedimentation tendency          [kg/kg/s]
    2277           0 :        rs_sed_tend, & ! Mean snow sedimentation tendency               [kg/kg/s]
    2278           0 :        vtrmc,       & ! Mean cloud water sedimentation velocity        [m/s]
    2279           0 :        umr,         & ! Mean rain water sedimentation velocity         [m/s]
    2280           0 :        vtrmi,       & ! Mean cloud ice sedimentation velocity          [m/s]
    2281           0 :        ums,         & ! Mean snow sedimentation velocity               [m/s]
    2282           0 :        rc_sed_evap, & ! Mean evap of cloud water during sedimentation  [kg/kg/s]
    2283           0 :        ri_sed_subl    ! Mean subl of cloud ice during sedimentation    [kg/kg/s]
    2284             : 
    2285             :      real(r8), dimension(pcols,pver) :: &
    2286             :        rv_mc_tend, & ! Water vapor mixing ratio microphysics tendency  [kg/kg/s]
    2287             :        rc_mc_tend, & ! Cloud water mixing ratio microphysics tendency  [kg/kg/s]
    2288             :        rr_mc_tend, & ! Rain water mixing ratio microphysics tendency   [kg/kg/s]
    2289             :        ri_mc_tend, & ! Cloud ice mixing ratio microphysics tendency    [kg/kg/s]
    2290             :        rs_mc_tend    ! Snow mixing ratio microphysics tendency         [kg/kg/s]
    2291             : 
    2292             :      real(r8) :: &
    2293             :        rv_curr, & ! Current water vapor mixing ratio    [kg/kg]
    2294             :        rc_curr, & ! Current cloud water mixing ratio    [kg/kg]
    2295             :        rr_curr, & ! Current rain water mixing ratio     [kg/kg]
    2296             :        ri_curr, & ! Current cloud ice mixing ratio      [kg/kg]
    2297             :        rs_curr    ! Current snow mixing ratio           [kg/kg]
    2298             : 
    2299             :      logical :: &
    2300             :        l_pos_rv_mc_tend, & ! Flag for positive water vapor mixing ratio mc tend.
    2301             :        l_pos_rc_mc_tend, & ! Flag for positive cloud water mixing ratio mc tend.
    2302             :        l_pos_rr_mc_tend, & ! Flag for positive rain water mixing ratio mc tend.
    2303             :        l_pos_ri_mc_tend, & ! Flag for positive cloud ice mixing ratio mc tend.
    2304             :        l_pos_rs_mc_tend    ! Flag for positive snow mixing ratio mc tend.
    2305             : 
    2306             :      real(r8) :: &
    2307             :        mc_tend_max_mag,     & ! Max. allowable mag. of (neg.) mc tend [kg/kg/s]
    2308             :        mc_tend_correction,  & ! Amnt. correction necessary to mc tend [kg/kg/s]
    2309             :        total_mc_positive,   & ! Total of all positive mc tendencies   [kg/kg/s]
    2310             :        mc_correction_ratio    ! Ratio: mc_tend_correction/total_mc_positive [-]
    2311             : 
    2312             :      real(r8), dimension(pcols) :: &
    2313             :        precl    ! Liquid-phase precipitation rate (surface)        [m/s]
    2314             : 
    2315             :      ! Budgeting terms for hole filling.
    2316             :      ! These variables are for use in stats output.
    2317             :      real(r8), dimension(pcols,pver) :: &
    2318             :        rv_hf_tend, & ! Water vapor mixing ratio hole-filling tendency  [kg/kg/s]
    2319             :        rc_hf_tend, & ! Cloud water mixing ratio hole-filling tendency  [kg/kg/s]
    2320             :        rr_hf_tend, & ! Rain water mixing ratio hole-filling tendency   [kg/kg/s]
    2321             :        ri_hf_tend, & ! Cloud ice mixing ratio hole-filling tendency    [kg/kg/s]
    2322             :        rs_hf_tend, & ! Snow mixing ratio hole-filling tendency         [kg/kg/s]
    2323             :        s_hf_tend     ! Dry static energy hole-filling tendency         [J/kg/s]
    2324             : 
    2325             :      integer :: ncol  ! Number of grid columns
    2326             : 
    2327             :      integer :: icol, k  ! Loop indices
    2328             : 
    2329             :      ! Flag to perform hole filling after the original sedimentation tendency
    2330             :      ! is added back on to the new microphysics process tendency.  This calls
    2331             :      ! the sedimentation hole filler.
    2332             :      logical, parameter :: &
    2333             :        l_sed_hole_fill = .true.
    2334             : 
    2335             :      logical, parameter :: &
    2336             :        l_check_conservation = .true. ! Flag to perform water conservation check
    2337             : 
    2338             :      ! Vertically-integrated grand total water (rv+rc+rr+ri+rs)    [kg/m^2]
    2339             :      real(r8), dimension(pcols) :: &
    2340             :        grand_total_water_column_start,  & ! Column integral at start
    2341             :        grand_total_water_column_finish    ! Column integral at finish
    2342             : 
    2343             :      ! Vertically-integrated total water energy    [J/m^2]
    2344             :      real(r8), dimension(pcols) :: &
    2345             :        total_energy_column_start,  & ! Column integral at start
    2346             :        total_energy_column_finish    ! Column integral at finish
    2347             : 
    2348             :      real(r8), dimension(pcols) :: &
    2349             :        tot_water_rel_err,  & ! Relative error: vert-integrated grand total water
    2350             :        tot_energy_rel_err    ! Relative error: vert-integrated total energy
    2351             : 
    2352             :      real(r8), parameter :: &
    2353             :        err_thresh = 1.0e-14_r8  ! Threshold of relative error
    2354             : 
    2355             : 
    2356             :      ! Get the number of grid columns.
    2357           0 :      ncol = state%ncol
    2358             : 
    2359             :      ! Get fields from the pbuf.
    2360           0 :      call pbuf_get_field(pbuf, prec_pcw_idx, prect)
    2361           0 :      call pbuf_get_field(pbuf, snow_pcw_idx, preci)
    2362           0 :      call pbuf_get_field(pbuf, prec_str_idx, prec_str)
    2363           0 :      call pbuf_get_field(pbuf, snow_str_idx, snow_str)
    2364           0 :      call pbuf_get_field(pbuf, qcsedten_idx, rc_sed_tend)
    2365           0 :      call pbuf_get_field(pbuf, qrsedten_idx, rr_sed_tend)
    2366           0 :      call pbuf_get_field(pbuf, qisedten_idx, ri_sed_tend)
    2367           0 :      call pbuf_get_field(pbuf, qssedten_idx, rs_sed_tend)
    2368           0 :      call pbuf_get_field(pbuf, vtrmc_idx, vtrmc)
    2369           0 :      call pbuf_get_field(pbuf, umr_idx, umr)
    2370           0 :      call pbuf_get_field(pbuf, vtrmi_idx, vtrmi)
    2371           0 :      call pbuf_get_field(pbuf, ums_idx, ums)
    2372           0 :      call pbuf_get_field(pbuf, qcsevap_idx, rc_sed_evap)
    2373           0 :      call pbuf_get_field(pbuf, qisevap_idx, ri_sed_subl)
    2374             : 
    2375             :      ! Calculate liquid precipitation rate (precl) from the total precipitation
    2376             :      ! rate (prect) and the frozen preciptation rate (preci).  This should never
    2377             :      ! be negative, but just to be safe, threshold at 0.
    2378           0 :      precl(:ncol) = max( prect(:ncol) - preci(:ncol), 0.0_r8 )
    2379             : 
    2380             :      ! Perform total water and total energy conservation checks.
    2381             :      if ( l_check_conservation ) then
    2382             : 
    2383             :         ! Calculate total water in each column.
    2384             :         ! This calculation is the vertically-integrated grand total water (where
    2385             :         ! grand total water is the sum of water vapor, cloud water, rain water,
    2386             :         ! cloud ice, and snow, as well as the amount of water that precipitated
    2387             :         ! to the surface) in each grid column after microphysics, but at the
    2388             :         ! start of hole filling.
    2389           0 :         do icol = 1, ncol
    2390           0 :            grand_total_water_column_start(icol) = 0.0_r8
    2391           0 :            do k = top_lev, pver
    2392             :               grand_total_water_column_start(icol) &
    2393             :               = grand_total_water_column_start(icol) &
    2394           0 :                 + ( state%q(icol,k,1) + ptend%q(icol,k,1) * dt &
    2395           0 :                     + state%q(icol,k,ixcldliq) &
    2396           0 :                     + ptend%q(icol,k,ixcldliq) * dt &
    2397           0 :                     + state%q(icol,k,ixcldice) &
    2398           0 :                     + ptend%q(icol,k,ixcldice) * dt ) &
    2399           0 :                   * state%pdel(icol,k) * rga
    2400           0 :               if ( ixrain > 0 ) then
    2401             :                  grand_total_water_column_start(icol) &
    2402             :                  = grand_total_water_column_start(icol) &
    2403           0 :                    + ( state%q(icol,k,ixrain) + ptend%q(icol,k,ixrain) * dt ) &
    2404           0 :                      * state%pdel(icol,k) * rga
    2405             :               endif
    2406           0 :               if ( ixsnow > 0 ) then
    2407             :                  grand_total_water_column_start(icol) &
    2408             :                  = grand_total_water_column_start(icol) &
    2409           0 :                    + ( state%q(icol,k,ixsnow) + ptend%q(icol,k,ixsnow) * dt ) &
    2410           0 :                      * state%pdel(icol,k) * rga
    2411             :               endif
    2412             :            end do ! k = top_lev, pver
    2413             :            grand_total_water_column_start(icol) &
    2414             :            = grand_total_water_column_start(icol) &
    2415           0 :              + prect(icol) * dt * 1000.0_r8
    2416             :         end do ! icol = 1, ncol
    2417             : 
    2418             :         ! Calculate total energy in each column.
    2419             :         ! This calculation is the vertically-integrated total energy in each
    2420             :         ! grid column after microphysics, but at the start of hole filling.
    2421             :         ! Since the microphysics and hole filling code does not directly change
    2422             :         ! kinetic energy, 0.5 * ( u^2 + v^2 ), it can be skipped as part of the
    2423             :         ! energy conservation check.
    2424           0 :         do icol = 1, ncol
    2425           0 :            total_energy_column_start(icol) = 0.0_r8
    2426           0 :            do k = top_lev, pver
    2427             :               total_energy_column_start(icol) &
    2428             :               = total_energy_column_start(icol) &
    2429           0 :                 + ( state%s(icol,k) + ptend%s(icol,k) * dt &
    2430             :                     + ( latvap + latice ) &
    2431           0 :                       * ( state%q(icol,k,1) + ptend%q(icol,k,1) * dt ) &
    2432           0 :                     + latice * ( state%q(icol,k,ixcldliq) &
    2433           0 :                                  + ptend%q(icol,k,ixcldliq) * dt ) ) &
    2434           0 :                   * state%pdel(icol,k) * rga
    2435           0 :               if ( ixrain > 0 ) then
    2436             :                  total_energy_column_start(icol) &
    2437             :                  = total_energy_column_start(icol) &
    2438           0 :                    + latice * ( state%q(icol,k,ixrain) &
    2439           0 :                                 + ptend%q(icol,k,ixrain) * dt ) &
    2440           0 :                      * state%pdel(icol,k) * rga
    2441             :               endif
    2442             :            end do ! k = top_lev, pver
    2443             :            total_energy_column_start(icol) &
    2444             :            = total_energy_column_start(icol) &
    2445           0 :              + latice * precl(icol) * dt * 1000.0_r8
    2446             :         end do ! icol = 1, ncol
    2447             : 
    2448             :      endif ! l_check_conservation
    2449             : 
    2450             :      ! The fields within state haven't been updated yet, since this is before
    2451             :      ! the call to physics_update.
    2452           0 :      rv_start = state%q(:,:,1)
    2453           0 :      rc_start = state%q(:,:,ixcldliq)
    2454           0 :      if ( ixrain > 0 ) then
    2455           0 :         rr_start = state%q(:,:,ixrain)
    2456             :      endif
    2457           0 :      ri_start = state%q(:,:,ixcldice)
    2458           0 :      if ( ixsnow > 0 ) then
    2459           0 :         rs_start = state%q(:,:,ixsnow)
    2460             :      endif
    2461             : 
    2462             :      ! Unpack the current total tendencies for hydrometeor mixing ratio fields.
    2463           0 :      rv_tend = ptend%q(:,:,1)
    2464           0 :      rc_tend = ptend%q(:,:,ixcldliq)
    2465           0 :      if ( ixrain > 0 ) then
    2466           0 :         rr_tend = ptend%q(:,:,ixrain)
    2467             :      endif
    2468           0 :      ri_tend = ptend%q(:,:,ixcldice)
    2469           0 :      if ( ixsnow > 0 ) then
    2470           0 :         rs_tend = ptend%q(:,:,ixsnow)
    2471             :      endif
    2472             : 
    2473             :      ! Unpack the current tendency for dry static energy.
    2474           0 :      stend = ptend%s
    2475             : 
    2476             :      ! The total hydrometeor tendencies are the sum of microphysics process
    2477             :      ! rates and sedimentation rates.  Calculate the microphysics process
    2478             :      ! tendencies by subtracting the sedimentation tendencies from the overall
    2479             :      ! tendencies.
    2480             :      ! The sedimentation tendencies for cloud water (rc_sed_tend) and cloud ice
    2481             :      ! (ri_sed_tend) include the evaporation of cloud water during sedimentation
    2482             :      ! and the sublimation of cloud ice during sedimentation, respectively.  The
    2483             :      ! true sedimentation of cloud water is the sum of rc_sed_tend and
    2484             :      ! rc_sed_evap, and the true sedimentation of cloud ice is the sum of
    2485             :      ! ri_sed_tend and ri_sed_subl.  Subtract off only the true sedimentation
    2486             :      ! rates, as evaporation and sublimation need to be included in the
    2487             :      ! microphysics process rates.
    2488           0 :      rv_mc_tend(:ncol,:) = rv_tend(:ncol,:)
    2489           0 :      rc_mc_tend(:ncol,:) = rc_tend(:ncol,:) - ( rc_sed_tend(:ncol,:) + rc_sed_evap(:ncol,:) )
    2490           0 :      if ( ixrain > 0 ) then
    2491           0 :         rr_mc_tend(:ncol,:) = rr_tend(:ncol,:) - rr_sed_tend(:ncol,:)
    2492             :      endif
    2493           0 :      ri_mc_tend(:ncol,:) = ri_tend(:ncol,:) - ( ri_sed_tend(:ncol,:) + ri_sed_subl(:ncol,:) )
    2494           0 :      if ( ixsnow > 0 ) then
    2495           0 :         rs_mc_tend(:ncol,:) = rs_tend(:ncol,:) - rs_sed_tend(:ncol,:)
    2496             :      endif
    2497             : 
    2498             :      ! This section adjusts microphysics process rate tendencies so that the
    2499             :      ! resulting values of all hydrometeor mixing ratios are greater than or
    2500             :      ! equal to qmin after this section is complete.  Once sedimentation is
    2501             :      ! added back on after this section, some of the hydrometeor mixing ratios
    2502             :      ! may become less than qmin again.
    2503             :      !
    2504             :      ! This section, which again is concerned only with adjusting microphysics
    2505             :      ! process rates, makes use of the following two principles:
    2506             :      !
    2507             :      ! 1) When adjusting the tendencies from microphysics process rates,
    2508             :      !    conserve:
    2509             :      !
    2510             :      !    rv_mc_tend(k) + rc_mc_tend(k) + rr_mc_tend(k)
    2511             :      !    + ri_mc_tend(k) + rs_mc_tend(k) = 0; for all k from top_lev to pver.
    2512             :      !
    2513             :      ! 2) When adjusting the tendencies from microphysics process rates, adjust
    2514             :      !    dry static energy appropriately.  The change in dry static energy
    2515             :      !    is necessary because of phase changes.  This "puts back" the extra dry
    2516             :      !    static energy that was "taken out" when an excessive phase-changing
    2517             :      !    process rate was produced by microphysics.
    2518             : 
    2519             :      ! Loop over all columns, performing any tendency adjustments one column
    2520             :      ! at a time.
    2521           0 :      do icol = 1, ncol
    2522             : 
    2523             :         ! Loop over all vertical levels, performing any microphysics process
    2524             :         ! tendency adjustments one level at a time.
    2525           0 :         do k = top_lev, pver
    2526             : 
    2527             :            ! Find which hydrometeors have positive microphysics process
    2528             :            ! tendencies at this level.
    2529           0 :            if ( rv_mc_tend(icol,k) >= 0.0_r8 ) then
    2530             :               l_pos_rv_mc_tend = .true.
    2531             :            else
    2532           0 :               l_pos_rv_mc_tend = .false.
    2533             :            endif
    2534           0 :            if ( rc_mc_tend(icol,k) >= 0.0_r8 ) then
    2535             :               l_pos_rc_mc_tend = .true.
    2536             :            else
    2537           0 :               l_pos_rc_mc_tend = .false.
    2538             :            endif
    2539           0 :            if ( ixrain > 0 ) then
    2540           0 :               if ( rr_mc_tend(icol,k) >= 0.0_r8 ) then
    2541             :                  l_pos_rr_mc_tend = .true.
    2542             :               else
    2543           0 :                  l_pos_rr_mc_tend = .false.
    2544             :               endif
    2545             :            endif
    2546           0 :            if ( ri_mc_tend(icol,k) >= 0.0_r8 ) then
    2547             :               l_pos_ri_mc_tend = .true.
    2548             :            else
    2549           0 :               l_pos_ri_mc_tend = .false.
    2550             :            endif
    2551           0 :            if ( ixsnow > 0 ) then
    2552           0 :               if ( rs_mc_tend(icol,k) >= 0.0_r8 ) then
    2553             :                  l_pos_rs_mc_tend = .true.
    2554             :               else
    2555           0 :                  l_pos_rs_mc_tend = .false.
    2556             :               endif
    2557             :            endif
    2558             : 
    2559             :            !!! Check for holes in water vapor mixing ratio
    2560           0 :            if ( .not. l_pos_rv_mc_tend ) then
    2561             : 
    2562             :               ! Calculate the water vapor mixing ratio as it would be with the
    2563             :               ! current microphysics process tendency.
    2564           0 :               rv_curr = rv_start(icol,k) + rv_mc_tend(icol,k) * dt
    2565             : 
    2566           0 :               if ( rv_curr < qmin(1) ) then
    2567             : 
    2568             :                  ! Microphysics processes are causing a hole in water vapor
    2569             :                  ! mixing ratio.
    2570             : 
    2571             :                  ! Calculate the maximum allowable magnitude of (negative) water
    2572             :                  ! vapor microphysics process tendency.
    2573           0 :                  mc_tend_max_mag = ( qmin(1) - rv_start(icol,k) ) / dt
    2574             : 
    2575             :                  ! Calculate the amount of the correction that needs to be made
    2576             :                  ! to the water vapor mixing ratio microphysics process
    2577             :                  ! tendency.  This number is positive.
    2578           0 :                  mc_tend_correction = mc_tend_max_mag - rv_mc_tend(icol,k)
    2579             : 
    2580             :                  ! Calculate the total amount of positive microphysics process
    2581             :                  ! tendencies for all hydrometeor mixing ratios.
    2582           0 :                  total_mc_positive = 0.0_r8
    2583           0 :                  if ( l_pos_rc_mc_tend ) then
    2584           0 :                     total_mc_positive = total_mc_positive + rc_mc_tend(icol,k)
    2585             :                  endif
    2586           0 :                  if ( ixrain > 0 .and. l_pos_rr_mc_tend ) then
    2587           0 :                     total_mc_positive = total_mc_positive + rr_mc_tend(icol,k)
    2588             :                  endif
    2589           0 :                  if ( l_pos_ri_mc_tend ) then
    2590           0 :                     total_mc_positive = total_mc_positive + ri_mc_tend(icol,k)
    2591             :                  endif
    2592           0 :                  if ( ixsnow > 0 .and. l_pos_rs_mc_tend ) then
    2593           0 :                     total_mc_positive = total_mc_positive + rs_mc_tend(icol,k)
    2594             :                  endif
    2595             : 
    2596             :                  ! Calculate the correction ratio.
    2597             :                  ! In principle, this should never be greater than 1 outside of
    2598             :                  ! numerical round-off errors.  This is limited at 1 to be safe.
    2599             :                  mc_correction_ratio &
    2600             :                  = min( mc_tend_correction &
    2601           0 :                         / max( total_mc_positive, 1.0e-30_r8 ), 1.0_r8 )
    2602             : 
    2603             :                  ! Adjust (decrease) the tendencies of all positive hydrometeor
    2604             :                  ! mixing ratio tendencies to balance the adjustment (increase)
    2605             :                  ! to the excessively negative water vapor mixing ratio.
    2606             :                  ! Transfer dry static energy appropriately (in response to the
    2607             :                  ! excessive depletion of water vapor).
    2608           0 :                  if ( l_pos_rc_mc_tend ) then
    2609             :                     ! Changing cloud water to water vapor cools and reduces
    2610             :                     ! dry static energy.
    2611             :                     stend(icol,k) &
    2612             :                     = stend(icol,k) &
    2613           0 :                       - latvap * mc_correction_ratio * rc_mc_tend(icol,k)
    2614             :                     ! Update cloud water mixing ratio microphysics tendency.
    2615             :                     rc_mc_tend(icol,k) &
    2616           0 :                     = rc_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2617             :                  endif
    2618           0 :                  if ( ixrain > 0 .and. l_pos_rr_mc_tend ) then
    2619             :                     ! Changing rain water to water vapor cools and reduces
    2620             :                     ! dry static energy.
    2621             :                     stend(icol,k) &
    2622             :                     = stend(icol,k) &
    2623           0 :                       - latvap * mc_correction_ratio * rr_mc_tend(icol,k)
    2624             :                     ! Update rain water mixing ratio microphysics tendency.
    2625             :                     rr_mc_tend(icol,k) &
    2626           0 :                     = rr_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2627             :                  endif
    2628           0 :                  if ( l_pos_ri_mc_tend ) then
    2629             :                     ! Changing cloud ice to water vapor cools and reduces
    2630             :                     ! dry static energy.
    2631             :                     stend(icol,k) &
    2632             :                     = stend(icol,k) &
    2633             :                       - ( latvap + latice ) &
    2634           0 :                         * mc_correction_ratio * ri_mc_tend(icol,k)
    2635             :                     ! Update cloud ice mixing ratio microphysics tendency.
    2636             :                     ri_mc_tend(icol,k) &
    2637           0 :                     = ri_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2638             :                  endif
    2639           0 :                  if ( ixsnow > 0 .and. l_pos_rs_mc_tend ) then
    2640             :                     ! Changing snow to water vapor cools and reduces dry
    2641             :                     ! static energy.
    2642             :                     stend(icol,k) &
    2643             :                     = stend(icol,k) &
    2644             :                       - ( latvap + latice ) &
    2645           0 :                         * mc_correction_ratio * rs_mc_tend(icol,k)
    2646             :                     ! Update snow mixing ratio microphysics tendency.
    2647             :                     rs_mc_tend(icol,k) &
    2648           0 :                     = rs_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2649             :                  endif
    2650             : 
    2651             :                  ! Calculate the new water vapor mixing ratio microphysics
    2652             :                  ! process tendency.  This should be equal to the maximum
    2653             :                  ! magnitude (negative) amount allowed, mc_tend_max_mag.
    2654             :                  rv_mc_tend(icol,k) &
    2655             :                  = rv_mc_tend(icol,k) &
    2656           0 :                    + mc_correction_ratio * total_mc_positive
    2657             : 
    2658             :               endif ! rv_curr < qmin(1)
    2659             : 
    2660             :            endif ! .not. l_pos_rv_mc_tend
    2661             : 
    2662             :            !!! Check for holes in cloud water mixing ratio
    2663           0 :            if ( .not. l_pos_rc_mc_tend ) then
    2664             : 
    2665             :               ! Calculate the cloud water mixing ratio as it would be with the
    2666             :               ! current microphysics process tendency.
    2667           0 :               rc_curr = rc_start(icol,k) + rc_mc_tend(icol,k) * dt
    2668             : 
    2669           0 :               if ( rc_curr < qmin(ixcldliq) ) then
    2670             : 
    2671             :                  ! Microphysics processes are causing a hole in cloud water
    2672             :                  ! mixing ratio.
    2673             : 
    2674             :                  ! Calculate the maximum allowable magnitude of (negative) cloud
    2675             :                  ! water microphysics process tendency.
    2676           0 :                  mc_tend_max_mag = ( qmin(ixcldliq) - rc_start(icol,k) ) / dt
    2677             : 
    2678             :                  ! Calculate the amount of the correction that needs to be made
    2679             :                  ! to the cloud water mixing ratio microphysics process
    2680             :                  ! tendency.  This number is positive.
    2681           0 :                  mc_tend_correction = mc_tend_max_mag - rc_mc_tend(icol,k)
    2682             : 
    2683             :                  ! Calculate the total amount of positive microphysics process
    2684             :                  ! tendencies for all hydrometeor mixing ratios.
    2685           0 :                  total_mc_positive = 0.0_r8
    2686           0 :                  if ( l_pos_rv_mc_tend ) then
    2687           0 :                     total_mc_positive = total_mc_positive + rv_mc_tend(icol,k)
    2688             :                  endif
    2689           0 :                  if ( ixrain > 0 .and. l_pos_rr_mc_tend ) then
    2690           0 :                     total_mc_positive = total_mc_positive + rr_mc_tend(icol,k)
    2691             :                  endif
    2692           0 :                  if ( l_pos_ri_mc_tend ) then
    2693           0 :                     total_mc_positive = total_mc_positive + ri_mc_tend(icol,k)
    2694             :                  endif
    2695           0 :                  if ( ixsnow > 0 .and. l_pos_rs_mc_tend ) then
    2696           0 :                     total_mc_positive = total_mc_positive + rs_mc_tend(icol,k)
    2697             :                  endif
    2698             : 
    2699             :                  ! Calculate the correction ratio.
    2700             :                  ! In principle, this should never be greater than 1 outside of
    2701             :                  ! numerical round-off errors.  This is limited at 1 to be safe.
    2702             :                  mc_correction_ratio &
    2703             :                  = min( mc_tend_correction &
    2704           0 :                         / max( total_mc_positive, 1.0e-30_r8 ), 1.0_r8 )
    2705             : 
    2706             :                  ! Adjust (decrease) the tendencies of all positive hydrometeor
    2707             :                  ! mixing ratio tendencies to balance the adjustment (increase)
    2708             :                  ! to the excessively negative cloud water mixing ratio.
    2709             :                  ! Transfer dry static energy appropriately (in response to the
    2710             :                  ! excessive depletion of cloud water).
    2711           0 :                  if ( l_pos_rv_mc_tend ) then
    2712             :                     ! Changing water vapor to cloud water heats and increases
    2713             :                     ! dry static energy.
    2714             :                     stend(icol,k) &
    2715             :                     = stend(icol,k) &
    2716           0 :                       + latvap * mc_correction_ratio * rv_mc_tend(icol,k)
    2717             :                     ! Update water vapor mixing ratio microphysics tendency.
    2718             :                     rv_mc_tend(icol,k) &
    2719           0 :                     = rv_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2720             :                  endif
    2721           0 :                  if ( ixrain > 0 .and. l_pos_rr_mc_tend ) then
    2722             :                     ! Changing rain water to cloud water does not change
    2723             :                     ! dry static energy.
    2724             :                     ! Update rain water mixing ratio microphysics tendency.
    2725             :                     rr_mc_tend(icol,k) &
    2726           0 :                     = rr_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2727             :                  endif
    2728           0 :                  if ( l_pos_ri_mc_tend ) then
    2729             :                     ! Changing cloud ice to cloud water cools and reduces
    2730             :                     ! dry static energy.
    2731             :                     stend(icol,k) &
    2732             :                     = stend(icol,k) &
    2733           0 :                       - latice * mc_correction_ratio * ri_mc_tend(icol,k)
    2734             :                     ! Update cloud ice mixing ratio microphysics tendency.
    2735             :                     ri_mc_tend(icol,k) &
    2736           0 :                     = ri_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2737             :                  endif
    2738           0 :                  if ( ixsnow > 0 .and. l_pos_rs_mc_tend ) then
    2739             :                     ! Changing snow to cloud water cools and reduces dry
    2740             :                     ! static energy.
    2741             :                     stend(icol,k) &
    2742             :                     = stend(icol,k) &
    2743           0 :                       - latice * mc_correction_ratio * rs_mc_tend(icol,k)
    2744             :                     ! Update snow mixing ratio microphysics tendency.
    2745             :                     rs_mc_tend(icol,k) &
    2746           0 :                     = rs_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2747             :                  endif
    2748             : 
    2749             :                  ! Calculate the new cloud water mixing ratio microphysics
    2750             :                  ! process tendency.  This should be equal to the maximum
    2751             :                  ! magnitude (negative) amount allowed, mc_tend_max_mag.
    2752             :                  rc_mc_tend(icol,k) &
    2753             :                  = rc_mc_tend(icol,k) &
    2754           0 :                    + mc_correction_ratio * total_mc_positive
    2755             : 
    2756             :               endif ! rc_curr < qmin(ixcldliq)
    2757             : 
    2758             :            endif ! .not. l_pos_rc_mc_tend
    2759             : 
    2760             :            !!! Check for holes in rain water mixing ratio
    2761           0 :            if ( ixrain > 0 .and. ( .not. l_pos_rr_mc_tend ) ) then
    2762             : 
    2763             :               ! Calculate the rain water mixing ratio as it would be with the
    2764             :               ! current microphysics process tendency.
    2765           0 :               rr_curr = rr_start(icol,k) + rr_mc_tend(icol,k) * dt
    2766             : 
    2767           0 :               if ( rr_curr < qmin(ixrain) ) then
    2768             : 
    2769             :                  ! Microphysics processes are causing a hole in rain water
    2770             :                  ! mixing ratio.
    2771             : 
    2772             :                  ! Calculate the maximum allowable magnitude of (negative) rain
    2773             :                  ! water microphysics process tendency.
    2774           0 :                  mc_tend_max_mag = ( qmin(ixrain) - rr_start(icol,k) ) / dt
    2775             : 
    2776             :                  ! Calculate the amount of the correction that needs to be made
    2777             :                  ! to the rain water mixing ratio microphysics process
    2778             :                  ! tendency.  This number is positive.
    2779           0 :                  mc_tend_correction = mc_tend_max_mag - rr_mc_tend(icol,k)
    2780             : 
    2781             :                  ! Calculate the total amount of positive microphysics process
    2782             :                  ! tendencies for all hydrometeor mixing ratios.
    2783           0 :                  total_mc_positive = 0.0_r8
    2784           0 :                  if ( l_pos_rv_mc_tend ) then
    2785           0 :                     total_mc_positive = total_mc_positive + rv_mc_tend(icol,k)
    2786             :                  endif
    2787           0 :                  if ( l_pos_rc_mc_tend ) then
    2788           0 :                     total_mc_positive = total_mc_positive + rc_mc_tend(icol,k)
    2789             :                  endif
    2790           0 :                  if ( l_pos_ri_mc_tend ) then
    2791           0 :                     total_mc_positive = total_mc_positive + ri_mc_tend(icol,k)
    2792             :                  endif
    2793           0 :                  if ( ixsnow > 0 .and. l_pos_rs_mc_tend ) then
    2794           0 :                     total_mc_positive = total_mc_positive + rs_mc_tend(icol,k)
    2795             :                  endif
    2796             : 
    2797             :                  ! Calculate the correction ratio.
    2798             :                  ! In principle, this should never be greater than 1 outside of
    2799             :                  ! numerical round-off errors.  This is limited at 1 to be safe.
    2800             :                  mc_correction_ratio &
    2801             :                  = min( mc_tend_correction &
    2802           0 :                         / max( total_mc_positive, 1.0e-30_r8 ), 1.0_r8 )
    2803             : 
    2804             :                  ! Adjust (decrease) the tendencies of all positive hydrometeor
    2805             :                  ! mixing ratio tendencies to balance the adjustment (increase)
    2806             :                  ! to the excessively negative rain water mixing ratio.
    2807             :                  ! Transfer dry static energy appropriately (in response to the
    2808             :                  ! excessive depletion of rain water).
    2809           0 :                  if ( l_pos_rv_mc_tend ) then
    2810             :                     ! Changing water vapor to rain water heats and increases
    2811             :                     ! dry static energy.
    2812             :                     stend(icol,k) &
    2813             :                     = stend(icol,k) &
    2814           0 :                       + latvap * mc_correction_ratio * rv_mc_tend(icol,k)
    2815             :                     ! Update water vapor mixing ratio microphysics tendency.
    2816             :                     rv_mc_tend(icol,k) &
    2817           0 :                     = rv_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2818             :                  endif
    2819           0 :                  if ( l_pos_rc_mc_tend ) then
    2820             :                     ! Changing cloud water to rain water does not change
    2821             :                     ! dry static energy.
    2822             :                     ! Update cloud water mixing ratio microphysics tendency.
    2823             :                     rc_mc_tend(icol,k) &
    2824           0 :                     = rc_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2825             :                  endif
    2826           0 :                  if ( l_pos_ri_mc_tend ) then
    2827             :                     ! Changing cloud ice to rain water cools and reduces
    2828             :                     ! dry static energy.
    2829             :                     stend(icol,k) &
    2830             :                     = stend(icol,k) &
    2831           0 :                       - latice * mc_correction_ratio * ri_mc_tend(icol,k)
    2832             :                     ! Update cloud ice mixing ratio microphysics tendency.
    2833             :                     ri_mc_tend(icol,k) &
    2834           0 :                     = ri_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2835             :                  endif
    2836           0 :                  if ( ixsnow > 0 .and. l_pos_rs_mc_tend ) then
    2837             :                     ! Changing snow to rain water cools and reduces dry
    2838             :                     ! static energy.
    2839             :                     stend(icol,k) &
    2840             :                     = stend(icol,k) &
    2841           0 :                       - latice * mc_correction_ratio * rs_mc_tend(icol,k)
    2842             :                     ! Update snow mixing ratio microphysics tendency.
    2843             :                     rs_mc_tend(icol,k) &
    2844           0 :                     = rs_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2845             :                  endif
    2846             : 
    2847             :                  ! Calculate the new rain water mixing ratio microphysics
    2848             :                  ! process tendency.  This should be equal to the maximum
    2849             :                  ! magnitude (negative) amount allowed, mc_tend_max_mag.
    2850             :                  rr_mc_tend(icol,k) &
    2851             :                  = rr_mc_tend(icol,k) &
    2852           0 :                    + mc_correction_ratio * total_mc_positive
    2853             : 
    2854             :               endif ! rr_curr < qmin(ixrain)
    2855             : 
    2856             :            endif ! ixrain > 0 .and. ( .not. l_pos_rr_mc_tend )
    2857             : 
    2858             :            !!! Check for holes in cloud ice mixing ratio
    2859           0 :            if ( .not. l_pos_ri_mc_tend ) then
    2860             : 
    2861             :               ! Calculate the cloud ice mixing ratio as it would be with the
    2862             :               ! current microphysics process tendency.
    2863           0 :               ri_curr = ri_start(icol,k) + ri_mc_tend(icol,k) * dt
    2864             : 
    2865           0 :               if ( ri_curr < qmin(ixcldice) ) then
    2866             : 
    2867             :                  ! Microphysics processes are causing a hole in cloud ice
    2868             :                  ! mixing ratio.
    2869             : 
    2870             :                  ! Calculate the maximum allowable magnitude of (negative) cloud
    2871             :                  ! ice microphysics process tendency.
    2872           0 :                  mc_tend_max_mag = ( qmin(ixcldice) - ri_start(icol,k) ) / dt
    2873             : 
    2874             :                  ! Calculate the amount of the correction that needs to be made
    2875             :                  ! to the cloud ice mixing ratio microphysics process
    2876             :                  ! tendency.  This number is positive.
    2877           0 :                  mc_tend_correction = mc_tend_max_mag - ri_mc_tend(icol,k)
    2878             : 
    2879             :                  ! Calculate the total amount of positive microphysics process
    2880             :                  ! tendencies for all hydrometeor mixing ratios.
    2881           0 :                  total_mc_positive = 0.0_r8
    2882           0 :                  if ( l_pos_rv_mc_tend ) then
    2883           0 :                     total_mc_positive = total_mc_positive + rv_mc_tend(icol,k)
    2884             :                  endif
    2885           0 :                  if ( l_pos_rc_mc_tend ) then
    2886           0 :                     total_mc_positive = total_mc_positive + rc_mc_tend(icol,k)
    2887             :                  endif
    2888           0 :                  if ( ixrain > 0 .and. l_pos_rr_mc_tend ) then
    2889           0 :                     total_mc_positive = total_mc_positive + rr_mc_tend(icol,k)
    2890             :                  endif
    2891           0 :                  if ( ixsnow > 0 .and. l_pos_rs_mc_tend ) then
    2892           0 :                     total_mc_positive = total_mc_positive + rs_mc_tend(icol,k)
    2893             :                  endif
    2894             : 
    2895             :                  ! Calculate the correction ratio.
    2896             :                  ! In principle, this should never be greater than 1 outside of
    2897             :                  ! numerical round-off errors.  This is limited at 1 to be safe.
    2898             :                  mc_correction_ratio &
    2899             :                  = min( mc_tend_correction &
    2900           0 :                         / max( total_mc_positive, 1.0e-30_r8 ), 1.0_r8 )
    2901             : 
    2902             :                  ! Adjust (decrease) the tendencies of all positive hydrometeor
    2903             :                  ! mixing ratio tendencies to balance the adjustment (increase)
    2904             :                  ! to the excessively negative cloud ice mixing ratio.
    2905             :                  ! Transfer dry static energy appropriately (in response to the
    2906             :                  ! excessive depletion of cloud ice).
    2907           0 :                  if ( l_pos_rv_mc_tend ) then
    2908             :                     ! Changing water vapor to cloud ice heats and increases
    2909             :                     ! dry static energy.
    2910             :                     stend(icol,k) &
    2911             :                     = stend(icol,k) &
    2912             :                       + ( latvap + latice ) &
    2913           0 :                         * mc_correction_ratio * rv_mc_tend(icol,k)
    2914             :                     ! Update water vapor mixing ratio microphysics tendency.
    2915             :                     rv_mc_tend(icol,k) &
    2916           0 :                     = rv_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2917             :                  endif
    2918           0 :                  if ( l_pos_rc_mc_tend ) then
    2919             :                     ! Changing cloud water to cloud ice heats and increases
    2920             :                     ! dry static energy.
    2921             :                     stend(icol,k) &
    2922             :                     = stend(icol,k) &
    2923           0 :                       + latice * mc_correction_ratio * rc_mc_tend(icol,k)
    2924             :                     ! Update cloud water mixing ratio microphysics tendency.
    2925             :                     rc_mc_tend(icol,k) &
    2926           0 :                     = rc_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2927             :                  endif
    2928           0 :                  if ( ixrain > 0 .and. l_pos_rr_mc_tend ) then
    2929             :                     ! Changing rain water to cloud ice heats and increases
    2930             :                     ! dry static energy.
    2931             :                     stend(icol,k) &
    2932             :                     = stend(icol,k) &
    2933           0 :                       + latice * mc_correction_ratio * rr_mc_tend(icol,k)
    2934             :                     ! Update rain water mixing ratio microphysics tendency.
    2935             :                     rr_mc_tend(icol,k) &
    2936           0 :                     = rr_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2937             :                  endif
    2938           0 :                  if ( ixsnow > 0 .and. l_pos_rs_mc_tend ) then
    2939             :                     ! Changing snow to cloud ice does not change dry static
    2940             :                     ! energy.
    2941             :                     ! Update snow mixing ratio microphysics tendency.
    2942             :                     rs_mc_tend(icol,k) &
    2943           0 :                     = rs_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    2944             :                  endif
    2945             : 
    2946             :                  ! Calculate the new cloud ice mixing ratio microphysics
    2947             :                  ! process tendency.  This should be equal to the maximum
    2948             :                  ! magnitude (negative) amount allowed, mc_tend_max_mag.
    2949             :                  ri_mc_tend(icol,k) &
    2950             :                  = ri_mc_tend(icol,k) &
    2951           0 :                    + mc_correction_ratio * total_mc_positive
    2952             : 
    2953             :               endif ! ri_curr < qmin(ixcldice)
    2954             : 
    2955             :            endif ! .not. l_pos_ri_mc_tend
    2956             : 
    2957             :            !!! Check for holes in snow mixing ratio
    2958           0 :            if ( ixsnow > 0 .and. ( .not. l_pos_rs_mc_tend ) ) then
    2959             : 
    2960             :               ! Calculate the snow mixing ratio as it would be with the
    2961             :               ! current microphysics process tendency.
    2962           0 :               rs_curr = rs_start(icol,k) + rs_mc_tend(icol,k) * dt
    2963             : 
    2964           0 :               if ( rs_curr < qmin(ixsnow) ) then
    2965             : 
    2966             :                  ! Microphysics processes are causing a hole in snow mixing
    2967             :                  ! ratio.
    2968             : 
    2969             :                  ! Calculate the maximum allowable magnitude of (negative) snow
    2970             :                  ! microphysics process tendency.
    2971           0 :                  mc_tend_max_mag = ( qmin(ixsnow) - rs_start(icol,k) ) / dt
    2972             : 
    2973             :                  ! Calculate the amount of the correction that needs to be made
    2974             :                  ! to the snow mixing ratio microphysics process tendency.
    2975             :                  ! This number is positive.
    2976           0 :                  mc_tend_correction = mc_tend_max_mag - rs_mc_tend(icol,k)
    2977             : 
    2978             :                  ! Calculate the total amount of positive microphysics process
    2979             :                  ! tendencies for all hydrometeor mixing ratios.
    2980           0 :                  total_mc_positive = 0.0_r8
    2981           0 :                  if ( l_pos_rv_mc_tend ) then
    2982           0 :                     total_mc_positive = total_mc_positive + rv_mc_tend(icol,k)
    2983             :                  endif
    2984           0 :                  if ( l_pos_rc_mc_tend ) then
    2985           0 :                     total_mc_positive = total_mc_positive + rc_mc_tend(icol,k)
    2986             :                  endif
    2987           0 :                  if ( ixrain > 0 .and. l_pos_rr_mc_tend ) then
    2988           0 :                     total_mc_positive = total_mc_positive + rr_mc_tend(icol,k)
    2989             :                  endif
    2990           0 :                  if ( l_pos_ri_mc_tend ) then
    2991           0 :                     total_mc_positive = total_mc_positive + ri_mc_tend(icol,k)
    2992             :                  endif
    2993             : 
    2994             :                  ! Calculate the correction ratio.
    2995             :                  ! In principle, this should never be greater than 1 outside of
    2996             :                  ! numerical round-off errors.  This is limited at 1 to be safe.
    2997             :                  mc_correction_ratio &
    2998             :                  = min( mc_tend_correction &
    2999           0 :                         / max( total_mc_positive, 1.0e-30_r8 ), 1.0_r8 )
    3000             : 
    3001             :                  ! Adjust (decrease) the tendencies of all positive hydrometeor
    3002             :                  ! mixing ratio tendencies to balance the adjustment (increase)
    3003             :                  ! to the excessively negative snow mixing ratio.
    3004             :                  ! Transfer dry static energy appropriately (in response to the
    3005             :                  ! excessive depletion of snow).
    3006           0 :                  if ( l_pos_rv_mc_tend ) then
    3007             :                     ! Changing water vapor to snow heats and increases dry
    3008             :                     ! static energy.
    3009             :                     stend(icol,k) &
    3010             :                     = stend(icol,k) &
    3011             :                       + ( latvap + latice ) &
    3012           0 :                         * mc_correction_ratio * rv_mc_tend(icol,k)
    3013             :                     ! Update water vapor mixing ratio microphysics tendency.
    3014             :                     rv_mc_tend(icol,k) &
    3015           0 :                     = rv_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    3016             :                  endif
    3017           0 :                  if ( l_pos_rc_mc_tend ) then
    3018             :                     ! Changing cloud water to snow heats and increases dry
    3019             :                     ! static energy.
    3020             :                     stend(icol,k) &
    3021             :                     = stend(icol,k) &
    3022           0 :                       + latice * mc_correction_ratio * rc_mc_tend(icol,k)
    3023             :                     ! Update cloud water mixing ratio microphysics tendency.
    3024             :                     rc_mc_tend(icol,k) &
    3025           0 :                     = rc_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    3026             :                  endif
    3027           0 :                  if ( ixrain > 0 .and. l_pos_rr_mc_tend ) then
    3028             :                     ! Changing rain water to snow heats and increases dry
    3029             :                     ! static energy.
    3030             :                     stend(icol,k) &
    3031             :                     = stend(icol,k) &
    3032           0 :                       + latice * mc_correction_ratio * rr_mc_tend(icol,k)
    3033             :                     ! Update rain water mixing ratio microphysics tendency.
    3034             :                     rr_mc_tend(icol,k) &
    3035           0 :                     = rr_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    3036             :                  endif
    3037           0 :                  if ( l_pos_ri_mc_tend ) then
    3038             :                     ! Changing cloud ice to snow does not change dry static
    3039             :                     ! energy.
    3040             :                     ! Update cloud ice mixing ratio microphysics tendency.
    3041             :                     ri_mc_tend(icol,k) &
    3042           0 :                     = ri_mc_tend(icol,k) * ( 1.0_r8 - mc_correction_ratio )
    3043             :                  endif
    3044             : 
    3045             :                  ! Calculate the new snow mixing ratio microphysics process
    3046             :                  ! tendency.  This should be equal to the maximum magnitude
    3047             :                  ! (negative) amount allowed, mc_tend_max_mag.
    3048             :                  rs_mc_tend(icol,k) &
    3049             :                  = rs_mc_tend(icol,k) &
    3050           0 :                    + mc_correction_ratio * total_mc_positive
    3051             : 
    3052             :               endif ! rs_curr < qmin(ixsnow)
    3053             : 
    3054             :            endif ! ixsnow > 0 .and. ( .not. l_pos_rs_mc_tend )
    3055             : 
    3056             :         end do ! k = top_lev, pver
    3057             : 
    3058             :      end do ! icol = 1, ncol
    3059             : 
    3060             :      ! Calculate the new overall tendencies by adding the sedimentation
    3061             :      ! tendencies back onto the new microphysics process tendencies.
    3062             :      ! For cloud water and cloud ice, the sedimentation tendencies that are
    3063             :      ! added back on are the true sedimentation tendencies.  For cloud water,
    3064             :      ! this is the sum of rc_sed_tend and rc_sed_evap, and for cloud ice, this
    3065             :      ! is the sum of ri_sed_tend and ri_sed_subl.
    3066           0 :      rv_tend(:ncol,:) = rv_mc_tend(:ncol,:)
    3067           0 :      rc_tend(:ncol,:) = rc_mc_tend(:ncol,:) + ( rc_sed_tend(:ncol,:) + rc_sed_evap(:ncol,:) )
    3068           0 :      if ( ixrain > 0 ) then
    3069           0 :         rr_tend(:ncol,:) = rr_mc_tend(:ncol,:) + rr_sed_tend(:ncol,:)
    3070             :      endif
    3071           0 :      ri_tend(:ncol,:) = ri_mc_tend(:ncol,:) + ( ri_sed_tend(:ncol,:) + ri_sed_subl(:ncol,:) )
    3072           0 :      if ( ixsnow > 0 ) then
    3073           0 :         rs_tend(:ncol,:) = rs_mc_tend(:ncol,:) + rs_sed_tend(:ncol,:)
    3074             :      endif
    3075             : 
    3076             :      ! Now that the original sedimentation tendency has been added to the
    3077             :      ! new microphysics process tendency, the new total microphysics tendency
    3078             :      ! can still cause holes to form.  After the microphysics process rates were
    3079             :      ! adjusted, the values of the hydrometeor fields were greater than or equal
    3080             :      ! to 0 at all grid levels, which means their vertical integrals were also
    3081             :      ! greater than or equal to 0.  Sedimentation by itself has a vertical
    3082             :      ! integral of 0 (including the amount that sedimented to the surface).
    3083             :      ! This means that after the microphysics process rates have been adjusted
    3084             :      ! and sedimentation has been added back on, the resulting hydrometeor
    3085             :      ! fields all still have vertical integrals that are greater than or equal
    3086             :      ! to 0.  Holes that develop at any particular grid level can be filled.
    3087             :      ! These holes can be filled conservatively using the sedimentation hole
    3088             :      ! filler.
    3089             :      if ( l_sed_hole_fill ) then
    3090             : 
    3091             :         ! This section makes use of the following principle:
    3092             :         !
    3093             :         ! 3) When adjusting the hydrometeor tendency from sedimentation of a
    3094             :         !    liquid hydrometeor (cloud water or rain water), conserve:
    3095             :         !
    3096             :         !    SUM(k=top_lev:pver) ( rc_sed_tend(k) + rr_sed_tend(k) )
    3097             :         !                        * dt * pdel(k) / g
    3098             :         !    + precl * dt * 1000 = 0.
    3099             : 
    3100             :         ! Call the sedimentation hole filler for rain water mixing ratio.
    3101             :         ! This can update rr_tend and precl.
    3102           0 :         if ( ixrain > 0 ) then
    3103             :            call fill_holes_sedimentation( dt, ncol, rr_start, state%pdel, &
    3104           0 :                                           umr, state%zi, qmin(ixrain), &
    3105           0 :                                           rr_tend, precl )
    3106             :         endif ! ixrain > 0
    3107             : 
    3108             :         ! Call the sedimentation hole filler for cloud water mixing ratio.
    3109             :         ! This can update rc_tend and precl.
    3110             :         call fill_holes_sedimentation( dt, ncol, rc_start, state%pdel, &
    3111           0 :                                        vtrmc, state%zi, qmin(ixcldliq), &
    3112           0 :                                        rc_tend, precl )
    3113             : 
    3114             :         ! Occasionally, a situation can occur where filling a hole in rain can
    3115             :         ! deplete all the surface liquid-phase precipitation (precl), resulting
    3116             :         ! in not enough water mass in the vertical profile of cloud water to
    3117             :         ! fill a hole in cloud water.  When this happens, there must be liquid
    3118             :         ! water found in the vertical profile of rain, so pull the water from
    3119             :         ! rain to fill any remaining holes in cloud water.
    3120           0 :         if ( ixrain > 0 ) then
    3121             :            call fill_holes_same_phase_vert( dt, ncol, rc_start, rr_start, &
    3122           0 :                                             state%pdel, qmin(ixcldliq), &
    3123           0 :                                             qmin(ixrain), &
    3124           0 :                                             rc_tend, rr_tend )
    3125             :         endif ! ixrain > 0
    3126             : 
    3127             :         ! This section makes use of the following principle:
    3128             :         !
    3129             :         ! 4) When adjusting the hydrometeor tendency from sedimentation of a
    3130             :         !    frozen hydrometeor (cloud ice or snow), conserve:
    3131             :         !
    3132             :         !    SUM(k=top_lev:pver) ( ri_sed_tend(k) + rs_sed_tend(k) )
    3133             :         !                        * dt * pdel(k) / g
    3134             :         !    + preci * dt * 1000 = 0.
    3135             : 
    3136             :         ! Call the sedimentation hole filler for snow mixing ratio.
    3137             :         ! This can update rs_tend and preci.
    3138           0 :         if ( ixsnow > 0 ) then
    3139             :            call fill_holes_sedimentation( dt, ncol, rs_start, state%pdel, &
    3140           0 :                                           ums, state%zi, qmin(ixsnow), &
    3141           0 :                                           rs_tend, preci )
    3142             :         endif ! ixsnow > 0
    3143             : 
    3144             :         ! Call the sedimentation hole filler for cloud ice mixing ratio.
    3145             :         ! This can update ri_tend and preci.
    3146             :         call fill_holes_sedimentation( dt, ncol, ri_start, state%pdel, &
    3147           0 :                                        vtrmi, state%zi, qmin(ixcldice), &
    3148           0 :                                        ri_tend, preci )
    3149             : 
    3150             :         ! Occasionally, a situation can occur where filling a hole in snow can
    3151             :         ! deplete all the surface ice-phase precipitation (preci), resulting
    3152             :         ! in not enough water mass in the vertical profile of cloud ice to
    3153             :         ! fill a hole in cloud ice.  When this happens, there must be ice-phase
    3154             :         ! water found in the vertical profile of snow, so pull the water from
    3155             :         ! snow to fill any remaining holes in cloud ice.
    3156           0 :         if ( ixsnow > 0 ) then
    3157             :            call fill_holes_same_phase_vert( dt, ncol, ri_start, rs_start, &
    3158           0 :                                             state%pdel, qmin(ixcldice), &
    3159           0 :                                             qmin(ixsnow), &
    3160           0 :                                             ri_tend, rs_tend )
    3161             :         endif  ! ixsnow > 0
    3162             : 
    3163             :         ! Update the total precipitation rate (prect) from the updated liquid
    3164             :         ! precipitation rate (precl) and the updated frozen preciptation rate
    3165             :         ! (preci).
    3166           0 :         prect(:ncol) = precl(:ncol) + preci(:ncol)
    3167             : 
    3168             :         ! The MG code sets prec_str equal to prect (prec_pcw) and snow_str equal
    3169             :         ! to preci (snow_pcw).  The prec_str and snow_str variables are used
    3170             :         ! in the calculations for energy and water conservation.  Since prect
    3171             :         ! and preci are adjusted here, when necessary, prec_str and snow_str
    3172             :         ! also need to be adjusted.
    3173           0 :         prec_str(:ncol) = prect(:ncol)
    3174           0 :         snow_str(:ncol) = preci(:ncol)
    3175             : 
    3176             :      endif ! l_sed_hole_fill
    3177             : 
    3178             :      ! The updated total microphysics tendencies after hole filling have not
    3179             :      ! been used to update ptend yet, so record the budget terms for hole
    3180             :      ! filling first.
    3181           0 :      rv_hf_tend = rv_tend - ptend%q(:,:,1)
    3182           0 :      rc_hf_tend = rc_tend - ptend%q(:,:,ixcldliq)
    3183           0 :      if ( ixrain > 0 ) then
    3184           0 :         rr_hf_tend = rr_tend - ptend%q(:,:,ixrain)
    3185             :      endif ! ixrain > 0
    3186           0 :      ri_hf_tend = ri_tend - ptend%q(:,:,ixcldice)
    3187           0 :      if ( ixsnow > 0 ) then
    3188           0 :         rs_hf_tend = rs_tend - ptend%q(:,:,ixsnow)
    3189             :      endif ! ixsnow > 0
    3190             : 
    3191             :      ! The updated dry static energy tendency after hole filling has not been
    3192             :      ! used to update ptend yet, so record the budget term for hole filling
    3193             :      ! first.
    3194           0 :      s_hf_tend = stend - ptend%s
    3195             : 
    3196             :      ! Pack the current total tendencies for hydrometeor mixing ratio fields.
    3197           0 :      ptend%q(:,:,1) = rv_tend
    3198           0 :      ptend%q(:,:,ixcldliq) = rc_tend
    3199           0 :      if ( ixrain > 0 ) then
    3200           0 :         ptend%q(:,:,ixrain) = rr_tend
    3201             :      endif
    3202           0 :      ptend%q(:,:,ixcldice) = ri_tend
    3203           0 :      if ( ixsnow > 0 ) then
    3204           0 :         ptend%q(:,:,ixsnow) = rs_tend
    3205             :      endif
    3206             : 
    3207             :      ! Pack the current tendency for dry static energy.
    3208           0 :      ptend%s = stend
    3209             : 
    3210             :      ! Output stats for hole filling tendencies.
    3211           0 :      call outfld( 'QVHFTEN', rv_hf_tend, pcols, state%lchnk )
    3212           0 :      call outfld( 'QCHFTEN', rc_hf_tend, pcols, state%lchnk )
    3213           0 :      call outfld( 'QRHFTEN', rr_hf_tend, pcols, state%lchnk )
    3214           0 :      call outfld( 'QIHFTEN', ri_hf_tend, pcols, state%lchnk )
    3215           0 :      call outfld( 'QSHFTEN', rs_hf_tend, pcols, state%lchnk )
    3216           0 :      call outfld( 'THFTEN', s_hf_tend / cpair, pcols, state%lchnk )
    3217             : 
    3218             :      ! Perform total water and total energy conservation checks.
    3219             :      if ( l_check_conservation ) then
    3220             : 
    3221             :         ! Calculate total water in each grid column.
    3222             :         ! This calculation is the vertically-integrated grand total water
    3223             :         ! in each grid column updated for all microphysics and hole filling.
    3224             :         ! This includes the amount that precipitated to the surface.
    3225           0 :         do icol = 1, ncol
    3226           0 :            grand_total_water_column_finish(icol) = 0.0_r8
    3227           0 :            do k = top_lev, pver
    3228             :               grand_total_water_column_finish(icol) &
    3229             :               = grand_total_water_column_finish(icol) &
    3230           0 :                 + ( state%q(icol,k,1) &
    3231           0 :                     + ptend%q(icol,k,1) * dt &
    3232           0 :                     + state%q(icol,k,ixcldliq) &
    3233           0 :                     + ptend%q(icol,k,ixcldliq) * dt &
    3234           0 :                     + state%q(icol,k,ixcldice) &
    3235           0 :                     + ptend%q(icol,k,ixcldice) * dt ) &
    3236           0 :                   * state%pdel(icol,k) * rga
    3237           0 :               if ( ixrain > 0 ) then
    3238             :                  grand_total_water_column_finish(icol) &
    3239             :                  = grand_total_water_column_finish(icol) &
    3240           0 :                    + ( state%q(icol,k,ixrain) + ptend%q(icol,k,ixrain) * dt ) &
    3241           0 :                      * state%pdel(icol,k) * rga
    3242             :               endif
    3243           0 :               if ( ixsnow > 0 ) then
    3244             :                  grand_total_water_column_finish(icol) &
    3245             :                  = grand_total_water_column_finish(icol) &
    3246           0 :                    + ( state%q(icol,k,ixsnow) + ptend%q(icol,k,ixsnow) * dt ) &
    3247           0 :                      * state%pdel(icol,k) * rga
    3248             :               endif
    3249             :            end do ! k = top_lev, pver
    3250             :            grand_total_water_column_finish(icol) &
    3251             :            = grand_total_water_column_finish(icol) &
    3252           0 :              + prect(icol) * dt * 1000.0_r8
    3253             :         end do ! icol = 1, ncol
    3254             : 
    3255             :         ! Calculate total energy in each column.
    3256             :         ! This calculation is the vertically-integrated total energy in each
    3257             :         ! grid column updated for all microphysics and hole filling.  This
    3258             :         ! includes the amount that precipitated to the surface.  Since, the
    3259             :         ! microphysics code does not directly change kinetic energy,
    3260             :         ! 0.5 * ( u^2 + v^2 ), it can be skipped as part of the energy
    3261             :         ! conservation check.
    3262           0 :         do icol = 1, ncol
    3263           0 :            total_energy_column_finish(icol) = 0.0_r8
    3264           0 :            do k = top_lev, pver
    3265             :               total_energy_column_finish(icol) &
    3266             :               = total_energy_column_finish(icol) &
    3267           0 :                 + ( state%s(icol,k) + ptend%s(icol,k) * dt &
    3268             :                     + ( latvap + latice ) &
    3269           0 :                       * ( state%q(icol,k,1) + ptend%q(icol,k,1) * dt ) &
    3270           0 :                     + latice * ( state%q(icol,k,ixcldliq) &
    3271           0 :                                  + ptend%q(icol,k,ixcldliq) * dt ) ) &
    3272           0 :                   * state%pdel(icol,k) * rga
    3273           0 :               if ( ixrain > 0 ) then
    3274             :                  total_energy_column_finish(icol) &
    3275             :                  = total_energy_column_finish(icol) &
    3276           0 :                    + latice * ( state%q(icol,k,ixrain) &
    3277           0 :                                 + ptend%q(icol,k,ixrain) * dt ) &
    3278           0 :                      * state%pdel(icol,k) * rga
    3279             :               endif
    3280             :            end do ! k = top_lev, pver
    3281             :            total_energy_column_finish(icol) &
    3282             :            = total_energy_column_finish(icol) &
    3283           0 :              + latice * precl(icol) * dt * 1000.0_r8
    3284             :         end do ! icol = 1, ncol
    3285             : 
    3286             :         ! Calculate the total relative error in each grid column.
    3287           0 :         do icol = 1, ncol
    3288             : 
    3289           0 :            tot_water_rel_err(icol) &
    3290             :            = abs( ( grand_total_water_column_finish(icol) &
    3291             :                     - grand_total_water_column_start(icol) ) ) &
    3292             :              / min( grand_total_water_column_finish(icol), &
    3293           0 :                     grand_total_water_column_start(icol) )
    3294             : 
    3295             :            tot_energy_rel_err(icol) &
    3296             :            = abs( ( total_energy_column_finish(icol) &
    3297             :                     - total_energy_column_start(icol) ) ) &
    3298             :              / min( total_energy_column_finish(icol), &
    3299           0 :                     total_energy_column_start(icol) )
    3300             : 
    3301             :         end do ! icol = 1, ncol
    3302             : 
    3303             :         ! Print an error message if any total water relative error is found to
    3304             :         ! be greater than the threshold.
    3305           0 :         if ( any( tot_water_rel_err(:ncol) >= err_thresh ) ) then
    3306           0 :            write(iulog,*) "Water conservation error reported in hole filling"
    3307           0 :            do icol = 1, ncol
    3308           0 :               if ( tot_water_rel_err(icol) >= err_thresh ) then
    3309           0 :                  write(iulog,*) "Column = ", icol, &
    3310           0 :                           "Relative error = ", tot_water_rel_err(icol), &
    3311           0 :                           "Column-integrated grand total water at start = ", &
    3312           0 :                           grand_total_water_column_start(icol), &
    3313           0 :                           "Column-integrated grand total water at finish = ", &
    3314           0 :                           grand_total_water_column_finish(icol)
    3315             :               endif ! tot_water_rel_err(icol) >= err_thresh
    3316             :            end do ! icol = 1, ncol
    3317             :         endif ! any( tot_water_rel_err >= err_thresh )
    3318             : 
    3319             :         ! Print an error message if any total energy relative error is found to
    3320             :         ! be greater than the threshold.
    3321           0 :         if ( any( tot_energy_rel_err(:ncol) >= err_thresh ) ) then
    3322           0 :            write(iulog,*) "Energy conservation error reported in hole filling"
    3323           0 :            do icol = 1, ncol
    3324           0 :               if ( tot_energy_rel_err(icol) >= err_thresh ) then
    3325           0 :                  write(iulog,*) "Column = ", icol, &
    3326           0 :                           "Relative error = ", tot_energy_rel_err(icol), &
    3327           0 :                           "Column-integrated total energy at start = ", &
    3328           0 :                           total_energy_column_start(icol), &
    3329           0 :                           "Column-integrated total energy at finish = ", &
    3330           0 :                           total_energy_column_finish(icol)
    3331             :               endif ! tot_energy_rel_err(icol) >= err_thresh
    3332             :            end do ! icol = 1, ncol
    3333             :         endif ! any( tot_energy_rel_err >= err_thresh )
    3334             : 
    3335             :      endif ! l_check_conservation
    3336             : 
    3337             : 
    3338           0 :      return
    3339             : 
    3340           0 :    end subroutine subcol_SILHS_fill_holes_conserv
    3341             : 
    3342             :    !============================================================================
    3343           0 :    subroutine fill_holes_sedimentation( dt, ncol, hm_start, pdel, &
    3344             :                                         fallspeed_m_per_s, zi, qmin_hm, &
    3345             :                                         hm_tend, prec )
    3346             : 
    3347             :      ! Description:
    3348             :      ! After hydrometeor tendencies from microphysics processes were adjusted
    3349             :      ! so that holes don't form in a hydrometeor field from microphysics
    3350             :      ! processes, the sedimentation tendency was added back on to produce an
    3351             :      ! updated total microphysics tendency.  The first-order "up-gravity"
    3352             :      ! sedimentation method that was originally used is positive definite.
    3353             :      ! However, since the microphysics process tendencies were altered so that
    3354             :      ! holes don't form, it is possible that adding the old sedimentation
    3355             :      ! tendencies back onto the new microphysics process tendencies could
    3356             :      ! produce new total microphysics tendencies that cause holes to form.
    3357             :      !
    3358             :      ! In this subroutine, holes in a hydrometeor field are checked for after
    3359             :      ! the updated microphysics tendency is applied.  If any are found, they are
    3360             :      ! filled from positive hydrometeor mass found at grid levels below where
    3361             :      ! the hole is found.  The levels that are used to fill are within range
    3362             :      ! based on fallspeed of the hydrometeor.  If the level that contains the
    3363             :      ! hole is within proximity to the surface, then the water that sedimented
    3364             :      ! to the surface can be used to fill the hole, as well.
    3365             :      !
    3366             :      ! If there isn't enough total hydrometeor mass within the fall range to
    3367             :      ! fill the hole, then positive hydrometeor mass from levels below the fall
    3368             :      ! range is to be added to the total available mass to fill the hole.  Mass
    3369             :      ! is added one level at a time until enough mass is found to fill the hole
    3370             :      ! or until the surface is reached and the surface precipitation is added to
    3371             :      ! the total available fill mass.
    3372             :      !
    3373             :      ! After this, if there still isn't enough available mass to fill the hole,
    3374             :      ! then positive hydrometeor mass is added from all levels above the hole to
    3375             :      ! the total mass that is available to fill the hole.
    3376             : 
    3377             :      !----------------------------------------------------------------------
    3378             : 
    3379           0 :      use ppgrid, only: &
    3380             :          pcols
    3381             : 
    3382             :      use ref_pres, only: &
    3383             :          top_lev => trop_cloud_top_lev
    3384             : 
    3385             :      implicit none
    3386             : 
    3387             :      ! Input Variables
    3388             :      real(r8), intent(in) :: dt                   ! Time step duration
    3389             : 
    3390             :      integer, intent(in) :: ncol                  ! Number of grid columns
    3391             : 
    3392             :      real(r8), dimension(pcols,pver), intent(in) :: &
    3393             :        hm_start, & ! Hydrometeor mixing ratio at start of microphysics  [kg/kg]
    3394             :        pdel        ! Pressure difference between grid levels            [Pa]
    3395             : 
    3396             :      real(r8), dimension(pcols,pver), intent(in) :: &
    3397             :        fallspeed_m_per_s    ! Hydrometeor mixing ratio fall speed     [m/s]
    3398             : 
    3399             :      real(r8), dimension(pcols,pverp), intent(in) :: &
    3400             :        zi    ! Height of momentum (interface) grid levels    [m]
    3401             : 
    3402             :      real(r8), intent(in) :: &
    3403             :        qmin_hm    ! Minimum threshold value of hydrometeor mixing ratio  [kg/kg]
    3404             : 
    3405             :      ! Input/Output Variables
    3406             :      real(r8), dimension(pcols,pver), intent(inout) :: &
    3407             :        hm_tend    ! Hydrometeor mixing ratio tendency  [kg/kg/s]
    3408             : 
    3409             :      real(r8), dimension(pcols), intent(inout) :: &
    3410             :        prec    ! Precipitation rate (surface)        [m/s]
    3411             : 
    3412             :      ! Local Variables
    3413             :      real(r8), dimension(pver) :: &
    3414             :        hm_update, & ! Hydrometeor mixing ratio; start of sed. hole fill  [kg/kg]
    3415             :        hm_curr      ! Current value of hydrometeor mixing ratio          [kg/kg]
    3416             : 
    3417             :      real(r8) :: &
    3418             :        total_hole,          & ! Total mass of hole in hydrometeor       [kg/m^2]
    3419             :        total_fill_mass,     & ! Total mass available to fill hole       [kg/m^2]
    3420             :        hole_fillmass_ratio, & ! Ratio: total_hole / total_fill_mass     [-]
    3421             :        fallspeed_Pa_per_s,  & ! Hydrometeor mixing ratio fall speed     [Pa/s]
    3422             :        total_fall_Pa,       & ! Pressure "distance" hydrometeor fell    [Pa]
    3423             :        sum_pdel               ! Sum of pdel over levels                 [Pa]
    3424             : 
    3425             :      logical, dimension(pver) :: &
    3426             :        l_pos_hm  ! Flag for a hydrometeor having a positive (>= qmin_hm) value
    3427             : 
    3428             :      ! Flag for whether surface precipitation mass needs to be included in
    3429             :      ! the total_fill_mass for hole filling.
    3430             :      logical :: l_reached_surface
    3431             : 
    3432             :      ! Flag for whether hydrometeor mass from levels above the hole needs to be
    3433             :      ! included in the total_fill_mass for hole filling.
    3434             :      logical :: l_fill_from_above
    3435             : 
    3436             :      integer :: icol  ! Grid column index
    3437             : 
    3438             :      integer :: k, idx  ! Vertical grid level indices
    3439             : 
    3440             :      ! Index of the lowest vertical grid level that needs to be included in the
    3441             :      ! total_fill_mass for hole filling.
    3442             :      integer :: lowest_level_idx
    3443             : 
    3444             : 
    3445             :      ! Loop over all columns, performing any adjustments one column at a time.
    3446           0 :      do icol = 1, ncol
    3447             : 
    3448             :         ! Calculate the updated value of the hydrometeor field based on the
    3449             :         ! updated microphysics tendency.  Since the original sedimentation
    3450             :         ! tendency has been added to the updated microphysics process tendency
    3451             :         ! to produce the updated total microphysics tendency (hm_tend), the
    3452             :         ! updated value of the hydrometeor field (hm_update) could be negative.
    3453           0 :         hm_update = hm_start(icol,:) + hm_tend(icol,:) * dt
    3454           0 :         hm_curr = hm_update
    3455             : 
    3456             :         ! Check for any holes in the vertical profile
    3457           0 :         if ( any( hm_curr(top_lev:pver) < qmin_hm ) ) then
    3458             : 
    3459             :            ! At least one hole is found in this hydrometeor species in this
    3460             :            ! grid column.  The holes must be filled conservatively.
    3461             : 
    3462             :            ! Check which levels have values of the hydrometeor that are at or
    3463             :            ! above the minimum threshold value.
    3464           0 :            do k = top_lev, pver
    3465           0 :               if ( hm_curr(k) >= qmin_hm ) then
    3466           0 :                 l_pos_hm(k) = .true.
    3467             :               else ! hm_curr < qmin_hm
    3468           0 :                 l_pos_hm(k) = .false.
    3469             :               endif ! hm_curr >= qmin_hm
    3470             :            end do ! k = top_lev, pver
    3471             : 
    3472           0 :            do k = pver, top_lev, -1
    3473             : 
    3474           0 :               if ( .not. l_pos_hm(k) ) then
    3475             : 
    3476             :                  ! A hole is found in the hydrometeor at this grid level.
    3477             : 
    3478             :                  ! Calculate the total hydrometeor mass of the hole that needs
    3479             :                  ! to be filled.
    3480             :                  ! The value of the hydrometeor mixing ratio is negative, but
    3481             :                  ! the value of total_hole is positive.
    3482           0 :                  total_hole = ( qmin_hm - hm_curr(k) ) * pdel(icol,k) * rga
    3483             : 
    3484             :                  ! Calculate the total hydrometeor mass available from below
    3485             :                  ! to fill the hole.
    3486           0 :                  if ( k == pver ) then
    3487             : 
    3488             :                     ! A hole is found at the lowermost level.
    3489             :                     ! The only place the hydrometeor could have sedimented
    3490             :                     ! to is the surface, so fill from only the surface.
    3491           0 :                     l_reached_surface = .true.
    3492             : 
    3493             :                     ! Calculate the available amount of hydrometeor mass to
    3494             :                     ! fill the hole.
    3495           0 :                     total_fill_mass = prec(icol) * dt * 1000.0_r8
    3496             : 
    3497             :                  else ! top_lev <= k < pver
    3498             : 
    3499             :                     ! Calculate the hydrometeor fallspeed in Pa/s.
    3500             :                     ! In MG2, the equation for this is given by:
    3501             :                     !
    3502             :                     ! fallspeed([Pa/s]) = g * rho * fallspeed([m/s]).
    3503             :                     !
    3504             :                     ! The value of rho is typically calculated from the
    3505             :                     ! hydrostatic approximation:
    3506             :                     !
    3507             :                     ! rho = - ( 1 / g ) * dp/dz.
    3508             :                     !
    3509             :                     ! The equation for fallspeed in Pa/s becomes:
    3510             :                     !
    3511             :                     ! fallspeed([Pa/s]) = - dp/dz * fallspeed([m/s]).
    3512             :                     fallspeed_Pa_per_s &
    3513             :                     = fallspeed_m_per_s(icol,k) &
    3514           0 :                       * pdel(icol,k) / ( zi(icol,k) - zi(icol,k+1) )
    3515             : 
    3516             :                     ! Calculate the fall "distance" in Pa.
    3517           0 :                     total_fall_Pa = fallspeed_Pa_per_s * dt
    3518             : 
    3519             :                     ! Find the index of the vertical level that the hydrometeor
    3520             :                     ! sedimented to in one timestep.  It must sediment at least
    3521             :                     ! one level.
    3522           0 :                     sum_pdel = 0.0_r8
    3523           0 :                     idx = k + 1
    3524           0 :                     do
    3525             :                        ! Update the total pressure difference between the
    3526             :                        ! level of origin and the current level.
    3527           0 :                        sum_pdel = sum_pdel + pdel(icol,idx)
    3528           0 :                        if ( sum_pdel >= total_fall_Pa ) then
    3529             :                           ! The total pressure difference between the level of
    3530             :                           ! origin and the current level exceeds the total
    3531             :                           ! hydrometeor fall "distance" (in Pa).
    3532             :                           lowest_level_idx = idx
    3533             :                           l_reached_surface = .false.
    3534             :                           exit
    3535             :                        else ! sum_pdel < total_fall_Pa
    3536             :                           ! The total hydrometeor fall "distance" (in Pa)
    3537             :                           ! exceeds the total pressure difference between the
    3538             :                           ! level of origin and the current level.
    3539           0 :                           if ( idx == pver ) then
    3540             :                              ! The lowest level of the model has been reached.
    3541             :                              ! The hydrometeor sedimented to the surface.
    3542             :                              lowest_level_idx = pver
    3543             :                              l_reached_surface = .true.
    3544             :                              exit
    3545             :                           else ! idx < pver
    3546             :                              ! Increment idx and keep going.
    3547           0 :                              idx = idx + 1
    3548             :                           endif ! idx == pver
    3549             :                        endif ! sum_pdel >= total_fall_Pa
    3550             :                     end do
    3551             : 
    3552             :                     ! Calculate the available amount of hydrometeor mass to
    3553             :                     ! fill the hole.
    3554             :                     total_fill_mass = 0.0_r8
    3555             :                     if ( l_reached_surface ) then
    3556             :                        ! The hydrometeor sedimented to the surface, so
    3557             :                        ! automatically loop down to pver and include the
    3558             :                        ! surface mass.
    3559           0 :                        do idx = k+1, pver, 1
    3560           0 :                           if ( l_pos_hm(idx) ) then
    3561             :                              total_fill_mass &
    3562             :                              = total_fill_mass &
    3563             :                                + ( hm_curr(idx) - qmin_hm ) &
    3564           0 :                                  * pdel(icol,idx) * rga
    3565             :                           endif ! l_pos_hm(idx)
    3566             :                        end do ! idx = k+1, pver, 1
    3567             :                        ! Contribution to total fill mass from the surface.
    3568             :                        total_fill_mass &
    3569           0 :                        = total_fill_mass + prec(icol) * dt * 1000.0_r8
    3570             :                     else ! .not. l_reached_surface
    3571             :                        ! The hydrometeor sedimented to lowest_level_idx.
    3572             :                        idx = k + 1
    3573             :                        do
    3574           0 :                           if ( l_pos_hm(idx) ) then
    3575             :                              total_fill_mass &
    3576             :                              = total_fill_mass &
    3577             :                                + ( hm_curr(idx) - qmin_hm ) &
    3578           0 :                                  * pdel(icol,idx) * rga
    3579             :                           endif ! l_pos_hm(idx)
    3580           0 :                           if ( idx >= lowest_level_idx ) then
    3581             :                              ! Check if enough mass has been gathered in
    3582             :                              ! total_fill_mass to fill the hole.
    3583           0 :                              if ( total_fill_mass >= total_hole ) then
    3584             :                                 ! There has been enough total_fill_mass
    3585             :                                 ! gathered to completely fill the hole.
    3586             :                                 lowest_level_idx = idx
    3587             :                                 exit
    3588             :                              else ! total_fill_mass < total_hole
    3589             :                                 ! Even though lowest_level_idx has been reached,
    3590             :                                 ! more total_fill_mass needs to be added in
    3591             :                                 ! order to completely fill the hole, so keep
    3592             :                                 ! going.
    3593           0 :                                 if ( idx == pver ) then
    3594             :                                    ! The lowest vertical level has already been
    3595             :                                    ! reached, so go to the surface.
    3596           0 :                                    lowest_level_idx = pver
    3597           0 :                                    l_reached_surface = .true.
    3598             :                                    ! Contribution to total fill mass from the
    3599             :                                    ! surface.
    3600             :                                    total_fill_mass &
    3601             :                                    = total_fill_mass &
    3602           0 :                                      + prec(icol) * dt * 1000.0_r8
    3603           0 :                                    exit
    3604             :                                 else ! idx < pver
    3605             :                                    ! Haven't reached pver yet, so increment
    3606             :                                    ! and keep going.
    3607           0 :                                    idx = idx + 1
    3608             :                                 endif ! idx == pver
    3609             :                              endif ! total_fill_mass >= total_hole
    3610             :                           else ! idx < lowest_level_idx
    3611             :                              ! Haven't reached lowest_level_idx yet, so
    3612             :                              ! increment and keep going.
    3613           0 :                              idx = idx + 1
    3614             :                           endif ! idx >= lowest_level_idx
    3615             :                        end do
    3616             :                     endif ! l_reached_surface
    3617             : 
    3618             :                  endif ! k == pver
    3619             : 
    3620             :                  ! If mass has been added all the way down to the surface and
    3621             :                  ! there's still not enough mass to fill the hole, then fill the
    3622             :                  ! hole pulling mass from above.
    3623           0 :                  if ( total_fill_mass >= total_hole ) then
    3624             :                     l_fill_from_above = .false.
    3625             :                  else ! total_fill_mass < total_hole
    3626           0 :                     l_fill_from_above = .true.
    3627           0 :                     do idx = top_lev, k-1, 1
    3628           0 :                        if ( l_pos_hm(idx) ) then
    3629             :                           total_fill_mass &
    3630             :                           = total_fill_mass &
    3631             :                             + ( hm_curr(idx) - qmin_hm ) &
    3632           0 :                               * pdel(icol,idx) * rga
    3633             :                        endif ! l_pos_hm(idx)
    3634             :                     end do ! idx = top_lev, k-1, 1
    3635             :                  endif ! total_fill_mass >= total_hole
    3636             : 
    3637             :                  ! Calculate the ratio of total hole to total fill mass.  This
    3638             :                  ! should not exceed 1 except as a result of numerical round-off
    3639             :                  ! errors.  Use thresholding to be safe.
    3640             :                  hole_fillmass_ratio &
    3641             :                  = min( total_hole / max( total_fill_mass, 1.0e-30_r8 ), &
    3642           0 :                         1.0_r8 )
    3643             : 
    3644           0 :                  if ( k < pver ) then
    3645             :                     ! Modify (reduce) the amount of the hydrometeor at levels
    3646             :                     ! that were used to fill the hole.
    3647           0 :                     do idx = k+1, lowest_level_idx
    3648           0 :                        if ( l_pos_hm(idx) ) then
    3649             :                           ! Since pdel at a grid level does not change and
    3650             :                           ! gravit is constant, the only variable that needs to
    3651             :                           ! be modified proportionately is hm_curr.
    3652             :                           hm_curr(idx) &
    3653             :                           = qmin_hm &
    3654             :                             + ( hm_curr(idx) - qmin_hm ) &
    3655           0 :                               * ( 1.0_r8 - hole_fillmass_ratio )
    3656             :                        endif ! l_pos_hm(idx)
    3657             :                     end do ! idx = k+1, lowest_level_idx
    3658             :                  endif ! k < pver
    3659             : 
    3660           0 :                  if ( l_reached_surface ) then
    3661             :                     ! Modify (reduce) the amount of surface precipitation in
    3662             :                     ! order to fill the hole.  Since dt and 1000 are constants,
    3663             :                     ! the only variable that needs to be modified
    3664             :                     ! proportionately is prec.
    3665           0 :                     prec(icol) = prec(icol) * ( 1.0_r8 - hole_fillmass_ratio )
    3666             :                  endif ! l_reached_surface
    3667             : 
    3668           0 :                  if ( l_fill_from_above ) then
    3669             :                     ! Modify (reduce) the amount of the hydrometeor at levels
    3670             :                     ! that were used to fill the hole.
    3671           0 :                     do idx = top_lev, k-1
    3672           0 :                        if ( l_pos_hm(idx) ) then
    3673             :                           ! Since pdel at a grid level does not change and
    3674             :                           ! gravit is constant, the only variable that needs to
    3675             :                           ! be modified proportionately is hm_curr.
    3676             :                           hm_curr(idx) &
    3677             :                           = qmin_hm &
    3678             :                             + ( hm_curr(idx) - qmin_hm ) &
    3679           0 :                               * ( 1.0_r8 - hole_fillmass_ratio )
    3680             :                        endif ! l_pos_hm(idx)
    3681             :                     end do ! idx = top_lev, k-1
    3682             :                  endif ! l_fill_from_above
    3683             : 
    3684             :                  ! Update the value of the hydrometeor at the level where the
    3685             :                  ! hole was found.  Mathematically, as long as the available
    3686             :                  ! mass was able to fill the entire hole, the new value of the
    3687             :                  ! hydrometeor mixing ratio (hm_curr) should be qmin_hm.
    3688             :                  hm_curr(k) &
    3689             :                  = hm_curr(k) &
    3690             :                    + hole_fillmass_ratio * total_fill_mass &
    3691           0 :                      * gravit / pdel(icol,k)
    3692             : 
    3693             :               endif ! .not. l_pos_hm(k)
    3694             : 
    3695             :            end do ! k = pver, top_lev, -1
    3696             : 
    3697             :         endif ! any( hm_curr(top_lev:pver) < qmin_hm )
    3698             : 
    3699             :         ! Update the value of total microphysics tendency after hole filling.
    3700           0 :         hm_tend(icol,:) = hm_tend(icol,:) + ( hm_curr - hm_update ) / dt
    3701             : 
    3702             :      end do ! icol = 1, ncol
    3703             : 
    3704             : 
    3705           0 :      return
    3706             : 
    3707             :    end subroutine fill_holes_sedimentation
    3708             : 
    3709             :    !============================================================================
    3710           0 :    subroutine fill_holes_same_phase_vert( dt, ncol, hm_start, hm_start_filler, &
    3711             :                                           pdel, qmin_hm, qmin_hm_filler, &
    3712             :                                           hm_tend, hm_tend_filler )
    3713             : 
    3714             :      ! Description:
    3715             :      ! Fills remaining holes in a hydrometeor with mass from the the vertical
    3716             :      ! profile of another hydrometeor of the same phase.  Remaining holes in
    3717             :      ! cloud water are filled with rain water and remaining holes in snow are
    3718             :      ! filled with cloud ice.
    3719             :      !
    3720             :      ! This subroutine, combined with subroutine fill_holes_sedimentation, fill
    3721             :      ! holes making use of the following principles:
    3722             :      !
    3723             :      ! 3) When adjusting the hydrometeor tendency from sedimentation of a
    3724             :      !    liquid hydrometeor (cloud water or rain water), conserve:
    3725             :      !
    3726             :      !    SUM(k=top_lev:pver) ( rc_sed_tend(k) + rr_sed_tend(k) )
    3727             :      !                        * dt * pdel(k) / g
    3728             :      !    + precl * dt * 1000 = 0.
    3729             :      !
    3730             :      ! 4) When adjusting the hydrometeor tendency from sedimentation of a
    3731             :      !    frozen hydrometeor (cloud ice or snow), conserve:
    3732             :      !
    3733             :      !    SUM(k=top_lev:pver) ( ri_sed_tend(k) + rs_sed_tend(k) )
    3734             :      !                        * dt * pdel(k) / g
    3735             :      !    + preci * dt * 1000 = 0.
    3736             :      !
    3737             :      ! These two equations (one for liquid-phase hydrometeors and one for
    3738             :      ! ice-phase hydrometeors) could be further split into one equation for
    3739             :      ! each hydrometeor if there was prec output for each hydrometeor.  However,
    3740             :      ! there's only prec output for ice-phase precipitation rate and total
    3741             :      ! precipitation rate (liquid preciptation rate is total rate minus
    3742             :      ! ice-phase rate).
    3743             :      !
    3744             :      ! Since only liquid-phase precipitation rate (precl) and ice-phase
    3745             :      ! precipitation rate (preci) are available, and there are two hydrometeors
    3746             :      ! in each category, one hydrometeor from each category must fill before
    3747             :      ! the other hydrometeor from its category and get priority access to precl
    3748             :      ! or preci.  Since a vast majority of liquid precipitation comes from rain
    3749             :      ! rather than sedimenting cloud water, rain is filled before cloud water
    3750             :      ! and gets priority access to precl.  Likewise, since a vast majority of
    3751             :      ! frozen precipitation comes from snow rather than sedimenting cloud ice,
    3752             :      ! snow is filled before cloud ice and gets priority access to preci.
    3753             :      !
    3754             :      ! The order of sedimentation hole filling is as follows.  First, a level
    3755             :      ! with a hole in it is identified.  The fall distance for the hydrometeor
    3756             :      ! that originated at a level is calculated.  Total mass to fill the hole is
    3757             :      ! calculated from all levels within the fall range that have positive
    3758             :      ! values of the hydrometeor.  The amount that precipitated to the surface
    3759             :      ! is also included if the hydrometeor fell that far.  If that isn't enough
    3760             :      ! mass to fill the hole, then levels that are lower in the profile are
    3761             :      ! included (if the hydrometeor has a positive value) until enough mass is
    3762             :      ! found to fill the hole or until the surface is reached.  If there isn't
    3763             :      ! enough mass found in all levels below the hole, including the amount that
    3764             :      ! precipitated to the ground, to fill the hole, then the hydrometeor mass
    3765             :      ! from all levels above the hole (again, where a positive value of the
    3766             :      ! hydrometeor is found) are included in the total available mass to fill
    3767             :      ! the hole.
    3768             :      !
    3769             :      ! Occasionally, a situation can occur where both hydrometeors in a category
    3770             :      ! contributed to surface precipitation rate, and filling a hole in rain
    3771             :      ! (or snow) can deplete all the surface precl (or preci), resulting in not
    3772             :      ! enough water mass in the vertical profile (including the surface) of
    3773             :      ! cloud water (or cloud ice) to fill a hole in cloud water (or cloud ice).
    3774             :      ! When this happens, there must still be liquid water (or frozen water)
    3775             :      ! found in the vertical profile of rain (or snow), so pull the water from
    3776             :      ! rain (or snow) to fill any remaining holes in cloud water (or cloud ice).
    3777             : 
    3778             :      !----------------------------------------------------------------------
    3779             : 
    3780             :      use ppgrid, only: &
    3781             :          pcols
    3782             : 
    3783             :      use ref_pres, only: &
    3784             :          top_lev => trop_cloud_top_lev
    3785             : 
    3786             :      implicit none
    3787             : 
    3788             :      ! Input Variables
    3789             :      real(r8), intent(in) :: dt                   ! Time step duration
    3790             : 
    3791             :      integer, intent(in) :: ncol                  ! Number of grid columns
    3792             : 
    3793             :      real(r8), dimension(pcols,pver), intent(in) :: &
    3794             :        hm_start,        & ! Hydrometeor mixing ratio (microphys start)   [kg/kg]
    3795             :        hm_start_filler, & ! Filler hydromet mix ratio (microphys start)  [kg/kg]
    3796             :        pdel               ! Pressure difference between grid levels      [Pa]
    3797             : 
    3798             :      real(r8), intent(in) :: &
    3799             :        qmin_hm,        & ! Minimum threshold hydrometeor mixing ratio  [kg/kg]
    3800             :        qmin_hm_filler    ! Min threshold filler hydromet mixing ratio  [kg/kg]
    3801             : 
    3802             :      ! Input/Output Variables
    3803             :      real(r8), dimension(pcols,pver), intent(inout) :: &
    3804             :        hm_tend,        & ! Hydrometeor mixing ratio tendency         [kg/kg/s]
    3805             :        hm_tend_filler    ! Filler hydrometeor mixing ratio tendency  [kg/kg/s]
    3806             : 
    3807             :      ! Local Variables
    3808             :      real(r8), dimension(pver) :: &
    3809             :        hm_update,        & ! Hydrometeor mixing ratio; start           [kg/kg]
    3810             :        hm_update_filler, & ! Filler Hydrometeor mixing ratio; start    [kg/kg]
    3811             :        hm_curr,          & ! Current hydrometeor mixing ratio          [kg/kg]
    3812             :        hm_curr_filler      ! Current filler hydrometeor mixing ratio   [kg/kg]
    3813             : 
    3814             :      real(r8) :: &
    3815             :        total_hole,          & ! Total mass of hole in hydrometeor       [kg/m^2]
    3816             :        total_fill_mass,     & ! Total mass available to fill hole       [kg/m^2]
    3817             :        hole_fillmass_ratio    ! Ratio: total_hole / total_fill_mass     [-]
    3818             : 
    3819             :      logical, dimension(pver) :: &
    3820             :        l_pos_hm,        & ! Flag: hydrometeor has positive (>= qmin_hm) value
    3821             :        l_pos_hm_filler    ! Flag: filler hydrometeor has positive value
    3822             : 
    3823             :      integer :: icol  ! Grid column index
    3824             : 
    3825             :      integer :: k, idx  ! Vertical grid level indices
    3826             : 
    3827             : 
    3828             :      ! Loop over all columns, performing any adjustments one column at a time.
    3829           0 :      do icol = 1, ncol
    3830             : 
    3831             :         ! Calculate the updated value of the hydrometeor field based on the
    3832             :         ! updated microphysics tendency.
    3833           0 :         hm_update = hm_start(icol,:) + hm_tend(icol,:) * dt
    3834           0 :         hm_curr = hm_update
    3835             : 
    3836             :         ! Calculate the updated value of the filler hydrometeor field based on
    3837             :         ! the updated microphysics tendency.
    3838           0 :         hm_update_filler = hm_start_filler(icol,:) + hm_tend_filler(icol,:) * dt
    3839           0 :         hm_curr_filler = hm_update_filler
    3840             : 
    3841             :         ! Check for any holes in the vertical profile
    3842           0 :         if ( any( hm_curr(top_lev:pver) < qmin_hm ) ) then
    3843             : 
    3844             :            ! At least one hole is found in this hydrometeor species in this
    3845             :            ! grid column.  The holes must be filled conservatively.
    3846             : 
    3847             :            ! Check which levels have values of the hydrometeor that are at or
    3848             :            ! above the minimum threshold value.
    3849           0 :            do k = top_lev, pver
    3850             :               ! Check for the hydrometeor that might need to be filled.
    3851           0 :               if ( hm_curr(k) >= qmin_hm ) then
    3852           0 :                 l_pos_hm(k) = .true.
    3853             :               else ! hm_curr < qmin_hm
    3854           0 :                 l_pos_hm(k) = .false.
    3855             :               endif ! hm_curr >= qmin_hm
    3856             :               ! Check for the filler hydrometeor, as some levels might have
    3857             :               ! numerical round-off level, small negative values.
    3858           0 :               if ( hm_curr_filler(k) >= qmin_hm_filler ) then
    3859           0 :                 l_pos_hm_filler(k) = .true.
    3860             :               else ! hm_curr_filler < qmin_hm_filler
    3861           0 :                 l_pos_hm_filler(k) = .false.
    3862             :               endif ! hm_curr_filler >= qmin_hm_filler
    3863             :            end do ! k = top_lev, pver
    3864             : 
    3865           0 :            do k = top_lev, pver
    3866             : 
    3867           0 :               if ( .not. l_pos_hm(k) ) then
    3868             : 
    3869             :                  ! A hole is found in the hydrometeor at this grid level.
    3870             : 
    3871             :                  ! Calculate the total hydrometeor mass of the hole that needs
    3872             :                  ! to be filled.
    3873             :                  ! The value of the hydrometeor mixing ratio is negative, but
    3874             :                  ! the value of total_hole is positive.
    3875           0 :                  total_hole = ( qmin_hm - hm_curr(k) ) * pdel(icol,k) * rga
    3876             : 
    3877             :                  ! Calculate the total hydrometeor mass available from the
    3878             :                  ! filler hydrometeor to fill the hole.
    3879           0 :                  total_fill_mass = 0.0_r8
    3880           0 :                  do idx = top_lev, pver, 1
    3881           0 :                     if ( l_pos_hm_filler(idx) ) then
    3882             :                         total_fill_mass &
    3883             :                         = total_fill_mass &
    3884             :                           + ( hm_curr_filler(idx) - qmin_hm_filler ) &
    3885           0 :                             * pdel(icol,idx) * rga
    3886             :                      endif ! l_pos_hm_filler(idx)
    3887             :                  end do ! idx = top_lev, pver, 1
    3888             : 
    3889             :                  ! Calculate the ratio of total hole to total fill mass.  This
    3890             :                  ! should not exceed 1 except as a result of numerical round-off
    3891             :                  ! errors.  Use thresholding to be safe.
    3892             :                  hole_fillmass_ratio &
    3893             :                  = min( total_hole / max( total_fill_mass, 1.0e-30_r8 ), &
    3894           0 :                         1.0_r8 )
    3895             : 
    3896             :                  ! Modify (reduce) the amount of the filler hydrometeor.
    3897           0 :                  do idx = top_lev, pver
    3898           0 :                     if ( l_pos_hm_filler(idx) ) then
    3899             :                        ! Since pdel at a grid level does not change and gravit
    3900             :                        ! is constant, the only variable that needs to be
    3901             :                        ! modified proportionately is hm_curr_filler.
    3902             :                        hm_curr_filler(idx) &
    3903             :                        = qmin_hm_filler &
    3904             :                          + ( hm_curr_filler(idx) - qmin_hm_filler ) &
    3905           0 :                            * ( 1.0_r8 - hole_fillmass_ratio )
    3906             :                     endif ! l_pos_hm_filler(idx)
    3907             :                  end do ! idx = top_lev, pver
    3908             : 
    3909             :                  ! Update the value of the hydrometeor at the level where the
    3910             :                  ! hole was found.  Mathematically, as long as the available
    3911             :                  ! mass was able to fill the entire hole, the new value of the
    3912             :                  ! hydrometeor mixing ratio (hm_curr) should be qmin_hm.
    3913             :                  hm_curr(k) &
    3914             :                  = hm_curr(k) &
    3915             :                    + hole_fillmass_ratio * total_fill_mass &
    3916           0 :                      * gravit / pdel(icol,k)
    3917             : 
    3918             :               endif ! .not. l_pos_hm(k)
    3919             : 
    3920             :            end do ! k = top_lev, pver
    3921             : 
    3922             :         endif ! any( hm_curr(top_lev:pver) < qmin_hm )
    3923             : 
    3924             :         ! Update the value of total microphysics tendency after hole filling.
    3925           0 :         hm_tend(icol,:) = hm_tend(icol,:) + ( hm_curr - hm_update ) / dt
    3926             : 
    3927             :         ! Update the value of total microphysics tendency after hole filling for
    3928             :         ! the filler hydrometeor.
    3929             :         hm_tend_filler(icol,:) &
    3930           0 :         = hm_tend_filler(icol,:) + ( hm_curr_filler - hm_update_filler ) / dt
    3931             : 
    3932             :      end do ! icol = 1, ncol
    3933             : 
    3934             : 
    3935           0 :      return
    3936             : 
    3937             :    end subroutine fill_holes_same_phase_vert
    3938             : 
    3939             :    !============================================================================
    3940           0 :    subroutine subcol_SILHS_hydromet_conc_tend_lim( state, dt, ptend )
    3941             : 
    3942             :      ! Description:
    3943             :      ! Limits the values of mean hydrometeor concentrations so that the mean
    3944             :      ! drop size for the hydrometeor type remains reasonable and does not become
    3945             :      ! too large.
    3946             : 
    3947             :      !----------------------------------------------------------------------
    3948             : 
    3949             :      use shr_const_mod, only: &
    3950             :          shr_const_pi, &
    3951             :          shr_const_rhofw
    3952             : 
    3953             :      use constituents, only: &
    3954             :          qmin
    3955             : 
    3956             :      use ref_pres, only: &
    3957             :          top_lev => trop_cloud_top_lev
    3958             : 
    3959             :      implicit none
    3960             : 
    3961             :      ! Input Variables
    3962             :      type(physics_state), intent(in) :: state     ! Physics state variables
    3963             :      real(r8), intent(in) :: dt                   ! Time step duration
    3964             : 
    3965             :      ! Input/Output Variable
    3966             :      type(physics_ptend),  intent(inout) :: ptend  ! Parameterization tendencies
    3967             : 
    3968             :      ! Local Variables
    3969             :      real( r8 ) :: &
    3970             :        rcm_update, & ! New value of mean cloud water mixing ratio    [kg/kg]
    3971             :        rrm_update, & ! New value of mean rain water mixing ratio     [kg/kg]
    3972             :        rim_update, & ! New value of mean ice mixing ratio            [kg/kg]
    3973             :        rsm_update    ! New value of mean snow mixing ratio           [kg/kg]
    3974             : 
    3975             :      real( r8 ) :: &
    3976             :        Nc_tend_min, & ! Minimum value of cloud droplet conc. tendency [num/kg/s]
    3977             :        Nr_tend_min, & ! Minimum value of rain drop conc. tendency     [num/kg/s]
    3978             :        Ni_tend_min, & ! Minimum value of ice conc. tendency           [num/kg/s]
    3979             :        Ns_tend_min    ! Minimum value of snow conc. tendency          [num/kg/s]
    3980             : 
    3981             :      real( r8 ), parameter :: &
    3982             :        four_thirds = 4.0_r8/3.0_r8,    & ! 4/3
    3983             :        rho_ice     = 917.0_r8,         & ! Density of ice            [kg/m^3]
    3984             :        rho_lw      = shr_const_rhofw,  & ! Density of liquid water   [kg/m^3]
    3985             :        pi          = shr_const_pi        ! Pi
    3986             : 
    3987             :      real( r8 ), parameter :: &
    3988             :        mvr_cloud_max = 1.6E-5_r8, & ! Max. avg. mean vol. rad. cloud   [m]
    3989             :        mvr_rain_max  = 5.0E-3_r8, & ! Max. avg. mean vol. rad. rain    [m]
    3990             :        mvr_ice_max   = 1.3E-4_r8, & ! Max. avg. mean vol. rad. ice     [m]
    3991             :        mvr_snow_max  = 1.0E-2_r8    ! Max. avg. mean vol. rad. snow    [m]
    3992             : 
    3993             :      ! Calculate the coefficient for the minimum mean cloud droplet
    3994             :      ! concentration, where <Nc>|_min = Ncm_min_coef * <rc> and has units of
    3995             :      ! 1/kg.
    3996             :      real( r8 ), parameter :: &
    3997             :        Ncm_min_coef = 1.0_r8 / ( four_thirds * pi * rho_lw * mvr_cloud_max**3 )
    3998             : 
    3999             :      ! Calculate the coefficient for the minimum mean rain drop concentration,
    4000             :      ! where <Nr>|_min = Nrm_min_coef * <rr> and has units of 1/kg.
    4001             :      real( r8 ), parameter :: &
    4002             :        Nrm_min_coef = 1.0_r8 / ( four_thirds * pi * rho_lw * mvr_rain_max**3 )
    4003             : 
    4004             :      ! Calculate the coefficient for the minimum mean ice crystal concentration,
    4005             :      ! where <Ni>|_min = Nim_min_coef * <ri> and has units of 1/kg.
    4006             :      real( r8 ), parameter :: &
    4007             :        Nim_min_coef = 1.0_r8 / ( four_thirds * pi * rho_ice * mvr_ice_max**3 )
    4008             : 
    4009             :      ! Calculate the coefficient for the minimum mean snow flake concentration,
    4010             :      ! where <Ns>|_min = Nsm_min_coef * <rs> and has units of 1/kg.
    4011             :      real( r8 ), parameter :: &
    4012             :        Nsm_min_coef = 1.0_r8 / ( four_thirds * pi * rho_ice * mvr_snow_max**3 )
    4013             : 
    4014             :      integer :: ncol  ! Number of grid columns
    4015             : 
    4016             :      integer :: icol    ! Column loop index
    4017             : 
    4018             :      integer :: k    ! Vertical level loop index
    4019             : 
    4020             : 
    4021             :      ! Get the number of grid columns.
    4022           0 :      ncol = state%ncol
    4023             : 
    4024             :      ! Loop over all grid columns.
    4025           0 :      do icol = 1, ncol
    4026             : 
    4027             :         ! Loop over all vertical levels from top_lev to pver.
    4028           0 :         do k = top_lev, pver
    4029             : 
    4030             :            ! Cloud droplet concentration
    4031           0 :            if ( ixcldliq > 0 .and. ixnumliq > 0 ) then
    4032             : 
    4033             :               ! Calculate the value of cloud water mixing ratio after the
    4034             :               ! update.
    4035             :               rcm_update &
    4036           0 :               = max( state%q(icol,k,ixcldliq) + ptend%q(icol,k,ixcldliq) * dt, &
    4037           0 :                      qmin(ixcldliq) )
    4038             : 
    4039             :               ! Calculate the limiting cloud droplet concentration tendency so
    4040             :               ! that cloud maintains a reasonable (not too big) mean volume
    4041             :               ! radius.
    4042             :               Nc_tend_min &
    4043           0 :               = ( Ncm_min_coef * rcm_update - state%q(icol,k,ixnumliq) ) / dt
    4044             : 
    4045             :               ! The cloud droplet concentration tendency needs to be the greater
    4046             :               ! of the current Nc_tend and Nc_tend_min.
    4047           0 :               ptend%q(icol,k,ixnumliq) &
    4048           0 :               = max( ptend%q(icol,k,ixnumliq), Nc_tend_min )
    4049             : 
    4050             :            endif ! ixcldliq > 0 .and. ixnumliq > 0
    4051             : 
    4052             :            ! Rain drop concentration
    4053           0 :            if ( ixrain > 0 .and. ixnumrain > 0 ) then
    4054             : 
    4055             :               ! Calculate the value of rain water mixing ratio after the update.
    4056             :               rrm_update &
    4057           0 :               = max( state%q(icol,k,ixrain) + ptend%q(icol,k,ixrain) * dt, &
    4058           0 :                      qmin(ixrain) )
    4059             : 
    4060             :               ! Calculate the limiting rain drop concentration tendency so that
    4061             :               ! rain maintains a reasonable (not too big) mean volume radius.
    4062             :               Nr_tend_min &
    4063           0 :               = ( Nrm_min_coef * rrm_update - state%q(icol,k,ixnumrain) ) / dt
    4064             : 
    4065             :               ! The rain drop concentration tendency needs to be the greater of
    4066             :               ! the current Nr_tend and Nr_tend_min.
    4067           0 :               ptend%q(icol,k,ixnumrain) &
    4068           0 :               = max( ptend%q(icol,k,ixnumrain), Nr_tend_min )
    4069             : 
    4070             :            endif ! ixrain > 0 .and. ixnumrain > 0
    4071             : 
    4072             :            ! Ice crystal concentration
    4073           0 :            if ( ixcldice > 0 .and. ixnumice > 0 ) then
    4074             : 
    4075             :               ! Calculate the value of ice mixing ratio after the update.
    4076             :               rim_update &
    4077           0 :               = max( state%q(icol,k,ixcldice) + ptend%q(icol,k,ixcldice) * dt, &
    4078           0 :                      qmin(ixcldice) )
    4079             : 
    4080             :               ! Calculate the limiting ice crystal concentration tendency so
    4081             :               ! that ice maintains a reasonable (not too big) mean volume
    4082             :               ! radius.
    4083             :               Ni_tend_min &
    4084           0 :               = ( Nim_min_coef * rim_update - state%q(icol,k,ixnumice) ) / dt
    4085             : 
    4086             :               ! The ice crystal concentration tendency needs to be the greater
    4087             :               ! of the current Ni_tend and Ni_tend_min.
    4088           0 :               ptend%q(icol,k,ixnumice) &
    4089           0 :               = max( ptend%q(icol,k,ixnumice), Ni_tend_min )
    4090             : 
    4091             :            endif ! ixcldice > 0 .and. ixnumice > 0
    4092             : 
    4093             :            ! Snow flake concentration
    4094           0 :            if ( ixsnow > 0 .and. ixnumsnow > 0 ) then
    4095             : 
    4096             :               ! Calculate the value of snow mixing ratio after the update.
    4097             :               rsm_update &
    4098           0 :               = max( state%q(icol,k,ixsnow) + ptend%q(icol,k,ixsnow) * dt, &
    4099           0 :                      qmin(ixsnow) )
    4100             : 
    4101             :               ! Calculate the limiting snow flake concentration tendency so that
    4102             :               ! snow maintains a reasonable (not too big) mean volume radius.
    4103             :               Ns_tend_min &
    4104           0 :               = ( Nsm_min_coef * rsm_update - state%q(icol,k,ixnumsnow) ) / dt
    4105             : 
    4106             :               ! The snow flake concentration tendency needs to be the greater of
    4107             :               ! the current Ns_tend and Ns_tend_min.
    4108           0 :               ptend%q(icol,k,ixnumsnow) &
    4109           0 :               = max( ptend%q(icol,k,ixnumsnow), Ns_tend_min )
    4110             : 
    4111             :            endif ! ixsnow > 0 .and. ixnumsnow > 0
    4112             : 
    4113             :         end do ! k = top_lev, pver
    4114             : 
    4115             :      end do ! icol = 1, ncol
    4116             : 
    4117             : 
    4118           0 :      return
    4119             : 
    4120             :    end subroutine subcol_SILHS_hydromet_conc_tend_lim
    4121             : 
    4122             :    !============================================================================
    4123             : 
    4124             :    ! Getunit and Freeunit are depreciated in Fortran going forward, so this is a 
    4125             :    ! small function to get an unused stream identifier to send to setup_corr_varnce_array_api
    4126             :    ! or any other silhs/clubb functions that require a unit number argument
    4127             :    ! This comes directly from the Fortran wiki
    4128             :    integer function newunit(unit)
    4129             :      integer, intent(out), optional :: unit
    4130             :     
    4131             :      integer, parameter :: LUN_MIN=10, LUN_MAX=1000
    4132             :      logical :: opened
    4133             :      integer :: lun
    4134             :    
    4135             :      newunit=-1
    4136             :      do lun=LUN_MIN,LUN_MAX
    4137             :         inquire(unit=lun,opened=opened)
    4138             :         if (.not. opened) then
    4139             :            newunit=lun
    4140             :            exit
    4141             :         end if
    4142             :      end do
    4143             :      if (present(unit)) unit=newunit
    4144             :    end function newunit
    4145             :    
    4146             : end module subcol_SILHS 

Generated by: LCOV version 1.14