Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugs in PDER, OCPISOA and TotalOC in complexSOA #2315

Merged
merged 5 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ This file documents all notable changes to the GEOS-Chem repository starting in

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Changed
- Simplified SOA representations and fixed related AOD and TotalOA/OC calculations in benchmark.

## [14.4.1] - 2024-06-28
### Added
- Added initialization of PHOTDELTA in `ucx_h2so4phot` to avoid run-time error in CESM
Expand Down
91 changes: 39 additions & 52 deletions GeosCore/aerosol_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -763,39 +763,31 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, &

! Use simple SOA by default over complex SOA in calculations
IF ( Is_SimpleSOA ) THEN
State_Chm%AerMass%OCPISOA(I,J,L) = ( Spc(id_OCPI)%Conc(I,J,L) * State_chm%AerMass%OCFOPOA(I,J) + &
Spc(id_SOAS)%Conc(I,J,L) ) / AIRVOL(I,J,L)
State_Chm%AerMass%OCPISOA(I,J,L) = State_Chm%AerMass%OCPI(I,J,L) + &
State_Chm%AerMass%SOAS(I,J,L)

ELSEIF ( Is_ComplexSOA ) THEN

State_Chm%AerMass%OCPISOA(I,J,L) = ( Spc(id_TSOA1)%Conc(I,J,L) &
+ Spc(id_TSOA2)%Conc(I,J,L) &
+ Spc(id_TSOA3)%Conc(I,J,L) &
+ Spc(id_TSOA0)%Conc(I,J,L) &
+ Spc(id_ASOAN)%Conc(I,J,L) &
+ Spc(id_ASOA1)%Conc(I,J,L) &
+ Spc(id_ASOA2)%Conc(I,J,L) &
+ Spc(id_ASOA3)%Conc(I,J,L) ) &
/ AIRVOL(I,J,L)

IF ( IS_OPOA ) THEN ! hotp 7/28/10
State_Chm%AerMass%OCPISOA(I,J,L) = State_Chm%AerMass%OCPISOA(I,J,L) + &
( Spc(id_OPOA1)%Conc(I,J,L) &
+ Spc(id_OPOA2)%Conc(I,J,L) ) &
* State_chm%AerMass%OCFOPOA(I,J) / AIRVOL(I,J,L)
ENDIF
State_Chm%AerMass%OCPISOA(I,J,L) = State_Chm%AerMass%TSOA(I,J,L) + &
State_Chm%AerMass%ASOA(I,J,L)

IF ( IS_OCPI ) THEN ! hotp 7/28/10
State_Chm%AerMass%OCPISOA(I,J,L) = State_Chm%AerMass%OCPISOA(I,J,L) + Spc(id_OCPI)%Conc(I,J,L) &
* State_chm%AerMass%OCFOPOA(I,J) / AIRVOL(I,J,L)
State_Chm%AerMass%OCPISOA(I,J,L) = State_Chm%AerMass%OCPISOA(I,J,L) + &
State_Chm%AerMass%OCPI(I,J,L)
ENDIF

ENDIF
IF ( IS_OPOA ) THEN ! hotp 7/28/10
State_Chm%AerMass%OCPISOA(I,J,L) = State_Chm%AerMass%OCPISOA(I,J,L) + &
State_Chm%AerMass%OPOA(I,J,L)
ENDIF

! Add mechanistic isoprene OA (eam, 08/2015)
! Skip adding this for Simple SOA (jaf, clh, bmy, 5/17/18)
IF ( Is_ComplexSOA ) THEN
! Add mechanistic isoprene OA (eam, 08/2015)
! Skip adding this for Simple SOA (jaf, clh, bmy, 5/17/18)
! benchmark OCPISOA follows simpleSOA and
! should exculde ISOAAQ to avoid double-counting
! (yuanjianz, 8 Jun 2024)
State_Chm%AerMass%OCPISOA(I,J,L) = State_Chm%AerMass%OCPISOA(I,J,L) + State_Chm%AerMass%ISOAAQ(I,J,L)

ENDIF

! Now avoid division by zero (bmy, 4/20/04)
Expand Down Expand Up @@ -825,20 +817,18 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, &
State_Chm%AerMass%BCPI(I,J,L) + &
State_Chm%AerMass%BCPO(I,J,L) + &
State_Chm%AerMass%OCPO(I,J,L) + &
State_Chm%AerMass%OCPI(I,J,L) * ORG_GROWTH + &
State_Chm%AerMass%SALA(I,J,L) * SSA_GROWTH + &
SOILDUST(I,J,L,1) + &
SOILDUST(I,J,L,2) + &
SOILDUST(I,J,L,3) + &
SOILDUST(I,J,L,4) + &
SOILDUST(I,J,L,5) * 0.3_fp ! + 30% of DST2

! Particulate matter < 10um [kg/m3]
State_Chm%AerMass%PM10(I,J,L) = State_Chm%AerMass%PM25(I,J,L) + & ! PM2.5
SOILDUST(I,J,L,5) * 0.7_fp + & ! + 70% of DST2
SOILDUST(I,J,L,6) + & ! + 100% of DST3
SOILDUST(I,J,L,7) * 0.9_fp + & ! + 90% of DST4
State_Chm%AerMass%SALC(I,J,L) * SSA_GROWTH
! OCPI is not present in SVPOA simulation
! OCPO represents all POA intead (factor*POA)
IF ( Is_OCPI ) THEN
State_Chm%AerMass%PM25(I,J,L) = State_Chm%AerMass%PM25(I,J,L) + &
State_Chm%AerMass%OCPI(I,J,L) * ORG_GROWTH
ENDIF

! Include either simple SOA (default) or Complex SOA in
! PM2.5 calculation. In simulations where both Simple SOA and
Expand All @@ -847,27 +837,27 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, &
! to avoid double-counting. (bmy, 03 Nov 2021)
IF ( Is_SimpleSOA ) THEN
State_Chm%AerMass%PM25(I,J,L) = State_Chm%AerMass%PM25(I,J,L) + ( State_Chm%AerMass%SOAS(I,J,L) * ORG_GROWTH )
State_Chm%AerMass%PM10(I,J,L) = State_Chm%AerMass%PM10(I,J,L) + ( State_Chm%AerMass%SOAS(I,J,L) * ORG_GROWTH )

ELSE IF ( Is_ComplexSOA ) THEN
State_Chm%AerMass%PM25(I,J,L) = State_Chm%AerMass%PM25(I,J,L) + &
State_Chm%AerMass%TSOA(I,J,L) * ORG_GROWTH + &
State_Chm%AerMass%ASOA(I,J,L) * ORG_GROWTH + &
State_Chm%AerMass%ISOAAQ(I,J,L) * ORG_GROWTH ! Includes SOAGX

State_Chm%AerMass%PM10(I,J,L) = State_Chm%AerMass%PM10(I,J,L) + &
State_Chm%AerMass%TSOA(I,J,L) * ORG_GROWTH + &
State_Chm%AerMass%ASOA(I,J,L) * ORG_GROWTH + &
State_Chm%AerMass%ISOAAQ(I,J,L) * ORG_GROWTH ! Includes SOAGX

! Need to add OPOA to PM2.5 for complexSOA_SVPOA simulations
! -- Maggie Marvin (15 Jul 2020)
IF ( Is_OPOA ) THEN
State_Chm%AerMass%PM25(I,J,L) = State_Chm%AerMass%PM25(I,J,L) + ( State_Chm%AerMass%OPOA(I,J,L) * ORG_GROWTH )
State_Chm%AerMass%PM10(I,J,L) = State_Chm%AerMass%PM10(I,J,L) + ( State_Chm%AerMass%OPOA(I,J,L) * ORG_GROWTH )
ENDIF
ENDIF

! Particulate matter < 10um [kg/m3]
State_Chm%AerMass%PM10(I,J,L) = State_Chm%AerMass%PM25(I,J,L) + & ! PM2.5
SOILDUST(I,J,L,5) * 0.7_fp + & ! + 70% of DST2
SOILDUST(I,J,L,6) + & ! + 100% of DST3
SOILDUST(I,J,L,7) * 0.9_fp + & ! + 90% of DST4
State_Chm%AerMass%SALC(I,J,L) * SSA_GROWTH

! Apply STP correction factor based on ideal gas law
State_Chm%AerMass%PM25(I,J,L) = State_Chm%AerMass%PM25(I,J,L) * ( 1013.25_fp / PMID(I,J,L) ) * &
( T(I,J,L) / 298.0_fp )
Expand All @@ -881,19 +871,16 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, &
! Parameterized dry effective radius for SNA and OM
!===========================================================
IF ( State_Chm%AerMass%SO4_NH4_NIT(I,J,L) > 0e+0_fp ) THEN
IF ( Is_SimpleSOA ) THEN
! dry SNA and OM mass, in unit of ug/m3
State_Chm%AerMass%SNAOM(I,J,L) = ( State_Chm%AerMass%SO4_NH4_NIT(I,J,L) + State_Chm%AerMass%OCPO(I,J,L) + State_Chm%AerMass%OCPI(I,J,L) + State_Chm%AerMass%SOAS(I,J,L) )*1.0e+9_fp
! ratio between OM and SNA, unitless
State_Chm%AerMass%R_OMSNA(I,J,L) = (State_Chm%AerMass%OCPO(I,J,L) + State_Chm%AerMass%OCPI(I,J,L) + State_Chm%AerMass%SOAS(I,J,L)) / State_Chm%AerMass%SO4_NH4_NIT(I,J,L)

ELSE IF ( Is_ComplexSOA ) THEN
! dry SNA and OM mass, in unit of ug/m3
State_Chm%AerMass%SNAOM(I,J,L) = ( State_Chm%AerMass%SO4_NH4_NIT(I,J,L) + State_Chm%AerMass%OCPO(I,J,L) + State_Chm%AerMass%OCPI(I,J,L) + State_Chm%AerMass%TSOA(I,J,L) + State_Chm%AerMass%ASOA(I,J,L) + State_Chm%AerMass%ISOAAQ(I,J,L) ) * 1.0e+9_fp
! ratio between OM and SNA, unitless
State_Chm%AerMass%R_OMSNA(I,J,L) = (State_Chm%AerMass%OCPO(I,J,L) + State_Chm%AerMass%OCPI(I,J,L) + State_Chm%AerMass%TSOA(I,J,L) + State_Chm%AerMass%ASOA(I,J,L) + State_Chm%AerMass%ISOAAQ(I,J,L) )/ State_Chm%AerMass%SO4_NH4_NIT(I,J,L)

ENDIF
! dry SNA and OM mass, in unit of ug/m3
State_Chm%AerMass%SNAOM(I,J,L) = ( State_Chm%AerMass%SO4_NH4_NIT(I,J,L) + &
State_Chm%AerMass%OCPO(I,J,L) + &
State_Chm%AerMass%OCPISOA(I,J,L) ) * 1.0e+9_fp

! ratio between OM and SNA, unitless
State_Chm%AerMass%R_OMSNA(I,J,L) = ( State_Chm%AerMass%OCPO(I,J,L) + &
State_Chm%AerMass%OCPISOA(I,J,L) ) / &
State_Chm%AerMass%SO4_NH4_NIT(I,J,L)

! Parameterized dry effective radius, in unit of um
State_Chm%AerMass%PDER(I,J,L) = (exp( 4.36_fp + 0.20_fp*log(State_Chm%AerMass%SNAOM(I,J,L)) + 0.065_fp*log(State_Chm%AerMass%R_OMSNA(I,J,L)) ) *0.001_fp )/0.9_fp ;

Expand Down
47 changes: 31 additions & 16 deletions GeosCore/diagnostics_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,8 @@ SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, &
!
! !USES:
!
USE Aerosol_Mod, ONLY : IS_POA, IS_OPOA
USE Aerosol_Mod, ONLY : Is_POA, Is_OPOA, Is_OCPO, Is_OCPI
USE Aerosol_Mod, ONLY : Is_ComplexSOA, Is_SimpleSOA
USE ErrCode_Mod
USE Input_Opt_Mod, ONLY : OptInput
USE Species_Mod, ONLY : Species, SpcConc
Expand Down Expand Up @@ -2087,7 +2088,7 @@ SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, &
IF ( State_Diag%Archive_AerMassPOA ) THEN
IF ( Is_POA ) THEN
State_Diag%AerMassPOA(I,J,L) = OCPO(I,J,L) * kgm3_to_ugm3
ELSE
ELSEIF ( Is_OCPO ) THEN
State_Diag%AerMassPOA(I,J,L) = ( OCPI(I,J,L) + OCPO(I,J,L) ) * &
kgm3_to_ugm3
ENDIF
Expand Down Expand Up @@ -2158,12 +2159,13 @@ SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, &
! PDER [nm]
!--------------------------------------
IF ( State_Diag%Archive_PDER ) THEN
State_Diag%PDER(I,J,L) = PDER(I,J,L)
State_Diag%PDER(I,J,L) = PDER(I,J,L)
ENDIF

!--------------------------------------
! Sum of all biogenic organic aerosol
!--------------------------------------
! ComplexSOA only
IF ( State_Diag%Archive_TotalBiogenicOA ) THEN
State_Diag%TotalBiogenicOA(I,J,L) = ( TSOA(I,J,L) + ISOAAQ(I,J,L) ) &
* kgm3_to_ugm3
Expand All @@ -2172,34 +2174,47 @@ SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, &
!--------------------------------------
! Sum of all organic aerosol [ug/m3]
!--------------------------------------
! Now TotalOA also works for simpleSOA
IF ( State_Diag%Archive_TotalOA ) THEN
State_Diag%TotalOA(I,J,L) = ( TSOA(I,J,L) + &
ASOA(I,J,L) + &
OCPO(I,J,L) + &
OCPI(I,J,L) + &
OPOA(I,J,L) + &
ISOAAQ(I,J,L) ) * kgm3_to_ugm3
State_Diag%TotalOA(I,J,L) = ( OCPO(I,J,L) + &
OCPISOA(I,J,L) ) * kgm3_to_ugm3
ENDIF

!--------------------------------------
! Sum of all organic carbon [ug/m3]
!--------------------------------------
! ComplexSOA only
! since OM/OC ratio is not available for SOAS
! consistent with aerosol_mod.F90
IF ( State_Diag%Archive_TotalOC ) THEN

! Hydrophobic OC
IF ( Is_POA ) THEN
State_Diag%TotalOC(I,J,L) = &
( ( TSOA(I,J,L) + ASOA(I,J,L) &
+ OCPI(I,J,L) + OPOA(I,J,L) ) / OCFOPOA(I,J) &
( ( TSOA(I,J,L) + ASOA(I,J,L) ) / OCFOPOA(I,J) &
+ OCPO(I,J,L) / OCFPOA(I,J) ) * kgm3_to_ugm3

ELSE IF ( Is_OPOA ) THEN
ELSE IF ( Is_OCPO ) THEN
State_Diag%TotalOC(I,J,L) = &
( ( TSOA(I,J,L) + ASOA(I,J,L) &
+ OCPO(I,J,L) + OCPI(I,J,L) + OPOA(I,J,L) ) &
/ OCFOPOA(I,J) ) * kgm3_to_ugm3
+ OCPO(I,J,L) ) / OCFOPOA(I,J) ) * kgm3_to_ugm3
ENDIF

! Hydrophilic OC
IF (Is_OCPI) THEN
State_Diag%TotalOC(I,J,L) = State_Diag%TotalOC(I,J,L) + &
( OCPI(I,J,L) / OCFOPOA(I,J) * &
kgm3_to_ugm3 )
ENDIF

! OPOA OC
IF (Is_OPOA) THEN
State_Diag%TotalOC(I,J,L) = State_Diag%TotalOC(I,J,L) + &
( OPOA(I,J,L) / OCFOPOA(I,J) * &
kgm3_to_ugm3 )
ENDIF

IF ( Input_Opt%LSOA ) THEN
! Isoprene SOA OC
IF ( Is_ComplexSOA ) THEN
State_Diag%TotalOC(I,J,L) = State_Diag%TotalOC(I,J,L) + &
( ( Spc(id_SOAIE )%Conc(I,J,L) * Fac_SOAIE ) + &
( Spc(id_INDIOL)%Conc(I,J,L) * Fac_INDIOL ) + &
Expand Down