Files
GEOS-Chem-adjoint-v35-note/code/diag42_mod.f
2018-08-28 00:43:47 -04:00

426 lines
16 KiB
Fortran

! $Id: diag42_mod.f,v 1.1 2009/06/09 21:51:53 daven Exp $
MODULE DIAG42_MOD
!
!******************************************************************************
! Module DIAG42_MOD contains arrays and routines for archiving the ND42
! diagnostic -- secondary organic aerosols [ug/m3]. (dkh,bmy,5/22/06,3/29/07)
!
! Module Variables:
! ============================================================================
! (1 ) AD42 (REAL*4) : Array for SOA concentrations [ug/m3]
!
! Module Routines:
! ============================================================================
! (1 ) DIAG42 : Archives quantities for diagnostic
! (2 ) ZERO_DIAG42 : Sets all module arrays to zero
! (3 ) WRITE_DIAG42 : Writes data in module arrays to bpch file
! (4 ) INIT_DIAG42 : Allocates all module arrays
! (5 ) CLEANUP_DIAG42 : Deallocates all module arrays
!
! GEOS-CHEM modules referenced by diag03_mod.f
! ============================================================================
! (1 ) bpch2_mod.f : Module w/ routines for binary pch file I/O
! (2 ) error_mod.f : Module w/ NaN and other error check routines
! (3 ) file_mod.f : Module w/ file unit numbers and error checks
! (4 ) grid_mod.f : Module w/ horizontal grid information
! (5 ) pressure_mod.f : Module w/ routines to compute P(I,J,L)
! (6 ) time_mod.f : Module w/ routines to compute date & time
!
! NOTES:
! (1 ) Replace TINY(1d0) with 1d-32 to avoid problems on SUN 4100 platform
! (bmy, 9/5/06)
! (2 ) Now use ratio of 2.1 instead of 1.4 for SOA4 (dkh, bmy, 3/29/07)
! (3 ) Add diagnostics for SOAG and SOAM (tmf, 1/7/09)
!******************************************************************************
!
IMPLICIT NONE
!=================================================================
! MODULE PRIVATE DECLARATIONS -- keep certain internal variables
! and routines from being seen outside "diag42_mod.f"
!=================================================================
! Make everything PUBLIC
PUBLIC
!=================================================================
! MODULE VARIABLES
!=================================================================
! Scalars
INTEGER :: ND42, LD42
! Parameters
INTEGER, PARAMETER :: PD42 = 14
! Arrays
REAL*4, ALLOCATABLE :: AD42(:,:,:,:)
!=================================================================
! MODULE ROUTINES -- follow below the "CONTAINS" statement
!=================================================================
CONTAINS
!------------------------------------------------------------------------------
SUBROUTINE DIAG42
!
!******************************************************************************
! Subroutine DIAG42 archives SOA concentrations [ug/m3] for the ND42
! diagnostic. (dkh, bmy, 5/22/06, 3/29/07)
!
! NOTES:
! (1 ) Now use ratio of 2.1 instead of 1.4 for SOA4 (dkh, bmy, 3/29/07)
!******************************************************************************
!
! References to F90 modules
USE DAO_MOD, ONLY : AIRVOL, T
!USE DIAG_MOD, ONLY : LTOTH
USE PRESSURE_MOD, ONLY : GET_PCENTER
USE TRACER_MOD, ONLY : STT
USE TRACERID_MOD, ONLY : IDTSOA1, IDTSOA2, IDTSOA3, IDTSOA4
USE TRACERID_MOD, ONLY : IDTOCPI, IDTOCPO
USE TRACERID_MOD, ONLY : IDTSOAG, IDTSOAM
# include "CMN_SIZE" ! Size parameters
# include "CMN_DIAG" ! NDxx flags
! Local variables
INTEGER :: I, J, L
REAL*8 :: FACTOR, PRES
! Factor for computing standard volume
REAL*8, PARAMETER :: STD_VOL_FAC = 1013.25d0 / 273.15d0
!=================================================================
! DIAG42 begins here!
!=================================================================
! Error check
IF ( IDTSOA1 == 0 ) RETURN
IF ( IDTSOA2 == 0 ) RETURN
IF ( IDTSOA3 == 0 ) RETURN
IF ( IDTSOA4 == 0 ) RETURN
IF ( IDTOCPO == 0 ) RETURN
IF ( IDTOCPI == 0 ) RETURN
! Loop over grid boxes
!$OMP PARALLEL DO
!$OMP+DEFAULT( SHARED )
!$OMP+PRIVATE( I, J, L, FACTOR, PRES )
DO L = 1, LD42
DO J = 1, JJPAR
DO I = 1, IIPAR
! Conversion factor from [kg] --> [ug/m3]
! (LTOTH=1 if between OTH_HR1 and OTH_HR2, LTOTH=0 otherwise)
!FACTOR = 1d9 / AIRVOL(I,J,L) * LTOTH(I,J)
! Conversion factor from [kg] --> [ug/m3]
FACTOR = 1d9 / AIRVOL(I,J,L)
! SOA1 [ug/m3]
AD42(I,J,L,1) = AD42(I,J,L,1) +
& ( STT(I,J,L,IDTSOA1) * FACTOR )
! SOA2 [ug/m3]
AD42(I,J,L,2) = AD42(I,J,L,2) +
& ( STT(I,J,L,IDTSOA2) * FACTOR )
! SOA3 [ug/m3]
AD42(I,J,L,3) = AD42(I,J,L,3) +
& ( STT(I,J,L,IDTSOA3) * FACTOR )
! SOA4 [ug/m3]
AD42(I,J,L,4) = AD42(I,J,L,4) +
& ( STT(I,J,L,IDTSOA4) * FACTOR )
! Sum of original 3 SOA types [ug/m3]
AD42(I,J,L,5) = AD42(I,J,L,5) +
& ( STT(I,J,L,IDTSOA1) +
& STT(I,J,L,IDTSOA2) +
& STT(I,J,L,IDTSOA3) ) * FACTOR
! Sum of SOA1 to SOA4
AD42(I,J,L,6) = AD42(I,J,L,6) +
& ( STT(I,J,L,IDTSOA1) +
& STT(I,J,L,IDTSOA2) +
& STT(I,J,L,IDTSOA3) +
& STT(I,J,L,IDTSOA4) ) * FACTOR
! Sum of primary OC + SOA1 to SOA4 [ug C/m3]
! Use higher ratio (2.1) of molecular weight of
! organic mass per carbon mass accounting for non-carbon
! components attached to OC [Turpin and Lim, 2001]
AD42(I,J,L,7) = AD42(I,J,L,7) +
& ( ( STT(I,J,L,IDTSOA1) +
& STT(I,J,L,IDTSOA2) +
& STT(I,J,L,IDTSOA3) +
& STT(I,J,L,IDTSOA4) ) / 2.1d0
& + ( STT(I,J,L,IDTOCPO) +
& STT(I,J,L,IDTOCPI) ) ) * FACTOR
! Sum of PRIMARY OC + SOA1 to SOA4 [ug C/m3] at STP
PRES = GET_PCENTER( I, J, L )
AD42(I,J,L,8) = AD42(I,J,L,7) * STD_VOL_FAC * T(I,J,L) / PRES
!--------------------------------------------------------
! Additional diagnostics for SOAG, SOAM (tmf, 12/8/07)
! Assume SOAG mass = GLYX mass, SOAM mass = MGLY mass
! Test if SOAG and SOAM are simulated (ccc, 12/18/08)
!--------------------------------------------------------
IF ( IDTSOAG /= 0 .AND. IDTSOAM /=0 ) THEN
! SOAG [ug total mass /m3]
AD42(I,J,L,9) = AD42(I,J,L,9) +
& ( STT(I,J,L,IDTSOAG) * 1.d0 * FACTOR )
! SOAM [ug total mass /m3]
AD42(I,J,L,10) = AD42(I,J,L,10) +
& ( STT(I,J,L,IDTSOAM) * 1.d0 * FACTOR )
! Sum of SOA1 to SOA4, SOAG, SOAM (tmf, 1/31/07)
AD42(I,J,L,11) = AD42(I,J,L,11) +
& ( STT(I,J,L,IDTSOA1) +
& STT(I,J,L,IDTSOA2) +
& STT(I,J,L,IDTSOA3) +
& STT(I,J,L,IDTSOA4) +
& ( STT(I,J,L,IDTSOAG) * 1.d0 ) +
& ( STT(I,J,L,IDTSOAM) * 1.d0 )) * FACTOR
! Sum of SOA1 to SOA4, SOAG, SOAM in carbon (tmf, 1/31/07)
! Except SOAG is 0.41 carbon, SOAM is 0.5 carbon
AD42(I,J,L,12) = AD42(I,J,L,12) +
& ( ( STT(I,J,L,IDTSOA1) +
& STT(I,J,L,IDTSOA2) +
& STT(I,J,L,IDTSOA3) +
& STT(I,J,L,IDTSOA4) ) / 2.1d0 +
& ( STT(I,J,L,IDTSOAG) * 0.41D0 ) +
& ( STT(I,J,L,IDTSOAM) * 0.50D0 ) +
& ( STT(I,J,L,IDTOCPO) +
& STT(I,J,L,IDTOCPI) ) ) * FACTOR
! Sum of SOA1 to SOA4, SOAG, SOAM at STP [ug/sm3 STP] (tmf, 1/31/07)
PRES = GET_PCENTER( I, J, L )
AD42(I,J,L,13) = AD42(I,J,L,11) * STD_VOL_FAC * T(I,J,L)
& / PRES
! Sum of all OC [ug C/sm3] at STP (including SOAG, SOAM)
AD42(I,J,L,14) = AD42(I,J,L,12) * STD_VOL_FAC * T(I,J,L)
& / PRES
ENDIF
ENDDO
ENDDO
ENDDO
!$OMP END PARALLEL DO
! Return to calling program
END SUBROUTINE DIAG42
!------------------------------------------------------------------------------
SUBROUTINE ZERO_DIAG42
!
!******************************************************************************
! Subroutine ZERO_DIAG42 zeroes the ND03 diagnostic arrays.
! (dkh, bmy, 5/22/06)
!
! NOTES:
!******************************************************************************
!
!=================================================================
! ZERO_DIAG42 begins here!
!=================================================================
! Exit if ND42 is turned off
IF ( ND42 == 0 ) RETURN
! Zero arrays
AD42(:,:,:,:) = 0e0
! Return to calling program
END SUBROUTINE ZERO_DIAG42
!------------------------------------------------------------------------------
SUBROUTINE WRITE_DIAG42
!
!******************************************************************************
! Subroutine WRITE_DIAG03 writes the ND03 diagnostic arrays to the binary
! punch file at the proper time. (bmy, 5/22/06, 9/5/06)
!
! # : Field : Description : Units : Scale factor
! -----------------------------------------------------------------------
! (1 ) IJ-SOA-$ : SOA1 : ug/m3 : SCALE_OTH
! (2 ) IJ-SOA-$ : SOA2 : ug/m3 : SCALE_OTH
! (3 ) IJ-SOA-$ : SOA3 : ug/m3 : SCALE_OTH
! (4 ) IJ-SOA-$ : SOA4 : ug/m3 : SCALE_OTH
! (5 ) IJ-SOA-$ : SOA1 + SOA2 + SOA3 : ug/m3 : SCALE_OTH
! (6 ) IJ-SOA-$ : SOA1 + SOA2 + SOA3 + SOA4 : ug/m3 : SCALE_OTH
! (7 ) IJ-SOA-$ : Sum of all Org Carbon : ug C/m3 : SCALE_OTH
! (8 ) IJ-SOA-$ : Sum of all Org Carbon @ STP : ug C/sm3 : SCALE_OTH
!
! NOTES:
! (1 ) Replace TINY(1d0) with 1d-32 to avoid problems on SUN 4100 platform
! (bmy, 9/5/06)
!******************************************************************************
!
! References to F90 modules
USE BPCH2_MOD, ONLY : BPCH2, GET_MODELNAME, GET_HALFPOLAR
!USE DIAG_MOD, ONLY : CTOTH
USE FILE_MOD, ONLY : IU_BPCH
USE GRID_MOD, ONLY : GET_XOFFSET, GET_YOFFSET
USE TIME_MOD, ONLY : GET_CT_DYN, GET_DIAGb, GET_DIAGe
# include "CMN_SIZE" ! Size parameters
# include "CMN_DIAG" ! TINDEX
! Local variables
INTEGER :: CENTER180, HALFPOLAR
INTEGER :: L, M, N
INTEGER :: IFIRST, JFIRST, LFIRST
REAL*4 :: LONRES, LATRES
REAL*4 :: ARRAY(IIPAR,JJPAR,LLPAR)
!REAL*8 :: SCALE(IIPAR,JJPAR)
REAL*8 :: SCALE
REAL*8 :: DIAGb, DIAGe
CHARACTER(LEN=20) :: MODELNAME
CHARACTER(LEN=40) :: CATEGORY
CHARACTER(LEN=40) :: RESERVED
CHARACTER(LEN=40) :: UNIT
!=================================================================
! WRITE_DIAG42 begins here!
!=================================================================
! Exit if ND03 is turned off
IF ( ND42 == 0 ) RETURN
! Initialize
CENTER180 = 1
DIAGb = GET_DIAGb()
DIAGe = GET_DIAGe()
HALFPOLAR = GET_HALFPOLAR()
IFIRST = GET_XOFFSET( GLOBAL=.TRUE. ) + 1
JFIRST = GET_YOFFSET( GLOBAL=.TRUE. ) + 1
LATRES = DJSIZE
LFIRST = 1
LONRES = DISIZE
MODELNAME = GET_MODELNAME()
RESERVED = ''
!SCALE = FLOAT( CTOTH ) + TINY( 1d0 )
!SCALE = DBLE( GET_CT_DYN() ) + TINY( 1d0 )
SCALE = DBLE( GET_CT_DYN() ) + TINY( 1e0 )
!=================================================================
! Write data to the bpch file
!=================================================================
! Loop over ND03 diagnostic tracers
DO M = 1, TMAX(42)
! Define quantities
N = TINDEX(42,M)
CATEGORY = 'IJ-SOA-$'
! Pick proper unit
SELECT CASE ( N )
CASE( 7 )
UNIT = 'ug C/m3'
CASE( 8 )
UNIT = 'ug C/sm3'
CASE( 12 )
UNIT = 'ug C/m3'
CASE( 13 )
UNIT = 'ug/sm3'
CASE( 14 )
UNIT = 'ug C/sm3'
CASE DEFAULT
UNIT = 'ug/m3'
END SELECT
! Apply scale factor
DO L = 1, LD42
!ARRAY(:,:,L) = AD42(:,:,L,N) / SCALE(:,:)
ARRAY(:,:,L) = AD42(:,:,L,N) / SCALE
ENDDO
! Write data to disk
CALL BPCH2( IU_BPCH, MODELNAME, LONRES, LATRES,
& HALFPOLAR, CENTER180, CATEGORY, N,
& UNIT, DIAGb, DIAGe, RESERVED,
& IIPAR, JJPAR, LD42, IFIRST,
& JFIRST, LFIRST, ARRAY(:,:,1:LD42) )
ENDDO
! Return to calling program
END SUBROUTINE WRITE_DIAG42
!------------------------------------------------------------------------------
SUBROUTINE INIT_DIAG42
!
!******************************************************************************
! Subroutine INIT_DIAG42 allocates all module arrays (bmy, 5/22/06)
!
! NOTES:
!******************************************************************************
!
! References to F90 modules
USE ERROR_MOD, ONLY : ALLOC_ERR
USE LOGICAL_MOD, ONLY : LSOA
# include "CMN_SIZE" ! Size parameters
! Local variables
INTEGER :: AS
!=================================================================
! INIT_DIAG42 begins here!
!=================================================================
! Turn off ND42 if SOA tracers are not used
IF ( .not. LSOA ) THEN
ND42 = 0
RETURN
ENDIF
! Exit if ND42 is turned off
IF ( ND42 == 0 ) RETURN
! Number of levels to save for this diagnostic
LD42 = MIN( ND42, LLPAR )
! 2-D array ("LFLASH-$")
ALLOCATE( AD42( IIPAR, JJPAR, LD42, PD42 ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'AD42' )
! Zero arrays
CALL ZERO_DIAG42
! Return to calling program
END SUBROUTINE INIT_DIAG42
!------------------------------------------------------------------------------
SUBROUTINE CLEANUP_DIAG42
!
!******************************************************************************
! Subroutine CLEANUP_DIAG42 deallocates all module arrays (bmy, 5/22/06)
!
! NOTES:
!******************************************************************************
!
!=================================================================
! CLEANUP_DIAG42 begins here!
!=================================================================
IF ( ALLOCATED( AD42 ) ) DEALLOCATE( AD42 )
! Return to calling program
END SUBROUTINE CLEANUP_DIAG42
!------------------------------------------------------------------------------
! End of module
END MODULE DIAG42_MOD