LCOV - code coverage report
Current view: top level - physics/cam - phys_prop.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 360 642 56.1 %
Date: 2025-03-13 19:21:45 Functions: 13 24 54.2 %

          Line data    Source code
       1             : module phys_prop
       2             : 
       3             : ! Properties of aerosols that are used by radiation and other parameterizations.
       4             : 
       5             : ! *****N.B.*****
       6             : ! This module is a utility used by the rad_constituents module.  The properties stored
       7             : ! here are meant to be accessed via that module.  This module knows nothing about how
       8             : ! this data is associated with the constituents that are radiatively active or those that
       9             : ! are being used for diagnostic calculations.  That is the responsibility of the
      10             : ! rad_constituents module.
      11             : 
      12             : use shr_kind_mod,   only: r8 => shr_kind_r8
      13             : use spmd_utils,     only: masterproc
      14             : use radconstants,   only: nlwbands, nswbands, idx_sw_diag
      15             : use ioFileMod,      only: getfil
      16             : use cam_pio_utils,  only: cam_pio_openfile
      17             : use pio,            only: file_desc_t, var_desc_t, pio_get_var, pio_inq_varid, &
      18             :                           pio_inq_dimlen, pio_inq_dimid , pio_nowrite, pio_closefile, &
      19             :                           pio_seterrorhandling, PIO_BCAST_ERROR, PIO_INTERNAL_ERROR, PIO_NOERR
      20             : 
      21             : use cam_logfile,    only: iulog
      22             : use cam_abortutils, only: endrun
      23             : 
      24             : implicit none
      25             : private
      26             : save
      27             : 
      28             : integer, parameter, public :: ot_length = 32
      29             : 
      30             : public :: &
      31             :    physprop_accum_unique_files,  &! Make a list of the unique set of files that contain properties
      32             :                                   ! This is an initialization step that must be done before calling physprop_init
      33             :    physprop_init,                &! Initialization -- read the input datasets
      34             :    physprop_get_id,              &! Return ID used to access the property data from the input files
      35             :    physprop_get                   ! Return data for specified ID
      36             : 
      37             : ! Data from one input dataset is stored in a structure of type(physprop_type).
      38             : type :: physprop_type
      39             :    character(len=256) :: sourcefile ! Absolute pathname of data file.
      40             :    character(len=ot_length)  :: opticsmethod ! one of {hygro,nonhygro}
      41             : 
      42             :    ! for hygroscopic species of externally mixed aerosols
      43             :    real(r8), pointer :: sw_hygro_ext(:,:)
      44             :    real(r8), pointer :: sw_hygro_ssa(:,:)
      45             :    real(r8), pointer :: sw_hygro_asm(:,:)
      46             :    real(r8), pointer :: lw_hygro_abs(:,:)
      47             : 
      48             :    ! for nonhygroscopic species of externally mixed aerosols
      49             :    real(r8), pointer :: sw_nonhygro_ext(:)
      50             :    real(r8), pointer :: sw_nonhygro_ssa(:)
      51             :    real(r8), pointer :: sw_nonhygro_asm(:)
      52             :    real(r8), pointer :: sw_nonhygro_scat(:)
      53             :    real(r8), pointer :: sw_nonhygro_ascat(:)
      54             :    real(r8), pointer :: lw_abs(:)
      55             : 
      56             :    ! complex refractive index
      57             :    complex(r8), pointer :: refindex_aer_sw(:)
      58             :    complex(r8), pointer :: refindex_aer_lw(:)
      59             : 
      60             :    ! for radius-dependent mass-specific quantities
      61             :    real(r8), pointer :: r_sw_ext(:,:)
      62             :    real(r8), pointer :: r_sw_scat(:,:)
      63             :    real(r8), pointer :: r_sw_ascat(:,:)
      64             :    real(r8), pointer :: r_lw_abs(:,:)
      65             :    real(r8), pointer :: mu(:)
      66             : 
      67             :    ! for modal optics
      68             :    real(r8), pointer :: extpsw(:,:,:,:) ! specific extinction
      69             :    real(r8), pointer :: abspsw(:,:,:,:) ! specific absorption
      70             :    real(r8), pointer :: asmpsw(:,:,:,:) ! asymmetry factor
      71             :    real(r8), pointer :: absplw(:,:,:,:) ! specific absorption
      72             :    real(r8), pointer :: refrtabsw(:,:)  ! table of real refractive indices for aerosols visible
      73             :    real(r8), pointer :: refitabsw(:,:)  ! table of imag refractive indices for aerosols visible
      74             :    real(r8), pointer :: refrtablw(:,:)  ! table of real refractive indices for aerosols infrared
      75             :    real(r8), pointer :: refitablw(:,:)  ! table of imag refractive indices for aerosols infrared
      76             : 
      77             :    ! for core/shell optics
      78             :    real(r8), pointer :: extpsw2(:,:) ! specific extinction
      79             :    real(r8), pointer :: abspsw2(:,:) ! specific absorption
      80             :    real(r8), pointer :: asmpsw2(:,:) ! asymmetry factor
      81             :    real(r8), pointer :: absplw2(:,:) ! specific absorption
      82             :    real(r8), pointer :: corefrac(:)  ! table of real refractive indices for aerosols visible
      83             :    integer :: nfraC       ! number of Chebyshev coefficients
      84             : 
      85             :    ! for hygroscopic species of pure sulfate
      86             :    real(r8), pointer :: sw_hygro_ext_wtp(:,:)
      87             :    real(r8), pointer :: sw_hygro_ssa_wtp(:,:)
      88             :    real(r8), pointer :: sw_hygro_asm_wtp(:,:)
      89             :    real(r8), pointer :: lw_hygro_abs_wtp(:,:)
      90             :    real(r8), pointer :: wgtpct (:)  ! weight percent!
      91             :    integer :: nwtp       ! number weight percent
      92             :    ! for hygroscopic species of externally mixed aerosols
      93             :    real(r8), pointer :: sw_hygro_coreshell_ext(:,:,:,:,:)
      94             :    real(r8), pointer :: sw_hygro_coreshell_ssa(:,:,:,:,:)
      95             :    real(r8), pointer :: sw_hygro_coreshell_asm(:,:,:,:,:)
      96             :    real(r8), pointer :: lw_hygro_coreshell_abs(:,:,:,:,:)
      97             :    real(r8), pointer :: bcdust(:)  ! table of bc-dust mass ratio
      98             :    real(r8), pointer :: kap(:)         ! table of kappa
      99             :    real(r8), pointer :: relh(:)         ! table of relative humidity
     100             :    integer :: nbcdust
     101             :    integer :: nkap
     102             :    integer :: nrelh
     103             : 
     104             :    ! microphysics parameters.
     105             :    character(len=32) :: aername ! for output of number concentration
     106             :    real(r8) :: density_aer      ! density of aerosol (kg/m3)
     107             :    real(r8) :: hygro_aer        ! hygroscopicity of aerosol
     108             :    real(r8) :: dryrad_aer       ! number mode radius (m) of aerosol size distribution
     109             :    real(r8) :: dispersion_aer   ! geometric standard deviation of aerosol size distribution
     110             :    real(r8) :: num_to_mass_aer  ! ratio of number concentration to mass concentration (#/kg)
     111             :                                 ! *** Is this actually (kg/#) ???
     112             :    ! mode parameters
     113             :    integer :: ncoef       ! number of Chebyshev coefficients
     114             :    integer :: prefr       ! dimension in table of real refractive indices
     115             :    integer :: prefi       ! dimension in table of imag refractive indices
     116             :    real(r8) :: sigmag     ! geometric standard deviation of the number distribution for aerosol mode
     117             :    real(r8) :: dgnum      ! geometric dry mean diameter of the number distribution for aerosol mode
     118             :    real(r8) :: dgnumlo    ! lower limit of dgnum
     119             :    real(r8) :: dgnumhi    ! upper limit of dgnum
     120             :    real(r8) :: rhcrystal  ! crystalization relative humidity for mode
     121             :    real(r8) :: rhdeliques ! deliquescence relative humidity for mode
     122             : 
     123             : endtype physprop_type
     124             : 
     125             : ! This module stores data in an array of physprop_type structures.  The way this data
     126             : ! is accessed outside the module is via a physprop ID, which is an index into the array.
     127             : integer :: numphysprops = 0 ! an incremental total across ALL clim and diag constituents
     128             : type (physprop_type), pointer :: physprop(:)
     129             : 
     130             : ! Temporary storage location for filenames in namelist, and construction of dynamic index
     131             : ! to properties.  The unique filenames specified in the namelist are the identifiers of
     132             : ! the properties.  Searching the uniquefilenames array provides the index into the physprop
     133             : ! array.
     134             : character(len=256), allocatable :: uniquefilenames(:)
     135             : 
     136             : ! Number of evenly spaced intervals in rh used in this module and in the aer_rad_props module
     137             : ! for calculations of aerosol hygroscopic growth.
     138             : integer, parameter, public :: nrh = 1000
     139             : 
     140             : !================================================================================================
     141             : contains
     142             : !================================================================================================
     143             : 
     144        7680 : subroutine physprop_accum_unique_files(radname, type)
     145             : 
     146             :    ! Count number of aerosols in input radname array.  Aerosols are identified
     147             :    ! as strings with a ".nc" suffix.
     148             :    ! Construct a cumulative list of unique filenames containing physical property data.
     149             : 
     150             :    character(len=*), intent(in)  :: radname(:)
     151             :    character(len=1), intent(in)  :: type(:)
     152             : 
     153             :    integer :: ncnst, i
     154             :    character(len=*), parameter :: subname = 'physprop_accum_unique_files'
     155             :    !------------------------------------------------------------------------------------
     156             : 
     157             :    ! Initial guess for number of files we need.
     158        7680 :    if (.not. allocated(uniquefilenames)) allocate(uniquefilenames(50))
     159             : 
     160        7680 :    ncnst = ubound(radname, 1)
     161             : 
     162       53760 :    do i = 1, ncnst
     163             : 
     164             :       ! check if radname is either a bulk aerosol or a mode
     165       53760 :       if (type(i) == 'A' .or. type(i) == 'M' .or. type(i) == 'B') then
     166             : 
     167             :          ! check if this filename has been used by another aerosol.  If not
     168             :          ! then add it to the list of unique names.
     169       33792 :          if (physprop_get_id(radname(i)) < 0) then
     170       19968 :             numphysprops = numphysprops + 1
     171       19968 :             if (numphysprops > size(uniquefilenames)) then
     172           0 :                call double_capacity(uniquefilenames)
     173             :             end if
     174       19968 :             uniquefilenames(numphysprops) = trim(radname(i))
     175             :          endif
     176             : 
     177             :       endif
     178             :    enddo
     179             : 
     180             :  contains
     181             : 
     182             :    ! Simple routine to re-allocate an array with twice the size, but with
     183             :    ! the inital values being preserved.
     184           0 :    subroutine double_capacity(array)
     185             :      character(len=256), intent(inout), allocatable :: array(:)
     186             : 
     187           0 :      character(len=256), allocatable :: tmp(:)
     188             :      integer :: ierr
     189             : 
     190           0 :      allocate(tmp(size(array)*2), stat=ierr)
     191           0 :      if ( ierr /= 0 ) then
     192           0 :         call endrun('physprop_accum_unique_files: Allocation error.')
     193             :      end if
     194             : 
     195           0 :      tmp(:size(array)) = array
     196             : 
     197           0 :      deallocate(array, stat=ierr)
     198             :      if ( ierr /= 0 ) then
     199           0 :         call endrun('physprop_accum_unique_files: Deallocation error.')
     200             :      end if
     201             : 
     202           0 :      call move_alloc(tmp, array)
     203             : 
     204           0 :    end subroutine double_capacity
     205             : 
     206             : end subroutine physprop_accum_unique_files
     207             : 
     208             : !================================================================================================
     209             : 
     210        1536 : subroutine physprop_init()
     211             : 
     212             :    ! Read properties from the aerosol data files.
     213             : 
     214             :    ! ***N.B.*** The calls to physprop_accum_unique_files must be made before calling
     215             :    !            this init routine.  physprop_accum_unique_files is responsible for building
     216             :    !            the list of files to be read here.
     217             : 
     218             :    ! Local variables
     219             :    integer            :: fileindex
     220             :    type(file_desc_t)  :: nc_id ! index to netcdf file
     221             :    character(len=256) :: locfn ! path to actual file used
     222             :    character(len=32)  :: aername_str ! string read from netCDF file -- may contain trailing
     223             :                                      ! nulls which aren't dealt with by trim()
     224             : 
     225             :    integer :: ierr ! error codes from mpi
     226             : 
     227             :    !------------------------------------------------------------------------------------
     228             : 
     229        4608 :    allocate(physprop(numphysprops))
     230             : 
     231       21504 :    do fileindex = 1, numphysprops
     232       19968 :       nullify(physprop(fileindex)%sw_hygro_ext)
     233       19968 :       nullify(physprop(fileindex)%sw_hygro_ssa)
     234       19968 :       nullify(physprop(fileindex)%sw_hygro_asm)
     235       19968 :       nullify(physprop(fileindex)%lw_hygro_abs)
     236             : 
     237       19968 :       nullify(physprop(fileindex)%sw_hygro_ext_wtp)
     238       19968 :       nullify(physprop(fileindex)%sw_hygro_ssa_wtp)
     239       19968 :       nullify(physprop(fileindex)%sw_hygro_asm_wtp)
     240       19968 :       nullify(physprop(fileindex)%lw_hygro_abs_wtp)
     241       19968 :       nullify(physprop(fileindex)%wgtpct)
     242             : 
     243       19968 :       nullify(physprop(fileindex)%sw_hygro_coreshell_ext)
     244       19968 :       nullify(physprop(fileindex)%sw_hygro_coreshell_ssa)
     245       19968 :       nullify(physprop(fileindex)%sw_hygro_coreshell_asm)
     246       19968 :       nullify(physprop(fileindex)%lw_hygro_coreshell_abs)
     247       19968 :       nullify(physprop(fileindex)%bcdust)
     248       19968 :       nullify(physprop(fileindex)%kap)
     249       19968 :       nullify(physprop(fileindex)%relh)
     250             : 
     251       19968 :       nullify(physprop(fileindex)%sw_nonhygro_ext)
     252       19968 :       nullify(physprop(fileindex)%sw_nonhygro_ssa)
     253       19968 :       nullify(physprop(fileindex)%sw_nonhygro_asm)
     254       19968 :       nullify(physprop(fileindex)%sw_nonhygro_scat)
     255       19968 :       nullify(physprop(fileindex)%sw_nonhygro_ascat)
     256       19968 :       nullify(physprop(fileindex)%lw_abs)
     257             : 
     258       19968 :       nullify(physprop(fileindex)%refindex_aer_sw)
     259       19968 :       nullify(physprop(fileindex)%refindex_aer_lw)
     260             : 
     261       19968 :       nullify(physprop(fileindex)%r_sw_ext)
     262       19968 :       nullify(physprop(fileindex)%r_sw_scat)
     263       19968 :       nullify(physprop(fileindex)%r_sw_ascat)
     264       19968 :       nullify(physprop(fileindex)%r_lw_abs)
     265       19968 :       nullify(physprop(fileindex)%mu)
     266             : 
     267       19968 :       nullify(physprop(fileindex)%extpsw)
     268       19968 :       nullify(physprop(fileindex)%abspsw)
     269       19968 :       nullify(physprop(fileindex)%asmpsw)
     270       19968 :       nullify(physprop(fileindex)%absplw)
     271       19968 :       nullify(physprop(fileindex)%refrtabsw)
     272       19968 :       nullify(physprop(fileindex)%refitabsw)
     273       19968 :       nullify(physprop(fileindex)%refrtablw)
     274       19968 :       nullify(physprop(fileindex)%refitablw)
     275             : 
     276       19968 :       nullify(physprop(fileindex)%extpsw2)
     277       19968 :       nullify(physprop(fileindex)%abspsw2)
     278       19968 :       nullify(physprop(fileindex)%asmpsw2)
     279       19968 :       nullify(physprop(fileindex)%absplw2)
     280       19968 :       nullify(physprop(fileindex)%corefrac)
     281             : 
     282       19968 :       call getfil(uniquefilenames(fileindex), locfn, 0)
     283       19968 :       physprop(fileindex)%sourcefile = locfn
     284             : 
     285             :       ! Open the physprop file
     286       19968 :       call cam_pio_openfile(nc_id, locfn, PIO_NOWRITE)
     287             : 
     288       19968 :       call aerosol_optics_init(physprop(fileindex), nc_id)
     289             : 
     290             :       ! Close the physprop file
     291       21504 :       call pio_closefile(nc_id)
     292             : 
     293             :    end do
     294        1536 : end subroutine physprop_init
     295             : 
     296             : !================================================================================================
     297             : 
     298       67584 : integer function physprop_get_id(filename)
     299             : 
     300             :    ! Look for filename in the global list of unique filenames (module data uniquefilenames).
     301             :    ! If found, return it's index in the list.  Otherwise return -1.
     302             : 
     303             :    character(len=*), intent(in) :: filename
     304             :    integer iphysprop
     305             : 
     306       67584 :    physprop_get_id = -1
     307      574464 :    do iphysprop = 1, numphysprops
     308      574464 :      if(trim(uniquefilenames(iphysprop)) == trim(filename) ) then
     309       47616 :        physprop_get_id = iphysprop
     310       47616 :        return
     311             :      endif
     312             :    enddo
     313             : 
     314             : end function physprop_get_id
     315             : 
     316             : !================================================================================================
     317             : 
     318           0 : subroutine physprop_get(id, sourcefile, opticstype, &
     319             :    sw_hygro_ext, sw_hygro_ssa, sw_hygro_asm, lw_hygro_abs, &
     320             :    sw_hygro_ext_wtp, sw_hygro_ssa_wtp, sw_hygro_asm_wtp, lw_hygro_abs_wtp, &
     321             :    sw_nonhygro_ext, sw_nonhygro_ssa, sw_nonhygro_asm, &
     322             :    sw_nonhygro_scat, sw_nonhygro_ascat, lw_abs, &
     323             :    refindex_aer_sw, refindex_aer_lw, &
     324             :    r_sw_ext, r_sw_scat, r_sw_ascat, r_lw_abs, mu, &
     325             :    extpsw, abspsw, asmpsw, absplw, refrtabsw, &
     326             :    refitabsw, refrtablw, refitablw, &
     327           0 :    aername, density_aer, hygro_aer, dryrad_aer, dispersion_aer, &
     328             :    num_to_mass_aer, ncoef, prefr, prefi, sigmag, &
     329             :    dgnum, dgnumlo, dgnumhi, rhcrystal, rhdeliques, &
     330             :    extpsw2, abspsw2, asmpsw2, absplw2, corefrac, nfrac, &
     331             :    wgtpct, bcdust, kap, relh, &
     332             :    nkap, nwtp, nbcdust, nrelh, &
     333             :    sw_hygro_coreshell_ext, sw_hygro_coreshell_ssa, &
     334             :    sw_hygro_coreshell_asm, lw_hygro_coreshell_abs )
     335             : 
     336             :    ! Return requested properties for specified ID.
     337             : 
     338             :    ! Arguments
     339             :    integer,                            intent(in)  :: id
     340             :    character(len=256),       optional, intent(out) :: sourcefile ! Absolute pathname of data file.
     341             :    character(len=ot_length), optional, intent(out) :: opticstype
     342             :    real(r8),          optional, pointer     :: sw_hygro_ext(:,:)
     343             :    real(r8),          optional, pointer     :: sw_hygro_ssa(:,:)
     344             :    real(r8),          optional, pointer     :: sw_hygro_asm(:,:)
     345             :    real(r8),          optional, pointer     :: lw_hygro_abs(:,:)
     346             :    real(r8),          optional, pointer     :: sw_hygro_ext_wtp(:,:)
     347             :    real(r8),          optional, pointer     :: sw_hygro_ssa_wtp(:,:)
     348             :    real(r8),          optional, pointer     :: sw_hygro_asm_wtp(:,:)
     349             :    real(r8),          optional, pointer     :: lw_hygro_abs_wtp(:,:)
     350             :    real(r8),          optional, pointer     :: wgtpct(:)
     351             :    integer,           optional, intent(out) :: nwtp
     352             : 
     353             :    real(r8),          optional, pointer     :: sw_hygro_coreshell_ext(:,:,:,:,:)
     354             :    real(r8),          optional, pointer     :: sw_hygro_coreshell_ssa(:,:,:,:,:)
     355             :    real(r8),          optional, pointer     :: sw_hygro_coreshell_asm(:,:,:,:,:)
     356             :    real(r8),          optional, pointer     :: lw_hygro_coreshell_abs(:,:,:,:,:)
     357             :    real(r8),          optional, pointer     :: kap(:)
     358             :    integer,           optional, intent(out) :: nkap
     359             :    real(r8),          optional, pointer     :: bcdust(:)
     360             :    integer,           optional, intent(out) :: nbcdust
     361             :    real(r8),          optional, pointer     :: relh(:)
     362             :    integer,           optional, intent(out) :: nrelh
     363             : 
     364             :    real(r8),          optional, pointer     :: sw_nonhygro_ext(:)
     365             :    real(r8),          optional, pointer     :: sw_nonhygro_ssa(:)
     366             :    real(r8),          optional, pointer     :: sw_nonhygro_asm(:)
     367             :    real(r8),          optional, pointer     :: sw_nonhygro_scat(:)
     368             :    real(r8),          optional, pointer     :: sw_nonhygro_ascat(:)
     369             :    real(r8),          optional, pointer     :: lw_abs(:)
     370             :    complex(r8),       optional, pointer     :: refindex_aer_sw(:)
     371             :    complex(r8),       optional, pointer     :: refindex_aer_lw(:)
     372             :    real(r8),          optional, pointer     :: r_sw_ext(:,:)
     373             :    real(r8),          optional, pointer     :: r_sw_scat(:,:)
     374             :    real(r8),          optional, pointer     :: r_sw_ascat(:,:)
     375             :    real(r8),          optional, pointer     :: r_lw_abs(:,:)
     376             :    real(r8),          optional, pointer     :: mu(:)
     377             :    real(r8),          optional, pointer     :: extpsw(:,:,:,:)
     378             :    real(r8),          optional, pointer     :: abspsw(:,:,:,:)
     379             :    real(r8),          optional, pointer     :: asmpsw(:,:,:,:)
     380             :    real(r8),          optional, pointer     :: absplw(:,:,:,:)
     381             :    real(r8),          optional, pointer     :: refrtabsw(:,:)
     382             :    real(r8),          optional, pointer     :: refitabsw(:,:)
     383             :    real(r8),          optional, pointer     :: refrtablw(:,:)
     384             :    real(r8),          optional, pointer     :: refitablw(:,:)
     385             :    character(len=20), optional, intent(out) :: aername
     386             :    real(r8),          optional, intent(out) :: density_aer
     387             :    real(r8),          optional, intent(out) :: hygro_aer
     388             :    real(r8),          optional, intent(out) :: dryrad_aer
     389             :    real(r8),          optional, intent(out) :: dispersion_aer
     390             :    real(r8),          optional, intent(out) :: num_to_mass_aer
     391             :    integer,           optional, intent(out) :: ncoef
     392             :    integer,           optional, intent(out) :: prefr
     393             :    integer,           optional, intent(out) :: prefi
     394             :    real(r8),          optional, intent(out) :: sigmag
     395             :    real(r8),          optional, intent(out) :: dgnum
     396             :    real(r8),          optional, intent(out) :: dgnumlo
     397             :    real(r8),          optional, intent(out) :: dgnumhi
     398             :    real(r8),          optional, intent(out) :: rhcrystal
     399             :    real(r8),          optional, intent(out) :: rhdeliques
     400             : ! for core/shell
     401             :    real(r8),          optional, pointer     :: extpsw2(:,:)
     402             :    real(r8),          optional, pointer     :: abspsw2(:,:)
     403             :    real(r8),          optional, pointer     :: asmpsw2(:,:)
     404             :    real(r8),          optional, pointer     :: absplw2(:,:)
     405             :    real(r8),          optional, pointer     :: corefrac(:)
     406             :    integer,           optional, intent(out) :: nfrac
     407             : 
     408             :    ! Local variables
     409             :    character(len=*), parameter :: subname = 'physprop_get'
     410             :    !------------------------------------------------------------------------------------
     411             : 
     412  5696288967 :    if (id <= 0 .or. id > numphysprops) then
     413           0 :       write(iulog,*) subname//': illegal ID value: ', id
     414           0 :       call endrun('physprop_get: ID out of range')
     415             :    end if
     416             : 
     417  5696288967 :    if (present(sourcefile))        sourcefile        =  physprop(id)%sourcefile
     418  5696288967 :    if (present(opticstype))        opticstype        =  physprop(id)%opticsmethod
     419  5696288967 :    if (present(sw_hygro_ext))      sw_hygro_ext      => physprop(id)%sw_hygro_ext
     420  5696288967 :    if (present(sw_hygro_ssa))      sw_hygro_ssa      => physprop(id)%sw_hygro_ssa
     421  5696288967 :    if (present(sw_hygro_asm))      sw_hygro_asm      => physprop(id)%sw_hygro_asm
     422  5696288967 :    if (present(lw_hygro_abs))      lw_hygro_abs      => physprop(id)%lw_hygro_abs
     423  5696288967 :    if (present(sw_hygro_ext_wtp))  sw_hygro_ext_wtp  => physprop(id)%sw_hygro_ext_wtp
     424  5696288967 :    if (present(sw_hygro_ssa_wtp))  sw_hygro_ssa_wtp  => physprop(id)%sw_hygro_ssa_wtp
     425  5696288967 :    if (present(sw_hygro_asm_wtp))  sw_hygro_asm_wtp  => physprop(id)%sw_hygro_asm_wtp
     426  5696288967 :    if (present(lw_hygro_abs_wtp))  lw_hygro_abs_wtp  => physprop(id)%lw_hygro_abs_wtp
     427  5696288967 :    if (present(wgtpct))            wgtpct            => physprop(id)%wgtpct
     428  5696288967 :    if (present(nwtp))              nwtp              =  physprop(id)%nwtp
     429  5696288967 :    if (present(sw_hygro_coreshell_ext)) sw_hygro_coreshell_ext => physprop(id)%sw_hygro_coreshell_ext
     430  5696288967 :    if (present(sw_hygro_coreshell_ssa)) sw_hygro_coreshell_ssa => physprop(id)%sw_hygro_coreshell_ssa
     431  5696288967 :    if (present(sw_hygro_coreshell_asm)) sw_hygro_coreshell_asm => physprop(id)%sw_hygro_coreshell_asm
     432  5696288967 :    if (present(lw_hygro_coreshell_abs)) lw_hygro_coreshell_abs => physprop(id)%lw_hygro_coreshell_abs
     433  5696288967 :    if (present(kap))                    kap                    => physprop(id)%kap
     434  5696288967 :    if (present(nkap))                   nkap                   =  physprop(id)%nkap
     435  5696288967 :    if (present(bcdust))                 bcdust                 => physprop(id)%bcdust
     436  5696288967 :    if (present(nbcdust))                nbcdust                =  physprop(id)%nbcdust
     437  5696288967 :    if (present(relh))                   relh                   => physprop(id)%relh
     438  5696288967 :    if (present(nrelh))                  nrelh                  =  physprop(id)%nrelh
     439  5696288967 :    if (present(sw_nonhygro_ext))   sw_nonhygro_ext   => physprop(id)%sw_nonhygro_ext
     440  5696288967 :    if (present(sw_nonhygro_ssa))   sw_nonhygro_ssa   => physprop(id)%sw_nonhygro_ssa
     441  5696288967 :    if (present(sw_nonhygro_asm))   sw_nonhygro_asm   => physprop(id)%sw_nonhygro_asm
     442  5696288967 :    if (present(sw_nonhygro_scat))  sw_nonhygro_scat  => physprop(id)%sw_nonhygro_scat
     443  5696288967 :    if (present(sw_nonhygro_ascat)) sw_nonhygro_ascat => physprop(id)%sw_nonhygro_ascat
     444  5696288967 :    if (present(lw_abs))            lw_abs            => physprop(id)%lw_abs
     445             : 
     446  5696288967 :    if (present(refindex_aer_sw))   refindex_aer_sw   => physprop(id)%refindex_aer_sw
     447  5696288967 :    if (present(refindex_aer_lw))   refindex_aer_lw   => physprop(id)%refindex_aer_lw
     448             : 
     449  5696288967 :    if (present(r_sw_ext))          r_sw_ext      => physprop(id)%r_sw_ext
     450  5696288967 :    if (present(r_sw_scat))         r_sw_scat     => physprop(id)%r_sw_scat
     451  5696288967 :    if (present(r_sw_ascat))        r_sw_ascat    => physprop(id)%r_sw_ascat
     452  5696288967 :    if (present(r_lw_abs))          r_lw_abs      => physprop(id)%r_lw_abs
     453  5696288967 :    if (present(mu))                mu            => physprop(id)%mu
     454             : 
     455  5696288967 :    if (present(extpsw))            extpsw        => physprop(id)%extpsw
     456  5696288967 :    if (present(abspsw))            abspsw        => physprop(id)%abspsw
     457  5696288967 :    if (present(asmpsw))            asmpsw        => physprop(id)%asmpsw
     458  5696288967 :    if (present(absplw))            absplw        => physprop(id)%absplw
     459  5696288967 :    if (present(refrtabsw))         refrtabsw     => physprop(id)%refrtabsw
     460  5696288967 :    if (present(refitabsw))         refitabsw     => physprop(id)%refitabsw
     461  5696288967 :    if (present(refrtablw))         refrtablw     => physprop(id)%refrtablw
     462  5696288967 :    if (present(refitablw))         refitablw     => physprop(id)%refitablw
     463             : 
     464  5696288967 :    if (present(aername))         aername         =  physprop(id)%aername
     465  5696288967 :    if (present(density_aer))     density_aer     =  physprop(id)%density_aer
     466  5696288967 :    if (present(hygro_aer))       hygro_aer       =  physprop(id)%hygro_aer
     467  5696288967 :    if (present(dryrad_aer))      dryrad_aer      =  physprop(id)%dryrad_aer
     468  5696288967 :    if (present(dispersion_aer))  dispersion_aer  =  physprop(id)%dispersion_aer
     469  5696288967 :    if (present(num_to_mass_aer)) num_to_mass_aer =  physprop(id)%num_to_mass_aer
     470             : 
     471  5696288967 :    if (present(ncoef))           ncoef           =  physprop(id)%ncoef
     472  5696288967 :    if (present(prefr))           prefr           =  physprop(id)%prefr
     473  5696288967 :    if (present(prefi))           prefi           =  physprop(id)%prefi
     474  5696288967 :    if (present(sigmag))          sigmag          =  physprop(id)%sigmag
     475  5696288967 :    if (present(dgnum))           dgnum           =  physprop(id)%dgnum
     476  5696288967 :    if (present(dgnumlo))         dgnumlo         =  physprop(id)%dgnumlo
     477  5696288967 :    if (present(dgnumhi))         dgnumhi         =  physprop(id)%dgnumhi
     478  5696288967 :    if (present(rhcrystal))       rhcrystal       =  physprop(id)%rhcrystal
     479  5696288967 :    if (present(rhdeliques))      rhdeliques      =  physprop(id)%rhdeliques
     480             : 
     481             : ! For core/shell bins
     482  5696288967 :    if (present(extpsw2))            extpsw2        => physprop(id)%extpsw2
     483  5696288967 :    if (present(abspsw2))            abspsw2        => physprop(id)%abspsw2
     484  5696288967 :    if (present(asmpsw2))            asmpsw2        => physprop(id)%asmpsw2
     485  5696288967 :    if (present(absplw2))            absplw2        => physprop(id)%absplw2
     486  5696288967 :    if (present(corefrac))           corefrac       => physprop(id)%corefrac
     487  5696288967 :    if (present(nfrac))              nfrac         =  physprop(id)%nfrac
     488             : 
     489  5696288967 : end subroutine physprop_get
     490             : 
     491             : !================================================================================================
     492             : ! Private methods
     493             : !================================================================================================
     494             : 
     495       19968 : subroutine aerosol_optics_init(phys_prop, nc_id)
     496             : 
     497             :    ! Determine the opticstype, then call the
     498             :    ! appropriate routine to read the data.
     499             : 
     500             :    type(physprop_type), intent(inout) :: phys_prop  ! data after interp onto cam rh mesh
     501             :    type(file_desc_t),   intent(inout) :: nc_id      ! indentifier for netcdf file
     502             : 
     503             :    integer :: opticslength_id, opticslength
     504             :    type(var_desc_t) :: op_type_id
     505             :    integer :: ierr ! mpi error codes
     506             :    character(len=ot_length)  :: opticstype_str ! string read from netCDF file -- may contain trailing
     507             :                                         ! nulls which aren't dealt with by trim()
     508             :    !------------------------------------------------------------------------------------
     509             : 
     510       19968 :    ierr = pio_inq_dimid(nc_id, 'opticsmethod_len', opticslength_id)
     511       19968 :    ierr = pio_inq_dimlen(nc_id, opticslength_id, opticslength)
     512       19968 :    if ( opticslength .gt. ot_length ) then
     513           0 :       call endrun(" optics type length in "//phys_prop%sourcefile//" excedes maximum length of 32")
     514             :    endif
     515       19968 :    ierr = pio_inq_varid(nc_id, 'opticsmethod', op_type_id)
     516       19968 :    ierr = pio_get_var(nc_id, op_type_id,phys_prop%opticsmethod )
     517             : 
     518           0 :    select case (phys_prop%opticsmethod)
     519             :    case ('zero')
     520           0 :       call zero_optics_init(phys_prop, nc_id)
     521             : 
     522             :    case ('hygro')
     523           0 :       call hygro_optics_init(phys_prop, nc_id)
     524             : 
     525             :    case ('hygroscopic')
     526        4608 :       call hygroscopic_optics_init(phys_prop, nc_id)
     527             : 
     528             :    case ('hygroscopic_wtp')
     529           0 :       call hygroscopic_wtp_optics_init(phys_prop, nc_id)
     530             : 
     531             :    case ('hygroscopic_coreshell')
     532           0 :       call hygroscopic_coreshell_optics_init(phys_prop, nc_id)
     533             : 
     534             :    case ('nonhygro')
     535           0 :       call nonhygro_optics_init(phys_prop, nc_id)
     536             : 
     537             :    case ('insoluble')
     538        4608 :       call insoluble_optics_init(phys_prop, nc_id)
     539             : 
     540             :    case ('volcanic_radius','volcanic_radius1','volcanic_radius2','volcanic_radius3')
     541        4608 :       call volcanic_radius_optics_init(phys_prop, nc_id)
     542             : 
     543             :    case ('volcanic')
     544           0 :       call volcanic_optics_init(phys_prop, nc_id)
     545             : 
     546             :    case ('modal')
     547        6144 :       call modal_optics_init(phys_prop, nc_id)
     548             : 
     549             :    case ('sectional')
     550           0 :       call bin_optics_init(phys_prop, nc_id)
     551             : 
     552             :    case ('sectional_props')
     553           0 :       call bindef_optics_init(phys_prop, nc_id)
     554             : 
     555             :    ! other types of optics can be added here
     556             : 
     557             :    case default
     558             :       call endrun('aerosol_optics_init: unsupported optics type '//&
     559       19968 :          trim(phys_prop%opticsmethod)//' in file '//phys_prop%sourcefile)
     560             :    end select
     561             : 
     562  5696288967 : end subroutine aerosol_optics_init
     563             : 
     564             : !================================================================================================
     565             : 
     566           0 : subroutine hygro_optics_init(phys_prop, nc_id)
     567             : 
     568             :    ! Read optics data of type 'hygro' and interpolate it to CAM's rh mesh.
     569             : 
     570             :    type (physprop_type), intent(inout) :: phys_prop  ! data after interp onto cam rh mesh
     571             :    type (file_desc_t),   intent(inout) :: nc_id      ! indentifier for netcdf file
     572             : 
     573             :    ! Local variables
     574             :    integer :: ierr ! error flag
     575             : 
     576             :    integer :: rh_idx_id, lw_band_id, sw_band_id
     577             :    integer :: kbnd, krh
     578             :    integer :: rh_id, sw_ext_id, sw_ssa_id, sw_asm_id, lw_ext_id
     579             :    integer :: nbnd, swbands
     580             : 
     581             :    ! temp data from hygroscopic file before interpolation onto cam-rh-mesh
     582             :    integer  :: nfilerh ! number of rh values in file
     583           0 :    real(r8), allocatable, dimension(:) :: frh
     584           0 :    real(r8), allocatable, dimension(:,:)  :: fsw_ext
     585           0 :    real(r8), allocatable, dimension(:,:)  :: fsw_ssa
     586           0 :    real(r8), allocatable, dimension(:,:)  :: fsw_asm
     587             : 
     588             :    real(r8) :: rh ! real rh value on cam rh mesh (indexvalue)
     589             :    !------------------------------------------------------------------------------------
     590             : 
     591           0 :    allocate(phys_prop%sw_hygro_ext(nrh,nswbands))
     592           0 :    allocate(phys_prop%sw_hygro_ssa(nrh,nswbands))
     593           0 :    allocate(phys_prop%sw_hygro_asm(nrh,nswbands))
     594           0 :    allocate(phys_prop%lw_abs(nlwbands))
     595             : 
     596           0 :    ierr = pio_inq_dimid(nc_id, 'rh_idx', rh_idx_id)
     597             : 
     598           0 :    ierr = pio_inq_dimlen(nc_id, rh_idx_id, nfilerh)
     599             : 
     600           0 :    ierr = pio_inq_dimid(nc_id, 'lw_band', lw_band_id)
     601             : 
     602           0 :    ierr = pio_inq_dimid(nc_id, 'sw_band', sw_band_id)
     603             : 
     604           0 :    ierr = pio_inq_dimlen(nc_id, lw_band_id, nbnd)
     605             : 
     606           0 :    if (nbnd .ne. nlwbands) call endrun(phys_prop%sourcefile// &
     607           0 :         ' has the wrong number of lwbands')
     608             : 
     609           0 :    ierr = pio_inq_dimlen(nc_id, sw_band_id, swbands)
     610             : 
     611           0 :    if(swbands .ne. nswbands) call endrun(phys_prop%sourcefile// &
     612           0 :          ' has the wrong number of sw bands')
     613             : 
     614           0 :    ierr = pio_inq_varid(nc_id, 'rh', rh_id)
     615             : 
     616           0 :    ierr = pio_inq_varid(nc_id, 'ext_sw', sw_ext_id)
     617             : 
     618           0 :    ierr = pio_inq_varid(nc_id, 'ssa_sw', sw_ssa_id)
     619             : 
     620           0 :    ierr = pio_inq_varid(nc_id, 'asm_sw', sw_asm_id)
     621             : 
     622           0 :    ierr = pio_inq_varid(nc_id, 'abs_lw', lw_ext_id)
     623             : 
     624             :    ! specific optical properties on file's rh mesh
     625           0 :    allocate(fsw_ext(nfilerh,nswbands))
     626           0 :    allocate(fsw_asm(nfilerh,nswbands))
     627           0 :    allocate(fsw_ssa(nfilerh,nswbands))
     628           0 :    allocate(frh(nfilerh))
     629             : 
     630           0 :    ierr = pio_get_var(nc_id, rh_id, frh)
     631             : 
     632           0 :    ierr = pio_get_var(nc_id, sw_ext_id, fsw_ext)
     633             : 
     634           0 :    ierr = pio_get_var(nc_id, sw_ssa_id, fsw_ssa)
     635             : 
     636           0 :    ierr = pio_get_var(nc_id, sw_asm_id, fsw_asm)
     637             : 
     638           0 :    ierr = pio_get_var(nc_id, lw_ext_id, phys_prop%lw_abs)
     639             : 
     640             :    ! interpolate onto cam's rh mesh
     641           0 :    do kbnd = 1,nswbands
     642           0 :       do krh = 1, nrh
     643           0 :          rh = 1.0_r8 / nrh * (krh - 1)
     644           0 :          phys_prop%sw_hygro_ext(krh,kbnd) = &
     645           0 :             exp_interpol( frh, fsw_ext(:,kbnd) / fsw_ext(1,kbnd), rh ) &
     646           0 :             * fsw_ext(1, kbnd)
     647           0 :          phys_prop%sw_hygro_ssa(krh,kbnd) = &
     648           0 :             lin_interpol( frh, fsw_ssa(:,kbnd) / fsw_ssa(1,kbnd), rh ) &
     649           0 :             * fsw_ssa(1, kbnd)
     650           0 :          phys_prop%sw_hygro_asm(krh,kbnd) = &
     651           0 :             lin_interpol( frh, fsw_asm(:,kbnd) / fsw_asm(1,kbnd), rh ) &
     652           0 :             * fsw_asm(1, kbnd)
     653             :       enddo
     654             :    enddo
     655             : 
     656           0 :    deallocate (fsw_ext, fsw_asm, fsw_ssa, frh)
     657             : 
     658             :    ! read refractive index data if available
     659           0 :    call refindex_aer_init(phys_prop, nc_id)
     660             : 
     661             :    ! read bulk aero props
     662           0 :    call bulk_props_init(phys_prop, nc_id)
     663             : 
     664           0 : end subroutine hygro_optics_init
     665             : 
     666             : !================================================================================================
     667             : 
     668           0 : subroutine zero_optics_init(phys_prop, nc_id)
     669             : 
     670             :    ! Read optics data of type 'nonhygro'
     671             : 
     672             :    type (physprop_type), intent(inout) :: phys_prop  ! storage for file data
     673             :    type (file_desc_t),   intent(inout) :: nc_id      ! indentifier for netcdf file
     674             : 
     675             :    ! Local variables
     676             :    integer :: lw_band_id, sw_band_id
     677             :    integer :: sw_ext_id, sw_ssa_id, sw_asm_id, lw_ext_id
     678             :    integer :: swbands, nbnd
     679             :    integer :: ierr ! error flag
     680             :    !------------------------------------------------------------------------------------
     681             : 
     682             :    ! perhaps this doesn't even need allocated.
     683           0 :    allocate (phys_prop%sw_nonhygro_ext(nswbands))
     684           0 :    allocate (phys_prop%sw_nonhygro_ssa(nswbands))
     685           0 :    allocate (phys_prop%sw_nonhygro_asm(nswbands))
     686           0 :    allocate (phys_prop%lw_abs(nlwbands))
     687             : 
     688           0 :    phys_prop%sw_nonhygro_ext = 0._r8
     689           0 :    phys_prop%sw_nonhygro_ssa = 0._r8
     690           0 :    phys_prop%sw_nonhygro_asm = 0._r8
     691           0 :    phys_prop%lw_abs = 0._r8
     692             : 
     693           0 : end subroutine zero_optics_init
     694             : 
     695             : !================================================================================================
     696             : 
     697        4608 : subroutine insoluble_optics_init(phys_prop, nc_id)
     698             : 
     699             :    ! Read optics data of type 'nonhygro'
     700             : 
     701             :    type (physprop_type), intent(inout) :: phys_prop  ! storage for file data
     702             :    type (file_desc_t),   intent(inout) :: nc_id      ! indentifier for netcdf file
     703             : 
     704             :    ! Local variables
     705             :    integer :: lw_band_id, sw_band_id
     706             :    integer :: sw_ext_id, sw_ssa_id, sw_asm_id, lw_ext_id
     707             :    integer :: swbands, nbnd
     708             :    integer :: ierr ! error flag
     709             :    integer :: start(2), count(2)
     710             :    !------------------------------------------------------------------------------------
     711             : 
     712        4608 :    allocate (phys_prop%sw_nonhygro_ext(nswbands))
     713        4608 :    allocate (phys_prop%sw_nonhygro_ssa(nswbands))
     714        4608 :    allocate (phys_prop%sw_nonhygro_asm(nswbands))
     715        4608 :    allocate (phys_prop%lw_abs(nlwbands))
     716             : 
     717        4608 :    ierr = pio_inq_dimid(nc_id, 'lw_band', lw_band_id)
     718             : 
     719        4608 :    ierr = pio_inq_dimid(nc_id, 'sw_band', sw_band_id)
     720             : 
     721        4608 :    ierr = pio_inq_dimlen(nc_id, lw_band_id, nbnd)
     722             : 
     723        4608 :    if (nbnd .ne. nlwbands) call endrun(phys_prop%sourcefile// &
     724           0 :         ' has the wrong number of lwbands')
     725             : 
     726        4608 :    ierr = pio_inq_dimlen(nc_id, sw_band_id, swbands)
     727             : 
     728        4608 :    if (swbands .ne. nswbands) call endrun(phys_prop%sourcefile// &
     729           0 :         ' has the wrong number of sw bands')
     730             : 
     731             :    ! read file data
     732        4608 :    ierr = pio_inq_varid(nc_id, 'ext_sw', sw_ext_id)
     733        4608 :    ierr = pio_inq_varid(nc_id, 'ssa_sw', sw_ssa_id)
     734        4608 :    ierr = pio_inq_varid(nc_id, 'asm_sw', sw_asm_id)
     735        4608 :    ierr = pio_inq_varid(nc_id, 'abs_lw', lw_ext_id)
     736             : 
     737       13824 :    start = 1
     738       13824 :    count=(/1,swbands/)
     739             : 
     740        4608 :    ierr = pio_get_var(nc_id, sw_ext_id, start, count, phys_prop%sw_nonhygro_ext)
     741        4608 :    ierr = pio_get_var(nc_id, sw_ssa_id, start, count, phys_prop%sw_nonhygro_ssa)
     742        4608 :    ierr = pio_get_var(nc_id, sw_asm_id, start, count, phys_prop%sw_nonhygro_asm)
     743       13824 :    count = (/1,nbnd/)
     744        4608 :    ierr = pio_get_var(nc_id, lw_ext_id, start, count, phys_prop%lw_abs)
     745             : 
     746             :    ! read refractive index data if available
     747        4608 :    call refindex_aer_init(phys_prop, nc_id)
     748             : 
     749             :    ! read bulk aero props
     750        4608 :    call bulk_props_init(phys_prop, nc_id)
     751             : 
     752        4608 : end subroutine insoluble_optics_init
     753             : 
     754             : !================================================================================================
     755             : 
     756        4608 : subroutine volcanic_radius_optics_init(phys_prop, nc_id)
     757             : 
     758             :    ! Read optics data of type 'volcanic_radius'
     759             : 
     760             :    type (physprop_type), intent(inout) :: phys_prop  ! storage for file data
     761             :    type (file_desc_t),   intent(inout) :: nc_id      ! indentifier for netcdf file
     762             : 
     763             :    ! Local variables
     764             :    integer :: lw_band_id, sw_band_id, mu_id, mu_did
     765             :    integer :: sw_ext_id, sw_scat_id, sw_ascat_id, lw_abs_id
     766             :    integer :: swbands, nbnd, n_mu_samples
     767             :    integer :: ierr ! error flag
     768             :    !------------------------------------------------------------------------------------
     769             : 
     770        4608 :    ierr = pio_inq_dimid(nc_id, 'mu_samples', mu_did)
     771        4608 :    ierr = pio_inq_dimlen(nc_id, mu_did, n_mu_samples)
     772             : 
     773       13824 :    allocate (phys_prop%r_sw_ext(nswbands,n_mu_samples))
     774        9216 :    allocate (phys_prop%r_sw_scat(nswbands,n_mu_samples))
     775        9216 :    allocate (phys_prop%r_sw_ascat(nswbands,n_mu_samples))
     776       13824 :    allocate (phys_prop%r_lw_abs(nlwbands,n_mu_samples))
     777       13824 :    allocate (phys_prop%mu(n_mu_samples))
     778             : 
     779        4608 :    ierr = pio_inq_dimid(nc_id, 'lw_band', lw_band_id)
     780             : 
     781        4608 :    ierr = pio_inq_dimid(nc_id, 'sw_band', sw_band_id)
     782             : 
     783        4608 :    ierr = pio_inq_dimlen(nc_id, lw_band_id, nbnd)
     784             : 
     785        4608 :    if (nbnd .ne. nlwbands) call endrun(phys_prop%sourcefile// &
     786           0 :         ' has the wrong number of lwbands')
     787             : 
     788        4608 :    ierr = pio_inq_dimlen(nc_id, sw_band_id, swbands)
     789             : 
     790        4608 :    if (swbands .ne. nswbands) call endrun(phys_prop%sourcefile// &
     791           0 :         ' has the wrong number of sw bands')
     792             : 
     793             :    ! read file data
     794        4608 :    ierr = pio_inq_varid(nc_id, 'bext_sw', sw_ext_id)
     795        4608 :    ierr = pio_inq_varid(nc_id, 'bsca_sw', sw_scat_id)
     796        4608 :    ierr = pio_inq_varid(nc_id, 'basc_sw', sw_ascat_id)
     797        4608 :    ierr = pio_inq_varid(nc_id, 'babs_lw', lw_abs_id)
     798        4608 :    ierr = pio_inq_varid(nc_id, 'mu_samples', mu_id)
     799             : 
     800        4608 :    ierr = pio_get_var(nc_id, sw_ext_id, phys_prop%r_sw_ext)
     801        4608 :    ierr = pio_get_var(nc_id, sw_scat_id, phys_prop%r_sw_scat)
     802        4608 :    ierr = pio_get_var(nc_id, sw_ascat_id, phys_prop%r_sw_ascat)
     803        4608 :    ierr = pio_get_var(nc_id, lw_abs_id, phys_prop%r_lw_abs)
     804        4608 :    ierr = pio_get_var(nc_id, mu_id, phys_prop%mu)
     805             : 
     806             :    ! read bulk aero props
     807        4608 :    call bulk_props_init(phys_prop, nc_id)
     808             : 
     809        4608 : end subroutine volcanic_radius_optics_init
     810             : 
     811             : !================================================================================================
     812             : 
     813           0 : subroutine volcanic_optics_init(phys_prop, nc_id)
     814             : 
     815             :    ! Read optics data of type 'volcanic'
     816             : 
     817             :    type (physprop_type), intent(inout) :: phys_prop  ! storage for file data
     818             :    type (file_desc_t)  , intent(inout) :: nc_id      ! indentifier for netcdf file
     819             : 
     820             :    ! Local variables
     821             :    integer :: lw_band_id, sw_band_id
     822             :    integer :: sw_ext_id, sw_scat_id, sw_ascat_id, lw_abs_id
     823             :    integer :: swbands, nbnd
     824             :    integer :: ierr ! error flag
     825             :    !------------------------------------------------------------------------------------
     826             : 
     827           0 :    allocate (phys_prop%sw_nonhygro_ext(nswbands))
     828           0 :    allocate (phys_prop%sw_nonhygro_scat(nswbands))
     829           0 :    allocate (phys_prop%sw_nonhygro_ascat(nswbands))
     830           0 :    allocate (phys_prop%lw_abs(nlwbands))
     831             : 
     832           0 :    ierr = pio_inq_dimid(nc_id, 'lw_band', lw_band_id)
     833           0 :    ierr = pio_inq_dimid(nc_id, 'sw_band', sw_band_id)
     834             : 
     835           0 :    ierr = pio_inq_dimlen(nc_id, lw_band_id, nbnd)
     836             : 
     837           0 :    if (nbnd .ne. nlwbands) call endrun(phys_prop%sourcefile// &
     838           0 :         ' has the wrong number of lwbands')
     839             : 
     840           0 :    ierr = pio_inq_dimlen(nc_id, sw_band_id, swbands)
     841           0 :    if(masterproc) write(iulog,*) 'swbands',swbands
     842             : 
     843           0 :    if (swbands .ne. nswbands) call endrun(phys_prop%sourcefile// &
     844           0 :         ' has the wrong number of sw bands')
     845             : 
     846             :    ! read file data
     847           0 :    ierr = pio_inq_varid(nc_id, 'bext_sw', sw_ext_id)
     848           0 :    ierr = pio_inq_varid(nc_id, 'bsca_sw', sw_scat_id)
     849           0 :    ierr = pio_inq_varid(nc_id, 'basc_sw', sw_ascat_id)
     850           0 :    ierr = pio_inq_varid(nc_id, 'babs_lw', lw_abs_id)
     851             : 
     852           0 :    ierr = pio_get_var(nc_id, sw_ext_id, phys_prop%sw_nonhygro_ext)
     853           0 :    ierr = pio_get_var(nc_id, sw_scat_id, phys_prop%sw_nonhygro_scat)
     854           0 :    ierr = pio_get_var(nc_id, sw_ascat_id, phys_prop%sw_nonhygro_ascat)
     855           0 :    ierr = pio_get_var(nc_id, lw_abs_id, phys_prop%lw_abs)
     856             : 
     857             :    ! read bulk aero props
     858           0 :    call bulk_props_init(phys_prop, nc_id)
     859             : 
     860           0 : end subroutine volcanic_optics_init
     861             : 
     862             : !================================================================================================
     863             : 
     864        4608 : subroutine hygroscopic_optics_init(phys_prop, nc_id)
     865             : 
     866             :    ! Read optics data of type 'hygroscopic' and interpolate it to CAM's rh mesh.
     867             : 
     868             :    type (physprop_type), intent(inout) :: phys_prop  ! data after interp onto cam rh mesh
     869             :    type (file_desc_T),   intent(inout) :: nc_id      ! indentifier for netcdf file
     870             : 
     871             :    ! Local variables
     872             :    integer :: ierr ! error flag
     873             : 
     874             :    integer :: rh_idx_id, lw_band_id, sw_band_id
     875             :    integer :: kbnd, krh
     876             :    integer :: rh_id, sw_ext_id, sw_ssa_id, sw_asm_id, lw_ext_id
     877             :    integer :: nbnd, swbands
     878             : 
     879             :    ! temp data from hygroscopic file before interpolation onto cam-rh-mesh
     880             :    integer  :: nfilerh ! number of rh values in file
     881        4608 :    real(r8), allocatable, dimension(:) :: frh
     882        4608 :    real(r8), allocatable, dimension(:,:)  :: fsw_ext
     883        4608 :    real(r8), allocatable, dimension(:,:)  :: fsw_ssa
     884        4608 :    real(r8), allocatable, dimension(:,:)  :: fsw_asm
     885        4608 :    real(r8), allocatable, dimension(:,:)  :: flw_abs
     886             : 
     887             :    real(r8) :: rh ! real rh value on cam rh mesh (indexvalue)
     888             :    character(len=*), parameter :: sub = 'hygroscopic_optics_init'
     889             :    !------------------------------------------------------------------------------------
     890             : 
     891        4608 :    allocate(phys_prop%sw_hygro_ext(nrh,nswbands))
     892        4608 :    allocate(phys_prop%sw_hygro_ssa(nrh,nswbands))
     893        4608 :    allocate(phys_prop%sw_hygro_asm(nrh,nswbands))
     894        4608 :    allocate(phys_prop%lw_hygro_abs(nrh,nlwbands))
     895             : 
     896        4608 :    ierr = pio_inq_dimid(nc_id, 'rh_idx', rh_idx_id)
     897        4608 :    ierr = pio_inq_dimlen(nc_id, rh_idx_id, nfilerh)
     898             : 
     899        4608 :    ierr = pio_inq_dimid(nc_id, 'lw_band', lw_band_id)
     900        4608 :    ierr = pio_inq_dimlen(nc_id, lw_band_id, nbnd)
     901        4608 :    if (nbnd .ne. nlwbands) call endrun(phys_prop%sourcefile// &
     902           0 :         ' has the wrong number of lwbands')
     903             : 
     904        4608 :    ierr = pio_inq_dimid(nc_id, 'sw_band', sw_band_id)
     905        4608 :    ierr = pio_inq_dimlen(nc_id, sw_band_id, swbands)
     906        4608 :    if(swbands .ne. nswbands) call endrun(phys_prop%sourcefile// &
     907           0 :         ' has the wrong number of sw bands')
     908             : 
     909        4608 :    ierr = pio_inq_varid(nc_id, 'rh', rh_id)
     910        4608 :    ierr = pio_inq_varid(nc_id, 'ext_sw', sw_ext_id)
     911        4608 :    ierr = pio_inq_varid(nc_id, 'ssa_sw', sw_ssa_id)
     912        4608 :    ierr = pio_inq_varid(nc_id, 'asm_sw', sw_asm_id)
     913        4608 :    ierr = pio_inq_varid(nc_id, 'abs_lw', lw_ext_id)
     914             : 
     915             :    ! specific optical properties on file's rh mesh
     916       13824 :    allocate(fsw_ext(nfilerh,nswbands))
     917        9216 :    allocate(fsw_asm(nfilerh,nswbands))
     918        9216 :    allocate(fsw_ssa(nfilerh,nswbands))
     919       13824 :    allocate(flw_abs(nfilerh,nlwbands))
     920       13824 :    allocate(frh(nfilerh))
     921             : 
     922        4608 :    ierr = pio_get_var(nc_id, rh_id, frh)
     923        4608 :    ierr = pio_get_var(nc_id, sw_ext_id, fsw_ext)
     924        4608 :    ierr = pio_get_var(nc_id, sw_ssa_id, fsw_ssa)
     925        4608 :    ierr = pio_get_var(nc_id, sw_asm_id, fsw_asm)
     926        4608 :    ierr = pio_get_var(nc_id, lw_ext_id, flw_abs)
     927             : 
     928             :    ! interpolate onto cam's rh mesh
     929       69120 :    do kbnd = 1,nswbands
     930    64581120 :       do krh = 1, nrh
     931    64512000 :          rh = 1.0_r8 / nrh * (krh - 1)
     932           0 :          phys_prop%sw_hygro_ext(krh,kbnd) = &
     933    64512000 :             exp_interpol( frh, fsw_ext(:,kbnd) / fsw_ext(1,kbnd), rh ) &
     934   645120000 :             * fsw_ext(1, kbnd)
     935           0 :          phys_prop%sw_hygro_ssa(krh,kbnd) = &
     936    64512000 :             lin_interpol( frh, fsw_ssa(:,kbnd) / fsw_ssa(1,kbnd), rh ) &
     937   645120000 :             * fsw_ssa(1, kbnd)
     938           0 :          phys_prop%sw_hygro_asm(krh,kbnd) = &
     939    64512000 :             lin_interpol( frh, fsw_asm(:,kbnd) / fsw_asm(1,kbnd), rh ) &
     940   645184512 :             * fsw_asm(1, kbnd)
     941             :       enddo
     942             :    enddo
     943       78336 :    do kbnd = 1,nlwbands
     944    73806336 :       do krh = 1, nrh
     945    73728000 :          rh = 1.0_r8 / nrh * (krh - 1)
     946           0 :          phys_prop%lw_hygro_abs(krh,kbnd) = &
     947    73728000 :             exp_interpol( frh, flw_abs(:,kbnd) / flw_abs(1,kbnd), rh ) &
     948   737353728 :             * flw_abs(1, kbnd)
     949             :       enddo
     950             :    enddo
     951             : 
     952        4608 :    deallocate (fsw_ext, fsw_asm, fsw_ssa, flw_abs, frh)
     953             : 
     954             :    ! read refractive index data if available
     955        4608 :    call refindex_aer_init(phys_prop, nc_id)
     956             : 
     957             :    ! read bulk aero props
     958        4608 :    call bulk_props_init(phys_prop, nc_id)
     959             : 
     960        4608 : end subroutine hygroscopic_optics_init
     961             : 
     962             : !================================================================================================
     963             : 
     964           0 : subroutine nonhygro_optics_init(phys_prop, nc_id)
     965             : 
     966             :    ! Read optics data of type 'nonhygro'
     967             : 
     968             :    type (physprop_type), intent(inout) :: phys_prop  ! storage for file data
     969             :    type (file_desc_t)  , intent(inout) :: nc_id      ! indentifier for netcdf file
     970             : 
     971             :    ! Local variables
     972             :    integer :: lw_band_id, sw_band_id
     973             :    integer :: sw_ext_id, sw_ssa_id, sw_asm_id, lw_ext_id
     974             :    integer :: swbands, nbnd
     975             :    integer :: ierr ! error flag
     976             :    !------------------------------------------------------------------------------------
     977             : 
     978           0 :    allocate (phys_prop%sw_nonhygro_ext(nswbands))
     979           0 :    allocate (phys_prop%sw_nonhygro_ssa(nswbands))
     980           0 :    allocate (phys_prop%sw_nonhygro_asm(nswbands))
     981           0 :    allocate (phys_prop%lw_abs(nlwbands))
     982             : 
     983           0 :    ierr = pio_inq_dimid(nc_id, 'lw_band', lw_band_id)
     984           0 :    ierr = pio_inq_dimid(nc_id, 'sw_band', sw_band_id)
     985             : 
     986           0 :    ierr = pio_inq_dimlen(nc_id, lw_band_id, nbnd)
     987             : 
     988           0 :    if (nbnd .ne. nlwbands) call endrun(phys_prop%sourcefile// &
     989           0 :         ' has the wrong number of lwbands')
     990             : 
     991           0 :    ierr = pio_inq_dimlen(nc_id, sw_band_id, swbands)
     992             : 
     993           0 :    if (swbands .ne. nswbands) call endrun(phys_prop%sourcefile// &
     994           0 :         ' has the wrong number of sw bands')
     995             : 
     996             :    ! read file data
     997           0 :    ierr = pio_inq_varid(nc_id, 'ext_sw', sw_ext_id)
     998           0 :    ierr = pio_inq_varid(nc_id, 'ssa_sw', sw_ssa_id)
     999           0 :    ierr = pio_inq_varid(nc_id, 'asm_sw', sw_asm_id)
    1000           0 :    ierr = pio_inq_varid(nc_id, 'abs_lw', lw_ext_id)
    1001             : 
    1002           0 :    ierr = pio_get_var(nc_id, sw_ext_id, phys_prop%sw_nonhygro_ext)
    1003           0 :    ierr = pio_get_var(nc_id, sw_ssa_id, phys_prop%sw_nonhygro_ssa)
    1004           0 :    ierr = pio_get_var(nc_id, sw_asm_id, phys_prop%sw_nonhygro_asm)
    1005           0 :    ierr = pio_get_var(nc_id, lw_ext_id, phys_prop%lw_abs)
    1006             : 
    1007             :    ! read refractive index data if available
    1008           0 :    call refindex_aer_init(phys_prop, nc_id)
    1009             : 
    1010             :    ! read bulk aero props
    1011           0 :    call bulk_props_init(phys_prop, nc_id)
    1012             : 
    1013           0 : end subroutine nonhygro_optics_init
    1014             : 
    1015             : !================================================================================================
    1016             : 
    1017        9216 : subroutine refindex_aer_init(phys_prop, nc_id)
    1018             : 
    1019             : !  Read refractive indices of aerosol
    1020             : 
    1021             :    type (physprop_type), intent(inout) :: phys_prop  ! storage for file data
    1022             :    type (file_desc_T),   intent(inout) :: nc_id      ! indentifier for netcdf file
    1023             : 
    1024             :    ! Local variables
    1025             :    integer :: i
    1026             :    integer :: istat1, istat2, istat3     ! status flags
    1027             :    integer :: vid_real, vid_im           ! variable ids
    1028        9216 :    real(r8), pointer :: ref_real(:), ref_im(:)  ! tmp storage for components of complex index
    1029             :    character(len=*), parameter :: subname = 'refindex_aer_init'
    1030             :    !------------------------------------------------------------------------------------
    1031             : 
    1032             :    ! assume that the dimensions lw_band and sw_band have already been checked
    1033             :    ! by the calling subroutine
    1034             : 
    1035             :    ! Check that the variables are present before allocating storage and reading.
    1036             :    ! Since we're setting complex data values, both the real and imaginary parts must
    1037             :    ! be present or neither will be read.
    1038             : 
    1039             :    ! set PIO to return control to the caller when variable not found
    1040        9216 :    call pio_seterrorhandling(nc_id, PIO_BCAST_ERROR)
    1041             : 
    1042        9216 :    istat1 = pio_inq_varid(nc_id, 'refindex_real_aer_sw', vid_real)
    1043        9216 :    istat2 = pio_inq_varid(nc_id, 'refindex_im_aer_sw',   vid_im)
    1044             : 
    1045        9216 :    if (istat1 == PIO_NOERR  .and. istat2 == PIO_NOERR) then
    1046             : 
    1047        9216 :       allocate(ref_real(nswbands), ref_im(nswbands))
    1048             : 
    1049        9216 :       istat3 = pio_get_var(nc_id, vid_real, ref_real)
    1050        9216 :       if (istat3 /= PIO_NOERR) then
    1051           0 :          call endrun(subname//': ERROR reading refindex_real_aer_sw')
    1052             :       end if
    1053             : 
    1054        9216 :       istat3 = pio_get_var(nc_id, vid_im, ref_im)
    1055        9216 :       if (istat3 /= PIO_NOERR) then
    1056           0 :          call endrun(subname//': ERROR reading refindex_im_aer_sw')
    1057             :       end if
    1058             : 
    1059             :       ! successfully read refindex data -- set complex values in physprop object
    1060        9216 :       allocate(phys_prop%refindex_aer_sw(nswbands))
    1061      138240 :       do i = 1, nswbands
    1062           0 :          phys_prop%refindex_aer_sw(i) = cmplx(ref_real(i), abs(ref_im(i)),&
    1063      138240 :               kind=r8)
    1064             :       end do
    1065             : 
    1066        9216 :       deallocate(ref_real, ref_im)
    1067             : 
    1068             :    end if
    1069             : 
    1070        9216 :    istat1 = pio_inq_varid(nc_id, 'refindex_real_aer_lw', vid_real)
    1071        9216 :    istat2 = pio_inq_varid(nc_id, 'refindex_im_aer_lw',   vid_im)
    1072             : 
    1073        9216 :    if (istat1 == PIO_NOERR  .and. istat2 == PIO_NOERR) then
    1074             : 
    1075        9216 :       allocate(ref_real(nlwbands), ref_im(nlwbands))
    1076             : 
    1077        9216 :       istat3 = pio_get_var(nc_id, vid_real, ref_real)
    1078        9216 :       if (istat3 /= PIO_NOERR) then
    1079           0 :          call endrun(subname//': ERROR reading refindex_real_aer_lw')
    1080             :       end if
    1081             : 
    1082        9216 :       istat3 = pio_get_var(nc_id, vid_im, ref_im)
    1083        9216 :       if (istat3 /= PIO_NOERR) then
    1084           0 :          call endrun(subname//': ERROR reading refindex_im_aer_lw')
    1085             :       end if
    1086             : 
    1087             :       ! successfully read refindex data -- set complex value in physprop object
    1088        9216 :       allocate(phys_prop%refindex_aer_lw(nlwbands))
    1089      156672 :       do i = 1, nlwbands
    1090           0 :          phys_prop%refindex_aer_lw(i) = cmplx(ref_real(i), abs(ref_im(i)),&
    1091      156672 :               kind=r8)
    1092             :       end do
    1093             : 
    1094        9216 :       deallocate(ref_real, ref_im)
    1095             : 
    1096             :    end if
    1097             : 
    1098             :    ! reset PIO to handle errors internally
    1099        9216 :    call pio_seterrorhandling(nc_id, PIO_INTERNAL_ERROR)
    1100             : 
    1101        9216 : end subroutine refindex_aer_init
    1102             : 
    1103             : !================================================================================================
    1104             : 
    1105        6144 : subroutine modal_optics_init(props, ncid)
    1106             : 
    1107             : !  Read optics data for modal aerosols
    1108             : 
    1109             :    type (physprop_type), intent(inout) :: props   ! storage for file data
    1110             :    type (file_desc_T),   intent(inout) :: ncid    ! indentifier for netcdf file
    1111             : 
    1112             :    ! Local variables
    1113             :    integer :: ierr
    1114             :    integer :: did
    1115             :    integer :: ival
    1116             :    type(var_desc_t) :: vid
    1117        6144 :    real(r8), pointer :: rval(:,:,:,:,:) ! temp array used to eliminate a singleton dimension
    1118             : 
    1119             :    character(len=*), parameter :: subname = 'modal_optics_init'
    1120             :    !------------------------------------------------------------------------------------
    1121             : 
    1122             :    ! Check dimensions for number of lw and sw bands
    1123             : 
    1124        6144 :    ierr = pio_inq_dimid(ncid, 'lw_band', did)
    1125        6144 :    ierr = pio_inq_dimlen(ncid, did, ival)
    1126        6144 :    if (ival .ne. nlwbands) call endrun(subname//':'//props%sourcefile// &
    1127           0 :         ' has the wrong number of lw bands')
    1128             : 
    1129        6144 :    ierr = pio_inq_dimid(ncid, 'sw_band', did)
    1130        6144 :    ierr = pio_inq_dimlen(ncid, did, ival)
    1131        6144 :    if (ival .ne. nswbands) call endrun(subname//':'//props%sourcefile// &
    1132           0 :         ' has the wrong number of sw bands')
    1133             : 
    1134             :    ! Get other dimensions
    1135        6144 :    ierr = pio_inq_dimid(ncid, 'coef_number', did)
    1136        6144 :    ierr = pio_inq_dimlen(ncid, did, props%ncoef)
    1137             : 
    1138        6144 :    ierr = pio_inq_dimid(ncid, 'refindex_real', did)
    1139        6144 :    ierr = pio_inq_dimlen(ncid, did, props%prefr)
    1140             : 
    1141        6144 :    ierr = pio_inq_dimid(ncid, 'refindex_im', did)
    1142        6144 :    ierr = pio_inq_dimlen(ncid, did, props%prefi)
    1143             : 
    1144             :    ! Allocate arrays
    1145             :    allocate( &
    1146             :       props%extpsw(props%ncoef,props%prefr,props%prefi,nswbands), &
    1147             :       props%abspsw(props%ncoef,props%prefr,props%prefi,nswbands), &
    1148             :       props%asmpsw(props%ncoef,props%prefr,props%prefi,nswbands), &
    1149             :       props%absplw(props%ncoef,props%prefr,props%prefi,nlwbands), &
    1150             :       props%refrtabsw(props%prefr,nswbands), &
    1151             :       props%refitabsw(props%prefi,nswbands), &
    1152             :       props%refrtablw(props%prefr,nlwbands), &
    1153      153600 :       props%refitablw(props%prefi,nlwbands)  )
    1154             : 
    1155             : 
    1156             :    ! allocate temp to remove the mode dimension from the sw variables
    1157       24576 :    allocate(rval(props%ncoef,props%prefr,props%prefi,1,nswbands))
    1158             : 
    1159        6144 :    ierr = pio_inq_varid(ncid, 'extpsw', vid)
    1160        6144 :    ierr = pio_get_var(ncid, vid, rval)
    1161    37079040 :    props%extpsw = rval(:,:,:,1,:)
    1162             : 
    1163        6144 :    ierr = pio_inq_varid(ncid, 'abspsw', vid)
    1164        6144 :    ierr = pio_get_var(ncid, vid, rval)
    1165    37079040 :    props%abspsw = rval(:,:,:,1,:)
    1166             : 
    1167        6144 :    ierr = pio_inq_varid(ncid, 'asmpsw', vid)
    1168        6144 :    ierr = pio_get_var(ncid, vid, rval)
    1169    37079040 :    props%asmpsw = rval(:,:,:,1,:)
    1170             : 
    1171        6144 :    deallocate(rval)
    1172             : 
    1173             :    ! allocate temp to remove the mode dimension from the lw variables
    1174       36864 :    allocate(rval(props%ncoef,props%prefr,props%prefi,1,nlwbands))
    1175             : 
    1176        6144 :    ierr = pio_inq_varid(ncid, 'absplw', vid)
    1177        6144 :    ierr = pio_get_var(ncid, vid, rval)
    1178    42375168 :    props%absplw = rval(:,:,:,1,:)
    1179             : 
    1180        6144 :    deallocate(rval)
    1181             : 
    1182        6144 :    ierr = pio_inq_varid(ncid, 'refindex_real_sw', vid)
    1183        6144 :    ierr = pio_get_var(ncid, vid, props%refrtabsw)
    1184             : 
    1185        6144 :    ierr = pio_inq_varid(ncid, 'refindex_im_sw', vid)
    1186        6144 :    ierr = pio_get_var(ncid, vid, props%refitabsw)
    1187             : 
    1188        6144 :    ierr = pio_inq_varid(ncid, 'refindex_real_lw', vid)
    1189        6144 :    ierr = pio_get_var(ncid, vid, props%refrtablw)
    1190             : 
    1191        6144 :    ierr = pio_inq_varid(ncid, 'refindex_im_lw', vid)
    1192        6144 :    ierr = pio_get_var(ncid, vid, props%refitablw)
    1193             : 
    1194        6144 :    ierr = pio_inq_varid(ncid, 'sigmag', vid)
    1195        6144 :    ierr = pio_get_var(ncid, vid, props%sigmag)
    1196             : 
    1197        6144 :    ierr = pio_inq_varid(ncid, 'dgnum', vid)
    1198        6144 :    ierr = pio_get_var(ncid, vid, props%dgnum)
    1199             : 
    1200        6144 :    ierr = pio_inq_varid(ncid, 'dgnumlo', vid)
    1201        6144 :    ierr = pio_get_var(ncid, vid, props%dgnumlo)
    1202             : 
    1203        6144 :    ierr = pio_inq_varid(ncid, 'dgnumhi', vid)
    1204        6144 :    ierr = pio_get_var(ncid, vid, props%dgnumhi)
    1205             : 
    1206        6144 :    ierr = pio_inq_varid(ncid, 'rhcrystal', vid)
    1207        6144 :    ierr = pio_get_var(ncid, vid, props%rhcrystal)
    1208             : 
    1209        6144 :    ierr = pio_inq_varid(ncid, 'rhdeliques', vid)
    1210        6144 :    ierr = pio_get_var(ncid, vid, props%rhdeliques)
    1211             : 
    1212        6144 : end subroutine modal_optics_init
    1213             : 
    1214             : !================================================================================================
    1215             : 
    1216           0 : subroutine bin_optics_init(props, ncid)
    1217             : 
    1218             : !  Read optics data for modal aerosols
    1219             : 
    1220             :    type (physprop_type), intent(inout) :: props   ! storage for file data
    1221             :    type (file_desc_T),   intent(inout) :: ncid    ! indentifier for netcdf file
    1222             : 
    1223             :    ! Local variables
    1224             :    integer :: ierr
    1225             :    integer :: did
    1226             :    integer :: ival
    1227             :    type(var_desc_t) :: vid
    1228             : 
    1229             :    character(len=*), parameter :: subname = 'bin_optics_init'
    1230             :    !------------------------------------------------------------------------------------
    1231             : 
    1232             :    ! Check dimensions for number of lw and sw bands
    1233             : 
    1234           0 :    ierr = pio_inq_dimid(ncid, 'lw_band', did)
    1235           0 :    ierr = pio_inq_dimlen(ncid, did, ival)
    1236           0 :    if (ival .ne. nlwbands) call endrun(subname//':'//props%sourcefile// &
    1237           0 :         ' has the wrong number of lw bands')
    1238             : 
    1239           0 :    ierr = pio_inq_dimid(ncid, 'sw_band', did)
    1240           0 :    ierr = pio_inq_dimlen(ncid, did, ival)
    1241           0 :    if (ival .ne. nswbands) call endrun(subname//':'//props%sourcefile// &
    1242           0 :         ' has the wrong number of sw bands')
    1243             : 
    1244             :    ! Get other dimensions
    1245           0 :    ierr = pio_inq_dimid(ncid, 'corefrac', did)
    1246           0 :    ierr = pio_inq_dimlen(ncid, did, props%nfrac)
    1247             : 
    1248             : 
    1249             :    ! Allocate arrays
    1250             :    allocate( &
    1251             :       props%extpsw2(props%nfrac,nswbands), &
    1252             :       props%abspsw2(props%nfrac,nswbands), &
    1253             :       props%asmpsw2(props%nfrac,nswbands), &
    1254             :       props%absplw2(props%nfrac,nlwbands), &
    1255           0 :       props%corefrac(props%nfrac) )
    1256             : 
    1257           0 :    ierr = pio_inq_varid(ncid, 'extpsw2', vid)
    1258           0 :    ierr = pio_get_var(ncid, vid, props%extpsw2)
    1259             : 
    1260           0 :    ierr = pio_inq_varid(ncid, 'abspsw2', vid)
    1261           0 :    ierr = pio_get_var(ncid, vid, props%abspsw2)
    1262             : 
    1263           0 :    ierr = pio_inq_varid(ncid, 'asmpsw2', vid)
    1264           0 :    ierr = pio_get_var(ncid, vid, props%asmpsw2)
    1265             : 
    1266           0 :    ierr = pio_inq_varid(ncid, 'absplw2', vid)
    1267           0 :    ierr = pio_get_var(ncid, vid, props%absplw2)
    1268             : 
    1269           0 :    ierr = pio_inq_varid(ncid, 'corefrac', vid)
    1270           0 :    ierr = pio_get_var(ncid, vid, props%corefrac)
    1271             : 
    1272           0 : end subroutine bin_optics_init
    1273             : 
    1274             : 
    1275             : !================================================================================================
    1276             : 
    1277           0 : subroutine bindef_optics_init(props, ncid)
    1278             : 
    1279             : !  Read optics data for modal aerosols
    1280             : 
    1281             :    type (physprop_type), intent(inout) :: props   ! storage for file data
    1282             :    type (file_desc_T),   intent(inout) :: ncid    ! indentifier for netcdf file
    1283             : 
    1284             :    ! Local variables
    1285             :    integer :: ierr
    1286             :    integer :: did
    1287             :    integer :: ival
    1288             :    type(var_desc_t) :: vid
    1289             : 
    1290             :    character(len=*), parameter :: subname = 'bin_optics_init'
    1291             :    !------------------------------------------------------------------------------------
    1292             : 
    1293             :    ! Check dimensions for number of lw and sw bands
    1294             : 
    1295           0 :    ierr = pio_inq_dimid(ncid, 'lw_band', did)
    1296           0 :    ierr = pio_inq_dimlen(ncid, did, ival)
    1297           0 :    if (ival .ne. nlwbands) call endrun(subname//':'//props%sourcefile// &
    1298           0 :         ' has the wrong number of lw bands')
    1299             : 
    1300           0 :    ierr = pio_inq_dimid(ncid, 'sw_band', did)
    1301           0 :    ierr = pio_inq_dimlen(ncid, did, ival)
    1302           0 :    if (ival .ne. nswbands) call endrun(subname//':'//props%sourcefile// &
    1303           0 :         ' has the wrong number of sw bands')
    1304             : 
    1305           0 :    ierr = pio_inq_varid(ncid, 'density', vid)
    1306           0 :    ierr = pio_get_var(ncid, vid, props%density_aer)
    1307             : 
    1308           0 :    ierr = pio_inq_varid(ncid, 'hygroscopicity', vid)
    1309           0 :    ierr = pio_get_var(ncid, vid, props%hygro_aer)
    1310             : 
    1311             :   ! read refractive index data if available
    1312           0 :    call refindex_aer_init(props, ncid)
    1313             : 
    1314           0 : end subroutine bindef_optics_init
    1315             : 
    1316             : !================================================================================================
    1317             : 
    1318       13824 : subroutine bulk_props_init(physprop, nc_id)
    1319             : 
    1320             : !  Read props for bulk aerosols
    1321             : 
    1322             :    type (physprop_type), intent(inout) :: physprop ! storage for file data
    1323             :    type (file_desc_T),   intent(inout) :: nc_id    ! indentifier for netcdf file
    1324             : 
    1325             :    ! Local variables
    1326             :    integer :: ierr
    1327             : 
    1328             :    type(var_desc_T) :: vid
    1329             : 
    1330             :    logical :: debug = .false.
    1331             : 
    1332             :    character(len=*), parameter :: subname = 'bulk_props_init'
    1333             :    !------------------------------------------------------------------------------------
    1334             : 
    1335             :    ! read microphys
    1336       13824 :    ierr = pio_inq_varid(nc_id, 'name', vid)
    1337       13824 :    ierr = pio_get_var(nc_id, vid, physprop%aername)
    1338             : 
    1339             :    ! use GLC function to remove trailing nulls and blanks.
    1340             :    ! physprop%aername = aername_str(:GLC(aername_str))
    1341             : 
    1342       13824 :    ierr = pio_inq_varid(nc_id, 'density', vid)
    1343       13824 :    ierr = pio_get_var(nc_id, vid, physprop%density_aer)
    1344             : 
    1345       13824 :    ierr = pio_inq_varid(nc_id, 'sigma_logr', vid)
    1346       13824 :    ierr = pio_get_var(nc_id, vid, physprop%dispersion_aer)
    1347             : 
    1348       13824 :    ierr = pio_inq_varid(nc_id, 'dryrad', vid)
    1349       13824 :    ierr = pio_get_var(nc_id, vid, physprop%dryrad_aer)
    1350             : 
    1351       13824 :    ierr = pio_inq_varid(nc_id, 'hygroscopicity', vid)
    1352       13824 :    ierr = pio_get_var(nc_id, vid, physprop%hygro_aer)
    1353             : 
    1354       13824 :    ierr = pio_inq_varid(nc_id, 'num_to_mass_ratio', vid)
    1355       13824 :    ierr = pio_get_var(nc_id, vid, physprop%num_to_mass_aer)
    1356             : 
    1357             :    ! Output select data to log file
    1358       13824 :    if (debug .and. masterproc .and. idx_sw_diag > 0) then
    1359           0 :       if (trim(physprop%aername) == 'SULFATE') then
    1360           0 :          write(iulog, '(2x, a)') '_______ hygroscopic growth in visible band _______'
    1361           0 :          call aer_optics_log_rh('SO4', physprop%sw_hygro_ext(:,idx_sw_diag), &
    1362           0 :             physprop%sw_hygro_ssa(:,idx_sw_diag), physprop%sw_hygro_asm(:,idx_sw_diag))
    1363             :       end if
    1364           0 :       write(iulog, *) subname//': finished for ', trim(physprop%aername)
    1365             :    end if
    1366             : 
    1367       13824 : end subroutine bulk_props_init
    1368             : 
    1369             : !================================================================================================
    1370             : 
    1371   138240000 : function exp_interpol(x, f, y) result(g)
    1372             : ! Purpose:
    1373             : !   interpolates f(x) to point y
    1374             : !   assuming f(x) = f(x0) exp a(x - x0)
    1375             : !   where a = ( ln f(x1) - ln f(x0) ) / (x1 - x0)
    1376             : !   x0 <= x <= x1
    1377             : !   assumes x is monotonically increasing
    1378             : ! Author: D. Fillmore
    1379             : 
    1380             :    implicit none
    1381             : 
    1382             :    real(r8), intent(in), dimension(:) :: x  ! grid points
    1383             :    real(r8), intent(in), dimension(:) :: f  ! grid function values
    1384             :    real(r8), intent(in) :: y                ! interpolation point
    1385             :    real(r8) :: g                            ! interpolated function value
    1386             : 
    1387             :    integer :: k  ! interpolation point index
    1388             :    integer :: n  ! length of x
    1389             :    real(r8) :: a
    1390             : 
    1391   138240000 :    n = size(x)
    1392             : 
    1393             :    ! find k such that x(k) < y =< x(k+1)
    1394             :    ! set k = 1 if y <= x(1)  and  k = n-1 if y > x(n)
    1395             : 
    1396   138240000 :    if (y <= x(1)) then
    1397             :      k = 1
    1398   138101760 :    else if (y >= x(n)) then
    1399     1382400 :      k = n - 1
    1400             :    else
    1401             :      k = 1
    1402   289612800 :      do while (y > x(k+1) .and. k < n)
    1403   136719360 :        k = k + 1
    1404             :      end do
    1405             :    end if
    1406             : 
    1407             :    ! interpolate
    1408   138240000 :    a = (  log( f(k+1) / f(k) )  ) / ( x(k+1) - x(k) )
    1409   138240000 :    g = f(k) * exp( a * (y - x(k)) )
    1410             :    return
    1411             : end function exp_interpol
    1412             : 
    1413             : !================================================================================================
    1414             : 
    1415   129024000 : function lin_interpol(x, f, y) result(g)
    1416             : ! Purpose:
    1417             : !   interpolates f(x) to point y
    1418             : !   assuming f(x) = f(x0) + a * (x - x0)
    1419             : !   where a = ( f(x1) - f(x0) ) / (x1 - x0)
    1420             : !   x0 <= x <= x1
    1421             : !   assumes x is monotonically increasing
    1422             : ! Author: D. Fillmore
    1423             : 
    1424             :    implicit none
    1425             : 
    1426             :    real(r8), intent(in), dimension(:) :: x  ! grid points
    1427             :    real(r8), intent(in), dimension(:) :: f  ! grid function values
    1428             :    real(r8), intent(in) :: y                ! interpolation point
    1429             :    real(r8) :: g                            ! interpolated function value
    1430             : 
    1431             :    integer :: k  ! interpolation point index
    1432             :    integer :: n  ! length of x
    1433             :    real(r8) :: a
    1434             : 
    1435   129024000 :    n = size(x)
    1436             : 
    1437             :    ! find k such that x(k) < y =< x(k+1)
    1438             :    ! set k = 1 if y <= x(1)  and  k = n-1 if y > x(n)
    1439             : 
    1440   129024000 :    if (y <= x(1)) then
    1441             :      k = 1
    1442   128894976 :    else if (y >= x(n)) then
    1443     1290240 :      k = n - 1
    1444             :    else
    1445             :      k = 1
    1446   270305280 :      do while (y > x(k+1) .and. k < n)
    1447   127604736 :        k = k + 1
    1448             :      end do
    1449             :    end if
    1450             : 
    1451             :    ! interpolate
    1452   129024000 :    a = (  f(k+1) - f(k) ) / ( x(k+1) - x(k) )
    1453   129024000 :    g = f(k) + a * (y - x(k))
    1454             :    return
    1455             : end function lin_interpol
    1456             : 
    1457             : !================================================================================================
    1458             : 
    1459             : subroutine aer_optics_log(name, ext, ssa, asm)
    1460             : 
    1461             :    ! Purpose:
    1462             :    !   write aerosol optical constants to log file
    1463             : 
    1464             :    ! Author: D. Fillmore
    1465             : 
    1466             :    character(len=*), intent(in) :: name
    1467             :    real(r8), intent(in) :: ext(:)
    1468             :    real(r8), intent(in) :: ssa(:)
    1469             :    real(r8), intent(in) :: asm(:)
    1470             : 
    1471             :    integer :: kbnd, nbnd
    1472             :    !------------------------------------------------------------------------------------
    1473             : 
    1474             :    nbnd = ubound(ext, 1)
    1475             : 
    1476             :    write(iulog, '(2x, a)') name
    1477             :    write(iulog, '(2x, a, 4x, a, 4x, a, 4x, a)') 'SW band', 'ext (m^2 kg^-1)', ' ssa', ' asm'
    1478             :    do kbnd = 1, nbnd
    1479             :       write(iulog, '(2x, i7, 4x, f13.2, 4x, f4.2, 4x, f4.2)') kbnd, ext(kbnd), ssa(kbnd), asm(kbnd)
    1480             :    end do
    1481             : 
    1482             : end subroutine aer_optics_log
    1483             : 
    1484             : !================================================================================================
    1485             : 
    1486             : 
    1487           0 : subroutine aer_optics_log_rh(name, ext, ssa, asm)
    1488             : 
    1489             :    ! Purpose:
    1490             :    !   write out aerosol optical properties
    1491             :    !   for a set of test rh values
    1492             :    !   to test hygroscopic growth interpolation
    1493             : 
    1494             :    ! Author: D. Fillmore
    1495             : 
    1496             :    character(len=*), intent(in) :: name
    1497             :    real(r8), intent(in) :: ext(nrh)
    1498             :    real(r8), intent(in) :: ssa(nrh)
    1499             :    real(r8), intent(in) :: asm(nrh)
    1500             : 
    1501             :    integer :: krh_test
    1502             :    integer, parameter :: nrh_test = 36
    1503             :    integer :: krh
    1504             :    real(r8) :: rh
    1505             :    real(r8) :: rh_test(nrh_test)
    1506             :    real(r8) :: exti
    1507             :    real(r8) :: ssai
    1508             :    real(r8) :: asmi
    1509             :    real(r8) :: wrh
    1510             :    !------------------------------------------------------------------------------------
    1511             : 
    1512           0 :    do krh_test = 1, nrh_test
    1513           0 :       rh_test(krh_test) = sqrt(sqrt(sqrt(sqrt(((krh_test - 1.0_r8) / (nrh_test - 1))))))
    1514             :    enddo
    1515           0 :    write(iulog, '(2x, a)') name
    1516           0 :    write(iulog, '(2x, a, 4x, a, 4x, a, 4x, a)') '   rh', 'ext (m^2 kg^-1)', '  ssa', '  asm'
    1517             : 
    1518             :    ! loop through test rh values
    1519           0 :    do krh_test = 1, nrh_test
    1520             :       ! find corresponding rh index
    1521           0 :       rh = rh_test(krh_test)
    1522           0 :       krh = min(floor( (rh) * nrh ) + 1, nrh - 1)
    1523           0 :       wrh = (rh) *nrh - krh
    1524           0 :       exti = ext(krh + 1) * (wrh + 1) - ext(krh) * wrh
    1525           0 :       ssai = ssa(krh + 1) * (wrh + 1) - ssa(krh) * wrh
    1526           0 :       asmi = asm(krh + 1) * (wrh + 1) - asm(krh) * wrh
    1527           0 :       write(iulog, '(2x, f5.3, 4x, f13.3, 4x, f5.3, 4x, f5.3)') rh_test(krh_test), exti, ssai, asmi
    1528             :    end do
    1529             : 
    1530           0 : end subroutine aer_optics_log_rh
    1531             : 
    1532             : 
    1533             : !================================================================================================
    1534             : 
    1535           0 : subroutine hygroscopic_coreshell_optics_init(phys_prop, nc_id)
    1536             : 
    1537             :    ! Read optics data of type 'hygroscopic_coreshell' and interpolate it to CAM's rh mesh.
    1538             : 
    1539             :    type (physprop_type), intent(inout) :: phys_prop  ! data after interp onto cam rh mesh
    1540             :    type (file_desc_T),   intent(inout) :: nc_id      ! indentifier for netcdf file
    1541             : 
    1542             :    ! Local variables
    1543             :    integer :: ierr ! error flag
    1544             : 
    1545             :    integer :: rh_id, lw_band_id, sw_band_id, coreshell_id, dstbc_id, kap_id
    1546             :    integer :: sw_ext_id, sw_ssa_id, sw_asm_id, lw_abs_id
    1547             :    integer :: nbnd, swbands, did
    1548             : 
    1549             :    ! temp data from hygroscopic file before interpolation onto cam-rh-mesh
    1550             :    integer  :: nrh ! number of rh values in file
    1551             :    integer  :: nfrac  ! number of core/shell ratio values in file
    1552             :    integer  :: nbcdust,nkap
    1553             : 
    1554             :    real(r8) :: rh ! real rh value on cam rh mesh (indexvalue)
    1555             :    character(len=*), parameter :: sub = 'hygroscopic_coreshell_optics_init'
    1556             :    !------------------------------------------------------------------------------------
    1557             : 
    1558           0 :    if (masterproc) then
    1559           0 :      write(iulog,*) 'hygroscopic_coreshell_optics_init: Read file '//trim(phys_prop%sourcefile)
    1560             :    endif
    1561             : 
    1562           0 :    ierr = pio_inq_dimid(nc_id, 'lw_band', lw_band_id)
    1563           0 :    ierr = pio_inq_dimlen(nc_id, lw_band_id, nbnd)
    1564           0 :    if (nbnd .ne. nlwbands) call endrun(trim(phys_prop%sourcefile)// &
    1565           0 :         ' has the wrong number of lwbands')
    1566             : 
    1567           0 :    ierr = pio_inq_dimid(nc_id, 'sw_band', sw_band_id)
    1568           0 :    ierr = pio_inq_dimlen(nc_id, sw_band_id, swbands)
    1569           0 :    if(swbands .ne. nswbands) call endrun(trim(phys_prop%sourcefile)// &
    1570           0 :         ' has the wrong number of sw bands')
    1571             : 
    1572             : 
    1573           0 :    ierr = pio_inq_dimid(nc_id, 'coreshellratio', did)
    1574           0 :    ierr = pio_inq_dimlen(nc_id, did, phys_prop%nfrac)
    1575             : 
    1576           0 :    ierr = pio_inq_dimid(nc_id, 'dstbcratio', did)
    1577           0 :    ierr = pio_inq_dimlen(nc_id, did, phys_prop%nbcdust)
    1578             : 
    1579           0 :    ierr = pio_inq_dimid(nc_id, 'kap', did)
    1580           0 :    ierr = pio_inq_dimlen(nc_id, did, phys_prop%nkap)
    1581             : 
    1582           0 :    ierr = pio_inq_dimid(nc_id, 'rh_idx', rh_id)
    1583           0 :    ierr = pio_inq_dimlen(nc_id, rh_id, phys_prop%nrelh)
    1584             : 
    1585             :    allocate(phys_prop%sw_hygro_coreshell_ext(phys_prop%nrelh,nswbands, &
    1586           0 :                                              phys_prop%nfrac,phys_prop%nbcdust,phys_prop%nkap))
    1587             :    allocate(phys_prop%sw_hygro_coreshell_ssa(phys_prop%nrelh,nswbands, &
    1588           0 :                                              phys_prop%nfrac,phys_prop%nbcdust,phys_prop%nkap))
    1589             :    allocate(phys_prop%sw_hygro_coreshell_asm(phys_prop%nrelh,nswbands, &
    1590           0 :                                              phys_prop%nfrac,phys_prop%nbcdust,phys_prop%nkap))
    1591             :    allocate(phys_prop%lw_hygro_coreshell_abs(phys_prop%nrelh,nlwbands, &
    1592           0 :                                              phys_prop%nfrac,phys_prop%nbcdust,phys_prop%nkap))
    1593           0 :    allocate(phys_prop%corefrac(phys_prop%nfrac))
    1594           0 :    allocate(phys_prop%bcdust(phys_prop%nbcdust))
    1595           0 :    allocate(phys_prop%kap(phys_prop%nkap))
    1596           0 :    allocate(phys_prop%relh(phys_prop%nrelh))
    1597             : 
    1598           0 :    ierr = pio_inq_varid(nc_id, 'rh', rh_id)
    1599           0 :    ierr = pio_inq_varid(nc_id, 'coreshellratio', coreshell_id)  ! modified by Pengfei for coreshell
    1600           0 :    ierr = pio_inq_varid(nc_id, 'dstbcratio', dstbc_id)  ! modified by Pengfei for coreshell
    1601           0 :    ierr = pio_inq_varid(nc_id, 'kap', kap_id)
    1602             : 
    1603           0 :    ierr = pio_inq_varid(nc_id, 'ext_sw_coreshell', sw_ext_id)
    1604           0 :    ierr = pio_inq_varid(nc_id, 'ssa_sw_coreshell', sw_ssa_id)
    1605           0 :    ierr = pio_inq_varid(nc_id, 'asm_sw_coreshell', sw_asm_id)
    1606           0 :    ierr = pio_inq_varid(nc_id, 'abs_lw_coreshell', lw_abs_id)
    1607             : 
    1608           0 :    ierr = pio_get_var(nc_id, sw_ext_id, phys_prop%sw_hygro_coreshell_ext)
    1609           0 :    ierr = pio_get_var(nc_id, sw_ssa_id, phys_prop%sw_hygro_coreshell_ssa)
    1610           0 :    ierr = pio_get_var(nc_id, sw_asm_id, phys_prop%sw_hygro_coreshell_asm)
    1611           0 :    ierr = pio_get_var(nc_id, lw_abs_id, phys_prop%lw_hygro_coreshell_abs)
    1612           0 :    ierr = pio_get_var(nc_id, kap_id, phys_prop%kap)
    1613           0 :    ierr = pio_get_var(nc_id, rh_id, phys_prop%relh)
    1614           0 :    ierr = pio_get_var(nc_id, dstbc_id, phys_prop%bcdust)
    1615           0 :    ierr = pio_get_var(nc_id, coreshell_id, phys_prop%corefrac)
    1616             : 
    1617             :    ! read refractive index data if available
    1618           0 :    call refindex_aer_init(phys_prop, nc_id)
    1619             : 
    1620           0 : end subroutine hygroscopic_coreshell_optics_init
    1621             : 
    1622             : !================================================================================================
    1623             : 
    1624           0 : subroutine hygroscopic_wtp_optics_init(phys_prop, nc_id)
    1625             : 
    1626             :    ! Read optics data of type 'hygroscopic' and interpolate it to CAM's rh mesh.
    1627             : 
    1628             :    type (physprop_type), intent(inout) :: phys_prop  ! data after interp onto cam rh mesh
    1629             :    type (file_desc_T),   intent(inout) :: nc_id      ! indentifier for netcdf file
    1630             : 
    1631             :    ! Local variables
    1632             :    integer :: ierr ! error flag
    1633             : 
    1634             :    integer :: lw_band_id, sw_band_id, did
    1635             :    integer :: sw_ext_wtp_id, sw_ssa_wtp_id, sw_asm_wtp_id, lw_ext_wtp_id, wtp_id
    1636             :    integer :: nbnd, swbands
    1637             : 
    1638             :    real(r8) :: rh ! real rh value on cam rh mesh (indexvalue)
    1639             :    character(len=*), parameter :: sub = 'hygroscopic_wtp_optics_init'
    1640             :    !------------------------------------------------------------------------------------
    1641             : 
    1642             : !st
    1643             :   ! Get other dimensions
    1644           0 :    ierr = pio_inq_dimid(nc_id, 'wgtpct', did)
    1645           0 :    ierr = pio_inq_dimlen(nc_id, did, phys_prop%nwtp)
    1646             : 
    1647             : 
    1648           0 :    allocate(phys_prop%sw_hygro_ext_wtp(phys_prop%nwtp,nswbands))
    1649           0 :    allocate(phys_prop%sw_hygro_ssa_wtp(phys_prop%nwtp,nswbands))
    1650           0 :    allocate(phys_prop%sw_hygro_asm_wtp(phys_prop%nwtp,nswbands))
    1651           0 :    allocate(phys_prop%lw_hygro_abs_wtp(phys_prop%nwtp,nlwbands))
    1652           0 :    allocate(phys_prop%wgtpct(phys_prop%nwtp))
    1653             : 
    1654           0 :    ierr = pio_inq_dimid(nc_id, 'lw_band', lw_band_id)
    1655           0 :    ierr = pio_inq_dimlen(nc_id, lw_band_id, nbnd)
    1656           0 :    if (nbnd .ne. nlwbands) call endrun(phys_prop%sourcefile// &
    1657           0 :         ' has the wrong number of lwbands')
    1658             : 
    1659           0 :    ierr = pio_inq_dimid(nc_id, 'sw_band', sw_band_id)
    1660           0 :    ierr = pio_inq_dimlen(nc_id, sw_band_id, swbands)
    1661           0 :    if(swbands .ne. nswbands) call endrun(phys_prop%sourcefile// &
    1662           0 :         ' has the wrong number of sw bands')
    1663             : 
    1664           0 :    ierr = pio_inq_varid(nc_id, 'ext_sw_wtp', sw_ext_wtp_id)
    1665           0 :    ierr = pio_inq_varid(nc_id, 'ssa_sw_wtp', sw_ssa_wtp_id)
    1666           0 :    ierr = pio_inq_varid(nc_id, 'asm_sw_wtp', sw_asm_wtp_id)
    1667           0 :    ierr = pio_inq_varid(nc_id, 'abs_lw_wtp', lw_ext_wtp_id)
    1668           0 :    ierr = pio_inq_varid(nc_id, 'wgtpct', wtp_id)
    1669             : 
    1670           0 :    ierr = pio_get_var(nc_id, sw_ext_wtp_id, phys_prop%sw_hygro_ext_wtp)
    1671           0 :    ierr = pio_get_var(nc_id, sw_ssa_wtp_id, phys_prop%sw_hygro_ssa_wtp)
    1672           0 :    ierr = pio_get_var(nc_id, sw_asm_wtp_id, phys_prop%sw_hygro_asm_wtp)
    1673           0 :    ierr = pio_get_var(nc_id, lw_ext_wtp_id, phys_prop%lw_hygro_abs_wtp)
    1674           0 :    ierr = pio_get_var(nc_id, wtp_id, phys_prop%wgtpct)
    1675             : 
    1676             :    ! read refractive index data if available
    1677           0 :    call refindex_aer_init(phys_prop, nc_id)
    1678             : 
    1679             :    ! read bulk aero props
    1680           0 :    call bulk_props_init(phys_prop, nc_id)
    1681             : 
    1682           0 : end subroutine hygroscopic_wtp_optics_init
    1683             : 
    1684             : 
    1685           0 : end module phys_prop

Generated by: LCOV version 1.14