LCOV - code coverage report
Current view: top level - physics/cam - nucleate_ice_cam.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 270 382 70.7 %
Date: 2025-03-13 18:42:46 Functions: 4 4 100.0 %

          Line data    Source code
       1             : module nucleate_ice_cam
       2             : 
       3             : !---------------------------------------------------------------------------------
       4             : !
       5             : !  CAM Interfaces for nucleate_ice module.
       6             : !
       7             : !  B. Eaton - Sept 2014
       8             : !---------------------------------------------------------------------------------
       9             : 
      10             : use shr_kind_mod,   only: r8=>shr_kind_r8
      11             : use spmd_utils,     only: masterproc
      12             : use ppgrid,         only: pcols, pver
      13             : use physconst,      only: pi, rair, tmelt
      14             : use constituents,   only: pcnst, cnst_get_ind
      15             : use physics_types,  only: physics_state, physics_ptend, physics_ptend_init
      16             : use physics_buffer, only: physics_buffer_desc
      17             : use phys_control,   only: use_hetfrz_classnuc
      18             : use rad_constituents, only: rad_cnst_get_info, rad_cnst_get_aer_mmr, rad_cnst_get_aer_props
      19             : 
      20             : use physics_buffer, only: pbuf_add_field, dtype_r8, pbuf_old_tim_idx, &
      21             :                           pbuf_get_index, pbuf_get_field, &
      22             :                           pbuf_set_field
      23             : use cam_history,    only: addfld, add_default, outfld
      24             : 
      25             : use ref_pres,       only: top_lev => trop_cloud_top_lev
      26             : use wv_saturation,  only: qsat_water
      27             : 
      28             : use cam_logfile,    only: iulog
      29             : use cam_abortutils, only: endrun
      30             : 
      31             : use nucleate_ice,   only: nucleati_init, nucleati
      32             : 
      33             : use aerosol_properties_mod, only: aerosol_properties
      34             : use aerosol_state_mod, only: aerosol_state
      35             : 
      36             : use phys_control,   only: cam_physpkg_is
      37             : 
      38             : implicit none
      39             : private
      40             : save
      41             : 
      42             : public :: &
      43             :    nucleate_ice_cam_readnl,   &
      44             :    nucleate_ice_cam_register, &
      45             :    nucleate_ice_cam_init,     &
      46             :    nucleate_ice_cam_calc
      47             : 
      48             : ! Namelist variables
      49             : logical, public, protected :: use_preexisting_ice = .false.
      50             : logical                    :: hist_preexisting_ice = .false.
      51             : logical                    :: nucleate_ice_incloud = .false.
      52             : logical                    :: nucleate_ice_use_troplev = .false.
      53             : real(r8)                   :: nucleate_ice_subgrid = -1._r8
      54             : real(r8)                   :: nucleate_ice_subgrid_strat = -1._r8
      55             : real(r8)                   :: nucleate_ice_strat = 0.0_r8
      56             : 
      57             : ! Vars set via init method.
      58             : real(r8) :: mincld      ! minimum allowed cloud fraction
      59             : real(r8) :: bulk_scale  ! prescribed aerosol bulk sulfur scale factor
      60             : 
      61             : ! constituent indices
      62             : integer :: &
      63             :    cldliq_idx = -1, &
      64             :    cldice_idx = -1, &
      65             :    numice_idx = -1
      66             : 
      67             : integer :: &
      68             :    naai_idx = -1,     &
      69             :    naai_hom_idx = -1
      70             : 
      71             : integer :: &
      72             :    ast_idx   = -1
      73             : 
      74             : integer :: &
      75             :     qsatfac_idx = -1
      76             : 
      77             : ! Bulk aerosols
      78             : character(len=20), allocatable :: aername(:)
      79             : real(r8), allocatable :: num_to_mass_aer(:)
      80             : 
      81             : integer :: naer_all = -1 ! number of aerosols affecting climate
      82             : integer :: idxsul   = -1 ! index in aerosol list for sulfate
      83             : integer :: idxdst1  = -1 ! index in aerosol list for dust1
      84             : integer :: idxdst2  = -1 ! index in aerosol list for dust2
      85             : integer :: idxdst3  = -1 ! index in aerosol list for dust3
      86             : integer :: idxdst4  = -1 ! index in aerosol list for dust4
      87             : integer :: idxbcphi = -1 ! index in aerosol list for Soot (BCPHIL)
      88             : 
      89             : ! modal aerosols
      90             : logical :: clim_modal_aero = .false.
      91             : logical :: prog_modal_aero = .false.
      92             : 
      93             : logical :: lq(pcnst) = .false. ! set flags true for constituents with non-zero tendencies
      94             : 
      95             : integer, allocatable :: aer_cnst_idx(:,:)
      96             : 
      97             : !===============================================================================
      98             : contains
      99             : !===============================================================================
     100             : 
     101      178008 : subroutine nucleate_ice_cam_readnl(nlfile)
     102             : 
     103             :   use namelist_utils,  only: find_group_name
     104             :   use units,           only: getunit, freeunit
     105             :   use spmd_utils,      only: mpicom, masterprocid, mpi_logical, mpi_real8
     106             : 
     107             :   character(len=*), intent(in) :: nlfile  ! filepath for file containing namelist input
     108             : 
     109             :   ! Local variables
     110             :   integer :: unitn, ierr
     111             :   character(len=*), parameter :: subname = 'nucleate_ice_cam_readnl'
     112             : 
     113             :   namelist /nucleate_ice_nl/ use_preexisting_ice, hist_preexisting_ice, &
     114             :        nucleate_ice_subgrid, nucleate_ice_subgrid_strat, nucleate_ice_strat, &
     115             :        nucleate_ice_incloud, nucleate_ice_use_troplev
     116             : 
     117             :   !-----------------------------------------------------------------------------
     118             : 
     119        1536 :   if (masterproc) then
     120           2 :      unitn = getunit()
     121           2 :      open( unitn, file=trim(nlfile), status='old' )
     122           2 :      call find_group_name(unitn, 'nucleate_ice_nl', status=ierr)
     123           2 :      if (ierr == 0) then
     124           2 :         read(unitn, nucleate_ice_nl, iostat=ierr)
     125           2 :         if (ierr /= 0) then
     126           0 :            call endrun(subname // ':: ERROR reading namelist')
     127             :         end if
     128             :      end if
     129           2 :      close(unitn)
     130           2 :      call freeunit(unitn)
     131             : 
     132             :   end if
     133             : 
     134             :   ! Broadcast namelist variables
     135        1536 :   call mpi_bcast(use_preexisting_ice,  1, mpi_logical,masterprocid, mpicom, ierr)
     136        1536 :   call mpi_bcast(hist_preexisting_ice, 1, mpi_logical,masterprocid, mpicom, ierr)
     137        1536 :   call mpi_bcast(nucleate_ice_subgrid, 1, mpi_real8,  masterprocid, mpicom, ierr)
     138        1536 :   call mpi_bcast(nucleate_ice_subgrid_strat, 1, mpi_real8,  masterprocid, mpicom, ierr)
     139        1536 :   call mpi_bcast(nucleate_ice_strat,   1, mpi_real8,  masterprocid, mpicom, ierr)
     140        1536 :   call mpi_bcast(nucleate_ice_incloud, 1, mpi_logical,masterprocid, mpicom, ierr)
     141        1536 :   call mpi_bcast(nucleate_ice_use_troplev, 1, mpi_logical,masterprocid, mpicom, ierr)
     142             : 
     143        1536 : end subroutine nucleate_ice_cam_readnl
     144             : 
     145             : !================================================================================================
     146             : 
     147        1536 : subroutine nucleate_ice_cam_register()
     148             : 
     149             :    ! global scope for NAAI needed when clubb_do_icesuper=.true.
     150        1536 :    call pbuf_add_field('NAAI',     'global', dtype_r8, (/pcols,pver/), naai_idx)
     151        1536 :    call pbuf_add_field('NAAI_HOM', 'physpkg', dtype_r8, (/pcols,pver/), naai_hom_idx)
     152             : 
     153        1536 : end subroutine nucleate_ice_cam_register
     154             : 
     155             : !================================================================================================
     156             : 
     157        1536 : subroutine nucleate_ice_cam_init(mincld_in, bulk_scale_in, pbuf2d, aero_props)
     158             :    use phys_control, only: phys_getopts
     159             :    use time_manager, only: is_first_step
     160             : 
     161             :    real(r8), intent(in) :: mincld_in
     162             :    real(r8), intent(in) :: bulk_scale_in
     163             :    class(aerosol_properties), optional, intent(in) :: aero_props
     164             : 
     165             :    type(physics_buffer_desc), pointer :: pbuf2d(:,:)
     166             : 
     167             :    ! local variables
     168             :    integer :: iaer
     169             :    integer :: ierr
     170             :    integer :: ispc, ibin
     171             :    integer :: idxtmp
     172             :    integer :: nmodes
     173             : 
     174             :    character(len=*), parameter :: routine = 'nucleate_ice_cam_init'
     175             :    logical :: history_cesm_forcing
     176             : 
     177             :    character(len=32) :: tmpname
     178             : 
     179             :    !--------------------------------------------------------------------------------------------
     180        1536 :    call phys_getopts(prog_modal_aero_out = prog_modal_aero, history_cesm_forcing_out = history_cesm_forcing)
     181             : 
     182        1536 :    mincld     = mincld_in
     183        1536 :    bulk_scale = bulk_scale_in
     184             : 
     185        1536 :    lq(:) = .false.
     186             : 
     187        1536 :    if (prog_modal_aero.and.use_preexisting_ice) then
     188             : 
     189        1536 :       if (.not. present(aero_props)) then
     190           0 :          call endrun(routine//' :  aero_props must be present')
     191             :       end if
     192             : 
     193             :       ! constituent tendencies are calculated only if use_preexisting_ice is TRUE
     194             :       ! set lq for constituent tendencies --
     195             : 
     196       13824 :       allocate(aer_cnst_idx(aero_props%nbins(),0:maxval(aero_props%nspecies())), stat=ierr)
     197        1536 :       if( ierr /= 0 ) then
     198           0 :          call endrun(routine//': aer_cnst_idx allocation failed')
     199             :       end if
     200       55296 :       aer_cnst_idx = -1
     201             : 
     202        9216 :       do ibin = 1, aero_props%nbins()
     203        7680 :          if (aero_props%icenuc_updates_num(ibin)) then
     204             : 
     205             :             ! constituents of this bin will need to be updated
     206             : 
     207        1536 :             if (aero_props%icenuc_updates_mmr(ibin,0)) then ! species 0 indicates bin MMR
     208           0 :                call aero_props%amb_mmr_name( ibin, 0, tmpname)
     209             :             else
     210        1536 :                call aero_props%amb_num_name( ibin, tmpname)
     211             :             end if
     212             : 
     213        1536 :             call cnst_get_ind(tmpname, idxtmp, abort=.false.)
     214        1536 :             aer_cnst_idx(ibin,0) = idxtmp
     215        1536 :             if (idxtmp>0) then
     216        1536 :                lq(idxtmp) = .true.
     217             :             end if
     218             : 
     219             :             ! iterate over the species within the bin
     220        6144 :             do ispc = 1, aero_props%nspecies(ibin)
     221        6144 :                if (aero_props%icenuc_updates_mmr(ibin,ispc)) then
     222             :                   ! this aerosol constituent will be updated
     223        1536 :                   call aero_props%amb_mmr_name( ibin, ispc, tmpname)
     224        1536 :                   call cnst_get_ind(tmpname, idxtmp, abort=.false.)
     225        1536 :                   aer_cnst_idx(ibin,ispc) = idxtmp
     226        1536 :                   if (idxtmp>0) then
     227        1536 :                      lq(idxtmp) = .true.
     228             :                   end if
     229             :                end if
     230             :             end do
     231             : 
     232             :          end if
     233             :       end do
     234             : 
     235             :    end if
     236             : 
     237             :    ! Initialize naai.
     238        1536 :    if (is_first_step()) then
     239         768 :       call pbuf_set_field(pbuf2d, naai_idx, 0.0_r8)
     240             :    end if
     241             : 
     242        1536 :    if( masterproc ) then
     243           2 :       write(iulog,*) 'nucleate_ice parameters:'
     244           2 :       write(iulog,*) '  mincld                     = ', mincld_in
     245           2 :       write(iulog,*) '  bulk_scale                 = ', bulk_scale_in
     246           2 :       write(iulog,*) '  use_preexisiting_ice       = ', use_preexisting_ice
     247           2 :       write(iulog,*) '  hist_preexisiting_ice      = ', hist_preexisting_ice
     248           2 :       write(iulog,*) '  nucleate_ice_subgrid       = ', nucleate_ice_subgrid
     249           2 :       write(iulog,*) '  nucleate_ice_subgrid_strat = ', nucleate_ice_subgrid_strat
     250           2 :       write(iulog,*) '  nucleate_ice_strat         = ', nucleate_ice_strat
     251           2 :       write(iulog,*) '  nucleate_ice_incloud       = ', nucleate_ice_incloud
     252           2 :       write(iulog,*) '  nucleate_ice_use_troplev   = ', nucleate_ice_use_troplev
     253             :    end if
     254             : 
     255        1536 :    call cnst_get_ind('CLDLIQ', cldliq_idx)
     256        1536 :    call cnst_get_ind('CLDICE', cldice_idx)
     257        1536 :    call cnst_get_ind('NUMICE', numice_idx)
     258        1536 :    qsatfac_idx  = pbuf_get_index('QSATFAC', ierr)
     259             : 
     260        1536 :    if (((nucleate_ice_subgrid .eq. -1._r8) .or. (nucleate_ice_subgrid_strat .eq. -1._r8)) .and. (qsatfac_idx .eq. -1)) then
     261           0 :      call endrun(routine//': ERROR qsatfac is required when subgrid = -1 or subgrid_strat = -1')
     262             :    end if
     263             : 
     264        1536 :    if (cam_physpkg_is("cam7")) then
     265             :       ! Updates for PUMAS v1.21+
     266        3072 :       call addfld('NIHFTEN',  (/ 'lev' /), 'A', '1/m3/s', 'Activated Ice Number Concentration tendency due to homogenous freezing')
     267        3072 :       call addfld('NIDEPTEN', (/ 'lev' /), 'A', '1/m3/s', 'Activated Ice Number Concentration tendency due to deposition nucleation')
     268        3072 :       call addfld('NIIMMTEN', (/ 'lev' /), 'A', '1/m3/s', 'Activated Ice Number Concentration tendency due to immersion freezing')
     269        3072 :       call addfld('NIMEYTEN', (/ 'lev' /), 'A', '1/m3/s', 'Activated Ice Number Concentration tendency due to meyers deposition')
     270             :    else
     271           0 :       call addfld('NIHF',  (/ 'lev' /), 'A', '1/m3', 'Activated Ice Number Concentration due to homogenous freezing')
     272           0 :       call addfld('NIDEP', (/ 'lev' /), 'A', '1/m3', 'Activated Ice Number Concentration due to deposition nucleation')
     273           0 :       call addfld('NIIMM', (/ 'lev' /), 'A', '1/m3', 'Activated Ice Number Concentration due to immersion freezing')
     274           0 :       call addfld('NIMEY', (/ 'lev' /), 'A', '1/m3', 'Activated Ice Number Concentration due to meyers deposition')
     275             :    endif
     276             : 
     277        3072 :    call addfld('NIREGM',(/ 'lev' /), 'A', 'C', 'Ice Nucleation Temperature Threshold for Regime')
     278        3072 :    call addfld('NISUBGRID',(/ 'lev' /), 'A', '', 'Ice Nucleation subgrid saturation factor')
     279        3072 :    call addfld('NITROP_PD',(/ 'lev' /), 'A', '', 'Chemical Tropopause probability')
     280        1536 :    if ( history_cesm_forcing ) then
     281           0 :       call add_default('NITROP_PD',8,' ')
     282             :    endif
     283             : 
     284        1536 :    if (use_preexisting_ice) then
     285        3072 :       call addfld('fhom',      (/ 'lev' /), 'A','fraction', 'Fraction of cirrus where homogeneous freezing occur'   )
     286        3072 :       call addfld ('WICE',     (/ 'lev' /), 'A','m/s','Vertical velocity Reduction caused by preexisting ice'  )
     287        3072 :       call addfld ('WEFF',     (/ 'lev' /), 'A','m/s','Effective Vertical velocity for ice nucleation' )
     288             : 
     289        1536 :       if (cam_physpkg_is("cam7")) then
     290             :          ! Updates for PUMAS v1.21+
     291        3072 :          call addfld ('INnso4TEN',   (/ 'lev' /), 'A','1/m3/s','Number Concentration tendency so4 (in) to ice_nucleation')
     292        3072 :          call addfld ('INnbcTEN',    (/ 'lev' /), 'A','1/m3/s','Number Concentration tendency bc  (in) to ice_nucleation')
     293        3072 :          call addfld ('INndustTEN',  (/ 'lev' /), 'A','1/m3/s','Number Concentration tendency dust (in) ice_nucleation')
     294        3072 :          call addfld ('INondustTEN',  (/ 'lev' /), 'A','1/m3/s','Number Concentration tendency dust (out) from ice_nucleation')
     295             :          call addfld ('INhetTEN',    (/ 'lev' /), 'A','1/m3/s', &
     296        3072 :               'Tendency for contribution for in-cloud ice number density increase by het nucleation in ice cloud')
     297             :          call addfld ('INhomTEN',    (/ 'lev' /), 'A','1/m3/s', &
     298        3072 :               'Tendency for contribution for in-cloud ice number density increase by hom nucleation in ice cloud')
     299             :       else
     300           0 :          call addfld ('INnso4',   (/ 'lev' /), 'A','1/m3','Number Concentration so4 (in) to ice_nucleation')
     301           0 :          call addfld ('INnbc',    (/ 'lev' /), 'A','1/m3','Number Concentration bc  (in) to ice_nucleation')
     302           0 :          call addfld ('INndust',  (/ 'lev' /), 'A','1/m3','Number Concentration dust (in) ice_nucleation')
     303           0 :          call addfld ('INondust',  (/ 'lev' /), 'A','1/m3','Number Concentration dust (out) from ice_nucleation')
     304             :          call addfld ('INhet',    (/ 'lev' /), 'A','1/m3', &
     305           0 :               'contribution for in-cloud ice number density increase by het nucleation in ice cloud')
     306             :          call addfld ('INhom',    (/ 'lev' /), 'A','1/m3', &
     307           0 :               'contribution for in-cloud ice number density increase by hom nucleation in ice cloud')
     308             :       endif
     309             : 
     310        3072 :       call addfld ('INFrehom', (/ 'lev' /), 'A','frequency','hom IN frequency ice cloud')
     311        3072 :       call addfld ('INFreIN',  (/ 'lev' /), 'A','frequency','frequency of ice nucleation occur')
     312             : 
     313        1536 :       if (hist_preexisting_ice) then
     314           0 :          call add_default ('WSUBI   ', 1, ' ')  ! addfld/outfld calls are in microp_aero
     315             : 
     316           0 :          call add_default ('fhom    ', 1, ' ')
     317           0 :          call add_default ('WICE    ', 1, ' ')
     318           0 :          call add_default ('WEFF    ', 1, ' ')
     319           0 :          call add_default ('INnso4  ', 1, ' ')
     320           0 :          call add_default ('INnbc   ', 1, ' ')
     321           0 :          call add_default ('INndust ', 1, ' ')
     322           0 :          call add_default ('INhet   ', 1, ' ')
     323           0 :          call add_default ('INhom   ', 1, ' ')
     324           0 :          call add_default ('INFrehom', 1, ' ')
     325           0 :          call add_default ('INFreIN ', 1, ' ')
     326             :       end if
     327             :    end if
     328             : 
     329             :    ! clim_modal_aero determines whether modal aerosols are used in the climate calculation.
     330             :    ! The modal aerosols can be either prognostic or prescribed.
     331        1536 :    call rad_cnst_get_info(0, nmodes=nmodes)
     332             : 
     333        1536 :    clim_modal_aero = (nmodes > 0)
     334             : 
     335        1536 :    if (.not. clim_modal_aero) then
     336             : 
     337             :       ! Props needed for BAM number concentration calcs.
     338             : 
     339           0 :       call rad_cnst_get_info(0, naero=naer_all)
     340             :       allocate( &
     341           0 :          aername(naer_all),        &
     342           0 :          num_to_mass_aer(naer_all) )
     343             : 
     344           0 :       do iaer = 1, naer_all
     345             :          call rad_cnst_get_aer_props(0, iaer, &
     346           0 :             aername         = aername(iaer), &
     347           0 :             num_to_mass_aer = num_to_mass_aer(iaer))
     348             :          ! Look for sulfate, dust, and soot in this list (Bulk aerosol only)
     349           0 :          if (trim(aername(iaer)) == 'SULFATE') idxsul = iaer
     350           0 :          if (trim(aername(iaer)) == 'DUST1') idxdst1 = iaer
     351           0 :          if (trim(aername(iaer)) == 'DUST2') idxdst2 = iaer
     352           0 :          if (trim(aername(iaer)) == 'DUST3') idxdst3 = iaer
     353           0 :          if (trim(aername(iaer)) == 'DUST4') idxdst4 = iaer
     354           0 :          if (trim(aername(iaer)) == 'BCPHI') idxbcphi = iaer
     355             :       end do
     356             :    end if
     357             : 
     358             : 
     359             :    call nucleati_init(use_preexisting_ice, use_hetfrz_classnuc, nucleate_ice_incloud, iulog, pi, &
     360        1536 :         mincld)
     361             : 
     362             :    ! get indices for fields in the physics buffer
     363        1536 :    ast_idx = pbuf_get_index('AST')
     364             : 
     365        1536 : end subroutine nucleate_ice_cam_init
     366             : 
     367             : !================================================================================================
     368             : 
     369     7588296 : subroutine nucleate_ice_cam_calc( &
     370      176472 :    state, wsubi, pbuf, dtime, ptend, aero_props, aero_state )
     371             : 
     372        1536 :    use tropopause,     only: tropopause_findChemTrop
     373             : 
     374             :    ! arguments
     375             :    type(physics_state), target, intent(in)    :: state
     376             :    real(r8),                    intent(in)    :: wsubi(:,:)
     377             :    type(physics_buffer_desc),   pointer       :: pbuf(:)
     378             :    real(r8),                    intent(in)    :: dtime
     379             :    type(physics_ptend),         intent(out)   :: ptend
     380             :    class(aerosol_properties),optional, intent(in) :: aero_props
     381             :    class(aerosol_state),optional, intent(in) :: aero_state
     382             : 
     383             :    ! local workspace
     384             : 
     385             :    ! naai and naai_hom are the outputs shared with the microphysics
     386      176472 :    real(r8), pointer :: naai(:,:)       ! number of activated aerosol for ice nucleation
     387      176472 :    real(r8), pointer :: naai_hom(:,:)   ! number of activated aerosol for ice nucleation (homogeneous freezing only)
     388             : 
     389             :    integer :: lchnk, ncol
     390             :    integer :: itim_old
     391             :    integer :: i, k, l, m
     392             : 
     393             :    character(len=32) :: spectype
     394             : 
     395      176472 :    real(r8), pointer :: t(:,:)          ! input temperature (K)
     396      176472 :    real(r8), pointer :: qn(:,:)         ! input water vapor mixing ratio (kg/kg)
     397      176472 :    real(r8), pointer :: qc(:,:)         ! cloud water mixing ratio (kg/kg)
     398      176472 :    real(r8), pointer :: qi(:,:)         ! cloud ice mixing ratio (kg/kg)
     399      176472 :    real(r8), pointer :: ni(:,:)         ! cloud ice number conc (1/kg)
     400      176472 :    real(r8), pointer :: pmid(:,:)       ! pressure at layer midpoints (pa)
     401             : 
     402      176472 :    real(r8), pointer :: aer_mmr(:,:)    ! aerosol mass mixing ratio
     403             : 
     404      176472 :    real(r8), pointer :: ast(:,:)
     405             :    real(r8) :: icecldf(pcols,pver)  ! ice cloud fraction
     406      176472 :    real(r8), pointer :: qsatfac(:,:)      ! Subgrid cloud water saturation scaling factor.
     407             : 
     408             :    real(r8) :: rho(pcols,pver)      ! air density (kg m-3)
     409             : 
     410      176472 :    real(r8), allocatable :: naer2(:,:,:)    ! bulk aerosol number concentration (1/m3)
     411      176472 :    real(r8), allocatable :: maerosol(:,:,:) ! bulk aerosol mass conc (kg/m3)
     412             : 
     413             :    real(r8) :: qs(pcols)            ! liquid-ice weighted sat mixing rat (kg/kg)
     414             :    real(r8) :: es(pcols)            ! liquid-ice weighted sat vapor press (pa)
     415             :    real(r8) :: gammas(pcols)        ! parameter for cond/evap of cloud water
     416             :    integer  :: troplev(pcols)       ! tropopause level
     417             : 
     418             :    real(r8) :: relhum(pcols,pver)  ! relative humidity
     419             :    real(r8) :: icldm(pcols,pver)   ! ice cloud fraction
     420             : 
     421             :    real(r8) :: dst_num                               ! total dust aerosol number (#/cm^3)
     422             :    real(r8) :: dso4_num                               ! so4 aerosol number (#/cm^3)
     423             :    real(r8) :: so4_num                               ! so4 aerosol number (#/cm^3)
     424             :    real(r8) :: soot_num                              ! soot (hydrophilic) aerosol number (#/cm^3)
     425             :    real(r8) :: wght
     426             :    real(r8) :: oso4_num
     427             :    real(r8) :: odst_num
     428             :    real(r8) :: osoot_num
     429             :    real(r8) :: so4_num_st_cr_tot
     430             :    real(r8) :: ramp
     431             : 
     432             :    real(r8) :: subgrid(pcols,pver)
     433             :    real(r8) :: trop_pd(pcols,pver)
     434             : 
     435             :    ! For pre-existing ice
     436             :    real(r8) :: fhom(pcols,pver)    ! how much fraction of cloud can reach Shom
     437             :    real(r8) :: wice(pcols,pver)    ! diagnosed Vertical velocity Reduction caused by preexisting ice (m/s), at Shom
     438             :    real(r8) :: weff(pcols,pver)    ! effective Vertical velocity for ice nucleation (m/s); weff=wsubi-wice
     439             :    real(r8) :: INnso4(pcols,pver)   ! #/m3, so4 aerosol number used for ice nucleation
     440             :    real(r8) :: INnbc(pcols,pver)    ! #/m3, bc aerosol number used for ice nucleation
     441             :    real(r8) :: INndust(pcols,pver)  ! #/m3, dust aerosol number used for ice nucleation
     442             :    real(r8) :: INondust(pcols,pver)  ! #/m3, dust aerosol number used for ice nucleation
     443             :    real(r8) :: INhet(pcols,pver)    ! #/m3, ice number from het freezing
     444             :    real(r8) :: INhom(pcols,pver)    ! #/m3, ice number from hom freezing
     445             :    real(r8) :: INFrehom(pcols,pver) !  hom freezing occurence frequency.  1 occur, 0 not occur.
     446             :    real(r8) :: INFreIN(pcols,pver)  !  ice nucleation occerence frequency.   1 occur, 0 not occur.
     447             : 
     448             :    ! history output for ice nucleation
     449             :    real(r8) :: nihf(pcols,pver)  !output number conc of ice nuclei due to heterogenous freezing (1/m3)
     450             :    real(r8) :: niimm(pcols,pver) !output number conc of ice nuclei due to immersion freezing (hetero nuc) (1/m3)
     451             :    real(r8) :: nidep(pcols,pver) !output number conc of ice nuclei due to deoposion nucleation (hetero nuc) (1/m3)
     452             :    real(r8) :: nimey(pcols,pver) !output number conc of ice nuclei due to meyers deposition (1/m3)
     453             :    real(r8) :: regm(pcols,pver)  !output temperature thershold for nucleation regime
     454             : 
     455             :    real(r8) :: size_wghts(pcols,pver)
     456             :    real(r8) :: type_wghts(pcols,pver)
     457             :    real(r8), pointer :: num_col(:,:)
     458             :    real(r8) :: dust_num_col(pcols,pver)
     459             :    real(r8) :: sulf_num_col(pcols,pver)
     460             :    real(r8) :: soot_num_col(pcols,pver)
     461             :    real(r8) :: sulf_num_tot_col(pcols,pver)
     462             : 
     463             :    integer :: idxtmp
     464      176472 :    real(r8), pointer :: amb_num(:,:)
     465      176472 :    real(r8), pointer :: amb_mmr(:,:)
     466      176472 :    real(r8), pointer :: cld_num(:,:)
     467      176472 :    real(r8), pointer :: cld_mmr(:,:)
     468             : 
     469             :    real(r8) :: delmmr, delmmr_sum
     470             :    real(r8) :: delnum, delnum_sum
     471             : 
     472             :    real(r8), parameter :: per_cm3 = 1.e-6_r8 ! factor for m-3 to cm-3 conversions
     473             : 
     474             :    !-------------------------------------------------------------------------------
     475             : 
     476      176472 :    lchnk = state%lchnk
     477      176472 :    ncol  = state%ncol
     478      176472 :    t     => state%t
     479      176472 :    qn    => state%q(:,:,1)
     480      176472 :    qc    => state%q(:,:,cldliq_idx)
     481      176472 :    qi    => state%q(:,:,cldice_idx)
     482      176472 :    ni    => state%q(:,:,numice_idx)
     483      176472 :    pmid  => state%pmid
     484             : 
     485   274216968 :    rho(:ncol,:) = pmid(:ncol,:)/(rair*t(:ncol,:))
     486             : 
     487      176472 :    if (clim_modal_aero) then
     488             : 
     489      176472 :       call physics_ptend_init(ptend, state%psetcols, 'nucleatei', lq=lq)
     490             : 
     491             :    else
     492             :       ! init number/mass arrays for bulk aerosols
     493             :       allocate( &
     494             :            naer2(pcols,pver,naer_all), &
     495           0 :            maerosol(pcols,pver,naer_all))
     496             : 
     497           0 :       do m = 1, naer_all
     498           0 :          call rad_cnst_get_aer_mmr(0, m, state, pbuf, aer_mmr)
     499           0 :          maerosol(:ncol,:,m) = aer_mmr(:ncol,:)*rho(:ncol,:)
     500             : 
     501           0 :          if (m .eq. idxsul) then
     502           0 :             naer2(:ncol,:,m) = maerosol(:ncol,:,m)*num_to_mass_aer(m)*bulk_scale
     503             :          else
     504           0 :             naer2(:ncol,:,m) = maerosol(:ncol,:,m)*num_to_mass_aer(m)
     505             :          end if
     506             :       end do
     507             : 
     508           0 :       call physics_ptend_init(ptend, state%psetcols, 'nucleatei')
     509             :    end if
     510             : 
     511      176472 :    itim_old = pbuf_old_tim_idx()
     512      705888 :    call pbuf_get_field(pbuf, ast_idx, ast, start=(/1,1,itim_old/), kount=(/pcols,pver,1/))
     513             : 
     514   274216968 :    icecldf(:ncol,:pver) = ast(:ncol,:pver)
     515             : 
     516             :    ! naai and naai_hom are the outputs from this parameterization
     517      176472 :    call pbuf_get_field(pbuf, naai_idx, naai)
     518      176472 :    call pbuf_get_field(pbuf, naai_hom_idx, naai_hom)
     519   274216968 :    naai(1:ncol,1:pver)     = 0._r8
     520   274216968 :    naai_hom(1:ncol,1:pver) = 0._r8
     521             : 
     522             :    ! Use the same criteria that is used in chemistry and in CLUBB (for cloud fraction)
     523             :    ! to determine whether to use tropospheric or stratospheric settings. Include the
     524             :    ! tropopause level so that the cold point tropopause will use the stratospheric values.
     525      176472 :    call tropopause_findChemTrop(state, troplev)
     526             : 
     527      176472 :    if ((nucleate_ice_subgrid .eq. -1._r8) .or. (nucleate_ice_subgrid_strat .eq. -1._r8)) then
     528           0 :       call pbuf_get_field(pbuf, qsatfac_idx, qsatfac)
     529             :    end if
     530             : 
     531      176472 :    trop_pd(:,:) = 0._r8
     532             : 
     533    15000120 :    do k = top_lev, pver
     534   247696920 :       do i = 1, ncol
     535   232696800 :          trop_pd(i, troplev(i)) = 1._r8
     536             : 
     537   247520448 :          if (k <= troplev(i)) then
     538   119318698 :             if (nucleate_ice_subgrid_strat .eq. -1._r8) then
     539           0 :                subgrid(i, k) = 1._r8 / qsatfac(i, k)
     540             :             else
     541   119318698 :                subgrid(i, k) = nucleate_ice_subgrid_strat
     542             :             end if
     543             :          else
     544   113378102 :             if (nucleate_ice_subgrid .eq. -1._r8) then
     545           0 :                subgrid(i, k) = 1._r8 / qsatfac(i, k)
     546             :             else
     547   113378102 :                subgrid(i, k) = nucleate_ice_subgrid
     548             :             end if
     549             :          end if
     550             :       end do
     551             :    end do
     552             : 
     553             : 
     554             :    ! initialize history output fields for ice nucleation
     555   274216968 :    nihf(1:ncol,1:pver)  = 0._r8
     556   274216968 :    niimm(1:ncol,1:pver) = 0._r8
     557   274216968 :    nidep(1:ncol,1:pver) = 0._r8
     558   274216968 :    nimey(1:ncol,1:pver) = 0._r8
     559             : 
     560   274216968 :    regm(1:ncol,1:pver) = 0._r8
     561             : 
     562      176472 :    if (use_preexisting_ice) then
     563      176472 :       fhom(:,:)     = 0.0_r8
     564      176472 :       wice(:,:)     = 0.0_r8
     565      176472 :       weff(:,:)     = 0.0_r8
     566      176472 :       INnso4(:,:)   = 0.0_r8
     567      176472 :       INnbc(:,:)    = 0.0_r8
     568      176472 :       INndust(:,:)  = 0.0_r8
     569      176472 :       INondust(:,:)  = 0.0_r8
     570      176472 :       INhet(:,:)    = 0.0_r8
     571      176472 :       INhom(:,:)    = 0.0_r8
     572      176472 :       INFrehom(:,:) = 0.0_r8
     573      176472 :       INFreIN(:,:)  = 0.0_r8
     574             :    endif
     575             : 
     576    15000120 :    do k = top_lev, pver
     577             :       ! Get humidity and saturation vapor pressures
     578    14823648 :       call qsat_water(t(1:ncol,k), pmid(1:ncol,k), es(1:ncol), qs(1:ncol), ncol, gam=gammas(1:ncol))
     579             : 
     580   247696920 :       do i = 1, ncol
     581             : 
     582   232696800 :          relhum(i,k) = qn(i,k)/qs(i)
     583             : 
     584             :          ! get cloud fraction, check for minimum
     585   247520448 :          icldm(i,k) = max(icecldf(i,k), mincld)
     586             : 
     587             :       end do
     588             :    end do
     589             : 
     590      176472 :    dust_num_col = 0._r8
     591      176472 :    sulf_num_col = 0._r8
     592      176472 :    sulf_num_tot_col = 0._r8
     593      176472 :    soot_num_col = 0._r8
     594             : 
     595      176472 :    if (clim_modal_aero) then
     596             : 
     597      529416 :       if (.not.(present(aero_props).and.present(aero_state))) then
     598           0 :          call endrun('nucleate_ice_cam_calc: aero_props and aero_state must be present')
     599             :       end if
     600             : 
     601             :       ! collect number densities (#/cm^3) for dust, sulfate, and soot
     602             :       call aero_state%nuclice_get_numdens( aero_props, use_preexisting_ice, ncol, pver, rho, &
     603      176472 :                                            dust_num_col, sulf_num_col, soot_num_col, sulf_num_tot_col )
     604             : 
     605             :    else
     606             :       ! for bulk model
     607           0 :       dust_num_col(:ncol,:) = naer2(:ncol,:,idxdst1)/25._r8 * per_cm3 & ! #/cm3
     608           0 :                             + naer2(:ncol,:,idxdst2)/25._r8 * per_cm3 &
     609           0 :                             + naer2(:ncol,:,idxdst3)/25._r8 * per_cm3 &
     610           0 :                             + naer2(:ncol,:,idxdst4)/25._r8 * per_cm3
     611           0 :       sulf_num_col(:ncol,:) = naer2(:ncol,:,idxsul)/25._r8 * per_cm3
     612           0 :       soot_num_col(:ncol,:) = naer2(:ncol,:,idxbcphi)/25._r8 * per_cm3
     613             :    endif
     614             : 
     615    15000120 :    kloop: do k = top_lev, pver
     616   247696920 :       iloop: do i = 1, ncol
     617             : 
     618   232696800 :          so4_num_st_cr_tot = 0._r8
     619             : 
     620   247520448 :          freezing: if (t(i,k) < tmelt - 5._r8) then
     621             : 
     622             :             ! set aerosol number for so4, soot, and dust with units #/cm^3
     623   180451908 :             so4_num = sulf_num_col(i,k)
     624   180451908 :             dst_num = dust_num_col(i,k)
     625   180451908 :             so4_num_st_cr_tot=sulf_num_tot_col(i,k)
     626             : 
     627             :             ! *** Turn off soot nucleation ***
     628   180451908 :             soot_num = 0.0_r8
     629             : 
     630   180451908 :             if (cam_physpkg_is("cam7")) then
     631             : 
     632             :                call nucleati( &
     633   360903816 :                     wsubi(i,k), t(i,k), pmid(i,k), relhum(i,k), icldm(i,k),   &
     634   180451908 :                     qc(i,k), qi(i,k), ni(i,k), rho(i,k),                      &
     635             :                     so4_num, dst_num, soot_num, subgrid(i,k),                 &
     636           0 :                     naai(i,k), nihf(i,k), niimm(i,k), nidep(i,k), nimey(i,k), &
     637             :                     wice(i,k), weff(i,k), fhom(i,k), regm(i,k),               &
     638             :                     oso4_num, odst_num, osoot_num, &
     639   541355724 :                     call_frm_zm_in = .false., add_preexisting_ice_in = .false.)
     640             : 
     641             :             else
     642             : 
     643             :                call nucleati( &
     644           0 :                     wsubi(i,k), t(i,k), pmid(i,k), relhum(i,k), icldm(i,k),   &
     645           0 :                     qc(i,k), qi(i,k), ni(i,k), rho(i,k),                      &
     646             :                     so4_num, dst_num, soot_num, subgrid(i,k),                 &
     647           0 :                     naai(i,k), nihf(i,k), niimm(i,k), nidep(i,k), nimey(i,k), &
     648             :                     wice(i,k), weff(i,k), fhom(i,k), regm(i,k),               &
     649           0 :                     oso4_num, odst_num, osoot_num)
     650             : 
     651             :             end if
     652             : 
     653             :             ! Move aerosol used for nucleation from interstial to cloudborne,
     654             :             ! otherwise the same coarse mode aerosols will be available again
     655             :             ! in the next timestep and will supress homogeneous freezing.
     656             : 
     657             : 
     658   180451908 :             if (prog_modal_aero .and. use_preexisting_ice) then
     659             : 
     660             :                ! compute tendencies for transported aerosol constituents
     661             :                ! and update not-transported constituents
     662             : 
     663   902259540 :                do m = 1, aero_props%nbins()
     664             : 
     665   902259540 :                   if (aero_props%icenuc_updates_num(m)) then
     666             : 
     667             :                      ! constituents of this bin will need to be updated
     668             : 
     669   180451908 :                      call aero_state%get_ambient_num(m, amb_num)
     670   180451908 :                      call aero_state%get_cldbrne_num(m, cld_num)
     671             : 
     672   180451908 :                      if (amb_num(i,k)>0._r8) then
     673   180451908 :                         delmmr_sum = 0._r8
     674   180451908 :                         delnum_sum = 0._r8
     675             : 
     676             :                         ! iterate over the species within the bin
     677   721807632 :                         do l = 1, aero_props%nspecies(m)
     678   721807632 :                            if (aero_props%icenuc_updates_mmr(m,l)) then
     679             : 
     680   180451908 :                               call aero_props%species_type(m, l, spectype)
     681   180451908 :                               call aero_state%icenuc_size_wght( m, i,k, spectype, use_preexisting_ice, wght)
     682             : 
     683   180451908 :                               if (wght>0._r8) then
     684             : 
     685             :                                  ! this aerosol constituent will be updated
     686             : 
     687   180451908 :                                  idxtmp = aer_cnst_idx(m,l)
     688             : 
     689   180451908 :                                  call aero_state%get_ambient_mmr(l,m,amb_mmr)
     690   180451908 :                                  call aero_state%get_cldbrne_mmr(l,m,cld_mmr)
     691             : 
     692             :                                  ! determine change in aerosol mass
     693   180451908 :                                  delmmr = 0._r8
     694   180451908 :                                  delnum = 0._r8
     695   180451908 :                                  if (trim(spectype)=='dust') then
     696   180451908 :                                     if (dst_num>0._r8) then
     697   180451908 :                                        delmmr = (odst_num / dst_num) * icldm(i,k) * amb_mmr(i,k) * wght
     698   180451908 :                                        delnum = (odst_num * icldm(i,k)) /rho(i,k)/per_cm3
     699             :                                     endif
     700           0 :                                  elseif (trim(spectype)=='sulfate') then
     701           0 :                                     if (so4_num>0._r8) then
     702           0 :                                        delmmr = (oso4_num / so4_num) * icldm(i,k) * amb_mmr(i,k) * wght
     703           0 :                                        delnum = (oso4_num * icldm(i,k)) /rho(i,k)/per_cm3
     704             :                                     endif
     705             :                                  endif
     706             : 
     707   180451908 :                                  if (idxtmp>0) then
     708             :                                     ! constituent tendency (for transported species)
     709   180451908 :                                     ptend%q(i,k,idxtmp) = -delmmr/dtime
     710             :                                  else
     711             :                                     ! apply change of mass to not-transported species
     712           0 :                                     amb_mmr(i,k) = amb_mmr(i,k) - delmmr
     713             :                                  endif
     714   180451908 :                                  cld_mmr(i,k) = cld_mmr(i,k) + delmmr
     715             : 
     716   180451908 :                                  delmmr_sum = delmmr_sum + delmmr
     717   180451908 :                                  delnum_sum = delnum_sum + delnum
     718             :                               end if
     719             :                            end if
     720             :                         end do
     721             : 
     722   180451908 :                         idxtmp = aer_cnst_idx(m,0)
     723             : 
     724             :                         ! update aerosol state bin and tendency for grid box i,k
     725   180451908 :                         call aero_state%update_bin( m,i,k, delmmr_sum, delnum_sum, idxtmp, dtime, ptend%q )
     726             : 
     727             :                      end if
     728             : 
     729             :                   end if
     730             :                end do
     731             : 
     732             :             end if
     733             : 
     734             : 
     735             :             ! Liu&Penner does not generate enough nucleation in the polar winter
     736             :             ! stratosphere, which affects surface area density, dehydration and
     737             :             ! ozone chemistry. Part of this is that there are a larger number of
     738             :             ! particles in the accumulation mode than in the Aitken mode. In volcanic
     739             :             ! periods, the coarse mode may also be important. As a short
     740             :             ! term work around, include the accumulation and coarse mode particles
     741             :             ! and assume a larger fraction of the sulfates nucleate in the polar
     742             :             ! stratosphere.
     743             :             !
     744             :             ! Do not include the tropopause level, as stratospheric aerosols
     745             :             ! only exist above the tropopause level.
     746             :             !
     747             :             ! NOTE: This may still not represent the proper particles that
     748             :             ! participate in nucleation, because it doesn't include STS and NAT
     749             :             ! particles. It may not represent the proper saturation threshold for
     750             :             ! nucleation, and wsubi from CLUBB is probably not representative of
     751             :             ! wave driven varaibility in the polar stratosphere.
     752   180451908 :             if (nucleate_ice_use_troplev .and. clim_modal_aero) then
     753   180451908 :                if ((k < troplev(i)) .and. (nucleate_ice_strat > 0._r8) .and. (oso4_num > 0._r8)) then
     754         100 :                   dso4_num = max(0._r8, (nucleate_ice_strat*so4_num_st_cr_tot - oso4_num) * 1e6_r8 / rho(i,k))
     755         100 :                   naai(i,k) = naai(i,k) + dso4_num
     756         100 :                   nihf(i,k) = nihf(i,k) + dso4_num
     757             :                endif
     758             :             else
     759             :                ! This maintains backwards compatibility with the previous version.
     760           0 :                if (pmid(i,k) <= 12500._r8 .and. pmid(i,k) > 100._r8 .and. abs(state%lat(i)) >= 60._r8 * pi / 180._r8) then
     761           0 :                   ramp = 1._r8 - min(1._r8, max(0._r8, (pmid(i,k) - 10000._r8) / 2500._r8))
     762             : 
     763           0 :                   if (oso4_num > 0._r8) then
     764           0 :                      dso4_num = (max(oso4_num, ramp * nucleate_ice_strat * so4_num) - oso4_num) * 1e6_r8 / rho(i,k)
     765           0 :                      naai(i,k) = naai(i,k) + dso4_num
     766           0 :                      nihf(i,k) = nihf(i,k) + dso4_num
     767             :                   end if
     768             :                end if
     769             :             end if
     770             : 
     771   180451908 :             if (cam_physpkg_is("cam7")) then
     772             :                !Updates for pumas v1.21+
     773             : 
     774   180451908 :                naai_hom(i,k) = nihf(i,k)/dtime
     775   180451908 :                naai(i,k)= naai(i,k)/dtime
     776             : 
     777             :                ! output activated ice (convert from #/kg -> #/m3/s)
     778   180451908 :                nihf(i,k)     = nihf(i,k) *rho(i,k)/dtime
     779   180451908 :                niimm(i,k)    = niimm(i,k)*rho(i,k)/dtime
     780   180451908 :                nidep(i,k)    = nidep(i,k)*rho(i,k)/dtime
     781   180451908 :                nimey(i,k)    = nimey(i,k)*rho(i,k)/dtime
     782             : 
     783   180451908 :                if (use_preexisting_ice) then
     784   180451908 :                   INnso4(i,k) =so4_num*1e6_r8/dtime  ! (convert from #/cm3 -> #/m3/s)
     785   180451908 :                   INnbc(i,k)  =soot_num*1e6_r8/dtime
     786   180451908 :                   INndust(i,k)=dst_num*1e6_r8/dtime
     787   180451908 :                   INondust(i,k)=odst_num*1e6_r8/dtime
     788   180451908 :                   INFreIN(i,k)=1.0_r8          ! 1,ice nucleation occur
     789   180451908 :                   INhet(i,k) = (niimm(i,k) + nidep(i,k))   ! #/m3/s, nimey not in cirrus
     790   180451908 :                   INhom(i,k) = nihf(i,k)                 ! #/m3/s
     791   180451908 :                   if (INhom(i,k).gt.1e3_r8)   then ! > 1/L
     792        1495 :                      INFrehom(i,k)=1.0_r8       ! 1, hom freezing occur
     793             :                   endif
     794             : 
     795             :                   ! exclude  no ice nucleaton
     796   180451908 :                   if ((INFrehom(i,k) < 0.5_r8) .and. (INhet(i,k) < 1.0_r8))   then
     797   180323503 :                      INnso4(i,k) =0.0_r8
     798   180323503 :                      INnbc(i,k)  =0.0_r8
     799   180323503 :                      INndust(i,k)=0.0_r8
     800   180323503 :                      INondust(i,k)=0.0_r8
     801   180323503 :                      INFreIN(i,k)=0.0_r8
     802   180323503 :                      INhet(i,k) = 0.0_r8
     803   180323503 :                      INhom(i,k) = 0.0_r8
     804   180323503 :                      INFrehom(i,k)=0.0_r8
     805   180323503 :                      wice(i,k) = 0.0_r8
     806   180323503 :                      weff(i,k) = 0.0_r8
     807   180323503 :                      fhom(i,k) = 0.0_r8
     808             :                   endif
     809             :                endif
     810             : 
     811             :             else ! Not cam7
     812             : 
     813           0 :                naai_hom(i,k) = nihf(i,k)
     814             : 
     815             :                ! output activated ice (convert from #/kg -> #/m3/s)
     816           0 :                nihf(i,k)     = nihf(i,k) *rho(i,k)
     817           0 :                niimm(i,k)    = niimm(i,k)*rho(i,k)
     818           0 :                nidep(i,k)    = nidep(i,k)*rho(i,k)
     819           0 :                nimey(i,k)    = nimey(i,k)*rho(i,k)
     820             : 
     821           0 :                if (use_preexisting_ice) then
     822           0 :                   INnso4(i,k) =so4_num*1e6_r8 ! (convert from #/cm3 -> #/m3/s)
     823           0 :                   INnbc(i,k)  =soot_num*1e6_r8
     824           0 :                   INndust(i,k)=dst_num*1e6_r8
     825           0 :                   INondust(i,k)=odst_num*1e6_r8
     826           0 :                   INFreIN(i,k)=1.0_r8          ! 1,ice nucleation occur
     827           0 :                   INhet(i,k) = (niimm(i,k) + nidep(i,k))   ! #/m3, nimey not in cirrus
     828           0 :                   INhom(i,k) = nihf(i,k)                 ! #/m3
     829           0 :                   if (INhom(i,k).gt.1e3_r8)   then ! > 1/L
     830           0 :                      INFrehom(i,k)=1.0_r8       ! 1, hom freezing occur
     831             :                   endif
     832             : 
     833             :                   ! exclude  no ice nucleaton
     834           0 :                   if ((INFrehom(i,k) < 0.5_r8) .and. (INhet(i,k) < 1.0_r8))   then
     835           0 :                      INnso4(i,k) =0.0_r8
     836           0 :                      INnbc(i,k)  =0.0_r8
     837           0 :                      INndust(i,k)=0.0_r8
     838           0 :                      INondust(i,k)=0.0_r8
     839           0 :                      INFreIN(i,k)=0.0_r8
     840           0 :                      INhet(i,k) = 0.0_r8
     841           0 :                      INhom(i,k) = 0.0_r8
     842           0 :                      INFrehom(i,k)=0.0_r8
     843           0 :                      wice(i,k) = 0.0_r8
     844           0 :                      weff(i,k) = 0.0_r8
     845           0 :                      fhom(i,k) = 0.0_r8
     846             :                   endif
     847             :                end if
     848             : 
     849             :             end if ! cam7
     850             :          end if freezing
     851             :       end do iloop
     852             :    end do kloop
     853             : 
     854      176472 :    if (.not. clim_modal_aero) then
     855           0 :       deallocate( &
     856             :            naer2, &
     857           0 :            maerosol)
     858             :    end if
     859             : 
     860      176472 :    if (cam_physpkg_is("cam7")) then
     861             :       ! Updates for PUMAS v1.21+
     862      176472 :       call outfld('NIHFTEN',   nihf, pcols, lchnk)
     863      176472 :       call outfld('NIIMMTEN', niimm, pcols, lchnk)
     864      176472 :       call outfld('NIDEPTEN', nidep, pcols, lchnk)
     865      176472 :       call outfld('NIMEYTEN', nimey, pcols, lchnk)
     866             :    else
     867           0 :       call outfld('NIHF',   nihf, pcols, lchnk)
     868           0 :       call outfld('NIIMM', niimm, pcols, lchnk)
     869           0 :       call outfld('NIDEP', nidep, pcols, lchnk)
     870           0 :       call outfld('NIMEY', nimey, pcols, lchnk)
     871             :    end if
     872      176472 :    call outfld('NIREGM', regm, pcols, lchnk)
     873      176472 :    call outfld('NISUBGRID', subgrid, pcols, lchnk)
     874      176472 :    call outfld('NITROP_PD', trop_pd, pcols, lchnk)
     875             : 
     876      176472 :    if (use_preexisting_ice) then
     877      176472 :       call outfld( 'fhom' , fhom, pcols, lchnk)
     878      176472 :       call outfld( 'WICE' , wice, pcols, lchnk)
     879      176472 :       call outfld( 'WEFF' , weff, pcols, lchnk)
     880      176472 :       if (cam_physpkg_is("cam7")) then
     881             :          ! Updates for PUMAS v1.21+
     882      176472 :          call outfld('INnso4TEN',INnso4 , pcols,lchnk)
     883      176472 :          call outfld('INnbcTEN',INnbc  , pcols,lchnk)
     884      176472 :          call outfld('INndustTEN',INndust, pcols,lchnk)
     885      176472 :          call outfld('INondustTEN',INondust, pcols,lchnk)
     886      176472 :          call outfld('INhetTEN',INhet  , pcols,lchnk)
     887      176472 :          call outfld('INhomTEN',INhom  , pcols,lchnk)
     888             :       else
     889           0 :          call outfld('INnso4  ',INnso4 , pcols,lchnk)
     890           0 :          call outfld('INnbc   ',INnbc  , pcols,lchnk)
     891           0 :          call outfld('INndust ',INndust, pcols,lchnk)
     892           0 :          call outfld('INondust ',INondust, pcols,lchnk)
     893           0 :          call outfld('INhet   ',INhet  , pcols,lchnk)
     894           0 :          call outfld('INhom   ',INhom  , pcols,lchnk)
     895             :       end if
     896      176472 :       call outfld('INFrehom',INFrehom,pcols,lchnk)
     897      176472 :       call outfld('INFreIN ',INFreIN, pcols,lchnk)
     898             :    end if
     899             : 
     900      352944 : end subroutine nucleate_ice_cam_calc
     901             : 
     902             : !================================================================================================
     903             : 
     904             : end module nucleate_ice_cam

Generated by: LCOV version 1.14