LCOV - code coverage report
Current view: top level - chemistry/modal_aero - modal_aero_gasaerexch.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 615 785 78.3 %
Date: 2024-12-17 22:39:59 Functions: 4 4 100.0 %

          Line data    Source code
       1             : ! modal_aero_gasaerexch.F90
       2             : 
       3             : 
       4             : !----------------------------------------------------------------------
       5             : !----------------------------------------------------------------------
       6             : !BOP
       7             : !
       8             : ! !MODULE: modal_aero_gasaerexch --- does modal aerosol gas-aerosol exchange
       9             : !
      10             : ! !INTERFACE:
      11             :    module modal_aero_gasaerexch
      12             : 
      13             : ! !USES:
      14             :   use shr_kind_mod,    only:  r8 => shr_kind_r8
      15             :   use chem_mods,       only:  gas_pcnst
      16             :   use modal_aero_data, only:  nspec_max, nsoa, npoa, soa_multi_species
      17             :   use ref_pres,        only:  top_lev => clim_modal_aero_top_lev
      18             :   use ppgrid,          only:  pcols, pver
      19             :   use modal_aero_data, only:  ntot_amode, numptr_amode, sigmag_amode
      20             :   use modal_aero_data, only: lptr2_soa_g_amode, lptr2_soa_a_amode, lptr2_pom_a_amode
      21             : 
      22             :   implicit none
      23             :   private
      24             :   save
      25             : 
      26             : ! !PUBLIC MEMBER FUNCTIONS:
      27             :   public modal_aero_gasaerexch_sub, modal_aero_gasaerexch_init
      28             : 
      29             : ! !PUBLIC DATA MEMBERS:
      30             :   integer, parameter :: pcnstxx = gas_pcnst
      31             :   integer, protected, public :: maxspec_pcage != nspec_max
      32             : 
      33             :   integer, protected, public :: modefrm_pcage
      34             :   integer, protected, public :: nspecfrm_pcage
      35             :   integer :: modetoo_pcage
      36             : 
      37             :   integer, protected, allocatable, public :: lspecfrm_pcage(:)
      38             :   integer, protected, allocatable, public :: lspectoo_pcage(:)
      39             : 
      40             :   real(r8), parameter, public :: n_so4_monolayers_pcage = 8.0_r8
      41             : 
      42             : ! number of so4(+nh4) monolayers needed to "age" a carbon particle
      43             : 
      44             :   real(r8), parameter, public :: &
      45             :               dr_so4_monolayers_pcage = n_so4_monolayers_pcage * 4.76e-10_r8
      46             : ! thickness of the so4 monolayers (m)
      47             : ! for so4(+nh4), use bi-sulfate mw and 1.77 g/cm3,
      48             : !    --> 1 mol so4(+nh4)  = 65 cm^3 --> 1 molecule = (4.76e-10 m)^3
      49             : ! aging criterion is approximate so do not try to distinguish
      50             : !    sulfuric acid, bisulfate, ammonium sulfate
      51             : 
      52             :   real(r8), protected, allocatable, public :: soa_equivso4_factor(:)
      53             : ! this factor converts an soa volume to a volume of so4(+nh4)
      54             : ! having same hygroscopicity as the soa
      55             : 
      56             :   real (r8) :: fac_m2v_nh4, fac_m2v_so4
      57             :   real (r8), allocatable :: fac_m2v_soa(:)
      58             : 
      59             :   real (r8), allocatable :: fac_m2v_pcarbon(:)
      60             : 
      61             : ! !DESCRIPTION: This module implements ...
      62             : !
      63             : ! !REVISION HISTORY:
      64             : !
      65             : !   RCE 07.04.13:  Adapted from MIRAGE2 code
      66             : !
      67             : !EOP
      68             : !----------------------------------------------------------------------
      69             : !BOC
      70             : 
      71             : ! list private module data here
      72             : 
      73             : !EOC
      74             : !----------------------------------------------------------------------
      75             : 
      76             : 
      77             :   contains
      78             : 
      79             : 
      80             : !----------------------------------------------------------------------
      81             : !----------------------------------------------------------------------
      82             : !BOP
      83             : ! !ROUTINE:  modal_aero_gasaerexch_sub --- ...
      84             : !
      85             : ! !INTERFACE:
      86     1490712 : subroutine modal_aero_gasaerexch_sub(                            &
      87             :                         lchnk,    ncol,     nstep,               &
      88             :                         loffset,  deltat,                        &
      89             :                         t,        pmid,     pdel,                &
      90             :                         qh2o,               troplev,             &
      91     1489176 :                         q,                  qqcw,                &
      92     1489176 :                         dqdt_other,         dqqcwdt_other,       &
      93     1489176 :                         dgncur_a,           dgncur_awet,         &
      94             :                         sulfeq         )
      95             : 
      96             : ! !USES:
      97             : use modal_aero_data,   only:  alnsg_amode,lmassptr_amode,cnst_name_cw
      98             : use modal_aero_data,   only:  lptr_so4_a_amode,lptr_nh4_a_amode
      99             : use modal_aero_data,   only:  modeptr_pcarbon,nspec_amode,specmw_amode,specdens_amode
     100             : use modal_aero_rename, only:  modal_aero_rename_sub
     101             : use rad_constituents,  only: rad_cnst_get_info
     102             : use constituents,      only: pcnst, cnst_mw
     103             : 
     104             : use cam_history,       only:  outfld, fieldname_len
     105             : use chem_mods,         only:  adv_mass
     106             : use constituents,      only:  pcnst, cnst_name, cnst_get_ind
     107             : use mo_tracname,       only:  solsym
     108             : use physconst,         only:  gravit, mwdry, rair
     109             : use cam_abortutils,    only:  endrun
     110             : use spmd_utils,        only:  iam, masterproc
     111             : use phys_control,      only:  cam_chempkg_is
     112             : 
     113             : implicit none
     114             : 
     115             : ! !PARAMETERS:
     116             :    integer,  intent(in)    :: lchnk                ! chunk identifier
     117             :    integer,  intent(in)    :: ncol                 ! number of atmospheric column
     118             :    integer,  intent(in)    :: nstep                ! model time-step number
     119             :    integer,  intent(in)    :: loffset              ! offset applied to modal aero "ptrs"
     120             :    integer,  intent(in)    :: troplev(pcols)       ! tropopause vertical index
     121             :    real(r8), intent(in)    :: deltat               ! time step (s)
     122             : 
     123             :    real(r8), intent(inout) :: q(ncol,pver,pcnstxx) ! tracer mixing ratio (TMR) array
     124             :                                                    ! *** MUST BE  #/kmol-air for number
     125             :                                                    ! *** MUST BE mol/mol-air for mass
     126             :                                                    ! *** NOTE ncol dimension
     127             :    real(r8), intent(inout) :: qqcw(ncol,pver,pcnstxx)
     128             :                                                    ! like q but for cloud-borner tracers
     129             :    real(r8), intent(in)    :: dqdt_other(ncol,pver,pcnstxx)
     130             :                                                    ! TMR tendency from other continuous
     131             :                                                    ! growth processes (aqchem, soa??)
     132             :                                                    ! *** NOTE ncol dimension
     133             :    real(r8), intent(in)    :: dqqcwdt_other(ncol,pver,pcnstxx)
     134             :                                                    ! like dqdt_other but for cloud-borner tracers
     135             :    real(r8), intent(in)    :: t(pcols,pver)        ! temperature at model levels (K)
     136             :    real(r8), intent(in)    :: pmid(pcols,pver)     ! pressure at model levels (Pa)
     137             :    real(r8), intent(in)    :: pdel(pcols,pver)     ! pressure thickness of levels (Pa)
     138             :    real(r8), intent(in)    :: qh2o(pcols,pver)     ! water vapor mixing ratio (kg/kg)
     139             :    real(r8), intent(in)    :: dgncur_a(pcols,pver,ntot_amode)
     140             :    real(r8), intent(in)    :: dgncur_awet(pcols,pver,ntot_amode)
     141             :    real(r8), pointer       :: sulfeq(:,:,:)
     142             : 
     143             :                                  ! dry & wet geo. mean dia. (m) of number distrib.
     144             : 
     145             : ! !DESCRIPTION:
     146             : ! computes TMR (tracer mixing ratio) tendencies for gas condensation
     147             : !    onto aerosol particles
     148             : !
     149             : ! this version does condensation of H2SO4, NH3, and MSA, both treated as
     150             : ! completely non-volatile (gas --> aerosol, but no aerosol --> gas)
     151             : !    gas H2SO4 goes to aerosol SO4
     152             : !    gas MSA (if present) goes to aerosol SO4
     153             : !       aerosol MSA is not distinguished from aerosol SO4
     154             : !    gas NH3 (if present) goes to aerosol NH4
     155             : !       if gas NH3 is not present, then ????
     156             : !
     157             : !
     158             : ! !REVISION HISTORY:
     159             : !   RCE 07.04.13:  Adapted from MIRAGE2 code
     160             : !
     161             : !EOP
     162             : !----------------------------------------------------------------------
     163             : !BOC
     164             : 
     165             : ! local variables
     166             :    integer, parameter :: jsrflx_gaexch = 1
     167             :    integer, parameter :: jsrflx_rename = 2
     168             :    integer, parameter :: ldiag1=-1, ldiag2=-1, ldiag3=-1, ldiag4=-1
     169             :    integer, parameter :: method_soa = 2
     170             : !     method_soa=0 is no uptake
     171             : !     method_soa=1 is irreversible uptake done like h2so4 uptake
     172             : !     method_soa=2 is reversible uptake using subr modal_aero_soaexch
     173             : 
     174             :    integer :: i, iq, itmpa
     175             :    integer :: idiagss
     176     2978352 :    integer :: ido_so4a(ntot_amode), ido_nh4a(ntot_amode)
     177     2978352 :    integer ::  ido_soaa(ntot_amode,nsoa)
     178             :    integer :: j, jac, jsrf, jsoa
     179             :    integer :: k,p
     180             :    integer :: l, l2, lb, lsfrm, lstoo
     181             :    integer :: l_so4g, l_nh4g, l_msag
     182     2978352 :    integer :: l_soag(nsoa)
     183             :    integer :: n, nn, niter, niter_max, ntot_soamode
     184             : 
     185     2978352 :    logical :: is_dorename_atik, dorename_atik(ncol,pver)
     186             : 
     187             :    character(len=fieldname_len+3) :: fieldname
     188             :    character(len=100) :: msg ! string for endrun calls
     189             :    character(len=32) :: spec_type
     190             : 
     191     2978352 :    real (r8) :: avg_uprt_nh4, avg_uprt_so4, avg_uprt_soa(nsoa)
     192             :    real (r8) :: deltatxx
     193     2978352 :    real (r8) :: dqdt_nh4(ntot_amode), dqdt_so4(ntot_amode)
     194     2978352 :    real (r8) :: dqdt_soa(ntot_amode,nsoa)
     195     2978352 :    real (r8) :: dqdt_soag(nsoa)
     196             :    real (r8) :: fac_volsfc_pcarbon
     197     2978352 :    real (r8) :: fgain_nh4(ntot_amode), fgain_so4(ntot_amode)
     198     2978352 :    real (r8) :: fgain_soa(ntot_amode,nsoa)
     199             :    real (r8) :: g0_soa(nsoa)
     200     2978352 :    real(r8)  :: mw_poa_host(npoa)          ! molec wght of poa used in host code
     201     2978352 :    real(r8)  :: mw_soa_host(nsoa)          ! molec wght of poa used in host code
     202             :    real (r8) :: pdel_fac
     203             :    real (r8) :: qmax_nh4, qnew_nh4, qnew_so4
     204     2978352 :    real (r8) :: qold_nh4(ntot_amode), qold_so4(ntot_amode)
     205     2978352 :    real (r8) :: qold_poa(ntot_amode,npoa)
     206     2978352 :    real (r8) :: qold_soa(ntot_amode,nsoa)
     207     2978352 :    real (r8) :: qold_soag(nsoa)
     208             :    real (r8) :: sum_dqdt_msa, sum_dqdt_so4
     209     2978352 :    real (r8) :: sum_dqdt_soa(nsoa)
     210             :    real (r8) :: sum_dqdt_nh4, sum_dqdt_nh4_b
     211             :    real (r8) :: sum_uprt_msa, sum_uprt_nh4, sum_uprt_so4
     212     2978352 :    real (r8) :: sum_uprt_soa(nsoa)
     213             :    real (r8) :: tmp1, tmp2, tmpa
     214             :    real (r8) :: tmp_kxt, tmp_pxt
     215             :    real (r8) :: tmp_so4a_bgn, tmp_so4a_end
     216             :    real (r8) :: tmp_so4g_avg, tmp_so4g_bgn, tmp_so4g_equ
     217     2978352 :    real (r8) :: uptkrate(ntot_amode,pcols,pver)
     218     2978352 :    real (r8) :: uptkratebb(ntot_amode)
     219     2978352 :    real (r8) :: uptkrate_soa(ntot_amode,nsoa)
     220             :                 ! gas-to-aerosol mass transfer rates (1/s)
     221             :    real (r8) :: vol_core, vol_shell
     222             :    real (r8) :: xferfrac_pcage, xferfrac_max
     223             :    real (r8) :: xferrate
     224             : 
     225             :    logical  :: do_msag         ! true if msa gas is a species
     226             :    logical  :: do_nh4g         ! true if nh3 gas is a species
     227             :    logical  :: do_soag_any         ! true if soa gas is a species
     228     2978352 :    logical  :: do_soag(nsoa)       ! true if soa gas is a species
     229             : 
     230             :    logical  :: dotend(pcnstxx)          ! identifies species directly involved in
     231             :                                         !    gas-aerosol exchange (gas condensation)
     232             :    logical  :: dotendqqcw(pcnstxx)      ! like dotend but for cloud-borner tracers
     233             :    logical  :: dotendrn(pcnstxx), dotendqqcwrn(pcnstxx)
     234             :                                         ! identifies species involved in renaming
     235             :                                         !    after "continuous growth"
     236             :                                         !    (gas-aerosol exchange and aqchem)
     237             : 
     238             :    integer, parameter :: nsrflx = 2     ! last dimension of qsrflx
     239     2978352 :    real(r8) :: dqdt(ncol,pver,pcnstxx)  ! TMR "delta q" array - NOTE dims
     240     2978352 :    real(r8) :: dqqcwdt(ncol,pver,pcnstxx) ! like dqdt but for cloud-borner tracers
     241             :    real(r8) :: qsrflx(pcols,pcnstxx,nsrflx)
     242             :                               ! process-specific column tracer tendencies
     243             :                               ! (1=renaming, 2=gas condensation)
     244             :    real(r8) :: qconff(pcols,pver),qevapff(pcols,pver)
     245             :    real(r8) :: qconbb(pcols,pver),qevapbb(pcols,pver)
     246             :    real(r8) :: qconbg(pcols,pver),qevapbg(pcols,pver)
     247             :    real(r8) :: qcon(pcols,pver),qevap(pcols,pver)
     248             : 
     249             :    real(r8) :: qqcwsrflx(pcols,pcnstxx,nsrflx)
     250             : 
     251             : !  following only needed for diagnostics
     252     2978352 :    real(r8) :: qold(ncol,pver,pcnstxx)  ! NOTE dims
     253             :    real(r8) :: qnew(ncol,pver,pcnstxx)  ! NOTE dims
     254             :    real(r8) :: qdel(ncol,pver,pcnstxx)  ! NOTE dims
     255             :    real(r8) :: dumavec(1000), dumbvec(1000), dumcvec(1000)
     256     2978352 :    real(r8) :: qqcwold(ncol,pver,pcnstxx)
     257     2978352 :    real(r8) :: dqdtsv1(ncol,pver,pcnstxx)
     258     2978352 :    real(r8) :: dqqcwdtsv1(ncol,pver,pcnstxx)
     259             : 
     260             : 
     261             : !----------------------------------------------------------------------
     262             : 
     263             : ! set gas species indices
     264     1489176 :    call cnst_get_ind( 'H2SO4', l_so4g, .false. )
     265     1489176 :    call cnst_get_ind( 'NH3',   l_nh4g, .false. )
     266     1489176 :    if ( .not. cam_chempkg_is('geoschem_mam4') ) then
     267     1489176 :       call cnst_get_ind( 'MSA',   l_msag, .false. )
     268             :    else
     269           0 :       l_msag = 0
     270             :    endif
     271     1489176 :    l_so4g = l_so4g - loffset
     272     1489176 :    l_nh4g = l_nh4g - loffset
     273     1489176 :    l_msag = l_msag - loffset
     274     1489176 :    if ((l_so4g <= 0) .or. (l_so4g > pcnstxx)) then
     275             :       write( *, '(/a/a,2i7)' )   &
     276           0 :          '*** modal_aero_gasaerexch_sub -- cannot find H2SO4 species',   &
     277           0 :          '    l_so4g, loffset =', l_so4g, loffset
     278           0 :       call endrun( 'modal_aero_gasaerexch_sub error' )
     279             :    end if
     280     1489176 :    do_nh4g = .false.
     281     1489176 :    do_msag = .false.
     282     1489176 :    if ((l_nh4g > 0) .and. (l_nh4g <= pcnstxx)) do_nh4g = .true.
     283     1489176 :    if ((l_msag > 0) .and. (l_msag <= pcnstxx)) do_msag = .true.
     284             : 
     285     1489176 :    do_soag_any = .false.
     286     2978352 :    do_soag(:) = .false.
     287     2978352 :    do jsoa = 1, nsoa
     288     1489176 :       l_soag(jsoa) = lptr2_soa_g_amode(jsoa) - loffset
     289     1489176 :       if ((method_soa == 1) .or. (method_soa == 2)) then
     290     1489176 :          if ((l_soag(jsoa) > 0) .and. (l_soag(jsoa) <= pcnstxx)) then
     291     1489176 :             do_soag_any = .true.
     292     1489176 :             do_soag(jsoa) = .true.
     293             :          end if
     294             :       else if (method_soa /= 0) then
     295             :          write(*,'(/a,1x,i10)') '*** modal_aero_gasaerexch_sub - bad method_soa =', method_soa
     296             :          call endrun( 'modal_aero_gasaerexch_sub error' )
     297             :       end if
     298             :    end do ! jsoa
     299             : 
     300             : ! set tendency flags
     301     1489176 :    dotend(:) = .false.
     302     1489176 :    dotendqqcw(:) = .false.
     303     7445880 :    ido_so4a(:) = 0
     304     7445880 :    ido_nh4a(:) = 0
     305     8935056 :    ido_soaa(:,:) = 0
     306             : 
     307     1489176 :    dotend(l_so4g) = .true.
     308     1489176 :    if ( do_nh4g ) dotend(l_nh4g) = .true.
     309     1489176 :    if ( do_msag ) dotend(l_msag) = .true.
     310     2978352 :    do jsoa = 1, nsoa
     311     2978352 :       if ( do_soag(jsoa) ) dotend(l_soag(jsoa)) = .true.
     312             :    end do
     313             : 
     314     1489176 :    ntot_soamode = 0
     315     7445880 :    do n = 1, ntot_amode
     316     5956704 :       l = lptr_so4_a_amode(n)-loffset
     317     5956704 :       if ((l > 0) .and. (l <= pcnstxx)) then
     318     4467528 :          dotend(l) = .true.
     319     4467528 :          ido_so4a(n) = 1
     320     4467528 :          if ( do_nh4g ) then
     321           0 :             l = lptr_nh4_a_amode(n)-loffset
     322           0 :             if ((l > 0) .and. (l <= pcnstxx)) then
     323           0 :                dotend(l) = .true.
     324           0 :                ido_nh4a(n) = 1
     325             :             end if
     326             :          end if
     327             :       end if
     328             : 
     329    13402584 :       do jsoa = 1, nsoa
     330    11913408 :          if ( do_soag(jsoa) ) then
     331     5956704 :             l = lptr2_soa_a_amode(n,jsoa)-loffset
     332     5956704 :             if ((l > 0) .and. (l <= pcnstxx)) then
     333     2978352 :                dotend(l) = .true.
     334     2978352 :                ido_soaa(n,jsoa) = 1
     335     2978352 :                ntot_soamode = n
     336             :             end if
     337             :          end if
     338             :       end do ! jsoa
     339             :    end do ! n
     340             : 
     341             : 
     342     1489176 :    if ( do_soag_any ) ntot_soamode = max( ntot_soamode, modefrm_pcage )
     343             : 
     344     1489176 :    if (modefrm_pcage > 0) then
     345     1489176 :       ido_so4a(modefrm_pcage) = 2
     346     1489176 :       if (ido_nh4a(modetoo_pcage) == 1) ido_nh4a(modefrm_pcage) = 2
     347     2978352 :       do jsoa = 1, nsoa
     348     2978352 :          if (ido_soaa(modetoo_pcage,jsoa) == 1) ido_soaa(modefrm_pcage,jsoa) = 2
     349             :       end do
     350     5956704 :       do iq = 1, nspecfrm_pcage
     351     4467528 :          lsfrm = lspecfrm_pcage(iq)-loffset
     352     4467528 :          lstoo = lspectoo_pcage(iq)-loffset
     353     5956704 :          if ((lsfrm > 0) .and. (lsfrm <= pcnst)) then
     354     4467528 :             dotend(lsfrm) = .true.
     355     4467528 :             if ((lstoo > 0) .and. (lstoo <= pcnst)) then
     356     4467528 :                dotend(lstoo) = .true.
     357             :             end if
     358             :          end if
     359             :       end do
     360             : 
     361             : 
     362     1489176 :       n = modeptr_pcarbon
     363     1489176 :       fac_volsfc_pcarbon = exp( 2.5_r8*(alnsg_amode(n)**2) )
     364     1489176 :       xferfrac_max = 1.0_r8 - 10.0_r8*epsilon(1.0_r8)   ! 1-eps
     365             :    end if
     366             : 
     367             : 
     368             : ! zero out tendencies and other
     369 71735685840 :    dqdt(:,:,:) = 0.0_r8
     370 71735685840 :    dqqcwdt(:,:,:) = 0.0_r8
     371     1489176 :    qsrflx(:,:,:) = 0.0_r8
     372     1489176 :    qqcwsrflx(:,:,:) = 0.0_r8
     373             : 
     374             : !-------Initialize evap/cond diagnostics (ncols x pver)-----------
     375     1489176 :    qconff(:,:) = 0.0_r8
     376     1489176 :    qevapff(:,:) = 0.0_r8
     377     1489176 :    qconbb(:,:) = 0.0_r8
     378     1489176 :    qevapbb(:,:) = 0.0_r8
     379     1489176 :    qconbg(:,:) = 0.0_r8
     380     1489176 :    qevapbg(:,:) = 0.0_r8
     381     1489176 :    qcon(:,:) = 0.0_r8
     382     1489176 :    qevap(:,:) = 0.0_r8
     383             : !---------------------------------------------------
     384             : 
     385             : ! compute gas-to-aerosol mass transfer rates
     386             :    call gas_aer_uptkrates( ncol,       loffset,                &
     387             :                            q,          t,          pmid,       &
     388     1489176 :                            dgncur_awet,            uptkrate    )
     389             : 
     390             : 
     391             : ! use this for tendency calcs to avoid generating very small negative values
     392     1489176 :    deltatxx = deltat * (1.0_r8 + 1.0e-15_r8)
     393             : 
     394             : 
     395     1489176 :    jsrf = jsrflx_gaexch
     396   139982544 :    do k=top_lev,pver
     397  2314006344 :       do i=1,ncol
     398             : 
     399             : !   fgain_so4(n) = fraction of total h2so4 uptake going to mode n
     400             : !   fgain_nh4(n) = fraction of total  nh3  uptake going to mode n
     401  4348047600 :          sum_uprt_so4 = 0.0_r8
     402  4348047600 :          sum_uprt_nh4 = 0.0_r8
     403  4348047600 :          sum_uprt_soa = 0.0_r8
     404 10870119000 :          do n = 1, ntot_amode
     405  8696095200 :             uptkratebb(n) = uptkrate(n,i,k)
     406  8696095200 :             if (ido_so4a(n) > 0) then
     407  8696095200 :                fgain_so4(n) = uptkratebb(n)
     408  8696095200 :                sum_uprt_so4 = sum_uprt_so4 + fgain_so4(n)
     409  8696095200 :                if (ido_so4a(n) == 1) then
     410  6522071400 :                   qold_so4(n) = q(i,k,lptr_so4_a_amode(n)-loffset)
     411             :                else
     412  2174023800 :                   qold_so4(n) = 0.0_r8
     413             :                end if
     414             :             else
     415           0 :                fgain_so4(n) = 0.0_r8
     416           0 :                qold_so4(n) = 0.0_r8
     417             :             end if
     418             : 
     419  8696095200 :             if (ido_nh4a(n) > 0) then
     420             :                !   2.08 factor is for gas diffusivity (nh3/h2so4)
     421             :                !   differences in fuch-sutugin and accom coef ignored
     422           0 :                fgain_nh4(n) = uptkratebb(n)*2.08_r8
     423           0 :                sum_uprt_nh4 = sum_uprt_nh4 + fgain_nh4(n)
     424           0 :                if (ido_nh4a(n) == 1) then
     425           0 :                   qold_nh4(n) = q(i,k,lptr_nh4_a_amode(n)-loffset)
     426             :                else
     427           0 :                   qold_nh4(n) = 0.0_r8
     428             :                end if
     429             :             else
     430  8696095200 :                fgain_nh4(n) = 0.0_r8
     431  8696095200 :                qold_nh4(n) = 0.0_r8
     432             :             end if
     433             : 
     434 17392190400 :             do j = 1, npoa
     435  8696095200 :                l = lptr2_pom_a_amode(n,j)-loffset
     436 17392190400 :                if (l > 0) then
     437  4348047600 :                   qold_poa(n,j) = q(i,k,l)
     438             :                else
     439  4348047600 :                   qold_poa(n,j) = 0.0_r8
     440             :                end if
     441             :             end do
     442             : 
     443  8696095200 :             itmpa = 0
     444 17392190400 :             do jsoa = 1, nsoa
     445  8696095200 :                if (ido_soaa(n,jsoa) > 0) then
     446             :                   ! 0.81 factor is for gas diffusivity (soa/h2so4)
     447             :                   ! (differences in fuch-sutugin and accom coef ignored)
     448  6522071400 :                   fgain_soa(n,jsoa) = uptkratebb(n)*0.81_r8
     449  6522071400 :                   sum_uprt_soa(jsoa) = sum_uprt_soa(jsoa) + fgain_soa(n,jsoa)
     450  6522071400 :                   if (ido_soaa(n,jsoa) == 1) then
     451  4348047600 :                      l = lptr2_soa_a_amode(n,jsoa)-loffset
     452  4348047600 :                      qold_soa(n,jsoa) = q(i,k,l)
     453  4348047600 :                      itmpa = itmpa + 1
     454             :                   else
     455  2174023800 :                      qold_soa(n,jsoa) = 0.0_r8
     456             :                   end if
     457             :                else
     458  2174023800 :                   fgain_soa(n,jsoa) = 0.0_r8
     459  2174023800 :                   qold_soa(n,jsoa) = 0.0_r8
     460             :                end if
     461 17392190400 :                uptkrate_soa(n,jsoa) = fgain_soa(n,jsoa)
     462             :             end do ! jsoa
     463             :             ! in previous code versions with nsoa=1,
     464             :             !    qold_poa was non-zero (i.e., loaded from q) only when ido_soaa(n)=1
     465             :             ! thus qold_poa=0 for the primary carbon mode which has ido_soaa=2
     466             :             ! this is probably not how it should be
     467 15218166600 :             if (itmpa == 0) qold_poa(n,:) = 0.0_r8
     468             : 
     469             :          end do ! n
     470             : 
     471  2174023800 :          if (sum_uprt_so4 > 0.0_r8) then
     472 10870119000 :             do n = 1, ntot_amode
     473 10870119000 :                fgain_so4(n) = fgain_so4(n) / sum_uprt_so4
     474             :             end do
     475             :          end if
     476             : !       at this point (sum_uprt_so4 <= 0.0) only when all the fgain_so4 are zero
     477  2174023800 :          if (sum_uprt_nh4 > 0.0_r8) then
     478           0 :             do n = 1, ntot_amode
     479           0 :                fgain_nh4(n) = fgain_nh4(n) / sum_uprt_nh4
     480             :             end do
     481             :          end if
     482             : 
     483  4348047600 :          do jsoa = 1, nsoa
     484  4348047600 :             if (sum_uprt_soa(jsoa) > 0.0_r8) then
     485 10870119000 :                do n = 1, ntot_amode
     486 10870119000 :                   fgain_soa(n,jsoa) = fgain_soa(n,jsoa) / sum_uprt_soa(jsoa)
     487             :                end do
     488             :             end if
     489             :          end do
     490             : 
     491             : !   uptake amount (fraction of gas uptaken) over deltat
     492  2174023800 :          avg_uprt_so4 = (1.0_r8 - exp(-deltatxx*sum_uprt_so4))/deltatxx
     493  2174023800 :          avg_uprt_nh4 = (1.0_r8 - exp(-deltatxx*sum_uprt_nh4))/deltatxx
     494             : 
     495  4348047600 :          do jsoa = 1, nsoa
     496  4348047600 :             avg_uprt_soa(jsoa) = (1.0_r8 - exp(-deltatxx*sum_uprt_soa(jsoa)))/deltatxx
     497             :          end do
     498             : 
     499             : !   sum_dqdt_so4 = so4_a tendency from h2so4 gas uptake (mol/mol/s)
     500             : !   sum_dqdt_msa = msa_a tendency from msa   gas uptake (mol/mol/s)
     501             : !   sum_dqdt_nh4 = nh4_a tendency from nh3   gas uptake (mol/mol/s)
     502             : !   sum_dqdt_soa = soa_a tendency from soa   gas uptake (mol/mol/s)
     503  2174023800 :          sum_dqdt_so4 = q(i,k,l_so4g) * avg_uprt_so4
     504  2174023800 :          if ( do_msag ) then
     505           0 :             sum_dqdt_msa = q(i,k,l_msag) * avg_uprt_so4
     506             :          else
     507             :             sum_dqdt_msa = 0.0_r8
     508             :          end if
     509  2174023800 :          if ( do_nh4g ) then
     510           0 :             sum_dqdt_nh4 = q(i,k,l_nh4g) * avg_uprt_nh4
     511             :          else
     512             :             sum_dqdt_nh4 = 0.0_r8
     513             :          end if
     514             : 
     515  4348047600 :          do jsoa = 1, nsoa
     516  4348047600 :             if ( do_soag(jsoa) ) then
     517  2174023800 :                sum_dqdt_soa(jsoa) = q(i,k,l_soag(jsoa)) * avg_uprt_soa(jsoa)
     518             :             else
     519           0 :                sum_dqdt_soa(jsoa) = 0.0_r8
     520             :             end if
     521             :          end do
     522             : 
     523  2174023800 :          if ( associated(sulfeq) .and. (k <= troplev(i)) ) then
     524             :             !   compute TMR tendencies for so4 interstial aerosol due to reversible gas uptake
     525             :             !   only above the tropopause
     526             : 
     527           0 :             tmp_kxt = deltatxx*sum_uprt_so4  ! sum over modes of uptake_rate*deltat
     528           0 :             tmp_pxt = 0.0_r8
     529           0 :             do n = 1, ntot_amode
     530           0 :                if (ido_so4a(n) <= 0) cycle
     531           0 :                tmp_pxt = tmp_pxt + uptkratebb(n)*sulfeq(i,k,n)
     532             :             end do
     533           0 :             tmp_pxt = max( 0.0_r8, tmp_pxt*deltatxx )  ! sum over modes of uptake_rate*sulfeq*deltat
     534           0 :             tmp_so4g_bgn = q(i,k,l_so4g)
     535             :             ! calc avg h2so4(g) over deltat
     536           0 :             if (tmp_kxt >= 1.0e-5_r8) then
     537             :                ! exponential decay towards equilibrium value solution
     538           0 :                tmp_so4g_equ = tmp_pxt/tmp_kxt
     539           0 :                tmp_so4g_avg = tmp_so4g_equ + (tmp_so4g_bgn-tmp_so4g_equ)*(1.0_r8-exp(-tmp_kxt))/tmp_kxt
     540             :             else
     541             :                ! first order approx for tmp_kxt small
     542           0 :                tmp_so4g_avg = tmp_so4g_bgn*(1.0_r8-0.5_r8*tmp_kxt) + 0.5_r8*tmp_pxt
     543             :             end if
     544           0 :             sum_dqdt_so4 = 0.0_r8
     545           0 :             do n = 1, ntot_amode
     546           0 :                if (ido_so4a(n) <= 0) cycle
     547             :                ! calc change to so4(a) in mode n
     548           0 :                if (ido_so4a(n) == 1) then
     549           0 :                   l = lptr_so4_a_amode(n)-loffset
     550           0 :                   tmp_so4a_bgn = q(i,k,l)
     551             :                else
     552             :                   tmp_so4a_bgn = 0.0_r8
     553             :                end if
     554           0 :                tmp_so4a_end = tmp_so4a_bgn + deltatxx*uptkratebb(n)*(tmp_so4g_avg-sulfeq(i,k,n))
     555           0 :                tmp_so4a_end = max( 0.0_r8, tmp_so4a_end )
     556           0 :                dqdt_so4(n) = (tmp_so4a_end - tmp_so4a_bgn)/deltatxx
     557           0 :                sum_dqdt_so4 = sum_dqdt_so4 + dqdt_so4(n)
     558             :             end do
     559             :             ! do not allow msa condensation in stratosphere
     560             :             ! ( Note that the code for msa has never been used.
     561             :             !   The plan was to simulate msa(g), treat it as non-volatile (like h2so4(g)),
     562             :             !   and treat condensed msa as sulfate, so just one additional tracer. )
     563           0 :             if ( do_msag ) sum_dqdt_msa = 0.0_r8
     564             : 
     565             :          else
     566             :             !   compute TMR tendencies for so4 interstial aerosol due to simple gas uptake
     567 10870119000 :             do n = 1, ntot_amode
     568 10870119000 :                dqdt_so4(n) = fgain_so4(n)*(sum_dqdt_so4 + sum_dqdt_msa)
     569             :             end do
     570             :          end if
     571             : 
     572             :          !   compute TMR tendencies for nh4 interstial aerosol due to simple gas uptake
     573             :          !   but force nh4/so4 molar ratio <= 2
     574  2174023800 :          sum_dqdt_nh4_b = 0.0_r8
     575 10870119000 :          dqdt_nh4(:) = 0._r8
     576  2174023800 :          if ( do_nh4g ) then
     577           0 :             do n = 1, ntot_amode
     578           0 :                dqdt_nh4(n) = fgain_nh4(n)*sum_dqdt_nh4
     579           0 :                qnew_nh4 = qold_nh4(n) + dqdt_nh4(n)*deltat
     580           0 :                qnew_so4 = qold_so4(n) + dqdt_so4(n)*deltat
     581           0 :                qmax_nh4 = 2.0_r8*qnew_so4
     582           0 :                if (qnew_nh4 > qmax_nh4) then
     583           0 :                   dqdt_nh4(n) = (qmax_nh4 - qold_nh4(n))/deltatxx
     584             :                end if
     585           0 :                sum_dqdt_nh4_b = sum_dqdt_nh4_b + dqdt_nh4(n)
     586             :             end do
     587             :          end if
     588             : 
     589  2174023800 :          if (( do_soag_any ) .and. (method_soa > 1)) then
     590             : !   compute TMR tendencies for soag and soa interstial aerosol
     591             : !   using soa parameterization
     592  2174023800 :             niter_max = 1000
     593 13044142800 :             dqdt_soa(:,:) = 0.0_r8
     594  4348047600 :             dqdt_soag(:) = 0.0_r8
     595  4348047600 :             do jsoa = 1, nsoa
     596  4348047600 :                qold_soag(jsoa) = q(i,k,l_soag(jsoa))
     597             :             end do
     598             : 
     599             :             ! get molecular weight from the host model
     600 10870119000 :             do n = 1, ntot_amode
     601 43480476000 :               do l = 1, nspec_amode(n)
     602 32610357000 :                   call rad_cnst_get_info(0, n, l, spec_type=spec_type )
     603  8696095200 :                   select case( spec_type )
     604             :                    case('s-organic')
     605  8696095200 :                      mw_soa_host(:) = specmw_amode(l,n)
     606             :                    case('p-organic')
     607 36958404600 :                      mw_poa_host(:) = specmw_amode(l,n)
     608             :                    end select
     609             :                end do
     610             :             end do
     611             : 
     612             :             call modal_aero_soaexch( deltat, t(i,k), pmid(i,k), &
     613             :                  niter, niter_max, ntot_amode, ntot_soamode, npoa, nsoa, &
     614             :                  mw_poa_host, mw_soa_host, &
     615             :                  qold_soag, qold_soa, qold_poa, uptkrate_soa, &
     616  2174023800 :                  dqdt_soag, dqdt_soa )
     617  4348047600 :             sum_dqdt_soa(:) = -dqdt_soag(:)
     618             : 
     619             :          else if ( do_soag_any ) then
     620             : !   compute TMR tendencies for soa interstial aerosol
     621             : !   due to simple gas uptake
     622             : 
     623             :             do jsoa = 1, nsoa
     624             :                do n = 1, ntot_amode
     625             :                   dqdt_soa(n,jsoa) = fgain_soa(n,jsoa)*sum_dqdt_soa(jsoa)
     626             :                end do
     627             :             end do
     628             :          else ! method_soa is neither 1 nor 2, no uptake
     629           0 :             dqdt_soa(:,:) = 0.0_r8
     630             :          end if
     631             : 
     632  2174023800 :          pdel_fac = pdel(i,k)/gravit
     633 10870119000 :          do n = 1, ntot_amode
     634  8696095200 :             if (ido_so4a(n) == 1) then
     635  6522071400 :                l = lptr_so4_a_amode(n)-loffset
     636  6522071400 :                dqdt(i,k,l) = dqdt_so4(n)
     637  6522071400 :                qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt_so4(n)*pdel_fac
     638             :             end if
     639             : 
     640  8696095200 :             if ( do_nh4g ) then
     641           0 :                if (ido_nh4a(n) == 1) then
     642           0 :                   l = lptr_nh4_a_amode(n)-loffset
     643           0 :                   dqdt(i,k,l) = dqdt_nh4(n)
     644           0 :                   qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt_nh4(n)*pdel_fac
     645             :                end if
     646             :             end if
     647             : 
     648 19566214200 :             do jsoa = 1, nsoa
     649 17392190400 :                if ( do_soag(jsoa) ) then
     650  8696095200 :                   if (ido_soaa(n,jsoa) == 1) then
     651  4348047600 :                      l = lptr2_soa_a_amode(n,jsoa)-loffset
     652  4348047600 :                      dqdt(i,k,l) = dqdt_soa(n,jsoa) !calculated by  modal_aero_soaexch for method_soa=2
     653  4348047600 :                      qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt_soa(n,jsoa)*pdel_fac
     654             : !------- Add code for condensation/evaporation diagnostics---
     655  4348047600 :                      if (nsoa.eq.15) then !check for current SOA package
     656           0 :                         if(jsoa.ge.1.and.jsoa.le.5) then ! Fossil SOA species
     657           0 :                            if (dqdt_soa(n,jsoa).ge.0.0_r8) then
     658           0 :                               qconff(i,k)=qconff(i,k)+dqdt_soa(n,jsoa)*(adv_mass(l)/mwdry)
     659           0 :                            elseif(dqdt_soa(n,jsoa).lt.0.0_r8) then
     660           0 :                               qevapff(i,k)=qevapff(i,k)+dqdt_soa(n,jsoa)*(adv_mass(l)/mwdry)
     661             :                            endif
     662             : 
     663           0 :                         elseif(jsoa.ge.6.and.jsoa.le.10) then ! Biomass SOA species
     664           0 :                            if (dqdt_soa(n,jsoa).ge.0.0_r8) then
     665           0 :                               qconbb(i,k)=qconbb(i,k)+dqdt_soa(n,jsoa)*(adv_mass(l)/mwdry)
     666           0 :                            elseif(dqdt_soa(n,jsoa).lt.0.0_r8) then
     667           0 :                               qevapbb(i,k)=qevapbb(i,k)+dqdt_soa(n,jsoa)*(adv_mass(l)/mwdry)
     668             :                            endif
     669             : 
     670           0 :                         elseif(jsoa.ge.11.and.jsoa.le.15) then ! Biomass SOA species
     671           0 :                            if (dqdt_soa(n,jsoa).ge.0.0_r8) then
     672           0 :                               qconbg(i,k)=qconbg(i,k)+dqdt_soa(n,jsoa)*(adv_mass(l)/mwdry)
     673           0 :                            elseif(dqdt_soa(n,jsoa).lt.0.0_r8) then
     674           0 :                               qevapbg(i,k)=qevapbg(i,k)+dqdt_soa(n,jsoa)*(adv_mass(l)/mwdry)
     675             :                            endif
     676             : 
     677             :                         endif ! jsoa
     678             :                      endif !nsoa
     679  4348047600 :                      if (nsoa.eq.5) then !check for current SOA package
     680           0 :                            if (dqdt_soa(n,jsoa).ge.0.0_r8) then
     681           0 :                               qcon(i,k)=qcon(i,k)+dqdt_soa(n,jsoa)*(adv_mass(l)/mwdry)
     682           0 :                            elseif(dqdt_soa(n,jsoa).lt.0.0_r8) then
     683           0 :                               qevap(i,k)=qevap(i,k)+dqdt_soa(n,jsoa)*(adv_mass(l)/mwdry)
     684             :                            endif
     685             :                      endif !nsoa
     686             : !---------------------------------------------------------------------------------------------------------------------
     687             :                   end if
     688             :                end if
     689             :             end do
     690             :          end do ! n
     691             : 
     692             : !   compute TMR tendencies for h2so4, nh3, and msa gas
     693             : !   due to simple gas uptake
     694  2174023800 :          l = l_so4g
     695  2174023800 :          dqdt(i,k,l) = -sum_dqdt_so4
     696  2174023800 :          qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt(i,k,l)*pdel_fac
     697             : 
     698  2174023800 :          if ( do_msag ) then
     699           0 :             l = l_msag
     700           0 :             dqdt(i,k,l) = -sum_dqdt_msa
     701           0 :             qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt(i,k,l)*pdel_fac
     702             :          end if
     703             : 
     704  2174023800 :          if ( do_nh4g ) then
     705           0 :             l = l_nh4g
     706           0 :             dqdt(i,k,l) = -sum_dqdt_nh4_b
     707           0 :             qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt(i,k,l)*pdel_fac
     708             :          end if
     709             : 
     710  4348047600 :          do jsoa = 1, nsoa
     711  4348047600 :             if ( do_soag(jsoa) ) then
     712  2174023800 :                l = l_soag(jsoa)
     713  2174023800 :                dqdt(i,k,l) = -sum_dqdt_soa(jsoa)
     714             : ! dqdt for gas is negative of the sum of dqdt for aerosol soa species in each mode: Manish
     715  2174023800 :                qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt(i,k,l)*pdel_fac
     716             :             end if
     717             :          end do
     718             : 
     719             : !   compute TMR tendencies associated with primary carbon aging
     720  2312517168 :          if (modefrm_pcage > 0) then
     721  2174023800 :             n = modeptr_pcarbon
     722  2174023800 :             tmpa = 0.0_r8
     723  4348047600 :             do jsoa = 1, nsoa
     724  4348047600 :                tmpa = tmpa + dqdt_soa(n,jsoa)*fac_m2v_soa(jsoa)*soa_equivso4_factor(jsoa)
     725             :             end do
     726             :             vol_shell = deltat *   &
     727  2174023800 :                  ( dqdt_so4(n)*fac_m2v_so4 + dqdt_nh4(n)*fac_m2v_nh4 + tmpa )
     728  2174023800 :             vol_core = 0.0_r8
     729  6522071400 :             do l = 1, nspec_amode(n)
     730             :                vol_core = vol_core + &
     731  6522071400 :                     q(i,k,lmassptr_amode(l,n)-loffset)*fac_m2v_pcarbon(l)
     732             :             end do
     733             : !   ratio1 = vol_shell/vol_core =
     734             : !      actual hygroscopic-shell-volume/carbon-core-volume after gas uptake
     735             : !   ratio2 = 6.0_r8*dr_so4_monolayers_pcage/(dgncur_a*fac_volsfc_pcarbon)
     736             : !      = (shell-volume corresponding to n_so4_monolayers_pcage)/core-volume
     737             : !      The 6.0/(dgncur_a*fac_volsfc_pcarbon) = (mode-surface-area/mode-volume)
     738             : !   Note that vol_shell includes both so4+nh4 AND soa as "equivalent so4",
     739             : !      The soa_equivso4_factor accounts for the lower hygroscopicity of soa.
     740             : !
     741             : !   Define xferfrac_pcage = min( 1.0, ratio1/ratio2)
     742             : !   But ratio1/ratio2 == tmp1/tmp2, and coding below avoids possible overflow
     743             : !
     744  2174023800 :             tmp1 = vol_shell*dgncur_a(i,k,n)*fac_volsfc_pcarbon
     745  2174023800 :             tmp2 = max( 6.0_r8*dr_so4_monolayers_pcage*vol_core, 0.0_r8 )
     746  2174023800 :             if (tmp1 >= tmp2) then
     747             :                xferfrac_pcage = xferfrac_max
     748             :             else
     749  2173297671 :                xferfrac_pcage = min( tmp1/tmp2, xferfrac_max )
     750             :             end if
     751             : 
     752  2174023800 :             if (xferfrac_pcage > 0.0_r8) then
     753  8696095200 :                do iq = 1, nspecfrm_pcage
     754  6522071400 :                   lsfrm = lspecfrm_pcage(iq)-loffset
     755  6522071400 :                   lstoo = lspectoo_pcage(iq)-loffset
     756  6522071400 :                   xferrate = (xferfrac_pcage/deltat)*q(i,k,lsfrm)
     757  6522071400 :                   dqdt(i,k,lsfrm) = dqdt(i,k,lsfrm) - xferrate
     758  6522071400 :                   qsrflx(i,lsfrm,jsrf) = qsrflx(i,lsfrm,jsrf) - xferrate*pdel_fac
     759  8696095200 :                   if ((lstoo > 0) .and. (lstoo <= pcnst)) then
     760  6522071400 :                      dqdt(i,k,lstoo) = dqdt(i,k,lstoo) + xferrate
     761  6522071400 :                      qsrflx(i,lstoo,jsrf) = qsrflx(i,lstoo,jsrf) + xferrate*pdel_fac
     762             :                   end if
     763             :                end do
     764             : 
     765  2174023800 :                if (ido_so4a(modetoo_pcage) > 0) then
     766  2174023800 :                   l = lptr_so4_a_amode(modetoo_pcage)-loffset
     767  2174023800 :                   dqdt(i,k,l) = dqdt(i,k,l) + dqdt_so4(modefrm_pcage)
     768  2174023800 :                   qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt_so4(modefrm_pcage)*pdel_fac
     769             :                end if
     770             : 
     771  2174023800 :                if (ido_nh4a(modetoo_pcage) > 0) then
     772           0 :                   l = lptr_nh4_a_amode(modetoo_pcage)-loffset
     773           0 :                   dqdt(i,k,l) = dqdt(i,k,l) + dqdt_nh4(modefrm_pcage)
     774           0 :                   qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt_nh4(modefrm_pcage)*pdel_fac
     775             :                end if
     776             : 
     777  4348047600 :                do jsoa = 1, nsoa
     778  4348047600 :                   if (ido_soaa(modetoo_pcage,jsoa) > 0) then
     779  2174023800 :                      l = lptr2_soa_a_amode(modetoo_pcage,jsoa)-loffset
     780  2174023800 :                      dqdt(i,k,l) = dqdt(i,k,l) + dqdt_soa(modefrm_pcage,jsoa)
     781  2174023800 :                      qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf) + dqdt_soa(modefrm_pcage,jsoa)*pdel_fac
     782             :                   end if
     783             :                end do
     784             : 
     785             :             end if
     786             : 
     787             :          end if
     788             : 
     789             :       end do   ! "i = 1, ncol"
     790             :    end do     ! "k = top_lev, pver"
     791             : 
     792             : ! set "temporary testing arrays"
     793 71735685840 :    qold(:,:,:) = q(:,:,:)
     794 71735685840 :    qqcwold(:,:,:) = qqcw(:,:,:)
     795 71735685840 :    dqdtsv1(:,:,:) = dqdt(:,:,:)
     796 71735685840 :    dqqcwdtsv1(:,:,:) = dqqcwdt(:,:,:)
     797             : 
     798             : 
     799             : !
     800             : ! do renaming calcs
     801             : !
     802     1489176 :    dotendrn(:) = .false.
     803     1489176 :    dotendqqcwrn(:) = .false.
     804  2314006344 :    dorename_atik(1:ncol,:) = .true.
     805     1489176 :    is_dorename_atik = .true.
     806             :    call modal_aero_rename_sub(                              &
     807             :         'modal_aero_gasaerexch_sub',            &
     808             :         lchnk,             ncol,      nstep,    &
     809             :         loffset,           deltat,              &
     810             :         pdel,              troplev,             &
     811             :         dotendrn,          q,                   &
     812             :         dqdt,              dqdt_other,          &
     813             :         dotendqqcwrn,      qqcw,                &
     814             :         dqqcwdt,           dqqcwdt_other,       &
     815             :         is_dorename_atik,  dorename_atik,       &
     816             :         jsrflx_rename,     nsrflx,              &
     817     1489176 :         qsrflx,            qqcwsrflx            )
     818             : 
     819             : 
     820             : !  This applies dqdt tendencies for all species
     821             : !  apply the dqdt to update q (and same for qqcw)
     822             : !
     823    47653632 :    do l = 1, pcnstxx
     824    46164456 :       if ( dotend(l) .or. dotendrn(l) ) then
     825  2939633424 :          do k = top_lev, pver
     826 48594133224 :             do i = 1, ncol
     827 48562860528 :                q(i,k,l) = q(i,k,l) + dqdt(i,k,l)*deltat
     828             :             end do
     829             :          end do
     830             :       end if
     831    47653632 :       if ( dotendqqcw(l) .or. dotendqqcwrn(l) ) then
     832  1959755616 :          do k = top_lev, pver
     833 32396088816 :             do i = 1, ncol
     834 32375240352 :                qqcw(i,k,l) = qqcw(i,k,l) + dqqcwdt(i,k,l)*deltat
     835             :             end do
     836             :          end do
     837             :       end if
     838             :    end do
     839             : 
     840             : ! diagnostics start -------------------------------------------------------
     841             : !!$   if (ldiag3 > 0) then
     842             : !!$   if (icol_diag > 0) then
     843             : !!$      i = icol_diag
     844             : !!$      write(*,'(a,3i5)') 'gasaerexch ppp nstep,lat,lon', nstep, latndx(i), lonndx(i)
     845             : !!$      write(*,'(2i5,3(2x,a))') 0, 0, 'ppp', 'pdel for all k'
     846             : !!$      write(*,'(1p,7e12.4)') (pdel(i,k), k=top_lev,pver)
     847             : !!$
     848             : !!$      write(*,'(a,3i5)') 'gasaerexch ddd nstep,lat,lon', nstep, latndx(i), lonndx(i)
     849             : !!$      do l = 1, pcnstxx
     850             : !!$         lb = l + loffset
     851             : !!$
     852             : !!$         if ( dotend(l) .or. dotendrn(l) ) then
     853             : !!$            write(*,'(2i5,3(2x,a))') 1, l, 'ddd1', cnst_name(lb),    'qold for all k'
     854             : !!$            write(*,'(1p,7e12.4)') (qold(i,k,l), k=top_lev,pver)
     855             : !!$            write(*,'(2i5,3(2x,a))') 1, l, 'ddd2', cnst_name(lb),    'qnew for all k'
     856             : !!$            write(*,'(1p,7e12.4)') (q(i,k,l), k=top_lev,pver)
     857             : !!$            write(*,'(2i5,3(2x,a))') 1, l, 'ddd3', cnst_name(lb),    'dqdt from conden for all k'
     858             : !!$            write(*,'(1p,7e12.4)') (dqdtsv1(i,k,l), k=top_lev,pver)
     859             : !!$            write(*,'(2i5,3(2x,a))') 1, l, 'ddd4', cnst_name(lb),    'dqdt from rename for all k'
     860             : !!$            write(*,'(1p,7e12.4)') ((dqdt(i,k,l)-dqdtsv1(i,k,l)), k=top_lev,pver)
     861             : !!$            write(*,'(2i5,3(2x,a))') 1, l, 'ddd5', cnst_name(lb),    'dqdt other for all k'
     862             : !!$            write(*,'(1p,7e12.4)') (dqdt_other(i,k,l), k=top_lev,pver)
     863             : !!$         end if
     864             : !!$
     865             : !!$         if ( dotendqqcw(l) .or. dotendqqcwrn(l) ) then
     866             : !!$            write(*,'(2i5,3(2x,a))') 2, l, 'ddd1', cnst_name_cw(lb), 'qold for all k'
     867             : !!$            write(*,'(1p,7e12.4)') (qqcwold(i,k,l), k=top_lev,pver)
     868             : !!$            write(*,'(2i5,3(2x,a))') 2, l, 'ddd2', cnst_name_cw(lb), 'qnew for all k'
     869             : !!$            write(*,'(1p,7e12.4)') (qqcw(i,k,l), k=top_lev,pver)
     870             : !!$            write(*,'(2i5,3(2x,a))') 2, l, 'ddd3', cnst_name_cw(lb), 'dqdt from conden for all k'
     871             : !!$            write(*,'(1p,7e12.4)') (dqqcwdtsv1(i,k,l), k=top_lev,pver)
     872             : !!$            write(*,'(2i5,3(2x,a))') 2, l, 'ddd4', cnst_name_cw(lb), 'dqdt from rename for all k'
     873             : !!$            write(*,'(1p,7e12.4)') ((dqqcwdt(i,k,l)-dqqcwdtsv1(i,k,l)), k=top_lev,pver)
     874             : !!$            write(*,'(2i5,3(2x,a))') 2, l, 'ddd5', cnst_name_cw(lb), 'dqdt other for all k'
     875             : !!$            write(*,'(1p,7e12.4)') (dqqcwdt_other(i,k,l), k=top_lev,pver)
     876             : !!$         end if
     877             : !!$
     878             : !!$      end do
     879             : !!$
     880             : !!$      write(*,'(a,3i5)') 'gasaerexch fff nstep,lat,lon', nstep, latndx(i), lonndx(i)
     881             : !!$      do l = 1, pcnstxx
     882             : !!$         lb = l + loffset
     883             : !!$         if ( dotend(l) .or. dotendrn(l) .or. dotendqqcw(l) .or. dotendqqcwrn(l) ) then
     884             : !!$            write(*,'(i5,2(2x,a,2l3))') l, &
     885             : !!$               cnst_name(lb), dotend(l), dotendrn(l), &
     886             : !!$               cnst_name_cw(lb), dotendqqcw(l), dotendqqcwrn(l)
     887             : !!$         end if
     888             : !!$      end do
     889             : !!$
     890             : !!$   end if
     891             : !!$   end if
     892             : ! diagnostics end ---------------------------------------------------------
     893             : 
     894             : !-----Outfld for condensation/evaporation------------------------------
     895     1489176 :    if (nsoa.eq.5) then !check for current SOA package
     896           0 :       call outfld(trim('qcon_gaex'), qcon(:,:), pcols, lchnk )
     897           0 :       call outfld(trim('qevap_gaex'), qevap(:,:), pcols, lchnk )
     898             :    endif
     899             : !-----------------------------------------------------------------------
     900     1489176 :    if (nsoa.eq.15) then !check for current SOA package
     901           0 :       call outfld(trim('qconff_gaex'), qconff(:,:), pcols, lchnk )
     902           0 :       call outfld(trim('qevapff_gaex'), qevapff(:,:), pcols, lchnk )
     903           0 :       call outfld(trim('qconbb_gaex'), qconbb(:,:), pcols, lchnk )
     904           0 :       call outfld(trim('qevapbb_gaex'), qevapbb(:,:), pcols, lchnk )
     905           0 :       call outfld(trim('qconbg_gaex'), qconbg(:,:), pcols, lchnk )
     906           0 :       call outfld(trim('qevapbg_gaex'), qevapbg(:,:), pcols, lchnk )
     907             :    endif
     908             : !-----------------------------------------------------------------------
     909             : 
     910             : !   do history file column-tendency fields
     911    47653632 :    do l = 1, pcnstxx
     912    46164456 :       lb = l + loffset
     913   139982544 :       do jsrf = 1, 2
     914   323151192 :          do jac = 1, 2
     915   276986736 :             if (jac == 1) then
     916    92328912 :                if (jsrf == jsrflx_gaexch) then
     917    46164456 :                   if ( .not. dotend(l) ) cycle
     918    19359288 :                   fieldname = trim(cnst_name(lb)) // '_sfgaex1'
     919    46164456 :                else if (jsrf == jsrflx_rename) then
     920    46164456 :                   if ( .not. dotendrn(l) ) cycle
     921    20848464 :                   fieldname = trim(cnst_name(lb)) // '_sfgaex2'
     922             :                else
     923             :                   cycle
     924             :                end if
     925   671375952 :                do i = 1, ncol
     926   671375952 :                   qsrflx(i,l,jsrf) = qsrflx(i,l,jsrf)*(adv_mass(l)/mwdry)
     927             :                end do
     928    40207752 :                call outfld( fieldname, qsrflx(:,l,jsrf), pcols, lchnk )
     929             :             else
     930    92328912 :                if (jsrf == jsrflx_gaexch) then
     931             :                   cycle
     932    46164456 :                else if (jsrf == jsrflx_rename) then
     933    46164456 :                   if ( .not. dotendqqcwrn(l) ) cycle
     934    20848464 :                   fieldname = trim(cnst_name_cw(lb)) // '_sfgaex2'
     935             :                else
     936             :                   cycle
     937             :                end if
     938   348120864 :                do i = 1, ncol
     939   348120864 :                   qqcwsrflx(i,l,jsrf) = qqcwsrflx(i,l,jsrf)*(adv_mass(l)/mwdry)
     940             :                end do
     941    20848464 :                call outfld( fieldname, qqcwsrflx(:,l,jsrf), pcols, lchnk )
     942             :             end if
     943             :          end do ! jac = ...
     944             :       end do ! jsrf = ...
     945             :    end do ! l = ...
     946             : 
     947     1489176 :    return
     948     1489176 :    end subroutine modal_aero_gasaerexch_sub
     949             : 
     950             : 
     951             : !----------------------------------------------------------------------
     952             : !----------------------------------------------------------------------
     953     1489176 : subroutine gas_aer_uptkrates( ncol,       loffset,                &
     954     1489176 :                               q,          t,          pmid,       &
     955     1489176 :                               dgncur_awet,            uptkrate    )
     956             : 
     957             : !
     958             : !                         /
     959             : !   computes   uptkrate = | dx  dN/dx  gas_conden_rate(Dp(x))
     960             : !                         /
     961             : !   using Gauss-Hermite quadrature of order nghq=2
     962             : !
     963             : !       Dp = particle diameter (cm)
     964             : !       x = ln(Dp)
     965             : !       dN/dx = log-normal particle number density distribution
     966             : !       gas_conden_rate(Dp) = 2 * pi * gasdiffus * Dp * F(Kn,ac)
     967             : !           F(Kn,ac) = Fuchs-Sutugin correction factor
     968             : !           Kn = Knudsen number
     969             : !           ac = accomodation coefficient
     970             : !
     971             : 
     972     1489176 : use physconst, only: mwdry, rair
     973             : 
     974             : implicit none
     975             : 
     976             : 
     977             :    integer,  intent(in) :: ncol                 ! number of atmospheric column
     978             :    integer,  intent(in) :: loffset
     979             :    real(r8), intent(in) :: q(ncol,pver,pcnstxx) ! Tracer array (mol,#/mol-air)
     980             :    real(r8), intent(in) :: t(pcols,pver)        ! Temperature in Kelvin
     981             :    real(r8), intent(in) :: pmid(pcols,pver)     ! Air pressure in Pa
     982             :    real(r8), intent(in) :: dgncur_awet(pcols,pver,ntot_amode)
     983             : 
     984             :    real(r8), intent(out) :: uptkrate(ntot_amode,pcols,pver)
     985             :                             ! gas-to-aerosol mass transfer rates (1/s)
     986             : 
     987             : 
     988             : ! local
     989             :    integer, parameter :: nghq = 2
     990             :    integer :: i, iq, k, l1, l2, la, n
     991             : 
     992             :    ! Can use sqrt here once Lahey is gone.
     993             :    real(r8), parameter :: tworootpi = 3.5449077_r8
     994             :    real(r8), parameter :: root2 = 1.4142135_r8
     995             :    real(r8), parameter :: beta = 2.0_r8
     996             : 
     997             :    real(r8) :: aircon
     998             :    real(r8) :: const
     999             :    real(r8) :: dp, dum_m2v
    1000             :    real(r8) :: dryvol_a(pcols,pver)
    1001             :    real(r8) :: gasdiffus, gasspeed
    1002             :    real(r8) :: freepathx2, fuchs_sutugin
    1003             :    real(r8) :: knudsen
    1004             :    real(r8) :: lndp, lndpgn, lnsg
    1005             :    real(r8) :: num_a
    1006             :    real(r8) :: rhoair
    1007             :    real(r8) :: sumghq
    1008             :    real(r8), save :: xghq(nghq), wghq(nghq) ! quadrature abscissae and weights
    1009             : 
    1010             :    data xghq / 0.70710678_r8, -0.70710678_r8 /
    1011             :    data wghq / 0.88622693_r8,  0.88622693_r8 /
    1012             : 
    1013             : 
    1014             : ! outermost loop over all modes
    1015     7445880 :    do n = 1, ntot_amode
    1016             : 
    1017             : ! 22-aug-2007 rc easter - get number from q array rather
    1018             : !    than computing a "bounded" number conc.
    1019             : !! compute dry volume = sum_over_components{ component_mass / density }
    1020             : !!    (m3-AP/mol-air)
    1021             : !! compute it for all i,k to improve accessing q array
    1022             : !      dryvol_a(1:ncol,:) = 0.0_r8
    1023             : !      do l1 = 1, nspec_amode(n)
    1024             : !         l2 = lspectype_amode(l1,n)
    1025             : !! dum_m2v converts (kmol-AP/kmol-air) to (m3-AP/kmol-air)
    1026             : !! [m3-AP/kmol-AP]= [kg-AP/kmol-AP]  / [kg-AP/m3-AP]
    1027             : !         dum_m2v = specmw_amode(l2) / specdens_amode(l2)
    1028             : !         la = lmassptr_amode(l1,n)
    1029             : !         dryvol_a(1:ncol,:) = dryvol_a(1:ncol,:)    &
    1030             : !                            + max(0.0_r8,q(1:ncol,:,la))*dum_m2v
    1031             : !      end do
    1032             : 
    1033             : ! loops k and i
    1034   561419352 :       do k=top_lev,pver
    1035  9256025376 :       do i=1,ncol
    1036             : 
    1037  8696095200 :          rhoair = pmid(i,k)/(rair*t(i,k))   ! (kg-air/m3)
    1038             : !        aircon = 1.0e3*rhoair/mwdry        ! (mol-air/m3)
    1039             : 
    1040             : !!   "bounded" number conc. (#/m3)
    1041             : !        num_a = dryvol_a(i,k)*v2ncur_a(i,k,n)*aircon
    1042             : 
    1043             : !   number conc. (#/m3) -- note q(i,k,numptr) is (#/kmol-air)
    1044             : !   so need aircon in (kmol-air/m3)
    1045  8696095200 :          aircon = rhoair/mwdry              ! (kmol-air/m3)
    1046  8696095200 :          num_a = q(i,k,numptr_amode(n)-loffset)*aircon
    1047             : 
    1048             : !   gasdiffus = h2so4 gas diffusivity from mosaic code (m^2/s)
    1049             : !               (pmid must be Pa)
    1050  8696095200 :          gasdiffus = 0.557e-4_r8 * (t(i,k)**1.75_r8) / pmid(i,k)
    1051             : !   gasspeed = h2so4 gas mean molecular speed from mosaic code (m/s)
    1052  8696095200 :          gasspeed  = 1.470e1_r8 * sqrt(t(i,k))
    1053             : !   freepathx2 = 2 * (h2so4 mean free path)  (m)
    1054  8696095200 :          freepathx2 = 6.0_r8*gasdiffus/gasspeed
    1055             : 
    1056  8696095200 :          lnsg   = log( sigmag_amode(n) )
    1057  8696095200 :          lndpgn = log( dgncur_awet(i,k,n) )   ! (m)
    1058  8696095200 :          const  = tworootpi * num_a * exp(beta*lndpgn + 0.5_r8*(beta*lnsg)**2)
    1059             : 
    1060             : !   sum over gauss-hermite quadrature points
    1061  8696095200 :          sumghq = 0.0_r8
    1062 26088285600 :          do iq = 1, nghq
    1063 17392190400 :             lndp = lndpgn + beta*lnsg**2 + root2*lnsg*xghq(iq)
    1064 17392190400 :             dp = exp(lndp)
    1065             : 
    1066             : !   knudsen number
    1067 17392190400 :             knudsen = freepathx2/dp
    1068             : !  Changed by Manish Shrivastava on 7/17/2013 to use accom=1; because we do not know better
    1069             : !   following assumes accomodation coefficient = ac = 1. instead 0.65 ! answer change needs to be tested
    1070             : !   (Adams & Seinfeld, 2002, JGR, and references therein)
    1071             : !           fuchs_sutugin = (0.75*ac*(1. + knudsen)) /
    1072             : !                           (knudsen*(1.0 + knudsen + 0.283*ac) + 0.75*ac)
    1073             :             fuchs_sutugin = (0.4875_r8*(1._r8 + knudsen)) /   &
    1074 17392190400 :                             (knudsen*(1.184_r8 + knudsen) + 0.4875_r8)
    1075 26088285600 :             sumghq = sumghq + wghq(iq)*dp*fuchs_sutugin/(dp**beta)
    1076             :          end do
    1077  9250068672 :          uptkrate(n,i,k) = const * gasdiffus * sumghq
    1078             : 
    1079             :       end do   ! "do i = 1, ncol"
    1080             :       end do   ! "do k = 1, pver"
    1081             : 
    1082             :    end do   ! "do n = 1, ntot_soamode"
    1083             : 
    1084             : 
    1085     1489176 :    return
    1086             :    end subroutine gas_aer_uptkrates
    1087             : 
    1088             : !----------------------------------------------------------------------
    1089             : 
    1090  2174023800 :       subroutine modal_aero_soaexch( dtfull, temp, pres, &
    1091             :           niter, niter_max, ntot_amode, ntot_soamode, ntot_poaspec, ntot_soaspec, &
    1092  2174023800 :           mw_poa_host, mw_soa_host, &
    1093  2174023800 :           g_soa_in, a_soa_in, a_poa_in, xferrate_in, &
    1094  2174023800 :           g_soa_tend, a_soa_tend )
    1095             : !         g_soa_tend, a_soa_tend, g0_soa, idiagss )
    1096             : 
    1097             : !-----------------------------------------------------------------------
    1098             : !
    1099             : ! Purpose:
    1100             : !
    1101             : ! calculates condensation/evaporation of "soa gas"
    1102             : ! to/from multiple aerosol modes in 1 grid cell
    1103             : !
    1104             : ! key assumptions
    1105             : ! (1) ambient equilibrium vapor pressure of soa gas
    1106             : !     is given by p0_soa_298 and delh_vap_soa
    1107             : ! (2) equilibrium vapor pressure of soa gas at aerosol
    1108             : !     particle surface is given by raoults law in the form
    1109             : !     g_star = g0_soa*[a_soa/(a_soa + a_opoa)]
    1110             : ! (3) (oxidized poa)/(total poa) is equal to frac_opoa (constant)
    1111             : !
    1112             : !
    1113             : ! Author: R. Easter and R. Zaveri
    1114             : ! Additions to run with multiple BC, SOA and POM's: Shrivastava et al., 2015
    1115             : !-----------------------------------------------------------------------
    1116             : 
    1117             :       use mo_constants, only: rgas ! Gas constant (J/K/mol)
    1118             : 
    1119             :       implicit none
    1120             : 
    1121             :       real(r8), intent(in)  :: dtfull                     ! full integration time step (s)
    1122             :       real(r8), intent(in)  :: temp                       ! air temperature (K)
    1123             :       real(r8), intent(in)  :: pres                       ! air pressure (Pa)
    1124             :       integer,  intent(out) :: niter                      ! number of iterations performed
    1125             :       integer,  intent(in)  :: niter_max                  ! max allowed number of iterations
    1126             :       integer,  intent(in)  :: ntot_amode                 ! number of modes
    1127             :       integer,  intent(in)  :: ntot_soamode               ! number of modes having soa
    1128             :       integer,  intent(in)  :: ntot_poaspec               ! number of poa species
    1129             :       integer,  intent(in)  :: ntot_soaspec               ! number of soa species
    1130             :       real(r8), intent(in)  :: mw_poa_host(ntot_poaspec)  ! molec wght of poa used in host code
    1131             :       real(r8), intent(in)  :: mw_soa_host(ntot_soaspec)  ! molec wght of poa used in host code
    1132             :       real(r8), intent(in)  :: g_soa_in(ntot_soaspec)               ! initial soa gas mixrat (mol/mol at host mw)
    1133             :       real(r8), intent(in)  :: a_soa_in(ntot_amode,ntot_soaspec)    ! initial soa aerosol mixrat (mol/mol at host mw)
    1134             :       real(r8), intent(in)  :: a_poa_in(ntot_amode,ntot_poaspec)    ! initial poa aerosol mixrat (mol/mol at host mw)
    1135             :       real(r8), intent(in)  :: xferrate_in(ntot_amode,ntot_soaspec) ! gas-aerosol mass transfer rate (1/s)
    1136             :       real(r8), intent(out) :: g_soa_tend(ntot_soaspec)             ! soa gas mixrat tendency (mol/mol/s at host mw)
    1137             :       real(r8), intent(out) :: a_soa_tend(ntot_amode,ntot_soaspec)  ! soa aerosol mixrat tendency (mol/mol/s at host mw)
    1138             : !     integer,  intent(in)  :: idiagss
    1139             : 
    1140             :       integer :: ll
    1141             :       integer :: m,k
    1142             : 
    1143  4348047600 :       logical :: skip_soamode(ntot_amode)   ! true if this mode does not have soa
    1144             : 
    1145             :       real(r8), parameter :: a_min1 = 1.0e-20_r8
    1146             :       real(r8), parameter :: g_min1 = 1.0e-20_r8
    1147             :       real(r8), parameter :: alpha = 0.05_r8     ! parameter used in calc of time step
    1148             :       real(r8), parameter :: dtsub_fixed = -1.0_r8  ! fixed sub-step for time integration (s)
    1149             : 
    1150  4348047600 :       real(r8) :: a_ooa_sum_tmp(ntot_soamode)          ! total ooa (=soa+opoa) in a mode
    1151  4348047600 :       real(r8) :: a_opoa(ntot_soamode)                 ! oxidized-poa aerosol mixrat (mol/mol at actual mw)
    1152  4348047600 :       real(r8) :: a_soa(ntot_soamode,ntot_soaspec)     ! soa aerosol mixrat (mol/mol at actual mw)
    1153  4348047600 :       real(r8) :: a_soa_tmp(ntot_soamode,ntot_soaspec) ! temporary soa aerosol mixrat (mol/mol)
    1154  4348047600 :       real(r8) :: beta(ntot_soamode,ntot_soaspec)      ! dtcur*xferrate
    1155  4348047600 :       real(r8) :: delh_vap_soa(ntot_soaspec)           ! delh_vap_soa = heat of vaporization for gas soa (J/mol)
    1156  4348047600 :       real(r8) :: del_g_soa_tmp(ntot_soaspec)
    1157             :       real(r8) :: dtcur                                ! current time step (s)
    1158             :       real(r8) :: dtmax                                ! = (dtfull-tcur)
    1159  4348047600 :       real(r8) :: g0_soa(ntot_soaspec)                 ! ambient soa gas equilib mixrat (mol/mol at actual mw)
    1160  4348047600 :       real(r8) :: g_soa(ntot_soaspec)                  ! soa gas mixrat (mol/mol at actual mw)
    1161  4348047600 :       real(r8) :: g_star(ntot_soamode,ntot_soaspec)    ! soa gas mixrat that is in equilib
    1162             :                                                        ! with each aerosol mode (mol/mol)
    1163  4348047600 :       real(r8) :: mw_poa(ntot_poaspec)                 ! actual molec wght of poa
    1164  4348047600 :       real(r8) :: mw_soa(ntot_soaspec)                 ! actual molec wght of soa
    1165  4348047600 :       real(r8) :: opoa_frac(ntot_poaspec)              ! fraction of poa that is opoa
    1166  4348047600 :       real(r8) :: phi(ntot_soamode,ntot_soaspec)       ! "relative driving force"
    1167  4348047600 :       real(r8) :: p0_soa(ntot_soaspec)                 ! soa gas equilib vapor presssure (atm)
    1168  4348047600 :       real(r8) :: p0_soa_298(ntot_soaspec)             ! p0_soa_298 = soa gas equilib vapor presssure (atm) at 298 k
    1169  4348047600 :       real(r8) :: sat(ntot_soamode,ntot_soaspec)       ! sat(m,ll) = g0_soa(ll)/a_ooa_sum_tmp(m) = g_star(m,ll)/a_soa(m,ll)
    1170             :                                                        !    used by the numerical integration scheme -- it is not a saturation rato!
    1171             :       real(r8) :: tcur                                 ! current integration time (from 0 s)
    1172             :       real(r8) :: tmpa, tmpb, tmpf
    1173  4348047600 :       real(r8) :: tot_soa(ntot_soaspec)                ! g_soa + sum( a_soa(:) )
    1174  2174023800 :       real(r8) :: xferrate(ntot_amode,ntot_soaspec)    ! gas-aerosol mass transfer rate (1/s)
    1175             : 
    1176             : ! Changed by Manish Shrivastava
    1177  4348047600 :       opoa_frac(:) = 0.0_r8 !POA does not form solution with SOA for all runs; set opoa_frac=0.0_r8  by Manish Shrivastava
    1178  4348047600 :       mw_poa(:) = 250.0_r8
    1179  4348047600 :       mw_soa(:) = 250.0_r8
    1180             : 
    1181             :       ! New SOA properties added by Manish Shrivastava on 09/27/2012
    1182  2174023800 :       if (ntot_soaspec ==1) then
    1183  4348047600 :          p0_soa_298(:) = 9.7831E-11_r8
    1184  4348047600 :          delh_vap_soa(:) = 131.0e3_r8
    1185  4348047600 :          opoa_frac(:) = 0.0_r8
    1186           0 :       elseif (ntot_soaspec ==2) then
    1187             :          ! same for anthropogenic and biomass burning species
    1188           0 :          p0_soa_298 (1) = 1.0e-10_r8
    1189           0 :          p0_soa_298 (2) = 1.0e-10_r8
    1190           0 :          delh_vap_soa(:) = 156.0e3_r8
    1191           0 :       elseif(ntot_soaspec ==5) then
    1192             :          ! 5 volatility bins for each of the a combined SOA classes ( including biomass burning, fossil fuel, biogenic)
    1193           0 :          p0_soa_298 (1) = 9.7831E-13_r8 !soaff0 C*=0.01ug/m3
    1194           0 :          p0_soa_298 (2) = 9.7831E-12_r8 !soaff1 C*=0.10ug/m3
    1195           0 :          p0_soa_298 (3) = 9.7831E-11_r8 !soaff2 C*=1.0ug/m3
    1196           0 :          p0_soa_298 (4) = 9.7831E-10_r8 !soaff3 C*=10.0ug/m3
    1197           0 :          p0_soa_298 (5) = 9.7831E-9_r8  !soaff4 C*=100.0ug/m3
    1198             : 
    1199           0 :          delh_vap_soa(1) = 153.0e3_r8
    1200           0 :          delh_vap_soa(2) = 142.0e3_r8
    1201           0 :          delh_vap_soa(3) = 131.0e3_r8
    1202           0 :          delh_vap_soa(4) = 120.0e3_r8
    1203           0 :          delh_vap_soa(5) = 109.0e3_r8
    1204           0 :       elseif(ntot_soaspec ==15) then
    1205             :          !
    1206             :          ! 5 volatility bins for each of the 3 SOA classes ( biomass burning, fossil fuel, biogenic)
    1207             :          ! SOA species 1-5 are for anthropogenic while 6-10 are for biomass burning SOA
    1208             :          ! SOA species 11-15 are for biogenic SOA, based on Cappa et al., Reference needs to be updated
    1209             :          ! For MW=250.0
    1210           0 :          p0_soa_298 (1) = 9.7831E-13_r8 !soaff0 C*=0.01ug/m3
    1211           0 :          p0_soa_298 (2) = 9.7831E-12_r8 !soaff1 C*=0.10ug/m3
    1212           0 :          p0_soa_298 (3) = 9.7831E-11_r8 !soaff2 C*=1.0ug/m3
    1213           0 :          p0_soa_298 (4) = 9.7831E-10_r8 !soaff3 C*=10.0ug/m3
    1214           0 :          p0_soa_298 (5) = 9.7831E-9_r8  !soaff4 C*=100.0ug/m3
    1215           0 :          p0_soa_298 (6) = 9.7831E-13_r8 !soabb0 C*=0.01ug/m3
    1216           0 :          p0_soa_298 (7) = 9.7831E-12_r8 !soabb1 C*=0.10ug/m3
    1217           0 :          p0_soa_298 (8) = 9.7831E-11_r8 !soabb2 C*=1.0ug/m3
    1218           0 :          p0_soa_298 (9) = 9.7831E-10_r8 !soabb3 C*=10.0ug/m3
    1219           0 :          p0_soa_298 (10) = 9.7831E-9_r8  !soabb4 C*=100.0ug/m3
    1220           0 :          p0_soa_298 (11) = 9.7831E-13_r8 !soabg0 C*=0.01ug/m3
    1221           0 :          p0_soa_298 (12) = 9.7831E-12_r8 !soabg1 C*=0.1ug/m3
    1222           0 :          p0_soa_298 (13) = 9.7831E-11_r8 !soabg2 C*=1.0ug/m3
    1223           0 :          p0_soa_298 (14) = 9.7831E-10_r8 !soabg3 C*=10.0ug/m3
    1224           0 :          p0_soa_298 (15) = 9.7831E-9_r8  !soabg4 C*=100.0ug/m3
    1225             : 
    1226             :          !
    1227             :          ! have to be adjusted to 15 species, following the numbers by Epstein et al., 2012
    1228             :          !
    1229           0 :          delh_vap_soa(1) = 153.0e3_r8
    1230           0 :          delh_vap_soa(2) = 142.0e3_r8
    1231           0 :          delh_vap_soa(3) = 131.0e3_r8
    1232           0 :          delh_vap_soa(4) = 120.0e3_r8
    1233           0 :          delh_vap_soa(5) = 109.0e3_r8
    1234           0 :          delh_vap_soa(6) = 153.0e3_r8
    1235           0 :          delh_vap_soa(7) = 142.0e3_r8
    1236           0 :          delh_vap_soa(8) = 131.0e3_r8
    1237           0 :          delh_vap_soa(9) = 120.0e3_r8
    1238           0 :          delh_vap_soa(10) = 109.0e3_r8
    1239           0 :          delh_vap_soa(11) = 153.0e3_r8
    1240           0 :          delh_vap_soa(12) = 142.0e3_r8
    1241           0 :          delh_vap_soa(13) = 131.0e3_r8
    1242           0 :          delh_vap_soa(14) = 120.0e3_r8
    1243           0 :          delh_vap_soa(15) = 109.0e3_r8
    1244             :       endif
    1245             : 
    1246             :       !BSINGH - Initialized g_soa_tend and a_soa_tend to circumvent the undefined behavior (04/16/12)
    1247  4348047600 :       g_soa_tend(:)   = 0.0_r8
    1248 13044142800 :       a_soa_tend(:,:) = 0.0_r8
    1249             : 
    1250             :       ! determine which modes have non-zero transfer rates
    1251             :       !    and are involved in the soa gas-aerosol transfer
    1252             :       ! for diameter = 1 nm and number = 1 #/cm3, xferrate ~= 1e-9 s-1
    1253 10870119000 :       do m = 1, ntot_soamode
    1254  8696095200 :          skip_soamode(m) = .true.
    1255 19566214200 :          do ll = 1, ntot_soaspec
    1256  8696095200 :             xferrate(m,ll) = xferrate_in(m,ll)
    1257 17392190400 :             skip_soamode(m) = .false.
    1258             :          end do
    1259             :       end do
    1260             : 
    1261             :       ! convert incoming mixing ratios from mol/mol at the "host-code" molec. weight (12.0 in cam5)
    1262             :       !    to mol/mol at the "actual" molec. weight (currently assumed to be 250.0)
    1263             :       ! also
    1264             :       !    force things to be non-negative
    1265             :       !    calc tot_soa(ll)
    1266             :       !    calc a_opoa (always slightly >0)
    1267  4348047600 :       do ll = 1, ntot_soaspec
    1268  2174023800 :          tmpf = mw_soa_host(ll)/mw_soa(ll)
    1269  2174023800 :          g_soa(ll) = max( g_soa_in(ll), 0.0_r8 ) * tmpf
    1270  2174023800 :          tot_soa(ll) = g_soa(ll)
    1271 13044142800 :          do m = 1, ntot_soamode
    1272  8696095200 :             if ( skip_soamode(m) ) cycle
    1273  8696095200 :             a_soa(m,ll) = max( a_soa_in(m,ll), 0.0_r8 ) * tmpf
    1274 10870119000 :             tot_soa(ll) = tot_soa(ll) + a_soa(m,ll)
    1275             :          end do
    1276             :       end do
    1277             : 
    1278 10870119000 :       do m = 1, ntot_soamode
    1279  8696095200 :          if ( skip_soamode(m) ) cycle
    1280  8696095200 :          a_opoa(m) = 0.0_r8
    1281 19566214200 :          do ll = 1, ntot_poaspec
    1282 17392190400 :             a_opoa(m) = opoa_frac(ll)*a_poa_in(m,ll)
    1283             :          end do
    1284             :       end do
    1285             : 
    1286             :       ! calc ambient equilibrium soa gas
    1287  4348047600 :       do ll = 1, ntot_soaspec
    1288  2174023800 :          p0_soa(ll) = p0_soa_298(ll) * &
    1289  2174023800 :               exp( -(delh_vap_soa(ll)/rgas)*((1.0_r8/temp)-(1.0_r8/298.0_r8)) )
    1290  4348047600 :          g0_soa(ll) = 1.01325e5_r8*p0_soa(ll)/pres
    1291             :       end do
    1292             : 
    1293  2174023800 :       niter = 0
    1294  2174023800 :       tcur = 0.0_r8
    1295  2174023800 :       dtcur = 0.0_r8
    1296 13044142800 :       phi(:,:) = 0.0_r8
    1297 13044142800 :       g_star(:,:) = 0.0_r8
    1298             : 
    1299             : !     if (idiagss > 0) then
    1300             : !        write(luna,'(a,1p,10e11.3)') 'p0, g0_soa', p0_soa, g0_soa
    1301             : !        write(luna,'(3a)') &
    1302             : !           'niter, tcur,   dtcur,    phi(:),                       ', &
    1303             : !           'g_star(:),                    ', &
    1304             : !           'a_soa(:),                     g_soa'
    1305             : !        write(luna,'(3a)') &
    1306             : !           '                         sat(:),                       ', &
    1307             : !           'sat(:)*a_soa(:)               ', &
    1308             : !           'a_opoa(:)'
    1309             : !        write(luna,'(i3,1p,20e10.2)') niter, tcur, dtcur, &
    1310             : !           phi(:), g_star(:), a_soa(:), g_soa
    1311             : !     end if
    1312             : 
    1313             : 
    1314             : ! integration loop -- does multiple substeps to reach dtfull
    1315             : time_loop: &
    1316  8438889498 :       do while (tcur < dtfull-1.0e-3_r8 )
    1317             : 
    1318  6264865698 :       niter = niter + 1
    1319  6264865698 :       if (niter > niter_max) exit
    1320             : 
    1321 31324328490 :       tmpa = 0.0_r8  ! time integration parameter for all soa species
    1322 31324328490 :       do m = 1, ntot_soamode
    1323 25059462792 :          if ( skip_soamode(m) ) cycle
    1324 56383791282 :          a_ooa_sum_tmp(m) = a_opoa(m) + sum( a_soa(m,1:ntot_soaspec) )
    1325             :       end do
    1326 12529731396 :       do ll = 1, ntot_soaspec
    1327             :          tmpb = 0.0_r8  ! time integration parameter for a single soa species
    1328 31324328490 :          do m = 1, ntot_soamode
    1329 25059462792 :             if ( skip_soamode(m) ) cycle
    1330 25059462792 :             sat(m,ll) = g0_soa(ll)/max( a_ooa_sum_tmp(m), a_min1 )
    1331 25059462792 :             g_star(m,ll) = sat(m,ll)*a_soa(m,ll)
    1332 25059462792 :             phi(m,ll) = (g_soa(ll) - g_star(m,ll))/max( g_soa(ll), g_star(m,ll), g_min1 )
    1333 31324328490 :             tmpb = tmpb + xferrate(m,ll)*abs(phi(m,ll))
    1334             :          end do
    1335 12529731396 :          tmpa = max( tmpa, tmpb )
    1336             :       end do
    1337             : 
    1338             :       if (dtsub_fixed > 0.0_r8) then
    1339             :          dtcur = dtsub_fixed
    1340             :          tcur = tcur + dtcur
    1341             :       else
    1342  6264865698 :          dtmax = dtfull-tcur
    1343  6264865698 :          if (dtmax*tmpa <= alpha) then
    1344             : ! here alpha/tmpa >= dtmax, so this is final substep
    1345             :             dtcur = dtmax
    1346             :             tcur = dtfull
    1347             :          else
    1348  4090843651 :             dtcur = alpha/tmpa
    1349  4090843651 :             tcur = tcur + dtcur
    1350             :          end if
    1351             :       end if
    1352             : 
    1353             : ! step 1 - for modes where soa is condensing, estimate "new" a_soa(m,ll)
    1354             : !    using an explicit calculation with "old" g_soa
    1355             : !    and g_star(m,ll) calculated using "old" a_soa(m,ll)
    1356             : ! do this to get better estimate of "new" a_soa(m,ll) and sat(m,ll)
    1357 31324328490 :       do m = 1, ntot_soamode
    1358 25059462792 :          if ( skip_soamode(m) ) cycle
    1359 50118925584 :          do ll = 1, ntot_soaspec
    1360             :             ! first ll loop calcs a_soa_tmp(m,ll) & a_ooa_sum_tmp
    1361 25059462792 :             a_soa_tmp(m,ll) = a_soa(m,ll)
    1362 25059462792 :             beta(m,ll) = dtcur*xferrate(m,ll)
    1363 25059462792 :             del_g_soa_tmp(ll) = g_soa(ll) - g_star(m,ll)
    1364 50118925584 :             if (del_g_soa_tmp(ll) > 0.0_r8) then
    1365 19816107746 :                a_soa_tmp(m,ll) = a_soa(m,ll) + beta(m,ll)*del_g_soa_tmp(ll)
    1366             :             end if
    1367             :          end do
    1368 50118925584 :          a_ooa_sum_tmp(m) = a_opoa(m) + sum( a_soa_tmp(m,1:ntot_soaspec) )
    1369 56383791282 :          do ll = 1, ntot_soaspec
    1370             :             ! second ll loop calcs sat & g_star
    1371 50118925584 :             if (del_g_soa_tmp(ll) > 0.0_r8) then
    1372 19816107746 :                sat(m,ll) = g0_soa(ll)/max( a_ooa_sum_tmp(m), a_min1 )
    1373 19816107746 :                g_star(m,ll) = sat(m,ll)*a_soa_tmp(m,ll)   ! this just needed for diagnostics
    1374             :             end if
    1375             :          end do
    1376             :       end do
    1377             : 
    1378             : ! step 2 - implicit in g_soa and semi-implicit in a_soa,
    1379             : !    with g_star(m,ll) calculated semi-implicitly
    1380 14703755196 :       do ll = 1, ntot_soaspec
    1381             :          tmpa = 0.0_r8
    1382             :          tmpb = 0.0_r8
    1383 31324328490 :          do m = 1, ntot_soamode
    1384 25059462792 :             if ( skip_soamode(m) ) cycle
    1385 25059462792 :             tmpa = tmpa + a_soa(m,ll)/(1.0_r8 + beta(m,ll)*sat(m,ll))
    1386 31324328490 :             tmpb = tmpb + beta(m,ll)/(1.0_r8 + beta(m,ll)*sat(m,ll))
    1387             :          end do
    1388             : 
    1389  6264865698 :          g_soa(ll) = (tot_soa(ll) - tmpa)/(1.0_r8 + tmpb)
    1390  6264865698 :          g_soa(ll) = max( 0.0_r8, g_soa(ll) )
    1391 37589194188 :          do m = 1, ntot_soamode
    1392 25059462792 :             if ( skip_soamode(m) ) cycle
    1393 25059462792 :             a_soa(m,ll) = (a_soa(m,ll) + beta(m,ll)*g_soa(ll))/   &
    1394 31324328490 :                        (1.0_r8 + beta(m,ll)*sat(m,ll))
    1395             :          end do
    1396             :       end do
    1397             : 
    1398             : !     if (idiagss > 0) then
    1399             : !        write(luna,'(i3,1p,20e10.2)') niter, tcur, dtcur, &
    1400             : !           phi(:), g_star(:), a_soa(:), g_soa
    1401             : !        write(luna,'(23x,1p,20e10.2)') &
    1402             : !           sat(:), sat(:)*a_soa(:), a_opoa(:)
    1403             : !     end if
    1404             : 
    1405             : !     if (niter > 9992000) then
    1406             : !        write(luna,'(a)') '*** to many iterations'
    1407             : !        exit
    1408             : !     end if
    1409             : 
    1410             :       end do time_loop
    1411             : 
    1412             : 
    1413             : ! calculate outgoing tendencies (at the host-code molec. weight)
    1414             : ! (a_soa & g_soa are at actual mw, but a_soa_in & g_soa_in are at host-code mw)
    1415  4348047600 :       do ll = 1, ntot_soaspec
    1416  2174023800 :          tmpf = mw_soa(ll)/mw_soa_host(ll)
    1417  2174023800 :          g_soa_tend(ll) = (g_soa(ll)*tmpf - g_soa_in(ll))/dtfull
    1418 13044142800 :          do m = 1, ntot_soamode
    1419  8696095200 :             if ( skip_soamode(m) ) cycle
    1420 10870119000 :             a_soa_tend(m,ll) = (a_soa(m,ll)*tmpf - a_soa_in(m,ll))/dtfull
    1421             :          end do
    1422             :       end do
    1423             : 
    1424             : 
    1425  2174023800 :       return
    1426             : 
    1427             :       end subroutine modal_aero_soaexch
    1428             : 
    1429             : !----------------------------------------------------------------------
    1430             : 
    1431             : !----------------------------------------------------------------------
    1432             : 
    1433        1536 :       subroutine modal_aero_gasaerexch_init
    1434             : 
    1435             : !-----------------------------------------------------------------------
    1436             : !
    1437             : ! Purpose:
    1438             : !    set do_adjust and do_aitken flags
    1439             : !    create history fields for column tendencies associated with
    1440             : !       modal_aero_calcsize
    1441             : !
    1442             : ! Author: R. Easter
    1443             : !
    1444             : !-----------------------------------------------------------------------
    1445             : 
    1446             : use modal_aero_data
    1447             : use modal_aero_rename
    1448             : 
    1449             : use cam_abortutils, only: endrun
    1450             : use cam_history,    only: addfld, add_default, fieldname_len, horiz_only
    1451             : use constituents,   only: pcnst, cnst_get_ind, cnst_name
    1452             : use spmd_utils,     only: masterproc
    1453             : use phys_control,   only: phys_getopts
    1454             : 
    1455             : implicit none
    1456             : 
    1457             : !-----------------------------------------------------------------------
    1458             : ! arguments
    1459             : 
    1460             : !-----------------------------------------------------------------------
    1461             : ! local
    1462             :    integer  :: ipair, iq, iqfrm, iqfrm_aa, iqtoo, iqtoo_aa
    1463             :    integer  :: jac,jsoa,p
    1464             :    integer  :: l, l1, l2, lsfrm, lstoo, lunout
    1465             :    integer  :: l_so4g, l_nh4g, l_msag
    1466             :    integer  :: m, mfrm, mtoo
    1467             :    integer  :: n, nacc, nait
    1468             :    integer  :: nchfrm, nchfrmskip, nchtoo, nchtooskip, nspec
    1469             : 
    1470             :    logical  :: do_msag, do_nh4g
    1471        3072 :    logical  :: do_soag_any, do_soag(nsoa)
    1472             :    logical  :: dotend(pcnst), dotendqqcw(pcnst)
    1473             : 
    1474             :    real(r8) :: tmp1, tmp2
    1475             : 
    1476             :    character(len=fieldname_len)   :: tmpnamea, tmpnameb
    1477             :    character(len=fieldname_len+3) :: fieldname
    1478             :    character(128)                 :: long_name
    1479             :    character(128)                 :: msg
    1480             :    character(8)                   :: unit
    1481             : 
    1482             :    logical                        :: history_aerosol      ! Output the MAM aerosol tendencies
    1483             :    logical                        :: history_aerocom    ! Output the aerocom history
    1484             :    !-----------------------------------------------------------------------
    1485             : 
    1486        1536 :         call phys_getopts( history_aerosol_out        = history_aerosol   )
    1487             : 
    1488        1536 :         maxspec_pcage = nspec_max
    1489        4608 :         allocate(lspecfrm_pcage(maxspec_pcage))
    1490        3072 :         allocate(lspectoo_pcage(maxspec_pcage))
    1491        4608 :         allocate(soa_equivso4_factor(nsoa))
    1492        3072 :         allocate(fac_m2v_soa(nsoa))
    1493        4608 :         allocate(fac_m2v_pcarbon(nspec_max))
    1494        1536 :         lunout = 6
    1495             : !
    1496             : !   define "from mode" and "to mode" for primary carbon aging
    1497             : !
    1498             : !   skip (turn off) aging if either is absent,
    1499             : !      or if accum mode so4 is absent
    1500             : !
    1501        1536 :         modefrm_pcage = -999888777
    1502        1536 :         modetoo_pcage = -999888777
    1503        1536 :         if ((modeptr_pcarbon <= 0) .or. (modeptr_accum <= 0)) goto 15000
    1504        1536 :         l = lptr_so4_a_amode(modeptr_accum)
    1505        1536 :         if ((l < 1) .or. (l > pcnst)) goto 15000
    1506             : 
    1507        1536 :         modefrm_pcage = modeptr_pcarbon
    1508        1536 :         modetoo_pcage = modeptr_accum
    1509             : 
    1510             : !
    1511             : !   define species involved in each primary carbon aging pairing
    1512             : !       (include aerosol water)
    1513             : !
    1514             : !
    1515        1536 :         mfrm = modefrm_pcage
    1516        1536 :         mtoo = modetoo_pcage
    1517             : 
    1518        1536 :         if (mfrm < 10) then
    1519             :             nchfrmskip = 1
    1520           0 :         else if (mfrm < 100) then
    1521             :             nchfrmskip = 2
    1522             :         else
    1523           0 :             nchfrmskip = 3
    1524             :         end if
    1525        1536 :         if (mtoo < 10) then
    1526             :             nchtooskip = 1
    1527           0 :         else if (mtoo < 100) then
    1528             :             nchtooskip = 2
    1529             :         else
    1530           0 :             nchtooskip = 3
    1531             :         end if
    1532        1536 :         nspec = 0
    1533             : 
    1534        7680 : aa_iqfrm: do iqfrm = -1, nspec_amode(mfrm)
    1535             : 
    1536        6144 :             if (iqfrm == -1) then
    1537        1536 :                 lsfrm = numptr_amode(mfrm)
    1538        1536 :                 lstoo = numptr_amode(mtoo)
    1539        4608 :             else if (iqfrm == 0) then
    1540             : !   bypass transfer of aerosol water due to primary-carbon aging
    1541             :                 cycle aa_iqfrm
    1542             : !               lsfrm = lwaterptr_amode(mfrm)
    1543             : !               lstoo = lwaterptr_amode(mtoo)
    1544             :             else
    1545        3072 :                 lsfrm = lmassptr_amode(iqfrm,mfrm)
    1546        3072 :                 lstoo = 0
    1547             :             end if
    1548        4608 :             if ((lsfrm < 1) .or. (lsfrm > pcnst)) cycle aa_iqfrm
    1549             : 
    1550        4608 :             if (lsfrm>0 .and. iqfrm>0 ) then
    1551        3072 :                 nchfrm = len( trim( cnst_name(lsfrm) ) ) - nchfrmskip
    1552             : 
    1553             : ! find "too" species having same lspectype_amode as the "frm" species
    1554             : ! AND same cnst_name (except for last 1/2/3 characters which are the mode index)
    1555        9216 :                 do iqtoo = 1, nspec_amode(mtoo)
    1556             : !                   if ( lspectype_amode(iqtoo,mtoo) .eq.   &
    1557             : !                        lspectype_amode(iqfrm,mfrm) ) then
    1558        9216 :                         lstoo = lmassptr_amode(iqtoo,mtoo)
    1559        9216 :                         nchtoo = len( trim( cnst_name(lstoo) ) ) - nchtooskip
    1560        9216 :                         if (cnst_name(lsfrm)(1:nchfrm) == cnst_name(lstoo)(1:nchtoo)) then
    1561             :                             exit
    1562             :                         else
    1563        6144 :                             lstoo = 0
    1564             :                         end if
    1565             : !                   end if
    1566             :                 end do
    1567             :             end if
    1568             : 
    1569        4608 :             if ((lstoo < 1) .or. (lstoo > pcnst)) lstoo = 0
    1570        4608 :             nspec = nspec + 1
    1571        4608 :             lspecfrm_pcage(nspec) = lsfrm
    1572        7680 :             lspectoo_pcage(nspec) = lstoo
    1573             :         end do aa_iqfrm
    1574             : 
    1575        1536 :         nspecfrm_pcage = nspec
    1576             : 
    1577             : !
    1578             : !   output results
    1579             : !
    1580        1536 :         if ( masterproc ) then
    1581             : 
    1582           2 :         write(lunout,9310)
    1583             : 
    1584           2 :           mfrm = modefrm_pcage
    1585           2 :           mtoo = modetoo_pcage
    1586           2 :           write(lunout,9320) 1, mfrm, mtoo
    1587             : 
    1588           8 :           do iq = 1, nspecfrm_pcage
    1589           6 :             lsfrm = lspecfrm_pcage(iq)
    1590           6 :             lstoo = lspectoo_pcage(iq)
    1591           8 :             if (lstoo .gt. 0) then
    1592           6 :                 write(lunout,9330) lsfrm, cnst_name(lsfrm),   &
    1593          12 :                         lstoo, cnst_name(lstoo)
    1594             :             else
    1595           0 :                 write(lunout,9340) lsfrm, cnst_name(lsfrm)
    1596             :             end if
    1597             :           end do
    1598             : 
    1599           2 :         write(lunout,*)
    1600             : 
    1601             :         end if ! ( masterproc )
    1602             : 
    1603             : 9310    format( / 'subr. modal_aero_gasaerexch_init - primary carbon aging pointers' )
    1604             : 9320    format( 'pair', i3, 5x, 'mode', i3, ' ---> mode', i3 )
    1605             : 9330    format( 5x, 'spec', i3, '=', a, ' ---> spec', i3, '=', a )
    1606             : 9340    format( 5x, 'spec', i3, '=', a, ' ---> LOSS' )
    1607             : 
    1608             : 
    1609             : 15000 continue
    1610             : 
    1611             : ! set tendency flags and gas species indices and flags
    1612        1536 :       dotend(:) = .false.
    1613             : 
    1614        1536 :       call cnst_get_ind( 'H2SO4', l_so4g, .false. )
    1615        1536 :       if ((l_so4g <= 0) .or. (l_so4g > pcnst)) then
    1616             :          write( *, '(/a/a,2i7)' )   &
    1617           0 :             '*** modal_aero_gasaerexch_init -- cannot find H2SO4 species',   &
    1618           0 :             '    l_so4g=', l_so4g
    1619           0 :          call endrun( 'modal_aero_gasaerexch_init error' )
    1620             :       end if
    1621        1536 :       dotend(l_so4g) = .true.
    1622             : 
    1623        1536 :       call cnst_get_ind( 'NH3',   l_nh4g, .false. )
    1624        1536 :       do_nh4g = .false.
    1625        1536 :       if ((l_nh4g > 0) .and. (l_nh4g <= pcnst)) then
    1626           0 :          do_nh4g = .true.
    1627           0 :          dotend(l_nh4g) = .true.
    1628             :       end if
    1629             : 
    1630        1536 :       call cnst_get_ind( 'MSA',   l_msag, .false. )
    1631        1536 :       do_msag = .false.
    1632        1536 :       if ((l_msag > 0) .and. (l_msag <= pcnst)) then
    1633           0 :          do_msag = .true.
    1634           0 :          dotend(l_msag) = .true.
    1635             :       end if
    1636             : 
    1637        1536 :       do_soag_any = .false.
    1638        3072 :       do_soag(:) = .false.
    1639        3072 :       do jsoa = 1, nsoa
    1640        1536 :          l = lptr2_soa_g_amode(jsoa)
    1641        3072 :          if ((l > 0) .and. (l <= pcnst)) then
    1642        1536 :             do_soag_any = .true.
    1643        1536 :             do_soag(jsoa) = .true.
    1644        1536 :             dotend(l) = .true.
    1645             :          end if
    1646             :       end do
    1647             : 
    1648             : 
    1649        7680 :       do n = 1, ntot_amode
    1650        6144 :          l = lptr_so4_a_amode(n)
    1651        6144 :          if ((l > 0) .and. (l <= pcnst)) then
    1652        4608 :             dotend(l) = .true.
    1653        4608 :             if ( do_nh4g ) then
    1654           0 :                l = lptr_nh4_a_amode(n)
    1655           0 :                if ((l > 0) .and. (l <= pcnst)) dotend(l) = .true.
    1656             :             end if
    1657             :          end if
    1658       13824 :          do jsoa = 1, nsoa
    1659       12288 :             if ( do_soag(jsoa) ) then
    1660        6144 :                l = lptr2_soa_a_amode(n,jsoa)
    1661        6144 :                if ((l > 0) .and. (l <= pcnst)) dotend(l) = .true.
    1662             :             end if
    1663             :          end do
    1664             :       end do
    1665             : 
    1666        1536 :       if (modefrm_pcage > 0) then
    1667        6144 :          do iq = 1, nspecfrm_pcage
    1668        4608 :             lsfrm = lspecfrm_pcage(iq)
    1669        4608 :             lstoo = lspectoo_pcage(iq)
    1670        6144 :             if ((lsfrm > 0) .and. (lsfrm <= pcnst)) then
    1671        4608 :                dotend(lsfrm) = .true.
    1672        4608 :                if ((lstoo > 0) .and. (lstoo <= pcnst)) then
    1673        4608 :                   dotend(lstoo) = .true.
    1674             :                end if
    1675             :             end if
    1676             :          end do
    1677             :       end if
    1678             : 
    1679             : !---------define history fields for new cond/evap diagnostics----------------------------------------
    1680        1536 :       fieldname=trim('qconff_gaex')
    1681        1536 :       long_name = trim('3D fields for Fossil SOA condensation')
    1682        1536 :       unit = 'kg/kg/s'
    1683        3072 :       call addfld(fieldname, (/'lev'/), 'A', unit, long_name )
    1684        1536 :       if ( history_aerosol ) then
    1685           0 :          call add_default( fieldname,  1, ' ' )
    1686             :       endif
    1687        1536 :       if ( masterproc ) write(*,'(3(a,3x))') 'qconff addfld', fieldname, unit
    1688             : 
    1689        1536 :       fieldname=trim('qevapff_gaex')
    1690        1536 :       long_name = trim('3D fields for Fossil SOA evaporation')
    1691        3072 :       call addfld(fieldname, (/'lev'/), 'A', unit, long_name )
    1692        1536 :       if ( history_aerosol ) then
    1693           0 :          call add_default( fieldname,  1, ' ' )
    1694             :       endif
    1695        1536 :       if ( masterproc ) write(*,'(3(a,3x))') 'qevapff addfld', fieldname, unit
    1696             : 
    1697        1536 :       fieldname=trim('qconbb_gaex')
    1698        1536 :       long_name = trim('3D fields for Biomass SOA condensation')
    1699        3072 :       call addfld(fieldname, (/'lev'/), 'A', unit, long_name )
    1700        1536 :       if ( history_aerosol ) then
    1701           0 :          call add_default( fieldname,  1, ' ' )
    1702             :       endif
    1703        1536 :       if ( masterproc ) write(*,'(3(a,3x))') 'qconbb addfld', fieldname, unit
    1704             : 
    1705        1536 :       fieldname=trim('qevapbb_gaex')
    1706        1536 :       long_name = trim('3D fields for Biomass SOA evaporation')
    1707        3072 :       call addfld(fieldname, (/'lev'/), 'A', unit, long_name )
    1708        1536 :       if ( history_aerosol ) then
    1709           0 :          call add_default( fieldname,  1, ' ' )
    1710             :       endif
    1711        1536 :       if ( masterproc ) write(*,'(3(a,3x))') 'qevapbb addfld', fieldname, unit
    1712             : 
    1713        1536 :       fieldname=trim('qconbg_gaex')
    1714        1536 :       long_name = trim('3D fields for Biogenic SOA condensation')
    1715        3072 :       call addfld(fieldname, (/'lev'/), 'A', unit, long_name )
    1716        1536 :       if ( history_aerosol ) then
    1717           0 :          call add_default( fieldname,  1, ' ' )
    1718             :       endif
    1719        1536 :       if ( masterproc ) write(*,'(3(a,3x))') 'qconbg addfld', fieldname, unit
    1720             : 
    1721        1536 :       fieldname=trim('qevapbg_gaex')
    1722        1536 :       long_name = trim('3D fields for Biogenic SOA evaporation')
    1723        3072 :       call addfld(fieldname, (/'lev'/), 'A', unit, long_name )
    1724        1536 :       if ( history_aerosol ) then
    1725           0 :          call add_default( fieldname,  1, ' ' )
    1726             :       endif
    1727        1536 :       if ( masterproc ) write(*,'(3(a,3x))') 'qevapbg addfld', fieldname, unit
    1728             : 
    1729        1536 :       fieldname=trim('qcon_gaex')
    1730        1536 :       long_name = trim('3D fields for SOA condensation')
    1731        3072 :       call addfld(fieldname, (/'lev'/), 'A', unit, long_name )
    1732        1536 :       if ( history_aerosol ) then
    1733           0 :          call add_default( fieldname,  1, ' ' )
    1734             :       endif
    1735        1536 :       if ( masterproc ) write(*,'(3(a,3x))') 'qcon addfld', fieldname, unit
    1736             : 
    1737        1536 :       fieldname=trim('qevap_gaex')
    1738        1536 :       long_name = trim('3D fields for Biogenic SOA evaporation')
    1739        3072 :       call addfld(fieldname, (/'lev'/), 'A', unit, long_name )
    1740        1536 :       if ( history_aerosol ) then
    1741           0 :          call add_default( fieldname,  1, ' ' )
    1742             :       endif
    1743        1536 :       if ( masterproc ) write(*,'(3(a,3x))') 'qevap addfld', fieldname, unit
    1744             : !------------------------------------------------------------------------------
    1745             : 
    1746             : !  define history fields for basic gas-aer exchange
    1747             : !  and primary carbon aging from that
    1748       64512 :       do l = 1, pcnst
    1749       62976 :          if ( .not. dotend(l) ) cycle
    1750             : 
    1751       19968 :          tmpnamea = cnst_name(l)
    1752       19968 :          fieldname = trim(tmpnamea) // '_sfgaex1'
    1753       19968 :          long_name = trim(tmpnamea) // ' gas-aerosol-exchange primary column tendency'
    1754       19968 :          unit = 'kg/m2/s'
    1755       19968 :          call addfld( fieldname, horiz_only, 'A', unit, long_name )
    1756       19968 :          if ( history_aerosol ) then
    1757           0 :             call add_default( fieldname, 1, ' ' )
    1758             :          endif
    1759       21504 :          if ( masterproc ) write(*,'(3(a,3x))') 'gasaerexch addfld', fieldname, unit
    1760             : 
    1761             :       end do   ! l = ...
    1762             : !  define history fields for aitken-->accum renaming
    1763        1536 :       dotend(:) = .false.
    1764        1536 :       dotendqqcw(:) = .false.
    1765        6144 :       do ipair = 1, npair_renamexf
    1766       26112 :          do iq = 1, nspecfrm_renamexf(ipair)
    1767       19968 :             lsfrm = lspecfrma_renamexf(iq,ipair)
    1768       19968 :             lstoo = lspectooa_renamexf(iq,ipair)
    1769       19968 :             if ((lsfrm > 0) .and. (lsfrm <= pcnst)) then
    1770       19968 :                dotend(lsfrm) = .true.
    1771       19968 :                if ((lstoo > 0) .and. (lstoo <= pcnst)) then
    1772       19968 :                   dotend(lstoo) = .true.
    1773             :                end if
    1774             :             end if
    1775             : 
    1776       19968 :             lsfrm = lspecfrmc_renamexf(iq,ipair)
    1777       19968 :             lstoo = lspectooc_renamexf(iq,ipair)
    1778       24576 :             if ((lsfrm > 0) .and. (lsfrm <= pcnst)) then
    1779       19968 :                dotendqqcw(lsfrm) = .true.
    1780       19968 :                if ((lstoo > 0) .and. (lstoo <= pcnst)) then
    1781       19968 :                   dotendqqcw(lstoo) = .true.
    1782             :                end if
    1783             :             end if
    1784             :          end do ! iq = ...
    1785             :       end do ! ipair = ...
    1786             : 
    1787       64512 :       do l = 1, pcnst
    1788      190464 :       do jac = 1, 2
    1789      125952 :          if (jac == 1) then
    1790       62976 :             if ( .not. dotend(l) ) cycle
    1791       21504 :             tmpnamea = cnst_name(l)
    1792             :          else
    1793       62976 :             if ( .not. dotendqqcw(l) ) cycle
    1794       21504 :             tmpnamea = cnst_name_cw(l)
    1795             :          end if
    1796             : 
    1797       43008 :          fieldname = trim(tmpnamea) // '_sfgaex2'
    1798       43008 :          long_name = trim(tmpnamea) // ' gas-aerosol-exchange renaming column tendency'
    1799       43008 :          unit = 'kg/m2/s'
    1800       43008 :          if ((tmpnamea(1:3) == 'num') .or. &
    1801        9216 :              (tmpnamea(1:3) == 'NUM')) unit = '#/m2/s'
    1802       43008 :          call addfld( fieldname, horiz_only, 'A', unit, long_name )
    1803       43008 :          if ( history_aerosol ) then
    1804           0 :             call add_default( fieldname, 1, ' ' )
    1805             :          endif
    1806      105984 :          if ( masterproc ) write(*,'(3(a,3x))') 'gasaerexch addfld', fieldname, unit
    1807             :       end do   ! jac = ...
    1808             :       end do   ! l = ...
    1809             : 
    1810             : 
    1811             : ! set for used in aging calcs:
    1812             : !    fac_m2v_so4, fac_m2v_nh4, fac_m2v_soa(:)
    1813             : !    soa_equivso4_factor(:)
    1814        3072 :       soa_equivso4_factor = 0.0_r8
    1815        1536 :       if (modefrm_pcage > 0) then
    1816        1536 :          n = modeptr_accum
    1817        1536 :          l = lptr_so4_a_amode(n) ; l2 = -1
    1818        1536 :          if (l <= 0) call endrun( 'modal_aero_gasaerexch_init error a001 finding accum. so4' )
    1819       10752 :          do l1 = 1, nspec_amode(n)
    1820       10752 :             if (lmassptr_amode(l1,n) == l) then
    1821             : !               l2 = lspectype_amode(l1,n)
    1822        1536 :                l2 = l1
    1823             : !               fac_m2v_so4 = specmw_amode(l2) / specdens_amode(l2)
    1824        1536 :                fac_m2v_so4 = specmw_amode(l1,n) / specdens_amode(l1,n)
    1825             : !               tmp2 = spechygro(l2)
    1826        1536 :                tmp2 = spechygro(l1,n)
    1827             : 
    1828             :             end if
    1829             :          end do
    1830        1536 :          if (l2 <= 0) call endrun( 'modal_aero_gasaerexch_init error a002 finding accum. so4' )
    1831             : 
    1832        1536 :          l = lptr_nh4_a_amode(n) ; l2 = -1
    1833        1536 :          if (l > 0) then
    1834           0 :             do l1 = 1, nspec_amode(n)
    1835           0 :                if (lmassptr_amode(l1,n) == l) then
    1836             : !                  l2 = lspectype_amode(l1,n)
    1837           0 :                   l2 = l1
    1838             : !                  fac_m2v_nh4 = specmw_amode(l2) / specdens_amode(l2)
    1839           0 :                   fac_m2v_nh4 = specmw_amode(l1,n) / specdens_amode(l1,n)
    1840             : 
    1841             :                end if
    1842             :             end do
    1843           0 :             if (l2 <= 0) call endrun( 'modal_aero_gasaerexch_init error a002 finding accum. nh4' )
    1844             :          else
    1845        1536 :             fac_m2v_nh4 = fac_m2v_so4
    1846             :          end if
    1847             : 
    1848        3072 :          do jsoa = 1, nsoa
    1849        1536 :             l = lptr2_soa_a_amode(n,jsoa) ; l2 = -1
    1850        1536 :             if (l <= 0) then
    1851           0 :                write( msg, '(a,i4)') 'modal_aero_gasaerexch_init error a001 finding accum. jsoa =', jsoa
    1852           0 :                call endrun( msg )
    1853             :             end if
    1854       10752 :             do l1 = 1, nspec_amode(n)
    1855       10752 :                if (lmassptr_amode(l1,n) == l) then
    1856             : !                  l2 = lspectype_amode(l1,n)
    1857        1536 :                   l2 = l1
    1858             : !                  fac_m2v_soa(jsoa) = specmw_amode(l2) / specdens_amode(l2)
    1859        1536 :                   fac_m2v_soa(jsoa) = specmw_amode(l1,n) / specdens_amode(l1,n)
    1860             : !                  soa_equivso4_factor(jsoa) = spechygro(l2)/tmp2
    1861        1536 :                   soa_equivso4_factor(jsoa) = spechygro(l1,n)/tmp2
    1862             :                end if
    1863             :             end do
    1864        3072 :             if (l2 <= 0) then
    1865           0 :                write( msg, '(a,i4)') 'modal_aero_gasaerexch_init error a002 finding accum. jsoa =', jsoa
    1866           0 :                call endrun( msg )
    1867             :             end if
    1868             :          end do
    1869             : 
    1870       10752 :          fac_m2v_pcarbon(:) = 0.0_r8
    1871        1536 :          n = modeptr_pcarbon
    1872        4608 :          do l = 1, nspec_amode(n)
    1873             : !            l2 = lspectype_amode(l,n)
    1874             : !      fac_m2v converts (kmol-AP/kmol-air) to (m3-AP/kmol-air)
    1875             : !           [m3-AP/kmol-AP]    = [kg-AP/kmol-AP]  / [kg-AP/m3-AP]
    1876             : !            fac_m2v_pcarbon(l) = specmw_amode(l2) / specdens_amode(l2)
    1877        4608 :             fac_m2v_pcarbon(l) = specmw_amode(l,n) / specdens_amode(l,n)
    1878             :          end do
    1879             :       end if
    1880             : 
    1881             : 
    1882        1536 :       return
    1883             : 
    1884        3072 :       end subroutine modal_aero_gasaerexch_init
    1885             : 
    1886             : 
    1887             : !----------------------------------------------------------------------
    1888             : 
    1889             : end module modal_aero_gasaerexch

Generated by: LCOV version 1.14