! $Id: diag48_mod.f,v 1.10 2005/10/27 13:59:53 bmy Exp $ MODULE DIAG48_MOD 3 ! !****************************************************************************** ! Module DIAG48_MOD contains variables and routines to save out 3-D ! timeseries output to disk (bmy, 7/20/04, 10/25/05) ! ! Module Variables: ! ============================================================================ ! (1 ) DO_SAVE_DIAG48 (LOGICAL ) : Switch to turn ND49 timeseries on/off ! (2 ) I0 (INTEGER ) : Lon offset between global & nested grid ! ! Module Routines: ! ============================================================================ ! (1 ) DIAG48 : Main driver routine ! (2 ) ITS_TIME_FOR_DIAG48 : Returns TRUE if it's time to save to disk ! (3 ) INIT_DIAG48 : Gets variable values from "input_mod.f" ! ! GEOS-CHEM modules referenced by "diag48_mod.f" ! ============================================================================ ! (1 ) bpch2_mod.f : Module w/ routines for binary punch file I/O ! (2 ) dao_mod.f : Module w/ arrays for DAO met fields ! (3 ) file_mod.f : Module w/ file unit numbers & error checks ! (4 ) grid_mod.f : Module w/ horizontal grid information ! (5 ) pbl_mix_mod.f : Module w/ routines for PBL height & mixing ! (6 ) pressure_mod.f : Module w/ routines to compute P(I,J,L) ! (7 ) time_mod.f : Module w/ routines for computing time & date ! (8 ) tracer_mod.f : Module w/ GEOS-CHEM tracer array STT etc. ! (9 ) tracerid_mod.f : Module w/ pointers to tracers & emissions ! ! ND48 tracer numbers: ! ============================================================================ ! 1 - N_TRACERS : GEOS-CHEM transported tracers [v/v ] ! 71 : Pure O3 (not Ox) concentration [v/v ] ! 72 : NO concentration [v/v ] ! 73 : NOy concentration [v/v ] ! 74 : OH concentration [molec/cm3] ! 75 : NO2 concentration [v/v ] ! 76 : PBL heights [m ] ! 77 : PBL heights [levels ] ! 78 : Air density [molec/cm3] ! 79 : 3-D Cloud fractions [unitless ] ! 80 : Column optical depths [unitless ] ! 81 : Cloud top heights [hPa ] ! 82 : Sulfate aerosol optical depth [unitless ] ! 83 : Black carbon aerosol optical depth [unitless ] ! 84 : Organic carbon aerosol optical depth [unitless ] ! 85 : Accumulation mode seasalt optical depth [unitless ] ! 86 : Coarse mode seasalt optical depth [unitless ] ! 87 : Total dust optical depth [unitless ] ! 88 : Total seasalt tracer concentration [unitless ] ! 89 - 93 : RESERVED FOR FUTURE USE ! 93 : Grid box heights [m ] ! 94 : Relative humidity [% ] ! 95 : Sea level pressure [hPa ] ! 96 : Zonal wind (a.k.a. U-wind) [m/s ] ! 97 : Meridional wind (a.k.a. V-wind) [m/s ] ! 98 : P(surface) - PTOP [hPa ] ! 99 : Temperature [K ] ! ! NOTES: ! (1 ) Now save out cld frac and grid box heights (bmy, 4/20/05) ! (2 ) Remove TRCOFFSET because it's always zero. Now call GET_HALFPOLAR ! to get the value for GEOS or GCAP grids. (bmy, 6/28/05) ! (3 ) Now make sure all USE statements are USE, ONLY (bmy, 10/3/05) ! (4 ) Now references XNUMOLAIR from "tracer_mod.f" (bmy, 10/25/05) !****************************************************************************** ! IMPLICIT NONE !================================================================= ! MODULE PRIVATE DECLARATIONS -- keep certain internal variables ! and routines from being seen outside "diag48_mod.f" !================================================================= ! Make everything PRIVATE ... PRIVATE ! ... except these variables ... PUBLIC :: DO_SAVE_DIAG48 PUBLIC :: ND48_MAX_STATIONS ! ... and these routines PUBLIC :: CLEANUP_DIAG48 PUBLIC :: DIAG48 PUBLIC :: INIT_DIAG48 PUBLIC :: ITS_TIME_FOR_DIAG48 !================================================================= ! MODULE VARIABLES !================================================================= ! Scalars LOGICAL :: DO_SAVE_DIAG48 INTEGER, PARAMETER :: ND48_MAX_STATIONS=1000 INTEGER :: ND48_FREQ INTEGER :: ND48_N_STATIONS INTEGER :: HALFPOLAR INTEGER, PARAMETER :: CENTER180=1 REAL*4 :: LONRES REAL*4 :: LATRES CHARACTER(LEN=20) :: MODELNAME CHARACTER(LEN=40) :: RESERVED = 'ND48 station timeseries' CHARACTER(LEN=80) :: TITLE CHARACTER(LEN=255) :: ND48_OUTPUT_FILE ! Arrays INTEGER, ALLOCATABLE :: ND48_I(:) INTEGER, ALLOCATABLE :: ND48_J(:) INTEGER, ALLOCATABLE :: ND48_L(:) INTEGER, ALLOCATABLE :: ND48_N(:) !================================================================= ! MODULE ROUTINES -- follow below the "CONTAINS" statement !================================================================= CONTAINS !------------------------------------------------------------------------------ SUBROUTINE DIAG48 1,33 ! !****************************************************************************** ! Subroutine DIAG48 saves station time series diagnostics to disk. ! (bmy, bey, amf, 6/1/99, 10/25/05) ! ! NOTES: ! (1 ) Remove reference to "CMN". Also now get PBL heights in meters and ! model layers from GET_PBL_TOP_m and GET_PBL_TOP_L of "pbl_mix_mod.f". ! (bmy, 2/16/05) ! (2 ) Now reference CLDF and BXHEIGHT from "dao_mod.f". Now save 3-D cloud ! fraction as tracer #79 and box height as tracer #93. Now remove ! reference to PBL from "dao_mod.f" (bmy, 4/20/05) ! (3 ) Remove references to TRCOFFSET because it's always zero. Now call ! GET_HALFPOLAR from "bpch2_mod.f" to get the HALFPOLAR flag value for ! GEOS or GCAP grids. (bmy, 6/28/05) ! (4 ) Now do not save SLP data if it is not allocated (bmy, 8/2/05) ! (5 ) Now make sure all USE statements are USE, ONLY (bmy, 10/3/05) ! (6 ) Now references XNUMOLAIR from "tracer_mod.f" (bmy, 10/25/05) !****************************************************************************** ! ! References to F90 modules USE BPCH2_MOD, ONLY : BPCH2 USE DAO_MOD, ONLY : AD, AIRDEN, BXHEIGHT, CLDF USE DAO_MOD, ONLY : CLDTOPS, OPTD, RH, SLP USE DAO_MOD, ONLY : T, UWND, VWND USE ERROR_MOD, ONLY : ERROR_STOP USE FILE_MOD, ONLY : IU_ND48 USE GRID_MOD, ONLY : GET_XOFFSET, GET_YOFFSET USE PBL_MIX_MOD, ONLY : GET_PBL_TOP_L, GET_PBL_TOP_m USE PRESSURE_MOD, ONLY : GET_PEDGE USE TIME_MOD, ONLY : GET_LOCALTIME, GET_NYMD USE TIME_MOD, ONLY : GET_NHMS, GET_TAU USE TIME_MOD, ONLY : EXPAND_DATE, ITS_A_NEW_DAY USE TRACER_MOD, ONLY : ITS_A_FULLCHEM_SIM, N_TRACERS USE TRACER_MOD, ONLY : STT, TCVV USE TRACER_MOD, ONLY : XNUMOLAIR USE TRACERID_MOD, ONLY : IDTHNO3, IDTN2O5, IDTHNO4, IDTNOX USE TRACERID_MOD, ONLY : IDTPAN, IDTPMN, IDTPPN, IDTOX USE TRACERID_MOD, ONLY : IDTR4N2, IDTSALA, IDTSALC # include "cmn_fj.h" ! Size parameters + FAST-J stuff # include "jv_cmn.h" ! ODAER, ODMDUST # include "CMN_O3" ! XNUMOLAIR # include "CMN_GCTM" ! SCALE_HEIGHT ! Local variables LOGICAL, SAVE :: IS_CLDTOPS, IS_OPTD, IS_SEASALT, IS_SLP LOGICAL, SAVE :: IS_FULLCHEM, IS_Ox, IS_NOx, IS_NOy LOGICAL, SAVE :: FIRST = .TRUE. INTEGER :: GMTRC, I, I0, J, J0, L, N, K, R, TMP, W REAL*8 :: LT, TAU, Q(LLPAR), SCALE400nm CHARACTER(LEN=40) :: CATEGORY CHARACTER(LEN=40) :: UNIT CHARACTER(LEN=255) :: FILENAME ! Aerosol types (rvm, aad, bmy, 7/20/04) INTEGER :: IND(6) = (/ 22, 29, 36, 43, 50, 15 /) !================================================================= ! DIAG48 begins here! !================================================================= ! Get grid offsets I0 = GET_XOFFSET( GLOBAL=.TRUE. ) J0 = GET_YOFFSET( GLOBAL=.TRUE. ) ! First-time initialization IF ( FIRST ) THEN ! Set logical flags on first timestep IS_CLDTOPS = ALLOCATED( CLDTOPS ) IS_OPTD = ALLOCATED( OPTD ) IS_SLP = ALLOCATED( SLP ) IS_FULLCHEM = ITS_A_FULLCHEM_SIM() IS_SEASALT = ( IDTSALA > 0 .and. IDTSALC > 0 ) IS_Ox = ( IS_FULLCHEM .and. IDTOX > 0 ) IS_NOx = ( IS_FULLCHEM .and. IDTNOX > 0 ) IS_NOy = ( IS_FULLCHEM .and. & IDTNOX > 0 .and. IDTPAN > 0 .and. & IDTHNO3 > 0 .and. IDTPMN > 0 .and. & IDTPPN > 0 .and. IDTR4N2 > 0 .and. & IDTN2O5 > 0 .and. IDTHNO4 > 0 ) ! Replace YYYYMMDD tokens in filename FILENAME = TRIM( ND48_OUTPUT_FILE ) CALL EXPAND_DATE( FILENAME, GET_NYMD(), GET_NHMS() ) ! Open file for writing CALL OPEN_ND48_FILE( FILENAME ) ! Reset first-time flag FIRST = .FALSE. ENDIF !================================================================= ! Store station timeseries data in the Q array !================================================================= ! Get TAU value TAU = GET_TAU() ! Loop over each station DO W = 1, ND48_N_STATIONS ! Get lon, lat, alt, tracer indices I = ND48_I(W) J = ND48_J(W) K = ND48_L(W) N = ND48_N(W) ! Get local time LT = GET_LOCALTIME( I ) ! Initialize Q(:) = 0 IF ( N <= N_TRACERS ) THEN !------------------------------------ ! GEOS-CHEM tracers [v/v] !------------------------------------ CATEGORY = 'IJ-AVG-$' UNIT = '' ! Let GAMAP pick the unit GMTRC = N DO L = 1, K Q(L) = STT(I,J,L,N) * TCVV(N) / AD(I,J,L) ENDDO ELSE IF ( N == 71 .and. IS_Ox ) THEN !------------------------------------ ! PURE O3 CONCENTRATION [v/v] !------------------------------------ CATEGORY = 'IJ-AVG-$' UNIT = '' ! Let GAMAP pick the unit GMTRC = N_TRACERS + 1 DO L = 1, K Q(L) = STT(I,J,L,IDTOX) * TCVV(IDTOX) / & AD(I,J,L) * FRACO3(I,J,L) ENDDO ELSE IF ( N == 72 .and. IS_NOx ) THEN !------------------------------------ ! NO CONCENTRATION [v/v] !------------------------------------ CATEGORY = 'TIME-SER' UNIT = '' ! Let GAMAP pick the unit GMTRC = 9 DO L = 1, K Q(L) = STT(I,J,L,IDTNOX) * TCVV(IDTNOX) * & FRACNO(I,J,L) / AD(I,J,L) ENDDO ELSE IF ( N == 73 .and. IS_NOy ) THEN !------------------------------------- ! NOy CONCENTRATION [v/v] !------------------------------------- CATEGORY = 'TIME-SER' UNIT = '' ! Let GAMAP pick unit GMTRC = 3 DO L = 1, K ! Initialize Q(L) = 0d0 ! NOx Q(L) = Q(L) + ( TCVV(IDTNOX) * & STT(I,J,L,IDTNOX) / AD(I,J,L) ) ! PAN Q(L) = Q(L) + ( TCVV(IDTPAN) * & STT(I,J,L,IDTPAN) / AD(I,J,L) ) ! HNO3 Q(L) = Q(L) + ( TCVV(IDTHNO3) * & STT(I,J,L,IDTHNO3) / AD(I,J,L) ) ! PMN Q(L) = Q(L) + ( TCVV(IDTPMN) * & STT(I,J,L,IDTPMN) / AD(I,J,L) ) ! PPN Q(L) = Q(L) + ( TCVV(IDTPPN) * & STT(I,J,L,IDTPPN) / AD(I,J,L) ) ! R4N2 Q(L) = Q(L) + ( TCVV(IDTR4N2) * & STT(I,J,L,IDTR4N2) / AD(I,J,L) ) ! N2O5 Q(L) = Q(L) + ( 2d0 * TCVV(IDTN2O5) * & STT(I,J,L,IDTN2O5) / AD(I,J,L) ) ! HNO4 Q(L) = Q(L) + ( TCVV(IDTHNO4) * & STT(I,J,L,IDTHNO4) / AD(I,J,L) ) ENDDO ELSE IF ( N == 74 .and. IS_FULLCHEM ) THEN !------------------------------------ ! OH CONCENTRATION [molec/cm3] !------------------------------------ CATEGORY = 'TIME-SER' UNIT = 'molec/cm3' GMTRC = 2 DO L = 1, K Q(L) = SAVEOH(I,J,L) ENDDO ELSE IF ( N == 75 .and. IS_FULLCHEM ) THEN !------------------------------------ ! NO2 CONCENTRATION [molec/cm3] !------------------------------------ CATEGORY = 'TIME-SER' UNIT = '' ! Let GAMAP pick the unit GMTRC = 19 DO L = 1, K Q(L) = SAVENO2(I,J,L) ENDDO ELSE IF ( N == 76 ) THEN !------------------------------------- ! PBL HEIGHTS [m] !------------------------------------- CATEGORY = 'PBLDEPTH' UNIT = 'm' GMTRC = 1 IF ( K == 1 ) THEN Q(1) = GET_PBL_TOP_m( I, J ) ENDIF ELSE IF ( N == 77 ) THEN !------------------------------------- ! PBL HEIGHTS [layers] !------------------------------------- CATEGORY = 'PBLDEPTH' UNIT = 'm' GMTRC = 2 IF ( K == 1 ) THEN Q(1) = GET_PBL_TOP_L( I, J ) ENDIF ELSE IF ( N == 78 ) THEN !------------------------------------- ! AIR DENSITY [molec/cm3] !------------------------------------- CATEGORY = 'TIME-SER' UNIT = 'molec/cm3' GMTRC = 22 DO L = 1, K Q(L) = AIRDEN(L,I,J) * XNUMOLAIR * 1d-6 ENDDO ELSE IF ( N == 79 ) THEN !------------------------------------- ! CLOUD FRACTIONS [unitless] !------------------------------------- CATEGORY = 'TIME-SER' UNIT = 'unitless' GMTRC = 19 DO L = 1, K Q(L) = CLDF(L,I,J) ENDDO ELSE IF ( N == 80 .and. IS_OPTD ) THEN !--------------------------------------- ! COLUMN OPTICAL DEPTHS [unitless] !--------------------------------------- CATEGORY = 'TIME-SER' UNIT = 'unitless' GMTRC = 20 Q(1) = SUM( OPTD(:,I,J) ) ELSE IF ( N == 81 .and. IS_CLDTOPS ) THEN !--------------------------------------- ! CLOUD TOP HEIGHTS [hPa] !--------------------------------------- CATEGORY = 'TIME_SER' UNIT = 'hPa' GMTRC = 21 IF ( K == 1 ) THEN Q(1) = GET_PEDGE( I, J, CLDTOPS(I,J) ) ENDIF ELSE IF ( N == 82 ) THEN !--------------------------------------- ! SULFATE AOD @ 400nm [unitless] !--------------------------------------- CATEGORY = 'OD-MAP-$' UNIT = 'unitless' GMTRC = 6 DO R = 1, NRH ! Scaling factor for 400nm SCALE400nm = QAA(2,IND(1)+R-1) / QAA(4,IND(1)+R-1) DO L = 1, K Q(L) = ODAER(I,J,L,R) * SCALE400nm ENDDO ENDDO ELSE IF ( N == 83 ) THEN !------------------------------------- ! BLACK CARBON AOD @ 400nm [unitless] !------------------------------------- CATEGORY = 'OD-MAP-$' UNIT = 'unitless' GMTRC = 9 DO R = 1, NRH ! Scaling factor for 400nm SCALE400nm = QAA(2,IND(2)+R-1) / QAA(4,IND(2)+R-1) DO L = 1, K Q(L) = ODAER(I,J,L,NRH+R) * SCALE400nm ENDDO ENDDO ELSE IF ( N == 84 ) THEN !----------------------------------- ! ORGANIC CARBON AOD [unitless] !----------------------------------- CATEGORY = 'OD-MAP-$' UNIT = 'unitless' GMTRC = 12 DO R = 1, NRH ! Scaling factor for 400nm SCALE400nm = QAA(2,IND(3)+R-1) / QAA(4,IND(3)+R-1) DO L = 1, K Q(L) = ODAER(I,J,L,2*NRH+R) * SCALE400nm ENDDO ENDDO ELSE IF ( N == 85 ) THEN !------------------------------------- ! ACCUM SEASALT AOD @ 400nm [unitless] !------------------------------------- CATEGORY = 'OD-MAP-$' UNIT = 'unitless' GMTRC = 15 DO R = 1, NRH ! Scaling factor for 400nm SCALE400nm = QAA(2,IND(4)+R-1) / QAA(4,IND(4)+R-1) DO L = 1, K Q(L) = ODAER(I,J,L,3*NRH+R) * SCALE400nm ENDDO ENDDO ELSE IF ( N == 86 ) THEN !------------------------------------- ! COARSE SEASALT AOD @ 40nm [unitless] !------------------------------------- CATEGORY = 'OD-MAP-$' UNIT = 'unitless' GMTRC = 18 DO R = 1, NRH ! Scaling factor for 400nm SCALE400nm = QAA(2,IND(5)+R-1) / QAA(4,IND(5)+R-1) DO L = 1, K Q(L) = ODAER(I,J,L,4*NRH+R) * SCALE400nm ENDDO ENDDO ELSE IF ( N == 87 ) THEN !----------------------------------- ! TOTAL DUST OPT DEPTH [unitless] !----------------------------------- CATEGORY = 'OD-MAP-$' UNIT = 'unitless' GMTRC = 4 DO R = 1, NDUST ! Scaling factor for 400nm SCALE400nm = QAA(2,IND(6)+R-1) / QAA(4,IND(6)+R-1) DO L = 1, K Q(L) = ODMDUST(I,J,L,R) ENDDO ENDDO ELSE IF ( N == 88 .and. IS_SEASALT ) THEN !----------------------------------- ! TOTAL SEASALT TRACER [v/v] !----------------------------------- CATEGORY = 'TIME-SER' UNIT = '' ! Let GAMAP pick unit GMTRC = 24 DO L = 1, K Q(L) = ( STT(I,J,L,IDTSALA) + STT(I,J,L,IDTSALC) ) * & TCVV(IDTSALA) / AD(I,J,L) ENDDO ELSE IF ( N == 93 ) THEN !----------------------------------- ! GRID BOX HEIGHTS [m] !----------------------------------- CATEGORY = 'BXHGHT-$' UNIT = 'm' GMTRC = 1 DO L = 1, K Q(L) = BXHEIGHT(I,J,L) ENDDO ELSE IF ( N == 94 ) THEN !----------------------------------- ! RELATIVE HUMIDITY [%] !----------------------------------- CATEGORY = 'DAO-3D-$' UNIT = '%' GMTRC = 11 DO L = 1, K Q(L) = RH(I,J,L) ENDDO ELSE IF ( N == 95 .and. IS_SLP ) THEN !----------------------------------- ! SEA LEVEL PRESSURE [hPa] !----------------------------------- CATEGORY = 'DAO-FLDS' UNIT = 'hPa' GMTRC = 21 IF ( K == 1 ) THEN Q(1) = SLP(I,J) ENDIF ELSE IF ( N == 96 ) THEN !----------------------------------- ! ZONAL (U) WIND [M/S] !----------------------------------- CATEGORY = 'DAO-3D-$' UNIT = 'm/s' GMTRC = 1 DO L = 1, K Q(L) = UWND(I,J,L) ENDDO ELSE IF ( N == 97 ) THEN !----------------------------------- ! ZONAL (V) WIND [M/S] !----------------------------------- CATEGORY = 'DAO-3D-$' UNIT = 'm/s' GMTRC = 2 DO L = 1, K Q(L) = VWND(I,J,L) ENDDO ELSE IF ( N == 98 ) THEN !----------------------------------- ! PSURFACE - PTOP [hPa] !----------------------------------- CATEGORY = 'PS-PTOP' UNIT = 'hPa' GMTRC = 1 IF ( K == 1 ) THEN Q(1) = GET_PEDGE(I,J,1) - PTOP ENDIF ELSE IF ( N == 99 ) THEN !----------------------------------- ! TEMPERATURE [K] !----------------------------------- CATEGORY = 'DAO-3D-$' UNIT = 'K' GMTRC = 3 DO L = 1, K Q(L) = T(I,J,L) ENDDO ELSE ! Skip other tracers CYCLE ENDIF !============================================================== ! Write each station to a bpch file !============================================================== CALL BPCH2( IU_ND48, MODELNAME, LONRES, LATRES, & HALFPOLAR, CENTER180, CATEGORY, GMTRC, & UNIT, TAU, TAU, RESERVED, & 1, 1, K, I+I0, & J+J0, 1, REAL( Q(1:K) ) ) ENDDO !================================================================= ! Close the file at the proper time !================================================================= ! IF ( ITS_TIME_TO_CLOSE_FILE() ) THEN ! ! ! Expand date tokens in the file name ! FILENAME = TRIM( ND49_OUTPUT_FILE ) ! CALL EXPAND_DATE( FILENAME, GET_NYMD(), GET_NHMS() ) ! ! ! Echo info ! WRITE( 6, 120 ) TRIM( FILENAME ) ! 120 FORMAT( ' - DIAG49: Closing file : ', a ) ! ! ! Close file ! CLOSE( IU_ND49 ) ! ENDIF ! Flush the file once per day IF ( ITS_A_NEW_DAY() ) CALL FLUSH( IU_ND48 ) ! Return to calling program END SUBROUTINE DIAG48 !------------------------------------------------------------------------------ SUBROUTINE OPEN_ND48_FILE( FILENAME ) 1,4 ! !****************************************************************************** ! Subroutine OPEN_ND48_FILE opens a binary punch file (version 2.0) ! for writing GEOS-CHEM ND48 station timeseries data. (bmy, 7/30/02) ! ! Arguments as Input: ! ============================================================================ ! (1 ) FILENAME (CHARACTER) : Name of the file to be opened ! ! NOTES: !****************************************************************************** ! ! References to F90 modules USE FILE_MOD, ONLY : IU_ND48, IOERROR ! Arguments CHARACTER(LEN=*), INTENT(IN) :: FILENAME ! Local variables INTEGER :: IOS CHARACTER(LEN=40) :: FTI CHARACTER(LEN=80) :: TITLE !================================================================= ! OPEN_ND48_FOR_WRITE begins here! !================================================================= ! Initialize FTI = 'CTM bin 02 -- GEOS-CHEM station ts' TITLE = 'GEOS-CHEM ND48 station timeseries diagnostic' ! Open file for output OPEN( IU_ND48, FILE=TRIM( FILENAME ), STATUS='UNKNOWN', & IOSTAT=IOS, FORM='UNFORMATTED', ACCESS='SEQUENTIAL' ) ! Error check IF ( IOS /= 0 ) CALL IOERROR( IOS, IU_ND48, 'open_nd48_file:1' ) ! Write file type identifier WRITE ( IU_ND48, IOSTAT=IOS ) FTI IF ( IOS /= 0 ) CALL IOERROR( IOS, IU_ND48, 'open_nd48_file:2' ) ! Write top title WRITE ( IU_ND48, IOSTAT=IOS ) TITLE IF ( IOS /= 0 ) CALL IOERROR( IOS, IU_ND48, 'open_nd48_file:3' ) ! Return to calling program END SUBROUTINE OPEN_ND48_FILE !------------------------------------------------------------------------------ FUNCTION ITS_TIME_FOR_DIAG48() RESULT( ITS_TIME ) 1,2 ! !****************************************************************************** ! Function ITS_TIME_FOR_DIAG48 returns TRUE if it's time for the next ! timeseries data write. (bmy, 7/20/04) ! ! NOTES: !****************************************************************************** ! ! References to F90 modules USE TIME_MOD, ONLY : GET_ELAPSED_MIN ! Local variables LOGICAL :: ITS_TIME INTEGER :: XMIN !================================================================= ! ITS_TIME_FOR_DIAG48 begins here! !================================================================= ! Get elapsed minutes XMIN = GET_ELAPSED_MIN() ! Is it time to save the next timeseries station? ITS_TIME = ( DO_SAVE_DIAG48 .and. MOD( XMIN, ND48_FREQ ) == 0 ) ! Return to calling program END FUNCTION ITS_TIME_FOR_DIAG48 !------------------------------------------------------------------------------ SUBROUTINE INIT_DIAG48( DO_ND48, FREQ, N_STA, IARR, 1,12 & JARR, LARR, NARR, FILE ) ! !****************************************************************************** ! Subroutine INIT_DIAG48 allocates and zeroes all module arrays (bmy, 7/20/04) ! ! Arguments as Input: ! ============================================================================ ! (1 ) DO_ND48 (LOGICAL ) : Switch to turn on ND49 timeseries diagnostic ! (2 ) FREQ (INTEGER ) : Frequency for saving to disk [min] ! (3 ) N_STA (INTEGER ) : Number of ND48 stations from "input_mod.f" ! (4 ) IARR (INTEGER ) : Array w/ ND48 lon indices from "input_mod.f" ! (5 ) JARR (INTEGER ) : Array w/ ND48 lat indices from "input_mod.f" ! (6 ) LARR (INTEGER ) : Array w/ ND48 alt indices from "input_mod.f" ! (7 ) NARR (INTEGER ) : Array w/ ND48 tracer indices from "input_mod.f" ! (8 ) FILE (CHAR*255) : ND48 output file name read by "input_mod.f" ! ! NOTES: ! (1 ) Now call GET_HALFPOLAR from "bpch2_mod.f" to get the HALFPOLAR flag ! value for GEOS or GCAP grids. (bmy, 6/28/05) !****************************************************************************** ! ! References to F90 modules USE BPCH2_MOD, ONLY : GET_MODELNAME, GET_HALFPOLAR USE ERROR_MOD, ONLY : ALLOC_ERR, ERROR_STOP # include "CMN_SIZE" ! Size parameters ! Arguments LOGICAL, INTENT(IN) :: DO_ND48 INTEGER, INTENT(IN) :: FREQ INTEGER, INTENT(IN) :: N_STA INTEGER, INTENT(IN) :: IARR(ND48_MAX_STATIONS) INTEGER, INTENT(IN) :: JARR(ND48_MAX_STATIONS) INTEGER, INTENT(IN) :: LARR(ND48_MAX_STATIONS) INTEGER, INTENT(IN) :: NARR(ND48_MAX_STATIONS) CHARACTER(LEN=255), INTENT(IN) :: FILE ! Local variables INTEGER :: AS, N CHARACTER(LEN=255) :: LOCATION !================================================================= ! INIT_DIAG48 begins here! !================================================================= ! Location string LOCATION = 'INIT_DIAG48 ("diag48_mod.f")' !----------------------------- ! Get values from input_mod.f !----------------------------- DO_SAVE_DIAG48 = DO_ND48 ND48_FREQ = FREQ ND48_N_STATIONS = N_STA ND48_OUTPUT_FILE = TRIM( FILE ) ! Error check IF ( ND48_N_STATIONS > ND48_MAX_STATIONS ) THEN CALL ERROR_STOP( 'Too many ND48 stations!', LOCATION ) ENDIF !------------------------------ ! Allocate module arrays !------------------------------ ALLOCATE( ND48_I( ND48_N_STATIONS ), STAT=AS ) IF ( AS /= 0 ) CALL ALLOC_ERR( 'ND48_I' ) ALLOCATE( ND48_J( ND48_N_STATIONS ), STAT=AS ) IF ( AS /= 0 ) CALL ALLOC_ERR( 'ND48_J' ) ALLOCATE( ND48_L( ND48_N_STATIONS ), STAT=AS ) IF ( AS /= 0 ) CALL ALLOC_ERR( 'ND48_L' ) ALLOCATE( ND48_N( ND48_N_STATIONS ), STAT=AS ) IF ( AS /= 0 ) CALL ALLOC_ERR( 'ND48_N' ) !------------------------------- ! Copy values & error check !------------------------------- DO N = 1, ND48_N_STATIONS ! Error check longitude IF ( IARR(N) < 1 .or. IARR(N) > IIPAR ) THEN CALL ERROR_STOP( 'Bad longitude index!', LOCATION ) ELSE ND48_I(N) = IARR(N) ENDIF ! Error check latitude IF ( JARR(N) < 1 .or. JARR(N) > JJPAR ) THEN CALL ERROR_STOP( 'Bad latitude index!', LOCATION ) ELSE ND48_J(N) = JARR(N) ENDIF ! Error check longitude IF ( LARR(N) < 1 .or. LARR(N) > LLPAR ) THEN CALL ERROR_STOP( 'Bad altitude index!', LOCATION ) ELSE ND48_L(N) = LARR(N) ENDIF ! Tracer array ND48_N(N) = NARR(N) ENDDO !------------------------------- ! For bpch file output !------------------------------- LONRES = DISIZE LATRES = DJSIZE MODELNAME = GET_MODELNAME() HALFPOLAR = GET_HALFPOLAR() ! Return to calling program END SUBROUTINE INIT_DIAG48 !------------------------------------------------------------------------------ SUBROUTINE CLEANUP_DIAG48 ! !****************************************************************************** ! Subroutine CLEANUP_DIAG48 deallocates all module arrays (bmy, 7/20/04) ! ! NOTES: !****************************************************************************** ! !================================================================= ! CLEANUP_DIAG48 begins here! !================================================================= IF ( ALLOCATED( ND48_I ) ) DEALLOCATE( ND48_I ) IF ( ALLOCATED( ND48_J ) ) DEALLOCATE( ND48_J ) IF ( ALLOCATED( ND48_L ) ) DEALLOCATE( ND48_L ) IF ( ALLOCATED( ND48_N ) ) DEALLOCATE( ND48_N ) ! Return to calling program END SUBROUTINE CLEANUP_DIAG48 !------------------------------------------------------------------------------ ! Return to calling program END MODULE DIAG48_MOD