LCOV - code coverage report
Current view: top level - physics/cam - macrop_driver.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 15 431 3.5 %
Date: 2025-03-14 01:21:06 Functions: 1 5 20.0 %

          Line data    Source code
       1             :   module macrop_driver
       2             : 
       3             :   !-------------------------------------------------------------------------------------------------------
       4             :   ! Purpose:
       5             :   !
       6             :   ! Provides the CAM interface to the prognostic cloud macrophysics
       7             :   !
       8             :   ! Author: Andrew Gettelman, Cheryl Craig October 2010
       9             :   ! Origin: modified from stratiform.F90 elements
      10             :   !    (Boville 2002, Coleman 2004, Park 2009, Kay 2010)
      11             :   !-------------------------------------------------------------------------------------------------------
      12             : 
      13             :   use shr_kind_mod,  only: r8=>shr_kind_r8
      14             :   use spmd_utils,    only: masterproc
      15             :   use ppgrid,        only: pcols, pver, pverp
      16             :   use physconst,     only: latice, latvap
      17             :   use phys_control,  only: phys_getopts
      18             :   use constituents,  only: cnst_get_ind, pcnst
      19             :   use physics_buffer,    only: physics_buffer_desc, pbuf_set_field, pbuf_get_field, pbuf_old_tim_idx
      20             :   use time_manager,      only: is_first_step
      21             :   use cldwat2m_macro,    only: ini_macro
      22             :   use perf_mod,          only: t_startf, t_stopf
      23             :   use cam_logfile,       only: iulog
      24             :   use cam_abortutils,    only: endrun
      25             : 
      26             :   implicit none
      27             :   private
      28             :   save
      29             : 
      30             :   public :: macrop_driver_readnl
      31             :   public :: macrop_driver_register
      32             :   public :: macrop_driver_init
      33             :   public :: macrop_driver_tend
      34             :   public :: liquid_macro_tend
      35             : 
      36             :   logical, public :: do_cldice             ! .true., park macrophysics is prognosing cldice
      37             :   logical, public :: do_cldliq             ! .true., park macrophysics is prognosing cldliq
      38             :   logical, public :: do_detrain            ! .true., park macrophysics is detraining ice into stratiform
      39             : 
      40             :   ! ------------------------- !
      41             :   ! Private Module Parameters !
      42             :   ! ------------------------- !
      43             : 
      44             :   ! 'cu_det_st' : If .true. (.false.), detrain cumulus liquid condensate into the pre-existing liquid stratus
      45             :   !               (environment) without (with) macrophysical evaporation. If there is no pre-esisting stratus,
      46             :   !               evaporate cumulus liquid condensate. This option only influences the treatment of cumulus
      47             :   !               liquid condensate, not cumulus ice condensate.
      48             : 
      49             :   logical, parameter :: cu_det_st  = .false.
      50             : 
      51             :   ! Parameters used for selecting generalized critical RH for liquid and ice stratus
      52             :   integer :: rhminl_opt = 0
      53             :   integer :: rhmini_opt = 0
      54             : 
      55             : 
      56             :   character(len=16) :: shallow_scheme
      57             :   logical           :: use_shfrc                       ! Local copy of flag from convect_shallow_use_shfrc
      58             : 
      59             :   integer :: &
      60             :     ixcldliq,     &! cloud liquid amount index
      61             :     ixcldice,     &! cloud ice amount index
      62             :     ixnumliq,     &! cloud liquid number index
      63             :     ixnumice,     &! cloud ice water index
      64             :     qcwat_idx,    &! qcwat index in physics buffer
      65             :     lcwat_idx,    &! lcwat index in physics buffer
      66             :     iccwat_idx,   &! iccwat index in physics buffer
      67             :     nlwat_idx,    &! nlwat index in physics buffer
      68             :     niwat_idx,    &! niwat index in physics buffer
      69             :     tcwat_idx,    &! tcwat index in physics buffer
      70             :     CC_T_idx,     &!
      71             :     CC_qv_idx,    &!
      72             :     CC_ql_idx,    &!
      73             :     CC_qi_idx,    &!
      74             :     CC_nl_idx,    &!
      75             :     CC_ni_idx,    &!
      76             :     CC_qlst_idx,  &!
      77             :     cld_idx,      &! cld index in physics buffer
      78             :     ast_idx,      &! stratiform cloud fraction index in physics buffer
      79             :     aist_idx,     &! ice stratiform cloud fraction index in physics buffer
      80             :     alst_idx,     &! liquid stratiform cloud fraction index in physics buffer
      81             :     qist_idx,     &! ice stratiform in-cloud IWC
      82             :     qlst_idx,     &! liquid stratiform in-cloud LWC
      83             :     concld_idx,   &! concld index in physics buffer
      84             :     fice_idx,     &
      85             :     cmeliq_idx,   &
      86             :     shfrc_idx
      87             : 
      88             :   integer :: &
      89             :     dlfzm_idx  = -1,    & ! ZM detrained convective cloud water mixing ratio.
      90             :     dnlfzm_idx = -1,    & ! ZM detrained convective cloud water num concen.
      91             :     dnifzm_idx = -1       ! ZM detrained convective cloud ice num concen.
      92             : 
      93             : 
      94             :   integer :: &
      95             :     tke_idx = -1,       &! tke defined at the model interfaces
      96             :     qtl_flx_idx = -1,   &! overbar(w'qtl' where qtl = qv + ql) from the PBL scheme
      97             :     qti_flx_idx = -1,   &! overbar(w'qti' where qti = qv + qi) from the PBL scheme
      98             :     cmfr_det_idx = -1,  &! detrained convective mass flux from UNICON
      99             :     qlr_det_idx = -1,   &! detrained convective ql from UNICON
     100             :     qir_det_idx = -1,   &! detrained convective qi from UNICON
     101             :     cmfmc_sh_idx = -1
     102             : 
     103             :   contains
     104             : 
     105             :   ! ===============================================================================
     106        1536 :   subroutine macrop_driver_readnl(nlfile)
     107             : 
     108             :     use namelist_utils,  only: find_group_name
     109             :     use units,           only: getunit, freeunit
     110             :     use mpishorthand
     111             : 
     112             :     character(len=*), intent(in) :: nlfile  ! filepath for file containing namelist input
     113             : 
     114             :    ! Namelist variables
     115             :    logical  :: macro_park_do_cldice  = .true.   ! do_cldice = .true., park macrophysics is prognosing cldice
     116             :    logical  :: macro_park_do_cldliq  = .true.   ! do_cldliq = .true., park macrophysics is prognosing cldliq
     117             :    logical  :: macro_park_do_detrain = .true.   ! do_detrain = .true., park macrophysics is detraining ice into stratiform
     118             : 
     119             :    ! Local variables
     120             :    integer :: unitn, ierr
     121             :    character(len=*), parameter :: subname = 'macrop_driver_readnl'
     122             : 
     123             :    namelist /macro_park_nl/ macro_park_do_cldice, macro_park_do_cldliq, macro_park_do_detrain
     124             :    !-----------------------------------------------------------------------------
     125             : 
     126        1536 :    if (masterproc) then
     127           2 :       unitn = getunit()
     128           2 :       open( unitn, file=trim(nlfile), status='old' )
     129           2 :       call find_group_name(unitn, 'macro_park_nl', status=ierr)
     130           2 :       if (ierr == 0) then
     131           0 :          read(unitn, macro_park_nl, iostat=ierr)
     132           0 :          if (ierr /= 0) then
     133           0 :             call endrun(subname // ':: ERROR reading namelist')
     134             :          end if
     135             :       end if
     136           2 :       close(unitn)
     137           2 :       call freeunit(unitn)
     138             : 
     139             :       ! set local variables
     140             : 
     141           2 :       do_cldice  = macro_park_do_cldice
     142           2 :       do_cldliq  = macro_park_do_cldliq
     143           2 :       do_detrain = macro_park_do_detrain
     144             : 
     145             :    end if
     146             : 
     147             : #ifdef SPMD
     148             :    ! Broadcast namelist variables
     149        1536 :    call mpibcast(do_cldice,             1, mpilog, 0, mpicom)
     150        1536 :    call mpibcast(do_cldliq,             1, mpilog, 0, mpicom)
     151        1536 :    call mpibcast(do_detrain,            1, mpilog, 0, mpicom)
     152             : #endif
     153             : 
     154        1536 : end subroutine macrop_driver_readnl
     155             : 
     156             :   !================================================================================================
     157             : 
     158           0 :   subroutine macrop_driver_register
     159             : 
     160             :   !---------------------------------------------------------------------- !
     161             :   !                                                                       !
     162             :   ! Register the constituents (cloud liquid and cloud ice) and the fields !
     163             :   ! in the physics buffer.                                                !
     164             :   !                                                                       !
     165             :   !---------------------------------------------------------------------- !
     166             : 
     167             : 
     168             :    use physics_buffer, only : pbuf_add_field, dtype_r8, dyn_time_lvls
     169             : 
     170             :   !-----------------------------------------------------------------------
     171             : 
     172           0 :     call phys_getopts(shallow_scheme_out=shallow_scheme)
     173             : 
     174           0 :     call pbuf_add_field('AST',      'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), ast_idx)
     175           0 :     call pbuf_add_field('AIST',     'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), aist_idx)
     176           0 :     call pbuf_add_field('ALST',     'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), alst_idx)
     177           0 :     call pbuf_add_field('QIST',     'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), qist_idx)
     178           0 :     call pbuf_add_field('QLST',     'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), qlst_idx)
     179           0 :     call pbuf_add_field('CLD',      'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), cld_idx)
     180           0 :     call pbuf_add_field('CONCLD',   'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), concld_idx)
     181             : 
     182           0 :     call pbuf_add_field('QCWAT',    'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), qcwat_idx)
     183           0 :     call pbuf_add_field('LCWAT',    'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), lcwat_idx)
     184           0 :     call pbuf_add_field('ICCWAT',   'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), iccwat_idx)
     185           0 :     call pbuf_add_field('NLWAT',    'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), nlwat_idx)
     186           0 :     call pbuf_add_field('NIWAT',    'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), niwat_idx)
     187           0 :     call pbuf_add_field('TCWAT',    'global',  dtype_r8, (/pcols,pver,dyn_time_lvls/), tcwat_idx)
     188             : 
     189           0 :     call pbuf_add_field('FICE',     'physpkg', dtype_r8, (/pcols,pver/), fice_idx)
     190             : 
     191           0 :     call pbuf_add_field('CMELIQ',   'physpkg', dtype_r8, (/pcols,pver/), cmeliq_idx)
     192             : 
     193           0 :   end subroutine macrop_driver_register
     194             : 
     195             :   !============================================================================ !
     196             :   !                                                                             !
     197             :   !============================================================================ !
     198             : 
     199           0 :   subroutine macrop_driver_init(pbuf2d)
     200             : 
     201             :   !-------------------------------------------- !
     202             :   !                                             !
     203             :   ! Initialize the cloud water parameterization !
     204             :   !                                             !
     205             :   !-------------------------------------------- !
     206           0 :     use physics_buffer, only : pbuf_get_index
     207             :     use cam_history,     only: addfld, add_default
     208             :     use convect_shallow, only: convect_shallow_use_shfrc
     209             : 
     210             :     type(physics_buffer_desc), pointer :: pbuf2d(:,:)
     211             : 
     212             :     logical              :: history_aerosol      ! Output the MAM aerosol tendencies
     213             :     logical              :: history_budget       ! Output tendencies and state variables for CAM4
     214             :                                                  ! temperature, water vapor, cloud ice and cloud
     215             :                                                  ! liquid budgets.
     216             :     integer              :: history_budget_histfile_num ! output history file number for budget fields
     217             :     integer :: istat
     218             : 
     219             :     character(len=*), parameter :: subname = 'macrop_driver_init'
     220             :     !-----------------------------------------------------------------------
     221             : 
     222             :     ! Initialization routine for cloud macrophysics
     223           0 :     if (shallow_scheme .eq. 'UNICON') rhminl_opt = 1
     224           0 :     call ini_macro(rhminl_opt, rhmini_opt)
     225             : 
     226             :     call phys_getopts(history_aerosol_out              = history_aerosol      , &
     227             :                       history_budget_out               = history_budget       , &
     228           0 :                       history_budget_histfile_num_out  = history_budget_histfile_num )
     229             : 
     230             :   ! Find out whether shfrc from convect_shallow will be used in cldfrc
     231             : 
     232           0 :     if( convect_shallow_use_shfrc() ) then
     233           0 :         use_shfrc = .true.
     234           0 :         shfrc_idx = pbuf_get_index('shfrc')
     235             :     else
     236           0 :         use_shfrc = .false.
     237             :     endif
     238             : 
     239           0 :     call addfld ('DPDLFLIQ',  (/ 'lev' /), 'A', 'kg/kg/s',  'Detrained liquid water from deep convection',       sampled_on_subcycle=.true.)
     240           0 :     call addfld ('DPDLFICE',  (/ 'lev' /), 'A', 'kg/kg/s',  'Detrained ice from deep convection',                sampled_on_subcycle=.true.)
     241           0 :     call addfld ('SHDLFLIQ',  (/ 'lev' /), 'A', 'kg/kg/s',  'Detrained liquid water from shallow convection',    sampled_on_subcycle=.true.)
     242           0 :     call addfld ('SHDLFICE',  (/ 'lev' /), 'A', 'kg/kg/s',  'Detrained ice from shallow convection',             sampled_on_subcycle=.true.)
     243           0 :     call addfld ('DPDLFT',    (/ 'lev' /), 'A', 'K/s',      'T-tendency due to deep convective detrainment',     sampled_on_subcycle=.true.)
     244           0 :     call addfld ('SHDLFT',    (/ 'lev' /), 'A', 'K/s',      'T-tendency due to shallow convective detrainment',  sampled_on_subcycle=.true.)
     245             : 
     246           0 :     call addfld ('ZMDLF',     (/ 'lev' /), 'A', 'kg/kg/s',  'Detrained liquid water from ZM convection',         sampled_on_subcycle=.true.)
     247             : 
     248           0 :     call addfld ('MACPDT',    (/ 'lev' /), 'A', 'W/kg',     'Heating tendency - Revised  macrophysics',          sampled_on_subcycle=.true.)
     249           0 :     call addfld ('MACPDQ',    (/ 'lev' /), 'A', 'kg/kg/s',  'Q tendency - Revised macrophysics',                 sampled_on_subcycle=.true.)
     250           0 :     call addfld ('MACPDLIQ',  (/ 'lev' /), 'A', 'kg/kg/s',  'CLDLIQ tendency - Revised macrophysics',            sampled_on_subcycle=.true.)
     251           0 :     call addfld ('MACPDICE',  (/ 'lev' /), 'A', 'kg/kg/s',  'CLDICE tendency - Revised macrophysics',            sampled_on_subcycle=.true.)
     252             : 
     253             :     call addfld ('CLDVAPADJ', (/ 'lev' /), 'A', 'kg/kg/s',  &
     254           0 :          'Q tendency associated with liq/ice adjustment - Revised macrophysics',                                 sampled_on_subcycle=.true.)
     255           0 :     call addfld ('CLDLIQADJ', (/ 'lev' /), 'A', 'kg/kg/s',  'CLDLIQ adjustment tendency - Revised macrophysics', sampled_on_subcycle=.true.)
     256           0 :     call addfld ('CLDICEADJ', (/ 'lev' /), 'A', 'kg/kg/s',  'CLDICE adjustment tendency - Revised macrophysics', sampled_on_subcycle=.true.)
     257             :     call addfld ('CLDLIQDET', (/ 'lev' /), 'A', 'kg/kg/s',  &
     258           0 :          'Detrainment of conv cld liq into envrionment  - Revised macrophysics',                                 sampled_on_subcycle=.true.)
     259             :     call addfld ('CLDICEDET', (/ 'lev' /), 'A', 'kg/kg/s',  &
     260           0 :          'Detrainment of conv cld ice into envrionment  - Revised macrophysics',                                 sampled_on_subcycle=.true.)
     261           0 :     call addfld ('CLDLIQLIM', (/ 'lev' /), 'A', 'kg/kg/s',  'CLDLIQ limiting tendency - Revised macrophysics',   sampled_on_subcycle=.true.)
     262           0 :     call addfld ('CLDICELIM', (/ 'lev' /), 'A', 'kg/kg/s',  'CLDICE limiting tendency - Revised macrophysics',   sampled_on_subcycle=.true.)
     263             : 
     264           0 :     call addfld ('AST',       (/ 'lev' /), 'A', '1',        'Stratus cloud fraction',                            sampled_on_subcycle=.true.)
     265           0 :     call addfld ('LIQCLDF',   (/ 'lev' /), 'A', '1',        'Stratus Liquid cloud fraction',                     sampled_on_subcycle=.true.)
     266           0 :     call addfld ('ICECLDF',   (/ 'lev' /), 'A', '1',        'Stratus ICE cloud fraction',                        sampled_on_subcycle=.true.)
     267             : 
     268           0 :     call addfld ('CLDST',     (/ 'lev' /), 'A', 'fraction', 'Stratus cloud fraction',                            sampled_on_subcycle=.true.)
     269           0 :     call addfld ('CONCLD',    (/ 'lev' /), 'A', 'fraction', 'Convective cloud cover',                            sampled_on_subcycle=.true.)
     270             : 
     271           0 :     call addfld ('CLR_LIQ',   (/ 'lev' /), 'A', 'fraction', 'Clear sky fraction for liquid stratus',             sampled_on_subcycle=.true.)
     272           0 :     call addfld ('CLR_ICE',   (/ 'lev' /), 'A', 'fraction', 'Clear sky fraction for ice stratus',                sampled_on_subcycle=.true.)
     273             : 
     274           0 :     call addfld ('CLDLIQSTR', (/ 'lev' /), 'A', 'kg/kg',    'Stratiform CLDLIQ',                                 sampled_on_subcycle=.true.)
     275           0 :     call addfld ('CLDICESTR', (/ 'lev' /), 'A', 'kg/kg',    'Stratiform CLDICE',                                 sampled_on_subcycle=.true.)
     276           0 :     call addfld ('CLDLIQCON', (/ 'lev' /), 'A', 'kg/kg',    'Convective CLDLIQ',                                 sampled_on_subcycle=.true.)
     277           0 :     call addfld ('CLDICECON', (/ 'lev' /), 'A', 'kg/kg',    'Convective CLDICE',                                 sampled_on_subcycle=.true.)
     278             : 
     279           0 :     call addfld ('CLDSICE',   (/ 'lev' /), 'A', 'kg/kg',    'CloudSat equivalent ice mass mixing ratio',         sampled_on_subcycle=.true.)
     280           0 :     call addfld ('CMELIQ',    (/ 'lev' /), 'A', 'kg/kg/s',  'Rate of cond-evap of liq within the cloud',         sampled_on_subcycle=.true.)
     281             : 
     282           0 :     call addfld ('TTENDICE',  (/ 'lev' /), 'A', 'K/s',      'T tendency from Ice Saturation Adjustment',         sampled_on_subcycle=.true.)
     283           0 :     call addfld ('QVTENDICE', (/ 'lev' /), 'A', 'kg/kg/s',  'Q tendency from Ice Saturation Adjustment',         sampled_on_subcycle=.true.)
     284           0 :     call addfld ('QITENDICE', (/ 'lev' /), 'A', 'kg/kg/s',  'CLDICE tendency from Ice Saturation Adjustment',    sampled_on_subcycle=.true.)
     285           0 :     call addfld ('NITENDICE', (/ 'lev' /), 'A', 'kg/kg/s',  'NUMICE tendency from Ice Saturation Adjustment',    sampled_on_subcycle=.true.)
     286           0 :     if ( history_budget ) then
     287             : 
     288           0 :           call add_default ('DPDLFLIQ ', history_budget_histfile_num, ' ')
     289           0 :           call add_default ('DPDLFICE ', history_budget_histfile_num, ' ')
     290           0 :           call add_default ('SHDLFLIQ ', history_budget_histfile_num, ' ')
     291           0 :           call add_default ('SHDLFICE ', history_budget_histfile_num, ' ')
     292           0 :           call add_default ('DPDLFT   ', history_budget_histfile_num, ' ')
     293           0 :           call add_default ('SHDLFT   ', history_budget_histfile_num, ' ')
     294           0 :           call add_default ('ZMDLF    ', history_budget_histfile_num, ' ')
     295             : 
     296           0 :           call add_default ('MACPDT   ', history_budget_histfile_num, ' ')
     297           0 :           call add_default ('MACPDQ   ', history_budget_histfile_num, ' ')
     298           0 :           call add_default ('MACPDLIQ ', history_budget_histfile_num, ' ')
     299           0 :           call add_default ('MACPDICE ', history_budget_histfile_num, ' ')
     300             : 
     301           0 :           call add_default ('CLDVAPADJ', history_budget_histfile_num, ' ')
     302           0 :           call add_default ('CLDLIQLIM', history_budget_histfile_num, ' ')
     303           0 :           call add_default ('CLDLIQDET', history_budget_histfile_num, ' ')
     304           0 :           call add_default ('CLDLIQADJ', history_budget_histfile_num, ' ')
     305           0 :           call add_default ('CLDICELIM', history_budget_histfile_num, ' ')
     306           0 :           call add_default ('CLDICEDET', history_budget_histfile_num, ' ')
     307           0 :           call add_default ('CLDICEADJ', history_budget_histfile_num, ' ')
     308             : 
     309           0 :           call add_default ('CMELIQ   ', history_budget_histfile_num, ' ')
     310             : 
     311             :     end if
     312             : 
     313             :     ! Get constituent indices
     314           0 :     call cnst_get_ind('CLDLIQ', ixcldliq)
     315           0 :     call cnst_get_ind('CLDICE', ixcldice)
     316           0 :     call cnst_get_ind('NUMLIQ', ixnumliq)
     317           0 :     call cnst_get_ind('NUMICE', ixnumice)
     318             : 
     319             :     ! Get physics buffer indices
     320           0 :     CC_T_idx    = pbuf_get_index('CC_T')
     321           0 :     CC_qv_idx   = pbuf_get_index('CC_qv')
     322           0 :     CC_ql_idx   = pbuf_get_index('CC_ql')
     323           0 :     CC_qi_idx   = pbuf_get_index('CC_qi')
     324           0 :     CC_nl_idx   = pbuf_get_index('CC_nl')
     325           0 :     CC_ni_idx   = pbuf_get_index('CC_ni')
     326           0 :     CC_qlst_idx = pbuf_get_index('CC_qlst')
     327           0 :     cmfmc_sh_idx = pbuf_get_index('CMFMC_SH')
     328             : 
     329           0 :     if (rhminl_opt > 0 .or. rhmini_opt > 0) then
     330           0 :        cmfr_det_idx = pbuf_get_index('cmfr_det', istat)
     331           0 :        if (istat < 0) call endrun(subname//': macrop option requires cmfr_det in pbuf')
     332           0 :        if (rhminl_opt > 0) then
     333           0 :           qlr_det_idx  = pbuf_get_index('qlr_det', istat)
     334           0 :           if (istat < 0) call endrun(subname//': macrop option requires qlr_det in pbuf')
     335             :        end if
     336           0 :        if (rhmini_opt > 0) then
     337           0 :           qir_det_idx  = pbuf_get_index('qir_det', istat)
     338           0 :           if (istat < 0) call endrun(subname//': macrop option requires qir_det in pbuf')
     339             :        end if
     340             :     end if
     341             : 
     342           0 :     if (rhminl_opt == 2 .or. rhmini_opt == 2) then
     343           0 :        tke_idx = pbuf_get_index('tke')
     344           0 :        if (rhminl_opt == 2) then
     345           0 :           qtl_flx_idx = pbuf_get_index('qtl_flx', istat)
     346           0 :           if (istat < 0) call endrun(subname//': macrop option requires qtl_flx in pbuf')
     347             :        end if
     348           0 :        if (rhmini_opt == 2) then
     349           0 :           qti_flx_idx = pbuf_get_index('qti_flx', istat)
     350           0 :           if (istat < 0) call endrun(subname//': macrop option requires qti_flx in pbuf')
     351             :        end if
     352             :     end if
     353             : 
     354             :     ! Init pbuf fields.  Note that the fields CLD, CONCLD, QCWAT, LCWAT,
     355             :     ! ICCWAT, and TCWAT are initialized in phys_inidat.
     356           0 :     if (is_first_step()) then
     357           0 :        call pbuf_set_field(pbuf2d, ast_idx,    0._r8)
     358           0 :        call pbuf_set_field(pbuf2d, aist_idx,   0._r8)
     359           0 :        call pbuf_set_field(pbuf2d, alst_idx,   0._r8)
     360           0 :        call pbuf_set_field(pbuf2d, qist_idx,   0._r8)
     361           0 :        call pbuf_set_field(pbuf2d, qlst_idx,   0._r8)
     362           0 :        call pbuf_set_field(pbuf2d, nlwat_idx,  0._r8)
     363           0 :        call pbuf_set_field(pbuf2d, niwat_idx,  0._r8)
     364             :     end if
     365             : 
     366             :     ! the following are physpkg, so they need to be init every time
     367           0 :     call pbuf_set_field(pbuf2d, fice_idx,   0._r8)
     368           0 :     call pbuf_set_field(pbuf2d, cmeliq_idx, 0._r8)
     369             : 
     370           0 :   end subroutine macrop_driver_init
     371             : 
     372             :   !============================================================================ !
     373             :   !                                                                             !
     374             :   !============================================================================ !
     375             : 
     376             : 
     377           0 :   subroutine macrop_driver_tend(                             &
     378             :              state, ptend, dtime, landfrac,  &
     379             :              ocnfrac,  snowh,                       &
     380             :              dlf, dlf2, cmfmc, ts,          &
     381             :              sst, zdu,       &
     382             :              pbuf, &
     383             :              det_s, det_ice)
     384             : 
     385             :   !-------------------------------------------------------- !
     386             :   !                                                         !
     387             :   ! Purpose:                                                !
     388             :   !                                                         !
     389             :   ! Interface to detrain, cloud fraction and                !
     390             :   !     cloud macrophysics subroutines                      !
     391             :   !                                                         !
     392             :   ! Author: A. Gettelman, C. Craig, Oct 2010                !
     393             :   ! based on stratiform_tend by D.B. Coleman 4/2010         !
     394             :   !                                                         !
     395             :   !-------------------------------------------------------- !
     396             : 
     397           0 :   use cloud_fraction,   only: cldfrc
     398             :   use cloud_fraction_fice,  only: cloud_fraction_fice_run
     399             :   use physics_types,    only: physics_state, physics_ptend
     400             :   use physics_types,    only: physics_ptend_init, physics_update
     401             :   use physics_types,    only: physics_ptend_sum,  physics_state_copy
     402             :   use physics_types,    only: physics_state_dealloc
     403             :   use cam_history,      only: outfld
     404             :   use constituents,     only: cnst_get_ind, pcnst
     405             :   use cldwat2m_macro,   only: mmacro_pcond
     406             :   use physconst,        only: cpair, tmelt, gravit
     407             :   use time_manager,     only: get_nstep
     408             : 
     409             :   use ref_pres,         only: top_lev => trop_cloud_top_lev
     410             : 
     411             :   !
     412             :   ! Input arguments
     413             :   !
     414             : 
     415             :   type(physics_state), intent(in)    :: state       ! State variables
     416             :   type(physics_ptend), intent(out)   :: ptend       ! macrophysics parameterization tendencies
     417             :   type(physics_buffer_desc), pointer :: pbuf(:)     ! Physics buffer
     418             : 
     419             :   real(r8), intent(in)  :: dtime                    ! Timestep
     420             :   real(r8), intent(in)  :: landfrac(pcols)          ! Land fraction (fraction)
     421             :   real(r8), intent(in)  :: ocnfrac (pcols)          ! Ocean fraction (fraction)
     422             :   real(r8), intent(in)  :: snowh(pcols)             ! Snow depth over land, water equivalent (m)
     423             :   real(r8), intent(in)  :: dlf(pcols,pver)          ! Detrained water from convection schemes
     424             :   real(r8), intent(in)  :: dlf2(pcols,pver)         ! Detrained water from shallow convection scheme
     425             :   real(r8), intent(in)  :: cmfmc(pcols,pverp)       ! Deep + Shallow Convective mass flux [ kg /s/m^2 ]
     426             : 
     427             :   real(r8), intent(in)  :: ts(pcols)                ! Surface temperature
     428             :   real(r8), intent(in)  :: sst(pcols)               ! Sea surface temperature
     429             :   real(r8), intent(in)  :: zdu(pcols,pver)          ! Detrainment rate from deep convection
     430             : 
     431             : 
     432             :   ! These two variables are needed for energy check
     433             :   real(r8), intent(out) :: det_s(pcols)             ! Integral of detrained static energy from ice
     434             :   real(r8), intent(out) :: det_ice(pcols)           ! Integral of detrained ice for energy check
     435             : 
     436             :   !
     437             :   ! Local variables
     438             :   !
     439             : 
     440           0 :   type(physics_state) :: state_loc                  ! Local copy of the state variable
     441           0 :   type(physics_ptend) :: ptend_loc                  ! Local parameterization tendencies
     442             : 
     443             :   integer i,k
     444             :   integer :: lchnk                                  ! Chunk identifier
     445             :   integer :: ncol                                   ! Number of atmospheric columns
     446             : 
     447             :   ! Physics buffer fields
     448             : 
     449             :   integer itim_old
     450           0 :   real(r8), pointer, dimension(:,:) :: qcwat        ! Cloud water old q
     451           0 :   real(r8), pointer, dimension(:,:) :: tcwat        ! Cloud water old temperature
     452           0 :   real(r8), pointer, dimension(:,:) :: lcwat        ! Cloud liquid water old q
     453           0 :   real(r8), pointer, dimension(:,:) :: iccwat       ! Cloud ice water old q
     454           0 :   real(r8), pointer, dimension(:,:) :: nlwat        ! Cloud liquid droplet number condentration. old.
     455           0 :   real(r8), pointer, dimension(:,:) :: niwat        ! Cloud ice    droplet number condentration. old.
     456           0 :   real(r8), pointer, dimension(:,:) :: CC_T         ! Grid-mean microphysical tendency
     457           0 :   real(r8), pointer, dimension(:,:) :: CC_qv        ! Grid-mean microphysical tendency
     458           0 :   real(r8), pointer, dimension(:,:) :: CC_ql        ! Grid-mean microphysical tendency
     459           0 :   real(r8), pointer, dimension(:,:) :: CC_qi        ! Grid-mean microphysical tendency
     460           0 :   real(r8), pointer, dimension(:,:) :: CC_nl        ! Grid-mean microphysical tendency
     461           0 :   real(r8), pointer, dimension(:,:) :: CC_ni        ! Grid-mean microphysical tendency
     462           0 :   real(r8), pointer, dimension(:,:) :: CC_qlst      ! In-liquid stratus microphysical tendency
     463           0 :   real(r8), pointer, dimension(:,:) :: cld          ! Total cloud fraction
     464           0 :   real(r8), pointer, dimension(:,:) :: ast          ! Relative humidity cloud fraction
     465           0 :   real(r8), pointer, dimension(:,:) :: aist         ! Physical ice stratus fraction
     466           0 :   real(r8), pointer, dimension(:,:) :: alst         ! Physical liquid stratus fraction
     467           0 :   real(r8), pointer, dimension(:,:) :: qist         ! Physical in-cloud IWC
     468           0 :   real(r8), pointer, dimension(:,:) :: qlst         ! Physical in-cloud LWC
     469           0 :   real(r8), pointer, dimension(:,:) :: concld       ! Convective cloud fraction
     470             : 
     471           0 :   real(r8), pointer, dimension(:,:) :: shfrc        ! Cloud fraction from shallow convection scheme
     472           0 :   real(r8), pointer, dimension(:,:) :: cmfmc_sh     ! Shallow convective mass flux (pcols,pverp) [ kg/s/m^2 ]
     473             : 
     474           0 :   real(r8), pointer, dimension(:,:) :: cmeliq
     475             : 
     476           0 :   real(r8), pointer, dimension(:,:) :: tke
     477           0 :   real(r8), pointer, dimension(:,:) :: qtl_flx
     478           0 :   real(r8), pointer, dimension(:,:) :: qti_flx
     479           0 :   real(r8), pointer, dimension(:,:) :: cmfr_det
     480           0 :   real(r8), pointer, dimension(:,:) :: qlr_det
     481           0 :   real(r8), pointer, dimension(:,:) :: qir_det
     482             : 
     483             :   ! Convective cloud to the physics buffer for purposes of ql contrib. to radn.
     484             : 
     485           0 :   real(r8), pointer, dimension(:,:) :: fice_ql      ! Cloud ice/water partitioning ratio.
     486             : 
     487             :   ! ZM microphysics
     488             :   real(r8), pointer :: dlfzm(:,:)  ! ZM detrained convective cloud water mixing ratio.
     489             :   real(r8), pointer :: dnlfzm(:,:) ! ZM detrained convective cloud water num concen.
     490             :   real(r8), pointer :: dnifzm(:,:) ! ZM detrained convective cloud ice num concen.
     491             : 
     492             :   real(r8) :: latsub
     493             : 
     494             :   ! tendencies for ice saturation adjustment
     495             :   real(r8)  :: stend(pcols,pver)
     496             :   real(r8)  :: qvtend(pcols,pver)
     497             :   real(r8)  :: qitend(pcols,pver)
     498             :   real(r8)  :: initend(pcols,pver)
     499             : 
     500             :   ! Local variables for cldfrc
     501             : 
     502             :   real(r8)  cldst(pcols,pver)                       ! Stratus cloud fraction
     503             :   real(r8)  rhcloud(pcols,pver)                     ! Relative humidity cloud (last timestep)
     504             :   real(r8)  clc(pcols)                              ! Column convective cloud amount
     505             :   real(r8)  rhu00(pcols,pver)                       ! RH threshold for cloud
     506             :   real(r8)  icecldf(pcols,pver)                     ! Ice cloud fraction
     507             :   real(r8)  liqcldf(pcols,pver)                     ! Liquid cloud fraction (combined into cloud)
     508             :   real(r8)  relhum(pcols,pver)                      ! RH, output to determine drh/da
     509             : 
     510             :   ! Local variables for macrophysics
     511             : 
     512             :   real(r8)  rdtime                                  ! 1./dtime
     513             :   real(r8)  qtend(pcols,pver)                       ! Moisture tendencies
     514             :   real(r8)  ttend(pcols,pver)                       ! Temperature tendencies
     515             :   real(r8)  ltend(pcols,pver)                       ! Cloud liquid water tendencies
     516             :   real(r8)  fice(pcols,pver)                        ! Fractional ice content within cloud
     517             :   real(r8)  fsnow(pcols,pver)                       ! Fractional snow production
     518             :   real(r8)  homoo(pcols,pver)
     519             :   real(r8)  qcreso(pcols,pver)
     520             :   real(r8)  prcio(pcols,pver)
     521             :   real(r8)  praio(pcols,pver)
     522             :   real(r8)  qireso(pcols,pver)
     523             :   real(r8)  ftem(pcols,pver)
     524             :   real(r8)  pracso (pcols,pver)
     525             :   real(r8)  dpdlfliq(pcols,pver)
     526             :   real(r8)  dpdlfice(pcols,pver)
     527             :   real(r8)  shdlfliq(pcols,pver)
     528             :   real(r8)  shdlfice(pcols,pver)
     529             :   real(r8)  dpdlft  (pcols,pver)
     530             :   real(r8)  shdlft  (pcols,pver)
     531             : 
     532             :   real(r8)  dum1
     533             :   real(r8)  qc(pcols,pver)
     534             :   real(r8)  qi(pcols,pver)
     535             :   real(r8)  nc(pcols,pver)
     536             :   real(r8)  ni(pcols,pver)
     537             : 
     538             :   logical   lq(pcnst)
     539             : 
     540             :   ! Output from mmacro_pcond
     541             : 
     542             :   real(r8)  tlat(pcols,pver)
     543             :   real(r8)  qvlat(pcols,pver)
     544             :   real(r8)  qcten(pcols,pver)
     545             :   real(r8)  qiten(pcols,pver)
     546             :   real(r8)  ncten(pcols,pver)
     547             :   real(r8)  niten(pcols,pver)
     548             : 
     549             :   ! Output from mmacro_pcond
     550             : 
     551             :   real(r8)  qvadj(pcols,pver)                       ! Macro-physics adjustment tendency from "positive_moisture" call (vapor)
     552             :   real(r8)  qladj(pcols,pver)                       ! Macro-physics adjustment tendency from "positive_moisture" call (liquid)
     553             :   real(r8)  qiadj(pcols,pver)                       ! Macro-physics adjustment tendency from "positive_moisture" call (ice)
     554             :   real(r8)  qllim(pcols,pver)                       ! Macro-physics tendency from "instratus_condensate" call (liquid)
     555             :   real(r8)  qilim(pcols,pver)                       ! Macro-physics tendency from "instratus_condensate" call (ice)
     556             : 
     557             :   ! For revised macophysics, mmacro_pcond
     558             : 
     559             :   real(r8)  itend(pcols,pver)
     560             :   real(r8)  lmitend(pcols,pver)
     561             :   real(r8)  zeros(pcols,pver)
     562             :   real(r8)  t_inout(pcols,pver)
     563             :   real(r8)  qv_inout(pcols,pver)
     564             :   real(r8)  ql_inout(pcols,pver)
     565             :   real(r8)  qi_inout(pcols,pver)
     566             :   real(r8)  concld_old(pcols,pver)
     567             : 
     568             :   ! Note that below 'clr_old' is defined using 'alst_old' not 'ast_old' for full consistency with the
     569             :   ! liquid condensation process which is using 'alst' not 'ast'.
     570             :   ! For microconsistency use 'concld_old', since 'alst_old' was computed using 'concld_old'.
     571             :   ! Since convective updraft fractional area is small, it does not matter whether 'concld' or 'concld_old' is used.
     572             :   ! Note also that 'clri_old' is defined using 'ast_old' since current microphysics is operating on 'ast_old'
     573             :   real(r8)  clrw_old(pcols,pver) ! (1 - concld_old - alst_old)
     574             :   real(r8)  clri_old(pcols,pver) ! (1 - concld_old -  ast_old)
     575             : 
     576             :   real(r8)  nl_inout(pcols,pver)
     577             :   real(r8)  ni_inout(pcols,pver)
     578             : 
     579             :   real(r8)  nltend(pcols,pver)
     580             :   real(r8)  nitend(pcols,pver)
     581             : 
     582             : 
     583             :   ! For detraining cumulus condensate into the 'stratus' without evaporation
     584             :   ! This is for use in mmacro_pcond
     585             : 
     586             :   real(r8)  dlf_T(pcols,pver)
     587             :   real(r8)  dlf_qv(pcols,pver)
     588             :   real(r8)  dlf_ql(pcols,pver)
     589             :   real(r8)  dlf_qi(pcols,pver)
     590             :   real(r8)  dlf_nl(pcols,pver)
     591             :   real(r8)  dlf_ni(pcols,pver)
     592             : 
     593             :   ! Local variables for CFMIP calculations
     594             :   real(r8) :: mr_lsliq(pcols,pver)  ! mixing_ratio_large_scale_cloud_liquid (kg/kg)
     595             :   real(r8) :: mr_lsice(pcols,pver)  ! mixing_ratio_large_scale_cloud_ice (kg/kg)
     596             :   real(r8) :: mr_ccliq(pcols,pver)  ! mixing_ratio_convective_cloud_liquid (kg/kg)
     597             :   real(r8) :: mr_ccice(pcols,pver)  ! mixing_ratio_convective_cloud_ice (kg/kg)
     598             : 
     599             :   ! CloudSat equivalent ice mass mixing ratio (kg/kg)
     600             :   real(r8) :: cldsice(pcols,pver)
     601             : 
     602             :   ! For CCPPized schemes
     603             :   character(len=512)   :: errmsg
     604             :   integer              :: errflg
     605             : 
     606             :   ! ======================================================================
     607             : 
     608           0 :   lchnk = state%lchnk
     609           0 :   ncol  = state%ncol
     610             : 
     611           0 :   call physics_state_copy(state, state_loc)            ! Copy state to local state_loc.
     612             : 
     613             :   ! Associate pointers with physics buffer fields
     614             : 
     615           0 :   itim_old = pbuf_old_tim_idx()
     616             : 
     617           0 :   call pbuf_get_field(pbuf, qcwat_idx,   qcwat,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     618           0 :   call pbuf_get_field(pbuf, tcwat_idx,   tcwat,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     619           0 :   call pbuf_get_field(pbuf, lcwat_idx,   lcwat,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     620           0 :   call pbuf_get_field(pbuf, iccwat_idx,  iccwat,  start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     621           0 :   call pbuf_get_field(pbuf, nlwat_idx,   nlwat,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     622           0 :   call pbuf_get_field(pbuf, niwat_idx,   niwat,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     623             : 
     624           0 :   call pbuf_get_field(pbuf, cc_t_idx,    cc_t,    start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     625           0 :   call pbuf_get_field(pbuf, cc_qv_idx,   cc_qv,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     626           0 :   call pbuf_get_field(pbuf, cc_ql_idx,   cc_ql,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     627           0 :   call pbuf_get_field(pbuf, cc_qi_idx,   cc_qi,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     628           0 :   call pbuf_get_field(pbuf, cc_nl_idx,   cc_nl,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     629           0 :   call pbuf_get_field(pbuf, cc_ni_idx,   cc_ni,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     630           0 :   call pbuf_get_field(pbuf, cc_qlst_idx, cc_qlst, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     631             : 
     632           0 :   call pbuf_get_field(pbuf, cld_idx,     cld,    start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     633           0 :   call pbuf_get_field(pbuf, concld_idx,  concld, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     634           0 :   call pbuf_get_field(pbuf, ast_idx,     ast,    start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     635           0 :   call pbuf_get_field(pbuf, aist_idx,    aist,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     636           0 :   call pbuf_get_field(pbuf, alst_idx,    alst,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     637           0 :   call pbuf_get_field(pbuf, qist_idx,    qist,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     638           0 :   call pbuf_get_field(pbuf, qlst_idx,    qlst,   start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
     639             : 
     640           0 :   call pbuf_get_field(pbuf, cmeliq_idx,  cmeliq)
     641             : 
     642             : ! For purposes of convective ql.
     643             : 
     644           0 :   call pbuf_get_field(pbuf, fice_idx,     fice_ql )
     645             : 
     646           0 :   call pbuf_get_field(pbuf, cmfmc_sh_idx, cmfmc_sh)
     647             : 
     648             :   ! check that qcwat and tcwat were initialized; if not then do it now.
     649           0 :   if (qcwat(1,1) == huge(1._r8)) then
     650           0 :      qcwat(:ncol,:) = state%q(:ncol,:,1)
     651             :   end if
     652           0 :   if (tcwat(1,1) == huge(1._r8)) then
     653           0 :      tcwat(:ncol,:) = state%t(:ncol,:)
     654             :   end if
     655             : 
     656             :   ! Initialize convective detrainment tendency
     657             : 
     658           0 :   dlf_T(:,:)  = 0._r8
     659           0 :   dlf_qv(:,:) = 0._r8
     660           0 :   dlf_ql(:,:) = 0._r8
     661           0 :   dlf_qi(:,:) = 0._r8
     662           0 :   dlf_nl(:,:) = 0._r8
     663           0 :   dlf_ni(:,:) = 0._r8
     664             : 
     665             :    ! ------------------------------------- !
     666             :    ! From here, process computation begins !
     667             :    ! ------------------------------------- !
     668             : 
     669             :    ! ----------------------------------------------------------------------------- !
     670             :    ! Detrainment of convective condensate into the environment or stratiform cloud !
     671             :    ! ----------------------------------------------------------------------------- !
     672             : 
     673           0 :    lq(:)        = .FALSE.
     674           0 :    lq(ixcldliq) = .TRUE.
     675           0 :    lq(ixcldice) = .TRUE.
     676           0 :    lq(ixnumliq) = .TRUE.
     677           0 :    lq(ixnumice) = .TRUE.
     678           0 :    call physics_ptend_init(ptend_loc, state%psetcols, 'pcwdetrain', ls=.true., lq=lq)   ! Initialize local physics_ptend object
     679             : 
     680             :      ! Procedures :
     681             :      ! (1) Partition detrained convective cloud water into liquid and ice based on T.
     682             :      !     This also involves heating.
     683             :      !     If convection scheme can handle this internally, this step is not necssary.
     684             :      ! (2) Assuming a certain effective droplet radius, computes number concentration
     685             :      !     of detrained convective cloud liquid and ice.
     686             :      ! (3) If 'cu_det_st = .true' ('false'), detrain convective cloud 'liquid' into
     687             :      !     the pre-existing 'liquid' stratus ( mean environment ).  The former does
     688             :      !     not involve any macrophysical evaporation while the latter does. This is
     689             :      !     a kind of 'targetted' deposition. Then, force in-stratus LWC to be bounded
     690             :      !     by qcst_min and qcst_max in mmacro_pcond.
     691             :      ! (4) In contrast to liquid, convective ice is detrained into the environment
     692             :      !     and involved in the sublimation. Similar bounds as liquid stratus are imposed.
     693             :      ! This is the key procesure generating upper-level cirrus clouds.
     694             :      ! The unit of dlf : [ kg/kg/s ]
     695             : 
     696           0 :    det_s(:)   = 0._r8
     697           0 :    det_ice(:) = 0._r8
     698             : 
     699           0 :    dpdlfliq = 0._r8
     700           0 :    dpdlfice = 0._r8
     701           0 :    shdlfliq = 0._r8
     702           0 :    shdlfice = 0._r8
     703           0 :    dpdlft   = 0._r8
     704           0 :    shdlft   = 0._r8
     705             : 
     706           0 :    do k = top_lev, pver
     707           0 :    do i = 1, state_loc%ncol
     708           0 :       if( state_loc%t(i,k) > 268.15_r8 ) then
     709             :           dum1 = 0.0_r8
     710           0 :       elseif( state_loc%t(i,k) < 238.15_r8 ) then
     711             :           dum1 = 1.0_r8
     712             :       else
     713           0 :           dum1 = ( 268.15_r8 - state_loc%t(i,k) ) / 30._r8
     714             :       endif
     715             : 
     716             :      ! If detrainment was done elsewhere, still update the variables used for output
     717             :      ! assuming that the temperature split between liquid and ice is the same as assumed
     718             :      ! here.
     719           0 :      if (do_detrain) then
     720           0 :         ptend_loc%q(i,k,ixcldliq) = dlf(i,k) * ( 1._r8 - dum1 )
     721           0 :         ptend_loc%q(i,k,ixcldice) = dlf(i,k) * dum1
     722             :       ! dum2                      = dlf(i,k) * ( 1._r8 - dum1 )
     723           0 :         ptend_loc%q(i,k,ixnumliq) = 3._r8 * ( max(0._r8, ( dlf(i,k) - dlf2(i,k) )) * ( 1._r8 - dum1 ) ) / &
     724             :              (4._r8*3.14_r8* 8.e-6_r8**3*997._r8) + & ! Deep    Convection
     725             :              3._r8 * (                         dlf2(i,k)    * ( 1._r8 - dum1 ) ) / &
     726           0 :              (4._r8*3.14_r8*10.e-6_r8**3*997._r8)     ! Shallow Convection
     727             :       ! dum2                      = dlf(i,k) * dum1
     728           0 :         ptend_loc%q(i,k,ixnumice) = 3._r8 * ( max(0._r8, ( dlf(i,k) - dlf2(i,k) )) *  dum1 ) / &
     729             :              (4._r8*3.14_r8*25.e-6_r8**3*500._r8) + & ! Deep    Convection
     730             :              3._r8 * (                         dlf2(i,k)    *  dum1 ) / &
     731           0 :              (4._r8*3.14_r8*50.e-6_r8**3*500._r8)     ! Shallow Convection
     732           0 :         ptend_loc%s(i,k)          = dlf(i,k) * dum1 * latice
     733             :        else
     734           0 :           ptend_loc%q(i,k,ixcldliq) = 0._r8
     735           0 :           ptend_loc%q(i,k,ixcldice) = 0._r8
     736           0 :           ptend_loc%q(i,k,ixnumliq) = 0._r8
     737           0 :           ptend_loc%q(i,k,ixnumice) = 0._r8
     738           0 :           ptend_loc%s(i,k)          = 0._r8
     739             :      end if
     740             : 
     741             :      ! Only rliq is saved from deep convection, which is the reserved liquid.  We need to keep
     742             :      !   track of the integrals of ice and static energy that is effected from conversion to ice
     743             :      !   so that the energy checker doesn't complain.
     744           0 :        det_s(i)                  = det_s(i) + ptend_loc%s(i,k)*state_loc%pdel(i,k)/gravit
     745           0 :        det_ice(i)                = det_ice(i) - ptend_loc%q(i,k,ixcldice)*state_loc%pdel(i,k)/gravit
     746             : 
     747             :      ! Targetted detrainment of convective liquid water either directly into the
     748             :      ! existing liquid stratus or into the environment.
     749           0 :       if( cu_det_st ) then
     750             :           dlf_T(i,k)  = ptend_loc%s(i,k)/cpair
     751             :           dlf_qv(i,k) = 0._r8
     752             :           dlf_ql(i,k) = ptend_loc%q(i,k,ixcldliq)
     753             :           dlf_qi(i,k) = ptend_loc%q(i,k,ixcldice)
     754             :           dlf_nl(i,k) = ptend_loc%q(i,k,ixnumliq)
     755             :           dlf_ni(i,k) = ptend_loc%q(i,k,ixnumice)
     756             :           ptend_loc%q(i,k,ixcldliq) = 0._r8
     757             :           ptend_loc%q(i,k,ixcldice) = 0._r8
     758             :           ptend_loc%q(i,k,ixnumliq) = 0._r8
     759             :           ptend_loc%q(i,k,ixnumice) = 0._r8
     760             :           ptend_loc%s(i,k)          = 0._r8
     761             :           dpdlfliq(i,k)             = 0._r8
     762             :           dpdlfice(i,k)             = 0._r8
     763             :           shdlfliq(i,k)             = 0._r8
     764             :           shdlfice(i,k)             = 0._r8
     765             :           dpdlft  (i,k)             = 0._r8
     766             :           shdlft  (i,k)             = 0._r8
     767             :        else
     768           0 :           dpdlfliq(i,k) = ( dlf(i,k) - dlf2(i,k) ) * ( 1._r8 - dum1 )
     769           0 :           dpdlfice(i,k) = ( dlf(i,k) - dlf2(i,k) ) * ( dum1 )
     770           0 :           dpdlft  (i,k) = ( dlf(i,k) - dlf2(i,k) ) * dum1 * latice/cpair
     771             : 
     772           0 :           shdlfliq(i,k) = dlf2(i,k) * ( 1._r8 - dum1 )
     773           0 :           shdlfice(i,k) = dlf2(i,k) * ( dum1 )
     774           0 :           shdlft  (i,k) = dlf2(i,k) * dum1 * latice/cpair
     775             :       endif
     776             :    end do
     777             :    end do
     778             : 
     779           0 :    call outfld( 'DPDLFLIQ ', dpdlfliq, pcols, lchnk )
     780           0 :    call outfld( 'DPDLFICE ', dpdlfice, pcols, lchnk )
     781           0 :    call outfld( 'SHDLFLIQ ', shdlfliq, pcols, lchnk )
     782           0 :    call outfld( 'SHDLFICE ', shdlfice, pcols, lchnk )
     783           0 :    call outfld( 'DPDLFT   ', dpdlft  , pcols, lchnk )
     784           0 :    call outfld( 'SHDLFT   ', shdlft  , pcols, lchnk )
     785             : 
     786           0 :    call outfld( 'ZMDLF',     dlf     , pcols, state_loc%lchnk )
     787             : 
     788           0 :    det_ice(:ncol) = det_ice(:ncol)/1000._r8  ! divide by density of water
     789             : 
     790             :    ! Add the detrainment tendency to the output tendency
     791           0 :    call physics_ptend_init(ptend, state%psetcols, 'macrop')
     792           0 :    call physics_ptend_sum(ptend_loc, ptend, ncol)
     793             : 
     794             :    ! update local copy of state with the detrainment tendency
     795             :    ! ptend_loc is reset to zero by this call
     796           0 :    call physics_update(state_loc, ptend_loc, dtime)
     797             : 
     798             :    ! -------------------------------------- !
     799             :    ! Computation of Various Cloud Fractions !
     800             :    ! -------------------------------------- !
     801             : 
     802             :    ! ----------------------------------------------------------------------------- !
     803             :    ! Treatment of cloud fraction in CAM4 and CAM5 differs                          !
     804             :    ! (1) CAM4                                                                      !
     805             :    !     . Cumulus AMT = Deep    Cumulus AMT ( empirical fcn of mass flux ) +      !
     806             :    !                     Shallow Cumulus AMT ( empirical fcn of mass flux )        !
     807             :    !     . Stratus AMT = max( RH stratus AMT, Stability Stratus AMT )              !
     808             :    !     . Cumulus and Stratus are 'minimally' overlapped without hierarchy.       !
     809             :    !     . Cumulus LWC,IWC is assumed to be the same as Stratus LWC,IWC            !
     810             :    ! (2) CAM5                                                                      !
     811             :    !     . Cumulus AMT = Deep    Cumulus AMT ( empirical fcn of mass flux ) +      !
     812             :    !                     Shallow Cumulus AMT ( internally fcn of mass flux and w ) !
     813             :    !     . Stratus AMT = fcn of environmental-mean RH ( no Stability Stratus )     !
     814             :    !     . Cumulus and Stratus are non-overlapped with higher priority on Cumulus  !
     815             :    !     . Cumulus ( both Deep and Shallow ) has its own LWC and IWC.              !
     816             :    ! ----------------------------------------------------------------------------- !
     817             : 
     818           0 :    concld_old(:ncol,top_lev:pver) = concld(:ncol,top_lev:pver)
     819             : 
     820           0 :    nullify(tke, qtl_flx, qti_flx, cmfr_det, qlr_det, qir_det)
     821           0 :    if (tke_idx      > 0) call pbuf_get_field(pbuf, tke_idx, tke)
     822           0 :    if (qtl_flx_idx  > 0) call pbuf_get_field(pbuf, qtl_flx_idx,  qtl_flx)
     823           0 :    if (qti_flx_idx  > 0) call pbuf_get_field(pbuf, qti_flx_idx,  qti_flx)
     824           0 :    if (cmfr_det_idx > 0) call pbuf_get_field(pbuf, cmfr_det_idx, cmfr_det)
     825           0 :    if (qlr_det_idx  > 0) call pbuf_get_field(pbuf, qlr_det_idx,  qlr_det)
     826           0 :    if (qir_det_idx  > 0) call pbuf_get_field(pbuf, qir_det_idx,  qir_det)
     827             : 
     828           0 :    clrw_old(:ncol,:top_lev-1) = 0._r8
     829           0 :    clri_old(:ncol,:top_lev-1) = 0._r8
     830           0 :    do k = top_lev, pver
     831           0 :       do i = 1, ncol
     832           0 :          clrw_old(i,k) = max( 0._r8, min( 1._r8, 1._r8 - concld(i,k) - alst(i,k) ) )
     833           0 :          clri_old(i,k) = max( 0._r8, min( 1._r8, 1._r8 - concld(i,k) -  ast(i,k) ) )
     834             :       end do
     835             :    end do
     836             : 
     837           0 :    if( use_shfrc ) then
     838           0 :        call pbuf_get_field(pbuf, shfrc_idx, shfrc )
     839             :    else
     840           0 :        allocate(shfrc(pcols,pver))
     841           0 :        shfrc(:,:) = 0._r8
     842             :    endif
     843             : 
     844             :    ! CAM5 only uses 'concld' output from the below subroutine.
     845             :    ! Stratus ('ast' = max(alst,aist)) and total cloud fraction ('cld = ast + concld')
     846             :    ! will be computed using this updated 'concld' in the stratiform macrophysics
     847             :    ! scheme (mmacro_pcond) later below.
     848             : 
     849           0 :    call t_startf("cldfrc")
     850             : 
     851             :    call cldfrc( lchnk, ncol, pbuf,                                                 &
     852             :                 state_loc%pmid, state_loc%t, state_loc%q(:,:,1), state_loc%omega,  &
     853             :                 state_loc%phis, shfrc, use_shfrc,                                  &
     854             :                 cld, rhcloud, clc, state_loc%pdel,                                 &
     855             :                 cmfmc, cmfmc_sh, landfrac,snowh, concld, cldst,                    &
     856             :                 ts, sst, state_loc%pint(:,pverp), zdu, ocnfrac, rhu00,             &
     857             :                 state_loc%q(:,:,ixcldice), icecldf, liqcldf,                       &
     858           0 :                 relhum, 0 )
     859             : 
     860           0 :    call t_stopf("cldfrc")
     861             : 
     862             :    ! ---------------------------------------------- !
     863             :    ! Stratiform Cloud Macrophysics and Microphysics !
     864             :    ! ---------------------------------------------- !
     865             : 
     866           0 :    lchnk  = state_loc%lchnk
     867           0 :    ncol   = state_loc%ncol
     868           0 :    rdtime = 1._r8/dtime
     869             : 
     870             :  ! Define fractional amount of stratus condensate and precipitation in ice phase.
     871             :  ! This uses a ramp ( -30 ~ -10 for fice, -5 ~ 0 for fsnow ).
     872             :  ! The ramp within convective cloud may be different
     873             : 
     874             : !REMOVECAM - no longer need these when CAM is retired and pcols no longer exists
     875           0 :    fice(:,:) = 0._r8
     876           0 :    fsnow(:,:) = 0._r8
     877             : !REMOVECAM_END
     878             : 
     879           0 :    call cloud_fraction_fice_run(ncol, state_loc%t(:ncol,:), tmelt, top_lev, pver, fice(:ncol,:), fsnow(:ncol,:), errmsg, errflg)
     880             : 
     881           0 :    lq(:)        = .FALSE.
     882             : 
     883           0 :    lq(1)        = .true.
     884           0 :    lq(ixcldice) = .true.
     885           0 :    lq(ixcldliq) = .true.
     886             : 
     887           0 :    lq(ixnumliq) = .true.
     888           0 :    lq(ixnumice) = .true.
     889             : 
     890             :    ! Initialize local physics_ptend object again
     891             :    call physics_ptend_init(ptend_loc, state%psetcols, 'macro_park', &
     892           0 :         ls=.true., lq=lq )
     893             : 
     894             :  ! --------------------------------- !
     895             :  ! Liquid Macrop_Driver Macrophysics !
     896             :  ! --------------------------------- !
     897             : 
     898           0 :    call t_startf('mmacro_pcond')
     899             : 
     900           0 :    zeros(:ncol,top_lev:pver)  = 0._r8
     901           0 :    qc(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,ixcldliq)
     902           0 :    qi(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,ixcldice)
     903           0 :    nc(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,ixnumliq)
     904           0 :    ni(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,ixnumice)
     905             : 
     906             :  ! In CAM5, 'microphysical forcing' ( CC_... ) and 'the other advective forcings' ( ttend, ... )
     907             :  ! are separately provided into the prognostic microp_driver macrophysics scheme. This is an
     908             :  ! attempt to resolve in-cloud and out-cloud forcings.
     909             : 
     910           0 :    if( get_nstep() .le. 1 ) then
     911           0 :        tcwat(:ncol,top_lev:pver)   = state_loc%t(:ncol,top_lev:pver)
     912           0 :        qcwat(:ncol,top_lev:pver)   = state_loc%q(:ncol,top_lev:pver,1)
     913           0 :        lcwat(:ncol,top_lev:pver)   = qc(:ncol,top_lev:pver) + qi(:ncol,top_lev:pver)
     914           0 :        iccwat(:ncol,top_lev:pver)  = qi(:ncol,top_lev:pver)
     915           0 :        nlwat(:ncol,top_lev:pver)   = nc(:ncol,top_lev:pver)
     916           0 :        niwat(:ncol,top_lev:pver)   = ni(:ncol,top_lev:pver)
     917           0 :        ttend(:ncol,:)   = 0._r8
     918           0 :        qtend(:ncol,:)   = 0._r8
     919           0 :        ltend(:ncol,:)   = 0._r8
     920           0 :        itend(:ncol,:)   = 0._r8
     921           0 :        nltend(:ncol,:)  = 0._r8
     922           0 :        nitend(:ncol,:)  = 0._r8
     923           0 :        CC_T(:ncol,:)    = 0._r8
     924           0 :        CC_qv(:ncol,:)   = 0._r8
     925           0 :        CC_ql(:ncol,:)   = 0._r8
     926           0 :        CC_qi(:ncol,:)   = 0._r8
     927           0 :        CC_nl(:ncol,:)   = 0._r8
     928           0 :        CC_ni(:ncol,:)   = 0._r8
     929           0 :        CC_qlst(:ncol,:) = 0._r8
     930             :    else
     931           0 :        ttend(:ncol,top_lev:pver)   = ( state_loc%t(:ncol,top_lev:pver)   -  tcwat(:ncol,top_lev:pver)) * rdtime &
     932           0 :             - CC_T(:ncol,top_lev:pver)
     933           0 :        qtend(:ncol,top_lev:pver)   = ( state_loc%q(:ncol,top_lev:pver,1) -  qcwat(:ncol,top_lev:pver)) * rdtime &
     934           0 :             - CC_qv(:ncol,top_lev:pver)
     935           0 :        ltend(:ncol,top_lev:pver)   = ( qc(:ncol,top_lev:pver) + qi(:ncol,top_lev:pver) - lcwat(:ncol,top_lev:pver) ) * rdtime &
     936           0 :             - (CC_ql(:ncol,top_lev:pver) + CC_qi(:ncol,top_lev:pver))
     937           0 :        itend(:ncol,top_lev:pver)   = ( qi(:ncol,top_lev:pver)         - iccwat(:ncol,top_lev:pver)) * rdtime &
     938           0 :             - CC_qi(:ncol,top_lev:pver)
     939           0 :        nltend(:ncol,top_lev:pver)  = ( nc(:ncol,top_lev:pver)         -  nlwat(:ncol,top_lev:pver)) * rdtime &
     940           0 :             - CC_nl(:ncol,top_lev:pver)
     941           0 :        nitend(:ncol,top_lev:pver)  = ( ni(:ncol,top_lev:pver)         -  niwat(:ncol,top_lev:pver)) * rdtime &
     942           0 :             - CC_ni(:ncol,top_lev:pver)
     943             :    endif
     944           0 :    lmitend(:ncol,top_lev:pver) = ltend(:ncol,top_lev:pver) - itend(:ncol,top_lev:pver)
     945             : 
     946           0 :    t_inout(:ncol,top_lev:pver)  =  tcwat(:ncol,top_lev:pver)
     947           0 :    qv_inout(:ncol,top_lev:pver) =  qcwat(:ncol,top_lev:pver)
     948           0 :    ql_inout(:ncol,top_lev:pver) =  lcwat(:ncol,top_lev:pver) - iccwat(:ncol,top_lev:pver)
     949           0 :    qi_inout(:ncol,top_lev:pver) = iccwat(:ncol,top_lev:pver)
     950           0 :    nl_inout(:ncol,top_lev:pver) =  nlwat(:ncol,top_lev:pver)
     951           0 :    ni_inout(:ncol,top_lev:pver) =  niwat(:ncol,top_lev:pver)
     952             : 
     953             :  ! Liquid Microp_Driver Macrophysics.
     954             :  ! The main roles of this subroutines are
     955             :  ! (1) compute net condensation rate of stratiform liquid ( cmeliq )
     956             :  ! (2) compute liquid stratus and ice stratus fractions.
     957             :  ! Note 'ttend...' are advective tendencies except microphysical process while
     958             :  !      'CC...'    are microphysical tendencies.
     959             : 
     960             :    call mmacro_pcond( lchnk, ncol, dtime, state_loc%pmid, state_loc%pdel,        &
     961             :                       t_inout, qv_inout, ql_inout, qi_inout, nl_inout, ni_inout, &
     962             :                       ttend, qtend, lmitend, itend, nltend, nitend,              &
     963             :                       CC_T, CC_qv, CC_ql, CC_qi, CC_nl, CC_ni, CC_qlst,          &
     964             :                       dlf_T, dlf_qv, dlf_ql, dlf_qi, dlf_nl, dlf_ni,             &
     965             :                       concld_old, concld, clrw_old, clri_old, landfrac, snowh,   &
     966             :                       tke, qtl_flx, qti_flx, cmfr_det, qlr_det, qir_det,         &
     967             :                       tlat, qvlat, qcten, qiten, ncten, niten,                   &
     968             :                       cmeliq, qvadj, qladj, qiadj, qllim, qilim,                 &
     969           0 :                       cld, alst, aist, qlst, qist, do_cldice )
     970             : 
     971             :  ! Copy of concld/fice to put in physics buffer
     972             :  ! Below are used only for convective cloud.
     973             : 
     974           0 :    fice_ql(:ncol,:top_lev-1)     = 0._r8
     975           0 :    fice_ql(:ncol,top_lev:pver)   = fice(:ncol,top_lev:pver)
     976             : 
     977             : 
     978             :  ! Compute net stratus fraction using maximum over-lapping assumption
     979           0 :    ast(:ncol,:top_lev-1) = 0._r8
     980           0 :    ast(:ncol,top_lev:pver) = max( alst(:ncol,top_lev:pver), aist(:ncol,top_lev:pver) )
     981             : 
     982           0 :    call t_stopf('mmacro_pcond')
     983             : 
     984           0 :    do k = top_lev, pver
     985           0 :       do i = 1, ncol
     986           0 :          ptend_loc%s(i,k)          =  tlat(i,k)
     987           0 :          ptend_loc%q(i,k,1)        = qvlat(i,k)
     988           0 :          ptend_loc%q(i,k,ixcldliq) = qcten(i,k)
     989           0 :          ptend_loc%q(i,k,ixcldice) = qiten(i,k)
     990           0 :          ptend_loc%q(i,k,ixnumliq) = ncten(i,k)
     991           0 :          ptend_loc%q(i,k,ixnumice) = niten(i,k)
     992             : 
     993             :          ! Check to make sure that the macrophysics code is respecting the flags that control
     994             :          ! whether cldwat should be prognosing cloud ice and cloud liquid or not.
     995           0 :          if ((.not. do_cldice) .and. (qiten(i,k) /= 0.0_r8)) then
     996             :             call endrun("macrop_driver:ERROR - "// &
     997           0 :                  "Cldwat is configured not to prognose cloud ice, but mmacro_pcond has ice mass tendencies.")
     998             :          end if
     999           0 :          if ((.not. do_cldice) .and. (niten(i,k) /= 0.0_r8)) then
    1000             :             call endrun("macrop_driver:ERROR -"// &
    1001           0 :                  " Cldwat is configured not to prognose cloud ice, but mmacro_pcond has ice number tendencies.")
    1002             :          end if
    1003             : 
    1004           0 :          if ((.not. do_cldliq) .and. (qcten(i,k) /= 0.0_r8)) then
    1005             :             call endrun("macrop_driver:ERROR - "// &
    1006           0 :                  "Cldwat is configured not to prognose cloud liquid, but mmacro_pcond has liquid mass tendencies.")
    1007             :          end if
    1008           0 :          if ((.not. do_cldliq) .and. (ncten(i,k) /= 0.0_r8)) then
    1009             :             call endrun("macrop_driver:ERROR - "// &
    1010           0 :                  "Cldwat is configured not to prognose cloud liquid, but mmacro_pcond has liquid number tendencies.")
    1011             :          end if
    1012             :       end do
    1013             :    end do
    1014             : 
    1015             :    ! update the output tendencies with the mmacro_pcond tendencies
    1016           0 :    call physics_ptend_sum(ptend_loc, ptend, ncol)
    1017             : 
    1018             :    ! state_loc is the equlibrium state after macrophysics
    1019           0 :    call physics_update(state_loc, ptend_loc, dtime)
    1020             : 
    1021           0 :    call outfld('CLR_LIQ', clrw_old,  pcols, lchnk)
    1022           0 :    call outfld('CLR_ICE', clri_old,  pcols, lchnk)
    1023             : 
    1024           0 :    call outfld( 'MACPDT   ', tlat ,  pcols, lchnk )
    1025           0 :    call outfld( 'MACPDQ   ', qvlat,  pcols, lchnk )
    1026           0 :    call outfld( 'MACPDLIQ ', qcten,  pcols, lchnk )
    1027           0 :    call outfld( 'MACPDICE ', qiten,  pcols, lchnk )
    1028           0 :    call outfld( 'CLDVAPADJ', qvadj,  pcols, lchnk )
    1029           0 :    call outfld( 'CLDLIQADJ', qladj,  pcols, lchnk )
    1030           0 :    call outfld( 'CLDICEADJ', qiadj,  pcols, lchnk )
    1031           0 :    call outfld( 'CLDLIQDET', dlf_ql, pcols, lchnk )
    1032           0 :    call outfld( 'CLDICEDET', dlf_qi, pcols, lchnk )
    1033           0 :    call outfld( 'CLDLIQLIM', qllim,  pcols, lchnk )
    1034           0 :    call outfld( 'CLDICELIM', qilim,  pcols, lchnk )
    1035             : 
    1036           0 :    call outfld( 'ICECLDF ', aist,   pcols, lchnk )
    1037           0 :    call outfld( 'LIQCLDF ', alst,   pcols, lchnk )
    1038           0 :    call outfld( 'AST',      ast,    pcols, lchnk )
    1039             : 
    1040           0 :    call outfld( 'CONCLD  ', concld, pcols, lchnk )
    1041           0 :    call outfld( 'CLDST   ', cldst,  pcols, lchnk )
    1042             : 
    1043           0 :    call outfld( 'CMELIQ'  , cmeliq, pcols, lchnk )
    1044             : 
    1045             : 
    1046             :    ! calculations and outfld calls for CLDLIQSTR, CLDICESTR, CLDLIQCON, CLDICECON for CFMIP
    1047             : 
    1048             :    ! initialize local variables
    1049           0 :    mr_ccliq = 0._r8   !! not seen by radiation, so setting to 0
    1050           0 :    mr_ccice = 0._r8   !! not seen by radiation, so setting to 0
    1051           0 :    mr_lsliq = 0._r8
    1052           0 :    mr_lsice = 0._r8
    1053             : 
    1054           0 :    do k=top_lev,pver
    1055           0 :       do i=1,ncol
    1056           0 :          if (cld(i,k) .gt. 0._r8) then
    1057           0 :             mr_lsliq(i,k) = state_loc%q(i,k,ixcldliq)
    1058           0 :             mr_lsice(i,k) = state_loc%q(i,k,ixcldice)
    1059             :          else
    1060           0 :             mr_lsliq(i,k) = 0._r8
    1061           0 :             mr_lsice(i,k) = 0._r8
    1062             :          end if
    1063             :       end do
    1064             :    end do
    1065             : 
    1066           0 :    call outfld( 'CLDLIQSTR  ', mr_lsliq,    pcols, lchnk )
    1067           0 :    call outfld( 'CLDICESTR  ', mr_lsice,    pcols, lchnk )
    1068           0 :    call outfld( 'CLDLIQCON  ', mr_ccliq,    pcols, lchnk )
    1069           0 :    call outfld( 'CLDICECON  ', mr_ccice,    pcols, lchnk )
    1070             : 
    1071             :    ! ------------------------------------------------- !
    1072             :    ! Save equilibrium state variables for macrophysics !
    1073             :    ! at the next time step                             !
    1074             :    ! ------------------------------------------------- !
    1075           0 :    cldsice = 0._r8
    1076           0 :    do k = top_lev, pver
    1077           0 :       tcwat(:ncol,k)  = state_loc%t(:ncol,k)
    1078           0 :       qcwat(:ncol,k)  = state_loc%q(:ncol,k,1)
    1079           0 :       lcwat(:ncol,k)  = state_loc%q(:ncol,k,ixcldliq) + state_loc%q(:ncol,k,ixcldice)
    1080           0 :       iccwat(:ncol,k) = state_loc%q(:ncol,k,ixcldice)
    1081           0 :       nlwat(:ncol,k)  = state_loc%q(:ncol,k,ixnumliq)
    1082           0 :       niwat(:ncol,k)  = state_loc%q(:ncol,k,ixnumice)
    1083           0 :       cldsice(:ncol,k) = lcwat(:ncol,k) * min(1.0_r8, max(0.0_r8, (tmelt - tcwat(:ncol,k)) / 20._r8))
    1084             :    end do
    1085             : 
    1086           0 :    call outfld( 'CLDSICE'    , cldsice,   pcols, lchnk )
    1087             : 
    1088             :    ! ptend_loc is deallocated in physics_update above
    1089           0 :    call physics_state_dealloc(state_loc)
    1090             : 
    1091           0 : end subroutine macrop_driver_tend
    1092             : 
    1093             : 
    1094             : ! Saturation adjustment for liquid
    1095             : !
    1096             : ! With CLUBB, we are seeing relative humidity with respect to water
    1097             : ! greater than 1. This should not be happening and is not what the
    1098             : ! microphsyics expects from the macrophysics. As a work around while
    1099             : ! this issue is investigated in CLUBB, this routine will enfornce a
    1100             : ! maximum RHliq of 1 everywhere in the atmosphere. Any excess water will
    1101             : ! be converted into cloud drops.
    1102           0 : subroutine liquid_macro_tend(npccn,t,p,qv,qc,nc,xxlv,deltat,stend,qvtend,qctend,nctend,vlen)
    1103             : 
    1104           0 :   use wv_sat_methods, only: wv_sat_qsat_ice_vect, wv_sat_qsat_water_vect
    1105             :   use micro_pumas_utils, only: rhow
    1106             :   use physconst,      only: rair
    1107             :   use cldfrc2m,       only: rhmini_const, rhmaxi_const
    1108             : 
    1109             :   integer,                   intent(in)  :: vlen
    1110             :   real(r8), dimension(vlen), intent(in)  :: npccn  !Activated number of cloud condensation nuclei
    1111             :   real(r8), dimension(vlen), intent(in)  :: t      !temperature (k)
    1112             :   real(r8), dimension(vlen), intent(in)  :: p      !pressure (pa)
    1113             :   real(r8), dimension(vlen), intent(in)  :: qv     !water vapor mixing ratio
    1114             :   real(r8), dimension(vlen), intent(in)  :: qc     !liquid mixing ratio
    1115             :   real(r8), dimension(vlen), intent(in)  :: nc     !liquid number concentration
    1116             :   real(r8),                  intent(in)  :: xxlv   !latent heat of vaporization
    1117             :   real(r8),                  intent(in)  :: deltat !timestep
    1118             :   real(r8), dimension(vlen), intent(out) :: stend  ! 'temperature' tendency
    1119             :   real(r8), dimension(vlen), intent(out) :: qvtend !vapor tendency
    1120             :   real(r8), dimension(vlen), intent(out) :: qctend !liquid mass tendency
    1121             :   real(r8), dimension(vlen), intent(out) :: nctend !liquid number tendency
    1122             : 
    1123           0 :   real(r8) :: ESL(vlen)
    1124           0 :   real(r8) :: QSL(vlen)
    1125             :   real(r8) :: drop_size_param
    1126             :   integer  :: i
    1127             : 
    1128           0 :   drop_size_param = 3._r8/(4._r8*3.14_r8*6.e-6_r8**3*rhow)
    1129             : 
    1130           0 :   do i = 1, vlen
    1131           0 :      stend(i) = 0._r8
    1132           0 :      qvtend(i) = 0._r8
    1133           0 :      qctend(i) = 0._r8
    1134           0 :      nctend(i) = 0._r8
    1135             :   end do
    1136             : 
    1137             :   ! calculate qsatl from t,p,q
    1138             :   !$acc data copyin(t,p) copyout(ESL,QSL)
    1139           0 :   call wv_sat_qsat_water_vect(t, p, ESL, QSL, vlen)
    1140             :   !$acc end data
    1141             : 
    1142           0 :   do i = 1, vlen
    1143             :      ! Don't allow supersaturation with respect to liquid.
    1144           0 :      if (qv(i) > QSL(i)) then
    1145             : 
    1146           0 :         qctend(i) = (qv(i) - QSL(i)) / deltat
    1147           0 :         qvtend(i) = 0._r8 - qctend(i)
    1148           0 :         stend(i)  = qctend(i) * xxlv    ! moist static energy tend...[J/kg/s] !
    1149             : 
    1150             :         ! If drops  exists (more than 1 L-1) and there is condensation,
    1151             :         ! do not add to number (= growth), otherwise  add 6um drops.
    1152             :         !
    1153             :         ! This is somewhat arbitrary, but ensures that some reasonable droplet
    1154             :         ! size is created to remove the excess water. This could be enhanced to
    1155             :         ! look at npccn, but ideally this entire routine should go away.
    1156           0 :         if ((nc(i)*p(i)/rair/t(i) < 1e3_r8) .and. (qc(i)+qctend(i)*deltat > 1e-18_r8)) then
    1157           0 :            nctend(i) = nctend(i) + qctend(i)*drop_size_param
    1158             :         end if
    1159             :      end if
    1160             :   end do
    1161             : 
    1162           0 : end subroutine liquid_macro_tend
    1163             : 
    1164             : end module macrop_driver

Generated by: LCOV version 1.14