! $Id: bpch2_mod.f,v 1.10 2006/09/08 19:20:51 bmy Exp $ MODULE BPCH2_MOD 193,1 ! !****************************************************************************** ! Module BPCH2_MOD contains the routines used to read data from and write ! data to binary punch (BPCH) file format (v. 2.0). (bmy, 6/28/00, 8/4/06) ! ! Module Routines: ! ============================================================================ ! (1 ) OPEN_BPCH2_FOR_READ : Opens binary punch file for input ! (2 ) OPEN_BPCH_FOR_WRITE : Opens binary punch file for output ! (3 ) BPCH2_HDR : writes "top-of-file" header to BPCH file ! (4 ) BPCH2 : writes a data block to a binary punch file ! (5 ) READ_BPCH2 : reads a data block from a binary punch file ! (6 ) GET_MODELNAME : returns MODELNAME for the given met field ! (7 ) GET_NAME_EXT : returns file extension string for model name ! (8 ) GET_NAME_EXT_2D : returns file extension string for 2-D model name ! (9 ) GET_RES_EXT : returns file extension string for model res. ! (10) GET_HALFPOLAR : returns 1 for half-polar grids; 0 otherwise ! (11) GET_TAU0_6A : computes TAU0 from MONTH, DAY, YEAR (, H, M, SEC) ! ! Module Interfaces ! ============================================================================ ! (1 ) GET_TAU0 : Overloads GET_TAU0_6A ! ! GEOS-CHEM modules referenced by bpch2_mod.f ! ============================================================================ ! (1 ) error_mod.f : Module w/ NaN and other error-check routines ! (2 ) file_mod.f : Module w/ file unit numbers and error checks ! (3 ) julday_mod.f : Module w/ astronomical Julian date routines ! ! NOTES: ! (1 ) Added routine GET_TAU0 (bmy, 7/20/00) ! (2 ) Added years 1985-2001 for routine GET_TAU0 (bmy, 8/1/00) ! (3 ) Use IOS /= 0 criterion to also check for EOF (bmy, 9/12/00) ! (4 ) Removed obsolete code in "read_bpch2.f" (bmy, 12/18/00) ! (5 ) Correct error for 1991 TAU values in GET_TAU0 (bnd, bmy, 1/4/01) ! (6 ) BPCH2_MOD is now independent of any GEOS-CHEM size parameters. ! (bmy, 4/18/01) ! (7 ) Now have 2 versions of "GET_TAU0" overloaded by an interface. The ! original version takes 2 arguments (MONTH, YEAR). The new version ! takes 3 arguments (MONTH, DAY, YEAR). (bmy, 8/22/01) ! (8 ) Updated comments (bmy, 9/4/01) ! (9 ) Renamed GET_TAU0_3A to GET_TAU0_6A, and updated the GET_TAU0 ! interface. Also updated comments (bmy, 9/26/01) ! (10) Now use special model name for GEOS-3 w/ 30 layers (bmy, 10/9/01) ! (11) Minor bug fix in GET_TAU0_2A. Also deleted obsolete code from 9/01. ! (bmy, 11/15/01) ! (12) Moved routines JULDAY, MINT, CALDATE to "julian_mod.f". Now ! references routine JULDAY from "julday_mod.f". Also added code ! for GEOS-4/fvDAS model type. (bmy, 11/20/01) ! (23) Now divide module header into MODULE PRIVATE, MODULE VARIABLES, and ! MODULE ROUTINES sections. Also add MODULE INTERFACES section, ! since we have an interface here. (bmy, 5/28/02) ! (24) Added OPEN_BPCH2_FOR_READ and OPEN_BPCH2_FOR_WRITE. Also now ! reference IU_FILE and IOERROR from "file_mod.f". (bmy, 7/30/02) ! (25) Now references "error_mod.f". Also obsoleted routine GET_TAU0_2A. ! (bmy, 10/15/02) ! (26) Made modification in READ_BPCH2 for 1x1 nested grids (bmy, 3/11/03) ! (27) Modifications for GEOS-4, 30-layer grid (bmy, 11/3/03) ! (28) Added cpp switches for GEOS-4 1x125 grid (bmy, 12/1/04) ! (29) Modified for GCAP and GEOS-5 met fields. Added function ! GET_HALFPOLAR. (bmy, 6/28/05) ! (30) Added GET_NAME_EXT_2D to get filename extension for files which do ! not contain any vertical information (bmy, 8/16/05) ! (31) Remove support for GEOS-1 and GEOS-STRAT met fields (bmy, 8/4/06) !****************************************************************************** ! IMPLICIT NONE !================================================================= ! MODULE PRIVATE DECLARATIONS -- keep certain internal variables ! and routines from being seen outside "bpch2_mod.f" !================================================================= ! PRIVATE module routines PRIVATE :: GET_TAU0_6A !================================================================= ! MODULE INTERFACES -- "bind" two or more routines with different ! argument types or # of arguments under one unique name !================================================================= INTERFACE GET_TAU0 MODULE PROCEDURE GET_TAU0_6A END INTERFACE !================================================================= ! MODULE ROUTINES -- follow below the "CONTAINS" statement !================================================================= CONTAINS !------------------------------------------------------------------------------ SUBROUTINE OPEN_BPCH2_FOR_READ( IUNIT, FILENAME, TITLE ) 6,6 ! !****************************************************************************** ! Subroutine OPEN_BPCH2_FOR_READ opens a binary punch file (version 2.0 ! format) for reading only. Also reads FTI and TITLE strings. ! (bmy, 7/30/02, 10/15/02) ! ! Arguments as Input: ! ============================================================================ ! (1 ) IUNIT (INTEGER ) : Logical unit number of the file to be opened ! (2 ) FILENAME (CHARACTER) : Name of the file to be opened ! ! Arguments as Output: ! ============================================================================ ! (3 ) TITLE (CHARACTER) : OPTIONAL: returns TITLE to calling program ! ! NOTES: ! (1 ) Now references ERROR_STOP from "error_mod.f" (bmy, 10/15/02) !****************************************************************************** ! ! References to F90 modules USE ERROR_MOD, ONLY : ERROR_STOP USE FILE_MOD, ONLY : IOERROR ! Arguments INTEGER, INTENT(IN) :: IUNIT CHARACTER(LEN=*), INTENT(IN) :: FILENAME CHARACTER(LEN=80), INTENT(OUT), OPTIONAL :: TITLE ! Local variables INTEGER :: IOS CHARACTER(LEN=40) :: FTI CHARACTER(LEN=80) :: TMP_TITLE !================================================================= ! OPEN_BPCH2_FOR_READ begins here! !================================================================= ! Open file for input -- readonly OPEN( IUNIT, FILE=TRIM( FILENAME ), STATUS='OLD', & IOSTAT=IOS, FORM='UNFORMATTED', ACCESS='SEQUENTIAL' ) ! Error check IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT, 'open_bpch2_for_read:1') ! Read file type identifier READ( IUNIT, IOSTAT=IOS ) FTI ! Error check IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT, 'open_bpch2_for_read:2') ! Stop if this is not a binary punch file IF ( TRIM( FTI ) /= 'CTM bin 02' ) THEN CALL ERROR_STOP( 'Invalid file format!', & 'OPEN_BPCH2_FOR_READ (bpch2_mod.f)') ENDIF ! Read top title READ( IUNIT, IOSTAT=IOS ) TMP_TITLE ! Error check IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT, 'open_bpch2_for_read:3') ! Copy value of TMP_TITLE to TITLE for return IF ( PRESENT( TITLE ) ) TITLE = TMP_TITLE ! Return to calling program END SUBROUTINE OPEN_BPCH2_FOR_READ !------------------------------------------------------------------------------ SUBROUTINE OPEN_BPCH2_FOR_WRITE( IUNIT, FILENAME, TITLE ) 11,3 ! !****************************************************************************** ! Subroutine OPEN_BPCH2_FOR_WRITE opens a binary punch file (version 2.0) ! for writing. (bmy, 7/30/02) ! ! Arguments as Input: ! ============================================================================ ! (1 ) IUNIT (INTEGER ) : Logical unit number of the file to be opened ! (2 ) FILENAME (CHARACTER) : Name of the file to be opened ! (3 ) TITLE (CHARACTER) : Optional: title for top of file ! ! NOTES: !****************************************************************************** ! ! References to F90 modules USE FILE_MOD, ONLY : IOERROR ! Arguments INTEGER, INTENT(IN) :: IUNIT CHARACTER(LEN=*), INTENT(IN) :: FILENAME CHARACTER(LEN=80), INTENT(IN), OPTIONAL :: TITLE ! Local variables INTEGER :: IOS CHARACTER(LEN=80) :: TMP_TITLE !================================================================= ! OPEN_BPCH2_FOR_WRITE begins here! !================================================================= ! If TITLE is not passed, create a default title string IF ( PRESENT( TITLE ) ) THEN TMP_TITLE = TITLE ELSE TMP_TITLE = 'GEOS-CHEM binary punch file v. 2.0' ENDIF ! Open file for output OPEN( IUNIT, FILE=TRIM( FILENAME ), STATUS='UNKNOWN', & IOSTAT=IOS, FORM='UNFORMATTED', ACCESS='SEQUENTIAL' ) ! Error check IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT,'open_bpch2_for_write:1') ! Write the top-of-file title to disk CALL BPCH2_HDR( IUNIT, TMP_TITLE ) ! Return to calling program END SUBROUTINE OPEN_BPCH2_FOR_WRITE !------------------------------------------------------------------------------ SUBROUTINE BPCH2_HDR ( IUNIT, TITLE ) 2,3 ! !****************************************************************************** ! Subroutine BPCH2_HDR writes a header at the top of the binary ! punch file, version 2.0 (bmy, 5/27/99, 7/30/02). ! ! Arguments as input: ! ============================================================================ ! (1) IUNIT : INTEGER - logical unit number of binary punch file ! (2) TITLE : CHAR*80 - description of data contained in binary punch file ! ! NOTES: ! (1 ) Added this routine to "bpch_mod.f" (bmy, 6/28/00) ! (2 ) Use IOS /= 0 criterion to also check for EOF condition (bmy, 9/12/00) ! (3 ) Now reference IOERROR from "file_mod.f". (bmy, 6/26/02) !****************************************************************************** ! ! References to F90 modules USE FILE_MOD, ONLY : IOERROR ! Arguments INTEGER, INTENT(IN) :: IUNIT CHARACTER(LEN=80), INTENT(IN) :: TITLE ! Local variable INTEGER :: IOS CHARACTER(LEN=40) :: FTI = 'CTM bin 02' !================================================================= ! BPCH2_HDR begins here! ! ! Write header information to binary punch file ! Also be sure to trap I/O Error conditions !================================================================= WRITE ( IUNIT, IOSTAT=IOS ) FTI IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT, 'bpch2_hdr:1' ) WRITE ( IUNIT, IOSTAT=IOS ) TITLE IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT, 'bpch2_hdr:2' ) ! Return to calling program END SUBROUTINE BPCH2_HDR !------------------------------------------------------------------------------ SUBROUTINE BPCH2( IUNIT, MODELNAME, LONRES, LATRES, 108,4 & HALFPOLAR, CENTER180, CATEGORY, NTRACER, & UNIT, TAU0, TAU1, RESERVED, & NI, NJ, NL, IFIRST, & JFIRST, LFIRST, ARRAY ) ! !****************************************************************************** ! Subroutine BPCH2 writes binary punch file (version 2.0) to disk. ! Information about the model grid is also stored with each data block. ! (bmy, 5/27/99, 7/30/02) ! ! Arguments as input: ! ============================================================================ ! (1 ) IUNIT : INTEGER - logical unit number of the file ! (2 ) MODELNAME : CHAR*40 - Name of model used to create output ! (3 ) LONRES : REAL*4 - Longitude resolution of grid, in degrees ! (4 ) LATRES : REAL*4 - Latitude resolution of grid, in degrees ! (4 ) HALFPOLAR : INTEGER - flag, =1 if model has half-polar boxes ! (5 ) CENTER180 : INTEGER - flag, =1 if model has lon center on 180 deg ! (6 ) CATEGORY : CHAR*40 - diagnostic category name ! (7 ) NTRACER : INTEGER - number of tracer ! (8 ) UNIT : CHAR*40 - units of data ! (9 ) TAU0 : REAL*8 - TAU at start of diagnostic interval ! (10 ) TAU1 : REAL*8 - TAU at end of diagnostic interval ! (11 ) RESERVED : CHAR*40 - Reserved for future use ! (12-14) NI,NJ,NL : INTEGER - dimensions of ARRAY ! (15 ) IFIRST : INTEGER - I-index of the first grid box ! (16 ) JFIRST : INTEGER - J-index of the first grid box ! (17 ) LFIRST : INTEGER - L-index of the first grid box ! (18 ) ARRAY : REAL*4 - data block to be written to the file ! ! NOTES: ! (1 ) Added indices to IOERROR calls (e.g. "bpch2:1", "bpch2:2", etc.) ! (bmy, 10/4/99) ! (2 ) Added this routine to "bpch_mod.f" (bmy, 6/28/00) ! (3 ) Use IOS /= 0 criterion to also check for EOF condition (bmy, 9/12/00) ! (4 ) Now reference IOERROR from "file_mod.f". (bmy, 6/26/02) !****************************************************************************** ! ! References to F90 modules USE FILE_MOD, ONLY : IOERROR ! Arguments INTEGER, INTENT(IN) :: IUNIT INTEGER, INTENT(IN) :: NTRACER INTEGER, INTENT(IN) :: NI, NJ, NL INTEGER, INTENT(IN) :: IFIRST, JFIRST, LFIRST INTEGER, INTENT(IN) :: HALFPOLAR, CENTER180 REAL*4, INTENT(IN) :: ARRAY( NI, NJ, NL ) REAL*4, INTENT(IN) :: LONRES, LATRES REAL*8, INTENT(IN) :: TAU0, TAU1 CHARACTER(LEN=20), INTENT(IN) :: MODELNAME CHARACTER(LEN=40), INTENT(IN) :: CATEGORY CHARACTER(LEN=40), INTENT(IN) :: RESERVED CHARACTER(LEN=40), INTENT(IN) :: UNIT ! Local variables INTEGER :: I, J, L, NSKIP, IOS ! For computing NSKIP INTEGER, PARAMETER :: BYTES_PER_NUMBER = 4 INTEGER, PARAMETER :: END_OF_RECORD = 8 !================================================================= ! BPCH2 begins here!! ! ! Compute the number of bytes to skip between the end of one ! data block and the beginning of the next data header line !================================================================= NSKIP = ( BYTES_PER_NUMBER * ( NI * NJ * NL ) ) + END_OF_RECORD !================================================================= ! Write data block to binary punch file ! Check for I/O errors !================================================================= WRITE( IUNIT, IOSTAT=IOS ) & MODELNAME, LONRES, LATRES, HALFPOLAR, CENTER180 IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT, 'bpch2:1' ) WRITE( IUNIT, IOSTAT = IOS ) & CATEGORY, NTRACER, UNIT, TAU0, TAU1, RESERVED, & NI, NJ, NL, IFIRST, JFIRST, LFIRST, & NSKIP IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT, 'bpch2:2' ) WRITE( IUNIT, IOSTAT=IOS ) & ( ( ( ARRAY(I,J,L), I=1,NI ), J=1,NJ ), L=1,NL ) IF ( IOS /= 0 ) CALL IOERROR( IOS, IUNIT, 'bpch2:3' ) !================================================================= ! Return to calling program !================================================================= END SUBROUTINE BPCH2 !------------------------------------------------------------------------------ SUBROUTINE READ_BPCH2( FILENAME, CATEGORY_IN, TRACER_IN, 174,7 & TAU0_IN, IX, JX, & LX, ARRAY, QUIET ) ! !****************************************************************************** ! Subroutine READ_BPCH2 reads a binary punch file (v. 2.0) and extracts ! a data block that matches the given category, tracer, and tau value. ! (bmy, 12/10/99, 12/1/04) ! ! Arguments as Input: ! ============================================================================ ! (1 ) FILENAME : (CHARACTER) String for input file name ! (2 ) CATEGORY_IN : (CHARACTER) Category name for the desired data block ! (3 ) TRACER_IN : (INTEGER ) Tracer number for which to extract data ! (4 ) TAU0_IN : (REAL*8 ) TAU value for which to extract data ! (5-7) IX, JX, LX : (INTEGER ) Dimensions of ARRAY (see below) ! (9 ) QUIET : (LOGICAL ) Optional flag for suppressing printing ! ! Arguments as Output: ! ============================================================================ ! (8 ) ARRAY : (REAL*4 ) Array to hold extracted data values ! ! NOTES: ! (1 ) Assumes that we are reading in a global-size data block. ! (2 ) Trap all I/O errors with subroutine IOERROR.F. ! (3 ) Now stop with an error message if no matches are found. (bmy, 3/9/00) ! (4 ) Added this routine to "bpch_mod.f" (bmy, 6/28/00) ! (5 ) Use IOS /= 0 criterion to also check for EOF condition (bmy, 9/12/00) ! (6 ) TEMPARRAY now dimensioned to be of global size (bmy, 10/12/00) ! (7 ) Removed obsolete code from 10/12/00 (bmy, 12/18/00) ! (8 ) Now make TEMPARRAY independent of CMN_SIZE parameters (bmy, 4/17/01) ! (9 ) Removed old commented-out code (bmy, 4/20/01) ! (10) Now reference IU_FILE and IOERROR from "file_mod.f". Now call ! OPEN_BPCH2_FOR_READ to open the binary punch file. Now use IU_FILE ! as the unit number instead of a locally-defined IUNIT. (bmy, 7/30/02) ! (11) Now references ERROR_STOP from "error_mod.f" (bmy, 10/15/02) ! (12) Now set IFIRST=1, JFIRST=1 for 1x1 nested grids. Now needs to ! reference "define.h". Added OPTIONAL QUIET flag. (bmy, 3/14/03) ! (13) Now separate off nested grid code in an #ifdef block using ! NESTED_CH or NESTED_NA cpp switches (bmy, 12/1/04) !****************************************************************************** ! ! References to F90 modules USE ERROR_MOD, ONLY : ERROR_STOP USE FILE_MOD, ONLY : IU_FILE, IOERROR # include "define.h" ! Arguments LOGICAL, OPTIONAL, INTENT(IN) :: QUIET INTEGER, INTENT(IN) :: IX, JX, LX, TRACER_IN CHARACTER(LEN=*), INTENT(IN) :: FILENAME, CATEGORY_IN REAL*8, INTENT(IN) :: TAU0_IN REAL*4, INTENT(OUT) :: ARRAY(IX, JX, LX) ! Local variables LOGICAL :: FOUND, TMP_QUIET INTEGER :: I, J, L, N, IOS, M INTEGER :: I1, I2, J1, J2, L1, L2 CHARACTER(LEN=255) :: MSG ! Make TEMPARRAY big enough to for a 1x1 grid (bmy, 4/17/01) REAL*4 :: TEMPARRAY(360,181,70) ! For binary punch file, version 2.0 INTEGER :: NTRACER, NSKIP INTEGER :: HALFPOLAR, CENTER180 INTEGER :: NI, NJ, NL INTEGER :: IFIRST, JFIRST, LFIRST REAL*4 :: LONRES, LATRES REAL*8 :: ZTAU0, ZTAU1 CHARACTER(LEN=20) :: MODELNAME CHARACTER(LEN=40) :: CATEGORY CHARACTER(LEN=40) :: UNIT CHARACTER(LEN=40) :: RESERVED !================================================================= ! READ_BPCH2 begins here! ! ! Initialize some variables !================================================================= FOUND = .FALSE. ARRAY(:,:,:) = 0e0 TEMPARRAY(:,:,:) = 0e0 ! Define a temporary variable for QUIET IF ( PRESENT( QUIET ) ) THEN TMP_QUIET = QUIET ELSE TMP_QUIET = .FALSE. ENDIF !================================================================= ! Open binary punch file and read top-of-file header. ! Do some error checking to make sure the file is the right format. !================================================================= CALL OPEN_BPCH2_FOR_READ( IU_FILE, FILENAME ) !================================================================= ! Read data from the binary punch file ! ! NOTE: IOS < 0 is end-of-file, IOS > 0 is error condition !================================================================= DO READ( IU_FILE, IOSTAT=IOS ) & MODELNAME, LONRES, LATRES, HALFPOLAR, CENTER180 IF ( IOS < 0 ) EXIT IF ( IOS > 0 ) CALL IOERROR( IOS, IU_FILE, 'read_bpch2:4' ) READ( IU_FILE, IOSTAT=IOS ) & CATEGORY, NTRACER, UNIT, ZTAU0, ZTAU1, RESERVED, & NI, NJ, NL, IFIRST, JFIRST, LFIRST, & NSKIP IF ( IOS /= 0 ) CALL IOERROR( IOS, IU_FILE, 'read_bpch2:5' ) READ( IU_FILE, IOSTAT=IOS ) & ( ( ( TEMPARRAY(I,J,L), I=1,NI ), J=1,NJ ), L=1,NL ) IF ( IOS /= 0 ) CALL IOERROR( IOS, IU_FILE, 'read_bpch2:6' ) ! Test for a match IF ( TRIM( CATEGORY_IN ) == TRIM( CATEGORY ) .and. & TRACER_IN == NTRACER .and. & TAU0_IN == ZTAU0 ) THEN FOUND = .TRUE. EXIT ENDIF ENDDO !================================================================= ! We have found a match! Copy TEMPARRAY to ARRAY, taking into ! account the starting positions (IFIRST, JFIRST, LFIRST) of ! the data block. !================================================================= IF ( FOUND ) THEN #if defined( GRID1x1 ) #if defined( NESTED_CH ) || defined( NESTED_NA ) ! *** NOTE: now use NESTED_CH or NESTED_NA cpp switches *** ! *** to block off this section of code (bmy, 12/1/04) *** ! This is a kludge to overwrite the IFIRST, JFIRST, LFIRST For ! the 1x1 nested grid. 1x1 met fields & other data are already ! cut down to size to save space. (bmy, 3/11/03) I1 = 1 J1 = 1 L1 = LFIRST #endif #else ! Otherwise IFIRST, JFIRST, FIRST from the file (bmy, 3/11/03) I1 = IFIRST J1 = JFIRST L1 = LFIRST #endif I2 = NI + I1 - 1 J2 = NJ + J1 - 1 L2 = NL + L1 - 1 ARRAY( I1:I2, J1:J2, L1:L2 ) = TEMPARRAY( 1:NI, 1:NJ, 1:NL ) ! Flag to decide whether or not we will echo info (bmy, 3/14/03) IF ( .not. TMP_QUIET ) THEN WRITE( 6, 100 ) ZTAU0, NTRACER 100 FORMAT( 'READ_BPCH2: Found data for TAU = ', f10.2, & ' and tracer # ', i6 ) ENDIF ELSE MSG = 'No matches found for file ' // TRIM( FILENAME ) // '!' CALL ERROR_STOP( MSG, 'READ_BPCH2 (bpch2_mod.f)!' ) ENDIF !================================================================= ! Close file and quit !================================================================= CLOSE( IU_FILE ) ! Return to calling program END SUBROUTINE READ_BPCH2 !------------------------------------------------------------------------------ FUNCTION GET_MODELNAME() RESULT( MODELNAME ) 17 ! !****************************************************************************** ! Function GET_MODELNAME returns the proper value of MODELNAME for GEOS-1, ! GEOS-STRAT, GEOS-2, or GEOS-3 data. MODELNAME is written to the binary ! punch file and is used by the GAMAP package. (bmy, 6/22/00, 8/4/06) ! ! NOTES: ! (1 ) Now use special model name for GEOS-3 w/ 30 layers (bmy, 10/9/01) ! (2 ) Added modelname for GEOS-4/fvDAS model type (bmy, 11/20/01) ! (3 ) Added "GEOS4_30L" for reduced GEOS-4 grid. Also now use C-preprocessor ! switch "GRID30LEV" instead of IF statements. (bmy, 11/3/03) ! (4 ) Updated for GCAP and GEOS-5 met fields. Rearranged coding for ! simplicity. (swu, bmy, 5/24/05) ! (5 ) Remove support for GEOS-1 and GEOS-STRAT met fields (bmy, 8/4/06) !****************************************************************************** ! # include "CMN_SIZE" ! MODELNAME holds the return value for the function CHARACTER(LEN=20) :: MODELNAME !================================================================= ! GET_MODELNAME begins here! !================================================================= #if defined( GEOS_3 ) && defined( GRID30LEV ) MODELNAME = 'GEOS3_30L' #elif defined( GEOS_3 ) MODELNAME = 'GEOS3' #elif defined( GEOS_4 ) && defined( GRID30LEV ) MODELNAME = 'GEOS4_30L' #elif defined( GEOS_4 ) MODELNAME = 'GEOS4' #elif defined( GEOS_5 ) && defined( GRID30LEV ) MODELNAME = 'GEOS5_30L' #elif defined( GEOS_5 ) MODELNAME = 'GEOS5' #elif defined( GCAP ) MODELNAME = 'GCAP' #endif ! Return to calling program END FUNCTION GET_MODELNAME !------------------------------------------------------------------------------ FUNCTION GET_NAME_EXT() RESULT( NAME_EXT ) 36 ! !****************************************************************************** ! Function GET_NAME_EXT returns the proper filename extension for CTM ! model name (i.e. "geos3", "geos4", "geos5", or "gcap"). ! (bmy, 6/28/00, 8/4/06) ! ! NOTES: ! (1 ) Added name string for GEOS-4/fvDAS model type (bmy, 11/20/01) ! (2 ) Remove obsolete "geos2" model name strning (bmy, 11/3/03) ! (3 ) Modified for GCAP and GEOS-5 met fields (bmy, 5/24/05) ! (4 ) Remove support for GEOS-1 and GEOS-STRAT met fields (bmy, 8/4/06) !****************************************************************************** ! # include "define.h" #if defined( GEOS_3 ) CHARACTER(LEN=5) :: NAME_EXT NAME_EXT = 'geos3' #elif defined( GEOS_4 ) CHARACTER(LEN=5) :: NAME_EXT NAME_EXT = 'geos4' #elif defined( GEOS_5 ) CHARACTER(LEN=5) :: NAME_EXT NAME_EXT = 'geos5' #elif defined( GCAP ) CHARACTER(LEN=4) :: NAME_EXT NAME_EXT = 'gcap' #endif ! Return to calling program END FUNCTION GET_NAME_EXT !------------------------------------------------------------------------------ FUNCTION GET_NAME_EXT_2D() RESULT( NAME_EXT_2D ) 62,1 ! !****************************************************************************** ! Function GET_NAME_EXT_2D returns the proper filename extension for CTM ! model name for files which do not contain any vertical information ! (i.e. "geos" or "gcap"). (bmy, 8/16/05) ! ! NOTES: !****************************************************************************** ! ! Local variables CHARACTER(LEN=4) :: NAME_EXT_2D CHARACTER(LEN=5) :: TEMP_NAME !================================================================= ! GET_NAME_EXT_2D begins here! !================================================================= ! Get the name extension TEMP_NAME = GET_NAME_EXT() ! Take the 1st 4 characters ("geos" or "gcap") and return NAME_EXT_2D = TEMP_NAME(1:4) ! Return to calling program END FUNCTION GET_NAME_EXT_2D !------------------------------------------------------------------------------ FUNCTION GET_RES_EXT() RESULT( RES_EXT ) 142 ! !****************************************************************************** ! Function GET_RES_EXT returns the proper filename extension for ! CTM grid resolution (i.e. "1x1", "2x25", "4x5"). (bmy, 6/28/00, 12/1/04) ! ! NOTES: ! (1 ) Added extension for 1 x 1.25 grid (bmy, 12/1/04) !****************************************************************************** ! # include "define.h" #if defined( GRID4x5 ) CHARACTER(LEN=3) :: RES_EXT RES_EXT = '4x5' #elif defined( GRID2x25 ) CHARACTER(LEN=4) :: RES_EXT RES_EXT = '2x25' #elif defined( GRID1x125 ) CHARACTER(LEN=5) :: RES_EXT RES_EXT = '1x125' #elif defined( GRID1x1 ) CHARACTER(LEN=3) :: RES_EXT RES_EXT = '1x1' #endif END FUNCTION GET_RES_EXT !------------------------------------------------------------------------------ FUNCTION GET_HALFPOLAR() RESULT( HALFPOLAR ) 16 ! !****************************************************************************** ! Function GET_HALFPOLAR returns 1 if the current grid has half-sized polar ! boxes (e.g. GEOS), or zero otherwise (e.g. GCAP). (swu, bmy, 6/28/05) ! ! NOTES: !****************************************************************************** ! # include "define.h" ! Local variables INTEGER :: HALFPOLAR !================================================================= ! GET_HALFPOLAR begins here! !================================================================= #if defined( GCAP ) ! GCAP grid does not have half-sized polar boxes HALFPOLAR = 0 #else ! All GEOS grids have half-sized polar boxes HALFPOLAR = 1 #endif ! Return to calling program END FUNCTION GET_HALFPOLAR !------------------------------------------------------------------------------ FUNCTION GET_TAU0_6A( MONTH, DAY, YEAR, HOUR, MIN, SEC ) 1,5 & RESULT( THIS_TAU0 ) ! !****************************************************************************** ! Function GET_TAU0_6A returns the corresponding TAU0 value for the first ! day of a given MONTH of a given YEAR. This is necessary to index monthly ! mean binary punch files, which are used as input to GEOS-CHEM. ! (bmy, 9/26/01) ! ! This function takes 3 mandatory arguments (MONTH, DAY, YEAR) and 3 ! optional arguments (HOUR, MIN, SEC). It is intended to replace the current ! 2-argument version of GET_TAU0. The advantage being that GET_TAU0_3A can ! compute a TAU0 for any date and time in the GEOS-CHEM epoch, rather than ! just the first day of each month. Overload this w/ an interface so that ! the user can also choose the version of GET_TAU0 w/ 2 arguments ! (MONTH, YEAR), which is the prior version. ! ! Arguments as Input: ! =========================================================================== ! (1 ) MONTH (INTEGER) : Month of year (1-12) ! (2 ) DAY (INTEGER) : Day of month (1-31) ! (3 ) YEAR (INTEGER) : 4-digit year number (e.g. 1985,2001) ! (4 ) HOUR (INTEGER) : OPTIONAL: Hour of day (0-24) ! (5 ) MIN (INTEGER) : OPTIONAL: Minute of hour (0-59) ! (6 ) SEC (INTEGER) : OPTIONAL: Seconds of minute (0-59) ! ! NOTES: ! (1 ) 1985 is the first year of the GEOS epoch. ! (2 ) Add TAU0 values for years 1985-2001 (bmy, 8/1/00) ! (3 ) Correct error for 1991 TAU values. Also added 2002 and 2003. ! (bnd, bmy, 1/4/01) ! (4 ) Updated comments (bmy, 9/26/01) ! (5 ) Now references JULDAY from "julday_mod.f" (bmy, 11/20/01) ! (6 ) Now references ERROR_STOP from "error_mod.f" (bmy, 10/15/02) !****************************************************************************** ! ! Reference to F90 modules USE ERROR_MOD, ONLY : ERROR_STOP USE JULDAY_MOD, ONLY : JULDAY ! Arguments INTEGER, INTENT(IN) :: MONTH INTEGER, INTENT(IN) :: DAY INTEGER, INTENT(IN) :: YEAR INTEGER, INTENT(IN), OPTIONAL :: HOUR INTEGER, INTENT(IN), OPTIONAL :: MIN INTEGER, INTENT(IN), OPTIONAL :: SEC ! Local variables INTEGER :: TMP_HOUR, TMP_MIN, TMP_SEC REAL*8 :: DAYS ! Return value REAL*8 :: THIS_TAU0 !================================================================= ! GET_TAU0_6A begins here! !================================================================= ! Error checking IF ( MONTH < 1 .or. MONTH > 12 ) THEN CALL ERROR_STOP ( 'Invalid MONTH selection!', 'GET_TAU0' ) ENDIF ! Error checking IF ( DAY < 1 .or. DAY > 31 ) THEN CALL ERROR_STOP ( 'Invalid DAY selection!', 'GET_TAU0' ) ENDIF ! If HOUR isn't passed, default to 0 IF ( PRESENT( HOUR ) ) THEN TMP_HOUR = HOUR ELSE TMP_HOUR = 0 ENDIF ! If MIN isn't passed, default to 0 IF ( PRESENT( MIN ) ) THEN TMP_MIN = MIN ELSE TMP_MIN = 0 ENDIF ! If SEC isn't passed, default to 0 IF ( PRESENT( SEC ) ) THEN TMP_SEC = SEC ELSE TMP_SEC = 0 ENDIF ! Number of days since midnight on 1/1/1985 THIS_TAU0 = JULDAY( YEAR, MONTH, DBLE( DAY ) ) - 2446066.5d0 ! Multiply by 24 to get hours since 1/1/1985 ! Also add in the hours elapsed since midnight on this date THIS_TAU0 = ( THIS_TAU0 * 24d0 ) + ( TMP_HOUR ) + & ( TMP_MIN / 60d0 ) + ( TMP_SEC / 3600d0 ) ! Return to calling program END FUNCTION GET_TAU0_6A !------------------------------------------------------------------------------ ! End of module END MODULE BPCH2_MOD