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

Generated by: LCOV version 1.14