LCOV - code coverage report
Current view: | top level - chemistry/aerosol - modal_aero_data.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 0 | 457 | 0.0 %
Date: | 2025-01-13 21:54:50 |  | Functions: | 0 | 9 | 0.0 %

              Line data    Source code
           1             :       module modal_aero_data
           2             :
           3             : !--------------------------------------------------------------
           4             : ! ... Basic aerosol mode parameters and arrays
           5             : !--------------------------------------------------------------
           6             :       use shr_kind_mod,    only: r8 => shr_kind_r8
           7             :       use constituents,    only: pcnst, cnst_mw, cnst_name, cnst_get_ind, cnst_set_convtran2, &
           8             :                                  cnst_set_spec_class, cnst_spec_class_aerosol, cnst_spec_class_undefined, &
           9             :                                  cnst_species_class, cnst_spec_class_gas
          10             :       use physics_buffer,  only: pbuf_add_field, dtype_r8
          11             :       use time_manager,    only: is_first_step
          12             :       use phys_control,    only: phys_getopts
          13             :       use infnan,          only: nan, assignment(=)
          14             :       use cam_logfile,     only: iulog
          15             :       use cam_abortutils,  only: endrun
          16             :       use spmd_utils,      only: masterproc
          17             :       use ppgrid,          only: pcols, pver, begchunk, endchunk
          18             :       use mo_tracname,     only: solsym
          19             :       use chem_mods,       only: gas_pcnst
          20             :       use radconstants,    only: nswbands, nlwbands
          21             :       use shr_const_mod,   only: pi => shr_const_pi
          22             :       use rad_constituents,only: rad_cnst_get_info, rad_cnst_get_aer_props, rad_cnst_get_mode_props
          23             :       use physics_buffer,  only: physics_buffer_desc, pbuf_get_chunk
          24             :
          25             :       implicit none
          26             :       private
          27             :
          28             :       public :: modal_aero_data_init
          29             :       public :: modal_aero_data_reg
          30             :       public :: qqcw_get_field
          31             :
          32             :       integer, public, protected :: nsoa = 0
          33             :       integer, public, protected :: npoa = 0
          34             :       integer, public, protected :: nbc = 0
          35             :       integer, public, protected :: nspec_max = 0
          36             :       integer, public, protected :: ntot_amode = 0
          37             :       integer, public, protected :: nSeaSalt=0, nDust=0
          38             :       integer, public, protected :: nSO4=0, nNH4=0
          39             :
          40             :       !
          41             :       ! definitions for aerosol chemical components
          42             :       !
          43             :
          44             :       real(r8), public, protected, allocatable :: specmw_amode(:,:)
          45             :       character(len=16), public, protected, allocatable :: modename_amode(:)
          46             :
          47             :       integer, public, protected, allocatable :: nspec_amode(:)
          48             :
          49             :       character(len=20), public, protected :: cnst_name_cw( pcnst )
          50             :
          51             :       !   input mprognum_amode, mdiagnum_amode, mprogsfc_amode, mcalcwater_amode
          52             :       integer, public, protected, allocatable :: mprognum_amode(:)
          53             :       integer, public, protected, allocatable :: mdiagnum_amode(:)
          54             :       integer, public, protected, allocatable :: mprogsfc_amode(:)
          55             :       integer, public, protected, allocatable :: mcalcwater_amode(:)
          56             :
          57             :       !   input dgnum_amode, dgnumlo_amode, dgnumhi_amode (units = m)
          58             :       real(r8), public, protected, allocatable :: dgnum_amode(:)
          59             :       real(r8), public, protected, allocatable :: dgnumlo_amode(:)
          60             :       real(r8), public, protected, allocatable :: dgnumhi_amode(:)
          61             :       integer,  public, protected, allocatable :: mode_size_order(:)
          62             :
          63             :       !   input sigmag_amode
          64             :       real(r8), public, protected, allocatable :: sigmag_amode(:)
          65             :
          66             :       !   input crystalization and deliquescence points
          67             :       real(r8), allocatable :: rhcrystal_amode(:)
          68             :       real(r8), allocatable :: rhdeliques_amode(:)
          69             :
          70             :
          71             :       integer, public, protected, allocatable :: &
          72             :            lmassptr_amode( :, : ),   &
          73             :            lmassptrcw_amode( :, : ), &
          74             :            numptr_amode( : ),        &
          75             :            numptrcw_amode( : )
          76             :
          77             :       real(r8), public, protected, allocatable :: &
          78             :            alnsg_amode( : ),              &
          79             :            voltonumb_amode( : ),          &
          80             :            voltonumblo_amode( : ),        &
          81             :            voltonumbhi_amode( : ),        &
          82             :            alnv2n_amode( : ),             &
          83             :            alnv2nlo_amode( : ),           &
          84             :            alnv2nhi_amode( : ),           &
          85             :            specdens_amode(:,:),   &
          86             :            spechygro(:,:)
          87             :
          88             :       integer, public, protected, allocatable ::  &
          89             :            lptr_so4_a_amode(:),     lptr_so4_cw_amode(:), &
          90             :            lptr_msa_a_amode(:),     lptr_msa_cw_amode(:), &
          91             :            lptr_nh4_a_amode(:),     lptr_nh4_cw_amode(:), &
          92             :            lptr_no3_a_amode(:),     lptr_no3_cw_amode(:), &
          93             :            lptr_nacl_a_amode(:),    lptr_nacl_cw_amode(:),&
          94             :            lptr_dust_a_amode(:),    lptr_dust_cw_amode(:)
          95             :
          96             :       integer, public, protected :: &
          97             :            modeptr_accum,  modeptr_aitken,                               &
          98             :            modeptr_ufine,  modeptr_coarse,                               &
          99             :            modeptr_pcarbon,                                              &
         100             :            modeptr_finedust,  modeptr_fineseas,                          &
         101             :            modeptr_coardust,  modeptr_coarseas, modeptr_stracoar
         102             :
         103             :       !2D lptr variables added by RCE to access speciated species
         104             :       integer, public, protected, allocatable :: &
         105             :            lptr2_bc_a_amode(:,:),   lptr2_bc_cw_amode(:,:), &
         106             :            lptr2_pom_a_amode(:,:),  lptr2_pom_cw_amode(:,:), &
         107             :            lptr2_soa_a_amode(:,:),  lptr2_soa_cw_amode(:,:), &
         108             :            lptr2_soa_g_amode(:)
         109             :
         110             :       real(r8), public, protected :: specmw_so4_amode
         111             :
         112             :       logical, public, protected :: soa_multi_species = .false.
         113             :
         114             :       character(len=16), allocatable :: xname_massptr(:,:)     ! names of species in each mode
         115             :       character(len=16), allocatable :: xname_massptrcw(:,:)   ! names of cloud-borne species in each mode
         116             :
         117             :       complex(r8), allocatable :: &
         118             :            specrefndxsw( :,:,: ), &
         119             :            specrefndxlw( :,:,: )
         120             :
         121             :       character(len=8), allocatable :: &
         122             :            aodvisname(: ), &
         123             :            ssavisname(: )
         124             :       character(len=48), allocatable :: &
         125             :            aodvislongname(: ), &
         126             :            ssavislongname(: )
         127             :
         128             :       character(len=8), allocatable :: &
         129             :            fnactname(: ), &
         130             :            fmactname(: ), &
         131             :            nactname(: )
         132             :
         133             :       character(len=48), allocatable :: &
         134             :            fnactlongname(: ), &
         135             :            fmactlongname(: ), &
         136             :            nactlongname(: )
         137             :
         138             :
         139             :       !   threshold for reporting negatives from subr qneg3
         140             :       real(r8) :: qneg3_worst_thresh_amode(pcnst)
         141             :
         142             :       integer :: qqcw(pcnst)=-1 ! Remaps modal_aero indices into pbuf
         143             :
         144             :       logical :: convproc_do_aer
         145             :       logical :: cam_do_aero_conv = .true.
         146             :     contains
         147             :
         148             : !--------------------------------------------------------------
         149             : !--------------------------------------------------------------
         150           0 :   subroutine modal_aero_data_reg
         151             :
         152             :     character(len=6) :: xname_numptr, xname_numptrcw
         153             :     character(len=1) :: modechr
         154             :     integer :: m, l, iptr,i, idx
         155             :     character(len=3) :: trnum       ! used to hold mode number (as characters)
         156             :
         157             :     character(len=32) :: spec_name, mode_type
         158             :     character(len=1) :: modestr
         159             :
         160           0 :     call rad_cnst_get_info( 0, nmodes=ntot_amode )
         161           0 :     allocate( nspec_amode(ntot_amode) )
         162           0 :     allocate( numptr_amode(ntot_amode) )
         163           0 :     allocate( numptrcw_amode(ntot_amode) )
         164           0 :     allocate(modename_amode(ntot_amode))
         165           0 :     allocate(mprognum_amode(ntot_amode))
         166           0 :     allocate(mdiagnum_amode(ntot_amode))
         167           0 :     allocate(mprogsfc_amode(ntot_amode))
         168           0 :     allocate(mcalcwater_amode(ntot_amode))
         169           0 :     mprognum_amode(:) = 1
         170           0 :     mdiagnum_amode(:) = 0
         171           0 :     mprogsfc_amode(:) = 0
         172           0 :     if (ntot_amode==7) then
         173           0 :        mcalcwater_amode(:) = 1
         174             :     else
         175           0 :        mcalcwater_amode(:) = 0
         176             :     endif
         177           0 :     allocate(dgnum_amode(ntot_amode))
         178           0 :     allocate(mode_size_order(ntot_amode))
         179           0 :     allocate(dgnumlo_amode(ntot_amode))
         180           0 :     allocate(dgnumhi_amode(ntot_amode))
         181           0 :     allocate(sigmag_amode(ntot_amode))
         182           0 :     allocate(rhcrystal_amode(ntot_amode))
         183           0 :     allocate(rhdeliques_amode(ntot_amode))
         184             :     allocate( &
         185           0 :          alnsg_amode( ntot_amode ),              &   !
         186           0 :          voltonumb_amode( ntot_amode ),          &   !
         187           0 :          voltonumblo_amode( ntot_amode ),        &   !
         188           0 :          voltonumbhi_amode( ntot_amode ),        &   !
         189           0 :          alnv2n_amode( ntot_amode ),             &   !
         190           0 :          alnv2nlo_amode( ntot_amode ),           &   !
         191           0 :          alnv2nhi_amode( ntot_amode ),           &   !
         192           0 :          aodvisname(ntot_amode ), &
         193           0 :          ssavisname(ntot_amode ), &
         194           0 :          fnactname(ntot_amode ), &
         195           0 :          fmactname(ntot_amode ), &
         196           0 :          nactname(ntot_amode ), &
         197           0 :          fnactlongname(ntot_amode ), &
         198           0 :          fmactlongname(ntot_amode ), &
         199           0 :          nactlongname(ntot_amode ), &
         200           0 :          lptr_so4_a_amode(ntot_amode), lptr_so4_cw_amode(ntot_amode), &
         201           0 :          lptr_msa_a_amode(ntot_amode), lptr_msa_cw_amode(ntot_amode), &
         202           0 :          lptr_nh4_a_amode(ntot_amode), lptr_nh4_cw_amode(ntot_amode), &
         203           0 :          lptr_nacl_a_amode(ntot_amode), lptr_nacl_cw_amode(ntot_amode), &
         204           0 :          lptr_dust_a_amode(ntot_amode), lptr_dust_cw_amode(ntot_amode), &
         205           0 :          lptr_no3_a_amode(ntot_amode), lptr_no3_cw_amode(ntot_amode) &
         206           0 :     )
         207             :
         208             :     allocate( &
         209           0 :          aodvislongname(ntot_amode ), &
         210           0 :          ssavislongname(ntot_amode ) &
         211           0 :     )
         212             :
         213           0 :     do m = 1, ntot_amode
         214           0 :        call rad_cnst_get_info(0, m, mode_type=mode_type, nspec=nspec_amode(m))
         215           0 :        modename_amode(m) = mode_type
         216             :        ! count number of soa, poa, and bc bins in mode 1
         217           0 :        if (m==1) then
         218           0 :           do l = 1, nspec_amode(m)
         219           0 :              call rad_cnst_get_info(0, m, l, spec_name=spec_name )
         220           0 :              if (spec_name(:3) == 'soa') nsoa=nsoa+1
         221           0 :              if (spec_name(:3) == 'pom') npoa=npoa+1
         222           0 :              if (spec_name(:2) == 'bc' ) nbc =nbc +1
         223             :           enddo
         224             :        endif
         225             :     enddo
         226             :
         227           0 :     soa_multi_species = nsoa > 1
         228             :
         229           0 :     nspec_max = maxval( nspec_amode )
         230             :
         231           0 :     allocate ( specdens_amode(nspec_max,ntot_amode) )
         232           0 :     allocate ( spechygro(nspec_max,ntot_amode) )
         233           0 :     allocate ( specmw_amode(nspec_max,ntot_amode) )
         234           0 :     allocate ( xname_massptr(nspec_max,ntot_amode) )
         235           0 :     allocate ( xname_massptrcw(nspec_max,ntot_amode) )
         236           0 :     specmw_amode = nan
         237           0 :     xname_massptr(:,:) = ' '
         238           0 :     xname_massptrcw(:,:) = ' '
         239             :
         240           0 :     do m = 1, ntot_amode
         241           0 :        do l = 1, nspec_amode(m)
         242           0 :           call rad_cnst_get_info(0, m, l, spec_name=spec_name )
         243           0 :           xname_massptr(l,m) = spec_name
         244           0 :           write(modestr,'(I1)') m
         245           0 :           idx = index( xname_massptr(l,m), '_' )
         246           0 :           xname_massptrcw(l,m) = xname_massptr(l,m)(:idx-1)//'_c'//modestr
         247           0 :           if (xname_massptr(l,m)(:3) == 'dst') nDust=nDust+1
         248           0 :           if (xname_massptr(l,m)(:3) == 'ncl') nSeaSalt=nSeaSalt+1
         249           0 :           if (xname_massptr(l,m)(:3) == 'nh4') nNH4=nNH4+1
         250           0 :           if (xname_massptr(l,m)(:3) == 'so4') nSO4=nSO4+1
         251             :        enddo
         252             :     enddo
         253             :
         254             :     allocate( &
         255           0 :          lmassptr_amode( nspec_max, ntot_amode ),&
         256           0 :          lmassptrcw_amode( nspec_max, ntot_amode ),&
         257           0 :          lptr2_pom_a_amode(ntot_amode,npoa),  lptr2_pom_cw_amode(ntot_amode,npoa), &
         258           0 :          lptr2_soa_a_amode(ntot_amode,nsoa),  lptr2_soa_cw_amode(ntot_amode,nsoa), &
         259           0 :          lptr2_bc_a_amode(ntot_amode,nbc),   lptr2_bc_cw_amode(ntot_amode,nbc), &
         260           0 :          lptr2_soa_g_amode(nsoa) &
         261           0 :          )
         262           0 :     lmassptr_amode = -999999
         263           0 :     lptr2_soa_g_amode = -999999
         264             :
         265           0 :     allocate( specrefndxsw(nswbands,nspec_max,ntot_amode ) )
         266           0 :     allocate( specrefndxlw(nlwbands,nspec_max,ntot_amode) )
         267             :
         268           0 :     do m = 1, ntot_amode
         269           0 :        if(nspec_amode(m).gt.nspec_max)then
         270           0 :           write(iulog,*)'modal_aero_data_reg: nspec_amode(m).gt.nspec_max '
         271           0 :           write(iulog,*)'modal_aero_data_reg: m,nspec_amode(m), nspec_max=',m, nspec_amode(m), nspec_max
         272           0 :           call endrun('modal_aero_data_reg: nspec_amode(m).gt.nspec_max ')
         273             :        end if
         274             :     end do
         275             :
         276           0 :     call phys_getopts(convproc_do_aer_out = convproc_do_aer)
         277           0 :     if (convproc_do_aer) cam_do_aero_conv = .false.
         278             :
         279           0 :     do m = 1, ntot_amode
         280           0 :        write(modechr,fmt='(I1)') m
         281           0 :        xname_numptr = 'num_a'//modechr
         282           0 :        xname_numptrcw  = 'num_c'//modechr
         283             :
         284           0 :        if (masterproc) then
         285           0 :           write(iulog,9231) m, modename_amode(m)
         286             :           write(iulog,9232)                                          &
         287           0 :                'nspec                       ',                         &
         288           0 :                nspec_amode(m)
         289             :           write(iulog,9232)                                          &
         290           0 :                'mprognum, mdiagnum, mprogsfc',                         &
         291           0 :                mprognum_amode(m), mdiagnum_amode(m), mprogsfc_amode(m)
         292             :           write(iulog,9232)                                          &
         293           0 :                'mcalcwater                  ',                         &
         294           0 :                mcalcwater_amode(m)
         295             :        endif
         296             :
         297             :        !    define species to hold interstitial & activated number
         298             :        call search_list_of_names(                                      &
         299           0 :             xname_numptr, numptr_amode(m), cnst_name, pcnst )
         300           0 :        if (numptr_amode(m) .le. 0) then
         301           0 :           write(iulog,9061) 'xname_numptr', xname_numptr, m
         302           0 :           call endrun('modal_aero_data_reg: numptr_amode(m) .le. 0')
         303             :        end if
         304           0 :        if (numptr_amode(m) .gt. pcnst) then
         305           0 :           write(iulog,9061) 'numptr_amode', numptr_amode(m), m
         306           0 :           write(iulog,9061) 'xname_numptr', xname_numptr, m
         307           0 :           call endrun('modal_aero_data_reg: numptr_amode(m) .gt. pcnst')
         308             :        end if
         309             :
         310           0 :        call cnst_set_spec_class(numptr_amode(m), cnst_spec_class_aerosol)
         311           0 :        call cnst_set_convtran2(numptr_amode(m), cam_do_aero_conv)
         312             :
         313           0 :        numptrcw_amode(m) = numptr_amode(m)  !use the same index for Q and QQCW arrays
         314           0 :        if (numptrcw_amode(m) .le. 0) then
         315           0 :           write(iulog,9061) 'xname_numptrcw', xname_numptrcw, m
         316           0 :           call endrun('modal_aero_data_reg: numptrcw_amode(m) .le. 0')
         317             :        end if
         318           0 :        if (numptrcw_amode(m) .gt. pcnst) then
         319           0 :           write(iulog,9061) 'numptrcw_amode', numptrcw_amode(m), m
         320           0 :           write(iulog,9061) 'xname_numptrcw', xname_numptrcw, m
         321           0 :           call endrun('modal_aero_data_reg: numptrcw_amode(m) .gt. pcnst')
         322             :        end if
         323             :
         324           0 :        call pbuf_add_field(xname_numptrcw,'global',dtype_r8,(/pcols,pver/),iptr)
         325           0 :        call qqcw_set_ptr(numptrcw_amode(m),iptr)
         326             :
         327             :        !   output mode information
         328           0 :        if ( masterproc ) then
         329           0 :           write(iulog,9233) 'numptr         ',                           &
         330           0 :                numptr_amode(m), xname_numptr
         331           0 :           write(iulog,9233) 'numptrcw       ',                           &
         332           0 :                numptrcw_amode(m), xname_numptrcw
         333             :        end if
         334             :
         335             :        !   define the chemical species for the mode
         336           0 :        do l = 1, nspec_amode(m)
         337             :
         338             :           call search_list_of_names(                                  &
         339           0 :                xname_massptr(l,m), lmassptr_amode(l,m), cnst_name, pcnst )
         340           0 :           if (lmassptr_amode(l,m) .le. 0) then
         341           0 :              write(iulog,9062) 'xname_massptr', xname_massptr(l,m), l, m
         342           0 :              write(iulog,'(10(a8,1x))')(cnst_name(i),i=1,pcnst)
         343           0 :              call endrun('modal_aero_data_reg: lmassptr_amode(l,m) .le. 0')
         344             :           end if
         345           0 :           call cnst_set_spec_class(lmassptr_amode(l,m), cnst_spec_class_aerosol)
         346           0 :           call cnst_set_convtran2(lmassptr_amode(l,m), cam_do_aero_conv)
         347             :
         348           0 :           lmassptrcw_amode(l,m) = lmassptr_amode(l,m)  !use the same index for Q and QQCW arrays
         349           0 :           if (lmassptrcw_amode(l,m) .le. 0) then
         350           0 :              write(iulog,9062) 'xname_massptrcw', xname_massptrcw(l,m), l, m
         351           0 :              call endrun('modal_aero_data_reg: lmassptrcw_amode(l,m) .le. 0')
         352             :           end if
         353           0 :           call pbuf_add_field(xname_massptrcw(l,m),'global',dtype_r8,(/pcols,pver/),iptr)
         354           0 :           call qqcw_set_ptr(lmassptrcw_amode(l,m), iptr)
         355             :
         356           0 :           if ( masterproc ) then
         357           0 :              write(iulog,9236) 'spec, massptr  ', l,                    &
         358           0 :                   lmassptr_amode(l,m), xname_massptr(l,m)
         359           0 :              write(iulog,9236) 'spec, massptrcw', l,                    &
         360           0 :                   lmassptrcw_amode(l,m), xname_massptrcw(l,m)
         361             :           end if
         362             :
         363             :        end do
         364             :
         365             :        !   set names for aodvis and ssavis
         366           0 :        write(unit=trnum,fmt='(i3)') m+100
         367             :
         368           0 :        aodvisname(m) = 'AODVIS'//trnum(2:3)
         369           0 :        aodvislongname(m) = 'Aerosol optical depth for mode '//trnum(2:3)
         370           0 :        ssavisname(m) = 'SSAVIS'//trnum(2:3)
         371           0 :        ssavislongname(m) = 'Single-scatter albedo for mode '//trnum(2:3)
         372           0 :        fnactname(m) = 'FNACT'//trnum(2:3)
         373           0 :        fnactlongname(m) = 'Number faction activated for mode '//trnum(2:3)
         374           0 :        fmactname(m) = 'FMACT'//trnum(2:3)
         375           0 :        fmactlongname(m) = 'Fraction mass activated for mode'//trnum(2:3)
         376             :     end do
         377             :
         378             :     ! At this point, species_class is either undefined or aerosol.
         379             :     ! For the "chemistry species" set the undefined ones to gas,
         380             :     ! and leave the aerosol ones as is
         381             :     do i = 1, gas_pcnst
         382             :        call cnst_get_ind(solsym(i), idx, abort=.false.)
         383             :        if (idx > 0) then
         384             :           if (cnst_species_class(idx) == cnst_spec_class_undefined) then
         385             :              call cnst_set_spec_class(idx, cnst_spec_class_gas)
         386             :           end if
         387             :        end if
         388             :     end do
         389             :
         390           0 :        if (masterproc) write(iulog,9230)
         391             : 9230   format( // '*** init_aer_modes mode definitions' )
         392             : 9231   format( 'mode = ', i4, ' = "', a, '"' )
         393             : 9232   format( 4x, a, 4(1x, i5 ) )
         394             : 9233   format( 4x, a15, 4x, i7, '="', a, '"' )
         395             : 9236   format( 4x, a15, i4, i7, '="', a, '"' )
         396             : 9061   format( '*** subr modesmodal_aero_data_reg - bad ', a /                   &
         397             :             5x, 'name, m =  ', a, 5x, i5 )
         398             : 9062   format( '*** subr modal_aero_data_reg - bad ', a /                       &
         399             :             5x, 'name, l, m =  ', a, 5x, 2i5 )
         400           0 :  end subroutine modal_aero_data_reg
         401             :
         402             : !--------------------------------------------------------------
         403             : !--------------------------------------------------------------
         404           0 :     subroutine modal_aero_data_init(pbuf2d)
         405             :
         406             :        type(physics_buffer_desc), pointer :: pbuf2d(:,:)
         407             :
         408             :        !--------------------------------------------------------------
         409             :        ! ... local variables
         410             :        !--------------------------------------------------------------
         411             :        integer :: l, m, i, lchnk, tmp
         412             :
         413             :        integer :: qArrIndex
         414           0 :        complex(r8), pointer  :: refindex_aer_sw(:), &
         415           0 :             refindex_aer_lw(:)
         416           0 :        real(r8), pointer :: qqcw(:,:)
         417             :        real(r8), parameter :: huge_r8 = huge(1._r8)
         418             :        character(len=*), parameter :: routine='modal_aero_initialize'
         419             :        character(len=32) :: spec_type
         420             :        integer :: soa_ndx
         421             :
         422             :        !-----------------------------------------------------------------------
         423             :
         424             :        ! Mode specific properties.
         425           0 :        do m = 1, ntot_amode
         426             :           call rad_cnst_get_mode_props(0, m, &
         427           0 :              sigmag=sigmag_amode(m), dgnum=dgnum_amode(m), dgnumlo=dgnumlo_amode(m), &
         428           0 :              dgnumhi=dgnumhi_amode(m), rhcrystal=rhcrystal_amode(m), rhdeliques=rhdeliques_amode(m))
         429             :
         430           0 :           mode_size_order(m) = m
         431             :
         432             :           !   compute frequently used parameters: ln(sigmag),
         433             :           !   volume-to-number and volume-to-surface conversions, ...
         434           0 :           alnsg_amode(m) = log( sigmag_amode(m) )
         435             :
         436           0 :           voltonumb_amode(m) = 1._r8 / ( (pi/6._r8)*                            &
         437           0 :              (dgnum_amode(m)**3._r8)*exp(4.5_r8*alnsg_amode(m)**2._r8) )
         438           0 :           voltonumblo_amode(m) = 1._r8 / ( (pi/6._r8)*                          &
         439           0 :              (dgnumlo_amode(m)**3._r8)*exp(4.5_r8*alnsg_amode(m)**2._r8) )
         440           0 :           voltonumbhi_amode(m) = 1._r8 / ( (pi/6._r8)*                          &
         441           0 :              (dgnumhi_amode(m)**3._r8)*exp(4.5_r8*alnsg_amode(m)**2._r8) )
         442             :
         443           0 :           alnv2n_amode(m)   = log( voltonumb_amode(m) )
         444           0 :           alnv2nlo_amode(m) = log( voltonumblo_amode(m) )
         445           0 :           alnv2nhi_amode(m) = log( voltonumbhi_amode(m) )
         446             :
         447             :        end do
         448             :
         449           0 :        do i = 1, ntot_amode-1 ! order from largest to smallest
         450           0 :           do m = 2, ntot_amode
         451           0 :              if (dgnum_amode(mode_size_order(m-1))<dgnum_amode(mode_size_order(m))) then
         452           0 :                 tmp = mode_size_order(m-1)
         453           0 :                 mode_size_order(m-1)= mode_size_order(m)
         454           0 :                 mode_size_order(m) = tmp
         455             :              endif
         456             :           enddo
         457             :        enddo
         458             :
         459           0 :        lptr2_soa_g_amode(:) = -1
         460           0 :        soa_ndx = 0
         461           0 :        do i = 1, pcnst
         462           0 :           if (cnst_name(i)(:4) == 'SOAG' .and. cnst_name(i)(:5) /= 'SOAGX') then
         463           0 :              soa_ndx = soa_ndx+1
         464           0 :              lptr2_soa_g_amode(soa_ndx) = i
         465             :           endif
         466             :        enddo
         467           0 :        if (.not.any(lptr2_soa_g_amode>0)) call endrun('modal_aero_data_init: lptr2_soa_g_amode is not set properly')
         468             :        ! Properties of mode specie types.
         469             :
         470             :        !     values from Koepke, Hess, Schult and Shettle, Global Aerosol Data Set
         471             :        !     Report #243, Max-Planck Institute for Meteorology, 1997a
         472             :        !     See also Hess, Koepke and Schult, Optical Properties of Aerosols and Clouds (OPAC)
         473             :        !     BAMS, 1998.
         474             :
         475             :        !      specrefndxsw(:ntot_aspectype)     = (/ (1.53,  0.01),   (1.53,  0.01),  (1.53,  0.01), &
         476             :        !                                           (1.55,  0.01),   (1.55,  0.01),  (1.90, 0.60), &
         477             :        !                                           (1.50, 1.0e-8), (1.50, 0.005) /)
         478             :        !      specrefndxlw(:ntot_aspectype)   = (/ (2.0, 0.5),   (2.0, 0.5), (2.0, 0.5), &
         479             :        !                                           (1.7, 0.5),   (1.7, 0.5), (2.22, 0.73), &
         480             :        !                                           (1.50, 0.02), (2.6, 0.6) /)
         481             :        !     get refractive indices from phys_prop files
         482             :
         483             :        ! The following use of the rad_constituent interfaces makes the assumption that the
         484             :        ! prognostic modes are used in the mode climate (index 0) list.
         485             :
         486           0 :        if (masterproc) write(iulog,9210)
         487           0 :        do m = 1, ntot_amode
         488           0 :           do l = 1, nspec_amode(m)
         489           0 :              qArrIndex =  lmassptr_amode(l,m)     !index of the species in the state%q array
         490             :              call rad_cnst_get_aer_props(0, m, l , &
         491             :                   refindex_aer_sw=refindex_aer_sw, &
         492             :                   refindex_aer_lw=refindex_aer_lw, &
         493           0 :                   density_aer=specdens_amode(l,m), &
         494           0 :                   hygro_aer=spechygro(l,m)         )
         495             :
         496           0 :                  specmw_amode(l,m) = cnst_mw(qArrIndex)
         497             :
         498           0 :              if(masterproc) then
         499           0 :                 write(iulog,9212) '        name : ', cnst_name(qArrIndex)
         500           0 :                 write(iulog,9213) ' density, MW : ', specdens_amode(l,m), specmw_amode(l,m)
         501           0 :                 write(iulog,9213) '       hygro : ', spechygro(l,m)
         502             :              endif
         503           0 :              do i=1,nswbands
         504           0 :                 specrefndxsw(i,l,m)=refindex_aer_sw(i)
         505           0 :                 if(masterproc) write(iulog,9213) 'ref index sw    ', (specrefndxsw(i,l,m))
         506             :              end do
         507           0 :              do i=1,nlwbands
         508           0 :                 specrefndxlw(i,l,m)=refindex_aer_lw(i)
         509           0 :                 if(masterproc) write(iulog,9213) 'ref index ir    ', (specrefndxlw(i,l,m))
         510             :              end do
         511             :
         512             :           enddo
         513             :        enddo
         514             :
         515             : 9210   format( // '*** init_aer_modes aerosol species-types' )
         516             : 9211   format( 'spectype =', i4)
         517             : 9212   format( 4x, a, 3x, '"', a, '"' )
         518             : 9213   format( 4x, a, 5(1pe14.5) )
         519             :
         520             :        !   set cnst_name_cw
         521           0 :        call initaermodes_set_cnstnamecw()
         522             :
         523             :
         524             :        !
         525             :        !   set the lptr_so4_a_amode(m), lptr_so4_cw_amode(m), ...
         526             :        !
         527           0 :        call initaermodes_setspecptrs
         528             :
         529             :        !
         530             :        !   set threshold for reporting negatives from subr qneg3
         531             :        !   for aerosol number species set this to
         532             :        !      1e3 #/kg ~= 1e-3 #/cm3 for accum, aitken, pcarbon, ufine modes
         533             :        !      3e1 #/kg ~= 3e-5 #/cm3 for fineseas and finedust modes
         534             :        !      1e0 #/kg ~= 1e-6 #/cm3 for other modes which are coarse
         535             :        !   for other species, set this to zero so that it will be ignored
         536             :        !      by qneg3
         537             :        !
         538           0 :        if ( masterproc ) write(iulog,'(/a)') &
         539           0 :             'mode, modename_amode, qneg3_worst_thresh_amode'
         540           0 :        qneg3_worst_thresh_amode(:) = 0.0_r8
         541           0 :        do m = 1, ntot_amode
         542           0 :           l = numptr_amode(m)
         543           0 :           if ((l <= 0) .or. (l > pcnst)) cycle
         544             :
         545           0 :           if      (m == modeptr_accum) then
         546           0 :              qneg3_worst_thresh_amode(l) = 1.0e3_r8
         547           0 :           else if (m == modeptr_aitken) then
         548           0 :              qneg3_worst_thresh_amode(l) = 1.0e3_r8
         549           0 :           else if (m == modeptr_pcarbon) then
         550           0 :              qneg3_worst_thresh_amode(l) = 1.0e3_r8
         551           0 :           else if (m == modeptr_ufine) then
         552           0 :              qneg3_worst_thresh_amode(l) = 1.0e3_r8
         553             :
         554           0 :           else if (m == modeptr_fineseas) then
         555           0 :              qneg3_worst_thresh_amode(l) = 3.0e1_r8
         556           0 :           else if (m == modeptr_finedust) then
         557           0 :              qneg3_worst_thresh_amode(l) = 3.0e1_r8
         558             :
         559             :           else
         560           0 :              qneg3_worst_thresh_amode(l) = 1.0e0_r8
         561             :           end if
         562             :
         563           0 :           if ( masterproc ) write(iulog,'(i3,2x,a,1p,e12.3)') &
         564           0 :                m, modename_amode(m), qneg3_worst_thresh_amode(l)
         565             :        end do
         566             :
         567           0 :        if (is_first_step()) then
         568             :           ! initialize cloud bourne constituents in physics buffer
         569             :
         570           0 :           do i = 1, pcnst
         571           0 :              do lchnk = begchunk, endchunk
         572           0 :                 qqcw => qqcw_get_field(pbuf_get_chunk(pbuf2d,lchnk), i, lchnk, .true.)
         573           0 :                 if (associated(qqcw)) then
         574           0 :                    qqcw = 1.e-38_r8
         575             :                 end if
         576             :              end do
         577             :           end do
         578             :        end if
         579             :
         580           0 :     end subroutine modal_aero_data_init
         581             :
         582             : !--------------------------------------------------------------
         583             : !--------------------------------------------------------------
         584           0 :         subroutine qqcw_set_ptr(index, iptr)
         585             :           use cam_abortutils, only : endrun
         586             :
         587             :
         588             :           integer, intent(in) :: index, iptr
         589             :
         590           0 :           if(index>0 .and. index <= pcnst ) then
         591           0 :              qqcw(index)=iptr
         592             :           else
         593           0 :              call endrun('qqcw_set_ptr: attempting to set qqcw pointer already defined')
         594             :           end if
         595           0 :         end subroutine qqcw_set_ptr
         596             :
         597             : !--------------------------------------------------------------
         598             : !--------------------------------------------------------------
         599           0 :         function qqcw_get_field(pbuf, index, lchnk, errorhandle)
         600             :           use cam_abortutils, only : endrun
         601             :           use physics_buffer, only : physics_buffer_desc, pbuf_get_field
         602             :
         603             :           integer, intent(in) :: index, lchnk
         604             :           real(r8), pointer :: qqcw_get_field(:,:)
         605             :           logical, optional :: errorhandle
         606             :           type(physics_buffer_desc), pointer :: pbuf(:)
         607             :
         608             :           logical :: error
         609             :
         610           0 :           nullify(qqcw_get_field)
         611           0 :           error = .false.
         612           0 :           if (index>0 .and. index <= pcnst) then
         613           0 :              if (qqcw(index)>0) then
         614             :                 call pbuf_get_field(pbuf, qqcw(index), qqcw_get_field)
         615             :              else
         616             :                 error = .true.
         617             :              endif
         618             :           else
         619             :              error = .true.
         620             :           end if
         621             :
         622           0 :           if (error .and. .not. present(errorhandle)) then
         623           0 :              call endrun('qqcw_get_field: attempt to access undefined qqcw')
         624             :           end if
         625             :
         626           0 :         end function qqcw_get_field
         627             :
         628             : !----------------------------------------------------------------
         629             : !
         630             : !   nspec_max = maximum allowable number of chemical species
         631             : !       in each aerosol mode
         632             : !
         633             : !   ntot_amode = number of aerosol modes
         634             : !   ( ntot_amode_gchm = number of aerosol modes in gchm
         635             : !     ntot_amode_ccm2 = number of aerosol modes to be made known to ccm2
         636             : !       These are temporary until multi-mode activation scavenging is going.
         637             : !       Until then, ntot_amode is set to either ntot_amode_gchm or
         638             : !       ntot_amode_ccm2 depending on which code is active )
         639             : !
         640             : !   msectional - if positive, moving-center sectional code is utilized,
         641             : !       and each mode is actually a section.
         642             : !   msectional_concinit - if positive, special code is used to initialize
         643             : !       the mixing ratios of all the sections.
         644             : !
         645             : !   nspec_amode(m) = number of chemical species in aerosol mode m
         646             : !   nspec_amode_ccm2(m) = . . .  while in ccm2 code
         647             : !   nspec_amode_gchm(m) = . . .  while in gchm code
         648             : !   nspec_amode_nontracer(m) = number of "non-tracer" chemical
         649             : !       species while in gchm code
         650             : !   lspectype_amode(l,m) = species type/i.d. for chemical species l
         651             : !       in aerosol mode m.  (1=sulfate, others to be defined)
         652             : !   lmassptr_amode(l,m) = gchm r-array index for the mixing ratio
         653             : !       (moles-x/mole-air) for chemical species l in aerosol mode m
         654             : !       that is in clear air or interstitial air (but not in cloud water)
         655             : !   lmassptrcw_amode(l,m) = gchm r-array index for the mixing ratio
         656             : !       (moles-x/mole-air) for chemical species l in aerosol mode m
         657             : !       that is currently bound/dissolved in cloud water
         658             : !   lwaterptr_amode(m) = gchm r-array index for the mixing ratio
         659             : !       (moles-water/mole-air) for water associated with aerosol mode m
         660             : !       that is in clear air or interstitial air
         661             : !   lkohlercptr_amode(m) = gchm r-array index for the kohler "c" parameter
         662             : !       for aerosol mode m.  This is defined on a per-dry-particle-mass basis:
         663             : !           c = r(i,j,k,lkohlercptr_amode) * [rhodry * (4*pi/3) * rdry^3]
         664             : !   numptr_amode(m) = gchm r-array index for the number mixing ratio
         665             : !       (particles/mole-air) for aerosol mode m that is in clear air or
         666             : !       interstitial are (but not in cloud water).  If zero or negative,
         667             : !       then number is not being simulated.
         668             : !   ( numptr_amode_gchm(m) = same thing but for within gchm
         669             : !     numptr_amode_ccm2(m) = same thing but for within ccm2
         670             : !       These are temporary, to allow testing number in gchm before ccm2 )
         671             : !   numptrcw_amode(m) = gchm r-array index for the number mixing ratio
         672             : !       (particles/mole-air) for aerosol mode m
         673             : !       that is currently bound/dissolved in cloud water
         674             : !   lsfcptr_amode(m) = gchm r-array index for the surface area mixing ratio
         675             : !       (cm^2/mole-air) for aerosol mode m that is in clear air or
         676             : !       interstitial are (but not in cloud water).  If zero or negative,
         677             : !       then surface area is not being simulated.
         678             : !   lsfcptrcw_amode(m) = gchm r-array index for the surface area mixing ratio
         679             : !       (cm^2/mole-air) for aerosol mode m that is currently
         680             : !       bound/dissolved in cloud water.
         681             : !   lsigptr_amode(m) = gchm r-array index for sigmag for aerosol mode m
         682             : !       that is in clear air or interstitial are (but not in cloud water).
         683             : !       If zero or negative, then the constant sigmag_amode(m) is used.
         684             : !   lsigptrcw_amode(m) = gchm r-array index for sigmag for aerosol mode m
         685             : !       that is currently bound/dissolved in cloud water.
         686             : !       If zero or negative, then the constant sigmag_amode(m) is used.
         687             : !   lsigptrac_amode(m) = gchm r-array index for sigmag for aerosol mode m
         688             : !       for combined clear-air/interstial plus bound/dissolved in cloud water.
         689             : !       If zero or negative, then the constant sigmag_amode(m) is used.
         690             : !
         691             : !   dgnum_amode(m) = geometric dry mean diameter (m) of the number
         692             : !       distribution for aerosol mode m.
         693             : !       (Only used when numptr_amode(m) is zero or negative.)
         694             : !   dgnumlo_amode(m), dgnumhi_amode(m) = lower and upper limits on the
         695             : !       geometric dry mean diameter (m) of the number distribution
         696             : !       (Used when mprognum_amode>0, to limit dgnum to reasonable values)
         697             : !   sigmag_amode(m) = geometric standard deviation for aerosol mode m
         698             : !   sigmaglo_amode(m), sigmaghi_amode(m) = lower and upper limits on the
         699             : !       geometric standard deviation of the number distribution
         700             : !       (Used when mprogsfc_amode>0, to limit sigmag to reasonable values)
         701             : !   alnsg_amode(m) = alog( sigmag_amode(m) )
         702             : !   alnsglo_amode(m), alnsghi_amode(m) = alog( sigmaglo/hi_amode(m) )
         703             : !   voltonumb_amode(m) = ratio of number to volume for mode m
         704             : !   voltonumblo_amode(m), voltonumbhi_amode(m) = ratio of number to volume
         705             : !       when dgnum = dgnumlo_amode or dgnumhi_amode, respectively
         706             : !   voltosfc_amode(m), voltosfclo_amode(m), voltosfchi_amode(m) - ratio of
         707             : !       surface to volume for mode m (like the voltonumb_amode's)
         708             : !   alnv2n_amode(m), alnv2nlo_amode(m), alnv2nhi_amode(m) -
         709             : !       alnv2n_amode(m) = alog( voltonumblo_amode(m) ), ...
         710             : !   alnv2s_amode(m), alnv2slo_amode(m), alnv2shi_amode(m) -
         711             : !       alnv2s_amode(m) = alog( voltosfclo_amode(m) ), ...
         712             : !   rhcrystal_amode(m) = crystalization r.h. for mode m
         713             : !   rhdeliques_amode(m) = deliquescence r.h. for mode m
         714             : !   (*** these r.h. values are 0-1 fractions, not 0-100 percentages)
         715             : !
         716             : !   mcalcwater_amode(m) - if positive, water content for mode m will be
         717             : !       calculated and stored in rclm(k,lwaterptr_amode(m)).  Otherwise, no.
         718             : !   mprognum_amode(m) - if positive, number mixing-ratio for mode m will
         719             : !       be prognosed.  Otherwise, no.
         720             : !   mdiagnum_amode(m) - if positive, number mixing-ratio for mode m will
         721             : !       be diagnosed and put into rclm(k,numptr_amode(m)).  Otherwise, no.
         722             : !   mprogsfc_amode(m) - if positive, surface area mixing-ratio for mode m will
         723             : !       be prognosed, and sigmag will vary temporally and spatially.
         724             : !       Otherwise, sigmag is constant.
         725             : !       *** currently surface area is not prognosed when msectional>0 ***
         726             : !
         727             : !   ntot_aspectype = overall number of aerosol chemical species defined (over all modes)
         728             : !   specdens_amode(l) = dry density (kg/m^3) of aerosol chemical species type l
         729             : !   specmw_amode(l) = molecular weight (kg/kmol) of aerosol chemical species type l
         730             : !   specname_amode(l) = name of aerosol chemical species type l
         731             : !   specrefndxsw(l) = complex refractive index (visible wavelengths)
         732             : !                   of aerosol chemical species type l
         733             : !   specrefndxlw(l) = complex refractive index (infrared wavelengths)
         734             : !                   of aerosol chemical species type l
         735             : !   spechygro(l) = hygroscopicity of aerosol chemical species type l
         736             : !
         737             : !   lptr_so4_a_amode(m), lptr_so4_cw_amode(m) = gchm r-array index for the
         738             : !       mixing ratio for sulfate associated with aerosol mode m
         739             : !       ("a" and "cw" phases)
         740             : !   (similar for msa, oc, bc, nacl, dust)
         741             : !
         742             : !   modename_amode(m) = character-variable name for mode m,
         743             : !       read from mirage2.inp
         744             : !   modeptr_accum - mode index for the main accumulation mode
         745             : !       if modeptr_accum = 1, then mode 1 is the main accumulation mode,
         746             : !       and modename_amode(1) = "accum"
         747             : !   modeptr_aitken - mode index for the main aitken mode
         748             : !       if modeptr_aitken = 2, then mode 2 is the main aitken mode,
         749             : !       and modename_amode(2) = "aitken"
         750             : !   modeptr_ufine - mode index for the ultrafine mode
         751             : !       if modeptr_ufine = 3, then mode 3 is the ultrafine mode,
         752             : !       and modename_amode(3) = "ufine"
         753             : !   modeptr_coarseas - mode index for the coarse sea-salt mode
         754             : !       if modeptr_coarseas = 4, then mode 4 is the coarse sea-salt mode,
         755             : !       and modename_amode(4) = "coarse_seasalt"
         756             : !   modeptr_coardust - mode index for the coarse dust mode
         757             : !       if modeptr_coardust = 5, then mode 5 is the coarse dust mode,
         758             : !       and modename_amode(5) = "coarse_dust"
         759             : !
         760             : !   specdens_XX_amode = dry density (kg/m^3) of aerosol chemical species type XX
         761             : !       where XX is so4, om, bc, dust, seasalt
         762             : !       contains same values as the specdens_amode array
         763             : !       allows values to be referenced differently
         764             : !   specmw_XX_amode = molecular weight (kg/kmol) of aerosol chemical species type XX
         765             : !       contains same values as the specmw_amode array
         766             : !
         767             : !-----------------------------------------------------------------------
         768             :
         769             :
         770             : !--------------------------------------------------------------
         771             : !
         772             : ! ... aerosol size information for the current chunk
         773             : !
         774             : !--------------------------------------------------------------
         775             : !
         776             : !  dgncur = current geometric mean diameters (cm) for number distributions
         777             : !  dgncur_a - for unactivated particles, dry
         778             : !             (in physics buffer as DGNUM)
         779             : !  dgncur_awet - for unactivated particles, wet at grid-cell ambient RH
         780             : !             (in physics buffer as DGNUMWET)
         781             : !
         782             : !  the dgncur are computed from current mass and number
         783             : !  mixing ratios in the grid cell, BUT are then adjusted to be within
         784             : !  the bounds defined by dgnumlo/hi_amode
         785             : !
         786             : !  v2ncur = current (number/volume) ratio based on dgncur and sgcur
         787             : !              (volume in cm^3/whatever, number in particles/whatever)
         788             : !         == 1.0 / ( pi/6 * dgncur**3 * exp(4.5*((log(sgcur))**2)) )
         789             : !  v2ncur_a - for unactivated particles
         790             : !             (currently just defined locally)
         791             : !
         792             :
         793             :      !==============================================================
         794           0 :      subroutine search_list_of_names(                                &
         795           0 :           name_to_find, name_id, list_of_names, list_length )
         796             :        !
         797             :        !   searches for a name in a list of names
         798             :        !
         799             :        !   name_to_find - the name to be found in the list  [input]
         800             :        !   name_id - the position of "name_to_find" in the "list_of_names".
         801             :        !       If the name is not found in the list, then name_id=0.  [output]
         802             :        !   list_of_names - the list of names to be searched  [input]
         803             :        !   list_length - the number of names in the list  [input]
         804             :        !
         805             :        character(len=*), intent(in):: name_to_find, list_of_names(:)
         806             :        integer, intent(in) :: list_length
         807             :        integer, intent(out) :: name_id
         808             :
         809             :        integer :: i
         810           0 :        name_id = -999888777
         811           0 :        if (name_to_find .ne. ' ') then
         812           0 :           do i = 1, list_length
         813           0 :              if (name_to_find .eq. list_of_names(i)) then
         814           0 :                 name_id = i
         815           0 :                 exit
         816             :              end if
         817             :           end do
         818             :        end if
         819           0 :      end subroutine search_list_of_names
         820             :
         821             :
         822             :      !==============================================================
         823           0 :      subroutine initaermodes_setspecptrs
         824             :        !
         825             :        !   sets the lptr_so4_a_amode(m), lptr_so4_cw_amode(m), ...
         826             :        !       and writes them to iulog
         827             :        !   ALSO sets the mode-pointers:  modeptr_accum, modeptr_aitken, ...
         828             :        !       and writes them to iulog
         829             :        !   ALSO sets values of specdens_XX_amode and specmw_XX_amode
         830             :        !       (XX = so4, om, bc, dust, seasalt)
         831             :        !
         832             :        implicit none
         833             :
         834             :        !   local variables
         835             :        integer :: i, l, lmassa, lmassc, m
         836             :        character(len=1000) :: msg
         837             :        character*8 :: dumname
         838             :        character*3 :: tmpch3
         839             :        integer, parameter :: init_val=-999888777
         840             :        integer :: bc_ndx, soa_ndx, pom_ndx
         841             :
         842             :        !   all processes set the pointers
         843             :
         844           0 :        modeptr_accum = init_val
         845           0 :        modeptr_aitken = init_val
         846           0 :        modeptr_ufine = init_val
         847           0 :        modeptr_coarse = init_val
         848           0 :        modeptr_pcarbon = init_val
         849           0 :        modeptr_fineseas = init_val
         850           0 :        modeptr_finedust = init_val
         851           0 :        modeptr_coarseas = init_val
         852           0 :        modeptr_coardust = init_val
         853           0 :        modeptr_stracoar = init_val
         854             :
         855           0 :        do m = 1, ntot_amode
         856           0 :           if (modename_amode(m) .eq. 'accum') then
         857           0 :              modeptr_accum = m
         858           0 :           else if (modename_amode(m) .eq. 'aitken') then
         859           0 :              modeptr_aitken = m
         860           0 :           else if (modename_amode(m) .eq. 'ufine') then
         861           0 :              modeptr_ufine = m
         862           0 :           else if (modename_amode(m) .eq. 'coarse') then
         863           0 :              modeptr_coarse = m
         864           0 :           else if (modename_amode(m) .eq. 'primary_carbon') then
         865           0 :              modeptr_pcarbon = m
         866           0 :           else if (modename_amode(m) .eq. 'fine_seasalt') then
         867           0 :              modeptr_fineseas = m
         868           0 :           else if (modename_amode(m) .eq. 'fine_dust') then
         869           0 :              modeptr_finedust = m
         870           0 :           else if (modename_amode(m) .eq. 'coarse_seasalt') then
         871           0 :              modeptr_coarseas = m
         872           0 :           else if (modename_amode(m) .eq. 'coarse_dust') then
         873           0 :              modeptr_coardust = m
         874           0 :           else if (modename_amode(m) .eq. 'coarse_strat') then
         875           0 :              modeptr_stracoar = m
         876             :           end if
         877             :        end do
         878             :
         879           0 :        lptr2_pom_a_amode   = init_val
         880           0 :        lptr2_pom_cw_amode  = init_val
         881           0 :        lptr2_soa_a_amode   = init_val
         882           0 :        lptr2_soa_cw_amode  = init_val
         883           0 :        lptr2_bc_a_amode    = init_val
         884           0 :        lptr2_bc_cw_amode   = init_val
         885             :
         886           0 :        do m = 1, ntot_amode
         887             :
         888           0 :           lptr_so4_a_amode(m)    = init_val
         889           0 :           lptr_so4_cw_amode(m)   = init_val
         890           0 :           lptr_msa_a_amode(m)    = init_val
         891           0 :           lptr_msa_cw_amode(m)   = init_val
         892           0 :           lptr_nh4_a_amode(m)    = init_val
         893           0 :           lptr_nh4_cw_amode(m)   = init_val
         894           0 :           lptr_no3_a_amode(m)    = init_val
         895           0 :           lptr_no3_cw_amode(m)   = init_val
         896           0 :           lptr_nacl_a_amode(m)   = init_val
         897           0 :           lptr_nacl_cw_amode(m)  = init_val
         898           0 :           lptr_dust_a_amode(m)   = init_val
         899           0 :           lptr_dust_cw_amode(m)  = init_val
         900             :
         901           0 :           pom_ndx = 0
         902           0 :           soa_ndx = 0
         903           0 :           bc_ndx = 0
         904             :
         905           0 :           do l = 1, nspec_amode(m)
         906           0 :              lmassa  = lmassptr_amode(l,m)
         907           0 :              lmassc = lmassptrcw_amode(l,m)
         908             :
         909           0 :              if (lmassa > 0 .and. lmassa <= pcnst) then
         910             :                 write( msg, '(2a,3(1x,i12),2x,a)' ) &
         911           0 :                      'subr initaermodes_setspecptrs error setting lptr_', &
         912           0 :                      ' - m, l, lmassa, cnst_name = ', m, l, lmassa, cnst_name(lmassa)
         913             :              else
         914             :                 write( msg, '(2a,3(1x,i12),2x,a)' ) &
         915           0 :                      'subr initaermodes_setspecptrs error setting lptr_', &
         916           0 :                      ' - m, l, lmassa, cnst_name = ', m, l, lmassa, 'UNDEF '
         917           0 :                 call endrun( trim(msg) )
         918             :              end if
         919             :
         920           0 :              tmpch3 = cnst_name(lmassa)(:3)
         921           0 :              select case (tmpch3)
         922             :              case('so4')
         923           0 :                 lptr_so4_a_amode(m)  = lmassa
         924           0 :                 lptr_so4_cw_amode(m) = lmassc
         925             :              case('msa')
         926           0 :                 lptr_msa_a_amode(m)  = lmassa
         927           0 :                 lptr_msa_cw_amode(m) = lmassc
         928             :              case('nh4')
         929           0 :                 lptr_nh4_a_amode(m)  = lmassa
         930           0 :                 lptr_nh4_cw_amode(m) = lmassc
         931             :              case('no3')
         932           0 :                 lptr_no3_a_amode(m)  = lmassa
         933           0 :                 lptr_no3_cw_amode(m) = lmassc
         934             :              case('dst')
         935           0 :                 lptr_dust_a_amode(m)  = lmassa
         936           0 :                 lptr_dust_cw_amode(m) = lmassc
         937             :              case('ncl')
         938           0 :                 lptr_nacl_a_amode(m)  = lmassa
         939           0 :                 lptr_nacl_cw_amode(m) = lmassc
         940             :              case('pom')
         941           0 :                 pom_ndx = pom_ndx+1
         942           0 :                 lptr2_pom_a_amode(m,pom_ndx)  = lmassa
         943           0 :                 lptr2_pom_cw_amode(m,pom_ndx) = lmassc
         944             :              case('soa')
         945           0 :                 soa_ndx = soa_ndx+1
         946           0 :                 lptr2_soa_a_amode(m,soa_ndx)  = lmassa
         947           0 :                 lptr2_soa_cw_amode(m,soa_ndx) = lmassc
         948             :              case('bc_','bcf','bcb')
         949           0 :                 bc_ndx = bc_ndx+1
         950           0 :                 lptr2_bc_a_amode(m,bc_ndx)  = lmassa
         951           0 :                 lptr2_bc_cw_amode(m,bc_ndx) = lmassc
         952             :              case default
         953           0 :                 call endrun( trim(msg) )
         954             :              end select
         955             :           end do ! l
         956             :        end do ! m
         957             :
         958           0 :        specmw_so4_amode = 1.0_r8
         959             :
         960           0 :        do m = 1, ntot_amode
         961           0 :           do l = 1, nspec_amode(m)
         962           0 :              dumname = trim(adjustl(xname_massptr(l,m)))
         963           0 :              tmpch3  = trim(adjustl(dumname(:3)))
         964           0 :              if(trim(adjustl(tmpch3)) == 'so4' .or. trim(adjustl(tmpch3)) == 'SO4') then
         965           0 :                 specmw_so4_amode = specmw_amode(l,m)
         966             :              endif
         967             :           enddo
         968             :        enddo
         969             :
         970             :
         971             :        !   masterproc writes out the pointers
         972           0 :        if ( .not. ( masterproc ) ) return
         973             :
         974           0 :        write(iulog,9230)
         975           0 :        write(iulog,*) 'modeptr_accum    =', modeptr_accum
         976           0 :        write(iulog,*) 'modeptr_aitken   =', modeptr_aitken
         977           0 :        write(iulog,*) 'modeptr_ufine    =', modeptr_ufine
         978           0 :        write(iulog,*) 'modeptr_coarse   =', modeptr_coarse
         979           0 :        write(iulog,*) 'modeptr_pcarbon  =', modeptr_pcarbon
         980           0 :        write(iulog,*) 'modeptr_fineseas =', modeptr_fineseas
         981           0 :        write(iulog,*) 'modeptr_finedust =', modeptr_finedust
         982           0 :        write(iulog,*) 'modeptr_coarseas =', modeptr_coarseas
         983           0 :        write(iulog,*) 'modeptr_coardust =', modeptr_coardust
         984           0 :        write(iulog,*) 'modeptr_stracoar =', modeptr_stracoar
         985             :
         986           0 :        dumname = 'none'
         987           0 :        write(iulog,9240)
         988           0 :        write(iulog,9000) 'sulfate    '
         989           0 :        do m = 1, ntot_amode
         990             :           call initaermodes_setspecptrs_write2( m,                    &
         991           0 :                lptr_so4_a_amode(m), lptr_so4_cw_amode(m),  'so4' )
         992             :        end do
         993             :
         994           0 :        write(iulog,9000) 'msa        '
         995           0 :        do m = 1, ntot_amode
         996             :           call initaermodes_setspecptrs_write2( m,                    &
         997           0 :                lptr_msa_a_amode(m), lptr_msa_cw_amode(m),  'msa' )
         998             :        end do
         999             :
        1000           0 :        write(iulog,9000) 'ammonium   '
        1001           0 :        do m = 1, ntot_amode
        1002             :           call initaermodes_setspecptrs_write2( m,                    &
        1003           0 :                lptr_nh4_a_amode(m), lptr_nh4_cw_amode(m),  'nh4' )
        1004             :        end do
        1005             :
        1006           0 :        write(iulog,9000) 'nitrate    '
        1007           0 :        do m = 1, ntot_amode
        1008             :           call initaermodes_setspecptrs_write2( m,                    &
        1009           0 :                lptr_no3_a_amode(m), lptr_no3_cw_amode(m),  'no3' )
        1010             :        end do
        1011             :
        1012           0 :        write(iulog,9000) 'p-organic  '
        1013           0 :        do m = 1, ntot_amode
        1014           0 :           do i = 1, npoa
        1015           0 :              write(dumname,'(a,i2.2)') 'pom', i
        1016             :              call initaermodes_setspecptrs_write2b( m, &
        1017           0 :                   lptr2_pom_a_amode(m,i), lptr2_pom_cw_amode(m,i),  dumname(1:5) )
        1018             :           end do
        1019             :        end do
        1020             :
        1021           0 :        write(iulog,9000) 's-organic  '
        1022           0 :        do m = 1, ntot_amode
        1023           0 :           do i = 1, nsoa
        1024           0 :              write(dumname,'(a,i2.2)') 'soa', i
        1025             :              call initaermodes_setspecptrs_write2b( m, &
        1026           0 :                   lptr2_soa_a_amode(m,i), lptr2_soa_cw_amode(m,i), dumname(1:5) )
        1027             :           end do
        1028             :        end do
        1029           0 :        do i = 1, nsoa
        1030           0 :           l = lptr2_soa_g_amode(i)
        1031           0 :           write(iulog,'(i4,2x,i12,2x,a,20x,a,i2.2,a)') i, l, cnst_name(l), 'lptr2_soa', i, '_g'
        1032             :        end do
        1033             :
        1034           0 :        write(iulog,9000) 'black-c    '
        1035           0 :        do m = 1, ntot_amode
        1036           0 :           do i = 1, nbc
        1037           0 :              write(dumname,'(a,i2.2)') 'bc', i
        1038             :              call initaermodes_setspecptrs_write2b( m, &
        1039           0 :                   lptr2_bc_a_amode(m,i), lptr2_bc_cw_amode(m,i), dumname(1:5) )
        1040             :           end do
        1041             :        end do
        1042             :
        1043           0 :        write(iulog,9000) 'seasalt   '
        1044           0 :        do m = 1, ntot_amode
        1045             :           call initaermodes_setspecptrs_write2( m,                    &
        1046           0 :                lptr_nacl_a_amode(m), lptr_nacl_cw_amode(m),  'nacl' )
        1047             :        end do
        1048             :
        1049           0 :        write(iulog,9000) 'dust       '
        1050           0 :        do m = 1, ntot_amode
        1051             :           call initaermodes_setspecptrs_write2( m,                    &
        1052           0 :                lptr_dust_a_amode(m), lptr_dust_cw_amode(m),  'dust' )
        1053             :        end do
        1054             :
        1055             : 9000   format( a )
        1056             : 9230   format(                                                         &
        1057             :             / 'mode-pointer output from subr initaermodes_setspecptrs' )
        1058             : 9240   format(                                                         &
        1059             :             / 'species-pointer output from subr initaermodes_setspecptrs' / &
        1060             :             'mode', 12x, 'id  name_a  ', 12x, 'id  name_cw' )
        1061             :
        1062             :        return
        1063             :      end subroutine initaermodes_setspecptrs
        1064             :
        1065             :
        1066             :      !==============================================================
        1067           0 :      subroutine initaermodes_setspecptrs_write2(                     &
        1068             :           m, laptr, lcptr, txtdum )
        1069             :        !
        1070             :        !   does some output for initaermodes_setspecptrs
        1071             :
        1072             :        use constituents, only: pcnst, cnst_name
        1073             :
        1074             :        implicit none
        1075             :
        1076             :        !   subr arguments
        1077             :        integer, intent(in) :: m, laptr, lcptr
        1078             :        character*(*), intent(in) ::  txtdum
        1079             :
        1080             :        !   local variables
        1081             :        character*8 dumnamea, dumnamec
        1082             :
        1083           0 :        dumnamea = 'none'
        1084           0 :        dumnamec = 'none'
        1085           0 :        if (laptr > pcnst .or. lcptr > pcnst ) then
        1086           0 :           call endrun('initaermodes_setspecptrs_write2: ERROR')
        1087             :        endif
        1088           0 :        if (laptr .gt. 0) dumnamea = cnst_name(laptr)
        1089           0 :        if (lcptr .gt. 0) dumnamec = cnst_name(lcptr)
        1090           0 :        write(iulog,9241) m, laptr, dumnamea, lcptr, dumnamec, txtdum
        1091             :
        1092             : 9241   format( i4, 2( 2x, i12, 2x, a ),                                &
        1093             :             4x, 'lptr_', a, '_a/cw_amode' )
        1094             :
        1095           0 :        return
        1096             :      end subroutine initaermodes_setspecptrs_write2
        1097             :
        1098             :
        1099             :      !==============================================================
        1100           0 :      subroutine initaermodes_setspecptrs_write2b( &
        1101             :           m, laptr, lcptr, txtdum )
        1102             :        !
        1103             :        !   does some output for initaermodes_setspecptrs
        1104             :
        1105             :        implicit none
        1106             :
        1107             :        !   subr arguments
        1108             :        integer, intent(in) :: m, laptr, lcptr
        1109             :        character*(*), intent(in) :: txtdum
        1110             :
        1111             :        !   local variables
        1112             :        character*8 dumnamea, dumnamec
        1113             :
        1114           0 :        dumnamea = 'none'
        1115           0 :        dumnamec = 'none'
        1116           0 :        if (laptr .gt. 0) dumnamea = cnst_name(laptr)
        1117           0 :        if (lcptr .gt. 0) dumnamec = cnst_name(lcptr)
        1118           0 :        write(iulog,9241) m, laptr, dumnamea, lcptr, dumnamec, txtdum
        1119             :
        1120             : 9241   format( i4, 2( 2x, i12, 2x, a ),                                &
        1121             :             4x, 'lptr2_', a, '_a/cw_amode' )
        1122             :
        1123           0 :        return
        1124             :      end subroutine initaermodes_setspecptrs_write2b
        1125             :
        1126             :      !==============================================================
        1127           0 :      subroutine initaermodes_set_cnstnamecw
        1128             :        !
        1129             :        !   sets the cnst_name_cw
        1130             :        !
        1131             :        use constituents, only: pcnst, cnst_name
        1132             :        implicit none
        1133             :
        1134             :        !   subr arguments (none)
        1135             :
        1136             :        !   local variables
        1137             :        integer j, l, la, lc, ll, m
        1138             :
        1139             :        !   set cnst_name_cw
        1140           0 :        cnst_name_cw = ' '
        1141           0 :        do m = 1, ntot_amode
        1142           0 :           do ll = 0, nspec_amode(m)
        1143           0 :              if (ll == 0) then
        1144           0 :                 la = numptr_amode(m)
        1145           0 :                 lc = numptrcw_amode(m)
        1146             :              else
        1147           0 :                 la = lmassptr_amode(ll,m)
        1148           0 :                 lc = lmassptrcw_amode(ll,m)
        1149             :              end if
        1150             :              if ((la < 1) .or. (la > pcnst) .or.   &
        1151           0 :                   (lc < 1) .or. (lc > pcnst)) then
        1152             :                 write(*,'(/2a/a,5(1x,i10))')   &
        1153           0 :                      '*** initaermodes_set_cnstnamecw error',   &
        1154           0 :                      ' -- bad la or lc',   &
        1155           0 :                      '    m, ll, la, lc, pcnst =', m, ll, la, lc, pcnst
        1156           0 :                 call endrun( '*** initaermodes_set_cnstnamecw error' )
        1157             :              end if
        1158           0 :              do j = 2, len( cnst_name(la) ) - 1
        1159           0 :                 if (cnst_name(la)(j:j+1) == '_a') then
        1160           0 :                    cnst_name_cw(lc) = cnst_name(la)
        1161           0 :                    cnst_name_cw(lc)(j:j+1) = '_c'
        1162           0 :                    exit
        1163           0 :                 else if (cnst_name(la)(j:j+1) == '_A') then
        1164           0 :                    cnst_name_cw(lc) = cnst_name(la)
        1165           0 :                    cnst_name_cw(lc)(j:j+1) = '_C'
        1166           0 :                    exit
        1167             :                 end if
        1168             :              end do
        1169           0 :              if (cnst_name_cw(lc) == ' ') then
        1170             :                 write(*,'(/2a/a,3(1x,i10),2x,a)')   &
        1171           0 :                      '*** initaermodes_set_cnstnamecw error',   &
        1172           0 :                      ' -- bad cnst_name(la)',   &
        1173           0 :                      '    m, ll, la, cnst_name(la) =',   &
        1174           0 :                      m, ll, la, cnst_name(la)
        1175           0 :                 call endrun( '*** initaermodes_set_cnstnamecw error' )
        1176             :              end if
        1177             :           end do   ! ll = 0, nspec_amode(m)
        1178             :        end do   ! m = 1, ntot_amode
        1179             :
        1180           0 :        if ( masterproc ) then
        1181           0 :           write(*,'(/a)') 'l, cnst_name(l), cnst_name_cw(l)'
        1182           0 :           do l = 1, pcnst
        1183           0 :              write(*,'(i4,2(2x,a))') l, cnst_name(l), cnst_name_cw(l)
        1184             :           end do
        1185             :        end if
        1186             :
        1187           0 :        return
        1188             :      end subroutine initaermodes_set_cnstnamecw
        1189             :
        1190             :   end module modal_aero_data

Generated by: LCOV version 1.14