6556 lines
239 KiB
Fortran
6556 lines
239 KiB
Fortran
! $Id: carbon_mod.f,v 1.4 2011/02/23 00:08:48 daven Exp $
|
|
MODULE CARBON_MOD
|
|
!
|
|
!******************************************************************************
|
|
! Module CARBON_MOD contains arrays and routines for performing a
|
|
! carbonaceous aerosol simulation. Original code taken from Mian Chin's
|
|
! GOCART model and modified accordingly. (rjp, bmy, 4/2/04, 2/19/09)
|
|
!
|
|
! 4 Aerosol species : Organic and Black carbon
|
|
! : hydrophilic (soluble) and hydrophobic of each
|
|
! For secondary organic aerosol (SOA) simulation orginal code developed
|
|
! by Chung and Seinfeld [2002] and Hong Liao from John Seinfeld's group
|
|
! at Caltech was taken and further modified accordingly (rjp, bmy, 7/15/04)
|
|
! This simulation introduces additional following species:
|
|
! ALPH, LIMO, ALCO, SOA1, SOA2, SOA3, SOA4, SOG1, SOG2, SOG3, SOG4
|
|
!
|
|
! References for BC/OC emissions:
|
|
! --------------------------------
|
|
! Bond, T.C. et al.: Historical emissions of black and organic carbon
|
|
! aerosol fromenergy-related combustion, 1850-2000, Global Biogeochem. Cycles,
|
|
! 21 GB2018, doi: 10.1029/2006GB002840, 2007.
|
|
!
|
|
! Base Year is 2000. More at http://www.hiwater.org
|
|
!
|
|
! Module Variables:
|
|
! ============================================================================
|
|
! (1 ) ANTH_BLKC (REAL*8 ) : BC anthropogenic emissions [kg C ]
|
|
! (2 ) ANTH_ORGC (REAL*8 ) : OC anthropogenic emissions [kg C ]
|
|
! (3 ) APROD (REAL*8 ) : Aerosol mass ratio
|
|
! (4 ) BCCONV (REAL*8 ) : Hydrophilic BC from Hydrophobic [kg C ]
|
|
! (5 ) BIOB_BLKC (REAL*8 ) : BC biomass emissions [kg C ]
|
|
! (6 ) BIOB_ORGC (REAL*8 ) : OC biomass emissions [kg C ]
|
|
! (7 ) BIOF_BLKC (REAL*8 ) : BC biofuel emissions [kg C ]
|
|
! (8 ) BIOF_ORGC (REAL*8 ) : OC biofuel emissions [kg C ]
|
|
! (9 ) BIOG_ALPH (REAL*8 ) : A-PINENE biogenic emissions [kg]
|
|
! (10) BIOG_LIMO (REAL*8 ) : LIMONENE biogenic emissions [kg]
|
|
! (11) BIOG_ALCO (REAL*8 ) : ALCOHOL biogenic emissions [kg]
|
|
! (12) BIOG_TERP (REAL*8 ) : TERPENE biogenic emissions [kg]
|
|
! (13) BIOG_SESQ (REAL*8 ) : SESQTERPENE biogenic emissions [kg]
|
|
! (14) DIUR_ORVC (REAL*8 ) : Diurnal variation of NVOC [kg C]
|
|
! (15) DRYBCPI (INTEGER) : Index for BCPI in drydep array
|
|
! (16) DRYOCPI (INTEGER) : Index for OCPI in drydep array
|
|
! (17) DRYBCPO (INTEGER) : Index for BCPO in drydep array
|
|
! (18) DRYOCPO (INTEGER) : Index for OCPO in drydep array
|
|
! (19) DRYALPH (INTEGER) : Index for ALPH in drydep array
|
|
! (20) DRYLIMO (INTEGER) : Index for LIMO in drydep array
|
|
! (21) DRYALCO (INTEGER) : Index for ALCO in drydep array
|
|
! (22) DRYSOG1 (INTEGER) : Index for SOG1 in drydep array
|
|
! (23) DRYSOG2 (INTEGER) : Index for SOG2 in drydep array
|
|
! (24) DRYSOG3 (INTEGER) : Index for SOG3 in drydep array
|
|
! (25) DRYSOA1 (INTEGER) : Index for SOA1 in drydep array
|
|
! (26) DRYSOA2 (INTEGER) : Index for SOA2 in drydep array
|
|
! (27) DRYSOA3 (INTEGER) : Index for SOA3 in drydep array
|
|
! (28) EF_BLKC (REAL*8 ) : Emission factors for BC [kg/kg]
|
|
! (29) EF_ORGC (REAL*8 ) : Emission factors for OC [kg/kg]
|
|
! (30) GEIA_ORVC (REAL*8 ) : NVOC emissions from GEIA [kg C ]
|
|
! (31) I1_NA (REAL*8 ) : Starting lon index for N. America region
|
|
! (32) I2_NA (REAL*8 ) : Ending lon index for N. America region
|
|
! (33) J1_NA (REAL*8 ) : Starting lat index for N. America region
|
|
! (34) J2_NA (REAL*8 ) : Ending lat index for N. America region
|
|
! (35) GPROD (REAL*8 ) : Gas mass ratio
|
|
! (36) MHC (INTEGER) : Number of VOC clasees
|
|
! (37) NDAYS (INTEGER) : Array w/ number of days per month
|
|
! (38) NPROD (INTEGER) : Number of products by oxdation
|
|
! (39) OCCONV (REAL*8 ) : Hydrophilic OC from Hydrophobic [kg C ]
|
|
! (40) ORVC_SESQ (REAL*8 ) : SESQTERPENE concentration [kg]
|
|
! (41) ORVC_TERP (REAL*8 ) : MONOTERPENES concentration [kg]
|
|
! (42) TCOSZ (REAL*8 ) : Summing array for SUNCOS
|
|
! (43) TERP_ORGC (REAL*8 ) : Lumped terpene emissions [kg C ]
|
|
! (44) SMALLNUM (REAL*8 ) : A small positive number
|
|
! (45) USE_BOND_BIOBURN (LOGICAL) : Flag to use annual biomass emiss.
|
|
!
|
|
! Module Routines:
|
|
! ============================================================================
|
|
! (1 ) CHEMCARBON : Driver program for carbon aerosol chemistry
|
|
! (2 ) CHEM_BCPO : Chemistry routine for hydrophobic BC (aka EC)
|
|
! (3 ) CHEM_BCPI : Chemistry routine for hydrophilic BC (aka EC)
|
|
! (4 ) CHEM_OCPO : Chemistry routine for hydrophobic OC
|
|
! (5 ) CHEM_OCPI : Chemistry routine for hydrophilic OC
|
|
! (6 ) SOA_CHEMISTRY : Driver routine for SOA chemistry
|
|
! (7 ) SOA_EQUIL : Determines mass of SOA
|
|
! (8 ) ZEROIN : Finds root of an equation by bisection method
|
|
! (9 ) SOA_PARA : Gets SOA yield parameters
|
|
! (10) CHEM_NVOC : Computes oxidation of HC by O3, OH, NO3
|
|
! (11) SOA_PARTITION : Partitions mass of SOA gas & aerosol tracers
|
|
! (12) SOA_LUMP : Returns organic gas & aerosol back to STT
|
|
! (13) SOA_DEPO : Performs dry deposition of SOA tracers & species
|
|
! (14) EMISSCARBON : Driver routine for carbon aerosol emissions
|
|
! (15) BIOGENIC_OC : Computes biogenic OC [each time step]
|
|
! (16) ANTHRO_CARB_TBOND : Computes anthropogenic OC/EC [annual data]
|
|
! (17) ANTHRO_CARB_COOKE : Computes anthropogenic OC/EC [monthly data]
|
|
! (18) BIOMASS_CARB_TBOND : Computes biomass burning OC/EC [annual data]
|
|
! (19) BIOMASS_CARB_GEOS : Computes biomass burning OC/EC [monthly data]
|
|
! (20) EMITHIGH : Computes complete mixing of emission within PBL
|
|
! (21) OHNO3TIME : Computes the sum of the cosine of SZA
|
|
! (22) GET_OH : Returns monthly-mean OH conc. at grid box (I,J,L)
|
|
! (23) GET_NO3 : Returns monthly-mean O3 conc. at grid box (I,J,L)
|
|
! (24) GET_O3 : Returns monthly-mean NO3 conc. at grid box (I,J,L)
|
|
! (25) GET_DOH : Returns ISOP lost to rxn w/ OH at grid box (I,J,L)
|
|
! (26) INIT_CARBON : Allocates and zeroes all module arrays
|
|
! (27) CLEANUP_CARBON : Deallocates all module arrays
|
|
!
|
|
! NOTE: Choose either (16) or (17) for ANTHROPOGENIC emission
|
|
! Choose either (18) or (19) for BIOMASS BURNING emission.
|
|
!
|
|
! GEOS-CHEM modules referenced by carbon_mod.f
|
|
! ============================================================================
|
|
! (1 ) bpch2_mod.f : Module w/ routines for binary punch file I/O
|
|
! (2 ) dao_mod.f : Module w/ arrays for DAO met fields
|
|
! (3 ) diag_mod.f : Module w/ GEOS-CHEM diagnostic arrays
|
|
! (4 ) directory_mod.f : Module w/ GEOS-CHEM data & met field dirs
|
|
! (5 ) drydep_mod.f : Module w/ routines for dry deposition
|
|
! (6 ) error_mod.f : Module w/ I/O error and NaN check routines
|
|
! (7 ) global_no3_mod.f : Module w/ routines to read 3-D NO3 field
|
|
! (8 ) global_oh_mod.f : Module w/ routines to read 3-D OH field
|
|
! (9 ) global_o3_mod.f : Module w/ routines to read 3-D O3 field
|
|
! (10) grid_mod.f : Module w/ horizontal grid information
|
|
! (11) logical_mod.f : Module w/ GEOS-CHEM logical switches
|
|
! (12) megan_mod.f : Module w/ routines to read MEGAN biogenic emiss
|
|
! (13) pbl_mix_mod.f : Module w/ routines for PBL height & mixing
|
|
! (14) pressure_mod.f : Module w/ routines to compute P(I,J,L)
|
|
! (15) time_mod.f : Module w/ routines for computing time & date
|
|
! (16) tracer_mod.f : Module w/ GEOS-CHEM tracer array STT etc.
|
|
! (17) tracerid_mod.f : Module w/ pointers to tracers & emissions
|
|
! (18) transfer_mod.f : Module w/ routines to cast & resize arrays
|
|
!
|
|
! NOTES:
|
|
! (1 ) Added code from the Caltech group for SOA chemistry (rjp, bmy, 7/15/04)
|
|
! (2 ) Now references "directory_mod.f", "logical_mod.f", "tracer_mod.f".
|
|
! (bmy, 7/20/04)
|
|
! (3 ) Now read data from carbon_200411/ subdir of DATA_DIR. Also added
|
|
! some extra debug output. Now read T. Bond yearly emissions as
|
|
! default, but overwrite N. America with the monthly Cooke/RJP
|
|
! emissions. Added module variables I1_NA, I2_NA, J1_NA, J2_NA.
|
|
! (rjp, bmy, 12/1/04)
|
|
! (4 ) Now can read seasonal or interannual BCPO, OCPO biomass emissions.
|
|
! Also parallelize loop in OHNO3TIME. (rjp, bmy, 1/18/05)
|
|
! (5 ) Now references "pbl_mix_mod.f". Bug fix: now make sure only to save
|
|
! up to LD07 levels for the ND07 diagnostic in SOA_LUMP. (bmy, 3/4/05)
|
|
! (6 ) Now can read data for both GEOS and GCAP grids (bmy, 8/16/05)
|
|
! (7 ) Now make sure all USE statements are USE, ONLY (bmy, 10/3/05)
|
|
! (8 ) Now references "megan_mod.f". Also now references XNUMOL and
|
|
! XNUMOLAIR from "tracer_mod.f" (tmf, bmy, 10/25/05)
|
|
! (9 ) Bug fix for GCAP in BIOGENIC_OC (bmy, 4/11/06)
|
|
! (10) Updated for SOA production from ISOP (dkh, bmy, 5/22/06)
|
|
! (11) Updated for IPCC future emission scale factors. Also added function
|
|
! GET_DOH to return ISOP that has reacted w/ OH. (swu, dkh, bmy, 6/1/06)
|
|
! (12) Now add SOG condensation onto SO4, NH4, NIT (rjp, bmy, 8/3/06)
|
|
! (13) Minor fix for 20 carbon tracers. (phs, 9/14/06)
|
|
! (14) Now remove reading of biomass emissions from "carbon_mod.f", since
|
|
! they are better done in gc_biomass_mod.f. This will allow us to
|
|
! standardize treatment of GFED2 or default BB emissions. Also applied
|
|
! a typo fix in SOA_LUMP. (tmf, bmy, 10/16/06)
|
|
! (15) Prevent seg fault error in BIOMASS_CARB_GEOS (bmy, 11/3/06)
|
|
! (16) Corrected typos in SOA_LUMP. Now also save GPROD and APROD to disk
|
|
! for each new diagnostic interval. (dkh, tmv, havala, bmy, 2/6/07)
|
|
! (17) Modifications for 0.5 x 0.666 nested grids (yxw, dan, bmy, 11/6/08)
|
|
! (18) Now account for various GFED2 products (yc, phs, 12/23/08)
|
|
! (19) Now add future scaling to BIOMASS_CARB_GEOS (hotp, swu, 2/19/09)
|
|
! (20) Added SOA production from dicarbonyls (tmf, 3/2/09)
|
|
! (21) Bugfix: cleanup ORVC_TERP and ORVC_SESQ (tmf, 3/2/09)
|
|
! (22) Replace USE_MONTHLY_BIOB with USE_BOND_BIOBURN, since this hardwired
|
|
! flag is a switc b/w annual Bond biomass burning emissions, and default
|
|
! GC source, which can be monthly/8 days/3hr.
|
|
! Implement changes for reading new Bond files (eml, phs, 5/18/09)
|
|
! (23) Add option for non-local PBL scheme (lin, 06/09/08)
|
|
! (24) Modified to include GFED3 (psk, 1/5/11)
|
|
!******************************************************************************
|
|
!
|
|
IMPLICIT NONE
|
|
|
|
!=================================================================
|
|
! MODULE PRIVATE DECLARATIONS -- keep certain internal variables
|
|
! and routines from being seen outside "carbon_mod.f"
|
|
!=================================================================
|
|
|
|
! Declare everything PRIVATE ...
|
|
PRIVATE
|
|
|
|
! ... except these routines
|
|
PUBLIC :: CHEMCARBON
|
|
PUBLIC :: CLEANUP_CARBON
|
|
PUBLIC :: EMISSCARBON
|
|
PUBLIC :: WRITE_GPROD_APROD
|
|
PUBLIC :: BIOMASS_CARB_GEOS !lzhang
|
|
|
|
! adj_group: make these public (dkh, 09/09/09)
|
|
PUBLIC :: DRYBCPI, DRYOCPI, DRYBCPO, DRYOCPO
|
|
! ... and these (dkh, 11/11/09)
|
|
PUBLIC :: ANTH_ORGC, ANTH_BLKC, BIOB_ORGC, BIOB_BLKC
|
|
PUBLIC :: BIOF_ORGC, BIOF_BLKC
|
|
|
|
!=================================================================
|
|
! MODULE VARIABLES
|
|
!=================================================================
|
|
|
|
! Scalars
|
|
!LOGICAL :: USE_MONTHLY_BIOB = .TRUE.
|
|
LOGICAL :: USE_BOND_BIOBURN = .FALSE.
|
|
INTEGER :: DRYBCPI, DRYOCPI, DRYBCPO, DRYOCPO
|
|
INTEGER :: DRYALPH, DRYLIMO, DRYALCO
|
|
INTEGER :: DRYSOG1, DRYSOG2, DRYSOG3, DRYSOG4
|
|
INTEGER :: DRYSOA1, DRYSOA2, DRYSOA3, DRYSOA4
|
|
INTEGER :: I1_NA, J1_NA
|
|
INTEGER :: I2_NA, J2_NA
|
|
INTEGER :: DRYSOAG, DRYSOAM
|
|
|
|
! Parameters
|
|
INTEGER, PARAMETER :: MHC = 6
|
|
INTEGER, PARAMETER :: NPROD = 3
|
|
REAL*8, PARAMETER :: SMALLNUM = 1d-20
|
|
|
|
! Arrays
|
|
REAL*8, ALLOCATABLE :: ANTH_BLKC(:,:,:)
|
|
REAL*8, ALLOCATABLE :: ANTH_ORGC(:,:,:)
|
|
REAL*8, ALLOCATABLE :: BIOB_BLKC(:,:,:)
|
|
REAL*8, ALLOCATABLE :: BIOB_ORGC(:,:,:)
|
|
REAL*8, ALLOCATABLE :: BIOF_BLKC(:,:,:)
|
|
REAL*8, ALLOCATABLE :: BIOF_ORGC(:,:,:)
|
|
REAL*8, ALLOCATABLE :: EF_BLKC(:,:)
|
|
REAL*8, ALLOCATABLE :: EF_ORGC(:,:)
|
|
REAL*8, ALLOCATABLE :: TERP_ORGC(:,:)
|
|
REAL*8, ALLOCATABLE :: BCCONV(:,:,:)
|
|
REAL*8, ALLOCATABLE :: OCCONV(:,:,:)
|
|
REAL*8, ALLOCATABLE :: BIOG_ALPH(:,:)
|
|
REAL*8, ALLOCATABLE :: BIOG_LIMO(:,:)
|
|
REAL*8, ALLOCATABLE :: BIOG_ALCO(:,:)
|
|
REAL*8, ALLOCATABLE :: BIOG_TERP(:,:)
|
|
REAL*8, ALLOCATABLE :: BIOG_SESQ(:,:)
|
|
REAL*8, ALLOCATABLE :: DIUR_ORVC(:,:)
|
|
REAL*8, ALLOCATABLE :: GEIA_ORVC(:,:)
|
|
REAL*8, ALLOCATABLE :: TCOSZ(:,:)
|
|
REAL*8, ALLOCATABLE :: ORVC_SESQ(:,:,:)
|
|
REAL*8, ALLOCATABLE :: ORVC_TERP(:,:,:)
|
|
REAL*8, ALLOCATABLE :: GPROD(:,:,:,:,:)
|
|
REAL*8, ALLOCATABLE :: APROD(:,:,:,:,:)
|
|
! Cloud fraction - for cloud droplet uptake of dicarbonyls
|
|
! (tmf, 12/07/07)
|
|
REAL*8, ALLOCATABLE :: VCLDF(:,:,:)
|
|
|
|
! Days per month (based on 1998)
|
|
INTEGER :: NDAYS(12) = (/ 31, 28, 31, 30, 31, 30,
|
|
& 31, 31, 30, 31, 30, 31 /)
|
|
|
|
!=================================================================
|
|
! MODULE ROUTINES -- follow below the "CONTAINS" statement
|
|
!=================================================================
|
|
CONTAINS
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE CHEMCARBON
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine CHEMCARBON is the interface between the GEOS-CHEM main program
|
|
! and the carbon aerosol chemistry routines that calculates dry deposition,
|
|
! chemical conversion between hydrophilic and hydrophobic, and SOA production.
|
|
! (rjp, bmy, 4/1/04, 9/14/06)
|
|
!
|
|
! NOTES:
|
|
! (1 ) Added code from the Caltech group for SOA chemistry. Also now
|
|
! reference "global_oh_mod.f", "global_o3_mod.f", "global_no3_mod.f".
|
|
! (rjp, bmy, 7/8/04)
|
|
! (2 ) Now reference LSOA and LEMIS from CMN_SETUP. Now only call OHNO3TIME
|
|
! if it hasn't been done before w/in EMISSCARBON. (rjp, bmy, 7/15/04)
|
|
! (3 ) Now reference LSOA, LEMIS, LPRT from "logical_mod.f". Now reference
|
|
! STT and ITS_AN_AEROSOL_SIM from "tracer_mod.f" (bmy, 7/20/04)
|
|
! (4 ) Now make sure all USE statements are USE, ONLY (bmy, 10/3/05)
|
|
! (5 ) Now updated for SOA production from ISOP. (dkh, bmy, 6/1/06)
|
|
! (6 ) Bug fix for aerosol sim w/ 20 tracers (phs, 9/14/06)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DRYDEP_MOD, ONLY : DEPNAME, NUMDEP
|
|
USE ERROR_MOD, ONLY : DEBUG_MSG
|
|
USE GLOBAL_OH_MOD, ONLY : GET_GLOBAL_OH
|
|
USE GLOBAL_NO3_MOD, ONLY : GET_GLOBAL_NO3
|
|
USE GLOBAL_O3_MOD, ONLY : GET_GLOBAL_O3
|
|
USE LOGICAL_MOD, ONLY : LSOA, LEMIS, LPRT
|
|
USE TIME_MOD, ONLY : GET_MONTH, ITS_A_NEW_MONTH
|
|
USE TRACER_MOD, ONLY : STT, ITS_AN_AEROSOL_SIM
|
|
USE TRACERID_MOD, ONLY : IDTBCPI, IDTBCPO, IDTOCPI
|
|
USE TRACERID_MOD, ONLY : IDTOCPO, IDTSOG4, IDTSOA4
|
|
USE TRACERID_MOD, ONLY : IDTSOAG, IDTSOAM
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Local variables
|
|
LOGICAL, SAVE :: FIRSTCHEM = .TRUE.
|
|
INTEGER :: N, THISMONTH
|
|
|
|
!=================================================================
|
|
! CHEMCARBON begins here!
|
|
!=================================================================
|
|
|
|
! First-time initialization
|
|
IF ( FIRSTCHEM ) THEN
|
|
|
|
! Initialize arrays (if not already done before)
|
|
CALL INIT_CARBON
|
|
|
|
! Find drydep species in DEPSAV
|
|
DO N = 1, NUMDEP
|
|
SELECT CASE ( TRIM( DEPNAME(N) ) )
|
|
CASE ( 'BCPI' )
|
|
DRYBCPI = N
|
|
CASE ( 'OCPI' )
|
|
DRYOCPI = N
|
|
CASE ( 'BCPO' )
|
|
DRYBCPO = N
|
|
CASE ( 'OCPO' )
|
|
DRYOCPO = N
|
|
CASE ( 'ALPH' )
|
|
DRYALPH = N
|
|
CASE ( 'LIMO' )
|
|
DRYLIMO = N
|
|
CASE ( 'ALCO' )
|
|
DRYALCO = N
|
|
CASE ( 'SOG1' )
|
|
DRYSOG1 = N
|
|
CASE ( 'SOG2' )
|
|
DRYSOG2 = N
|
|
CASE ( 'SOG3' )
|
|
DRYSOG3 = N
|
|
CASE ( 'SOG4' )
|
|
DRYSOG4 = N
|
|
CASE ( 'SOA1' )
|
|
DRYSOA1 = N
|
|
CASE ( 'SOA2' )
|
|
DRYSOA2 = N
|
|
CASE ( 'SOA3' )
|
|
DRYSOA3 = N
|
|
CASE ( 'SOA4' )
|
|
DRYSOA4 = N
|
|
CASE ( 'SOAG' )
|
|
DRYSOAG = N
|
|
CASE ( 'SOAM' )
|
|
DRYSOAM = N
|
|
CASE DEFAULT
|
|
! Nothing
|
|
END SELECT
|
|
ENDDO
|
|
|
|
! Zero SOG4 and SOA4 (SOA from ISOP in gas & aerosol form)
|
|
! for offline aerosol simulations. Eventually we should have
|
|
! archived isoprene oxidation fields available for offline
|
|
! simulations but for now we just set them to zero.
|
|
! (dkh, bmy, 6/1/06)
|
|
IF ( ITS_AN_AEROSOL_SIM() ) THEN
|
|
|
|
! temp fix for aerosol w/ 20 tracers simulation (phs)
|
|
IF ( IDTSOG4 .NE. 0 ) THEN
|
|
STT(:,:,:,IDTSOG4) = 0d0
|
|
STT(:,:,:,IDTSOA4) = 0d0
|
|
ENDIF
|
|
ENDIF
|
|
|
|
! Reset first-time flag
|
|
FIRSTCHEM = .FALSE.
|
|
ENDIF
|
|
|
|
!=================================================================
|
|
! Do chemistry for carbon aerosol tracers
|
|
!=================================================================
|
|
|
|
! Chemistry for hydrophobic BC
|
|
IF ( IDTBCPO > 0 ) THEN
|
|
CALL CHEM_BCPO( STT(:,:,:,IDTBCPO) )
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### CHEMCARBON: a CHEM_BCPO' )
|
|
ENDIF
|
|
|
|
! Chemistry for hydrophilic BC
|
|
IF ( IDTBCPI > 0 ) THEN
|
|
CALL CHEM_BCPI( STT(:,:,:,IDTBCPI) )
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### CHEMCARBON: a CHEM_BCPI' )
|
|
ENDIF
|
|
|
|
! Chemistry for hydrophobic OC
|
|
IF ( IDTOCPO > 0 ) THEN
|
|
CALL CHEM_OCPO( STT(:,:,:,IDTOCPO) )
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### CHEMCARBON: a CHEM_OCPO' )
|
|
ENDIF
|
|
|
|
! Chemistry for hydrophilic OC
|
|
IF ( IDTOCPI > 0 ) THEN
|
|
CALL CHEM_OCPI( STT(:,:,:,IDTOCPI) )
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### CHEMCARBON: a CHEM_OCPI' )
|
|
ENDIF
|
|
|
|
!=================================================================
|
|
! Do chemistry for secondary organic aerosols
|
|
!=================================================================
|
|
IF ( LSOA ) THEN
|
|
|
|
! Read offline OH, NO3, O3 fields from disk
|
|
IF ( ITS_AN_AEROSOL_SIM() ) THEN
|
|
|
|
! Current month
|
|
THISMONTH = GET_MONTH()
|
|
|
|
IF ( ITS_A_NEW_MONTH() ) THEN
|
|
CALL GET_GLOBAL_OH( THISMONTH )
|
|
CALL GET_GLOBAL_NO3( THISMONTH )
|
|
CALL GET_GLOBAL_O3( THISMONTH )
|
|
ENDIF
|
|
|
|
! Compute time scaling arrays for offline OH, NO3
|
|
! but only if it hasn't been done in EMISSCARBON
|
|
IF ( LSOA .and. ( .not. LEMIS ) ) THEN
|
|
CALL OHNO3TIME
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### CHEMCARB: a OHNO3TIME' )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
! Compute SOA chemistry
|
|
! NOTE: This is SOA production from the reversible mechanism only
|
|
! (tmf, 12/07/07)
|
|
CALL SOA_CHEMISTRY
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### CHEMCARBON: a SOA_CHEM' )
|
|
|
|
! If SOAG and SOAM are declared, switch on
|
|
! SOA production from dicarbonyls (tmf, 12/07/07)
|
|
IF ( IDTSOAG > 0 ) THEN
|
|
|
|
! Get grid box cloud fraction
|
|
! (tmf, 2/26/07)
|
|
CALL GET_VCLDF
|
|
|
|
! Cloud uptake
|
|
CALL SOAG_CLOUD
|
|
IF ( LPRT )
|
|
& CALL DEBUG_MSG('### CHEMCARBON: a SOAG_CLOUD')
|
|
|
|
! Aqueous aerosol uptake
|
|
CALL SOAG_LIGGIO_DIFF
|
|
IF ( LPRT )
|
|
& CALL DEBUG_MSG('### CHEMCARBON: a SOAG_LIGGIO_DIFF')
|
|
|
|
ENDIF
|
|
|
|
IF ( IDTSOAM > 0 ) THEN
|
|
|
|
! Get grid box cloud fraction
|
|
! (tmf, 2/26/07)
|
|
CALL GET_VCLDF
|
|
|
|
! Cloud uptake
|
|
CALL SOAM_CLOUD
|
|
IF ( LPRT )
|
|
& CALL DEBUG_MSG('### CHEMCARBON: a SOAM_CLOUD')
|
|
|
|
! Aqueous aerosol uptake
|
|
CALL SOAM_LIGGIO_DIFF
|
|
IF ( LPRT )
|
|
& CALL DEBUG_MSG( '### CHEMCARBON: a SOAM_LIGGIO_DIFF' )
|
|
|
|
|
|
|
|
ENDIF
|
|
|
|
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE CHEMCARBON
|
|
|
|
!-----------------------------------------------------------------------------
|
|
|
|
SUBROUTINE CHEM_BCPO( TC )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine CHEM_BCPO converts hydrophobic BC to hydrophilic BC and
|
|
! calculates the dry deposition of hydrophobic BC. (rjp, bmy, 4/1/04,10/25/05)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) TC (REAL*8) : Array of hydrophobic BC tracer
|
|
!
|
|
! NOTES:
|
|
! (1 ) Remove reference to "CMN", it's obsolete (bmy, 7/20/04)
|
|
! (2 ) Replace PBLFRAC from "drydep_mod.f" with GET_FRAC_UNDER_PBLTOP
|
|
! from "pbl_mix_mod.f" (bmy, 2/17/05)
|
|
! (3 ) Now references XNUMOL from "tracer_mod.f" (bmy, 10/25/05)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DAO_MOD, ONLY : AD
|
|
USE DIAG_MOD, ONLY : AD44, AD07_BC
|
|
USE DRYDEP_MOD, ONLY : DEPSAV
|
|
USE GRID_MOD, ONLY : GET_AREA_CM2
|
|
USE PBL_MIX_MOD, ONLY : GET_FRAC_UNDER_PBLTOP
|
|
USE TRACER_MOD, ONLY : XNUMOL
|
|
USE TRACERID_MOD, ONLY : IDTBCPO
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND44, ND07, LD07
|
|
|
|
! Arguments
|
|
REAL*8, INTENT(INOUT) :: TC(IIPAR,JJPAR,LLPAR)
|
|
|
|
! Local variables
|
|
INTEGER :: I, J, L
|
|
REAL*8 :: ND44_TMP(IIPAR,JJPAR,LLPAR)
|
|
REAL*8 :: DTCHEM, FLUX, KBC, FREQ
|
|
REAL*8 :: TC0, CNEW, RKT, AREA_CM2, BL_FRAC
|
|
REAL*8, PARAMETER :: BC_LIFE = 1.15D0
|
|
|
|
!=================================================================
|
|
! CHEM_BCPO begins here!
|
|
!=================================================================
|
|
|
|
! Return if BCPO isn't defined
|
|
IF ( IDTBCPO == 0 .or. DRYBCPO == 0 ) RETURN
|
|
|
|
! Initialize
|
|
KBC = 1.D0 / ( 86400d0 * BC_LIFE )
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
BCCONV(I,J,L) = 0d0
|
|
|
|
! Initialize for drydep diagnostic
|
|
IF ( ND44 > 0 ) ND44_TMP(I,J,L) = 0d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! For tracers with dry deposition, the loss rate of dry dep is
|
|
! combined in chem loss term.
|
|
!
|
|
! Conversion from hydrophobic to hydrophilic:
|
|
! e-folding time 1.15 days
|
|
! ----------------------------------------
|
|
! Use an e-folding time of 1.15 days or a convertion rate
|
|
! of 1.0e-5 /sec.
|
|
!
|
|
! Hydrophobic(2) --> Hydrophilic(1) , k = 1.0e-5
|
|
! Both aerosols are dry-deposited, kd = Dvel/DELZ (sec-1)
|
|
!=================================================================
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L, TC0, FREQ, BL_FRAC, RKT, CNEW, AREA_CM2, FLUX )
|
|
!$OMP+SCHEDULE( DYNAMIC )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Initial BC mass [kg]
|
|
TC0 = TC(I,J,L)
|
|
|
|
! Zero drydep freq
|
|
FREQ = 0d0
|
|
|
|
! Fraction of grid box underneath PBL top [unitless]
|
|
BL_FRAC = GET_FRAC_UNDER_PBLTOP( I, J, L )
|
|
|
|
! Only apply drydep to boxes w/in the PBL
|
|
IF ( BL_FRAC > 0d0 ) THEN
|
|
|
|
! BC drydep frequency [1/s] -- BL_FRAC accounts for the fraction
|
|
! of each grid box (I,J,L) that is located beneath the PBL top
|
|
FREQ = DEPSAV(I,J,DRYBCPO) * BL_FRAC
|
|
|
|
ENDIF
|
|
|
|
! Amount of BCPO left after chemistry and drydep [kg]
|
|
RKT = ( KBC + FREQ ) * DTCHEM
|
|
CNEW = TC0 * EXP( -RKT )
|
|
|
|
! Prevent underflow condition
|
|
IF ( CNEW < SMALLNUM ) CNEW = 0d0
|
|
|
|
! Amount of BCPO converted to BCPI [kg/timestep]
|
|
BCCONV(I,J,L) = ( TC0 - CNEW ) * KBC / ( KBC + FREQ )
|
|
|
|
!==============================================================
|
|
! ND44 diagnostic: drydep loss [atoms C/cm2/s]
|
|
!==============================================================
|
|
IF ( ND44 > 0 .AND. FREQ > 0d0 ) THEN
|
|
|
|
! Surface area [cm2]
|
|
AREA_CM2 = GET_AREA_CM2( J )
|
|
|
|
! Convert drydep loss from [kg/timestep] to [atoms C/cm2/s]
|
|
! XNUMOL is the ratio [molec tracer/kg tracer]
|
|
FLUX = TC0 - CNEW - BCCONV(I,J,L)
|
|
FLUX = FLUX * XNUMOL(IDTBCPO) / ( DTCHEM * AREA_CM2 )
|
|
|
|
! Store in ND44_TMP as a placeholder
|
|
ND44_TMP(I,J,L) = ND44_TMP(I,J,L) + FLUX
|
|
ENDIF
|
|
|
|
!==============================================================
|
|
! ND07 diagnostic: H-philic BC from H_phobic BC [kg/timestep]
|
|
!==============================================================
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_BC(I,J,L) = AD07_BC(I,J,L) + BCCONV(I,J,L)
|
|
ENDIF
|
|
|
|
! Store new concentration back into tracer array
|
|
TC(I,J,L) = CNEW
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!===============================================================
|
|
! ND44: Sum drydep fluxes by level into the AD44 array in
|
|
! order to ensure that we get the same results w/ sp or mp
|
|
!===============================================================
|
|
IF ( ND44 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
DO L = 1, LLPAR
|
|
AD44(I,J,DRYBCPO,1) = AD44(I,J,DRYBCPO,1) + ND44_TMP(I,J,L)
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE CHEM_BCPO
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE CHEM_BCPI( TC )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine CHEM_BCPI calculates dry deposition of hydrophilic BC.
|
|
! (rjp, bmy, 4/1/04, 10/25/05)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) TC (REAL*8) : Array of hydrophilic BC tracer
|
|
!
|
|
! NOTES:
|
|
! (1 ) Remove reference to "CMN", it's obsolete (bmy, 7/20/04)
|
|
! (2 ) Replace PBLFRAC from "drydep_mod.f" with GET_FRAC_UNDER_PBLTOP from
|
|
! "pbl_mix_mod.f" (bmy, 2/17/05)
|
|
! (3 ) Now references XNUMOL from "tracer_mod.f" (bmy, 10/25/05)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DAO_MOD, ONLY : AD
|
|
USE DIAG_MOD, ONLY : AD44
|
|
USE DRYDEP_MOD, ONLY : DEPSAV
|
|
USE GRID_MOD, ONLY : GET_AREA_CM2
|
|
USE PBL_MIX_MOD, ONLY : GET_FRAC_UNDER_PBLTOP
|
|
USE TRACER_MOD, ONLY : XNUMOL
|
|
USE TRACERID_MOD, ONLY : IDTBCPI
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND44
|
|
|
|
! Arguments
|
|
REAL*8, INTENT(INOUT) :: TC(IIPAR,JJPAR,LLPAR)
|
|
|
|
! Local variables
|
|
INTEGER :: I, J, L
|
|
REAL*8 :: DTCHEM, FLUX, BL_FRAC, AREA_CM2
|
|
REAL*8 :: TC0, CNEW, CCV, FREQ
|
|
REAL*8 :: ND44_TMP(IIPAR,JJPAR,LLPAR)
|
|
|
|
!=================================================================
|
|
! CHEM_BCPI begins here!
|
|
!=================================================================
|
|
|
|
! Return if BCPI isn't defined
|
|
IF ( IDTBCPI == 0 .or. DRYBCPI == 0 ) RETURN
|
|
|
|
! Chemistry timestep [s]
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
! Initialize for ND44 diagnostic
|
|
IF ( ND44 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
ND44_TMP(I,J,L) = 0d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
ENDIF
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L, TC0, CCV, FREQ, BL_FRAC, CNEW, AREA_CM2, FLUX )
|
|
!$OMP+SCHEDULE( DYNAMIC )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Initial H-philic BC [kg]
|
|
TC0 = TC(I,J,L)
|
|
|
|
! H-philic BC that used to be H-phobic BC [kg]
|
|
CCV = BCCONV(I,J,L)
|
|
|
|
! Fraction of grid box under the PBL top [unitless]
|
|
BL_FRAC = GET_FRAC_UNDER_PBLTOP( I, J, L )
|
|
|
|
! Only apply drydep to boxes w/in the PBL
|
|
IF ( BL_FRAC > 0d0 ) THEN
|
|
|
|
! Drydep frequency
|
|
FREQ = DEPSAV(I,J,DRYBCPI) * BL_FRAC
|
|
|
|
!===========================================================
|
|
! Note, This is an analytical solution of first order
|
|
! partial differential equations (w/ 2 solutions):
|
|
!
|
|
! #1) CNEW = Cphi * exp(-RKT) + Cconv/RKT * (1.-exp(-RKT))
|
|
! #2) CNEW = ( Cphi + Cconv ) * exp(-RKT)
|
|
!===========================================================
|
|
|
|
! Comment out for now
|
|
!CNEW = TC0 * EXP( -FREQ * DTCHEM )
|
|
! + CCV / FREQ * ( 1.D0 - EXP( -FREQ * DTCHEM ) )
|
|
|
|
! Amount of BCPI left after drydep [kg]
|
|
CNEW = ( TC0 + CCV ) * EXP( -FREQ * DTCHEM )
|
|
|
|
!===========================================================
|
|
! ND44 diagnostic: drydep flux [atoms C/cm2/s]
|
|
!===========================================================
|
|
IF ( ND44 > 0 .and. FREQ > 0d0 ) THEN
|
|
|
|
! Surface area [cm2]
|
|
AREA_CM2 = GET_AREA_CM2( J )
|
|
|
|
! Convert drydep loss from [kg/timestep] to [molec/cm2/s]
|
|
FLUX = ( TC0 + CCV - CNEW )
|
|
FLUX = FLUX * XNUMOL(IDTBCPI) / ( AREA_CM2 * DTCHEM )
|
|
|
|
! Store in ND44_TMP as a placeholder
|
|
ND44_TMP(I,J,L) = ND44_TMP(I,J,L) + FLUX
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
! Otherwise, omit the exponential to save on clock cycles
|
|
CNEW = TC0 + CCV
|
|
|
|
ENDIF
|
|
|
|
! Prevent underflow condition
|
|
IF ( CNEW < SMALLNUM ) CNEW = 0d0
|
|
|
|
! Save new concentration of H-philic IC in tracer array
|
|
TC(I,J,L) = CNEW
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! Zero out the BCCONV array for the next iteration
|
|
!=================================================================
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
BCCONV(I,J,L) = 0.d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! ND44: Sum drydep fluxes by level into the AD44 array in
|
|
! order to ensure that we get the same results w/ sp or mp
|
|
!=================================================================
|
|
IF ( ND44 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
DO L = 1, LLPAR
|
|
AD44(I,J,DRYBCPI,1) = AD44(I,J,DRYBCPI,1) + ND44_TMP(I,J,L)
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE CHEM_BCPI
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE CHEM_OCPO( TC )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine CHEM_OCPO converts hydrophobic OC to hydrophilic OC and
|
|
! calculates the dry deposition of hydrophobic OC. (rjp, bmy, 4/1/04,10/25/05)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) TC (REAL*8) : Array of hydrophobic OC tracer [kg]
|
|
!
|
|
! NOTES:
|
|
! (1 ) Remove reference to "CMN", it's obsolete (bmy, 7/20/04)
|
|
! (2 ) Replace PBLFRAC from "drydep_mod.f" with GET_FRAC_UNDER_PBLTOP from
|
|
! "pbl_mix_mod.f" (bmy, 2/17/05)
|
|
! (3 ) Now references XNUMOL from "tracer_mod.f" (bmy, 10/25/05)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DAO_MOD, ONLY : AD
|
|
USE DIAG_MOD, ONLY : AD44, AD07_OC
|
|
USE DRYDEP_MOD, ONLY : DEPSAV
|
|
USE GRID_MOD, ONLY : GET_AREA_CM2
|
|
USE PBL_MIX_MOD, ONLY : GET_FRAC_UNDER_PBLTOP
|
|
USE TRACER_MOD, ONLY : XNUMOL
|
|
USE TRACERID_MOD, ONLY : IDTOCPO
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND44, ND07, LD07
|
|
|
|
! Arguments
|
|
REAL*8, INTENT(INOUT) :: TC(IIPAR,JJPAR,LLPAR)
|
|
|
|
! Local variable
|
|
INTEGER :: I, J, L
|
|
REAL*8 :: ND44_TMP(IIPAR,JJPAR,LLPAR)
|
|
REAL*8 :: DTCHEM, FLUX, KOC, BL_FRAC
|
|
REAL*8 :: TC0, FREQ, CNEW, RKT, AREA_CM2
|
|
REAL*8, PARAMETER :: OC_LIFE = 1.15D0
|
|
|
|
!=================================================================
|
|
! CHEM_OCPO begins here!
|
|
!=================================================================
|
|
|
|
! Return if OCPO isn't defined
|
|
IF ( IDTOCPO == 0 .or. DRYOCPO == 0 ) RETURN
|
|
|
|
! Initialize
|
|
KOC = 1.D0 / ( 86400d0 * OC_LIFE )
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
OCCONV(I,J,L) = 0d0
|
|
|
|
! Initialize for drydep diagnostic
|
|
IF ( ND44 > 0 ) ND44_TMP(I,J,L) = 0d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! For tracers with dry deposition, the loss rate of dry dep is
|
|
! combined in chem loss term.
|
|
!
|
|
! Conversion from hydrophobic to hydrophilic:
|
|
! e-folding time 1.15 days
|
|
! ----------------------------------------
|
|
! Use an e-folding time of 1.15 days or a convertion rate
|
|
! of 1.0e-5 /sec.
|
|
! Hydrophobic --> Hydrophilic, k = 1.0e-5
|
|
! Aerosols are dry-deposited, kd = DEPSAV (sec-1)
|
|
!=================================================================
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L, TC0, FREQ, BL_FRAC, RKT, CNEW, AREA_CM2, FLUX )
|
|
!$OMP+SCHEDULE( DYNAMIC )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Initial OC [kg]
|
|
TC0 = TC(I,J,L)
|
|
|
|
! Zero drydep freq
|
|
FREQ = 0d0
|
|
|
|
! Fraction of grid box under the PBL top [unitless]
|
|
BL_FRAC = GET_FRAC_UNDER_PBLTOP( I, J, L )
|
|
|
|
! Only apply drydep to boxes w/in the PBL
|
|
IF ( BL_FRAC > 0d0 ) THEN
|
|
|
|
! OC drydep frequency [1/s] -- BL_FRAC accounts for the fraction
|
|
! of each grid box (I,J,L) that is located beneath the PBL top
|
|
FREQ = DEPSAV(I,J,DRYOCPO) * BL_FRAC
|
|
|
|
ENDIF
|
|
|
|
! Amount of OCPO left after chemistry and drydep [kg]
|
|
RKT = ( KOC + FREQ ) * DTCHEM
|
|
CNEW = TC0 * EXP( -RKT )
|
|
|
|
! Prevent underflow condition
|
|
IF ( CNEW < SMALLNUM ) CNEW = 0d0
|
|
|
|
! Amount of OCPO converted to OCPI [kg/timestep]
|
|
OCCONV(I,J,L) = ( TC0 - CNEW ) * KOC / ( KOC + FREQ )
|
|
|
|
!==============================================================
|
|
! ND44 diagnostic: drydep loss [atoms C/cm2/s]
|
|
!==============================================================
|
|
IF ( ND44 > 0 .AND. FREQ > 0d0 ) THEN
|
|
|
|
! Surface area [cm2]
|
|
AREA_CM2 = GET_AREA_CM2( J )
|
|
|
|
! Convert drydep loss from [kg/timestep] to [atoms C/cm2/s]
|
|
! XNUMOL is the ratio [molec tracer/kg tracer]
|
|
FLUX = TC0 - CNEW - OCCONV(I,J,L)
|
|
FLUX = FLUX * XNUMOL(IDTOCPO) / ( DTCHEM * AREA_CM2 )
|
|
|
|
! Store in ND44_TMP as a placeholder
|
|
ND44_TMP(I,J,L) = ND44_TMP(I,J,L) + FLUX
|
|
ENDIF
|
|
|
|
!==============================================================
|
|
! ND07 diagnostic: H-Philic OC from H-phobic [kg/timestep]
|
|
!==============================================================
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_OC(I,J,L) = AD07_OC(I,J,L) + OCCONV(I,J,L)
|
|
ENDIF
|
|
|
|
! Store modified OC concentration back in tracer array
|
|
TC(I,J,L) = CNEW
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! ND44: Sum drydep fluxes by level into the AD44 array in
|
|
! order to ensure that we get the same results w/ sp or mp
|
|
!=================================================================
|
|
IF ( ND44 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
DO L = 1, LLPAR
|
|
AD44(I,J,DRYOCPO,1) = AD44(I,J,DRYOCPO,1) + ND44_TMP(I,J,L)
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE CHEM_OCPO
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE CHEM_OCPI( TC )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine CHEM_BCPI calculates dry deposition of hydrophilic OC.
|
|
! (rjp, bmy, 4/1/04, 10/25/05)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) TC (REAL*8) : Array of hydrophilic BC tracer
|
|
!
|
|
! NOTES:
|
|
! (1 ) Remove reference to "CMN", it's obsolete (bmy, 7/20/04)
|
|
! (2 ) Replace PBLFRAC from "drydep_mod.f" with GET_FRAC_UNDER_PBLTOP from
|
|
! "pbl_mix_mod.f" (bmy, 2/17/05)
|
|
! (3 ) Bug fix: add BL_FRAC to the PRIVATE list (mak, bmy, 10/3/05)
|
|
! (4 ) Now refrerences XNUMOL from "tracer_mod.f" (bmy, 10/25/05)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DAO_MOD, ONLY : AD
|
|
USE DIAG_MOD, ONLY : AD44
|
|
USE DRYDEP_MOD, ONLY : DEPSAV
|
|
USE GRID_MOD, ONLY : GET_AREA_CM2
|
|
USE PBL_MIX_MOD, ONLY : GET_FRAC_UNDER_PBLTOP
|
|
USE TRACER_MOD, ONLY : XNUMOL
|
|
USE TRACERID_MOD, ONLY : IDTOCPI
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND44
|
|
|
|
! Arguments
|
|
REAL*8, INTENT(INOUT) :: TC(IIPAR,JJPAR,LLPAR)
|
|
|
|
! Local variable
|
|
INTEGER :: I, J, L
|
|
REAL*8 :: DTCHEM, FLUX, BL_FRAC
|
|
REAL*8 :: TC0, CNEW, CCV, FREQ, AREA_CM2
|
|
REAL*8 :: ND44_TMP(IIPAR,JJPAR,LLPAR)
|
|
|
|
!=================================================================
|
|
! CHEM_OCPI begins here!
|
|
!=================================================================
|
|
IF ( IDTOCPI == 0 .or. DRYOCPI == 0 ) RETURN
|
|
|
|
! Chemistry timestep [s]
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
! Initialize for drydep diagnostic
|
|
IF ( ND44 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
ND44_TMP(I,J,L) = 0d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
ENDIF
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L, TC0, CCV, BL_FRAC, FREQ, CNEW, AREA_CM2, FLUX )
|
|
!$OMP+SCHEDULE( DYNAMIC )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Initial H-philic OC [kg]
|
|
TC0 = TC(I,J,L)
|
|
|
|
! H-philic OC that used to be H-phobic OC [kg]
|
|
CCV = OCCONV(I,J,L)
|
|
|
|
! Fraction of box under the PBL top [unitless]
|
|
BL_FRAC = GET_FRAC_UNDER_PBLTOP( I, J, L )
|
|
|
|
! Only apply drydep to boxes w/in the PBL
|
|
IF ( BL_FRAC > 0d0 ) THEN
|
|
|
|
! Drydep frequency [1/s]
|
|
FREQ = DEPSAV(I,J,DRYOCPI) * BL_FRAC
|
|
|
|
!===========================================================
|
|
! Note, This is an analytical solution of first order
|
|
! partial differential equations (w/ 2 solutions):
|
|
!
|
|
! #1) CNEW = Cphi * exp(-RKT) + Cconv/RKT * (1.-exp(-RKT))
|
|
! #2) CNEW = ( Cphi + Cconv ) * exp(-RKT)
|
|
!===========================================================
|
|
|
|
! CNEW = TC0 * EXP( -FREQ * DTCHEM )
|
|
! + CCV / FREQ * ( 1.D0 - EXP( -FREQ * DTCHEM ) )
|
|
|
|
! Amount of BCPI left after drydep [kg]
|
|
CNEW = ( TC0 + CCV ) * EXP( -FREQ * DTCHEM )
|
|
|
|
!===========================================================
|
|
! ND44 diagnostic: drydep loss [atoms C/cm2/s]
|
|
!===========================================================
|
|
IF ( ND44 > 0 ) THEN
|
|
|
|
! Surface area [cm2]
|
|
AREA_CM2 = GET_AREA_CM2( J )
|
|
|
|
! Convert drydep loss from [kg/timestep] to [atoms C/cm2/s]
|
|
FLUX = ( TC0 + CCV - CNEW )
|
|
FLUX = FLUX * XNUMOL(IDTOCPI) / ( AREA_CM2 * DTCHEM )
|
|
|
|
! Store in ND44_TMP as a placeholder
|
|
ND44_TMP(I,J,L) = ND44_TMP(I,J,L) + FLUX
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
! Otherwise, avoid doing the exponential
|
|
! to preserve precision and clock cycles
|
|
CNEW = TC0 + CCV
|
|
|
|
ENDIF
|
|
|
|
! Prevent underflow condition
|
|
IF ( CNEW < SMALLNUM ) CNEW = 0d0
|
|
|
|
! Store modified concentration back in tracer array [kg]
|
|
TC(I,J,L) = CNEW
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! Zero OCCONV array for next timestep
|
|
!=================================================================
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
OCCONV(I,J,L) = 0d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
|
|
!=================================================================
|
|
! ND44: Sum drydep fluxes by level into the AD44 array in
|
|
! order to ensure that we get the same results w/ sp or mp
|
|
!=================================================================
|
|
IF ( ND44 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
DO L = 1, LLPAR
|
|
AD44(I,J,DRYOCPI,1) = AD44(I,J,DRYOCPI,1) + ND44_TMP(I,J,L)
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE CHEM_OCPI
|
|
|
|
!-------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOAG_LIGGIO_DIFF
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOAG_LIGGIO_DIFF produces SOA on aqueous aerosol surfaces
|
|
! from GLYX following the uptake model used for N2O5, and the gamma
|
|
! from Liggio et al. [2005]. (tmf, 5/30/06)
|
|
!
|
|
! Procedure:
|
|
! ============================================================================
|
|
! (1 )
|
|
!
|
|
! NOTES:
|
|
! (1 ) SOAG (SOA product of GLYX is produced at existing hydrophilic aerosol
|
|
! surface.
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE COMODE_MOD, ONLY : WTAREA, WERADIUS
|
|
USE COMODE_MOD, ONLY : AIRDENS, JLOP
|
|
USE DAO_MOD, ONLY : AIRVOL, T, RH
|
|
|
|
USE ERROR_MOD, ONLY : DEBUG_MSG
|
|
USE DIAG_MOD, ONLY : AD07_SOAGM
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM, GET_MONTH
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTGLYX, IDTSOAG
|
|
USE TROPOPAUSE_MOD, ONLY : ITS_IN_THE_TROP
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_O3" ! XNUMOL
|
|
# include "CMN_DIAG" ! ND44, ND07, LD07
|
|
# include "comode.h" ! AD, WTAIR, other SMVGEAR variables
|
|
|
|
|
|
! Local variables
|
|
INTEGER :: I, J, L, JLOOP, N
|
|
REAL*8 :: XTEMP ! Temperature [K]
|
|
REAL*8 :: XSQTEMP ! SQRT of Temperature
|
|
REAL*8 :: XAD ! Air density [molec/cm3]
|
|
REAL*8 :: XRADIUS ! particle radius [cm]
|
|
REAL*8 :: XDFKG ! Gas phase diffusion coeff [cm2/s]
|
|
REAL*8 :: XARSL1K ! 1st order k
|
|
REAL*8 :: XRH ! Relative humidity [%]
|
|
REAL*8 :: XAIRM3 ! Air volume in grid box [m3]
|
|
REAL*8 :: XGASM ! Gas mass at grid box before uptake [kg]
|
|
REAL*8 :: XGASC ! Gas concentration at grid box before uptake [molec/cm3]
|
|
REAL*8 :: XWAREA ! Wet aerosol surface area at grid box [cm^2 wet sfc area of aerosol cm^-3 air]
|
|
REAL*8 :: XUPTK0 ! Potential uptake of gas by aerosol in grid box by aerosol type [molec/cm3]
|
|
REAL*8 :: XUPTK1 ! Potential uptake of gas by aerosol in grid box by aerosol type [kg]
|
|
REAL*8 :: XUPTKSUM ! Potential uptake of gas by aerosol in grid box [kg]
|
|
REAL*8 :: XUPTK ! Actual uptake of gas by aerosol in grid box [kg]
|
|
! XUPTK <= STT( I, J, L, IDTGLYX )
|
|
REAL*8 :: XGAMMA ! Uptake coefficient
|
|
|
|
! Local variables not changing
|
|
REAL*8 :: DTCHEM ! Chemistry time step [s]
|
|
REAL*8 :: XMW ! Molecular weight of gas [g/mole]
|
|
REAL*8 :: XSQMW ! Square root of molecular weight [g/mole]
|
|
REAL*8 :: CRITRH ! Critical RH [%], above which
|
|
! heteorogeneous chem takes place
|
|
REAL*8 :: XNAVO ! Avogadro number
|
|
|
|
!=================================================================
|
|
! SOAG_LIGGIO_DIFF begins here!
|
|
!=================================================================
|
|
|
|
! Get chemistry time step
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
! Molecular weight of GLYX [g/mole]
|
|
XMW = 58.d0
|
|
XSQMW = SQRT( XMW )
|
|
|
|
! Critical RH, above which heteorogeneous chem takes place
|
|
CRITRH = 35.0d0 ! [%]
|
|
|
|
! Avogadro number
|
|
XNAVO = 6.022d23
|
|
|
|
! Uptake coefficient from Liggio et al. [2005b]
|
|
XGAMMA = 2.9d-3
|
|
|
|
!=================================================================
|
|
! Loop over grid boxes
|
|
!=================================================================
|
|
DO L = 1, LLTROP
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Get 1-D index
|
|
JLOOP = JLOP( I, J, L )
|
|
|
|
! Get RH
|
|
XRH = RH( I, J, L ) ![%]
|
|
|
|
! initialize for safety
|
|
XUPTK0 = 0d0
|
|
XUPTK1 = 0d0
|
|
XUPTKSUM = 0d0
|
|
XUPTK = 0d0
|
|
|
|
! Get T
|
|
XTEMP = T( I, J, L )
|
|
XSQTEMP = SQRT( XTEMP )
|
|
|
|
! Get air density [molec/cm3]
|
|
XAD = AIRDENS( JLOOP )
|
|
|
|
! Get air volumne [m3]
|
|
XAIRM3 = AIRVOL( I, J, L )
|
|
|
|
! Get gas mass at grid box [kg]
|
|
XGASM = STT( I, J, L, IDTGLYX )
|
|
|
|
! Get gas concentration at grid box [molec/cm3]
|
|
XGASC = XGASM / (XMW*1.d-3) * XNAVO / (XAIRM3*1.d6)
|
|
|
|
!---------------------------------------
|
|
! Gas phase diffusion coeff [cm2/s]
|
|
!---------------------------------------
|
|
XDFKG = 9.45D17 / XAD * XSQTEMP *
|
|
& SQRT( 3.472D-2 + (1.D0/XMW) )
|
|
|
|
|
|
!========================================================
|
|
! Calculate heteorogeneous uptake only if the grid box
|
|
! relative humidity XRH is >= critical relative humidity CRITRH
|
|
!========================================================
|
|
IF ( XRH >= CRITRH ) THEN
|
|
|
|
! Loop over sulfate and other aerosols
|
|
DO N = 1, NDUST + NAER
|
|
|
|
!---------------------------------------
|
|
! Total available wet aerosol area
|
|
! archived in 'aerosol_mod.f.glyx'
|
|
! XWAREA [ cm^2 wet sfc area of aerosol cm^-3 air ]
|
|
!---------------------------------------
|
|
XWAREA = WTAREA( JLOOP, N)
|
|
|
|
IF ( XWAREA > 0D0 ) THEN
|
|
|
|
! Get particle radius [cm]
|
|
XRADIUS = WERADIUS( JLOOP, N )
|
|
|
|
!---------------------------------------
|
|
! First order rate constant
|
|
!---------------------------------------
|
|
XARSL1K = XWAREA /
|
|
& (XRADIUS/XDFKG + 2.749064D-4*XSQMW/XGAMMA/XSQTEMP)
|
|
|
|
!---------------------------------------
|
|
! Calculate potential uptake: Liggio et al. (2005b) Eq (3)
|
|
!
|
|
! d( organic carbon conc ) / dt =
|
|
! XARSL1K * XGASC
|
|
!---------------------------------------
|
|
XUPTK0 = XARSL1K * XGASC * DTCHEM
|
|
XUPTK1 = XUPTK0 / XNAVO*(XMW*1.d-3)*(XAIRM3*1.d6)
|
|
XUPTKSUM = XUPTKSUM + XUPTK1
|
|
|
|
ENDIF
|
|
|
|
ENDDO
|
|
|
|
! However, the mass of gas being absorbed by aerosol
|
|
! cannot exceed the original amount of gas XGASM
|
|
XUPTK = MIN( XUPTKSUM, XGASM )
|
|
|
|
! Update GLYX in the STT array
|
|
STT( I, J, L, IDTGLYX ) = STT( I, J, L, IDTGLYX ) -
|
|
& XUPTK
|
|
|
|
! Update SOAG in the STT array
|
|
STT( I, J, L, IDTSOAG ) = STT( I, J, L, IDTSOAG ) +
|
|
& XUPTK
|
|
|
|
ENDIF
|
|
|
|
!==============================================================
|
|
! ND07 diagnostic: SOAG from GLYX [kg/timestep] on aerosol
|
|
!==============================================================
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_SOAGM(I,J,L,1) = AD07_SOAGM(I,J,L,1) + XUPTK
|
|
ENDIF
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!=================================================================
|
|
! Calculate dry-deposition
|
|
!=================================================================
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOAG), DRYSOAG, IDTSOAG )
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOAG_LIGGIO_DIFF
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOAM_LIGGIO_DIFF
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOAG_LIGGIO_DIFF produces SOA on aqueous aerosol surfaces
|
|
! from GLYX following the uptake model used for N2O5, and the gamma
|
|
! from Liggio et al. [2005]. (tmf, 5/30/06)
|
|
!
|
|
! Procedure:
|
|
! ============================================================================
|
|
! (1 )
|
|
!
|
|
! NOTES:
|
|
! (1 ) SOAM (SOA product of MGLY) is produced at existing hydrophilic aerosol
|
|
! surface.
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE COMODE_MOD, ONLY : WTAREA, WERADIUS
|
|
USE COMODE_MOD, ONLY : AIRDENS, JLOP
|
|
USE DAO_MOD, ONLY : AIRVOL, T, RH
|
|
|
|
USE ERROR_MOD, ONLY : DEBUG_MSG
|
|
USE DIAG_MOD, ONLY : AD07_SOAGM
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM, GET_MONTH
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTMGLY, IDTSOAM
|
|
USE TROPOPAUSE_MOD, ONLY : ITS_IN_THE_TROP
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_O3" ! XNUMOL
|
|
# include "CMN_DIAG" ! ND44, ND07, LD07
|
|
# include "comode.h" ! AD, WTAIR, other SMVGEAR variables
|
|
|
|
|
|
! Local variables
|
|
INTEGER :: I, J, L, JLOOP, N
|
|
REAL*8 :: XTEMP ! Temperature [K]
|
|
REAL*8 :: XSQTEMP ! SQRT of Temperature
|
|
REAL*8 :: XAD ! Air density [molec/cm3]
|
|
REAL*8 :: XRADIUS ! particle radius [cm]
|
|
REAL*8 :: XDFKG ! Gas phase diffusion coeff [cm2/s]
|
|
REAL*8 :: XARSL1K ! 1st order k
|
|
REAL*8 :: XRH ! Relative humidity [%]
|
|
REAL*8 :: XAIRM3 ! Air volume in grid box [m3]
|
|
REAL*8 :: XGASM ! Gas mass at grid box before uptake [kg]
|
|
REAL*8 :: XGASC ! Gas concentration at grid box before uptake [molec/cm3]
|
|
REAL*8 :: XWAREA ! Wet aerosol surface area at grid box [cm^2 wet sfc area of aerosol cm^-3 air]
|
|
REAL*8 :: XUPTK0 ! Potential uptake of gas by aerosol in grid box by aerosol type [molec/cm3]
|
|
REAL*8 :: XUPTK1 ! Potential uptake of gas by aerosol in grid box by aerosol type [kg]
|
|
REAL*8 :: XUPTKSUM ! Potential uptake of gas by aerosol in grid box [kg]
|
|
REAL*8 :: XUPTK ! Actual uptake of gas by aerosol in grid box [kg]
|
|
! XUPTK <= STT( I, J, L, IDTGLYX )
|
|
REAL*8 :: XGAMMA ! Uptake coefficient
|
|
|
|
! Local variables not changing
|
|
REAL*8 :: DTCHEM ! Chemistry time step [s]
|
|
REAL*8 :: XMW ! Molecular weight of gas [g/mole]
|
|
REAL*8 :: XSQMW ! Square root of molecular weight [g/mole]
|
|
REAL*8 :: CRITRH ! Critical RH [%], above which
|
|
! heteorogeneous chem takes place
|
|
REAL*8 :: XNAVO ! Avogadro number
|
|
|
|
!=================================================================
|
|
! SOAG_LIGGIO_DIFF begins here!
|
|
!=================================================================
|
|
|
|
! Get chemistry time step
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
! Molecular weight of MGLY [g/mole]
|
|
XMW = 72.d0
|
|
XSQMW = SQRT( XMW )
|
|
|
|
! Critical RH, above which heteorogeneous chem takes place
|
|
CRITRH = 35.0d0 ! [%]
|
|
|
|
! Avogadro number
|
|
XNAVO = 6.022d23
|
|
|
|
! Uptake coefficient from Liggio et al. [2005b]
|
|
XGAMMA = 2.9d-3
|
|
|
|
! Create RH field -- relative humidity (in dao_mod.f)
|
|
! CALL MAKE_RH
|
|
|
|
!=================================================================
|
|
! Loop over grid boxes
|
|
!=================================================================
|
|
DO L = 1, LLTROP
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Get 1-D index
|
|
JLOOP = JLOP( I, J, L )
|
|
|
|
! Get RH
|
|
XRH = RH( I, J, L ) ![%]
|
|
|
|
! initialize for safety
|
|
XUPTK0 = 0d0
|
|
XUPTK1 = 0d0
|
|
XUPTKSUM = 0d0
|
|
XUPTK = 0d0
|
|
|
|
! Get T
|
|
XTEMP = T( I, J, L )
|
|
XSQTEMP = SQRT( XTEMP )
|
|
|
|
! Get air density [molec/cm3]
|
|
XAD = AIRDENS( JLOOP )
|
|
|
|
! Get air volumne [m3]
|
|
XAIRM3 = AIRVOL( I, J, L )
|
|
|
|
! Get gas mass at grid box [kg]
|
|
XGASM = STT( I, J, L, IDTMGLY )
|
|
|
|
! Get gas concentration at grid box [molec/cm3]
|
|
XGASC = XGASM / (XMW*1.d-3) * XNAVO / (XAIRM3*1.d6)
|
|
|
|
!---------------------------------------
|
|
! Gas phase diffusion coeff [cm2/s]
|
|
!---------------------------------------
|
|
XDFKG = 9.45D17 / XAD * XSQTEMP *
|
|
& SQRT( 3.472D-2 + (1.D0/XMW) )
|
|
|
|
|
|
!========================================================
|
|
! Calculate heteorogeneous uptake only if the grid box
|
|
! relative humidity XRH is >= critical relative humidity CRITRH
|
|
!========================================================
|
|
IF ( XRH >= CRITRH ) THEN
|
|
|
|
! Loop over sulfate and other aerosols
|
|
DO N = 1, NDUST + NAER
|
|
|
|
!---------------------------------------
|
|
! Total available wet aerosol area
|
|
! archived in 'aerosol_mod.f.glyx'
|
|
! XWAREA [ cm^2 wet sfc area of aerosol cm^-3 air ]
|
|
!---------------------------------------
|
|
XWAREA = WTAREA( JLOOP, N)
|
|
|
|
IF ( XWAREA > 0D0 ) THEN
|
|
|
|
! Get particle radius [cm]
|
|
XRADIUS = WERADIUS( JLOOP, N )
|
|
|
|
!---------------------------------------
|
|
! First order rate constant
|
|
!---------------------------------------
|
|
XARSL1K = XWAREA /
|
|
& (XRADIUS/XDFKG + 2.749064D-4*XSQMW/XGAMMA/XSQTEMP)
|
|
|
|
!---------------------------------------
|
|
! Calculate potential uptake: Liggio et al. (2005b) Eq (3)
|
|
!
|
|
! d( organic carbon conc ) / dt =
|
|
! XARSL1K * XGASC
|
|
!---------------------------------------
|
|
XUPTK0 = XARSL1K * XGASC * DTCHEM
|
|
XUPTK1 = XUPTK0 / XNAVO*(XMW*1.d-3)*(XAIRM3*1.d6)
|
|
XUPTKSUM = XUPTKSUM + XUPTK1
|
|
|
|
ENDIF
|
|
|
|
ENDDO
|
|
|
|
! However, the mass of gas being absorbed by aerosol
|
|
! cannot exceed the original amount of gas XGASM
|
|
XUPTK = MIN( XUPTKSUM, XGASM )
|
|
|
|
! Update MGLY in the STT array
|
|
STT( I, J, L, IDTMGLY ) = STT( I, J, L, IDTMGLY ) -
|
|
& XUPTK
|
|
|
|
! Update SOAM in the STT array
|
|
STT( I, J, L, IDTSOAM ) = STT( I, J, L, IDTSOAM ) +
|
|
& XUPTK
|
|
|
|
ENDIF
|
|
|
|
!==============================================================
|
|
! ND07 diagnostic: SOAM from MGLY [kg/timestep] on aerosol
|
|
!==============================================================
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_SOAGM(I,J,L,2) = AD07_SOAGM(I,J,L,2) + XUPTK
|
|
ENDIF
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!=================================================================
|
|
! Calculate dry-deposition
|
|
!=================================================================
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOAM), DRYSOAM, IDTSOAM )
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOAM_LIGGIO_DIFF
|
|
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOA_CHEMISTRY
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOA_CHEMISTRY performs SOA formation. This code is from the
|
|
! Caltech group (Hong Liao, Serena Chung, et al) and was modified for
|
|
! GEOS-CHEM. (rjp, bmy, 7/8/04, 8/3/06)
|
|
!
|
|
! Procedure:
|
|
! ============================================================================
|
|
! (1 ) Read in NO3, O3, OH in CHEM_SOA
|
|
! (2 ) Scales these fields using OHNO3TIME in sulfate_mod.f (see GET_OH)
|
|
! (3 ) Calculate reaction rates (Serena's OCHEMPARAETER)
|
|
! (4 ) CALCULATE DELHC
|
|
! (5 ) get T0M gas products
|
|
! (6 ) equilibrium calculation
|
|
!
|
|
! There are total of 42 tracers considered in this routine:
|
|
!
|
|
! 4 classes of primary carbonaceous aerosols:
|
|
! BCPI = Hydrophilic black carbon
|
|
! OCPI = Hydrophilic organic carbon
|
|
! BCPO = Hydrophobic black carbon
|
|
! OCPO = Hydrophobic organic carbon
|
|
!
|
|
! 6 reactive biogenic hydrocarbon groups (NVOC):
|
|
! ALPH = a-pinene, b-pinene, sabinene, carene, terpenoid ketones
|
|
! LIMO = limonene
|
|
! TERP = a-terpinene, r-terpinene, terpinolene
|
|
! ALCO = myrcene, terpenoid alcohols, ocimene
|
|
! SESQ = sesquiterpenes
|
|
! ISOP = Isoprene
|
|
!
|
|
! NOTE: TERP and SESQ are not tracers because of their high reactivity
|
|
!
|
|
! 32 organic oxidation products by O3+OH and NO3:
|
|
! 6 ( 3 gases + 3 aerosols ) from each of first four NVOC = 24
|
|
! 4 ( 2 gases + 2 aerosols ) from sesquiterpenes oxidation = 4
|
|
! 4 ( 2 gases + 2 aerosols ) from isoprene oxidation = 4
|
|
!
|
|
! NOTE: We aggregate these into 6 tracers according to HC classes
|
|
! SOG1 = lump of gas products of first three (ALPH+LIMO+TERP) HC oxidation.
|
|
! SOG2 = gas product of ALCO oxidation
|
|
! SOG3 = gas product of SESQ oxidation
|
|
! SOG4 = gas product of ISOP oxidation
|
|
! SOA1 = lump of aerosol products of first 3 (ALPH+LIMO+TERP) HC oxidation.
|
|
! SOA2 = aerosol product of ALCO oxidation
|
|
! SOA3 = aerosol product of SESQ oxidation
|
|
! SOA4 = aerosol product of ISOP oxidation
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references STT from "tracer_mod.f" (bmy, 7/20/04)
|
|
! (2 ) Now modified for SOG4, SOA4 -- products of oxidation by isoprene.
|
|
! (dkh, bmy, 6/1/06)
|
|
! (3 ) Now consider SOG condensation onto SO4, NH4, NIT aerosols (if SO4,
|
|
! NH4, NIT are defined as tracers). (rjp, bmy, 8/3/06)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE ERROR_MOD, ONLY : DEBUG_MSG
|
|
USE DAO_MOD, ONLY : T, AD, AIRVOL, SUNCOS
|
|
USE DIAG_MOD, ONLY : AD07_HC
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTALCO, IDTALPH, IDTLIMO, IDTOCPI
|
|
USE TRACERID_MOD, ONLY : IDTOCPO, IDTSOA1, IDTSOA2, IDTSOA3
|
|
USE TRACERID_MOD, ONLY : IDTSOA4, IDTSOG1, IDTSOG2, IDTSOG3
|
|
USE TRACERID_MOD, ONLY : IDTSOG4, IDTSO4, IDTNH4, IDTNIT
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM, GET_MONTH
|
|
USE TIME_MOD, ONLY : ITS_TIME_FOR_BPCH
|
|
USE LOGICAL_MOD, ONLY : LDICARB
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_O3" ! XNUMOL
|
|
# include "CMN_DIAG" ! ND44
|
|
|
|
! Local variables
|
|
LOGICAL, SAVE :: FIRST = .TRUE.
|
|
INTEGER :: I, J, L, N
|
|
INTEGER :: JHC, IPR
|
|
REAL*8 :: RTEMP, VOL, FAC, MPOC
|
|
REAL*8 :: MNEW, MSOA_OLD, MPRODUCT, CAIR
|
|
REAL*8 :: LOWER, UPPER, TOL, VALUE
|
|
REAL*8 :: KO3(MHC), KOH(MHC), KNO3(MHC)
|
|
REAL*8 :: ALPHA(NPROD,MHC), KOM(NPROD,MHC)
|
|
REAL*8 :: GM0(NPROD,MHC), AM0(NPROD,MHC)
|
|
REAL*8 :: ORG_AER(NPROD,MHC), ORG_GAS(NPROD,MHC)
|
|
|
|
!=================================================================
|
|
! SOA_CHEMISTRY begins here!
|
|
!=================================================================
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L, JHC, IPR, GM0, AM0 )
|
|
!$OMP+PRIVATE( VOL, FAC, RTEMP, KO3, KOH, KNO3, CAIR )
|
|
!$OMP+PRIVATE( MPRODUCT, MSOA_OLD, VALUE, UPPER, LOWER, MNEW, TOL )
|
|
!$OMP+PRIVATE( ORG_AER, ORG_GAS, ALPHA, KOM, MPOC )
|
|
DO L = 1, LLTROP
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Volume of grid box [m3]
|
|
VOL = AIRVOL(I,J,L)
|
|
|
|
! conversion factor from kg to ug/m3
|
|
FAC = 1.D9 / VOL
|
|
|
|
! air conc. in kg/m3
|
|
CAIR = AD(I,J,L) / VOL
|
|
|
|
! Temperature [K]
|
|
RTEMP = T(I,J,L)
|
|
|
|
! Get SOA yield parameters
|
|
CALL SOA_PARA( I, J, L, RTEMP, KO3, KOH, KNO3, ALPHA, KOM )
|
|
|
|
! Partition mass of gas & aerosol tracers
|
|
! according to 5 VOC classes & 3 oxidants
|
|
CALL SOA_PARTITION( I, J, L, GM0, AM0 )
|
|
|
|
! Compute oxidation of hydrocarbons by O3, OH, NO3
|
|
CALL CHEM_NVOC( I, J, L, KO3, KOH, KNO3, ALPHA, GM0 )
|
|
|
|
!==============================================================
|
|
! Equilibrium calculation between GAS (SOG) and Aerosol (SOA)
|
|
!==============================================================
|
|
|
|
! Total VOC oxidation products (gas and aerosol) [kg]
|
|
MPRODUCT = 0.D0
|
|
|
|
! Initialize aerosol-only total [kg]
|
|
MSOA_OLD = 0.D0
|
|
|
|
! Compute total VOC and aerosol-only total
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
MPRODUCT = MPRODUCT + GM0(IPR,JHC) + AM0(IPR,JHC)
|
|
MSOA_OLD = MSOA_OLD + AM0(IPR,JHC)
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! No need to proceed because there is no
|
|
! products that need to be re-equilibrated.
|
|
IF ( ( MPRODUCT / AD(I,J,L) ) <= 29.D-18 ) CYCLE
|
|
|
|
! Individual SOA's; units: [ug/m3]
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
ORG_GAS(IPR,JHC) = GM0(IPR,JHC) * FAC
|
|
ORG_AER(IPR,JHC) = AM0(IPR,JHC) * FAC
|
|
ENDDO
|
|
ENDDO
|
|
|
|
IF ( IDTSO4 > 0 .and. IDTNH4 > 0 .and. IDTNIT > 0 ) THEN
|
|
|
|
!-----------------------------------------------------------
|
|
! Condensation of SOG onto seed aerosols (rjp, bmy, 8/3/06)
|
|
!
|
|
! If SO4, NH4, and NIT are defined tracers in this run
|
|
! (i.e. as in full-chemistry simulations), then:
|
|
!
|
|
! (1) Compute the condensation of SOG on seed aerosols
|
|
! including preexisting OC and inorganic aerosols
|
|
!
|
|
! (2) Use higher ratio (2.1) of molecular weight of
|
|
! organic mass per carbon mass accounting for non-carbon
|
|
! components attached to OC [Turpin and Lim, 2001]
|
|
!
|
|
! NOTE...The remaining question is:
|
|
!
|
|
! Do we have to include other types of aerosols such
|
|
! as dust, sea salt, and aerosol water which should be
|
|
! available in ISORROPIA?
|
|
!
|
|
! I think that aerosol water is valuable information for
|
|
! this and also AOD computation so at least we need to
|
|
! archive it if including it as a tracer is too expensive.
|
|
! (Rokjin Park, 8/3/06)
|
|
!-----------------------------------------------------------
|
|
|
|
!-----------------------------------------------------------
|
|
! The standard code reversibly-partitions SOA mass onto all
|
|
! aqueous aerosols.
|
|
! However, if the dicarbonyl SOA formation pathway is included,
|
|
! this would lead to an overestimate of SOA mass compare to
|
|
! observations during ICARTT. So LDICARB was introduced to
|
|
! change to partitioning only onto pre-existing organic aerosols
|
|
! when adding the dicarbonyl SOA formation pathway. (tmf, 3/06/09)
|
|
!-----------------------------------------------------------
|
|
|
|
IF ( .not. LDICARB ) THEN
|
|
! First compute SOG condensation onto OC aerosol
|
|
MPOC = ( STT(I,J,L,IDTOCPI) + STT(I,J,L,IDTOCPO) ) * FAC
|
|
MPOC = MPOC * 2.1d0
|
|
ENDIF
|
|
|
|
! Then compute SOG condensation onto SO4, NH4, NIT aerosols
|
|
MPOC = MPOC + ( STT(I,J,L,IDTSO4) +
|
|
& STT(I,J,L,IDTNH4) +
|
|
& STT(I,J,L,IDTNIT) ) * FAC
|
|
|
|
ELSE
|
|
|
|
!-----------------------------------------------------------
|
|
! If SO4, NIT, and NH3 are all undefined for this run,
|
|
! then we will omit SOG condensation onto these aerosols
|
|
! (at least for the time being).
|
|
!
|
|
! We carry carbon mass only in STT array and here multiply
|
|
! by the ratio (2.1) of molecular weight of organic mass
|
|
! per carbon mass. This ratio accounts for non-carbon
|
|
! components attached to OC [Turpin and Lim, 2001].
|
|
!
|
|
! %%% NOTE: Ideally we should read in offline monthly %%%
|
|
! %%% mean concentrations of SO4, NH4, NIT, and then use %%%
|
|
! %%% these to compute SOG condensation. Implement this %%%
|
|
! %%% later. %%%
|
|
! %%% %%%
|
|
! %%% For the time being, GEOS-Chem users are STRONGLY %%%
|
|
! %%% encouraged to include sulfate aerosol and 2dary %%%
|
|
! %%% organic aerosol tracers in offline carbon aerosol %%%
|
|
! %%% simulations. Without these extra aerosol tracers, %%%
|
|
! %%% the carbon aerosol simulation alone may under- %%%
|
|
! %%% estimate SOA formation. %%%
|
|
!
|
|
! (rjp, bmy, 8/3/06)
|
|
!-----------------------------------------------------------
|
|
|
|
! Compute SOG condensation onto OC aerosol
|
|
MPOC = ( STT(I,J,L,IDTOCPI) + STT(I,J,L,IDTOCPO) ) * FAC
|
|
MPOC = MPOC * 2.1d0
|
|
|
|
ENDIF
|
|
|
|
!==============================================================
|
|
! Solve for MNEW by solving for SOA=0
|
|
!==============================================================
|
|
IF ( ( MPOC / ( CAIR*1.D9 ) ) <= 2.1D-18 ) THEN
|
|
VALUE = 0.D0
|
|
UPPER = 0.D0
|
|
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
VALUE = VALUE + KOM(IPR,JHC) *
|
|
& (ORG_GAS(IPR,JHC) + ORG_AER(IPR,JHC))
|
|
|
|
UPPER = UPPER + ORG_GAS(IPR,JHC) + ORG_AER(IPR,JHC)
|
|
ENDDO
|
|
ENDDO
|
|
|
|
IF ( VALUE <= 1.D0 ) THEN
|
|
MNEW = 0.D0
|
|
ELSE
|
|
LOWER = 1.D-18 * ( CAIR * 1.D9 )
|
|
TOL = 1.D-18
|
|
MNEW = ZEROIN(LOWER,UPPER,TOL,MPOC,ORG_AER,ORG_GAS,KOM)
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
UPPER = MPOC
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
UPPER = UPPER + ORG_GAS(IPR,JHC) + ORG_AER(IPR,JHC)
|
|
ENDDO
|
|
ENDDO
|
|
|
|
LOWER = MPOC
|
|
TOL = 1.D-9*MPOC
|
|
MNEW = ZEROIN(LOWER,UPPER,TOL,MPOC,ORG_AER,ORG_GAS,KOM)
|
|
|
|
ENDIF
|
|
|
|
!==============================================================
|
|
! Equilibrium partitioning into new gas and aerosol
|
|
! concentrations for individual contributions of SOA
|
|
!==============================================================
|
|
IF ( MNEW > 0.D0 ) THEN
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
|
|
ORG_AER(IPR,JHC) = KOM(IPR,JHC)*MNEW /
|
|
& (1.D0 + KOM(IPR,JHC) * MNEW ) *
|
|
& (ORG_AER(IPR,JHC) + ORG_GAS(IPR,JHC))
|
|
|
|
IF ( KOM(IPR,JHC).NE.0D0 ) THEN
|
|
ORG_GAS(IPR,JHC) = ORG_AER(IPR,JHC) * 1.D8 /
|
|
& ( KOM(IPR,JHC) * MNEW * 1.D8 )
|
|
ELSE
|
|
ORG_GAS(IPR,JHC) = 0.D0
|
|
ENDIF
|
|
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! STORE PRODUCT INTO T0M
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
GM0(IPR,JHC) = ORG_GAS(IPR,JHC) / FAC
|
|
AM0(IPR,JHC) = ORG_AER(IPR,JHC) / FAC
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!==============================================================
|
|
! Mnew=0.D0, all SOA evaporates to the gas-phase
|
|
!==============================================================
|
|
ELSE
|
|
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
GM0(IPR,JHC) = GM0(IPR,JHC) + AM0(IPR,JHC)
|
|
AM0(IPR,JHC) = 1.D-18 * AD(I,J,L)
|
|
ENDDO
|
|
ENDDO
|
|
|
|
ENDIF
|
|
|
|
! Lump SOA
|
|
CALL SOA_LUMP( I, J, L, GM0, AM0 )
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! Calculate dry-deposition
|
|
!=================================================================
|
|
CALL SOA_DEPO( STT(:,:,:,IDTALPH), DRYALPH, IDTALPH )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTLIMO), DRYLIMO, IDTLIMO )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTALCO), DRYALCO, IDTALCO )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOG1), DRYSOG1, IDTSOG1 )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOG2), DRYSOG2, IDTSOG2 )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOG3), DRYSOG3, IDTSOG3 )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOG4), DRYSOG4, IDTSOG4 )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOA1), DRYSOA1, IDTSOA1 )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOA2), DRYSOA2, IDTSOA2 )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOA3), DRYSOA3, IDTSOA3 )
|
|
CALL SOA_DEPO( STT(:,:,:,IDTSOA4), DRYSOA4, IDTSOA4 )
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOA_CHEMISTRY
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
FUNCTION SOA_EQUIL( MASS, MPOC, AEROSOL, GAS, KOM )
|
|
& RESULT( SOA_MASS )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOA_EQUIL solves SOAeqn=0 to determine Mnew (= mass)
|
|
! See Eqn (27) on page 70 of notes. Originally written by Serena Chung at
|
|
! Caltech, and modified for inclusion into GEOS-CHEM. (rjp, bmy, 7/8/04)
|
|
!
|
|
! This version does NOT assume that the gas and aerosol phases are in
|
|
! equilibrium before chemistry; therefore, gas phase concentrations are
|
|
! needed explicitly. The gas and aerosol phases are assumed to be in
|
|
! equilibrium after chemistry.
|
|
!
|
|
! Note: Unlike FUNCTION SOA, this function assumes no reactions. It only
|
|
! considers the partitioning of existing products of VOC oxidation.
|
|
!
|
|
! HC_JHC + OXID_IOXID - >
|
|
! alpha(1,IOXID,JHC) [SOAprod_gas(1,IOXID,JHC)+SOAprod(1,IOXID,JHC)]+
|
|
! alpha(2,IOXID,JHC) [SOAprod_gas(2,IOXID,JHC)+SOAprod(2,IOXID,JHC)]
|
|
!
|
|
! SOAprod_gas(IPR,IOXID,JHC) <--> SOAprod(IPR,IOXID,JHC)
|
|
! (aerosol phase)
|
|
!
|
|
! w/ equilibrium partitioning:
|
|
!
|
|
! SOAprod(IPR,IOXID,JHC)
|
|
! SOAprod_gas(IPR,IOXID,JHC) = ------------------------
|
|
! Kom(IPR,IOXID,JHC)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) MASS (REAL*8) : Pre-existing aerosol mass [ug/m3]
|
|
! (2 ) MPOC (REAL*8) : POA Mass [ug/m3]
|
|
! (3 ) AEROSOL (REAL*8) : Aerosol concentration [ug/m3]
|
|
! (4 ) GAS (REAL*8) : Gas-phase concentration [ug/m3]
|
|
! (5 ) KOM (REAL*8) : Equilibrium gas-aerosol partition coeff. [m3/ug]
|
|
!
|
|
! NOTES:
|
|
!******************************************************************************
|
|
!
|
|
! Arguments
|
|
REAL*8, INTENT(IN) :: MASS, MPOC
|
|
REAL*8, INTENT(IN) :: AEROSOL(NPROD,MHC)
|
|
REAL*8, INTENT(IN) :: GAS(NPROD,MHC)
|
|
REAL*8, INTENT(IN) :: KOM(NPROD,MHC)
|
|
|
|
! Local variables
|
|
INTEGER :: JHC, IPR
|
|
REAL*8 :: VALUE, SOA_MASS
|
|
|
|
!=================================================================
|
|
! SOA_EQUIL begins here!
|
|
!=================================================================
|
|
|
|
! Equation (39) on page 139 of notes:
|
|
VALUE = 0.D0
|
|
|
|
!
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
VALUE = VALUE + KOM(IPR,JHC) /
|
|
& ( 1.D0 + KOM(IPR,JHC) * MASS ) *
|
|
& ( GAS(IPR,JHC) + AEROSOL(IPR,JHC) )
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! Compute SOA mass
|
|
SOA_MASS = VALUE + ( 1.D5 * MPOC ) / ( 1.D5 * MASS ) - 1.0D0
|
|
|
|
! Return to calling program
|
|
END FUNCTION SOA_EQUIL
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
FUNCTION ZEROIN(AX,BX,TOL,MPOC,AEROSOL,GAS,KOM) RESULT( MNEW )
|
|
!
|
|
!******************************************************************************
|
|
! NOTE: This function may be problematic -- it uses GOTO's, which are not
|
|
! good for parallelization. (bmy, 7/8/04)
|
|
!
|
|
! shc I got this code from http://www.netlib.org
|
|
!
|
|
! a zero of the function f(x) is computed in the interval ax,bx .
|
|
!
|
|
! input..
|
|
!
|
|
! ax left endpoint of initial interval
|
|
! bx right endpoint of initial interval
|
|
! f function subprogram which evaluates f(x) for any x in
|
|
! the interval ax,bx
|
|
! tol desired length of the interval of uncertainty of the
|
|
! final result ( .ge. 0.0d0)
|
|
!
|
|
!
|
|
! output..
|
|
!
|
|
! zeroin abcissa approximating a zero of f in the interval ax,bx
|
|
!
|
|
!
|
|
! it is assumed that f(ax) and f(bx) have opposite signs
|
|
! without a check. zeroin returns a zero x in the given interval
|
|
! ax,bx to within a tolerance 4*macheps*abs(x) + tol, where macheps
|
|
! is the relative machine precision.
|
|
! this function subprogram is a slightly modified translation of
|
|
! the algol 60 procedure zero given in richard brent, algorithms for
|
|
! minimization without derivatives, prentice - hall, inc. (1973).
|
|
!
|
|
! NOTES:
|
|
! (1 ) Change dabs to ABS and dsign to SIGN, in order to avoid conflicts
|
|
! with intrinsic function names on the PGI compiler. (bmy, 12/2/04)
|
|
!******************************************************************************
|
|
!
|
|
real*8, intent(in) :: ax,bx,tol
|
|
REAL*8, INTENT(IN) :: Mpoc
|
|
REAL*8, INTENT(IN) :: Aerosol(NPROD,MHC), Gas(NPROD,MHC)
|
|
REAL*8, INTENT(IN) :: Kom(NPROD,MHC)
|
|
|
|
!local variables
|
|
real*8 :: MNEW
|
|
real*8 :: a,b,c,d,e,eps,fa,fb,fc,tol1,xm,p,q,r,s
|
|
c
|
|
c compute eps, the relative machine precision
|
|
c
|
|
eps = 1.0d0
|
|
10 eps = eps/2.0d0
|
|
tol1 = 1.0d0 + eps
|
|
if (tol1 .gt. 1.0d0) go to 10
|
|
c
|
|
c initialization
|
|
c
|
|
a = ax
|
|
b = bx
|
|
fa = SOA_equil( A, MPOC, Aerosol, GAS, Kom )
|
|
fb = SOA_equil( B, MPOC, Aerosol, GAS, Kom )
|
|
c
|
|
c begin step
|
|
c
|
|
20 c = a
|
|
fc = fa
|
|
d = b - a
|
|
e = d
|
|
|
|
30 if (ABS(fc) .ge. ABS(fb)) go to 40
|
|
a = b
|
|
b = c
|
|
c = a
|
|
fa = fb
|
|
fb = fc
|
|
fc = fa
|
|
c
|
|
c convergence test
|
|
c
|
|
40 tol1 = 2.0d0*eps*ABS(b) + 0.5d0*tol
|
|
xm = 0.5D0*(c - b)
|
|
if (ABS(xm) .le. tol1) go to 90
|
|
if (fb .eq. 0.0d0) go to 90
|
|
c
|
|
c is bisection necessary
|
|
c
|
|
if (ABS(e) .lt. tol1) go to 70
|
|
if (ABS(fa) .le. ABS(fb)) go to 70
|
|
c
|
|
c is quadratic interpolation possible
|
|
c
|
|
if (a .ne. c) go to 50
|
|
c
|
|
c linear interpolation
|
|
c
|
|
s = fb/fa
|
|
p = 2.0d0*xm*s
|
|
q = 1.0d0 - s
|
|
go to 60
|
|
c
|
|
c inverse quadratic interpolation
|
|
c
|
|
50 q = fa/fc
|
|
r = fb/fc
|
|
s = fb/fa
|
|
p = s*(2.0d0*xm*q*(q - r) - (b - a)*(r - 1.0d0))
|
|
q = (q - 1.0d0)*(r - 1.0d0)*(s - 1.0d0)
|
|
c
|
|
c adjust signs
|
|
c
|
|
60 if (p .gt. 0.0d0) q = -q
|
|
p = ABS(p)
|
|
c
|
|
c is interpolation acceptable
|
|
c
|
|
if ((2.0d0*p) .ge. (3.0d0*xm*q - ABS(tol1*q))) go to 70
|
|
if (p .ge. ABS(0.5d0*e*q)) go to 70
|
|
|
|
e = d
|
|
d = p/q
|
|
go to 80
|
|
c
|
|
c bisection
|
|
c
|
|
70 d = xm
|
|
e = d
|
|
c
|
|
c complete step
|
|
c
|
|
80 a = b
|
|
fa = fb
|
|
if (ABS(d) .gt. tol1) b = b + d
|
|
if (ABS(d) .le. tol1) b = b + SIGN(tol1, xm)
|
|
|
|
fb = SOA_equil( B, MPOC, Aerosol, GAS, Kom )
|
|
if ((fb*(fc/ABS(fc))) .gt. 0.0d0) go to 20
|
|
go to 30
|
|
c
|
|
c done
|
|
c
|
|
90 MNEW = b
|
|
|
|
! Return to calling program
|
|
END FUNCTION ZEROIN
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
FUNCTION RTBIS( X1, X2, XACC,
|
|
& MPOC, AEROSOL, GAS, KOM ) RESULT( ROOT )
|
|
!
|
|
!******************************************************************************
|
|
! Function RTBIS finds the root of the function SOA_EQUIL via the bisection
|
|
! method. Original algorithm from "Numerical Recipes" by Press et al,
|
|
! Cambridge UP, 1986. Modified for inclusion into GEOS-CHEM. (bmy, 7/8/04)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) X1 (REAL*8) : Endpoint #1
|
|
! (2 ) X2 (REAL*8) : Endpoint #2
|
|
! (3 ) XACC (REAL*8) : Desired accuracy of solution
|
|
! (4 ) MPOC (REAL*8) : POA Mass [ug/m3]
|
|
! (5 ) AEROSOL (REAL*8) : Aerosol concentration [ug/m3]
|
|
! (6 ) GAS (REAL*8) : Gas-phase concentration [ug/m3]
|
|
! (7 ) KOM (REAL*8) : Equilibrium gas-aerosol partition coeff. [m3/ug]
|
|
!
|
|
! NOTES:
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE ERROR_MOD, ONLY : ERROR_STOP
|
|
|
|
! Arguments
|
|
REAL*8, INTENT(IN) :: X1, X2, XACC, MPOC
|
|
REAL*8, INTENT(IN) :: AEROSOL(NPROD,MHC)
|
|
REAL*8, INTENT(IN) :: GAS(NPROD,MHC)
|
|
REAL*8, INTENT(IN) :: KOM(NPROD,MHC)
|
|
|
|
! Local variables
|
|
INTEGER, PARAMETER :: JMAX = 100
|
|
INTEGER :: J
|
|
REAL*8 :: ROOT, DX, F, FMID, XMID
|
|
|
|
!=================================================================
|
|
! RTBIS begins here!
|
|
!=================================================================
|
|
|
|
! Compute value of function SOA_EQUIL at endpoints
|
|
FMID = SOA_EQUIL( X2, MPOC, AEROSOL, GAS, KOM )
|
|
F = SOA_EQUIL( X1, MPOC, AEROSOL, GAS, KOM )
|
|
|
|
! Test if we are bracketing a root
|
|
IF ( F * FMID >= 0d0 ) THEN
|
|
CALL ERROR_STOP( 'Root must be bracketed!',
|
|
& 'RTBIS ("carbon_mod.f")' )
|
|
ENDIF
|
|
|
|
! Set initial root and interval
|
|
IF ( F < 0d0 ) THEN
|
|
ROOT = X1
|
|
DX = X2 - X1
|
|
ELSE
|
|
ROOT = X2
|
|
DX = X1 - X2
|
|
ENDIF
|
|
|
|
! Loop until max iteration count
|
|
DO J = 1, JMAX
|
|
|
|
! Halve the existing interval
|
|
DX = DX * 0.5D0
|
|
|
|
! Compute midpoint of new interval
|
|
XMID = ROOT + DX
|
|
|
|
! Compute value of function SOA_EQUIL at new midpoint
|
|
FMID = SOA_EQUIL( XMID, MPOC, AEROSOL, GAS, KOM )
|
|
|
|
! We have found the root!
|
|
IF ( FMID <= 0D0 ) ROOT = XMID
|
|
|
|
! We have reached the tolerance, so return
|
|
IF ( ABS( DX ) < XACC .OR. FMID == 0.D0 ) RETURN
|
|
ENDDO
|
|
|
|
! Stop with error condition
|
|
CALL ERROR_STOP( 'Too many bisections!',
|
|
& 'RTBIS ("carbon_mod.f")' )
|
|
|
|
! Return to calling program
|
|
END FUNCTION RTBIS
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOA_PARA( II, JJ, LL, TEMP,
|
|
& KO3, KOH, KNO3, RALPHA, KOM )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOA_PARA gves mass-based stoichiometric coefficients for semi-
|
|
! volatile products from the oxidation of hydrocarbons. It calculates
|
|
! secondary organic aerosol yield parameters. Temperature effects are
|
|
! included. Original code from the CALTECH group and modified for inclusion
|
|
! to GEOS-CHEM. (rjp, bmy, 7/8/04, 6/30/08)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) II (INTEGER) : GEOS-Chem longitude index
|
|
! (2 ) JJ (INTEGER) : GEOS-Chem latitude index
|
|
! (3 ) LL (INTEGER) : GEOS-Chem altitude index
|
|
! (4 ) TEMP (REAL*8 ) : Temperature [k]
|
|
!
|
|
! Arguments as Output:
|
|
! ============================================================================
|
|
! (5 ) KO3 (REAL*8 ) : Rxn rate for HC oxidation by O3 [cm3/molec/s]
|
|
! (6 ) KOH (REAL*8 ) : Rxn rate for HC oxidation by OH [cm3/molec/s]
|
|
! (7 ) KNO3 (REAL*8 ) : Rxn rate for HC oxidation by NO3 [cm3/molec/s]
|
|
! (8 ) RALPHA (REAL*8 ) : Mass-based stoichiometric coefficients [unitless]
|
|
! (9 ) KOM (REAL*8 ) : Equilibrium gas-aerosol partition coeff [m3/ug]
|
|
!
|
|
! References:
|
|
! ============================================================================
|
|
! PHOTO-OXIDATION RATE CONSTANTS OF ORGANICS come from:
|
|
! (1 ) Atkinson, el al., Int. J. Chem.Kinet., 27: 941-955 (1995)
|
|
! (2 ) Shu and Atkinson, JGR 100: 7275-7281 (1995)
|
|
! (3 ) Atkinson, J. Phys. Chem. Ref. Data 26: 215-290 (1997)
|
|
! (4 ) Some are reproduced in Table 1 of Griffin, et al., JGR 104: 3555-3567
|
|
! (5 ) Chung and Seinfeld (2002)
|
|
!
|
|
! ACTIVATION ENERGIES come from:
|
|
! (6 ) Atkinson, R. (1994) Gas-Phase Tropospheric Chemistry of Organic
|
|
! Compounds. J. Phys. Chem. Ref. Data, Monograph No.2, 1-216.
|
|
! (7 ) They are also reproduced in Tables B.9 and B.10 of Seinfeld and
|
|
! Pandis (1988).
|
|
!
|
|
! PARAMETERS FOR ISOPRENE:
|
|
! (8 ) Kroll et al., GRL, 109, L18808 (2005)
|
|
! (9 ) Kroll et al., Environ Sci Tech, in press (2006)
|
|
! (10) Henze and Seinfeld, GRL, submitted (2006)
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now use temporary variables TMP1, TMP2, TMP3 to pre-store the values
|
|
! of exponential terms outside of DO-loops (bmy, 7/8/04)
|
|
! (2 ) Add parameters for isoprene. Now include grid cell location in
|
|
! subroutine arguments. Define a reference temperature at 295.
|
|
! Now use ITS_IN_THE_TROP to determine if we are in a tropospheric
|
|
! grid box. Now pass II, JJ, LL via the argument list.
|
|
! (dkh, bmy, 5/22/06)
|
|
! (3 ) Corrected confusing documentation. (clh, bmy, 6/30/08)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE TROPOPAUSE_MOD, ONLY : ITS_IN_THE_TROP
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: II, JJ, LL
|
|
REAL*8, INTENT(IN) :: TEMP
|
|
REAL*8, INTENT(OUT) :: KO3(MHC), KOH(MHC), KNO3(MHC)
|
|
REAL*8, INTENT(OUT) :: RALPHA(NPROD,MHC), KOM(NPROD,MHC)
|
|
|
|
! Local variables
|
|
INTEGER :: IPR, JHC, J
|
|
REAL*8 :: TMP1, TMP2, TMP3, OVER
|
|
|
|
! Activation Energy/R [K] for O3, OH, NO3 (see Refs #6-7)
|
|
REAL*8, PARAMETER :: ACT_O3 = 732.0d0
|
|
REAL*8, PARAMETER :: ACT_OH = -400.0d0
|
|
REAL*8, PARAMETER :: ACT_NO3 = -490.0d0
|
|
|
|
! Heat of vaporization (from CRC Handbook of Chemistry & Physics)
|
|
REAL*8, PARAMETER :: HEAT_VAPOR = 5.d3
|
|
|
|
! Reciprocal reference temperatures at 298K and 310K
|
|
REAL*8, PARAMETER :: REF295 = 1d0 / 295d0
|
|
REAL*8, PARAMETER :: REF298 = 1d0 / 298d0
|
|
REAL*8, PARAMETER :: REF310 = 1d0 / 310d0
|
|
|
|
!=================================================================
|
|
! SOA_PARA begins here!
|
|
!=================================================================
|
|
|
|
! Photo-oxidation rates of O3 [cm3/molec/s] (See Refs #1-4)
|
|
KO3(1) = 56.15d-18
|
|
KO3(2) = 200.d-18
|
|
KO3(3) = 7707.d-18
|
|
KO3(4) = 422.5d-18
|
|
KO3(5) = ( 11600.D0 + 11700.D0 ) / 2.D0 * 1.D-18
|
|
|
|
! Photo-oxidation rates of OH [cm3/molec/s] (See Refs #1-4)
|
|
KOH(1) = 84.4d-12
|
|
KOH(2) = 171.d-12
|
|
KOH(3) = 255.d-12
|
|
KOH(4) = 199.d-12
|
|
KOH(5) = ( 197.d0 + 293.d0 ) / 2.d0 * 1.d-12
|
|
|
|
! Photo-oxidation rate of NO3 [cm3/molec/s] (See Refs #1-4)
|
|
KNO3(1) = 6.95d-12
|
|
KNO3(2) = 12.2d-12
|
|
KNO3(3) = 88.7d-12
|
|
KNO3(4) = 14.7d-12
|
|
KNO3(5) = ( 19.d0 + 35.d0 ) / 2.d0 * 1.d-12
|
|
|
|
!=================================================================
|
|
! Temperature Adjustments of KO3, KOH, KNO3
|
|
!=================================================================
|
|
|
|
! Reciprocal temperature [1/K]
|
|
OVER = 1.0d0 / TEMP
|
|
|
|
! Compute the exponentials once outside the DO loop
|
|
TMP1 = EXP( ACT_O3 * ( REF298 - OVER ) )
|
|
TMP2 = EXP( ACT_OH * ( REF298 - OVER ) )
|
|
TMP3 = EXP( ACT_NO3 * ( REF298 - OVER ) )
|
|
|
|
! Multiply photo-oxidation rates by exponential of temperature
|
|
DO JHC = 1, MHC
|
|
KO3(JHC) = KO3(JHC) * TMP1
|
|
KOH(JHC) = KOH(JHC) * TMP2
|
|
KNO3(JHC) = KNO3(JHC) * TMP3
|
|
ENDDO
|
|
|
|
! If we are in the troposphere, then calculate ISOP oxidation rates
|
|
! If we are in the stratosphere, set ISOP oxidation rates to zero
|
|
! (dkh, bmy, 5/22/06)
|
|
IF ( ITS_IN_THE_TROP( II, JJ, LL ) ) THEN
|
|
KO3(6) = 1.05d-14 * EXP(-2000.d0 / TEMP )
|
|
KOH(6) = 2.70d-11 * EXP( 390.d0 / TEMP )
|
|
KNO3(6) = 3.03d-12 * EXP(-446.d0 / TEMP )
|
|
ELSE
|
|
KO3(6) = 0d0
|
|
KOH(6) = 0d0
|
|
KNO3(6) = 0d0
|
|
ENDIF
|
|
|
|
!=================================================================
|
|
! SOA YIELD PARAMETERS
|
|
!
|
|
! Aerosol yield parameters for photooxidation of biogenic organics
|
|
! The data (except for C7-C10 n-carbonyls, aromatics, and higher
|
|
! ketones are from:
|
|
!
|
|
! (7) Tables 1 and 2 of Griffin, et al., Geophys. Res. Lett.
|
|
! 26: (17)2721-2724 (1999)
|
|
!
|
|
! These parameters neglect contributions of the photooxidation
|
|
! by NO3.
|
|
!
|
|
! For the aromatics, the data are from
|
|
! (8) Odum, et al., Science 276: 96-99 (1997).
|
|
!
|
|
! Isoprene (dkh, bmy, 5/22/06)
|
|
! Unlike the other species, we consider oxidation by purely OH.
|
|
! CHEM_NVOC has been adjusted accordingly. There's probably
|
|
! significant SOA formed from NO3 oxidation, but we don't know
|
|
! enough to include that yet. Data for the high NOX and low NOX
|
|
! parameters are given in Kroll 05 and Kroll 06, respectively.
|
|
! The paramters for low NOX are given in Table 1 of Henze 06.
|
|
!=================================================================
|
|
|
|
! Average of ALPHA-PINENE, BETA-PINENE, SABINENE, D3-CARENE
|
|
RALPHA(1,1) = 0.067d0
|
|
RALPHA(2,1) = 0.35425d0
|
|
|
|
! LIMONENE
|
|
RALPHA(1,2) = 0.239d0
|
|
RALPHA(2,2) = 0.363d0
|
|
|
|
! Average of TERPINENES and TERPINOLENE
|
|
RALPHA(1,3) = 0.0685d0
|
|
RALPHA(2,3) = 0.2005d0
|
|
|
|
! Average of MYRCENE, LINALOOL, TERPINENE-4-OL, OCIMENE
|
|
RALPHA(1,4) = 0.06675d0
|
|
RALPHA(2,4) = 0.135d0
|
|
|
|
! Average of BETA-CARYOPHYLLENE and and ALPHA-HUMULENE
|
|
RALPHA(1,5) = 1.0d0
|
|
RALPHA(2,5) = 0.0d0
|
|
|
|
! Using BETA-PINENE for all species for NO3 oxidation
|
|
! Data from Table 4 of Griffin, et al., JGR 104 (D3): 3555-3567 (1999)
|
|
RALPHA(3,:) = 1.d0
|
|
|
|
! Here we define some alphas for isoprene (dkh, bmy, 5/22/06)
|
|
|
|
! high NOX [Kroll et al, 2005]
|
|
!RALPHA(1,6) = 0.264d0
|
|
!RALPHA(2,6) = 0.0173d0
|
|
!RALPHA(3,6) = 0d0
|
|
|
|
! low NOX [Kroll et al, 2006; Henze and Seinfeld, 2006]
|
|
RALPHA(1,6) = 0.232d0
|
|
RALPHA(2,6) = 0.0288d0
|
|
RALPHA(3,6) = 0d0
|
|
|
|
!=================================================================
|
|
! Equilibrium gas-particle partition coefficients of
|
|
! semi-volatile compounds [ug-1 m**3]
|
|
!=================================================================
|
|
|
|
! Average of ALPHA-PINENE, BETA-PINENE, SABINENE, D3-CARENE
|
|
KOM(1,1) = 0.1835d0
|
|
KOM(2,1) = 0.004275d0
|
|
|
|
! LIMONENE
|
|
KOM(1,2) = 0.055d0
|
|
KOM(2,2) = 0.0053d0
|
|
|
|
! Average of TERPINENES and TERPINOLENE
|
|
KOM(1,3) = 0.133d0
|
|
KOM(2,3) = 0.0035d0
|
|
|
|
! Average of MYRCENE, LINALOOL, TERPINENE-4-OL, OCIMENE
|
|
KOM(1,4) = 0.22375d0
|
|
KOM(2,4) = 0.0082d0
|
|
|
|
! Average of BETA-CARYOPHYLLENE and and ALPHA-HUMULENE
|
|
KOM(1,5) = ( 0.04160d0 + 0.0501d0 ) / 2.d0
|
|
KOM(2,5) = 0.0d0
|
|
|
|
! NOT APPLICABLE -- using BETA-PINENE for all species
|
|
! Data from Table 4 of Griffin, et al., JGR 104 (D3): 3555-3567 (1999)
|
|
KOM(3,:) = 0.0163d0
|
|
|
|
! Again, for isoprene we only consider two products,
|
|
! both from OH oxidation. (dkh, bmy, 5/22/06)
|
|
|
|
! High NOX
|
|
!KOM(1,6) = 0.00115d0
|
|
!KOM(2,6) = 1.52d0
|
|
!KOM(3,6) = 0d0
|
|
|
|
! Low NOX
|
|
KOM(1,6) = 0.00862d0
|
|
KOM(2,6) = 1.62d0
|
|
KOM(3,6) = 0d0
|
|
|
|
!=================================================================
|
|
! Temperature Adjustments of KOM
|
|
!=================================================================
|
|
|
|
! Reciprocal temperature [1/K]
|
|
OVER = 1.0D0 / TEMP
|
|
|
|
! Divide TEMP by 310K outside the DO loop
|
|
TMP1 = ( TEMP / 310.D0 )
|
|
|
|
! Compute the heat-of-vaporization exponential term outside the DO loop
|
|
TMP2 = EXP( HEAT_VAPOR * ( OVER - REF310 ) )
|
|
|
|
! Multiply KOM by the temperature and heat-of-vaporization terms
|
|
DO JHC = 1, 5
|
|
DO IPR = 1, 3
|
|
KOM(IPR,JHC) = KOM(IPR,JHC) * TMP1 * TMP2
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!--------------------------------------------------------
|
|
! For isoprene products, reference temperature is 295 K.
|
|
! (dkh, bmy, 5/22/06)
|
|
!--------------------------------------------------------
|
|
|
|
! Divide TEMP by 295K outside the DO loop
|
|
TMP1 = ( TEMP / 295.D0 )
|
|
|
|
! Compute the heat-of-vaporization exponential term outside the DO loop
|
|
TMP2 = EXP( HEAT_VAPOR * ( OVER - REF295 ) )
|
|
|
|
! Multiply KOM by the temperature and heat-of-vaporization terms
|
|
JHC = 6
|
|
DO IPR = 1, 3
|
|
KOM(IPR,JHC) = KOM(IPR,JHC) * TMP1 * TMP2
|
|
ENDDO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOA_PARA
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE CHEM_NVOC( I, J, L, KO3, KOH, KNO3, ALPHA, GM0 )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine CHEM_NVOC computes the oxidation of Hydrocarbon by O3, OH, and
|
|
! NO3. This comes from the Caltech group (Hong Liao, Serena Chung, et al)
|
|
! and was incorporated into GEOS-CHEM. (rjp, bmy, 7/6/04, 6/1/06)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) I (INTEGER) : GEOS-Chem longitude index
|
|
! (2 ) J (INTEGER) : GEOS-Chem latitude index
|
|
! (3 ) L (INTEGER) : GEOS-Chem altitude index
|
|
! (4 ) KO3 (REAL*8 ) : Rxn rate for HC oxidation by O3 [cm3/molec/s]
|
|
! (5 ) KOH (REAL*8 ) : Rxn rate for HC oxidation by OH [cm3/molec/s]
|
|
! (6 ) KNO3 (REAL*8 ) : Rxn rate for HC oxidation by NO3 [cm3/molec/s]
|
|
! (7 ) ALPHA (REAL*8 ) : Mass-based stoichiometric coefficients [unitless]
|
|
!
|
|
! Arguments as Output:
|
|
! ============================================================================
|
|
! (8 ) GM0 (REAL*8 ) : Gas mass for each HC and its oxidation product [kg]
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references STT from "tracer_mod.f" (bmy, 7/20/04)
|
|
! (2 ) Now make sure all USE statements are USE, ONLY (bmy, 10/3/05)
|
|
! (3 ) Updated for SOA from isoprene. Now calls GET_DOH. (dkh, bmy, 6/1/06)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 kmodules
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTALCO, IDTALPH, IDTLIMO
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM, GET_MONTH
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: I, J, L
|
|
REAL*8, INTENT(IN) :: KO3(MHC), KOH(MHC), KNO3(MHC)
|
|
REAL*8, INTENT(IN) :: ALPHA(NPROD,MHC)
|
|
REAL*8, INTENT(INOUT) :: GM0(NPROD,MHC)
|
|
|
|
! Local variables
|
|
INTEGER :: JHC, IPR
|
|
REAL*8 :: DELHC(NPROD), CHANGE(MHC), NMVOC(MHC)
|
|
REAL*8 :: OHMC, TTNO3, TTO3, DTCHEM, RK
|
|
REAL*8 :: OVER, DO3, DOH, DNO3
|
|
|
|
!=================================================================
|
|
! CHEM_NVOC begins here!
|
|
!=================================================================
|
|
|
|
! Chemistry timestep [s]
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
! Get offline OH, NO3, O3 concentrations [molec/cm3]
|
|
OHMC = GET_OH( I, J, L )
|
|
TTNO3 = GET_NO3( I, J, L )
|
|
TTO3 = GET_O3( I, J, L )
|
|
|
|
! 6 classes NVOC concentrations followed by 4 primary species
|
|
NMVOC(1) = STT(I,J,L,IDTALPH)
|
|
NMVOC(2) = STT(I,J,L,IDTLIMO)
|
|
NMVOC(3) = ORVC_TERP(I,J,L)
|
|
NMVOC(4) = STT(I,J,L,IDTALCO)
|
|
NMVOC(5) = ORVC_SESQ(I,J,L)
|
|
|
|
! Initialize DELHC so that the values from the previous
|
|
! time step are not carried over.
|
|
DELHC(:) = 0.D0
|
|
|
|
!=================================================================
|
|
! Change in NVOC concentration due to photooxidation [kg]
|
|
!=================================================================
|
|
DO JHC = 1, MHC
|
|
|
|
IF ( JHC <= 5 ) THEN
|
|
|
|
!-------------------------------
|
|
! Individual gas-phase products
|
|
!-------------------------------
|
|
|
|
RK = KO3(JHC)*TTO3 + KOH(JHC)*OHMC
|
|
& + KNO3(JHC)*TTNO3
|
|
CHANGE(JHC) = NMVOC(JHC) * ( 1.D0 - DEXP( -RK * DTCHEM ) )
|
|
|
|
! In case that the biogenic hydrocarbon is the limiting reactant
|
|
IF ( CHANGE(JHC) >= NMVOC(JHC) ) CHANGE(JHC) = NMVOC(JHC)
|
|
|
|
! NMVOC concentration after oxidation reactions
|
|
NMVOC(JHC) = NMVOC(JHC) - CHANGE(JHC)
|
|
|
|
IF( CHANGE(JHC) > 1.D-16 ) THEN
|
|
OVER = 1.D0 / RK
|
|
DO3 = CHANGE(JHC) * KO3(JHC) * TTO3 * OVER ![kg]
|
|
DOH = CHANGE(JHC) * KOH(JHC) * OHMC * OVER ![kg]
|
|
DNO3 = CHANGE(JHC) * KNO3(JHC) * TTNO3 * OVER ![kg]
|
|
ELSE
|
|
DO3 = 0.D0
|
|
DOH = 0.D0
|
|
DNO3 = 0.D0
|
|
ENDIF
|
|
|
|
! VOC change by photooxidation of O3 and OH [kg]
|
|
DELHC(1) = DO3 + DOH
|
|
DELHC(2) = DO3 + DOH
|
|
|
|
! VOC change by photooxidation of NO3 [kg]
|
|
DELHC(3) = DNO3
|
|
|
|
! Lump OH and O3 oxidation for HC 1-5
|
|
DO IPR = 1, NPROD
|
|
GM0(IPR,JHC) = GM0(IPR,JHC) + ALPHA(IPR,JHC) * DELHC(IPR)
|
|
ENDDO
|
|
|
|
ELSE
|
|
|
|
!-------------------------------
|
|
! SOA from ISOPRENE
|
|
!-------------------------------
|
|
|
|
! Get ISOP lost to rxn with OH [kg]
|
|
DOH = GET_DOH( I, J, L )
|
|
|
|
! Consider only OH oxidation for isoprene. Also convert
|
|
! from mass of carbon to mass of isoprene. (dkh, bmy, 5/22/06)
|
|
DO IPR = 1, 3
|
|
GM0(IPR,JHC) = GM0(IPR,JHC) + ALPHA(IPR,JHC) * DOH
|
|
& * 68d0 / 60d0
|
|
ENDDO
|
|
ENDIF
|
|
|
|
ENDDO
|
|
|
|
!=================================================================
|
|
! Store Hydrocarbon remaining after oxidation rxn back into STT
|
|
!=================================================================
|
|
STT(I,J,L,IDTALPH) = MAX( NMVOC(1), 1.D-32 )
|
|
STT(I,J,L,IDTLIMO) = MAX( NMVOC(2), 1.D-32 )
|
|
ORVC_TERP(I,J,L) = MAX( NMVOC(3), 1.D-32 )
|
|
STT(I,J,L,IDTALCO) = MAX( NMVOC(4), 1.D-32 )
|
|
ORVC_SESQ(I,J,L) = MAX( NMVOC(5), 1.D-32 )
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE CHEM_NVOC
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOA_PARTITION( I, J, L, GM0, AM0 )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOA_PARTITION partitions the mass of gas and aerosol
|
|
! tracers according to five Hydrocarbon species and three oxidants.
|
|
! (rjp, bmy, 7/7/04, 5/22/06)
|
|
!
|
|
! NOTE: GPROD and APROD are mass ratios of individual oxidation
|
|
! products of gas/aerosol to the sum of all.
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) I (INTEGER) : GEOS-CHEM longitude index
|
|
! (2 ) J (INTEGER) : GEOS-CHEM latitude index
|
|
! (3 ) L (INTEGER) : GEOS-CHEM altitude index
|
|
!
|
|
! Arguments as Output:
|
|
! ============================================================================
|
|
! (4 ) GM0 (REAL*8 ) : Gas mass for each HC and its oxidation product [kg]
|
|
! (5 ) AM0 (REAL*8 ) : Aerosol mass for each HC and its oxidation product [kg]
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references STT from "tracer_mod.f" (bmy, 7/20/04)
|
|
! (2 ) Now make sure all USE statements are USE, ONLY (bmy, 10/3/05)
|
|
! (3 ) Updated for SOG4, SOA4 (bmy, 5/22/06)
|
|
!******************************************************************************
|
|
!
|
|
! Refrences to F90 modules
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTSOA1, IDTSOA2, IDTSOA3, IDTSOA4
|
|
USE TRACERID_MOD, ONLY : IDTSOG1, IDTSOG2, IDTSOG3, IDTSOG4
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: I, J, L
|
|
REAL*8, INTENT(OUT) :: GM0(NPROD,MHC), AM0(NPROD,MHC)
|
|
|
|
! Local variables
|
|
INTEGER :: JHC, IPR
|
|
|
|
!=================================================================
|
|
! SOA_PARTITION begins here!
|
|
!=================================================================
|
|
|
|
! Initialize
|
|
DO JHC = 1, 3
|
|
DO IPR = 1, NPROD
|
|
GM0(IPR,JHC) = 0D0
|
|
AM0(IPR,JHC) = 0D0
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! Partition the lump of first three HC (ALPH + LIMO + TERP)
|
|
! oxidation products. These are grouped together because they
|
|
! have the same molecular weight.
|
|
DO JHC = 1, 3
|
|
DO IPR = 1, NPROD
|
|
GM0(IPR,JHC) = STT(I,J,L,IDTSOG1) * GPROD(I,J,L,IPR,JHC)
|
|
AM0(IPR,JHC) = STT(I,J,L,IDTSOA1) * APROD(I,J,L,IPR,JHC)
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! Alcohol
|
|
JHC = 4
|
|
DO IPR = 1, NPROD
|
|
GM0(IPR,JHC) = STT(I,J,L,IDTSOG2) * GPROD(I,J,L,IPR,JHC)
|
|
AM0(IPR,JHC) = STT(I,J,L,IDTSOA2) * APROD(I,J,L,IPR,JHC)
|
|
ENDDO
|
|
|
|
! Sesqterpene
|
|
JHC = 5
|
|
DO IPR = 1, NPROD
|
|
GM0(IPR,JHC) = STT(I,J,L,IDTSOG3) * GPROD(I,J,L,IPR,JHC)
|
|
AM0(IPR,JHC) = STT(I,J,L,IDTSOA3) * APROD(I,J,L,IPR,JHC)
|
|
ENDDO
|
|
|
|
! Isoprene
|
|
JHC = 6
|
|
DO IPR = 1, NPROD
|
|
GM0(IPR,JHC) = STT(I,J,L,IDTSOG4) * GPROD(I,J,L,IPR,JHC)
|
|
AM0(IPR,JHC) = STT(I,J,L,IDTSOA4) * APROD(I,J,L,IPR,JHC)
|
|
ENDDO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOA_PARTITION
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOA_LUMP( I, J, L, GM0, AM0 )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOA_LUMP returns the organic gas and aerosol back to the
|
|
! STT array. (rjp, bmy, 7/7/04, 2/6/07)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) I (INTEGER) : Longitude index
|
|
! (2 ) J (INTEGER) : Latitude index
|
|
! (3 ) L (INTEGER) : Altitude index
|
|
! (4 ) GM0 (REAL*8 ) : Gas mass for each HC and its oxidation product [kg]
|
|
! (5 ) AM0 (REAL*8 ) : Aerosol mass for each HC and its oxidation product [kg]
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references STT from "tracer_mod.f" (bmy, 7/20/04)
|
|
! (2 ) Bug fix: make sure L <= LD07 before saving into AD07 array, or else
|
|
! we will get an out-of-bounds error. (bmy, 3/4/05)
|
|
! (3 ) Now make sure all USE statements are USE, ONLY (bmy, 10/3/05)
|
|
! (4 ) Updated for SOG4, SOA4 (dkh, bmy, 5/22/06)
|
|
! (5 ) Typo fix: GPROD should be APROD in a couple places (tmf, bmy, 10/16/06)
|
|
! (6 ) Bug fix: For SOA4, GPROD and APROD should have default values of 0.5,
|
|
! instead of 1.0 (dkh, bmy, 2/6/07)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DIAG_MOD, ONLY : AD07_HC
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTSOA1, IDTSOA2, IDTSOA3, IDTSOA4
|
|
USE TRACERID_MOD, ONLY : IDTSOG1, IDTSOG2, IDTSOG3, IDTSOG4
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND44, ND07, LD07
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: I, J, L
|
|
REAL*8, INTENT(IN) :: GM0(NPROD,MHC), AM0(NPROD,MHC)
|
|
|
|
! Local variables
|
|
INTEGER :: JHC, IPR
|
|
REAL*8 :: GASMASS, AERMASS
|
|
|
|
!=================================================================
|
|
! SOA_LUMP begins here!
|
|
!=================================================================
|
|
|
|
! Initialize
|
|
GASMASS = 0D0
|
|
AERMASS = 0D0
|
|
|
|
! Compute total gas & aerosol mass
|
|
DO JHC = 1, 3
|
|
DO IPR = 1, NPROD
|
|
GASMASS = GASMASS + GM0(IPR,JHC)
|
|
AERMASS = AERMASS + AM0(IPR,JHC)
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!----------------------------
|
|
! SOA1 net Production (kg)
|
|
!----------------------------
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_HC(I,J,L,1) = AD07_HC(I,J,L,1)
|
|
& + ( AERMASS - STT(I,J,L,IDTSOA1) )
|
|
ENDIF
|
|
|
|
STT(I,J,L,IDTSOG1) = MAX( GASMASS, 1.D-32 )
|
|
STT(I,J,L,IDTSOA1) = MAX( AERMASS, 1.D-32 )
|
|
|
|
IF ( STT(I,J,L,IDTSOG1) > 1.0E-6 ) THEN
|
|
DO JHC = 1, 3
|
|
DO IPR = 1, NPROD
|
|
GPROD(I,J,L,IPR,JHC) = GM0(IPR,JHC) / STT(I,J,L,IDTSOG1)
|
|
ENDDO
|
|
ENDDO
|
|
ELSE
|
|
DO JHC = 1, 3
|
|
DO IPR = 1, NPROD
|
|
GPROD(I,J,L,IPR,JHC)= 0.111111111d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDIF
|
|
|
|
IF ( STT(I,J,L,IDTSOA1) > 1.0E-6 ) THEN
|
|
DO JHC = 1, 3
|
|
DO IPR = 1, NPROD
|
|
APROD(I,J,L,IPR,JHC) = AM0(IPR,JHC) / STT(I,J,L,IDTSOA1)
|
|
ENDDO
|
|
ENDDO
|
|
ELSE
|
|
DO JHC = 1, 3
|
|
DO IPR = 1, NPROD
|
|
APROD(I,J,L,IPR,JHC) = 0.111111111d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDIF
|
|
|
|
!=================================================================
|
|
! Lump of products of fourth Hydrocarbon class (ALCOHOL)
|
|
!=================================================================
|
|
|
|
JHC = 4
|
|
GASMASS = 0D0
|
|
AERMASS = 0D0
|
|
|
|
DO IPR = 1, NPROD
|
|
GASMASS = GASMASS + GM0(IPR,JHC)
|
|
AERMASS = AERMASS + AM0(IPR,JHC)
|
|
ENDDO
|
|
|
|
!---------------------------
|
|
! SOA2 net Production (kg)
|
|
!---------------------------
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_HC(I,J,L,2) = AD07_HC(I,J,L,2)
|
|
& + ( AERMASS - STT(I,J,L,IDTSOA2) )
|
|
ENDIF
|
|
|
|
STT(I,J,L,IDTSOG2) = MAX(GASMASS, 1.D-32)
|
|
STT(I,J,L,IDTSOA2) = MAX(AERMASS, 1.D-32)
|
|
|
|
IF ( STT(I,J,L,IDTSOG2) > 1.0E-6 ) THEN
|
|
DO IPR = 1, NPROD
|
|
GPROD(I,J,L,IPR,JHC) = GM0(IPR,JHC) / STT(I,J,L,IDTSOG2)
|
|
ENDDO
|
|
ELSE
|
|
DO IPR = 1, NPROD
|
|
GPROD(I,J,L,IPR,JHC) = 0.333333333d0
|
|
ENDDO
|
|
ENDIF
|
|
|
|
IF ( STT(I,J,L,IDTSOA2) > 1.0E-6 ) THEN
|
|
DO IPR = 1, NPROD
|
|
APROD(I,J,L,IPR,JHC) = AM0(IPR,JHC) / STT(I,J,L,IDTSOA2)
|
|
ENDDO
|
|
ELSE
|
|
DO IPR = 1, NPROD
|
|
APROD(I,J,L,IPR,JHC) = 0.333333333d0
|
|
ENDDO
|
|
ENDIF
|
|
|
|
!=================================================================
|
|
! Lump of products of fifth Hydrocarbon class (SESQTERPINE)
|
|
!=================================================================
|
|
JHC = 5
|
|
GASMASS = 0D0
|
|
AERMASS = 0D0
|
|
|
|
DO IPR = 1, NPROD
|
|
GASMASS = GASMASS + GM0(IPR,JHC)
|
|
AERMASS = AERMASS + AM0(IPR,JHC)
|
|
ENDDO
|
|
|
|
!---------------------------
|
|
! SOA3 net Production (kg)
|
|
!---------------------------
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_HC(I,J,L,3) = AD07_HC(I,J,L,3)
|
|
& + ( AERMASS - STT(I,J,L,IDTSOA3) )
|
|
ENDIF
|
|
|
|
STT(I,J,L,IDTSOG3) = MAX(GASMASS, 1.D-32)
|
|
STT(I,J,L,IDTSOA3) = MAX(AERMASS, 1.D-32)
|
|
|
|
IF ( STT(I,J,L,IDTSOG3) > 1.0E-6 ) THEN
|
|
DO IPR = 1, NPROD
|
|
GPROD(I,J,L,IPR,JHC) = GM0(IPR,JHC) / STT(I,J,L,IDTSOG3)
|
|
ENDDO
|
|
ELSE
|
|
DO IPR = 1, NPROD
|
|
GPROD(I,J,L,IPR,JHC) = 0.5D0
|
|
ENDDO
|
|
ENDIF
|
|
|
|
IF ( STT(I,J,L,IDTSOA3) > 1.0E-6 ) THEN
|
|
DO IPR = 1, NPROD
|
|
APROD(I,J,L,IPR,JHC) = AM0(IPR,JHC) / STT(I,J,L,IDTSOA3)
|
|
ENDDO
|
|
ELSE
|
|
DO IPR = 1, NPROD
|
|
APROD(I,J,L,IPR,JHC) = 0.5D0
|
|
ENDDO
|
|
ENDIF
|
|
|
|
! make sure there is no second oxidation product
|
|
! for SESQTERPENE by OH + O3
|
|
GPROD(I,J,L,2,JHC) = 0.D0
|
|
APROD(I,J,L,2,JHC) = 0.D0
|
|
|
|
|
|
!=================================================================
|
|
! Lump of products of sixth Hydrocarbon class (ISOP)
|
|
! (dkh, bmy, 5/22/06)
|
|
!=================================================================
|
|
JHC = 6
|
|
GASMASS = 0D0
|
|
AERMASS = 0D0
|
|
|
|
DO IPR = 1, NPROD
|
|
GASMASS = GASMASS + GM0(IPR,JHC)
|
|
AERMASS = AERMASS + AM0(IPR,JHC)
|
|
ENDDO
|
|
|
|
!---------------------------
|
|
! SOA4 net Production (kg)
|
|
!---------------------------
|
|
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_HC(I,J,L,4) = AD07_HC(I,J,L,4)
|
|
& + ( AERMASS - STT(I,J,L,IDTSOA4) )
|
|
ENDIF
|
|
|
|
STT(I,J,L,IDTSOG4) = MAX( GASMASS, 1.D-32 )
|
|
STT(I,J,L,IDTSOA4) = MAX( AERMASS, 1.D-32 )
|
|
|
|
IF ( STT(I,J,L,IDTSOG4) > 1.0E-6 ) THEN
|
|
DO IPR = 1, NPROD
|
|
GPROD(I,J,L,IPR,JHC) = GM0(IPR,JHC) / STT(I,J,L,IDTSOG4)
|
|
ENDDO
|
|
ELSE
|
|
DO IPR = 1, NPROD
|
|
GPROD(I,J,L,IPR,JHC) = 0.5d0 ! only one product
|
|
ENDDO
|
|
ENDIF
|
|
|
|
IF ( STT(I,J,L,IDTSOA4) > 1.0E-6 ) THEN
|
|
DO IPR = 1, NPROD
|
|
APROD(I,J,L,IPR,JHC) = AM0(IPR,JHC) / STT(I,J,L,IDTSOA4)
|
|
ENDDO
|
|
ELSE
|
|
DO IPR = 1, NPROD
|
|
APROD(I,J,L,IPR,JHC) = 0.5d0
|
|
ENDDO
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOA_LUMP
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOA_DEPO( TC, DEPID, TRID )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOA_DEPO computes dry-deposition of a particular SOA species.
|
|
! (rjp, bmy, 7/8/04, 10/25/05)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) TC (REAL*8 ) : Array of SOA tracer
|
|
! (2 ) DEPID (INTEGER) : Dry deposition ID # (from DEPVEL)
|
|
! (3 ) TRID (INTEGER) : GEOS-CHEM tracer number
|
|
!
|
|
! NOTES:
|
|
! (1 ) Remove reference to CMN, it's obsolete (bmy, 7/20/04)
|
|
! (2 ) Replace PBLFRAC from "drydep_mod.f" with GET_FRAC_UNDER_PBLTOP from
|
|
! "pbl_mix_mod.f" (bmy, 2/17/05)
|
|
! (3 ) Bug fix: Add BL_FRAC to the PRIVATE list (mak, bmy, 10/3/05)
|
|
! (4 ) Now references XNUMOL from "tracer_mod.f" (bmy, 10/25/05)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DAO_MOD, ONLY : AD
|
|
USE DIAG_MOD, ONLY : AD44
|
|
USE DRYDEP_MOD, ONLY : DEPSAV
|
|
USE GRID_MOD, ONLY : GET_AREA_CM2
|
|
USE PBL_MIX_MOD, ONLY : GET_FRAC_UNDER_PBLTOP
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
USE TRACER_MOD, ONLY : XNUMOL
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND44
|
|
|
|
! Arguments
|
|
REAL*8, INTENT(INOUT) :: TC(IIPAR,JJPAR,LLPAR)
|
|
INTEGER, INTENT(IN) :: DEPID, TRID
|
|
|
|
! Local variable
|
|
INTEGER :: I, J, L
|
|
REAL*8 :: DTCHEM, FLUX, BL_FRAC
|
|
REAL*8 :: TC0, CNEW, FREQ, AREA_CM2
|
|
REAL*8 :: ND44_TMP(IIPAR,JJPAR,LLPAR)
|
|
|
|
!=================================================================
|
|
! SOA_DEPO begins here!
|
|
!=================================================================
|
|
|
|
! Return if tracer ID or tracer ID is undefined
|
|
IF ( TRID == 0 .OR. DEPID == 0 ) RETURN
|
|
|
|
! Chemistry timestep [s]
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
! Initialize for drydep diagnostic
|
|
IF ( ND44 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
ND44_TMP(I,J,L) = 0d0
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
ENDIF
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L, TC0, BL_FRAC, FREQ, CNEW, AREA_CM2, FLUX )
|
|
!$OMP+SCHEDULE( DYNAMIC )
|
|
DO L = 1, LLPAR
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Initial SOA [kg]
|
|
TC0 = TC(I,J,L)
|
|
|
|
! Fraction of box under the PBL top [unitless]
|
|
BL_FRAC = GET_FRAC_UNDER_PBLTOP( I, J, L )
|
|
|
|
! Only apply drydep to boxes w/in the PBL
|
|
IF ( BL_FRAC > 0d0 ) THEN
|
|
|
|
! Drydep frequency [1/s]
|
|
FREQ = DEPSAV(I,J,DEPID) * BL_FRAC
|
|
|
|
! Amount of SOA[G] left after drydep [kg]
|
|
CNEW = TC0 * EXP( -FREQ * DTCHEM )
|
|
|
|
!===========================================================
|
|
! ND44 diagnostic: drydep loss [atoms C/cm2/s]
|
|
!===========================================================
|
|
IF ( ND44 > 0 ) THEN
|
|
|
|
! Surface area [cm2]
|
|
AREA_CM2 = GET_AREA_CM2( J )
|
|
|
|
! Convert drydep loss from [kg/timestep] to [atoms C/cm2/s]
|
|
FLUX = ( TC0 - CNEW )
|
|
FLUX = FLUX * XNUMOL(TRID) / ( AREA_CM2 * DTCHEM )
|
|
|
|
! Store in ND44_TMP as a placeholder
|
|
ND44_TMP(I,J,L) = ND44_TMP(I,J,L) + FLUX
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
! Otherwise, avoid doing the exponential
|
|
! to preserve precision and clock cycles
|
|
CNEW = TC0
|
|
|
|
ENDIF
|
|
|
|
! Prevent underflow condition
|
|
IF ( CNEW < SMALLNUM ) CNEW = 0d0
|
|
|
|
! Store modified concentration back in tracer array [kg]
|
|
TC(I,J,L) = CNEW
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! ND44: Sum drydep fluxes by level into the AD44 array in
|
|
! order to ensure that we get the same results w/ sp or mp
|
|
!=================================================================
|
|
IF ( ND44 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
DO L = 1, LLPAR
|
|
AD44(I,J,DEPID,1) = AD44(I,J,DEPID,1) + ND44_TMP(I,J,L)
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOA_DEPO
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE EMISSCARBON
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine EMISSCARBON is the interface between the GEOS-CHEM model
|
|
! and the CARBONACEOUS AEROSOL emissions (rjp, bmy, 1/24/02, 9/25/06)
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references LSOA from "CMN_SETUP". Also now call OHNO3TIME since
|
|
! biogenic emissions also have a diurnal variation. (rjp, bmy, 7/15/04)
|
|
! (2 ) Now references LSOA and LPRT from "logical_mod.f". Now references
|
|
! STT from "tracer_mod.f" (bmy, 7/20/04)
|
|
! (3 ) Bug fix: removed "," from FORMAT 111. Also added extra DEBUG_MSG
|
|
! output after calling emissions routines. (bmy, 11/19/04)
|
|
! (4 ) Now always call ANTHRO_CARB_TBOND and ANTHRO_CARB_COOKE. This will
|
|
! read the T. Bond et al [2004] emissions but overwrite the North
|
|
! America region with monthly-mean emissions from Cooke et al [1999]
|
|
! with imposed seasonality from R. Park [2003]. (bmy, 12/1/04)
|
|
! (5 ) Now remove THISMONTH from the arg list to BIOMASS_CARB_GEOS
|
|
! (bmy, 9/25/06)
|
|
! (6 ) Now check that GFED2 has been updated if we do not use the annual
|
|
! Bond Biomass emission (phs, yc, 12/18/08)
|
|
! (7 ) adj_group: Now add scaling factors for adjoint (dkh, 11/10/09)
|
|
! (8 ) Now reads monthly (eml, phs, 5/18/09)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DIAG_MOD, ONLY : AD07
|
|
USE DAO_MOD, ONLY : PBL
|
|
USE ERROR_MOD, ONLY : DEBUG_MSG
|
|
USE LOGICAL_MOD, ONLY : LSOA, LPRT, LCOOKE, LRCP
|
|
USE TIME_MOD, ONLY : GET_MONTH, ITS_A_NEW_MONTH
|
|
USE TIME_MOD, ONLY : GET_TS_EMIS
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE GFED2_BIOMASS_MOD, ONLY : GFED2_IS_NEW
|
|
USE GFED3_BIOMASS_MOD, ONLY : GFED3_IS_NEW
|
|
USE TRACERID_MOD, ONLY : IDTBCPO, IDTOCPO
|
|
USE HTAP_MOD, ONLY : GET_HTAP
|
|
USE GRID_MOD, ONLY : GET_AREA_CM2
|
|
|
|
! adj_group: add for emissions scale factors
|
|
USE ADJ_ARRAYS_MOD, ONLY : EMS_SF
|
|
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EBCPI_an, IDADJ_EBCPO_an
|
|
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EOCPI_an, IDADJ_EOCPO_an
|
|
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EBCPI_bb, IDADJ_EBCPO_bb
|
|
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EOCPI_bb, IDADJ_EOCPO_bb
|
|
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EBCPI_bf, IDADJ_EBCPO_bf
|
|
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EOCPI_bf, IDADJ_EOCPO_bf
|
|
USE ADJ_ARRAYS_MOD, ONLY : IS_CARB_EMS_ADJ
|
|
USE ADJ_ARRAYS_MOD, ONLY : MMSCL
|
|
USE ERROR_MOD, ONLY : ERROR_STOP
|
|
USE LOGICAL_ADJ_MOD, ONLY : LADJ_EMS
|
|
USE LOGICAL_MOD, ONLY : LHTAP, LBIOFUEL
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND07
|
|
|
|
! Local variables
|
|
LOGICAL, SAVE :: FIRST = .TRUE.
|
|
LOGICAL :: MOLEC_CM2_S
|
|
INTEGER :: I, J, MONTH, N, THISMONTH
|
|
REAL*8 :: BCSRC(IIPAR,JJPAR,2)
|
|
REAL*8 :: OCSRC(IIPAR,JJPAR,2)
|
|
REAL*8 :: BC(IIPAR,JJPAR), OC(IIPAR,JJPAR)
|
|
REAL*8 :: STEPS_PER_MON, AREA_CM2
|
|
REAL*8 :: FAC
|
|
|
|
! Hydrophilic fraction of BLACK CARBON (aka ELEMENTAL CARBON)
|
|
REAL*8, PARAMETER :: FHB = 0.2d0
|
|
|
|
! Hydrophilic fraction of ORGANIC CARBON
|
|
REAL*8, PARAMETER :: FHO = 0.5d0
|
|
|
|
!=================================================================
|
|
! EMISSCARBON begins here!
|
|
!
|
|
! Read carbonaceous aerosols from disk and compute hydrophilic
|
|
! and hydrophobic fractions. NOTE, CARBON AEROSOLS HAVE TO BE
|
|
! ORDERED AS Hydrophilic(BC[1], OC[2]) Hydrophobic(BC[3], OC[4]).
|
|
!=================================================================
|
|
|
|
!--------------------------
|
|
! Read time-invariant data
|
|
!--------------------------
|
|
IF ( FIRST ) THEN
|
|
|
|
! Echo info
|
|
WRITE( 6, '(a)' ) REPEAT( '=', 79 )
|
|
WRITE( 6, 100 )
|
|
|
|
! Echo info about ANTHRO emissionls
|
|
WRITE( 6, 110 )
|
|
IF ( LCOOKE ) WRITE( 6, 111 )
|
|
WRITE( 6, 112 )
|
|
WRITE( 6, 113 )
|
|
|
|
! Monthly or annual BIOMASS emissions?
|
|
IF ( USE_BOND_BIOBURN ) THEN
|
|
WRITE( 6, 120 )
|
|
ELSE
|
|
WRITE( 6, 130 )
|
|
ENDIF
|
|
|
|
IF ( LHTAP ) WRITE( 6, 140 )
|
|
|
|
! Write spacer
|
|
WRITE( 6, '(a)' ) REPEAT( '=', 79 )
|
|
|
|
! FORMAT strings
|
|
100 FORMAT( 'C A R B O N A E R O S O L E M I S S I O N S' )
|
|
110 FORMAT( 'w/ ANTHROPOGENIC emissions from Bond et al [2007]' )
|
|
111 FORMAT( 'w/ North American emissions from Cooke et al [1999]')
|
|
112 FORMAT( 'w/ North American emissions having imposed' )
|
|
113 FORMAT( ' seasonality following Park et al [2003]' )
|
|
120 FORMAT( 'w/ BIOMASS emissions from Bond et al [2004]' )
|
|
130 FORMAT( 'w/ BIOMASS emissions from GEOS-CHEM inventory' )
|
|
140 FORMAT( 'w/ Emissions from HTAP V2 inventory' )
|
|
|
|
! Initialize arrays
|
|
CALL INIT_CARBON
|
|
|
|
!----------------------
|
|
! prior to 5/18/09 - now reads monthly data below (phs)
|
|
! ! Read annual mean anthro emissions from T. Bond [2004]
|
|
! CALL ANTHRO_CARB_TBOND
|
|
! IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: a A_CRB_TBOND' )
|
|
!---------------------
|
|
|
|
! Read annual mean biomass emissions if necessary
|
|
IF ( USE_BOND_BIOBURN ) THEN
|
|
CALL BIOMASS_CARB_TBOND
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: a B_CRB_TBOND' )
|
|
ENDIF
|
|
|
|
! Reset flag
|
|
FIRST = .FALSE.
|
|
ENDIF
|
|
|
|
! Compute time scaling arrays which are used both for
|
|
! biogenic emission and offline OH (rjp, bmy, 7/15/04)
|
|
IF ( LSOA ) THEN
|
|
CALL OHNO3TIME
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: after OHNO3TIME' )
|
|
ENDIF
|
|
|
|
!------------------------------
|
|
! Read monthly-mean ANTHRO data
|
|
!------------------------------
|
|
IF ( ITS_A_NEW_MONTH() ) THEN
|
|
|
|
! Current month
|
|
MONTH = GET_MONTH()
|
|
|
|
! Read in monthly emissions from T Bond [2007], with imposed
|
|
! seasonality over North America by R. Park [2003]
|
|
IF ( .not. LRCP ) THEN
|
|
CALL ANTHRO_CARB_TBOND( MONTH )
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: a A_CRB_TBOND' )
|
|
ENDIF
|
|
|
|
! Read in RCP emissions.
|
|
! Seasonality included for ships, but none included or imposed
|
|
! for land-based anthropogenic emissions
|
|
IF ( LRCP ) THEN
|
|
CALL ANTHRO_CARB_RCP( MONTH )
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: a A_CRB_RCP' )
|
|
ENDIF
|
|
|
|
IF ( LCOOKE ) THEN
|
|
! Overwrite the T. Bond [2004] emissions over North America
|
|
! with monthly mean anthro emissions from Cooke et al [1999]
|
|
! having imposed seasonality by R. Park [2003]
|
|
CALL ANTHRO_CARB_COOKE( MONTH )
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: a A_CRB_COOKE' )
|
|
ENDIF
|
|
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! ! Read monthly mean biomass emissions
|
|
! IF ( .not. USE_BOND_BIOBURN ) THEN
|
|
! CALL BIOMASS_CARB_GEOS
|
|
! IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: a B_CRB_COOKE' )
|
|
! ENDIF
|
|
!-----------------------------------
|
|
|
|
IF ( LHTAP ) THEN
|
|
|
|
THISMONTH = GET_MONTH()
|
|
! STEPS_PER_MON = ( ( 1440 * NDAYS ( THISMONTH ) )
|
|
! & / GET_TS_EMIS() )
|
|
FAC = GET_TS_EMIS() * 60d0 * 1d-4
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, AREA_CM2 )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Surface area [cm2]
|
|
AREA_CM2 = GET_AREA_CM2( J )
|
|
|
|
! Get HTAP BC [kg/m2/s]
|
|
BC(I,J) = GET_HTAP( I, J, IDTBCPO ) * FAC * AREA_CM2
|
|
|
|
! Hydrophilic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_BLKC(I,J,1) = FHB * BC(I,J)
|
|
|
|
! Hydrophobic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_BLKC(I,J,2) = ( 1.d0 - FHB ) * BC(I,J)
|
|
|
|
! Get HTAP OC [kg/m2/s]
|
|
OC(I,J) = GET_HTAP( I, J, IDTOCPO ) * FAC * AREA_CM2
|
|
|
|
! Hydrophilic ORGANIC CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_ORGC(I,J,1) = FHO * OC(I,J)
|
|
|
|
! Hydrophobic ORGANIC CARBON from anthropogenics [kgC/timestep]
|
|
ANTH_ORGC(I,J,2) = ( 1.d0 - FHO ) * OC(I,J)
|
|
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
!-----------------------------------
|
|
! Read monthly/8-day/3-hr mean biomass emissions
|
|
!-----------------------------------
|
|
IF ( .not. USE_BOND_BIOBURN ) THEN
|
|
|
|
IF ( GFED2_IS_NEW() .or. GFED3_IS_NEW() .or.
|
|
& ITS_A_NEW_MONTH() ) THEN
|
|
CALL BIOMASS_CARB_GEOS
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: a BB_CRB_GEOS' )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
!--------------------------
|
|
! Compute biogenic OC
|
|
!--------------------------
|
|
CALL BIOGENIC_OC
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISSCARB: after BIOGENIC_OC' )
|
|
|
|
!=================================================================
|
|
! Sum up BC and OC sources.
|
|
! N=1 is HYDROPHILIC; N=2 is HYDROPHOBIC.
|
|
!
|
|
! COMMENT: Maybe someday we'll want to play with the different
|
|
! emission height for different source type. For example the
|
|
! carbon from biomass burning could be emitted to the higher
|
|
! altitude due to the thermal bouyancy and shallow convection.
|
|
! The current setting to use EMITHIGH seems rather inefficient
|
|
! but robust for sensitivity studies for emission height
|
|
! variation on carbon concentrations, so please keep using the
|
|
! current setup until we decide otherwise. (rjp, 4/2/02)
|
|
!=================================================================
|
|
|
|
! Set biofuel emissions to zero if they are turned off
|
|
IF ( .not. LBIOFUEL ) THEN
|
|
BIOF_BLKC = 0d0
|
|
BIOF_ORGC = 0d0
|
|
ENDIF
|
|
|
|
! adj_group: make a version that applies scaling factors
|
|
! and use this if the emissions adjoint ID #'s are active
|
|
IF ( LADJ_EMS .and. IS_CARB_EMS_ADJ ) THEN
|
|
|
|
IF ( MMSCL /= 1 ) CALL ERROR_STOP('MMSCL /= 1','carbon_mod.f')
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Total HYDROPHILIC BC source [kg]
|
|
BCSRC(I,J,1)= ANTH_BLKC(I,J,1) * EMS_SF(I,J,1,IDADJ_EBCPI_an)
|
|
& + BIOF_BLKC(I,J,1) * EMS_SF(I,J,1,IDADJ_EBCPI_bf)
|
|
& + BIOB_BLKC(I,J,1) * EMS_SF(I,J,1,IDADJ_EBCPI_bb)
|
|
|
|
! Total HYDROPHOBIC BC source [kg]
|
|
BCSRC(I,J,2)= ANTH_BLKC(I,J,2) * EMS_SF(I,J,1,IDADJ_EBCPO_an)
|
|
& + BIOF_BLKC(I,J,2) * EMS_SF(I,J,1,IDADJ_EBCPO_bf)
|
|
& + BIOB_BLKC(I,J,2) * EMS_SF(I,J,1,IDADJ_EBCPO_bb)
|
|
|
|
IF ( LSOA ) THEN
|
|
|
|
CALL ERROR_STOP('LSOA not supported for adj',
|
|
& 'carbon_mod.f')
|
|
|
|
!! Total HYDROPHILIC OC source [kg]
|
|
!! (Don't use archived TERP_ORGC if LSOA=T)
|
|
!OCSRC(I,J,1) = ANTH_ORGC(I,J,1) +
|
|
& ! BIOF_ORGC(I,J,1) +
|
|
& ! BIOB_ORGC(I,J,1)
|
|
|
|
ELSE
|
|
|
|
! Total HYDROPHILIC OC source [kg]
|
|
! (Use archived TERP_ORGC for if LSOA=F)
|
|
OCSRC(I,J,1)
|
|
& = ANTH_ORGC(I,J,1) * EMS_SF(I,J,1,IDADJ_EOCPI_an)
|
|
& + BIOF_ORGC(I,J,1) * EMS_SF(I,J,1,IDADJ_EOCPI_bf)
|
|
& + BIOB_ORGC(I,J,1) * EMS_SF(I,J,1,IDADJ_EOCPI_bb)
|
|
& + TERP_ORGC(I,J)
|
|
|
|
ENDIF
|
|
|
|
! Total HYDROPHOBIC OC source [kg]
|
|
OCSRC(I,J,2)
|
|
& = ANTH_ORGC(I,J,2) * EMS_SF(I,J,1,IDADJ_EOCPO_an)
|
|
& + BIOF_ORGC(I,J,2) * EMS_SF(I,J,1,IDADJ_EOCPO_bf)
|
|
& + BIOB_ORGC(I,J,2) * EMS_SF(I,J,1,IDADJ_EOCPO_bb)
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!$OMP END PARALLEL DO
|
|
|
|
ELSE
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Total HYDROPHILIC BC source [kg]
|
|
BCSRC(I,J,1) = ANTH_BLKC(I,J,1) +
|
|
& BIOF_BLKC(I,J,1) +
|
|
& BIOB_BLKC(I,J,1)
|
|
|
|
! Total HYDROPHOBIC BC source [kg]
|
|
BCSRC(I,J,2) = ANTH_BLKC(I,J,2) +
|
|
& BIOF_BLKC(I,J,2) +
|
|
& BIOB_BLKC(I,J,2)
|
|
|
|
IF ( LSOA ) THEN
|
|
|
|
! Total HYDROPHILIC OC source [kg]
|
|
! (Don't use archived TERP_ORGC if LSOA=T)
|
|
OCSRC(I,J,1) = ANTH_ORGC(I,J,1) +
|
|
& BIOF_ORGC(I,J,1) +
|
|
& BIOB_ORGC(I,J,1)
|
|
|
|
ELSE
|
|
|
|
! Total HYDROPHILIC OC source [kg]
|
|
! (Use archived TERP_ORGC for if LSOA=F)
|
|
OCSRC(I,J,1) = ANTH_ORGC(I,J,1) +
|
|
& BIOF_ORGC(I,J,1) +
|
|
& BIOB_ORGC(I,J,1) +
|
|
& TERP_ORGC(I,J)
|
|
|
|
ENDIF
|
|
|
|
! Total HYDROPHOBIC OC source [kg]
|
|
OCSRC(I,J,2) = ANTH_ORGC(I,J,2) +
|
|
& BIOF_ORGC(I,J,2) +
|
|
& BIOB_ORGC(I,J,2)
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
ENDIF ! EMS_ADJ
|
|
|
|
! Sum up all carbon tracers throughout the boundary layer
|
|
CALL EMITHIGH( BCSRC, OCSRC )
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISCARB: after EMITHIGH' )
|
|
|
|
!=================================================================
|
|
! ND07 diagnostic: Carbon aerosol emissions [kg/timestep]
|
|
!=================================================================
|
|
! adj_group: include scaling factors if they are activated
|
|
IF ( ND07 > 0 .and. IS_CARB_EMS_ADJ ) THEN
|
|
|
|
IF ( MMSCL /= 1 ) CALL ERROR_STOP('MMSCL /= 1','carbon_mod.f')
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Anthropogenic BC source
|
|
AD07(I,J,1) = AD07(I,J,1)
|
|
& + ANTH_BLKC(I,J,1) * EMS_SF(I,J,1,IDADJ_EBCPI_an)
|
|
& + ANTH_BLKC(I,J,2) * EMS_SF(I,J,1,IDADJ_EBCPO_an)
|
|
|
|
! Biogenic BC source
|
|
AD07(I,J,2) = AD07(I,J,2) +
|
|
& + BIOB_BLKC(I,J,1) * EMS_SF(I,J,1,IDADJ_EBCPI_bb)
|
|
& + BIOB_BLKC(I,J,2) * EMS_SF(I,J,1,IDADJ_EBCPO_bb)
|
|
|
|
! Biofuel BC source
|
|
AD07(I,J,3) = AD07(I,J,3) +
|
|
& + BIOF_BLKC(I,J,1) * EMS_SF(I,J,1,IDADJ_EBCPI_bf)
|
|
& + BIOF_BLKC(I,J,2) * EMS_SF(I,J,1,IDADJ_EBCPO_bf)
|
|
|
|
! Anthropogenic OC source
|
|
AD07(I,J,4) = AD07(I,J,4) +
|
|
& + ANTH_ORGC(I,J,1) * EMS_SF(I,J,1,IDADJ_EOCPI_an)
|
|
& + ANTH_ORGC(I,J,2) * EMS_SF(I,J,1,IDADJ_EOCPO_an)
|
|
|
|
! Biomass OC source
|
|
AD07(I,J,5) = AD07(I,J,5) +
|
|
& + BIOB_ORGC(I,J,1) * EMS_SF(I,J,1,IDADJ_EOCPI_bb)
|
|
& + BIOB_ORGC(I,J,2) * EMS_SF(I,J,1,IDADJ_EOCPO_bb)
|
|
|
|
! Biofuel OC source
|
|
AD07(I,J,6) = AD07(I,J,6) +
|
|
& + BIOF_ORGC(I,J,1) * EMS_SF(I,J,1,IDADJ_EOCPI_bf)
|
|
& + BIOF_ORGC(I,J,2) * EMS_SF(I,J,1,IDADJ_EOCPO_bf)
|
|
|
|
! Terpene source
|
|
AD07(I,J,7) = AD07(I,J,7) + TERP_ORGC(I,J)
|
|
|
|
IF ( LSOA ) THEN
|
|
|
|
CALL ERROR_STOP('LSOA not supported for adj',
|
|
& 'carbon_mod.f')
|
|
! ! ALPHA-PINENE
|
|
! AD07(I,J,8) = AD07(I,J,8) + BIOG_ALPH(I,J)
|
|
!
|
|
! ! LIMONENE
|
|
! AD07(I,J,9) = AD07(I,J,9) + BIOG_LIMO(I,J)
|
|
!
|
|
! ! TERPENE
|
|
! AD07(I,J,10) = AD07(I,J,10) + BIOG_TERP(I,J)
|
|
!
|
|
! ! ALCOHOL
|
|
! AD07(I,J,11) = AD07(I,J,11) + BIOG_ALCO(I,J)
|
|
!
|
|
! ! SESQTERPENE
|
|
! AD07(I,J,12) = AD07(I,J,12) + BIOG_SESQ(I,J)
|
|
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!### Debug
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISCARB: after ND07' )
|
|
|
|
ELSEIF ( ND07 > 0 ) THEN
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Anthropogenic BC source
|
|
AD07(I,J,1) = AD07(I,J,1) +
|
|
& ( ANTH_BLKC(I,J,1) + ANTH_BLKC(I,J,2) )
|
|
|
|
! Biogenic BC source
|
|
AD07(I,J,2) = AD07(I,J,2) +
|
|
& ( BIOB_BLKC(I,J,1) + BIOB_BLKC(I,J,2) )
|
|
|
|
! Biofuel BC source
|
|
AD07(I,J,3) = AD07(I,J,3) +
|
|
& ( BIOF_BLKC(I,J,1) + BIOF_BLKC(I,J,2) )
|
|
|
|
! Anthropogenic OC source
|
|
AD07(I,J,4) = AD07(I,J,4) +
|
|
& ( ANTH_ORGC(I,J,1) + ANTH_ORGC(I,J,2) )
|
|
|
|
! Biomass OC source
|
|
AD07(I,J,5) = AD07(I,J,5) +
|
|
& ( BIOB_ORGC(I,J,1) + BIOB_ORGC(I,J,2) )
|
|
|
|
! Biofuel OC source
|
|
AD07(I,J,6) = AD07(I,J,6) +
|
|
& ( BIOF_ORGC(I,J,1) + BIOF_ORGC(I,J,2) )
|
|
|
|
! Terpene source
|
|
AD07(I,J,7) = AD07(I,J,7) + TERP_ORGC(I,J)
|
|
|
|
IF ( LSOA ) THEN
|
|
|
|
! ALPHA-PINENE
|
|
AD07(I,J,8) = AD07(I,J,8) + BIOG_ALPH(I,J)
|
|
|
|
! LIMONENE
|
|
AD07(I,J,9) = AD07(I,J,9) + BIOG_LIMO(I,J)
|
|
|
|
! TERPENE
|
|
AD07(I,J,10) = AD07(I,J,10) + BIOG_TERP(I,J)
|
|
|
|
! ALCOHOL
|
|
AD07(I,J,11) = AD07(I,J,11) + BIOG_ALCO(I,J)
|
|
|
|
! SESQTERPENE
|
|
AD07(I,J,12) = AD07(I,J,12) + BIOG_SESQ(I,J)
|
|
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!### Debug
|
|
IF ( LPRT ) CALL DEBUG_MSG( '### EMISCARB: after ND07' )
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE EMISSCARBON
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE BIOGENIC_OC
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine BIOGENIC_OC emits secondary organic carbon aerosols.
|
|
! Also modified for SOA tracers. (rjp, bmy, 4/1/04, 1/24/08)
|
|
!
|
|
! Terpene emissions as a source of OC: TERP.GEIA90.a1.2x2.5.*
|
|
! Assuming 10% yield of OC(hydrophilic) from terpene emission.
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now separate computation for FULLCHEM and OFFLINE runs (bmy, 7/8/04)
|
|
! (2 ) Now references DATA_DIR from "directory_mod.f". Now references LSOA
|
|
! from "logical_mod.f". (bmy, 7/20/04)
|
|
! (3 ) Now reads data from "carbon_200411" subdir of DATA_DIR (bmy, 11/15/04)
|
|
! (4 ) Now can use MEGAN biogenic emissions (tmf, bmy, 10/20/05)
|
|
! (5 ) For GCAP, need to use GET_NAME_EXT_2D in NVOC file name (bmy, 4/11/06)
|
|
! (6 ) Bug fix: add MEGAN emissions to TERP_ORGC when SOA emissions are
|
|
! turned on (dkh, bmy, 1/24/08)
|
|
! (7 ) Change LMEGAN switch to LMEGANMONO switch (ccc, 3/2/09)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE BPCH2_MOD, ONLY : GET_NAME_EXT_2D, GET_RES_EXT
|
|
USE BPCH2_MOD, ONLY : GET_TAU0, READ_BPCH2
|
|
USE DAO_MOD, ONLY : SUNCOS
|
|
USE DIRECTORY_MOD, ONLY : DATA_DIR
|
|
USE LOGICAL_MOD, ONLY : LMEGANMONO, LSOA
|
|
USE MEGAN_MOD, ONLY : GET_EMMONOT_MEGAN
|
|
USE TIME_MOD, ONLY : GET_MONTH, GET_TS_CHEM
|
|
USE TIME_MOD, ONLY : GET_TS_EMIS, ITS_A_NEW_MONTH
|
|
USE TRANSFER_MOD, ONLY : TRANSFER_2D
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Local variables
|
|
LOGICAL, SAVE :: FIRST = .TRUE.
|
|
INTEGER :: I, J, IJLOOP, THISMONTH
|
|
REAL*4 :: ARRAY(IGLOB,JGLOB,1)
|
|
REAL*8 :: CONVERT(NVEGTYPE)
|
|
REAL*8 :: GMONOT(NVEGTYPE)
|
|
REAL*8 :: FD2D(IIPAR,JJPAR)
|
|
REAL*8 :: TMMP, EMMO, VALUE
|
|
REAL*8 :: XTAU, STEPS_PER_MON
|
|
REAL*8, PARAMETER :: FC1 = 136.2364D0 / 120.11D0
|
|
REAL*8, PARAMETER :: FC2 = 154.2516D0 / 120.11D0
|
|
REAL*8, PARAMETER :: FC3 = 204.3546D0 / 180.165D0
|
|
REAL*8, PARAMETER :: FC4 = 152.D0 / 120.11D0
|
|
CHARACTER(LEN=255) :: FILENAME
|
|
|
|
! Fraction of yield of OC (hydrophilic) from terpene emission
|
|
REAL*8, PARAMETER :: FBIOG = 1.0d-1
|
|
|
|
! External functions
|
|
REAL*8, EXTERNAL :: XLTMMP
|
|
REAL*8, EXTERNAL :: EMMONOT
|
|
|
|
!=================================================================
|
|
! BIOGENIC_OC begins here!
|
|
!=================================================================
|
|
|
|
! Get ISOPRENE baseline emissions (first-time only)
|
|
IF ( FIRST ) THEN
|
|
CALL RDISOPT( CONVERT )
|
|
CALL RDMONOT( GMONOT )
|
|
CALL SETBASE( CONVERT, GMONOT )
|
|
|
|
! Resety first-time flag
|
|
FIRST = .FALSE.
|
|
ENDIF
|
|
|
|
!=================================================================
|
|
! If secondary organic aerosols are turned off ...
|
|
! Compute biogenic organic carbon as 0.1 * MONOTERPENES
|
|
!=================================================================
|
|
IF ( .not. LSOA ) THEN
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, IJLOOP, TMMP, EMMO )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! 1-D loop index
|
|
IJLOOP = ( (J-1) * IIPAR ) + I
|
|
|
|
! Surface temperature [K]
|
|
TMMP = XLTMMP(I,J,IJLOOP)
|
|
|
|
! Get monoterpenes from MEGAN or GEIA [kg C/box]
|
|
IF ( LMEGANMONO ) THEN
|
|
EMMO = GET_EMMONOT_MEGAN( I, J, TMMP, 1d0 )
|
|
ELSE
|
|
EMMO = EMMONOT( IJLOOP, TMMP, 1d0 )
|
|
ENDIF
|
|
|
|
! Fraction of EMMO that converts into OC [kg/box/timestep]
|
|
TERP_ORGC(I,J) = EMMO * FBIOG
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! If secondary organic aerosols are turned on ...
|
|
! Then use CALTECH algorithm
|
|
!=================================================================
|
|
ELSE
|
|
|
|
! Current month
|
|
THISMONTH = GET_MONTH()
|
|
|
|
! Number of emission timesteps per month
|
|
STEPS_PER_MON = ( ( 1440 * NDAYS(THISMONTH) ) / GET_TS_EMIS() )
|
|
|
|
!-----------------------------------------
|
|
! Read data from disk if it's a new month
|
|
!-----------------------------------------
|
|
IF ( ITS_A_NEW_MONTH() ) THEN
|
|
|
|
! Get TAU0 value to index the punch file
|
|
XTAU = GET_TAU0( THISMONTH, 1, 1990 )
|
|
|
|
! Filename for carbon aerosol from fossil fuel use
|
|
FILENAME = TRIM( DATA_DIR ) //
|
|
& 'carbon_200411/NVOC.' // GET_NAME_EXT_2D() //
|
|
& '.' // GET_RES_EXT()
|
|
|
|
! Echo info
|
|
WRITE( 6, 100 ) TRIM( FILENAME )
|
|
100 FORMAT( ' - BIOGENIC_OC: Reading ', a )
|
|
|
|
! Read NVOC emission in kg/month
|
|
CALL READ_BPCH2( FILENAME, 'NVOCSRCE', 35,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), GEIA_ORVC )
|
|
|
|
! from kgC/month to kgC/timestep
|
|
GEIA_ORVC(:,:) = GEIA_ORVC(:,:) / STEPS_PER_MON
|
|
ENDIF
|
|
|
|
!------------------------------
|
|
! Get TERP_ORGC and DIUR_ORVC
|
|
!------------------------------
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, IJLOOP, TMMP, EMMO )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! 1-D loop index
|
|
IJLOOP = ( (J-1) * IIPAR ) + I
|
|
|
|
! Surface temperature [K]
|
|
TMMP = XLTMMP(I,J,IJLOOP)
|
|
|
|
! Monoterpene emission [kg C/box/timestep]
|
|
IF ( LMEGANMONO ) THEN
|
|
TERP_ORGC(I,J) = GET_EMMONOT_MEGAN( I, J, TMMP, 1d0 )
|
|
ELSE
|
|
TERP_ORGC(I,J) = EMMONOT( IJLOOP, TMMP, 1d0 )
|
|
ENDIF
|
|
|
|
!---------------------------------------------------
|
|
! Impose a diurnal variation on NVOC during the day
|
|
!---------------------------------------------------
|
|
IF ( SUNCOS(IJLOOP) > 0d0 .and. TCOSZ(I,J) > 0d0 ) THEN
|
|
DIUR_ORVC(I,J) = GEIA_ORVC(I,J)*
|
|
& ( SUNCOS(IJLOOP) / TCOSZ(I,J) ) *
|
|
& ( 1440d0 / GET_TS_CHEM() )
|
|
|
|
! Make sure ORVC is not negative
|
|
DIUR_ORVC(I,J) = MAX( DIUR_ORVC(I,J), 0d0 )
|
|
|
|
ELSE
|
|
|
|
! At night, ORVC goes to zero
|
|
DIUR_ORVC(I,J) = 0d0
|
|
|
|
ENDIF
|
|
|
|
!===========================================================
|
|
! For SOA (Hong Liao, 02/13/04)
|
|
!
|
|
! The input emission data files have units of
|
|
! [kg C/box/timestep]
|
|
!
|
|
! The variable scale is used to convert to the relevant
|
|
! units as follows:
|
|
! (1) Convert from kg C/step to kg compound/step
|
|
! (2) Multiply by the fraction of monoterpenes that
|
|
! contributes to the particular species of interest.
|
|
!
|
|
! The fraction of monoterpenes is from Table 4 of Griffin
|
|
! et al., Geophys. Res. Lett. 26 (17): 2721-2724 (1999)
|
|
!===========================================================
|
|
|
|
! ALPHA-PINENE (0.35)
|
|
! BETA-PINENE lumped with ALPHA-PINENE (0.23)
|
|
! SABINENE lumped with ALPHA-PINENE (0.05)
|
|
! D3-CARENE lumped with ALPHA-PINENE (0.04)
|
|
BIOG_ALPH(I,J) = TERP_ORGC(I,J) * FC1 * 0.67D0
|
|
|
|
! TERPENOID KETONE is lumped with SABINENE
|
|
! Then SABINENE is lumped with ALPHA-PINENE
|
|
BIOG_ALPH(I,J) = BIOG_ALPH(I,J)
|
|
& + ( DIUR_ORVC(I,J) * FC4 * 0.04D0 ) !using campher
|
|
|
|
! LIMONENE
|
|
BIOG_LIMO(I,J) = TERP_ORGC(I,J) * FC1 * 0.23D0
|
|
|
|
! TERPINENE is lumped with TERPINOLENE
|
|
BIOG_TERP(I,J) = TERP_ORGC(I,J) * FC1 * 0.03D0
|
|
|
|
! MYRCENE is lumped with TERPENOID ALCOHOL (0.05)
|
|
! OCIMENE lumped with TERPENOID ALCOHOL (0.02)
|
|
BIOG_ALCO(I,J) = TERP_ORGC(I,J) * FC1 * 0.07D0
|
|
|
|
! Other reactive volatile organic carbon emissions
|
|
BIOG_ALCO(I,J) = BIOG_ALCO(I,J)
|
|
& + ( DIUR_ORVC(I,J) * FC2 * 0.09D0 ) !using LINALOOL
|
|
|
|
! We do not transport SESQ (C15H24)
|
|
! because its chemical lifetime is short (reactive)
|
|
BIOG_SESQ(I,J) = DIUR_ORVC(I,J) * FC3 * 0.05D0
|
|
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE BIOGENIC_OC
|
|
|
|
!------------------------------------------------------------------------------
|
|
! v8-02-01, now use v8-02-02 version
|
|
!
|
|
! SUBROUTINE ANTHRO_CARB_TBOND
|
|
!!
|
|
!!******************************************************************************
|
|
!! Subroutine ANTHRO_CARB_TBOND computes annual mean anthropogenic and
|
|
!! biofuel emissions of BLACK CARBON (aka ELEMENTAL CARBON) and ORGANIC
|
|
!! CARBON. It also separates these into HYDROPHILIC and HYDROPHOBIC
|
|
!! fractions. (rjp, bmy, 4/2/04, 5/30/06)
|
|
!!
|
|
!! Emissions data comes from the Bond et al [2004] inventory and has units
|
|
!! of [kg C/yr]. This will be converted to [kg C/timestep] below.
|
|
!!
|
|
!! We also assume that 20% of BC and 50% of OC from anthropogenic
|
|
!! emissions are hydrophilic (soluble) and the rest are hydrophobic.
|
|
!!
|
|
!! NOTES:
|
|
!! (1 ) Now references DATA_DIR from "directory_mod.f" (bmy, 7/20/04)
|
|
!! (2 ) Now read data from "carbon_200411" subdir of DATA_DIR (bmy, 11/15/04)
|
|
!! (3 ) Now can read data for both GEOS and GCAP grids (bmy, 8/16/05)
|
|
!! (4 ) Now compute future emissions of BC,OC if necessary. (swu, bmy, 5/30/06)
|
|
!!******************************************************************************
|
|
!!
|
|
! ! References to F90 modules
|
|
! USE BPCH2_MOD, ONLY : GET_NAME_EXT_2D, GET_RES_EXT
|
|
! USE BPCH2_MOD, ONLY : GET_TAU0, READ_BPCH2
|
|
! USE DIRECTORY_MOD, ONLY : DATA_DIR
|
|
! USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_BCbf
|
|
! USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_BCff
|
|
! USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_OCbf
|
|
! USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_OCff
|
|
! USE LOGICAL_MOD, ONLY : LFUTURE
|
|
! USE TIME_MOD, ONLY : GET_TS_EMIS
|
|
! USE TRANSFER_MOD, ONLY : TRANSFER_2D
|
|
!
|
|
!# include "CMN_SIZE" ! Size parameters
|
|
!
|
|
! ! Local variables
|
|
! INTEGER :: I, J
|
|
! REAL*4 :: ARRAY(IGLOB,JGLOB,1)
|
|
! REAL*8 :: XTAU, STEPS_PER_YR, FUT_SCL
|
|
! REAL*8 :: FD2D(IIPAR,JJPAR)
|
|
! CHARACTER(LEN=255) :: FILENAME
|
|
!
|
|
! ! Hydrophilic fraction of BLACK CARBON (aka ELEMENTAL CARBON)
|
|
! REAL*8, PARAMETER :: FHB = 0.2d0
|
|
!
|
|
! ! Hydrophilic fraction of ORGANIC CARBON
|
|
! REAL*8, PARAMETER :: FHO = 0.5d0
|
|
!
|
|
! !=================================================================
|
|
! ! ANTHRO_CARB_TBOND begins here!
|
|
! !=================================================================
|
|
!
|
|
! ! Number of emission timesteps per year
|
|
! STEPS_PER_YR = ( ( 1440 * 365 ) / GET_TS_EMIS() )
|
|
!
|
|
! ! Get TAU0 value to index the punch file
|
|
! XTAU = GET_TAU0( 1, 1, 2001 )
|
|
!
|
|
! !=================================================================
|
|
! ! Read BLACK CARBON (aka ELEMENTAL CARBON) emission from
|
|
! ! anthropogenic sources as tracer #34 in [kg C/year].
|
|
! ! Then convert to [kg C/timestep] and store in ANTH_BLKC.
|
|
! !=================================================================
|
|
!
|
|
! ! Filename for carbon aerosol from fossil fuel use
|
|
! FILENAME = TRIM( DATA_DIR ) //
|
|
! & 'carbon_200411/BCOC_TBond_fossil.' //
|
|
! & GET_NAME_EXT_2D() // '.' // GET_RES_EXT()
|
|
!
|
|
! ! Echo info
|
|
! WRITE( 6, 100 ) TRIM( FILENAME )
|
|
! 100 FORMAT( ' - ANTHRO_CARB_TBOND: Reading ', a )
|
|
!
|
|
! ! Read BLCK emission
|
|
! CALL READ_BPCH2( FILENAME, 'ANTHSRCE', 34,
|
|
! & XTAU, IGLOB, JGLOB,
|
|
! & 1, ARRAY, QUIET=.TRUE. )
|
|
!
|
|
! ! Cast to REAL*8 and resize
|
|
! CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
!
|
|
!!$OMP PARALLEL DO
|
|
!!$OMP+DEFAULT( SHARED )
|
|
!!$OMP+PRIVATE( I, J, FUT_SCL )
|
|
! DO J = 1, JJPAR
|
|
! DO I = 1, IIPAR
|
|
!
|
|
! ! Hydrophilic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
! ANTH_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_YR
|
|
!
|
|
! ! Hydrophobic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
! ANTH_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_YR
|
|
!
|
|
! ! Compute future emissions of BLACK CARBON (if necessary)
|
|
! IF ( LFUTURE ) THEN
|
|
! FUT_SCL = GET_FUTURE_SCALE_BCff( I, J )
|
|
! ANTH_BLKC(I,J,1) = ANTH_BLKC(I,J,1) * FUT_SCL
|
|
! ANTH_BLKC(I,J,2) = ANTH_BLKC(I,J,2) * FUT_SCL
|
|
! ENDIF
|
|
! ENDDO
|
|
! ENDDO
|
|
!!$OMP END PARALLEL DO
|
|
!
|
|
! !=================================================================
|
|
! ! Read ORGANIC CARBON from anthropogenic sources as tracer #35
|
|
! ! in [kg C/year]. Then Convert to [kg C/timestep] and store in
|
|
! ! ANTH_ORGC.
|
|
! !=================================================================
|
|
! CALL READ_BPCH2( FILENAME, 'ANTHSRCE', 35,
|
|
! & XTAU, IGLOB, JGLOB,
|
|
! & 1, ARRAY, QUIET=.TRUE. )
|
|
!
|
|
! ! Cast to REAL*8 and resize
|
|
! CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
!
|
|
!!$OMP PARALLEL DO
|
|
!!$OMP+DEFAULT( SHARED )
|
|
!!$OMP+PRIVATE( I, J, FUT_SCL )
|
|
! DO J = 1, JJPAR
|
|
! DO I = 1, IIPAR
|
|
!
|
|
! ! Hydrophilic ORGANIC CARBON from anthropogenics [kg C/timestep]
|
|
! ANTH_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_YR
|
|
!
|
|
! ! Hydrophobic ORGANIC CARBON from anthropogenics [kgC/timestep]
|
|
! ANTH_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_YR
|
|
!
|
|
! ! Compute future emissions of ORGANIC CARBON (if necessary)
|
|
! IF ( LFUTURE ) THEN
|
|
! FUT_SCL = GET_FUTURE_SCALE_OCff( I, J )
|
|
! ANTH_ORGC(I,J,1) = ANTH_ORGC(I,J,1) * FUT_SCL
|
|
! ANTH_ORGC(I,J,2) = ANTH_ORGC(I,J,2) * FUT_SCL
|
|
! ENDIF
|
|
! ENDDO
|
|
! ENDDO
|
|
!!$OMP END PARALLEL DO
|
|
!
|
|
! !=================================================================
|
|
! ! Read BLACK CARBON (aka ELEMENTAL CARBON) emission from biofuel
|
|
! ! combustion as tracer #34 in [kg C/year]. Then convert to
|
|
! ! [kg C/timestep] and store in BIOF_BLKC.
|
|
! !=================================================================
|
|
!
|
|
! ! Filename
|
|
! FILENAME = TRIM( DATA_DIR ) //
|
|
! & 'carbon_200411/BCOC_TBond_biofuel.' //
|
|
! & GET_NAME_EXT_2D() // '.' // GET_RES_EXT()
|
|
!
|
|
!
|
|
! ! Echo info
|
|
! WRITE( 6, 100 ) TRIM( FILENAME )
|
|
!
|
|
! ! Read data
|
|
! CALL READ_BPCH2( FILENAME, 'BIOFSRCE', 34,
|
|
! & XTAU, IGLOB, JGLOB,
|
|
! & 1, ARRAY, QUIET=.TRUE. )
|
|
!
|
|
! ! Cast to REAL*8 and resize
|
|
! CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
!
|
|
!!$OMP PARALLEL DO
|
|
!!$OMP+DEFAULT( SHARED )
|
|
!!$OMP+PRIVATE( I, J, FUT_SCL )
|
|
! DO J = 1, JJPAR
|
|
! DO I = 1, IIPAR
|
|
!
|
|
! ! Hydrophilic BLACK CARBON from biofuels [kg C /timestep]
|
|
! BIOF_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_YR
|
|
!
|
|
! ! Hydrophobic BLACK CARBON from biofuels [kg C/timestep]
|
|
! BIOF_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_YR
|
|
!
|
|
! ! Compute future emissions of BLACK CARBON (if necessary)
|
|
! IF ( LFUTURE ) THEN
|
|
! FUT_SCL = GET_FUTURE_SCALE_BCbf( I, J )
|
|
! BIOF_BLKC(I,J,1) = BIOF_BLKC(I,J,1) * FUT_SCL
|
|
! BIOF_BLKC(I,J,2) = BIOF_BLKC(I,J,2) * FUT_SCL
|
|
! ENDIF
|
|
! ENDDO
|
|
! ENDDO
|
|
!!$OMP END PARALLEL DO
|
|
!
|
|
! !=================================================================
|
|
! ! Read ORGANIC CARBON from biofuel combustion as tracer #35 in
|
|
! ! [kg C/year]. Convert to [kg C/timestep] and store in BIOF_BLKC.
|
|
! !=================================================================
|
|
!
|
|
! CALL READ_BPCH2( FILENAME, 'BIOFSRCE', 35,
|
|
! & XTAU, IGLOB, JGLOB,
|
|
! & 1, ARRAY, QUIET=.TRUE. )
|
|
!
|
|
! ! Cast to REAL*8 and resize
|
|
! CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
!
|
|
!!$OMP PARALLEL DO
|
|
!!$OMP+DEFAULT( SHARED )
|
|
!!$OMP+PRIVATE( I, J )
|
|
! DO J = 1, JJPAR
|
|
! DO I = 1, IIPAR
|
|
!
|
|
! ! Hydrophilic ORGANIC CARBON from biofuels [kg C/timestep]
|
|
! BIOF_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_YR
|
|
!
|
|
! ! Hydrophobic ORGANIC CARBON from biofuels [kg C/timestep]
|
|
! BIOF_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_YR
|
|
!
|
|
! ! Compute future emissions of BLACK CARBON (if necessary)
|
|
! IF ( LFUTURE ) THEN
|
|
! FUT_SCL = GET_FUTURE_SCALE_OCbf( I, J )
|
|
! BIOF_ORGC(I,J,1) = BIOF_ORGC(I,J,1) * FUT_SCL
|
|
! BIOF_ORGC(I,J,2) = BIOF_ORGC(I,J,2) * FUT_SCL
|
|
! ENDIF
|
|
! ENDDO
|
|
! ENDDO
|
|
!!$OMP END PARALLEL DO
|
|
!
|
|
! ! Return to calling program
|
|
! END SUBROUTINE ANTHRO_CARB_TBOND
|
|
!
|
|
!!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE ANTHRO_CARB_TBOND( THISMONTH )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine ANTHRO_CARB_TBOND reads monthly mean anthropogenic and biofuel
|
|
! emissions of BLACK CARBON (aka ELEMENTAL CARBON) and ORGANIC CARBON.
|
|
! It also separates these into HYDROPHILIC and HYDROPHOBIC fractions.
|
|
! (eml 4/17/09, rjp, bmy, 4/2/04, 5/30/06)
|
|
!
|
|
! Emissions data comes from Bond et al [GBC, 2007] inventory and has units
|
|
! of [kg C/yr], which is converted to [kg C/timestep] below. Seasonality is
|
|
! applied over the US as in Park [2003].
|
|
!
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! ! OLD:
|
|
! ! Subroutine ANTHRO_CARB_TBOND computes annual mean anthropogenic and
|
|
! ! biofuel emissions of BLACK CARBON (aka ELEMENTAL CARBON) and ORGANIC
|
|
! ! CARBON. It also separates these into HYDROPHILIC and HYDROPHOBIC
|
|
! ! fractions. (rjp, bmy, 4/2/04, 5/30/06)
|
|
! !
|
|
! ! Emissions data comes from the Bond et al [2004] inventory and has units
|
|
! ! of [kg C/yr]. This will be converted to [kg C/timestep] below.
|
|
! !
|
|
!----------------------------------
|
|
! We also assume that 20% of BC and 50% of OC from anthropogenic
|
|
! emissions are hydrophilic (soluble) and the rest are hydrophobic.
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references DATA_DIR from "directory_mod.f" (bmy, 7/20/04)
|
|
! (2 ) Now read data from "carbon_200411" subdir of DATA_DIR (bmy, 11/15/04)
|
|
! (3 ) Now can read data for both GEOS and GCAP grids (bmy, 8/16/05)
|
|
! (4 ) Now compute future emissions of BC,OC if necessary. (swu, bmy, 5/30/06)
|
|
! (5 ) Now reads in monthly data from Bond et al [2007] (eml, 4/17/09)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE BPCH2_MOD, ONLY : GET_NAME_EXT_2D, GET_RES_EXT
|
|
USE BPCH2_MOD, ONLY : GET_TAU0, READ_BPCH2
|
|
USE DIRECTORY_MOD, ONLY : DATA_DIR
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_BCbf
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_BCff
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_OCbf
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_OCff
|
|
USE LOGICAL_MOD, ONLY : LFUTURE
|
|
USE TIME_MOD, ONLY : GET_TS_EMIS
|
|
USE TRANSFER_MOD, ONLY : TRANSFER_2D
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: THISMONTH
|
|
|
|
! Local variables
|
|
INTEGER :: I, J
|
|
REAL*4 :: ARRAY(IGLOB,JGLOB,1)
|
|
REAL*8 :: XTAU, STEPS_PER_YR, FUT_SCL
|
|
REAL*8 :: STEPS_PER_MON
|
|
REAL*8 :: FD2D(IIPAR,JJPAR)
|
|
CHARACTER(LEN=255) :: FILENAME
|
|
|
|
! Hydrophilic fraction of BLACK CARBON (aka ELEMENTAL CARBON)
|
|
REAL*8, PARAMETER :: FHB = 0.2d0
|
|
|
|
! Hydrophilic fraction of ORGANIC CARBON
|
|
REAL*8, PARAMETER :: FHO = 0.5d0
|
|
|
|
!=================================================================
|
|
! ANTHRO_CARB_TBOND begins here!
|
|
!=================================================================
|
|
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! ! Number of emission timesteps per year
|
|
! STEPS_PER_YR = ( ( 1440 * 365 ) / GET_TS_EMIS() )
|
|
!
|
|
! ! Get TAU0 value to index the punch file
|
|
! XTAU = GET_TAU0( 1, 1, 2001 )
|
|
!----------------------------------
|
|
|
|
! Number of emission timesteps per month
|
|
STEPS_PER_MON = ( ( 1440 * NDAYS ( THISMONTH ) ) / GET_TS_EMIS() )
|
|
|
|
! Get TAU0 value to index the punch file
|
|
XTAU = GET_TAU0( THISMONTH, 1, 2000 )
|
|
|
|
|
|
!=================================================================
|
|
! Read BLACK CARBON (aka ELEMENTAL CARBON) emission from
|
|
! anthropogenic sources as tracer #34 in [kg C/month].
|
|
! Then convert to [kg C/timestep] and store in ANTH_BLKC.
|
|
!=================================================================
|
|
! Filename for carbon aerosol from fossil fuel use
|
|
FILENAME = TRIM( DATA_DIR ) //
|
|
! & 'carbon_200905/BCOC_TBond_fossil.2000.' //
|
|
& 'carbon_200909/BCOC_TBond_fossil.2000.' //
|
|
& GET_NAME_EXT_2D() // '.' // GET_RES_EXT()
|
|
|
|
|
|
! Echo info
|
|
WRITE( 6, 100 ) TRIM( FILENAME )
|
|
100 FORMAT( ' - ANTHRO_CARB_TBOND: Reading ', a )
|
|
|
|
! Read BLCK emission
|
|
CALL READ_BPCH2( FILENAME, 'ANTHSRCE', 34,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, FUT_SCL )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Hydrophilic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! ANTH_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_YR
|
|
ANTH_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Hydrophobic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! ANTH_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_YR
|
|
ANTH_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Compute future emissions of BLACK CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_BCff( I, J )
|
|
ANTH_BLKC(I,J,1) = ANTH_BLKC(I,J,1) * FUT_SCL
|
|
ANTH_BLKC(I,J,2) = ANTH_BLKC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! Read ORGANIC CARBON from anthropogenic sources as tracer #35
|
|
! in [kg C/month]. Then Convert to [kg C/timestep] and store in
|
|
! ANTH_ORGC.
|
|
!=================================================================
|
|
CALL READ_BPCH2( FILENAME, 'ANTHSRCE', 35,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, FUT_SCL )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Hydrophilic ORGANIC CARBON from anthropogenics [kg C/timestep]
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! ANTH_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_YR
|
|
ANTH_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Hydrophobic ORGANIC CARBON from anthropogenics [kgC/timestep]
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! ANTH_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_YR
|
|
ANTH_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Compute future emissions of ORGANIC CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_OCff( I, J )
|
|
ANTH_ORGC(I,J,1) = ANTH_ORGC(I,J,1) * FUT_SCL
|
|
ANTH_ORGC(I,J,2) = ANTH_ORGC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! Read BLACK CARBON (aka ELEMENTAL CARBON) emission from biofuel
|
|
! combustion as tracer #34 in [kg C/year]. Then convert to
|
|
! [kg C/timestep] and store in BIOF_BLKC.
|
|
!=================================================================
|
|
! Filename
|
|
FILENAME = TRIM( DATA_DIR ) //
|
|
! & 'carbon_200905/BCOC_TBond_biofuel.2000.' //
|
|
& 'carbon_200909/BCOC_TBond_biofuel.2000.' //
|
|
& GET_NAME_EXT_2D() // '.' // GET_RES_EXT()
|
|
|
|
|
|
! Echo info
|
|
WRITE( 6, 100 ) TRIM( FILENAME )
|
|
|
|
! Read data
|
|
CALL READ_BPCH2( FILENAME, 'BIOFSRCE', 34,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, FUT_SCL )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Hydrophilic BLACK CARBON from biofuels [kg C /timestep]
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! BIOF_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_YR
|
|
BIOF_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Hydrophobic BLACK CARBON from biofuels [kg C/timestep]
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! BIOF_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_YR
|
|
BIOF_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
|
|
! Compute future emissions of BLACK CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_BCbf( I, J )
|
|
BIOF_BLKC(I,J,1) = BIOF_BLKC(I,J,1) * FUT_SCL
|
|
BIOF_BLKC(I,J,2) = BIOF_BLKC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! Read ORGANIC CARBON from biofuel combustion as tracer #35 in
|
|
! [kg C/year]. Convert to [kg C/timestep] and store in BIOF_BLKC.
|
|
!=================================================================
|
|
|
|
CALL READ_BPCH2( FILENAME, 'BIOFSRCE', 35,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Hydrophilic ORGANIC CARBON from biofuels [kg C/timestep]
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! BIOF_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_YR
|
|
BIOF_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Hydrophobic ORGANIC CARBON from biofuels [kg C/timestep]
|
|
!-----------------------------------
|
|
! Prior to 12/18/08
|
|
! BIOF_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_YR
|
|
BIOF_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Compute future emissions of BLACK CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_OCbf( I, J )
|
|
BIOF_ORGC(I,J,1) = BIOF_ORGC(I,J,1) * FUT_SCL
|
|
BIOF_ORGC(I,J,2) = BIOF_ORGC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE ANTHRO_CARB_TBOND
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
|
|
SUBROUTINE ANTHRO_CARB_COOKE( THISMONTH )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine ANTHRO_CARB_COOKE computes monthly mean anthropogenic and
|
|
! biofuel emissions of BLACK CARBON (aka ELEMENTAL CARBON) and ORGANIC
|
|
! CARBON. It also separates these into HYDROPHILIC and HYDROPHOBIC
|
|
! fractions. (rjp, bmy, 4/2/04, 5/30/06)
|
|
!
|
|
! Emissions data comes from the Cooke et al. [1999] inventory and
|
|
! seasonality imposed by Park et al. [2003]. The data has units of
|
|
! [kg C/month]. This will be converted to [kg C/timestep] below.
|
|
!
|
|
! We also assume that 20% of BC and 50% of OC from anthropogenic
|
|
! emissions are hydrophilic (soluble) and the rest are hydrophobic.
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references DATA_DIR from "directory_mod.f" (bmy, 7/20/04)
|
|
! (2 ) Now read data from "carbon_200411" subdir of DATA_DIR. Now only apply
|
|
! Cooke/RJP emissions over the North American region (i.e. the region
|
|
! bounded by indices I1_NA, J1_NA, I2_NA, J2_NA). (rjp, bmy, 12/1/04)
|
|
! (3 ) Now can read data from both GEOS and GCAP grids (bmy, 8/16/05)
|
|
! (4 ) Now compute future emissions of BC,OC if necessary. (swu, bmy, 5/30/06)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE BPCH2_MOD, ONLY : GET_NAME_EXT_2D, GET_RES_EXT
|
|
USE BPCH2_MOD, ONLY : GET_TAU0, READ_BPCH2
|
|
USE DIRECTORY_MOD, ONLY : DATA_DIR
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_BCbf
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_BCff
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_OCbf
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_OCff
|
|
USE LOGICAL_MOD, ONLY : LFUTURE
|
|
USE TIME_MOD, ONLY : GET_TS_EMIS
|
|
USE TRANSFER_MOD, ONLY : TRANSFER_2D
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: THISMONTH
|
|
|
|
! Local variables
|
|
INTEGER :: I, J
|
|
REAL*4 :: ARRAY(IGLOB,JGLOB,1)
|
|
REAL*8 :: XTAU, STEPS_PER_MON, FUT_SCL
|
|
REAL*8 :: FD2D(IIPAR,JJPAR)
|
|
CHARACTER(LEN=255) :: FILENAME
|
|
|
|
! Hydrophilic fraction of BLACK CARBON aerosol
|
|
REAL*8, PARAMETER :: FHB = 0.2d0
|
|
|
|
! Hydrophilic fraction of ORGANIC CARBON aerosol
|
|
REAL*8, PARAMETER :: FHO = 0.5d0
|
|
|
|
!=================================================================
|
|
! ANTHRO_CARB_COOKE begins here!
|
|
!=================================================================
|
|
|
|
! Return if we are running on a nested grid (e.g. China) which
|
|
! does not cover the North America region (rjp, bmy, 12/1/04)
|
|
IF ( I1_NA + J1_NA + I2_NA + J2_NA == 0 ) RETURN
|
|
|
|
! Number of emission timesteps per month
|
|
STEPS_PER_MON = ( ( 1440 * NDAYS( THISMONTH ) ) / GET_TS_EMIS() )
|
|
|
|
! Get TAU0 value to index the punch file
|
|
XTAU = GET_TAU0( THISMONTH, 1, 1998 )
|
|
|
|
!=================================================================
|
|
! Read BLACK CARBON (aka ELEMENTAL CARBON) emission from
|
|
! anthropogenic sources as tracer #34 in [kg C/month].
|
|
! Then convert to [kg C/timestep] and store in ANTH_BLKC.
|
|
!
|
|
! The ANTH_BLKC array is initialized with the Bond et al [2004]
|
|
! emissions in READ_ANTHRO_TBOND on the very first timestep.
|
|
! Overwrite the contents of ANTH_BLKC over North America below.
|
|
!=================================================================
|
|
|
|
! Filename
|
|
FILENAME = TRIM( DATA_DIR ) //
|
|
& 'carbon_200411/BCOC_anthsrce.' // GET_NAME_EXT_2D() //
|
|
& '.' // GET_RES_EXT()
|
|
|
|
! Echo info
|
|
WRITE( 6, 100 ) TRIM( FILENAME )
|
|
100 FORMAT( ' - ANTHRO_CARB_COOKE: Reading ', a )
|
|
|
|
! Read data
|
|
CALL READ_BPCH2( FILENAME, 'ANTHSRCE', 34,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
DO J = J1_NA, J2_NA
|
|
DO I = I1_NA, I2_NA
|
|
|
|
! Hydrophilic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Hydrophobic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Compute future emissions of BLACK CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_BCff( I, J )
|
|
ANTH_BLKC(I,J,1) = ANTH_BLKC(I,J,1) * FUT_SCL
|
|
ANTH_BLKC(I,J,2) = ANTH_BLKC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!=================================================================
|
|
! Read ORGANIC CARBON from anthropogenic sources as tracer #35
|
|
! in [kg C/month]. Then Convert to [kg C/timestep] and store in
|
|
! ANTH_ORGC.
|
|
!
|
|
! The ANTH_ORGC array is initialized with the Bond et al [2004]
|
|
! emissions in READ_ANTHRO_TBOND on the very first timestep.
|
|
! Overwrite the contents of ANTH_ORGC over North America below.
|
|
!=================================================================
|
|
CALL READ_BPCH2( FILENAME, 'ANTHSRCE', 35,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
DO J = J1_NA, J2_NA
|
|
DO I = I1_NA, I2_NA
|
|
|
|
! Hydrophilic ORGANIC CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Hydrophobic ORGANIC CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Compute future emissions of ORGANIC CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_OCff( I, J )
|
|
ANTH_ORGC(I,J,1) = ANTH_ORGC(I,J,1) * FUT_SCL
|
|
ANTH_ORGC(I,J,2) = ANTH_ORGC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!=================================================================
|
|
! Read BLACK CARBON (aka ELEMENTAL CARBON) emission from biofuel
|
|
! combustion over Canada and the US as tracer #34 in [kg C/year].
|
|
! Then convert to [kg C/timestep] and store in BIOF_BLKC.
|
|
!
|
|
! Seasonality has been imposed using the heating degree approach
|
|
! for year 1998 [Park et al., 2003].
|
|
!
|
|
! The BIOF_BLKC array is initialized with the Bond et al [2004]
|
|
! emissions in READ_ANTHRO_TBOND on the very first timestep.
|
|
! Overwrite the contents of BIOF_BLKC over North America below.
|
|
!=================================================================
|
|
|
|
! Filename
|
|
FILENAME = TRIM( DATA_DIR ) //
|
|
& 'carbon_200411/BCOC_biofuel.' // GET_NAME_EXT_2D() //
|
|
& '.' // GET_RES_EXT()
|
|
|
|
! Echo info
|
|
WRITE( 6, 100 ) TRIM( FILENAME )
|
|
|
|
! Read data
|
|
CALL READ_BPCH2( FILENAME, 'BIOFSRCE', 34,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
DO J = J1_NA, J2_NA
|
|
DO I = I1_NA, I2_NA
|
|
|
|
! Hydrophilic BLACK CARBON from biofuels [kg C/timestep]
|
|
BIOF_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Hydrophobic BLACK CARBON from biofuels [kg C/timestep]
|
|
BIOF_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Compute future emissions of BLACK CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_BCbf( I, J )
|
|
BIOF_BLKC(I,J,1) = BIOF_BLKC(I,J,1) * FUT_SCL
|
|
BIOF_BLKC(I,J,2) = BIOF_BLKC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
|
|
!=================================================================
|
|
! Read ORGANIC CARBON emission from biofuel combustion over
|
|
! Canada and the US as tracer #35 in [kg C/year]. Then convert
|
|
! to [kg C/timestep] and store in BIOF_ORGC.
|
|
!
|
|
! Seasonality has been imposed using the heating degree approach
|
|
! for year 1998 [Park et al., 2003].
|
|
!
|
|
! The BIOF_ORGC array is initialized with the Bond et al [2004]
|
|
! emissions in READ_ANTHRO_TBOND on the very first timestep.
|
|
! Overwrite the contents of BIOF_ORGC over North America below.
|
|
!=================================================================
|
|
CALL READ_BPCH2( FILENAME, 'BIOFSRCE', 35,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
DO J = J1_NA, J2_NA
|
|
DO I = I1_NA, I2_NA
|
|
|
|
! Hydrophilic ORGANIC CARBON from biofuels [kg C/timestep]
|
|
BIOF_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Hydrophobic ORGANIC CARBON from biofuels [kg C/timestep]
|
|
BIOF_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_MON
|
|
|
|
! Compute future emissions of BLACK CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_OCbf( I, J )
|
|
BIOF_ORGC(I,J,1) = BIOF_ORGC(I,J,1) * FUT_SCL
|
|
BIOF_ORGC(I,J,2) = BIOF_ORGC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE ANTHRO_CARB_COOKE
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE ANTHRO_CARB_RCP( THISMONTH )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine ANTHRO_CARB_RCP reads monthly mean anthropogenic and biofuel
|
|
! emissions of BLACK CARBON (aka ELEMENTAL CARBON) and ORGANIC CARBON.
|
|
! (cdh, 1/2/2013)
|
|
!
|
|
! It also separates these into HYDROPHILIC and HYDROPHOBIC fractions using
|
|
! the same fractions as the Bond et al. (2007) global inventory.
|
|
!
|
|
! We also assume that 20% of BC and 50% of OC from anthropogenic
|
|
! emissions are hydrophilic (soluble) and the rest are hydrophobic.
|
|
!
|
|
! NOTES:
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE TIME_MOD, ONLY : GET_TS_EMIS
|
|
USE GRID_MOD, ONLY : GET_AREA_CM2
|
|
USE TRACERID_MOD, ONLY : IDTBCPO, IDTOCPO
|
|
USE TRACER_MOD, ONLY : XNUMOL
|
|
USE RCP_MOD, ONLY : GET_RCP_EMISSION
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: THISMONTH
|
|
|
|
! Local variables
|
|
INTEGER :: I, J
|
|
REAL*8 :: AREA_CM2, BC, OC
|
|
|
|
! Hydrophilic fraction of BLACK CARBON (aka ELEMENTAL CARBON)
|
|
REAL*8, PARAMETER :: FHB = 0.2d0
|
|
|
|
! Hydrophilic fraction of ORGANIC CARBON
|
|
REAL*8, PARAMETER :: FHO = 0.5d0
|
|
|
|
!=================================================================
|
|
! ANTHRO_CARB_RCP begins here!
|
|
!=================================================================
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, BC, OC, AREA_CM2 )
|
|
DO J = 1, JJPAR
|
|
|
|
! Grid box area [cm2]
|
|
AREA_CM2 = GET_AREA_CM2( J )
|
|
|
|
DO I = 1, IIPAR
|
|
|
|
!-----------------------------------------------------------
|
|
! Anthropogenic Black Carbon from fossil fuel and biofuel
|
|
!-----------------------------------------------------------
|
|
|
|
! RCP emissions, atoms C/cm2/s
|
|
BC = GET_RCP_EMISSION( I, J, IDTBCPO,
|
|
& LAND=.TRUE., SHIP=.TRUE. )
|
|
|
|
! Convert atoms C/cm2/s -> kg/timestep
|
|
BC = BC * AREA_CM2 / XNUMOL(IDTBCPO) * GET_TS_EMIS() * 60D0
|
|
|
|
! Hydrophilic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_BLKC(I,J,1) = FHB * BC
|
|
|
|
! Hydrophobic BLACK CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_BLKC(I,J,2) = ( 1.d0 - FHB ) * BC
|
|
|
|
!-----------------------------------------------------------
|
|
! Anthropogenic Organic Carbon from fossil fuel and biofuel
|
|
!-----------------------------------------------------------
|
|
|
|
! RCP emissions, atoms C/cm2/s
|
|
OC = GET_RCP_EMISSION( I, J, IDTOCPO,
|
|
& LAND=.TRUE., SHIP=.TRUE. )
|
|
|
|
! Convert atoms C/cm2/s -> kg/timestep
|
|
OC = OC * AREA_CM2 / XNUMOL(IDTOCPO) * GET_TS_EMIS() * 60D0
|
|
|
|
! Hydrophilic ORGANIC CARBON from anthropogenics [kg C/timestep]
|
|
ANTH_ORGC(I,J,1) = FHO * OC
|
|
|
|
! Hydrophobic ORGANIC CARBON from anthropogenics [kgC/timestep]
|
|
ANTH_ORGC(I,J,2) = ( 1.d0 - FHO ) * OC
|
|
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE ANTHRO_CARB_RCP
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE BIOMASS_CARB_TBOND
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine BIOMASS_CARB_TBOND computes annual mean biomass burning
|
|
! emissions of BLACK CARBON (aka ELEMENTAL CARBON) and ORGANIC CARBON.
|
|
! It also separates these into HYDROPHILIC and HYDROPHOBIC fractions.
|
|
! (rjp, bmy, 4/2/04, 5/30/06)
|
|
!
|
|
! Emissions data comes from the Bond et al [2004] inventory and has units
|
|
! of [kg C/yr]. This will be converted to [kg C/timestep] below.
|
|
!
|
|
! We also assume that 20% of BC and 50% of OC from anthropogenic
|
|
! emissions are hydrophilic (soluble) and the rest are hydrophobic.
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references DATA_DIR from "directory_mod.f" (bmy, 7/20/04)
|
|
! (2 ) Now read data from "carbon_200411" subdir of DATA_DIR (bmy, 11/15/04)
|
|
! (3 ) Now can read from both GEOS and GCAP grids (bmy, 8/16/05)
|
|
! (4 ) Now compute future emissions of BC,OC if necessary (swu, bmy, 5/30/06)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE BPCH2_MOD, ONLY : GET_NAME_EXT_2D, GET_RES_EXT
|
|
USE BPCH2_MOD, ONLY : GET_TAU0, READ_BPCH2
|
|
USE DIRECTORY_MOD, ONLY : DATA_DIR
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_BCbb
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_OCbb
|
|
USE LOGICAL_MOD, ONLY : LFUTURE
|
|
USE TIME_MOD, ONLY : GET_TS_EMIS
|
|
USE TRANSFER_MOD, ONLY : TRANSFER_2D
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Local variables
|
|
INTEGER :: I, J
|
|
REAL*4 :: ARRAY(IGLOB,JGLOB,1)
|
|
REAL*8 :: XTAU, STEPS_PER_YR, FUT_SCL
|
|
REAL*8 :: FD2D(IIPAR,JJPAR)
|
|
CHARACTER(LEN=255) :: FILENAME
|
|
|
|
! Hydrophilic fraction of carbonaceous aerosols
|
|
REAL*8, PARAMETER :: FHB = 0.2d0
|
|
REAL*8, PARAMETER :: FHO = 0.5d0
|
|
|
|
!=================================================================
|
|
! BIOMASS_CARB_TBOND begins here!
|
|
!=================================================================
|
|
|
|
! Number of emission timesteps per year
|
|
STEPS_PER_YR = ( ( 1440 * 365 ) / GET_TS_EMIS() )
|
|
|
|
! Filename containing biomass emissions
|
|
FILENAME = TRIM( DATA_DIR ) //
|
|
& 'carbon_200411/BCOC_TBond_biomass.' //
|
|
& GET_NAME_EXT_2D() // '.' // GET_RES_EXT()
|
|
|
|
|
|
! Get TAU0 value to index the punch file
|
|
XTAU = GET_TAU0( 1, 1, 2001 )
|
|
|
|
! Echo info
|
|
WRITE( 6, 100 ) TRIM( FILENAME )
|
|
100 FORMAT( ' - BIOMASS_CARB_TBOND: Reading ', a )
|
|
|
|
!=================================================================
|
|
! Read BLACK CARBON (aka ELEMENTAL CARBON) emission from
|
|
! biomass burning as tracer #34 in [kg C/year]. Then
|
|
! convert to [kg C/timestep] and store in BIOB_BLKC.
|
|
!=================================================================
|
|
CALL READ_BPCH2( FILENAME, 'BIOBSRCE', 34,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, FUT_SCL )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Hydrophilic BLACK CARBON from biomass [kg C/timestep]
|
|
BIOB_BLKC(I,J,1) = FHB * FD2D(I,J) / STEPS_PER_YR
|
|
|
|
! Hydrophobic BLACK CARBON from biomass [kg C/timestep]
|
|
BIOB_BLKC(I,J,2) = ( 1.d0 - FHB ) * FD2D(I,J) / STEPS_PER_YR
|
|
|
|
! Compute future emissions of BLACK CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_BCbb( I, J )
|
|
BIOB_BLKC(I,J,1) = BIOB_BLKC(I,J,1) * FUT_SCL
|
|
BIOB_BLKC(I,J,2) = BIOB_BLKC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
!=================================================================
|
|
! Read ORGANIC CARBON from biomass burning as tracer #35 in
|
|
! [kg C/year]. Then convert to [kg C/timestep] and store in
|
|
! BIOF_BLKC.
|
|
!=================================================================
|
|
CALL READ_BPCH2( FILENAME, 'BIOBSRCE', 35,
|
|
& XTAU, IGLOB, JGLOB,
|
|
& 1, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8 and resize
|
|
CALL TRANSFER_2D( ARRAY(:,:,1), FD2D )
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, FUT_SCL )
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Hydrophilic ORGANIC CARBON from biomass [kg C/timestep]
|
|
BIOB_ORGC(I,J,1) = FHO * FD2D(I,J) / STEPS_PER_YR
|
|
|
|
! Hydrophobic ORGANIC CARBON from biomass [kg C/timestep]
|
|
BIOB_ORGC(I,J,2) = ( 1.d0 - FHO ) * FD2D(I,J) / STEPS_PER_YR
|
|
|
|
! Compute future emissions of ORGANIC CARBON (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
FUT_SCL = GET_FUTURE_SCALE_OCbb( I, J )
|
|
BIOB_ORGC(I,J,1) = BIOB_ORGC(I,J,1) * FUT_SCL
|
|
BIOB_ORGC(I,J,2) = BIOB_ORGC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE BIOMASS_CARB_TBOND
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE BIOMASS_CARB_GEOS
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine BIOMASS_CARB_GEOS computes monthly mean biomass burning
|
|
! emissions of BLACK CARBON (aka ELEMENTAL CARBON) and ORGANIC CARBON.
|
|
! It also separates these into HYDROPHILIC and HYDROPHOBIC fractions.
|
|
! (rjp, bmy, 4/2/04, 2/19/09)
|
|
!
|
|
! Emissions are contained in the BIOMASS array of "biomass_mod.f", and will
|
|
! contain biomass emissions from either the Duncan et al [2001] inventory or
|
|
! the GFED2 inventory, depending on the option selected at runtime startup.
|
|
! BIOMASS has units of [atoms C/cm3/s]. Units will be converted to
|
|
! [kg C/timestep] below.
|
|
!
|
|
! We also assume that 20% of BC and 50% of OC from anthropogenic
|
|
! emissions are hydrophilic (soluble) and the rest are hydrophobic.
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references DATA_DIR from "directory_mod.f". Also removed CMN,
|
|
! it's obsolete. (bmy, 7/20/04)
|
|
! (2 ) Now read data from "carbon_200411" subdir of DATA_DIR (bmy, 11/15/04)
|
|
! (3 ) Now read BCPO, OCPO biomass burning data directly from files instead
|
|
! of computing from emission factors. (rjp, bmy, 1/11/05)
|
|
! (4 ) Now can read data for both GEOS and GCAP grids (bmy, 8/16/05)
|
|
! (5 ) Now compute future emissions of BC,OC if necessary (swu, bmy, 5/30/06)
|
|
! (6 ) Now get biomass emissions from the BIOMASS array of "biomass_mod.f",
|
|
! which will contain either GFED2 or default emissions. Also move
|
|
! file-reading code to gc_biomass_mod.f. (bmy, 9/25/06)
|
|
! (7 ) Prevent seg fault error when LBIOMASS=F (bmy, 11/3/06)
|
|
! (8 ) Now apply future emissions if necessary (hotp, swu, bmy, 2/19/09)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE BIOMASS_MOD, ONLY : BIOMASS, IDBBC, IDBOC
|
|
USE GRID_MOD, ONLY : GET_AREA_CM2
|
|
USE LOGICAL_MOD, ONLY : LBIOMASS, LFUTURE
|
|
USE TIME_MOD, ONLY : GET_TS_EMIS
|
|
USE TRACER_MOD, ONLY : XNUMOL
|
|
USE TRACERID_MOD, ONLY : IDTBCPO, IDTOCPO
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_OCbb
|
|
USE FUTURE_EMISSIONS_MOD, ONLY : GET_FUTURE_SCALE_BCbb
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
!-------------------
|
|
! Local variables
|
|
!-------------------
|
|
|
|
! Hydrophilic fraction of BLACK CARBON
|
|
REAL*8, PARAMETER :: FHB = 0.2d0
|
|
|
|
! Hydrophilic fraction of ORGANIC CARBON
|
|
REAL*8, PARAMETER :: FHO = 0.5d0
|
|
|
|
INTEGER :: I, J
|
|
REAL*8 :: A_CM2, BIOBC, BIOOC
|
|
REAL*8 :: CONV_BC, CONV_OC, DTSRCE, FUT_SCL
|
|
CHARACTER(LEN=255) :: BC_FILE, OC_FILE
|
|
|
|
!=================================================================
|
|
! BIOMASS_CARB_GEOS begins here!
|
|
!=================================================================
|
|
|
|
! Emission timestep [s]
|
|
DTSRCE = 60d0 * GET_TS_EMIS()
|
|
|
|
! Conversion factor for [s * kg/molec]
|
|
CONV_BC = DTSRCE / XNUMOL(IDTBCPO)
|
|
CONV_OC = DTSRCE / XNUMOL(IDTOCPO)
|
|
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, BIOBC, BIOOC, A_CM2, FUT_SCL )
|
|
|
|
! Loop over latitudes
|
|
DO J = 1, JJPAR
|
|
|
|
! Grid box area [cm2]
|
|
A_CM2 = GET_AREA_CM2( J )
|
|
|
|
! Loop over longitudes
|
|
DO I = 1, IIPAR
|
|
|
|
! Convert [molec/cm2/s] --> [kg C/timestep]
|
|
IF ( LBIOMASS ) THEN
|
|
BIOBC = BIOMASS(I,J,IDBBC) * A_CM2 * CONV_BC
|
|
BIOOC = BIOMASS(I,J,IDBOC) * A_CM2 * CONV_OC
|
|
ELSE
|
|
BIOBC = 0d0
|
|
BIOOC = 0d0
|
|
ENDIF
|
|
|
|
! Hydrophilic BLACK CARBON from biomass [kg C/timestep]
|
|
BIOB_BLKC(I,J,1) = FHB * BIOBC
|
|
|
|
! Hydrophobic BLACK CARBON from biomass [kg C/timestep]
|
|
BIOB_BLKC(I,J,2) = ( 1.D0 - FHB ) * BIOBC
|
|
|
|
! Hydrophilic ORGANIC CARBON from biomass [kg C/timestep]
|
|
BIOB_ORGC(I,J,1) = FHO * BIOOC
|
|
|
|
! Hydrophobic ORGANIC CARBON from biomass [kg C/timestep]
|
|
BIOB_ORGC(I,J,2) = ( 1.D0 - FHO ) * BIOOC
|
|
|
|
! Apply future emissions for GCAP (if necessary)
|
|
IF ( LFUTURE ) THEN
|
|
|
|
! Compute future emissions of ORGANIC CARBON
|
|
FUT_SCL = GET_FUTURE_SCALE_OCbb( I, J )
|
|
BIOB_ORGC(I,J,1) = BIOB_ORGC(I,J,1) * FUT_SCL
|
|
BIOB_ORGC(I,J,2) = BIOB_ORGC(I,J,2) * FUT_SCL
|
|
|
|
! Compute future emissions of BLACK CARBON
|
|
FUT_SCL = GET_FUTURE_SCALE_BCbb( I, J )
|
|
BIOB_BLKC(I,J,1) = BIOB_BLKC(I,J,1) * FUT_SCL
|
|
BIOB_BLKC(I,J,2) = BIOB_BLKC(I,J,2) * FUT_SCL
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE BIOMASS_CARB_GEOS
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE EMITHIGH( BCSRC, OCSRC )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine EMITHIGH mixes tracer completely from the surface to the PBL
|
|
! top. (rjp, bmy, 4/2/04, 2/17/05)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) BCSRC (REAL*8) : Array which holds Total BC (H-phobic & H-philic)
|
|
! (2 ) OCSRC (REAL*8) : Array which holds Total OC (H-phobic & H-philic)
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now also mix ALPH, LIMO, ALCO tracers (rjp, bmy, 7/8/04)
|
|
! (2 ) Now reference STT from "tracer_mod.f" (bmy, 7/20/04)
|
|
! (3 ) Remove references to "dao_mod.f", "pressure_mod.f", and "error_mod.f".
|
|
! Rewrote for computational expediency using routines from
|
|
! "pbl_mix_mod.f". (bmy, 2/17/05)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE PBL_MIX_MOD, ONLY : GET_FRAC_OF_PBL, GET_PBL_MAX_L
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTBCPI, IDTBCPO, IDTOCPI, IDTOCPO
|
|
USE TRACERID_MOD, ONLY : IDTALPH, IDTLIMO, IDTALCO
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
REAL*8, INTENT(IN) :: BCSRC(IIPAR,JJPAR,2)
|
|
REAL*8, INTENT(IN) :: OCSRC(IIPAR,JJPAR,2)
|
|
|
|
! Local variables
|
|
LOGICAL :: IS_BCPO, IS_OCPO, IS_BCPI, IS_OCPI
|
|
LOGICAL :: IS_ALPH, IS_LIMO, IS_ALCO
|
|
INTEGER :: I, J, L, PBL_MAX
|
|
REAL*8 :: F_OF_PBL
|
|
|
|
!=================================================================
|
|
! EMITHIGH begins here!
|
|
!=================================================================
|
|
|
|
! Define logical flags for expediency
|
|
IS_BCPI = ( IDTBCPI > 0 )
|
|
IS_OCPI = ( IDTOCPI > 0 )
|
|
IS_BCPO = ( IDTBCPO > 0 )
|
|
IS_OCPO = ( IDTOCPO > 0 )
|
|
IS_ALPH = ( IDTALPH > 0 )
|
|
IS_LIMO = ( IDTLIMO > 0 )
|
|
IS_ALCO = ( IDTALCO > 0 )
|
|
|
|
! Maximum extent of PBL [model levels]
|
|
PBL_MAX = GET_PBL_MAX_L()
|
|
|
|
!=================================================================
|
|
! Partition emissions throughout the boundary layer
|
|
!=================================================================
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L, F_OF_PBL )
|
|
DO L = 1, PBL_MAX
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Fraction of PBL spanned by grid box (I,J,L) [unitless]
|
|
F_OF_PBL = GET_FRAC_OF_PBL( I, J, L )
|
|
|
|
! Hydrophilic BLACK CARBON
|
|
IF ( IS_BCPI ) THEN
|
|
STT(I,J,L,IDTBCPI) = STT(I,J,L,IDTBCPI) +
|
|
& ( F_OF_PBL * BCSRC(I,J,1) )
|
|
ENDIF
|
|
|
|
! Hydrophilic ORGANIC CARBON
|
|
IF ( IS_OCPI ) THEN
|
|
STT(I,J,L,IDTOCPI) = STT(I,J,L,IDTOCPI) +
|
|
& ( F_OF_PBL * OCSRC(I,J,1) )
|
|
ENDIF
|
|
|
|
! Hydrophobic BLACK CARBON
|
|
IF ( IS_BCPO ) THEN
|
|
STT(I,J,L,IDTBCPO) = STT(I,J,L,IDTBCPO) +
|
|
& ( F_OF_PBL * BCSRC(I,J,2) )
|
|
ENDIF
|
|
|
|
! Hydrophobic ORGANIC CARBON
|
|
IF ( IS_OCPO ) THEN
|
|
STT(I,J,L,IDTOCPO) = STT(I,J,L,IDTOCPO) +
|
|
& ( F_OF_PBL * OCSRC(I,J,2) )
|
|
ENDIF
|
|
|
|
! ALPHA-PINENE
|
|
IF ( IS_ALPH ) THEN
|
|
STT(I,J,L,IDTALPH) = STT(I,J,L,IDTALPH) +
|
|
& ( F_OF_PBL * BIOG_ALPH(I,J) )
|
|
ENDIF
|
|
|
|
! LIMONENE
|
|
IF ( IS_LIMO ) THEN
|
|
STT(I,J,L,IDTLIMO) = STT(I,J,L,IDTLIMO) +
|
|
& ( F_OF_PBL * BIOG_LIMO(I,J) )
|
|
|
|
ORVC_TERP(I,J,L) = ORVC_TERP(I,J,L) +
|
|
& ( F_OF_PBL * BIOG_TERP(I,J) )
|
|
ENDIF
|
|
|
|
! ALCOHOL and SESQTERPENE (not a tracer)
|
|
IF ( IS_ALCO ) THEN
|
|
STT(I,J,L,IDTALCO) = STT(I,J,L,IDTALCO) +
|
|
& ( F_OF_PBL * BIOG_ALCO(I,J) )
|
|
|
|
ORVC_SESQ(I,J,L) = ORVC_SESQ(I,J,L) +
|
|
& ( F_OF_PBL * BIOG_SESQ(I,J) )
|
|
ENDIF
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE EMITHIGH
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE OHNO3TIME
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine OHNO3TIME computes the sum of cosine of the solar zenith
|
|
! angle over a 24 hour day, as well as the total length of daylight.
|
|
! This is needed to scale the offline OH and NO3 concentrations.
|
|
! (rjp, bmy, 12/16/02, 1/18/05)
|
|
!
|
|
! NOTES:
|
|
! (1 ) Copy code from COSSZA directly for now, so that we don't get NaN
|
|
! values. Figure this out later (rjp, bmy, 1/10/03)
|
|
! (2 ) Now replace XMID(I) with routine GET_XMID from "grid_mod.f".
|
|
! Now replace RLAT(J) with routine GET_YMID_R from "grid_mod.f".
|
|
! Removed NTIME, NHMSb from the arg list. Now use GET_NHMSb,
|
|
! GET_ELAPSED_SEC, GET_TS_CHEM, GET_DAY_OF_YEAR, GET_GMT from
|
|
! "time_mod.f". (bmy, 3/27/03)
|
|
! (3 ) Now store the peak SUNCOS value for each surface grid box (I,J) in
|
|
! the COSZM array. (rjp, bmy, 3/30/04)
|
|
! (4 ) Also added parallel loop over grid boxes (bmy, 1/18/05)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE GRID_MOD, ONLY : GET_XMID, GET_YMID_R
|
|
USE TIME_MOD, ONLY : GET_NHMSb, GET_ELAPSED_SEC
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM, GET_DAY_OF_YEAR, GET_GMT
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_GCTM"
|
|
|
|
! Local variables
|
|
LOGICAL, SAVE :: FIRST = .TRUE.
|
|
INTEGER :: I, IJLOOP, J, L, N, NT, NDYSTEP
|
|
REAL*8 :: A0, A1, A2, A3, B1, B2, B3
|
|
REAL*8 :: LHR0, R, AHR, DEC, TIMLOC, YMID_R
|
|
REAL*8 :: SUNTMP(MAXIJ)
|
|
|
|
!=================================================================
|
|
! OHNO3TIME begins here!
|
|
!=================================================================
|
|
|
|
! Solar declination angle (low precision formula, good enough for us):
|
|
A0 = 0.006918
|
|
A1 = 0.399912
|
|
A2 = 0.006758
|
|
A3 = 0.002697
|
|
B1 = 0.070257
|
|
B2 = 0.000907
|
|
B3 = 0.000148
|
|
R = 2.* PI * float( GET_DAY_OF_YEAR() - 1 ) / 365.
|
|
|
|
DEC = A0 - A1*cos( R) + B1*sin( R)
|
|
& - A2*cos(2*R) + B2*sin(2*R)
|
|
& - A3*cos(3*R) + B3*sin(3*R)
|
|
|
|
LHR0 = int(float( GET_NHMSb() )/10000.)
|
|
|
|
! Only do the following at the start of a new day
|
|
IF ( FIRST .or. GET_GMT() < 1e-5 ) THEN
|
|
|
|
! Zero arrays
|
|
TCOSZ(:,:) = 0d0
|
|
|
|
! NDYSTEP is # of chemistry time steps in this day
|
|
NDYSTEP = ( 24 - INT( GET_GMT() ) ) * 60 / GET_TS_CHEM()
|
|
|
|
! NT is the elapsed time [s] since the beginning of the run
|
|
NT = GET_ELAPSED_SEC()
|
|
|
|
! Loop forward through NDYSTEP "fake" timesteps for this day
|
|
DO N = 1, NDYSTEP
|
|
|
|
! Zero SUNTMP array
|
|
SUNTMP(:) = 0d0
|
|
|
|
! Loop over surface grid boxes
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, YMID_R, IJLOOP, TIMLOC, AHR )
|
|
DO J = 1, JJPAR
|
|
|
|
! Grid box latitude center [radians]
|
|
YMID_R = GET_YMID_R( J )
|
|
|
|
DO I = 1, IIPAR
|
|
|
|
! Increment IJLOOP
|
|
IJLOOP = ( (J-1) * IIPAR ) + I
|
|
TIMLOC = real(LHR0) + real(NT)/3600.0 + GET_XMID(I)/15.0
|
|
|
|
DO WHILE (TIMLOC .lt. 0)
|
|
TIMLOC = TIMLOC + 24.0
|
|
ENDDO
|
|
|
|
DO WHILE (TIMLOC .gt. 24.0)
|
|
TIMLOC = TIMLOC - 24.0
|
|
ENDDO
|
|
|
|
AHR = abs(TIMLOC - 12.) * 15.0 * PI_180
|
|
|
|
!===========================================================
|
|
! The cosine of the solar zenith angle (SZA) is given by:
|
|
!
|
|
! cos(SZA) = sin(LAT)*sin(DEC) + cos(LAT)*cos(DEC)*cos(AHR)
|
|
!
|
|
! where LAT = the latitude angle,
|
|
! DEC = the solar declination angle,
|
|
! AHR = the hour angle, all in radians.
|
|
!
|
|
! If SUNCOS < 0, then the sun is below the horizon, and
|
|
! therefore does not contribute to any solar heating.
|
|
!===========================================================
|
|
|
|
! Compute Cos(SZA)
|
|
SUNTMP(IJLOOP) = sin(YMID_R) * sin(DEC) +
|
|
& cos(YMID_R) * cos(DEC) * cos(AHR)
|
|
|
|
! TCOSZ is the sum of SUNTMP at location (I,J)
|
|
! Do not include negative values of SUNTMP
|
|
TCOSZ(I,J) = TCOSZ(I,J) + MAX( SUNTMP(IJLOOP), 0d0 )
|
|
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
! Increment elapsed time [sec]
|
|
NT = NT + ( GET_TS_CHEM() * 60 )
|
|
ENDDO
|
|
|
|
! Reset first-time flag
|
|
FIRST = .FALSE.
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE OHNO3TIME
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
FUNCTION GET_OH( I, J, L ) RESULT( OH_MOLEC_CM3 )
|
|
!
|
|
!******************************************************************************
|
|
! Function GET_OH returns OH from SMVGEAR's CSPEC array (for coupled runs)
|
|
! or monthly mean OH (for offline runs). Imposes a diurnal variation on
|
|
! OH for offline simulations. (bmy, 7/9/04)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1-3) I, J, L (INTEGER) : Grid box indices for lon, lat, vertical level
|
|
!
|
|
! NOTES:
|
|
! (1 ) We assume SETTRACE has been called to define IDOH (bmy, 11/1/02)
|
|
! (2 ) Now use function GET_TS_CHEM from "time_mod.f" (bmy, 3/27/03)
|
|
! (3 ) Now reference inquiry functions from "tracer_mod.f" (bmy, 7/20/04)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE COMODE_MOD, ONLY : CSPEC, JLOP
|
|
USE DAO_MOD, ONLY : SUNCOS
|
|
USE ERROR_MOD, ONLY : ERROR_STOP
|
|
USE GLOBAL_OH_MOD, ONLY : OH
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
USE TRACER_MOD, ONLY : ITS_A_FULLCHEM_SIM, ITS_AN_AEROSOL_SIM
|
|
USE TRACERID_MOD, ONLY : IDOH
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: I, J, L
|
|
|
|
! Local variables
|
|
INTEGER :: JLOOP
|
|
REAL*8 :: OH_MOLEC_CM3
|
|
|
|
!=================================================================
|
|
! GET_OH begins here!
|
|
!=================================================================
|
|
IF ( ITS_A_FULLCHEM_SIM() ) THEN
|
|
|
|
!---------------------
|
|
! Coupled simulation
|
|
!---------------------
|
|
|
|
! JLOOP = SMVGEAR 1-D grid box index
|
|
JLOOP = JLOP(I,J,L)
|
|
|
|
! Take OH from the SMVGEAR array CSPEC
|
|
! OH is defined only in the troposphere
|
|
IF ( JLOOP > 0 ) THEN
|
|
OH_MOLEC_CM3 = CSPEC(JLOOP,IDOH)
|
|
ELSE
|
|
OH_MOLEC_CM3 = 0d0
|
|
ENDIF
|
|
|
|
ELSE IF ( ITS_AN_AEROSOL_SIM() ) THEN
|
|
|
|
!---------------------
|
|
! Offline simulation
|
|
!---------------------
|
|
|
|
! 1-D grid box index for SUNCOS
|
|
JLOOP = ( (J-1) * IIPAR ) + I
|
|
|
|
! Test for sunlight...
|
|
IF ( SUNCOS(JLOOP) > 0d0 .and. TCOSZ(I,J) > 0d0 ) THEN
|
|
|
|
! Impose a diurnal variation on OH during the day
|
|
OH_MOLEC_CM3 = OH(I,J,L) *
|
|
& ( SUNCOS(JLOOP) / TCOSZ(I,J) ) *
|
|
& ( 1440d0 / GET_TS_CHEM() )
|
|
|
|
! Make sure OH is not negative
|
|
OH_MOLEC_CM3 = MAX( OH_MOLEC_CM3, 0d0 )
|
|
|
|
ELSE
|
|
|
|
! At night, OH goes to zero
|
|
OH_MOLEC_CM3 = 0d0
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
!---------------------
|
|
! Invalid sim type!
|
|
!---------------------
|
|
CALL ERROR_STOP( 'Invalid Simulation Type!',
|
|
& 'GET_OH ("carbon_mod.f")' )
|
|
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END FUNCTION GET_OH
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
FUNCTION GET_NO3( I, J, L ) RESULT( NO3_MOLEC_CM3 )
|
|
!
|
|
!******************************************************************************
|
|
! Function GET_NO3 returns NO3 from SMVGEAR's CSPEC array (for coupled runs)
|
|
! or monthly mean OH (for offline runs). For offline runs, the concentration
|
|
! of NO3 is set to zero during the day. (rjp, bmy, 12/16/02, 7/20/04)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1-3) I, J, L (INTEGER) : Grid box indices for lon, lat, vertical level
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now references ERROR_STOP from "error_mod.f". We also assume that
|
|
! SETTRACE has been called to define IDNO3. Now also set NO3 to
|
|
! zero during the day. (rjp, bmy, 12/16/02)
|
|
! (2 ) Now reference inquiry functions from "tracer_mod.f" (bmy, 7/20/04)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE COMODE_MOD, ONLY : CSPEC, JLOP
|
|
USE DAO_MOD, ONLY : AD, SUNCOS
|
|
USE ERROR_MOD, ONLY : ERROR_STOP
|
|
USE GLOBAL_NO3_MOD, ONLY : NO3
|
|
USE TRACER_MOD, ONLY : ITS_A_FULLCHEM_SIM, ITS_AN_AEROSOL_SIM
|
|
USE TRACERID_MOD, ONLY : IDNO3
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN" ! NSRCX
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: I, J, L
|
|
|
|
! Local variables
|
|
INTEGER :: JLOOP
|
|
REAL*8 :: NO3_MOLEC_CM3
|
|
REAL*8, PARAMETER :: XNUMOL_NO3 = 6.022d23 / 62d-3
|
|
|
|
! External functions
|
|
REAL*8, EXTERNAL :: BOXVL
|
|
|
|
!=================================================================
|
|
! GET_NO3 begins here!
|
|
!=================================================================
|
|
IF ( ITS_A_FULLCHEM_SIM() ) THEN
|
|
|
|
!----------------------
|
|
! Fullchem simulation
|
|
!----------------------
|
|
|
|
! 1-D SMVGEAR grid box index
|
|
JLOOP = JLOP(I,J,L)
|
|
|
|
! Take NO3 from the SMVGEAR array CSPEC
|
|
! NO3 is defined only in the troposphere
|
|
IF ( JLOOP > 0 ) THEN
|
|
NO3_MOLEC_CM3 = CSPEC(JLOOP,IDNO3)
|
|
ELSE
|
|
NO3_MOLEC_CM3 = 0d0
|
|
ENDIF
|
|
|
|
ELSE IF ( ITS_AN_AEROSOL_SIM() ) THEN
|
|
|
|
!==============================================================
|
|
! Offline simulation: Read monthly mean GEOS-CHEM NO3 fields
|
|
! in [v/v]. Convert these to [molec/cm3] as follows:
|
|
!
|
|
! vol NO3 moles NO3 kg air kg NO3/mole NO3
|
|
! ------- = --------- * -------- * ---------------- = kg NO3
|
|
! vol air moles air 1 kg air/mole air
|
|
!
|
|
! And then we convert [kg NO3] to [molec NO3/cm3] by:
|
|
!
|
|
! kg NO3 molec NO3 mole NO3 1 molec NO3
|
|
! ------ * --------- * -------- * ----- = ---------
|
|
! 1 mole NO3 kg NO3 cm3 cm3
|
|
! ^ ^
|
|
! |____________________|
|
|
! this is XNUMOL_NO3
|
|
!
|
|
! If at nighttime, use the monthly mean NO3 concentration from
|
|
! the NO3 array of "global_no3_mod.f". If during the daytime,
|
|
! set the NO3 concentration to zero. We don't have to relax to
|
|
! the monthly mean concentration every 3 hours (as for HNO3)
|
|
! since NO3 has a very short lifetime. (rjp, bmy, 12/16/02)
|
|
!==============================================================
|
|
|
|
! 1-D grid box index for SUNCOS
|
|
JLOOP = ( (J-1) * IIPAR ) + I
|
|
|
|
! Test if daylight
|
|
IF ( SUNCOS(JLOOP) > 0d0 ) THEN
|
|
|
|
! NO3 goes to zero during the day
|
|
NO3_MOLEC_CM3 = 0d0
|
|
|
|
ELSE
|
|
|
|
! At night: Get NO3 [v/v] and convert it to [kg]
|
|
NO3_MOLEC_CM3 = NO3(I,J,L) * AD(I,J,L) * ( 62d0/28.97d0 )
|
|
|
|
! Convert NO3 from [kg] to [molec/cm3]
|
|
NO3_MOLEC_CM3 = NO3_MOLEC_CM3 * XNUMOL_NO3 / BOXVL(I,J,L)
|
|
|
|
ENDIF
|
|
|
|
! Make sure NO3 is not negative
|
|
NO3_MOLEC_CM3 = MAX( NO3_MOLEC_CM3, 0d0 )
|
|
|
|
ELSE
|
|
|
|
!----------------------
|
|
! Invalid sim type!
|
|
!----------------------
|
|
CALL ERROR_STOP( 'Invalid Simulation Type!',
|
|
& 'GET_NO3 ("carbon_mod.f")' )
|
|
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END FUNCTION GET_NO3
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
FUNCTION GET_O3( I, J, L ) RESULT( O3_MOLEC_CM3 )
|
|
!
|
|
!******************************************************************************
|
|
! Function GET_O3 returns monthly mean O3 for offline sulfate aerosol
|
|
! simulations. (bmy, 12/16/02, 7/20/04)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1-3) I, J, L (INTEGER) : Grid box indices for lon, lat, vertical level
|
|
!
|
|
! NOTES:
|
|
! (1 ) We assume SETTRACE has been called to define IDO3. (bmy, 12/16/02)
|
|
! (2 ) Now reference inquiry functions from "tracer_mod.f" (bmy, 7/20/04)
|
|
! (3 ) Now reference XNUMOLAIR from "tracer_mod.f" (bmy, 10/20/05)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE COMODE_MOD, ONLY : CSPEC, JLOP, VOLUME
|
|
USE DAO_MOD, ONLY : SUNCOS, AD
|
|
USE ERROR_MOD, ONLY : ERROR_STOP
|
|
USE GLOBAL_O3_MOD, ONLY : O3
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
USE TRACER_MOD, ONLY : ITS_A_FULLCHEM_SIM, ITS_AN_AEROSOL_SIM
|
|
USE TRACER_MOD, ONLY : XNUMOLAIR
|
|
USE TRACERID_MOD, ONLY : IDO3
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: I, J, L
|
|
|
|
! Local variables
|
|
INTEGER :: JLOOP
|
|
REAL*8 :: O3_MOLEC_CM3
|
|
REAL*8, PARAMETER :: XNUMOL_O3 = 6.022d23 / 48d-3
|
|
|
|
! External functions
|
|
REAL*8, EXTERNAL :: BOXVL
|
|
|
|
!=================================================================
|
|
! GET_O3 begins here!
|
|
!=================================================================
|
|
IF ( ITS_A_FULLCHEM_SIM() ) THEN
|
|
|
|
!--------------------
|
|
! Coupled simulation
|
|
!--------------------
|
|
|
|
! JLOOP = SMVGEAR 1-D grid box index
|
|
JLOOP = JLOP(I,J,L)
|
|
|
|
! Get O3 from CSPEC [molec/cm3]
|
|
! O3 data will only be defined below the tropopause
|
|
IF ( JLOOP > 0 ) THEN
|
|
O3_MOLEC_CM3 = CSPEC(JLOOP,IDO3)
|
|
ELSE
|
|
O3_MOLEC_CM3 = 0d0
|
|
ENDIF
|
|
|
|
ELSE IF ( ITS_AN_AEROSOL_SIM() ) THEN
|
|
|
|
!--------------------
|
|
! Offline simulation
|
|
!--------------------
|
|
|
|
! Get O3 [v/v] for this gridbox & month
|
|
! O3 data will only be defined below the tropopause
|
|
IF ( L <= LLTROP ) THEN
|
|
|
|
! Get O3 [v/v] and convert it to [kg]
|
|
O3_MOLEC_CM3 = O3(I,J,L) * AD(I,J,L) * ( 48d0/28.97d0 )
|
|
|
|
! Convert O3 from [kg] to [molec/cm3]
|
|
O3_MOLEC_CM3 = O3_MOLEC_CM3 * XNUMOL_O3 / BOXVL(I,J,L)
|
|
ELSE
|
|
O3_MOLEC_CM3 = 0d0
|
|
ENDIF
|
|
|
|
! 1-D grid box index for SUNCOS
|
|
JLOOP = ( (J-1) * IIPAR ) + I
|
|
|
|
! Test for sunlight...
|
|
IF ( SUNCOS(JLOOP) > 0d0 .and. TCOSZ(I,J) > 0d0 ) THEN
|
|
|
|
! Impose a diurnal variation on OH during the day
|
|
O3_MOLEC_CM3 = O3_MOLEC_CM3 *
|
|
& ( SUNCOS(JLOOP) / TCOSZ(I,J) ) *
|
|
& ( 1440d0 / GET_TS_CHEM() )
|
|
|
|
! Make sure OH is not negative
|
|
O3_MOLEC_CM3 = MAX( O3_MOLEC_CM3, 0d0 )
|
|
|
|
ELSE
|
|
O3_MOLEC_CM3 = 0d0
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
!--------------------
|
|
! Invalid sim type!
|
|
!--------------------
|
|
CALL ERROR_STOP( 'Invalid Simulation Type!',
|
|
& 'GET_O3 ("carbon_mod.f")' )
|
|
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END FUNCTION GET_O3
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
FUNCTION GET_DOH( I, J, L ) RESULT( DOH )
|
|
!
|
|
!******************************************************************************
|
|
! Function GET_DOH returns the amount of isoprene [kg] that has reacted with
|
|
! OH during the last chemistry time step. (dkh, bmy, 6/01/06)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1-3) I, J, L (INTEGER) : Grid box indices for lon, lat, vertical level
|
|
!
|
|
!
|
|
! NOTES:
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE COMODE_MOD, ONLY : CSPEC, JLOP, VOLUME
|
|
USE ERROR_MOD, ONLY : ERROR_STOP
|
|
USE TRACER_MOD, ONLY : ITS_A_FULLCHEM_SIM, ITS_AN_AEROSOL_SIM
|
|
USE TRACER_MOD, ONLY : XNUMOL, TRACER_COEFF
|
|
USE TRACERID_MOD, ONLY : IDTISOP
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "comode.h" ! ILISOPOH (dkh, 05/29/06)
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: I, J, L
|
|
|
|
! Function returns
|
|
REAL*8 :: DOH
|
|
|
|
! Local variables
|
|
INTEGER :: JLOOP
|
|
|
|
!=================================================================
|
|
! GET_DOH begins here!
|
|
!=================================================================
|
|
|
|
IF ( ITS_A_FULLCHEM_SIM() ) THEN
|
|
|
|
!--------------------
|
|
! Coupled simulation
|
|
!--------------------
|
|
|
|
! Get 1-D index from current 3-D position
|
|
JLOOP = JLOP(I,J,L)
|
|
|
|
! Test if we are in the troposphere
|
|
IF ( JLOOP > 0 ) THEN
|
|
|
|
!-----------------------------------------------------------
|
|
! Get DOH from CSPEC [molec/cm3] and
|
|
! convert to [kg C isop / box]
|
|
!
|
|
! CSPEC(JLOOP,ILISOPOH) : molec isop (lost to OH) / cm3
|
|
! XNUMOL(IDTISOP) : atom C / kg C isop
|
|
! TRACER_COEFF(IDTISOP,1) : atom C / molec isop
|
|
! VOLUME : cm3 / box
|
|
!-----------------------------------------------------------
|
|
DOH = CSPEC(JLOOP,ILISOPOH) *
|
|
& VOLUME(JLOOP) *
|
|
& TRACER_COEFF(IDTISOP,1) /
|
|
& XNUMOL(IDTISOP)
|
|
|
|
ELSE
|
|
|
|
! Otherwise set DOH=0
|
|
DOH = 0d0
|
|
|
|
ENDIF
|
|
|
|
ELSE IF ( ITS_AN_AEROSOL_SIM() ) THEN
|
|
|
|
!--------------------
|
|
! Offline simulation
|
|
!--------------------
|
|
|
|
! ISOP from OH not is yet supported for
|
|
! offline aerosol simulations, set DOH=0
|
|
DOH = 0d0
|
|
|
|
ELSE
|
|
|
|
!--------------------
|
|
! Invalid sim type!
|
|
!--------------------
|
|
CALL ERROR_STOP( 'Invalid simulation type!',
|
|
& 'GET_DOH ("carbon_mod.f")' )
|
|
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END FUNCTION GET_DOH
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE GET_VCLDF
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine GET_VCLDF computes the volume cloud fraction for SO2 chemistry.
|
|
! (rjp, bdf, bmy, 9/23/02)
|
|
!
|
|
! References:
|
|
! ============================================================================
|
|
! (1) Sundqvist et al. [1989]
|
|
!
|
|
! NOTES:
|
|
! (1 ) Copied from 'sulfate_mod.f' for cloud uptake of GLYX and MGLY (tmf, 2/26/07)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE DAO_MOD, ONLY : RH
|
|
USE PRESSURE_MOD, ONLY : GET_PCENTER, GET_PEDGE
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Local variables
|
|
INTEGER :: I, J, L
|
|
REAL*8 :: PRES, PSFC, RH2, R0, B0
|
|
|
|
! Parameters
|
|
REAL*8, PARAMETER :: ZRT = 0.60d0, ZRS = 0.99d0
|
|
|
|
!=================================================================
|
|
! GET_VCLDF begins here!
|
|
!=================================================================
|
|
!$OMP PARALLEL DO
|
|
!$OMP+DEFAULT( SHARED )
|
|
!$OMP+PRIVATE( I, J, L, PSFC, PRES, RH2, R0, B0 )
|
|
DO L = 1, LLTROP
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Surface pressure
|
|
PSFC = GET_PEDGE(I,J,1)
|
|
|
|
! Pressure at the center of the grid box
|
|
PRES = GET_PCENTER(I,J,L)
|
|
|
|
! RH (from "dao_mod.f") is relative humidity [%]
|
|
! Convert to fraction and store in RH2
|
|
RH2 = RH(I,J,L) * 1.0d-2
|
|
|
|
! Terms from Sundqvist ???
|
|
R0 = ZRT + ( ZRS - ZRT ) * EXP( 1d0 - ( PSFC / PRES )**2.5 )
|
|
B0 = ( RH2 - R0 ) / ( 1d0 - R0 )
|
|
|
|
! Force B0 into the range 0-1
|
|
IF ( RH2 < R0 ) B0 = 0d0
|
|
IF ( B0 > 1d0 ) B0 = 1d0
|
|
|
|
! Volume cloud fraction
|
|
VCLDF(I,J,L) = 1d0 - SQRT( 1d0 - B0 )
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
!$OMP END PARALLEL DO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE GET_VCLDF
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
FUNCTION GET_LWC( T ) RESULT( LWC )
|
|
!
|
|
!******************************************************************************
|
|
! Function GET_LWC returns the cloud liquid water content at a GEOS-CHEM
|
|
! grid box as a function of temperature. (rjp, bmy, 10/31/02, 1/14/03)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) T (REAL*8) : Temperature value at a GEOS-CHEM grid box [K]
|
|
!
|
|
! NOTES:
|
|
! (1 ) Copied from 'sulfate_mod.f' for cloud uptake of GLYX and MGLY (tmf, 2/26/07)
|
|
!******************************************************************************
|
|
!
|
|
! Arguments
|
|
REAL*8, INTENT(IN) :: T
|
|
|
|
! Function value
|
|
REAL*8 :: LWC
|
|
|
|
!=================================================================
|
|
! GET_LWC begins here!
|
|
!=================================================================
|
|
|
|
! Compute Liquid water content in [g/m3]
|
|
IF ( T > 293d0 ) THEN
|
|
LWC = 0.2d0
|
|
|
|
ELSE IF ( T >= 280.d0 .AND. T <= 293.d0 ) THEN
|
|
LWC = 0.32d0 - 0.0060d0 * ( T - 273.D0 )
|
|
|
|
ELSE IF ( T >= 248.d0 .AND. T < 280.d0 ) THEN
|
|
LWC = 0.23d0 + 0.0065d0 * ( T - 273.D0 )
|
|
|
|
ELSE IF ( T < 248.d0 ) THEN
|
|
LWC = 0.07d0
|
|
|
|
ENDIF
|
|
|
|
! Return to calling program
|
|
END FUNCTION GET_LWC
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOAG_CLOUD
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOAG_CLOUD produces SOAG from GLYX during a cloud event.
|
|
! Mimics the SO2 -> SO4 process from 'sulfate_mod.f'. (tmf, 2/26/07)
|
|
!
|
|
! Procedure:
|
|
! ============================================================================
|
|
! (1 )
|
|
!
|
|
! NOTES:
|
|
! (1 ) SOAG (SOA product of GLYX is produced at existing hydrophilic aerosol
|
|
! surface. (tmf, 2/26/07)
|
|
! (2 ) Assume marine and continental cloud droplet size (tmf, 2/26/07)
|
|
!******************************************************************************
|
|
!
|
|
! Reference to diagnostic arrays
|
|
USE DAO_MOD, ONLY : AD, T, AIRVOL
|
|
USE DAO_MOD, ONLY : IS_LAND ! return true if sfc grid box is land
|
|
USE DIAG_MOD, ONLY : AD07_SOAGM
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
USE TROPOPAUSE_MOD, ONLY : ITS_IN_THE_STRAT
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTGLYX, IDTSOAG
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND44, ND07, LD07
|
|
|
|
! Local variables
|
|
INTEGER :: I, J, L
|
|
REAL*8 :: DTCHEM ! Chemistry time step [s]
|
|
REAL*8 :: XAIRM ! Air mass in grid box [kg/box]
|
|
REAL*8 :: XAIRM3 ! Air volume in grid box [m3]
|
|
REAL*8 :: XGASM ! Gas mass at grid box before uptake [kg]
|
|
REAL*8 :: XGASC ! Gas concentration at grid box before uptake [molec/cm3]
|
|
REAL*8 :: XGASMIX ! Gas mixing ratio [v/v]
|
|
|
|
REAL*8 :: XCLDR ! cloud droplet radius [cm]
|
|
REAL*8 :: XDF ! gas-phase diffusivity [cm2/s]
|
|
REAL*8 :: XMS ! Mean molecular speed [cm/s]
|
|
REAL*8 :: XKT ! phase-transfer coefficient [1/s]
|
|
REAL*8 :: XTEMP ! Temperature [K]
|
|
REAL*8 :: XDELTAC ! Potential maximum change of gas concentration due to cloud chemistry [molecules/cm3]
|
|
REAL*8 :: XUPTKMAX ! Potential maximum uptake of gas by cloud in grid box [kg]
|
|
REAL*8 :: XUPTK ! Actual uptake of gas by cloud in grid box [kg]
|
|
! XUPTK <= STT( I, J, L, IDTGLYX )
|
|
REAL*8 :: FC ! Cloud fraction by volume [unitless]
|
|
REAL*8 :: LWC ! Liquid water content [g/m3]
|
|
|
|
! Parameters
|
|
REAL*8, PARAMETER :: XCLDR_CONT = 6.d-4 ! Cloud droplet radius in continental warm clouds [cm]
|
|
REAL*8, PARAMETER :: XCLDR_MARI = 10.d-4 ! Cloud droplet radius in marine warm clouds [cm]
|
|
REAL*8, PARAMETER :: XMW = 58.d0 ! Molecular weight of glyoxal [g/mole]
|
|
REAL*8, PARAMETER :: XNAVO = 6.023d23 ! Avogadro's number
|
|
REAL*8, PARAMETER :: MINDAT = 1.d-20 ! Minimum GLYX mixing ratio to calculate cloud uptake
|
|
REAL*8, PARAMETER :: XGAMMA = 2.9d-3 ! Uptake coefficient (Assume XGAMMA = 2.9d-3 following Liggio et al., 2005)
|
|
|
|
!=================================================================
|
|
! SOAG_CLOUD
|
|
!=================================================================
|
|
|
|
! DTCHEM is the chemistry timestep in seconds
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
! Loop over tropospheric grid boxes
|
|
DO L = 1, LLTROP
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Skip stratospheric boxes
|
|
IF ( ITS_IN_THE_STRAT( I, J, L ) ) CYCLE
|
|
|
|
! initialize for safety
|
|
XUPTKMAX = 0d0
|
|
XUPTK = 0d0
|
|
|
|
! Get temperature
|
|
XTEMP = T( I, J, L )
|
|
|
|
! Get air mass [kg/box]
|
|
XAIRM = AD( I, J, L )
|
|
|
|
! Get air volumne [m3]
|
|
XAIRM3 = AIRVOL( I, J, L )
|
|
|
|
! Get gas mass at grid box [kg]
|
|
XGASM = STT( I, J, L, IDTGLYX )
|
|
|
|
! Get gas concentration at grid box [molec/cm3]
|
|
XGASC = XGASM / (XMW*1.d-3) * XNAVO / (XAIRM3*1.d6)
|
|
|
|
! GET gas mixing ratio [v/v]
|
|
XGASMIX = XGASM / XMW / ( XAIRM / 28.97d0 )
|
|
|
|
! Volume cloud fraction (Sundqvist et al 1989) [unitless]
|
|
FC = VCLDF(I,J,L)
|
|
|
|
! Liquid water content in cloudy area of grid box [g/m3]
|
|
LWC = GET_LWC( XTEMP ) * FC
|
|
|
|
!==============================================================
|
|
! If (1) there is cloud, (2) there is GLYX present, and
|
|
! (3) the T > -15 C, then compute cloud uptake
|
|
!==============================================================
|
|
IF ( ( FC > 0.d0 ) .AND.
|
|
& ( XGASMIX > MINDAT ) .AND.
|
|
& ( XTEMP > 258.0 ) ) THEN
|
|
|
|
IF ( IS_LAND(I,J) ) THEN
|
|
XCLDR = XCLDR_CONT ! Continental cloud droplet radius [m]
|
|
ELSE
|
|
XCLDR = XCLDR_MARI ! Marine cloud droplet radius [m]
|
|
ENDIF
|
|
|
|
!---------------------------------------
|
|
! Gas phase diffusivity [cm2/s] [Lim et al., 2005 Eq. (4)]
|
|
!---------------------------------------
|
|
XDF = 1.9d0 * (XMW**(-0.667))
|
|
|
|
!---------------------------------------
|
|
! Mean molecular speed [cm/s] [Lim et al., 2005 Eq. (5)]
|
|
! XMS = SQRT( ( 8 * Boltzmann const * Temperature * N_Avogadro ) /
|
|
! ( pi * molecular weight [g/mole] ) )
|
|
! = SQRT( 2.117d8 * Temperature / molecular weight )
|
|
!---------------------------------------
|
|
XMS = SQRT( 2.117d8 * XTEMP / XMW )
|
|
|
|
!---------------------------------------
|
|
! Phase transfer coeff [1/s] [Lim et al., 2005 Eq. (3)]
|
|
! XGAMMA = ALPHA, XGAMMA = 2.9d-3 following Liggio et al., 2005
|
|
!---------------------------------------
|
|
XKT = 1.d0 / ( ( XCLDR * XCLDR / 3.d0 / XDF ) +
|
|
& ( 4.d0 * XCLDR / 3.d0 / XMS / XGAMMA ) )
|
|
|
|
!---------------------------------------
|
|
! Maximum potential change in concentration [molecules/cm3] [Lim et al., 2005 Eq. (1)]
|
|
!---------------------------------------
|
|
XDELTAC = LWC * XKT * XGASC * DTCHEM
|
|
|
|
!---------------------------------------
|
|
! Maximum potential uptake of gas mass [kg/box]
|
|
!---------------------------------------
|
|
XUPTKMAX = XDELTAC * 1.d6 / XNAVO * XMW * 1.d-3 * XAIRM3
|
|
|
|
!---------------------------------------
|
|
! However, the mass of gas being absorbed by aerosol
|
|
! cannot exceed the original amount of gas XGASM
|
|
!---------------------------------------
|
|
XUPTK = MIN( XUPTKMAX, XGASM )
|
|
|
|
! Update GLYX in the STT array
|
|
STT( I, J, L, IDTGLYX ) = STT( I, J, L, IDTGLYX ) -
|
|
& XUPTK
|
|
|
|
! Update SOAG in the STT array
|
|
STT( I, J, L, IDTSOAG ) = STT( I, J, L, IDTSOAG ) +
|
|
& XUPTK
|
|
|
|
!==============================================================
|
|
! ND07 diagnostic: SOAG from GLYX in cloud [kg/timestep]
|
|
!==============================================================
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_SOAGM(I,J,L,3) = AD07_SOAGM(I,J,L,3) + XUPTK
|
|
ENDIF
|
|
|
|
|
|
ENDIF ! End of IN CLOUD criteria
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOAG_CLOUD
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE SOAM_CLOUD
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine SOAM_CLOUD produces SOAM from MGLY during a cloud event.
|
|
! Mimics the SO2 -> SO4 process from 'sulfate_mod.f'. (tmf, 2/26/07)
|
|
!
|
|
! Procedure:
|
|
! ============================================================================
|
|
! (1 )
|
|
!
|
|
! NOTES:
|
|
! (1 ) SOAM (SOA product of MGLY is produced at existing hydrophilic aerosol
|
|
! surface. (tmf, 2/26/07)
|
|
! (2 ) Assume typical marine and continental cloud droplet size (tmf, 2/26/07)
|
|
!******************************************************************************
|
|
!
|
|
! Reference to diagnostic arrays
|
|
USE DAO_MOD, ONLY : AD, T, AIRVOL
|
|
USE DAO_MOD, ONLY : IS_LAND ! return true if sfc grid box is land
|
|
USE DIAG_MOD, ONLY : AD07_SOAGM
|
|
USE TIME_MOD, ONLY : GET_TS_CHEM
|
|
USE TROPOPAUSE_MOD, ONLY : ITS_IN_THE_STRAT
|
|
USE TRACER_MOD, ONLY : STT
|
|
USE TRACERID_MOD, ONLY : IDTMGLY, IDTSOAM
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
# include "CMN_DIAG" ! ND44, ND07, LD07
|
|
|
|
! Local variables
|
|
INTEGER :: I, J, L
|
|
REAL*8 :: DTCHEM ! Chemistry time step [s]
|
|
REAL*8 :: XAIRM ! Air mass in grid box [kg/box]
|
|
REAL*8 :: XAIRM3 ! Air volume in grid box [m3]
|
|
REAL*8 :: XGASM ! Gas mass at grid box before uptake [kg]
|
|
REAL*8 :: XGASC ! Gas concentration at grid box before uptake [molec/cm3]
|
|
REAL*8 :: XGASMIX ! Gas mixing ratio [v/v]
|
|
|
|
REAL*8 :: XCLDR ! cloud droplet radius [cm]
|
|
REAL*8 :: XDF ! gas-phase diffusivity [cm2/s]
|
|
REAL*8 :: XMS ! Mean molecular speed [cm/s]
|
|
REAL*8 :: XKT ! phase-transfer coefficient [1/s]
|
|
REAL*8 :: XTEMP ! Temperature [K]
|
|
REAL*8 :: XDELTAC ! Potential maximum change of gas concentration due to cloud chemistry [molecules/cm3]
|
|
REAL*8 :: XUPTKMAX ! Potential maximum uptake of gas by cloud in grid box [kg]
|
|
REAL*8 :: XUPTK ! Actual uptake of gas by cloud in grid box [kg]
|
|
! XUPTK <= STT( I, J, L, IDTGLYX )
|
|
REAL*8 :: FC ! Cloud fraction by volume [unitless]
|
|
REAL*8 :: LWC ! Liquid water content [g/m3]
|
|
|
|
! Parameters
|
|
REAL*8, PARAMETER :: XCLDR_CONT = 6.d-4 ! Cloud droplet radius in continental warm clouds [cm]
|
|
REAL*8, PARAMETER :: XCLDR_MARI = 10.d-4 ! Cloud droplet radius in marine warm clouds [cm]
|
|
REAL*8, PARAMETER :: XMW = 72.d0 ! Molecular weight of methylglyoxal [g/mole]
|
|
REAL*8, PARAMETER :: XNAVO = 6.023d23 ! Avogadro's number
|
|
REAL*8, PARAMETER :: MINDAT = 1.d-20 ! Minimum GLYX mixing ratio to calculate cloud uptake
|
|
REAL*8, PARAMETER :: XGAMMA = 2.9d-3 ! Uptake coefficient (Assume XGAMMA = 2.9d-3 following Liggio et al., 2005)
|
|
|
|
!=================================================================
|
|
! SOAG_CLOUD
|
|
!=================================================================
|
|
|
|
! DTCHEM is the chemistry timestep in seconds
|
|
DTCHEM = GET_TS_CHEM() * 60d0
|
|
|
|
! Loop over tropospheric grid boxes
|
|
DO L = 1, LLTROP
|
|
DO J = 1, JJPAR
|
|
DO I = 1, IIPAR
|
|
|
|
! Skip stratospheric boxes
|
|
IF ( ITS_IN_THE_STRAT( I, J, L ) ) CYCLE
|
|
|
|
! initialize for safety
|
|
XUPTKMAX = 0d0
|
|
XUPTK = 0d0
|
|
|
|
! Get temperature
|
|
XTEMP = T( I, J, L )
|
|
|
|
! Get air mass [kg/box]
|
|
XAIRM = AD( I, J, L )
|
|
|
|
! Get air volumne [m3]
|
|
XAIRM3 = AIRVOL( I, J, L )
|
|
|
|
! Get gas mass at grid box [kg]
|
|
XGASM = STT( I, J, L, IDTMGLY )
|
|
|
|
! Get gas concentration at grid box [molec/cm3]
|
|
XGASC = XGASM / (XMW*1.d-3) * XNAVO / (XAIRM3*1.d6)
|
|
|
|
! GET gas mixing ratio [v/v]
|
|
XGASMIX = XGASM / XMW / ( XAIRM / 28.97d0 )
|
|
|
|
! Volume cloud fraction (Sundqvist et al 1989) [unitless]
|
|
FC = VCLDF(I,J,L)
|
|
|
|
! Liquid water content in cloudy area of grid box [g/m3]
|
|
LWC = GET_LWC( XTEMP ) * FC
|
|
|
|
!==============================================================
|
|
! If (1) there is cloud, (2) there is MGLY present, and
|
|
! (3) the T > -15 C, then compute cloud uptake
|
|
!==============================================================
|
|
IF ( ( FC > 0.d0 ) .AND.
|
|
& ( XGASMIX > MINDAT ) .AND.
|
|
& ( XTEMP > 258.0 ) ) THEN
|
|
|
|
IF ( IS_LAND(I,J) ) THEN
|
|
XCLDR = XCLDR_CONT ! Continental cloud droplet radius [m]
|
|
ELSE
|
|
XCLDR = XCLDR_MARI ! Marine cloud droplet radius [m]
|
|
ENDIF
|
|
|
|
!---------------------------------------
|
|
! Gas phase diffusivity [cm2/s] [Lim et al., 2005 Eq. (4)]
|
|
!---------------------------------------
|
|
XDF = 1.9d0 * (XMW**(-0.667))
|
|
|
|
!---------------------------------------
|
|
! Mean molecular speed [cm/s] [Lim et al., 2005 Eq. (5)]
|
|
! XMS = SQRT( ( 8 * Boltzmann const * Temperature * N_Avogadro ) /
|
|
! ( pi * molecular weight [g/mole] ) )
|
|
! = SQRT( 2.117d8 * Temperature / molecular weight )
|
|
!---------------------------------------
|
|
XMS = SQRT( 2.117d8 * XTEMP / XMW )
|
|
|
|
!---------------------------------------
|
|
! Phase transfer coeff [1/s] [Lim et al., 2005 Eq. (3)]
|
|
! XGAMMA = ALPHA, XGAMMA = 2.9d-3 following Liggio et al., 2005
|
|
!---------------------------------------
|
|
XKT = 1.d0 / ( ( XCLDR * XCLDR / 3.d0 / XDF ) +
|
|
& ( 4.d0 * XCLDR / 3.d0 / XMS / XGAMMA ) )
|
|
|
|
!---------------------------------------
|
|
! Maximum potential change in concentration [molecules/cm3] [Lim et al., 2005 Eq. (1)]
|
|
!---------------------------------------
|
|
XDELTAC = LWC * XKT * XGASC * DTCHEM
|
|
|
|
!---------------------------------------
|
|
! Maximum potential uptake of gas mass [kg/box]
|
|
!---------------------------------------
|
|
XUPTKMAX = XDELTAC * 1.d6 / XNAVO * XMW * 1.d-3 * XAIRM3
|
|
|
|
!---------------------------------------
|
|
! However, the mass of gas being absorbed by aerosol
|
|
! cannot exceed the original amount of gas XGASM
|
|
!---------------------------------------
|
|
XUPTK = MIN( XUPTKMAX, XGASM )
|
|
|
|
! Update MGLY in the STT array
|
|
STT( I, J, L, IDTMGLY ) = STT( I, J, L, IDTMGLY ) -
|
|
& XUPTK
|
|
|
|
! Update SOAM in the STT array
|
|
STT( I, J, L, IDTSOAM ) = STT( I, J, L, IDTSOAM ) +
|
|
& XUPTK
|
|
|
|
!==============================================================
|
|
! ND07 diagnostic: SOAM from MGLY in cloud [kg/timestep]
|
|
!==============================================================
|
|
IF ( ND07 > 0 .and. L <= LD07 ) THEN
|
|
AD07_SOAGM(I,J,L,4) = AD07_SOAGM(I,J,L,4) + XUPTK
|
|
ENDIF
|
|
|
|
|
|
ENDIF ! End of IN CLOUD criteria
|
|
|
|
ENDDO
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE SOAM_CLOUD
|
|
|
|
! <<<<<
|
|
!------------------------------------------------------------------------------
|
|
|
|
|
|
SUBROUTINE WRITE_GPROD_APROD( YYYYMMDD, HHMMSS, TAU )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine WRITE_GPROD_APROD writes the SOA quantities GPROD and APROD to
|
|
! disk at the start of a new diagnostic interval. (tmf, havala, bmy, 2/6/07)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) YYYYMMDD (INTEGER) : YYYY/MM/DD value at which to write file
|
|
! (2 ) HHMMSS (INTEGER) : hh:mm:ss value at which to write file
|
|
! (3 ) TAU (REAL*8 ) : TAU value corresponding to YYYYMMDD, HHMMSS
|
|
!
|
|
! NOTES:
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE BPCH2_MOD, ONLY : BPCH2, GET_MODELNAME
|
|
USE BPCH2_MOD, ONLY : GET_HALFPOLAR, OPEN_BPCH2_FOR_WRITE
|
|
USE FILE_MOD, ONLY : IU_FILE
|
|
USE GRID_MOD, ONLY : GET_XOFFSET, GET_YOFFSET
|
|
USE TIME_MOD, ONLY : EXPAND_DATE
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: YYYYMMDD, HHMMSS
|
|
REAL*8, INTENT(IN) :: TAU
|
|
|
|
! Local variables
|
|
INTEGER :: HALFPOLAR
|
|
INTEGER, PARAMETER :: CENTER180 = 1
|
|
INTEGER :: I0, IPR, J0, JHC, N
|
|
REAL*4 :: LONRES, LATRES
|
|
REAL*4 :: ARRAY(IIPAR,JJPAR,LLPAR)
|
|
CHARACTER(LEN=20) :: MODELNAME
|
|
CHARACTER(LEN=40) :: CATEGORY
|
|
CHARACTER(LEN=40) :: UNIT
|
|
CHARACTER(LEN=40) :: RESERVED = ''
|
|
CHARACTER(LEN=80) :: TITLE
|
|
CHARACTER(LEN=255) :: FILENAME
|
|
|
|
!=================================================================
|
|
! WRITE_GPROD_APROD begins here
|
|
!=================================================================
|
|
|
|
! Define variables for binary punch file
|
|
FILENAME = 'restart_gprod_aprod.YYYYMMDDhh'
|
|
TITLE = 'GEOS-Chem SOA restart file: GPROD & APROD'
|
|
UNIT = 'kg/kg'
|
|
LONRES = DISIZE
|
|
LATRES = DJSIZE
|
|
MODELNAME = GET_MODELNAME()
|
|
HALFPOLAR = GET_HALFPOLAR()
|
|
I0 = GET_XOFFSET( GLOBAL=.TRUE. )
|
|
J0 = GET_YOFFSET( GLOBAL=.TRUE. )
|
|
|
|
! Replace date & time tokens in FILENAME
|
|
CALL EXPAND_DATE( FILENAME, YYYYMMDD, HHMMSS )
|
|
|
|
! Open restart file for output
|
|
CALL OPEN_BPCH2_FOR_WRITE( IU_FILE, FILENAME, TITLE )
|
|
|
|
! Loop over VOC classes and products
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
|
|
! Tracer number
|
|
N = ( JHC - 1 ) * NPROD + IPR
|
|
|
|
!----------------------
|
|
! Write GPROD to file
|
|
!----------------------
|
|
|
|
! Initialize
|
|
CATEGORY = 'IJ-GPROD'
|
|
ARRAY = GPROD(:,:,:,IPR,JHC)
|
|
|
|
! Write to disk
|
|
CALL BPCH2( IU_FILE, MODELNAME, LONRES, LATRES,
|
|
& HALFPOLAR, CENTER180, CATEGORY, N,
|
|
& UNIT, TAU, TAU, RESERVED,
|
|
& IIPAR, JJPAR, LLPAR, I0+1,
|
|
& J0+1, 1, ARRAY )
|
|
|
|
!----------------------
|
|
! Write APROD to file
|
|
!----------------------
|
|
|
|
! Initialize
|
|
CATEGORY = 'IJ-APROD'
|
|
ARRAY = APROD(:,:,:,IPR,JHC)
|
|
|
|
! Write to disk
|
|
CALL BPCH2( IU_FILE, MODELNAME, LONRES, LATRES,
|
|
& HALFPOLAR, CENTER180, CATEGORY, N,
|
|
& UNIT, TAU, TAU, RESERVED,
|
|
& IIPAR, JJPAR, LLPAR, I0+1,
|
|
& J0+1, 1, ARRAY )
|
|
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! Close file
|
|
CLOSE( IU_FILE )
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE WRITE_GPROD_APROD
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE READ_GPROD_APROD( YYYYMMDD, HHMMSS, TAU )
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine READ_GPROD_APROD writes the SOA quantities GPROD and APROD from
|
|
! disk at the start of a new diagnostic interval. (tmf, havala, bmy, 2/6/07)
|
|
!
|
|
! Arguments as Input:
|
|
! ============================================================================
|
|
! (1 ) YYYYMMDD (INTEGER) : YYYY/MM/DD value at which to write file
|
|
! (2 ) HHMMSS (INTEGER) : hh:mm:ss value at which to write file
|
|
! (3 ) TAU (REAL*8 ) : TAU value corresponding to YYYYMMDD, HHMMSS
|
|
!
|
|
! NOTES:
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE BPCH2_MOD, ONLY : READ_BPCH2
|
|
USE FILE_MOD, ONLY : IU_FILE
|
|
USE TIME_MOD, ONLY : EXPAND_DATE
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Arguments
|
|
INTEGER, INTENT(IN) :: YYYYMMDD, HHMMSS
|
|
REAL*8, INTENT(IN) :: TAU
|
|
|
|
! Local variables
|
|
INTEGER :: IPR, JHC, N
|
|
REAL*4 :: ARRAY(IIPAR,JJPAR,LLPAR)
|
|
CHARACTER(LEN=255) :: FILENAME
|
|
|
|
!=================================================================
|
|
! READ_GPROD_APROD begins here!
|
|
!=================================================================
|
|
|
|
! File name
|
|
FILENAME = 'restart_gprod_aprod.YYYYMMDDhh'
|
|
|
|
! Replace date & time tokens in FILENAME
|
|
CALL EXPAND_DATE( FILENAME, YYYYMMDD, HHMMSS )
|
|
|
|
! Loop over VOC classes and products
|
|
DO JHC = 1, MHC
|
|
DO IPR = 1, NPROD
|
|
|
|
! Tracer number
|
|
N = ( JHC - 1 ) * NPROD + IPR
|
|
|
|
!-----------------------
|
|
! Read GPROD from file
|
|
!-----------------------
|
|
|
|
! Read data
|
|
CALL READ_BPCH2( FILENAME, 'IJ-GPROD', N,
|
|
& TAU, IIPAR, JJPAR,
|
|
& LLPAR, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8
|
|
GPROD(:,:,:,IPR,JHC) = ARRAY
|
|
|
|
!-----------------------
|
|
! Read APROD from file
|
|
!-----------------------
|
|
|
|
! Read data
|
|
CALL READ_BPCH2( FILENAME, 'IJ-APROD', N,
|
|
& TAU, IIPAR, JJPAR,
|
|
& LLPAR, ARRAY, QUIET=.TRUE. )
|
|
|
|
! Cast to REAL*8
|
|
APROD(:,:,:,IPR,JHC) = ARRAY
|
|
|
|
ENDDO
|
|
ENDDO
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE READ_GPROD_APROD
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE INIT_CARBON
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine INIT_CARBON initializes all module arrays.
|
|
! (rjp, bmy, 4/1/04, 11/6/08)
|
|
!
|
|
! NOTES:
|
|
! (1 ) Also added arrays for secondary organic aerosols (rjp, bmy, 7/8/04)
|
|
! (2 ) Remove reference to CMN, it's obsolete (bmy, 7/20/04)
|
|
! (3 ) Now reference LSOA from "logical_mod.f" not CMN_SETUP. Now call
|
|
! GET_BOUNDING_BOX from "grid_mod.f" to compute the indices I1_NA,
|
|
! I2_NA, J1_NA, J2_NA which define the N. America region. (bmy, 12/1/04)
|
|
! (4 ) Now call READ_GPROD_APROD to read GPROD & APROD from disk.
|
|
! (tmf, havala, bmy, 2/6/07)
|
|
! (5 ) Now set I1_NA, I2_NA, J1_NA, J2_NA appropriately for both 1 x 1 and
|
|
! 0.5 x 0.666 nested grids (yxw, dan, bmy, 11/6/08)
|
|
!******************************************************************************
|
|
!
|
|
! References to F90 modules
|
|
USE ERROR_MOD, ONLY : ALLOC_ERR, ERROR_STOP
|
|
USE GRID_MOD, ONLY : GET_BOUNDING_BOX
|
|
USE LOGICAL_MOD, ONLY : LCHEM, LSOA
|
|
USE TIME_MOD, ONLY : GET_NYMDb, GET_NHMSb, GET_TAUb
|
|
|
|
# include "CMN_SIZE" ! Size parameters
|
|
|
|
! Local variables
|
|
LOGICAL, SAVE :: IS_INIT = .FALSE.
|
|
INTEGER :: AS, INDICES(4), YYYYMMDD, HHMMSS
|
|
REAL*8 :: COORDS(4), TAU
|
|
|
|
!=================================================================
|
|
! INIT_CARBON begins here!
|
|
!=================================================================
|
|
|
|
! Return if we already allocated arrays
|
|
IF ( IS_INIT ) RETURN
|
|
|
|
ALLOCATE( ANTH_BLKC( IIPAR, JJPAR, 2 ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'ANTH_BLKC' )
|
|
ANTH_BLKC = 0d0
|
|
|
|
ALLOCATE( ANTH_ORGC( IIPAR, JJPAR, 2 ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'ANTH_ORGC' )
|
|
ANTH_ORGC = 0d0
|
|
|
|
ALLOCATE( BIOB_BLKC( IIPAR, JJPAR, 2 ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOB_BLKC' )
|
|
BIOB_BLKC = 0d0
|
|
|
|
ALLOCATE( BIOB_ORGC( IIPAR, JJPAR, 2 ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOB_ORGC' )
|
|
BIOB_ORGC = 0d0
|
|
|
|
ALLOCATE( BIOF_BLKC( IIPAR, JJPAR, 2 ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOF_BLKC' )
|
|
BIOF_BLKC = 0d0
|
|
|
|
ALLOCATE( BIOF_ORGC( IIPAR, JJPAR, 2 ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOF_ORGC' )
|
|
BIOF_ORGC = 0d0
|
|
|
|
ALLOCATE( TERP_ORGC( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'TERP_ORGC' )
|
|
TERP_ORGC = 0d0
|
|
|
|
ALLOCATE( BCCONV( IIPAR, JJPAR, LLPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BCCONV' )
|
|
BCCONV = 0d0
|
|
|
|
ALLOCATE( OCCONV( IIPAR, JJPAR, LLPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'OCCONV' )
|
|
OCCONV = 0d0
|
|
|
|
!=================================================================
|
|
! These only have to be allocated if we are
|
|
! reading in monthly/8-day/3-hr mean
|
|
!=================================================================
|
|
IF ( .not. USE_BOND_BIOBURN ) THEN
|
|
|
|
ALLOCATE( EF_BLKC( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'EF_BLKC' )
|
|
EF_BLKC = 0d0
|
|
|
|
ALLOCATE( EF_ORGC( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'EF_ORGC' )
|
|
EF_ORGC = 0d0
|
|
|
|
ENDIF
|
|
|
|
!=================================================================
|
|
! SOA arrays only have to be allocated if LSOA = T
|
|
!=================================================================
|
|
IF ( LSOA ) THEN
|
|
|
|
ALLOCATE( BIOG_ALPH( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOG_ALPH' )
|
|
BIOG_ALPH = 0d0
|
|
|
|
ALLOCATE( BIOG_LIMO( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOG_LIMO' )
|
|
BIOG_LIMO = 0d0
|
|
|
|
ALLOCATE( BIOG_ALCO( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOG_ALCO' )
|
|
BIOG_ALCO = 0d0
|
|
|
|
ALLOCATE( BIOG_TERP( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOG_TERP' )
|
|
BIOG_TERP = 0d0
|
|
|
|
ALLOCATE( BIOG_SESQ( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'BIOG_SESQ' )
|
|
BIOG_SESQ = 0d0
|
|
|
|
ALLOCATE( DIUR_ORVC( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'DIUR_ORVC' )
|
|
DIUR_ORVC = 0d0
|
|
|
|
ALLOCATE( GEIA_ORVC( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'GEIA_ORVC' )
|
|
GEIA_ORVC = 0d0
|
|
|
|
ALLOCATE( TCOSZ( IIPAR, JJPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'TCOSZ' )
|
|
TCOSZ = 0d0
|
|
|
|
ALLOCATE( ORVC_TERP( IIPAR, JJPAR, LLPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'ORVC_TERP' )
|
|
ORVC_TERP = 0d0
|
|
|
|
ALLOCATE( ORVC_SESQ( IIPAR, JJPAR, LLPAR ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'ORVC_SESQ' )
|
|
ORVC_SESQ = 0d0
|
|
|
|
ALLOCATE( VCLDF( IIPAR, JJPAR, LLTROP ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'VCLDF' )
|
|
VCLDF = 0d0
|
|
|
|
ALLOCATE( GPROD( IIPAR, JJPAR, LLPAR, NPROD, MHC ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'GPROD' )
|
|
GPROD = 0D0
|
|
|
|
ALLOCATE( APROD( IIPAR, JJPAR, LLPAR, NPROD, MHC ), STAT=AS )
|
|
IF ( AS /= 0 ) CALL ALLOC_ERR( 'APROD' )
|
|
APROD = 0D0
|
|
|
|
!--------------------------------------------------------------
|
|
! Read GPROD and APROD from disk from the last simulation
|
|
! NOTE: do this here after GPROD, APROD are allocated!
|
|
!--------------------------------------------------------------
|
|
|
|
IF ( LCHEM ) THEN
|
|
|
|
! Get time values at start of the run
|
|
YYYYMMDD = GET_NYMDb()
|
|
HHMMSS = GET_NHMSb()
|
|
TAU = GET_TAUb()
|
|
|
|
! Read GPROD, APROD from restart file
|
|
CALL READ_GPROD_APROD( YYYYMMDD, HHMMSS, TAU )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
!=================================================================
|
|
! Compute indices which define the N. America region so that we
|
|
! can overwrite T. Bond emissions w/ Cooke/RJP emissions
|
|
!=================================================================
|
|
|
|
#if defined( NESTED_NA )
|
|
! For 1x1 N. America nested grid: set indices to grid extent
|
|
I1_NA = 1
|
|
J1_NA = 1
|
|
I2_NA = IIPAR
|
|
J2_NA = JJPAR
|
|
|
|
#elif defined( NESTED_CH )
|
|
! For 1x1 China nested grid: we don't cover N. America region
|
|
! Setting these to zero will turn off Cooke/RJP emissions
|
|
I1_NA = 0
|
|
J1_NA = 0
|
|
I2_NA = 0
|
|
J2_NA = 0
|
|
|
|
#else
|
|
|
|
! Definition of the N. American bounding box
|
|
! with LL corner (10N,165W) and UR corner (90N,40W)
|
|
! Lon_LL Lat_LL Lon_UR Lat_UR
|
|
COORDS = (/ -165d0, 10d0, -40d0, 90d0 /)
|
|
|
|
! Get the indices corresponding to the lon/lat values in COORDS
|
|
CALL GET_BOUNDING_BOX( COORDS, INDICES )
|
|
|
|
! Copy values from INDEX array to scalars
|
|
I1_NA = INDICES(1)
|
|
J1_NA = INDICES(2)
|
|
I2_NA = INDICES(3)
|
|
J2_NA = INDICES(4)
|
|
|
|
#endif
|
|
|
|
! Reset IS_INIT before exiting
|
|
IS_INIT = .TRUE.
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE INIT_CARBON
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
SUBROUTINE CLEANUP_CARBON
|
|
!
|
|
!******************************************************************************
|
|
! Subroutine CLEANUP_CARBON deallocates all module arrays
|
|
! (rjp, bmy, 4/1/04, 7/8/04)
|
|
!
|
|
! NOTES:
|
|
! (1 ) Now deallocate arrays for secondary organic aerosols (rjp, bmy, 7/8/04)
|
|
!******************************************************************************
|
|
!
|
|
!=================================================================
|
|
! CLEANUP_CARBON begins here!
|
|
!=================================================================
|
|
IF ( ALLOCATED( ANTH_BLKC ) ) DEALLOCATE( ANTH_BLKC )
|
|
IF ( ALLOCATED( ANTH_ORGC ) ) DEALLOCATE( ANTH_ORGC )
|
|
IF ( ALLOCATED( BIOB_BLKC ) ) DEALLOCATE( BIOB_BLKC )
|
|
IF ( ALLOCATED( BIOB_ORGC ) ) DEALLOCATE( BIOB_ORGC )
|
|
IF ( ALLOCATED( BIOF_BLKC ) ) DEALLOCATE( BIOF_BLKC )
|
|
IF ( ALLOCATED( BIOF_ORGC ) ) DEALLOCATE( BIOF_ORGC )
|
|
IF ( ALLOCATED( TERP_ORGC ) ) DEALLOCATE( TERP_ORGC )
|
|
IF ( ALLOCATED( BCCONV ) ) DEALLOCATE( BCCONV )
|
|
IF ( ALLOCATED( OCCONV ) ) DEALLOCATE( OCCONV )
|
|
IF ( ALLOCATED( EF_BLKC ) ) DEALLOCATE( EF_BLKC )
|
|
IF ( ALLOCATED( EF_ORGC ) ) DEALLOCATE( EF_ORGC )
|
|
IF ( ALLOCATED( BIOG_ALPH ) ) DEALLOCATE( BIOG_ALPH )
|
|
IF ( ALLOCATED( BIOG_LIMO ) ) DEALLOCATE( BIOG_LIMO )
|
|
IF ( ALLOCATED( BIOG_ALCO ) ) DEALLOCATE( BIOG_ALCO )
|
|
IF ( ALLOCATED( BIOG_TERP ) ) DEALLOCATE( BIOG_TERP )
|
|
IF ( ALLOCATED( BIOG_SESQ ) ) DEALLOCATE( BIOG_SESQ )
|
|
IF ( ALLOCATED( DIUR_ORVC ) ) DEALLOCATE( DIUR_ORVC )
|
|
IF ( ALLOCATED( GEIA_ORVC ) ) DEALLOCATE( GEIA_ORVC )
|
|
IF ( ALLOCATED( TCOSZ ) ) DEALLOCATE( TCOSZ )
|
|
IF ( ALLOCATED( GPROD ) ) DEALLOCATE( GPROD )
|
|
IF ( ALLOCATED( APROD ) ) DEALLOCATE( APROD )
|
|
IF ( ALLOCATED( ORVC_TERP ) ) DEALLOCATE( ORVC_TERP )
|
|
IF ( ALLOCATED( ORVC_SESQ ) ) DEALLOCATE( ORVC_SESQ )
|
|
|
|
IF ( ALLOCATED( VCLDF ) ) DEALLOCATE( VCLDF )
|
|
|
|
! Return to calling program
|
|
END SUBROUTINE CLEANUP_CARBON
|
|
|
|
!------------------------------------------------------------------------------
|
|
|
|
! End of module
|
|
END MODULE CARBON_MOD
|