LCOV - code coverage report
Current view: top level - chemistry/aerosol - aerosol_state_mod.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 220 227 96.9 %
Date: 2025-03-13 18:42:46 Functions: 10 11 90.9 %

          Line data    Source code
       1             : module aerosol_state_mod
       2             :   use shr_kind_mod, only: r8 => shr_kind_r8
       3             :   use aerosol_properties_mod, only: aerosol_properties, aero_name_len
       4             :   use physconst, only: pi
       5             : 
       6             :   implicit none
       7             : 
       8             :   private
       9             : 
      10             :   public :: aerosol_state
      11             :   public :: ptr2d_t
      12             : 
      13             :   !> aerosol_state defines the interface to the time-varying aerosol state
      14             :   !! variables (e.g., mixing ratios, number concentrations). This includes the
      15             :   !! aerosol portion of the overall model state.
      16             :   !!
      17             :   !! Each aerosol package (e.g., MAM, CARMA, etc) must extend the aerosol_state
      18             :   !! class to allow access to the state information (transported and not transported)
      19             :   !! of the aerosol package. Any package must implement each of the deferred
      20             :   !! procedures of the abstract aerosol_state class, may include additional private
      21             :   !! data members and type-bound procedures, and may override functions of the
      22             :   !! abstract class.
      23             :   !!
      24             :   !! Please see the modal_aerosol_state module for an example of how the aerosol_state
      25             :   !! class can be extended for a specific aerosol package.
      26             :   type, abstract :: aerosol_state
      27             :    contains
      28             :      procedure(aero_get_transported), deferred :: get_transported
      29             :      procedure(aero_set_transported), deferred :: set_transported
      30             :      procedure(aero_get_amb_total_bin_mmr), deferred :: ambient_total_bin_mmr
      31             :      procedure(aero_get_state_mmr), deferred :: get_ambient_mmr_0list
      32             :      procedure(aero_get_list_mmr), deferred :: get_ambient_mmr_rlist
      33             :      generic :: get_ambient_mmr=>get_ambient_mmr_0list,get_ambient_mmr_rlist
      34             :      procedure(aero_get_state_mmr), deferred :: get_cldbrne_mmr
      35             :      procedure(aero_get_state_num), deferred :: get_ambient_num
      36             :      procedure(aero_get_state_num), deferred :: get_cldbrne_num
      37             :      procedure(aero_get_states), deferred :: get_states
      38             :      procedure(aero_update_bin), deferred :: update_bin
      39             :      procedure :: loadaer
      40             :      procedure(aero_icenuc_size_wght_arr), deferred :: icenuc_size_wght_arr
      41             :      procedure(aero_icenuc_size_wght_val), deferred :: icenuc_size_wght_val
      42             :      generic :: icenuc_size_wght => icenuc_size_wght_arr,icenuc_size_wght_val
      43             :      procedure :: icenuc_type_wght_base
      44             :      procedure :: icenuc_type_wght => icenuc_type_wght_base
      45             :      procedure :: nuclice_get_numdens
      46             :      procedure :: get_amb_species_numdens
      47             :      procedure :: get_cld_species_numdens
      48             :      procedure :: coated_frac
      49             :      procedure :: mass_mean_radius
      50             :      procedure :: watact_mfactor
      51             :      procedure(aero_hetfrz_size_wght), deferred :: hetfrz_size_wght
      52             :      procedure(aero_hygroscopicity), deferred :: hygroscopicity
      53             :      procedure(aero_water_uptake), deferred :: water_uptake
      54             :      procedure :: refractive_index_sw
      55             :      procedure :: refractive_index_lw
      56             :      procedure(aero_volume), deferred :: dry_volume
      57             :      procedure(aero_volume), deferred :: wet_volume
      58             :      procedure(aero_volume), deferred :: water_volume
      59             :  end type aerosol_state
      60             : 
      61             :   ! for state fields
      62             :   type ptr2d_t
      63             :      real(r8), pointer :: fld(:,:)
      64             :   end type ptr2d_t
      65             : 
      66             :   real(r8), parameter :: per_cm3 = 1.e-6_r8 ! factor for m-3 to cm-3 conversions
      67             :   real(r8), parameter :: per_m3 = 1.e6_r8   ! factor for cm-3 to m-3 conversions
      68             :   real(r8), parameter :: kg2mug = 1.e9_r8   ! factor for kg to micrograms (mug) conversions
      69             : 
      70             :   abstract interface
      71             : 
      72             :      !------------------------------------------------------------------------
      73             :      ! Total aerosol mass mixing ratio for a bin in a given grid box location (column and layer)
      74             :      !------------------------------------------------------------------------
      75             :      function aero_get_amb_total_bin_mmr(self, aero_props, bin_ndx, col_ndx, lyr_ndx) result(mmr_tot)
      76             :        import :: aerosol_state, aerosol_properties, r8
      77             :        class(aerosol_state), intent(in) :: self
      78             :        class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
      79             :        integer, intent(in) :: bin_ndx      ! bin index
      80             :        integer, intent(in) :: col_ndx      ! column index
      81             :        integer, intent(in) :: lyr_ndx      ! vertical layer index
      82             : 
      83             :        real(r8) :: mmr_tot                 ! mass mixing ratios totaled for all species
      84             : 
      85             :      end function aero_get_amb_total_bin_mmr
      86             : 
      87             :      !------------------------------------------------------------------------
      88             :      ! returns aerosol mass mixing ratio for a given species index and bin index
      89             :      !------------------------------------------------------------------------
      90             :      subroutine aero_get_state_mmr(self, species_ndx, bin_ndx, mmr)
      91             :        import :: aerosol_state, r8
      92             :        class(aerosol_state), intent(in) :: self
      93             :        integer, intent(in) :: species_ndx  ! species index
      94             :        integer, intent(in) :: bin_ndx      ! bin index
      95             :        real(r8), pointer :: mmr(:,:)       ! mass mixing ratios (ncol,nlev)
      96             :      end subroutine aero_get_state_mmr
      97             : 
      98             :      !------------------------------------------------------------------------
      99             :      ! returns aerosol mass mixing ratio for a given species index, bin index
     100             :      ! and raditaion climate or diagnsotic list number
     101             :      !------------------------------------------------------------------------
     102             :      subroutine aero_get_list_mmr(self, list_ndx, species_ndx, bin_ndx, mmr)
     103             :        import :: aerosol_state, r8
     104             :        class(aerosol_state), intent(in) :: self
     105             :        integer, intent(in) :: list_ndx     ! rad climate/diagnostic list index
     106             :        integer, intent(in) :: species_ndx  ! species index
     107             :        integer, intent(in) :: bin_ndx      ! bin index
     108             :        real(r8), pointer :: mmr(:,:)       ! mass mixing ratios (ncol,nlev)
     109             :      end subroutine aero_get_list_mmr
     110             : 
     111             :      !------------------------------------------------------------------------
     112             :      ! returns aerosol number mixing ratio for a given species index and bin index
     113             :      !------------------------------------------------------------------------
     114             :      subroutine aero_get_state_num(self, bin_ndx, num)
     115             :        import :: aerosol_state, r8
     116             :        class(aerosol_state), intent(in) :: self
     117             :        integer, intent(in) :: bin_ndx     ! bin index
     118             :        real(r8), pointer   :: num(:,:)    ! number densities (ncol,nlev)
     119             :      end subroutine aero_get_state_num
     120             : 
     121             :      !------------------------------------------------------------------------
     122             :      ! returns interstitial and cloud-borne aerosol states
     123             :      !------------------------------------------------------------------------
     124             :      subroutine aero_get_states( self, aero_props, raer, qqcw )
     125             :        import :: aerosol_state, aerosol_properties, ptr2d_t
     126             : 
     127             :        class(aerosol_state), intent(in) :: self
     128             :        class(aerosol_properties), intent(in) :: aero_props ! properties of the aerosol model
     129             :        type(ptr2d_t), intent(out) :: raer(:) ! state of interstitial aerosols
     130             :        type(ptr2d_t), intent(out) :: qqcw(:) ! state of cloud-borne aerosols
     131             : 
     132             :      end subroutine aero_get_states
     133             : 
     134             :      !------------------------------------------------------------------------------
     135             :      ! sets transported components
     136             :      ! This updates the aerosol model state from the host transported aerosol constituents array.
     137             :      ! (mass mixing ratios or number mixing ratios)
     138             :      !------------------------------------------------------------------------------
     139             :      subroutine aero_set_transported( self, transported_array )
     140             :        import :: aerosol_state, r8
     141             :        class(aerosol_state), intent(inout) :: self
     142             :        real(r8), intent(in) :: transported_array(:,:,:)
     143             :      end subroutine aero_set_transported
     144             : 
     145             :      !------------------------------------------------------------------------------
     146             :      ! returns transported components
     147             :      ! This updates the transported aerosol constituent array to match the aerosol model state.
     148             :      ! (mass mixing ratios or number mixing ratios)
     149             :      !------------------------------------------------------------------------------
     150             :      subroutine aero_get_transported( self, transported_array )
     151             :        import :: aerosol_state, r8
     152             :        class(aerosol_state), intent(in) :: self
     153             :        real(r8), intent(out) :: transported_array(:,:,:)
     154             :      end subroutine aero_get_transported
     155             : 
     156             :      !------------------------------------------------------------------------------
     157             :      ! return aerosol bin size weights for a given bin
     158             :      !------------------------------------------------------------------------------
     159             :      subroutine aero_icenuc_size_wght_arr(self, bin_ndx, ncol, nlev, species_type, use_preexisting_ice, wght)
     160             :        import :: aerosol_state, r8
     161             :        class(aerosol_state), intent(in) :: self
     162             :        integer, intent(in) :: bin_ndx             ! bin number
     163             :        integer, intent(in) :: ncol                ! number of columns
     164             :        integer, intent(in) :: nlev                ! number of vertical levels
     165             :        character(len=*), intent(in) :: species_type  ! species type
     166             :        logical, intent(in) :: use_preexisting_ice ! pre-existing ice flag
     167             :        real(r8), intent(out) :: wght(:,:)
     168             : 
     169             :      end subroutine aero_icenuc_size_wght_arr
     170             : 
     171             :      !------------------------------------------------------------------------------
     172             :      ! return aerosol bin size weights for a given bin, column and vertical layer
     173             :      !------------------------------------------------------------------------------
     174             :      subroutine aero_icenuc_size_wght_val(self, bin_ndx, col_ndx, lyr_ndx, species_type, use_preexisting_ice, wght)
     175             :        import :: aerosol_state, r8
     176             :        class(aerosol_state), intent(in) :: self
     177             :        integer, intent(in) :: bin_ndx                ! bin number
     178             :        integer, intent(in) :: col_ndx                ! column index
     179             :        integer, intent(in) :: lyr_ndx                ! vertical layer index
     180             :        character(len=*), intent(in) :: species_type  ! species type
     181             :        logical, intent(in) :: use_preexisting_ice    ! pre-existing ice flag
     182             :        real(r8), intent(out) :: wght
     183             : 
     184             :      end subroutine aero_icenuc_size_wght_val
     185             : 
     186             :      !------------------------------------------------------------------------------
     187             :      ! updates state and tendency
     188             :      !------------------------------------------------------------------------------
     189             :      subroutine aero_update_bin( self, bin_ndx, col_ndx, lyr_ndx, delmmr_sum, delnum_sum, tnd_ndx, dtime, tend )
     190             :        import :: aerosol_state, r8
     191             :        class(aerosol_state), intent(in) :: self
     192             :        integer, intent(in) :: bin_ndx                ! bin number
     193             :        integer, intent(in) :: col_ndx                ! column index
     194             :        integer, intent(in) :: lyr_ndx                ! vertical layer index
     195             :        real(r8),intent(in) :: delmmr_sum             ! mass mixing ratio change summed over all species in bin
     196             :        real(r8),intent(in) :: delnum_sum             ! number mixing ratio change summed over all species in bin
     197             :        integer, intent(in) :: tnd_ndx                ! tendency index
     198             :        real(r8),intent(in) :: dtime                  ! time step size (sec)
     199             :        real(r8),intent(inout) :: tend(:,:,:)         ! tendency
     200             : 
     201             :      end subroutine aero_update_bin
     202             : 
     203             :      !------------------------------------------------------------------------------
     204             :      ! returns the volume-weighted fractions of aerosol subset `bin_ndx` that can act
     205             :      ! as heterogeneous freezing nuclei
     206             :      !------------------------------------------------------------------------------
     207             :      function aero_hetfrz_size_wght(self, bin_ndx, ncol, nlev) result(wght)
     208             :        import :: aerosol_state, r8
     209             :        class(aerosol_state), intent(in) :: self
     210             :        integer, intent(in) :: bin_ndx             ! bin number
     211             :        integer, intent(in) :: ncol                ! number of columns
     212             :        integer, intent(in) :: nlev                ! number of vertical levels
     213             : 
     214             :        real(r8) :: wght(ncol,nlev)
     215             : 
     216             :      end function aero_hetfrz_size_wght
     217             : 
     218             :      !------------------------------------------------------------------------------
     219             :      ! returns hygroscopicity for a given radiation diagnostic list number and
     220             :      ! bin number
     221             :      !------------------------------------------------------------------------------
     222             :      function aero_hygroscopicity(self, list_ndx, bin_ndx) result(kappa)
     223             :        import :: aerosol_state, r8
     224             :        class(aerosol_state), intent(in) :: self
     225             :        integer, intent(in) :: list_ndx     ! rad climate/diagnostic list index
     226             :        integer, intent(in) :: bin_ndx      ! bin number
     227             : 
     228             :        real(r8), pointer :: kappa(:,:)     ! hygroscopicity (ncol,nlev)
     229             : 
     230             :      end function aero_hygroscopicity
     231             : 
     232             :      !------------------------------------------------------------------------------
     233             :      ! returns aerosol wet diameter and aerosol water concentration for a given
     234             :      ! radiation diagnostic list number and bin number
     235             :      !------------------------------------------------------------------------------
     236             :      subroutine aero_water_uptake(self, aero_props, list_idx, bin_idx, ncol, nlev, dgnumwet, qaerwat)
     237             :        import :: aerosol_state, aerosol_properties, r8
     238             : 
     239             :        class(aerosol_state), intent(in) :: self
     240             :        class(aerosol_properties), intent(in) :: aero_props
     241             :        integer, intent(in) :: list_idx             ! rad climate/diags list number
     242             :        integer, intent(in) :: bin_idx              ! bin number
     243             :        integer, intent(in) :: ncol                 ! number of columns
     244             :        integer, intent(in) :: nlev                 ! number of levels
     245             :        real(r8),intent(out) :: dgnumwet(ncol,nlev) ! aerosol wet diameter (m)
     246             :        real(r8),intent(out) :: qaerwat(ncol,nlev)  ! aerosol water concentration (g/g)
     247             : 
     248             :      end subroutine aero_water_uptake
     249             : 
     250             :      !------------------------------------------------------------------------------
     251             :      ! aerosol volume interface
     252             :      !------------------------------------------------------------------------------
     253             :      function aero_volume(self, aero_props, list_idx, bin_idx, ncol, nlev) result(vol)
     254             :        import :: aerosol_state, aerosol_properties, r8
     255             : 
     256             :        class(aerosol_state), intent(in) :: self
     257             :        class(aerosol_properties), intent(in) :: aero_props
     258             :        integer, intent(in) :: list_idx  ! rad climate/diags list number
     259             :        integer, intent(in) :: bin_idx   ! bin number
     260             :        integer, intent(in) :: ncol      ! number of columns
     261             :        integer, intent(in) :: nlev      ! number of levels
     262             : 
     263             :        real(r8) :: vol(ncol,nlev)       ! m3/kg
     264             : 
     265             :      end function aero_volume
     266             : 
     267             :   end interface
     268             : 
     269             : contains
     270             : 
     271             :   !------------------------------------------------------------------------------
     272             :   ! returns aerosol number, volume concentrations, and bulk hygroscopicity
     273             :   !------------------------------------------------------------------------------
     274   342714084 :   subroutine loadaer( self, aero_props, istart, istop, k,  m, cs, phase, &
     275   114238028 :                        naerosol, vaerosol, hygro, errnum, errstr)
     276             : 
     277             :     use aerosol_properties_mod, only: aerosol_properties
     278             : 
     279             :     ! input arguments
     280             :     class(aerosol_state), intent(in) :: self
     281             :     class(aerosol_properties), intent(in) :: aero_props
     282             : 
     283             :     integer,  intent(in) :: istart      ! start column index (1 <= istart <= istop <= pcols)
     284             :     integer,  intent(in) :: istop       ! stop column index
     285             :     integer,  intent(in) :: k           ! level index
     286             :     integer,  intent(in) :: m           ! mode or bin index
     287             :     real(r8), intent(in) :: cs(:,:)     ! air density (kg/m3)
     288             :     integer,  intent(in) :: phase       ! phase of aerosol: 1 for interstitial, 2 for cloud-borne, 3 for sum
     289             : 
     290             :     ! output arguments
     291             :     real(r8), intent(out) :: naerosol(:)  ! number conc (1/m3)
     292             :     real(r8), intent(out) :: vaerosol(:)  ! volume conc (m3/m3)
     293             :     real(r8), intent(out) :: hygro(:)     ! bulk hygroscopicity of mode
     294             : 
     295             :     integer ,         intent(out) :: errnum
     296             :     character(len=*), intent(out) :: errstr
     297             : 
     298             :     ! internal
     299   114238028 :     real(r8), pointer :: raer(:,:) ! interstitial aerosol mass, number mixing ratios
     300   114238028 :     real(r8), pointer :: qqcw(:,:) ! cloud-borne aerosol mass, number mixing ratios
     301             :     real(r8) :: specdens, spechygro
     302             : 
     303   114238028 :     real(r8) :: vol(istart:istop) ! aerosol volume mixing ratio
     304             :     integer  :: i, l
     305             :     !-------------------------------------------------------------------------------
     306   114238028 :     errnum = 0
     307             : 
     308  1099968664 :     do i = istart, istop
     309   985730636 :        vaerosol(i) = 0._r8
     310  1099968664 :        hygro(i)    = 0._r8
     311             :     end do
     312             : 
     313   542630633 :     do l = 1, aero_props%nspecies(m)
     314             : 
     315   428392605 :        call self%get_ambient_mmr(l,m, raer)
     316   428392605 :        call self%get_cldbrne_mmr(l,m, qqcw)
     317   428392605 :        call aero_props%get(m,l, density=specdens, hygro=spechygro)
     318             : 
     319   428392605 :        if (phase == 3) then
     320  3712806720 :           do i = istart, istop
     321  3712806720 :              vol(i) = max(raer(i,k) + qqcw(i,k), 0._r8)/specdens
     322             :           end do
     323   206037885 :        else if (phase == 2) then
     324           0 :           do i = istart, istop
     325           0 :              vol(i) = max(qqcw(i,k), 0._r8)/specdens
     326             :           end do
     327   206037885 :        else if (phase == 1) then
     328   412075770 :           do i = istart, istop
     329   412075770 :              vol(i) = max(raer(i,k), 0._r8)/specdens
     330             :           end do
     331             :        else
     332           0 :           errnum = -1
     333           0 :           write(errstr,*)'phase = ',phase,' in aerosol_state::loadaer not recognized'
     334             :           return
     335             :        end if
     336             : 
     337  4667513123 :        do i = istart, istop
     338  3696489885 :           vaerosol(i) = vaerosol(i) + vol(i)
     339  4124882490 :           hygro(i)    = hygro(i) + vol(i)*spechygro
     340             :        end do
     341             : 
     342             :     end do
     343             : 
     344  1099968664 :     do i = istart, istop
     345  1099968664 :        if (vaerosol(i) > 1.0e-30_r8) then
     346   985730411 :           hygro(i)    = hygro(i)/(vaerosol(i))
     347   985730411 :           vaerosol(i) = vaerosol(i)*cs(i,k)
     348             :        else
     349         225 :           hygro(i)    = 0.0_r8
     350         225 :           vaerosol(i) = 0.0_r8
     351             :        end if
     352             :     end do
     353             : 
     354             :     ! aerosol number mixing ratios (#/kg)
     355   114238028 :     call self%get_ambient_num(m, raer)
     356   114238028 :     call self%get_cldbrne_num(m, qqcw)
     357   114238028 :     if (phase == 3) then
     358   990081792 :        do i = istart, istop
     359   990081792 :           naerosol(i) = (raer(i,k) + qqcw(i,k))*cs(i,k) ! #/kg -> #/m3
     360             :        end do
     361    54943436 :     else if (phase == 2) then
     362           0 :        do i = istart, istop
     363           0 :           naerosol(i) = qqcw(i,k)*cs(i,k)
     364             :        end do
     365             :     else
     366   109886872 :        do i = istart, istop
     367   109886872 :           naerosol(i) = raer(i,k)*cs(i,k)
     368             :        end do
     369             :     end if
     370             : 
     371             :     ! adjust number
     372   114238028 :     call aero_props%apply_number_limits( naerosol, vaerosol, istart, istop, m )
     373             : 
     374   114238028 :   end subroutine loadaer
     375             : 
     376             :   !------------------------------------------------------------------------------
     377             :   ! returns ambient aerosol number density for a given bin number and species type
     378             :   !------------------------------------------------------------------------------
     379     2117664 :   subroutine get_amb_species_numdens(self, bin_ndx, ncol, nlev, species_type, aero_props, rho, numdens)
     380             :     use aerosol_properties_mod, only: aerosol_properties
     381             :     class(aerosol_state), intent(in) :: self
     382             :     integer, intent(in) :: bin_ndx                ! bin number
     383             :     integer, intent(in) :: ncol                   ! number of columns
     384             :     integer, intent(in) :: nlev                   ! number of vertical levels
     385             :     character(len=*), intent(in) :: species_type  ! species type
     386             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     387             :     real(r8), intent(in) :: rho(:,:)              ! air density (kg m-3)
     388             :     real(r8), intent(out) :: numdens(:,:)         ! species number densities (#/cm^3)
     389             : 
     390     2117664 :     real(r8), pointer :: num(:,:)
     391     4235328 :     real(r8) :: type_wght(ncol,nlev)
     392     4235328 :     real(r8) :: size_wght(ncol,nlev)
     393             : 
     394  3290603616 :     size_wght = self%hetfrz_size_wght(bin_ndx, ncol, nlev)
     395             : 
     396     2117664 :     call self%icenuc_type_wght_base(bin_ndx, ncol, nlev, species_type, aero_props, rho, type_wght)
     397             : 
     398     2117664 :     call self%get_ambient_num(bin_ndx, num)
     399             : 
     400  3290603616 :     numdens(:ncol,:) = num(:ncol,:)*rho(:ncol,:)*type_wght(:ncol,:)*size_wght(:ncol,:)*per_cm3
     401             : 
     402     2117664 :   end subroutine get_amb_species_numdens
     403             : 
     404             :   !------------------------------------------------------------------------------
     405             :   ! returns cloud-borne aerosol number density for a given bin number and species type
     406             :   !------------------------------------------------------------------------------
     407      705888 :   subroutine get_cld_species_numdens(self, bin_ndx, ncol, nlev, species_type, aero_props, rho, numdens)
     408             :     use aerosol_properties_mod, only: aerosol_properties
     409             :     class(aerosol_state), intent(in) :: self
     410             :     integer, intent(in) :: bin_ndx                ! bin number
     411             :     integer, intent(in) :: ncol                   ! number of columns
     412             :     integer, intent(in) :: nlev                   ! number of vertical levels
     413             :     character(len=*), intent(in) :: species_type  ! species type
     414             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     415             :     real(r8), intent(in) :: rho(:,:)              ! air density (kg m-3)
     416             :     real(r8), intent(out) :: numdens(:,:)         ! number densities (#/cm^3)
     417             : 
     418      705888 :     real(r8), pointer :: num(:,:)
     419     1411776 :     real(r8) :: type_wght(ncol,nlev)
     420     1411776 :     real(r8) :: size_wght(ncol,nlev)
     421             : 
     422  1096867872 :     size_wght = self%hetfrz_size_wght(bin_ndx, ncol, nlev)
     423             : 
     424      705888 :     call self%icenuc_type_wght_base(bin_ndx, ncol, nlev, species_type, aero_props, rho, type_wght, cloud_borne=.true.)
     425             : 
     426      705888 :     call self%get_cldbrne_num(bin_ndx, num)
     427             : 
     428  1096867872 :     numdens(:ncol,:) = num(:ncol,:)*rho(:ncol,:)*type_wght(:ncol,:)*size_wght(:ncol,:)*per_cm3
     429             : 
     430      705888 :   end subroutine get_cld_species_numdens
     431             : 
     432             :   !------------------------------------------------------------------------------
     433             :   ! returns aerosol type weights for a given aerosol type and bin
     434             :   !------------------------------------------------------------------------------
     435     3529440 :   subroutine icenuc_type_wght_base(self, bin_ndx, ncol, nlev, species_type, aero_props, rho, wght, cloud_borne)
     436             : 
     437             :     use aerosol_properties_mod, only: aerosol_properties
     438             : 
     439             :     class(aerosol_state), intent(in) :: self
     440             :     integer, intent(in) :: bin_ndx                ! bin number
     441             :     integer, intent(in) :: ncol                   ! number of columns
     442             :     integer, intent(in) :: nlev                   ! number of vertical levels
     443             :     character(len=*), intent(in) :: species_type  ! species type
     444             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     445             :     real(r8), intent(in) :: rho(:,:)              ! air density (kg m-3)
     446             :     real(r8), intent(out) :: wght(:,:)            ! type weights
     447             :     logical, optional, intent(in) :: cloud_borne  ! if TRUE cloud-borne aerosols are used
     448             :                                                   ! otherwise ambient aerosols are used
     449             : 
     450     7058880 :     real(r8) :: mass(ncol,nlev)
     451     7058880 :     real(r8) :: totalmass(ncol,nlev)
     452     3529440 :     real(r8), pointer :: aer_bin(:,:)
     453             : 
     454             :     character(len=aero_name_len) :: spectype, sptype
     455             :     integer :: ispc
     456             :     logical :: cldbrne
     457             : 
     458     3529440 :     if (present(cloud_borne)) then
     459      705888 :        cldbrne = cloud_borne
     460             :     else
     461             :        cldbrne = .false.
     462             :     end if
     463             : 
     464  5484339360 :     wght(:,:) = 0._r8
     465  5484339360 :     totalmass(:,:) = 0._r8
     466  5484339360 :     mass(:,:)   = 0._r8
     467             : 
     468     3529440 :     if (species_type=='sulfate_strat') then
     469      176472 :        sptype = 'sulfate'
     470             :     else
     471     3352968 :        sptype = species_type
     472             :     end if
     473             : 
     474    18353088 :     do ispc = 1, aero_props%nspecies(bin_ndx)
     475             : 
     476    14823648 :        if (cldbrne) then
     477     3000024 :           call self%get_cldbrne_mmr(ispc, bin_ndx, aer_bin)
     478             :        else
     479    11823624 :           call self%get_ambient_mmr(ispc, bin_ndx, aer_bin)
     480             :        end if
     481    14823648 :        call aero_props%species_type(bin_ndx, ispc, spectype=spectype)
     482             : 
     483 23034225312 :        totalmass(:ncol,:) = totalmass(:ncol,:) + aer_bin(:ncol,:)*rho(:ncol,:)
     484             : 
     485    18353088 :        if (trim(spectype) == trim(sptype)) then
     486  5484339360 :           mass(:ncol,:) = mass(:ncol,:) + aer_bin(:ncol,:)*rho(:ncol,:)
     487             :        end if
     488             : 
     489             :     end do
     490             : 
     491  5484339360 :     where (totalmass(:ncol,:) > 0._r8)
     492     3529440 :        wght(:ncol,:) = mass(:ncol,:)/totalmass(:ncol,:)
     493             :     end where
     494             : 
     495     7058880 :   end subroutine icenuc_type_wght_base
     496             : 
     497             :   !------------------------------------------------------------------------------
     498      176472 :   subroutine nuclice_get_numdens(self, aero_props, use_preexisting_ice, ncol, nlev, rho, dust_num_col, sulf_num_col, soot_num_col, sulf_num_tot_col )
     499             : 
     500             :     class(aerosol_state), intent(in) :: self
     501             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     502             : 
     503             :     logical, intent(in) :: use_preexisting_ice
     504             :     integer, intent(in) :: ncol                   ! number of columns
     505             :     integer, intent(in) :: nlev                   ! number of vertical levels
     506             :     real(r8), intent(in) :: rho(:,:) ! air density (kg m-3)
     507             :     real(r8), intent(out) :: dust_num_col(:,:) ! dust number densities (#/cm^3)
     508             :     real(r8), intent(out) :: sulf_num_col(:,:) ! sulfate number densities (#/cm^3)
     509             :     real(r8), intent(out) :: soot_num_col(:,:) ! soot number densities (#/cm^3)
     510             :     real(r8), intent(out) :: sulf_num_tot_col(:,:) ! stratopsheric sulfate number densities (#/cm^3)
     511             : 
     512             :     integer :: ibin,ispc
     513             :     character(len=aero_name_len) :: spectype
     514      352944 :     real(r8) :: size_wghts(ncol,nlev)
     515      352944 :     real(r8) :: type_wghts(ncol,nlev)
     516             : 
     517      176472 :     real(r8), pointer :: num_col(:,:)
     518             : 
     519   279178704 :     dust_num_col(:,:) = 0._r8
     520   279178704 :     sulf_num_col(:,:) = 0._r8
     521   279178704 :     soot_num_col(:,:) = 0._r8
     522   279178704 :     sulf_num_tot_col(:,:) = 0._r8
     523             : 
     524             :     ! collect number densities (#/cm^3) for dust, sulfate, and soot
     525      882360 :     do ibin = 1,aero_props%nbins()
     526             : 
     527      705888 :        call self%get_ambient_num(ibin, num_col)
     528             : 
     529     3352968 :        do ispc = 1,aero_props%nspecies(ibin)
     530             : 
     531     2647080 :           call aero_props%species_type(ibin, ispc, spectype)
     532             : 
     533     2647080 :           call self%icenuc_size_wght(ibin, ncol, nlev, spectype, use_preexisting_ice, size_wghts)
     534             : 
     535     2647080 :           call self%icenuc_type_wght(ibin, ncol, nlev, spectype, aero_props, rho, type_wghts)
     536             : 
     537     6000048 :           select case ( trim(spectype) )
     538             :           case('dust')
     539      529416 :              dust_num_col(:ncol,:) = dust_num_col(:ncol,:) &
     540   823180320 :                   + size_wghts(:ncol,:)*type_wghts(:ncol,:)*num_col(:ncol,:)*rho(:ncol,:)*per_cm3
     541             :           case('sulfate')
     542             :              ! This order of ops gives bit-for-bit results for cam5 phys ( use_preexisting_ice = .false. )
     543      529416 :              sulf_num_col(:ncol,:) = sulf_num_col(:ncol,:) &
     544   823180320 :                   + num_col(:ncol,:)*rho(:ncol,:)*per_cm3  * size_wghts(:ncol,:)*type_wghts(:ncol,:)
     545             :           case('black-c')
     546      352944 :              soot_num_col(:ncol,:) = soot_num_col(:ncol,:) &
     547   553728096 :                   + size_wghts(:ncol,:)*type_wghts(:ncol,:)*num_col(:ncol,:)*rho(:ncol,:)*per_cm3
     548             :           end select
     549             : 
     550             :        enddo
     551             : 
     552             :        ! stratospheric sulfates -- special case not included in the species loop above
     553      705888 :        call self%icenuc_size_wght(ibin, ncol, nlev, 'sulfate_strat', use_preexisting_ice, size_wghts)
     554      705888 :        call self%icenuc_type_wght(ibin, ncol, nlev, 'sulfate_strat', aero_props, rho, type_wghts)
     555      705888 :        sulf_num_tot_col(:ncol,:) = sulf_num_tot_col(:ncol,:) &
     556  1097750232 :             + size_wghts(:ncol,:)*type_wghts(:ncol,:)*num_col(:ncol,:)*rho(:ncol,:)*per_cm3
     557             : 
     558             :     enddo
     559             : 
     560      176472 :   end subroutine nuclice_get_numdens
     561             : 
     562             :   !------------------------------------------------------------------------------
     563             :   ! returns the fraction of particle surface area of aerosol subset `bin_ndx` covered
     564             :   ! by at least a monolayer of species `species_type` [0-1]
     565             :   !------------------------------------------------------------------------------
     566      705888 :   function coated_frac(self, bin_ndx,  species_type, ncol, nlev, aero_props, radius) result(frac)
     567             : 
     568             :     class(aerosol_state), intent(in) :: self
     569             :     integer, intent(in) :: bin_ndx                ! bin number
     570             :     character(len=*), intent(in) :: species_type  ! species type
     571             :     integer, intent(in) :: ncol                   ! number of columns
     572             :     integer, intent(in) :: nlev                   ! number of vertical levels
     573             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     574             :     real(r8), intent(in) :: radius(:,:) ! m
     575             : 
     576             :     real(r8) :: frac(ncol,nlev)                              ! coated fraction
     577             : 
     578             :     !------------coated variables--------------------
     579             :     real(r8), parameter :: n_so4_monolayers_dust = 1.0_r8 ! number of so4(+nh4) monolayers needed to coat a dust particle
     580             :     real(r8), parameter :: dr_so4_monolayers_dust = n_so4_monolayers_dust * 4.76e-10_r8
     581     1411776 :     real(r8) :: vol_shell(ncol,nlev)
     582     1411776 :     real(r8) :: vol_core(ncol,nlev)
     583             :     real(r8) :: alnsg, fac_volsfc
     584     1411776 :     real(r8) :: tmp1(ncol,nlev), tmp2(ncol,nlev)
     585      705888 :     real(r8),pointer :: sulf_mmr(:,:)
     586      705888 :     real(r8),pointer :: soa_mmr(:,:)
     587      705888 :     real(r8),pointer :: pom_mmr(:,:)
     588      705888 :     real(r8),pointer :: aer_mmr(:,:)
     589             : 
     590             :     integer :: sulf_ndx
     591             :     integer :: soa_ndx
     592             :     integer :: pom_ndx
     593             :     integer :: species_ndx
     594             : 
     595             :     real(r8) :: specdens_so4
     596             :     real(r8) :: specdens_pom
     597             :     real(r8) :: specdens_soa
     598             :     real(r8) :: specdens
     599             : 
     600             :     character(len=aero_name_len) :: spectype
     601             :     integer :: ispc
     602             : 
     603  1096867872 :     frac = -huge(1._r8)
     604             : 
     605      705888 :     sulf_ndx = -1
     606      705888 :     pom_ndx = -1
     607      705888 :     soa_ndx = -1
     608      705888 :     species_ndx = -1
     609             : 
     610     3705912 :     do ispc = 1, aero_props%nspecies(bin_ndx)
     611     3000024 :        call aero_props%species_type(bin_ndx, ispc, spectype)
     612             : 
     613     6000048 :        select case ( trim(spectype) )
     614             :        case('sulfate')
     615      529416 :           sulf_ndx = ispc
     616             :        case('p-organic')
     617      529416 :           pom_ndx = ispc
     618             :        case('s-organic')
     619     6000048 :           soa_ndx = ispc
     620             :        end select
     621     3705912 :        if (spectype==species_type) then
     622      705888 :           species_ndx = ispc
     623             :        end if
     624             :     end do
     625             : 
     626  1096867872 :     vol_shell(:ncol,:) = 0._r8
     627             : 
     628      705888 :     if (sulf_ndx>0) then
     629      529416 :        call aero_props%get(bin_ndx, sulf_ndx, density=specdens_so4)
     630      529416 :        call self%get_ambient_mmr(sulf_ndx, bin_ndx, sulf_mmr)
     631   822650904 :        vol_shell(:ncol,:) = vol_shell(:ncol,:) + sulf_mmr(:ncol,:)/specdens_so4
     632             :     end if
     633      705888 :     if (pom_ndx>0) then
     634      529416 :        call aero_props%get(bin_ndx, pom_ndx, density=specdens_pom)
     635      529416 :        call self%get_ambient_mmr(pom_ndx, bin_ndx, pom_mmr)
     636   822650904 :        vol_shell(:ncol,:) = vol_shell(:ncol,:) + pom_mmr(:ncol,:)*aero_props%pom_equivso4_factor()/specdens_pom
     637             :     end if
     638      705888 :     if (soa_ndx>0) then
     639      352944 :        call aero_props%get(bin_ndx, soa_ndx, density=specdens_soa)
     640      352944 :        call self%get_ambient_mmr(soa_ndx, bin_ndx, soa_mmr)
     641   548433936 :        vol_shell(:ncol,:) = vol_shell(:ncol,:) + soa_mmr(:ncol,:)*aero_props%soa_equivso4_factor()/specdens_soa
     642             :     end if
     643             : 
     644      705888 :     call aero_props%get(bin_ndx, species_ndx, density=specdens)
     645      705888 :     call self%get_ambient_mmr(species_ndx, bin_ndx, aer_mmr)
     646  1096867872 :     vol_core(:ncol,:) = aer_mmr(:ncol,:)/specdens
     647             : 
     648      705888 :     alnsg = aero_props%alogsig(bin_ndx)
     649      705888 :     fac_volsfc = exp(2.5_r8*alnsg**2)
     650             : 
     651  1096867872 :     tmp1(:ncol,:) = vol_shell(:ncol,:)*(radius(:ncol,:)*2._r8)*fac_volsfc
     652  1096867872 :     tmp2(:ncol,:) = max(6.0_r8*dr_so4_monolayers_dust*vol_core(:ncol,:), 0.0_r8)
     653             : 
     654  1096867872 :     where(tmp1(:ncol,:)>0._r8 .and. tmp2(:ncol,:)>0._r8)
     655             :        frac(:ncol,:) = tmp1(:ncol,:)/tmp2(:ncol,:)
     656             :     elsewhere
     657             :        frac(:ncol,:) = 0.001_r8
     658             :     end where
     659             : 
     660  1096867872 :     where(frac(:ncol,:)>1._r8)
     661             :        frac(:ncol,:) = 1._r8
     662             :     end where
     663  1096867872 :     where(frac(:ncol,:) < 0.001_r8)
     664             :        frac(:ncol,:) = 0.001_r8
     665             :     end where
     666             : 
     667      705888 :   end function coated_frac
     668             : 
     669             :   !------------------------------------------------------------------------------
     670             :   ! returns the radius [m] of particles in aerosol subset `bin_ndx` assuming all particles are
     671             :   ! the same size and only species `species_ndx` contributes to the particle volume
     672             :   !------------------------------------------------------------------------------
     673      705888 :   function mass_mean_radius(self, bin_ndx, species_ndx, ncol, nlev, aero_props, rho) result(radius)
     674             : 
     675             :     class(aerosol_state), intent(in) :: self
     676             :     integer, intent(in) :: bin_ndx                ! bin number
     677             :     integer, intent(in) :: species_ndx            ! species number
     678             :     integer, intent(in) :: ncol                   ! number of columns
     679             :     integer, intent(in) :: nlev                   ! number of vertical levels
     680             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     681             :     real(r8), intent(in) :: rho(:,:)              ! air density (kg m-3)
     682             : 
     683             :     real(r8) :: radius(ncol,nlev) ! m
     684             : 
     685             :     character(len=aero_name_len) :: species_type
     686     1411776 :     real(r8) :: aer_numdens(ncol,nlev) ! kg/m3
     687     1411776 :     real(r8) :: aer_massdens(ncol,nlev) ! kg/m3
     688      705888 :     real(r8),pointer :: aer_mmr(:,:) ! kg/kg
     689             : 
     690             :     real(r8) :: specdens,minrad
     691     1411776 :     real(r8) :: wght(ncol,nlev)
     692             :     integer :: i,k
     693             : 
     694  1096867872 :     wght = self%hetfrz_size_wght(bin_ndx, ncol, nlev)
     695             : 
     696      705888 :     call aero_props%species_type(bin_ndx, species_ndx, spectype=species_type)
     697             : 
     698      705888 :     call aero_props%get(bin_ndx, species_ndx, density=specdens) ! kg/m3
     699      705888 :     call self%get_ambient_mmr(species_ndx, bin_ndx, aer_mmr) ! kg/kg
     700      705888 :     call self%get_amb_species_numdens(bin_ndx, ncol, nlev, species_type, aero_props, rho, aer_numdens) ! #/cm3
     701             : 
     702  1096867872 :     aer_massdens(:ncol,:) = aer_mmr(:ncol,:)*rho(:ncol,:)*wght(:ncol,:) ! kg/m3
     703             : 
     704      705888 :     minrad = aero_props%min_mass_mean_rad(bin_ndx, species_ndx)
     705             : 
     706    66353472 :     do k = 1,nlev
     707  1096867872 :        do i = 1,ncol
     708  1096161984 :           if (aer_massdens(i,k)*1.0e-3_r8 > 1.0e-30_r8 .and. aer_numdens(i,k) > 1.0e-3_r8) then
     709   583205383 :              radius(i,k) = (3._r8/(4*pi*specdens)*aer_massdens(i,k)/(aer_numdens(i,k)*per_m3))**(1._r8/3._r8) ! m
     710             :           else
     711   447309017 :              radius(i,k) = minrad
     712             :           end if
     713             :        end do
     714             :     end do
     715             : 
     716      705888 :   end function mass_mean_radius
     717             : 
     718             :   !------------------------------------------------------------------------------
     719             :   ! calculates water activity mass factor -- density*(1.-(OC+BC)/(OC+BC+SO4)) [mug m-3]
     720             :   ! of species `species_type` in subset `bin_ndx`
     721             :   !------------------------------------------------------------------------------
     722      705888 :   subroutine watact_mfactor(self, bin_ndx,  species_type, ncol, nlev, aero_props, rho, wact_factor)
     723             : 
     724             :     class(aerosol_state), intent(in) :: self
     725             :     integer, intent(in) :: bin_ndx                ! bin number
     726             :     character(len=*), intent(in) :: species_type  ! species type
     727             :     integer, intent(in) :: ncol                   ! number of columns
     728             :     integer, intent(in) :: nlev                   ! number of vertical levels
     729             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     730             :     real(r8), intent(in) :: rho(:,:)              ! air density (kg m-3)
     731             :     real(r8), intent(out) :: wact_factor(:,:)     ! water activity factor -- density*(1.-(OC+BC)/(OC+BC+SO4)) [mug m-3]
     732             : 
     733      705888 :     real(r8), pointer :: aer_mmr(:,:)
     734      705888 :     real(r8), pointer :: bin_num(:,:)
     735     1411776 :     real(r8) :: tot2_mmr(ncol,nlev)
     736     1411776 :     real(r8) :: tot1_mmr(ncol,nlev)
     737     1411776 :     real(r8) :: aer_numdens(ncol,nlev)
     738             :     integer :: ispc
     739             :     character(len=aero_name_len) :: spectype
     740             : 
     741     1411776 :     real(r8) :: awcam(ncol,nlev)          ! mass density [mug m-3]
     742     1411776 :     real(r8) :: awfacm(ncol,nlev)         ! mass factor ! (OC+BC)/(OC+BC+SO4)
     743             : 
     744  1096867872 :     tot2_mmr = 0.0_r8
     745  1096867872 :     tot1_mmr = 0.0_r8
     746             : 
     747      705888 :     if (aero_props%soluble(bin_ndx)) then
     748             : 
     749     3176496 :        do ispc = 1, aero_props%nspecies(bin_ndx)
     750             : 
     751     2647080 :           call aero_props%species_type(bin_ndx, ispc, spectype)
     752             : 
     753     2647080 :           if (trim(spectype)=='black-c' .or. trim(spectype)=='p-organic' .or. trim(spectype)=='s-organic') then
     754     1058832 :              call self%get_ambient_mmr(ispc, bin_ndx, aer_mmr)
     755  1645301808 :              tot2_mmr(:ncol,:) = tot2_mmr(:ncol,:) + aer_mmr(:ncol,:)
     756             :           end if
     757     3176496 :           if (trim(spectype)=='sulfate') then
     758      529416 :              call self%get_ambient_mmr(ispc, bin_ndx, aer_mmr)
     759   822650904 :              tot1_mmr(:ncol,:) = tot1_mmr(:ncol,:) + aer_mmr(:ncol,:)
     760             :           end if
     761             :        end do
     762             : 
     763             :     end if
     764             : 
     765  1096867872 :     tot1_mmr(:ncol,:) = tot1_mmr(:ncol,:) + tot2_mmr(:ncol,:)
     766             : 
     767      705888 :     call self%get_amb_species_numdens(bin_ndx, ncol, nlev, species_type, aero_props, rho, aer_numdens) ! #/cm3
     768      705888 :     call self%get_ambient_num(bin_ndx, bin_num) ! #/kg
     769             : 
     770  1096867872 :     where(bin_num(:ncol,:)>0._r8)
     771      705888 :        awcam(:ncol,:) = ((aer_numdens(:ncol,:)*per_m3/bin_num(:ncol,:)) * tot1_mmr(:ncol,:)) * kg2mug  ! [mug m-3]
     772             :     elsewhere
     773             :        awcam(:ncol,:) = 0._r8
     774             :     end where
     775             : 
     776  1096867872 :     where(tot1_mmr(:ncol,:)>0)
     777             :        awfacm(:ncol,:) = tot2_mmr(:ncol,:) / tot1_mmr(:ncol,:)
     778             :     elsewhere
     779             :        awfacm(:ncol,:) = 0._r8
     780             :     end where
     781             : 
     782  1096867872 :     wact_factor(:ncol,:) = awcam(:ncol,:)*(1._r8-awfacm(:ncol,:))
     783             : 
     784      705888 :   end subroutine watact_mfactor
     785             : 
     786             :   !------------------------------------------------------------------------------
     787             :   ! aerosol short wave refactive index
     788             :   !------------------------------------------------------------------------------
     789   161239680 :   function refractive_index_sw(self, ncol, ilev, ilist, ibin, iwav, aero_props) result(crefin)
     790             : 
     791             :     class(aerosol_state), intent(in) :: self
     792             :     integer, intent(in) :: ncol   ! number of columes
     793             :     integer, intent(in) :: ilev   ! level index
     794             :     integer, intent(in) :: ilist  ! radiation diagnostics list index
     795             :     integer, intent(in) :: ibin   ! bin index
     796             :     integer, intent(in) :: iwav   ! wave length index
     797             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     798             : 
     799             :     complex(r8) :: crefin(ncol) ! complex refractive index
     800             : 
     801   161239680 :     real(r8), pointer :: specmmr(:,:) ! species mass mixing ratio
     802   161239680 :     complex(r8), pointer :: specrefindex(:)     ! species refractive index
     803             :     real(r8) :: specdens              ! species density (kg/m3)
     804             :     integer :: ispec, icol
     805   322479360 :     real(r8) :: vol(ncol)
     806             : 
     807  2692327680 :     crefin(:ncol) = (0._r8, 0._r8)
     808             : 
     809   765888480 :     do ispec = 1, aero_props%nspecies(ilist,ibin)
     810             : 
     811   604648800 :        call self%get_ambient_mmr(ilist,ispec,ibin,specmmr)
     812   604648800 :        call aero_props%get(ibin, ispec, list_ndx=ilist, density=specdens,  refindex_sw=specrefindex)
     813             : 
     814 10257468480 :        do icol = 1, ncol
     815  9491580000 :           vol(icol) = specmmr(icol,ilev)/specdens
     816 10096228800 :           crefin(icol) = crefin(icol) + vol(icol)*specrefindex(iwav)
     817             :        end do
     818             :     end do
     819             : 
     820   161239680 :   end function refractive_index_sw
     821             : 
     822             :   !------------------------------------------------------------------------------
     823             :   ! aerosol long wave refactive index
     824             :   !------------------------------------------------------------------------------
     825   184273920 :   function refractive_index_lw(self, ncol, ilev, ilist, ibin, iwav, aero_props) result(crefin)
     826             : 
     827             :     class(aerosol_state), intent(in) :: self
     828             :     integer, intent(in) :: ncol   ! number of columes
     829             :     integer, intent(in) :: ilev   ! level index
     830             :     integer, intent(in) :: ilist  ! radiation diagnostics list index
     831             :     integer, intent(in) :: ibin   ! bin index
     832             :     integer, intent(in) :: iwav   ! wave length index
     833             :     class(aerosol_properties), intent(in) :: aero_props ! aerosol properties object
     834             : 
     835             :     complex(r8) :: crefin(ncol) ! complex refractive index
     836             : 
     837   184273920 :     real(r8), pointer :: specmmr(:,:) ! species mass mixing ratio
     838   184273920 :     complex(r8), pointer :: specrefindex(:)     ! species refractive index
     839             :     real(r8) :: specdens              ! species density (kg/m3)
     840             :     integer :: ispec, icol
     841   368547840 :     real(r8) :: vol(ncol)
     842             : 
     843  3076945920 :     crefin(:ncol) = (0._r8, 0._r8)
     844             : 
     845   875301120 :     do ispec = 1, aero_props%nspecies(ilist,ibin)
     846             : 
     847   691027200 :        call self%get_ambient_mmr(ilist,ispec,ibin,specmmr)
     848   691027200 :        call aero_props%get(ibin, ispec, list_ndx=ilist, density=specdens,  refindex_lw=specrefindex)
     849             : 
     850 11722821120 :        do icol = 1, ncol
     851 10847520000 :           vol(icol) = specmmr(icol,ilev)/specdens
     852 11538547200 :           crefin(icol) = crefin(icol) + vol(icol)*specrefindex(iwav)
     853             :        end do
     854             :     end do
     855             : 
     856   184273920 :   end function refractive_index_lw
     857             : 
     858           0 : end module aerosol_state_mod

Generated by: LCOV version 1.14