├── .gitignore ├── fortran_template ├── edits_v9_01_01.tar.gz ├── README ├── Makefile ├── findex.F ├── UTILIO_DEFN.F ├── GEOS_DOMAIN.INC ├── chem_map.F ├── vinterp_prof.F ├── run.sh ├── CMAQ_DATA.F ├── lat_lon.F ├── lr_interp.F ├── vinterp.F ├── defaults.F ├── prof_data.F ├── BPCH2_DATA.F └── repair_bcs.F ├── __init__.py ├── testdata ├── Species_Table_TR_0.nml ├── TR_SPC.EXT ├── NR_cb05tucl_ae6_aq.nml ├── NR_SPC.EXT ├── GC_cb05tucl_ae6_aq.nml ├── AE_SPC.EXT ├── AE_cb05tucl_ae6_aq.nml └── GC_SPC.EXT ├── tracerinfo.py ├── smv2.py ├── MANUSCRIPT_README.md ├── mapping ├── cb05cl_ae6_aq.csv ├── saprc07t.csv ├── saprc07tc.csv └── saprc07tb.csv ├── profile.py ├── map.py ├── mech.py ├── __main__.py ├── both.py ├── README.md ├── v9-01-01.patch ├── plot.py ├── overwrite_stratosphere.py └── MANUSCRIPT_CODE.diff /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.o 3 | mechmap_archive/* -------------------------------------------------------------------------------- /fortran_template/edits_v9_01_01.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barronh/geos2cmaq/HEAD/fortran_template/edits_v9_01_01.tar.gz -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = 'both map mech smv2 tracerinfo'.split() 2 | from . import both 3 | from . import map 4 | from . import mech 5 | from . import smv2 6 | from . import tracerinfo 7 | -------------------------------------------------------------------------------- /testdata/Species_Table_TR_0.nml: -------------------------------------------------------------------------------- 1 | ! RCS file, release, date & time of last delta, author, state, [and locker] 2 | ! $Header: /project/work/rep/arc/mechs/MECHS/src/trac0/Species_Table_TR_0.nml,v 1.1 2010/07/26 11:46:56 yoj Exp $ 3 | 4 | &TR_nml 5 | 6 | n_surr1 = 3, 7 | n_surr2 = 2, 8 | n_ctrl = 5, 9 | 10 | TYPE_HEADER =, 11 | TYPE_MATRIX = 12 | / 13 | -------------------------------------------------------------------------------- /fortran_template/README: -------------------------------------------------------------------------------- 1 | All files should be considered static except for 2 | MAPPING.MECH - Definition of chemical mechanism 3 | MAPPING.TRACER - Definition of GEOS-Chem tracer contents 4 | MAPPING.CSPEC - Definition of GEOS-Chem CSPEC contents 5 | MAPPING.PROFILE - Definition of PROFILE contents 6 | MAPPING.MAP - Definition of MAPPING from tracer, cspec and profile 7 | GEOS_DOMAIN.INC - Spatial definitions of GEOS-Chem run 8 | 9 | You can create new versions of the MAPPING files using geos2cmaq, or you can modify them directly. 10 | -------------------------------------------------------------------------------- /tracerinfo.py: -------------------------------------------------------------------------------- 1 | def get_tracers(tracerinfo): 2 | tracer_data = dict([(int(l[52:61].strip()), dict(NAME = l[:8].strip(), FULLNAME = l[9:39].strip(), MOLWT = float(l[39:49]), C = int(l[49:52]), TRACER = int(l[52:61]), SCALE = float(l[61:71]), UNIT = l[72:].strip())) for l in open(tracerinfo).readlines() if l[0] not in ('#', ' ')]) 3 | tracer_data = dict([(k, d) for k, d in tracer_data.items() if k < 1000 and 'Pure' not in d['FULLNAME']]) 4 | return tracer_data 5 | 6 | if __name__ == '__main__': 7 | tracers = get_tracers('testdata/tracerinfo.dat') 8 | 9 | -------------------------------------------------------------------------------- /testdata/TR_SPC.EXT: -------------------------------------------------------------------------------- 1 | C RCS file, release, date & time of last delta, author, state, [and locker] 2 | C $Header: /project/work/rep/include/ICL/src/mech/trac0/TR_SPC.EXT,v 1.1.1.1 1999/04/23 11:16:23 yoj Exp $ 3 | C------------------------------------------------------ 4 | C This file is generated by the Models-3 framework. 5 | C------------------------------------------------------ 6 | 7 | INTEGER N_TR_SPC 8 | PARAMETER (N_TR_SPC = 0) 9 | INTEGER N_TR_SPCD 10 | PARAMETER (N_TR_SPCD = 1) 11 | CHARACTER*16 TR_SPC(N_TR_SPCD) 12 | REAL TR_MOLWT(N_TR_SPCD) 13 | 14 | -------------------------------------------------------------------------------- /smv2.py: -------------------------------------------------------------------------------- 1 | import re 2 | from io import StringIO 3 | import numpy as np 4 | 5 | def get_cspec(smvpath): 6 | text = open(smvpath, 'r').read() 7 | reo = re.compile('(?:NBR NAME\s+MW BKGAS\(VMRAT\))(?P.*)(?:INACTIVE SPECIES FOR THIS RUN ARE:)(?P.*)(?:THE DEAD SPECIES FOR THIS RUN ARE:)(?P.*?)(?:=====)', re.M | re.DOTALL) 8 | gv = reo.search(text).groupdict() 9 | active = [v.strip().split()[1] for v in gv['active'].strip().split('\n')] 10 | inactive = gv['inactive'].replace('\n', ' ').split() 11 | dead = gv['dead'].replace('\n', ' ').split() 12 | all = active + inactive #+ dead 13 | return all 14 | 15 | if __name__ == '__main__': 16 | specs = get_cspec('/project/inf15w/bar/geos-chem/baseict/smv2.log') 17 | -------------------------------------------------------------------------------- /testdata/NR_cb05tucl_ae6_aq.nml: -------------------------------------------------------------------------------- 1 | ! RCS file, release, date & time of last delta, author, state, [and locker] 2 | ! $Header: /project/work/rep/arc/mechs/MECHS/src/cb05tucl_ae6_aq/NR_cb05tucl_ae6_aq.nml,v 1.1.1.1 2011/04/06 16:57:21 sjr Exp $ 3 | 4 | &NR_nml 5 | 6 | n_surr1 = 4, 7 | n_surr2 = 2, 8 | n_ctrl = 4, 9 | 10 | TYPE_HEADER = 11 | 'SPC:MOLWT:EMIS_SUR:EMIS_FAC:DEPV_SUR:DEPV_FAC:ICBC_SUR:ICBC_FAC:SCAV_SUR:SCAV_FAC:N2AE_SUR:N2AQ_SUR:TRNS:DDEP:WDEP:CONC', 12 | TYPE_MATRIX = 13 | 'NH3: 17.0:NH3:1.0:VD_NH3:1.0:::NH3:1.0:NH3:NH3:Yes:Yes:Yes:Yes', 14 | 'SV_ALK:150.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_ALK::Yes:::Yes', 15 | 'SV_XYL1:192.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_XYL1::Yes:::Yes', 16 | 'SV_XYL2:192.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_XYL2::Yes:::Yes', 17 | 'SV_TOL1:168.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_TOL1::Yes:::Yes', 18 | 'SV_TOL2:168.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_TOL2::Yes:::Yes', 19 | 'SV_BNZ1:144.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_BNZ1::Yes:::Yes', 20 | 'SV_BNZ2:144.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_BNZ2::Yes:::Yes', 21 | 'SV_TRP1:168.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_TRP1::Yes:::Yes', 22 | 'SV_TRP2:168.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_TRP2::Yes:::Yes', 23 | 'SV_ISO1: 96.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_ISO1::Yes:::Yes', 24 | 'SV_ISO2: 96.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_ISO2::Yes:::Yes', 25 | 'SV_SQT:378.0:::VD_ORA:1.0:::ADIPIC_ACID:1.0:SV_SQT::Yes:::Yes' 26 | / 27 | -------------------------------------------------------------------------------- /testdata/NR_SPC.EXT: -------------------------------------------------------------------------------- 1 | 2 | C RCS file, release, date & time of last delta, author, state, [and locker] 3 | C $Header: /project/work/rep/include/ICL/src/mech/cb05cl_ae5_aq/NR_SPC.EXT,v 1.2 2008/09/09 19:38:42 sjr Exp $ 4 | 5 | C what(1) key, module and SID; SCCS file; date and time of last delta: 6 | C %W% %P% %G% %U% 7 | 8 | C Mechanism Name: CB05CL_AE5_AQ 9 | 10 | INTEGER N_NR_SPC 11 | PARAMETER (N_NR_SPC = 13) 12 | INTEGER N_NR_SPCD 13 | PARAMETER (N_NR_SPCD = N_NR_SPC) 14 | CHARACTER*16 NR_SPC(N_NR_SPCD) 15 | REAL NR_MOLWT(N_NR_SPCD) 16 | 17 | DATA NR_SPC( 1), NR_MOLWT( 1) / 'NH3 ', 17.0 / 18 | DATA NR_SPC( 2), NR_MOLWT( 2) / 'SV_ALK ', 150.0 / 19 | DATA NR_SPC( 3), NR_MOLWT( 3) / 'SV_XYL1 ', 192.0 / 20 | DATA NR_SPC( 4), NR_MOLWT( 4) / 'SV_XYL2 ', 192.0 / 21 | DATA NR_SPC( 5), NR_MOLWT( 5) / 'SV_TOL1 ', 168.0 / 22 | DATA NR_SPC( 6), NR_MOLWT( 6) / 'SV_TOL2 ', 168.0 / 23 | DATA NR_SPC( 7), NR_MOLWT( 7) / 'SV_BNZ1 ', 144.0 / 24 | DATA NR_SPC( 8), NR_MOLWT( 8) / 'SV_BNZ2 ', 144.0 / 25 | DATA NR_SPC( 9), NR_MOLWT( 9) / 'SV_TRP1 ', 168.0 / 26 | DATA NR_SPC( 10), NR_MOLWT( 10) / 'SV_TRP2 ', 168.0 / 27 | DATA NR_SPC( 11), NR_MOLWT( 11) / 'SV_ISO1 ', 96.0 / 28 | DATA NR_SPC( 12), NR_MOLWT( 12) / 'SV_ISO2 ', 96.0 / 29 | DATA NR_SPC( 13), NR_MOLWT( 13) / 'SV_SQT ', 378.0 / 30 | -------------------------------------------------------------------------------- /fortran_template/Makefile: -------------------------------------------------------------------------------- 1 | MODEL = GC2CMAQ.exe 2 | 3 | #ckdesc3.o \ 4 | # List of Object files needed for linking 5 | OBJECTS = \ 6 | UTILIO_DEFN.o \ 7 | CGRID_SPCS.o \ 8 | CMAQ_DATA.o \ 9 | BPCH2_DATA.o \ 10 | prof_data.o \ 11 | geos2cmaq_semiflex.o \ 12 | chem_map.o \ 13 | findex.o \ 14 | lat_lon.o \ 15 | vinterp.o \ 16 | vinterp_prof.o \ 17 | repair_bcs.o \ 18 | lr_interp.o 19 | 20 | .SUFFIXES: .F .f 21 | 22 | help: 23 | @echo "--------------------------------------------------" 24 | @echo "GC2CMAQ requires netcdf and ioapi (with m3utilio)." 25 | @echo 26 | @echo "These libraries and associated include files must be available via default search paths, or they can be provided to the compiler via the LDFLAGS and FFLAGS environmental variables" 27 | @echo 28 | @echo "e.g., with gfortran the call is as follows:" 29 | @echo "FC=gfortran FFLAGS=\"-I/usr/local/include/ -I. -ffixed-line-length-none -fconvert=big-endian\" LD_FLAGS=\"-lioapi -lnetcdf -lnetcdff\" make all" 30 | @echo 31 | @echo "e.g., with intel the call is as follows:" 32 | @echo "FC=ifort FFLAGS=\"-I/usr/local/include/ -I. -fixed -extend_source -132 -convert big_endian -O2\" LD_FLAGS=\"-lioapi -lnetcdf -lnetcdff\" make all" 33 | @echo "--------------------------------------------------" 34 | @echo 35 | @echo 36 | 37 | all: $(MODEL) 38 | 39 | $(MODEL): $(OBJECTS) 40 | $(FC) $(OBJECTS) $(LD_FLAGS) -o $@ 41 | 42 | chem_map.o: MAPPING.MAP BPCH2_DATA.o CMAQ_DATA.o 43 | prof_map.o: MAPPING.PROFILE CMAQ_DATA.o prof_map.o 44 | BPCH2_DATA.o: MAPPING.CSPEC MAPPING.TRACER 45 | cmaq_data.o: MAPPING.MECH 46 | 47 | .f.o.F.o: 48 | $(FC) -c $(F_FLAGS) $< 49 | 50 | clean: 51 | rm -f $(OBJECTS) $(MODEL) *.mod 52 | 53 | 54 | -------------------------------------------------------------------------------- /MANUSCRIPT_README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | This software was used in Henderson et al.[1]. In that manuscript, the GEOS-Chem outputs were created using v8-03-02 and v9-01-01 code. For subsequent work, we use the ND49 option instead of modifying the code. These files are provided for posterity. 3 | 4 | # Code Specifics 5 | v8-03-02 was at the following commit with edits described in MANUSCRIPT_CODE.diff 6 | commit b27d73dc1ea51de3f9571b337408a93daf113c04 (aka tag v8-03-02-Patch-setemis) 7 | 8 | v9-01-01 was at the following commit with edits described in MANUSCRIPT_CODE.diff 9 | commit a03a26db8e453892f2f46d48f84c4a699d474432 (aka tag v9-01-01-Patch-CO2) 10 | 11 | # Example Run Scripts: 12 | ftp://data.as.essie.ufl.edu/pub/geos2cmaq/BCv8geos5_merra/work/MOD3EVAL/afd/GEOS-Chem_v8-03-02_v8-02-03CHEM_GEOS5/runarchive/GEOS-Chem.run.4-26-2012_SOA_v8-03-02_v8-2-3CHEM_BC/qscript.run 13 | 14 | # Configuration Files: 15 | ftp://data.as.essie.ufl.edu/pub/geos2cmaq/BCv8geos5_merra/work/MOD3EVAL/afd/GEOS-Chem_v8-03-02_v8-02-03CHEM_GEOS5/runarchive/GEOS-Chem.run.4-26-2012_SOA_v8-03-02_v8-2-3CHEM_BC/input.geos 16 | ftp://data.as.essie.ufl.edu/pub/geos2cmaq/BCv8geos5_merra/work/MOD3EVAL/afd/GEOS-Chem_v8-03-02_v8-02-03CHEM_GEOS5/runarchive/GEOS-Chem.run.4-26-2012_SOA_v8-03-02_v8-2-3CHEM_BC/*.dat 17 | ftp://data.as.essie.ufl.edu/pub/geos2cmaq/BCv8geos5_merra/work/MOD3EVAL/afd/GEOS-Chem_v8-03-02_v8-02-03CHEM_GEOS5/runarchive/GEOS-Chem.run.4-26-2012_SOA_v8-03-02_v8-2-3CHEM_BC/ratj.d 18 | 19 | # Restarts (including 2011-01-01): 20 | ftp://data.as.essie.ufl.edu/pub/geos2cmaq/BCv8geos5_merra/work/MOD3EVAL/afd/GEOS-Chem_v8-03-02_v8-02-03CHEM_GEOS5/restart 21 | 22 | 23 | [1]Henderson, B. H., Akhtar, F., Pye, H. O. T., Napelenok, S. L., and Hutzell, W. T.: A database and tool for boundary conditions for regional air quality modeling: description and evaluation, Geosci. Model Dev., 7, 339-360, doi:10.5194/gmd-7-339-2014, 2014. 24 | -------------------------------------------------------------------------------- /fortran_template/findex.F: -------------------------------------------------------------------------------- 1 | 2 | C*********************************************************************** 3 | C Portions of Models-3/CMAQ software were developed or based on * 4 | C information from various groups: Federal Government employees, * 5 | C contractors working on a United States Government contract, and * 6 | C non-Federal sources (including research institutions). These * 7 | C research institutions have given the Government permission to * 8 | C use, prepare derivative works, and distribute copies of their * 9 | C work in Models-3/CMAQ to the public and to permit others to do * 10 | C so. EPA therefore grants similar permissions for use of the * 11 | C Models-3/CMAQ software, but users are requested to provide copies * 12 | C of derivative works to the Government without restrictions as to * 13 | C use by others. Users are responsible for acquiring their own * 14 | C copies of commercial software associated with Models-3/CMAQ and * 15 | C for complying with vendor requirements. Software copyrights by * 16 | C the MCNC Environmental Modeling Center are used with their * 17 | C permissions subject to the above restrictions. * 18 | C*********************************************************************** 19 | 20 | C RCS file, release, date & time of last delta, author, state, [and locker] 21 | C $Header: /project/work/rep/BCON/src/driver/bcon/findex.F,v 1.3 2002/04/12 14:19:19 yoj Exp $ 22 | 23 | C what(1) key, module and SID; SCCS file; date and time of last delta: 24 | C %W% %P% %G% %U% 25 | 26 | 27 | C::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 28 | INTEGER FUNCTION FINDEX (INDX, N, NLIST) 29 | 30 | C Searches for INDX in list NLIST and returns the subscript 31 | C (1...N) at which it is found, or returns 0 when NAME not 32 | C found in NLIST 33 | 34 | IMPLICIT NONE 35 | 36 | INTEGER INDX ! index being searched for 37 | INTEGER N ! Length of array to be searched 38 | INTEGER NLIST(*) ! array to be searched 39 | 40 | INTEGER I 41 | 42 | DO I = 1, N 43 | IF ( INDX .EQ. NLIST( I ) ) THEN ! found 44 | FINDEX = I 45 | RETURN 46 | END IF 47 | END DO 48 | FINDEX = 0 ! not found 49 | RETURN 50 | 51 | END 52 | 53 | -------------------------------------------------------------------------------- /mapping/cb05cl_ae6_aq.csv: -------------------------------------------------------------------------------- 1 | MECHSPC, GEOS_EXPRESSION 2 | O3, Ox - NOx 3 | N2O5, N2O5 4 | HNO3, HNO3 5 | PNA, HNO4 6 | H2O2, H2O2 7 | NTR, R4N2 8 | FORM, CH2O 9 | ALD2, 1./2 * ALD2 10 | CO, CO 11 | MEPX, MP 12 | PAN, PAN 13 | PANX, PPN + PMN 14 | OLE, 0.5 * 1./2. * 3. * PRPE 15 | IOLE, 0.5 * 1./4. * 3. * PRPE 16 | TOL, TOLU 17 | XYL, XYLE 18 | ISPD, MACR + MVK 19 | SO2, SO2 20 | ETHA, C2H6 21 | BENZENE, BENZ 22 | ISOP, ISOP 23 | PAR, 1.5 * C3H8 24 | PAR, 4. * ALK4 25 | PAR, 3. * ACET 26 | PAR, 4. * MEK 27 | PAR, 1. * BENZ 28 | ALDX, RCHO 29 | ETH, ETH 30 | HO2, HO2 31 | HONO, HONO 32 | MGLY, MGLY 33 | NO, NO 34 | NO2, NO2 35 | NO3, NO3 36 | AALJ, 0.05695 * DST1 37 | AALKJ, AALKJ 38 | ABNZ1J, 0.12 * SOA5 39 | ABNZ2J, 0.04 * SOA5 40 | ABNZ3J, 0.32 * SOA5 41 | ACAJ, 0.0118 * SALA 42 | ACAJ, 0.07940 * DST1 43 | ACLJ, 0.00945 * DST1 44 | ACLJ, 0.5538 * SALA 45 | ACLK, 0.01190 * DST2 46 | ACLK, 0.01190 * DST3 47 | ACLK, 0.01190 * DST4 48 | ACLK, 0.5538 * SALC 49 | ACORS, ACORS 50 | AECI, 0.001 * BCPI 51 | AECI, 0.001 * BCPO 52 | AECJ, 0.999 * BCPI 53 | AECJ, 0.999 * BCPO 54 | AFEJ, 0.03355 * DST1 55 | AISO1J, 0.75 * SOA4 56 | AISO2J, 0.25 * SOA4 57 | AISO3J, AISO3J 58 | AKJ, 0.0114 * SALA 59 | AKJ, 0.03770 * DST1 60 | AMGJ, 0.0368 * SALA 61 | AMNJ, 0.00115 * DST1 62 | ANAJ, 0.3086 * SALA 63 | ANAJ, 0.03935 * DST1 64 | ANH4I, 0.01 * NH4 65 | ANH4J, 0.00005 * DST1 66 | ANH4J, 0.99 * NH4 67 | ANO3I, 0.01 * NIT 68 | ANO3J, 0.00020 * DST1 69 | ANO3J, 0.99 * NIT 70 | ANO3K, 0.0016 * DST2 71 | ANO3K, 0.0016 * DST3 72 | ANO3K, 0.0016 * DST4 73 | ANO3K, NITs 74 | AOLGAJ, AOLGAJ 75 | AOLGBJ, AOLGBJ 76 | AOTHRJ, 0.50219 * DST1 77 | APNCOMI, 0.4 * 0.001 * OCPI 78 | APNCOMI, 0.4 * 0.001 * OCPO 79 | APNCOMJ, 0.4 * 0.999 * OCPI 80 | APNCOMJ, 0.4 * 0.999 * OCPO 81 | APNCOMJ, 0.0043 * DST1 82 | APOCI, 0.001 * OCPI 83 | APOCI, 0.001 * OCPO 84 | APOCJ, 0.999 * OCPI 85 | APOCJ, 0.999 * OCPO 86 | APOCJ, 0.01075 * DST1 87 | ASEACAT, 0.3685 * SALC 88 | ASIJ, 0.19435 * DST1 89 | ASO4I, 0.01 * SO4 90 | ASO4J, 0.99 * SO4 91 | ASO4J, 0.0225 * DST1 92 | ASO4J, 0.0776 * SALA 93 | ASO4K, 0.0776 * SALC 94 | ASO4K, 0.02655 * DST2 95 | ASO4K, 0.02655 * DST3 96 | ASO4K, 0.02655 * DST4 97 | ASO4K, SO4s 98 | ASOIL, 0.95995 * DST2 99 | ASOIL, 0.95995 * DST3 100 | ASOIL, 0.95995 * DST4 101 | ASQTJ, SOA3 102 | ATIJ, 0.0028 * DST1 103 | ATOL1J, 0.04 * SOA5 104 | ATOL2J, 0.04 * SOA5 105 | ATOL3J, 0.29 * SOA5 106 | ATRP1J, 0.33 * SOA1 107 | ATRP1J, 0.33 * SOA2 108 | ATRP2J, 0.67 * SOA1 109 | ATRP2J, 0.67 * SOA2 110 | AXYL1J, 0.03 * SOA5 111 | AXYL2J, 0.01 * SOA5 112 | AXYL3J, 0.11 * SOA5 113 | NH3, NH3 114 | NUMACC, NUMACC 115 | NUMATKN, NUMATKN 116 | NUMCOR, NUMCOR 117 | SRFACC, SRFACC 118 | SRFATKN, SRFATKN 119 | SRFCOR, SRFCOR 120 | SULF, SULF 121 | SV_ALK, SV_ALK 122 | SV_BNZ1, 0.06 * SOG5 123 | SV_BNZ2, 0.23 * SOG5 124 | SV_ISO1, 0.75 * SOG4 125 | SV_ISO2, 0.25 * SOG4 126 | SV_SQT, SOG3 127 | SV_TOL1, 0.23 * SOG5 128 | SV_TOL2, 0.23 * SOG5 129 | SV_TRP1, 0.33 * SOG1 130 | SV_TRP1, 0.33 * SOG2 131 | SV_TRP2, 0.67 * SOG1 132 | SV_TRP2, 0.67 * SOG2 133 | SV_XYL1, 0.19 * SOG5 134 | SV_XYL2, 0.06 * SOG5 135 | -------------------------------------------------------------------------------- /profile.py: -------------------------------------------------------------------------------- 1 | from matplotlib.mlab import csv2rec 2 | from io import StringIO 3 | import numpy as np 4 | 5 | class profile(object): 6 | def __init__(self, path): 7 | lines = open(path).read().split('\n') 8 | header = lines[3].split() 9 | nlay, nspc = list(map(int, header[:2])) 10 | sigmas = list(map(float, header[2:])) 11 | nsigmas = len(sigmas) 12 | date, time = list(map(int, lines[4].split())) 13 | starts = [5 + i + i * nspc for i in range(4)] 14 | ends = [s + 1 + nspc for s in starts] 15 | keys = [lines[s].strip().lower() for s in starts] 16 | fieldnames = ('name',) + tuple(['s%f' % i for i in sigmas]) 17 | self.data = dict([(k, csv2rec(StringIO(u'\n'.join(lines[s+1:e])), delimiter = ' ', names = fieldnames, converterd = dict(names = lambda x: str(x).strip()))) for k, s, e in zip(keys, starts, ends)]) 18 | self._profile_spcs = np.char.strip(self.data[keys[0]]['name']) 19 | data_type = self.data[keys[0]].dtype 20 | data_shape = self.data[keys[0]].shape 21 | ks = keys[1:] 22 | for k in ks: 23 | try: 24 | assert((np.char.strip(self.data[k]['name']) == self._profile_spcs).all()) 25 | assert(self.data[k].dtype == data_type) 26 | assert(self.data[k].dtype == data_type) 27 | except AssertionError: 28 | raise IOError('File is corrupt or inconsistent') 29 | 30 | self._prof_spc = ['NO2', 'NO', 'O3P', 'O3', 'NO3', 'N2O5', 'HNO3', 'O1D', 'HO', 'HONO', 'HO2', 'CO', 'HNO4', 'H2O2', 'SO2', 'SULF', 'MO2', 'HCHO', 'OP1', 'OP2', 'ONIT', 'KET', 'ACO3', 'PAN', 'PAA', 'ORA2', 'TPAN', 'ALD', 'ORA1', 'GLY', 'MGLY', 'CSL', 'MACR', 'MVK', 'ISOPROD', 'DCB', 'OL2', 'ISO', 'TERP', 'ETH', 'HC3', 'HC3', 'HC5', 'HC8', 'TOL', 'XYL', 'XYL', 'XYL', 'OLT', 'OLI', 'BENZENE', 'HG', 'HGIIGAS', 'CO2'] 31 | self._prof_dict = dict([(k, []) for k in self._prof_spc]) 32 | 33 | def __missing__(self, gkey): 34 | if gkey in self._profile_spcs: 35 | return self.get_profile(gkey) 36 | else: 37 | raise KeyError('%s not in profile: %s' % (gkey, self._profile_spcs)) 38 | 39 | def __contains__(self, key): 40 | return key in self._profile_spcs.tolist() 41 | 42 | def __getitem__(self, key): 43 | return self.__missing__(key) 44 | 45 | def get_profile(self, key): 46 | out = '(BC1_PF_VERT( 1:N, 1:L, PF_%s ))' % key 47 | return out 48 | 49 | def profile_info(self): 50 | out = " INTEGER, PARAMETER :: NSPC_PF = %d\n" % len(self._profile_spcs) + \ 51 | " CHARACTER( 16 ) :: PF_SPNAME( NSPC_PF ) = ( /\n" 52 | ids = [] 53 | names = [] 54 | for pi, spcname in enumerate(self._profile_spcs): 55 | names.append(" & '%s'" % spcname.ljust(16)) 56 | ids.append(" INTEGER :: PF_%-16s = %4d" % (spcname, pi + 1)) 57 | out += ",\n".join(names) 58 | out += "\n & /)\n\n" 59 | out += '\n'.join(ids) 60 | out += '\n' 61 | return out 62 | 63 | if __name__ == '__main__': 64 | po = profile('testdata/profile.dat') 65 | -------------------------------------------------------------------------------- /map.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from .both import geos 4 | from .profile import profile 5 | from warnings import warn 6 | import re 7 | from functools import reduce 8 | 9 | var = re.compile('([^ .,+=\-*/%0-9)(][^ .,+=\-*/%)(]*)') 10 | def trymap(spc_data, mappath, mapo): 11 | outf = open(mappath, 'w') 12 | for spc_typ, spc_dat in list(spc_data.items()): 13 | for spcn, spcw in list(spc_dat.items()): 14 | if mapo.has_tracer(spcn) or mapo.has_cspec(spcn): 15 | outf.write('%s, %s\n' % (spcn, spcn)) 16 | else: 17 | outf.write('%s,\n' % (spcn, )) 18 | outf.close() 19 | 20 | def mapping(mappath): 21 | import csv 22 | rows = csv.reader(open(mappath)) 23 | next(rows) # ignore header 24 | rows = [row for row in rows if len(row) > 1] # Ignore unmapped 25 | rows = [[c.strip() for c in row] for row in rows if row[0][0] != '#'] # Ignore comments and empty rows 26 | rows = [row for row in rows if row[1].upper() not in ('PROFILE', '')] # Ignore profiles 27 | return rows 28 | 29 | def map(spc_data, mappath, mapo, profo): 30 | intext = mapping(mappath) 31 | # old mapping reader - [kv for kv in [kv.split(',') for kv in open(mappath).read().strip().split('\n')[1:] if kv[0] != '#'] if len(kv) > 1 and kv[-1].strip() != ''] 32 | ks = set([k for k, v in intext]) 33 | mechspcs = set(reduce(list.__add__, [list(spc_dat.keys()) for spc_dat in list(spc_data.values())])) 34 | mapped = list(ks) 35 | mapped.sort() 36 | nmapped = list(mechspcs.difference(ks)) 37 | nmapped.sort() 38 | print('Mapped MECH: ' + ' '.join(mapped)) 39 | print() 40 | print('Unmapped MECH: ' + ' '.join(nmapped)) 41 | print() 42 | print('Unmapped species might be available:') 43 | print(' - in TRACER data: ' + ' '.join([spc for spc in nmapped if mapo.has_tracer(spc)])) 44 | print(' - in CSPEC data: ' + ' '.join([spc for spc in nmapped if mapo.has_cspec(spc)])) 45 | print(' - in PROFILE data: ' + ' '.join([spc for spc in nmapped if spc in profo])) 46 | print() 47 | outs = [] 48 | nprof = 0 49 | for k, v in intext: 50 | if k in mechspcs: 51 | start = ' BC2( 1:N, 1:L, C_%s )' % k 52 | if k in ks: 53 | start += '= (%s)' 54 | ks.remove(k) 55 | else: 56 | start += '= %s +\n & (%%s)' % start.strip() 57 | if k in spc_data['AE']: 58 | mapo.aero(True) 59 | else: 60 | mapo.aero(False) 61 | try: 62 | out = start % (var.sub(r'%(\1)s', v) % mapo) 63 | except KeyError as e1: 64 | try: 65 | out = start % (var.sub(r'%(\1)s', v) % profo) 66 | nprof += 1 67 | except KeyError as e2: 68 | raise KeyError('Variable not found in either GEOS-Chem or Profile data\n\n' + str(e1) + '\n' + str(e2)) 69 | else: 70 | warn("Skipping %s; not in mech" % k) 71 | 72 | 73 | outs.append(out) 74 | mapo.check() 75 | return '\n'.join(outs), nprof 76 | 77 | if __name__ == '__main__': 78 | from .both import geos 79 | from .profile import profile 80 | go = geos('testdata/tracerinfo.dat', 81 | 'testdata/smv2.log') 82 | po = geos('testdata/profile.dat') 83 | from .mech import mechext as mech 84 | list(map(mech('testdata'), 'mapping/saprc07tb.csv', go, po)) 85 | -------------------------------------------------------------------------------- /mapping/saprc07t.csv: -------------------------------------------------------------------------------- 1 | MECHSPC, GEOS_EXPRESSION 2 | ACETONE, ACET 3 | ACROLEIN, 4 | ALK1, C2H6 5 | ALK2, C3H8 6 | ALK3, ALK4 / 2 7 | ALK4, ALK4 / 4 8 | ALK5, ALK4 / 4 9 | APIN, 10 | BENZENE, BENZ 11 | BUTADIENE13, 12 | CCHO, ALD2 / 3 13 | CCOOH, ACTA 14 | CCOOOH, MAP 15 | CO, CO 16 | COOH, MP 17 | HCHO, CH2O 18 | HCOOH, 19 | HNO3, HNO3 20 | HNO4, HNO4 21 | HO2H, H2O2 22 | HOCCHO, GLYC 23 | HONO, HNO2 24 | ISOPRENE, ISOP 25 | MACR, MACR 26 | MAPAN, PMN 27 | MEK, MEK / 3 28 | MEOH, MOH 29 | MGLY, MGLY 30 | MVK, MVK 31 | MXYL, XYLE / 3 32 | N2O5, N2O5 33 | NH3, NH3 34 | NO, NO 35 | NO2, NO2 36 | NO3, NO3 37 | O3, Ox - NOx 38 | OXYL, XYLE / 3 39 | PAN, PAN 40 | PAN2, PPN 41 | PRD2, MEK * 2 / 3 42 | PROPENE, PRPE 43 | PXYL, XYLE / 3 44 | RCHO, RCHO 45 | RNO3, R4N2 46 | ROOH, ETP 47 | ROOH, IAP 48 | ROOH, INPN 49 | ROOH, ISNP 50 | ROOH, MAOP 51 | ROOH, MRP 52 | ROOH, PP 53 | ROOH, PRPN 54 | ROOH, R4P 55 | ROOH, RA3P 56 | ROOH, RB3P 57 | ROOH, RIP 58 | ROOH, RP 59 | ROOH, VRP 60 | SO2, SO2 61 | TOLUENE, TOLU 62 | AALJ, 0.05695 * DST1 63 | AALKJ, AALKJ 64 | ABNZ1J, 0.12 * SOA5 65 | ABNZ2J, 0.04 * SOA5 66 | ABNZ3J, 0.32 * SOA5 67 | ACAJ, 0.0118 * SALA 68 | ACAJ, 0.07940 * DST1 69 | ACLJ, 0.00945 * DST1 70 | ACLJ, 0.5538 * SALA 71 | ACLK, 0.01190 * DST2 72 | ACLK, 0.01190 * DST3 73 | ACLK, 0.01190 * DST4 74 | ACLK, 0.5538 * SALC 75 | ACORS, ACORS 76 | AECI, 0.001 * BCPI 77 | AECI, 0.001 * BCPO 78 | AECJ, 0.999 * BCPI 79 | AECJ, 0.999 * BCPO 80 | AFEJ, 0.03355 * DST1 81 | AISO1J, 0.75 * SOA4 82 | AISO2J, 0.25 * SOA4 83 | AISO3J, AISO3J 84 | AKJ, 0.0114 * SALA 85 | AKJ, 0.03770 * DST1 86 | AMGJ, 0.0368 * SALA 87 | AMNJ, 0.00115 * DST1 88 | ANAJ, 0.3086 * SALA 89 | ANAJ, 0.03935 * DST1 90 | ANH4I, 0.01 * NH4 91 | ANH4J, 0.00005 * DST1 92 | ANH4J, 0.99 * NH4 93 | ANO3I, 0.01 * NIT 94 | ANO3J, 0.00020 * DST1 95 | ANO3J, 0.99 * NIT 96 | ANO3K, 0.0016 * DST2 97 | ANO3K, 0.0016 * DST3 98 | ANO3K, 0.0016 * DST4 99 | ANO3K, NITs 100 | AOLGAJ, AOLGAJ 101 | AOLGBJ, AOLGBJ 102 | AOTHRJ, 0.50219 * DST1 103 | APNCOMI, 0.4 * 0.001 * OCPI 104 | APNCOMI, 0.4 * 0.001 * OCPO 105 | APNCOMJ, 0.4 * 0.999 * OCPI 106 | APNCOMJ, 0.4 * 0.999 * OCPO 107 | APNCOMJ, 0.0043 * DST1 108 | APOCI, 0.001 * OCPI 109 | APOCI, 0.001 * OCPO 110 | APOCJ, 0.999 * OCPI 111 | APOCJ, 0.999 * OCPO 112 | APOCJ, 0.01075 * DST1 113 | ASEACAT, 0.3685 * SALC 114 | ASIJ, 0.19435 * DST1 115 | ASO4I, 0.01 * SO4 116 | ASO4J, 0.99 * SO4 117 | ASO4J, 0.0225 * DST1 118 | ASO4J, 0.0776 * SALA 119 | ASO4K, 0.0776 * SALC 120 | ASO4K, 0.02655 * DST2 121 | ASO4K, 0.02655 * DST3 122 | ASO4K, 0.02655 * DST4 123 | ASO4K, SO4s 124 | ASOIL, 0.95995 * DST2 125 | ASOIL, 0.95995 * DST3 126 | ASOIL, 0.95995 * DST4 127 | ASQTJ, SOA3 128 | ATIJ, 0.0028 * DST1 129 | ATOL1J, 0.04 * SOA5 130 | ATOL2J, 0.04 * SOA5 131 | ATOL3J, 0.29 * SOA5 132 | ATRP1J, 0.33 * SOA1 133 | ATRP1J, 0.33 * SOA2 134 | ATRP2J, 0.67 * SOA1 135 | ATRP2J, 0.67 * SOA2 136 | AXYL1J, 0.03 * SOA5 137 | AXYL2J, 0.01 * SOA5 138 | AXYL3J, 0.11 * SOA5 139 | NH3, NH3 140 | NUMACC, NUMACC 141 | NUMATKN, NUMATKN 142 | NUMCOR, NUMCOR 143 | SRFACC, SRFACC 144 | SRFATKN, SRFATKN 145 | SRFCOR, SRFCOR 146 | SULF, SULF 147 | SV_ALK, SV_ALK 148 | SV_BNZ1, 0.06 * SOG5 149 | SV_BNZ2, 0.23 * SOG5 150 | SV_ISO1, 0.75 * SOG4 151 | SV_ISO2, 0.25 * SOG4 152 | SV_SQT, SOG3 153 | SV_TOL1, 0.23 * SOG5 154 | SV_TOL2, 0.23 * SOG5 155 | SV_TRP1, 0.33 * SOG1 156 | SV_TRP1, 0.33 * SOG2 157 | SV_TRP2, 0.67 * SOG1 158 | SV_TRP2, 0.67 * SOG2 159 | SV_XYL1, 0.19 * SOG5 160 | SV_XYL2, 0.06 * SOG5 161 | -------------------------------------------------------------------------------- /fortran_template/UTILIO_DEFN.F: -------------------------------------------------------------------------------- 1 | 2 | C*********************************************************************** 3 | C Portions of Models-3/CMAQ software were developed or based on * 4 | C information from various groups: Federal Government employees, * 5 | C contractors working on a United States Government contract, and * 6 | C non-Federal sources (including research institutions). These * 7 | C research institutions have given the Government permission to * 8 | C use, prepare derivative works, and distribute copies of their * 9 | C work in Models-3/CMAQ to the public and to permit others to do * 10 | C so. EPA therefore grants similar permissions for use of the * 11 | C Models-3/CMAQ software, but users are requested to provide copies * 12 | C of derivative works to the Government without restrictions as to * 13 | C use by others. Users are responsible for acquiring their own * 14 | C copies of commercial software associated with Models-3/CMAQ and * 15 | C for complying with vendor requirements. Software copyrights by * 16 | C the MCNC Environmental Modeling Center are used with their * 17 | C permissions subject to the above restrictions. * 18 | C*********************************************************************** 19 | 20 | C RCS file, release, date & time of last delta, author, state, [and locker] 21 | C $Header: /project/work/rep/arc/CCTM/src/util/util/UTILIO_DEFN.F,v 1.2 2011/09/23 17:16:45 sjr Exp $ 22 | 23 | C what(1) key, module and SID; SCCS file; date and time of last delta: 24 | C %W% %P% %G% %U% 25 | 26 | C.................................................................... 27 | C CONTAINS: This module provides the interface to the Models3 IOAPI 28 | C using the M3UTILIO module. For parallel implementation of CMAQ, 29 | C several IOAPI routines are replaced with PARIO versions. For 30 | C example, the IOAPI function WRITE3 is renamed to an unused 31 | C function name "EXCLUDE_WRITE3", and the PARIO function PWRITE3 32 | C is aliased to WRITE3. So when WRITE3 is used in CMAQ, then the 33 | C the PARIO function PWRITE3 is accessed. This approach allows 34 | C flexibility in naming within CMAQ and eliminated the usage of 35 | C "cpp" flags to achieve the function overloading. 36 | C 37 | C REVISION HISTORY: 38 | C Original version 03/2011 by Shawn Roselle 39 | C 08/2011 by David Wong 40 | C -- extended to handle buffer file 41 | C.................................................................... 42 | 43 | MODULE UTILIO_DEFN 44 | 45 | #ifdef parallel 46 | 47 | USE M3UTILIO, EXCLUDE_INTERPB => INTERP3, 48 | & EXCLUDE_M3EXIT => M3EXIT, 49 | & EXCLUDE_M3WARN => M3WARN, 50 | & EXCLUDE_SHUT3 => SHUT3, 51 | & EXCLUDE_WRITE3 => WRITE3, 52 | & BUF_WRITE3 => WRITE3 53 | 54 | USE PARUTILIO, INTERPB => PINTERPB, 55 | & M3ERR => PM3ERR, 56 | & M3EXIT => PM3EXIT, 57 | & M3WARN => PM3WARN, 58 | & SHUT3 => PSHUT3, 59 | & WRITE3 => PWRITE3 60 | #else 61 | USE M3UTILIO, INTERPB => INTERP3 62 | ! USE M3UTILIO 63 | #endif 64 | ! BHH: You may need to comment the JUNIT lines out 65 | ! to make this work. 66 | EXTERNAL JUNIT 67 | INTEGER JUNIT 68 | 69 | END MODULE UTILIO_DEFN 70 | -------------------------------------------------------------------------------- /mapping/saprc07tc.csv: -------------------------------------------------------------------------------- 1 | MECHSPC, GEOS_EXPRESSION 2 | A25I, 3 | A25J, 4 | AALKJ, 5 | #ABNZ1J, 0.12 * SOA5 6 | #ABNZ2J, 0.04 * SOA5 7 | #ABNZ3J, 0.32 * SOA5 8 | ACETONE, ACET 9 | ACETYLENE, 10 | ACLI, 11 | ACLJ, 0.00945 * DST1 12 | ACLJ, 0.5538 * SALA 13 | ACLK, 0.0119 * DST2 14 | ACLK, 0.0119 * DST3 15 | ACLK, 0.0119 * DST4 16 | ACLK, 0.5538 * SALC 17 | ACORS, 18 | ACROLEIN, 19 | AECI, 0.001 * BCPO 20 | AECI, 0.001 * BCPI 21 | AECJ, 0.999 * BCPO 22 | AECJ, 0.999 * BCPI 23 | AFG1, 24 | AFG2, 25 | AFG3, 26 | AH2OI, 27 | AH2OJ, 28 | AH2OK, 29 | #AISO1J, 0.75 * SOA4 30 | #AISO2J, 0.25 * SOA4 31 | AISO3J, 32 | ALK1, C2H6 33 | ALK2, C3H8 34 | ALK3, ALK4 / 2 35 | ALK4, ALK4 / 4 36 | ALK5, ALK4 / 4 37 | ANAI, 38 | ANAJ, 0.03935 * DST1 39 | ANAJ, 0.3086 * SALA 40 | ANH4I, 0.01 * NH4 41 | ANH4J, 0.00005 * DST1 42 | ANH4J, 0.99 * NH4 43 | ANH4K, 44 | ANO3I, 0.01 * NIT 45 | ANO3J, 0.0002 * DST1 46 | ANO3J, 0.99 * NIT 47 | ANO3K, 0.0016 * DST2 48 | ANO3K, 0.0016 * DST3 49 | ANO3K, 0.0016 * DST4 50 | ANO3K, NITs 51 | AOLGAJ, 52 | AOLGBJ, 53 | AORGCJ, 54 | AORGPAI, 0.001 * OCPI 55 | AORGPAI, 0.001 * OCPO 56 | AORGPAJ, 0.999 * OCPI 57 | AORGPAJ, 0.999 * OCPO 58 | APIN,ALPH 59 | ARO1, 60 | ARO2, 61 | ASO4I, 0.01 * SO4 62 | ASO4J, 0.0776 * DST1 63 | ASO4J, 0.99 * SO4 64 | ASO4K, 0.02655 * DST2 65 | ASO4K, 0.02655 * DST3 66 | ASO4K, 0.02655 * DST4 67 | ASO4K, 0.0776 * SALC 68 | ASO4K, SO4s 69 | ASOIL, 0.95995 * DST2 70 | ASOIL, 0.95995 * DST3 71 | ASOIL, 0.95995 * DST4 72 | #ASQTJ, SOA3 73 | #ATOL1J, 0.04 * SOA5 74 | #ATOL2J, 0.04 * SOA5 75 | #ATOL3J, 0.29 * SOA5 76 | #ATRP1J, 0.33 * SOA1 77 | #ATRP1J, 0.33 * SOA2 78 | #ATRP2J, 0.67 * SOA1 79 | #ATRP2J, 0.67 * SOA2 80 | #AXYL1J, 0.03 * SOA5 81 | #AXYL2J, 0.01 * SOA5 82 | #AXYL3J, 0.11 * SOA5 83 | BACL, 84 | BALD, 85 | #BENZENE, BENZ 86 | BUTADIENE13, 87 | BZCO3, 88 | BZO, 89 | CCHO, ALD2 90 | CCOOH, ACTA 91 | CCOOOH, MAP 92 | CO, CO 93 | CO2, 94 | COOH, MP 95 | CRES, 96 | ETHENE, 97 | ETOH, EOH 98 | #GLY, GLYX 99 | HCHO, CH2O 100 | HCOOH, HCOOH 101 | HNO3, HNO3 102 | HNO4, HNO4 103 | HO2, HO2 104 | HO2H, H2O2 105 | HOCCHO, GLYC 106 | HONO, HNO2 107 | IPRD, 108 | ISOPRENE, ISOP 109 | MACO3, 110 | MACR, MACR 111 | MAPAN, PMN 112 | MECO3, 113 | MEK, MEK / 3. 114 | MEO2, 115 | MEOH, MOH 116 | MGLY, MGLY 117 | MVK, MVK 118 | #MXYL, XYLE / 3. 119 | N2O5, N2O5 120 | NC4, 121 | NH3, NH3 122 | NO, NO 123 | NO2, NO2 124 | NO2EX, 125 | NO3, NO3 126 | NPHE, 127 | NUMACC, 128 | NUMATKN, 129 | NUMCOR, 130 | O1D, 131 | O3, Ox - NOx 132 | O3P, 133 | OH, OH 134 | OLE1, 135 | OLE2, 136 | #OXYL, XYLE / 3 137 | PAN, PAN 138 | PAN2, PPN 139 | PBZN, 140 | PRD2, MEK * 2. / 3. 141 | PROPENE, PRPE 142 | #PXYL, XYLE / 3 143 | R6OOH, 144 | RAOOH, 145 | RCHO, RCHO 146 | RCO3, 147 | RCOOH, 148 | RCOOOH, 149 | RNO3, R4N2 150 | RO2C, 151 | RO2XC, 152 | ROOH, ETP 153 | ROOH, IAP 154 | ROOH, INPN 155 | ROOH, ISNP 156 | ROOH, MAOP 157 | ROOH, MRP 158 | ROOH, PP 159 | ROOH, PRPN 160 | ROOH, R4P 161 | ROOH, RA3P 162 | ROOH, RB3P 163 | ROOH, RIP 164 | ROOH, RP 165 | ROOH, VRP 166 | SESQ, 167 | SO2, SO2 168 | SRFACC, 169 | SRFATKN, 170 | SRFCOR, 171 | SULF, 172 | SULRXN, 173 | SV_ALK, 174 | #SV_BNZ1, 0.06 * SOG5 175 | #SV_BNZ2, 0.23 * SOG5 176 | #SV_ISO1, 0.75 * SOG4 177 | #SV_ISO2, 0.25 * SOG4 178 | #SV_SQT, SOG3 179 | #SV_TOL1, 0.23 * SOG5 180 | #SV_TOL2, 0.23 * SOG5 181 | #SV_TRP1, 0.33 * SOG1 182 | #SV_TRP1, 0.33 * SOG2 183 | #SV_TRP2, 0.67 * SOG1 184 | #SV_TRP2, 0.67 * SOG2 185 | #SV_XYL1, 0.19 * SOG5 186 | #SV_XYL2, 0.06 * SOG5 187 | TBUO, 188 | TERP, 189 | #TOLUENE, TOLU 190 | TRIMETH_BENZ124, 191 | -------------------------------------------------------------------------------- /mech.py: -------------------------------------------------------------------------------- 1 | from glob import glob 2 | import os 3 | import numpy as np 4 | from io import StringIO 5 | import csv 6 | 7 | def mechext(inpath): 8 | spc_paths = glob(os.path.join(inpath, '*_SPC.EXT')) 9 | spc_files = dict([(os.path.basename(p)[:2], p) for p in spc_paths]) 10 | spc_data = {} 11 | for k in list(spc_files.keys()): 12 | path = spc_files[k] 13 | spc_dat = dict([(key, eval(v)) for key, v in [l.strip().replace('/','').replace(' ', '').replace(',', '').split("'")[1:3] for l in open(path, 'rt').read().split('\n') if "'" in l]]) 14 | spc_data[k] = spc_dat 15 | return spc_data 16 | 17 | def mechnml(inpath): 18 | spc_paths = glob(os.path.join(inpath, '*.nml')) 19 | try: 20 | spc_files = dict([(os.path.basename(p)[:2], p) for p in spc_paths]) 21 | except SyntaxError as e: 22 | raise SyntaxError("You must have only one AE*.nml, one GC*.nml and one NR*.nml") 23 | 24 | spc_data = {} 25 | for k in list(spc_files.keys()): 26 | path = spc_files[k] 27 | start = False 28 | lines = [] 29 | for line in open(path, 'rt').readlines(): 30 | if start and '/' in line: 31 | break 32 | if start: 33 | lines.append(line[1:]) 34 | if 'TYPE_MATRIX' in line: 35 | start = True 36 | datstr = ''.join(lines).replace(',', '') 37 | datstr = datstr 38 | if datstr == '': 39 | spc_data[k] = {} 40 | else: 41 | #import pdb; pdb.set_trace() 42 | #data = np.loadtxt(StringIO(datstr), delimiter = ':', usecols = [0, 1], dtype = np.dtype([('NAME', 'S120'), ('MOLWT', 'd')])) 43 | name_wt = [line.split(':')[:2] for line in datstr.split('\n') if line.strip() != ''] 44 | name_wt = [(name, eval(wt)) for name, wt in name_wt] 45 | spc_dat = dict(name_wt) 46 | spc_data[k] = spc_dat 47 | return spc_data 48 | 49 | def mechinc(indict, convpath): 50 | from .map import mapping 51 | units = [] 52 | names = [] 53 | out = "" 54 | mech_spcs = [k for k, v in mapping(convpath)] 55 | for spc_typ, spc_dat in indict.items(): 56 | if spc_typ == 'AE': 57 | unit = "micrograms/m**3".ljust(16) 58 | else: 59 | unit = 'ppmV'.ljust(16) 60 | for spcn, spcw in spc_dat.items(): 61 | if not spcn in mech_spcs: continue 62 | units.append('# / m**3'.ljust(16) if spcn[:3] == 'NUM' and spc_typ == 'AE' else unit) 63 | names.append(spcn.ljust(16)) 64 | out += " INTEGER, PARAMETER :: NSPC_CMAQ = %d\n" % len(names) 65 | out += " CHARACTER( 16 ) :: CMAQ_SNAME( NSPC_CMAQ ) = ( /\n" 66 | out += ",\n".join([" & '%s'" % s for s in names]) 67 | out += "\n & /)\n" 68 | out += "\n" 69 | out += " CHARACTER( 16 ) :: CMAQ_LNAME( NSPC_CMAQ ) = ( /\n" 70 | out += ",\n".join([" & '%s'" % s for s in names]) 71 | out += "\n & /)\n" 72 | out += "\n" 73 | out += " CHARACTER( 16 ) :: CMAQ_UNITS( NSPC_CMAQ ) = ( /\n" 74 | out += ",\n".join([" & '%s'" % s for s in units]) 75 | out += "\n & /)\n" 76 | out += "\n" 77 | out += "\n".join([" INTEGER :: C_%-16s = %d" % (s.strip(), si + 1) for si, s in enumerate(names)]) 78 | out += "\n" 79 | return out 80 | 81 | 82 | if __name__ == "__main__": 83 | x = mechnml('testdata') 84 | y = mech('testdata') 85 | -------------------------------------------------------------------------------- /fortran_template/GEOS_DOMAIN.INC: -------------------------------------------------------------------------------- 1 | c SLN (14Mar2011) - sigma levels come from http://acmg.seas.harvard.edu/geos/doc/man/ 2 | REAL, PARAMETER :: DEL_LON = 2.5 3 | REAL, PARAMETER :: DEL_LAT = 2.0 4 | c..Vertical coordinate levels 5 | INTEGER, PARAMETER :: N_GEO_LAYS = 47 ! GEOS-5 reduced 6 | REAL :: GEO_SIGMA( N_GEO_LAYS + 1 ) = ( / 7 | & 1.000000, 8 | & 0.984999, 9 | & 0.969913, 10 | & 0.954828, 11 | & 0.939743, 12 | & 0.924658, 13 | & 0.909573, 14 | & 0.894489, 15 | & 0.879406, 16 | & 0.864323, 17 | & 0.849239, 18 | & 0.834157, 19 | & 0.819075, 20 | & 0.798967, 21 | & 0.773832, 22 | & 0.748698, 23 | & 0.723570, 24 | & 0.698442, 25 | & 0.673314, 26 | & 0.635628, 27 | & 0.597953, 28 | & 0.560278, 29 | & 0.522620, 30 | & 0.484970, 31 | & 0.447337, 32 | & 0.409720, 33 | & 0.372133, 34 | & 0.334566, 35 | & 0.285142, 36 | & 0.242032, 37 | & 0.205513, 38 | & 0.174608, 39 | & 0.148418, 40 | & 0.126157, 41 | & 0.107233, 42 | & 0.091149, 43 | & 0.077477, 44 | & 0.055641, 45 | & 0.039641, 46 | & 0.027987, 47 | & 0.019523, 48 | & 0.009162, 49 | & 0.004013, 50 | & 0.001619, 51 | & 0.000599, 52 | & 0.000199, 53 | & 0.000055, 54 | & 0.000000 / ) 55 | 56 | REAL :: GEO_TOP = 0.01 ! pressure at the top in hPa 57 | -------------------------------------------------------------------------------- /testdata/GC_cb05tucl_ae6_aq.nml: -------------------------------------------------------------------------------- 1 | ! RCS file, release, date & time of last delta, author, state, [and locker] 2 | ! $Header: /project/work/rep/arc/mechs/MECHS/src/cb05tucl_ae6_aq/GC_cb05tucl_ae6_aq.nml,v 1.1.1.1 2011/04/06 16:57:21 sjr Exp $ 3 | 4 | &GC_nml 5 | 6 | n_surr1 = 4, 7 | n_surr2 = 2, 8 | n_ctrl = 4, 9 | 10 | TYPE_HEADER = 11 | 'SPC:MOLWT:EMIS_SUR:EMIS_FAC:DEPV_SUR:DEPV_FAC:ICBC_SUR:ICBC_FAC:SCAV_SUR:SCAV_FAC:G2AE_SUR:G2AQ_SUR:TRNS:DDEP:WDEP:CONC', 12 | TYPE_MATRIX = 13 | 'NO2:46:NO2:1:VD_NO2:1:::NO2:1:NO2::Yes:Yes:Yes:Yes', 14 | 'NO:30:NO:1:VD_NO:1:::NO:1:::Yes:Yes:Yes:Yes', 15 | 'O:16::::::::::::::Yes', 16 | 'O3:48:::VD_O3:1:::O3:1::O3:Yes:Yes:Yes:Yes', 17 | 'NO3:62:::VD_NO3:1:::NO3:1:::Yes:Yes:Yes:Yes', 18 | 'O1D:16::::::::::::::Yes', 19 | 'OH:17:::::::::OH:HO::::Yes', 20 | 'HO2:33::::::::::::::Yes', 21 | 'N2O5:108:::VD_N2O5:1:::N2O5:1:N2O5:N2O5:Yes:Yes:Yes:Yes', 22 | 'HNO3:63:::VD_HNO3:1:::HNO3:1:HNO3:HNO3:Yes:Yes:Yes:Yes', 23 | 'HONO:47:HONO:1:VD_HONO:1:::HNO2:1:HONO::Yes:Yes:Yes:Yes', 24 | 'PNA:79:::::::HNO4:1:::Yes::Yes:Yes', 25 | 'H2O2:34:::VD_H2O2:1:::H2O2:1::H2O2:Yes:Yes:Yes:Yes', 26 | 'XO2:1::::::::::::::Yes', 27 | 'XO2N:1::::::::::::::Yes', 28 | 'NTR:130:::VD_PAN:1:::MPAN:1:::Yes:Yes:Yes:Yes', 29 | 'ROOH:62:::VD_OP:1:::METHYLHYDROPEROX:1:::Yes:Yes:Yes:Yes', 30 | 'FORM:30:FORM:1:VD_HCHO:1:::FORMALDEHYDE:1:::Yes:Yes:Yes:Yes', 31 | 'ALD2:44:ALD2:1:VD_ALD:1:::ACETALDEHYDE:1:::Yes:Yes:Yes:Yes', 32 | 'ALDX:44:ALDX:1:VD_GEN_ALD:1:::GENERIC_ALDEHYDE:1:::Yes:Yes:Yes:Yes', 33 | 'PAR:14:PAR:1:::::ETHANE:1:::Yes:::Yes', 34 | 'CO:28:CO:1:VD_CO:1:::CO:1:::Yes:Yes:Yes:Yes', 35 | 'MEO2:47::::::::::::::Yes', 36 | 'MEPX:48:::VD_OP:1:::METHYLHYDROPEROX:1::MHP:Yes:Yes:Yes:Yes', 37 | 'MEOH:32:MEOH:1:VD_METHANOL:1:::METHANOL:1:::Yes:Yes:Yes:Yes', 38 | 'HCO3:63::::::::::::::Yes', 39 | 'FACD:46:::VD_ORA:1:::FORMIC_ACID:1::FOA:Yes:Yes:Yes:Yes', 40 | 'C2O3:75::::::::::::::Yes', 41 | 'PAN:121:::VD_PAN:1:::PAN:1:::Yes:Yes:Yes:Yes', 42 | 'PACD:76:::VD_PAA:1:::PEROXYACETIC_ACI:1::PAA:Yes:Yes:Yes:Yes', 43 | 'AACD:60:::VD_ORA:1:::ACETIC_ACID:1:::Yes:Yes:Yes:Yes', 44 | 'CXO3:75::::::::::::::Yes', 45 | 'PANX:121:::VD_PAN:1:::PPN:1:::Yes:Yes:Yes:Yes', 46 | 'ROR:31::::::::::::::Yes', 47 | 'OLE:27:OLE:1:::::ETHENE:1:::Yes:::Yes', 48 | 'ETH:28:ETH:1:::::ETHENE:1:::Yes:::Yes', 49 | 'IOLE:48:IOLE:1:::::ETHENE:1:::Yes:::Yes', 50 | 'TOL:92:TOL:1:::::TOLUENE:1:::Yes:::Yes', 51 | 'CRES:108:::::::2-CRESOL:1:::Yes:::Yes', 52 | 'TO2:173::::::::::::::Yes', 53 | 'TOLRO2:141::::::::::::::Yes', 54 | 'OPEN:84:::::::::::Yes:::Yes', 55 | 'MGLY:72:::::::METHYL_GLYOXAL:1::MGLY:Yes:::Yes', 56 | 'CRO:107::::::::::::::Yes', 57 | 'CAT1:124:::::::PHENOL:1:::Yes:::Yes', 58 | 'CRON:153:::::::2-CRESOL:1:::Yes:::Yes', 59 | 'CRNO:152::::::::::::::Yes', 60 | 'CRN2:168::::::::::::::Yes', 61 | 'CRPX:169:::VD_OP:1:::METHYLHYDROPEROX:1:::Yes:Yes::Yes', 62 | 'OPO3:115::::::::::::::Yes', 63 | 'CAO2:133::::::::::::::Yes', 64 | 'OPAN:161:::VD_PAN:1:::MPAN:1:::Yes:Yes:Yes:Yes', 65 | 'XYL:106:XYL:1:::::O-XYLENE:1:::Yes:::Yes', 66 | 'XYLRO2:155::::::::::::::Yes', 67 | 'ISOP:68:ISOP:1:::::ISOPRENE:1:::Yes:::Yes', 68 | 'ISPD:70:::::::::::Yes:::Yes', 69 | 'ISOPRXN:68:::::::::ISOPRXN:::::', 70 | 'TERP:136:TERP:1:::::PINENE:1:::Yes:::Yes', 71 | 'TRPRXN:136:::::::::TRPRXN:::::', 72 | 'SO2:64:SO2:1:VD_SO2:1:::SO2:1::SO2:Yes:Yes:Yes:Yes', 73 | 'SULF:98:SULF:1:VD_SULF:1:::H2SO4:1:SULF:H2SO4:Yes:Yes:Yes:Yes', 74 | 'SULRXN:98:::::::::SULPRD:::::', 75 | 'ETOH:46:ETOH:1:::::ETHANOL:1:::Yes:::Yes', 76 | 'ETHA:30:ETHA:1:::::ETHANE:1:::Yes:::Yes', 77 | 'CL2:71:CL2:1:VD_CL2:1:::CL2:1:::Yes:Yes:Yes:Yes', 78 | 'CL:35.5::::::::::::::Yes', 79 | 'HOCL:52.5:::VD_HOCL:1:::HOCL:1:::Yes:Yes:Yes:Yes', 80 | 'CLO:51.5::::::::::::::Yes', 81 | 'FMCL:64.5:::VD_FMCL:1:::FMCL:1:::Yes:Yes:Yes:Yes', 82 | 'HCL:36.5:HCL:1:VD_HCL:1:::HCL:1:HCL:HCL:Yes:Yes:Yes:Yes', 83 | 'TOLNRXN:141:::::::::TOLNRXN:::::', 84 | 'TOLHRXN:141:::::::::TOLHRXN:::::', 85 | 'XYLNRXN:155:::::::::XYLNRXN:::::', 86 | 'XYLHRXN:155:::::::::XYLHRXN:::::', 87 | 'BENZENE:78:BENZENE:1:::::BENZENE:1:::Yes:::Yes', 88 | 'BENZRO2:127::::::::::::::Yes', 89 | 'BNZNRXN:127:::::::::BNZNRXN:::::', 90 | 'BNZHRXN:127:::::::::BNZHRXN:::::', 91 | 'SESQ:204:SESQ:1:::::PINENE:1:::Yes:::Yes', 92 | 'SESQRXN:204:::::::::SESQRXN:::::' 93 | / 94 | -------------------------------------------------------------------------------- /mapping/saprc07tb.csv: -------------------------------------------------------------------------------- 1 | MECHSPC, GEOS_EXPRESSION 2 | AALJ, 0.05695 * DST1 3 | AALKJ, 4 | ABNZ1J, 0.12 * SOA5 5 | ABNZ2J, 0.04 * SOA5 6 | ABNZ3J, 0.32 * SOA5 7 | ACAJ, 0.0118 * SALA 8 | ACAJ, 0.0794 * DST1 9 | ACETONE, ACET 10 | ACETYLENE, 11 | ACLI, 12 | ACLJ, 0.00945 * DST1 13 | ACLJ, 0.5538 * SALA 14 | ACLK, 0.0119 * DST2 15 | ACLK, 0.0119 * DST3 16 | ACLK, 0.0119 * DST4 17 | ACLK, 0.5538 * SALC 18 | ACORS, 19 | ACROLEIN, 20 | ACROLEIN_PRIMARY, 21 | AECI, 0.001 * BCPO 22 | AECJ, 0.999 * BCPI 23 | AFEJ, 0.03355 * DST1 24 | AFG1, 25 | AFG2, 26 | AFG3, 27 | AH2OI, 28 | AH2OJ, 29 | AH2OK, 30 | AISO1J, 0.75 * SOA4 31 | AISO2J, 0.25 * SOA4 32 | AISO3J, 33 | AKJ, 0.0386 * SALA 34 | ALK1, C2H6 35 | ALK2, C3H8 36 | ALK3, ALK4 / 2 37 | ALK4, ALK4 / 4 38 | ALK5, ALK4 / 4 39 | ALK5RXN, 40 | AMGJ, 0.0386 * SALA 41 | AMNJ, 0.00115 * DST1 42 | ANAI, 43 | ANAJ, 0.03935 * DST1 44 | ANAJ, 0.3086 * SALA 45 | ANH4I, 0.01 * NH4 46 | ANH4J, 0.00005 * DST1 47 | ANH4J, 0.99 * NH4 48 | ANH4K, 49 | ANO3I, 0.01 * NIT 50 | ANO3J, 0.002 * DST1 51 | ANO3J, 0.99 * NIT 52 | ANO3K, 0.0016 * DST2 53 | ANO3K, 0.0016 * DST3 54 | ANO3K, 0.0016 * DST4 55 | ANO3K, NITs 56 | AOLGAJ, 57 | AOLGBJ, 58 | AORGCJ, 59 | AOTHRI, 60 | AOTHRJ, 0.50219 * DST1 61 | APIN, 62 | APNCOMI, 0.4 * 0.001 * OCPI 63 | APNCOMI, 0.4 * 0.001 * OCPO 64 | APNCOMJ, 0.0043 * DST1 65 | APNCOMJ, 0.4 * 0.01075 * DST1 66 | APNCOMJ, 0.4 * 0.999 * OCPI 67 | APNCOMJ, 0.4 * 0.999 * OCPO 68 | APOCI, 0.001 * OCPI 69 | APOCI, 0.001 * OCPO 70 | APOCJ, 0.01075 * DST1 71 | APOCJ, 0.999 * OCPI 72 | APOCJ, 0.999 * OCPO 73 | ARO1, 74 | ARO2, 75 | ASEACAT, 0.3685 * SALC 76 | ASIJ, 0.19435 * DST1 77 | ASO4I, 0.01 * SO4 78 | ASO4J, 0.0776 * DST1 79 | ASO4J, 0.99 * SO4 80 | ASO4K, 0.02655 * DST2 81 | ASO4K, 0.02655 * DST3 82 | ASO4K, 0.02655 * DST4 83 | ASO4K, 0.0776 * SALC 84 | ASO4K, SO4s 85 | ASOIL, 0.95995 * DST2 86 | ASOIL, 0.95995 * DST3 87 | ASOIL, 0.95995 * DST4 88 | ASQTJ, SOA3 89 | ATIJ, 0.0028 * DST1 90 | ATOL1J, 0.04 * SOA5 91 | ATOL2J, 0.04 * SOA5 92 | ATOL3J, 0.29 * SOA5 93 | ATRP1J, 0.33 * SOA1 94 | ATRP1J, 0.33 * SOA2 95 | ATRP2J, 0.67 * SOA1 96 | ATRP2J, 0.67 * SOA2 97 | AXYL1J, 0.03 * SOA5 98 | AXYL2J, 0.01 * SOA5 99 | AXYL3J, 0.11 * SOA5 100 | BACL, 101 | BALD, 102 | BENZENE, BENZ 103 | BENZRO2, 104 | BNZHRXN, 105 | BNZNRXN, 106 | BUTADIENE13, 107 | BZCO3, 108 | BZO, 109 | CCHO, ALD2 / 3 110 | CCOOH, ACTA 111 | CCOOOH, MAP 112 | CL, 113 | CL2, 114 | CLACET, 115 | CLCCHO, 116 | CLCHO, 117 | CLNO, 118 | CLNO2, 119 | CLO, 120 | CLONO, 121 | CLONO2, 122 | CO, CO 123 | CO2, 124 | COOH, MP 125 | CRES, 126 | ETHENE, 127 | ETOH, 128 | GLY, 129 | HCHO, CH2O 130 | HCL, 131 | HCOOH, HCOOH 132 | HNO3, HNO3 133 | HNO4, HNO4 134 | HO2, 135 | HO2H, H2O2 136 | HOCCHO, GLYC 137 | HOCL, 138 | HONO, HNO2 139 | IPRD, 140 | ISOPRENE, ISOP 141 | ISOPRXN, 142 | MACO3, 143 | MACR, MACR 144 | MAPAN, PMN 145 | MECO3, 146 | MEK, MEK / 3 147 | MEO2, 148 | MEOH, MOH 149 | MGLY, MGLY 150 | MVK, MVK 151 | MXYL, XYLE / 3 152 | N2O5, N2O5 153 | NH3, NH3 154 | NO, NO 155 | NO2, NO2 156 | NO2EX, 157 | NO3, NO3 158 | NPHE, 159 | O1D, 160 | O3, Ox - NOx 161 | O3P, 162 | OH, 163 | OLE1, 164 | OLE2, 165 | OXYL, XYLE / 3 166 | PAN, PAN 167 | PAN2, PPN 168 | PBZN, 169 | PRD2, MEK * 2 / 3 170 | PROPENE, PRPE 171 | PXYL, XYLE / 3 172 | R6OOH, 173 | RAOOH, 174 | RCHO, RCHO 175 | RCO3, 176 | RCOOH, 177 | RCOOOH, 178 | RNO3, R4N2 179 | RO2C, 180 | RO2XC, 181 | ROOH, ETP 182 | ROOH, IAP 183 | ROOH, INPN 184 | ROOH, ISNP 185 | ROOH, MAOP 186 | ROOH, MRP 187 | ROOH, PP 188 | ROOH, PRPN 189 | ROOH, R4P 190 | ROOH, RA3P 191 | ROOH, RB3P 192 | ROOH, RIP 193 | ROOH, RP 194 | ROOH, VRP 195 | SESQ, 196 | SESQRXN, 197 | SO2, SO2 198 | SULF, 199 | SULRXN, 200 | SV_ALK, 201 | SV_BNZ1, 0.06 * SOG5 202 | SV_BNZ2, 0.23 * SOG5 203 | SV_ISO1, 0.75 * SOG4 204 | SV_ISO2, 0.25 * SOG4 205 | SV_SQT, SOG3 206 | SV_TOL1, 0.23 * SOG5 207 | SV_TOL2, 0.23 * SOG5 208 | SV_TRP1, 0.33 * SOG1 209 | SV_TRP1, 0.33 * SOG2 210 | SV_TRP2, 0.67 * SOG1 211 | SV_TRP2, 0.67 * SOG2 212 | SV_XYL1, 0.19 * SOG5 213 | SV_XYL2, 0.06 * SOG5 214 | TBUO, 215 | TERP, 216 | TOLHRXN, 217 | TOLNRXN, 218 | TOLRO2, 219 | TOLUENE, TOLU 220 | TRIMETH_BENZ124, 221 | TRPRXN, 222 | XYLHRXN, 223 | XYLNRXN, 224 | XYLRO2, 225 | 226 | -------------------------------------------------------------------------------- /__main__.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import optparse 3 | import os 4 | from glob import glob 5 | import shutil 6 | from sys import exit 7 | 8 | usage = "usage: %prog [options] outpath" 9 | parser = optparse.OptionParser(usage=usage) 10 | archived_options = list(map(os.path.basename, glob(os.path.join(os.path.dirname(__file__), 'mechmap_archive', '*')))) 11 | parser.add_option("-a", dest = "archive", help = "Use archived mapping (one of: %s)" % ', '.join(archived_options), metavar="ARCHIVE", default = None) 12 | parser.add_option("-t", dest = "tracerinfo", help = "path to tracerinfo.dat (defaults to SOA from v9-01-01)", metavar="TRACERINFO", default = None) 13 | parser.add_option("-s", dest = "smvlog", help = "path to smv2.log (defaults to SOA from v9-01-01)", metavar="SMV", default = None) 14 | parser.add_option("-m", dest = "mechpath", help = "path to mechanism include files (e.g., mechpath*.EXT; defaults to cb05cl_ae6_aq)", metavar="MECHPATH", default = None) 15 | parser.add_option("-c", dest = "conversion", help = "path to converstion (i.e., mapping file)", metavar="CONV", default = None) 16 | parser.add_option("-e", dest = "extfiles", help = "use ext files instead of namelist", metavar="EXT", default = False, action = 'store_true') 17 | parser.add_option("-p", dest = "profiledat", help = "path to profile (e.g., CMAQ BCON input) (defaults profile.dat", metavar="PROFILEDAT", default = None) 18 | options, args = parser.parse_args() 19 | 20 | mapopt = dict([(o.dest, getattr(options, o.dest)) for o in parser.option_list[1:]]) 21 | 22 | convpath = options.conversion or os.path.join(os.path.dirname(__file__), 'mapping', 'saprc07t.csv') 23 | if not os.path.exists(convpath): 24 | temppath = os.path.join(os.path.dirname(__file__), 'mapping', convpath + '.csv') 25 | if os.path.exists(temppath): 26 | convpath = temppath 27 | del temppath 28 | tracerpath = options.tracerinfo or os.path.join(os.path.dirname(__file__), 'testdata', 'tracerinfo.dat') 29 | smvpath = options.smvlog or os.path.join(os.path.dirname(__file__), 'testdata', 'smv2.log') 30 | mechpath = options.mechpath or os.path.join(os.path.dirname(__file__), 'testdata') 31 | profilepath = options.profiledat or os.path.join(os.path.dirname(__file__), 'testdata', 'profile.dat') 32 | if len(args) < 1: 33 | parser.print_help() 34 | exit() 35 | else: 36 | out = args[0] 37 | 38 | if not os.path.exists(out): 39 | os.mkdir(out) 40 | outdir = out 41 | 42 | if options.archive in archived_options: 43 | for f in glob(os.path.join(os.path.dirname(__file__), 'fortran_template', '*')): 44 | shutil.copy(f, outdir) 45 | for f in glob(os.path.join(os.path.dirname(__file__), 'mechmap_archive', options.archive, '*')): 46 | shutil.copy(f, outdir) 47 | 48 | 49 | 50 | from .both import geos 51 | from .profile import profile 52 | from .mech import mechnml, mechinc, mechext 53 | from .map import map, trymap 54 | if options.extfiles: 55 | mech = mechext 56 | else: 57 | mech = mechnml 58 | go = geos(tracerpath, 59 | smvpath) 60 | po = profile(profilepath) 61 | 62 | if not os.path.exists(convpath): 63 | if os.path.exists(os.path.join(os.path.dirname(__file__), convpath + '.csv')): 64 | convpath = os.path.join(os.path.dirname(__file__), convpath + '.csv') 65 | elif 'Y' == input("Conversion path does not exist; type Y to create it or any other key to abort\n"): 66 | trymap(mech(mechpath), convpath, go) 67 | else: 68 | exit() 69 | mech_info = mechinc(mech(mechpath), convpath) 70 | cspec_info = go.cspec_info() 71 | tracer_info = go.tracer_info() 72 | profile_info = po.profile_info() 73 | try: 74 | mappings, nprof = map(mech(mechpath), convpath, go, po) 75 | except TypeError as err: 76 | print('No CMAQ namelist found. Check namelist directory.') 77 | exit() 78 | mech_info = (" INTEGER :: NSPC_DFLT = %d\n" % nprof) + mech_info 79 | out = os.path.join(out, 'MAPPING') 80 | open('%s.MECH' % out, 'w').write(mech_info) 81 | open('%s.CSPEC' % out, 'w').write(cspec_info) 82 | open('%s.TRACER' % out, 'w').write(tracer_info) 83 | open('%s.MAP' % out, 'w').write(mappings) 84 | open('%s.PROFILE' % out, 'w').write(profile_info) 85 | 86 | for f in glob(os.path.join(os.path.dirname(__file__), 'fortran_template', '*')): 87 | shutil.copy(f, outdir) 88 | 89 | -------------------------------------------------------------------------------- /testdata/AE_SPC.EXT: -------------------------------------------------------------------------------- 1 | 2 | C RCS file, release, date & time of last delta, author, state, [and locker] 3 | C $Header: /project/work/rep/include/ICL/src/mech/cb05cl_ae5_aq/AE_SPC.EXT,v 1.3 2008/09/09 19:38:42 sjr Exp $ 4 | 5 | C what(1) key, module and SID; SCCS file; date and time of last delta: 6 | C %W% %P% %G% %U% 7 | 8 | C Mechanism Name: CB05CL_AE5_AQ 9 | 10 | INTEGER N_AE_SPC 11 | PARAMETER (N_AE_SPC = 51) 12 | INTEGER N_AE_SPCD 13 | PARAMETER (N_AE_SPCD = N_AE_SPC) 14 | CHARACTER*16 AE_SPC(N_AE_SPCD) 15 | REAL AE_MOLWT(N_AE_SPCD) 16 | 17 | DATA AE_SPC( 1), AE_MOLWT( 1) / 'ASO4J ',96.0 / 18 | DATA AE_SPC( 2), AE_MOLWT( 2) / 'ASO4I ',96.0 / 19 | DATA AE_SPC( 3), AE_MOLWT( 3) / 'ANH4J ',18.0 / 20 | DATA AE_SPC( 4), AE_MOLWT( 4) / 'ANH4I ',18.0 / 21 | DATA AE_SPC( 5), AE_MOLWT( 5) / 'ANO3J ',62.0 / 22 | DATA AE_SPC( 6), AE_MOLWT( 6) / 'ANO3I ',62.0 / 23 | DATA AE_SPC( 7), AE_MOLWT( 7) / 'AALKJ ',150.0 / 24 | DATA AE_SPC( 8), AE_MOLWT( 8) / 'AXYL1J ',192.0 / 25 | DATA AE_SPC( 9), AE_MOLWT( 9) / 'AXYL2J ',192.0 / 26 | DATA AE_SPC( 10), AE_MOLWT( 10) / 'AXYL3J ',192.0 / 27 | DATA AE_SPC( 11), AE_MOLWT( 11) / 'ATOL1J ',168.0 / 28 | DATA AE_SPC( 12), AE_MOLWT( 12) / 'ATOL2J ',168.0 / 29 | DATA AE_SPC( 13), AE_MOLWT( 13) / 'ATOL3J ',168.0 / 30 | DATA AE_SPC( 14), AE_MOLWT( 14) / 'ABNZ1J ',144.0 / 31 | DATA AE_SPC( 15), AE_MOLWT( 15) / 'ABNZ2J ',144.0 / 32 | DATA AE_SPC( 16), AE_MOLWT( 16) / 'ABNZ3J ',144.0 / 33 | DATA AE_SPC( 17), AE_MOLWT( 17) / 'ATRP1J ',168.0 / 34 | DATA AE_SPC( 18), AE_MOLWT( 18) / 'ATRP2J ',168.0 / 35 | DATA AE_SPC( 19), AE_MOLWT( 19) / 'AISO1J ', 96.0 / 36 | DATA AE_SPC( 20), AE_MOLWT( 20) / 'AISO2J ', 96.0 / 37 | DATA AE_SPC( 21), AE_MOLWT( 21) / 'ASQTJ ',378.0 / 38 | DATA AE_SPC( 22), AE_MOLWT( 22) / 'AORGCJ ',177.0 / 39 | DATA AE_SPC( 23), AE_MOLWT( 23) / 'AORGPAJ ',220.0 / 40 | DATA AE_SPC( 24), AE_MOLWT( 24) / 'AORGPAI ',220.0 / 41 | DATA AE_SPC( 25), AE_MOLWT( 25) / 'AECJ ',12.0 / 42 | DATA AE_SPC( 26), AE_MOLWT( 26) / 'AECI ',12.0 / 43 | DATA AE_SPC( 27), AE_MOLWT( 27) / 'A25J ',200.0 / 44 | DATA AE_SPC( 28), AE_MOLWT( 28) / 'A25I ',200.0 / 45 | DATA AE_SPC( 29), AE_MOLWT( 29) / 'ACORS ',100.0 / 46 | DATA AE_SPC( 30), AE_MOLWT( 30) / 'ASOIL ',100.0 / 47 | DATA AE_SPC( 31), AE_MOLWT( 31) / 'NUMATKN ',1.0 / 48 | DATA AE_SPC( 32), AE_MOLWT( 32) / 'NUMACC ',1.0 / 49 | DATA AE_SPC( 33), AE_MOLWT( 33) / 'NUMCOR ',1.0 / 50 | DATA AE_SPC( 34), AE_MOLWT( 34) / 'SRFATKN ',1.0 / 51 | DATA AE_SPC( 35), AE_MOLWT( 35) / 'SRFACC ',1.0 / 52 | DATA AE_SPC( 36), AE_MOLWT( 36) / 'SRFCOR ',1.0 / 53 | DATA AE_SPC( 37), AE_MOLWT( 37) / 'AH2OJ ',18.0 / 54 | DATA AE_SPC( 38), AE_MOLWT( 38) / 'AH2OI ',18.0 / 55 | DATA AE_SPC( 39), AE_MOLWT( 39) / 'ANAJ ',23.0 / 56 | DATA AE_SPC( 40), AE_MOLWT( 40) / 'ANAI ',23.0 / 57 | DATA AE_SPC( 41), AE_MOLWT( 41) / 'ACLJ ',35.0 / 58 | DATA AE_SPC( 42), AE_MOLWT( 42) / 'ACLI ',35.0 / 59 | DATA AE_SPC( 43), AE_MOLWT( 43) / 'ANAK ',23.0 / 60 | DATA AE_SPC( 44), AE_MOLWT( 44) / 'ACLK ',35.0 / 61 | DATA AE_SPC( 45), AE_MOLWT( 45) / 'ASO4K ',96.0 / 62 | DATA AE_SPC( 46), AE_MOLWT( 46) / 'ANH4K ',18.0 / 63 | DATA AE_SPC( 47), AE_MOLWT( 47) / 'ANO3K ',62.0 / 64 | DATA AE_SPC( 48), AE_MOLWT( 48) / 'AH2OK ',18.0 / 65 | DATA AE_SPC( 49), AE_MOLWT( 49) / 'AISO3J ',162.0 / 66 | DATA AE_SPC( 50), AE_MOLWT( 50) / 'AOLGAJ ',176.4 / 67 | DATA AE_SPC( 51), AE_MOLWT( 51) / 'AOLGBJ ',252.0 / 68 | -------------------------------------------------------------------------------- /both.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from .smv2 import get_cspec 4 | from .tracerinfo import get_tracers 5 | from collections import defaultdict 6 | class geos(defaultdict): 7 | def __init__(self, tracerinfo, smvlog = None): 8 | self.tracer_data = get_tracers(tracerinfo) 9 | keys = list(self.tracer_data.keys()) 10 | keys.sort() 11 | self._tracer_spcs = [self.tracer_data[k]['NAME'] for k in keys] 12 | self._tracer_usage = dict([(t,0) for t in self._tracer_spcs]) 13 | self._tracer_usage = dict([(t,0) for t in self._tracer_spcs]) 14 | self._cspec_spcs = [] 15 | self._cspec_spcs += get_cspec(smvlog) 16 | self._cspec_usage = dict([(t,0) for t in self._cspec_spcs]) 17 | self._aero = False 18 | def tracer_info(self): 19 | out = " INTEGER, PARAMETER :: NSPC_GT = %d\n" % len(self._tracer_spcs) + \ 20 | " CHARACTER( 16 ) :: GT_SPNAME( NSPC_GT ) = ( /\n" 21 | ids = [] 22 | names = [] 23 | for ti, tracer in enumerate(self._tracer_spcs): 24 | names.append(" & '%s'" % tracer.ljust(16)) 25 | ids.append(" INTEGER :: GT_%-16s = %4d" % (tracer, ti + 1)) 26 | out += ",\n".join(names) 27 | out += "\n & /)\n\n" 28 | out += '\n'.join(ids) 29 | out += '\n' 30 | return out 31 | def cspec_info(self): 32 | out = " INTEGER, PARAMETER :: NSPC_GS = %d\n" % len(self._cspec_spcs) + \ 33 | " CHARACTER( 16 ) :: GS_SPNAME( NSPC_GS ) = ( /\n" 34 | names = [] 35 | ids = [] 36 | for ti, tracer in enumerate(self._cspec_spcs): 37 | names.append(" & '%s'" % tracer.ljust(16)) 38 | ids.append(" INTEGER :: GS_%-16s = %d" % (tracer, ti + 1)) 39 | out += ",\n".join(names) 40 | out += "\n & /)\n\n" 41 | out += '\n'.join(ids) 42 | out += '\n' 43 | return out 44 | 45 | def has_tracer(self, key): 46 | return key in self._tracer_spcs 47 | def has_cspec(self, key): 48 | return key in self._cspec_spcs 49 | 50 | def __missing__(self, gkey): 51 | if gkey in self._tracer_spcs: 52 | self._tracer_usage[gkey] += 1 53 | return self.get_tracer(gkey) 54 | elif gkey in self._cspec_spcs: 55 | self._cspec_usage[gkey] += 1 56 | return self.get_cspec(gkey) 57 | else: 58 | raise KeyError('%s not in tracers or cspec\n\ttracer %s\n\tcspec: %s' % (gkey, self._tracer_spcs, self._cspec_spcs)) 59 | def get_tracer(self, key): 60 | out = '(BC1_GT_VERT( 1:N, 1:L, GT_%s ) * 1e6)' % key 61 | tracer_id = self._tracer_spcs.index(key) + 1 62 | tracer_dat = self.tracer_data[tracer_id] 63 | if tracer_dat['C'] > 1 and tracer_dat['MOLWT'] == .012: 64 | out = '(%s / %d)' % (out, tracer_dat['C']) 65 | if self._aero: 66 | out = '(%s * %s / UGMTOPPM(1:N, 1:L))' % (out, tracer_dat['MOLWT'] * 1000.) 67 | return out 68 | def get_cspec(self, key): 69 | out = '(BC1_GS_VERT( 1:N, 1:L, GS_%s ) * MOLTOPPM( 1:N, 1:L))' % key 70 | return out 71 | def check(self): 72 | uts = set([t for t, c in self._tracer_usage.items() if c > 0]) 73 | ts = set([t for t, c in self._tracer_usage.items() if c < 1]) 74 | ucs = set([t for t, c in self._cspec_usage.items() if c > 0]) 75 | cs = set([t for t, c in self._cspec_usage.items() if c < 1]) 76 | cs = set(cs).difference(self._tracer_spcs) 77 | uts =list(uts); uts.sort() 78 | ts =list(ts); ts.sort() 79 | ucs =list(ucs); ucs.sort() 80 | cs =list(cs); cs.sort() 81 | print('Used Tracers: %s' % (' '.join(uts))) 82 | print() 83 | print('Unused Tracers: %s' % (' '.join(ts))) 84 | print() 85 | print('Used CSPEC: %s' % (' '.join(ucs))) 86 | print() 87 | print('Unused CSPEC: %s' % (' '.join(cs))) 88 | print() 89 | def aero(self, aero): 90 | self._aero = aero 91 | 92 | 93 | 94 | 95 | 96 | if __name__ == '__main__': 97 | import unittest 98 | class TestGeos(unittest.TestCase): 99 | def __init__(self, *args, **kwds): 100 | pass 101 | def run(self): 102 | pass 103 | go = geos('/project/inf15w/bar/geos-chem/baseict/tracerinfo.dat', 104 | '/project/inf15w/bar/geos-chem/baseict/smv2.log') 105 | -------------------------------------------------------------------------------- /testdata/AE_cb05tucl_ae6_aq.nml: -------------------------------------------------------------------------------- 1 | ! RCS file, release, date & time of last delta, author, state, [and locker] 2 | ! $Header: /project/work/rep/arc/mechs/MECHS/src/cb05tucl_ae6_aq/AE_cb05tucl_ae6_aq.nml,v 1.2 2011/04/26 17:34:29 sjr Exp $ 3 | 4 | &AE_nml 5 | 6 | n_surr1 = 4, 7 | n_surr2 = 1, 8 | n_ctrl = 4, 9 | 10 | TYPE_HEADER = 11 | 'SPC:MOLWT:EMIS_SUR:EMIS_FAC:DEPV_SUR:DEPV_FAC:SCAV_SUR:SCAV_FAC:ICBC_SUR:ICBC_FAC:A2AQ_SUR:TRNS:DDEP:WDEP:CONC', 12 | TYPE_MATRIX = 13 | 'ASO4J:96:ASO4J:1:VMASSJ:1:SO4_ACCUM:1:::SO4_ACCUM:Yes:Yes:Yes:Yes', 14 | 'ASO4I:96:ASO4I:1:VMASSI:1:SO4_AITKEN:1:::SO4_AITKEN:Yes:Yes:Yes:Yes', 15 | 'ANH4J:18:ANH4J:1:VMASSJ:1:NH4_ACCUM:1:::NH4_ACCUM:Yes:Yes:Yes:Yes', 16 | 'ANH4I:18:::VMASSI:1:NH4_AITKEN:1:::NH4_AITKEN:Yes:Yes:Yes:Yes', 17 | 'ANO3J:62:ANO3J:1:VMASSJ:1:NO3_ACCUM:1:::NO3_ACCUM:Yes:Yes:Yes:Yes', 18 | 'ANO3I:62:ANO3I:1:VMASSI:1:NO3_AITKEN:1:::NO3_AITKEN:Yes:Yes:Yes:Yes', 19 | 'AALKJ:150:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 20 | 'AXYL1J:192:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 21 | 'AXYL2J:192:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 22 | 'AXYL3J:192:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 23 | 'ATOL1J:168:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 24 | 'ATOL2J:168:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 25 | 'ATOL3J:168:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 26 | 'ABNZ1J:144:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 27 | 'ABNZ2J:144:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 28 | 'ABNZ3J:144:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 29 | 'ATRP1J:168:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 30 | 'ATRP2J:168:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 31 | 'AISO1J:96:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 32 | 'AISO2J:96:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 33 | 'ASQTJ:378:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 34 | 'AORGCJ:177:::VMASSJ:1:ORG_ACCUM:1:::AORGC_ACCUM:Yes:Yes:Yes:Yes', 35 | 'APOCJ:220:APOCJ:1:VMASSJ:1:ORG_ACCUM:1:::POA_ACCUM:Yes:Yes:Yes:Yes', 36 | 'APOCI:220:APOCI:1:VMASSI:1:ORG_AITKEN:1:::POA_AITKEN:Yes:Yes:Yes:Yes', 37 | 'APNCOMJ:220:APNCOMJ:1:VMASSJ:1:ORG_ACCUM:1:::POA_ACCUM:Yes:Yes:Yes:Yes', 38 | 'APNCOMI:220:APNCOMI:1:VMASSI:1:ORG_AITKEN:1:::POA_AITKEN:Yes:Yes:Yes:Yes', 39 | 'AECJ:12:AECJ:1:VMASSJ:1:PRI_ACCUM:1:::EC_ACCUM:Yes:Yes:Yes:Yes', 40 | 'AECI:12:AECI:1:VMASSI:1:PRI_AITKEN:1:::EC_AITKEN:Yes:Yes:Yes:Yes', 41 | 'AOTHRJ:200:AOTHRJ:1:VMASSJ:1:PRI_ACCUM:1:::PRI_ACCUM:Yes:Yes:Yes:Yes', 42 | 'AOTHRI:200:AOTHRI:1:VMASSI:1:PRI_AITKEN:1:::PRI_AITKEN:Yes:::', 43 | 'AFEJ:55.8:AFEJ:1:VMASSJ:1:PRI_ACCUM:1:::FE_ACCUM:Yes:Yes:Yes:Yes', 44 | 'AALJ:27:AALJ:1:VMASSJ:1:PRI_ACCUM:1:::PRI_ACCUM:Yes:Yes:Yes:Yes', 45 | 'ASIJ:28.1:ASIJ:1:VMASSJ:1:PRI_ACCUM:1:::PRI_ACCUM:Yes:Yes:Yes:Yes', 46 | 'ATIJ:47.9:ATIJ:1:VMASSJ:1:PRI_ACCUM:1:::PRI_ACCUM:Yes:Yes:Yes:Yes', 47 | 'ACAJ:40.1:ACAJ:1:VMASSJ:1:PRI_ACCUM:1:::CA_ACCUM:Yes:Yes:Yes:Yes', 48 | 'AMGJ:24.3:AMGJ:1:VMASSJ:1:PRI_ACCUM:1:::MG_ACCUM:Yes:Yes:Yes:Yes', 49 | 'AKJ:39.1:AKJ:1:VMASSJ:1:PRI_ACCUM:1:::K_ACCUM:Yes:Yes:Yes:Yes', 50 | 'AMNJ:54.9:AMNJ:1:VMASSJ:1:PRI_ACCUM:1:::MN_ACCUM:Yes:Yes:Yes:Yes', 51 | 'ACORS:100:ACORS:1:VMASSC:1:PRI_COARSE:1:::ANTH_COARSE:Yes:Yes:Yes:Yes', 52 | 'ASOIL:100:ASOIL:1:VMASSC:1:PRI_COARSE:1:::SOIL_COARSE:Yes:Yes:Yes:Yes', 53 | 'NUMATKN:1:NUMATKN:1:VNUMATKN:1:NUM_AITKEN:1:::NUM_AITKEN:Yes:::Yes', 54 | 'NUMACC:1:NUMACC:1:VNUMACC:1:NUM_ACCUM:1:::NUM_ACCUM:Yes:::Yes', 55 | 'NUMCOR:1:NUMCOR:1:VNUMCOR:1:NUM_COARSE:1:::NUM_COARSE:Yes:::Yes', 56 | 'SRFATKN:1:SRFATKN:1:VSRFATKN:1:SRF_AITKEN:1:::SRF_AITKEN:Yes:::Yes', 57 | 'SRFACC:1:SRFACC:1:VSRFACC:1:SRF_ACCUM:1:::SRF_ACCUM:Yes:::Yes', 58 | 'SRFCOR:1:SRFCOR:1:VSRFCOR:1:SRF_COARSE:1:::SRF_COARSE:Yes:::Yes', 59 | 'AH2OJ:18:AH2OJ:1:VMASSJ:1:H2O_ACCUM:1:::H2O_ACCUM:Yes:::Yes', 60 | 'AH2OI:18:AH2OI:1:VMASSI:1:H2O_AITKEN:1:::H2O_AITKEN:Yes:::Yes', 61 | 'ANAJ:23:ANAJ:1:VMASSJ:1:NA_ACCUM:1:::NA_ACCUM:Yes:Yes:Yes:Yes', 62 | 'ANAI:23:ANAI:1:VMASSI:1:NA_AITKEN:1:::NA_AITKEN:Yes:::', 63 | 'ACLJ:35.5:ACLJ:1:VMASSJ:1:CL_ACCUM:1:::CL_ACCUM:Yes:Yes:Yes:Yes', 64 | 'ACLI:35.5:ACLI:1:VMASSI:1:CL_AITKEN:1:::CL_AITKEN:Yes:::Yes', 65 | 'ASEACAT:23.75:ASEACAT:1:VMASSC:1:PRI_COARSE:1:::SEAS_COARSE:Yes:Yes:Yes:Yes', 66 | 'ACLK:35.5:ACLK:1:VMASSC:1:CL_COARSE:1:::CL_COARSE:Yes:Yes:Yes:Yes', 67 | 'ASO4K:96:ASO4K:1:VMASSC:1:SO4_COARSE:1:::SO4_COARSE:Yes:Yes:Yes:Yes', 68 | 'ANH4K:18:::VMASSC:1:NH4_COARSE:1:::NH4_COARSE:Yes:Yes:Yes:Yes', 69 | 'ANO3K:62:ANO3K:1:VMASSC:1:NO3_COARSE:1:::NO3_COARSE:Yes:Yes:Yes:Yes', 70 | 'AH2OK:18:AH2OK:1:VMASSC:1:H2O_COARSE:1:::H2O_COARSE:Yes:::Yes', 71 | 'AISO3J:162:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 72 | 'AOLGAJ:176.4:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes', 73 | 'AOLGBJ:252:::VMASSJ:1:ORG_ACCUM:1:::SOA_ACCUM:Yes:Yes:Yes:Yes' 74 | / 75 | -------------------------------------------------------------------------------- /fortran_template/chem_map.F: -------------------------------------------------------------------------------- 1 | SUBROUTINE CHEM_MAP( NBDY, BC1_GT_VERT, BC1_GS_VERT, BC1_PF_VERT, 2 | & BC2, JDATE, JTIME ) 3 | 4 | C*********************************************************************** 5 | C 6 | C FUNCTION: Converts GEO CTM species to CMAQ/SAPRC species 7 | C concentrations 8 | C 9 | C Apr 2006 -- Sergey L. Napelenok 10 | C Modified to describe GEOS-Chem files provided by Daven Henze 11 | C Jun 2013 -- Farhan H. Akhtar 12 | C Modified to produce initial conditions 13 | C 14 | C KEY SUBROURINES/FUNCTIONS CALLED: 15 | C 16 | C*********************************************************************** 17 | 18 | USE UTILIO_DEFN 19 | USE GEO_DATA 20 | USE CMAQ_DATA 21 | USE PROFILE_DATA 22 | 23 | IMPLICIT NONE 24 | 25 | C..INCLUDE FILES: 26 | 27 | C..ARGUMENTS: 28 | INTEGER, INTENT( IN ) :: NBDY 29 | REAL, INTENT( IN ) :: BC1_GT_VERT( :, :, : ) 30 | REAL, INTENT( IN ) :: BC1_GS_VERT( :, :, : ) 31 | REAL, INTENT( IN ) :: BC1_PF_VERT( :, :, : ) 32 | REAL, INTENT( INOUT ) :: BC2( :, :, : ) 33 | 34 | 35 | C..PARAMETERS: 36 | CHARACTER( 16 ), PARAMETER :: PNAME = 'CHEM_MAP' 37 | 38 | C..EXTERNAL FUNCTIONS: 39 | 40 | C..SAVED LOCAL VARIABLES: None 41 | 42 | C..SCRATCH LOCAL VARIABLES: 43 | INTEGER C, R, L, N, S 44 | INTEGER JDATE 45 | INTEGER JTIME 46 | LOGICAL LERROR 47 | CHARACTER( 6 ) :: XCON ! Type of output 48 | CHARACTER( 16 ) :: INFILE ! Name of met file 49 | 50 | C SLN - add PRES and TA in addition to DENS 51 | REAL, ALLOCATABLE, SAVE :: DENS( :, : ) 52 | REAL, ALLOCATABLE, SAVE :: PRES( :, : ) 53 | REAL, ALLOCATABLE, SAVE :: TA ( :, : ) 54 | 55 | C SLN - conversion factors 56 | REAL :: MOLTOUGM 57 | REAL, ALLOCATABLE, SAVE :: MOLTOPPM( :, : ) 58 | REAL, ALLOCATABLE, SAVE :: UGMTOPPM( :, : ) 59 | 60 | REAL FAC 61 | 62 | LOGICAL, SAVE :: FIRSTCALL = .TRUE. 63 | 64 | C********************************************************************** 65 | N = NBDY 66 | L = NLAYS3D 67 | S = NSPC_CMAQ 68 | 69 | IF( FIRSTCALL )THEN 70 | 71 | FIRSTCALL = .FALSE. 72 | 73 | ALLOCATE( DENS( NBDY, NLAYS3D ), PRES( NBDY, NLAYS3D ), 74 | & TA( NBDY, NLAYS3D ) ) 75 | 76 | ALLOCATE( MOLTOPPM( NBDY, NLAYS3D ), UGMTOPPM( NBDY, NLAYS3D ) ) 77 | 78 | END IF 79 | C********************************************************************** 80 | C Check if initial conditions are requested, set input file accordingly 81 | CALL getenv( 'XCON', XCON ) 82 | 83 | IF ( XCON .EQ. 'ICON' ) THEN 84 | INFILE = 'MET_CRO_3D' 85 | ! IF ( .NOT. OPEN3( INFILE, FSREAD3, PNAME ) ) THEN 86 | ! MSG = 'Could not open ' // INFILE // ' file' 87 | ! ENDIF 88 | ELSE 89 | INFILE = 'MET_BDY_3D' 90 | ! IF ( .NOT. OPEN3( INFILE, FSREAD3, PNAME ) ) THEN 91 | ! MSG = 'Could not open ' // INFILE // ' file' 92 | ! ENDIF 93 | ENDIF 94 | 95 | C********************************************************************** 96 | C read air density from INPUT file (use for unit conversion) 97 | IF(.NOT. INTERPB(INFILE,'DENS', PNAME, JDATE, JTIME, 98 | & N*L, DENS)) then 99 | IF(.NOT. Read3(INFILE,'DENS', ALLAYS3, JDATE, JTIME, DENS)) then 100 | Call m3err(pname, JDATE, JTIME, 101 | & 'Reading DENS from ' // INFILE // ' file', .TRUE.) 102 | endif 103 | Endif 104 | C SLN - read PRES and TA also 105 | IF(.NOT. INTERPB(INFILE,'PRES', PNAME, JDATE, JTIME, 106 | & N*L, PRES)) then 107 | IF(.NOT. Read3(INFILE,'PRES', ALLAYS3, JDATE, JTIME, PRES)) then 108 | Call m3err(pname, JDATE, JTIME, 109 | & 'Reading PRES from ' // INFILE // ' file', .TRUE.) 110 | endif 111 | Endif 112 | IF(.NOT. INTERPB(INFILE,'TA', PNAME, JDATE, JTIME, 113 | & N*L, TA)) then 114 | IF(.NOT. Read3(INFILE,'TA', ALLAYS3, JDATE, JTIME, TA)) then 115 | Call m3err(pname, JDATE, JTIME, 116 | & 'Reading TA from ' // INFILE // ' file', .TRUE.) 117 | endif 118 | Endif 119 | 120 | 121 | 122 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 123 | c Transform GEO species concs to SAPRC species concs 124 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 125 | 126 | c SLN - common conversion factors 127 | 128 | MOLTOPPM( 1:N, 1:L) = ( 1.0E+12 * 8.314 / 6.022E+23 ) 129 | & * TA( 1:N, 1:L) / PRES( 1:N, 1:L) ! used in molecules/cm3 to ppm converstion 130 | 131 | MOLTOUGM = 1.0E+12 / 6.022E+23 ! used in molecules/cm3 to ug/m3 conversion (needs MW) 132 | 133 | UGMTOPPM( 1:N, 1:L) = 8.314 * TA( 1:N, 1:L) / PRES( 1:N, 1:L) 134 | ! used in ug/m3 to ppm conversion (needs MW) 135 | #include 136 | 137 | RETURN 138 | 139 | End SUBROUTINE CHEM_MAP 140 | -------------------------------------------------------------------------------- /fortran_template/vinterp_prof.F: -------------------------------------------------------------------------------- 1 | SUBROUTINE VINTERP_PROF( NEDGES, NLAYS_PROF, NSPC_PROF, 2 | & PROF_LEVS, BC1P, BC2P ) 3 | 4 | C*********************************************************************** 5 | C 6 | C FUNCTION: Does vertical interpolation of layer concentrations for 7 | C default profile 8 | C 9 | C PRECONDITIONS: Assumes vertical cooredinate types are consistent 10 | C 11 | C KEY SUBROUTINES/FUNCTIONS CALLED: 12 | C 13 | C REVISION HISTORY: Created October, 2004 by J Gipson 14 | C 15 | C*********************************************************************** 16 | USE UTILIO_DEFN 17 | USE CMAQ_DATA 18 | 19 | IMPLICIT NONE 20 | 21 | C..INCLUDE FILES: 22 | 23 | C..ARGUMENTS: 24 | 25 | INTEGER, INTENT( IN ) :: NEDGES ! No. of boundary edges 26 | INTEGER, INTENT( IN ) :: NSPC_PROF ! No. of species 27 | INTEGER, INTENT( IN ) :: NLAYS_PROF ! No. of layers 28 | REAL, INTENT( IN ) :: PROF_LEVS( : ) 29 | REAL, INTENT( IN ) :: BC1P( :, :, : ) ! profile conc bndy concs 30 | REAL, INTENT( OUT ) :: BC2P( :, :, : ) ! Interpolated bndy concs 31 | 32 | C..PARAMETERS: 33 | CHARACTER( 16 ), PARAMETER :: PNAME = 'VINTERP_PROF' ! Program Name 34 | LOGICAL, PARAMETER :: L_RATINT = .FALSE. ! Rat Interp flag 35 | 36 | C..EXTERNAL FUNCTIONS: 37 | 38 | C..SAVED LOCAL VARIABLES: 39 | 40 | C..SCRATCH LOCAL VARIABLES: 41 | CHARACTER( 132 ) MSG ! Log message 42 | 43 | INTEGER L ! Loop index for vertical layers 44 | INTEGER N ! Loop index for boundary cells 45 | INTEGER S ! Loop index for species 46 | INTEGER E 47 | 48 | LOGICAL LDEC ! Flag for monotonic decreasing layer levels 49 | LOGICAL LINC ! Flag for monotonic increasing layer levels 50 | 51 | REAL DELY ! Error estimate for conc interpolated by rational func 52 | REAL X3 ! Vertical coordinate used in interpolation 53 | REAL Y ! Interpolated concentration 54 | 55 | 56 | REAL, ALLOCATABLE :: WORKA( : ) ! Work array for conc input 57 | REAL, ALLOCATABLE :: X3_OLD( : ) ! GEO vertical levels 58 | REAL, ALLOCATABLE :: X3_NEW( : ) ! CMAQ vertical levels 59 | 60 | 61 | C********************************************************************** 62 | 63 | 64 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 65 | c Set-up for vertical interpolation using approximated pressures 66 | c Only option currently available 67 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 68 | LDEC = .FALSE. 69 | LINC = .FALSE. 70 | 71 | BC2P = 0.0 72 | 73 | IF( NLAYS3D .EQ. NLAYS_PROF ) THEN 74 | 75 | DO E = 1, NEDGES 76 | DO L = 1, NLAYS3D 77 | DO N = 1, NSPC_PROF 78 | BC2P( L, E, S ) = BC1P( L, E, S ) 79 | ENDDO 80 | ENDDO 81 | 82 | ENDDO 83 | 84 | RETURN 85 | 86 | ENDIF 87 | 88 | ALLOCATE( X3_OLD( NLAYS_PROF ) ) 89 | ALLOCATE( X3_NEW( NLAYS3D ) ) 90 | 91 | 92 | DO L = 1, NLAYS3D 93 | X3_NEW( L ) = 0.5 * ( VGLVS3D ( L ) + VGLVS3D ( L + 1 ) ) 94 | ENDDO 95 | 96 | DO L = 1, NLAYS_PROF 97 | X3_OLD( L ) = 0.5 * ( PROF_LEVS ( L ) + PROF_LEVS ( L + 1 ) ) 98 | ENDDO 99 | 100 | LDEC = .TRUE. 101 | 102 | 103 | 104 | 105 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 106 | c Generic interpolation section; X3_OLD and X3_NEW set above 107 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 108 | ALLOCATE( WORKA( NLAYS_PROF ) ) 109 | 110 | 111 | DO S = 1, NSPC_PROF 112 | 113 | DO N = 1, NEDGES 114 | 115 | DO L = 1, NLAYS_PROF 116 | WORKA( L ) = BC1P( L, N, S ) 117 | ENDDO 118 | 119 | DO L = 1, NLAYS3D 120 | 121 | IF( NLAYS_PROF .EQ. 1 ) THEN 122 | 123 | BC2P( L, N, S ) = WORKA( 1 ) 124 | 125 | ELSE 126 | 127 | X3 = X3_NEW( L ) 128 | 129 | IF( LINC .AND. X3 .LE. X3_OLD( 1 ) ) THEN 130 | BC2P( L, N, S ) = WORKA( 1 ) 131 | ELSEIF( LDEC .AND. X3 .GE. X3_OLD( 1 ) ) THEN 132 | BC2P( L, N, S ) = WORKA( 1 ) 133 | ELSEIF( LINC .AND. X3 .GE. X3_OLD( NLAYS_PROF ) ) THEN 134 | BC2P( L, N, S ) = WORKA( NLAYS_PROF ) 135 | ELSEIF( LDEC .AND. X3 .LE. X3_OLD( NLAYS_PROF ) ) THEN 136 | BC2P( L, N, S ) = WORKA( NLAYS_PROF ) 137 | ELSE 138 | CALL LR_INTERP( L_RATINT, X3_OLD, WORKA, NLAYS_PROF, 139 | & X3, Y, DELY ) 140 | BC2P( L, N, S ) = Y 141 | ENDIF 142 | 143 | ENDIF 144 | 145 | ENDDO 146 | 147 | ENDDO 148 | ENDDO 149 | 150 | DEALLOCATE( WORKA ) 151 | DEALLOCATE( X3_OLD ) 152 | DEALLOCATE( X3_NEW ) 153 | 154 | RETURN 155 | 156 | END 157 | 158 | -------------------------------------------------------------------------------- /fortran_template/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ ! -n ${START_DATE} && ! -n ${STOP_DATE} ]]; then 4 | echo "Usage: START_DATE=CCYYMMDD STOP_DATE=CCYYMMDD [MECHINC=] [PROFILE=] [OUTPATH=] $0" 5 | echo 6 | echo 7 | echo " Required:" 8 | echo " START_DATE First day of boundary condition file \(+%Y%m%d format as defined by GNU coreutils\)" 9 | echo " STOP_DATE Last day of boundary condition file \(format same as START_DATE\)" 10 | echo 11 | echo " Optional:" 12 | echo " MECHINC Path to CMAQ chemical mechanism namelist files \(*.NML\). Defaults to ./" 13 | echo " PROFILE CMAQ formated chemical profile \(i.e., BCON input\). Defaults to ./profile.dat" 14 | echo " XCON Create boundary 'BCON' or initial 'ICON' conditions. Defaults to 'BCON'" 15 | echo " OUTPATH Full path \(directory and file\) for output file to be written to. Defaults to BCON.geos2cmaq.CCYYMMDD.ncf" 16 | echo " GEO_INPUT_PATH Directory path where GEOS-Chem files (BC.CCYYMMDD and BC.CSPEC.CCYYMMDD); defaults to PWD" 17 | echo " MCIP_INPUT_PATH Directory path where CMAQ ready meteorology (METBDY_YYMMDD); defaults to PWD" 18 | echo 19 | exit 20 | fi 21 | echo 22 | echo "Reporting variables used (error for first missing variable)" 23 | echo 24 | echo " START_DATE=${START_DATE?You must provide START_DATE in the format CCYYMMDD.}" 25 | echo " STOP_DATE=${STOP_DATE?You must provide STOP_DATE in the format CCYYMMDD.}" 26 | echo 27 | echo " MECHINC=${MECHINC:=`pwd`/}" 28 | echo " PROFILE=${PROFILE:=`pwd`/profile.dat}" 29 | echo " XCON=${XCON:=BCON}" 30 | echo " OUTPATH=${OUTPATH:=`pwd`/${XCON}.geos2cmaq.${START_DATE}.ncf}" 31 | echo " GEO_INPUT_PATH=${GEO_INPUT_PATH:=`pwd`/}" 32 | echo " MCIP_INPUT_PATH=${MCIP_INPUT_PATH:=`pwd`/}" 33 | 34 | OUTDIR=`dirname $OUTPATH` 35 | 36 | # Set output directory to current working directory; Make directory if necessary 37 | mkdir -p ${OUTDIR} 38 | 39 | # Set output file environmental variable using a name recognized by the executable 40 | export GEO_INPUT_PATH=${GEO_INPUT_PATH} 41 | 42 | # Set output file environmental variable using a name recognized by the executable 43 | export BC_FNAME=${OUTPATH} 44 | 45 | # Set location of profile data using name recognized by executable 46 | export BC_PROFILE=${PROFILE} 47 | 48 | ############################################################# 49 | # Set IOAPI environmental variables 50 | ############################################################# 51 | export EXECUTION_ID=GC2CMAQ 52 | export IOAPI_ISPH=19 53 | export IOAPI_CHECK_HEADERS=Y 54 | 55 | 56 | GC_NML=$MECHINC/GC_*.nml 57 | AE_NML=$MECHINC/AE_*.nml 58 | NR_NML=$MECHINC/NR_*.nml 59 | TR_NML=$MECHINC/Species_Table_TR_0.nml 60 | 61 | ln -s -f $GC_NML gc_matrix.nml 62 | ln -s -f $AE_NML ae_matrix.nml 63 | ln -s -f $NR_NML nr_matrix.nml 64 | ln -s -f $TR_NML tr_matrix.nml 65 | # test for existence of NML files 66 | if [[ ! -e gc_matrix.nml || ! -e ae_matrix.nml || ! -e nr_matrix.nml || ! -e tr_matrix.nml ]]; then 67 | echo 'missing namelist file\(s\)' 68 | echo ${GC_NML} ${AE_NML} ${NR_NML} ${TR_NML} 69 | ls -lhg ${GC_NML} ${AE_NML} ${NR_NML} ${TR_NML} 70 | exit 71 | fi 72 | 73 | export XCON=${XCON} 74 | 75 | CURDATE=${START_DATE} 76 | 77 | if [[ -e "${BC_FNAME}" ]]; then 78 | rm -f "${BC_FNAME}" 79 | fi 80 | 81 | export SDATE=${START_DATE} 82 | export EDATE=${STOP_DATE} 83 | export START_DATE=`date -d "$CURDATE" +"%Y%j"` 84 | export START_TIME="230000" 85 | export STOP_DATE=`date -d "${STOP_DATE}" +"%Y%j"` 86 | export STOP_TIME="010000" 87 | export repair_date=`date -d "$EDATE -1 day" +"%Y%m%d"` 88 | 89 | until [[ $CURDATE > $EDATE ]]; do 90 | thisdate=$CURDATE 91 | thismo=`date -d "$CURDATE" +%m` 92 | thisjdate=`date -d "${thisdate}" +"%Y%j"` 93 | thisdate_nom=`date -d "${thisdate}" +"%y%m%d"` 94 | export MET_BDY_3D=${MCIP_INPUT_PATH}/METBDY3D_${thisdate_nom} 95 | if [[ ! -e $MET_BDY_3D ]]; then 96 | echo "MCIP files ${MET_BDY_3D} could not be found" 97 | echo "MCIP files should be retrieved from ASM prior to running" 98 | exit 99 | fi 100 | if [[ $XCON == 'ICON' ]]; then 101 | export MET_CRO_3D=${MCIP_INPUT_PATH}/METCRO3D_${thisdate_nom} 102 | if [[ ! -e $MET_CRO_3D ]]; then 103 | echo "MCIP files ${MET_CRO_3D} could not be found" 104 | echo "MCIP files should be retrieved from ASM prior to running" 105 | exit 106 | fi 107 | fi 108 | 109 | 110 | export GT_FILE="BC."${thisdate} 111 | export GS_FILE="BC.CSPEC."${thisdate} 112 | if [[ ! -e ${GEO_INPUT_PATH}/${GT_FILE} ]]; then 113 | echo "GEOS file ${GT_FILE} could not be found in ${GEO_INPUT_PATH}" 114 | echo "GEOS BC files should be retrieved prior to running" 115 | exit 116 | fi 117 | export GT_FILE="${GT_FILE}" 118 | if [[ ! -e ${GEO_INPUT_PATH}/${GS_FILE} ]]; then 119 | echo "GEOS file ${GS_FILE} could not be found in ${GEO_INPUT_PATH}" 120 | echo "GEOS BC files should be retrieved prior to running" 121 | exit 122 | fi 123 | export GS_FILE="${GS_FILE}" 124 | export REPAIR="F" 125 | if [[ $thisdate == ${repair_date} ]]; then 126 | export REPAIR="T" 127 | fi 128 | echo $thisdate ${REPAIR} 129 | ./GC2CMAQ.exe >& ${SDATE}_${thisdate}.log 130 | CURDATE=`date -d "$CURDATE +1 day" +%Y%m%d` 131 | done 132 | -------------------------------------------------------------------------------- /fortran_template/CMAQ_DATA.F: -------------------------------------------------------------------------------- 1 | MODULE CMAQ_DATA 2 | 3 | 4 | C************************************************************************ 5 | C 6 | C FUNCTION: Holds CMAQ data for generating BCs for CMAQ from the 7 | C Harvard Global CTM model 8 | C 9 | C Apr 2006 -- Sergey L. Napelenok 10 | C Modified to describe GEOS-Chem files provided by Daven Henze 11 | C 12 | C.................................................................... 13 | 14 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 15 | c Data for SAPRC species derived from GEO fila data 16 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 17 | #include 18 | 19 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 20 | c Data for SAPRC species derived from default clean air profile file 21 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 22 | C INCLUDE FILE: BC_PARMS.EXT 23 | C 24 | C CONTAINS: Dimensioning parameters and data for BCON 25 | C 26 | C DEPENDENT UPON: None 27 | C 28 | C REVISION HISTORY: Prototype created by Jerry Gipson, January, 1998 29 | C Modified by JG May, 1999 to treat PinG concs 30 | C 31 | C...................................................................... 32 | 33 | 34 | c..Dimensioning parameters 35 | INTEGER, PARAMETER :: NROOTS = 5 36 | 37 | INTEGER, PARAMETER :: MXCTMS = 3 ! Max no. of input CTM files 38 | 39 | INTEGER, PARAMETER :: MX_MECHFL_IC = 500 ! Max no. of species 40 | 41 | INTEGER, PARAMETER :: MXCVSP = 20 ! Max no. of terms per species for 42 | 43 | INTEGER, PARAMETER :: MX_INFL_SP = 500 ! Max no. of species in an input file 44 | 45 | INTEGER, PARAMETER :: NTRACERS = 8 ! No. of catalogued tracers 46 | 47 | INTEGER, PARAMETER :: NPILLARS = 10 ! No. of pillars in PinG plume 48 | 49 | 50 | C...........................BC_PARMS.EXT................................. 51 | 52 | 53 | CHARACTER( 16 ), ALLOCATABLE, SAVE :: DFLT_LNAME( : ) 54 | CHARACTER( 16 ), ALLOCATABLE, SAVE :: DFLT_SNAME( : ) 55 | CHARACTER( 16 ), ALLOCATABLE, SAVE :: DFLT_UNITS( : ) 56 | CHARACTER( 16 ), ALLOCATABLE, SAVE :: RQD_SP( : ) 57 | CONTAINS 58 | 59 | SUBROUTINE DEFINE_CMAQ_UNITS() 60 | 61 | USE UTILIO_DEFN 62 | USE CGRID_SPCS 63 | 64 | IMPLICIT NONE 65 | 66 | INTEGER :: IND, V 67 | CHARACTER( 132 ) :: XMSG 68 | CHARACTER( 18 ) :: PNAME = 'DEFINE_CMAQ_UNITS' 69 | LOGICAL :: FOUND_SPCS, EFLAG 70 | 71 | IND = 0 72 | CMAQ_LNAME( 1: NSPC_CMAQ ) = CMAQ_SNAME( 1:NSPC_CMAQ ) 73 | 74 | EFLAG = .FALSE. 75 | 76 | XMSG = 'IND CMAQ_LNAME CMAQ_UNITS ' 77 | CALL M3MESG( XMSG ) 78 | 79 | DO V = 1, NSPC_CMAQ 80 | 81 | IND = IND + 1 82 | 83 | CMAQ_UNITS( IND ) = 'ppmV' 84 | 85 | FOUND_SPCS = .TRUE. 86 | 87 | IF(INDEX1(CMAQ_LNAME( V ), N_GC_SPC, GC_SPC) .GT. 0)THEN 88 | WRITE( XMSG, 5001 )IND, CMAQ_LNAME( IND ), CMAQ_UNITS( IND ) 89 | CALL M3MESG( XMSG ) 90 | CYCLE 91 | ELSEIF(INDEX1(CMAQ_LNAME( V ), N_NR_SPC, NR_SPC) .GT. 0)THEN 92 | WRITE( XMSG, 5001 )IND, CMAQ_LNAME( IND ), CMAQ_UNITS( IND ) 93 | CALL M3MESG( XMSG ) 94 | CYCLE 95 | ELSEIF(INDEX1( CMAQ_LNAME( V ), N_TR_SPC, TR_SPC ) .GT. 0)THEN 96 | WRITE( XMSG, 5001 )IND, CMAQ_LNAME( IND ), CMAQ_UNITS( IND ) 97 | CALL M3MESG( XMSG ) 98 | CYCLE 99 | END IF 100 | 101 | IF( INDEX1( CMAQ_LNAME( V ), N_AE_SPC, AE_SPC ) .GT. 0 )THEN 102 | IF ( CMAQ_LNAME( V )( 1:3 ) .EQ. 'NUM' ) THEN 103 | CMAQ_UNITS( IND ) = '#/m**3' 104 | ELSEIF ( CMAQ_LNAME( V )( 1:3 ) .EQ. 'SRF' ) THEN 105 | CMAQ_UNITS( IND ) = 'm**2/m**3' 106 | ELSE 107 | CMAQ_UNITS( IND ) = 'micrograms/m**3' 108 | END IF 109 | ELSE 110 | FOUND_SPCS = .FALSE. 111 | XMSG = 'CMAQ_SNAME ' // TRIM( CMAQ_SNAME( V ) ) 112 | & // ' not found in mechanism namelists.' 113 | CALL M3MESG( XMSG ) 114 | END IF 115 | 116 | IF( .NOT. FOUND_SPCS )THEN 117 | EFLAG = .TRUE. 118 | ELSE 119 | WRITE( XMSG, 5001 )IND, CMAQ_LNAME( IND ), CMAQ_UNITS( IND ) 120 | CALL M3MESG( XMSG ) 121 | END IF 122 | 123 | END DO 124 | 125 | IF( EFLAG )THEN 126 | XMSG = 'Inconsistencies between CMAQ Species ' 127 | & // 'and Namelists' 128 | CALL M3ERR( PNAME, 0, 0, XMSG, .TRUE. ) 129 | END IF 130 | 131 | RETURN 132 | 5001 FORMAT(I3,1X,A16,1X,A16) 133 | END SUBROUTINE DEFINE_CMAQ_UNITS 134 | 135 | END MODULE CMAQ_DATA 136 | -------------------------------------------------------------------------------- /fortran_template/lat_lon.F: -------------------------------------------------------------------------------- 1 | C*********************************************************************** 2 | C Portions of Models-3/CMAQ software were developed or based on * 3 | C information from various groups: Federal Government employees, * 4 | C contractors working on a United States Government contract, and * 5 | C non-Federal sources (including research institutions). These * 6 | C research institutions have given the Government permission to * 7 | C use, prepare derivative works, and distribute copies of their * 8 | C work in Models-3/CMAQ to the public and to permit others to do * 9 | C so. EPA therefore grants similar permissions for use of the * 10 | C Models-3/CMAQ software, but users are requested to provide copies * 11 | C of derivative works to the Government without restrictions as to * 12 | C use by others. Users are responsible for acquiring their own * 13 | C copies of commercial software associated with Models-3/CMAQ and * 14 | C for complying with vendor requirements. Software copyrights by * 15 | C the MCNC Environmental Modeling Center are used with their * 16 | C permissions subject to the above restrictions. * 17 | C*********************************************************************** 18 | 19 | C RCS file, release, date & time of last delta, author, state, [and locker] 20 | C $Header: /project/work/rep/BCON/src/driver/bcon/lat_lon.F,v 1.3 2002/04/12 14:19:19 yoj Exp $ 21 | 22 | C what(1) key, module and SID; SCCS file; date and time of last delta: 23 | C %W% %P% %G% %U% 24 | 25 | 26 | SUBROUTINE LAT_LON( COL, ROW, GDTYP, XORIG, YORIG, XCELL, YCELL, 27 | & XCENT, YCENT, P_ALP, P_BET, P_GAM, LAT, LON ) 28 | 29 | 30 | C************************************************************************* 31 | C 32 | C FUNCTION: Computes latitude and longitude of center of grid cells 33 | C 34 | C PRECONDITIONS: None 35 | C 36 | C KEY SUBROUTINES/FUNCTIONS CALLED: SETLAM 37 | C LAM2LL 38 | C UTM2LL 39 | C 40 | C REVISION HISTORY: Modified form of LAT_LON program originally created 41 | C by C. J. Coats -- Jerry Gipson, January 1998 42 | C************************************************************************* 43 | IMPLICIT NONE 44 | 45 | C..INCLUDE FILES: 46 | INCLUDE "PARMS3.EXT" 47 | 48 | C..ARGUMENTS: 49 | INTEGER GDTYP ! Grid type 50 | INTEGER COL ! No. of columns 51 | INTEGER ROW ! No. of rows 52 | 53 | REAL( 8 ) P_ALP ! 1st map projection parameter 54 | REAL( 8 ) P_BET ! 2nd map projection parameter 55 | REAL( 8 ) P_GAM ! 3rd map projection parameter 56 | 57 | REAL( 8 ) XCELL ! X-dimension of cell (m) 58 | REAL( 8 ) XCENT ! Longitude of coordinate system center 59 | REAL( 8 ) XORIG ! X-origin of grid 60 | REAL( 8 ) YCELL ! Y-dimension of cell (m) 61 | REAL( 8 ) YCENT ! Latitude of coordinate system center 62 | REAL( 8 ) YORIG ! Y-origin of grid 63 | 64 | REAL LAT ! Output latitude 65 | REAL LON ! Output longitude 66 | 67 | C..PARAMETERS: None 68 | 69 | C..EXTERNAL FUNCTIONS: 70 | LOGICAL SETLAM ! Sets up Lambert projection 71 | LOGICAL LAM2LL ! Gets Lat/lons of Lambert projection 72 | 73 | C..SAVED LOCAL VARIABLES: None 74 | 75 | C..SCRATCH LOCAL VARIABLES: 76 | CHARACTER( 16 ) PNAME ! Program Name 77 | CHARACTER( 132 ) MSG ! Log message 78 | 79 | INTEGER ZONE ! UTM zone 80 | 81 | REAL X, X0 ! X-dimension origin 82 | REAL Y, Y0 ! Y-dimension origin 83 | 84 | C********************************************************************** 85 | DATA PNAME /'LAT_LON' / 86 | 87 | X0 = XORIG - 0.5D+00 * XCELL 88 | Y0 = YORIG - 0.5D+00 * YCELL 89 | 90 | IF( GDTYP .EQ. LATGRD3 ) THEN ! LAT_LON Coordinates 91 | 92 | LAT = Y0 + FLOAT( ROW ) * YCELL 93 | LON = X0 + FLOAT( COL ) * XCELL 94 | 95 | ELSEIF( GDTYP .EQ. LAMGRD3 ) THEN ! Lambert Coordinates 96 | 97 | IF( .NOT. SETLAM( SNGL( P_ALP ), ! first, initialize 98 | & SNGL( P_BET ), ! for LAM2LL() 99 | & SNGL( P_GAM ), 100 | & SNGL( XCENT ), 101 | & SNGL( YCENT ) ) ) THEN 102 | MSG = 'Lambert projection setup error for CTM CONC file' 103 | CALL M3EXIT( PNAME, 0, 0, MSG, XSTAT2 ) 104 | ENDIF 105 | 106 | X = X0 + FLOAT( COL ) * XCELL 107 | Y = Y0 + FLOAT( ROW ) * YCELL 108 | IF( .NOT. LAM2LL( X, Y, LON, LAT ) ) THEN 109 | MSG = 'Lambert conversion error for CTM CONC file' 110 | CALL M3EXIT( PNAME, 0, 0, MSG, XSTAT2 ) 111 | ENDIF 112 | 113 | ELSEIF ( GDTYP .EQ. UTMGRD3 ) THEN ! UTM Coordinates 114 | 115 | ZONE = NINT( P_ALP ) 116 | X = X0 + FLOAT( COL ) * XCELL 117 | Y = Y0 + FLOAT( ROW ) * YCELL 118 | 119 | CALL UTM2LL( X, Y, ZONE, LON, LAT ) 120 | 121 | ELSE ! Unsupported Coordinates 122 | 123 | CALL M3EXIT( PNAME, 0, 0, MSG, XSTAT2 ) 124 | 125 | ENDIF 126 | 127 | RETURN 128 | 129 | C************************* FORMAT STATEMENTS *************************** 130 | 131 | 94000 FORMAT( 'LAT/LON calculations for GDTYP3D ',I1, ' not supported' ) 132 | 133 | END 134 | 135 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # geos2cmaq 2 | 3 | GEOS2CMAQ maps GEOS-Chem outputs to CMAQ boundary conditions for any chemical mechanism. 4 | 5 | ## Introduction 6 | 7 | The GEOS2CMAQ tool is an advanced chemical mapping and interpolation tool which allows users to 8 | convert hourly GEOS-Chem output into CMAQ-ready boundary condition files. The tool provides a 9 | flexible mechanism for relating GEOS-Chem chemical species to a variety of chemical and aerosol 10 | mechanisms. 11 | 12 | Required input files 13 | 14 | 1. GEOS-Chem output: Both GEOS-Chem “tracers” and “chemical species” are used in the mapping lists provided with this tool. The US EPA has archived several GEOS-Chem runs from 2001-2010. These files can be provided to users as necessary. Please contact Farhan Akhtar or Barron Henderson for more details on how to receive these files. (NOTE: GEOS-Chem by default does not write out chemical species concentrations. Please contact [Barron Henderson](mailto:barronh@ufl.edu) for the code updates to output the chemical species from GEOS-Chem) 15 | 1. CMAQ/MCIP METBDY3D file: The tool dynamically regrids the GEOS-Chem output to the desired subdomain by using the grid description provided by these files. 16 | 1. CMAQ namelist files: Users must provide the *.nml files for the CMAQ application. 17 | 1. Chemical Mechanism Mapping files: These files provide the mapping of GEOS-Chem tracers and species to a desired chemical mechanism’s species set. Several default cases are provided with the tool and can be specified at compile time. See re-compiling the code for more details on the provided chemical mappings and how to specify alternative mappings. 18 | 19 | ## Installation 20 | 21 | ### Download location and software requirements 22 | 23 | The tool requires libraries for python (with numpy and matplotlib), netcdf and ioapi (with m3utilio) to be installed on the host system. 24 | 25 | Users can download the code directory at the following location using wget: 26 | 27 | 1. Clicking on https://github.com/barronh/geos2cmaq/archive/master.zip 28 | 2. Using git clone: `git clone https://github.com/barronh/geos2cmaq` 29 | 30 | This package includes the FORTRAN-based regridder and python pre-processor. 31 | Verify installation (recommended but optional) 32 | 33 | Users can download a test run directory from the following address: 34 | https://www.dropbox.com/s/ler7ey58bfe96no/testrun.tar.gz?dl=1 35 | 36 | 37 | This test case provides a simple framework for compiling and running the tool on a two day period. It provides a default case for compiling the code and contains a default script for interacting with the tool 38 | (see changing run options for more information). 39 | 40 | Download the version of geos2cmaq used in the test: 41 | https://www.dropbox.com/s/6w9ytecdk46irc1/geos2cmaq.tar.gz?dl=1 42 | 43 | Unzip the downloaded files into a common directory: 44 | 45 | tar -xvf geos2cmaq.tar.gz 46 | tar -xvf testrun.tar.gz 47 | 48 | In the run directory (‘testrun’) open the Makefile.test and update any compile flags as necessary for 49 | your system. Contact your computer support staff with help with this step if the code does not compile. 50 | The tool requires flags for netcdf and ioapi (with m3utilio) to be set in the makefile. 51 | Compile the code and run the test case conversion: 52 | 53 | make -f Makefile 54 | 55 | If the code is installed properly, this command will compile both the python and FORTRAN portions of 56 | the tool, producing a single executable and running the run.sh script for the default period (20050101- 57 | 20050102). Following successful completion, the following files will be available in the rundirectory 58 | folder: 59 | 60 | geos2cmaq.20050101.ncf 61 | geos2cmaq.20050102.ncf 62 | 63 | If these files are not produced or if any error messages are shown on screen, please revisit the compiler 64 | options or contact Barron Henderson for support. 65 | 66 | ## Running the tool 67 | 68 | ### Re-compiling the code: 69 | 70 | Recompilation of the code after installation verification is only necessary when changing the chemical 71 | mechanism from the default case (CB05/AE6). Alternate chemical mechanisms can be specified after the 72 | "-c" flag in the src section of the makefile. Several default mappings are included in the ./mapping folder 73 | in the code directory. Users can also specify the full path to another mapping file, if desired. 74 | 75 | ### Changing Run Options 76 | In the test run directory, the run.sh script can be used to create boundary condition files. The script has 77 | several required and optional variables, as outlined below: 78 | 79 | Usage: START_DATE=CCYYMMDD STOP_DATE=CCYYMMDD [MECHINC=] [PROFILE=] [XCON='XCON'] 80 | [OUTPATH=] [GEO_INPUT_PATH=] [MCIP_INPUT_PATH=] run.sh 81 | (see Makefile.test from testrun for an example) 82 | 83 | Required Variables: 84 | START_DATE First day of boundary condition file (+%Y%m%d format as defined by GNU coreutils) 85 | STOP_DATE Last day of boundary condition file (format same as START_DATE) 86 | Optional Variables: 87 | MECHINC Path to CMAQ chemical mechanism namelist files (*.NML). Defaults to ./ 88 | PROFILE CMAQ formated chemical profile (i.e., BCON input). Defaults to ./profile.dat 89 | XCON Set to BCON for boundary conditions and ICON for initial conditions. Defaults to BCON 90 | OUTPATH Full path (directory and file) for output file to be written to. Defaults to ./geos2cmaq.CCYYMMDD.ncf 91 | GEO_INPUT_PATH Directory path where GEOS-Chem files (BC.CCYYMMDD and BC.CSPEC.CCYYMMDD); defaults to PWD 92 | MCIP_INPUT_PATH Directory path where CMAQ ready meteorology (METBDY_YYMMDD or METCRO3D_YYMMDD); defaults to PWD 93 | 94 | Users can create a wrapper script to iterate across multiple dates if necessary. 95 | 96 | NOTE: The code will list any CMAQ species specified in the namelist file that cannot be found in the 97 | chemical mapping file. If the species exists in the specified CMAQ profile file, it will be mapped and 98 | placed into the output boundary conditions. Please review the lists of mapped species in the log files to 99 | ensure that all species are correctly mapped. 100 | 101 | For more information or questions, please contact developers. 102 | -------------------------------------------------------------------------------- /fortran_template/lr_interp.F: -------------------------------------------------------------------------------- 1 | SUBROUTINE LR_INTERP( L_RATINT, XA, YA, N, X, Y, DELY ) 2 | 3 | C************************************************************************* 4 | C 5 | C FUNCTION: Interpolates a value Y for a given X from the arrays XA and 6 | C YA. The flag L_RATINT determines whether linear or rational 7 | C function interpolation is done. 8 | C 9 | C PRECONDITIONS: Extrapolation will be performed unless controlled by 10 | C the calling routine 11 | C 12 | C KEY SUBROUTINES/FUNCTIONS CALLED: None 13 | C 14 | C REVISION HISTORY: Prototype created by Jerry Gipson, January, 1998 15 | C Rational Function Interpolation is from Numerical 16 | C Recipes (Press et al., 19??) 17 | C Linear interpolation equation modified by JG 5/27/99 18 | C to better treat large conc gradients 19 | C Improved Linear interpolation algorithm by JG 4/18/00 20 | C for interpolants close to interval end points 21 | C 22 | C************************************************************************* 23 | IMPLICIT NONE 24 | 25 | C..INCLUDES: None 26 | 27 | C..ARGUMENTS: 28 | INTEGER N ! Number of values in arrays XA and YA 29 | 30 | LOGICAL L_RATINT ! Flag for rational function interpolation 31 | 32 | REAL DELY ! Error estimate rational function interpolation 33 | REAL X ! Value of independent variable to be interpolated 34 | REAL Y ! Interpolated value of dependent variable 35 | REAL XA( * ) ! Independent variable array 36 | REAL YA( * ) ! Dependent variable array 37 | 38 | C..PARAMETERS: 39 | INTEGER NMAX ! Maximum number of points in arrays AX and YA 40 | PARAMETER ( NMAX = 100 ) 41 | 42 | REAL TINY ! Tiny number 43 | PARAMETER ( TINY = 1.0E-35 ) 44 | 45 | REAL EPS ! Small number 46 | PARAMETER ( EPS = 1.0E-05 ) 47 | 48 | C..EXTERNAL FUNCTIONS: None 49 | 50 | C..SAVED LOCAL VARIABLES: None 51 | 52 | C..SCRATCH LOCAL VARIABLES: 53 | CHARACTER( 16 ) PNAME ! Program Name 54 | CHARACTER( 80 ) MSG ! Log message 55 | 56 | INTEGER I, M ! Loop indices 57 | INTEGER NS ! Rat Func temporary variable 58 | 59 | REAL DX ! Incremental delta of independent variable 60 | c REAL DY ! Incremental delta of dependent variable 61 | REAL SX ! Incremental independent value for interpolation 62 | REAL SLP ! Slope for linear interpolation 63 | 64 | 65 | REAL H, HH, T, DD, W ! Rat Func temporary variables 66 | 67 | REAL C( NMAX ) ! Rat Func temporary variable 68 | REAL D( NMAX ) ! Rat Func temporary variable 69 | 70 | C************************************************************************* 71 | DATA PNAME /'LR_INTERP' / 72 | 73 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 74 | c Linear interpolation section 75 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 76 | IF( .NOT. L_RATINT ) THEN 77 | 78 | DELY = 0.0 79 | 80 | IF( ( XA( 1 ) .LT. XA( 2 ) .AND. X .LE. XA( 1 ) ) .OR. 81 | & ( XA( 1 ) .GT. XA( 2 ) .AND. X .GE. XA( 1 ) ) ) THEN 82 | 83 | DX = XA( 2 ) - XA( 1 ) 84 | 85 | IF( DX .EQ. 0.0 ) THEN 86 | MSG = 'Invalid Independent variables for interpolation' 87 | CALL M3ERR( PNAME, 0 , 0, MSG, .TRUE. ) 88 | ENDIF 89 | 90 | Y = YA( 1 ) + ( ( X - XA( 1 ) ) / DX ) * YA( 1 ) 91 | 92 | RETURN 93 | 94 | ENDIF 95 | 96 | IF( ( XA( N ) .GT. XA( N - 1 ) .AND. X .GE. XA( N ) ) .OR. 97 | & ( XA( N ) .LT. XA( N - 1 ) .AND. X .LE. XA( N ) ) ) THEN 98 | 99 | DX = XA( N ) - XA( N - 1 ) 100 | 101 | IF( DX .EQ. 0.0 ) THEN 102 | MSG = 'Invalid Independent variables for interpolation' 103 | CALL M3ERR( PNAME, 0 , 0, MSG, .TRUE. ) 104 | ENDIF 105 | 106 | Y = YA( N ) + ( ( X - XA( N ) ) / DX ) * YA( N - 1 ) 107 | 108 | RETURN 109 | 110 | ENDIF 111 | 112 | DO I = 1, N - 1 113 | 114 | DX = ABS( XA( I + 1 ) - XA( I ) ) 115 | c DY = YA( I + 1 ) - YA( I ) 116 | SX = ABS( X - XA( I ) ) 117 | 118 | IF ( SX - DX .LT. EPS ) THEN 119 | 120 | IF( DX .EQ. 0.0 ) THEN 121 | MSG = 'Invalid Independent variables for interpolation' 122 | CALL M3ERR( PNAME, 0 , 0, MSG, .TRUE. ) 123 | ENDIF 124 | 125 | c Y = YA( I ) + ( ( X - XA( I ) ) / 126 | c & ( XA( I + 1 ) - XA( I ) ) ) * DY 127 | 128 | SLP = ( X - XA( I ) ) / ( XA( I + 1 ) - XA( I ) ) 129 | IF( SLP .GT. 0.99999 ) SLP = 1.0 130 | IF( SLP .LT. 0.00001 ) SLP = 0.0 131 | 132 | Y = ( 1.0 - SLP ) * YA( I ) + SLP * YA( I + 1 ) 133 | 134 | RETURN 135 | 136 | ENDIF 137 | 138 | ENDDO 139 | 140 | MSG = 'No interval found for linear interpolation' 141 | CALL M3ERR( PNAME, 0 , 0, MSG, .TRUE. ) 142 | 143 | ENDIF 144 | 145 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 146 | c Rational function interpolation section 147 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 148 | NS = 1 149 | HH = ABS( X - XA( 1 ) ) 150 | 151 | DO I = 1, N 152 | H = ABS( X -XA( I ) ) 153 | IF( H .EQ. 0. )THEN 154 | Y = YA( I ) 155 | DELY = 0.0 156 | RETURN 157 | ELSEIF ( H .LT. HH ) THEN 158 | NS = I 159 | HH = H 160 | ENDIF 161 | C( I ) = YA( I ) 162 | D( I ) = YA( I ) + TINY 163 | ENDDO 164 | 165 | Y = YA( NS ) 166 | NS = NS - 1 167 | 168 | DO M = 1, N - 1 169 | DO I = 1, N - M 170 | W = C( I + 1 ) - D( I ) 171 | H = XA( I + M ) - X 172 | T = ( XA( I ) - X ) * D( I ) / H 173 | DD = T - C( I + 1 ) 174 | 175 | IF( DD .EQ. 0. ) THEN 176 | MSG = 'Rational function interpolation error' 177 | CALL M3ERR( PNAME, 0 , 0, MSG, .TRUE. ) 178 | ENDIF 179 | DD = W / DD 180 | D( I ) = C( I + 1 ) * DD 181 | C( I ) = T * DD 182 | ENDDO 183 | 184 | IF( 2 * NS .LT. N - M )THEN 185 | DELY = C( NS + 1 ) 186 | ELSE 187 | DELY = D( NS ) 188 | NS = NS - 1 189 | ENDIF 190 | 191 | Y = Y + DELY 192 | 193 | ENDDO 194 | 195 | RETURN 196 | 197 | END 198 | -------------------------------------------------------------------------------- /fortran_template/vinterp.F: -------------------------------------------------------------------------------- 1 | SUBROUTINE VINTERP( LOGUNIT, NBDY, BDY_GEO, NSPC_GEO, BDY1 ) 2 | 3 | C*********************************************************************** 4 | C 5 | C FUNCTION: Does vertical interpolation of layer concentrations 6 | C 7 | C PRECONDITIONS: Assumes species order listed in HGCTM_DATA module 8 | C 9 | C KEY SUBROUTINES/FUNCTIONS CALLED: 10 | C 11 | C REVISION HISTORY: Created October, 2004 by J Gipson using parts of 12 | C the geos2cmaq BCON program originally created 13 | C by Nankyoung Moon IMAQS, University of Houston, 14 | C November, 2002; also uses parts of CMAQ BCON 15 | C pre-processor 16 | C 17 | C*********************************************************************** 18 | USE UTILIO_DEFN 19 | USE GEO_DATA 20 | USE CMAQ_DATA 21 | 22 | IMPLICIT NONE 23 | 24 | C..INCLUDE FILES: 25 | 26 | C..ARGUMENTS: 27 | 28 | INTEGER LOGUNIT ! Unit number for output log 29 | INTEGER NBDY ! No. of boundary cells 30 | 31 | INTEGER NSPC_GEO 32 | 33 | REAL BDY_GEO( NBDY, N_GEO_LAYS, NSPC_GEO ) ! GEO conc bndy concs 34 | REAL BDY1( NBDY, NLAYS3D, NSPC_GEO ) ! Interpolated bndy concs 35 | 36 | C..PARAMETERS: 37 | CHARACTER( 16 ), PARAMETER :: PNAME = 'VINTERP' ! Program Name 38 | LOGICAL, PARAMETER :: L_INT_BY_PRESS = .TRUE. ! Interp flag 39 | LOGICAL, PARAMETER :: L_RATINT = .FALSE. ! Rat Interp flag 40 | 41 | REAL, PARAMETER :: PREF = 1000.0 ! Ref sfc press 42 | 43 | C..EXTERNAL FUNCTIONS: 44 | 45 | C..SAVED LOCAL VARIABLES: 46 | 47 | C..SCRATCH LOCAL VARIABLES: 48 | CHARACTER*80 MSG ! Log message 49 | 50 | INTEGER L ! Loop index for vertical layers 51 | INTEGER N ! Loop index for boundary cells 52 | INTEGER S ! Loop index for species 53 | INTEGER NLAYS2USE ! No. og GEO layers to use in interpolation 54 | 55 | LOGICAL LDEC ! Flag for monotonic decreasing layer levels 56 | LOGICAL LINC ! Flag for monotonic increasing layer levels 57 | 58 | REAL DELY ! Error estimate for conc interpolated by rational func 59 | REAL PSTAR ! Ref press minus top press 60 | REAL X3 ! Vertical coordinate used in interpolation 61 | REAL Y ! Interpolated concentration 62 | 63 | REAL CMAQ_PRESS( NLAYS3D + 1 ) 64 | REAL GEO_PRESS( N_GEO_LAYS + 1 ) 65 | 66 | REAL, ALLOCATABLE :: WORKA( : ) ! Work array for conc input 67 | REAL, ALLOCATABLE :: X3_OLD( : ) ! GEO vertical levels 68 | REAL, ALLOCATABLE :: X3_NEW( : ) ! CMAQ vertical levels 69 | 70 | 71 | C********************************************************************** 72 | 73 | 74 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 75 | c Set-up for vertical interpolation using approximated pressures 76 | c Only option currently available 77 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 78 | LDEC = .FALSE. 79 | LINC = .FALSE. 80 | 81 | IF( L_INT_BY_PRESS ) THEN 82 | 83 | c..set CMAQ pressure levels assuming PREF 84 | PSTAR = PREF - VGTOP3D * 0.01 85 | DO L = 1, NLAYS3D + 1 86 | CMAQ_PRESS( L ) = VGLVS3D( L ) * PSTAR + VGTOP3D * 0.01 87 | ENDDO 88 | 89 | 90 | c..set GEO pressure levels assuming PREF 91 | PSTAR = PREF - GEO_TOP 92 | DO L = 1, N_GEO_LAYS + 1 93 | GEO_PRESS( L ) = GEO_SIGMA( L ) * PSTAR + GEO_TOP 94 | ENDDO 95 | 96 | c..Do the interpolation 97 | NLAYS2USE = N_GEO_LAYS 98 | c NLAYS2USE = 5 99 | ALLOCATE( WORKA( NLAYS2USE ) ) 100 | ALLOCATE( X3_OLD( NLAYS2USE ) ) 101 | ALLOCATE( X3_NEW( NLAYS3D ) ) 102 | 103 | 104 | DO L = 1, NLAYS2USE 105 | X3_OLD( L ) = 0.5 * ( GEO_PRESS( L ) + GEO_PRESS( L + 1 ) ) 106 | ENDDO 107 | 108 | DO L = 1, NLAYS3D 109 | X3_NEW( L ) = 0.5 * ( CMAQ_PRESS( L ) + CMAQ_PRESS( L + 1 ) ) 110 | ENDDO 111 | 112 | LDEC = .TRUE. 113 | 114 | ENDIF 115 | 116 | c WRITE( LOGUNIT, 92000 ) GEO_TOP, PREF, PSTAR 117 | c WRITE( LOGUNIT, 92010 ) NLAYS2USE 118 | c WRITE( LOGUNIT, 92080 ) 119 | c DO L = 1, N_GEO_LAYS + 1 120 | c WRITE( LOGUNIT, 92020 ) L-1, GEO_SIGMA( L ), GEO_PRESS(L) 121 | c ENDDO 122 | 123 | 124 | c WRITE( LOGUNIT, 92040 ) 0.01 * VGTOP3D, PREF, PSTAR 125 | c WRITE( LOGUNIT, 92080 ) 126 | c DO L = 1, NLAYS3D + 1 127 | c WRITE( LOGUNIT, 92060 ) L-1, VGLVS3D( L ), CMAQ_PRESS( L ) 128 | c ENDDO 129 | 130 | 131 | 132 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 133 | c Generic interpolation section; X3_OLD and X3_NEW must have been set 134 | c above; normally they would be set to pressures, heights, or sigma 135 | c levels 136 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 137 | DO S = 1, NSPC_GEO 138 | 139 | DO N = 1, NBDY 140 | 141 | DO L = 1, NLAYS2USE 142 | WORKA( L ) = BDY_GEO( N, L, S ) 143 | ENDDO 144 | 145 | DO L = 1, NLAYS3D 146 | 147 | IF( NLAYS2USE .EQ. 1 ) THEN 148 | 149 | BDY1( N, L, S ) = WORKA( 1 ) 150 | 151 | ELSE 152 | 153 | X3 = X3_NEW( L ) 154 | 155 | IF( LINC .AND. X3 .LE. X3_OLD( 1 ) ) THEN 156 | BDY1( N, L, S ) = WORKA( 1 ) 157 | ELSEIF( LDEC .AND. X3 .GE. X3_OLD( 1 ) ) THEN 158 | BDY1( N, L, S ) = WORKA( 1 ) 159 | ELSEIF( LINC .AND. X3 .GE. X3_OLD( NLAYS2USE ) ) THEN 160 | BDY1( N, L, S ) = WORKA( NLAYS2USE ) 161 | ELSEIF( LDEC .AND. X3 .LE. X3_OLD( NLAYS2USE ) ) THEN 162 | BDY1( N, L, S ) = WORKA( NLAYS2USE ) 163 | ELSE 164 | CALL LR_INTERP( L_RATINT, X3_OLD, WORKA, NLAYS2USE, 165 | & X3, Y, DELY ) 166 | BDY1( N, L, S ) = Y 167 | ENDIF 168 | 169 | ENDIF 170 | 171 | ENDDO 172 | 173 | ENDDO 174 | ENDDO 175 | 176 | DEALLOCATE( WORKA ) 177 | DEALLOCATE( X3_OLD ) 178 | DEALLOCATE( X3_NEW ) 179 | 180 | RETURN 181 | 182 | 92000 FORMAT( /'GEO Vertical Structure:' 183 | & /2X, 'PTOP=', F10.2, ' PREF=', F10.2, ' PSTAR=', F10.2 ) 184 | 92010 FORMAT( 2X, 'Number of GEO layers used in interpolation = ', I3 ) 185 | 92080 FORMAT( ' Lev Sigma Pressure (mb)' ) 186 | 92020 FORMAT( 2X, I3, F10.5, 5X, F10.2 ) 187 | 92040 FORMAT( /'CMAQ Vertical Structure:' 188 | & /2X, 'PTOP=', F10.2, ' PREF=', F10.2, ' PSTAR=', F10.2 ) 189 | 92060 FORMAT( 2X, I3, F10.5, 5X, F10.2 ) 190 | 191 | END 192 | 193 | -------------------------------------------------------------------------------- /fortran_template/defaults.F: -------------------------------------------------------------------------------- 1 | SUBROUTINE DEFAULTS( LOGUNIT, NBDY, BC3D ) 2 | 3 | C*********************************************************************** 4 | C 5 | C FUNCTION: Gets BCs for species not in GEO files useing CMAQ 6 | C "clean air" default profiles 7 | C 8 | C PRECONDITIONS: 9 | C 10 | C KEY SUBROUTINES/FUNCTIONS CALLED: 11 | C 12 | C REVISION HISTORY: Created October, 2004 by J Gipson 13 | C 14 | C*********************************************************************** 15 | USE GEO_DATA 16 | USE CMAQ_DATA 17 | 18 | IMPLICIT NONE 19 | 20 | C..INCLUDE FILES: 21 | INCLUDE "PARMS3.EXT" 22 | INCLUDE "FDESC3.EXT" 23 | INCLUDE "IODECL3.EXT" 24 | 25 | 26 | C..ARGUMENTS: 27 | INTEGER :: NBDY 28 | INTEGER :: LOGUNIT 29 | REAL :: BC3D( NBDY, NLAYS3D, NSPC_DFLT ) 30 | 31 | C..PARAMETERS: 32 | CHARACTER( 16 ), PARAMETER :: PNAME = 'DEFAULTS' 33 | CHARACTER( 16 ), PARAMETER :: BC_PROFILE = 'BC_PROFILE' 34 | 35 | INTEGER, PARAMETER :: NEDGES = 4 36 | 37 | 38 | C..EXTERNAL FUNCTIONS: 39 | INTEGER GETEFILE 40 | INTEGER INDEX1 41 | 42 | C..SAVED LOCAL VARIABLES: None 43 | 44 | C..SCRATCH LOCAL VARIABLES: 45 | CHARACTER( 256 ) LINEIN ! Input line 46 | CHARACTER( 80 ) MSG ! Log message 47 | CHARACTER( 16 ) SPEC_IN ! 48 | CHARACTER( 5 ) EDGE_IN ! 49 | 50 | CHARACTER( 5 ) :: EDGE_NAME( NEDGES ) = ( / 51 | & 'NORTH' , 52 | & 'EAST ' , 53 | & 'SOUTH' , 54 | & 'WEST ' 55 | & / ) 56 | 57 | INTEGER :: E, L, N, S 58 | INTEGER :: IND, IND2 59 | INTEGER :: PFILE 60 | INTEGER :: JDATE = 0 61 | INTEGER :: JTIME = 0 62 | 63 | INTEGER :: NLAYS_PROF 64 | INTEGER :: NSPC_PROF 65 | 66 | INTEGER :: NORTH, EAST, SOUTH, WEST 67 | 68 | INTEGER :: SW, SE, ES, EN, NW, NE, WS, WN 69 | 70 | LOGICAL :: LRDONLY 71 | LOGICAL :: LFORMTD 72 | LOGICAL :: LERROR 73 | 74 | CHARACTER( 16 ), ALLOCATABLE :: PROF_SP_NAME( : ) 75 | 76 | REAL, ALLOCATABLE :: PROF_LEVS( : ) 77 | 78 | REAL, ALLOCATABLE :: BC1P( : , : , : ) 79 | REAL, ALLOCATABLE :: BC2P( : , : , : ) 80 | REAL, ALLOCATABLE :: BC3P( : , : , : ) 81 | 82 | C********************************************************************** 83 | 84 | 85 | 86 | 87 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 88 | c Open and read the input profile file 89 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 90 | 91 | LRDONLY = .TRUE. 92 | LFORMTD = .TRUE. 93 | PFILE = GETEFILE( BC_PROFILE, LRDONLY, LFORMTD, PNAME ) 94 | IF( PFILE .LT. 0 ) THEN 95 | MSG = 'ERROR: Could not open BC_PROFILE' 96 | CALL M3ERR (PNAME, JDATE, JTIME, MSG, .TRUE. ) 97 | ENDIF 98 | 99 | DO N = 1, 3 100 | READ( PFILE, 94000 ) LINEIN 101 | ENDDO 102 | 103 | READ( PFILE, 94000 ) LINEIN 104 | 105 | write( *, '(A)') LINEIN 106 | 107 | READ( LINEIN, * ) NLAYS_PROF, NSPC_PROF 108 | 109 | ALLOCATE( PROF_LEVS( NLAYS_PROF + 1 ) ) 110 | 111 | READ( LINEIN, * ) NLAYS_PROF, NSPC_PROF, 112 | & ( PROF_LEVS( L ), L = 1, NLAYS_PROF + 1 ) 113 | 114 | 115 | READ( PFILE, 94000 ) LINEIN 116 | 117 | ALLOCATE( BC1P( NEDGES, NLAYS_PROF, NSPC_PROF ) ) 118 | ALLOCATE( PROF_SP_NAME( NSPC_PROF ) ) 119 | 120 | LERROR = .FALSE. 121 | DO E = 1, NEDGES 122 | 123 | READ( PFILE, * ) EDGE_IN 124 | 125 | CALL UPCASE( EDGE_IN ) 126 | 127 | IND = INDEX1( EDGE_IN, NEDGES, EDGE_NAME ) 128 | IF( IND .EQ. 0 ) THEN 129 | MSG = 'ERROR: Invalid edge name: ' // 130 | & EDGE_IN( 1 : LEN_TRIM( EDGE_IN ) ) 131 | CALL M3ERR( PNAME, JDATE, JTIME, MSG, .TRUE. ) 132 | ENDIF 133 | 134 | DO S = 1, NSPC_PROF 135 | READ( PFILE, * ) SPEC_IN, ( BC1P( IND, L, S ), L = 1, NLAYS_PROF ) 136 | IF( E .EQ. 1 ) THEN 137 | PROF_SP_NAME( S ) = SPEC_IN 138 | ELSE 139 | IND2 = INDEX1( SPEC_IN, NSPC_PROF, PROF_SP_NAME ) 140 | IF( IND2 .EQ. 0 ) THEN 141 | WRITE( LOGUNIT, 92000 ) SPEC_IN 142 | LERROR = .TRUE. 143 | ENDIF 144 | ENDIF 145 | 146 | ENDDO 147 | 148 | ENDDO 149 | 150 | IF( LERROR ) THEN 151 | MSG = 'ERROR: Stopping because of inconsistent species names on ' // 152 | & ' profile file ' 153 | CALL M3ERR (PNAME, JDATE, JTIME, MSG, .TRUE. ) 154 | ENDIF 155 | 156 | 157 | CLOSE( PFILE ) 158 | 159 | 160 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 161 | c Vertically interpolate profile concs 162 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 163 | ALLOCATE( BC2P( NEDGES, NLAYS3D, NSPC_PROF ) ) 164 | 165 | CALL VINTERP_PROF( NEDGES, NLAYS_PROF, NSPC_PROF, PROF_LEVS, 166 | & BC1P, BC2P ) 167 | 168 | DEALLOCATE( BC1P ) 169 | 170 | 171 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 172 | c Transform profile species to CMAQ species 173 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 174 | ALLOCATE( BC3P( NEDGES, NLAYS3D, NSPC_DFLT ) ) 175 | 176 | CALL CHEM_MAP_PROF( LOGUNIT, NEDGES, NSPC_PROF, BC2P, BC3P, 177 | & PROF_SP_NAME ) 178 | 179 | DEALLOCATE( BC2P ) 180 | 181 | 182 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 183 | c Assign the edge boundary concs to the cell boundary concs 184 | c Assumes NTHIK=1 185 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 186 | 187 | SW = 1 188 | SE = NCOLS3D + 1 189 | 190 | ES = NCOLS3D + 2 191 | EN = NCOLS3D + NROWS3D + 2 192 | 193 | NW = NCOLS3D + NROWS3D + 3 194 | NE = 2 * NCOLS3D + NROWS3D + 3 195 | 196 | WS = 2 * NCOLS3D + NROWS3D + 4 197 | WN = 2 * ( NCOLS3D + NROWS3D ) + 4 198 | 199 | 200 | SOUTH = INDEX1( 'SOUTH', NEDGES, EDGE_NAME ) 201 | EAST = INDEX1( 'EAST ', NEDGES, EDGE_NAME ) 202 | NORTH = INDEX1( 'NORTH', NEDGES, EDGE_NAME ) 203 | WEST = INDEX1( 'WEST ', NEDGES, EDGE_NAME ) 204 | 205 | L = NLAYS3D 206 | S = NSPC_DFLT 207 | 208 | DO S = 1, NSPC_DFLT 209 | DO L = 1, NLAYS3D 210 | DO N = SW, SE 211 | BC3D( N, L, S ) = BC3P( SOUTH, L, S ) 212 | ENDDO 213 | DO N = ES, EN 214 | BC3D( N, L, S ) = BC3P( EAST, L, S ) 215 | ENDDO 216 | DO N = NW, NE 217 | BC3D( N, L, S ) = BC3P( NORTH, L, S ) 218 | ENDDO 219 | DO N = WS, WN 220 | BC3D( N, L, S ) = BC3P( WEST, L, S ) 221 | ENDDO 222 | ENDDO 223 | ENDDO 224 | 225 | RETURN 226 | 227 | 94000 FORMAT( A ) 228 | 229 | 92000 FORMAT( 'ERROR: Default profile species out of order - ', A ) 230 | END 231 | -------------------------------------------------------------------------------- /v9-01-01.patch: -------------------------------------------------------------------------------- 1 | diff --git a/GeosCore/tpcore_bc_mod.f b/GeosCore/tpcore_bc_mod.f 2 | index e690e87..468efbd 100644 3 | --- a/GeosCore/tpcore_bc_mod.f 4 | +++ b/GeosCore/tpcore_bc_mod.f 5 | @@ -32,6 +32,7 @@ 6 | ! (19b) BC_NA (REAL*4 ) : Array containing NA tracers on coarse grid 7 | ! (19c) BC_EU (REAL*4 ) : Array containing EU tracers on coarse grid 8 | ! (19d) BC_CH (REAL*4 ) : Array containing CH tracers on coarse grid 9 | +! (19e) BC_CP (REAL*4 ) : Array containing NA species on coarse grid 10 | ! (20) MAP1x1 (INTEGER ) : Mapping array from 1x1 -> 4x5 grid 11 | ! 12 | ! Module Routines: 13 | @@ -186,7 +187,8 @@ 14 | REAL*4, ALLOCATABLE :: BC_NA(:,:,:,:) 15 | REAL*4, ALLOCATABLE :: BC_EU(:,:,:,:) 16 | REAL*4, ALLOCATABLE :: BC_CH(:,:,:,:) 17 | - 18 | + !fha 3-3-11 19 | + REAL*4, ALLOCATABLE :: BC_CP(:,:,:,:) 20 | !================================================================= 21 | ! MODULE ROUTINES -- follow below the "CONTAINS" statement 22 | !================================================================= 23 | @@ -246,8 +248,10 @@ 24 | USE BPCH2_MOD, ONLY : OPEN_BPCH2_FOR_READ 25 | USE DIRECTORY_MOD, ONLY : TPBC_DIR, TPBC_DIR_NA 26 | USE DIRECTORY_MOD, ONLY : TPBC_DIR_CH, TPBC_DIR_EU 27 | - USE FILE_MOD, ONLY : IU_BC, IU_BC_NA, IU_BC_EU, IU_BC_CH 28 | + USE FILE_MOD, ONLY : IU_BC, IU_BC_NA, IU_BC_EU, IU_BC_CH 29 | USE TIME_MOD, ONLY : EXPAND_DATE, GET_NYMD, ITS_A_NEW_DAY 30 | + !fha 3-3-11 31 | + USE FILE_MOD, ONLY : IU_BC_CP 32 | 33 | IMPLICIT NONE 34 | 35 | @@ -284,6 +288,8 @@ 36 | FILENAME = TRIM( TPBC_DIR_EU ) // 'BC.YYYYMMDD' 37 | ELSEIF ( WINDOW .eq. 4 ) THEN 38 | FILENAME = TRIM( TPBC_DIR_CH ) // 'BC.YYYYMMDD' 39 | + ELSEIF ( WINDOW .eq. 102 ) THEN 40 | + FILENAME = TRIM( TPBC_DIR_NA ) // 'BC.CSPEC.YYYYMMDD' 41 | ENDIF 42 | 43 | ! Replace YYYYMMDD with the actual date 44 | @@ -311,7 +317,7 @@ 45 | & FILENAME ) 46 | ELSEIF ( WINDOW .eq. 4 ) THEN 47 | IF ( PRESENT( FOR_WRITE ) ) 48 | - & CALL OPEN_BPCH2_FOR_WRITE( IU_BC_CH, 49 | + & CALL OPEN_BPCH2_FOR_WRITE( IU_BC_CP, 50 | & FILENAME ) 51 | ENDIF 52 | 53 | @@ -347,8 +353,12 @@ 54 | USE TRACER_MOD, ONLY : N_TRACERS, STT 55 | USE LOGICAL_MOD, ONLY : LWINDO_CU, LWINDO_NA 56 | USE LOGICAL_MOD, ONLY : LWINDO_CH, LWINDO_EU 57 | + ! fha 3-3-11: write out CSPEC BC conditions 58 | + USE COMODE_MOD, ONLY : CSPEC_FULL 59 | + USE FILE_MOD, ONLY : IU_BC_CP 60 | 61 | # include "CMN_SIZE" ! Size parameters 62 | +# include "comode.h" ! IGAS 63 | 64 | ! Local variables 65 | LOGICAL, SAVE :: FIRST = .TRUE. 66 | @@ -363,6 +373,10 @@ 67 | CHARACTER(LEN=40) :: CATEGORY = 'IJ-AVG-$' 68 | CHARACTER(LEN=40) :: UNIT = 'v/v' 69 | CHARACTER(LEN=40) :: RESERVED = '' 70 | + ! fha 3-3-11 71 | + CHARACTER(LEN=40) :: CATEGOR_S = 'IJ-CHK-$' 72 | + CHARACTER(LEN=40) :: UNIT_S = 'molec/cm3/box' 73 | + 74 | 75 | !================================================================= 76 | ! SAVE_GLOBAL_TPCORE_BC begins here! 77 | @@ -435,6 +449,28 @@ 78 | 79 | ENDDO 80 | 81 | + ! fha 3-3-11: write out CSPEC BC conditions 82 | + CALL OPEN_BC_FILE( FOR_WRITE=.TRUE., WINDOW=102) 83 | + 84 | + ! Loop over each tracer 85 | + DO N = 1, NTSPEC(1) 86 | + 87 | + ! Save concentrations in WINDOW REGION to disk 88 | + DO L = 1, LLPAR 89 | + BC_CP(1:IM_BC_NA,1:JM_BC_NA,L,N) = 90 | + & CSPEC_FULL(I1_BC_NA:I2_BC_NA,J1_BC_NA:J2_BC_NA,L,N) 91 | + ENDDO 92 | + 93 | + ! Write boundary conditions to binary punch file 94 | + CALL BPCH2( IU_BC_CP, MODELNAME, LONRES, LATRES, 95 | + & HALFPOLAR, CENTER180, CATEGOR_S, N, 96 | + & UNIT_S, TAU, TAU, RESERVED, 97 | + & IM_BC_NA, JM_BC_NA, LLPAR, I1_BC_NA, 98 | + & J1_BC_NA, 1, BC_CP(1:IM_BC_NA, 1:JM_BC_NA, 99 | + & 1:LLPAR, N) ) 100 | + 101 | + ENDDO 102 | + 103 | ! Echo info 104 | STAMP = TIMESTAMP_STRING() 105 | WRITE( 6, 111 ) STAMP 106 | @@ -492,6 +528,8 @@ 107 | & 1:LLPAR, N) ) 108 | 109 | ENDDO 110 | + 111 | + 112 | 113 | ! Echo info 114 | STAMP = TIMESTAMP_STRING() 115 | @@ -698,6 +736,8 @@ 116 | DO J = 1, JM_BC_NA 117 | DO I = 1, IM_BC_NA 118 | BC_NA(I,J,L,N) = 0e0 119 | + !fha 3-3-11 120 | + BC_CP(I,J,L,N) = 0e0 121 | ENDDO 122 | ENDDO 123 | ENDDO 124 | @@ -1387,6 +1427,12 @@ 125 | IF ( AS /= 0 ) CALL ALLOC_ERR( 'BC_NA' ) 126 | BC_NA = 0e0 127 | 128 | + !fha 3-3-11 129 | + ALLOCATE( BC_CP( IM_BC_NA, JM_BC_NA, LLPAR, N_TRACERS ) 130 | + & , STAT=AS ) 131 | + IF ( AS /= 0 ) CALL ALLOC_ERR( 'BC_CP' ) 132 | + BC_CP = 0e0 133 | + 134 | ENDIF 135 | 136 | IF ( LWINDO_EU ) THEN 137 | @@ -1468,6 +1514,8 @@ 138 | IF ( ALLOCATED( BC_NA ) ) DEALLOCATE( BC_NA ) 139 | IF ( ALLOCATED( BC_EU ) ) DEALLOCATE( BC_EU ) 140 | IF ( ALLOCATED( BC_CH ) ) DEALLOCATE( BC_CH ) 141 | + !fha 3-3-11 142 | + IF ( ALLOCATED( BC_CP ) ) DEALLOCATE( BC_CP ) 143 | IF ( ALLOCATED( MAP1x1 ) ) DEALLOCATE( MAP1x1 ) 144 | 145 | ! Return to calling program 146 | diff --git a/GeosUtil/file_mod.f b/GeosUtil/file_mod.f 147 | index f6cecf8..fcb9719 100644 148 | --- a/GeosUtil/file_mod.f 149 | +++ b/GeosUtil/file_mod.f 150 | @@ -39,6 +39,7 @@ 151 | INTEGER, PUBLIC, PARAMETER :: IU_BC_NA = 20 ! TPCORE BC files: NA grid 152 | INTEGER, PUBLIC, PARAMETER :: IU_BC_EU = 21 ! TPCORE BC files: EU grid 153 | INTEGER, PUBLIC, PARAMETER :: IU_BC_CH = 22 ! TPCORE BC files: CH grid 154 | + INTEGER, PUBLIC, PARAMETER :: IU_BC_CP = 24 ! TPCORE BC files: NA CSPEC grid 155 | INTEGER, PUBLIC, PARAMETER :: IU_FILE = 65 ! Generic file 156 | INTEGER, PUBLIC, PARAMETER :: IU_TP = 69 ! "YYYYMMDD.tropp.*" 157 | INTEGER, PUBLIC, PARAMETER :: IU_PH = 70 ! "YYYYMMDD.phis.*" 158 | @@ -93,6 +94,7 @@ 159 | ! 15 Mar 2010 - D. Henze - Add IU_OAP for SOA restart file. 160 | ! 19 Aug 2010 - R. Yantosca - Added IU_CN and IU_A1 parameters for MERRA 161 | ! 19 Aug 2010 - R. Yantosca - Remove IU_KZZ 162 | +! 03 Mar 2011 - F. Akhtar - Added file units for IU_BC_CP 163 | !EOP 164 | !------------------------------------------------------------------------------ 165 | !BOC 166 | @@ -386,6 +388,7 @@ 167 | ! 18 Dec 2009 - Aaron van D - Now close files IU_BC_NA, IU_BC_EU, IU_BC_CH 168 | ! 19 Aug 2010 - R. Yantosca - Remove IU_KZZ 169 | ! 19 Aug 2010 - R. Yantosca - Now close IU_A1 170 | +! 03 Mar 2011 - F. Akhtar - Now close IU_BC_CP 171 | !EOP 172 | !------------------------------------------------------------------------------ 173 | !BOC 174 | @@ -406,6 +409,7 @@ 175 | CLOSE( IU_BC_NA ) 176 | CLOSE( IU_BC_EU ) 177 | CLOSE( IU_BC_CH ) 178 | + CLOSE( IU_BC_CP ) 179 | CLOSE( IU_FILE ) 180 | CLOSE( IU_PH ) 181 | CLOSE( IU_TP ) 182 | diff --git a/Headers/define.h b/Headers/define.h 183 | index cdfce94..3bacfe5 100644 184 | --- a/Headers/define.h 185 | +++ b/Headers/define.h 186 | @@ -139,8 +139,8 @@ 187 | !#define GRID05x0666 'GRID05x0666' 188 | !#define GRID1x1 'GRID1x1' 189 | !#define GRID1x125 'GRID1x125' 190 | -!#define GRID2x25 'GRID2x25' 191 | -#define GRID4x5 'GRID4x5' 192 | +#define GRID2x25 'GRID2x25' 193 | +!#define GRID4x5 'GRID4x5' 194 | #define GRIDREDUCED 'GRIDREDUCED' 195 | 196 | !----- Compilers ----- 197 | -------------------------------------------------------------------------------- /plot.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | import pylab as pl 4 | import numpy as np 5 | from warnings import warn 6 | from netCDF4 import MFDataset 7 | from functools import reduce 8 | 9 | 10 | def aqmeiidomain(): 11 | from mpl_toolkits.basemap import Basemap 12 | # From griddesc 13 | aqmeii_proj = {} 14 | aqmeii_proj['llcrnrx'] = -2556000. 15 | aqmeii_proj['llcrnry'] = -1728000. 16 | aqmeii_proj['dx'] = 12000.0 17 | aqmeii_proj['dy'] = 12000.0 18 | aqmeii_proj['nx'] = 459 19 | aqmeii_proj['ny'] = 299 20 | 21 | # Derived 22 | exec('width = nx * dx', None, aqmeii_proj) 23 | exec('height = ny * dy', None, aqmeii_proj) 24 | exec('urcrnrx = llcrnrx + width', None, aqmeii_proj) 25 | exec('urcrnry = llcrnry + height', None, aqmeii_proj) 26 | 27 | cmaqmap = Basemap(rsphere = (6370000., 6370000.),\ 28 | resolution = 'c', projection = 'lcc',\ 29 | lat_1 = 33., lat_2 = 45., lat_0 = 40., lon_0 = -97.,\ 30 | llcrnrx = aqmeii_proj['llcrnrx'], llcrnry = aqmeii_proj['llcrnry'],\ 31 | urcrnrx = aqmeii_proj['urcrnrx'], urcrnry = aqmeii_proj['urcrnry']) 32 | return cmaqmap 33 | 34 | 35 | 36 | def plot(paths, keys = ['O3'], func = 'mean', map = True, prefix = 'BC', scale = 'deciles', minmax = (None, None), minmaxq = (0, 100)): 37 | from pylab import figure, NullFormatter, close, rcParams 38 | rcParams['text.usetex'] = False 39 | from matplotlib.colors import LinearSegmentedColormap, BoundaryNorm, LogNorm 40 | f = MFDataset(paths) 41 | for var_name in keys: 42 | var = eval(var_name, None, f.variables)[:] 43 | if func == 'each': 44 | vars = [(vi, v) for vi, v in enumerate(var)] 45 | else: 46 | vars = [(func, getattr(np, func)(var, axis = 0))] 47 | for func, var in vars: 48 | bmap = None 49 | vmin, vmax = np.percentile(np.ma.compressed(var).ravel(), list(minmaxq)) 50 | if minmax[0] is not None: 51 | vmin = minmax[0] 52 | if minmax[1] is not None: 53 | vmax = minmax[1] 54 | if scale == 'log': 55 | bins = np.logspace(np.log10(vmin), np.log10(vmax), 11) 56 | elif scale == 'linear': 57 | bins = np.linspace(vmin, vmax, 11) 58 | elif scale == 'deciles': 59 | bins = np.percentile(np.ma.compressed(np.ma.masked_greater(np.ma.masked_less(var, vmin), vmax)).ravel(), [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]) 60 | bins[0] = vmin; bins[-1] = vmax 61 | norm = BoundaryNorm(bins, ncolors = 256) 62 | if map: 63 | fig = pl.figure(figsize = (8, 8)) 64 | axmap = fig.add_subplot(3,3,5) 65 | try: 66 | cmaqmap = aqmeiidomain() 67 | cmaqmap.drawcoastlines(ax = axmap) 68 | cmaqmap.drawcountries(ax = axmap) 69 | cmaqmap.drawstates(ax = axmap) 70 | except Exception as e: 71 | warn('An error occurred and no map will be shown:\n%s' % str(e)) 72 | axn = fig.add_subplot(3,3,2, sharex = axmap) 73 | axw = fig.add_subplot(3,3,4, sharey = axmap) 74 | axe = fig.add_subplot(3,3,6, sharey = axmap) 75 | axs = fig.add_subplot(3,3,8, sharex = axmap) 76 | cax = fig.add_axes([.8, .7, .05, .25]) 77 | for ax in [axmap, axe]: 78 | ax.yaxis.set_major_formatter(NullFormatter()) 79 | for ax in [axmap, axn]: 80 | ax.xaxis.set_major_formatter(NullFormatter()) 81 | for ax in [axn, axs]: 82 | ax.set_ylabel('sigma') 83 | for ax in [axe, axw]: 84 | ax.set_xlabel('sigma') 85 | xyfactor = 1 86 | else: 87 | fig = pl.figure(figsize = (16, 4)) 88 | axw = fig.add_subplot(1,4,1) 89 | axn = fig.add_subplot(1,4,2) 90 | axe = fig.add_subplot(1,4,3) 91 | axs = fig.add_subplot(1,4,4) 92 | cax = fig.add_axes([.91, .1, .025, .8]) 93 | axw.set_ylabel('sigma') 94 | 95 | xyfactor = 1e-3 96 | 97 | x = f.NCOLS + 1 98 | y = f.NROWS + 1 99 | X, Y = np.meshgrid(np.arange(x)[1:] * f.XCELL * xyfactor, f.VGLVLS) 100 | patchess = axs.pcolor(X, Y, var[:, :x-1], cmap = bmap, vmin = vmin, vmax = vmax, norm = norm) 101 | if not map: 102 | axs.set_ylim(*axs.get_ylim()[::-1]) 103 | axs.set_xlim(*axs.get_xlim()[::-1]) 104 | axs.set_title('South') 105 | axs.set_xlabel('E to W km') 106 | 107 | X, Y = np.meshgrid(np.arange(x) * f.XCELL * xyfactor, f.VGLVLS) 108 | patchesn = axn.pcolor(X, Y, var[:, x+y:x+y+x], cmap = bmap, vmin = vmin, vmax = vmax, norm = norm) 109 | axn.set_ylim(*axn.get_ylim()[::-1]) 110 | if not map: 111 | axn.set_title('North') 112 | axn.set_xlabel('W to E km') 113 | 114 | if map: 115 | X, Y = np.meshgrid(f.VGLVLS, np.arange(y) * f.YCELL) 116 | patchese = axe.pcolor(X, Y, var[:, x:x+y].swapaxes(0,1), cmap = bmap, vmin = vmin, vmax = vmax, norm = norm) 117 | axe.set_xlim(*axe.get_xlim()[::-1]) 118 | else: 119 | X, Y = np.meshgrid(np.arange(y) * f.YCELL * xyfactor, f.VGLVLS) 120 | patchese = axe.pcolor(X, Y, var[:, x:x+y], cmap = bmap, vmin = vmin, vmax = vmax, norm = norm) 121 | axe.set_ylim(*axe.get_ylim()[::-1]) 122 | axe.set_title('East') 123 | axe.set_xlabel('N to S km') 124 | axe.set_xlim(*axe.get_xlim()[::-1]) 125 | if map: 126 | X, Y = np.meshgrid(f.VGLVLS, np.arange(y) * f.YCELL) 127 | patchesw = axw.pcolor(X, Y, var[:, x+y+x:x+y+x+y].swapaxes(0,1), cmap = bmap, vmin = vmin, vmax = vmax, norm = norm) 128 | else: 129 | X, Y = np.meshgrid(np.arange(y) * f.YCELL * xyfactor, f.VGLVLS) 130 | patchesw = axw.pcolor(X, Y, var[:, x+y+x:x+y+x+y], cmap = bmap, vmin = vmin, vmax = vmax, norm = norm) 131 | axw.set_ylim(*axw.get_ylim()[::-1]) 132 | axw.set_title('West') 133 | axw.set_xlabel('S to N km') 134 | 135 | fig.colorbar(patchesw, cax = cax, boundaries = bins) 136 | fig.savefig('%s_%s_%s.png' % (prefix, var_name, func)) 137 | pl.close(fig) 138 | 139 | if __name__ == '__main__': 140 | from optparse import OptionParser 141 | parser = OptionParser() 142 | parser.set_usage("""Usage: python -m geos2cmaq.plot [-v VAR1,VAR2] [-p prefix] ifile 143 | 144 | ifile - path to a file formatted as type -f 145 | 146 | """) 147 | 148 | parser.add_option("-v", "--variables", dest = "variables", action = "append", default = ["O3"], 149 | help = "Variable names separated by ','") 150 | 151 | parser.add_option("-p", "--prefix", dest = "prefix", type = "string", default = None, 152 | help = "Prefix for figures") 153 | 154 | parser.add_option("-n", "--no-map", dest = "nomap", action = "store_true", default = False, 155 | help = "Try to plot with map") 156 | 157 | parser.add_option("-s", "--scale", dest = "scale", type = "string", default = 'deciles', 158 | help = "Defaults to deciles (i.e., 10 equal probability bins), but linear and log are also options.") 159 | 160 | parser.add_option("", "--minmax", dest = "minmax", type = "string", default = (None, None), 161 | help = "Defaults None, None.") 162 | 163 | parser.add_option("", "--minmaxq", dest = "minmaxq", type = "string", default = '0,100', 164 | help = "Defaults 0,100.") 165 | 166 | parser.add_option("-f", "--time-func", dest = "timefunc", default = "mean", 167 | help = "Use time-func to reduce the time dimension (mean, min, max, std, var, ndarray.__iter__, etc.") 168 | 169 | (options, args) = parser.parse_args() 170 | 171 | if not len(args) > 0: 172 | parser.print_help() 173 | exit() 174 | if options.prefix is None: 175 | options.prefix = args[0] 176 | plot(args, keys = reduce(list.__add__, [v.split(',') for v in options.variables]), map = not options.nomap, prefix = options.prefix, func = options.timefunc, scale = options.scale, minmax = eval(options.minmax), minmaxq = eval(options.minmaxq)) 177 | -------------------------------------------------------------------------------- /overwrite_stratosphere.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import os 4 | import shutil 5 | from glob import glob 6 | from datetime import datetime, timedelta 7 | from warnings import warn 8 | 9 | import numpy as np 10 | from netCDF4 import Dataset 11 | 12 | def copyup(date_start, date_end, bctemp, mettemp, minz = None, maxz = None): 13 | """ 14 | Identifying tropopause following Lam and Fu (doi:10.5194/acp-10-4013-2010) 15 | and using only GEOS-Chem values below or at the tropopause. 16 | """ 17 | if minz is None: 18 | minz = 8000. # based on where clause for equation 2 in Lam and Fu 19 | if maxz is None: 20 | maxz = 19000. # based on where clause for equation 2 in Lam and Fu 21 | 22 | # Require that ozone concentrations be representative 23 | # of the stratosphere Lam and Fu cite McPeters et al. 24 | # (2007, doi:10.1029/2005JD006823). 25 | mino3 = .3 # CMAQ concentrations are in ppmV 26 | 27 | # Decrement the day so that it can be incremented in the loop 28 | date_now = date_start - timedelta(days = 1) 29 | while date_now < date_end: 30 | # Increment the date by 1 day 31 | date_now = date_now + timedelta(days = 1) 32 | 33 | # Find the day specific METBDY file 34 | metpath = mettemp % date_now.strftime('%y%m%d') 35 | bcpathold = bctemp % date_now.strftime('%Y%m%d') 36 | bcpathnew = os.path.basename(bcpathold + '.LamFu') 37 | shutil.copyfile(bcpathold, bcpathnew) 38 | print(bcpathold, metpath, bcpathnew) 39 | bcf = Dataset(bcpathnew, mode = 'r+') 40 | o3 = bcf.variables['O3'] 41 | 42 | # Skip if no values are greater than 300 ppb 43 | o3constraint = o3[:] > mino3 44 | if (o3constraint == False).all(): 45 | warn('Boundary file (%s) has no ozone greater than 300 ppb; max o3=%.f ppb' % (bcpathold, o3.max() * 1000.)) 46 | return 47 | 48 | bctimes = len(bcf.dimensions['TSTEP']) 49 | 50 | metf = Dataset(metpath, 'r') 51 | mettimes = len(metf.dimensions['TSTEP']) 52 | if bctimes < mettimes: 53 | warn('Boundary files has %d times and met has %d times; pairing the first %d values from each file' % (bctimes, mettimes, bctimes)) 54 | 55 | # Get height values for layers. 56 | zf = metf.variables['ZF'][:bctimes] # Read Full Height of layer 57 | zh = metf.variables['ZH'][:bctimes] # Read half height of layer 58 | #zf = np.fromstring('17556 14780 12822 11282 10002 8901 7932 7064 6275 5553 4885 4264 3683 3136 2619 2226 1941 1665 1485 1308 1134 964 797 714 632 551 470 390 311 232 154 115 77 38 19', sep = ' ')[::-1] 59 | #zh = zf - np.diff(np.append(0, zf)) * .5 60 | #zf = zf[None, :, None].repeat(o3.shape[2], 2).repeat(o3.shape[0], 0) 61 | #zh = zh[None, :, None].repeat(o3.shape[2], 2).repeat(o3.shape[0], 0) 62 | # Lowest layer must have a full height (ZF) greater 63 | # than 8km. This could just as easily be half height (ZH) 64 | lowest = np.ma.masked_less(zf, minz).argmin(1) 65 | 66 | # Highest layer cannot have a full height (ZF) greater 67 | # than 8km. This could just as easily be half height (ZH) 68 | highest = np.ma.masked_greater(zf, maxz).argmax(1) 69 | 70 | # Calculate the C_i - C_{i-1} 71 | # for layers max to min+1 72 | do3 = np.diff(o3[:, :], axis = 1) 73 | 74 | # Calculate the Z_i - Z_{i-1} 75 | # for layers max to min+1 76 | # Distance between concentrations is based on half height 77 | dz = np.diff(zh, axis = 1) 78 | 79 | # Calculate the dC/dz 80 | do3dz = do3 / dz 81 | 82 | # Difference between dC(i+1,i)/dH(i+1,i) - dC(i,i-1)/dH(i,i-1) 83 | # Values at surface and at maximum layer are not calculatable 84 | costf = do3dz[:, 1:] - do3dz[:, :-1] 85 | 86 | # Mask (read as reject) any values where the full height 87 | # is lower than the minimum 88 | costf = np.ma.masked_where(zf[:, 1:-1] < minz, costf) 89 | 90 | # If there are no valid points, warn and skip. 91 | if costf.mask.all(): 92 | warn('Cannot copy up. Equation 2 from Lam and Fu (doi:10.5194/acp-10-4013-2010) \nhas no valid solution given the altitude constraints (min=%.f, max%.f).' % (minz, maxz)) 93 | return 94 | 95 | # The maximum layer index (argmax) must be 96 | # incremented by 1 to account for the lack of the 97 | # surface layer in the cost function 98 | id = costf.argmax(1) + 1 99 | 100 | # Triple check that the id is within the acceptable 101 | # boundaries 102 | id = np.where(id > highest, highest, id) 103 | id = np.where(id < lowest, lowest, id) 104 | # Loop over times 105 | for time_idx, timeslice in enumerate(id): 106 | # For each grid-cell in the perimeter 107 | count = 0. 108 | skipcount = 0 109 | writecount = 0 110 | for perim_idx, layv in enumerate(timeslice): 111 | count += 1 112 | if isinstance(layv,np.ndarray): 113 | # if data is multidimensional, iterate over add'l dims 114 | for perim_idx_2, layv_2 in enumerate(layv): 115 | # Check that ozone concentrations are above 300 ppb 116 | destination_vector = o3[time_idx, layv_2+1:, perim_idx, perim_idx_2].copy() 117 | destination_mask = destination_vector > mino3 118 | if not (destination_mask == False).all(): 119 | # Overwrite only those values where ozone is greater than 300ppb 120 | writecount += 1 121 | for di, dv in enumerate(destination_mask): 122 | if dv: o3[time_idx, layv_2+1+di, perim_idx, perim_idx_2] = o3[time_idx, layv_2, perim_idx, perim_idx_2] 123 | assert((o3[time_idx, layv_2+1:, perim_idx, perim_idx_2] != destination_vector).any()) 124 | else: 125 | skipcount += 1 126 | else: 127 | # Check that ozone concentrations are above 300 ppb 128 | destination_vector = o3[time_idx, layv+1:, perim_idx].copy() 129 | destination_mask = destination_vector > mino3 130 | if not (destination_mask == False).all(): 131 | # Overwrite only those values where ozone is greater than 300ppb 132 | writecount += 1 133 | for di, dv in enumerate(destination_mask): 134 | if dv: o3[time_idx, layv+1+di, perim_idx] = o3[time_idx, layv, perim_idx] 135 | assert((o3[time_idx, layv+1:, perim_idx] != destination_vector).any()) 136 | else: 137 | skipcount += 1 138 | bcf.sync() 139 | tflag = '%dT%06d' % tuple(bcf.variables['TFLAG'][time_idx, 0].tolist()) 140 | print('%s, N, Skip Col, Write Col, Skip/Count: %.f %6d %6d %.2f' % (tflag, count, skipcount, writecount, skipcount / count)) 141 | bcf.close() 142 | if __name__ == '__main__': 143 | import sys 144 | try: 145 | args = sys.argv[1:] 146 | if len(args) >= 4: 147 | year_month_day, ndays, bctemp, mettemp = args[:4] 148 | if len(args) == 4: 149 | minz, maxz = None, None 150 | elif len(args) == 6: 151 | minz, maxz = args[4:] 152 | else: 153 | raise ValueError('') 154 | else: 155 | raise ValueError('') 156 | except: 157 | print("""Usage: %s YYYYMMDD NDAYS BCTEMP METTEMP [minz maxz] 158 | 159 | Description: 160 | Identifies tropopause following Lam and Fu (doi:10.5194/acp-10-4013-2010) 161 | and copies troposphere values over any stratosphere values. 162 | 163 | Inputs are METBDY3D files from MCIP and a CMAQ IOAPI boundary file 164 | 165 | Parameters: 166 | - YYYYMMDD is the 4 digit year, 2 digit month and 2 digit day of the start date 167 | - NDAYS is the number of days to operate on (e.g., 1 = just the start date) 168 | - BCTEMP is a template string following printf that can take a date string (e.g. YYYYMMDD) to get a day value 169 | - METTEMP same as BCTEMP for metbdy, but uses two digit year (e.g., YYMMDD) 170 | - minz minimum altitude for the tropopause (based on layer top) (optional) 171 | - maxz minimum altitude for the tropopause (based on layer top) (optional) 172 | 173 | e.g., 174 | 175 | $ %s 176 | """ % (__file__, __file__)) 177 | exit() 178 | date_start = datetime.strptime(year_month_day, '%Y%m%d') 179 | date_end = date_start + timedelta(days = int(ndays) - 1) 180 | copyup(date_start = date_start, date_end = date_end, bctemp = bctemp, mettemp = mettemp, minz = minz, maxz = maxz) 181 | -------------------------------------------------------------------------------- /fortran_template/prof_data.F: -------------------------------------------------------------------------------- 1 | 2 | MODULE PROFILE_DATA 3 | IMPLICIT NONE 4 | REAL, ALLOCATABLE :: BDY_PF( :, :, :) 5 | INTEGER :: NLEVS_IN ! No. of layers in input conc file 6 | INTEGER :: NSPCS_IN ! No. of layers in input conc file 7 | 8 | #include 9 | CONTAINS 10 | 11 | SUBROUTINE LoadPROF(LOGUNIT, NBDY) 12 | USE CMAQ_DATA 13 | USE UTILIO_DEFN 14 | IMPLICIT NONE 15 | 16 | INTEGER, INTENT( IN ) :: LOGUNIT, NBDY 17 | 18 | CHARACTER(16) ENV_DFLT ! Environment variable default value 19 | CHARACTER(80) ENV_DESC ! Environment variable description 20 | CHARACTER(256) LINEIN ! Input line 21 | CHARACTER(80) MSG ! Log message 22 | CHARACTER(16) PROF_UNITS ! Environment variable for units 23 | CHARACTER(16) SPEC_NAME ! Species name 24 | CHARACTER(16) EDGE_IN ! Species name 25 | CHARACTER(16) PROF_SP ! Species name 26 | CHARACTER(256), SAVE :: PROF_FL_NAME ! Input profile file name 27 | 28 | CHARACTER(16), SAVE :: PNAME = 'LoadPROF' ! Program name 29 | CHARACTER(16), SAVE :: BC_PROFILE = 'BC_PROFILE' ! Logical name of input profile file 30 | CHARACTER(16), SAVE :: PUNITS = 'PROF_UNITS' ! Value of units Environment variable 31 | 32 | INTEGER, PARAMETER :: NEDGES = 4 33 | INTEGER NW, NS, NE ! North boundary loop indices 34 | INTEGER SW, SS, SE ! South boundary loop indices 35 | INTEGER WN, WS, WE ! West boundary loop indices 36 | INTEGER EN, ES, EE ! East boundary loop indices 37 | 38 | CHARACTER( 5 ), PARAMETER :: EDGE_NAME( NEDGES ) = ( / 39 | & 'NORTH' , 40 | & 'EAST ' , 41 | & 'SOUTH' , 42 | & 'WEST ' 43 | & / ) 44 | INTEGER, PARAMETER :: NORTH=1, EAST=2, SOUTH=3, WEST=4 ! Must be consistent with EDGE_NAME 45 | REAL VGLVS_IN( MXLAYS3 + 1 ) ! Input vertical levels 46 | INTEGER PFILE ! Unit number of profile file 47 | INTEGER :: N, STATUS, SPC, IND, L, C 48 | 49 | LOGICAL :: LERROR, LNEG ! Error flag 50 | 51 | REAL INPROF( MXLAYS3, 4, MX_INFL_SP ) ! Input conc profiles 52 | REAL, ALLOCATABLE, SAVE :: VIPROF( :, :, : ) ! Vertically interp profiles 53 | 54 | INTERFACE 55 | SUBROUTINE VINTERP_PROF( NEDGES, NLAYS_PROF, NSPC_PROF, 56 | & PROF_LEVS, BC1P, BC2P ) 57 | USE UTILIO_DEFN 58 | USE CMAQ_DATA 59 | IMPLICIT NONE 60 | INTEGER, INTENT( IN ) :: NEDGES ! No. of boundary edges 61 | INTEGER, INTENT( IN ) :: NSPC_PROF ! No. of species 62 | INTEGER, INTENT( IN ) :: NLAYS_PROF ! No. of layers 63 | REAL, INTENT( IN ) :: PROF_LEVS( : ) 64 | REAL, INTENT( IN ) :: BC1P( :, :, : ) ! profile conc bndy concs 65 | REAL, INTENT( OUT ) :: BC2P( :, :, : ) ! Interpolated bndy concs 66 | END SUBROUTINE VINTERP_PROF 67 | END INTERFACE 68 | IF (NSPC_DFLT .EQ. 0) RETURN 69 | ALLOCATE( BDY_PF( NBDY, NLAYS3D, NSPC_PF ) ) 70 | 71 | SS = 1 72 | SE = NCOLS3D + 1 73 | 74 | ES = NCOLS3D + 2 75 | EE = NCOLS3D + NROWS3D + 2 76 | 77 | NS = NCOLS3D + NROWS3D + 3 78 | NE = 2 * NCOLS3D + NROWS3D + 3 79 | 80 | WS = 2 * NCOLS3D + NROWS3D + 4 81 | WN = 2 * ( NCOLS3D + NROWS3D ) + 4 82 | 83 | SW = 1 84 | SE = NCOLS3D + 1 85 | 86 | ES = NCOLS3D + 2 87 | EN = NCOLS3D + NROWS3D + 2 88 | 89 | NW = NCOLS3D + NROWS3D + 3 90 | NE = 2 * NCOLS3D + NROWS3D + 3 91 | 92 | WS = 2 * NCOLS3D + NROWS3D + 4 93 | WN = 2 * ( NCOLS3D + NROWS3D ) + 4 94 | 95 | ENV_DFLT = ' ' 96 | ENV_DESC = 'Input BC Profile file' 97 | CALL ENVSTR( BC_PROFILE, ENV_DESC, ENV_DFLT, PROF_FL_NAME, STATUS) 98 | 99 | IF( STATUS .NE. 0 ) THEN 100 | MSG = 'No BC profile file assigned to BC_PROFILE' 101 | CALL M3ERR( PNAME, 0, 0, MSG, .TRUE. ) 102 | ENDIF 103 | 104 | PFILE = JUNIT() 105 | 106 | #ifdef verbose 107 | WRITE( LOGUNIT, * )TRIM( PNAME ) // ' attempting to open BC_PROFILE ' 108 | & // TRIM( PROF_FL_NAME ) 109 | #endif 110 | 111 | OPEN(UNIT = PFILE, FILE = PROF_FL_NAME, ERR = 999) 112 | 113 | WRITE( LOGUNIT, 92020) PROF_FL_NAME( 1 : 100 ) 114 | REWIND PFILE 115 | DO N = 1, 3 116 | READ( PFILE, 94000 ) LINEIN 117 | #ifdef verbose 118 | WRITE( LOGUNIT, 92040 ) LINEIN 119 | #endif 120 | ENDDO 121 | 122 | READ(PFILE, * )NLEVS_IN, NSPCS_IN 123 | BACKSPACE PFILE 124 | READ(PFILE, * )N, C, (VGLVS_IN( L ), L = 1, NLEVS_IN+1) 125 | #ifdef verbose 126 | WRITE(LOGUNIT, '(i4,1x,i4,50(1x,es12.4))' )NLEVS_IN, NSPCS_IN, (VGLVS_IN( L ), L = 1, NLEVS_IN+1) 127 | #endif 128 | READ( PFILE, 94000 ) LINEIN 129 | WRITE( LOGUNIT, 92040 ) LINEIN 130 | 131 | LERROR = .FALSE. 132 | IF( NLEVS_IN .GT. MXLAYS3 + 1 ) THEN 133 | MSG = 'ERROR: No of layers on profile file exceeds MXLAYS + 1' 134 | WRITE(LOGUNIT, 92080) MSG 135 | LERROR = .TRUE. 136 | ENDIF 137 | 138 | IF( NSPCS_IN .GT. MX_INFL_SP ) THEN 139 | MSG = 'ERROR: No of species profile file exceeds MXINFL_SP' 140 | WRITE( LOGUNIT, 92080 ) MSG 141 | LERROR = .TRUE. 142 | ENDIF 143 | 144 | IF( LERROR ) THEN 145 | MSG = 'Dimension problem in BC profile file' 146 | CALL M3ERR( PNAME, 0, 0, MSG, .TRUE.) 147 | ENDIF 148 | 149 | 150 | DO N = 1, 4 151 | READ( PFILE, * )EDGE_IN 152 | 153 | CALL UPCASE( EDGE_IN ) 154 | 155 | IND = INDEX1( EDGE_IN, NEDGES, EDGE_NAME ) 156 | 157 | DO SPC = 1, NSPCS_IN 158 | READ(PFILE,*)PROF_SP, (INPROF(L, IND, SPC),L = 1, NLEVS_IN) 159 | IF (PROF_SP .NE. PF_SPNAME(SPC)) THEN 160 | MSG = 'Species expected ' // PF_SPNAME(SPC) // '; received ' // PROF_SP 161 | CALL M3ERR( PNAME, 0, 0, MSG, .TRUE.) 162 | ENDIF 163 | #ifdef verbose 164 | WRITE(LOGUNIT,'(i4,1x,a16,50(1x,es12.4))')SPC, PROF_SP, (INPROF(L, IND, SPC),L = 1, NLEVS_IN) 165 | #endif 166 | ENDDO 167 | ENDDO 168 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 169 | 170 | c Do the vertical interpolation 171 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 172 | REWIND PFILE 173 | close(PFILE) 174 | ALLOCATE( VIPROF( NLAYS3D, 4, MX_INFL_SP ) ) 175 | CALL VINTERP_PROF( NEDGES, NLEVS_IN, NSPCS_IN, VGLVS_IN, 176 | & INPROF, VIPROF ) 177 | DO SPC = 1, NSPCS_IN 178 | DO L =1, NLAYS3D 179 | c..South 180 | DO C = SW, SE 181 | BDY_PF( C, 1:NLAYS3D, SPC ) = VIPROF( 1:NLAYS3D, SOUTH, IND ) 182 | ENDDO 183 | c..East 184 | DO C = ES, EN 185 | BDY_PF( C, 1:NLAYS3D, SPC ) = VIPROF( 1:NLAYS3D, EAST, IND ) 186 | ENDDO 187 | c..North 188 | DO C = NW, NE 189 | BDY_PF( C, 1:NLAYS3D, SPC ) = VIPROF( 1:NLAYS3D, NORTH,IND ) 190 | ENDDO 191 | c..West 192 | DO C = WS, WN 193 | BDY_PF( C, 1:NLAYS3D, SPC ) = VIPROF( 1:NLAYS3D, WEST, IND ) 194 | ENDDO 195 | ENDDO 196 | ENDDO 197 | 198 | RETURN 199 | 200 | 999 CONTINUE 201 | 202 | 203 | MSG = 'Could not open file ' // BC_PROFILE 204 | STATUS = 2 205 | CALL M3ERR( PNAME, 0, 0, MSG, .TRUE. ) 206 | 207 | C************************* FORMAT STATEMENTS *************************** 208 | 209 | 92000 FORMAT( // 1X, 79( '#' ) 210 | & / 1X, '# Input file section ' 211 | & / 1X, 79( '#' ) 212 | & // 5X, 'Boundary Concentrations from an input BC profile ', 213 | & 'file.' / 214 | & 5X, 'BCs do not vary with time.' ) 215 | 216 | 92020 FORMAT( //5X, 'Profile file name: ', A 217 | & //5X, 'File contents: ' 218 | & //1X ) 219 | 220 | 221 | 92040 FORMAT( 10X, A100 ) 222 | 223 | 92050 FORMAT( 5X, '---> ', A100 ) 224 | 225 | 92060 FORMAT( //5X, 'End of file contents.') 226 | 227 | 92080 FORMAT( //1X, A ) 228 | 229 | 92200 FORMAT( //5X, 'Profile concentration units assumed to be ppm' ) 230 | 231 | 92220 FORMAT( //5X, 'Profile concentration units assumed to be ppb' ) 232 | 233 | 94000 FORMAT( A ) 234 | 235 | 94020 FORMAT('Negative BC on ',A5,' Edge for ',A16,' at lay = ',I3) 236 | 237 | END SUBROUTINE 238 | END MODULE PROFILE_DATA -------------------------------------------------------------------------------- /testdata/GC_SPC.EXT: -------------------------------------------------------------------------------- 1 | 2 | C RCS file, release, date & time of last delta, author, state, [and locker] 3 | C $Header$ 4 | 5 | C what(1) key, module and SID; SCCS file; date and time of last delta: 6 | C %W% %P% %G% %U% 7 | 8 | C------------------------------------------------------------ 9 | C This file has been generated by code based on UCR-CMAQ-MP3 10 | C------------------------------------------------------------ 11 | C Mechanism Name: SAPRC07TC_AE5_AQ 12 | 13 | INTEGER, PARAMETER :: N_GC_SPC = 120 14 | INTEGER, PARAMETER :: N_GC_SPCD = N_GC_SPC + 1 15 | CHARACTER( 16 ) :: GC_SPC( N_GC_SPCD ) 16 | REAL :: GC_MOLWT( N_GC_SPCD ) 17 | 18 | DATA GC_SPC( 1 ), GC_MOLWT( 1 ) / 'NO2 ', 46 / 19 | DATA GC_SPC( 2 ), GC_MOLWT( 2 ) / 'NO ', 30 / 20 | DATA GC_SPC( 3 ), GC_MOLWT( 3 ) / 'O3P ', 16 / 21 | DATA GC_SPC( 4 ), GC_MOLWT( 4 ) / 'O3 ', 48 / 22 | DATA GC_SPC( 5 ), GC_MOLWT( 5 ) / 'NO3 ', 62 / 23 | DATA GC_SPC( 6 ), GC_MOLWT( 6 ) / 'N2O5 ', 108 / 24 | DATA GC_SPC( 7 ), GC_MOLWT( 7 ) / 'HNO3 ', 63 / 25 | DATA GC_SPC( 8 ), GC_MOLWT( 8 ) / 'O1D ', 16 / 26 | DATA GC_SPC( 9 ), GC_MOLWT( 9 ) / 'OH ', 17 / 27 | DATA GC_SPC( 10 ), GC_MOLWT( 10 ) / 'HONO ', 47 / 28 | DATA GC_SPC( 11 ), GC_MOLWT( 11 ) / 'HO2 ', 33 / 29 | DATA GC_SPC( 12 ), GC_MOLWT( 12 ) / 'CO ', 28 / 30 | DATA GC_SPC( 13 ), GC_MOLWT( 13 ) / 'CO2 ', 44 / 31 | DATA GC_SPC( 14 ), GC_MOLWT( 14 ) / 'HNO4 ', 79 / 32 | DATA GC_SPC( 15 ), GC_MOLWT( 15 ) / 'HO2H ', 34 / 33 | DATA GC_SPC( 16 ), GC_MOLWT( 16 ) / 'SO2 ', 64.1 / 34 | DATA GC_SPC( 17 ), GC_MOLWT( 17 ) / 'SULF ', 98.1 / 35 | DATA GC_SPC( 18 ), GC_MOLWT( 18 ) / 'SULRXN ', 98.1 / 36 | DATA GC_SPC( 19 ), GC_MOLWT( 19 ) / 'NO2EX ', 44 / 37 | DATA GC_SPC( 20 ), GC_MOLWT( 20 ) / 'MEO2 ', 47 / 38 | DATA GC_SPC( 21 ), GC_MOLWT( 21 ) / 'HCHO ', 30 / 39 | DATA GC_SPC( 22 ), GC_MOLWT( 22 ) / 'COOH ', 48 / 40 | DATA GC_SPC( 23 ), GC_MOLWT( 23 ) / 'MEOH ', 32 / 41 | DATA GC_SPC( 24 ), GC_MOLWT( 24 ) / 'RO2C ', 1 / 42 | DATA GC_SPC( 25 ), GC_MOLWT( 25 ) / 'RO2XC ', 1 / 43 | DATA GC_SPC( 26 ), GC_MOLWT( 26 ) / 'MECO3 ', 75 / 44 | DATA GC_SPC( 27 ), GC_MOLWT( 27 ) / 'PAN ', 121.1 / 45 | DATA GC_SPC( 28 ), GC_MOLWT( 28 ) / 'CCOOOH ', 76 / 46 | DATA GC_SPC( 29 ), GC_MOLWT( 29 ) / 'CCOOH ', 60.1 / 47 | DATA GC_SPC( 30 ), GC_MOLWT( 30 ) / 'RCO3 ', 89.1 / 48 | DATA GC_SPC( 31 ), GC_MOLWT( 31 ) / 'PAN2 ', 135.1 / 49 | DATA GC_SPC( 32 ), GC_MOLWT( 32 ) / 'xHO2 ', 33 / 50 | DATA GC_SPC( 33 ), GC_MOLWT( 33 ) / 'yROOH ', 76.1 / 51 | DATA GC_SPC( 34 ), GC_MOLWT( 34 ) / 'xCCHO ', 44.1 / 52 | DATA GC_SPC( 35 ), GC_MOLWT( 35 ) / 'RCOOOH ', 74.1 / 53 | DATA GC_SPC( 36 ), GC_MOLWT( 36 ) / 'RCOOH ', 74.1 / 54 | DATA GC_SPC( 37 ), GC_MOLWT( 37 ) / 'BZCO3 ', 137.1 / 55 | DATA GC_SPC( 38 ), GC_MOLWT( 38 ) / 'PBZN ', 183.1 / 56 | DATA GC_SPC( 39 ), GC_MOLWT( 39 ) / 'BZO ', 93 / 57 | DATA GC_SPC( 40 ), GC_MOLWT( 40 ) / 'MACO3 ', 101.1 / 58 | DATA GC_SPC( 41 ), GC_MOLWT( 41 ) / 'MAPAN ', 147.1 / 59 | DATA GC_SPC( 42 ), GC_MOLWT( 42 ) / 'TBUO ', 73 / 60 | DATA GC_SPC( 43 ), GC_MOLWT( 43 ) / 'RNO3 ', 147.2 / 61 | DATA GC_SPC( 44 ), GC_MOLWT( 44 ) / 'ACETONE ', 58.1 / 62 | DATA GC_SPC( 45 ), GC_MOLWT( 45 ) / 'NPHE ', 139.1 / 63 | DATA GC_SPC( 46 ), GC_MOLWT( 46 ) / 'CRES ', 108.1 / 64 | DATA GC_SPC( 47 ), GC_MOLWT( 47 ) / 'xOH ', 17 / 65 | DATA GC_SPC( 48 ), GC_MOLWT( 48 ) / 'xNO2 ', 46 / 66 | DATA GC_SPC( 49 ), GC_MOLWT( 49 ) / 'xMEO2 ', 47 / 67 | DATA GC_SPC( 50 ), GC_MOLWT( 50 ) / 'xMECO3 ', 75 / 68 | DATA GC_SPC( 51 ), GC_MOLWT( 51 ) / 'xRCO3 ', 89.1 / 69 | DATA GC_SPC( 52 ), GC_MOLWT( 52 ) / 'xMACO3 ', 101.1 / 70 | DATA GC_SPC( 53 ), GC_MOLWT( 53 ) / 'xTBUO ', 73 / 71 | DATA GC_SPC( 54 ), GC_MOLWT( 54 ) / 'xCO ', 28 / 72 | DATA GC_SPC( 55 ), GC_MOLWT( 55 ) / 'CCHO ', 44.1 / 73 | DATA GC_SPC( 56 ), GC_MOLWT( 56 ) / 'RCHO ', 58.1 / 74 | DATA GC_SPC( 57 ), GC_MOLWT( 57 ) / 'xHCHO ', 30 / 75 | DATA GC_SPC( 58 ), GC_MOLWT( 58 ) / 'MEK ', 72.1 / 76 | DATA GC_SPC( 59 ), GC_MOLWT( 59 ) / 'zRNO3 ', 147.2 / 77 | DATA GC_SPC( 60 ), GC_MOLWT( 60 ) / 'xRCHO ', 58.1 / 78 | DATA GC_SPC( 61 ), GC_MOLWT( 61 ) / 'HCOOH ', 46 / 79 | DATA GC_SPC( 62 ), GC_MOLWT( 62 ) / 'xMGLY ', 72.1 / 80 | DATA GC_SPC( 63 ), GC_MOLWT( 63 ) / 'xBACL ', 86.1 / 81 | DATA GC_SPC( 64 ), GC_MOLWT( 64 ) / 'ROOH ', 76.1 / 82 | DATA GC_SPC( 65 ), GC_MOLWT( 65 ) / 'xPROD2 ', 116.2 / 83 | DATA GC_SPC( 66 ), GC_MOLWT( 66 ) / 'R6OOH ', 118.2 / 84 | DATA GC_SPC( 67 ), GC_MOLWT( 67 ) / 'PRD2 ', 116.2 / 85 | DATA GC_SPC( 68 ), GC_MOLWT( 68 ) / 'yR6OOH ', 118.2 / 86 | DATA GC_SPC( 69 ), GC_MOLWT( 69 ) / 'RAOOH ', 188.2 / 87 | DATA GC_SPC( 70 ), GC_MOLWT( 70 ) / 'MGLY ', 72.1 / 88 | DATA GC_SPC( 71 ), GC_MOLWT( 71 ) / 'IPRD ', 100.1 / 89 | DATA GC_SPC( 72 ), GC_MOLWT( 72 ) / 'xGLY ', 58 / 90 | DATA GC_SPC( 73 ), GC_MOLWT( 73 ) / 'xMEK ', 72.1 / 91 | DATA GC_SPC( 74 ), GC_MOLWT( 74 ) / 'xAFG1 ', 98.1 / 92 | DATA GC_SPC( 75 ), GC_MOLWT( 75 ) / 'xAFG2 ', 98.1 / 93 | DATA GC_SPC( 76 ), GC_MOLWT( 76 ) / 'GLY ', 58 / 94 | DATA GC_SPC( 77 ), GC_MOLWT( 77 ) / 'AFG1 ', 98.1 / 95 | DATA GC_SPC( 78 ), GC_MOLWT( 78 ) / 'AFG2 ', 98.1 / 96 | DATA GC_SPC( 79 ), GC_MOLWT( 79 ) / 'BACL ', 86.1 / 97 | DATA GC_SPC( 80 ), GC_MOLWT( 80 ) / 'BALD ', 106.1 / 98 | DATA GC_SPC( 81 ), GC_MOLWT( 81 ) / 'AFG3 ', 124.1 / 99 | DATA GC_SPC( 82 ), GC_MOLWT( 82 ) / 'xIPRD ', 100.1 / 100 | DATA GC_SPC( 83 ), GC_MOLWT( 83 ) / 'MACR ', 70.1 / 101 | DATA GC_SPC( 84 ), GC_MOLWT( 84 ) / 'MVK ', 70.1 / 102 | DATA GC_SPC( 85 ), GC_MOLWT( 85 ) / 'xHOCCHO ', 60.1 / 103 | DATA GC_SPC( 86 ), GC_MOLWT( 86 ) / 'xRNO3 ', 147.2 / 104 | DATA GC_SPC( 87 ), GC_MOLWT( 87 ) / 'HOCCHO ', 60.1 / 105 | DATA GC_SPC( 88 ), GC_MOLWT( 88 ) / 'xACETONE ', 58.1 / 106 | DATA GC_SPC( 89 ), GC_MOLWT( 89 ) / 'ACROLEIN ', 56.1 / 107 | DATA GC_SPC( 90 ), GC_MOLWT( 90 ) / 'xBALD ', 106.1 / 108 | DATA GC_SPC( 91 ), GC_MOLWT( 91 ) / 'xAFG3 ', 124.7 / 109 | DATA GC_SPC( 92 ), GC_MOLWT( 92 ) / 'xMACR ', 70.1 / 110 | DATA GC_SPC( 93 ), GC_MOLWT( 93 ) / 'xMVK ', 70.1 / 111 | DATA GC_SPC( 94 ), GC_MOLWT( 94 ) / 'yRAOOH ', 188.2 / 112 | DATA GC_SPC( 95 ), GC_MOLWT( 95 ) / 'xACROLEIN ', 56.1 / 113 | DATA GC_SPC( 96 ), GC_MOLWT( 96 ) / 'ETHENE ', 28.1 / 114 | DATA GC_SPC( 97 ), GC_MOLWT( 97 ) / 'PROPENE ', 42.1 / 115 | DATA GC_SPC( 98 ), GC_MOLWT( 98 ) / 'BUTADIENE13 ', 54.1 / 116 | DATA GC_SPC( 99 ), GC_MOLWT( 99 ) / 'ISOPRENE ', 68.1 / 117 | DATA GC_SPC(100 ), GC_MOLWT(100 ) / 'APIN ', 136.2 / 118 | DATA GC_SPC(101 ), GC_MOLWT(101 ) / 'ACETYLENE ', 26 / 119 | DATA GC_SPC(102 ), GC_MOLWT(102 ) / 'BENZENE ', 78.1 / 120 | DATA GC_SPC(103 ), GC_MOLWT(103 ) / 'TOLUENE ', 92.1 / 121 | DATA GC_SPC(104 ), GC_MOLWT(104 ) / 'MXYL ', 106.2 / 122 | DATA GC_SPC(105 ), GC_MOLWT(105 ) / 'OXYL ', 106.2 / 123 | DATA GC_SPC(106 ), GC_MOLWT(106 ) / 'PXYL ', 106.2 / 124 | DATA GC_SPC(107 ), GC_MOLWT(107 ) / 'TRIMETH_BENZ124 ', 120.2 / 125 | DATA GC_SPC(108 ), GC_MOLWT(108 ) / 'ETOH ', 46.1 / 126 | DATA GC_SPC(109 ), GC_MOLWT(109 ) / 'ALK1 ', 30.1 / 127 | DATA GC_SPC(110 ), GC_MOLWT(110 ) / 'ALK2 ', 36.7 / 128 | DATA GC_SPC(111 ), GC_MOLWT(111 ) / 'ALK3 ', 58.6 / 129 | DATA GC_SPC(112 ), GC_MOLWT(112 ) / 'ALK4 ', 77.6 / 130 | DATA GC_SPC(113 ), GC_MOLWT(113 ) / 'ALK5 ', 118.9 / 131 | DATA GC_SPC(114 ), GC_MOLWT(114 ) / 'OLE1 ', 72.3 / 132 | DATA GC_SPC(115 ), GC_MOLWT(115 ) / 'OLE2 ', 75.8 / 133 | DATA GC_SPC(116 ), GC_MOLWT(116 ) / 'ARO1 ', 95.2 / 134 | DATA GC_SPC(117 ), GC_MOLWT(117 ) / 'ARO2 ', 118.7 / 135 | DATA GC_SPC(118 ), GC_MOLWT(118 ) / 'TERP ', 136.2 / 136 | DATA GC_SPC(119 ), GC_MOLWT(119 ) / 'SESQ ', 204.4 / 137 | DATA GC_SPC(120 ), GC_MOLWT(120 ) / 'NC4 ', 58.1 / 138 | -------------------------------------------------------------------------------- /fortran_template/BPCH2_DATA.F: -------------------------------------------------------------------------------- 1 | MODULE GEO_DATA 2 | 3 | C************************************************************************ 4 | C 5 | C FUNCTION: Defines Harvard CTM data BPCH2 format 6 | C 7 | C Apr 2006 -- Sergey L. Napelenok 8 | C Modified to describe GEOS-Chem files provided by Daven Henze 9 | C Mar 2011 -- Sergey L. Napelenok 10 | C Modified for AQMEII project 11 | C Use both tracer file and species file 12 | C 13 | C.................................................................... 14 | 15 | c..Data file variable 16 | CHARACTER( 256 ) :: GEO_INPUT_PATH 17 | CHARACTER( 256 ) :: GEO_INPUT_FILE 18 | CHARACTER( 16 ) :: GT_FILE = 'GT_FILE' 19 | CHARACTER( 16 ) :: GS_FILE = 'GS_FILE' 20 | c..Horizontal Grid data 21 | INTEGER :: NCOLS_GEO 22 | INTEGER :: NROWS_GEO 23 | 24 | REAL, ALLOCATABLE :: LON_GEO( : , : ) 25 | REAL, ALLOCATABLE :: LAT_GEO( : , : ) 26 | REAL, ALLOCATABLE :: CGRID_GT( : , :, :, :, : ) 27 | REAL, ALLOCATABLE :: CGRID_GS( : , :, :, :, : ) 28 | 29 | c..Redefinition of record's year 30 | INTEGER bpchYear, SKIP_COLS, SKIP_ROWS 31 | integer :: i, j, k 32 | 33 | #include 34 | 35 | c SLN (14Mar2011) species list in GEOSChem tracer file 36 | #include 37 | #include 38 | 39 | CONTAINS 40 | 41 | !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 42 | ! Subroutine to read the GEO monthly average data 43 | !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 44 | 45 | Subroutine LoadGEO(JDATE, JTIME, status ) 46 | 47 | USE UTILIO_DEFN 48 | 49 | Implicit None 50 | 51 | Integer, Intent( IN ) :: JDATE, JTIME 52 | Integer, Intent( OUT ) :: status 53 | ! array argument 54 | ! Real, Intent( OUT ) :: CGRID_GT( NCOLS_GEO, NROWS_GEO, N_GEO_LAYS, NSPC_GT, 24 ) 55 | ! Real, Intent( OUT ) :: CGRID_GS( NCOLS_GEO, NROWS_GEO, N_GEO_LAYS, NSPC_GS, 24 ) 56 | 57 | ! external functions 58 | ! Integer GETEFILE 59 | ! Integer SECSDIFF 60 | ! Integer ENVINT 61 | 62 | ! local variables 63 | Integer GEO_UNIT 64 | Character*(80) MSG 65 | Integer recDate, recTime, tDiff 66 | Logical found 67 | Character*(128) fname 68 | Character*(40) ftype 69 | Character*(80) toptitle 70 | 71 | Character*(20) modelName 72 | Real modelRes(2) 73 | Integer halfpolar 74 | Integer center180 75 | Integer myear,mnth, mday 76 | 77 | Character*40 category 78 | Integer tracer 79 | Character*40 unit 80 | Real*8 tau0, tau1, ntau0, ntau1 81 | Character*40 reserved 82 | Integer dim(6) 83 | Integer skip 84 | Real blank 85 | Logical, save :: first = .true. 86 | Logical, save :: firstread = .true. 87 | 88 | INTEGER :: NCOUNT, R, C 89 | 90 | 91 | Real, ALLOCATABLE :: buffer( :, :, :) 92 | 93 | integer timestep 94 | 95 | status = 0 96 | 97 | ! on first call, get path of input data file 98 | if( first ) then 99 | Call ENVSTR('GEO_INPUT_PATH','Path of GEO_INPUT_FILE', ' ', GEO_INPUT_PATH, status) 100 | if( status.ne.0 ) then 101 | MSG = 'ERROR: GEO_INPUT_PATH not defined' 102 | CALL M3ERR ('BPCH_BCON', JDATE, JTIME, MSG, .TRUE. ) 103 | endif 104 | first = .false. 105 | endif 106 | 107 | c - TRACER file 108 | 109 | ! build GEO_INPUT_FILE 110 | myear = JDATE / 1000 111 | Call DAYMON(JDATE, mnth, mday) 112 | c mhour = JTIME / 10000 113 | write(GEO_INPUT_FILE,'(a,''BC.'',i4.4,2i2.2)') TRIM(GEO_INPUT_PATH), 114 | & myear, mnth, mday 115 | !Write out filename to terminal for debugging - FHA 6-18-2013 116 | write(*,'(''Reading GEOS input file: '',a,''BC.'',i4.4,2i2.2)') 117 | & TRIM(GEO_INPUT_PATH), myear, mnth, mday 118 | 119 | ! open data file 120 | !GEO_UNIT=GETEFILE( GT_FILE, .TRUE., .FALSE., 'BPCH_BCON' ) 121 | GEO_UNIT = 98 122 | OPEN( GEO_UNIT,FILE=GEO_INPUT_FILE,STATUS='OLD',FORM='UNFORMATTED', 123 | & ACCESS='SEQUENTIAL',iostat=status) 124 | 125 | if( GEO_UNIT .lt. 0 ) then 126 | MSG = 'ERROR: Cannot open GEO_INPUT_FILE ' 127 | & // GT_FILE 128 | & // ' not defined ' 129 | CALL M3ERR ('BPCH_BCON', JDATE, JTIME, MSG, .TRUE. ) 130 | else 131 | MSG = 'Opening GEO_INPUT_FILE ' 132 | & // GT_FILE 133 | CALL M3MESG ( MSG ) 134 | endif 135 | 136 | C read header record 137 | read(GEO_UNIT, iostat=status) ftype 138 | if( status.ne.0 ) then 139 | write(*,'(''**ERROR** cannot read header record ftype'')') 140 | found = .false. 141 | goto 100 142 | endif 143 | 144 | read(GEO_UNIT, iostat=status) toptitle 145 | if( status.ne.0 ) then 146 | write(*,'(''**ERROR** cannot read header record toptitle'')') 147 | found = .false. 148 | goto 100 149 | endif 150 | 151 | C read record of data values 152 | IF (.not. FIRSTREAD) THEN 153 | CGRID_GT = -0.00001 154 | ENDIF 155 | 156 | C read record of data values and fill array 157 | found = .false. 158 | 159 | do timestep = 1, 24 160 | 161 | do NCOUNT = 1, NSPC_GT 162 | 163 | read(GEO_UNIT,iostat=status,end=100) modelName, modelRes, halfpolar, center180 164 | if( status.ne.0 ) then 165 | write(*,'(''**ERROR** cannot read data model header record'')') 166 | found = .false. 167 | goto 100 168 | endif 169 | 170 | read(GEO_UNIT,iostat=status) category, tracer, unit, tau0, tau1, 171 | & reserved, dim, skip 172 | IF (tracer.ne.NCOUNT) THEN 173 | write(*,'(''ERROR Tracer expected'' (i4)''; tracer found'' (i4))'), NCOUNT, tracer 174 | STOP 175 | ENDIF 176 | IF (FIRSTREAD) THEN 177 | SKIP_COLS = dim(4) 178 | SKIP_ROWS = dim(5) 179 | NCOLS_GEO = dim(1) 180 | NROWS_GEO = dim(2) 181 | print*,'Dimensions of GEOS-Chem data: ', NCOLS_GEO, NROWS_GEO 182 | print*,'Output excludes (NCOLS, NROWS): ', SKIP_COLS, SKIP_ROWS 183 | print*,'Resolution (hard coded lat/lon): ', DEL_LAT, DEL_LON 184 | print*,'Poles are at half resolution: ', halfpolar 185 | ! N_GEO_LAYS = dim(3) 186 | ALLOCATE( BUFFER( NCOLS_GEO, NROWS_GEO, N_GEO_LAYS) ) 187 | ALLOCATE( CGRID_GT( NCOLS_GEO, NROWS_GEO, N_GEO_LAYS, NSPC_GT, 25 ) ) 188 | ALLOCATE( CGRID_GS( NCOLS_GEO, NROWS_GEO, N_GEO_LAYS, NSPC_GS, 25 ) ) 189 | CGRID_GT = -0.00001 190 | CGRID_GS = -0.00001 191 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 192 | c Define the lat/lons for the GEOCTM model grid 193 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 194 | c Longitude sequence: -181.25 -178.75 .... 176.25 178.75 195 | c Latitude sequence: -90.00 -98.00 .... 87.0 89.0 90.0 196 | 197 | ALLOCATE( LON_GEO( NCOLS_GEO, NROWS_GEO ) ) 198 | ALLOCATE( LAT_GEO( NCOLS_GEO, NROWS_GEO ) ) 199 | 200 | c..temporarily set latitude of bottom row to -90.0 201 | DO C = 1, NCOLS_GEO 202 | IF (HALFPOLAR.eq.1) THEN 203 | IF (SKIP_ROWS.eq.1) THEN 204 | LAT_GEO( C, 1 ) = -89.5 205 | ELSE 206 | LAT_GEO( C, 1 ) = (SKIP_ROWS-1)*DEL_LAT - 0.25 * DEL_LAT - 89.5 207 | ENDIF 208 | ELSE 209 | LAT_GEO( C, 1 ) = (SKIP_ROWS-1)*DEL_LAT - 89 210 | ENDIF 211 | ENDDO 212 | 213 | c..set remaining rows by incrementing by delta latitude 214 | DO R = 2, NROWS_GEO 215 | DO C = 1, NCOLS_GEO 216 | LAT_GEO( C, R ) = LAT_GEO( C, R - 1 ) + DEL_LAT 217 | ENDDO 218 | ENDDO 219 | 220 | 221 | c..set remaining rows by incrementing by delta latitude 222 | DO R = 1, NROWS_GEO 223 | LON_GEO( 1, R ) = (SKIP_COLS-1) * DEL_LON - 180. 224 | ENDDO 225 | 226 | c..set remaining rows by incrementing by delta longitude 227 | DO R = 1, NROWS_GEO 228 | DO C = 2, NCOLS_GEO 229 | LON_GEO( C, R ) = LON_GEO( C-1, R ) + DEL_LON 230 | ENDDO 231 | ENDDO 232 | 233 | c.. Printing for testing purposes 234 | print*,'Latitudes of GEOS-Chem grid: ',(LAT_GEO(1,R),R=1,NROWS_GEO) 235 | print*,'Longitudes of GEOS-Chem grid: ', (LON_GEO(C, 1),C=1,NCOLS_GEO) 236 | 237 | FIRSTREAD = .false. 238 | ENDIF 239 | if( status.ne.0 ) then 240 | write(*,'(''**ERROR** cannot read simulation header'')') 241 | found = .false. 242 | goto 100 243 | endif 244 | 245 | ! skip species with less than N_GEO_LAYS layers 246 | if( dim(3) .gt. N_GEO_LAYS ) then 247 | read(GEO_UNIT) blank 248 | cycle 249 | endif 250 | 251 | read(GEO_UNIT,iostat=status) (((buffer(i, j, k), i=1,dim(1)), j=1,dim(2)), k=1,dim(3)) 252 | if( status.ne.0 ) then 253 | write(*,'(''**ERROR** cannot read data record for tracer'',i5)') NCOUNT 254 | found = .false. 255 | goto 100 256 | endif 257 | 258 | found = .true. 259 | CGRID_GT(:,:,1:MIN(dim(3), N_GEO_LAYS),NCOUNT,timestep) = buffer(:,:,1:MIN(dim(3), N_GEO_LAYS)) 260 | 261 | enddo 262 | 263 | enddo 264 | 265 | 100 Close (GEO_UNIT) 266 | if( .NOT.found) then 267 | print *, NCOUNT 268 | MSG = 'ERROR: Could not read GEO_INPUT_FILE' 269 | CALL M3ERR ('BPCH_BCON', JDATE, JTIME, MSG, .TRUE. ) 270 | endif 271 | 272 | c - SPECIES file 273 | 274 | ! build GEO_INPUT_FILE 275 | myear = JDATE / 1000 276 | Call DAYMON(JDATE, mnth, mday) 277 | c mhour = JTIME / 10000 278 | write(GEO_INPUT_FILE,'(a,''BC.CSPEC.'',i4.4,2i2.2)') TRIM(GEO_INPUT_PATH), 279 | & myear, mnth, mday 280 | 281 | ! open data file 282 | 283 | 284 | ! GEO_UNIT=GETEFILE( GS_FILE, .TRUE., .FALSE., 'BPCH_BCON' ) 285 | Call ENVSTR('GEO_INPUT_PATH','Path of GEO_INPUT_FILE', ' ', GEO_INPUT_PATH, status) 286 | 287 | OPEN( GEO_UNIT,FILE=GEO_INPUT_FILE,STATUS='OLD',FORM='UNFORMATTED', 288 | & ACCESS='SEQUENTIAL',iostat=status) 289 | 290 | if( GEO_UNIT .lt. 0 ) then 291 | MSG = 'ERROR: Cannot open GEO_INPUT_FILE ' 292 | & // GS_FILE 293 | & // ' not defined ' 294 | CALL M3ERR ('BPCH_BCON', JDATE, JTIME, MSG, .TRUE. ) 295 | else 296 | MSG = 'Opening GEO_INPUT_FILE ' 297 | & // TRIM( GEO_INPUT_FILE ) 298 | CALL M3MESG ( MSG ) 299 | endif 300 | 301 | C read header record 302 | read(GEO_UNIT, iostat=status) ftype 303 | if( status.ne.0 ) then 304 | write(*,'(''**ERROR** cannot read header record 1'')') 305 | goto 101 306 | endif 307 | 308 | read(GEO_UNIT, iostat=status) toptitle 309 | if( status.ne.0 ) then 310 | write(*,'(''**ERROR** cannot read header record 2'')') 311 | goto 101 312 | endif 313 | 314 | C read record of data values 315 | CGRID_GS = -0.00001 316 | 317 | C read record of data values and fill array 318 | found = .false. 319 | 320 | 321 | 1024 timeloop : do timestep = 1, 24 322 | 323 | specloop: do NCOUNT = 1, NSPC_GS 324 | 325 | if( NCOUNT.gt.NSPC_GS ) EXIT 326 | 327 | read(GEO_UNIT,iostat=status,end=101) modelName, modelRes, halfpolar, center180 328 | if( status.ne.0 ) then 329 | write(*,'(''**ERROR** cannot read data header record 1'')') 330 | goto 101 331 | endif 332 | 333 | read(GEO_UNIT,iostat=status) category, tracer, unit, tau0, tau1, 334 | & reserved, dim, skip 335 | IF (tracer.ne.NCOUNT) THEN 336 | write(*,'(''**ERROR** Tracer expected (i4); tracer found (i4)'')') 337 | write(*,*), NCOUNT, tracer, timestep 338 | BACKSPACE(GEO_UNIT) 339 | BACKSPACE(GEO_UNIT) 340 | CYCLE timeloop 341 | ENDIF 342 | if( status.ne.0 ) then 343 | write(*,'(''**ERROR** cannot read data header record 2'')') 344 | goto 101 345 | endif 346 | 347 | ! skip species with less than N_GEO_LAYS layers 348 | if( dim(3) .gt. N_GEO_LAYS ) then 349 | read(GEO_UNIT) blank 350 | cycle specloop 351 | endif 352 | 353 | read(GEO_UNIT,iostat=status) (((buffer(i, j, k), i=1,dim(1)), j=1,dim(2)), k=1,dim(3)) 354 | if( status.ne.0 ) then 355 | write(*,'(''**ERROR** cannot read data record for tracer'',i5)') NCOUNT 356 | goto 101 357 | endif 358 | 359 | found = .true. 360 | CGRID_GS(:,:,:,NCOUNT,timestep) = buffer 361 | 362 | enddo specloop 363 | ntau0 = tau0 364 | if (timestep.ne.24) then 365 | DO WHILE ( ntau0.eq.tau0 ) 366 | read(GEO_UNIT,iostat=status) 367 | read(GEO_UNIT,iostat=status) category, tracer, unit, ntau0, ntau1 368 | read(GEO_UNIT,iostat=status) 369 | enddo 370 | BACKSPACE(GEO_UNIT) 371 | BACKSPACE(GEO_UNIT) 372 | BACKSPACE(GEO_UNIT) 373 | endif 374 | enddo timeloop 375 | 376 | 101 Close (GEO_UNIT) 377 | if( .NOT.found) then 378 | MSG = 'ERROR: Could not read GEO_INPUT_FILE' 379 | CALL M3ERR ('BPCH_BCON', JDATE, JTIME, MSG, .TRUE. ) 380 | endif 381 | 382 | 383 | Return 384 | End Subroutine LoadGEO 385 | 386 | END MODULE GEO_DATA 387 | -------------------------------------------------------------------------------- /fortran_template/repair_bcs.F: -------------------------------------------------------------------------------- 1 | C----------------------------------------------------------------------- 2 | C 3 | C DESCRIPTION: 4 | C Read existing boundary condition file and repair the number 5 | C and aerosol surface area concentrations to be consistent with 6 | C assumed background aerosol distributions, i.e. the standard 7 | C deviation and geometric mean diameter around the boundaries 8 | C will be the same 9 | C Number and surface area variables must already be in the file 10 | C 11 | C 12 | C Sep 2008 -- Sergey L. Napelenok 13 | C Modified for AE5 14 | C Jun 2011 -- HOT Pye 15 | C Modified for AE6 (Ca, K, Mg, Fe, Al, Si, APNCOM, ASEACATK) 16 | C Updated organic aerosol density from 2.0e3 to 1.3e3 17 | C July 2011 -- HOT Pye 18 | C Added ATIJ and AMNJ 19 | C Aug 2011 -- HOT Pye 20 | C Replaced AORGPA with APOC for AERO6 21 | C Apr 2012 -- HOT Pye (with constributions from SJR) 22 | C Updated for full AERO6 consistency 23 | C Added coarse mode surface area 24 | C Organized and checked species (included some species that are currently zero from GEOS-Chem) 25 | C Jun 2013 -- F. Akhtar 26 | C Added ICON test in NCELLS calculation 27 | C 28 | C----------------------------------------------------------------------- 29 | SUBROUTINE REPAIR( BC_FILE ) 30 | 31 | IMPLICIT NONE 32 | 33 | INCLUDE "PARMS3.EXT" 34 | INCLUDE "FDESC3.EXT" 35 | INCLUDE "IODECL3.EXT" 36 | 37 | C...........PARAMETERS and their descriptions: 38 | 39 | REAL(8), PARAMETER :: PI = 3.14159265358979324 ! PI (single precision 3.141593) 40 | REAL, PARAMETER :: RHOSO4 = 1.8e3 ! bulk density of aerosol sulfate 41 | REAL, PARAMETER :: RHONH4 = 1.8e3 ! bulk density of aerosol ammonium 42 | REAL, PARAMETER :: RHONO3 = 1.8e3 ! bulk density of aerosol nitrate 43 | REAL, PARAMETER :: RHOORG = 1.3e3 ! bulk density for aerosol organics following Carlton et al. 2010 44 | !REAL, PARAMETER :: RHOORG = 2.0e3 ! bulk density for aerosol organics following Carlton et al. 2010 45 | REAL, PARAMETER :: RHOSOIL = 2.6e3 ! bulk density for aerosol soil dust 46 | REAL, PARAMETER :: RHOSEAS = 2.2e3 ! bulk density for marine aerosol 47 | REAL, PARAMETER :: RHOANTH = 2.2e3 ! bulk density for anthropogenic aerosol 48 | REAL, PARAMETER :: SGINIAT = 1.7 ! initial sigma-G for Aitken mode 49 | REAL, PARAMETER :: SGINIAC = 2.0 ! initial sigma-G for accumulation mode 50 | REAL, PARAMETER :: SGINICO = 2.2 ! initial sigma-G for coarse mode 51 | REAL, PARAMETER :: DGINIAT = 0.01E-6 ! geometric mean diameter for Aitken mode [ m ] 52 | REAL, PARAMETER :: DGINIAC = 0.07E-6 ! geometric mean diameter for accum mode [ m ] 53 | REAL, PARAMETER :: DGINICO = 1.0E-6 ! geometric mean diameter for coarse mode [ m ] 54 | REAL, PARAMETER :: CONMIN = 1.0E-30 ! minimum concentration [ ug/m**3 ] 55 | integer, parameter :: nspecies = 57 ! number of aerosol species treated 56 | 57 | C...........Argument VARIABLES 58 | CHARACTER( 16 ) :: BC_FILE 59 | 60 | C...........LOCAL VARIABLES (scalars) and their descriptions: 61 | 62 | CHARACTER( 16 ) :: PNAME = 'REPAIR_BCS' ! program name 63 | CHARACTER( 16 ) :: VNAME ! variable name 64 | CHARACTER( 220 ) :: MSG = ' ' ! status message string 65 | CHARACTER( 6 ) :: XCON ! Type of output 66 | 67 | INTEGER JDATE ! current model date, coded YYYYDDD 68 | INTEGER JTIME ! current model time, coded HHMMSS 69 | INTEGER VVERSION ! variable version 70 | INTEGER NOTFOUND ! integer of last missing variables version 71 | 72 | Type speciesstruct 73 | Character(16) :: name ! species name in BC file 74 | INTEGER :: ind ! index in array 75 | INTEGER :: mode ! 1: Aitken, 2: accumulation, 3: coarse 76 | REAL :: density ! species density 77 | INTEGER :: version ! 0: All, 5: AE5, 6: AE6 78 | LOGICAL :: found ! In file: true 79 | end type speciesstruct 80 | 81 | C...identification of aerosol species, mode, and density 82 | C that contribute to Aitken, Accumulation, and Coarse aerosol 83 | Type( speciesstruct ), save :: bcspecies( nspecies ) = (/ 84 | C name, ind, mode, density, version, found 85 | & speciesstruct ( 'ACLI', 0, 1, RHOSEAS, 0, .false.), 86 | & speciesstruct ( 'AECI', 0, 1, RHOANTH, 0, .false.), 87 | & speciesstruct ( 'ANAI', 0, 1, RHOSEAS, 0, .false.), 88 | & speciesstruct ( 'ANH4I', 0, 1, RHONH4, 0, .false.), 89 | & speciesstruct ( 'ANO3I', 0, 1, RHONO3, 0, .false.), 90 | & speciesstruct ( 'ASO4I', 0, 1, RHOSO4, 0, .false.), 91 | & speciesstruct ( 'AALKJ', 0, 2, RHOORG, 0, .false.), 92 | & speciesstruct ( 'ABNZ1J', 0, 2, RHOORG, 0, .false.), 93 | & speciesstruct ( 'ABNZ2J', 0, 2, RHOORG, 0, .false.), 94 | & speciesstruct ( 'ABNZ3J', 0, 2, RHOORG, 0, .false.), 95 | & speciesstruct ( 'ACLJ', 0, 2, RHOSEAS, 0, .false.), 96 | & speciesstruct ( 'AECJ', 0, 2, RHOANTH, 0, .false.), 97 | & speciesstruct ( 'AISO1J', 0, 2, RHOORG, 0, .false.), 98 | & speciesstruct ( 'AISO2J', 0, 2, RHOORG, 0, .false.), 99 | & speciesstruct ( 'AISO3J', 0, 2, RHOORG, 0, .false.), 100 | & speciesstruct ( 'ANAJ', 0, 2, RHOSEAS, 0, .false.), 101 | & speciesstruct ( 'ANH4J', 0, 2, RHONH4, 0, .false.), 102 | & speciesstruct ( 'ANO3J', 0, 2, RHONO3, 0, .false.), 103 | & speciesstruct ( 'AOLGAJ', 0, 2, RHOORG, 0, .false.), 104 | & speciesstruct ( 'AOLGBJ', 0, 2, RHOORG, 0, .false.), 105 | & speciesstruct ( 'AORGCJ', 0, 2, RHOORG, 0, .false.), 106 | & speciesstruct ( 'ASO4J', 0, 2, RHOSO4, 0, .false.), 107 | & speciesstruct ( 'ASQTJ', 0, 2, RHOORG, 0, .false.), 108 | & speciesstruct ( 'ATOL1J', 0, 2, RHOORG, 0, .false.), 109 | & speciesstruct ( 'ATOL2J', 0, 2, RHOORG, 0, .false.), 110 | & speciesstruct ( 'ATOL3J', 0, 2, RHOORG, 0, .false.), 111 | & speciesstruct ( 'ATRP1J', 0, 2, RHOORG, 0, .false.), 112 | & speciesstruct ( 'ATRP2J', 0, 2, RHOORG, 0, .false.), 113 | & speciesstruct ( 'AXYL1J', 0, 2, RHOORG, 0, .false.), 114 | & speciesstruct ( 'AXYL2J', 0, 2, RHOORG, 0, .false.), 115 | & speciesstruct ( 'AXYL3J', 0, 2, RHOORG, 0, .false.), 116 | & speciesstruct ( 'ACLK', 0, 3, RHOSEAS, 0, .false.), 117 | & speciesstruct ( 'ACORS', 0, 3, RHOANTH, 0, .false.), 118 | & speciesstruct ( 'ANH4K', 0, 3, RHONH4, 0, .false.), 119 | & speciesstruct ( 'ANO3K', 0, 3, RHONO3, 0, .false.), 120 | & speciesstruct ( 'ASO4K', 0, 3, RHOSO4, 0, .false.), 121 | & speciesstruct ( 'ASOIL', 0, 3, RHOSOIL, 0, .false.), 122 | & speciesstruct ( 'A25I', 0, 1, RHOANTH, 5, .false.), 123 | & speciesstruct ( 'A25J', 0, 2, RHOANTH, 5, .false.), 124 | & speciesstruct ( 'ANAK', 0, 3, RHOSEAS, 5, .false.), 125 | & speciesstruct ( 'AORGPAI', 0, 1, RHOORG, 5, .false.), 126 | & speciesstruct ( 'AORGPAJ', 0, 2, RHOORG, 5, .false.), 127 | & speciesstruct ( 'AALJ', 0, 2, RHOSOIL, 6, .false.), 128 | & speciesstruct ( 'ACAJ', 0, 2, RHOSOIL, 6, .false.), 129 | & speciesstruct ( 'AFEJ', 0, 2, RHOSOIL, 6, .false.), 130 | & speciesstruct ( 'AKJ', 0, 2, RHOSOIL, 6, .false.), 131 | & speciesstruct ( 'AMGJ', 0, 2, RHOSEAS, 6, .false.), 132 | & speciesstruct ( 'AMNJ', 0, 2, RHOSOIL, 6, .false.), 133 | & speciesstruct ( 'AOTHRI', 0, 1, RHOANTH, 6, .false.), 134 | & speciesstruct ( 'AOTHRJ', 0, 2, RHOSOIL, 6, .false.), 135 | & speciesstruct ( 'APNCOMI', 0, 1, RHOORG, 6, .false.), 136 | & speciesstruct ( 'APNCOMJ', 0, 2, RHOORG, 6, .false.), 137 | & speciesstruct ( 'APOCI', 0, 1, RHOORG, 6, .false.), 138 | & speciesstruct ( 'APOCJ', 0, 2, RHOORG, 6, .false.), 139 | & speciesstruct ( 'ASEACAT', 0, 3, RHOSEAS, 6, .false.), 140 | & speciesstruct ( 'ASIJ', 0, 2, RHOSOIL, 6, .false.), 141 | & speciesstruct ( 'ATIJ', 0, 2, RHOSOIL, 6, .false.) 142 | & /) 143 | 144 | INTEGER NSTEPS ! time, space, species dimensions/counters 145 | INTEGER TSTEP 146 | INTEGER NVARS 147 | INTEGER NLAYS 148 | INTEGER NCELLS 149 | INTEGER IVAR 150 | INTEGER ILAY 151 | INTEGER ISTEP 152 | INTEGER ICELL 153 | 154 | INTEGER VAT0, VAC0, VCOR0, VSURFAT, VSURFAC, VSURFCO ! array indices 155 | 156 | REAL M3ATKN ! Aitken mode 3rd moment 157 | REAL M3ACC ! accumulation mode 3rd moment 158 | REAL M3COR ! coarse mode 3rd moment 159 | REAL NUMFAC_ATKN ! number conversion factor 160 | REAL NUMFAC_ACC 161 | REAL NUMFAC_COR 162 | REAL SRFFAC_ATKN ! surface area conversion factor 163 | REAL SRFFAC_ACC 164 | REAL SRFFAC_COR 165 | 166 | REAL, ALLOCATABLE :: BC_VALUES( :,:,: ) 167 | 168 | C...........EXTERNAL FUNCTIONS and their descriptions: 169 | 170 | INTEGER, EXTERNAL :: INDEX1 171 | 172 | C********************************************************************* 173 | C begin body of program REPAIR_BCS 174 | 175 | C...conversion factors for number and surface area 176 | NUMFAC_ATKN = 1.0 / ( ( DGINIAT ** 3.0 ) * EXP( ( 9.0 / 2.0 ) * ( ( LOG( SGINIAT ) ) ** 2.0 ) ) ) 177 | NUMFAC_ACC = 1.0 / ( ( DGINIAC ** 3.0 ) * EXP( ( 9.0 / 2.0 ) * ( ( LOG( SGINIAC ) ) ** 2.0 ) ) ) 178 | NUMFAC_COR = 1.0 / ( ( DGINICO ** 3.0 ) * EXP( ( 9.0 / 2.0 ) * ( ( LOG( SGINICO ) ) ** 2.0 ) ) ) 179 | SRFFAC_ATKN = PI / ( DGINIAT * EXP( ( 5.0 / 2.0 ) * ( ( LOG( SGINIAT ) ) ** 2.0 ) ) ) 180 | SRFFAC_ACC = PI / ( DGINIAC * EXP( ( 5.0 / 2.0 ) * ( ( LOG( SGINIAC ) ) ** 2.0 ) ) ) 181 | SRFFAC_COR = PI / ( DGINICO * EXP( ( 5.0 / 2.0 ) * ( ( LOG( SGINICO ) ) ** 2.0 ) ) ) 182 | 183 | C...get the file description from the input boundary condition file 184 | 185 | IF ( .NOT. DESC3( BC_FILE ) ) THEN 186 | MSG = 'Could not get ' // BC_FILE // ' file description' 187 | CALL M3EXIT ( PNAME, 0, 0, MSG, XSTAT1 ) 188 | END IF 189 | 190 | NSTEPS = MXREC3D 191 | JDATE = SDATE3D 192 | JTIME = STIME3D 193 | TSTEP = TSTEP3D 194 | NVARS = NVARS3D 195 | NLAYS = NLAYS3D 196 | 197 | C...get indices for aerosols 198 | 199 | bcspecies%ind = 0 200 | do ivar= 1, nspecies 201 | vname = bcspecies(ivar)%name 202 | bcspecies(ivar)%ind = INDEX1( VNAME, NVARS, VNAME3D ) 203 | enddo 204 | notfound = -1 205 | do ivar= 1, nspecies 206 | if ( bcspecies(ivar)%ind == 0 ) THEN 207 | vname = bcspecies(ivar)%name 208 | vversion = bcspecies(ivar)%version 209 | WRITE(MSG, '(A,I1,A)') 'Could not find ' // VNAME // ' AE', vversion, ' in ' // BC_FILE //' file' 210 | CALL M3WARN ( PNAME, 0, 0, MSG ) 211 | if (notfound .le. 0) then 212 | notfound = vversion 213 | else 214 | if (notfound .ne. vversion) then 215 | WRITE(MSG, '(A,I2,A, I2,A)') 'Aerosols from both ', notfound, ' and ', vversion, ' were not found' 216 | CALL M3WARN( PNAME, 0, 0, MSG ) 217 | endif 218 | endif 219 | endif 220 | enddo 221 | 222 | C...get indices for the number concentration (add index if it does not exist) 223 | 224 | VNAME = 'NUMATKN' 225 | VAT0 = INDEX1( VNAME, NVARS, VNAME3D ) 226 | IF ( VAT0 .EQ. 0 ) THEN 227 | MSG = 'Could not find ' // VNAME // '...there is a problem' 228 | CALL M3EXIT ( PNAME, 0, 0, MSG, XSTAT1 ) 229 | END IF 230 | 231 | VNAME = 'NUMACC' 232 | VAC0 = INDEX1( VNAME, NVARS, VNAME3D ) 233 | IF ( VAC0 .EQ. 0 ) THEN 234 | MSG = 'Could not find ' // VNAME // '...there is a problem' 235 | CALL M3EXIT ( PNAME, 0, 0, MSG, XSTAT1 ) 236 | END IF 237 | 238 | VNAME = 'NUMCOR' 239 | VCOR0 = INDEX1( VNAME, NVARS, VNAME3D ) 240 | IF ( VCOR0 .EQ. 0 ) THEN 241 | MSG = 'Could not find ' // VNAME // '...there is a problem' 242 | CALL M3EXIT ( PNAME, 0, 0, MSG, XSTAT1 ) 243 | END IF 244 | 245 | C...get indices for the surface area concentration 246 | 247 | VNAME = 'SRFATKN' 248 | VSURFAT = INDEX1( VNAME, NVARS, VNAME3D ) 249 | IF ( VSURFAT .EQ. 0 ) THEN 250 | MSG = 'Could not find ' // VNAME // '...there is a problem' 251 | CALL M3EXIT ( PNAME, 0, 0, MSG, XSTAT1 ) 252 | END IF 253 | 254 | VNAME = 'SRFACC' 255 | VSURFAC = INDEX1( VNAME, NVARS, VNAME3D ) 256 | IF ( VSURFAC .EQ. 0 ) THEN 257 | MSG = 'Could not find ' // VNAME // '...there is a problem' 258 | CALL M3EXIT ( PNAME, 0, 0, MSG, XSTAT1 ) 259 | END IF 260 | 261 | VNAME = 'SRFCOR' 262 | VSURFCO = INDEX1( VNAME, NVARS, VNAME3D ) 263 | IF ( VSURFCO .EQ. 0 ) THEN 264 | MSG = 'Could not find ' // VNAME // '...there is a problem' 265 | CALL M3EXIT ( PNAME, 0, 0, MSG, XSTAT1 ) 266 | END IF 267 | 268 | C...allocate arrays 269 | C...define full array in case of icon files 270 | CALL getenv( 'XCON', XCON ) 271 | 272 | IF ( XCON == 'ICON' ) THEN 273 | NCELLS = NCOLS3D * NROWS3D 274 | ELSE 275 | NCELLS = 2 * NTHIK3D * ( NCOLS3D + NROWS3D + 2 * NTHIK3D ) 276 | END IF 277 | 278 | ALLOCATE( BC_VALUES( NCELLS, NLAYS, NVARS ) ) 279 | 280 | C...begin loop through all timesteps on input file 281 | 282 | DO ISTEP = 1, NSTEPS 283 | 284 | IF ( .NOT. READ3( BC_FILE, ALLVAR3, ALLAYS3, JDATE, 285 | & JTIME, BC_VALUES ) ) THEN 286 | MSG = 'Could not read all variables from ' // BC_FILE 287 | CALL M3ERR ( PNAME, JDATE, JTIME, MSG, .TRUE. ) 288 | END IF 289 | 290 | C...process data in all layers and cells 291 | 292 | DO ILAY = 1, NLAYS 293 | DO ICELL = 1, NCELLS 294 | 295 | C...Calculate aerosol 3rd moment concentrations [ m**3 / m**3 ] 296 | m3atkn = 0 297 | m3acc = 0 298 | m3cor = 0 299 | 300 | do ivar= 1, nspecies 301 | if ( bcspecies(ivar)%ind > 0 ) THEN 302 | if ( bcspecies(ivar)%mode == 1 ) THEN 303 | m3atkn = m3atkn + 1.0e-9*6.0/( pi*bcspecies(ivar)%density ) * bc_values(icell,ilay,bcspecies(ivar)%ind) 304 | elseif ( bcspecies(ivar)%mode == 2 ) THEN 305 | m3acc = m3acc + 1.0e-9*6.0/( pi*bcspecies(ivar)%density )* bc_values(icell,ilay,bcspecies(ivar)%ind) 306 | elseif ( bcspecies(ivar)%mode == 3 ) THEN 307 | m3cor = m3cor + 1.0e-9*6.0/( pi*bcspecies(ivar)%density )* bc_values(icell,ilay,bcspecies(ivar)%ind) 308 | endif 309 | endif 310 | enddo 311 | 312 | C...Calculate number concentrations [ # / m**3 ] and fill/overwrite position 313 | 314 | bc_values( ICELL, ILAY, VAT0 ) = NUMFAC_ATKN * M3ATKN 315 | bc_values( ICELL, ILAY, VAC0 ) = NUMFAC_ACC * M3ACC 316 | bc_values( ICELL, ILAY, VCOR0 ) = NUMFAC_COR * M3COR 317 | 318 | C...Calculate surface area concentrations [ m**2 / m**3 ] 319 | 320 | bc_values( ICELL, ILAY, VSURFAT ) = SRFFAC_ATKN * M3ATKN 321 | bc_values( ICELL, ILAY, VSURFAC ) = SRFFAC_ACC * M3ACC 322 | bc_values( ICELL, ILAY, VSURFCO ) = SRFFAC_COR * M3COR 323 | 324 | END DO 325 | END DO 326 | 327 | C...write updated boundary conditions to the output file 328 | 329 | IF ( .NOT. WRITE3( BC_FILE, ALLVAR3, JDATE, JTIME, 330 | & bc_values( 1, 1, 1 ) ) ) THEN 331 | MSG = 'Could not WRITE all species to file ' // BC_FILE 332 | CALL M3ERR ( PNAME, JDATE, JTIME, MSG, .TRUE. ) 333 | ENDIF 334 | 335 | CALL NEXTIME ( JDATE, JTIME, TSTEP ) 336 | 337 | END DO 338 | 339 | DEALLOCATE ( BC_VALUES ) 340 | RETURN 341 | 342 | END SUBROUTINE REPAIR 343 | -------------------------------------------------------------------------------- /MANUSCRIPT_CODE.diff: -------------------------------------------------------------------------------- 1 | There are two sections of code. One for v8-03-02 and one for v9-01-01. It would be better to simply use the ND49 outputs for future efforts. 2 | 3 | # v8-03-02 Differences 4 | 5 | diff -r code_2-15-2012.v8-03-02/GeosCore/main.f code_2-15-2012.v8-03-02.org/GeosCore/main.f 6 | 182,184d181 7 | < !for better CSPEC tracerinfos (fha, 10/28/11) 8 | < USE GAMAP_MOD, ONLY : DO_GAMAP 9 | < 10 | 207c204 11 | < CHARACTER(LEN=255) :: ZTYPE, DIAGINFO, TRACERINFO 12 | --- 13 | > CHARACTER(LEN=255) :: ZTYPE 14 | 978,983d974 15 | < ! fha - 10-28-11: Redo this after the chem initialization for CSPEC 16 | < ! Create "diaginfo.dat" and "tracerinfo.dat" files for GAMAP 17 | < DIAGINFO = 'diaginfo.dat' 18 | < TRACERINFO = 'tracerinfo.dat' 19 | < CALL DO_GAMAP( DIAGINFO, TRACERINFO ) 20 | < 21 | diff -r code_2-15-2012.v8-03-02/GeosCore/tpcore_bc_mod.f code_2-15-2012.v8-03-02.org/GeosCore/tpcore_bc_mod.f 22 | 35,36d34 23 | < ! (19e) BC_CP (REAL*4 ) : Array containing NA species on coarse grid 24 | < ! (19e) BC_CU_CP(REAL*4 ) : Array containing CU species on coarse grid 25 | 138c136 26 | < ! (3 ) Now get HALFPOLAR for GEOS or GCAP grids (bmy, 6/28/05)NC 27 | --- 28 | > ! (3 ) Now get HALFPOLAR for GEOS or GCAP grids (bmy, 6/28/05) 29 | 191,193c189 30 | < !fha 3-3-11 31 | < REAL*4, ALLOCATABLE :: BC_CP(:,:,:,:) 32 | < REAL*4, ALLOCATABLE :: BC_CU_CP(:,:,:,:) 33 | --- 34 | > 35 | 246d241 36 | < ! (5 ) Now creates CSPEC files too 101, 102 (fha, 3-4-11) 37 | 254c249 38 | < USE FILE_MOD, ONLY : IU_BC, IU_BC_NA, IU_BC_EU, IU_BC_CH 39 | --- 40 | > USE FILE_MOD, ONLY : IU_BC, IU_BC_NA, IU_BC_EU, IU_BC_CH 41 | 256,257d250 42 | < !fha 3-3-11 43 | < USE FILE_MOD, ONLY : IU_BC_CP, IU_BC_CU_CP 44 | 294,297d286 45 | < ELSEIF ( WINDOW .eq. 101 ) THEN 46 | < FILENAME = TRIM( TPBC_DIR ) // 'BC.CSPEC.YYYYMMDD' 47 | < ELSEIF ( WINDOW .eq. 102 ) THEN 48 | < FILENAME = TRIM( TPBC_DIR_NA ) // 'BC.CSPEC.YYYYMMDD' 49 | 315,318d303 50 | < ELSEIF ( WINDOW .eq. 101 ) THEN 51 | < IF ( PRESENT( FOR_WRITE ) ) 52 | < & CALL OPEN_BPCH2_FOR_WRITE( IU_BC_CU_CP, 53 | < & FILENAME ) 54 | 323,326d307 55 | < ELSEIF ( WINDOW .eq. 102 ) THEN 56 | < IF ( PRESENT( FOR_WRITE ) ) 57 | < & CALL OPEN_BPCH2_FOR_WRITE( IU_BC_CP, 58 | < & FILENAME ) 59 | 359,360d339 60 | < ! (5 ) Hardcoded act+inact species count for CSPEC output 116 (fha, 11/9/11) 61 | < ! (6 ) Changed CSPEC species count to NTSPEC(1) (fha, 5/17/12) 62 | 371,374d349 63 | < ! fha 3-3-11: write out CSPEC BC conditions 64 | < USE COMODE_MOD, ONLY : CSPEC_FULL 65 | < USE FILE_MOD, ONLY : IU_BC_CP, IU_BC_CU_CP 66 | < ! USE COMODE_LOOP_MOD, ONLY : IGAS, NTSPEC 67 | 377,378c352 68 | < # include "comode.h" ! NTSPEC (from havala: readchem:NACTIVE, NGAS, NTSPEC) 69 | < 70 | --- 71 | > 72 | 392,395d365 73 | < ! fha 3-3-11 74 | < CHARACTER(LEN=40) :: CATEGOR_S = 'IJ-CHK-$' 75 | < CHARACTER(LEN=40) :: UNIT_S = 'molec/cm3/box' 76 | < 77 | 422c392 78 | < DO N = 1, N_TRACERS 79 | --- 80 | > DO N = 1, N_TRACERS 81 | 438,463d407 82 | < ! Echo info 83 | < STAMP = TIMESTAMP_STRING() 84 | < WRITE( 6, 110 ) STAMP 85 | < 110 FORMAT( ' - SAVE_GLOBAL_TPCORE_BC: Wrote BC''s at ', a ) 86 | < 87 | < ! fha 3-3-11: write out CSPEC BC conditions 88 | < CALL OPEN_BC_FILE( FOR_WRITE=.TRUE., WINDOW=101) 89 | < 90 | < ! Loop over each tracer 91 | < DO N = 1, NTSPEC(1) 92 | < 93 | < ! Save concentrations in WINDOW REGION to diski 94 | < ! fha 11-9-11 95 | < DO L = 1, 38 96 | < BC_CU_CP(1:IM_BC,1:JM_BC,L,N) = 97 | < & CSPEC_FULL(I1_BC:I2_BC,J1_BC:J2_BC,L,N) 98 | < ENDDO 99 | < 100 | < ! Write boundary conditions to binary punch file 101 | < CALL BPCH2( IU_BC_CU_CP, MODELNAME, LONRES, LATRES, 102 | < & HALFPOLAR, CENTER180, CATEGOR_S, N, 103 | < & UNIT_S, TAU, TAU, RESERVED, 104 | < & IM_BC, JM_BC, LLPAR, I1_BC, 105 | < & J1_BC, 1, BC_CU_CP(1:IM_BC, 1:JM_BC, 106 | < & 1:LLPAR, N) ) 107 | 465,467d408 108 | < ENDDO 109 | < 110 | < 111 | 470,471c411,412 112 | < WRITE( 6, 120 ) STAMP 113 | < 120 FORMAT( ' - SAVE_GLOBAL_TPCORE_BC: Wrote CU CP BC''s at ', a ) 114 | --- 115 | > WRITE( 6, 110 ) STAMP 116 | > 110 FORMAT( ' - SAVE_GLOBAL_TPCORE_BC: Wrote BC''s at ', a ) 117 | 491c432 118 | < & IM_BC_NA, JM_BC_NA, 38, I1_BC_NA, 119 | --- 120 | > & IM_BC_NA, JM_BC_NA, LLPAR, I1_BC_NA, 121 | 493c434 122 | < & 1:38, N) ) 123 | --- 124 | > & 1:LLPAR, N) ) 125 | 495a437 126 | > 127 | 500,527d441 128 | < ! fha 3-3-11: write out CSPEC BC conditions 129 | < CALL OPEN_BC_FILE( FOR_WRITE=.TRUE., WINDOW=102) 130 | < 131 | < ! Loop over each tracer 132 | < DO N = 1, NTSPEC(1) 133 | < 134 | < ! Save concentrations in WINDOW REGION to disk 135 | < ! fha 11-9-11 136 | < DO L = 1, 38 137 | < BC_CP(1:IM_BC_NA,1:JM_BC_NA,L,N) = 138 | < & CSPEC_FULL(I1_BC_NA:I2_BC_NA,J1_BC_NA:J2_BC_NA,L,N) 139 | < ENDDO 140 | < 141 | < ! Write boundary conditions to binary punch file 142 | < CALL BPCH2( IU_BC_CP, MODELNAME, LONRES, LATRES, 143 | < & HALFPOLAR, CENTER180, CATEGOR_S, N, 144 | < & UNIT_S, TAU, TAU, RESERVED, 145 | < & IM_BC_NA, JM_BC_NA, 38, I1_BC_NA, 146 | < & J1_BC_NA, 1, BC_CP(1:IM_BC_NA, 1:JM_BC_NA, 147 | < & 1:38, N) ) 148 | < 149 | < ENDDO 150 | < 151 | < ! Echo info 152 | < STAMP = TIMESTAMP_STRING() 153 | < WRITE( 6, 121 ) STAMP 154 | < 121 FORMAT( ' - SAVE_GLOBAL_TPCORE_BC: Wrote NA CP BC''s at ', a ) 155 | 581,582d494 156 | < 157 | < 158 | 738,740c650 159 | < USE TIME_MOD, ONLY : TIMESTAMP_STRING !fha 3-5-11 160 | < ! USE COMODE_MOD, ONLY : IGAS, NTSPEC 161 | < 162 | --- 163 | > 164 | 743d652 165 | < # include "comode.h" 166 | 747d655 167 | < CHARACTER(LEN=16) :: STAMP !fha 3-5-11 168 | 767,770c675 169 | < ! Echo info 170 | < STAMP = TIMESTAMP_STRING() 171 | < WRITE( 6, 113 ) STAMP 172 | < 113 FORMAT( ' - BEGIN_CLEAR_TPCORE_BC: at ', a ) 173 | --- 174 | > 175 | 783,800d687 176 | < ENDDO 177 | < !$OMP END PARALLEL DO 178 | < ! Echo info 179 | < STAMP = TIMESTAMP_STRING() 180 | < WRITE( 6, 114 ) STAMP 181 | < 114 FORMAT( ' - CLEARED_CU_TPCORE_BC: at ', a ) 182 | < !$OMP PARALLEL DO 183 | < !$OMP+DEFAULT( SHARED ) 184 | < !$OMP+PRIVATE( I, J, L, N ) 185 | < DO N = 1, IGAS 186 | < DO L = 1, 38 187 | < DO J = 1, JM_BC 188 | < DO I = 1, IM_BC 189 | < !fha 3-4-11 190 | < BC_CU_CP(I,J,L,N) = 0e0 191 | < ENDDO 192 | < ENDDO 193 | < ENDDO 194 | 803,806d689 195 | < ! Echo info 196 | < STAMP = TIMESTAMP_STRING() 197 | < WRITE( 6, 115 ) STAMP 198 | < 115 FORMAT( ' - CLEARED_CU_CP_TPCORE_BC: at ', a ) 199 | 823,844d705 200 | < ! Echo info 201 | < STAMP = TIMESTAMP_STRING() 202 | < WRITE( 6, 116 ) STAMP 203 | < 116 FORMAT( ' - CLEARED_NA_TPCORE_BC: at ', a ) 204 | < !$OMP PARALLEL DO 205 | < !$OMP+DEFAULT( SHARED ) 206 | < !$OMP+PRIVATE( I, J, L, N ) 207 | < DO N = 1, IGAS 208 | < DO L = 1, 38 209 | < DO J = 1, JM_BC_NA 210 | < DO I = 1, IM_BC_NA 211 | < !fha 3-3-11 212 | < BC_CP(I,J,L,N) = 0e0 213 | < ENDDO 214 | < ENDDO 215 | < ENDDO 216 | < ENDDO 217 | < !$OMP END PARALLEL DO 218 | < ! Echo info 219 | < STAMP = TIMESTAMP_STRING() 220 | < WRITE( 6, 117 ) STAMP 221 | < 117 FORMAT( ' - CLEARED_NA_CP_TPCORE_BC: at ', a ) 222 | 1349d1209 223 | < # include "comode.h" !fha 3-4-11 224 | 1408c1268 225 | < #if defined(GRID4x5) || defined(NESTED_NA) 226 | --- 227 | > #if defined(GRID4x5) 228 | 1419,1421d1278 229 | < ! fha 3-4-11: New boundaries for CMAQ AQMII domain 230 | < ! actual corners: LL: (18,55) UR: (50, 73) 231 | < ! pad 5 cells to be sure LL-5 UR+5 232 | 1423,1424c1280,1281 233 | < I1_BC_NA = 13 !minimum longitude 234 | < J1_BC_NA = 50 !minimum latitude 235 | --- 236 | > I1_BC_NA = 17 237 | > J1_BC_NA = 51 238 | 1427,1437c1284,1285 239 | < I2_BC_NA = 55 !maximum longitude 240 | < J2_BC_NA = 78 !maximum latitude 241 | < 242 | < 243 | < ! Lower-left corner of coarse-grid NA BC WINDOW region 244 | < !I1_BC_NA = 10 245 | < !J1_BC_NA = 48 246 | < 247 | < ! Upper-right corner of coarse-grid NA BC WINDOW region 248 | < !I2_BC_NA = 61 249 | < !J2_BC_NA = 83 250 | --- 251 | > I2_BC_NA = 57 252 | > J2_BC_NA = 81 253 | 1524,1528d1371 254 | < !fha 3-4-11 255 | < ALLOCATE( BC_CU_CP( IM_BC, JM_BC, 38, IGAS ), STAT=AS ) 256 | < IF ( AS /= 0 ) CALL ALLOC_ERR( 'BC_CU_CP' ) 257 | < BC_CU_CP = 0e0 258 | < 259 | 1547,1552d1389 260 | < !fha 3-3-11 261 | < ALLOCATE( BC_CP( IM_BC_NA, JM_BC_NA, 38, IGAS ) 262 | < & , STAT=AS ) 263 | < IF ( AS /= 0 ) CALL ALLOC_ERR( 'BC_CP' ) 264 | < BC_CP = 0e0 265 | < 266 | 1634,1636d1470 267 | < !fha 3-3-11 268 | < IF ( ALLOCATED( BC_CP ) ) DEALLOCATE( BC_CP ) 269 | < IF ( ALLOCATED( BC_CU_CP ) ) DEALLOCATE( BC_CU_CP ) 270 | diff -r code_2-15-2012.v8-03-02/GeosCore/tracerid_mod.f code_2-15-2012.v8-03-02.org/GeosCore/tracerid_mod.f 271 | 1335,1338d1334 272 | < ! hotp for fha (3/9/11) 273 | < print*, 'CSPEC SPECIES NAMES' 274 | < ! end hotp for fha 275 | < 276 | 1340,1344d1335 277 | < 278 | < ! hotp for fha (3/9/11) 279 | < print*,I,NAMEGAS(I) 280 | < ! end hotp for fha 281 | < 282 | diff -r code_2-15-2012.v8-03-02/GeosCore/wetscav_mod.f code_2-15-2012.v8-03-02.org/GeosCore/wetscav_mod.f 283 | 378,380d377 284 | < 285 | < ! 062212 - fha - implemented fix for negative values on 22 July 2010 from wiki 286 | < ! http://wiki.seas.harvard.edu/geos-chem/index.php/Wet_deposition 287 | 384,385d380 288 | < ! mp hack for -ve wet deposition 289 | < if ( preacc(i,j) .lt. 1.0E-10 ) frac = 0.67 290 | 388,389d382 291 | < ! mp hack for -ve wet deposition 292 | < if ( preacc(i,j) .lt. 1.0E-10 ) frac = 0.33 293 | diff -r code_2-15-2012.v8-03-02/GeosUtil/file_mod.f code_2-15-2012.v8-03-02.org/GeosUtil/file_mod.f 294 | 43,44d42 295 | < INTEGER, PUBLIC, PARAMETER :: IU_BC_CP = 24 ! TPCORE BC files: NA CSPEC grid 296 | < INTEGER, PUBLIC, PARAMETER :: IU_BC_CU_CP = 25 ! TPCORE BC files: GLOBAL CSPEC grid 297 | 98d95 298 | < ! 26 Apr 2011 - F. Akhtar - Added boundary CSPEC array files 299 | 390d386 300 | < ! 26 Apr 2012 - F. Akhtar - Added boundary CSPEC files 301 | 411,412d406 302 | < CLOSE( IU_BC_CP ) 303 | < CLOSE( IU_BC_CU_CP ) 304 | diff -r code_2-15-2012.v8-03-02/Headers/define.h code_2-15-2012.v8-03-02.org/Headers/define.h 305 | 137,138c137,138 306 | < #define GRID2x25 'GRID2x25' 307 | < !#define GRID4x5 'GRID4x5' 308 | --- 309 | > !#define GRID2x25 'GRID2x25' 310 | > #define GRID4x5 'GRID4x5' 311 | 312 | 313 | # v9-01-01 Differences 314 | 315 | diff -r Code_v9_01_01_BC_CP/GeosCore/input_mod.f Code_v9_01_01/GeosCore/input_mod.f 316 | 4658a4659,4660 317 | > ! fha 3-8-11: for better organized BC directories index by DATE 318 | > USE TIME_MOD, ONLY : GET_NYMDb, GET_NHMSb, EXPAND_DATE 319 | 4664a4667 320 | > ! 08 Mar 2011 - F. Akhtar - Organized directories by date 321 | 4693a4697,4699 322 | > ! fha 3-8-11: Expand YYYYMM tokens in the directory name 323 | > CALL EXPAND_DATE( TPBC_DIR_NA, GET_NYMDb(), GET_NHMSb() ) 324 | > 325 | 4701a4708,4710 326 | > ! fha 3-8-11: Expand YYYYMM tokens in the directory name 327 | > CALL EXPAND_DATE( TPBC_DIR_EU, GET_NYMDb(), GET_NHMSb() ) 328 | > 329 | 4709a4719,4721 330 | > ! fha 3-8-11: Expand YYYYMM tokens in the directory name 331 | > CALL EXPAND_DATE( TPBC_DIR_CH, GET_NYMDb(), GET_NHMSb() ) 332 | > 333 | 4717a4730,4732 334 | > ! fha 3-8-11: Expand YYYYMM tokens in the directory name 335 | > CALL EXPAND_DATE( TPBC_DIR, GET_NYMDb(), GET_NHMSb() ) 336 | > 337 | 4743,4744c4758,4759 338 | < WRITE( 6, 110 ) 'Dir w/ archived OH files : ', 339 | < & TRIM( TPBC_DIR ) 340 | --- 341 | > WRITE( 6, 110 ) 'Dir w/ archived BC files : ', 342 | > & TRIM( TPBC_DIR ) !fha 3-8-11: fixed "OH" -> "BC" 343 | diff -r Code_v9_01_01_BC_CP/GeosCore/main.f Code_v9_01_01/GeosCore/main.f 344 | 166a167,168 345 | > !for better CSPEC tracerinfos (fha, 3/3/11) 346 | > USE GAMAP_MOD, ONLY : DO_GAMAP 347 | 231a234,235 348 | > CHARACTER(LEN=255) :: DIAGINFO 349 | > CHARACTER(LEN=255) :: TRACERINFO 350 | 546d549 351 | < 352 | 1171a1175,1179 353 | > ! fha - 3-8-11: Redo this after the chem initialization for CSPEC 354 | > ! Create "diaginfo.dat" and "tracerinfo.dat" files for GAMAP 355 | > DIAGINFO = 'diaginfo.dat' 356 | > TRACERINFO = 'tracerinfo.dat' 357 | > CALL DO_GAMAP( DIAGINFO, TRACERINFO ) 358 | diff -r Code_v9_01_01_BC_CP/GeosCore/tpcore_bc_mod.f Code_v9_01_01/GeosCore/tpcore_bc_mod.f 359 | 35a36 360 | > ! (19e) BC_CU_CP(REAL*4 ) : Array containing CU species on coarse grid 361 | 137c138 362 | < ! (3 ) Now get HALFPOLAR for GEOS or GCAP grids (bmy, 6/28/05) 363 | --- 364 | > ! (3 ) Now get HALFPOLAR for GEOS or GCAP grids (bmy, 6/28/05)NC 365 | 191a193 366 | > REAL*4, ALLOCATABLE :: BC_CU_CP(:,:,:,:) 367 | 243a246 368 | > ! (5 ) Now creates CSPEC files too 101, 102 (fha, 3-4-11) 369 | 254c257 370 | < USE FILE_MOD, ONLY : IU_BC_CP 371 | --- 372 | > USE FILE_MOD, ONLY : IU_BC_CP, IU_BC_CU_CP 373 | 290a294,295 374 | > ELSEIF ( WINDOW .eq. 101 ) THEN 375 | > FILENAME = TRIM( TPBC_DIR ) // 'BC.CSPEC.YYYYMMDD' 376 | 309a315,318 377 | > ELSEIF ( WINDOW .eq. 101 ) THEN 378 | > IF ( PRESENT( FOR_WRITE ) ) 379 | > & CALL OPEN_BPCH2_FOR_WRITE( IU_BC_CU_CP, 380 | > & FILENAME ) 381 | 313a323,326 382 | > ELSEIF ( WINDOW .eq. 102 ) THEN 383 | > IF ( PRESENT( FOR_WRITE ) ) 384 | > & CALL OPEN_BPCH2_FOR_WRITE( IU_BC_CP, 385 | > & FILENAME ) 386 | 320c333 387 | < & CALL OPEN_BPCH2_FOR_WRITE( IU_BC_CP, 388 | --- 389 | > & CALL OPEN_BPCH2_FOR_WRITE( IU_BC_CH, 390 | 358c371 391 | < USE FILE_MOD, ONLY : IU_BC_CP 392 | --- 393 | > USE FILE_MOD, ONLY : IU_BC_CP, IU_BC_CU_CP 394 | 422,423c435 395 | < 396 | < ! Echo info 397 | --- 398 | > ! Echo info 399 | 426a439,466 400 | > 401 | > ! fha 3-3-11: write out CSPEC BC conditions 402 | > CALL OPEN_BC_FILE( FOR_WRITE=.TRUE., WINDOW=101) 403 | > 404 | > ! Loop over each tracer 405 | > DO N = 1, IGAS 406 | > 407 | > ! Save concentrations in WINDOW REGION to disk 408 | > DO L = 1, LLPAR 409 | > BC_CU_CP(1:IM_BC,1:JM_BC,L,N) = 410 | > & CSPEC_FULL(I1_BC:I2_BC,J1_BC:J2_BC,L,N) 411 | > ENDDO 412 | > 413 | > ! Write boundary conditions to binary punch file 414 | > CALL BPCH2( IU_BC_CU_CP, MODELNAME, LONRES, LATRES, 415 | > & HALFPOLAR, CENTER180, CATEGOR_S, N, 416 | > & UNIT_S, TAU, TAU, RESERVED, 417 | > & IM_BC, JM_BC, LLPAR, I1_BC, 418 | > & J1_BC, 1, BC_CU_CP(1:IM_BC, 1:JM_BC, 419 | > & 1:LLPAR, N) ) 420 | > 421 | > ENDDO 422 | > 423 | > 424 | > ! Echo info 425 | > STAMP = TIMESTAMP_STRING() 426 | > WRITE( 6, 120 ) STAMP 427 | > 120 FORMAT( ' - SAVE_GLOBAL_TPCORE_BC: Wrote CU CP BC''s at ', a ) 428 | 451c491,494 429 | < 430 | --- 431 | > ! Echo info 432 | > STAMP = TIMESTAMP_STRING() 433 | > WRITE( 6, 111 ) STAMP 434 | > 111 FORMAT( ' - SAVE_GLOBAL_TPCORE_BC: Wrote NA BC''s at ', a ) 435 | 456c499 436 | < DO N = 1, NTSPEC(1) 437 | --- 438 | > DO N = 1, IGAS 439 | 476,477c519,520 440 | < WRITE( 6, 111 ) STAMP 441 | < 111 FORMAT( ' - SAVE_GLOBAL_TPCORE_BC: Wrote NA BC''s at ', a ) 442 | --- 443 | > WRITE( 6, 121 ) STAMP 444 | > 121 FORMAT( ' - SAVE_GLOBAL_TPCORE_BC: Wrote NA CP BC''s at ', a ) 445 | 688c731,732 446 | < 447 | --- 448 | > USE TIME_MOD, ONLY : TIMESTAMP_STRING !fha 3-5-11 449 | > 450 | 690a735 451 | > # include "comode.h" 452 | 693a739 453 | > CHARACTER(LEN=16) :: STAMP !fha 3-5-11 454 | 713c759,762 455 | < 456 | --- 457 | > ! Echo info 458 | > STAMP = TIMESTAMP_STRING() 459 | > WRITE( 6, 113 ) STAMP 460 | > 113 FORMAT( ' - BEGIN_CLEAR_TPCORE_BC: at ', a ) 461 | 725a775,792 462 | > ENDDO 463 | > !$OMP END PARALLEL DO 464 | > ! Echo info 465 | > STAMP = TIMESTAMP_STRING() 466 | > WRITE( 6, 114 ) STAMP 467 | > 114 FORMAT( ' - CLEARED_CU_TPCORE_BC: at ', a ) 468 | > !$OMP PARALLEL DO 469 | > !$OMP+DEFAULT( SHARED ) 470 | > !$OMP+PRIVATE( I, J, L, N ) 471 | > DO N = 1, IGAS 472 | > DO L = 1, LLPAR 473 | > DO J = 1, JM_BC 474 | > DO I = 1, IM_BC 475 | > !fha 3-4-11 476 | > BC_CU_CP(I,J,L,N) = 0e0 477 | > ENDDO 478 | > ENDDO 479 | > ENDDO 480 | 727a795,798 481 | > ! Echo info 482 | > STAMP = TIMESTAMP_STRING() 483 | > WRITE( 6, 115 ) STAMP 484 | > 115 FORMAT( ' - CLEARED_CU_CP_TPCORE_BC: at ', a ) 485 | 739,740d809 486 | < !fha 3-3-11 487 | < BC_CP(I,J,L,N) = 0e0 488 | 745a815,836 489 | > ! Echo info 490 | > STAMP = TIMESTAMP_STRING() 491 | > WRITE( 6, 116 ) STAMP 492 | > 116 FORMAT( ' - CLEARED_NA_TPCORE_BC: at ', a ) 493 | > !$OMP PARALLEL DO 494 | > !$OMP+DEFAULT( SHARED ) 495 | > !$OMP+PRIVATE( I, J, L, N ) 496 | > DO N = 1, IGAS 497 | > DO L = 1, LLPAR 498 | > DO J = 1, JM_BC_NA 499 | > DO I = 1, IM_BC_NA 500 | > !fha 3-3-11 501 | > BC_CP(I,J,L,N) = 0e0 502 | > ENDDO 503 | > ENDDO 504 | > ENDDO 505 | > ENDDO 506 | > !$OMP END PARALLEL DO 507 | > ! Echo info 508 | > STAMP = TIMESTAMP_STRING() 509 | > WRITE( 6, 117 ) STAMP 510 | > 117 FORMAT( ' - CLEARED_NA_CP_TPCORE_BC: at ', a ) 511 | 1249a1341 512 | > # include "comode.h" !fha 3-4-11 513 | 1318a1411,1420 514 | > ! fha 3-4-11: New boundaries for CMAQ AQMII domain 515 | > ! Lower-left corner of coarse-grid NA BC WINDOW region 516 | > I1_BC_NA = 18 !minimum longitude 517 | > J1_BC_NA = 51 !minimum latitude 518 | > 519 | > ! Upper-right corner of coarse-grid NA BC WINDOW region 520 | > I2_BC_NA = 62 !maximum longitude 521 | > J2_BC_NA = 83 !maximum latitude 522 | > 523 | > 524 | 1320,1321c1422,1423 525 | < I1_BC_NA = 17 526 | < J1_BC_NA = 51 527 | --- 528 | > !I1_BC_NA = 10 529 | > !J1_BC_NA = 48 530 | 1324,1325c1426,1427 531 | < I2_BC_NA = 57 532 | < J2_BC_NA = 81 533 | --- 534 | > !I2_BC_NA = 61 535 | > !J2_BC_NA = 83 536 | 1410a1513,1517 537 | > 538 | > !fha 3-4-11 539 | > ALLOCATE( BC_CU_CP( IM_BC, JM_BC, LLPAR, IGAS ), STAT=AS ) 540 | > IF ( AS /= 0 ) CALL ALLOC_ERR( 'BC_CU_CP' ) 541 | > BC_CU_CP = 0e0 542 | 1431c1538 543 | < ALLOCATE( BC_CP( IM_BC_NA, JM_BC_NA, LLPAR, N_TRACERS ) 544 | --- 545 | > ALLOCATE( BC_CP( IM_BC_NA, JM_BC_NA, LLPAR, IGAS ) 546 | 1518a1626 547 | > IF ( ALLOCATED( BC_CU_CP ) ) DEALLOCATE( BC_CU_CP ) 548 | diff -r Code_v9_01_01_BC_CP/GeosCore/tracerid_mod.f Code_v9_01_01/GeosCore/tracerid_mod.f 549 | 1334a1335,1338 550 | > ! hotp for fha (3/9/11) 551 | > print*, 'CSPEC SPECIES NAMES' 552 | > ! end hotp for fha 553 | > 554 | 1335a1340,1344 555 | > 556 | > ! hotp for fha (3/9/11) 557 | > print*,I,NAMEGAS(I) 558 | > ! end hotp for fha 559 | > 560 | diff -r Code_v9_01_01_BC_CP/GeosUtil/file_mod.f Code_v9_01_01/GeosUtil/file_mod.f 561 | 42c42,43 562 | < INTEGER, PUBLIC, PARAMETER :: IU_BC_CP = 24 ! TPCORE BC files: NA CSPEC grid 563 | --- 564 | > INTEGER, PUBLIC, PARAMETER :: IU_BC_CP = 24 ! TPCORE BC files: NA CSPEC grid 565 | > INTEGER, PUBLIC, PARAMETER :: IU_BC_CU_CP = 25 ! TPCORE BC files: GLOBAL CSPEC grid 566 | 391c392 567 | < ! 03 Mar 2011 - F. Akhtar - Now close IU_BC_CP 568 | --- 569 | > ! 03 Mar 2011 - F. Akhtar - Now close IU_BC_CP, IU_BC_CU_CP 570 | 412a414 571 | > CLOSE( IU_BC_CU_CP ) 572 | --------------------------------------------------------------------------------