LCOV - code coverage report
Current view: top level - physics/carma/base - rhopart.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 44 62 71.0 %
Date: 2025-03-14 01:33:33 Functions: 1 1 100.0 %

          Line data    Source code
       1             : ! Include shortname defintions, so that the F77 code does not have to be modified to
       2             : ! reference the CARMA structure.
       3             : #include "carma_globaer.h"
       4             : 
       5             : !!  This routine calculates new average particle densities.
       6             : !!
       7             : !!  The particle mass density can change at each time-step due to
       8             : !!  changes in the core mass fraction.
       9             : !!
      10             : !!  For particles that are hydrophilic and whose particle size changes based
      11             : !!  upon the relative humidity, and wet radius and density are also calculated.
      12             : !!  For particles that do not swell, the wet and dry radius and densities are
      13             : !!  the same.
      14             : !!
      15             : !! @author   Chuck Bardeen Eric Jensen
      16             : !! @ version May-2009; Oct-1995
      17             : !!
      18             : !! @see wetr
      19     1050624 : subroutine rhopart(carma, cstate, rc)
      20             : 
      21             :   ! types
      22             :   use carma_precision_mod
      23             :   use carma_enums_mod
      24             :   use carma_constants_mod
      25             :   use carma_types_mod
      26             :   use carmastate_mod
      27             :   use carma_mod
      28             :   use sulfate_utils
      29             :   use wetr
      30             : 
      31             :   implicit none
      32             : 
      33             :   type(carma_type), intent(in)         :: carma   !! the carma object
      34             :   type(carmastate_type), intent(inout) :: cstate  !! the carma state object
      35             :   integer, intent(inout)               :: rc      !! return code, negative indicates failure
      36             : 
      37             :   ! Local declarations
      38             :   integer         :: iz             !! z index
      39             :   integer         :: igroup         !! group index
      40             :   integer         :: ibin           !! bin index
      41             :   integer         :: iepart         !! element in group containing the particle concentration
      42             :   integer         :: jcore
      43             :   integer         :: iecore
      44     2101248 :   real(kind=f)    :: vcore(NBIN)
      45     2101248 :   real(kind=f)    :: mcore(NBIN)
      46             :   real(kind=f)    :: r_ratio
      47             :   real(kind=f)    :: h2o_mass
      48             : 
      49             :   1 format(/,'rhopart::WARNING - core mass > total mass, truncating : iz=',i4,',igroup=',&
      50             :               i4,',ibin=',i4,',total mass=',e10.3,',core mass=',e10.3,',using rhop=',f9.4)
      51             : 
      52             :   ! Calculate hygroscopicity parameter, kappa, for mixed aerosols (Yu et al., JAMES, 2015)
      53     1050624 :   call hygroscopicity(carma, cstate, rc)
      54             : 
      55             :   ! Calculate average particle mass density for each group
      56     3151872 :   do igroup = 1,NGROUP
      57             : 
      58             :     ! Define particle # concentration element index for current group
      59     2101248 :     iepart = ienconc(igroup)     ! element of particle number concentration
      60             : 
      61   150239232 :     do iz = 1, NZ
      62             : 
      63             :       ! If there are no cores, than the density of the particle is just the density
      64             :       ! of the element.
      65   147087360 :       if (ncore(igroup) < 1) then
      66  1544417280 :         rhop(iz,:,igroup) = rhoelem(:,iepart)
      67             : 
      68             :       ! Otherwise, the density changes depending on the amount of core and volatile
      69             :       ! components.
      70             :       else ! ncore(igroup) >= 1
      71             : 
      72             :         ! Calculate volume of cores and the mass of shell material
      73             :         ! <vcore> is the volume of core material and <rmshell> is the
      74             :         ! mass of shell material.
      75  1544417280 :         vcore(:) = 0._f
      76  1544417280 :         mcore(:) = 0._f
      77             : 
      78   441262080 :         do jcore = 1,ncore(igroup)
      79   367718400 :           iecore = icorelem(jcore,igroup)    ! core element
      80             : 
      81  7722086400 :           mcore(:) = mcore(:) + pc(iz,:,iecore)
      82  7795630080 :           vcore(:) = vcore(:) + pc(iz,:,iecore) / rhoelem(:,iecore)
      83             :         end do ! jcore = 1,ncore(igroup)
      84             : 
      85             :         ! Calculate average density
      86  1544417280 :         do ibin = 1,NBIN
      87             : 
      88             :           ! If there is no core, the the density is that of the volatile element.
      89  1544417280 :           if (mcore(ibin) == 0._f) then
      90       13363 :             rhop(iz,ibin,igroup) = rhoelem(ibin,iepart)
      91             :           else! mcore(ibin) /= 0._f
      92             : 
      93             :             ! Since core mass and particle number (i.e. total mass) are advected separately,
      94             :             ! numerical diffusion during advection can cause problems where the core mass
      95             :             ! becomes greater than the total mass. To prevent adevction errors from making the
      96             :             ! group inconsistent, we will truncate core mass if it is larger than the total
      97             :             ! mass.
      98  1470860237 :             if (mcore(ibin) > (rmass(ibin,igroup) * pc(iz,ibin,iepart))) then
      99             : 
     100             :               ! Calculate the density.
     101     5513213 :               rhop(iz,ibin,igroup) = mcore(ibin) / vcore(ibin)
     102             : 
     103             :               ! NOTE: This error happens a lot, so this error message is commented out
     104             :               ! by default.
     105             : !              if (do_print) write(LUNOPRT,1) iz, igroup, ibin, pc(iz,ibin,iepart)*rmass(ibin,igroup), &
     106             : !                mcore(ibin), rhop(iz,ibin,igroup)
     107             : !              rc = RC_WARNING
     108             : 
     109             :               ! Repair total mass.
     110     5513213 :               pc(iz,ibin,iepart) = mcore(ibin) / rmass(ibin,igroup)
     111             :             else
     112           0 :               rhop(iz,ibin,igroup) = (rmass(ibin,igroup) * pc(iz,ibin,iepart)) / &
     113  1465347024 :               ((pc(iz,ibin,iepart)*rmass(ibin,igroup) - mcore(ibin))/rhoelem(ibin,iepart) + vcore(ibin))
     114             :             end if ! mcore(ibin) > (rmass(ibin,igroup) * pc(iz,ibin,iepart))
     115             :           end if ! mcore(ibin) == 0._f
     116             :         end do ! ibin = 1,NBIN
     117             :       end if ! ncore(igroup) < 1
     118             : 
     119             :       ! If these particles are hygroscopic and grow in response to the relative
     120             :       ! humidity, then caclulate a wet radius and wet density. Otherwise the wet
     121             :       ! and dry radius are the same.
     122             : 
     123             :       ! Determine the weight percent of sulfate, and store it for later use.
     124   147087360 :       if (irhswell(igroup) == I_WTPCT_H2SO4 .or. irhswell(igroup) == I_PETTERS) then
     125   147087360 :         h2o_mass     = gc(iz, igash2o) / zmet(iz)
     126             :       end if
     127             : 
     128             :       ! Loop over particle size bins.
     129  3090935808 :       do ibin = 1,NBIN
     130             : 
     131             :          ! If humidity affects the particle, then determine the equilbirium
     132             :          ! radius and density based upon the relative humidity.
     133  3088834560 :          if (irhswell(igroup) == I_WTPCT_H2SO4) then
     134             : 
     135             :             ! rlow
     136           0 :             call getwetr(carma, igroup, relhum(iz), rlow(ibin,igroup), rlow_wet(iz,ibin,igroup), &
     137             :                          rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc, h2o_mass=h2o_mass, &
     138           0 :                          h2o_vp=pvapl(iz, igash2o), temp=t(iz))
     139  1470873600 :             if (rc < 0) return
     140  1470873600 : 
     141             :             ! rup
     142             :             call getwetr(carma, igroup, relhum(iz), rup(ibin,igroup), rup_wet(iz,ibin,igroup), &
     143  1470873600 :                          rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc, h2o_mass=h2o_mass, &
     144             :                          h2o_vp=pvapl(iz, igash2o), temp=t(iz))
     145           0 :             if (rc < 0) return
     146  2941747200 : 
     147  1470873600 :             ! r
     148             :             call getwetr(carma, igroup, relhum(iz), r(ibin,igroup), r_wet(iz,ibin,igroup), &
     149             :                          rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc, h2o_mass=h2o_mass, &
     150  1470873600 :                          h2o_vp=pvapl(iz, igash2o), temp=t(iz))
     151             :             if (rc < 0) return
     152           0 : 
     153  2941747200 :         else if (irhswell(igroup) == I_PETTERS) then
     154  1470873600 : 
     155             :             call getwetr(carma, igroup, relhum(iz), rlow(ibin,igroup), rlow_wet(iz,ibin,igroup), &
     156  1470873600 :                          rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc,h2o_mass=h2o_mass, &
     157             :                          h2o_vp=pvapl(iz, igash2o), temp=t(iz), kappa=kappahygro(iz,ibin,igroup))
     158           0 :             if (rc < 0) return
     159           0 : 
     160  1470873600 :             ! rup
     161  1470873600 :             call getwetr(carma, igroup, relhum(iz), rup(ibin,igroup), rup_wet(iz,ibin,igroup), &
     162             :                          rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc, h2o_mass=h2o_mass, &
     163             :                          h2o_vp=pvapl(iz, igash2o),temp=t(iz), kappa=kappahygro(iz,ibin,igroup))
     164  1470873600 :             if (rc < 0) return
     165             : 
     166           0 :             ! r
     167  2941747200 :             call getwetr(carma, igroup, relhum(iz), r(ibin,igroup), r_wet(iz,ibin,igroup), &
     168  1470873600 :                         rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc, h2o_mass=h2o_mass, &
     169             :                         h2o_vp=pvapl(iz, igash2o),temp=t(iz), kappa=kappahygro(iz,ibin,igroup))
     170             :             if (rc < 0) return
     171  1470873600 : 
     172             :          else ! I_GERBER and I_FITZGERALD
     173           0 : 
     174  2941747200 :             call getwetr(carma, igroup, relhum(iz), rlow(ibin,igroup), rlow_wet(iz,ibin,igroup), &
     175  1470873600 :                          rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc)
     176             :             if (rc < 0) return
     177             : 
     178             :             ! rup
     179           0 :             call getwetr(carma, igroup, relhum(iz), rup(ibin,igroup), rup_wet(iz,ibin,igroup), &
     180           0 :                          rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc)
     181           0 :             if (rc < 0) return
     182             : 
     183             :             ! r
     184           0 :             call getwetr(carma, igroup, relhum(iz), r(ibin,igroup), r_wet(iz,ibin,igroup), &
     185             :                          rhop(iz,ibin,igroup), rhop_wet(iz,ibin,igroup), rc)
     186           0 :             if (rc < 0) return
     187           0 : 
     188             :          end if
     189             :       end do ! ibin = 1,NBIN
     190           0 :     end do ! iz = 1, NZ
     191             :   end do ! igroup = 1,NGROUP
     192           0 : 
     193           0 :   !  Return to caller with new particle number densities.
     194             :   return
     195             : end subroutine rhopart

Generated by: LCOV version 1.14