From 81912e0a640470034d55315585bcefd3c98994d2 Mon Sep 17 00:00:00 2001 From: "yuanjian.z" Date: Sat, 8 Jun 2024 02:02:24 -0500 Subject: [PATCH 1/4] Simplified and removed unnecessary codes - use AerMass in OCPISOA to avoid unnecessary recalculation - removed unnecessary OCPI reference when SVPOA is activated --- GeosCore/aerosol_mod.F90 | 45 ++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/GeosCore/aerosol_mod.F90 b/GeosCore/aerosol_mod.F90 index b8dc32b59..f909567ae 100644 --- a/GeosCore/aerosol_mod.F90 +++ b/GeosCore/aerosol_mod.F90 @@ -763,39 +763,29 @@ 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) + ! Moved here (yzhang, 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) @@ -825,13 +815,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 + ! 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 ! Particulate matter < 10um [kg/m3] State_Chm%AerMass%PM10(I,J,L) = State_Chm%AerMass%PM25(I,J,L) + & ! PM2.5 From f79c9463daa1883a7eb26b26ddff55d286ee866c Mon Sep 17 00:00:00 2001 From: "yuanjian.z" Date: Sat, 8 Jun 2024 02:15:09 -0500 Subject: [PATCH 2/4] Supported SVPOA in SNAOM parameterized effective radius - replace verbose representation of SOA and OCPI with OCPISOA --- GeosCore/aerosol_mod.F90 | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/GeosCore/aerosol_mod.F90 b/GeosCore/aerosol_mod.F90 index f909567ae..d4d6d27ee 100644 --- a/GeosCore/aerosol_mod.F90 +++ b/GeosCore/aerosol_mod.F90 @@ -876,19 +876,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 ; From 2592c6d285de8f9bbb15f47307b8d1acdfa5aad6 Mon Sep 17 00:00:00 2001 From: "yuanjian.z" Date: Tue, 11 Jun 2024 23:49:54 -0500 Subject: [PATCH 3/4] Fixed bug only including Isoprene SOA OC for TotalOC in complexSOA_nonSVPOA - also includes some rewrites for better readability --- GeosCore/aerosol_mod.F90 | 25 ++++++++----------- GeosCore/diagnostics_mod.F90 | 47 ++++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/GeosCore/aerosol_mod.F90 b/GeosCore/aerosol_mod.F90 index d4d6d27ee..e8a554a5d 100644 --- a/GeosCore/aerosol_mod.F90 +++ b/GeosCore/aerosol_mod.F90 @@ -783,7 +783,9 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! Add mechanistic isoprene OA (eam, 08/2015) ! Skip adding this for Simple SOA (jaf, clh, bmy, 5/17/18) - ! Moved here (yzhang, 8 Jun 2024) + ! 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 @@ -828,13 +830,6 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & State_Chm%AerMass%OCPI(I,J,L) * ORG_GROWTH 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 - ! Include either simple SOA (default) or Complex SOA in ! PM2.5 calculation. In simulations where both Simple SOA and ! Complex SOA species are carried (i.e. "benchmark"), then @@ -842,7 +837,6 @@ 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) + & @@ -850,19 +844,20 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & 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 ) diff --git a/GeosCore/diagnostics_mod.F90 b/GeosCore/diagnostics_mod.F90 index 6ea561f4b..40c1c9e12 100644 --- a/GeosCore/diagnostics_mod.F90 +++ b/GeosCore/diagnostics_mod.F90 @@ -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 @@ -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 @@ -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 @@ -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 ) + & From 006d012540076a38788ab9612558ef2c513e351c Mon Sep 17 00:00:00 2001 From: "yuanjian.z" Date: Sun, 14 Jul 2024 17:50:37 -0500 Subject: [PATCH 4/4] Updated CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b1b11d39..0df7c50a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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