From cca2d416a4d6814e96bc433d210c3dd2d4ed2394 Mon Sep 17 00:00:00 2001 From: Megan He Date: Thu, 14 May 2026 18:29:05 -0400 Subject: [PATCH] Add brown carbon (BrC) with photolysis --- GeosCore/aerosol_mod.F90 | 25 ++++++++-- GeosCore/carbon_mod.F90 | 3 +- GeosCore/cldj_interface_mod.F90 | 64 +++++++++++++++++++++----- GeosCore/input_mod.F90 | 2 +- GeosCore/photolysis_mod.F90 | 2 +- Headers/CMN_SIZE_mod.F90 | 2 +- Headers/state_chm_mod.F90 | 47 +++++++++++++++---- KPP/fullchem/commonIncludeVars.H | 14 +++--- KPP/fullchem/fullchem_RateLawFuncs.F90 | 8 ++-- 9 files changed, 130 insertions(+), 37 deletions(-) diff --git a/GeosCore/aerosol_mod.F90 b/GeosCore/aerosol_mod.F90 index 0ab93bf8f7..2eea7b605b 100644 --- a/GeosCore/aerosol_mod.F90 +++ b/GeosCore/aerosol_mod.F90 @@ -92,12 +92,13 @@ MODULE AEROSOL_MOD INTEGER :: id_ASOA1, id_ASOA2, id_ASOA3, id_DUST01 INTEGER :: id_SOAS, id_SALACL, id_HMS, id_SOAGX INTEGER :: id_SOAIE, id_INDIOL, id_LVOCOA + INTEGER :: id_BrC ! Index to map between NRHAER and species database hygroscopic species ! NOTE: Increasing value of NRHAER in CMN_SIZE_Mod.F90 (e.g. if there is ! a new hygroscopic species) requires manual update of this mapping ! (ewl, 1/23/17) - INTEGER :: Map_NRHAER(5) + INTEGER :: Map_NRHAER(6) CONTAINS @@ -122,6 +123,7 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & ! ! !USES: ! + USE CMN_SIZE_Mod, ONLY : NRHAER USE ErrCode_Mod USE ERROR_MOD @@ -529,6 +531,17 @@ SUBROUTINE AEROSOL_CONC( Input_Opt, State_Chm, State_Diag, & * State_chm%AerMass%OCFOPOA(I,J) / AIRVOL(I,J,L) ENDIF + ! BrC [kg/m3] + ! Species concentrations are KG_SPECIES within AEROSOL_CONC. (MH,5/6/26) + IF ( NRHAER == 6 ) THEN + State_Chm%AerMass%WAERSL(I,J,L,6) = 0.0_fp + IF ( id_BrC > 0 ) THEN + State_Chm%AerMass%WAERSL(I,J,L,6) = & + State_Chm%AerMass%WAERSL(I,J,L,6) + & + Spc(id_BrC)%Conc(I,J,L) / AIRVOL(I,J,L) + ENDIF + ENDIF + ! Now avoid division by zero (bmy, 4/20/04) 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 ) @@ -1460,6 +1473,9 @@ SUBROUTINE RDAER( Input_Opt, State_Chm, State_Diag, State_Grid, State_Met, & ENDIF MSDENS(4) = State_Chm%SpcData(id_SALA)%Info%Density MSDENS(5) = State_Chm%SpcData(id_SALC)%Info%Density + IF ( NRHAER == 6 .and. id_BrC > 0 ) THEN + MSDENS(6) = State_Chm%SpcData(id_BrC)%Info%Density + ENDIF ! These default values unused (actively retrieved from ucx_mod) MSDENS(NRHAER+1) = 1700.0d0 ! SSA/STS @@ -2473,6 +2489,7 @@ SUBROUTINE Init_Aerosol( Input_Opt, State_Chm, State_Diag, State_Grid, RC ) id_NIT = Ind_( 'NIT' ) id_OCPO = Ind_( 'OCPO' ) id_OCPI = Ind_( 'OCPI' ) + id_BrC = Ind_( 'BRC' ) id_SOAS = Ind_( 'SOAS' ) id_SALA = Ind_( 'SALA' ) id_SALC = Ind_( 'SALC' ) @@ -2544,9 +2561,11 @@ SUBROUTINE Init_Aerosol( Input_Opt, State_Chm, State_Diag, State_Grid, RC ) Map_NRHAER(N) = 4 CASE ( 'SALC' ) Map_NRHAER(N) = 5 + CASE ( 'BRC' ) + Map_NRHAER(N) = 6 CASE DEFAULT ErrMsg = 'WARNING: aerosol diagnostics not defined' // & - ' for NRHAER greater than 5!' + ' for NRHAER greater than 6!' CALL GC_ERROR( ErrMsg, RC, 'Init_Aerosol in aerosol_mod.F90' ) SpcInfo => NULL() RETURN @@ -2739,7 +2758,7 @@ SUBROUTINE RD_AOD( Input_Opt, State_Chm, RC ) ! info but ref index is similar e.g. Scarchilli et al. (2005) !(DAR 05/2015) SPECFIL = (/ "so4.dat ", "soot.dat ", "org.dat ", "ssa.dat ", & - "ssc.dat ", "h2so4.dat", "h2so4.dat", "dust.dat " /) + "ssc.dat ", "brc.dat ", "h2so4.dat", "dust.dat " /) ! Loop over the array of filenames DO k = 1, State_Chm%Phot%NSPAA diff --git a/GeosCore/carbon_mod.F90 b/GeosCore/carbon_mod.F90 index 158534d4cb..d70759165e 100644 --- a/GeosCore/carbon_mod.F90 +++ b/GeosCore/carbon_mod.F90 @@ -272,7 +272,7 @@ MODULE CARBON_MOD INTEGER :: id_TSOG3, id_XYLE, id_LBRO2N, id_LBRO2H, id_LTRO2N INTEGER :: id_LTRO2H, id_LXRO2N, id_LXRO2H, id_LNRO2N, id_LNRO2H INTEGER :: id_LISOPOH, id_LISOPNO3 - INTEGER :: id_SOAS, id_SOAP + INTEGER :: id_SOAS, id_SOAP, id_BRC #ifdef APM REAL(fp), ALLOCATABLE :: BCCONVNEW(:,:,:) @@ -7676,6 +7676,7 @@ SUBROUTINE INIT_CARBON( Input_Opt, State_Chm, State_Diag, State_Grid, RC ) id_OH = IND_('OH' ) id_OCPO = IND_('OCPO' ) id_OCPI = IND_('OCPI' ) + id_BRC = IND_('BRC' ) id_OPOA1 = IND_('OPOA1' ) id_OPOG1 = IND_('OPOG1' ) id_OPOA2 = IND_('OPOA2' ) diff --git a/GeosCore/cldj_interface_mod.F90 b/GeosCore/cldj_interface_mod.F90 index 2ed7193cdb..bc08f5273c 100644 --- a/GeosCore/cldj_interface_mod.F90 +++ b/GeosCore/cldj_interface_mod.F90 @@ -221,7 +221,7 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & ! CHARACTER(LEN=255) :: ErrMsg, ThisLoc INTEGER :: A, I, J, L, K, N, S, MaxLev, RH_ind - INTEGER :: SO4_ind, BC_ind, OC_ind, SALA_ind, SALC_ind + INTEGER :: SO4_ind, BC_ind, OC_ind, SALA_ind, SALC_ind, BrC_ind INTEGER :: S_rh0, S_rhx, K_rh0, K_rhx, ind_1000 REAL(8) :: MW_g, BoxHt, Delta_P, IWC, LWC REAL(8) :: FRAC, RAA_eff, QAA_eff, SAA_eff @@ -314,11 +314,13 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & REAL(fp) :: SPHU_kgkg REAL(fp) :: H2O_kgkgdry REAL(fp) :: MW_kg + REAL(fp) :: BrC_kgm3 ! Species ids INTEGER, SAVE :: id_H2O INTEGER, SAVE :: id_O3 INTEGER, SAVE :: id_SO4 + INTEGER, SAVE :: id_BRC ! Index for Cloud-J prints if GEOS-Chem verbose is on INTEGER :: I_PRT, J_PRT @@ -364,6 +366,7 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & OC_ind = 3 SALA_ind = 4 SALC_ind = 5 + BrC_ind = 6 ! Relative humidities in FJX_spec-aer.dat RH_lut(1) = 0.d0 @@ -392,6 +395,7 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & id_H2O = Ind_('H2O') id_O3 = Ind_('O3') id_SO4 = Ind_('SO4') + id_BRC = Ind_('BRC') IF ( id_O3 <= 0 ) THEN ErrMsg = 'O3 is not a defined species but is required for Cloud-J photolysis!' CALL GC_Error( ErrMsg, RC, ThisLoc ) @@ -671,7 +675,7 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & IF ( Input_Opt%LSULF .AND. State_Met%InTroposphere(I,J,L) ) THEN ! Get indexes to optical property LUT - S_rh0 = 3 + NDUST + NRHAER*(SO4_ind-1) + 1 ! SO4 index for RH=0 in NDXAER + S_rh0 = 3 + NDUST + NRH*(SO4_ind-1) + 1 ! SO4 index for RH=0 in NDXAER S_rhx = S_rh0 + RH_ind - 1 ! Sulfate index for this RH K_rh0 = NDXAER(L,S_rh0) ! index for RH=0 in FJX_spec-aer.dat K_rhx = NDXAER(L,S_rhx) ! index for this RH in FJX_spec-aer.dat @@ -707,7 +711,7 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & !---------------------------------------------------- ! Get indexes to optical property LUT - S_rh0 = 3 + NDUST + NRHAER*(BC_ind-1) + 1 ! BC index for RH=0 in NDXAER + S_rh0 = 3 + NDUST + NRH*(BC_ind-1) + 1 ! BC index for RH=0 in NDXAER S_rhx = S_rh0 + RH_ind - 1 ! BC index for this RH K_rh0 = NDXAER(L,S_rh0) ! index for RH=0 in FJX_spec-aer.dat K_rhx = NDXAER(L,S_rhx) ! index for this RH in FJX_spec-aer.dat @@ -756,7 +760,7 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & !---------------------------------------------------- ! Get indexes to optical property LUT - S_rh0 = 3 + NDUST + NRHAER*(OC_ind-1) + 1 ! OC index for RH=0 in NDXAER + S_rh0 = 3 + NDUST + NRH*(OC_ind-1) + 1 ! OC index for RH=0 in NDXAER S_rhx = S_rh0 + RH_ind - 1 ! OC index for this RH K_rh0 = NDXAER(L,S_rh0) ! index for RH=0 in FJX_spec-aer.dat K_rhx = NDXAER(L,S_rhx) ! index for this RH in FJX_spec-aer.dat @@ -781,6 +785,42 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & * dry_to_wet_factor * Q_interp_factor / R_interp_factor ) ) & * 1.d3 * BoxHt + !---------------------------------------------------- + ! Brown carbon (Hammer et al. 2016), MH 5/6/26 + !---------------------------------------------------- + + ! Get indexes to optical property LUT + S_rh0 = 3 + NDUST + NRH*(BrC_ind-1) + 1 ! BrC index for RH=0 in NDXAER + S_rhx = S_rh0 + RH_ind - 1 + K_rh0 = NDXAER(L,S_rh0) + K_rhx = NDXAER(L,S_rhx) + + ! Get interpolated effective radius and extinction for RH in this grid box + IF ( RH_ind == NRH ) THEN + RAA_eff = RAA(K_rhx) + QAA_eff = QAA(ind_1000,K_rhx) + ELSE + FRAC = ( State_Met%RH(I,J,L) - RH_lut(RH_ind) ) & + / ( RH_lut(RH_ind+1) - RH_lut(RH_ind) ) + RAA_eff = RAA(K_rhx) + FRAC * ( RAA(K_rhx+1) - RAA(K_rhx) ) + QAA_eff = QAA(ind_1000,K_rhx) + FRAC * ( QAA(ind_1000,K_rhx+1) - QAA(ind_1000,K_rhx) ) + ENDIF + dry_to_wet_factor = ( RAA_eff / RAA(K_rh0) )**3 + R_interp_factor = RAA_eff / RAA(K_rhx) + Q_interp_factor = QAA_eff / QAA(ind_1000,K_rhx) + + BrC_kgm3 = 0.d0 + IF ( id_BRC > 0 ) THEN + BrC_kgm3 = State_Chm%Species(id_BRC)%Conc(I,J,L) & + * State_Chm%SpcData(id_BRC)%Info%MW_g & + / AVO * 1.d3 + ENDIF + + ! BrC is hygroscopic. Set concentration, converting [dry kg/m3] -> [wet g/m2] + AERSP(L,S_rhx) = BrC_kgm3 * dry_to_wet_factor & + * Q_interp_factor / R_interp_factor & + * 1.d3 * BoxHt + ENDIF !---------------------------------------------------- @@ -794,7 +834,7 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & !---------------------------------------------------- ! Get indexes to optical property LUT - S_rh0 = 3 + NDUST + NRHAER*(SALA_ind-1) + 1 ! SALA index for RH=0 in NDXAER + S_rh0 = 3 + NDUST + NRH*(SALA_ind-1) + 1 ! SALA index for RH=0 in NDXAER S_rhx = S_rh0 + RH_ind - 1 ! SALA index for this RH K_rh0 = NDXAER(L,S_rh0) ! index for RH=0 in FJX_spec-aer.dat K_rhx = NDXAER(L,S_rhx) ! index for this RH in FJX_spec-aer.dat @@ -822,7 +862,7 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & !---------------------------------------------------- ! Get indexes to optical property LUT - S_rh0 = 3 + NDUST + NRHAER*(SALC_ind-1) + 1 ! SALC index for RH=0 in NDXAER + S_rh0 = 3 + NDUST + NRH*(SALC_ind-1) + 1 ! SALC index for RH=0 in NDXAER S_rhx = S_rh0 + RH_ind - 1 ! SALC index for this RH K_rh0 = NDXAER(L,S_rh0) ! index for RH=0 in FJX_spec-aer.dat K_rhx = NDXAER(L,S_rhx) ! index for this RH in FJX_spec-aer.dat @@ -859,14 +899,14 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & ! depth computed in GEOS-Chem is non-zero. ! SSA/LBS/STS - IF ( State_Chm%Phot%ODAER(I,J,L,State_Chm%Phot%IWV1000,6) > 0._fp ) THEN - AERSP(L,36) = State_Chm%Species(id_SO4)%Conc(I,J,L) & + IF ( State_Chm%Phot%ODAER(I,J,L,State_Chm%Phot%IWV1000,7) > 0._fp ) THEN + AERSP(L,41) = State_Chm%Species(id_SO4)%Conc(I,J,L) & * MW_g / AVO * BoxHt * 1e+6_fp ENDIF ! NAT/ice PSCs - IF ( State_Chm%Phot%ODAER(I,J,L,State_Chm%Phot%IWV1000,7) > 0._fp ) THEN - AERSP(L,37) = State_Chm%Species(id_SO4)%Conc(I,J,L) & + IF ( State_Chm%Phot%ODAER(I,J,L,State_Chm%Phot%IWV1000,8) > 0._fp ) THEN + AERSP(L,42) = State_Chm%Species(id_SO4)%Conc(I,J,L) & * MW_g / AVO * BoxHt * 1e+6_fp ENDIF @@ -887,8 +927,8 @@ SUBROUTINE Run_CloudJ( Input_Opt, State_Chm, State_Diag, & !IF ( .NOT. use_oc ) AERSP(:,21:25) = 0.d0 !IF ( .NOT. use_sala ) AERSP(:,26:30) = 0.d0 !IF ( .NOT. use_salc ) AERSP(:,31:35) = 0.d0 - !IF ( .NOT. use_stratso4 ) AERSP(:,36) = 0.d0 - !IF ( .NOT. use_psc ) AERSP(:,37) = 0.d0 + !IF ( .NOT. use_stratso4 ) AERSP(:,41) = 0.d0 + !IF ( .NOT. use_psc ) AERSP(:,42) = 0.d0 !----------------------------------------------------------------- ! Set remaining inputs needed for Cloud_JX diff --git a/GeosCore/input_mod.F90 b/GeosCore/input_mod.F90 index d481a5d989..a64b427b82 100644 --- a/GeosCore/input_mod.F90 +++ b/GeosCore/input_mod.F90 @@ -1650,7 +1650,7 @@ SUBROUTINE Config_Aerosol( Config, Input_Opt, RC ) !------------------------------------------------------------------------ ! Use brown carbon aerosols? !------------------------------------------------------------------------ - key = "aerosols%carbon%use_brown_carbon" + key = "aerosols%carbon%brown_carbon" v_bool = MISSING_BOOL CALL QFYAML_Add_Get( Config, TRIM( key ), v_bool, "", RC ) IF ( RC /= GC_SUCCESS ) THEN diff --git a/GeosCore/photolysis_mod.F90 b/GeosCore/photolysis_mod.F90 index c3f4056a1f..df9b558ef0 100644 --- a/GeosCore/photolysis_mod.F90 +++ b/GeosCore/photolysis_mod.F90 @@ -838,7 +838,7 @@ SUBROUTINE SET_AER( Input_Opt, State_Chm, RC ) MIEDX => State_Chm%Phot%MIEDX ! Taken from aerosol_mod.F - IND = (/22,29,36,43,50/) + IND = (/22,29,36,43,50,57/) DO I=1,AN_ MIEDX(I) = 0 diff --git a/Headers/CMN_SIZE_mod.F90 b/Headers/CMN_SIZE_mod.F90 index ec588c0d40..4f0d93c16b 100644 --- a/Headers/CMN_SIZE_mod.F90 +++ b/Headers/CMN_SIZE_mod.F90 @@ -43,7 +43,7 @@ MODULE CMN_SIZE_MOD INTEGER, PARAMETER :: NDUST = 7 ! Number of aerosols undergoing hygroscopic growth - INTEGER, PARAMETER :: NRHAER = 5 + INTEGER, PARAMETER :: NRHAER = 6 ! Number of stratospheric aerosols (SDE 04/17/13) INTEGER, PARAMETER :: NSTRATAER = 2 diff --git a/Headers/state_chm_mod.F90 b/Headers/state_chm_mod.F90 index 0ed0b8f71b..7647213557 100644 --- a/Headers/state_chm_mod.F90 +++ b/Headers/state_chm_mod.F90 @@ -712,7 +712,7 @@ SUBROUTINE Init_State_Chm( Input_Opt, State_Chm, State_Grid, & CHARACTER(LEN=255) :: chmId, thisLoc ! String arrays - CHARACTER(LEN=31) :: fieldId(14) + CHARACTER(LEN=31) :: fieldId(15) ! Objects TYPE(Species), POINTER :: ThisSpc @@ -1053,7 +1053,9 @@ SUBROUTINE Init_State_Chm( Input_Opt, State_Chm, State_Grid, & 'AeroAreaMDUST7 ', 'AeroAreaSULF ', & 'AeroAreaBC ', 'AeroAreaOC ', & 'AeroAreaSSA ', 'AeroAreaSSC ', & - 'AeroAreaBGSULF ', 'AeroAreaICEI ' /) + 'AeroAreaBRC ', 'AeroAreaBGSULF ', & + 'AeroAreaICEI ' /) + ! Allocate and register each field individually DO N = 1, State_Chm%nAeroType @@ -1083,7 +1085,8 @@ SUBROUTINE Init_State_Chm( Input_Opt, State_Chm, State_Grid, & 'AeroRadiMDUST7 ', 'AeroRadiSULF ', & 'AeroRadiBC ', 'AeroRadiOC ', & 'AeroRadiSSA ', 'AeroRadiSSC ', & - 'AeroRadiBGSULF ', 'AeroRadiICEI ' /) + 'AeroRadiBRC ', 'AeroRadiBGSULF ', & + 'AeroRadiICEI ' /) ! Allocate and register each field individually DO N = 1, State_Chm%nAeroType @@ -1113,7 +1116,8 @@ SUBROUTINE Init_State_Chm( Input_Opt, State_Chm, State_Grid, & 'WetAeroAreaMDUST7', 'WetAeroAreaSULF ', & 'WetAeroAreaBC ', 'WetAeroAreaOC ', & 'WetAeroAreaSSA ', 'WetAeroAreaSSC ', & - 'WetAeroAreaBGSULF', 'WetAeroAreaICEI ' /) + 'WetAeroAreaBRC ', 'WetAeroAreaBGSULF', & + 'WetAeroAreaICEI ' /) ! Allocate and register each field individually DO N = 1, State_Chm%nAeroType @@ -1143,7 +1147,8 @@ SUBROUTINE Init_State_Chm( Input_Opt, State_Chm, State_Grid, & 'WetAeroRadiMDUST7', 'WetAeroRadiSULF ', & 'WetAeroRadiBC ', 'WetAeroRadiOC ', & 'WetAeroRadiSSA ', 'WetAeroRadiSSC ', & - 'WetAeroRadiBGSULF', 'WetAeroRadiICEI ' /) + 'WetAeroRadiBRC ', 'WetAeroRadiBGSULF', & + 'WetAeroRadiICEI ' /) ! Allocate and register each field individually DO N = 1, State_Chm%nAeroType @@ -1173,8 +1178,8 @@ SUBROUTINE Init_State_Chm( Input_Opt, State_Chm, State_Grid, & 'AeroH2OMDUST7 ', 'AeroH2OSNA ', & 'AeroH2OBC ', 'AeroH2OOC ', & 'AeroH2OSSA ', 'AeroH2OSSC ', & - 'AeroH2OBGSULF ', 'AeroH2OICEI ' /) - + 'AeroH2OBrC ', 'AeroH2OBGSULF ', & + 'AeroH2OICEI ' /) ! Allocate and register each field individually DO N = 1, State_Chm%nAeroType CALL Init_and_Register( & @@ -1792,7 +1797,8 @@ SUBROUTINE Init_State_Chm( Input_Opt, State_Chm, State_Grid, & 'KhetiSLABrNO3HCl ', 'KhetiSLAHOClHCl ', & 'KhetiSLAHOClHBr ', 'KhetiSLAHOBrHCl ', & 'KhetiSLAHOBrHBr ', ' ', & - ' ', ' ' /) + ' ', ' ', & + ' ' /) ! Allocate and register each field individually nKHLSA = 11 @@ -4062,6 +4068,11 @@ SUBROUTINE Get_Metadata_State_Chm( am_I_Root, metadataID, Found, & IF ( isUnits ) Units = 'cm2 cm-3' IF ( isRank ) Rank = 3 + CASE ( 'AEROAREABRC' ) + IF ( isDesc ) Desc = 'Dry aerosol area for brown carbon' + IF ( isUnits ) Units = 'cm2 cm-3' + IF ( isRank ) Rank = 3 + CASE ( 'AEROAREABGSULF' ) IF ( isDesc ) Desc = 'Dry aerosol area for background' & // ' stratospheric sulfate' @@ -4138,6 +4149,11 @@ SUBROUTINE Get_Metadata_State_Chm( am_I_Root, metadataID, Found, & IF ( isUnits ) Units = 'cm' IF ( isRank ) Rank = 3 + CASE ( 'AERORADIBRC' ) + IF ( isDesc ) Desc = 'Dry aerosol radius for brown carbon' + IF ( isUnits ) Units = 'cm' + IF ( isRank ) Rank = 3 + CASE ( 'AERORADIBGSULF' ) IF ( isDesc ) Desc = 'Dry aerosol radius for background' & // ' stratospheric sulfate' @@ -4184,6 +4200,11 @@ SUBROUTINE Get_Metadata_State_Chm( am_I_Root, metadataID, Found, & IF ( isDesc ) Desc = 'Wet aerosol area for mineral dust (4.0 um)' IF ( isUnits ) Units = 'cm2 cm-3' IF ( isRank ) Rank = 3 + + CASE ( 'WETAEROAREABRC' ) + IF ( isDesc ) Desc = 'Wet aerosol area for brown carbon' + IF ( isUnits ) Units = 'cm2 cm-3' + IF ( isRank ) Rank = 3 CASE ( 'WETAEROAREASULF' ) IF ( isDesc ) Desc = 'Wet aerosol area for tropospheric sulfate' @@ -4258,6 +4279,11 @@ SUBROUTINE Get_Metadata_State_Chm( am_I_Root, metadataID, Found, & IF ( isUnits ) Units = 'cm' IF ( isRank ) Rank = 3 + CASE ( 'WETAERORADIBRC' ) + IF ( isDesc ) Desc = 'Wet aerosol radius for brown carbon' + IF ( isUnits ) Units = 'cm' + IF ( isRank ) Rank = 3 + CASE ( 'WETAERORADISULF' ) IF ( isDesc ) Desc = 'Wet aerosol radius for tropospheric sulfate' IF ( isUnits ) Units = 'cm' @@ -4355,6 +4381,11 @@ SUBROUTINE Get_Metadata_State_Chm( am_I_Root, metadataID, Found, & IF ( isUnits ) Units = 'cm3(H2O) cm-3(air)' IF ( isRank ) Rank = 3 + CASE ( 'AEROH2OBRC' ) + IF ( isDesc ) Desc = 'Aerosol H2O content for brown carbon' + IF ( isUnits ) Units = 'cm3(H2O) cm-3(air)' + IF ( isRank ) Rank = 3 + CASE ( 'AEROH2OSNA' ) IF ( isDesc ) Desc = 'Sulfur-nitrogen-ammonia aerosol water content' IF ( isUnits ) Units = 'cm3(H2O) cm-3(air)' diff --git a/KPP/fullchem/commonIncludeVars.H b/KPP/fullchem/commonIncludeVars.H index ea4dfc164b..50bce4ff54 100644 --- a/KPP/fullchem/commonIncludeVars.H +++ b/KPP/fullchem/commonIncludeVars.H @@ -94,8 +94,8 @@ !$OMP THREADPRIVATE( K_CLD ) ! Liquid water conversion factor - ! - Size = number of aerosol types (nAeroType) - REAL(dp) :: CVFAC(14) + ! - Size = number of aerosol types (nAeroType = 15 with BrC aerosol) + REAL(dp) :: CVFAC(15) !$OMP THREADPRIVATE( CVFAC ) ! Proton activity [unitless] and H+ concentration [M] @@ -191,11 +191,11 @@ REAL(dp) :: vAir ! Volume of air [cm3] REAL(dp) :: vIce ! Ice volume [cm3] REAL(dp) :: vLiq ! Liquid volume [cm3] - REAL(dp) :: wetArea(14) ! Aerosol specific wet sfc area [cm2/cm3] - REAL(dp) :: xArea(14) ! Aerosol specific sfc area [cm2/cm3] - REAL(dp) :: xH2O(14) ! Aerosol water content [cm3/cm3] - REAL(dp) :: xRadi(14) ! Aerosol effective radius [cm] - REAL(dp) :: xVol(14) ! Aerosol specific volume [cm3/cm3] + REAL(dp) :: wetArea(15) ! Aerosol specific wet sfc area [cm2/cm3] + REAL(dp) :: xArea(15) ! Aerosol specific sfc area [cm2/cm3] + REAL(dp) :: xH2O(15) ! Aerosol water content [cm3/cm3] + REAL(dp) :: xRadi(15) ! Aerosol effective radius [cm] + REAL(dp) :: xVol(15) ! Aerosol specific volume [cm3/cm3] ! ! Additional fields only used by the Hg simulation ! diff --git a/KPP/fullchem/fullchem_RateLawFuncs.F90 b/KPP/fullchem/fullchem_RateLawFuncs.F90 index 246289eee4..3eca54b898 100644 --- a/KPP/fullchem/fullchem_RateLawFuncs.F90 +++ b/KPP/fullchem/fullchem_RateLawFuncs.F90 @@ -25,7 +25,7 @@ MODULE fullchem_RateLawFuncs ! ! !DEFINED PARAMETERS: ! - ! Indices for aerosol type (1 .. NAEROTYPE=14) + ! Indices for aerosol type (1 .. NAEROTYPE=15) INTEGER, PRIVATE, PARAMETER :: DU1 = 1 ! Dust (Reff = 0.151 um) INTEGER, PRIVATE, PARAMETER :: DU2 = 2 ! Dust (Reff = 0.253 um) INTEGER, PRIVATE, PARAMETER :: DU3 = 3 ! Dust (Reff = 0.402 um) @@ -38,8 +38,9 @@ MODULE fullchem_RateLawFuncs INTEGER, PRIVATE, PARAMETER :: ORC = 10 ! Organic Carbon INTEGER, PRIVATE, PARAMETER :: SSA = 11 ! Accum-mode sea salt INTEGER, PRIVATE, PARAMETER :: SSC = 12 ! Coarse-mode sea salt - INTEGER, PRIVATE, PARAMETER :: SLA = 13 ! Strat sulfate liq aer - INTEGER, PRIVATE, PARAMETER :: IIC = 14 ! Irregular ice cloud + INTEGER, PRIVATE, PARAMETER :: BRC = 13 ! Brown carbon + INTEGER, PRIVATE, PARAMETER :: SLA = 14 ! Strat sulfate liq aer + INTEGER, PRIVATE, PARAMETER :: IIC = 15 ! Irregular ice cloud ! Indices for Fine and Coarse sea-salt indices INTEGER, PRIVATE, PARAMETER :: SS_FINE = 1 @@ -1481,6 +1482,7 @@ FUNCTION HO2uptk1stOrd( H ) RESULT( k ) k = k + Ars_L1k( H%xArea(ORC), H%xRadi(ORC), H%gamma_HO2, srMw ) k = k + Ars_L1k( H%xArea(SSA), H%xRadi(SSA), H%gamma_HO2, srMw ) k = k + Ars_L1k( H%xArea(SSC), H%xRadi(SSC), H%gamma_HO2, srMw ) + k = k + Ars_L1k( H%xArea(BRC), H%xRadi(BRC), H%gamma_HO2, srMw ) END FUNCTION HO2uptk1stOrd !=========================================================================