From 0d55e42870b48280b4522e05757905e10ac4633a Mon Sep 17 00:00:00 2001 From: Lizzie Lundgren Date: Thu, 26 Oct 2023 17:30:06 -0400 Subject: [PATCH 1/6] Move all aerosol_mod gridded module arrays to new derived type in State_Chm Updates include: - New file aermass_container_mod.F90 to hold gridded arrays previously in aerosol_mod.F90, e.g. OCFPOA, BCPO, and other aerosol mass arrays computed in Aerosol_Conc - New derived type AerMassContainer defined in the new file - State_Chm%AerMass to point to the AerMassContainer object - Code updates to access the aerosol mass arrays via the State_Chm pointer, e.g. State_Chm%AerMass%OCFPOA - Removal of aerosol_mod.F90 subroutine Cleanup_Aerosol - Moved diagnostic submodule Set_AerMass_Diagnostic in aerosol_mod.F90 to be stored instead in diagnostics_mod.F90 - Remove the Transport library from GeosCore/CMakeLists.txt A note on the last update, to remove the Transport library from GeosCore: This code was put in years ago with the intention of making it easier to include GEOS-Chem in external models without GEOS-Chem Classic transport. However, the files in the library are built before GeosCore and include diagnostics_mod.F90. Excluding this built library in models would prevent using GEOS-Chem diagnostics. It also prevents using non-transport GeosCore modules within diagnostics_mod.F90, a problem that came up during this aerosols update. In practice we do not need this separately built library when porting GEOS-Chem to other models. There are simpler ways of not building the transport files for all cases thus far. Signed-off-by: Lizzie Lundgren --- GeosCore/CMakeLists.txt | 30 +- GeosCore/aerosol_mod.F90 | 1083 ++++++---------------------- GeosCore/carbon_mod.F90 | 31 +- GeosCore/cleanup.F90 | 2 - GeosCore/diagnostics_mod.F90 | 495 +++++++++++++ GeosCore/oasave.F90 | 15 +- Headers/CMakeLists.txt | 1 + Headers/aermass_container_mod.F90 | 482 +++++++++++++ Headers/state_chm_mod.F90 | 54 +- Interfaces/GCClassic/main.F90 | 1 - Interfaces/GCHP/gchp_chunk_mod.F90 | 2 +- 11 files changed, 1254 insertions(+), 942 deletions(-) create mode 100644 Headers/aermass_container_mod.F90 diff --git a/GeosCore/CMakeLists.txt b/GeosCore/CMakeLists.txt index 739b54b10..bec3dd154 100755 --- a/GeosCore/CMakeLists.txt +++ b/GeosCore/CMakeLists.txt @@ -1,26 +1,5 @@ # GeosCore/CMakeLists.txt -#----------------------------------------------------------------------------- -# Define libTransport.a -#----------------------------------------------------------------------------- -add_library(Transport - STATIC EXCLUDE_FROM_ALL - diag_mod.F90 - calc_met_mod.F90 - diagnostics_mod.F90 - pjc_pfix_mod.F90 - tpcore_fvdas_mod.F90 - tpcore_window_mod.F90 - pjc_pfix_window_mod.F90 - transport_mod.F90 -) - -# Dependencies -target_link_libraries(Transport - PUBLIC - GeosUtil -) - # Add a compilation flag to force REAL to REAL*8 if necessary # only for file tpcore_window_mod.F90 if(${USE_REAL8}) @@ -41,6 +20,7 @@ add_library(GeosCore aero_drydep.F90 aerosol_mod.F90 airs_ch4_mod.F90 + calc_met_mod.F90 carbon_mod.F90 carbon_gases_mod.F90 chemistry_mod.F90 @@ -49,6 +29,8 @@ add_library(GeosCore co2_mod.F90 convection_mod.F90 depo_mercury_mod.F90 + diag_mod.F90 + diagnostics_mod.F90 diag3.F90 drydep_mod.F90 dust_mod.F90 @@ -82,6 +64,8 @@ add_library(GeosCore olson_landmap_mod.F90 pbl_mix_mod.F90 photolysis_mod.F90 + pjc_pfix_mod.F90 + pjc_pfix_window_mod.F90 planeflight_mod.F90 pops_mod.F90 RnPbBe_mod.F90 @@ -94,7 +78,10 @@ add_library(GeosCore tagged_o3_mod.F90 tccon_ch4_mod.F90 toms_mod.F90 + tpcore_fvdas_mod.F90 + tpcore_window_mod.F90 tracer_mod.F90 + transport_mod.F90 ucx_mod.F90 uvalbedo_mod.F90 vdiff_mod.F90 @@ -119,7 +106,6 @@ endif() # Define dependencies for libGeosCore.a target_link_libraries(GeosCore PUBLIC - Transport ObsPack History Isorropia diff --git a/GeosCore/aerosol_mod.F90 b/GeosCore/aerosol_mod.F90 index 9ec5776cf..ca498eddc 100644 --- a/GeosCore/aerosol_mod.F90 +++ b/GeosCore/aerosol_mod.F90 @@ -24,72 +24,34 @@ MODULE AEROSOL_MOD ! ! !PUBLIC MEMBER FUNCTIONS: ! - PUBLIC :: AEROSOL_CONC - PUBLIC :: CLEANUP_AEROSOL PUBLIC :: INIT_AEROSOL + PUBLIC :: AEROSOL_CONC PUBLIC :: RDAER - PUBLIC :: Set_AerMass_Diagnostic ! ! !PUBLIC DATA MEMBERS: ! - !======================================================================== - ! BCPI : Hydrophilic black carbon aerosol [kg/m3] - ! BCPO : Hydrophobic black carbon aerosol [kg/m3] - ! OCPI : Hydrophilic organic carbon aerosol [kg/m3] - ! OCPO : Hydrophobic organic carbon aerosol [kg/m3] - ! OCPISOA : Hydrophilic OC + SOA aerosol [kg/m3] - ! SALA : Accumulation mode seasalt aerosol [kg/m3] - ! ACL : Accumulation mode Cl aerosol [kg/m3] - ! SALC : Coarse mode seasalt aerosol [kg/m3] - ! SO4_NH4_NIT : Lumped SO4-NH4-NIT aerosol [kg/m3] - ! SO4 : Sulfate aerosol [kg/m3] - ! HMS : Hydroxymethane sulfonate aerosol [kg/m3] ! (jmm, 06/29/18) - ! NH4 : Ammonium aerosol [kg/m3] - ! NIT : Inorganic nitrate aerosol [kg/m3] - ! SLA : Stratospheric liquid aerosol [kg/m3] - ! SPA : Stratospheric particulate aerosol [kg/m3] - ! TSOA : Terpene SOA [kg/m3] - ! ASOA : Aromatic + IVOC SOA [kg/m3] - ! OPOA : Aerosol product of SVOC oxidation [kg/m3] - ! SOAGX : SOA product of GLYX [kg/m3] - ! SOAIE : SOA product of IEPOX & HMML [kg/m3] - ! PM25 : Particulate matter < 2.5 um [kg/m3] - ! ISOAAQ : Isoprene SOA (aqueous formation) [kg/m3] - ! SOAS : Simple SOA [kg/m3] - ! OCFPOA : OM/OC for POA [unitless] - ! OCFOPOA : OM/OC for OPOA, OCPI, OCPO [unitless] - !======================================================================== - REAL(fp), ALLOCATABLE, PUBLIC :: BCPI(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: BCPO(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: OCPI(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: OCPO(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: OCPISOA(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: SALA(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: ACL(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: SALC(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: SO4_NH4_NIT(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: SO4(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: HMS(:,:,:) ! (jmm, 06/29/18) - REAL(fp), ALLOCATABLE, PUBLIC :: NH4(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: NIT(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: FRAC_SNA(:,:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: SLA(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: SPA(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: TSOA(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: ASOA(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: OPOA(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: SOAGX(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: PM25(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: PM10(:,:,:)!zhaisx - REAL(fp), ALLOCATABLE, PUBLIC :: ISOAAQ(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: SOAS(:,:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: OCFPOA(:,:) - REAL(fp), ALLOCATABLE, PUBLIC :: OCFOPOA(:,:) - ! Growth factors - REAL(fp), PUBLIC :: SIA_GROWTH - REAL(fp), PUBLIC :: ORG_GROWTH - REAL(fp), PUBLIC :: SSA_GROWTH + REAL(fp), PUBLIC :: SIA_GROWTH + REAL(fp), PUBLIC :: ORG_GROWTH + REAL(fp), PUBLIC :: SSA_GROWTH + + ! Logical flags + LOGICAL, PUBLIC :: IS_OCPI + LOGICAL, PUBLIC :: IS_OCPO + LOGICAL, PUBLIC :: IS_BC + LOGICAL, PUBLIC :: IS_SO4 + LOGICAL, PUBLIC :: IS_HMS + LOGICAL, PUBLIC :: IS_NH4 + LOGICAL, PUBLIC :: IS_NIT + LOGICAL, PUBLIC :: IS_DST + LOGICAL, PUBLIC :: IS_SAL + LOGICAL, PUBLIC :: IS_POA + LOGICAL, PUBLIC :: IS_OPOA + LOGICAL, PUBLIC :: IS_TSOA + LOGICAL, PUBLIC :: IS_ASOA + LOGICAL, PUBLIC :: IS_SOAGX + LOGICAL, PUBLIC :: IS_SimpleSOA + LOGICAL, PUBLIC :: IS_ComplexSOA ! ! !DEFINED PARAMETERS: ! @@ -117,12 +79,6 @@ MODULE AEROSOL_MOD ! ! !PRIVATE TYPES: ! - ! Mass of hydrophobic aerosol from Mian Chin - REAL(fp), ALLOCATABLE, SAVE :: DAERSL(:,:,:,:) - - ! Mass of hydrophilic aerosol from Mian Chin - REAL(fp), ALLOCATABLE, SAVE :: WAERSL(:,:,:,:) - ! Add tracer ID flags as module variables (bmy, 6/16/16) INTEGER :: id_BCPI, id_BCPO, id_DST1, id_DST2 INTEGER :: id_DST3, id_DST4, id_NH4, id_NIT @@ -140,17 +96,7 @@ MODULE AEROSOL_MOD ! a new hygroscopic species) requires manual update of this mapping ! (ewl, 1/23/17) INTEGER :: Map_NRHAER(5) - - ! Diagnostic switches - LOGICAL :: Is_POA - LOGICAL :: Is_OPOA - - ! Conversionf factors to ugC/m3 for Total Organic Carbon diagnostic - REAL(fp) :: Fac_INDIOL - REAL(fp) :: Fac_LVOCOA - REAL(fp) :: Fac_SOAGX - REAL(fp) :: Fac_SOAIE - + CONTAINS !EOC !------------------------------------------------------------------------------ @@ -232,14 +178,6 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & LOGICAL :: LDUST LOGICAL :: LSSALT LOGICAL :: LSULF - LOGICAL :: IS_OCPO, IS_OCPI, IS_BC - LOGICAL :: IS_SO4, IS_NH4, IS_NIT - LOGICAL :: IS_SAL, IS_DST, IS_HMS ! (jmm, 06/29/18) - LOGICAL :: IS_TSOA, IS_ASOA - LOGICAL :: IS_POA, IS_OPOA - LOGICAL :: IS_SOAGX - LOGICAL :: Is_SimpleSOA - LOGICAL :: Is_ComplexSOA ! Pointers TYPE(SpcConc), POINTER :: Spc(:) @@ -278,28 +216,6 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & LSSALT = Input_Opt%LSSALT LSULF = Input_Opt%LSULF - ! Define logical flags - IS_OCPI = ( id_OCPI > 0 ) - IS_OCPO = ( id_OCPO > 0 ) - IS_BC = ( id_BCPI > 0 .AND. id_BCPO > 0 ) - IS_SO4 = ( id_SO4 > 0 ) - IS_HMS = ( id_HMS > 0 ) !(jmm, 06/29/18) - IS_NH4 = ( id_NH4 > 0 ) - IS_NIT = ( id_NIT > 0 ) - IS_DST = ( id_DST1 > 0 .AND. id_DST2 > 0 ) - IS_SAL = ( id_SALA > 0 .AND. id_SALC > 0 ) - IS_TSOA = ( id_TSOA1 > 0 .AND. id_TSOA2 > 0 .AND. & - id_TSOA3 > 0 .AND. id_TSOA0 > 0 ) - IS_ASOA = ( id_ASOAN > 0 .AND. id_ASOA1 > 0 .AND. & - id_ASOA2 > 0 .AND. id_ASOA3 > 0 ) - IS_POA = ( id_POA1 > 0 .AND. id_POA2 > 0 ) - IS_OPOA = ( id_OPOA1 > 0 .AND. id_OPOA2 > 0 ) - IS_SOAGX = ( id_SOAGX > 0 ) - - ! Logical flags for SOA scheme - Is_SimpleSOA = ( id_SOAS > 0 ) - Is_ComplexSOA = Input_Opt%LSOA - ! Set pointers REAA => State_Chm%Phot%REAA @@ -359,20 +275,20 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! Set OM/OC using spatially and seasonally varying data from ! Philip et al. (2014) - OCFPOA(:,:) = State_Chm%OMOC(:,:) ! OM/OC for POA - OCFOPOA(:,:) = State_Chm%OMOC(:,:) ! OM/OC for OPOA, OCPI, and OCPO + State_Chm%AerMass%OCFPOA(:,:) = State_Chm%OMOC(:,:) ! OM/OC for POA + State_chm%AerMass%OCFOPOA(:,:) = State_Chm%OMOC(:,:) ! OM/OC for OPOA, OCPI, and OCPO ELSE ! Use default global mean OM/OC recommended by the Aerosols WG - OCFPOA(:,:) = 1.4e+0_fp ! OM/OC for POA - OCFOPOA(:,:) = 2.1e+0_fp ! OM/OC for OPOA, OCPI, and OCPO + State_Chm%AerMass%OCFPOA(:,:) = 1.4e+0_fp ! OM/OC for POA + State_chm%AerMass%OCFOPOA(:,:) = 2.1e+0_fp ! OM/OC for OPOA, OCPI, and OCPO ENDIF ! Save OM/OC - State_Chm%OMOC_POA(:,:) = OCFPOA(:,:) - State_Chm%OMOC_OPOA(:,:) = OCFOPOA(:,:) + State_Chm%OMOC_POA(:,:) = State_Chm%AerMass%OCFPOA(:,:) + State_Chm%OMOC_OPOA(:,:) = State_chm%AerMass%OCFOPOA(:,:) !================================================================= ! Compute growth factors at 35% RH @@ -481,75 +397,75 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & IF ( IS_HMS ) THEN !%%%%% Fullchem simulations: add contribution from HMS - SO4_NH4_NIT(I,J,L) = ( Spc(id_SO4)%Conc(I,J,L) & + State_Chm%AerMass%SO4_NH4_NIT(I,J,L) = ( Spc(id_SO4)%Conc(I,J,L) & + Spc(id_HMS)%Conc(I,J,L) & + Spc(id_NH4)%Conc(I,J,L) & + Spc(id_NIT)%Conc(I,J,L) ) & / AIRVOL(I,J,L) - HMS(I,J,L) = Spc(id_HMS)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%HMS(I,J,L) = Spc(id_HMS)%Conc(I,J,L) / AIRVOL(I,J,L) ELSE !%%%%% Aerosol-only simulations: Skip contribution from HMS - SO4_NH4_NIT(I,J,L) = ( Spc(id_SO4)%Conc(I,J,L) & + State_Chm%AerMass%SO4_NH4_NIT(I,J,L) = ( Spc(id_SO4)%Conc(I,J,L) & + Spc(id_NH4)%Conc(I,J,L) & + Spc(id_NIT)%Conc(I,J,L) ) & / AIRVOL(I,J,L) - HMS(I,J,L) = 0.0_fp + State_Chm%AerMass%HMS(I,J,L) = 0.0_fp ENDIF - SO4(I,J,L) = Spc(id_SO4)%Conc(I,J,L) / AIRVOL(I,J,L) - NH4(I,J,L) = Spc(id_NH4)%Conc(I,J,L) / AIRVOL(I,J,L) - NIT(I,J,L) = Spc(id_NIT)%Conc(I,J,L) / AIRVOL(I,J,L) - SLA(I,J,L) = 0.0_fp - SPA(I,J,L) = 0.0_fp + State_Chm%AerMass%SO4(I,J,L) = Spc(id_SO4)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%NH4(I,J,L) = Spc(id_NH4)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%NIT(I,J,L) = Spc(id_NIT)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%SLA(I,J,L) = 0.0_fp + State_Chm%AerMass%SPA(I,J,L) = 0.0_fp ELSE ! Tropospheric sulfate is zero in stratosphere - SO4_NH4_NIT(I,J,L) = 0.0_fp - SO4(I,J,L) = 0.0_fp - HMS(I,J,L) = 0.0_fp ! (jmm, 06/30/18) - NH4(I,J,L) = 0.0_fp - NIT(I,J,L) = 0.0_fp - SLA(I,J,L) = KG_STRAT_AER(I,J,L,1) / AIRVOL(I,J,L) - SPA(I,J,L) = KG_STRAT_AER(I,J,L,2) / AIRVOL(I,J,L) + State_Chm%AerMass%SO4_NH4_NIT(I,J,L) = 0.0_fp + State_Chm%AerMass%SO4(I,J,L) = 0.0_fp + State_Chm%AerMass%HMS(I,J,L) = 0.0_fp ! (jmm, 06/30/18) + State_Chm%AerMass%NH4(I,J,L) = 0.0_fp + State_Chm%AerMass%NIT(I,J,L) = 0.0_fp + State_Chm%AerMass%SLA(I,J,L) = KG_STRAT_AER(I,J,L,1) / AIRVOL(I,J,L) + State_Chm%AerMass%SPA(I,J,L) = KG_STRAT_AER(I,J,L,2) / AIRVOL(I,J,L) ENDIF ! Add error check for safe division (bmy, 4/7/15) - IF ( SO4_NH4_NIT(I,J,L) > 0e+0_fp ) THEN + IF ( State_Chm%AerMass%SO4_NH4_NIT(I,J,L) > 0e+0_fp ) THEN ! Save these fractions for partitioning of optics ! until later when these may be treated independently ! Only use HMS if it is defined (for fullchem sims) IF ( IS_HMS ) THEN - FRAC_SNA(I,J,L,1) = ( ( Spc(id_SO4)%Conc(I,J,L) + & + State_Chm%AerMass%FRAC_SNA(I,J,L,1) = ( ( Spc(id_SO4)%Conc(I,J,L) + & Spc(id_HMS)%Conc(I,J,L) ) & / AIRVOL(I,J,L) ) & - / SO4_NH4_NIT(I,J,L) + / State_Chm%AerMass%SO4_NH4_NIT(I,J,L) ELSE - FRAC_SNA(I,J,L,1) = ( Spc(id_SO4)%Conc(I,J,L) / AIRVOL(I,J,L) )& - / SO4_NH4_NIT(I,J,L) + State_Chm%AerMass%FRAC_SNA(I,J,L,1) = ( Spc(id_SO4)%Conc(I,J,L) / AIRVOL(I,J,L) )& + / State_Chm%AerMass%SO4_NH4_NIT(I,J,L) ENDIF - FRAC_SNA(I,J,L,2) = ( Spc(id_NIT)%Conc(I,J,L) / AIRVOL(I,J,L) ) & - / SO4_NH4_NIT(I,J,L) + State_Chm%AerMass%FRAC_SNA(I,J,L,2) = ( Spc(id_NIT)%Conc(I,J,L) / AIRVOL(I,J,L) ) & + / State_Chm%AerMass%SO4_NH4_NIT(I,J,L) - FRAC_SNA(I,J,L,3) = ( Spc(id_NH4)%Conc(I,J,L) / AIRVOL(I,J,L) ) & - / SO4_NH4_NIT(I,J,L) + State_Chm%AerMass%FRAC_SNA(I,J,L,3) = ( Spc(id_NH4)%Conc(I,J,L) / AIRVOL(I,J,L) ) & + / State_Chm%AerMass%SO4_NH4_NIT(I,J,L) ELSE ! If SO4_NH4_NIT(I,J,L) is zero, then avoid a div-by-zero ! error. Set all of these to zero because the division ! cannot be done. - FRAC_SNA(I,J,L,1) = 0e+0_fp - FRAC_SNA(I,J,L,2) = 0e+0_fp - FRAC_SNA(I,J,L,3) = 0e+0_fp + State_Chm%AerMass%FRAC_SNA(I,J,L,1) = 0e+0_fp + State_Chm%AerMass%FRAC_SNA(I,J,L,2) = 0e+0_fp + State_Chm%AerMass%FRAC_SNA(I,J,L,3) = 0e+0_fp ENDIF @@ -564,33 +480,33 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & IF ( LCARB ) THEN ! Hydrophilic BC [kg/m3] - BCPI(I,J,L) = Spc(id_BCPI)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%BCPI(I,J,L) = Spc(id_BCPI)%Conc(I,J,L) / AIRVOL(I,J,L) ! Hydrophobic BC [kg/m3] - BCPO(I,J,L) = Spc(id_BCPO)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%BCPO(I,J,L) = Spc(id_BCPO)%Conc(I,J,L) / AIRVOL(I,J,L) ! Hydrophobic OC [kg/m3] ! SOAupdate: Treat either OCPO (x2.1) or POA (x1.4) IF ( IS_POA ) THEN - OCPO(I,J,L) = ( Spc(id_POA1)%Conc(I,J,L) & + State_Chm%AerMass%OCPO(I,J,L) = ( Spc(id_POA1)%Conc(I,J,L) & + Spc(id_POA2)%Conc(I,J,L) ) & - * OCFPOA(I,J) / AIRVOL(I,J,L) + * State_Chm%AerMass%OCFPOA(I,J) / AIRVOL(I,J,L) ELSE IF ( IS_OCPO ) THEN - OCPO(I,J,L) = Spc(id_OCPO)%Conc(I,J,L) & - * OCFOPOA(I,J) / AIRVOL(I,J,L) + State_Chm%AerMass%OCPO(I,J,L) = Spc(id_OCPO)%Conc(I,J,L) & + * State_chm%AerMass%OCFOPOA(I,J) / AIRVOL(I,J,L) ENDIF ! Hydrophilic OC [kg/m3] IF ( IS_OCPI ) THEN - OCPI(I,J,L) = Spc(id_OCPI)%Conc(I,J,L) & - * OCFOPOA(I,J) / AIRVOL(I,J,L) + State_Chm%AerMass%OCPI(I,J,L) = Spc(id_OCPI)%Conc(I,J,L) & + * State_chm%AerMass%OCFOPOA(I,J) / AIRVOL(I,J,L) ENDIF ! Now avoid division by zero (bmy, 4/20/04) - BCPI(I,J,L) = MAX( BCPI(I,J,L), 1e-35_fp ) - OCPI(I,J,L) = MAX( OCPI(I,J,L), 1e-35_fp ) - BCPO(I,J,L) = MAX( BCPO(I,J,L), 1e-35_fp ) - OCPO(I,J,L) = MAX( OCPO(I,J,L), 1e-35_fp ) + State_Chm%AerMass%BCPI(I,J,L) = MAX( State_Chm%AerMass%BCPI(I,J,L), 1e-35_fp ) + State_Chm%AerMass%OCPI(I,J,L) = MAX( State_Chm%AerMass%OCPI(I,J,L), 1e-35_fp ) + State_Chm%AerMass%BCPO(I,J,L) = MAX( State_Chm%AerMass%BCPO(I,J,L), 1e-35_fp ) + State_Chm%AerMass%OCPO(I,J,L) = MAX( State_Chm%AerMass%OCPO(I,J,L), 1e-35_fp ) ENDIF ! LCARB @@ -712,19 +628,19 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & IF ( LSSALT ) THEN ! Accumulation mode seasalt aerosol [kg/m3] - SALA(I,J,L) = Spc(id_SALA)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%SALA(I,J,L) = Spc(id_SALA)%Conc(I,J,L) / AIRVOL(I,J,L) ! Coarse mode seasalt aerosol [kg/m3] - SALC(I,J,L) = Spc(id_SALC)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%SALC(I,J,L) = Spc(id_SALC)%Conc(I,J,L) / AIRVOL(I,J,L) ! Fine mode Cl-/sulfate interal mixed [kg/m3] - ACL(I,J,L) = ( Spc(id_SALACL)%Conc(I,J,L) + & + State_Chm%AerMass%ACL(I,J,L) = ( Spc(id_SALACL)%Conc(I,J,L) + & Spc(id_SALA)%Conc(I,J,L)*0.45e0_fp)/AIRVOL(I,J,L) ! Avoid division by zero - SALA(I,J,L) = MAX( SALA(I,J,L), 1e-35_fp ) - SALC(I,J,L) = MAX( SALC(I,J,L), 1e-35_fp ) - ACL(I,J,L) = MAX( ACL(I,J,L), 1e-35_fp ) + State_Chm%AerMass%SALA(I,J,L) = MAX( State_Chm%AerMass%SALA(I,J,L), 1e-35_fp ) + State_Chm%AerMass%SALC(I,J,L) = MAX( State_Chm%AerMass%SALC(I,J,L), 1e-35_fp ) + State_Chm%AerMass%ACL(I,J,L) = MAX( State_Chm%AerMass%ACL(I,J,L), 1e-35_fp ) ENDIF @@ -740,7 +656,7 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & IF ( Is_SimpleSOA ) THEN ! Simple SOA [kg/m3] - SOAS(I,J,L) = Spc(id_SOAS)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%SOAS(I,J,L) = Spc(id_SOAS)%Conc(I,J,L) / AIRVOL(I,J,L) ENDIF @@ -751,7 +667,7 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! TSOA (terpene SOA) [kg/m3] IF ( IS_TSOA ) THEN - TSOA(I,J,L) = ( Spc(id_TSOA1)%Conc(I,J,L) & + State_Chm%AerMass%TSOA(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) ) & @@ -760,7 +676,7 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! ASOA (benz, tolu, xyle, + NAP/IVOC SOA) [kg/m3] IF ( IS_ASOA ) THEN - ASOA(I,J,L) = ( Spc(id_ASOAN)%Conc(I,J,L) & + State_Chm%AerMass%ASOA(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) ) & @@ -769,9 +685,9 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! OPOA [kg/m3] IF ( IS_OPOA ) THEN - OPOA(I,J,L) = ( Spc(id_OPOA1)%Conc(I,J,L) & + State_Chm%AerMass%OPOA(I,J,L) = ( Spc(id_OPOA1)%Conc(I,J,L) & + Spc(id_OPOA2)%Conc(I,J,L) ) & - * OCFOPOA(I,J) / AIRVOL(I,J,L) + * State_chm%AerMass%OCFOPOA(I,J) / AIRVOL(I,J,L) ENDIF ENDIF @@ -781,12 +697,12 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! Glyoxal IF ( id_SOAGX > 0 ) THEN - ISOAAQ(I,J,L) = Spc(id_SOAGX)%Conc(I,J,L) / AIRVOL(I,J,L) + State_Chm%AerMass%ISOAAQ(I,J,L) = Spc(id_SOAGX)%Conc(I,J,L) / AIRVOL(I,J,L) ENDIF ! IEPOX IF ( id_SOAIE > 0 ) THEN - ISOAAQ(I,J,L) = ISOAAQ(I,J,L) & + State_Chm%AerMass%ISOAAQ(I,J,L) = State_Chm%AerMass%ISOAAQ(I,J,L) & + Spc(id_SOAIE)%Conc(I,J,L) / AIRVOL(I,J,L) ENDIF @@ -798,13 +714,13 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & !! SOA from alkyl nitrates (some contribution !! from non-isoprene sources) !IF ( id_INDIOL > 0 ) THEN - ! ISOAAQ(I,J,L) = ISOAAQ(I,J,L) + Spc(id_INDIOL)%Conc(I,J,L) / AIRVOL(I,J,L) + ! State_Chm%AerMass%ISOAAQ(I,J,L) = State_Chm%AerMass%ISOAAQ(I,J,L) + Spc(id_INDIOL)%Conc(I,J,L) / AIRVOL(I,J,L) !ENDIF !----------------------------------------------------------------------- ! SOA from ISOPOOH oxidation product IF ( id_LVOCOA > 0 ) THEN - ISOAAQ(I,J,L) = ISOAAQ(I,J,L) & + State_Chm%AerMass%ISOAAQ(I,J,L) = State_Chm%AerMass%ISOAAQ(I,J,L) & + Spc(id_LVOCOA)%Conc(I,J,L) / AIRVOL(I,J,L) ENDIF @@ -833,12 +749,12 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! Use simple SOA by default over complex SOA in calculations IF ( Is_SimpleSOA ) THEN - OCPISOA(I,J,L) = ( Spc(id_OCPI)%Conc(I,J,L) * OCFOPOA(I,J) + & + 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) ELSEIF ( Is_ComplexSOA ) THEN - OCPISOA(I,J,L) = ( Spc(id_TSOA1)%Conc(I,J,L) & + 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) & @@ -849,15 +765,15 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & / AIRVOL(I,J,L) IF ( IS_OPOA ) THEN ! hotp 7/28/10 - OCPISOA(I,J,L) = OCPISOA(I,J,L) + & + 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) ) & - * OCFOPOA(I,J) / AIRVOL(I,J,L) + * State_chm%AerMass%OCFOPOA(I,J) / AIRVOL(I,J,L) ENDIF IF ( IS_OCPI ) THEN ! hotp 7/28/10 - OCPISOA(I,J,L) = OCPISOA(I,J,L) + Spc(id_OCPI)%Conc(I,J,L) & - * OCFOPOA(I,J) / AIRVOL(I,J,L) + 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) ENDIF ENDIF @@ -865,17 +781,17 @@ 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) IF ( Is_ComplexSOA ) THEN - OCPISOA(I,J,L) = OCPISOA(I,J,L) + ISOAAQ(I,J,L) + 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) - OCPISOA(I,J,L) = MAX( OCPISOA(I,J,L), 1e-35_fp ) + State_Chm%AerMass%OCPISOA(I,J,L) = MAX( State_Chm%AerMass%OCPISOA(I,J,L), 1e-35_fp ) !=========================================================== ! SOAGX [kg/m3] !=========================================================== IF ( IS_SOAGX ) THEN - SOAGX(I,J,L) = Spc(id_SOAGX)%Conc(I,J,L) * OCFG / AIRVOL(I,J,L) + State_Chm%AerMass%SOAGX(I,J,L) = Spc(id_SOAGX)%Conc(I,J,L) * OCFG / AIRVOL(I,J,L) ENDIF !============================================================== @@ -888,15 +804,15 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & !============================================================== ! Particulate matter < 2.5um [kg/m3] - PM25(I,J,L) = NH4(I,J,L) * SIA_GROWTH + & - NIT(I,J,L) * SIA_GROWTH + & - SO4(I,J,L) * SIA_GROWTH + & - HMS(I,J,L) * SIA_GROWTH + & ! (jmm, 06/30/18) - BCPI(I,J,L) + & - BCPO(I,J,L) + & - OCPO(I,J,L) + & - OCPI(I,J,L) * ORG_GROWTH + & - SALA(I,J,L) * SSA_GROWTH + & + State_Chm%AerMass%PM25(I,J,L) = State_Chm%AerMass%NH4(I,J,L) * SIA_GROWTH + & + State_Chm%AerMass%NIT(I,J,L) * SIA_GROWTH + & + State_Chm%AerMass%SO4(I,J,L) * SIA_GROWTH + & + State_Chm%AerMass%HMS(I,J,L) * SIA_GROWTH + & ! (jmm, 06/30/18) + 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) + & @@ -904,11 +820,11 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & SOILDUST(I,J,L,5) * 0.3_fp ! + 30% of DST2 ! Particulate matter < 10um [kg/m3] - PM10(I,J,L) = PM25(I,J,L) + & ! PM2.5 + 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 - SALC(I,J,L) * SSA_GROWTH + 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 @@ -916,39 +832,39 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! only the Simple SOA will be added to PM2.5 and PM10, in order ! to avoid double-counting. (bmy, 03 Nov 2021) IF ( Is_SimpleSOA ) THEN - PM25(I,J,L) = PM25(I,J,L) + ( SOAS(I,J,L) * ORG_GROWTH ) - PM10(I,J,L) = PM10(I,J,L) + ( SOAS(I,J,L) * ORG_GROWTH ) + 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 - PM25(I,J,L) = PM25(I,J,L) + & - TSOA(I,J,L) * ORG_GROWTH + & - ASOA(I,J,L) * ORG_GROWTH + & - ISOAAQ(I,J,L) * ORG_GROWTH ! Includes SOAGX + 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 - PM10(I,J,L) = PM10(I,J,L) + & - TSOA(I,J,L) * ORG_GROWTH + & - ASOA(I,J,L) * ORG_GROWTH + & - 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 - PM25(I,J,L) = PM25(I,J,L) + ( OPOA(I,J,L) * ORG_GROWTH ) - PM10(I,J,L) = PM10(I,J,L) + ( OPOA(I,J,L) * ORG_GROWTH ) + 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 ! Apply STP correction factor based on ideal gas law - PM25(I,J,L) = PM25(I,J,L) * ( 1013.25_fp / PMID(I,J,L) ) * & + 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 ) - PM10(I,J,L) = PM10(I,J,L) * ( 1013.25_fp / PMID(I,J,L) ) * & + State_Chm%AerMass%PM10(I,J,L) = State_Chm%AerMass%PM10(I,J,L) * ( 1013.25_fp / PMID(I,J,L) ) * & ( T(I,J,L) / 298.0_fp ) #ifdef MODEL_GEOS ! PM2.5 sulfates IF ( State_Diag%Archive_PM25su ) THEN - State_Diag%PM25su(I,J,L) = ( SO4(I,J,L) * SIA_GROWTH ) & + State_Diag%PM25su(I,J,L) = ( State_Chm%AerMass%SO4(I,J,L) * SIA_GROWTH ) & * ( 1013.25_fp / PMID(I,J,L) ) & * ( T(I,J,L) / 298.0_fp ) & * 1.0e+9_fp @@ -956,8 +872,8 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! PM2.5 nitrates IF ( State_Diag%Archive_PM25ni ) THEN - State_Diag%PM25ni(I,J,L) = ( NH4(I,J,L) * SIA_GROWTH & - + NIT(I,J,L) * SIA_GROWTH ) & + State_Diag%PM25ni(I,J,L) = ( State_Chm%AerMass%NH4(I,J,L) * SIA_GROWTH & + + State_Chm%AerMass%NIT(I,J,L) * SIA_GROWTH ) & * ( 1013.25_fp / PMID(I,J,L) ) & * ( T(I,J,L) / 298.0_fp ) & * 1.0e+9_fp @@ -965,7 +881,7 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! PM2.5 BC IF ( State_Diag%Archive_PM25bc ) THEN - State_Diag%PM25bc(I,J,L) = ( BCPI(I,J,L) + BCPO(I,J,L) ) & + State_Diag%PM25bc(I,J,L) = ( State_Chm%AerMass%BCPI(I,J,L) + State_Chm%AerMass%BCPO(I,J,L) ) & * ( 1013.25_fp / PMID(I,J,L) ) & * ( T(I,J,L) / 298.0_fp ) & * 1.0e+9_fp @@ -973,8 +889,8 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! PM2.5 OC IF ( State_Diag%Archive_PM25oc ) THEN - State_Diag%PM25oc(I,J,L) = ( OCPO(I,J,L) & - + OCPI(I,J,L) * ORG_GROWTH ) & + State_Diag%PM25oc(I,J,L) = ( State_Chm%AerMass%OCPO(I,J,L) & + + State_Chm%AerMass%OCPI(I,J,L) * ORG_GROWTH ) & * ( 1013.25_fp / PMID(I,J,L) ) & * ( T(I,J,L) / 298.0_fp ) & * 1.0e+9_fp @@ -994,7 +910,7 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! PM2.5 sea salt IF ( State_Diag%Archive_PM25ss ) THEN - State_Diag%PM25ss(I,J,L) = ( SALA(I,J,L) * SSA_GROWTH ) & + State_Diag%PM25ss(I,J,L) = ( State_Chm%AerMass%SALA(I,J,L) * SSA_GROWTH ) & * ( 1013.25_fp / PMID(I,J,L) ) & * ( T(I,J,L) / 298.0_fp ) & * 1.0e+9_fp @@ -1002,10 +918,10 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! PM2.5 SOA IF ( State_Diag%Archive_PM25soa ) THEN - State_Diag%PM25soa(I,J,L) = ( TSOA(I,J,L) * ORG_GROWTH & - + ASOA(I,J,L) * ORG_GROWTH & - + SOAS(I,J,L) * ORG_GROWTH & - + ISOAAQ(I,J,L) * ORG_GROWTH ) & + State_Diag%PM25soa(I,J,L) = ( State_Chm%AerMass%TSOA(I,J,L) * ORG_GROWTH & + + State_Chm%AerMass%ASOA(I,J,L) * ORG_GROWTH & + + State_Chm%AerMass%SOAS(I,J,L) * ORG_GROWTH & + + State_Chm%AerMass%ISOAAQ(I,J,L) * ORG_GROWTH ) & * ( 1013.25_fp / PMID(I,J,L) ) & * ( T(I,J,L) / 298.0_fp ) & * 1.0e+9_fp @@ -1184,11 +1100,9 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & LOGICAL :: LCARB LOGICAL :: LSSALT LOGICAL :: LSULF - LOGICAL :: Is_ComplexSOA LOGICAL :: LSTRATOD LOGICAL :: LRAD LOGICAL :: LBCAE ! (xnw, 8/24/15) - LOGICAL :: IS_POA, IS_OCPI REAL(fp) :: GF_RH REAL(fp) :: BCAE_1, BCAE_2 @@ -1245,17 +1159,12 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & LCARB = Input_Opt%LCARB LSSALT = Input_Opt%LSSALT LSULF = Input_Opt%LSULF - Is_ComplexSOA = Input_Opt%LSOA LSTRATOD = Input_Opt%LSTRATOD LRAD = Input_Opt%LRAD LBCAE = Input_Opt%LBCAE !(xnw, 8/24/15) BCAE_1 = Input_Opt%BCAE_1 BCAE_2 = Input_Opt%BCAE_2 - ! Define logical flags - IS_OCPI = ( id_OCPI > 0 ) - IS_POA = ( id_POA1 > 0 .AND. id_POA2 > 0 ) - ! Initialize pointers IWVREQUIRED => State_Chm%Phot%IWVREQUIRED ! WL indexes for interpolation IWVSELECT => State_Chm%Phot%IWVSELECT ! Indexes of requested WLs @@ -1282,42 +1191,6 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & ACLRADIUS => State_Chm%AClRadi ! Fine Cl- Radius [cm] ACLAREA => State_Chm%AClArea ! Fine Cl- Area [cm2/cm3] - ! Initialize the mapping between hygroscopic species in the - ! species database and the species order in NRHAER - IF ( FIRST ) THEN - DO N = 1, NRHAER - - ! Get the species database index from the species database - ! mapping array for hygroscopic growth species - SpcID = State_Chm%Map_HygGrth(N) - - ! Point to the Species Database entry for species N - SpcInfo => State_Chm%SpcData(SpcID)%Info - - ! Set the mapping to the ordering of aerosol densities in RD_AOD - SELECT CASE ( TRIM(SpcInfo%Name) ) - CASE ( 'SO4' ) - Map_NRHAER(N) = 1 - CASE ( 'BCPI' ) - Map_NRHAER(N) = 2 - CASE ( 'OCPI', 'POA1' ) - Map_NRHAER(N) = 3 - CASE ( 'SALA' ) - Map_NRHAER(N) = 4 - CASE ( 'SALC' ) - Map_NRHAER(N) = 5 - CASE DEFAULT - ErrMsg = 'WARNING: aerosol diagnostics not defined' // & - ' for NRHAER greater than 5!' - CALL GC_ERROR( ErrMsg, RC, 'RDAER in aerosol_mod.F90' ) - END SELECT - - ! Free pointer - SpcInfo => NULL() - - ENDDO - ENDIF - !================================================================= ! S U L F A T E A E R O S O L S ! @@ -1346,7 +1219,7 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & DO L = 1, State_Grid%NZ DO J = 1, State_Grid%NY DO I = 1, State_Grid%NX - WAERSL(I,J,L,1) = SO4_NH4_NIT(I,J,L) + State_Chm%AerMass%WAERSL(I,J,L,1) = State_Chm%AerMass%SO4_NH4_NIT(I,J,L) ENDDO ENDDO ENDDO @@ -1386,16 +1259,16 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & DO I = 1, State_Grid%NX ! Hydrophilic BC (a.k.a EC) [kg/m3] - WAERSL(I,J,L,2) = BCPI(I,J,L) + State_Chm%AerMass%WAERSL(I,J,L,2) = State_Chm%AerMass%BCPI(I,J,L) ! Hydrophilic OC [kg/m3] - WAERSL(I,J,L,3) = OCPISOA(I,J,L) + State_Chm%AerMass%WAERSL(I,J,L,3) = State_Chm%AerMass%OCPISOA(I,J,L) ! Hydrophobic BC (a.k.a EC) [kg/m3] - DAERSL(I,J,L,1) = BCPO(I,J,L) + State_Chm%AerMass%DAERSL(I,J,L,1) = State_Chm%AerMass%BCPO(I,J,L) ! Hydrophobic OC [kg/m3] - DAERSL(I,J,L,2) = OCPO(I,J,L) + State_Chm%AerMass%DAERSL(I,J,L,2) = State_Chm%AerMass%OCPO(I,J,L) ENDDO ENDDO @@ -1439,10 +1312,10 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & DO I = 1, State_Grid%NX ! Accumulation mode seasalt aerosol [kg/m3] - WAERSL(I,J,L,4) = SALA(I,J,L) + State_Chm%AerMass%WAERSL(I,J,L,4) = State_Chm%AerMass%SALA(I,J,L) ! Coarse mode seasalt aerosol [kg/m3] - WAERSL(I,J,L,5) = SALC(I,J,L) + State_Chm%AerMass%WAERSL(I,J,L,5) = State_Chm%AerMass%SALC(I,J,L) ENDDO ENDDO @@ -1453,8 +1326,8 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & ! Transfer stratospheric aerosol data ! SDE 04/17/13 - WAERSL(:,:,:,NRHAER+1) = SLA - WAERSL(:,:,:,NRHAER+2) = SPA + State_Chm%AerMass%WAERSL(:,:,:,NRHAER+1) = State_Chm%AerMass%SLA + State_Chm%AerMass%WAERSL(:,:,:,NRHAER+2) = State_Chm%AerMass%SPA !================================================================= ! Calculate optical depth and surface area at each timestep @@ -1718,7 +1591,7 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & !calculate optics for hyrdophillic aerosol here !However MDENS in LUT was in g/cm3 not kg/m3 so x1e3 ODAER(I,J,L,IWV,N) = SCALEOD * BXHEIGHT(I,J,L) * 0.75d0 * & - WAERSL(I,J,L,N) * QQAA(IWV,1,N) / & + State_Chm%AerMass%WAERSL(I,J,L,N) * QQAA(IWV,1,N) / & ( MSDENS(N) * REAA(1,N) * 1.0D-6 ) !Include BC absorption enhancement (xnw, 8/24/15) @@ -1733,19 +1606,19 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & !now combine with hydrophilic OD as before BCSCAT_AE = BCSCAT_AE + SSAA(IWV,1,N) * & 0.75d0 * BXHEIGHT(I,J,L) * & - DAERSL(I,J,L,N-1) * QQAA(IWV,1,N) / & + State_Chm%AerMass%DAERSL(I,J,L,N-1) * QQAA(IWV,1,N) / & ( MSDENS(N) * REAA(1,N) * 1.0D-6 ) ODAER(I,J,L,IWV,N)= ODAER(I,J,L,IWV,N) + & (BCAE_2+SSAA(IWV,1,N) - SSAA(IWV,1,N)*BCAE_2) * & 0.75d0 * BXHEIGHT(I,J,L) * & - DAERSL(I,J,L,N-1) * QQAA(IWV,1,N) / & + State_Chm%AerMass%DAERSL(I,J,L,N-1) * QQAA(IWV,1,N) / & ( MSDENS(N) * REAA(1,N) * 1.0D-6 ) ELSE !now combine with hydrophilic OD as before ODAER(I,J,L,IWV,N)= ODAER(I,J,L,IWV,N) + & 0.75d0 * BXHEIGHT(I,J,L) * & - DAERSL(I,J,L,N-1) * QQAA(IWV,1,N) / & + State_Chm%AerMass%DAERSL(I,J,L,N-1) * QQAA(IWV,1,N) / & ( MSDENS(N) * REAA(1,N) * 1.0D-6 ) ENDIF @@ -1755,14 +1628,14 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & !now combine with hydrophilic OD as before ODAER(I,J,L,IWV,N)= ODAER(I,J,L,IWV,N) + & 0.75d0 * BXHEIGHT(I,J,L) * & - DAERSL(I,J,L,N-1) * QQAA(IWV,1,N) / & + State_Chm%AerMass%DAERSL(I,J,L,N-1) * QQAA(IWV,1,N) / & ( MSDENS(N) * REAA(1,N) * 1.0D-6 ) ENDIF ! Get the AOD contribution from isoprene SOA only (eam, 2014) IF ( N == 3 .and. Is_ComplexSOA ) THEN ISOPOD(I,J,L,IWV) = SCALEOD*BXHEIGHT(I,J,L)*0.75d0 & - * ISOAAQ(I,J,L) * QQAA(IWV,1,N) / & + * State_Chm%AerMass%ISOAAQ(I,J,L) * QQAA(IWV,1,N) / & ( MSDENS(N) * REAA(1,N) * 1.0D-6 ) ENDIF @@ -1796,7 +1669,7 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & IF (N.EQ.1) THEN DO IR=1,3 RTODAER(I,J,L,IWV,N+IR-1)= ODAER(I,J,L,IWV,N)* & - FRAC_SNA(I,J,L,IR) + State_Chm%AerMass%FRAC_SNA(I,J,L,IR) RTSSAER(I,J,L,IWV,N+IR-1) = SCALESSA*SSAA(IWV,1,N) RTASYMAER(I,J,L,IWV,N+IR-1) = SCALEASY*ASYMAA(IWV,1,N) ENDDO @@ -1874,7 +1747,7 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & ! Store aerosol surface areas in TAREA, and be sure ! to list them following the dust surface areas - TAREA(I,J,L,N+NDUST) = 3.D0 * WAERSL(I,J,L,N) * SCALEVOL / & + TAREA(I,J,L,N+NDUST) = 3.D0 * State_Chm%AerMass%WAERSL(I,J,L,N) * SCALEVOL / & ( ERADIUS(I,J,L,N+NDUST) * MSDENS(N) ) WTAREA(I,J,L,N+NDUST) = TAREA(I,J,L,N+NDUST) @@ -1895,7 +1768,7 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & ! AeroH2O has units g/m3 VH2O = State_Chm%AeroH2O(I,J,L,NDUST+1) / 1e6 ! Volume of dry aerosol, m3(aerosol)/m3(air) - VDry = WAERSL(I,J,L,1)/MSDENS(1) + WAERSL(I,J,L,4)/MSDENS(4) + VDry = State_Chm%AerMass%WAERSL(I,J,L,1)/MSDENS(1) + State_Chm%AerMass%WAERSL(I,J,L,4)/MSDENS(4) ! Notes on REFF derivation ! Volume of wet aerosol: VWet = VDry + VH2O [note: @@ -1924,7 +1797,7 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & ! Don't update SNA, keep ISORROPIA values IF (N.ne.1) THEN State_Chm%AeroH2O(I,J,L,N+NDUST) = 1e+6_fp * & - WAERSL(I,J,L,N) / MSDENS(N) * (ScaleVol - 1d0) + State_Chm%AerMass%WAERSL(I,J,L,N) / MSDENS(N) * (ScaleVol - 1d0) ENDIF !include hydrophobic BC and OC @@ -1934,7 +1807,7 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & ! Dry surface area ! SDE 2015-10-27: RW is in um, but everything ! else is in terms of cm. Correct with 10^-4 factor - DRYAREA = 3.D0 * DAERSL(I,J,L,N-1) / ( RW(1) * & + DRYAREA = 3.D0 * State_Chm%AerMass%DAERSL(I,J,L,N-1) / ( RW(1) * & 1.0D-4 * MSDENS(N) ) ! Add surface area to TAREA array @@ -2330,7 +2203,7 @@ END SUBROUTINE RDAER ! ! !IROUTINE: init_aerosol ! -! !DESCRIPTION: Subroutine INIT\_AEROSOL allocates and zeroes module arrays +! !DESCRIPTION: Subroutine INIT\_AEROSOL initializes module variables !\\ !\\ ! !INTERFACE: @@ -2339,9 +2212,10 @@ SUBROUTINE Init_Aerosol( Input_Opt, State_Chm, State_Diag, State_Grid, RC ) ! ! !USES: ! - USE CMN_SIZE_MOD, ONLY : NAER, NDUST + USE CMN_SIZE_MOD, ONLY : NAER, NDUST, NRHAER USE ErrCode_Mod USE Input_Opt_Mod, ONLY : OptInput + USE Species_Mod, ONLY : Species USE State_Chm_Mod, ONLY : Ind_ USE State_Chm_Mod, ONLY : ChmState USE State_Diag_Mod, ONLY : DgnState @@ -2370,9 +2244,11 @@ SUBROUTINE Init_Aerosol( Input_Opt, State_Chm, State_Diag, State_Grid, RC ) ! ! !LOCAL VARIABLES: ! - INTEGER :: AS + INTEGER :: N, SpcID CHARACTER(LEN=255) :: ErrMsg, ThisLoc + TYPE(Species), POINTER :: SpcInfo + !================================================================= ! INIT_AEROSOL begins here! !================================================================= @@ -2403,7 +2279,7 @@ SUBROUTINE Init_Aerosol( Input_Opt, State_Chm, State_Diag, State_Grid, RC ) id_SALACL = Ind_( 'SALACL' ) id_SO4 = Ind_( 'SO4' ) id_SO4s = Ind_( 'SO4s' ) - id_HMS = Ind_( 'HMS' ) ! (jmm, 06/30/18) + id_HMS = Ind_( 'HMS' ) id_NITs = Ind_( 'NITs' ) id_POA1 = Ind_( 'POA1' ) id_POA2 = Ind_( 'POA2' ) @@ -2422,607 +2298,60 @@ SUBROUTINE Init_Aerosol( Input_Opt, State_Chm, State_Diag, State_Grid, RC ) id_INDIOL = Ind_( 'INDIOL' ) id_LVOCOA = Ind_( 'LVOCOA' ) - !================================================================= - ! Allocate arrays - !================================================================= - ALLOCATE( BCPI( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - BCPI = 0.0_fp - - ALLOCATE( BCPO( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:BCPO', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - BCPO = 0.0_fp - - ALLOCATE( OCPI( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:OCPI', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - OCPI = 0.0_fp - - ALLOCATE( OCPO( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:OCPO', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - OCPO = 0.0_fp - - ALLOCATE( OCPISOA( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:OCPISOA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - OCPISOA = 0.0_fp - - ALLOCATE( SALA( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:SALA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - SALA = 0.0_fp - - ALLOCATE( SALC( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:SALC', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - SALC = 0.0_fp - - ALLOCATE( ACL( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F:ACL', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - ACL = 0.0_fp - - ALLOCATE( SO4_NH4_NIT(State_Grid%NX,State_Grid%NY,State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:SO4_NH4_NIT', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - SO4_NH4_NIT = 0.0_fp - - ALLOCATE( SO4( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:SO4', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - SO4 = 0.0_fp - - ! (jmm, 06/30/18) - ALLOCATE( HMS( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F:HMS', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - HMS = 0.0_fp - - ALLOCATE( NH4( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F:NH4', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - NH4 = 0.0_fp - - ALLOCATE( NIT( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:NIT', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - NIT = 0.0_fp - - ALLOCATE( FRAC_SNA( State_Grid%NX, State_Grid%NY, State_Grid%NZ, 3 ), & - STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:FRAC_SNA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - FRAC_SNA = 0.0_fp - - ALLOCATE( SLA( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:SLA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - SLA = 0.0_fp - - ALLOCATE( SPA( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:SPA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - SPA = 0.0_fp - - ALLOCATE( TSOA( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:TSOA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - TSOA = 0.0_fp - - ALLOCATE( ASOA( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:ASOA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - ASOA = 0.0_fp - - ALLOCATE( OPOA( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:OPOA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - OPOA = 0.0_fp - - ALLOCATE( PM25( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:PM25', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - PM25 = 0.0_fp - - !zhaisx - ALLOCATE( PM10( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:PM10', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - PM10 = 0.0_fp - - ALLOCATE( SOAGX( State_Grid%NX, State_Grid%NY, State_Grid%NZ ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:SOAGX', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - SOAGX = 0.0_fp - - ! Mass of hydrophobic aerosol from Mian Chin - ALLOCATE( DAERSL(State_Grid%NX,State_Grid%NY,State_Grid%NZ,2), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:DAERSL', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - DAERSL = 0.0_fp - - ! Mass of hydrophilic aerosol from Mian Chin - ALLOCATE( WAERSL(State_Grid%NX,State_Grid%NY,State_Grid%NZ,NAER), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:WAERSL', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - WAERSL = 0.0_fp - - ! Mechanistic isoprene SOA (eam, 2014): - ALLOCATE( ISOAAQ(State_Grid%NX,State_Grid%NY,State_Grid%NZ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:ISOAAQ', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - ISOAAQ = 0.0_fp - - ! Simple SOA - ALLOCATE( SOAS(State_Grid%NX,State_Grid%NY,State_Grid%NZ), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:SOAS', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - SOAS = 0.0_fp - - ! OM/OC for POA - ALLOCATE( OCFPOA(State_Grid%NX,State_Grid%NY), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:OCFPOA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - OCFPOA = 0.0_fp - - ! OM/OC for OPOA, OCPI, OCPO - ALLOCATE( OCFOPOA(State_Grid%NX,State_Grid%NY), STAT=RC ) - CALL GC_CheckVar( 'aerosol_mod.F90:OCFOPOA', 0, RC ) - IF ( RC /= GC_SUCCESS ) RETURN - OCFOPOA = 0.0_fp - - END SUBROUTINE INIT_AEROSOL -!EOC -!------------------------------------------------------------------------------ -! GEOS-Chem Global Chemical Transport Model ! -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: cleanup_aerosol -! -! !DESCRIPTION: Subroutine CLEANUP\_AEROSOL deallocates all module arrays -! (bmy, 7/20/04) -!\\ -!\\ -! !INTERFACE: -! - SUBROUTINE CLEANUP_AEROSOL -! -! !REVISION HISTORY: -! 20 Jul 2004 - R. Yantosca - Initial version -! See https://github.com/geoschem/geos-chem for complete history -!EOP -!------------------------------------------------------------------------------ -!BOC -! - IF ( ALLOCATED( BCPI ) ) DEALLOCATE( BCPI ) - IF ( ALLOCATED( BCPO ) ) DEALLOCATE( BCPO ) - IF ( ALLOCATED( OCPI ) ) DEALLOCATE( OCPI ) - IF ( ALLOCATED( OCPO ) ) DEALLOCATE( OCPO ) - IF ( ALLOCATED( OCPISOA ) ) DEALLOCATE( OCPISOA ) - IF ( ALLOCATED( SALA ) ) DEALLOCATE( SALA ) - IF ( ALLOCATED( SALC ) ) DEALLOCATE( SALC ) - IF ( ALLOCATED( ACL ) ) DEALLOCATE( ACL ) - IF ( ALLOCATED( SO4_NH4_NIT ) ) DEALLOCATE( SO4_NH4_NIT ) - IF ( ALLOCATED( SO4 ) ) DEALLOCATE( SO4 ) - IF ( ALLOCATED( HMS ) ) DEALLOCATE( HMS ) ! (jmm, 06/30/18) - IF ( ALLOCATED( NH4 ) ) DEALLOCATE( NH4 ) - IF ( ALLOCATED( NIT ) ) DEALLOCATE( NIT ) - IF ( ALLOCATED( FRAC_SNA ) ) DEALLOCATE( FRAC_SNA ) - IF ( ALLOCATED( SLA ) ) DEALLOCATE( SLA ) - IF ( ALLOCATED( SPA ) ) DEALLOCATE( SPA ) - IF ( ALLOCATED( TSOA ) ) DEALLOCATE( TSOA ) - IF ( ALLOCATED( ASOA ) ) DEALLOCATE( ASOA ) - IF ( ALLOCATED( OPOA ) ) DEALLOCATE( OPOA ) - IF ( ALLOCATED( SOAGX ) ) DEALLOCATE( SOAGX ) - IF ( ALLOCATED( PM25 ) ) DEALLOCATE( PM25 ) - IF ( ALLOCATED( PM10 ) ) DEALLOCATE( PM10 )!zhaisx - IF ( ALLOCATED( WAERSL ) ) DEALLOCATE( WAERSL ) - IF ( ALLOCATED( DAERSL ) ) DEALLOCATE( DAERSL ) - IF ( ALLOCATED( ISOAAQ ) ) DEALLOCATE( ISOAAQ ) - IF ( ALLOCATED( SOAS ) ) DEALLOCATE( SOAS ) - IF ( ALLOCATED( OCFPOA ) ) DEALLOCATE( OCFPOA ) - IF ( ALLOCATED( OCFOPOA ) ) DEALLOCATE( OCFOPOA ) - - END SUBROUTINE CLEANUP_AEROSOL -!EOC -!------------------------------------------------------------------------------ -! GEOS-Chem Global Chemical Transport Model ! -!------------------------------------------------------------------------------ -!BOP -! -! !IROUTINE: set_aermass_diagnostic -! -! !DESCRIPTION: Computes the aerosol mass diagnostic (formerly ND42 bpch -! diagnostic). -!\\ -!\\ -! !INTERFACE: -! - SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, & - State_Grid, State_Met, RC ) -! -! !USES: -! - USE ErrCode_Mod - USE Input_Opt_Mod, ONLY : OptInput - USE Species_Mod, ONLY : Species, SpcConc - USE State_Chm_Mod, ONLY : ChmState - USE State_Chm_Mod, ONLY : Ind_ - USE State_Diag_Mod, ONLY : DgnState - USE State_Grid_Mod, ONLY : GrdState - USE State_Met_Mod, ONLY : MetState - USE PhysConstants, ONLY : MwCarb - USE UnitConv_Mod -! -! !INPUT PARAMETERS: -! - TYPE(OptInput), INTENT(IN) :: Input_Opt ! Input Options object - TYPE(ChmState), INTENT(IN) :: State_Chm ! Chemistry State object - TYPE(GrdState), INTENT(IN) :: State_Grid ! Grid State object - TYPE(MetState), INTENT(IN) :: State_Met ! Meteorology State object -! -! !INPUT/OUTPUT PARAMETERS: -! - TYPE(DgnState), INTENT(INOUT) :: State_Diag ! Diagnostic State object -! -! !OUTPUT PARAMETERS: -! - INTEGER, INTENT(OUT) :: RC ! Success or failure? -! -! !REMARKS: -! NOTE: This diagnostic mimics the bpch diagnostic routine "DIAG42". -! -! !REVISION HISTORY: -! 05 Feb 2018 - R. Yantosca - Initial version -! See https://github.com/geoschem/geos-chem for complete history -!EOP -!------------------------------------------------------------------------------ -!BOC -! -! !LOCAL VARIABLES: -! - ! SAVEd scalars - LOGICAL :: First = .TRUE. - - ! Scalars - INTEGER :: I, J, L - - ! Strings - INTEGER :: origUnit - CHARACTER(LEN=255) :: ThisLoc - CHARACTER(LEN=512) :: ErrMsg - - ! Pointers - REAL(fp), POINTER :: AirDen(:,:,: ) - TYPE(SpcConc), POINTER :: Spc (: ) - TYPE(Species), POINTER :: SpcInfo -! -! !DEFINED PARAMETERS: -! - ! Convert [kg/m3] to [ug/m3] - REAL(fp), PARAMETER :: kgm3_to_ugm3 = 1.0e+9_fp - - ! Define number of carbon atoms in each irreversible isoprene - ! SOA tracer species. Named according to the parent HC (same - ! number of carbons): - REAL(fp), PARAMETER :: NCIMAE = 4e+0_fp - REAL(fp), PARAMETER :: NCIEPOX = 5e+0_fp - REAL(fp), PARAMETER :: NCINDIOL = NCIEPOX - REAL(fp), PARAMETER :: NCGLYX = 2e+0_fp - REAL(fp), PARAMETER :: NCGLYC = NCGLYX - REAL(fp), PARAMETER :: NCMGLY = 3e+0_fp - REAL(fp), PARAMETER :: NCLVOC = NCIEPOX - REAL(fp), PARAMETER :: NCISN1 = NCIEPOX - - !======================================================================= - ! Set_AerMass_Diagnostic begins here! - !======================================================================= - - ! Initialize - RC = GC_SUCCESS - errMsg = '' - thisLoc = & - ' -> at Set_AerMass_Diagnostic (in module GeosCore/aerosol_mod.F90)' - - ! Check that species units are kg/kg dry air - IF ( State_Chm%Spc_Units /= KG_SPECIES_PER_KG_DRY_AIR ) THEN - errMsg = 'Incorrect species units: ' // UNIT_STR( State_Chm%Spc_Units ) - CALL GC_Error( errMsg, RC, thisLoc ) - RETURN - ENDIF - - ! Define species ID flags for the aerosol mass diagnostics - IF ( First ) THEN - - !-------------------------------------------------------------------- - ! Look up species indices in State_Chm%SPECIES - !-------------------------------------------------------------------- - id_INDIOL = Ind_( 'INDIOL' ) - id_LVOCOA = Ind_( 'LVOCOA' ) - id_POA1 = Ind_( 'POA1' ) - id_POA2 = Ind_( 'POA2' ) - id_OPOA1 = Ind_( 'OPOA1' ) - id_OPOA2 = Ind_( 'OPOA2' ) - id_SOAGX = Ind_( 'SOAGX' ) - id_SOAIE = Ind_( 'SOAIE' ) - Is_POA = ( id_POA1 > 0 .and. id_POA2 > 0 ) - Is_OPOA = ( id_OPOA1 > 0 .and. id_OPOA2 > 0 ) - - ! Initialize conversion factors for total OC diagnostic - Fac_INDIOL = 0.0_fp - Fac_LVOCOA = 0.0_fp - Fac_SOAGX = 0.0_fp - Fac_SOAIE = 0.0_fp - - !-------------------------------------------------------------------- - ! Set conversion factors for certain isoprene SOA species, - ! or, if they aren't present, disable their diagnostics - !-------------------------------------------------------------------- - IF ( id_INDIOL > 0 ) THEN - SpcInfo => State_Chm%SpcData(id_INDIOL)%Info - Fac_INDIOL = ( NCINDIOL * MwCarb / ( SpcInfo%Mw_g * 1e-3_fp ) ) - SpcInfo => NULL() - ELSE - IF ( State_Diag%Archive_AerMassINDIOL ) THEN - State_Diag%Archive_AerMassINDIOL = .FALSE. - ErrMsg = 'Disabling AerMassINDIOL diagnostic. ' // & - 'INDIOL is not a defined species for this simulation.' - CALL GC_Warning( ErrMsg, RC, ThisLoc ) - ENDIF - ENDIF - - IF ( id_LVOCOA > 0 ) THEN - SpcInfo => State_Chm%SpcData(id_LVOCOA)%Info - Fac_LVOCOA = ( NCLVOC * MwCarb / ( SpcInfo%Mw_G * 1e-3_fp ) ) - SpcInfo => NULL() - ELSE - IF ( State_Diag%Archive_AerMassLVOCOA ) THEN - State_Diag%Archive_AerMassLVOCOA = .FALSE. - ErrMsg = 'Disabling AerMassLVOCOA diagnostic. ' // & - 'LVOCOA is not a defined species for this simulation.' - CALL GC_Warning( ErrMsg, RC, ThisLoc ) - ENDIF - ENDIF - - IF ( id_SOAGX > 0 ) THEN - SpcInfo => State_Chm%SpcData(id_SOAGX)%Info - Fac_SOAGX = ( NCGLYX * MwCarb / ( SpcInfo%Mw_g * 1e-3_fp ) ) - SpcInfo => NULL() - ELSE - IF ( State_Diag%Archive_AerMassSOAGX ) THEN - State_Diag%Archive_AerMassSOAGX = .FALSE. - ErrMsg = 'Disabling AerMassSOAGX diagnostic.' // & - 'SOAGX is not a defined species for this simulation.' - CALL GC_Warning( ErrMsg, RC, ThisLoc ) - ENDIF - ENDIF - - IF ( id_SOAIE > 0 ) THEN - SpcInfo => State_Chm%SpcData(id_SOAIE)%Info - Fac_SOAIE = ( NCIEPOX * MwCarb / ( SpcInfo%Mw_g * 1e-3_fp ) ) - SpcInfo => NULL() - ELSE - IF ( State_Diag%Archive_AerMassSOAIE ) THEN - State_Diag%Archive_AerMassSOAIE = .FALSE. - ErrMsg = 'Disabling AerMassSOAIE diagnostic. ' // & - 'SOAIE is not a defined species for this simulation.' - CALL GC_Warning( ErrMsg, RC, ThisLoc ) - ENDIF - ENDIF - - ! Reset first-time flag - First = .FALSE. - ENDIF - - !======================================================================= - ! Compute Aerosol mass and PM2.5 diagnostics using concentrations - ! from the end of the chemistry timestep, which should be more - ! consistent with the legacy ND42 bpch diagnostics - !======================================================================= - - ! Point to fields of State_Chm and State_Met - Spc => State_Chm%Species - AirDen => State_Met%AIRDEN - - ! Zero out the totalOC diagnostic - IF ( State_Diag%Archive_TotalOC ) THEN - State_Diag%TotalOC = 0.0_fp - ENDIF - - !$OMP PARALLEL DO & - !$OMP DEFAULT( SHARED ) & - !$OMP PRIVATE( I, J, L ) - DO L = 1, State_Grid%NZ - DO J = 1, State_Grid%NY - DO I = 1, State_Grid%NX - - !-------------------------------------- - ! AerMassASOA [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassASOA ) THEN - State_Diag%AerMassASOA(I,J,L) = ASOA(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! AerMassBC [ug C/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassBC ) THEN - State_Diag%AerMassBC(I,J,L) = ( BCPI(I,J,L) + BCPO(I,J,L) ) * & - kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! AerMassINDIOL [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassINDIOL ) THEN - State_Diag%AerMassINDIOL(I,J,L) = Spc(id_INDIOL)%Conc(I,J,L) * & - kgm3_to_ugm3 * AirDen(I,J,L) - ENDIF - - !-------------------------------------- - ! AerMassLVOCOA [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassLVOCOA ) THEN - State_Diag%AerMassLVOCOA(I,J,L) = Spc(id_LVOCOA)%Conc(I,J,L) * & - kgm3_to_ugm3 * AirDen(I,J,L) - ENDIF - - !-------------------------------------- - ! AerMassNH4 [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassNH4 ) THEN - State_Diag%AerMassNH4(I,J,L) = NH4(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! AerMassNIT [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassNIT ) THEN - State_Diag%AerMassNIT(I,J,L) = NIT(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! AerMassOPOA [ug/m3], OA:OC=2.1 - !-------------------------------------- - IF ( State_Diag%Archive_AerMassOPOA ) THEN - State_Diag%AerMassOPOA(I,J,L) = OPOA(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! AerMassPOA [ug/m3], OA:OC=2.1 - !-------------------------------------- - IF ( State_Diag%Archive_AerMassPOA ) THEN - IF ( Is_POA ) THEN - State_Diag%AerMassPOA(I,J,L) = OCPO(I,J,L) * kgm3_to_ugm3 - ELSE - State_Diag%AerMassPOA(I,J,L) = ( OCPI(I,J,L) + OCPO(I,J,L) ) * & - kgm3_to_ugm3 - ENDIF - ENDIF - - !-------------------------------------- - ! AerMassSAL [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassSAL ) THEN - State_Diag%AerMassSAL(I,J,L) = ( SALA(I,J,L) + SALC(I,J,L) ) * & - kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! AerMassSO4 [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassSO4 ) THEN - State_Diag%AerMassSO4(I,J,L) = SO4(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! AerMassHMS [ug/m3] - ! jmm 3/6/19 - !-------------------------------------- - IF ( State_Diag%Archive_AerMassHMS ) THEN - State_Diag%AerMassHMS(I,J,L) = HMS(I,J,L) * & - kgm3_to_ugm3 - ENDIF - - - !-------------------------------------- - ! AerMassSOAGX [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassSOAGX ) THEN - State_Diag%AerMassSOAGX(I,J,L) = SOAGX(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! AerMassSOAIE [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassSOAIE ) THEN - State_Diag%AerMassSOAIE(I,J,L) = Spc(id_SOAIE)%Conc(I,J,L) * & - kgm3_to_ugm3 * AirDen(I,J,L) - ENDIF - - !-------------------------------------- - ! AerMassTSOA [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_AerMassTSOA ) THEN - State_Diag%AerMassTSOA(I,J,L) = TSOA(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! PM25 [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_PM25 ) THEN - State_Diag%PM25(I,J,L) = PM25(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! PM10 [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_PM10 ) THEN - State_Diag%PM10(I,J,L) = PM10(I,J,L) * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! Sum of all biogenic organic aerosol - !-------------------------------------- - IF ( State_Diag%Archive_TotalBiogenicOA ) THEN - State_Diag%TotalBiogenicOA(I,J,L) = ( TSOA(I,J,L) + ISOAAQ(I,J,L) ) & - * kgm3_to_ugm3 - ENDIF - - !-------------------------------------- - ! Sum of all organic aerosol [ug/m3] - !-------------------------------------- - 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 - ENDIF - - !-------------------------------------- - ! Sum of all organic carbon [ug/m3] - !-------------------------------------- - IF ( State_Diag%Archive_TotalOC ) THEN - - 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) & - + OCPO(I,J,L) / OCFPOA(I,J) ) * kgm3_to_ugm3 - - ELSE IF ( IS_OPOA ) 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 - ENDIF + ! Define logical flags + IS_OCPI = ( id_OCPI > 0 ) + IS_OCPO = ( id_OCPO > 0 ) + IS_BC = ( id_BCPI > 0 .AND. id_BCPO > 0 ) + IS_SO4 = ( id_SO4 > 0 ) + IS_HMS = ( id_HMS > 0 ) + IS_NH4 = ( id_NH4 > 0 ) + IS_NIT = ( id_NIT > 0 ) + IS_DST = ( id_DST1 > 0 .AND. id_DST2 > 0 ) + IS_SAL = ( id_SALA > 0 .AND. id_SALC > 0 ) + IS_POA = ( id_POA1 > 0 .AND. id_POA2 > 0 ) + IS_OPOA = ( id_OPOA1 > 0 .AND. id_OPOA2 > 0 ) + IS_TSOA = ( id_TSOA1 > 0 .AND. id_TSOA2 > 0 .AND. & + id_TSOA3 > 0 .AND. id_TSOA0 > 0 ) + IS_ASOA = ( id_ASOAN > 0 .AND. id_ASOA1 > 0 .AND. & + id_ASOA2 > 0 .AND. id_ASOA3 > 0 ) + IS_SOAGX = ( id_SOAGX > 0 ) + Is_SimpleSOA = ( id_SOAS > 0 ) + Is_ComplexSOA = Input_Opt%LSOA - IF ( Input_Opt%LSOA ) 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 ) + & - ( Spc(id_SOAGX )%Conc(I,J,L) * Fac_SOAGX ) + & - ( Spc(id_LVOCOA)%Conc(I,J,L) * Fac_LVOCOA ) ) & - * AirDen(I,J,L) * kgm3_to_ugm3 - ENDIF + ! Initialize the mapping between hygroscopic species in the + ! species database and the species order in NRHAER + DO N = 1, NRHAER + + ! Get the species database index from the species database + ! mapping array for hygroscopic growth species + SpcID = State_Chm%Map_HygGrth(N) + + ! Point to the Species Database entry for species N + SpcInfo => State_Chm%SpcData(SpcID)%Info + + ! Set the mapping to the ordering of aerosol densities in RD_AOD + SELECT CASE ( TRIM(SpcInfo%Name) ) + CASE ( 'SO4' ) + Map_NRHAER(N) = 1 + CASE ( 'BCPI' ) + Map_NRHAER(N) = 2 + CASE ( 'OCPI', 'POA1' ) + Map_NRHAER(N) = 3 + CASE ( 'SALA' ) + Map_NRHAER(N) = 4 + CASE ( 'SALC' ) + Map_NRHAER(N) = 5 + CASE DEFAULT + ErrMsg = 'WARNING: aerosol diagnostics not defined' // & + ' for NRHAER greater than 5!' + CALL GC_ERROR( ErrMsg, RC, 'Init_Aerosol in aerosol_mod.F90' ) + END SELECT - ENDIF + ! Free pointer + SpcInfo => NULL() ENDDO - ENDDO - ENDDO - !$OMP END PARALLEL DO - ! Free pointers - Spc => NULL() - AirDen => NULL() - - END SUBROUTINE Set_AerMass_Diagnostic + END SUBROUTINE INIT_AEROSOL !EOC END MODULE AEROSOL_MOD diff --git a/GeosCore/carbon_mod.F90 b/GeosCore/carbon_mod.F90 index 385e95fdb..42c55e8f2 100644 --- a/GeosCore/carbon_mod.F90 +++ b/GeosCore/carbon_mod.F90 @@ -16,7 +16,6 @@ MODULE CARBON_MOD ! ! !USES: ! - USE AEROSOL_MOD, ONLY : OCFPOA, OCFOPOA USE PhysConstants ! Physical constants USE PRECISION_MOD ! For GEOS-Chem Precisions @@ -1891,8 +1890,8 @@ SUBROUTINE SOA_CHEMISTRY( Input_Opt, State_Chm, State_Diag, & JHC = PARENTPOA JSV = IDSV(JHC) DO IPR = 1, NPROD(JSV) - ORG_GAS(IPR,JSV) = ORG_GAS(IPR,JSV) * OCFPOA(I,J) - ORG_AER(IPR,JSV) = ORG_AER(IPR,JSV) * OCFPOA(I,J) + ORG_GAS(IPR,JSV) = ORG_GAS(IPR,JSV) * State_Chm%AerMass%OCFPOA(I,J) + ORG_AER(IPR,JSV) = ORG_AER(IPR,JSV) * State_Chm%AerMass%OCFPOA(I,J) ENDDO ENDIF @@ -1903,8 +1902,8 @@ SUBROUTINE SOA_CHEMISTRY( Input_Opt, State_Chm, State_Diag, & JHC = PARENTOPOA JSV = IDSV(JHC) DO IPR = 1, NPROD(JSV) - ORG_GAS(IPR,JSV) = ORG_GAS(IPR,JSV) * OCFOPOA(I,J) - ORG_AER(IPR,JSV) = ORG_AER(IPR,JSV) * OCFOPOA(I,J) + ORG_GAS(IPR,JSV) = ORG_GAS(IPR,JSV) * State_Chm%AerMass%OCFOPOA(I,J) + ORG_AER(IPR,JSV) = ORG_AER(IPR,JSV) * State_Chm%AerMass%OCFOPOA(I,J) ENDDO ENDIF @@ -2021,7 +2020,7 @@ SUBROUTINE SOA_CHEMISTRY( Input_Opt, State_Chm, State_Diag, & ! Now treat either traditional POA or semivolatile POA (hotp 7/25/10) IF ( id_OCPI > 0 .and. id_OCPO > 0 ) THEN MPOC = ( Spc(id_OCPI)%Conc(I,J,L) + Spc(id_OCPO)%Conc(I,J,L) ) * FAC - MPOC = MPOC * OCFOPOA(I,J) + MPOC = MPOC * State_Chm%AerMass%OCFOPOA(I,J) ELSE ! semivolpoa2: MPOC is zero now (hotp 2/27/09) MPOC = 1e-30_fp @@ -2101,8 +2100,8 @@ SUBROUTINE SOA_CHEMISTRY( Input_Opt, State_Chm, State_Diag, & JHC = PARENTPOA JSV = IDSV(JHC) DO IPR = 1, NPROD(JSV) - ORG_GAS(IPR,JSV) = ORG_GAS(IPR,JSV) / OCFPOA(I,J) - ORG_AER(IPR,JSV) = ORG_AER(IPR,JSV) / OCFPOA(I,J) + ORG_GAS(IPR,JSV) = ORG_GAS(IPR,JSV) / State_Chm%AerMass%OCFPOA(I,J) + ORG_AER(IPR,JSV) = ORG_AER(IPR,JSV) / State_Chm%AerMass%OCFPOA(I,J) ENDDO ENDIF @@ -2112,8 +2111,8 @@ SUBROUTINE SOA_CHEMISTRY( Input_Opt, State_Chm, State_Diag, & JHC = PARENTOPOA JSV = IDSV(JHC) DO IPR = 1, NPROD(JSV) - ORG_GAS(IPR,JSV) = ORG_GAS(IPR,JSV) / OCFOPOA(I,J) - ORG_AER(IPR,JSV) = ORG_AER(IPR,JSV) / OCFOPOA(I,J) + ORG_GAS(IPR,JSV) = ORG_GAS(IPR,JSV) / State_Chm%AerMass%OCFOPOA(I,J) + ORG_AER(IPR,JSV) = ORG_AER(IPR,JSV) / State_Chm%AerMass%OCFOPOA(I,J) ENDDO ENDIF @@ -3330,8 +3329,8 @@ SUBROUTINE SOA_PARA_INIT( Input_Opt ) print*, 'Semivolatile POA settings:---------------' print*, ' ALPHA: ', ALPHA(1,1,9), ALPHA(1,2,9) ! OCFPOA and OCFOPOA are now 2D arrays - !print*, ' POA OA/OC ratio: ', OCFPOA(I,J) - !print*, ' OPOA OA/OC ratio: ', OCFOPOA(I,J) + !print*, ' POA OA/OC ratio: ', State_Chm%AerMass%OCFPOA(I,J) + !print*, ' OPOA OA/OC ratio: ', State_Chm%AerMass%OCFOPOA(I,J) print*, ' LSVPOA is set to: ', Input_Opt%LSVPOA print*, 'CHECK MHC, NOX, PR', MHC, MNOX, MPROD @@ -6276,10 +6275,10 @@ SUBROUTINE CHECK_EQLB( I, J, L, KOMIJL, CONVFAC, MSOACHEM, & ! Add primary material as appropriate IF ( id_POA1 > 0 ) THEN MOTEMP = MOTEMP + & - Spc(id_POA1 )%Conc(I,J,L) * OCFPOA(I,J) + & - Spc(id_POA2 )%Conc(I,J,L) * OCFPOA(I,J) + & - Spc(id_OPOA1)%Conc(I,J,L) * OCFOPOA(I,J) + & - Spc(id_OPOA2)%Conc(I,J,L) * OCFOPOA(I,J) + Spc(id_POA1 )%Conc(I,J,L) * State_Chm%AerMass%OCFPOA(I,J) + & + Spc(id_POA2 )%Conc(I,J,L) * State_Chm%AerMass%OCFPOA(I,J) + & + Spc(id_OPOA1)%Conc(I,J,L) * State_Chm%AerMass%OCFOPOA(I,J) + & + Spc(id_OPOA2)%Conc(I,J,L) * State_Chm%AerMass%OCFOPOA(I,J) ELSEIF ( id_OCPI > 0 ) THEN MOTEMP = MOTEMP + & ( Spc(id_OCPI)%Conc(I,J,L) + Spc(id_OCPO)%Conc(I,J,L) ) * 2.1e+0_fp diff --git a/GeosCore/cleanup.F90 b/GeosCore/cleanup.F90 index f3bbc06d2..48609d233 100644 --- a/GeosCore/cleanup.F90 +++ b/GeosCore/cleanup.F90 @@ -15,7 +15,6 @@ SUBROUTINE CLEANUP( Input_Opt, State_Grid, ERROR, RC ) ! ! !USES: ! - USE AEROSOL_MOD, ONLY : CLEANUP_AEROSOL USE CARBON_MOD, ONLY : CLEANUP_CARBON USE Carbon_Gases_Mod, ONLY : Cleanup_Carbon_Gases USE CO2_MOD, ONLY : CLEANUP_CO2 @@ -127,7 +126,6 @@ SUBROUTINE CLEANUP( Input_Opt, State_Grid, ERROR, RC ) !================================================================= ! Call cleanup routines from individual F90 modules !================================================================= - CALL CLEANUP_AEROSOL() CALL CLEANUP_CARBON() CALL CLEANUP_CO2() CALL CLEANUP_DRYDEP() diff --git a/GeosCore/diagnostics_mod.F90 b/GeosCore/diagnostics_mod.F90 index 22ae5ce55..596321d40 100644 --- a/GeosCore/diagnostics_mod.F90 +++ b/GeosCore/diagnostics_mod.F90 @@ -24,6 +24,7 @@ MODULE Diagnostics_mod ! ! !PUBLIC MEMBER FUNCTIONS: ! + PUBLIC :: Set_AerMass_Diagnostic PUBLIC :: Set_Diagnostics_EndofTimestep PUBLIC :: Zero_Diagnostics_StartofTimestep PUBLIC :: Compute_Budget_Diagnostics @@ -1664,4 +1665,498 @@ SUBROUTINE Do_Archive_SatDiagn( Input_Opt, State_Chm, State_Diag, & END SUBROUTINE Do_Archive_SatDiagn !EOC +!------------------------------------------------------------------------------ +! GEOS-Chem Global Chemical Transport Model ! +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: set_aermass_diagnostic +! +! !DESCRIPTION: Computes the aerosol mass diagnostic (formerly ND42 bpch +! diagnostic). +!\\ +!\\ +! !INTERFACE: +! + SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, & + State_Grid, State_Met, RC ) +! +! !USES: +! + USE Aerosol_Mod, ONLY : IS_POA, IS_OPOA + USE ErrCode_Mod + USE Input_Opt_Mod, ONLY : OptInput + USE Species_Mod, ONLY : Species, SpcConc + USE State_Chm_Mod, ONLY : ChmState + USE State_Chm_Mod, ONLY : Ind_ + USE State_Diag_Mod, ONLY : DgnState + USE State_Grid_Mod, ONLY : GrdState + USE State_Met_Mod, ONLY : MetState + USE PhysConstants, ONLY : MwCarb + USE UnitConv_Mod, ONLY : Convert_Spc_Units +! +! !INPUT PARAMETERS: +! + TYPE(OptInput), INTENT(IN) :: Input_Opt ! Input Options object + TYPE(ChmState), INTENT(IN) :: State_Chm ! Chemistry State object + TYPE(GrdState), INTENT(IN) :: State_Grid ! Grid State object + TYPE(MetState), INTENT(IN) :: State_Met ! Meteorology State object +! +! !INPUT/OUTPUT PARAMETERS: +! + TYPE(DgnState), INTENT(INOUT) :: State_Diag ! Diagnostic State object +! +! !OUTPUT PARAMETERS: +! + INTEGER, INTENT(OUT) :: RC ! Success or failure? +! +! !REMARKS: +! NOTE: This diagnostic mimics the bpch diagnostic routine "DIAG42". +! +! !REVISION HISTORY: +! 05 Feb 2018 - R. Yantosca - Initial version +! See https://github.com/geoschem/geos-chem for complete history +!EOP +!------------------------------------------------------------------------------ +!BOC +! +! !LOCAL VARIABLES: +! + ! SAVEd scalars + LOGICAL :: First = .TRUE. + + ! Scalars + INTEGER :: I, J, L + + ! Strings + CHARACTER(LEN=63) :: OrigUnit + CHARACTER(LEN=255) :: ThisLoc + CHARACTER(LEN=512) :: ErrMsg + + ! Pointers + REAL(fp), POINTER :: AirDen(:,:,: ) + TYPE(SpcConc), POINTER :: Spc (: ) + TYPE(Species), POINTER :: SpcInfo + REAL(fp), POINTER :: OCFPOA (:,:) + REAL(fp), POINTER :: OCFOPOA (:,:) + REAL(fp), POINTER :: BCPI (:,:,:) + REAL(fp), POINTER :: BCPO (:,:,:) + REAL(fp), POINTER :: OCPI (:,:,:) + REAL(fp), POINTER :: OCPO (:,:,:) + REAL(fp), POINTER :: OCPISOA (:,:,:) + REAL(fp), POINTER :: SALA (:,:,:) + REAL(fp), POINTER :: ACL (:,:,:) + REAL(fp), POINTER :: SALC (:,:,:) + REAL(fp), POINTER :: SO4_NH4_NIT (:,:,:) + REAL(fp), POINTER :: SO4 (:,:,:) + REAL(fp), POINTER :: HMS (:,:,:) + REAL(fp), POINTER :: NH4 (:,:,:) + REAL(fp), POINTER :: NIT (:,:,:) + REAL(fp), POINTER :: SLA (:,:,:) + REAL(fp), POINTER :: SPA (:,:,:) + REAL(fp), POINTER :: TSOA (:,:,:) + REAL(fp), POINTER :: ASOA (:,:,:) + REAL(fp), POINTER :: OPOA (:,:,:) + REAL(fp), POINTER :: SOAGX (:,:,:) + REAL(fp), POINTER :: PM25 (:,:,:) + REAL(fp), POINTER :: PM10 (:,:,:) + REAL(fp), POINTER :: ISOAAQ (:,:,:) + REAL(fp), POINTER :: SOAS (:,:,:) + REAL(fp), POINTER :: FRAC_SNA (:,:,:,:) + REAL(fp), POINTER :: DAERSL (:,:,:,:) + REAL(fp), POINTER :: WAERSL (:,:,:,:) + + ! Conversionf factors to ugC/m3 for Total Organic Carbon diagnostic + REAL(fp), SAVE :: Fac_INDIOL + REAL(fp), SAVE :: Fac_LVOCOA + REAL(fp), SAVE :: Fac_SOAGX + REAL(fp), SAVE :: Fac_SOAIE + + ! Species ids + INTEGER, SAVE :: id_INDIOL + INTEGER, SAVE :: id_LVOCOA + INTEGER, SAVE :: id_SOAGX + INTEGER, SAVE :: id_SOAIE +! +! !DEFINED PARAMETERS: +! + ! Convert [kg/m3] to [ug/m3] + REAL(fp), PARAMETER :: kgm3_to_ugm3 = 1.0e+9_fp + + ! Define number of carbon atoms in each irreversible isoprene + ! SOA tracer species. Named according to the parent HC (same + ! number of carbons): + REAL(fp), PARAMETER :: NCIMAE = 4e+0_fp + REAL(fp), PARAMETER :: NCIEPOX = 5e+0_fp + REAL(fp), PARAMETER :: NCINDIOL = NCIEPOX + REAL(fp), PARAMETER :: NCGLYX = 2e+0_fp + REAL(fp), PARAMETER :: NCGLYC = NCGLYX + REAL(fp), PARAMETER :: NCMGLY = 3e+0_fp + REAL(fp), PARAMETER :: NCLVOC = NCIEPOX + REAL(fp), PARAMETER :: NCISN1 = NCIEPOX + + !======================================================================= + ! Set_AerMass_Diagnostic begins here! + !======================================================================= + + ! Initialize + RC = GC_SUCCESS + ErrMsg = '' + ThisLoc = ' -> at Set_AerMass_Diagnostic (in module GeosCore/aerosol_mod.F90)' + + ! Set pointers + OCFPOA => State_Chm%AerMass%OCFPOA + OCFOPOA => State_Chm%AerMass%OCFOPOA + BCPI => State_Chm%AerMass%BCPI + BCPO => State_Chm%AerMass%BCPO + OCPI => State_Chm%AerMass%OCPI + OCPO => State_Chm%AerMass%OCPO + OCPISOA => State_Chm%AerMass%OCPISOA + SALA => State_Chm%AerMass%SALA + ACL => State_Chm%AerMass%ACL + SALC => State_Chm%AerMass%SALC + SO4_NH4_NIT => State_Chm%AerMass%SO4_NH4_NIT + SO4 => State_Chm%AerMass%SO4 + HMS => State_Chm%AerMass%HMS + NH4 => State_Chm%AerMass%NH4 + NIT => State_Chm%AerMass%NIT + SLA => State_Chm%AerMass%SLA + SPA => State_Chm%AerMass%SPA + TSOA => State_Chm%AerMass%TSOA + ASOA => State_Chm%AerMass%ASOA + OPOA => State_Chm%AerMass%OPOA + SOAGX => State_Chm%AerMass%SOAGX + PM25 => State_Chm%AerMass%PM25 + PM10 => State_Chm%AerMass%PM10 + ISOAAQ => State_Chm%AerMass%ISOAAQ + SOAS => State_Chm%AerMass%SOAS + FRAC_SNA => State_Chm%AerMass%FRAC_SNA + DAERSL => State_Chm%AerMass%DAERSL + WAERSL => State_Chm%AerMass%WAERSL + + ! Check that species units are kg/kg dry air + IF ( TRIM( State_Chm%Spc_Units ) /= 'kg/kg dry' ) THEN + CALL GC_Error( 'Incorrect species units: ' // & + State_Chm%Spc_Units, RC, ThisLoc ) + RETURN + ENDIF + + ! Define species ID flags for the aerosol mass diagnostics + IF ( First ) THEN + + ! Initialize conversion factors for total OC diagnostic + Fac_INDIOL = 0.0_fp + Fac_LVOCOA = 0.0_fp + Fac_SOAGX = 0.0_fp + Fac_SOAIE = 0.0_fp + + ! Initialize species ids + id_INDIOL = Ind_('INDIOL') + id_LVOCOA = Ind_('LVOCOA') + id_SOAGX = Ind_('SOAGX') + id_SOAIE = Ind_('SOAIE') + + !-------------------------------------------------------------------- + ! Set conversion factors for certain isoprene SOA species, + ! or, if they aren't present, disable their diagnostics + !-------------------------------------------------------------------- + IF ( id_INDIOL > 0 ) THEN + IF ( State_Diag%Archive_TotalOC ) THEN + SpcInfo => State_Chm%SpcData(id_INDIOL)%Info + Fac_INDIOL = ( NCINDIOL * MwCarb / ( SpcInfo%Mw_g * 1e-3_fp ) ) + SpcInfo => NULL() + ENDIF + ELSE + IF ( State_Diag%Archive_AerMassINDIOL ) THEN + State_Diag%Archive_AerMassINDIOL = .FALSE. + ErrMsg = 'Disabling AerMassINDIOL diagnostic. ' // & + 'INDIOL is not a defined species for this simulation.' + CALL GC_Warning( ErrMsg, RC, ThisLoc ) + ENDIF + ENDIF + + IF ( id_LVOCOA > 0 ) THEN + IF ( State_Diag%Archive_TotalOC ) THEN + SpcInfo => State_Chm%SpcData(id_LVOCOA)%Info + Fac_LVOCOA = ( NCLVOC * MwCarb / ( SpcInfo%Mw_G * 1e-3_fp ) ) + SpcInfo => NULL() + ENDIF + ELSE + IF ( State_Diag%Archive_AerMassLVOCOA ) THEN + State_Diag%Archive_AerMassLVOCOA = .FALSE. + ErrMsg = 'Disabling AerMassLVOCOA diagnostic. ' // & + 'LVOCOA is not a defined species for this simulation.' + CALL GC_Warning( ErrMsg, RC, ThisLoc ) + ENDIF + ENDIF + + IF ( id_SOAGX > 0 ) THEN + IF ( State_Diag%Archive_TotalOC ) THEN + SpcInfo => State_Chm%SpcData(id_SOAGX)%Info + Fac_SOAGX = ( NCGLYX * MwCarb / ( SpcInfo%Mw_g * 1e-3_fp ) ) + SpcInfo => NULL() + ENDIF + ELSE + IF ( State_Diag%Archive_AerMassSOAGX ) THEN + State_Diag%Archive_AerMassSOAGX = .FALSE. + ErrMsg = 'Disabling AerMassSOAGX diagnostic.' // & + 'SOAGX is not a defined species for this simulation.' + CALL GC_Warning( ErrMsg, RC, ThisLoc ) + ENDIF + ENDIF + + IF ( id_SOAIE > 0 ) THEN + IF ( State_Diag%Archive_TotalOC ) THEN + SpcInfo => State_Chm%SpcData(id_SOAIE)%Info + Fac_SOAIE = ( NCIEPOX * MwCarb / ( SpcInfo%Mw_g * 1e-3_fp ) ) + SpcInfo => NULL() + ENDIF + ELSE + IF ( State_Diag%Archive_AerMassSOAIE ) THEN + State_Diag%Archive_AerMassSOAIE = .FALSE. + ErrMsg = 'Disabling AerMassSOAIE diagnostic. ' // & + 'SOAIE is not a defined species for this simulation.' + CALL GC_Warning( ErrMsg, RC, ThisLoc ) + ENDIF + ENDIF + + ! Reset first-time flag + First = .FALSE. + ENDIF + + !======================================================================= + ! Compute Aerosol mass and PM2.5 diagnostics using concentrations + ! from the end of the chemistry timestep, which should be more + ! consistent with the legacy ND42 bpch diagnostics + !======================================================================= + + ! Point to fields of State_Chm and State_Met + Spc => State_Chm%Species + AirDen => State_Met%AIRDEN + + ! Zero out the totalOC diagnostic + IF ( State_Diag%Archive_TotalOC ) THEN + State_Diag%TotalOC = 0.0_fp + ENDIF + + !$OMP PARALLEL DO & + !$OMP DEFAULT( SHARED ) & + !$OMP PRIVATE( I, J, L ) + DO L = 1, State_Grid%NZ + DO J = 1, State_Grid%NY + DO I = 1, State_Grid%NX + + !-------------------------------------- + ! AerMassASOA [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassASOA ) THEN + State_Diag%AerMassASOA(I,J,L) = ASOA(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! AerMassBC [ug C/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassBC ) THEN + State_Diag%AerMassBC(I,J,L) = ( BCPI(I,J,L) + BCPO(I,J,L) ) * & + kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! AerMassINDIOL [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassINDIOL ) THEN + State_Diag%AerMassINDIOL(I,J,L) = Spc(id_INDIOL)%Conc(I,J,L) * & + kgm3_to_ugm3 * AirDen(I,J,L) + ENDIF + + !-------------------------------------- + ! AerMassLVOCOA [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassLVOCOA ) THEN + State_Diag%AerMassLVOCOA(I,J,L) = Spc(id_LVOCOA)%Conc(I,J,L) * & + kgm3_to_ugm3 * AirDen(I,J,L) + ENDIF + + !-------------------------------------- + ! AerMassNH4 [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassNH4 ) THEN + State_Diag%AerMassNH4(I,J,L) = NH4(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! AerMassNIT [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassNIT ) THEN + State_Diag%AerMassNIT(I,J,L) = NIT(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! AerMassOPOA [ug/m3], OA:OC=2.1 + !-------------------------------------- + IF ( State_Diag%Archive_AerMassOPOA ) THEN + State_Diag%AerMassOPOA(I,J,L) = OPOA(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! AerMassPOA [ug/m3], OA:OC=2.1 + !-------------------------------------- + IF ( State_Diag%Archive_AerMassPOA ) THEN + IF ( Is_POA ) THEN + State_Diag%AerMassPOA(I,J,L) = OCPO(I,J,L) * kgm3_to_ugm3 + ELSE + State_Diag%AerMassPOA(I,J,L) = ( OCPI(I,J,L) + OCPO(I,J,L) ) * & + kgm3_to_ugm3 + ENDIF + ENDIF + + !-------------------------------------- + ! AerMassSAL [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassSAL ) THEN + State_Diag%AerMassSAL(I,J,L) = ( SALA(I,J,L) + SALC(I,J,L) ) * & + kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! AerMassSO4 [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassSO4 ) THEN + State_Diag%AerMassSO4(I,J,L) = SO4(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! AerMassHMS [ug/m3] + ! jmm 3/6/19 + !-------------------------------------- + IF ( State_Diag%Archive_AerMassHMS ) THEN + State_Diag%AerMassHMS(I,J,L) = HMS(I,J,L) * & + kgm3_to_ugm3 + ENDIF + + + !-------------------------------------- + ! AerMassSOAGX [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassSOAGX ) THEN + State_Diag%AerMassSOAGX(I,J,L) = SOAGX(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! AerMassSOAIE [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassSOAIE ) THEN + State_Diag%AerMassSOAIE(I,J,L) = Spc(id_SOAIE)%Conc(I,J,L) * & + kgm3_to_ugm3 * AirDen(I,J,L) + ENDIF + + !-------------------------------------- + ! AerMassTSOA [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_AerMassTSOA ) THEN + State_Diag%AerMassTSOA(I,J,L) = TSOA(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! PM25 [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_PM25 ) THEN + State_Diag%PM25(I,J,L) = PM25(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! PM10 [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_PM10 ) THEN + State_Diag%PM10(I,J,L) = PM10(I,J,L) * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! Sum of all biogenic organic aerosol + !-------------------------------------- + IF ( State_Diag%Archive_TotalBiogenicOA ) THEN + State_Diag%TotalBiogenicOA(I,J,L) = ( TSOA(I,J,L) + ISOAAQ(I,J,L) ) & + * kgm3_to_ugm3 + ENDIF + + !-------------------------------------- + ! Sum of all organic aerosol [ug/m3] + !-------------------------------------- + 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 + ENDIF + + !-------------------------------------- + ! Sum of all organic carbon [ug/m3] + !-------------------------------------- + IF ( State_Diag%Archive_TotalOC ) THEN + + 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) & + + OCPO(I,J,L) / OCFPOA(I,J) ) * kgm3_to_ugm3 + + ELSE IF ( Is_OPOA ) 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 + ENDIF + + IF ( Input_Opt%LSOA ) 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 ) + & + ( Spc(id_SOAGX )%Conc(I,J,L) * Fac_SOAGX ) + & + ( Spc(id_LVOCOA)%Conc(I,J,L) * Fac_LVOCOA ) ) & + * AirDen(I,J,L) * kgm3_to_ugm3 + ENDIF + + ENDIF + + ENDDO + ENDDO + ENDDO + !$OMP END PARALLEL DO + + ! Free pointers + Spc => NULL() + AirDen => NULL() + OCFPOA => NULL() + OCFOPOA => NULL() + BCPI => NULL() + BCPO => NULL() + OCPI => NULL() + OCPO => NULL() + OCPISOA => NULL() + SALA => NULL() + ACL => NULL() + SALC => NULL() + SO4_NH4_NIT => NULL() + SO4 => NULL() + HMS => NULL() + NH4 => NULL() + NIT => NULL() + SLA => NULL() + SPA => NULL() + TSOA => NULL() + ASOA => NULL() + OPOA => NULL() + SOAGX => NULL() + PM25 => NULL() + PM10 => NULL() + ISOAAQ => NULL() + SOAS => NULL() + FRAC_SNA => NULL() + DAERSL => NULL() + WAERSL => NULL() + + END SUBROUTINE Set_AerMass_Diagnostic +!EOC END MODULE Diagnostics_mod diff --git a/GeosCore/oasave.F90 b/GeosCore/oasave.F90 index 82d77d999..0b35e15d2 100644 --- a/GeosCore/oasave.F90 +++ b/GeosCore/oasave.F90 @@ -12,13 +12,12 @@ !\\ ! !INTERFACE: ! -SUBROUTINE OASAVE( State_Grid ) +SUBROUTINE OASAVE( State_Grid, State_Chm ) ! ! !USES: ! + USE State_Chm_Mod, ONLY : ChmState USE State_Grid_Mod, ONLY : GrdState - USE AEROSOL_MOD, ONLY : OCPI, OCPO - USE AEROSOL_MOD, ONLY : TSOA, ASOA, OPOA, ISOAAQ USE PRECISION_MOD ! For GEOS-Chem Precision (fp) USE CMN_O3_MOD, ONLY : SAVEOA @@ -26,6 +25,7 @@ SUBROUTINE OASAVE( State_Grid ) ! ! !INPUT PARAMETERS: ! + TYPE(ChmState), INTENT(IN) :: State_Chm ! Chemistry State object TYPE(GrdState), INTENT(IN) :: State_Grid ! Grid State object ! ! !REVISION HISTORY: @@ -57,9 +57,12 @@ SUBROUTINE OASAVE( State_Grid ) DO I = 1, State_Grid%NX ! Sum of all organic aerosol [ug/m3] - SAVEOA(I,J,L) = SAVEOA(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) ) * FACTOR + SAVEOA(I,J,L) = SAVEOA(I,J,L) + ( State_Chm%AerMass%TSOA(I,J,L) + & + State_Chm%AerMass%ASOA(I,J,L) + & + State_Chm%AerMass%OCPO(I,J,L) + & + State_Chm%AerMass%OCPI(I,J,L) + & + State_Chm%AerMass%OPOA(I,J,L) + & + State_Chm%AerMass%ISOAAQ(I,J,L) ) * FACTOR ENDDO ENDDO diff --git a/Headers/CMakeLists.txt b/Headers/CMakeLists.txt index 182658af2..08f874186 100755 --- a/Headers/CMakeLists.txt +++ b/Headers/CMakeLists.txt @@ -5,6 +5,7 @@ #---------------------------------------------------------------------------- add_library(Headers STATIC EXCLUDE_FROM_ALL + aermass_container_mod.F90 charpak_mod.F90 CMN_DIAG_mod.F90 CMN_FJX_MOD.F90 diff --git a/Headers/aermass_container_mod.F90 b/Headers/aermass_container_mod.F90 new file mode 100644 index 000000000..a7b0dbea2 --- /dev/null +++ b/Headers/aermass_container_mod.F90 @@ -0,0 +1,482 @@ +!------------------------------------------------------------------------------ +! GEOS-Chem Global Chemical Transport Model ! +!------------------------------------------------------------------------------ +!BOP +! +! !MODULE: aermass_container_mod.F90 +! +! !DESCRIPTION: Module AERMASS\_CONTAINER\_MOD contains the derived type used +! to store aerosol data used for computing optical depths and diagnostics. +!\\ +!\\ +! !INTERFACE: +! +MODULE AerMass_Container_Mod +! +! USES: +! + USE ErrCode_Mod + USE Precision_Mod + + IMPLICIT NONE + PRIVATE +! +! !PUBLIC MEMBER FUNCTIONS: +! + PUBLIC :: Init_AerMass_Container + PUBLIC :: Cleanup_AerMass_Container +! +! !PUBLIC DATA MEMBERS: +! + !========================================================================= + ! Derived type for aerosol data container + !========================================================================= + TYPE, PUBLIC :: AerMassContainer + + ! Arrays + !======================================================================== + ! OCFPOA : OM/OC for POA [unitless] - used in carbon_mod + ! OCFOPOA : OM/OC for OPOA, OCPI, OCPO [unitless] - used in carbon_mod + ! BCPI : Hydrophilic black carbon aerosol [kg/m3] + ! BCPO : Hydrophobic black carbon aerosol [kg/m3] + ! OCPI : Hydrophilic organic carbon aerosol [kg/m3] + ! OCPO : Hydrophobic organic carbon aerosol [kg/m3] + ! OCPISOA : Hydrophilic OC + SOA aerosol [kg/m3] + ! SALA : Accumulation mode seasalt aerosol [kg/m3] + ! ACL : Accumulation mode Cl aerosol [kg/m3] + ! SALC : Coarse mode seasalt aerosol [kg/m3] + ! SO4_NH4_NIT : Lumped SO4-NH4-NIT aerosol [kg/m3] + ! SO4 : Sulfate aerosol [kg/m3] + ! HMS : Hydroxymethane sulfonate aerosol [kg/m3] + ! NH4 : Ammonium aerosol [kg/m3] + ! NIT : Inorganic nitrate aerosol [kg/m3] + ! SLA : Stratospheric liquid aerosol [kg/m3] + ! SPA : Stratospheric particulate aerosol [kg/m3] + ! TSOA : Terpene SOA [kg/m3] + ! ASOA : Aromatic + IVOC SOA [kg/m3] + ! OPOA : Aerosol product of SVOC oxidation [kg/m3] + ! SOAGX : SOA product of GLYX [kg/m3] + ! SOAIE : SOA product of IEPOX & HMML [kg/m3] + ! PM25 : Particulate matter < 2.5 um [kg/m3] + ! PM10 : Particulate matter < 10 um [kg/m3] + ! ISOAAQ : Isoprene SOA (aqueous formation) [kg/m3] + ! SOAS : Simple SOA [kg/m3] + ! FRAC_SNA : + ! DAERSL : Mass of hydrophobic aerosol (Mian Chin) + ! WAERSL : Mass of hydrophilic aerosol (Mian Chin) + !======================================================================== + REAL(fp), ALLOCATABLE :: OCFPOA (:,:) + REAL(fp), ALLOCATABLE :: OCFOPOA (:,:) + REAL(fp), ALLOCATABLE :: BCPI (:,:,:) + REAL(fp), ALLOCATABLE :: BCPO (:,:,:) + REAL(fp), ALLOCATABLE :: OCPI (:,:,:) + REAL(fp), ALLOCATABLE :: OCPO (:,:,:) + REAL(fp), ALLOCATABLE :: OCPISOA (:,:,:) + REAL(fp), ALLOCATABLE :: SALA (:,:,:) + REAL(fp), ALLOCATABLE :: ACL (:,:,:) + REAL(fp), ALLOCATABLE :: SALC (:,:,:) + REAL(fp), ALLOCATABLE :: SO4_NH4_NIT(:,:,:) + REAL(fp), ALLOCATABLE :: SO4 (:,:,:) + REAL(fp), ALLOCATABLE :: HMS (:,:,:) + REAL(fp), ALLOCATABLE :: NH4 (:,:,:) + REAL(fp), ALLOCATABLE :: NIT (:,:,:) + REAL(fp), ALLOCATABLE :: SLA (:,:,:) + REAL(fp), ALLOCATABLE :: SPA (:,:,:) + REAL(fp), ALLOCATABLE :: TSOA (:,:,:) + REAL(fp), ALLOCATABLE :: ASOA (:,:,:) + REAL(fp), ALLOCATABLE :: OPOA (:,:,:) + REAL(fp), ALLOCATABLE :: SOAGX (:,:,:) + REAL(fp), ALLOCATABLE :: PM25 (:,:,:) + REAL(fp), ALLOCATABLE :: PM10 (:,:,:) + REAL(fp), ALLOCATABLE :: ISOAAQ (:,:,:) + REAL(fp), ALLOCATABLE :: SOAS (:,:,:) + REAL(fp), ALLOCATABLE :: FRAC_SNA (:,:,:,:) + REAL(fp), ALLOCATABLE :: DAERSL (:,:,:,:) + REAL(fp), ALLOCATABLE :: WAERSL (:,:,:,:) + + END TYPE AerMassContainer +! +! !REMARKS: +! +! !REVISION HISTORY: +! 28 Mar 2023 - E. Lundgren- Initial version +! See https://github.com/geoschem/geos-chem for complete history +!EOP +!------------------------------------------------------------------------------ +!BOC +! +CONTAINS +!EOC +!------------------------------------------------------------------------------ +! GEOS-Chem Global Chemical Transport Model ! +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: Init_AerMass_Container +! +! !DESCRIPTION: Subroutine INIT\_AER\_Container allocates and initializes +! the Aer container object. +!\\ +!\\ +! !INTERFACE: +! + SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) +! +! !USES: +! + USE CMN_Size_Mod, ONLY : NAER + USE Input_Opt_Mod, ONLY : OptInput + USE State_Grid_Mod, ONLY : GrdState +! +! !INPUT PARAMETERS: +! + TYPE(OptInput), INTENT(IN) :: Input_Opt ! Input Options object + TYPE(GrdState), INTENT(IN) :: State_Grid ! Grid object +! +! !INPUT/OUTPUT PARAMETERS: +! + TYPE(AerMassContainer), POINTER :: Aer ! Aerosol data container +! +! !OUTPUT PARAMETERS: +! + INTEGER, INTENT(OUT) :: RC ! Success or failure? +! +! !REVISION HISTORY: +! 28 Mar 2023 - E. Lundgren- Initial version +! See https://github.com/geoschem/geos-chem for complete history +!EOP +!------------------------------------------------------------------------------ +!BOC +! +! !LOCAL VARIABLES: +! + CHARACTER(LEN=255) :: errMsg, thisLoc + INTEGER :: NX, NY, NZ + + !====================================================================== + ! Init_AerMass_Container starts here + !====================================================================== + + ! Initialize local variables + RC = GC_SUCCESS + thisLoc = ' -> at Init_AerMass_Container (in module Headers/aermass_container_mod.F90)' + NX = State_Grid%NX + NY = State_Grid%NY + NZ = State_Grid%NZ + + ! Exit immediately if this is a dry-run + IF ( Input_Opt%DryRun ) RETURN + + !====================================================================== + ! Initialize arrays + !====================================================================== + + ! OM/OC for POA + ALLOCATE( Aer%OCFPOA( NX, NY ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array OCFPOA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%OCFPOA = 0.0_fp + + ! OM/OC for OPOA, OCPI, OCPO + ALLOCATE( Aer%OCFOPOA( NX, NY ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array OCFOPOA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%OCFOPOA = 0.0_fp + + ALLOCATE( Aer%BCPI( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array BCPI!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%BCPI = 0.0_fp + + ALLOCATE( Aer%BCPO( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array BCPO!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%BCPO = 0.0_fp + + ALLOCATE( Aer%OCPI( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array OCPI!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%OCPI = 0.0_fp + + ALLOCATE( Aer%OCPO( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array OCPO!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%OCPO = 0.0_fp + + ALLOCATE( Aer%OCPISOA( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array OCPISOA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%OCPISOA = 0.0_fp + + ALLOCATE( Aer%SALA( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array SALA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%SALA = 0.0_fp + + ALLOCATE( Aer%SALC( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array SALC!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%SALC = 0.0_fp + + ALLOCATE( Aer%ACL( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array ACL!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%ACL = 0.0_fp + + ALLOCATE( Aer%SO4_NH4_NIT( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array SO4_NH4_NIT!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%SO4_NH4_NIT = 0.0_fp + + ALLOCATE( Aer%SO4( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array SO4!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%SO4 = 0.0_fp + + ! (jmm, 06/30/18) + ALLOCATE( Aer%HMS( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array HMS!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%HMS = 0.0_fp + + ALLOCATE( Aer%NH4( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array NH4!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%NH4 = 0.0_fp + + ALLOCATE( Aer%NIT( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array NIT!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%NIT = 0.0_fp + + ALLOCATE( Aer%SLA( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array SLA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%SLA = 0.0_fp + + ALLOCATE( Aer%SPA( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array SPA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%SPA = 0.0_fp + + ALLOCATE( Aer%TSOA( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array TSOA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%TSOA = 0.0_fp + + ALLOCATE( Aer%ASOA( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array ASOA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%ASOA = 0.0_fp + + ALLOCATE( Aer%OPOA( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array OPOA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%OPOA = 0.0_fp + + ALLOCATE( Aer%PM25( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array PM25!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%PM25 = 0.0_fp + + !zhaisx + ALLOCATE( Aer%PM10( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array PM10!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%PM10 = 0.0_fp + + ALLOCATE( Aer%SOAGX( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array SOAGX!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%SOAGX = 0.0_fp + + ! Mechanistic isoprene SOA (eam, 2014): + ALLOCATE( Aer%ISOAAQ( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array ISOAAQ!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%ISOAAQ = 0.0_fp + + ! Simple SOA + ALLOCATE( Aer%SOAS( NX, NY, NZ ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array SOAS!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%SOAS = 0.0_fp + + ALLOCATE( Aer%FRAC_SNA( NX, NY, NZ, 3 ), & + STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array FRAC_SNA!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%FRAC_SNA = 0.0_fp + + ! Mass of hydrophobic aerosol from Mian Chin + ALLOCATE( Aer%DAERSL( NX, NY, NZ, 2 ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array DAERSL!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%DAERSL = 0.0_fp + + ! Mass of hydrophilic aerosol from Mian Chin + ALLOCATE( Aer%WAERSL( NX, NY, NZ, NAER ), STAT=RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error allocating array WAERSL!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + Aer%WAERSL = 0.0_fp + + END SUBROUTINE Init_AerMass_Container +!EOC +!------------------------------------------------------------------------------ +! GEOS-Chem Global Chemical Transport Model ! +!------------------------------------------------------------------------------ +!BOP +! +! !IROUTINE: Cleanup_AerMass_Container +! +! !DESCRIPTION: Subroutine CLEANUP\_AER\_CONTAINER deallocates all fields +! of the aer container object. +!\\ +!\\ +! !INTERFACE: +! + SUBROUTINE Cleanup_AerMass_Container( Aer, RC ) +! +! !INPUT/OUTPUT PARAMETERS: +! + TYPE(AerMassContainer), POINTER :: Aer ! Aer data container +! +! !OUTPUT PARAMETERS: +! + INTEGER, INTENT(OUT) :: RC ! Return code +! +! !REVISION HISTORY: +! 28 Mar 2023 - E. Lundgren- Initial version +! See https://github.com/geoschem/geos-chem for complete history +!EOP +!------------------------------------------------------------------------------ +!BOC + + !====================================================================== + ! Cleanup_AerMass_Container starts here + !====================================================================== + + ! Assume success + RC = GC_SUCCESS + + ! Deallocate arrays and nullify pointer + IF ( ASSOCIATED( Aer ) ) THEN + IF (ALLOCATED(Aer%OCFPOA )) DEALLOCATE(Aer%OCFPOA ) + IF (ALLOCATED(Aer%OCFOPOA )) DEALLOCATE(Aer%OCFOPOA ) + IF (ALLOCATED(Aer%BCPI )) DEALLOCATE(Aer%BCPI ) + IF (ALLOCATED(Aer%BCPO )) DEALLOCATE(Aer%BCPO ) + IF (ALLOCATED(Aer%OCPI )) DEALLOCATE(Aer%OCPI ) + IF (ALLOCATED(Aer%OCPO )) DEALLOCATE(Aer%OCPO ) + IF (ALLOCATED(Aer%OCPISOA )) DEALLOCATE(Aer%OCPISOA ) + IF (ALLOCATED(Aer%SALA )) DEALLOCATE(Aer%SALA ) + IF (ALLOCATED(Aer%ACL )) DEALLOCATE(Aer%ACL ) + IF (ALLOCATED(Aer%SALC )) DEALLOCATE(Aer%SALC ) + IF (ALLOCATED(Aer%SO4_NH4_NIT )) DEALLOCATE(Aer%SO4_NH4_NIT ) + IF (ALLOCATED(Aer%SO4 )) DEALLOCATE(Aer%SO4 ) + IF (ALLOCATED(Aer%HMS )) DEALLOCATE(Aer%HMS ) + IF (ALLOCATED(Aer%NH4 )) DEALLOCATE(Aer%NH4 ) + IF (ALLOCATED(Aer%NIT )) DEALLOCATE(Aer%NIT ) + IF (ALLOCATED(Aer%SLA )) DEALLOCATE(Aer%SLA ) + IF (ALLOCATED(Aer%SPA )) DEALLOCATE(Aer%SPA ) + IF (ALLOCATED(Aer%TSOA )) DEALLOCATE(Aer%TSOA ) + IF (ALLOCATED(Aer%ASOA )) DEALLOCATE(Aer%ASOA ) + IF (ALLOCATED(Aer%OPOA )) DEALLOCATE(Aer%OPOA ) + IF (ALLOCATED(Aer%SOAGX )) DEALLOCATE(Aer%SOAGX ) + IF (ALLOCATED(Aer%PM25 )) DEALLOCATE(Aer%PM25 ) + IF (ALLOCATED(Aer%PM10 )) DEALLOCATE(Aer%PM10 ) + IF (ALLOCATED(Aer%ISOAAQ )) DEALLOCATE(Aer%ISOAAQ ) + IF (ALLOCATED(Aer%SOAS )) DEALLOCATE(Aer%SOAS ) + IF (ALLOCATED(Aer%FRAC_SNA )) DEALLOCATE(Aer%FRAC_SNA ) + IF (ALLOCATED(Aer%DAERSL )) DEALLOCATE(Aer%DAERSL ) + IF (ALLOCATED(Aer%WAERSL )) DEALLOCATE(Aer%WAERSL ) + Aer => NULL() + ENDIF + + END SUBROUTINE Cleanup_AerMass_Container +!EOC + +END MODULE AerMass_Container_Mod diff --git a/Headers/state_chm_mod.F90 b/Headers/state_chm_mod.F90 index df1a117a9..82901bbbf 100644 --- a/Headers/state_chm_mod.F90 +++ b/Headers/state_chm_mod.F90 @@ -21,6 +21,7 @@ MODULE State_Chm_Mod ! ! USES: ! + USE AerMass_Container_Mod ! Aerosol mass object USE Dictionary_M, ONLY : dictionary_t ! Fortran hash table type USE ErrCode_Mod ! Error handling USE Phot_Container_Mod ! For photolysis state object @@ -142,23 +143,24 @@ MODULE State_Chm_Mod !----------------------------------------------------------------------- ! Aerosol quantities !----------------------------------------------------------------------- - REAL(fp), POINTER :: AeroArea (:,:,:,:) ! Aerosol Area [cm2/cm3] - REAL(fp), POINTER :: AeroRadi (:,:,:,:) ! Aerosol Radius [cm] - REAL(fp), POINTER :: WetAeroArea(:,:,:,:) ! Aerosol Area [cm2/cm3] - REAL(fp), POINTER :: WetAeroRadi(:,:,:,:) ! Aerosol Radius [cm] - REAL(fp), POINTER :: AeroH2O (:,:,:,:) ! Aerosol water [cm3/cm3] - REAL(fp), POINTER :: GammaN2O5 (:,:,:,:) ! N2O5 aerosol uptake [unitless] - REAL(fp), POINTER :: SSAlk (:,:,:,:) ! Sea-salt alkalinity[-] - REAL(fp), POINTER :: H2O2AfterChem(:,:,:) ! H2O2, SO2 [v/v] - REAL(fp), POINTER :: SO2AfterChem (:,:,:) ! after sulfate chem - REAL(fp), POINTER :: OMOC (:,:) ! OM:OC Ratio [unitless] - REAL(fp), POINTER :: OMOC_POA (:,:) ! OM:OC Ratio (OCFPOA) [unitless] - REAL(fp), POINTER :: OMOC_OPOA (:,:) ! OM:OC Ratio (OCFOPOA) [unitless] - REAL(fp), POINTER :: ACLArea (:,:,:) ! Fine Cl- Area [cm2/cm3] - REAL(fp), POINTER :: ACLRadi (:,:,:) ! Fine Cl- Radius [cm] - REAL(fp), POINTER :: QLxpHCloud (:,:,:) ! - REAL(fp), POINTER :: SoilDust (:,:,:,:) ! Soil dust [kg/m3] - REAL(fp), POINTER :: ORVCsesq (:,:,:) ! Sesquiterpenes mass [kg/box] + TYPE(AerMassContainer), POINTER :: AerMass ! Aerosol mass data object + REAL(fp), POINTER :: AeroArea (:,:,:,:) ! Aerosol Area [cm2/cm3] + REAL(fp), POINTER :: AeroRadi (:,:,:,:) ! Aerosol Radius [cm] + REAL(fp), POINTER :: WetAeroArea(:,:,:,:) ! Aerosol Area [cm2/cm3] + REAL(fp), POINTER :: WetAeroRadi(:,:,:,:) ! Aerosol Radius [cm] + REAL(fp), POINTER :: AeroH2O (:,:,:,:) ! Aerosol water [cm3/cm3] + REAL(fp), POINTER :: GammaN2O5 (:,:,:,:) ! N2O5 aerosol uptake [unitless] + REAL(fp), POINTER :: SSAlk (:,:,:,:) ! Sea-salt alkalinity[-] + REAL(fp), POINTER :: H2O2AfterChem(:,:,:) ! H2O2, SO2 [v/v] + REAL(fp), POINTER :: SO2AfterChem (:,:,:) ! after sulfate chem + REAL(fp), POINTER :: OMOC (:,:) ! OM:OC Ratio [unitless] + REAL(fp), POINTER :: OMOC_POA (:,:) ! OM:OC Ratio (OCFPOA) [unitless] + REAL(fp), POINTER :: OMOC_OPOA (:,:) ! OM:OC Ratio (OCFOPOA) [unitless] + REAL(fp), POINTER :: ACLArea (:,:,:) ! Fine Cl- Area [cm2/cm3] + REAL(fp), POINTER :: ACLRadi (:,:,:) ! Fine Cl- Radius [cm] + REAL(fp), POINTER :: QLxpHCloud (:,:,:) ! + REAL(fp), POINTER :: SoilDust (:,:,:,:) ! Soil dust [kg/m3] + REAL(fp), POINTER :: ORVCsesq (:,:,:) ! Sesquiterpenes mass [kg/box] !----------------------------------------------------------------------- ! Fields for nitrogen deposition @@ -505,6 +507,7 @@ SUBROUTINE Zero_State_Chm( State_Chm, RC ) State_Chm%RRTMG_iCld = 0 ! Aerosol and chemistry quantities + State_Chm%AerMass => NULL() State_Chm%AeroArea => NULL() State_Chm%AeroRadi => NULL() State_Chm%WetAeroArea => NULL() @@ -1006,6 +1009,18 @@ SUBROUTINE Init_State_Chm( Input_Opt, State_Chm, State_Grid, RC ) ! Save nAerosol to State_Chm State_Chm%nAeroType = nAerosol + !--------------------------------------------------------------------- + ! Aerosol object + ! NOTE: content is currently not registered + !--------------------------------------------------------------------- + ALLOCATE( State_Chm%AerMass, STAT=RC ) + CALL Init_AerMass_Container( Input_Opt, State_Grid, State_Chm%AerMass, RC ) + IF ( RC /= GC_SUCCESS ) THEN + errMsg = 'Error encountered in "Init_AerMass_Container" routine!' + CALL GC_Error( errMsg, RC, thisLoc ) + RETURN + ENDIF + !--------------------------------------------------------------------- ! AeroArea !--------------------------------------------------------------------- @@ -3184,6 +3199,11 @@ SUBROUTINE Cleanup_State_Chm( State_Chm, RC ) State_Chm%BoundaryCond => NULL() ENDIF + IF ( ASSOCIATED( State_Chm%AerMass ) ) THEN + CALL Cleanup_AerMass_Container(State_Chm%AerMass, RC ) + State_Chm%AerMass => NULL() + ENDIF + IF ( ASSOCIATED( State_Chm%AeroArea ) ) THEN DEALLOCATE( State_Chm%AeroArea, STAT=RC ) CALL GC_CheckVar( 'State_Chm%AeroArea', 2, RC ) diff --git a/Interfaces/GCClassic/main.F90 b/Interfaces/GCClassic/main.F90 index d1573f3da..00bbec0d0 100644 --- a/Interfaces/GCClassic/main.F90 +++ b/Interfaces/GCClassic/main.F90 @@ -61,7 +61,6 @@ PROGRAM GEOS_Chem !-------------------------------------------------------------------------- ! GEOS-Chem chemistry modules !-------------------------------------------------------------------------- - USE AEROSOL_MOD, ONLY : Set_AerMass_Diagnostic USE CARBON_MOD ! For SOA simulation USE CHEMISTRY_MOD ! Driver routines for chemistry USE LINEAR_CHEM_MOD ! For linearized chemistry above chem grid diff --git a/Interfaces/GCHP/gchp_chunk_mod.F90 b/Interfaces/GCHP/gchp_chunk_mod.F90 index ef6b5f890..78ccc01d7 100644 --- a/Interfaces/GCHP/gchp_chunk_mod.F90 +++ b/Interfaces/GCHP/gchp_chunk_mod.F90 @@ -642,11 +642,11 @@ SUBROUTINE GCHP_Chunk_Run( GC, & ! Diagnostics USE Diagnostics_Mod, ONLY : Zero_Diagnostics_StartofTimestep USE Diagnostics_Mod, ONLY : Set_Diagnostics_EndofTimestep + USE Diagnostics_Mod, ONLY : Set_AerMass_Diagnostic #ifdef ADJOINT USE PhysConstants, ONLY : AIRMW USE Diagnostics_Mod, ONLY : Set_SpcAdj_Diagnostic #endif - USE Aerosol_Mod, ONLY : Set_AerMass_Diagnostic #if defined( RRTMG ) USE RRTMG_RAD_TRANSFER_MOD, ONLY : Do_RRTMG_Rad_Transfer From c74a5c512570effe547d0ede9a2930f593c576a6 Mon Sep 17 00:00:00 2001 From: Lizzie Lundgren Date: Fri, 27 Oct 2023 12:57:28 -0400 Subject: [PATCH 2/6] Remove unused oasave.F90 and associated code In updating the aerosol mass arrays I changes code within oasave.F90. However, we actually do not need this anymore since it is for obsolute binary diagnostics. I am thus removing the file and the code that uses it. Signed-off-by: Lizzie Lundgren --- GeosCore/CMakeLists.txt | 1 - GeosCore/carbon_mod.F90 | 5 --- GeosCore/oasave.F90 | 74 ----------------------------------------- 3 files changed, 80 deletions(-) delete mode 100644 GeosCore/oasave.F90 diff --git a/GeosCore/CMakeLists.txt b/GeosCore/CMakeLists.txt index bec3dd154..ef6f232cf 100755 --- a/GeosCore/CMakeLists.txt +++ b/GeosCore/CMakeLists.txt @@ -59,7 +59,6 @@ add_library(GeosCore mixing_mod.F90 modis_lai_mod.F90 ndxx_setup.F90 - oasave.F90 ocean_mercury_mod.F90 olson_landmap_mod.F90 pbl_mix_mod.F90 diff --git a/GeosCore/carbon_mod.F90 b/GeosCore/carbon_mod.F90 index 42c55e8f2..6c5a78cac 100644 --- a/GeosCore/carbon_mod.F90 +++ b/GeosCore/carbon_mod.F90 @@ -897,11 +897,6 @@ SUBROUTINE CHEMCARBON( Input_Opt, State_Chm, State_Diag, & CALL DEBUG_MSG( '### CHEMCARBON: a SOA_CHEM' ) ENDIF -#ifdef BPCH_DIAG - ! NOTE: This is only needed for ND51, ND51b (bmy, 10/4/19) - ! Get total organic aerosol: - CALL OASAVE( SAVEOA, Input_Opt, State_Chm, State_Grid, State_Met, RC ) -#endif ENDIF END SUBROUTINE CHEMCARBON diff --git a/GeosCore/oasave.F90 b/GeosCore/oasave.F90 deleted file mode 100644 index 0b35e15d2..000000000 --- a/GeosCore/oasave.F90 +++ /dev/null @@ -1,74 +0,0 @@ -#ifdef BPCH_DIAG -!------------------------------------------------------------------------------ -! GEOS-Chem Global Chemical Transport Model ! -!------------------------------------------------------------------------------ -!BOP -! -! !ROUTINE: oasave.F90 -! -! !DESCRIPTION: Subroutine OASAVE stores the concentrations of organic aerosols -! for the ND42 diagnostic and for the timeseries and satellite diagnostics -!\\ -!\\ -! !INTERFACE: -! -SUBROUTINE OASAVE( State_Grid, State_Chm ) -! -! !USES: -! - USE State_Chm_Mod, ONLY : ChmState - USE State_Grid_Mod, ONLY : GrdState - USE PRECISION_MOD ! For GEOS-Chem Precision (fp) - USE CMN_O3_MOD, ONLY : SAVEOA - - IMPLICIT NONE -! -! !INPUT PARAMETERS: -! - TYPE(ChmState), INTENT(IN) :: State_Chm ! Chemistry State object - TYPE(GrdState), INTENT(IN) :: State_Grid ! Grid State object -! -! !REVISION HISTORY: -! 10 Jul 2014 - E. A. Marais- Initial version -! See https://github.com/geoschem/geos-chem for complete history -!EOP -!------------------------------------------------------------------------------ -!BOC -! -! !LOCAL VARIABLES: -! - INTEGER :: I, J, L - REAL(fp) :: FACTOR - - !================================================================= - ! OASAVE begins here! - ! - ! Save organic aerosol concentrations - !================================================================= - - ! Conversion factor from kg/m3 --> ug/m3 - FACTOR = 1e+9_fp - - !$OMP PARALLEL DO & - !$OMP DEFAULT( SHARED ) & - !$OMP PRIVATE( I, J, L ) - DO L = 1, State_Grid%NZ - DO J = 1, State_Grid%NY - DO I = 1, State_Grid%NX - - ! Sum of all organic aerosol [ug/m3] - SAVEOA(I,J,L) = SAVEOA(I,J,L) + ( State_Chm%AerMass%TSOA(I,J,L) + & - State_Chm%AerMass%ASOA(I,J,L) + & - State_Chm%AerMass%OCPO(I,J,L) + & - State_Chm%AerMass%OCPI(I,J,L) + & - State_Chm%AerMass%OPOA(I,J,L) + & - State_Chm%AerMass%ISOAAQ(I,J,L) ) * FACTOR - - ENDDO - ENDDO - ENDDO - !$OMP END PARALLEL DO -END SUBROUTINE OASAVE -!EOC -#endif - From 3743ae8eb53288040f7614482ea85ea5f919f9ca Mon Sep 17 00:00:00 2001 From: Lizzie Lundgren Date: Wed, 15 Nov 2023 16:37:33 -0500 Subject: [PATCH 3/6] Change AerMass arrays from allocatable to pointers Signed-off-by: Lizzie Lundgren --- Headers/aermass_container_mod.F90 | 280 +++++++++++++++++++++++------- 1 file changed, 222 insertions(+), 58 deletions(-) diff --git a/Headers/aermass_container_mod.F90 b/Headers/aermass_container_mod.F90 index a7b0dbea2..961aab317 100644 --- a/Headers/aermass_container_mod.F90 +++ b/Headers/aermass_container_mod.F90 @@ -65,34 +65,34 @@ MODULE AerMass_Container_Mod ! DAERSL : Mass of hydrophobic aerosol (Mian Chin) ! WAERSL : Mass of hydrophilic aerosol (Mian Chin) !======================================================================== - REAL(fp), ALLOCATABLE :: OCFPOA (:,:) - REAL(fp), ALLOCATABLE :: OCFOPOA (:,:) - REAL(fp), ALLOCATABLE :: BCPI (:,:,:) - REAL(fp), ALLOCATABLE :: BCPO (:,:,:) - REAL(fp), ALLOCATABLE :: OCPI (:,:,:) - REAL(fp), ALLOCATABLE :: OCPO (:,:,:) - REAL(fp), ALLOCATABLE :: OCPISOA (:,:,:) - REAL(fp), ALLOCATABLE :: SALA (:,:,:) - REAL(fp), ALLOCATABLE :: ACL (:,:,:) - REAL(fp), ALLOCATABLE :: SALC (:,:,:) - REAL(fp), ALLOCATABLE :: SO4_NH4_NIT(:,:,:) - REAL(fp), ALLOCATABLE :: SO4 (:,:,:) - REAL(fp), ALLOCATABLE :: HMS (:,:,:) - REAL(fp), ALLOCATABLE :: NH4 (:,:,:) - REAL(fp), ALLOCATABLE :: NIT (:,:,:) - REAL(fp), ALLOCATABLE :: SLA (:,:,:) - REAL(fp), ALLOCATABLE :: SPA (:,:,:) - REAL(fp), ALLOCATABLE :: TSOA (:,:,:) - REAL(fp), ALLOCATABLE :: ASOA (:,:,:) - REAL(fp), ALLOCATABLE :: OPOA (:,:,:) - REAL(fp), ALLOCATABLE :: SOAGX (:,:,:) - REAL(fp), ALLOCATABLE :: PM25 (:,:,:) - REAL(fp), ALLOCATABLE :: PM10 (:,:,:) - REAL(fp), ALLOCATABLE :: ISOAAQ (:,:,:) - REAL(fp), ALLOCATABLE :: SOAS (:,:,:) - REAL(fp), ALLOCATABLE :: FRAC_SNA (:,:,:,:) - REAL(fp), ALLOCATABLE :: DAERSL (:,:,:,:) - REAL(fp), ALLOCATABLE :: WAERSL (:,:,:,:) + REAL(fp), POINTER :: OCFPOA (:,:) + REAL(fp), POINTER :: OCFOPOA (:,:) + REAL(fp), POINTER :: BCPI (:,:,:) + REAL(fp), POINTER :: BCPO (:,:,:) + REAL(fp), POINTER :: OCPI (:,:,:) + REAL(fp), POINTER :: OCPO (:,:,:) + REAL(fp), POINTER :: OCPISOA (:,:,:) + REAL(fp), POINTER :: SALA (:,:,:) + REAL(fp), POINTER :: ACL (:,:,:) + REAL(fp), POINTER :: SALC (:,:,:) + REAL(fp), POINTER :: SO4_NH4_NIT(:,:,:) + REAL(fp), POINTER :: SO4 (:,:,:) + REAL(fp), POINTER :: HMS (:,:,:) + REAL(fp), POINTER :: NH4 (:,:,:) + REAL(fp), POINTER :: NIT (:,:,:) + REAL(fp), POINTER :: SLA (:,:,:) + REAL(fp), POINTER :: SPA (:,:,:) + REAL(fp), POINTER :: TSOA (:,:,:) + REAL(fp), POINTER :: ASOA (:,:,:) + REAL(fp), POINTER :: OPOA (:,:,:) + REAL(fp), POINTER :: SOAGX (:,:,:) + REAL(fp), POINTER :: PM25 (:,:,:) + REAL(fp), POINTER :: PM10 (:,:,:) + REAL(fp), POINTER :: ISOAAQ (:,:,:) + REAL(fp), POINTER :: SOAS (:,:,:) + REAL(fp), POINTER :: FRAC_SNA (:,:,:,:) + REAL(fp), POINTER :: DAERSL (:,:,:,:) + REAL(fp), POINTER :: WAERSL (:,:,:,:) END TYPE AerMassContainer ! @@ -444,36 +444,200 @@ SUBROUTINE Cleanup_AerMass_Container( Aer, RC ) RC = GC_SUCCESS ! Deallocate arrays and nullify pointer - IF ( ASSOCIATED( Aer ) ) THEN - IF (ALLOCATED(Aer%OCFPOA )) DEALLOCATE(Aer%OCFPOA ) - IF (ALLOCATED(Aer%OCFOPOA )) DEALLOCATE(Aer%OCFOPOA ) - IF (ALLOCATED(Aer%BCPI )) DEALLOCATE(Aer%BCPI ) - IF (ALLOCATED(Aer%BCPO )) DEALLOCATE(Aer%BCPO ) - IF (ALLOCATED(Aer%OCPI )) DEALLOCATE(Aer%OCPI ) - IF (ALLOCATED(Aer%OCPO )) DEALLOCATE(Aer%OCPO ) - IF (ALLOCATED(Aer%OCPISOA )) DEALLOCATE(Aer%OCPISOA ) - IF (ALLOCATED(Aer%SALA )) DEALLOCATE(Aer%SALA ) - IF (ALLOCATED(Aer%ACL )) DEALLOCATE(Aer%ACL ) - IF (ALLOCATED(Aer%SALC )) DEALLOCATE(Aer%SALC ) - IF (ALLOCATED(Aer%SO4_NH4_NIT )) DEALLOCATE(Aer%SO4_NH4_NIT ) - IF (ALLOCATED(Aer%SO4 )) DEALLOCATE(Aer%SO4 ) - IF (ALLOCATED(Aer%HMS )) DEALLOCATE(Aer%HMS ) - IF (ALLOCATED(Aer%NH4 )) DEALLOCATE(Aer%NH4 ) - IF (ALLOCATED(Aer%NIT )) DEALLOCATE(Aer%NIT ) - IF (ALLOCATED(Aer%SLA )) DEALLOCATE(Aer%SLA ) - IF (ALLOCATED(Aer%SPA )) DEALLOCATE(Aer%SPA ) - IF (ALLOCATED(Aer%TSOA )) DEALLOCATE(Aer%TSOA ) - IF (ALLOCATED(Aer%ASOA )) DEALLOCATE(Aer%ASOA ) - IF (ALLOCATED(Aer%OPOA )) DEALLOCATE(Aer%OPOA ) - IF (ALLOCATED(Aer%SOAGX )) DEALLOCATE(Aer%SOAGX ) - IF (ALLOCATED(Aer%PM25 )) DEALLOCATE(Aer%PM25 ) - IF (ALLOCATED(Aer%PM10 )) DEALLOCATE(Aer%PM10 ) - IF (ALLOCATED(Aer%ISOAAQ )) DEALLOCATE(Aer%ISOAAQ ) - IF (ALLOCATED(Aer%SOAS )) DEALLOCATE(Aer%SOAS ) - IF (ALLOCATED(Aer%FRAC_SNA )) DEALLOCATE(Aer%FRAC_SNA ) - IF (ALLOCATED(Aer%DAERSL )) DEALLOCATE(Aer%DAERSL ) - IF (ALLOCATED(Aer%WAERSL )) DEALLOCATE(Aer%WAERSL ) - Aer => NULL() + IF ( ASSOCIATED( Aer%OCFPOA ) ) THEN + DEALLOCATE( Aer%OCFPOA, STAT=RC ) + CALL GC_CheckVar( 'Aer%OCFPOA', 2, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%OCFPOA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%OCFOPOA ) ) THEN + DEALLOCATE( Aer%OCFOPOA, STAT=RC ) + CALL GC_CheckVar( 'Aer%OCFOPOA', 2, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%OCFOPOA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%BCPI ) ) THEN + DEALLOCATE( Aer%BCPI, STAT=RC ) + CALL GC_CheckVar( 'Aer%BCPI', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%BCPI => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%BCPO ) ) THEN + DEALLOCATE( Aer%BCPO, STAT=RC ) + CALL GC_CheckVar( 'Aer%BCPO', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%BCPO => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%OCPI ) ) THEN + DEALLOCATE( Aer%OCPI, STAT=RC ) + CALL GC_CheckVar( 'Aer%OCPI', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%OCPI => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%OCPO ) ) THEN + DEALLOCATE( Aer%OCPO, STAT=RC ) + CALL GC_CheckVar( 'Aer%OCPO', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%OCPO => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%OCPISOA ) ) THEN + DEALLOCATE( Aer%OCPISOA, STAT=RC ) + CALL GC_CheckVar( 'Aer%OCPISOA', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%OCPISOA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%SALA ) ) THEN + DEALLOCATE( Aer%SALA, STAT=RC ) + CALL GC_CheckVar( 'Aer%SALA', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%SALA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%ACL ) ) THEN + DEALLOCATE( Aer%ACL, STAT=RC ) + CALL GC_CheckVar( 'Aer%ACL', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%ACL => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%SALC ) ) THEN + DEALLOCATE( Aer%SALC, STAT=RC ) + CALL GC_CheckVar( 'Aer%SALC', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%SALC => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%SO4_NH4_NIT ) ) THEN + DEALLOCATE( Aer%SO4_NH4_NIT, STAT=RC ) + CALL GC_CheckVar( 'Aer%SO4_NH4_NIT', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%SO4_NH4_NIT => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%SO4 ) ) THEN + DEALLOCATE( Aer%SO4, STAT=RC ) + CALL GC_CheckVar( 'Aer%SO4', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%SO4 => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%HMS ) ) THEN + DEALLOCATE( Aer%HMS, STAT=RC ) + CALL GC_CheckVar( 'Aer%HMS', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%HMS => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%NH4 ) ) THEN + DEALLOCATE( Aer%NH4, STAT=RC ) + CALL GC_CheckVar( 'Aer%NH4', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%NH4 => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%NIT ) ) THEN + DEALLOCATE( Aer%NIT, STAT=RC ) + CALL GC_CheckVar( 'Aer%NIT', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%NIT => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%SLA ) ) THEN + DEALLOCATE( Aer%SLA, STAT=RC ) + CALL GC_CheckVar( 'Aer%SLA', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%SLA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%SPA ) ) THEN + DEALLOCATE( Aer%SPA, STAT=RC ) + CALL GC_CheckVar( 'Aer%SPA', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%SPA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%TSOA ) ) THEN + DEALLOCATE( Aer%TSOA, STAT=RC ) + CALL GC_CheckVar( 'Aer%TSOA', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%TSOA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%ASOA ) ) THEN + DEALLOCATE( Aer%ASOA, STAT=RC ) + CALL GC_CheckVar( 'Aer%ASOA', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%ASOA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%OPOA ) ) THEN + DEALLOCATE( Aer%OPOA, STAT=RC ) + CALL GC_CheckVar( 'Aer%OPOA', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%OPOA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%SOAGX ) ) THEN + DEALLOCATE( Aer%SOAGX, STAT=RC ) + CALL GC_CheckVar( 'Aer%SOAGX', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%SOAGX => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%PM25 ) ) THEN + DEALLOCATE( Aer%PM25, STAT=RC ) + CALL GC_CheckVar( 'Aer%PM25', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%PM25 => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%PM10 ) ) THEN + DEALLOCATE( Aer%PM10, STAT=RC ) + CALL GC_CheckVar( 'Aer%PM10', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%PM10 => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%ISOAAQ ) ) THEN + DEALLOCATE( Aer%ISOAAQ, STAT=RC ) + CALL GC_CheckVar( 'Aer%ISOAAQ', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%ISOAAQ => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%SOAS ) ) THEN + DEALLOCATE( Aer%SOAS, STAT=RC ) + CALL GC_CheckVar( 'Aer%SOAS', 3, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%SOAS => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%FRAC_SNA ) ) THEN + DEALLOCATE( Aer%FRAC_SNA, STAT=RC ) + CALL GC_CheckVar( 'Aer%FRAC_SNA', 4, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%FRAC_SNA => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%DAERSL ) ) THEN + DEALLOCATE( Aer%DAERSL, STAT=RC ) + CALL GC_CheckVar( 'Aer%DAERSL', 4, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%DAERSL => NULL() + ENDIF + + IF ( ASSOCIATED( Aer%WAERSL ) ) THEN + DEALLOCATE( Aer%WAERSL, STAT=RC ) + CALL GC_CheckVar( 'Aer%WAERSL', 4, RC ) + IF ( RC /= GC_SUCCESS ) RETURN + Aer%WAERSL => NULL() ENDIF END SUBROUTINE Cleanup_AerMass_Container From ffcfb72a7fa0a083c03f503332d64b6c65bb7b2c Mon Sep 17 00:00:00 2001 From: Lizzie Lundgren Date: Wed, 15 Nov 2023 17:06:41 -0500 Subject: [PATCH 4/6] Remove unused unit conversion use statement and local variable Signed-off-by: Lizzie Lundgren --- GeosCore/diagnostics_mod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/GeosCore/diagnostics_mod.F90 b/GeosCore/diagnostics_mod.F90 index 596321d40..b923bc05a 100644 --- a/GeosCore/diagnostics_mod.F90 +++ b/GeosCore/diagnostics_mod.F90 @@ -1693,7 +1693,6 @@ SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, & USE State_Grid_Mod, ONLY : GrdState USE State_Met_Mod, ONLY : MetState USE PhysConstants, ONLY : MwCarb - USE UnitConv_Mod, ONLY : Convert_Spc_Units ! ! !INPUT PARAMETERS: ! @@ -1729,7 +1728,6 @@ SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, & INTEGER :: I, J, L ! Strings - CHARACTER(LEN=63) :: OrigUnit CHARACTER(LEN=255) :: ThisLoc CHARACTER(LEN=512) :: ErrMsg From e749e5e0436296889e1ac4278eb001b8767c9214 Mon Sep 17 00:00:00 2001 From: Lizzie Lundgren Date: Wed, 15 Nov 2023 17:14:00 -0500 Subject: [PATCH 5/6] Update changelog and use updated method for unit conversion string checks Signed-off-by: Lizzie Lundgren --- CHANGELOG.md | 1 + GeosCore/diagnostics_mod.F90 | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8815333b..bf1d1ec84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Changed - Added the `-n` aka `--no-bootstrap` option to integration tests to disable bootstrapping missing species in restart files - Use integer parameters for species units instead of strings (for computational efficiency) +- Moved aerosol_mod module variables to new State_Chm container called AerMass ### Fixed - Prevent `POAEMISS` from being assigned a value if not allocated (in `carbon_mod.F90`) diff --git a/GeosCore/diagnostics_mod.F90 b/GeosCore/diagnostics_mod.F90 index b923bc05a..ba47d7472 100644 --- a/GeosCore/diagnostics_mod.F90 +++ b/GeosCore/diagnostics_mod.F90 @@ -1693,6 +1693,7 @@ SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, & USE State_Grid_Mod, ONLY : GrdState USE State_Met_Mod, ONLY : MetState USE PhysConstants, ONLY : MwCarb + USE UnitConv_Mod, ONLY : KG_SPECIES_PER_KG_DRY_AIR, UNIT_STR ! ! !INPUT PARAMETERS: ! @@ -1833,9 +1834,10 @@ SUBROUTINE Set_AerMass_Diagnostic( Input_Opt, State_Chm, State_Diag, & WAERSL => State_Chm%AerMass%WAERSL ! Check that species units are kg/kg dry air - IF ( TRIM( State_Chm%Spc_Units ) /= 'kg/kg dry' ) THEN - CALL GC_Error( 'Incorrect species units: ' // & - State_Chm%Spc_Units, RC, ThisLoc ) + IF ( State_Chm%Spc_Units /= KG_SPECIES_PER_KG_DRY_AIR ) THEN + errMsg = 'State_Chm%Species units must be kg/kg dry. ' // & + 'Incorrect units: '// TRIM( UNIT_STR(State_Chm%Spc_Units ) ) + CALL GC_Error( errMsg, RC, ThisLoc ) RETURN ENDIF From b9d2352716f44d35e710817a9c968924c62d09a7 Mon Sep 17 00:00:00 2001 From: Lizzie Lundgren Date: Wed, 15 Nov 2023 17:23:36 -0500 Subject: [PATCH 6/6] Use GC_CheckVar when allocating aerosol mass container arrays Signed-off-by: Lizzie Lundgren --- Headers/aermass_container_mod.F90 | 83 ++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/Headers/aermass_container_mod.F90 b/Headers/aermass_container_mod.F90 index 961aab317..a8418404f 100644 --- a/Headers/aermass_container_mod.F90 +++ b/Headers/aermass_container_mod.F90 @@ -173,6 +173,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) ! OM/OC for POA ALLOCATE( Aer%OCFPOA( NX, NY ), STAT=RC ) + CALL GC_CheckVar( 'OCFPOA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array OCFPOA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -182,6 +183,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) ! OM/OC for OPOA, OCPI, OCPO ALLOCATE( Aer%OCFOPOA( NX, NY ), STAT=RC ) + CALL GC_CheckVar( 'OCFOPOA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array OCFOPOA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -190,6 +192,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%OCFOPOA = 0.0_fp ALLOCATE( Aer%BCPI( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'BCPI', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array BCPI!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -198,6 +201,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%BCPI = 0.0_fp ALLOCATE( Aer%BCPO( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'BCPO', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array BCPO!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -206,6 +210,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%BCPO = 0.0_fp ALLOCATE( Aer%OCPI( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'OCPI', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array OCPI!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -214,6 +219,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%OCPI = 0.0_fp ALLOCATE( Aer%OCPO( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'OCPO', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array OCPO!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -222,6 +228,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%OCPO = 0.0_fp ALLOCATE( Aer%OCPISOA( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'OCPISOA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array OCPISOA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -230,6 +237,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%OCPISOA = 0.0_fp ALLOCATE( Aer%SALA( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'SALA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array SALA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -238,6 +246,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%SALA = 0.0_fp ALLOCATE( Aer%SALC( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'SALC', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array SALC!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -246,6 +255,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%SALC = 0.0_fp ALLOCATE( Aer%ACL( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'ACL', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array ACL!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -254,6 +264,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%ACL = 0.0_fp ALLOCATE( Aer%SO4_NH4_NIT( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'SO4_NH4_NIT', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array SO4_NH4_NIT!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -262,6 +273,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%SO4_NH4_NIT = 0.0_fp ALLOCATE( Aer%SO4( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'SO4', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array SO4!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -271,6 +283,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) ! (jmm, 06/30/18) ALLOCATE( Aer%HMS( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'HMS', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array HMS!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -279,6 +292,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%HMS = 0.0_fp ALLOCATE( Aer%NH4( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'NH4', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array NH4!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -287,6 +301,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%NH4 = 0.0_fp ALLOCATE( Aer%NIT( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'NIT', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array NIT!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -295,6 +310,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%NIT = 0.0_fp ALLOCATE( Aer%SLA( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'SLA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array SLA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -303,6 +319,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%SLA = 0.0_fp ALLOCATE( Aer%SPA( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'SPA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array SPA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -311,6 +328,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%SPA = 0.0_fp ALLOCATE( Aer%TSOA( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'TSOA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array TSOA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -319,6 +337,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%TSOA = 0.0_fp ALLOCATE( Aer%ASOA( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'ASOA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array ASOA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -327,6 +346,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%ASOA = 0.0_fp ALLOCATE( Aer%OPOA( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'OPOA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array OPOA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -335,6 +355,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%OPOA = 0.0_fp ALLOCATE( Aer%PM25( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'PM25', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array PM25!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -344,6 +365,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) !zhaisx ALLOCATE( Aer%PM10( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'PM10', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array PM10!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -352,6 +374,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) Aer%PM10 = 0.0_fp ALLOCATE( Aer%SOAGX( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'SOAGX', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array SOAGX!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -361,6 +384,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) ! Mechanistic isoprene SOA (eam, 2014): ALLOCATE( Aer%ISOAAQ( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'ISOAAQ', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array ISOAAQ!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -370,6 +394,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) ! Simple SOA ALLOCATE( Aer%SOAS( NX, NY, NZ ), STAT=RC ) + CALL GC_CheckVar( 'SOAS', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array SOAS!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -377,8 +402,8 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) ENDIF Aer%SOAS = 0.0_fp - ALLOCATE( Aer%FRAC_SNA( NX, NY, NZ, 3 ), & - STAT=RC ) + ALLOCATE( Aer%FRAC_SNA( NX, NY, NZ, 3 ), STAT=RC ) + CALL GC_CheckVar( 'FRAC_SNA', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array FRAC_SNA!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -388,6 +413,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) ! Mass of hydrophobic aerosol from Mian Chin ALLOCATE( Aer%DAERSL( NX, NY, NZ, 2 ), STAT=RC ) + CALL GC_CheckVar( 'DAERSL', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array DAERSL!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -397,6 +423,7 @@ SUBROUTINE Init_AerMass_Container( Input_Opt, State_Grid, Aer, RC ) ! Mass of hydrophilic aerosol from Mian Chin ALLOCATE( Aer%WAERSL( NX, NY, NZ, NAER ), STAT=RC ) + CALL GC_CheckVar( 'WAERSL', 0, RC ) IF ( RC /= GC_SUCCESS ) THEN errMsg = 'Error allocating array WAERSL!' CALL GC_Error( errMsg, RC, thisLoc ) @@ -460,182 +487,182 @@ SUBROUTINE Cleanup_AerMass_Container( Aer, RC ) IF ( ASSOCIATED( Aer%BCPI ) ) THEN DEALLOCATE( Aer%BCPI, STAT=RC ) - CALL GC_CheckVar( 'Aer%BCPI', 3, RC ) + CALL GC_CheckVar( 'Aer%BCPI', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%BCPI => NULL() ENDIF IF ( ASSOCIATED( Aer%BCPO ) ) THEN DEALLOCATE( Aer%BCPO, STAT=RC ) - CALL GC_CheckVar( 'Aer%BCPO', 3, RC ) + CALL GC_CheckVar( 'Aer%BCPO', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%BCPO => NULL() ENDIF IF ( ASSOCIATED( Aer%OCPI ) ) THEN DEALLOCATE( Aer%OCPI, STAT=RC ) - CALL GC_CheckVar( 'Aer%OCPI', 3, RC ) + CALL GC_CheckVar( 'Aer%OCPI', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%OCPI => NULL() ENDIF IF ( ASSOCIATED( Aer%OCPO ) ) THEN DEALLOCATE( Aer%OCPO, STAT=RC ) - CALL GC_CheckVar( 'Aer%OCPO', 3, RC ) + CALL GC_CheckVar( 'Aer%OCPO', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%OCPO => NULL() ENDIF IF ( ASSOCIATED( Aer%OCPISOA ) ) THEN DEALLOCATE( Aer%OCPISOA, STAT=RC ) - CALL GC_CheckVar( 'Aer%OCPISOA', 3, RC ) + CALL GC_CheckVar( 'Aer%OCPISOA', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%OCPISOA => NULL() ENDIF IF ( ASSOCIATED( Aer%SALA ) ) THEN DEALLOCATE( Aer%SALA, STAT=RC ) - CALL GC_CheckVar( 'Aer%SALA', 3, RC ) + CALL GC_CheckVar( 'Aer%SALA', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%SALA => NULL() ENDIF IF ( ASSOCIATED( Aer%ACL ) ) THEN DEALLOCATE( Aer%ACL, STAT=RC ) - CALL GC_CheckVar( 'Aer%ACL', 3, RC ) + CALL GC_CheckVar( 'Aer%ACL', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%ACL => NULL() ENDIF IF ( ASSOCIATED( Aer%SALC ) ) THEN DEALLOCATE( Aer%SALC, STAT=RC ) - CALL GC_CheckVar( 'Aer%SALC', 3, RC ) + CALL GC_CheckVar( 'Aer%SALC', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%SALC => NULL() ENDIF IF ( ASSOCIATED( Aer%SO4_NH4_NIT ) ) THEN DEALLOCATE( Aer%SO4_NH4_NIT, STAT=RC ) - CALL GC_CheckVar( 'Aer%SO4_NH4_NIT', 3, RC ) + CALL GC_CheckVar( 'Aer%SO4_NH4_NIT', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%SO4_NH4_NIT => NULL() ENDIF IF ( ASSOCIATED( Aer%SO4 ) ) THEN DEALLOCATE( Aer%SO4, STAT=RC ) - CALL GC_CheckVar( 'Aer%SO4', 3, RC ) + CALL GC_CheckVar( 'Aer%SO4', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%SO4 => NULL() ENDIF IF ( ASSOCIATED( Aer%HMS ) ) THEN DEALLOCATE( Aer%HMS, STAT=RC ) - CALL GC_CheckVar( 'Aer%HMS', 3, RC ) + CALL GC_CheckVar( 'Aer%HMS', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%HMS => NULL() ENDIF IF ( ASSOCIATED( Aer%NH4 ) ) THEN DEALLOCATE( Aer%NH4, STAT=RC ) - CALL GC_CheckVar( 'Aer%NH4', 3, RC ) + CALL GC_CheckVar( 'Aer%NH4', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%NH4 => NULL() ENDIF IF ( ASSOCIATED( Aer%NIT ) ) THEN DEALLOCATE( Aer%NIT, STAT=RC ) - CALL GC_CheckVar( 'Aer%NIT', 3, RC ) + CALL GC_CheckVar( 'Aer%NIT', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%NIT => NULL() ENDIF IF ( ASSOCIATED( Aer%SLA ) ) THEN DEALLOCATE( Aer%SLA, STAT=RC ) - CALL GC_CheckVar( 'Aer%SLA', 3, RC ) + CALL GC_CheckVar( 'Aer%SLA', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%SLA => NULL() ENDIF IF ( ASSOCIATED( Aer%SPA ) ) THEN DEALLOCATE( Aer%SPA, STAT=RC ) - CALL GC_CheckVar( 'Aer%SPA', 3, RC ) + CALL GC_CheckVar( 'Aer%SPA', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%SPA => NULL() ENDIF IF ( ASSOCIATED( Aer%TSOA ) ) THEN DEALLOCATE( Aer%TSOA, STAT=RC ) - CALL GC_CheckVar( 'Aer%TSOA', 3, RC ) + CALL GC_CheckVar( 'Aer%TSOA', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%TSOA => NULL() ENDIF IF ( ASSOCIATED( Aer%ASOA ) ) THEN DEALLOCATE( Aer%ASOA, STAT=RC ) - CALL GC_CheckVar( 'Aer%ASOA', 3, RC ) + CALL GC_CheckVar( 'Aer%ASOA', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%ASOA => NULL() ENDIF IF ( ASSOCIATED( Aer%OPOA ) ) THEN DEALLOCATE( Aer%OPOA, STAT=RC ) - CALL GC_CheckVar( 'Aer%OPOA', 3, RC ) + CALL GC_CheckVar( 'Aer%OPOA', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%OPOA => NULL() ENDIF IF ( ASSOCIATED( Aer%SOAGX ) ) THEN DEALLOCATE( Aer%SOAGX, STAT=RC ) - CALL GC_CheckVar( 'Aer%SOAGX', 3, RC ) + CALL GC_CheckVar( 'Aer%SOAGX', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%SOAGX => NULL() ENDIF IF ( ASSOCIATED( Aer%PM25 ) ) THEN DEALLOCATE( Aer%PM25, STAT=RC ) - CALL GC_CheckVar( 'Aer%PM25', 3, RC ) + CALL GC_CheckVar( 'Aer%PM25', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%PM25 => NULL() ENDIF IF ( ASSOCIATED( Aer%PM10 ) ) THEN DEALLOCATE( Aer%PM10, STAT=RC ) - CALL GC_CheckVar( 'Aer%PM10', 3, RC ) + CALL GC_CheckVar( 'Aer%PM10', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%PM10 => NULL() ENDIF IF ( ASSOCIATED( Aer%ISOAAQ ) ) THEN DEALLOCATE( Aer%ISOAAQ, STAT=RC ) - CALL GC_CheckVar( 'Aer%ISOAAQ', 3, RC ) + CALL GC_CheckVar( 'Aer%ISOAAQ', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%ISOAAQ => NULL() ENDIF IF ( ASSOCIATED( Aer%SOAS ) ) THEN DEALLOCATE( Aer%SOAS, STAT=RC ) - CALL GC_CheckVar( 'Aer%SOAS', 3, RC ) + CALL GC_CheckVar( 'Aer%SOAS', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%SOAS => NULL() ENDIF IF ( ASSOCIATED( Aer%FRAC_SNA ) ) THEN DEALLOCATE( Aer%FRAC_SNA, STAT=RC ) - CALL GC_CheckVar( 'Aer%FRAC_SNA', 4, RC ) + CALL GC_CheckVar( 'Aer%FRAC_SNA', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%FRAC_SNA => NULL() ENDIF IF ( ASSOCIATED( Aer%DAERSL ) ) THEN DEALLOCATE( Aer%DAERSL, STAT=RC ) - CALL GC_CheckVar( 'Aer%DAERSL', 4, RC ) + CALL GC_CheckVar( 'Aer%DAERSL', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%DAERSL => NULL() ENDIF IF ( ASSOCIATED( Aer%WAERSL ) ) THEN DEALLOCATE( Aer%WAERSL, STAT=RC ) - CALL GC_CheckVar( 'Aer%WAERSL', 4, RC ) + CALL GC_CheckVar( 'Aer%WAERSL', 2, RC ) IF ( RC /= GC_SUCCESS ) RETURN Aer%WAERSL => NULL() ENDIF