Files
GEOS-Chem-adjoint-v35-note/code/adjoint/input_adj_mod.f
2025-10-02 14:49:27 +08:00

4148 lines
150 KiB
Fortran

!$Id: input_adj_mod.f,v 1.21 2012/08/10 22:08:22 nicolas Exp $
MODULE INPUT_ADJ_MOD
!
!******************************************************************************
! Module INPUT_ADJ_MOD reads the GEOS-Chem ADJOINT input file (input.gcadj)
! at the start of the inverse run and passes the information to several other
! GEOS-Chem F90 modules. It complements input.geos with adjoint specific flags
! and settings. Most of the code follows the convention from input_mod.f
! (adj_group, 6/6/09)
!
! Module Variables:
! ============================================================================
! (1 ) VERBOSE (LOGICAL ) : Turns on echo-back of lines read from disk.
! (2 ) FIRSTCOL (INTEGER ) : First column of the input file (default=26)
! (3 ) MAXDIM (INTEGER ) : Maximum number of substrings to read in
! (9 ) FILENAME (CHAR*255) : GEOS-CHEM adjoint input file name
! (10) TOPTITLE (CHAR*255) : Top line of input file
!
! Module Routines:
! ============================================================================
! (1 ) READ_INPUT_ADJ_FILE : Driver routine for reading GEOS-CHEM input file 读取 GC 输入文件
! (2 ) READ_ONE_LINE : Reads one line at a time 一次读取一行
! (3 ) SPLIT_ONE_LINE : Splits one line into substrings (by spaces) 通过空格分割文本
! (4 ) READ_ADJ_SIMULATION_MENU : Reads the GEOS-Chem adjoint simulation menu 读取伴随设定
! (5 ) READ_FWD_MODEL_MENU : Reads forward model options 读取正向模拟选项
! (6 ) READ_ADJ_OPTIONS_MENU : Reads adjoint model options 读取伴随模式选项
! (7 ) READ_ADJ_DIRECTORIES_MENU : Reads the GEOS-Chem adj. directories 读取 GC 伴随路径
! (8 ) READ_CONTROL_VARS_MENU: Reads what are control variables 读取控制变量
! (9 ) READ_OBSERVATION_MENU : Reads vars related to observations 读取观测相关变量
! (10) READ_FD_ MENU : Reads finite difference test variables 读取有限差分测试变量
! (11) READ_ADJ_DIAGNOSTICS_MENU : Reads the GEOS-Chem adj. diagnostic menu 读取伴随诊断菜单
! (12) VALIDATE_DIRECTORIES : Makes sure all given directories are valid 确认给定目录有效
! (13) ARE_FLAGS_VALID : Makes sure all flags are valid/not conflicting 确认所有选项游戏哦啊
! (14) CHECK_DIRECTORY : Checks a single directory for errors 确认单个路径
! (15) CLEAN_FILE_DIRS : Clean out directories 清除路径
! (16) INIT_DEP_MAPS : Make mapping arrays for dep adjoint forcing 创建伴随强迫的映射数组
! (17) INIT_INPUT_ADJ : Initializes directory & logical variables 初始化路径
!
! GEOS-CHEM modules referenced by "input_adj_mod.f"
! ============================================================================
! (1 ) directory_adj_mod.f : Module w/ GC adjoint directories
! (2 ) error_mod.f : Module w/ I/O error and NaN check routines
! (3 ) file_mod.f : Module w/ file unit numbers and error checks
! (4 ) grid_mod.f : Module w/ horizontal grid information
! (5 ) logical_adj_mod.f : Module w/ GC adjoint logical switches
! (6 ) adj_arrays_mod.f : Module w/ adj. arrays.
! NOTES:
! (1 ) Add LPOP_UGM3 (sev, dkh, 02/13/12, adj32_024)
! (2 ) Add LINVH_BFGS (nab, 25/03/12 )
!******************************************************************************
!
IMPLICIT NONE
!=================================================================
! MODULE PRIVATE DECLARATIONS -- keep certain internal variables
! and routines from being seen outside "input_adj_mod.f"
!=================================================================
! Make everything PRIVATE ...
PRIVATE
! ... except these routines
PUBLIC :: READ_INPUT_ADJ_FILE
PUBLIC :: INIT_DEP_MAPS
!=================================================================
! MODULE VARIABLES
!=================================================================
LOGICAL :: VERBOSE = .FALSE.
INTEGER, PARAMETER :: FIRSTCOL = 33
INTEGER, PARAMETER :: MAXDIM = 255
INTEGER :: CT1, CT2, CT3
CHARACTER(LEN=255) :: FILENAME = 'input.gcadj'
CHARACTER(LEN=255) :: TOPTITLE
! For RRATE list
LOGICAL :: READ_STR_ID = .FALSE.
LOGICAL :: READ_RXN_ID = .FALSE.
!=================================================================
! MODULE ROUTINES -- follow below the "CONTAINS" statement
!=================================================================
CONTAINS
!------------------------------------------------------------------------------
SUBROUTINE READ_INPUT_ADJ_FILE
!
!******************************************************************************
! Subroutine READ_INPUT_ADJ_FILE is the driver program for reading the
! GEOS_CHEM adjoint input file "input.gcadj" from disk. (adj_group, 6/07/09)
!
! NOTES:
! (1 ) Now call DO_GAMAP (dkh, 02/09/10)
! (2 ) Now call INIT_TRACERID_ADJ (dkh, 03/30/10)
!******************************************************************************
!
! References to F90 modules
USE ADJ_ARRAYS_MOD, ONLY : INIT_TRACERID_ADJ
USE CHARPAK_MOD, ONLY : STRREPL
USE FILE_MOD, ONLY : IU_GEOS, IOERROR
USE INPUT_MOD, ONLY : TRACERINFO, DIAGINFO
USE GAMAP_MOD, ONLY : DO_GAMAP
! Local variables
LOGICAL :: EOF
INTEGER :: IOS
CHARACTER(LEN=1) :: TAB = ACHAR(9)
CHARACTER(LEN=1) :: SPACE = ' '
CHARACTER(LEN=255) :: LINE
!=================================================================
! READ_INPUT_ADJ_FILE begins here!
!=================================================================
! Echo output
WRITE( 6, '(a )' ) REPEAT( '=', 79 )
WRITE( 6, '(a,/)' )'G E O S - C H E M A D J O I N T I N P U T'
WRITE( 6, 100 ) TRIM( FILENAME )
100 FORMAT( 'READ_INPUT_ADJ_FILE: Reading ', a )
! Initialize directory & logical variables
CALL INIT_INPUT_ADJ
! Initialize adjoint tracer ID's to zero
CALL INIT_TRACERID_ADJ
! Open file
OPEN( IU_GEOS, FILE=TRIM( FILENAME ), STATUS='OLD', IOSTAT=IOS )
IF ( IOS /= 0 ) CALL IOERROR( IOS,IU_GEOS,'read_input_adj_file:1')
! Read TOPTITLE for binary punch file
TOPTITLE = READ_ONE_LINE( EOF )
IF ( EOF ) RETURN
! Loop until EOF
DO
! Read a line from the file, exit if EOF
LINE = READ_ONE_LINE( EOF )
IF ( EOF ) EXIT
! Replace tab characters in LINE (if any) w/ spaces
CALL STRREPL( LINE, TAB, SPACE )
!=============================================================
! Call individual subroutines to read sections of the file
!=============================================================
IF ( INDEX( LINE, 'ADJOINT SIMULATION MENU' ) > 0 ) THEN
CALL READ_ADJ_SIMULATION_MENU
ELSE IF ( INDEX( LINE, 'FORWARD MODEL OPTIONS' ) > 0 ) THEN
CALL READ_FWD_MODEL_MENU
ELSE IF ( INDEX( LINE, 'ADJOINT MODEL OPTIONS' ) > 0 ) THEN
CALL READ_ADJ_OPTIONS_MENU
ELSE IF ( INDEX( LINE, 'DIRECTORIES' ) > 0 ) THEN
CALL READ_ADJ_DIRECTORIES_MENU
ELSE IF ( INDEX( LINE, 'CONTROL VARIABLE MENU' ) > 0 ) THEN
CALL READ_CONTROL_VARS_MENU
!mkeller: weak constraint menu
ELSE IF ( INDEX( LINE, 'WEAK CONSTRAINT MENU' ) > 0 ) THEN
CALL READ_WEAK_CONSTRAINT_MENU
ELSE IF ( INDEX( LINE, 'OBSERVATION MENU' ) > 0 ) THEN
CALL READ_OBSERVATION_MENU
ELSE IF ( INDEX( LINE, 'FINITE DIFFERENCE MENU' ) > 0 ) THEN
CALL READ_FD_MENU
ELSE IF ( INDEX( LINE, 'DIAGNOSTICS MENU' ) > 0 ) THEN
CALL READ_ADJ_DIAGNOSTICS_MENU
ELSE IF ( INDEX( LINE, 'CRITICAL LOAD MENU' ) > 0 ) THEN
CALL READ_ADJ_CRITICAL_LOAD_MENU
ELSE IF ( INDEX( LINE, 'END OF FILE' ) > 0 ) THEN
EXIT
ENDIF
ENDDO
! Close input file
CLOSE( IU_GEOS )
!=================================================================
! Further error-checking and initialization
!=================================================================
! Make sure all directories are valid
CALL VALIDATE_DIRECTORIES
! Clean out file directories (rm *.chk.* , *.adj.* , *.sf.* and
! *.gdt.* files )
CALL CLEAN_FILE_DIRS
! Are all the flags a valid combination?
CALL ARE_FLAGS_VALID
! Echo output
WRITE( 6, '(a)' ) REPEAT( '=', 79 )
! Now call this routine here so that adjoint names have been
! defined. (dkh, 02/09/10)
CALL DO_GAMAP( DIAGINFO, TRACERINFO )
! Return to calling program
END SUBROUTINE READ_INPUT_ADJ_FILE
!------------------------------------------------------------------------------
FUNCTION READ_ONE_LINE( EOF, LOCATION ) RESULT( LINE )
!
!******************************************************************************
! Subroutine READ_ONE_LINE reads a line from the input file. If the global
! variable VERBOSE is set, the line will be printed to stdout. READ_ONE_LINE
! can trap an unexpected EOF if LOCATION is passed. Otherwise, it will pass
! a logical flag back to the calling routine, where the error trapping will
! be done. (bmy, 7/20/04)
!
! Arguments as Output:
! ===========================================================================
! (1 ) EOF (CHARACTER) : Logical flag denoting EOF condition
! (2 ) LOCATION (CHARACTER) : Name of calling routine; traps premature EOF
!
! Function value:
! ===========================================================================
! (1 ) LINE (CHARACTER) : A line of text as read from the file
!
! NOTES:
!******************************************************************************
!
! References to F90 modules
USE FILE_MOD, ONLY : IU_GEOS, IOERROR
USE FILE_MOD, ONLY : IU_RXN !(hml, 04/03/13)
USE FILE_MOD, ONLY : IU_STR !(hml, 05/22/13)
! Arguments
LOGICAL, INTENT(OUT) :: EOF
CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: LOCATION
! Local variables
INTEGER :: IOS
CHARACTER(LEN=255) :: LINE, MSG
!=================================================================
! READ_ONE_LINE begins here!
!=================================================================
! Initialize
EOF = .FALSE.
! Read a line from the file (hml, 05/22/13)
IF ( READ_STR_ID ) READ ( IU_STR, '(a)', IOSTAT=IOS ) LINE
IF ( READ_RXN_ID ) READ ( IU_RXN, '(a)', IOSTAT=IOS ) LINE
IF ( .NOT. READ_STR_ID .AND. .NOT. READ_RXN_ID ) THEN
READ ( IU_GEOS,'(a)', IOSTAT=IOS ) LINE
ENDIF
! IO Status < 0: EOF condition
IF ( IOS < 0 ) THEN
EOF = .TRUE.
! Trap unexpected EOF -- stop w/ error msg if LOCATION is passed
! Otherwise, return EOF to the calling program
IF ( PRESENT( LOCATION ) ) THEN
MSG = 'READ_ONE_LINE: error at: ' // TRIM( LOCATION )
WRITE( 6, '(a)' ) MSG
WRITE( 6, '(a)' ) 'Unexpected end of file encountered!'
WRITE( 6, '(a)' ) 'STOP in READ_ONE_LINE (input_mod.f)'
WRITE( 6, '(a)' ) REPEAT( '=', 79 )
STOP
ELSE
RETURN
ENDIF
ENDIF
! IO Status > 0: true I/O error condition (hml, 05/22/13)
IF ( READ_STR_ID ) THEN
IF ( IOS > 0 ) CALL IOERROR( IOS, IU_STR, 'read_one_line:1-a' )
ENDIF
IF ( READ_RXN_ID ) THEN
IF ( IOS > 0 ) CALL IOERROR( IOS, IU_RXN, 'read_one_line:1-b' )
ENDIF
IF ( .NOT. READ_STR_ID .AND. .NOT. READ_RXN_ID ) THEN
IF ( IOS > 0 ) CALL IOERROR( IOS, IU_GEOS,'read_one_line:1-c' )
ENDIF
! Print the line (if necessary)
IF ( VERBOSE ) WRITE( 6, '(a)' ) TRIM( LINE )
! Return to calling program
END FUNCTION READ_ONE_LINE
!------------------------------------------------------------------------------
SUBROUTINE SPLIT_ONE_LINE( SUBSTRS, N_SUBSTRS, N_EXP, LOCATION )
!
!******************************************************************************
! Subroutine SPLIT_ONE_LINE reads a line from the input file (via routine
! READ_ONE_LINE), and separates it into substrings. (bmy, 7/20/04)
!
! SPLIT_ONE_LINE also checks to see if the number of substrings found is
! equal to the number of substrings that we expected to find. However, if
! you don't know a-priori how many substrings to expect a-priori,
! you can skip the error check.
!
! Arguments as Input:
! ===========================================================================
! (3 ) N_EXP (INTEGER ) : Number of substrings we expect to find
! (N_EXP < 0 will skip the error check!)
! (4 ) LOCATION (CHARACTER) : Name of routine that called SPLIT_ONE_LINE
!
! Arguments as Output:
! ===========================================================================
! (1 ) SUBSTRS (CHARACTER) : Array of substrings (separated by " ")
! (2 ) N_SUBSTRS (INTEGER ) : Number of substrings actually found
!
! NOTES:
!******************************************************************************
!
! References to F90 modules
USE CHARPAK_MOD, ONLY: STRSPLIT
! Arguments
CHARACTER(LEN=255), INTENT(OUT) :: SUBSTRS(MAXDIM)
INTEGER, INTENT(OUT) :: N_SUBSTRS
INTEGER, INTENT(IN) :: N_EXP
CHARACTER(LEN=*), INTENT(IN) :: LOCATION
! Local varaibles
LOGICAL :: EOF
CHARACTER(LEN=255) :: LINE, MSG
!=================================================================
! SPLIT_ONE_LINE begins here!
!=================================================================
! Create error msg
MSG = 'SPLIT_ONE_LINE: error at ' // TRIM( LOCATION )
!=================================================================
! Read a line from disk
!=================================================================
LINE = READ_ONE_LINE( EOF )
! STOP on End-of-File w/ error msg
IF ( EOF ) THEN
WRITE( 6, '(a)' ) TRIM( MSG )
WRITE( 6, '(a)' ) 'End of file encountered!'
WRITE( 6, '(a)' ) 'STOP in SPLIT_ONE_LINE (input_mod.f)!'
WRITE( 6, '(a)' ) REPEAT( '=', 79 )
STOP
ENDIF
!=================================================================
! Split the lines between spaces -- start at column FIRSTCOL
!=================================================================
CALL STRSPLIT( LINE(FIRSTCOL:), ' ', SUBSTRS, N_SUBSTRS )
! Sometimes we don't know how many substrings to expect,
! if N_EXP is greater than MAXDIM, then skip the error check
IF ( N_EXP < 0 ) RETURN
! Stop if we found the wrong
IF ( N_EXP /= N_SUBSTRS ) THEN
WRITE( 6, '(a)' ) TRIM( MSG )
WRITE( 6, 100 ) N_EXP, N_SUBSTRS
WRITE( 6, '(a)' ) 'STOP in SPLIT_ONE_LINE (input_mod.f)!'
WRITE( 6, '(a)' ) REPEAT( '=', 79 )
STOP
100 FORMAT( 'Expected ',i2, ' substrs but found ',i3 )
ENDIF
! Return to calling program
END SUBROUTINE SPLIT_ONE_LINE
!------------------------------------------------------------------------------
!MK-WEAK_CONSTRAINT:
SUBROUTINE READ_WEAK_CONSTRAINT_MENU
!
!******************************************************************************
! Subroutine READ_WEAK_CONSTRAINT_MENU reads the WEAK CONSTRAINT MENU section of
! the GEOS-CHEM adjoint input file (adj_group, 6/07/09)
!
! NOTES:
! (1 ) first attempt at subroutine (mkeller)
!******************************************************************************
!
! References to F90 modules
USE WEAK_CONSTRAINT_MOD, ONLY : DO_WEAK_CONSTRAINT
USE WEAK_CONSTRAINT_MOD, ONLY : MIN_LON_U
USE WEAK_CONSTRAINT_MOD, ONLY : MAX_LON_U
USE WEAK_CONSTRAINT_MOD, ONLY : MIN_LAT_U
USE WEAK_CONSTRAINT_MOD, ONLY : MAX_LAT_U
USE WEAK_CONSTRAINT_MOD, ONLY : MIN_LEV_U_INDEX
USE WEAK_CONSTRAINT_MOD, ONLY : MAX_LEV_U_INDEX
USE WEAK_CONSTRAINT_MOD, ONLY : LEN_SUBWINDOW_U
USE WEAK_CONSTRAINT_MOD, ONLY : N_TRACER_U
USE TRACER_MOD, ONLY : N_TRACERS
USE ERROR_MOD, ONLY : ERROR_STOP
! Local variables
INTEGER :: N
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
!=================================================================
! READ_WEAK_CONSTRAINT_MENU begins here!
!=================================================================
! Check if we are running the weak constraint module at all
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:1')
READ( SUBSTRS(1:N), * ) DO_WEAK_CONSTRAINT
IF (.NOT. DO_WEAK_CONSTRAINT) THEN
PRINT*, 'NOT RUNNING WEAK CONSTRAINT MODEL!'
RETURN
ENDIF
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:2')
READ( SUBSTRS(1:N), * ) N_TRACER_U
IF ( N_TRACER_U > N_TRACERS ) THEN
CALL ERROR_STOP( 'WC-Index bigger than total number of tracers',
& 'read_weak_constraint_menu, input_adj_mod.f')
ENDIF
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:3')
READ( SUBSTRS(1:N), * ) MIN_LON_U
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:4')
READ( SUBSTRS(1:N), * ) MAX_LON_U
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:5')
READ( SUBSTRS(1:N), * ) MIN_LAT_U
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:6')
READ( SUBSTRS(1:N), * ) MAX_LAT_U
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:7')
READ( SUBSTRS(1:N), * ) MIN_LEV_U_INDEX
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:8')
READ( SUBSTRS(1:N), * ) MAX_LEV_U_INDEX
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_weak_constraint_menu:9')
READ( SUBSTRS(1:N), * ) LEN_SUBWINDOW_U
END SUBROUTINE READ_WEAK_CONSTRAINT_MENU
!------------------------------------------------------------------------------
SUBROUTINE READ_ADJ_SIMULATION_MENU
!
!******************************************************************************
! Subroutine READ_ADJ_SIMULATION_MENU reads the SIMULATION MENU section of
! the GEOS-CHEM adjoint input file (adj_group, 6/07/09)
!
! NOTES:
! (1 ) Reordering and updates (dkh, 02/09/11)
!******************************************************************************
!
! References to F90 modules
USE LOGICAL_MOD, ONLY : LTRAN
USE LOGICAL_ADJ_MOD, ONLY : LADJ
USE LOGICAL_ADJ_MOD, ONLY : LFD_SPOT
USE LOGICAL_ADJ_MOD, ONLY : LFD_GLOB
USE LOGICAL_ADJ_MOD, ONLY : LFDTEST
USE LOGICAL_ADJ_MOD, ONLY : LSENS
USE LOGICAL_ADJ_MOD, ONLY : L4DVAR
USE LOGICAL_ADJ_MOD, ONLY : L3DVAR
! Local variables
INTEGER :: N
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
!=================================================================
! READ_ADJ_SIMULATION_MENU begins here!
!=================================================================
! Check if we are running the adjoint at all
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:1' )
READ( SUBSTRS(1:N), * ) LADJ
IF (.NOT. LADJ) THEN
PRINT*, 'NOT RUNNING THE ADJOINT!'
RETURN
ENDIF
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_adj_sim_menu:2' )
!! Doing transport adjoint
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:2' )
!READ( SUBSTRS(1:N), * ) LADJ_TRAN
! Doing 4DVAR
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:3' )
READ( SUBSTRS(1:N), * ) L4DVAR
! Doing 3DVAR
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:4' )
READ( SUBSTRS(1:N), * ) L3DVAR
! Doing sensitivity run (no differences in cost function, just tracer conc)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:5' )
READ( SUBSTRS(1:N), * ) LSENS
! Move to FORWARD MODEL menu (dkh, 02/09/11)
!! Doing chemistry
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:3' )
!READ( SUBSTRS(1:N), * ) LADJ_CHEM
!
!! Doing aerosol thermodynamics
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:4' )
!READ( SUBSTRS(1:N), * ) LAERO_THERM
IF ( .NOT. ( LSENS .OR. L4DVAR .OR. L3DVAR ) ) THEN
PRINT*, '******************************************'
PRINT*, 'HAVE TO PICK A SIMULATION, READ THE MANUAL!'
PRINT*, '******************************************'
RETURN
ENDIF
! Check to see if its a finite difference calculation
IF ( LSENS ) THEN
! Doing finite difference test in 1 gridbox
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_menu:6' )
READ( SUBSTRS(1:N), * ) LFD_SPOT
! Doing finite difference test in all grid boxes, turn transport off
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_menu:7' )
READ( SUBSTRS(1:N), * ) LFD_GLOB
! turn of transport for global FD test
IF ( LFD_GLOB ) LTRAN = .FALSE.
! define a more generic LFDTEST flag if either method is true
IF ( LFD_GLOB .OR. LFD_SPOT ) LFDTEST = .TRUE.
ENDIF
! Move these to other menus (dkh, 02/09/11)
!!=================================================================
!! Include a priori term of the cost function (the one without the data)
!! aka source term
!! aka background term
!! aka penalty term
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:10' )
!READ( SUBSTRS(1:N), * ) LAPSRC
!
!! Compute background error covariance
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:11' )
!READ( SUBSTRS(1:N), * ) LBKCOV
!
!! Compute approximation of inverse Hessian
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:12' )
!READ( SUBSTRS(1:N), * ) LINVH
!
!! include LINOZ
!! NOTE: This flag controls both forward and adjoint execution
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim_menu:13' )
!READ( SUBSTRS(1:N), * ) LLINOZ
!
!! Check if we are running the adjoint at all
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_sim _menu:14' )
!READ( SUBSTRS(1:N), * ) LRXNR
!=================================================================
! Print to screen
!=================================================================
WRITE( 6, '(/,a)' ) 'ADJOINT SIMULATION MENU'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 100 ) 'Doing adjoint run : ', LADJ
!WRITE( 6, 100 ) 'Doing adjoint transport : ', LADJ_TRAN
!WRITE( 6, 100 ) 'Doing adjoint chemistry : ', LADJ_CHEM
!WRITE( 6, 100 ) 'Doing aerosol thermodynamics : ',LAERO_THERM
WRITE( 6, 100 ) 'Doing 4DVAR (inversion) : ', L4DVAR
WRITE( 6, 100 ) 'Doing 3DVAR : ', L3DVAR
WRITE( 6, 100 ) 'Doing sensitivity run : ', LSENS
!WRITE( 6, 100 ) 'Include source term in J : ', LAPSRC
!WRITE( 6, 100 ) 'Compute background error cov : ', LBKCOV
!WRITE( 6, 100 ) 'Compute inverse Hessian : ', LINVH
!WRITE( 6, 100 ) 'Use LINOZ (fwd and adj) : ', LLINOZ
!WRITE( 6, 100 ) 'Include reaction rates LRXNR : ', LRXNR
WRITE( 6, 100 ) 'Doing finite diff check (1box): ', LFD_SPOT
WRITE( 6, 100 ) 'Doing finite diff check (glob): ', LFD_GLOB
! Format statements
100 FORMAT( A, L5 )
110 FORMAT( A, I5 )
!=================================================================
! Call setup routines from other GEOS-CHEM modules
!=================================================================
! Set counter
CT1 = CT1 + 1
! Return to calling program
END SUBROUTINE READ_ADJ_SIMULATION_MENU
!------------------------------------------------------------------------------
SUBROUTINE READ_FWD_MODEL_MENU
!
!******************************************************************************
! Subroutine READ_FWD_MODEL_MENU reads the FORWARD MODEL OPTIONS section of
! the GEOS-CHEM adjoint input file (dkh, 02/09/11)
!
! NOTES:
!
!******************************************************************************
!
! References to F90 modules
USE LOGICAL_MOD, ONLY : LTRAN
USE LOGICAL_ADJ_MOD, ONLY : LADJ_CHEM
!USE LOGICAL_ADJ_MOD, ONLY : LLINOZ
USE LOGICAL_ADJ_MOD, ONLY : LAERO_THERM
USE LOGICAL_ADJ_MOD, ONLY : LISO
! Local variables
INTEGER :: N
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
!=================================================================
! READ_FWD_MODEL_MENU begins here!
!=================================================================
! Doing chemistry
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fwd_menu:1' )
READ( SUBSTRS(1:N), * ) LADJ_CHEM
! Doing aerosol thermodynamics
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fwd_menu:2' )
READ( SUBSTRS(1:N), * ) LAERO_THERM
! Use ISORROPIAII
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fwd_menu:3' )
READ( SUBSTRS(1:N), * ) LISO
! Now use new strat_chem_mod (hml, dkh, 02/14/12, adj32_025)
!! include LINOZ
!! NOTE: This flag controls both forward and adjoint execution
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fwd_menu:3' )
!READ( SUBSTRS(1:N), * ) LLINOZ
!=================================================================
! Print to screen
!=================================================================
WRITE( 6, '(/,a)' ) 'FORWARD MODEL OPTIONS'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 100 ) 'Doing adjoint chemistry : ', LADJ_CHEM
WRITE( 6, 100 ) 'Doing aerosol thermodynamics : ',LAERO_THERM
WRITE( 6, 100 ) ' => ISORROPIAII : ', LISO
!WRITE( 6, 100 ) 'Use LINOZ (fwd and adj) : ', LLINOZ
! Format statements
100 FORMAT( A, L5 )
110 FORMAT( A, I5 )
!=================================================================
! Call setup routines from other GEOS-CHEM modules
!=================================================================
! Set counter
CT1 = CT1 + 1
! Return to calling program
END SUBROUTINE READ_FWD_MODEL_MENU
!------------------------------------------------------------------------------
SUBROUTINE READ_ADJ_OPTIONS_MENU
!
!******************************************************************************
! Subroutine READ_ADJ_OPTIONS_MENU reads the ADJOINT MODEL OPTIONS section of
! the GEOS-CHEM adjoint input file (adj_group, 6/07/09)
!
! NOTES:
! (1 ) Reordering and updates (dkh, 02/09/11)
! (2 ) Add LINVH_BFGS (nab, 25/03/12 )
!******************************************************************************
!
! References to F90 modules
USE LOGICAL_MOD, ONLY : LTRAN
USE LOGICAL_ADJ_MOD, ONLY : LAPSRC
USE LOGICAL_ADJ_MOD, ONLY : LBKCOV
USE LOGICAL_ADJ_MOD, ONLY : LINVH, LINVH_BFGS
USE LOGICAL_ADJ_MOD, ONLY : LRXNR
USE LOGICAL_ADJ_MOD, ONLY : LDEL_CHKPT
USE LOGICAL_ADJ_MOD, ONLY : LFILL_ADJ
! Local variables
INTEGER :: N
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
!=================================================================
! READ_ADJ_OPTIONS_MENU begins here!
!=================================================================
! Move these to other menus (dkh, 02/09/11)
!=================================================================
! Include a priori term of the cost function (the one without the data)
! aka source term
! aka background term
! aka penalty term
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_opt_menu:10' )
READ( SUBSTRS(1:N), * ) LAPSRC
! Compute background error covariance
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_opt_menu:11' )
READ( SUBSTRS(1:N), * ) LBKCOV
! Compute approximation of inverse Hessian
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_opt_menu:12' )
READ( SUBSTRS(1:N), * ) LINVH
! Compute approximation of L-BFGS inverse Hessian
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_opt_menu:13' )
READ( SUBSTRS(1:N), * ) LINVH_BFGS
! Compute reaction rate constant sensitivities
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_opt_menu:14' )
READ( SUBSTRS(1:N), * ) LRXNR
! Delete checkpt files
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_opt_menu:15' )
READ( SUBSTRS(1:N), * ) LDEL_CHKPT
! Scale up and FILL adj transport
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_opt_menu:15' )
READ( SUBSTRS(1:N), * ) LFILL_ADJ
!=================================================================
! Print to screen
!=================================================================
WRITE( 6, '(/,a)' ) 'ADJOINT MODEL OPTIONS'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 100 ) 'Include source term in J : ', LAPSRC
WRITE( 6, 100 ) 'Compute background error cov : ', LBKCOV
WRITE( 6, 100 ) 'Compute inverse Hessian : ', LINVH
WRITE( 6, 100 ) 'Compute L-BFGS inverse Hessian : '
& , LINVH_BFGS
WRITE( 6, 100 ) 'Include reaction rates LRXNR : ', LRXNR
WRITE( 6, 100 ) 'Delete chkpt files LDEL_CHKPT : ',
& LDEL_CHKPT
WRITE( 6, 100 ) 'Scale up and FILL adj transport: ', LFILL_ADJ
! Format statements
100 FORMAT( A, L5 )
110 FORMAT( A, I5 )
!=================================================================
! Call setup routines from other GEOS-CHEM modules
!=================================================================
! Set counter
CT1 = CT1 + 1
! Return to calling program
END SUBROUTINE READ_ADJ_OPTIONS_MENU
!------------------------------------------------------------------------------
SUBROUTINE READ_ADJ_DIRECTORIES_MENU
!
!******************************************************************************
! Subroutine READ_ADJ_DIRECTORIES_MENU reads the DIRECTORIES MENU section of
! the GEOS-CHEM adjoint input file (adj_group, 6/07/09)
!
! NOTES:
!******************************************************************************
!
! References to F90 modules
USE DIRECTORY_ADJ_MOD, ONLY : OPTDATA_DIR, ADJTMP_DIR, DIAGADJ_DIR
! Local variables
INTEGER :: N
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
!=================================================================
! READ_ADJ_DIRECTORIES_MENU begins here!
!=================================================================
! Optimization output data dir
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_directories_menu:1' )
READ( SUBSTRS(1:N), '(a)' ) OPTDATA_DIR
! Optimization temporary directory
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_directories_menu:2' )
READ( SUBSTRS(1:N), '(a)' ) ADJTMP_DIR
! Optimization diagnostic file directory
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_directories_menu:2' )
READ( SUBSTRS(1:N), '(a)' ) DIAGADJ_DIR
WRITE( 6, '(/,a)' ) 'DIRECTORIES MENU'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 110 ) 'Optimization output directory : ',
& TRIM( OPTDATA_DIR )
WRITE( 6, 110 ) 'Temporary adjoint directory : ',
& TRIM( ADJTMP_DIR )
WRITE( 6, 110 ) 'Diagnostic adjoint directory : ',
& TRIM( DIAGADJ_DIR )
110 FORMAT( A, A )
! Set counter
CT1 = CT1 + 1
END SUBROUTINE READ_ADJ_DIRECTORIES_MENU
!---------------------------------------------------------------------------------------
!
! SUBROUTINE READ_CONTROL_PARAMS_MENU
!!
!!******************************************************************************
!! Subroutine READ_CONTROL_PARAMS_MENU reads the CONTROL PARAMETERS MENU section of
!! the GEOS-CHEM adjoint input file (adj_group, 6/07/09)
!!
!! NOTES:
!! (1 ) Add ICS_SF_tmp, EMS_SF_tmp (mak, dkh, 10/01/09)
!! (2 ) Merge this with CONTROL_VARS_MENU
!!******************************************************************************
!!
! ! References to F90 modules
! USE LOGICAL_ADJ_MOD, ONLY : LADJ_EMS
! USE LOGICAL_ADJ_MOD, ONLY : LICS
! USE ADJ_ARRAYS_MOD, ONLY : ICS_SF_tmp
! USE ADJ_ARRAYS_MOD, ONLY : EMS_SF_tmp
!
!
! ! Local variables
! INTEGER :: N
! CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
!
! !=================================================================
! ! READ_ADJ_SIMULATION_MENU begins here!
! !=================================================================
!
! ! Optimizing emissions
! CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_params_menu:1' )
! READ( SUBSTRS(1:N), * ) LADJ_EMS
!
! ! Optimizing initial conditions
! CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_params_menu:3' )
! READ( SUBSTRS(1:N), * ) LICS
!
! ! Optimizing initial conditions
! CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_params_menu:4' )
! READ( SUBSTRS(1:N), * ) ICS_SF_tmp
!
! ! Optimizing initial conditions
! CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_params_menu:5' )
! READ( SUBSTRS(1:N), * ) EMS_SF_tmp
!
!
! !=================================================================
! ! Print to screen
! !=================================================================
! WRITE( 6, '(/,a)' ) 'CONTROL PARAMETERS MENU'
! WRITE( 6, '( a)' ) '---------------'
! WRITE( 6, 100 ) 'Optimizing emissions : ', LADJ_EMS
! WRITE( 6, 100 ) 'Optimizing initial conditions : ', LICS
! WRITE( 6, 110 ) 'First guess for ICS_SF is : ', ICS_SF_tmp
! WRITE( 6, 110 ) 'First guess for EMS_SF is : ', EMS_SF_tmp
!
!
! ! Format statements
! 100 FORMAT( A, L5 )
! 110 FORMAT( A, f7.2 )
!
!
! !=================================================================
! ! Call setup routines from other GEOS-CHEM modules
! !=================================================================
!
! ! Set counter
! CT1 = CT1 + 1
!
! ! Return to calling program
! END SUBROUTINE READ_CONTROL_PARAMS_MENU
!
!!------------------------------------------------------------------------------
SUBROUTINE READ_CONTROL_VARS_MENU
!
!******************************************************************************
! Subroutine READ_CONTROL_VARS_MENU reads the CONTROL VARIABLES MENU section of
! the GEOS-CHEM adjoint input file (adj_group, 6/07/09)
!
! NOTES:
! (1 ) Reorder and update (dkh, 02/09/11)
! (2 ) Add support for strat fluxes LADJ_STRAT (hml, dkh, 02/14/12, adj32_025)
!******************************************************************************
!
! References to F90 modules
USE ERROR_MOD, ONLY : ALLOC_ERR
USE ERROR_MOD, ONLY : ERROR_STOP
USE LOGICAL_ADJ_MOD, ONLY : LADJ_EMS
USE LOGICAL_ADJ_MOD, ONLY : LICS
USE ADJ_ARRAYS_MOD, ONLY : NNEMS
USE ADJ_ARRAYS_MOD, ONLY : ID_ADEMS
USE ADJ_ARRAYS_MOD, ONLY : ADEMS_NAME
USE ADJ_ARRAYS_MOD, ONLY : TRACERID_ADJ
USE ADJ_ARRAYS_MOD, ONLY : INIT_ADJ_EMS
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_EMS
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_TRACER
USE ADJ_ARRAYS_MOD, ONLY : REG_PARAM_ICS
USE ADJ_ARRAYS_MOD, ONLY : REG_PARAM_EMS
USE ADJ_ARRAYS_MOD, ONLY : MMSCL
USE ADJ_ARRAYS_MOD, ONLY : EMS_ERROR
USE ADJ_ARRAYS_MOD, ONLY : COV_ERROR_LX, COV_ERROR_LY
USE ADJ_ARRAYS_MOD, ONLY : ICS_ERROR
USE ADJ_ARRAYS_MOD, ONLY : ICS_SF_DEFAULT
USE ADJ_ARRAYS_MOD, ONLY : EMS_SF_DEFAULT
USE TRACER_MOD, ONLY : N_TRACERS
USE TRACER_MOD, ONLY : TRACER_NAME
! for strat prod and loss SF (hml, 08/14/11)
USE LOGICAL_ADJ_MOD, ONLY : LADJ_STRAT
USE ADJ_ARRAYS_MOD, ONLY : NSTPL
USE ADJ_ARRAYS_MOD, ONLY : ID_PROD
USE ADJ_ARRAYS_MOD, ONLY : ID_LOSS
USE ADJ_ARRAYS_MOD, ONLY : PROD_NAME
USE ADJ_ARRAYS_MOD, ONLY : LOSS_NAME
USE ADJ_ARRAYS_MOD, ONLY : STRPID_ADJ
USE ADJ_ARRAYS_MOD, ONLY : STRLID_ADJ
USE ADJ_ARRAYS_MOD, ONLY : INIT_ADJ_STRAT
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_PROD
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_LOSS
USE ADJ_ARRAYS_MOD, ONLY : REG_PARAM_PROD
USE ADJ_ARRAYS_MOD, ONLY : REG_PARAM_LOSS
USE ADJ_ARRAYS_MOD, ONLY : PROD_ERROR
USE ADJ_ARRAYS_MOD, ONLY : LOSS_ERROR
USE ADJ_ARRAYS_MOD, ONLY : PROD_SF_DEFAULT
USE ADJ_ARRAYS_MOD, ONLY : LOSS_SF_DEFAULT
! for reaction rates (tww, 05/08/12)
USE LOGICAL_ADJ_MOD, ONLY : LADJ_RRATE
USE ADJ_ARRAYS_MOD, ONLY : NRRATES
USE ADJ_ARRAYS_MOD, ONLY : ID_RRATES
USE ADJ_ARRAYS_MOD, ONLY : RRATES_NAME
USE ADJ_ARRAYS_MOD, ONLY : INIT_ADJ_RRATES
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_RATE
USE ADJ_ARRAYS_MOD, ONLY : REG_PARAM_RATE
USE ADJ_ARRAYS_MOD, ONLY : RATE_ERROR
USE ADJ_ARRAYS_MOD, ONLY : RATE_SF_DEFAULT
USE GCKPP_ADJ_GLOBAL, ONLY : NCOEFF_RATE
! (hml, 05/22/13)
USE LOGICAL_ADJ_MOD, ONLY : FI_STRID
USE LOGICAL_ADJ_MOD, ONLY : FI_RXNID
USE FILE_MOD, ONLY : IOERROR
USE FILE_MOD, ONLY : IU_STR
USE FILE_MOD, ONLY : IU_RXN
# include "define_adj.h"
! Local variables
INTEGER :: N, T, NSOPT, TMP, AS
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
! For RRATE list (hml, 04/03/13)
INTEGER :: IOS
!=================================================================
! READ_CONTROL_VARS_MENU begins here!
!=================================================================
!=================================================================
! Allocate arrays
!=================================================================
! First allocate OPT_THIS_TRACER to be max species
ALLOCATE( OPT_THIS_TRACER( N_TRACERS ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'OPT_THIS_TRACER' )
OPT_THIS_TRACER = .FALSE.
ALLOCATE( REG_PARAM_ICS( N_TRACERS ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'REG_PARAM_ICS' )
REG_PARAM_ICS = 1d0
ALLOCATE( ICS_ERROR( N_TRACERS ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'ICS_ERROR' )
ICS_ERROR = 1d0
#if defined ( LOG_OPT )
ICS_ERROR = EXP(1d0)
#endif
ALLOCATE( ICS_SF_DEFAULT( N_TRACERS ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'ICS_SF_DEFAULT' )
ICS_SF_DEFAULT = 1d0
!=================================================================
! Read menu
!=================================================================
! Optimizing initial conditions
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_vars_menu:1' )
READ( SUBSTRS(1:N), * ) LICS
! Optimizing emissions
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_vars_menu:2' )
READ( SUBSTRS(1:N), * ) LADJ_EMS
! Optimizing strat prod & loss (hml, 08/11/11, adj32_025)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_vars_menu:3a' )
READ( SUBSTRS(1:N), * ) LADJ_STRAT
! Specifying reaction rates (tww, 05/08/12)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_vars_menu:3d' )
READ( SUBSTRS(1:N), * ) LADJ_RRATE
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:3b' )
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:3c')
! Number of species to optimize
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_vars_menu:4' )
READ( SUBSTRS(1:N), * ) NSOPT
IF ( LICS .AND. NSOPT .EQ. 0) THEN
CALL ERROR_STOP( ' LICS is T but NSOPT is 0 ',
& ' READ_CONTROL_VARS_MENU, geos_chem_mod.f ' )
ENDIF
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:5' )
DO T = 1, NSOPT
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,'read_control_vars_menu:6')
! set OPT_THIS_TRACER to true for species we're optimizing
READ( SUBSTRS(1), * ) TMP
OPT_THIS_TRACER(TMP) = .TRUE.
! now move this to observation menu (dkh, 02/09/11)
!! observe this species?
!READ( SUBSTRS(3), *) OBS_THIS_SPECIES(TMP)
! Defualt scaling factor for this initial condition
READ( SUBSTRS(3), *) ICS_SF_DEFAULT(TMP)
! REG_PARAM for this species
READ( SUBSTRS(4), *) REG_PARAM_ICS(TMP)
! ICS_ERROR for this emission
READ( SUBSTRS(5), *) ICS_ERROR(TMP)
ENDDO
! Obsolete -- now we only list tracer that are observed
! compute number of observed species
!NOBS = 0
!DO T = 1, N_TRACERS
! IF ( OBS_THIS_SPECIES(T) ) THEN
! NOBS = NOBS + 1
! ENDIF
!ENDDO
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:7' )
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:7b')
! Optimizing emissions
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_control_vars_menu:8' )
READ( SUBSTRS(1:N), * ) NNEMS
IF ( .NOT. LADJ_EMS ) NNEMS = 0
! If we're optimizing initial conditions, number of tracers is
!N_TRACERS
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:9' )
IF ( LADJ_EMS .AND. NNEMS .GT. 0) THEN
CALL INIT_ADJ_EMS
ELSEIF ( LADJ_EMS .AND. NNEMS .EQ. 0) THEN
CALL ERROR_STOP( ' LADJ_EMS is T but NNEMS is 0 ',
& ' READ_CONTROL_VARS_MENU, geos_chem_mod.f ' )
ENDIF
!=================================================================
! Read emission ID
!=================================================================
IF ( LADJ_EMS ) THEN
DO T = 1, NNEMS
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:10')
! Save tracer number
READ( SUBSTRS(1), * ) ID_ADEMS(T)
! Save tracer name
ADEMS_NAME(T) = TRIM( SUBSTRS(2) )
! optimize this emission?Q
READ( SUBSTRS(3), *) OPT_THIS_EMS(T)
! Defualt scaling factor for this emission
READ( SUBSTRS(4), *) EMS_SF_DEFAULT(T)
! REG_PARAM for this emission
READ( SUBSTRS(5), *) REG_PARAM_EMS(T)
! EMS_ERROR for this emission
READ( SUBSTRS(6), *) EMS_ERROR(T)
! CORR_LX for this emission
READ( SUBSTRS(7), *) COV_ERROR_LX(T)
! CORR_LY for this emission
READ( SUBSTRS(8), *) COV_ERROR_LY(T)
ENDDO
! Number of temporal groups of the control vector,
! e.g. monthly optimization in a year-long simulation would have
! 12. If in doubt, set to 1
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_control_vars_menu:11' )
READ( SUBSTRS(1:N), * ) MMSCL
! Strat prod and loss (hml, adj32_025)
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:12b')
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:12c')
! Optimizing strat prod & loss
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_control_vars_menu:13' )
READ( SUBSTRS(1:N), * ) NSTPL
IF ( .NOT. LADJ_STRAT ) NSTPL = 0
! Read the list from file? (hml, 05/21/13)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_control_vars_menu:14' )
READ( SUBSTRS(1:N), * ) FI_STRID
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:15' )
IF ( LADJ_STRAT .AND. NSTPL .GT. 0) THEN
CALL INIT_ADJ_STRAT
ELSEIF ( LADJ_STRAT .AND. NSTPL .EQ. 0) THEN
CALL ERROR_STOP( ' LADJ_STRAT is T but NSTPL is 0 ',
& ' READ_CONTROL_VARS_MENU, geos_chem_mod.f ' )
ENDIF
!PRINT *, ' NSTPL = ' , NSTPL
!=================================================================
! Read Stratospheric Tracers ID
!=================================================================
IF ( LADJ_STRAT .AND. .NOT. FI_STRID ) THEN ! (hml, 05/21/13)
DO T = 1, NSTPL
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:16')
! Save tracer number
READ( SUBSTRS(1), * ) ID_PROD(T)
! Save tracer name
PROD_NAME(T) = TRIM( SUBSTRS(2) )
! optimize this strat prod & loss?
READ( SUBSTRS(3), *) OPT_THIS_PROD(T)
! Defualt prod scaling factor for this strat tracer
READ( SUBSTRS(4), *) PROD_SF_DEFAULT(T)
! REG_PARAM for this strat tracer
READ( SUBSTRS(5), *) REG_PARAM_PROD(T)
! STR_ERROR for this strat tracer
READ( SUBSTRS(6), *) PROD_ERROR(T)
ENDDO
DO T = 1, NSTPL
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:16-b')
! Save tracer number
READ( SUBSTRS(1), * ) ID_LOSS(T)
! Save tracer name
LOSS_NAME(T) = TRIM( SUBSTRS(2) )
! optimize this strat prod & loss?
READ( SUBSTRS(3), *) OPT_THIS_LOSS(T)
! Defualt loss scaling factor for this strat tracer
READ( SUBSTRS(4), *) LOSS_SF_DEFAULT(T)
! REG_PARAM for this strat tracer
READ( SUBSTRS(5), *) REG_PARAM_LOSS(T)
! STR_ERROR for this strat tracer
READ( SUBSTRS(6), *) LOSS_ERROR(T)
ENDDO
ELSE IF ( LADJ_STRAT .AND. FI_STRID ) THEN
CALL READ_STRID_FILE
ENDIF
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:15' )
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:16' )
! Specifying reaction rates
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_control_vars_menu:16b' )
READ( SUBSTRS(1:N), * ) NRRATES
IF ( .NOT. LADJ_RRATE ) NRRATES = 0
! Read the list from file?
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_control_vars_menu:16c' )
READ( SUBSTRS(1:N), * ) FI_RXNID
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:16d' )
IF ( LADJ_RRATE .AND. NRRATES .GT. 0) THEN
CALL INIT_ADJ_RRATES
ELSEIF ( LADJ_RRATE .AND. NRRATES .EQ. 0) THEN
CALL ERROR_STOP( ' LADJ_RRATE is T but NRRATES is 0 ',
& ' READ_CONTROL_VARS_MENU, geos_chem_mod.f ' )
ENDIF
IF ( LADJ_RRATE .AND. ( NRRATES .NE. NCOEFF_RATE ) ) THEN
print*, 'NRRATES =', NRRATES
print*, 'NCOEFF_RATE =', NCOEFF_RATE
CALL ERROR_STOP( 'NRRATES not equal NCOEFF_RATE
& Check gckpp_adj_Global.f90 ',
& ' READ_CONTROL_VARS_MENU, geos_chem_mod.f ' )
ENDIF
!=================================================================
! Read Reaction Rates ID
!=================================================================
IF ( LADJ_RRATE .AND. .NOT. FI_RXNID ) THEN
! Added block to read reaction rate entries (tww, 05/08/12)
DO T = 1, NRRATES
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:17')
! Save tracer number
READ( SUBSTRS(1), * ) ID_RRATES(T)
! Save tracer name
RRATES_NAME(T) = TRIM( SUBSTRS(2) )
! Optimize this rate?
READ( SUBSTRS(3), *) OPT_THIS_RATE(T)
! Default scaling factor for this rate
READ( SUBSTRS(4), *) RATE_SF_DEFAULT(T)
! REG_PARAM for this rate
READ( SUBSTRS(5), *) REG_PARAM_RATE(T)
! RATE_ERROR for this rate
READ( SUBSTRS(6), *) RATE_ERROR(T)
ENDDO
ELSEIF ( LADJ_RRATE .AND. FI_RXNID ) THEN
CALL READ_RXNID_FILE
ENDIF
ENDIF
!=================================================================
! Print to screen
!=================================================================
WRITE( 6, '(/,a)' )
& 'CONTROL VARIABLE MENU'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 130 ) 'Optimizing initial conditions : ', LICS
WRITE( 6, 130 ) 'Optimizing emissions : ', LADJ_EMS
WRITE( 6, 130 ) 'Optimizing strat prod & loss : ', LADJ_STRAT
WRITE( 6, 130 ) 'Optimizing rxn rates : ', LADJ_RRATE
WRITE( 6, '( a)' ) '>------------------------------<'
IF ( LICS ) THEN
WRITE( 6, '( a)' )
& ' Tracers optimizing SF_DEFAULT REG_PARAM ERROR'
! Print info about each tracer
DO T = 1, N_TRACERS
IF( OPT_THIS_TRACER(T) ) THEN
! Write tracer number, name and it's default scaling factor
WRITE( 6, 140 ) T, TRACER_NAME(T), ICS_SF_DEFAULT(T),
& REG_PARAM_ICS(T), ICS_ERROR(T)
ENDIF
ENDDO
!mkeller
!ELSEIF ( LADJ_EMS ) THEN
ENDIF
IF ( LADJ_EMS ) THEN
WRITE( 6, '( a)' )
& ' # Emission Opt SF REG ERR'
! Print info about each tracer
DO T = 1, NNEMS
! Write tracer number, name, optimize, default SF, reg param
! and error
WRITE( 6, 120 ) ID_ADEMS(T), ADEMS_NAME(T), OPT_THIS_EMS(T),
& EMS_SF_DEFAULT(T), REG_PARAM_EMS(T), EMS_ERROR(T)
ENDDO
WRITE( 6, 110 ) 'Number of time contrl groups : ', MMSCL
! Strat prod and loss (hml)
IF ( LADJ_STRAT ) THEN
WRITE( 6, '( a)' )
& ' # Strat trc Opt SF REG ERR'
! Print info about each prod tracer
DO T = 1, NSTPL
! Write tracer number, name, default SF of prod,
! reg param, and error
WRITE( 6, 150 ) ID_PROD(T), PROD_NAME(T),
& OPT_THIS_PROD(T), PROD_SF_DEFAULT(T),
& REG_PARAM_PROD(T), PROD_ERROR(T)
ENDDO
CALL STRPID_ADJ
! Print info about each tracer loss
DO T = 1, NSTPL
! Write tracer number, name, default SF of loss,
! reg param, and error
WRITE( 6, 150 ) ID_LOSS(T), LOSS_NAME(T),
& OPT_THIS_LOSS(T), LOSS_SF_DEFAULT(T),
& REG_PARAM_LOSS(T), LOSS_ERROR(T)
ENDDO
CALL STRLID_ADJ
ENDIF
! Print info about rxn rates (tww, 05/15/12)
IF ( LADJ_RRATE ) THEN
WRITE( 6, '(a)' )
& ' RXN ID NAME OPT DEF_SF REG ERR'
! Print info about each tracer
DO T = 1, NRRATES
! Write tracer number, name
WRITE( 6, 150 ) ID_RRATES(T), RRATES_NAME(T),
& OPT_THIS_RATE(T), RATE_SF_DEFAULT(T),
& REG_PARAM_RATE(T), RATE_ERROR(T)
ENDDO
ENDIF
!=================================================================
! Call setup routines from other F90 modules
!=================================================================
CALL TRACERID_ADJ
ENDIF
! Set counter
CT1 = CT1 + 1
! Format statements
100 FORMAT( I3, 1x, A10, 6x, f5.2, 6x, f5.2 )
110 FORMAT( A, I5 )
! 120 FORMAT( I3, 1x, A14, 6x, L5, 1x, f5.2, 1x, f5.2, 1x, f5.2 )
120 FORMAT( I3, 1x, A14, 6x, L5, 1x, f5.2, 1x, f6.2, 1x, f5.2 )
130 FORMAT( A, L5 )
140 FORMAT( I3, 1x, A10, 6x, f5.2, 6x, f5.2, 6x f5.2 )
150 FORMAT( I3, 1x, A14, 5x, L5, 1x, f5.2, 1x, f5.2, 1x, f5.2 )
! Return to calling program
END SUBROUTINE READ_CONTROL_VARS_MENU
!------------------------------------------------------------------------------
SUBROUTINE READ_OBSERVATION_MENU
!
!******************************************************************************
! Subroutine READ_OBSERVATION_MENU reads the OBSERVATION OPTIONS MENU section of
! the GEOS-CHEM adjoint input file (adj_group, 6/07/09)
!
! NOTES:
! a) calculate NSPAN using NYMDf, NHMSf (fp)
!******************************************************************************
!
! References to F90 modules
USE ADJ_ARRAYS_MOD, ONLY : OBS_FREQ
USE ADJ_ARRAYS_MOD, ONLY : OBS_THIS_SPECIES
USE ADJ_ARRAYS_MOD, ONLY : OBS_THIS_TRACER
USE ADJ_ARRAYS_MOD, ONLY : NSPAN
USE ADJ_ARRAYS_MOD, ONLY : NOBS
USE ADJ_ARRAYS_MOD, ONLY : NOBS_CSPEC
USE ADJ_ARRAYS_MOD, ONLY : IDCSPEC_ADJ
USE ADJ_ARRAYS_MOD, ONLY : ID2C
USE ADJ_ARRAYS_MOD, ONLY : GET_SPEC
USE ADJ_ARRAYS_MOD, ONLY : CNAME
USE ADJ_ARRAYS_MOD, ONLY : FORCING_MASK_FILE
USE ADJ_ARRAYS_MOD, ONLY : FORCING_MASK_VARIABLE
USE ADJ_ARRAYS_MOD, ONLY : FORCING_MASK_FILE_NC
USE ADJ_ARRAYS_MOD, ONLY : NB_MASK_VAR
USE ADJ_ARRAYS_MOD, ONLY : DEP_UNIT
USE ADJ_ARRAYS_MOD, ONLY : TRACER_IND
USE ADJ_ARRAYS_MOD, ONLY : NFD
USE ERROR_MOD, ONLY : ALLOC_ERR
USE ERROR_MOD, ONLY : ERROR_STOP
USE LOGICAL_ADJ_MOD, ONLY : LMAX_OBS
USE LOGICAL_ADJ_MOD, ONLY : LKGBOX
USE LOGICAL_ADJ_MOD, ONLY : LUGM3
USE LOGICAL_ADJ_MOD, ONLY : LPOP_UGM3
USE LOGICAL_ADJ_MOD, ONLY : LSTT_PPB
USE LOGICAL_ADJ_MOD, ONLY : LSTT_TROP_PPM
USE LOGICAL_ADJ_MOD, ONLY : LCSPEC_PPB
USE LOGICAL_ADJ_MOD, ONLY : LCSPEC_OBS
USE LOGICAL_ADJ_MOD, ONLY : LSENS
USE LOGICAL_ADJ_MOD, ONLY : LFDTEST
USE LOGICAL_ADJ_MOD, ONLY : LFD_GLOB
USE LOGICAL_ADJ_MOD, ONLY : LADJ_FDEP
USE LOGICAL_ADJ_MOD, ONLY : LADJ_DDEP_TRACER
USE LOGICAL_ADJ_MOD, ONLY : LADJ_DDEP_CSPEC
USE LOGICAL_ADJ_MOD, ONLY : LADJ_WDEP_CV
USE LOGICAL_ADJ_MOD, ONLY : LADJ_WDEP_LS
USE LOGICAL_ADJ_MOD, ONLY : LKGNHAYR
USE LOGICAL_ADJ_MOD, ONLY : LEQHAYR
USE LOGICAL_ADJ_MOD, ONLY : LMOLECCM2S
USE LOGICAL_ADJ_MOD, ONLY : LKGS
USE LOGICAL_ADJ_MOD, ONLY : LFORCE_MASK
USE LOGICAL_ADJ_MOD, ONLY : LFORCE_MASK_NC, LFORCE_MASK_BPCH
USE LOGICAL_ADJ_MOD, ONLY : LFD_GLOB
USE TRACER_MOD, ONLY : N_TRACERS, ITS_A_FULLCHEM_SIM
USE TIME_MOD, ONLY : GET_JD, NYMDe, NHMSe, NYMDb, NHMSb
! for flux based cost function (hml,06/13/12)
USE LOGICAL_ADJ_MOD, ONLY : LFLX_UGM2
# include "CMN_SIZE"
# include "comode.h" ! IGAS, NAMEGAS
! Local variables
INTEGER :: N,T,J
INTEGER :: TMP
INTEGER :: NUNIT_COUNT
INTEGER :: AS
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
LOGICAL :: EOF
CHARACTER(LEN=255) :: LINE
CHARACTER(LEN=15) :: TNAME(N_TRACERS)
REAL*8 :: MASK_AREA
INTEGER :: NHMSf, NYMDf !fp
REAL*8 :: JDF, JDE, JDB !fp
!=================================================================
! READ_OBSERVATION_MENU begins here!
!=================================================================
! First allocate OBS_THIS_TRACER to be max species
ALLOCATE( OBS_THIS_TRACER( N_TRACERS ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'OBS_THIS_TRACER' )
OBS_THIS_TRACER = 0
! Also allocation the mapping between observed and all tracers
ALLOCATE( TRACER_IND( N_TRACERS ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'TRACER_IND' )
TRACER_IND = 0
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_obs_menu:1' )
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_obs_menu:2' )
! Optimization output data dir
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_obs_menu:3' )
READ( SUBSTRS(1:N), * ) OBS_FREQ
! Maximum number of obs?
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_obs_menu:4' )
READ( SUBSTRS(1:N), * ) LMAX_OBS
! Number of obs evaluations
CALL SPLIT_ONE_LINE( SUBSTRS, N, 2, 'read_observation_menu:5' )
READ( SUBSTRS(1:N), * ) NYMDf, NHMSf
!calculate nspan (fp)
JDE = GET_JD(NYMDe, NHMSe)
JDB = GET_JD(NYMDb, NHMSb)
! Need to review this with fp, not sure it gives desired behavior
! !fp to avoid error with new definition of nspan when LMAX_OBS is false but LFD_GLOB is true
! IF ( LFD_GLOB ) THEN
! IF ( .not. LMAX_OBS ) THEN
! LMAX_OBS = .TRUE.
! NYMDF = NYMDB
! NHMSF = NHMSB
! ENDIF
! ENDIF
JDF = GET_JD(NYMDf, NHMSf)
! add error catch (fp)
IF ( JDB .GT. JDF .and. LMAX_OBS) THEN
CALL ERROR_STOP(
& ' You cannot force adjoint beyond simulation start time ',
& ' input_adj_mod.f ')
ENDIF
! add error catch (yd)
IF ( JDF .GT. JDE .and. LMAX_OBS ) THEN
CALL ERROR_STOP(
& ' The forcing time period is outside of the run period',
& ' input_adj_mod.f ')
ENDIF
NSPAN = NINT( ( JDE - JDF ) * 24D0 * 60D0 / OBS_FREQ )
! Want to only evalute CF once for FD_GLOB test
IF ( LFD_GLOB ) THEN
LMAX_OBS = .TRUE.
NSPAN = 1
ENDIF
!=================================================================
! Cost function options
!=================================================================
NUNIT_COUNT = 0
! Separator line: COST FUNCTION options for LSENS:---
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_observation_menu:6' )
! Cost function STT in kg / box
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:7' )
READ( SUBSTRS(1:N), * ) LKGBOX
IF ( LKGBOX ) NUNIT_COUNT = NUNIT_COUNT + 1
! Cost function STT in ug / m3
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:8' )
READ( SUBSTRS(1:N), * ) LUGM3
IF ( LUGM3 ) NUNIT_COUNT = NUNIT_COUNT + 1
! Cost function STT in ppb
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:9' )
READ( SUBSTRS(1:N), * ) LSTT_PPB
IF ( LSTT_PPB ) NUNIT_COUNT = NUNIT_COUNT + 1
! Cost function STT in free trop in ppm
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:10' )
READ( SUBSTRS(1:N), * ) LSTT_TROP_PPM
IF ( LSTT_TROP_PPM ) NUNIT_COUNT = NUNIT_COUNT + 1
! Cost function CSPEC in ppb
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:11' )
READ( SUBSTRS(1:N), * ) LCSPEC_PPB
IF ( LCSPEC_PPB ) NUNIT_COUNT = NUNIT_COUNT + 1
! Cost function STT in population weighted ug / m3 (adj32_024)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:12' )
READ( SUBSTRS(1:N), * ) LPOP_UGM3
IF ( LPOP_UGM3 ) NUNIT_COUNT = NUNIT_COUNT + 1
! Cost function STT in flux ug / m2 / hr (hml,06/13/12)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13' )
READ( SUBSTRS(1:N), * ) LFLX_UGM2
IF ( LFLX_UGM2 ) NUNIT_COUNT = NUNIT_COUNT + 1
! deposition based cost function?
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.a' )
READ( SUBSTRS(1:N), * ) LADJ_FDEP
! tracer dry deposition
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.b' )
READ( SUBSTRS(1:N), * ) LADJ_DDEP_TRACER
! species dry deposition
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.b2')
READ( SUBSTRS(1:N), * ) LADJ_DDEP_CSPEC
! wet deposition LS
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.c' )
READ( SUBSTRS(1:N), * ) LADJ_WDEP_LS
! wet deposition CV
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.d' )
READ( SUBSTRS(1:N), * ) LADJ_WDEP_CV
! wet deposition units
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.e1')
READ( SUBSTRS(1:N), * ) LMOLECCM2S
IF ( LMOLECCM2S .and. LADJ_FDEP ) NUNIT_COUNT = NUNIT_COUNT + 1
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.e2')
READ( SUBSTRS(1:N), * ) LKGNHAYR
IF ( LKGNHAYR .and. LADJ_FDEP ) NUNIT_COUNT = NUNIT_COUNT + 1
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.e3')
READ( SUBSTRS(1:N), * ) LEQHAYR
IF ( LEQHAYR .and. LADJ_FDEP ) NUNIT_COUNT = NUNIT_COUNT + 1
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.e4')
READ( SUBSTRS(1:N), * ) LKGS
IF ( LKGS .and. LADJ_FDEP ) NUNIT_COUNT = NUNIT_COUNT + 1
! now we can define units of the deposition cost function
! fp 3/10/2013
IF ( LADJ_FDEP ) THEN
IF ( LKGNHAYR ) THEN
DEP_UNIT = TRIM( 'kgN/ha/yr' )
ELSEIF ( LEQHAYR ) THEN
DEP_UNIT = TRIM( 'eq/ha/yr' )
ELSEIF ( LMOLECCM2S ) THEN
DEP_UNIT = TRIM( 'molec/cm2/s' )
ELSEIF ( LKGS ) THEN
DEP_UNIT = TRIM( 'kg/s' )
ELSE
CALL ERROR_STOP(' No unit selected for deposition ',
& ' input_adj_mod.f ')
ENDIF
ELSE
!set all deposition switches to false to avoid unwanted behavior with fd tests (fp)
LKGS = .FALSE.
LEQHAYR = .FALSE.
LKGNHAYR = .FALSE.
LMOLECCM2S = .FALSE.
LADJ_DDEP_TRACER = .FALSE.
LADJ_DDEP_CSPEC = .FALSE.
LADJ_WDEP_CV = .FALSE.
LADJ_WDEP_LS = .FALSE.
ENDIF
! Make sure that we haven't defined too many
IF ( NUNIT_COUNT > 1 ) THEN
CALL ERROR_STOP(' More than one choice for cost function ',
& ' input_adj_mod.f ')
! Make sure that we have picked at least one. For
! FD tests, the default is forced to be kg/box.
ELSEIF ( NUNIT_COUNT == 0 .and. LSENS .and. ( .not. LFDTEST ) )
& THEN
CALL ERROR_STOP(' Need to choose one option for units ',
& ' input_adj_mod.f ')
ENDIF
! Make sure that if deposition is selected that at least one option
! is turned on.
IF ( LADJ_FDEP .and. ( .not. LADJ_FDEP )
& .and. ( .not. LADJ_WDEP_LS )
& .and. ( .not. LADJ_WDEP_CV ) ) THEN
CALL ERROR_STOP(' No deposition option selected ',
& ' input_adj_mod.f ')
ENDIF
! Regional mask?
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:13.f' )
READ( SUBSTRS(1:N), * ) LFORCE_MASK
IF ( LFORCE_MASK ) THEN
!fp add option for nc file
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_observation_menu:13.b1')
READ( SUBSTRS(1:N), * ) LFORCE_MASK_BPCH
IF ( LFORCE_MASK_BPCH ) THEN
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_observation_menu:13.b2' )
READ( SUBSTRS(1:N), '(a)' ) FORCING_MASK_FILE
CALL CHECK_FILE( FORCING_MASK_FILE )
ELSE
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_observation_menu:13.b2' )
ENDIF
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_observation_menu:13.b3')
READ( SUBSTRS(1:N), * ) LFORCE_MASK_NC
IF ( LFORCE_MASK_NC ) THEN
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1,
& 'read_observation_menu:13.b4' )
READ( SUBSTRS(1:N), '(a)' ) FORCING_MASK_FILE_NC
CALL CHECK_FILE( FORCING_MASK_FILE_NC )
CALL SPLIT_ONE_LINE( SUBSTRS, NB_MASK_VAR, -1,
& 'read_observation_menu:13.b5' )
ALLOCATE( FORCING_MASK_VARIABLE( NB_MASK_VAR ), STAT = AS )
DO N = 1, NB_MASK_VAR
FORCING_MASK_VARIABLE( N ) = TRIM( SUBSTRS(N) )
ENDDO
ELSE
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_observation_menu:13.b5' )
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_observation_menu:13.b5' )
ENDIF
ELSE
! skip lines
! bpch switch
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:13.a1')
! bpch file
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:13.a2')
! nc switch
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:13.a3')
! nc file
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:13.a4')
! nc variable
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:13.a5')
ENDIF
IF ( LFORCE_MASK ) THEN
IF ( LFORCE_MASK_BPCH .and. LFORCE_MASK_NC ) THEN
CALL ERROR_STOP(' Two mask files are defined',
& ' input_adj_mod.f ')
ENDIF
IF ( .not. LFORCE_MASK_BPCH .and. .not. LFORCE_MASK_NC ) THEN
CALL ERROR_STOP(' No mask file is defined',
& ' input_adj_mod.f ')
ENDIF
ENDIF
!=================================================================
! Tracer observations
!=================================================================
! Separator line: >------------------------------<
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:11b')
! Number of tracers to observe
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:12' )
READ( SUBSTRS(1:N), * ) NOBS
! Separator line: => obs these tracers------> : TRC# tracer_name
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:13' )
IF ( NOBS > 0 ) THEN
DO T = 1, NOBS
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:14')
! tracer id number
READ( SUBSTRS(1), *) TMP
! tracer name
READ( SUBSTRS(2), *) TNAME(TMP)
! observe this species?
OBS_THIS_TRACER(TMP) = .TRUE.
! track tracer index
TRACER_IND(T) = TMP
ENDDO
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_control_vars_menu:14b')
ELSE
! Loop until at the next section
DO
! Read a line from the file
LINE = READ_ONE_LINE( EOF )
! Stop reading lines when we've passed the Tracer section
IF ( .not. (INDEX( LINE, 'Tracer' ) > 0 ) ) EXIT
ENDDO
ENDIF
!=================================================================
! Species observations
!=================================================================
! Number of species to observe
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_observation_menu:15' )
READ( SUBSTRS(1:N), * ) NOBS_CSPEC
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:15b')
IF ( NOBS_CSPEC > 0 ) LCSPEC_OBS = .TRUE.
IF ( ITS_A_FULLCHEM_SIM() .and. LCSPEC_OBS ) THEN
! First allocate OBS_THIS_SPECIES to be max species
ALLOCATE( OBS_THIS_SPECIES( NOBS_CSPEC ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'OBS_THIS_SPECIES' )
OBS_THIS_SPECIES = 0
!
ALLOCATE( CNAME( NOBS_CSPEC ), STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'CNAME' )
CNAME = ''
DO T = 1, NOBS_CSPEC
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,
& 'read_observation_menu:17')
! Save species name
CNAME(T) = TRIM( SUBSTRS(1) )
! observe this species?
OBS_THIS_SPECIES(T) = .TRUE.
ENDDO
ENDIF
!=================================================================
! Print to screen
!=================================================================
WRITE( 6, '(/,a)' ) 'OBSERVATION MENU'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 110 ) 'Observation frequency : ', OBS_FREQ
IF ( LFD_GLOB ) THEN
!print*,' *** FD_GLOB: enforce values on LMAX_OBS and NSPAN ***'
print*,' *** FD_GLOB: enforce values on LMAX_OBS ***'
ENDIF
WRITE( 6, 100 ) 'Limit number of observations : ', LMAX_OBS
WRITE( 6, 150 ) 'Forcing time till : ',
& NYMDf, NHMSf
WRITE( 6, 110 ) ' NSPAN => ', NSPAN
WRITE( 6, '( a)' ) 'Cost function options :--- '
WRITE( 6, 100 ) ' tracer kg/box : ', LKGBOX
WRITE( 6, 100 ) ' tracer ug/m3 : ', LUGM3
WRITE( 6, 100 ) ' tracer ppb : ', LSTT_PPB
WRITE( 6, 100 ) ' tracer ppm free trop : ',
& LSTT_TROP_PPM
WRITE( 6, 100 ) ' species ppb w/averaging : ', LCSPEC_PPB
WRITE( 6, 100 ) ' tracer ug/m3 pop weighted : ', LPOP_UGM3
WRITE( 6, 100 ) ' deposition based? : ', LADJ_FDEP
WRITE( 6, 100 ) ' => tracer dry dep : ',
& LADJ_DDEP_TRACER
WRITE( 6, 100 ) ' => species dry dep : ',
& LADJ_DDEP_CSPEC
WRITE( 6, 100 ) ' => wet LS deposition : ',
& LADJ_WDEP_LS
WRITE( 6, 100 ) ' => wet CV deposition : ',
& LADJ_WDEP_CV
IF (LADJ_FDEP) THEN
WRITE( 6, 140 ) ' Deposition : ', DEP_UNIT
ELSE
WRITE( 6, 140 ) ' Deposition : NONE '
ENDIF
WRITE( 6, 100 ) ' Regional forcing mask? : ',
& LFORCE_MASK
IF ( LFORCE_MASK ) THEN
IF ( LFORCE_MASK_BPCH ) THEN
WRITE( 6, 140 ) ' => mask name : ',
& TRIM(FORCING_MASK_FILE)
ELSEIF ( LFORCE_MASK_NC ) THEN
WRITE( 6, 140 ) ' => mask name : ',
& TRIM(FORCING_MASK_FILE_NC)
DO N = 1,NB_MASK_VAR
WRITE( 6, 140 ) ' => varname : ',
& TRIM(FORCING_MASK_VARIABLE(N))
ENDDO
ENDIF
ELSE
WRITE( 6, 140 ) ' => mask name : ',
& 'NOT USED'
ENDIF
WRITE( 6, '( a)' ) '>------------------------------<'
WRITE( 6, 110 ) 'Number of tracers to observe : ', NOBS
IF ( NOBS > 0 ) THEN
WRITE( 6, '( a)' ) ' Tracers to observe '
! Print info about each tracer
DO T = 1, N_TRACERS
IF( OBS_THIS_TRACER(T) ) THEN
! Write tracer number, name and if it's observed
WRITE( 6, 130 ) T, TNAME(T)
ENDIF
ENDDO
ENDIF
IF ( LCSPEC_OBS ) THEN
WRITE( 6, '( a)' ) REPEAT( '-', 48 )
WRITE( 6, 110 ) 'Number of species to observe : ',
& NOBS_CSPEC
WRITE( 6, '( a)' ) ' Species to observe '
! Print info about each tracer
DO T = 1, NOBS_CSPEC
! Write tracer number, name and if it's observed
WRITE( 6, 120 ) T, CNAME(T)
ENDDO
ENDIF
100 FORMAT( A, L5 )
110 FORMAT( A, I5 )
120 FORMAT( I3, 1x, A10 )
130 FORMAT( I3, 1x, A10, 6x, I5 )
140 FORMAT( A, A )
150 FORMAT( A, I8, 1x, I6 )
! Set counter
CT1 = CT1 + 1
END SUBROUTINE READ_OBSERVATION_MENU
!---------------------------------------------------------------------------------------
SUBROUTINE READ_FD_MENU
!
!******************************************************************************
! Subroutine READ_FD_MENU reads the FINITE DIFFERENCE MENU section of
! the GEOS-CHEM adj input file (adj_group, 6/08/09)
!
! NOTES:
! (1 ) Add support for strat fluxes LADJ_STRAT (hml, dkh, 02/14/12, adj32_025)
!******************************************************************************
!
! References to F90 modules
USE ADJ_ARRAYS_MOD, ONLY : FD_DIFF
USE ADJ_ARRAYS_MOD, ONLY : LONFD
USE ADJ_ARRAYS_MOD, ONLY : LATFD
USE ADJ_ARRAYS_MOD, ONLY : IFD
USE ADJ_ARRAYS_MOD, ONLY : JFD
USE ADJ_ARRAYS_MOD, ONLY : LFD
USE ADJ_ARRAYS_MOD, ONLY : NFD
USE ADJ_ARRAYS_MOD, ONLY : ICSFD
USE ADJ_ARRAYS_MOD, ONLY : EMSFD
USE ADJ_ARRAYS_MOD, ONLY : MFD
USE ADJ_ARRAYS_MOD, ONLY : STRFD
USE DRYDEP_MOD, ONLY : NTRAIND
USE DRYDEP_MOD, ONLY : NUMDEP
USE ERROR_MOD, ONLY : ERROR_STOP
USE GRID_MOD, ONLY : GET_BOUNDING_BOX
USE GRID_MOD, ONLY : GET_XMID
USE GRID_MOD, ONLY : GET_YMID
USE LOGICAL_ADJ_MOD, ONLY : LPRINTFD
USE LOGICAL_ADJ_MOD, ONLY : LFD_SPOT
USE LOGICAL_ADJ_MOD, ONLY : LFD_GLOB
USE LOGICAL_ADJ_MOD, ONLY : LFDTEST
USE LOGICAL_ADJ_MOD, ONLY : LADJ_FDEP
USE LOGICAL_ADJ_MOD, ONLY : LADJ_DDEP_TRACER
USE LOGICAL_ADJ_MOD, ONLY : LADJ_DDEP_CSPEC
USE LOGICAL_ADJ_MOD, ONLY : LADJ_WDEP_CV
USE LOGICAL_ADJ_MOD, ONLY : LADJ_WDEP_LS
USE LOGICAL_MOD, ONLY : LTRAN
USE WETSCAV_MOD, ONLY : GET_WETDEP_IDWETD
USE WETSCAV_MOD, ONLY : NSOL
USE ADJ_ARRAYS_MOD, ONLY : RATFD
! Local variables
INTEGER :: N
REAL*8 :: tmpbox(4)
INTEGER :: tmpbox1(4)
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
LOGICAL :: USEINDEX = .FALSE.
INTEGER :: IFDTMP, JFDTMP
!=================================================================
! READ_FD_MENU begins here!
!=================================================================
! FD difference size
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:1' )
READ( SUBSTRS(1:N), * ) FD_DIFF
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_fd_menu:1.5' )
! if we're doing global check, then exit
! But it is still nice to define IFD, JFD, LFD, etc, if LPRINTFD
! is on. Returning here makes these ind undefined,
! which lead to seg faults (dkh, 06/11/09)
!IF ( LFD_GLOB ) THEN
! PRINT*, 'All gridboxes are used in the global FD test'
! RETURN
!ENDIF
! longitude of the FD gridbox
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:5' )
READ( SUBSTRS(1:N), * ) LONFD
! latitude of the FD gridbox
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:6' )
READ( SUBSTRS(1:N), * ) LATFD
! check if we're specifying indecies (as opposed to lat/lon)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:2' )
READ( SUBSTRS(1:N), * ) USEINDEX
! IFD gridbox
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:3' )
READ( SUBSTRS(1:N), * ) IFDTMP
! JFD gridbox
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:4' )
READ( SUBSTRS(1:N), * ) JFDTMP
! get corresponding box indecies for the LONFD and LATFD
tmpbox(1) = LONFD
tmpbox(2) = LATFD
tmpbox(3) = LONFD
tmpbox(4) = LATFD
! Move this below, as it doesn't work with nested domain (dkh, 01/19/12, adj32_015 )
!CALL GET_BOUNDING_BOX(tmpbox,tmpbox1)
IF ( USEINDEX ) THEN
IFD = IFDTMP
JFD = JFDTMP
! now also adjust LONFD and LATFD (dkh, 02/11/11)
LONFD = GET_XMID( IFD )
LATFD = GET_YMID( JFD )
ELSE
! Moved here (dkh, 01/19/12, adj32_015)
CALL GET_BOUNDING_BOX(tmpbox,tmpbox1)
IFD = tmpbox1(1)
JFD = tmpbox1(2)
ENDIF
! FD perturbation box level
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:7' )
READ( SUBSTRS(1:N), * ) LFD
! FD perturbation species
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:8' )
READ( SUBSTRS(1:N), * ) NFD
! Separator line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_fd_menu:8.5' )
! FD perturbation box temporal element
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:9' )
READ( SUBSTRS(1:N), * ) MFD
! FD perturbation species
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:10' )
READ( SUBSTRS(1:N), * ) EMSFD
! FD perturbation species
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:11' )
READ( SUBSTRS(1:N), * ) ICSFD
! FD perturbation species (hml, 08/11/11, adj32_025)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:12' )
READ( SUBSTRS(1:N), * ) STRFD
! FD perturbation rate (tww, 05/15/12)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:13' )
READ( SUBSTRS(1:N), * ) RATFD
! Move these to adjoint menu (dkh, 02/09/11)
!! Doing finite difference test in 1 gridbox
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:12' )
!READ( SUBSTRS(1:N), * ) LFD_SPOT
!
!! Doing finite difference test in all grid boxes, turn transport off
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_fd_menu:13' )
!READ( SUBSTRS(1:N), * ) LFD_GLOB
!
!! turn of transport for global FD test
!IF ( LFD_GLOB ) LTRAN = .FALSE.
!
!! define a more generic LFDTEST flag if either method is true
!IF ( LFD_GLOB .OR. LFD_SPOT ) LFDTEST = .TRUE.
!=================================================================
! Print to screen
!=================================================================
WRITE( 6, '(/,a)' ) 'FINITE DIFFERENCE MENU'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 100 ) 'Finite diff. increment FD_DIFF: ', FD_DIFF
WRITE( 6, 120 ) 'Finite diff longitude LONFD : ', LONFD
WRITE( 6, 110 ) 'Finite diff long. index IFD : ', IFD
WRITE( 6, 120 ) 'Finite diff latitude LATFD : ', LATFD
WRITE( 6, 110 ) 'Finite diff lat. index JFD : ', JFD
WRITE( 6, 110 ) 'Finite diff vert index LFD : ', LFD
WRITE( 6, 110 ) 'FD species NFD : ', NFD
WRITE( 6, 110 ) 'FD time.group index MFD : ', MFD
WRITE( 6, 110 ) 'FD emiss EMSFD : ', EMSFD
WRITE( 6, 110 ) 'FD initial cond ICSFD : ', ICSFD
WRITE( 6, 110 ) 'FD strat prod & loss STRFD : ', STRFD
WRITE( 6, 110 ) 'FD reaction rate RATFD : ', RATFD
!WRITE( 6, 130 ) 'Doing finite diff check (1box): ', LFD_SPOT
!WRITE( 6, 130 ) 'Doing finite diff check (glob): ', LFD_GLOB
! Format statements
100 FORMAT( A, f11.6 )
110 FORMAT( A, I4 )
120 FORMAT( A, f7.2 )
130 FORMAT( A, L5 )
!=================================================================
! Call setup routines from other GEOS-CHEM modules
!=================================================================
! Set counter
CT1 = CT1 + 1
! Return to calling program
END SUBROUTINE READ_FD_MENU
!------------------------------------------------------------------------------
SUBROUTINE READ_ADJ_DIAGNOSTICS_MENU
!
!******************************************************************************
! Subroutine READ_ADJ_DIAGNOSTICS_MENU reads the DIAGNOSTICS MENU section of
! the GEOS-CHEM adjoint input file (adj_group, 6/07/09)
!
! NOTES:
! (1 ) Add LITR (zhe, dkh, 02/04/11)
! (2 ) Add LTRAJ_SCALE (dkh, 02/09/11)
! (3 ) Add LEMS_ABS, LTES_BLVMR (dkh, 02/17/11)
! (4 ) Add support for strat fluxes LADJ_STRAT (hml, dkh, 02/14/12, adj32_025)
!******************************************************************************
!
! References to F90 modules
USE CHARPAK_MOD, ONLY : STRREPL
USE LOGICAL_ADJ_MOD, ONLY : LADJDIAG
USE LOGICAL_ADJ_MOD, ONLY : LJSAVE
USE LOGICAL_ADJ_MOD, ONLY : LADJ_TRAJ
USE LOGICAL_ADJ_MOD, ONLY : LDCOSAT
USE LOGICAL_ADJ_MOD, ONLY : LHMOD
USE LOGICAL_ADJ_MOD, ONLY : LhOBS
USE LOGICAL_ADJ_MOD, ONLY : LHMODIFF
USE LOGICAL_ADJ_MOD, ONLY : LADJ_FORCE
USE LOGICAL_ADJ_MOD, ONLY : LMODBIAS
USE LOGICAL_ADJ_MOD, ONLY : LOBS_COUNT
USE LOGICAL_ADJ_MOD, ONLY : LDOFS
USE LOGICAL_ADJ_MOD, ONLY : LPRINTFD
USE LOGICAL_ADJ_MOD, ONLY : LDEL_CHKPT
USE LOGICAL_ADJ_MOD, ONLY : LITR
USE LOGICAL_ADJ_MOD, ONLY : LTRAJ_SCALE
USE LOGICAL_ADJ_MOD, ONLY : LTES_BLVMR
USE LOGICAL_ADJ_MOD, ONLY : LEMS_ABS
USE LOGICAL_ADJ_MOD, ONLY : LSAT_HDF_L2, LSAT_HDF_L3
! Local variables
INTEGER :: N
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
! (dkh, 01/09/12, adj32_010)
LOGICAL :: EOF
INTEGER :: IOS
CHARACTER(LEN=1) :: TAB = ACHAR(9)
CHARACTER(LEN=1) :: SPACE = ' '
CHARACTER(LEN=255) :: LINE
!=================================================================
! READ_ADJ_SIMULATION_MENU begins here!
!=================================================================
LJSAVE = .FALSE.
LADJ_TRAJ = .FALSE.
LHMOD = .FALSE.
LhOBS = .FALSE.
LHMODIFF = .FALSE.
LADJ_FORCE = .FALSE.
LMODBIAS = .FALSE.
LOBS_COUNT = .FALSE.
LDOFS = .FALSE.
LITR = .FALSE.
LTRAJ_SCALE= .FALSE.
LTES_BLVMR = .FALSE.
LEMS_ABS = .FALSE.
LSAT_HDF_L2= .FALSE.
LSAT_HDF_L3= .FALSE.
! Save any diagnostics? If not, exit subroutine with all flags FALSE
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:1' )
READ( SUBSTRS(1:N), * ) LADJDIAG
IF ( .NOT. LADJDIAG ) THEN
WRITE( 6, '(/,a)' ) 'SKIPPING DIAGNOSTICS MENU'
RETURN
ENDIF
! PRINT debug messages in FD cell files
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:2' )
READ( SUBSTRS(1:N), * ) LPRINTFD
! Move to other menu (dkh, 02/09/11)
!! Delete checkpt files
!CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:2.1' )
!READ( SUBSTRS(1:N), * ) LDEL_CHKPT
! SAVE .save and .sav2 files
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:3' )
READ( SUBSTRS(1:N), * ) LJSAVE
! Save adjoint trajectory files
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:4' )
READ( SUBSTRS(1:N), * ) LADJ_TRAJ
! save STT adjoints as scaling factor sensitivities?
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:4.0' )
READ( SUBSTRS(1:N), * ) LTRAJ_SCALE
! Save iteration information
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:4.1' )
READ( SUBSTRS(1:N), * ) LITR
! Save sense w.r.t absolute emis
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:4.2' )
READ( SUBSTRS(1:N), * ) LEMS_ABS
! CO satellite diagnostics? if not, don't read the next 7 lines
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:5' )
READ( SUBSTRS(1:N), * ) LDCOSAT
IF ( LDCOSAT ) THEN
! Save H(model), model *ak
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:6' )
READ( SUBSTRS(1:N), * ) LHMOD
! Save h(obs), gridded and filtered observations
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:7' )
READ( SUBSTRS(1:N), * ) LhOBS
! Save H(mod) - h(obs)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:8' )
READ( SUBSTRS(1:N), * ) LHMODIFF
! Save adjoint forcing
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:9' )
READ( SUBSTRS(1:N), * ) LADJ_FORCE
! Save model bias (H(model)-h(obs))/h(obs)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:10' )
READ( SUBSTRS(1:N), * ) LMODBIAS
! Save observation count (array with count/box)
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:11' )
READ( SUBSTRS(1:N), * ) LOBS_COUNT
! Save gridded DOFs
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:12' )
READ( SUBSTRS(1:N), * ) LDOFs
!----------------------------------------------------------------
! BUG FIX: Allow for proper reading of menu below the CO sub menu
! (dkh, 01/08/12, adj32_010)
! OLD CODE:
!ENDIF
!
!! Separator line: TES NH3 diagnostics
!CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_fd_menu:8.5' )
! NEW CODE:
ELSE
DO WHILE ( INDEX( LINE, 'TES NH3 diagnostics' ) .le. 0 )
! still need to advance through the file
LINE = READ_ONE_LINE( EOF )
IF ( EOF ) EXIT
! Replace tab characters in LINE (if any) w/ spaces
CALL STRREPL( LINE, TAB, SPACE )
ENDDO
ENDIF
!----------------------------------------------------------------
! Save BLVMR
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:12' )
READ( SUBSTRS(1:N), * ) LTES_BLVMR
! Separator line: >------------------------------<
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_control_vars_menu:13')
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:14' )
READ( SUBSTRS(1:N), * ) LSAT_HDF_L2
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_adj_diag_menu:15' )
READ( SUBSTRS(1:N), * ) LSAT_HDF_L3
!=================================================================
! Print to screen
!=================================================================
WRITE( 6, '(/,a)' ) 'DIAGNOSTICS MENU'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 100 ) 'Print adj debug LPRINTFD : ', LPRINTFD
!WRITE( 6, 100 ) 'Delete chkpt files LDEL_CHKPT : ', LDEL_CHKPT
WRITE( 6, 100 ) 'Save .jsave and .jsave2 files : ', LJSAVE
WRITE( 6, 100 ) 'Adjoint trajectory files : ', LADJ_TRAJ
WRITE( 6, 100 ) ' w.r.t. scaling factors : ',
& LTRAJ_SCALE
WRITE( 6, 100 ) 'Save iteration diagnostics : ', LITR
WRITE( 6, 100 ) 'Save sense w.r.t absolute emis: ', LEMS_ABS
IF ( LEMS_ABS ) PRINT*, ' ### WARNING: LEMS_ABS only for SO2, BC'
WRITE( 6, 100 ) 'Save CO sat. diagnostics : ', LDCOSAT
IF ( LDCOSAT) THEN
WRITE( 6, 100 ) 'Save H(model) : ', LHMOD
WRITE( 6, 100 ) 'Save h(obs) : ', LhOBS
WRITE( 6, 100 ) 'Save H(model)-h(obs) : ', LHMODIFF
WRITE( 6, 100 ) 'Save adjoint forcing : ', LADJ_FORCE
WRITE( 6, 100 ) 'Save model bias : ', LMODBIAS
WRITE( 6, 100 ) 'Save number of obs/gridbox : ', LOBS_COUNT
WRITE( 6, 100 ) 'Save gridded DOFs : ', LDOFS
ENDIF
WRITE( 6, 100 ) 'TES NH3 BLVMR : ', LTES_BLVMR
WRITE( 6, 100 ) 'HDF Level 2 : ',LSAT_HDF_L2
WRITE( 6, 100 ) 'HDF Level 3 : ',LSAT_HDF_L3
! Format statements
100 FORMAT( A, L5 )
!=================================================================
! Call setup routines from other GEOS-CHEM modules
!=================================================================
! Set counter
CT1 = CT1 + 1
! Return to calling program
END SUBROUTINE READ_ADJ_DIAGNOSTICS_MENU
!------------------------------------------------------------------------------
SUBROUTINE READ_ADJ_CRITICAL_LOAD_MENU
!fp
!add new menu to streamline the inputs for critical load sensitivity simulations
USE CRITICAL_LOAD_MOD, ONLY : CL_FILENAME
USE CRITICAL_LOAD_MOD, ONLY : GC_FILENAME
USE LOGICAL_ADJ_MOD, ONLY : LADJ_CL
USE LOGICAL_ADJ_MOD, ONLY : LADJ_CL_NDEP
USE LOGICAL_ADJ_MOD, ONLY : LADJ_CL_ACID
# include "CMN_SIZE"
INTEGER :: N
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
REAL*8 :: MASK(IIPAR,JJPAR)
!=================================================================
! READ_ADJ_CRITICAL_LOAD begins here!
!=================================================================
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_critical_load_menu:1' )
READ( SUBSTRS(1:N), * ) LADJ_CL
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_critical_load_menu:2' )
READ( SUBSTRS(1:N), * ) LADJ_CL_NDEP
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_critical_load_menu:3' )
READ( SUBSTRS(1:N), * ) LADJ_CL_ACID
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_critical_load_menu:2' )
READ( SUBSTRS(1:N), '(a)' ) CL_FILENAME
CALL SPLIT_ONE_LINE( SUBSTRS, N, 1, 'read_critical_load_menu:3' )
READ( SUBSTRS(1:N), '(a)' ) GC_FILENAME
WRITE( 6, '(/,a)' ) 'CRITICAL LOAD MENU'
WRITE( 6, '( a)' ) '---------------'
WRITE( 6, 100 ) 'Doing critical load run : ',
& LADJ_CL
WRITE( 6, 100 ) ' => based on N deposition : ',
& LADJ_CL_NDEP
WRITE( 6, 100 ) ' => based on acid deposition : ',
& LADJ_CL_ACID
WRITE( 6, '( a)' ) ' Critical Load base file : ',
& TRIM(CL_FILENAME)
WRITE( 6, '( a)' ) ' GC Load file : ',
& TRIM(GC_FILENAME)
100 FORMAT( A, L5 )
! Return to calling program
END SUBROUTINE READ_ADJ_CRITICAL_LOAD_MENU
!------------------------------------------------------------------------------
SUBROUTINE ARE_FLAGS_VALID( )
!
!******************************************************************************
! Subroutine ARE_FLAGS_VALID checks to make sure that flags for the forward
! calculation (set in input.geos) do not confict with flags for the adjoint
! calculation (set in input.gcadj ). (dkh, 11/02/05, adj_group 6/07/09)
!
! NOTES:
! (1 ) Add support for strat fluxes LADJ_STRAT (hml, dkh, 02/14/12, adj32_025)
! (2 ) Add LINVH_BFGS (nab, 25/03/12)
!
!******************************************************************************
!
! Reference to f90 modules
USE ADJ_ARRAYS_MOD, ONLY : OBS_FREQ
USE ADJ_ARRAYS_MOD, ONLY : IFD, JFD, LFD, NFD
USE ADJ_ARRAYS_MOD, ONLY : ICSFD
USE ADJ_ARRAYS_MOD, ONLY : NNEMS, EMSFD
USE ADJ_ARRAYS_MOD, ONLY : MMSCL
USE ADJ_ARRAYS_MOD, ONLY : N_CALC, N_CALC_STOP
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EBCPI_an, IDADJ_EBCPO_an
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EOCPI_an, IDADJ_EOCPO_an
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EBCPI_bb, IDADJ_EBCPO_bb
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EOCPI_bb, IDADJ_EOCPO_bb
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EBCPI_bf, IDADJ_EBCPO_bf
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EOCPI_bf, IDADJ_EOCPO_bf
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ENH3_an
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ENH3_na
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ENH3_bb
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ENH3_bf
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ESO2_bf
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ESO2_bb
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ESO2_sh
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ESO2_an1
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_ESO2_an2
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EDST1, IDADJ_EDST2
USE ADJ_ARRAYS_MOD, ONLY : IDADJ_EDST3, IDADJ_EDST4
USE ADJ_ARRAYS_MOD, ONLY : N_CARB_EMS_ADJ
USE ADJ_ARRAYS_MOD, ONLY : N_SULF_EMS_ADJ
USE ADJ_ARRAYS_MOD, ONLY : N_DUST_EMS_ADJ
USE ADJ_ARRAYS_MOD, ONLY : IS_CARB_EMS_ADJ
USE ADJ_ARRAYS_MOD, ONLY : IS_SULF_EMS_ADJ
USE ADJ_ARRAYS_MOD, ONLY : IS_DUST_EMS_ADJ
USE ADJ_ARRAYS_MOD, ONLY : NOBS_CSPEC
USE ADJ_ARRAYS_MOD, ONLY : IDCSPEC_ADJ
USE ADJ_ARRAYS_MOD, ONLY : OBS_THIS_SPECIES
USE ADJ_ARRAYS_MOD, ONLY : OBS_THIS_TRACER
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_EMS
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_TRACER
USE ADJ_ARRAYS_MOD, ONLY : EMS_ERROR
USE ADJ_ARRAYS_MOD, ONLY : ICS_ERROR
USE ADJ_ARRAYS_MOD, ONLY : NOBS
USE ADJ_ARRAYS_MOD, ONLY : NSTPL, STRFD
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_PROD
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_LOSS
USE ADJ_ARRAYS_MOD, ONLY : PROD_ERROR
USE ADJ_ARRAYS_MOD, ONLY : LOSS_ERROR
USE ADJ_ARRAYS_MOD, ONLY : NRRATES, RATFD
USE ADJ_ARRAYS_MOD, ONLY : OBS_FREQ
USE ADJ_ARRAYS_MOD, ONLY : CNAME
USE ADJ_ARRAYS_MOD, ONLY : NSPAN
USE ERROR_MOD, ONLY : ERROR_STOP
USE LOGICAL_MOD, ONLY : LDRYD, LCHEM, LTURB,
& LCHEM, LWETD, LTRAN,
& LCONV, LSOILNOX, LSCHEM
USE LOGICAL_ADJ_MOD, ONLY : LADJ_CHEM, LAERO_THERM, LADJ_TRAN,
& LSENS, LFDTEST, L4DVAR,
& LICS, LADJ_EMS, LFD_GLOB,
& LBKCOV, LADJ, LLINOZ,
& L3DVAR, LCSPEC_PPB, LCSPEC_OBS,
& LEMS_ABS, LAPSRC, LINVH,
& LINVH_BFGS,
& LADJ_STRAT, LADJ_RRATE,
& LADJ_FDEP,
& LADJ_DDEP_TRACER,
& LADJ_DDEP_CSPEC,
& LADJ_WDEP_LS,
& LADJ_WDEP_CV,
& LMAX_OBS
USE ADJ_ARRAYS_MOD, ONLY : OBS_FREQ
USE LOGICAL_ADJ_MOD, ONLY : LKGNHAYR
USE LOGICAL_ADJ_MOD, ONLY : LEQHAYR
USE LOGICAL_ADJ_MOD, ONLY : LMOLECCM2S
USE LOGICAL_ADJ_MOD, ONLY : LKGS
USE TIME_MOD, ONLY : GET_TIME_AHEAD
USE TIME_MOD, ONLY : GET_NYMDe
USE TIME_MOD, ONLY : GET_NHMSe
USE TRACER_MOD, ONLY : N_TRACERS, ITS_A_FULLCHEM_SIM
USE TRACER_MOD, ONLY : ITS_A_TAGOX_SIM
USE TRACER_MOD, ONLY : SIM_TYPE
USE TRACERID_MOD, ONLY : IDTSO4, IDTDST1, IDTSOA1
USE TRACERID_MOD, ONLY : IDTSALA
USE TRACERID_MOD, ONLY : IDTNIT, IDTNH4, IDTNH3
USE TRACERID_MOD, ONLY : IDTHNO3, IDTSO2
USE LOGICAL_ADJ_MOD, ONLY : LSAT_HDF_L2, LSAT_HDF_L3
USE LOGICAL_ADJ_MOD, ONLY : LADJ_CL, LADJ_CL_NDEP, LADJ_CL_ACID
USE TRACER_MOD, ONLY : TRACER_NAME
USE GCKPP_ADJ_GLOBAL, ONLY: NCOEFF_RATE
# include "CMN_SIZE" ! Size params
# include "comode.h" ! NAMEGAS, SMAL2
# include "define_adj.h"
# include "CMN_DIAG" ! ND44
! local variables
INTEGER :: N,T
CHARACTER(LEN=255) :: MSG
INTEGER :: COUNT_ON
INTEGER, PARAMETER :: N_NDEP = 4 !number of tracers for N deposition
INTEGER, PARAMETER :: N_ACID = 2 !number of tracers for acid deposition (on top of N_NDEP tracers)
INTEGER, PARAMETER :: N_NDEP_CSPEC = 7
INTEGER :: NDEP(N_NDEP), ACID(N_ACID)
INTEGER :: DATE(2)
CHARACTER*255 :: NDEP_CSPEC(N_NDEP_CSPEC)
LOGICAL :: FOUND
!NITS and SO4S are not supported at the moment for wet/dry deposition (fp 1/5/2013)
NDEP(1) = IDTHNO3
NDEP(2) = IDTNIT
NDEP(3) = IDTNH3
NDEP(4) = IDTNH4
ACID(1) = IDTSO2
ACID(2) = IDTSO4
NDEP_CSPEC(1) = 'DRYHNO3'
NDEP_CSPEC(2) = 'DRYNO2'
NDEP_CSPEC(3) = 'DRYPAN'
NDEP_CSPEC(4) = 'DRYPPN'
NDEP_CSPEC(5) = 'DRYPMN'
NDEP_CSPEC(6) = 'DRYN2O5'
NDEP_CSPEC(7) = 'DRYR4N2'
!=================================================================
! ARE_FLAGS_VALID begins here!
!=================================================================
! check if we are even doing an adjoint run
IF ( .not. LADJ ) RETURN
!=================================================================
! Check forward model options
!=================================================================
! first check if "input.geos" is set to a supported simulation:
IF ( SIM_TYPE .NE. 7 .AND. ! FULL CHEM
& SIM_TYPE .NE. 3 .AND. ! TAGGED CO
& SIM_TYPE .NE. 9 .AND. ! CH4 (kjw, adj32_023)
& SIM_TYPE .NE. 6 .and. ! TAGGED OX (lzh, 12/12/2009)
& SIM_TYPE .NE.10 .and. ! Offline aerosol (adj32_013)
& SIM_TYPE .NE. 12) THEN ! TAGGED CO2
CALL ERROR_STOP( ' This simulation is not supported ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! So far only BC and OC will work with the offline aerosol sim,
! but not the other aerosols (well, dust might, but untested).
! (yhmao, dkh, 01/13/12, adj32_013)
IF ( SIM_TYPE == 10 ) THEN
IF ( IDTSO4 .or. IDTSALA .or. IDTSOA1 ) THEN
CALL ERROR_STOP('offline aero adj only for dust and BC/OC',
& ' ARE_FLAGS_VALID, input_adj_mod.f' )
ENDIF
ENDIF
!=================================================================
! Check forward and adjoint process options
!=================================================================
! Much of the relevant aerosol chemistry is DRYDEP, and adjoint
! of sulfate chemistry will get called if LADJ_CHEM is true,
! so we shouldn't have DRYDEP = FALSE and LADJ_CHEM = TRUE.
! Should this depend on LSULF at all?
! IF ( ( LADJ_CHEM .AND. ( .NOT. LDRYD ) ) .OR.
! & ( LDRYD .AND. ( .NOT. LADJ_CHEM ) ) ) THEN
! I think we can have DRYD w/o chem
IF ( ITS_A_FULLCHEM_SIM() .AND.
& LADJ_CHEM .AND. ( .NOT. LDRYD ) ) THEN
CALL ERROR_STOP( ' LADJ_CHEM and LDRYD inconsistent ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! Not sure about this, leave it out for now (dkh, 06/24/09)
! ! Don't know why, but if WETD, and CHEM are only fwd true
! ! and LADJ_CHEM is only adj true, get error. Have to turn
! ! on LTRAN. ( though just WETD, no adj_chem, no TRAN, seems ok).
! ! something to do with RH? I think there may be others that
! ! require LTRAN.... The error pops up as "Invalid EXTRA", caused
! ! because TS_DYN is 60.
! IF ( LCHEM .AND. ( .NOT. LTRAN ) ) THEN
! CALL ERROR_STOP( ' LCHEM and LTRAN inconsistent ',
! & ' ARE_FLAGS_VALID, geos_chem_mod.f ' )
! ENDIF
! LCHEM controls chemistry in the fwd calc, so need this on
! if want aerosol thermo or the rest of chemistry.
IF ( ( LAERO_THERM .OR. LADJ_CHEM )
& .AND. ( .NOT. LCHEM ) ) THEN
CALL ERROR_STOP( ' LCHEM, LADJ_CHEM, LAERO_THERM inconsistent',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! ... and the opposite...
IF ( .not. ( LADJ_CHEM )
& .and. ( LCHEM ) ) THEN
CALL ERROR_STOP( ' LADJ_CHEM off but LCHEM is on! ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! If you have LTURB and LTRAN, but nothing else, adjoints explode.
! (dkh, 11/22/05)
IF ( LTURB .AND. LTRAN .AND. LTRAN .AND. ( .NOT. LCONV )
& .AND. ( .NOT. LWETD ) .AND. ( .NOT. LCHEM ) ) THEN
CALL ERROR_STOP( ' LTURB and LTRAN lead to errors in adj? ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! Now use new strat_chem_mod (hml, dkh, 02/14/12, adj32_025)
!! Make sure that if strat fluxes are on, LINOZE adj is on (dkh, 04/25/10)
!IF ( LUPBD /= LLINOZ ) THEN
! CALL ERROR_STOP( ' LUPBD and LLINOZ not consistent ',
! ' ARE_FLAGS_VALID, input_adj_mod.f ' )
!ENDIF
! Only include adjoint w.r.t strat fluxes if strat chem is turned on
IF ( LADJ_STRAT .and. ( .not. LSCHEM ) ) THEN
CALL ERROR_STOP( ' LADJ_STRAT needs LSCHEM on ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
!=================================================================
! Check adjoint simulation type
!
! Overall simulation type must be one and only one of:
! - 3DVAR
! - 4DVAR
! - SENS
!=================================================================
! check at least one:
IF ( (.not. LSENS ) .and. ( .not. L3DVAR )
& .and. ( .not. L4DVAR ) ) THEN
MSG = 'Invalid adj run options: no simulation type defined!'
CALL ERROR_STOP( MSG, 'ARE_FLAGS_VALID ("input_adj_mod.f")' )
! check not more than one:
ENDIF
IF ( ( LSENS .AND. L4DVAR ) .or.
& ( LSENS .AND. L3DVAR ) .or.
& ( L4DVAR .AND. L3DVAR ) ) THEN
CALL ERROR_STOP( 'Either sensitivity or a var, pick only one!',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
!=================================================================
! Check adjoint simulation subtypes
!=================================================================
#if defined ( PM_ATTAINMENT ) || defined ( SOMO35_ATTAINMENT )
IF ( OBS_FREQ /= 60 ) THEN
CALL ERROR_STOP( ' OBS_FREQ should be 60 for attainment ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
#endif
!If none of the datasets are selected or PSEUDO_OBS FLAG, then it should be
! 3DVAR and 4DVAR
! add IMPROVE_BC_OC_OBS (adj32_013), MODIS_AOD_OBS (adj32_011)
! add OMI_SO2_OBS ()
! add MOPITT_V5_CO_OBS (adj32_016)
! add CH4 (kjw, dkh, 02/12/12, adj32_023)
IF ( L3DVAR .or. L4DVAR ) THEN
#if !defined(MOPITT_V5_CO_OBS) && !defined(MOPITT_V6_CO_OBS) && !defined(MOPITT_V7_CO_OBS) && !defined(AIRS_CO_OBS) && !defined(SCIA_BRE_CO_OBS) && !defined(TES_NH3_OBS)&& !defined(SCIA_DAL_SO2_OBS) && !defined(PM_ATTAINMENT) && !defined(IMPROVE_SO4_NIT_OBS) && !defined(CASTNET_NH4_OBS) && !defined(SOMO35_ATTAINMENT) && !defined(TES_O3_OBS)&& !defined(SCIA_KNMI_NO2_OBS) && !defined(SCIA_DAL_NO2_OBS) && !defined(PSEUDO_OBS) && !defined(GOSAT_CO2_OBS) & !defined(MODIS_AOD_OBS) && !defined(IMPROVE_BC_OC_OBS) && !defined(TES_CH4_OBS) && !defined(SCIA_CH4_OBS) && !defined(MEM_CH4_OBS) && !defined(LEO_CH4_OBS) && !defined(GEOCAPE_CH4_OBS) && !defined( TES_O3_IRK ) && !defined( OMI_SO2_OBS ) && !defined( OMI_NO2_OBS ) && !defined( OMI_CH2O_OBS ) && !defined( MLS_HNO3_OBS ) && !defined( MLS_O3_OBS ) && !defined( IASI_O3_OBS ) && !defined( IASI_CO_OBS ) && !defined( OSIRIS_OBS ) && !defined( OSIRIS_NO2_OBS)
MSG = 'Invalid adj run options: need to define obs for xDVAR'
CALL ERROR_STOP( MSG, 'ARE_FLAGS_VALID ("input_adj_mod.f")' )
#endif
ENDIF
! Conversely, if any of the obs operators are defined, then make sure it is
! a 3DVAR or 4DVAR simulation
! add IMPROVE_BC_OC_OBS (adj32_013), MODIS_AOD_OBS (adj32_011)
! add OMI_SO2_OBS ()
! add MOPITT_V5_CO_OBS (adj32_016)
! add CH4 (kjw, dkh, 02/12/12, adj32_023)
#if defined(MOPITT_V5_CO_OBS) || defined(MOPITT_V6_CO_OBS) || defined(MOPITT_V7_CO_OBS) || defined(AIRS_CO_OBS) || defined(SCIA_BRE_CO_OBS) || defined(TES_NH3_OBS) || defined(SCIA_DAL_SO2_OBS) || defined(PM_ATTAINMENT) || defined(IMPROVE_SO4_NIT_OBS) || defined(CASTNET_NH4_OBS) || defined(SOMO35_ATTAINMENT) || defined(TES_O3_OBS) || defined(SCIA_KNMI_NO2_OBS) || defined(SCIA_DAL_NO2_OBS) || defined(GOSAT_CO2_OBS) || defined(MODIS_AOD_OBS) || defined(IMPROVE_BC_OC_OBS) || defined(TES_CH4_OBS) || defined(SCIA_CH4_OBS) || defined(MEM_CH4_OBS) || defined(LEO_CH4_OBS) || defined(GEOCAPE_CH4_OBS) || defined(TES_O3_IRK) || defined(OMI_SO2_OBS) || defined( OMI_NO2_OBS ) || defined(OMI_CH2O_OBS) || defined( MLS_HNO3_OBS ) || defined( MLS_O3_OBS ) || defined( IASI_O3_OBS ) || defined( IASI_CO_OBS ) || defined( OSIRIS_OBS ) || defined( OSIRIS_NO2_OBS ) || defined(PSEUDO_OBS)
IF ( .not. ( L3DVAR .or. L4DVAR ) ) THEN
MSG = 'Invalid adj run options: need to define VAR for obs'
CALL ERROR_STOP( MSG, 'ARE_FLAGS_VALID ("input_adj_mod.f")')
ENDIF
#endif
IF ( LSAT_HDF_L2 .or. LSAT_HDF_L3 ) THEN
#if !defined(MOPITT_V5_CO_OBS) && !defined(MOPITT_V6_CO_OBS) && !defined(MOPITT_V7_CO_OBS) && !defined( OMI_SO2_OBS ) && !defined( OMI_NO2_OBS )
MSG = 'Invalid adj run options: Satellite HDF diagnostics are
& only supported by OMI, TES and MOPITT obs operator for xDVAR'
CALL ERROR_STOP( MSG, 'ARE_FLAGS_VALID ("input_adj_mod.f")' )
#endif
ENDIF
! If we are using real observations, make sure pseudo obs are commented (mak, dkh, 10/01/09)
! add IMPROVE_BC_OC_OBS (adj32_013), MODIS_AOD_OBS (adj32_011)
! add OMI_SO2_OBS ()
! add MOPITT_V5_CO_OBS (adj32_016)
! add CH4 (kjw, dkh, 02/12/12, adj32_023)
#if defined(MOPITT_V5_CO_OBS) || defined(MOPITT_V6_CO_OBS) || defined(MOPITT_V7_CO_OBS) || defined(AIRS_CO_OBS) || defined(SCIA_BRE_CO_OBS) || defined(TES_NH3_OBS) || defined(SCIA_DAL_SO2_OBS) || defined(PM_ATTAINMENT) || defined(IMPROVE_SO4_NIT_OBS) || defined(CASTNET_NH4_OBS) || defined(SOMO35_ATTAINMENT) || defined(TES_O3_OBS) || defined(SCIA_KNMI_NO2_OBS) || defined(SCIA_DAL_NO2_OBS) || defined(GOSAT_CO2_OBS) || defined(MODIS_AOD_OBS) || defined(IMPROVE_BC_OC_OBS) || defined(TES_CH4_OBS) || defined(SCIA_CH4_OBS) || defined(MEM_CH4_OBS) || defined(LEO_CH4_OBS) || defined(GEOCAPE_CH4_OBS) || defined(TES_O3_IRK) || defined(OMI_SO2_OBS) || defined( OMI_NO2_OBS ) || defined(OMI_CH2O_OBS) || defined( MLS_HNO3_OBS ) || defined( MLS_O3_OBS ) || defined( IASI_O3_OBS ) || defined( IASI_CO_OBS ) || defined( OSIRIS_OBS ) || defined( OSIRIS_NO2_OBS )
#if defined(PSEUDO_OBS)
IF ( L4DVAR ) THEN
MSG = 'Invalid adj options: define real or pseudo obs'
CALL ERROR_STOP( MSG, 'ARE_FLAGS_VALID ("input_adj_mod.f")')
ENDIF
#endif
#endif
! ( LFDTEST .AND. .NOT. LSENS ) LSENS = .TRUE.
IF ( LFDTEST .AND. (.not. LSENS ) ) THEN
CALL ERROR_STOP( 'FD tests are a subtpye of SENS',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
IF ( LFDTEST .AND. LICS .AND. LADJ_EMS ) THEN
CALL ERROR_STOP( 'FD test for ems AND ics not supported',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
IF ( LFDTEST .and.
& ( ( N_CALC_STOP > 3 ) .or.
& ( N_CALC_STOP < 1 ) ) ) THEN
CALL ERROR_STOP( 'FD tests need to have 1 < N_CALC_STOP < 3',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
IF ( LFDTEST .AND. LFD_GLOB .AND. LTRAN ) THEN
CALL ERROR_STOP( 'FD_GLOB should be done with transport off',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! Estimating inv Hessian only supported for 4DVar (dkh, 01/12/12, adj32_012)
IF ( ( LINVH .or. LINVH_BFGS ) .and. ( .not. L4DVAR ) ) THEN
CALL ERROR_STOP( 'LINVH and LINVH_BFGS only with 4DVAR ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! RTFD should equal the "Rate #" listed in input.gcadj (or RF_IDX)
! corresponding to the listed rate we wish to test
IF ( LFDTEST .and. LADJ_RRATE ) THEN
IF ( RATFD > NRRATES ) THEN
CALL ERROR_STOP('Invalid RTFD',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
ENDIF
IF ( .NOT. LADJ_RRATE .AND. ( NCOEFF_RATE .NE. 0 ) )
& CALL ERROR_STOP('Invalid NCOEFF_RATE', 'ARE_FLAGS_VALID,
& input_adj_mod.f ')
!=================================================================
! Check adjoint control parameters
!=================================================================
IF ( (.not. LICS ) .AND. ( .not. LADJ_EMS ) ) THEN
CALL ERROR_STOP( 'Must select either ICS or EMS ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! LADJ_STRAT is a sub-type of LADJ_EMS (dkh, 02/23/12, adj32_025)
IF ( ( LADJ_STRAT ) .AND. ( .not. LADJ_EMS ) ) THEN
CALL ERROR_STOP( 'LADJ_STRAT is a sub-type of LADJ_EMS',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! check settings for tagged Ox sim
IF ( ITS_A_TAGOX_SIM() ) THEN
IF ( LICS ) THEN
CALL ERROR_STOP( 'Tagged OX adjoint only LADJ_EMS ',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
IF ( MMSCL .ne. LLPAR ) THEN
CALL ERROR_STOP( 'Need MMSCL = LLPAR for tag ox adj ' ,
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
ENDIF
IF ( IFD .GT. IIPAR ) THEN
CALL ERROR_STOP( ' IFD has to be less than IIPAR !',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
IF ( JFD .GT. JJPAR ) THEN
CALL ERROR_STOP( ' JFD has to be less than JJPAR !',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
IF ( LFD .GT. LLPAR ) THEN
CALL ERROR_STOP( ' LFD has to be less than LLPAR !',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
IF ( NFD .GT. N_TRACERS ) THEN
CALL ERROR_STOP( ' NFD has to be less than number of tracers!',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
IF ( ICSFD .GT. N_TRACERS ) THEN
CALL ERROR_STOP( ' ICSFD has to be < number of tracers!',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
! (dkh, 11/11/09)
IF ( LADJ_EMS ) THEN
IF ( EMSFD .GT. NNEMS ) THEN
CALL ERROR_STOP(
& ' EMSFD has to be < number of active adj emissons!',
& ' ARE_FLAGS_VALID, input_adj_mod.f ' )
ENDIF
ENDIF
! (dkh, 01/12/12, adj32_012)
! IF ( LINVH .and. ( .not. LADJ_EMS .or. LICS ) ) THEN
! CALL ERROR_STOP( ' LINVH only supported for LADJ_EMS ',
! & ' ARE_FLAGS_VALID, input_adj_mod.f ' )
! ENDIF
! IF ( ( LINVH .or. LINVH_BFGS ) .and.
! & ( .not. LADJ_EMS .or. LICS ) ) THEN
! CALL ERROR_STOP( ' LINVH only supported for LADJ_EMS ',
! & ' ARE_FLAGS_VALID, input_adj_mod.f ' )
! ENDIF
! Check to make sure error specifications are usable for LAPSRC (dkh, 02/22/11)
IF ( LAPSRC ) THEN
! Check emissions
IF ( LADJ_EMS ) THEN
DO N = 1, NNEMS
! Skip emissions that are not included in optimization
IF ( .not. OPT_THIS_EMS(N) ) CYCLE
IF ( EMS_ERROR(N) < ( SMAL2 ) ) THEN
print*, ' EMS_ERROR stop at N = ', N
CALL ERROR_STOP( ' EMS_ERROR is too small ',
& ' input_adj_mod.f ' )
ENDIF
ENDDO
! Check strat prod and loss tracers (hml, adj32_025)
IF ( LADJ_STRAT ) THEN
DO N = 1, NSTPL
! Skip tracers that are not included in optimization
IF (.not. OPT_THIS_PROD(N) .AND.
& .not. OPT_THIS_LOSS(N)) CYCLE
IF ( PROD_ERROR(N) < ( SMAL2 ) ) THEN
print*, ' PROD_ERROR stop at N = ', N
CALL ERROR_STOP( ' PROD_ERROR is too small ',
& ' input_adj_mod.f ' )
ENDIF
IF ( LOSS_ERROR(N) < ( SMAL2 ) ) THEN
print*, ' LOSS_ERROR stop at N = ', N
CALL ERROR_STOP( ' LOSS_ERROR is too small ',
& ' input_adj_mod.f ' )
ENDIF
ENDDO
ENDIF
! Check tracers
ELSEIF ( LICS ) THEN
DO N = 1, N_TRACERS
! Skip tracers that are not included in optimization
IF ( .not. OPT_THIS_TRACER(N) ) CYCLE
#if defined ( LOG_OPT )
IF ( ICS_ERROR(N) < ( 1d0 + SMAL2 ) ) THEN
print*, ' ICS_ERROR stop at N = ', N
CALL ERROR_STOP( ' ICS_ERROR is too small ',
& ' input_adj_mod.f ' )
ENDIF
#else
IF ( ICS_ERROR(N) < ( SMAL2 ) ) THEN
print*, ' ICS_ERROR stop at N = ', N
CALL ERROR_STOP( ' ICS_ERROR is too small ',
& ' input_adj_mod.f ' )
ENDIF
#endif
ENDDO
ENDIF
ENDIF
!=================================================================
! Check observation settings
!=================================================================
#if defined ( SCIA_KNMI_NO2_OBS ) || defined ( SCIA_DAL_NO2_OBS )
! Since the NO2 obs operators will pass adjoints back
! to CSPEC via CSPEC_AFTER_CHEM_ADJ, we need to make sure that
! these species are listed as observed species
FOUND = .FALSE.
DO N = 1, NOBS_CSPEC
IF ( TRIM( NAMEGAS( IDCSPEC_ADJ(N) ) ) == 'NO2' ) THEN
FOUND = .TRUE.
ENDIF
ENDDO
IF ( .not. FOUND ) THEN
CALL ERROR_STOP( ' Need to list NO2 as observed species',
& ' input_adj_mod ' )
ENDIF
! BUG FIX: move this to INIT_CSPEC_ADJ, by which point the necessary
! CSPEC variables have been initialized (nb, dkh, 01/06/12, adj32_002)
!--------------------------------------------------------------------
!#elif defined ( TES_O3_OBS )
! ! Since the O3 obs operators will pass adjoints back
! ! to CSPEC via CSPEC_AFTER_CHEM_ADJ, we need to make sure that
! ! these species are listed as observed species
! FOUND = .FALSE.
! DO N = 1, NOBS_CSPEC
!
! IF ( TRIM( NAMEGAS( IDCSPEC_ADJ(N) ) ) == 'O3' ) THEN
! FOUND = .TRUE.
! ENDIF
!
! ENDDO
! IF ( .not. FOUND ) THEN
!
! CALL ERROR_STOP( ' Need to list O3 as observed species',
! & ' input_adj_mod ' )
! ENDIF
!--------------------------------------------------------------------
#endif
! We only observe species in CSPEC for full chemistry runs
IF ( .not. ITS_A_FULLCHEM_SIM() .and.
& NOBS_CSPEC /= 0 ) THEN
CALL ERROR_STOP( ' NOBS_CSPEC needs to be zero',
& ' input_adj_mod ' )
ENDIF
! If we are using CSPEC for the cost function, then
! at least one species needs to be listed in the obsevation
! menu.
IF ( LCSPEC_PPB .and. ( .not. LCSPEC_OBS ) ) THEN
CALL ERROR_STOP(
& ' Need to observe a cspec species for LCSPEC_PPB',
& ' input_adj_mod ' )
ENDIF
! If we are doing a sensitivty calculation w.r.t. cspec
! observations, then make sure we have the cspec-based
! option selected.
IF ( LSENS .and. LCSPEC_OBS .and. ( .not. LCSPEC_PPB )
& .and. ( .not. LADJ_DDEP_CSPEC ) ) THEN
CALL ERROR_STOP(
& ' Need to select a cost function option that uses CSPEC',
& ' input_adj_mod ' )
ENDIF
#if defined ( PSEUDO_OBS )
IF ( LCSPEC_OBS ) THEN
CALL ERROR_STOP(
& ' PSEUDO_OBS only implemented for tracer obs',
& ' input_adj_mod ' )
ENDIF
#endif
! ! The deposition forcings are cummulative, and the coding
! ! of the timing of the forcing assumes LMAX_OBS
! IF ( LADJ_FDEP .and. ( .not. LMAX_OBS ) ) THEN
! CALL ERROR_STOP (' Need LMAX_OBS = T and NSPAN for LADJ_FDEP',
! & ' input_adj_mod ' )
! ENDIF
! Deposition forcing FD tests use forward model diagnostics
! for evaluation of depo fluxes
IF ( LFD_GLOB .and. ( LADJ_DDEP_TRACER .or. LADJ_DDEP_CSPEC )
& .and. ( ND44 == 0 ) ) THEN
CALL ERROR_STOP (' Turn on ND44 for dry dep forcing FD test ',
& ' input_adj_mod ' )
ENDIF
! Only allow one dep forcing option at a time for FD tests
IF ( LFDTEST .and. LADJ_FDEP ) THEN
COUNT_ON = 0
IF ( LADJ_WDEP_LS ) COUNT_ON = COUNT_ON + 1
IF ( LADJ_WDEP_CV ) COUNT_ON = COUNT_ON + 1
IF ( LADJ_DDEP_TRACER ) COUNT_ON = COUNT_ON + 1
IF ( LADJ_DDEP_CSPEC ) COUNT_ON = COUNT_ON + 1
IF ( COUNT_ON > 1 ) THEN
CALL ERROR_STOP (' Only one dep forcing for FD test ',
& ' input_adj_mod ' )
ENDIF
IF ( COUNT_ON == 0 ) THEN
CALL ERROR_STOP (' Which dep forcing option do you want?',
& ' input_adj_mod ' )
ENDIF
ENDIF
! Deposition forcing uses forward model diagnostics
! for evaluation of depo fluxes
IF ( LADJ_WDEP_LS .and. ( ND39 == 0 ) ) THEN
CALL ERROR_STOP (' Turn on ND39 for wet LS forcing ',
& ' input_adj_mod ' )
ENDIF
! Deposition forcing uses forward model diagnostics
! for evaluation of depo fluxes
IF ( LADJ_WDEP_CV .and. ( ND38 == 0 ) ) THEN
CALL ERROR_STOP (' Turn on ND38 for wet CV forcing ',
& ' input_adj_mod ' )
ENDIF
! Deposition forcing uses forward model diagnostics
! for evaluation of depo fluxes
IF ( ( LADJ_DDEP_TRACER .or. LADJ_DDEP_CSPEC ) .and.
& ( ND44 == 0 ) ) THEN
CALL ERROR_STOP (' Turn on ND44 for DDEP forcing ',
& ' input_adj_mod ' )
ENDIF
! FD test of the dry deposition adjoint only supported for molec/cm2/s
IF ( LFD_GLOB .and. ( LADJ_DDEP_TRACER .or. LADJ_DDEP_CSPEC )
& .and. ( .not. LMOLECCM2S ) ) THEN
CALL ERROR_STOP (' Set units to molec/cm2/s for ddep FD test',
& ' input_adj_mod ' )
ENDIF
! FD test of the wet deposition adjoint only supported for kg/s
IF ( LFD_GLOB .and. ( LADJ_WDEP_LS .or. LADJ_WDEP_CV )
& .and. ( .not. LKGS ) ) THEN
CALL ERROR_STOP (' Set units to kg/s for wdep FD test',
& ' input_adj_mod ' )
ENDIF
! Make sure that NFD matches the observed tracer or species
IF ( LFDTEST ) THEN
! check species
IF ( NOBS_CSPEC > 0 ) THEN
IF ( NFD /= 1 .or. NOBS_CSPEC > 1 ) THEN
CALL ERROR_STOP(
& ' For species FD, list only one species and set NFD = 1',
& ' input_adj_mod' )
ENDIF
! check tracers
ELSE
IF ( .not. OBS_THIS_TRACER(NFD) ) THEN
CALL ERROR_STOP(' Observed tracer and NFD must match',
& ' input_adj_mod' )
ENDIF
IF ( NOBS > 1 ) THEN
CALL ERROR_STOP(' Only observe tracer NFD for FD test',
& ' input_adj_mod' )
ENDIF
ENDIF
ENDIF
! Check to make sure that our observation time range fits in the
! simulation time range
IF ( LMAX_OBS ) THEN
DATE = GET_TIME_AHEAD( NSPAN * OBS_FREQ )
print*, ' DDD DATE = ', DATE
print*, ' DDD NYMDe= ', GET_NYMDe()
print*, ' DDD NHMSe= ', GET_NHMSe()
IF ( ( DATE(1) > GET_NYMDe() ) .or.
& ( DATE(1) == GET_NYMDe().and.
& DATE(2) > GET_NHMSe() ) ) THEN
CALL ERROR_STOP(' NSPAN too long! ',
& ' input_adj_mod' )
ENDIF
ENDIF
!=================================================================
! Check diagnostics
!=================================================================
IF ( LEMS_ABS .and. ( .not. LADJ_EMS ) ) THEN
CALL ERROR_STOP (' LEMS_ABS only for active vars = emissions',
& ' input_adj_mod ' )
ENDIF
!=================================================================
! Check if all emissions adjoint ID #'s are defined for particular
! sets of emissions species.
!=================================================================
! Primary carbonaceous aerosol emissions
IF ( IDADJ_EBCPI_an > 0 .and. IDADJ_EBCPO_an > 0 .and.
& IDADJ_EOCPI_an > 0 .and. IDADJ_EOCPO_an > 0 .and.
& IDADJ_EBCPI_bb > 0 .and. IDADJ_EBCPO_bb > 0 .and.
& IDADJ_EOCPI_bb > 0 .and. IDADJ_EOCPO_bb > 0 .and.
& IDADJ_EBCPI_bf > 0 .and. IDADJ_EBCPO_bf > 0 .and.
& IDADJ_EOCPI_bf > 0 .and. IDADJ_EOCPO_bf > 0 ) THEN
IS_CARB_EMS_ADJ = .TRUE.
ENDIF
IF ( N_CARB_EMS_ADJ > 0 .and. ( .not. IS_CARB_EMS_ADJ ) ) THEN
CALL ERROR_STOP( 'Not enough carbon emissions adjoint IDs ',
& 'ARE_FLAGS_VALID')
ENDIF
IF ( N_CARB_EMS_ADJ > 12 ) THEN
CALL ERROR_STOP( 'Too many carbon emissions adjoint IDs ',
& 'ARE_FLAGS_VALID')
ENDIF
! Sulfate aerosol (and precursor) emissions
IF ( IDADJ_ENH3_bb > 0 .and. IDADJ_ENH3_bf > 0 .and.
& IDADJ_ENH3_na > 0 .and. IDADJ_ENH3_an > 0 .and.
& IDADJ_ESO2_bb > 0 .and. IDADJ_ESO2_an1 > 0 .and.
& IDADJ_ESO2_bf > 0 .and. IDADJ_ESO2_an2 > 0 .and.
& IDADJ_ESO2_sh > 0 ) THEN
IS_SULF_EMS_ADJ = .TRUE.
ENDIF
IF ( N_SULF_EMS_ADJ > 0 .and. ( .not. IS_SULF_EMS_ADJ ) ) THEN
CALL ERROR_STOP(
& 'Not enough sulfate aerosol emissions adjoint IDs ',
& 'ARE_FLAGS_VALID')
ENDIF
IF ( N_SULF_EMS_ADJ > 9 ) THEN
CALL ERROR_STOP( 'Too many sulfate emissions adjoint IDs ',
& 'ARE_FLAGS_VALID')
ENDIF
! Dust aerosol emissions ( xxu, 11/01/10) (dkh, 01/09/12, adj32_011)
IF ( IDADJ_EDST1 > 0 .and. IDADJ_EDST2 > 0 .and.
& IDADJ_EDST3 > 0 .and. IDADJ_EDST4 > 0 ) THEN
IS_DUST_EMS_ADJ = .TRUE.
ENDIF
IF ( N_DUST_EMS_ADJ > 0 .and. ( .not. IS_DUST_EMS_ADJ ) ) THEN
CALL ERROR_STOP(
& 'Not enough Dust aerosol emissions adjoint IDs ',
& 'ARE_FLAGS_VALID')
ENDIF
IF ( N_DUST_EMS_ADJ > 4 ) THEN
CALL ERROR_STOP( 'Too many dust emissions adjoint IDs ',
& 'ARE_FLAGS_VALID')
ENDIF
!=================================================================
! Check consistency between input.gcadj and define_adj.h options
!=================================================================
IF ( LBKCOV ) THEN
IF ( LICS ) CALL ERROR_STOP( 'Off-diagonal calculation only
& works with LADJ_EMDS', 'ARE_FLAGS_VALID' )
#if ! defined ( LBKCOV_ERR )
CALL ERROR_STOP( 'Off-diagonal calculation requires LBKCOV_ERR
& to be set in define_adj.h ', 'ARE_FLAGS_VALID' )
#endif
ENDIF
#if defined ( LBKCOV_ERR )
IF ( .not. LBKCOV ) THEN
CALL ERROR_STOP( 'Off-diagonal calculation requires LBKCOV
& to be set in input.gcadj ', 'ARE_FLAGS_VALID' )
ENDIF
#endif
IF ( LINVH_BFGS ) THEN
#if ! defined ( LBFGS_INV )
CALL ERROR_STOP( 'L-BFGS calculation requires LBFGS_INV
& to be set in define_adj.h ', 'ARE_FLAGS_VALID' )
#endif
ENDIF
#if defined ( LBFGS_INV )
IF ( .not. LINVH_BFGS ) THEN
CALL ERROR_STOP( 'L-BFGS calculation requires an option
& to be set in input.gcadj ', 'ARE_FLAGS_VALID' )
ENDIF
#endif
! fp check for wetdep sensitivities: these units only make sense
! if we observe one tracer or species at a time.
IF ( ( LKGS .OR. LMOLECCM2S ) .AND.
& ( ( NOBS_CSPEC .GT. 1 ) .OR. ( NOBS .GT. 1 ) ) ) THEN
CALL ERROR_STOP(' Does not seem to make sense ?',
& 'ARE_FLAGS_VALID')
ENDIF
!throw an error if kks and nobs_cspec>1
IF ( LKGS .AND. ( NOBS_CSPEC .GT. 1) ) THEN
CALL ERROR_STOP(' not implemented',
& 'ARE_FLAGS_VALID')
ENDIF
IF ( LEQHAYR .OR. LKGNHAYR ) THEN
DO T = 1, NOBS_CSPEC
FOUND = .FALSE.
DO N = 1, N_NDEP_CSPEC
IF ( TRIM(CNAME(T))
& .NE. TRIM(NDEP_CSPEC(N)) )
& FOUND = .TRUE.
ENDDO
IF ( .not. FOUND ) THEN
WRITE(6,'( a )') CNAME(T)
CALL ERROR_STOP(' Does not seem to make sense ?',
& 'ARE_FLAGS_VALID')
ENDIF
ENDDO
DO T = 1, N_TRACERS
IF ( OBS_THIS_TRACER(T) ) THEN
FOUND = .FALSE.
DO N = 1,N_NDEP
IF ( T .EQ. NDEP( N ) ) FOUND = .TRUE.
ENDDO
IF ( LEQHAYR ) THEN
DO N = 1,N_ACID
IF ( T .EQ. ACID(N) ) FOUND = .TRUE.
ENDDO
ENDIF
IF ( .not. FOUND ) THEN
WRITE(6,*) 'TRACER: ',TRACER_NAME(T)
CALL ERROR_STOP(' Does not seem to make sense ?',
& 'ARE_FLAGS_VALID')
ENDIF
ENDIF
ENDDO
ENDIF
IF ( LADJ_CL ) THEN
IF ( .not. LADJ_CL_NDEP .and.
& .not. LADJ_CL_ACID ) THEN
CALL ERROR_STOP(' Need to select N/Ac for Cl cost function',
& 'ARE_FLAGS_VALID')
ENDIF
IF ( LADJ_CL_NDEP .and. .not. LKGNHAYR )
& CALL ERROR_STOP(' Units are inconsistent',
& 'ARE_FLAGS_VALID')
IF ( LADJ_CL_ACID .and. .not. LEQHAYR )
& CALL ERROR_STOP(' Units are inconsistent',
& 'ARE_FLAGS_VALID')
IF ( .not. LADJ_DDEP_TRACER .OR.
& .not. LADJ_DDEP_CSPEC .OR.
& .not. LADJ_WDEP_LS .OR.
& .not. LADJ_WDEP_CV ) THEN
CALL ERROR_STOP(
& ' All deposition flags need to be turned on',
& 'ARE_FLAGS_VALID')
ENDIF
DO T = 1, N_NDEP
IF ( .not. OBS_THIS_TRACER( NDEP(T) ) ) THEN
WRITE(*,*) 'TRACER: ',TRACER_NAME(NDEP(T))
CALL ERROR_STOP(
& 'All N/Acid species need to be listed',
& 'ARE_FLAGS_VALID')
ENDIF
ENDDO
IF ( LADJ_CL_ACID ) THEN
DO T = 1, N_ACID
IF ( .not. OBS_THIS_TRACER( ACID(T) ) ) THEN
WRITE(*,*) 'TRACER: ',TRACER_NAME(ACID(T))
CALL ERROR_STOP(
& ' All N/Acid species need to be listed',
& 'ARE_FLAGS_VALID')
ENDIF
ENDDO
ENDIF
DO N = 1, N_NDEP_CSPEC
FOUND = .FALSE.
DO T = 1, NOBS_CSPEC
IF ( TRIM(CNAME(T))
& .NE. TRIM(NDEP_CSPEC(N)) )
& FOUND = .TRUE.
ENDDO
IF ( .not. FOUND ) THEN
WRITE(*,*) 'CSPEC: ',TRIM(NDEP_CSPEC(N))
CALL ERROR_STOP(
& ' All N/Acid species need to be listed',
& 'ARE_FLAGS_VALID')
ENDIF
ENDDO
ENDIF
! Return to calling program
END SUBROUTINE ARE_FLAGS_VALID
!------------------------------------------------------------------------------
SUBROUTINE VALIDATE_DIRECTORIES
!
!******************************************************************************
! Subroutine VALIDATE_DIRECTORIES makes sure that each of the directories
! that we have read from the GEOS-CHEM input file are valid. Also, trailing
! separator characters will be added. (bmy, 7/20/04, 8/4/06)
!
! NOTES:
! (1 ) Now make sure all USE statements are USE, ONLY. Now also validate
! GCAP and GEOS-5 directories. (bmy, 10/3/05)
! (2 ) Now references DATA_DIR_1x1 from directory_mod.f (bmy, 10/24/05)
! (3 ) Remove support for GEOS-1 and GEOS-STRAT met fields (bmy, 8/4/06)
!******************************************************************************
!
! References to F90 modules
! References to F90 modules
USE DIRECTORY_ADJ_MOD, ONLY : OPTDATA_DIR, ADJTMP_DIR, DIAGADJ_DIR
! Local variables
CHARACTER(LEN=255) :: DIR
!=================================================================
! VALIDATE_DIRECTORIES begins here!
!=================================================================
! Check directories
CALL CHECK_DIRECTORY( OPTDATA_DIR )
CALL CHECK_DIRECTORY( ADJTMP_DIR )
CALL CHECK_DIRECTORY( DIAGADJ_DIR )
! Return to calling program
END SUBROUTINE VALIDATE_DIRECTORIES
!------------------------------------------------------------------------------
SUBROUTINE CHECK_DIRECTORY( DIR )
!
!******************************************************************************
! Subroutine CHECK_DIRECTORY makes sure that the given directory
! is valid. Also a trailing slash character will be added if necessary.
! (bmy, 3/20/03, 3/23/05)
!
! Arguments as Input/Output:
! ============================================================================
! (1 ) DIR (CHARACTER) : Directory to be checked
!
! NOTES:
! (1 ) Now references FILE_EXISTS from "file_mod.f" (bmy, 3/23/05)
!******************************************************************************
!
! References to F90 modules
USE ERROR_MOD, ONLY : ERROR_STOP
USE FILE_MOD, ONLY : FILE_EXISTS
USE UNIX_CMDS_MOD, ONLY : SEPARATOR
! Arguments
CHARACTER(LEN=*), INTENT(INOUT) :: DIR
! Local variables
INTEGER :: C
CHARACTER(LEN=255) :: MSG
!=================================================================
! CHECK_DIRECTORY begins here!
!=================================================================
! Locate the last non-white-space character of NEWDIR
C = LEN_TRIM( DIR )
! Add the trailing directory separator if it is not present
IF ( DIR(C:C) /= TRIM( SEPARATOR ) ) THEN
DIR(C+1:C+1) = TRIM( SEPARATOR )
ENDIF
!=================================================================
! Test if the directory actually exists
!=================================================================
! If the directory does not exist then stop w/ an error message
IF ( .not. FILE_EXISTS( DIR ) ) THEN
MSG = 'Invalid directory: ' // TRIM( DIR )
CALL ERROR_STOP( MSG, 'CHECK_DIRECTORY ("input_adj_mod.f")' )
ENDIF
! Return to calling program
END SUBROUTINE CHECK_DIRECTORY
!------------------------------------------------------------------------------
SUBROUTINE CHECK_FILE( FILE )
!
!******************************************************************************
! Subroutine CHECK_FILE makes sure that the given file exists. (dkh, 03/10/13)
! Based on CHECK_DIR (bmy, 3/20/03, 3/23/05)
!
! Arguments as Input/Output:
! ============================================================================
! (1 ) FILE (CHARACTER) : File to be checked
!
! NOTES:
!
!******************************************************************************
!
! References to F90 modules
USE ERROR_MOD, ONLY : ERROR_STOP
USE FILE_MOD, ONLY : FILE_EXISTS
! Arguments
CHARACTER(LEN=*), INTENT(IN) :: FILE
! Local variables
CHARACTER(LEN=255) :: MSG
!=================================================================
! CHECK_FILE begins here!
!=================================================================
! If the directory does not exist then stop w/ an error message
IF ( .not. FILE_EXISTS( FILE ) ) THEN
MSG = 'Invalid file: ' // TRIM( FILE )
CALL ERROR_STOP( MSG, 'CHECK_FILE ("input_adj_mod.f")' )
ENDIF
! Return to calling program
END SUBROUTINE CHECK_FILE
!------------------------------------------------------------------------------
SUBROUTINE CLEAN_FILE_DIRS()
!
!******************************************************************************
! Subroutine CLEAN_FILE_DIRS gets rid of files in ADJTMP_DIR and in OptData that
! are left over from previous runs. (10/28/04)
!
!
! NOTES:
! (1 ) If the last run to be computed completed cleanly, there will not be
! any *.chk.* files, and SYSTEM will complain a bit about this. It's OK
! (dkh, 10/03/04)
! (2 ) Add caviot that if L_MAKE_CHK is false, don't delete old *chk* files
! (3 ) Add feature to clean out OPTDATA_DIR (dkh, 10/28/04)
! (4 ) Delete *.ics.* and *.gdt.* files during observation run. (dkh, 11/11/04)
! (5 ) Delete cfn.* files during observation run. (dkh, 02/13/06)
! (6 ) Move from inverse_mod.f to input_adj_mod.f (dkh, 07/28/09)
! (7 ) Now clean out old ems.adj.* and gctm.iteration files (dkh, 02/17/11)
! (8 ) Now keep files for offline inv hessian (dkh, 01/12/12, adj32_012)
! (9 ) Add support for strat fluxes LADJ_STRAT (hml, dkh, 02/14/12, adj32_025)
! (10 ) Add LINVH_BFGS (nab, 25/03/12 )
!******************************************************************************
!
! Reference to F90 modules
USE ADJ_ARRAYS_MOD, ONLY : N_CALC
USE ADJ_ARRAYS_MOD, ONLY : N_CALC_STOP
USE DIRECTORY_ADJ_MOD, ONLY : OPTDATA_DIR
USE DIRECTORY_ADJ_MOD, ONLY : ADJTMP_DIR
USE DIRECTORY_ADJ_MOD, ONLY : DIAGADJ_DIR
USE ERROR_MOD, ONLY : ERROR_STOP
USE LOGICAL_ADJ_MOD, ONLY : LEMS_ABS
USE LOGICAL_ADJ_MOD, ONLY : LITR
USE LOGICAL_ADJ_MOD, ONLY : LINVH,LINVH_BFGS
# include "CMN_SIZE" ! Size params
! Local variables
CHARACTER(LEN=255) :: REMOVE_OBS_FILE_CMD
CHARACTER(LEN=255) :: REMOVE_CHK_FILE_CMD
CHARACTER(LEN=255) :: REMOVE_ADJ_FILE_CMD
CHARACTER(LEN=255) :: REMOVE_OPT_FILE_CMD
CHARACTER(LEN=255) :: REMOVE_FD_FILE_CMD
!============================================================
! CLEAN_FILE_DIRS starts here!
!============================================================
WRITE( 6, '(a)' ) REPEAT( '=', 79 )
WRITE( 6, '(a,/)' ) 'C L E A N O U T O L D F I L E S'
IF ( N_CALC_STOP == 0 ) THEN
! Clear any old .obs. files
REMOVE_OBS_FILE_CMD = 'rm ' //
& TRIM( ADJTMP_DIR ) // '*.obs.*'
WRITE( 6, 102 ) TRIM( REMOVE_OBS_FILE_CMD )
102 FORMAT( ' - INVERSE: Executing: ',a )
CALL SYSTEM( TRIM ( REMOVE_OBS_FILE_CMD ) )
! Clean out old *.gdt.*, *.ics.* and cnf.* files
REMOVE_OPT_FILE_CMD = 'rm ' //
& TRIM (OPTDATA_DIR) // '*.gdt.*'
& // ' ' //
& TRIM (OPTDATA_DIR) // '*.sf.*'
& // ' ' //
& TRIM (OPTDATA_DIR) // 'cfn.*'
WRITE( 6, 102 ) TRIM( REMOVE_OPT_FILE_CMD )
CALL SYSTEM ( TRIM( REMOVE_OPT_FILE_CMD ) )
ELSE
! Clean out old .chk. files
REMOVE_CHK_FILE_CMD = 'rm ' //
& TRIM (ADJTMP_DIR) // '*.chk.*'
WRITE( 6, 102 ) TRIM( REMOVE_CHK_FILE_CMD )
CALL SYSTEM ( TRIM( REMOVE_CHK_FILE_CMD ) )
! Clean out old .adj. files
! BUG FIX: the *.adj.* files are in DAIGADJ_DIR (jk, dkh, 04/25/10)
! Update: be more specific here so that we don't delete ems.adj.NN
! (dkh, 02/18/11)
! Now keep these if doing inv Hessian update (dkh, 01/12/12, adj32_012)
IF ( .not. ( LINVH .or. LINVH_BFGS ) ) THEN
REMOVE_ADJ_FILE_CMD = 'rm ' //
& TRIM (DIAGADJ_DIR) // 'gctm.adj.*'
WRITE( 6, 102 ) TRIM( REMOVE_ADJ_FILE_CMD )
CALL SYSTEM ( TRIM( REMOVE_ADJ_FILE_CMD ) )
! Remove optimization files now, as would have been done normally
! for the "REFERENCE" run at N_CALC_STOP = 0, as the JACOBIAN test
! run begins with N_CALC_STOP = 1.
IF ( N_CALC_STOP == 1 ) THEN
! Clean out old *.gdt.*, *.ics.* and cnf.* files
REMOVE_OPT_FILE_CMD = 'rm ' //
& TRIM (OPTDATA_DIR) // '*.gdt.*'
& // ' ' //
& TRIM (OPTDATA_DIR) // '*.sf.*'
& // ' ' //
& TRIM (OPTDATA_DIR) // 'cfn.*'
WRITE( 6, 102 ) TRIM( REMOVE_OPT_FILE_CMD )
CALL SYSTEM ( TRIM( REMOVE_OPT_FILE_CMD ) )
! Clean out old *.fd.* files (dkh, 06/24/09)
REMOVE_FD_FILE_CMD = 'rm ' //
& TRIM (DIAGADJ_DIR) // '*.fd.*'
& // ' ' //
& TRIM (DIAGADJ_DIR) // '*.fdglob.*'
WRITE( 6, 102 ) TRIM( REMOVE_FD_FILE_CMD )
CALL SYSTEM ( TRIM( REMOVE_FD_FILE_CMD ) )
! Clean out old ems.adj.* files (dkh, 02/17/11)
IF ( LEMS_ABS ) THEN
REMOVE_ADJ_FILE_CMD = 'rm ' //
& TRIM (DIAGADJ_DIR) // 'ems.adj.*'
WRITE( 6, 102 ) TRIM( REMOVE_ADJ_FILE_CMD )
CALL SYSTEM ( TRIM( REMOVE_ADJ_FILE_CMD ) )
ENDIF
! Clean out old gctm.iteration file (dkh, 02/17/11)
IF ( LITR ) THEN
REMOVE_ADJ_FILE_CMD = 'rm ' //
& TRIM (DIAGADJ_DIR) // 'gctm.iteration'
WRITE( 6, 102 ) TRIM( REMOVE_ADJ_FILE_CMD )
CALL SYSTEM ( TRIM( REMOVE_ADJ_FILE_CMD ) )
ENDIF
ENDIF
ENDIF ! LINV
ENDIF
END SUBROUTINE CLEAN_FILE_DIRS
!-----------------------------------------------------------------------------------------
SUBROUTINE INIT_DEP_MAPS
!
!******************************************************************************
! Subroutine INIT_DEP_MAPS creates mapping arrays for going from tracer and
! species concentrations to deposition index. (dkh, 05/30/13)
!
! NOTES:
!
!******************************************************************************
!
! References to F90 modules
USE ADJ_ARRAYS_MOD, ONLY : NOBS2NDEP
USE ADJ_ARRAYS_MOD, ONLY : NOBSCSPEC2NDEP
USE ADJ_ARRAYS_MOD, ONLY : NOBS2NWDEP
USE ADJ_ARRAYS_MOD, ONLY : NTR2NOBS
USE ADJ_ARRAYS_MOD, ONLY : TRACER_IND
USE ADJ_ARRAYS_MOD, ONLY : NOBS
USE ADJ_ARRAYS_MOD, ONLY : NOBS_CSPEC
USE ADJ_ARRAYS_MOD, ONLY : IDCSPEC_ADJ
USE DRYDEP_MOD, ONLY : NTRAIND
USE DRYDEP_MOD, ONLY : NUMDEP
USE DRYDEP_MOD, ONLY : DEPNAME
USE ERROR_MOD, ONLY : ERROR_STOP
USE ERROR_MOD, ONLY : ALLOC_ERR
USE TRACER_MOD, ONLY : N_TRACERS
USE WETSCAV_MOD, ONLY : GET_WETDEP_IDWETD
USE WETSCAV_MOD, ONLY : NSOL
# include "CMN_SIZE"
# include "comode.h" ! IRM
! Local variables
INTEGER :: N
INTEGER :: NN
INTEGER :: AS
INTEGER :: JJ
INTEGER :: NK
LOGICAL :: FOUND
!=================================================================
! INIT_DEP_MAPS begins here!
!=================================================================
ALLOCATE( NOBS2NDEP( NOBS ) , STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'NOBS2NDEP' )
NOBS2NDEP = 0
ALLOCATE( NOBSCSPEC2NDEP( NOBS_CSPEC ) , STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'NOBSCSPEC2NDEP' )
NOBSCSPEC2NDEP = 0
ALLOCATE( NOBS2NWDEP( NOBS ) , STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'NOBS2NWDEP' )
NOBS2NWDEP = 0
ALLOCATE( NTR2NOBS( N_TRACERS ) , STAT=AS )
IF ( AS /= 0 ) CALL ALLOC_ERR( 'NTR2NOBS' )
NTR2NOBS = 0
! NOBS2NDEP: Map from NOBS to N_DEP (drydep id)
DO N = 1, NOBS
DO NN = 1, NUMDEP
IF ( NTRAIND(NN) == TRACER_IND(N) ) NOBS2NDEP(N) = NN
ENDDO
ENDDO
! NOBSCSPEC2NDEP: Map from NOBS_CSPEC to N_DEP (drydep id)
DO N = 1, NOBS_CSPEC
!DO NN = 1, NUMDEP
! this may not work since CNAME would by DRYNO2 and DEPNAME NO2? or NOx?
! IF ( DEPNAME(NN) == CNAME(N) ) NOBSCSPEC2NDEP(N) = NN
! ENDDO
! Determine drydep ID that corresponds to this species
NOBSCSPEC2NDEP(N) = -999
NCS = NCSURBAN
DO NN = 1, NUMDEP
NK = NTDEP(NN)
IF ( NK <= 0 ) CYCLE
JJ = IRM(NPRODLO+1,NK,NCS)
IF ( JJ == IDCSPEC_ADJ(N) ) NOBSCSPEC2NDEP(N) = NN
ENDDO
IF ( NOBSCSPEC2NDEP(N) < 0 ) THEN
CALL ERROR_STOP('Species not in ND44','INIT_CSPEC_ADJ.f')
ENDIF
ENDDO
! NOBS2NWDEP: Map from NOBS to N_WDEP (wetdep id)
DO N = 1, NOBS
! Get wetdep ID number for this observed tracer
DO NN = 1, NSOL
IF ( GET_WETDEP_IDWETD(NN) == TRACER_IND(N) )
& NOBS2NWDEP(N) = NN
ENDDO
ENDDO
! NTR2NOBS: Map from tracer index to observed tracer index
DO NN = 1, N_TRACERS
DO N = 1, NOBS
IF ( TRACER_IND(N) == NN ) NTR2NOBS(NN) = N
ENDDO
ENDDO
! ! NTR2NOBSCSPEC: Map from tracer index to observed species index
! DO NN = 1, NTRACER
!
! DO N = 1, NOBS_CSPEC
!
! IF ( TRACER_IND(N) == NN ) NTR2NOBSCSPEC(NN) = N
!
! ENDDO
!
! ENDDO
! Return to calling program
END SUBROUTINE INIT_DEP_MAPS
!-----------------------------------------------------------------------------
SUBROUTINE INIT_INPUT_ADJ
!
!******************************************************************************
! Subroutine INIT_INPUT_ADJ initializes all variables from
! "directory_adj_mod.f" and "logical_adj_mod.f" for safety's sake.
! (adj_group, 6/07/09)
!
! NOTES:
! (1 ) Add LTES_PSO (kjw, dkh, 02/12/12, adj32_023)
! (2 ) Add support for strat fluxes LADJ_STRAT (hml, dkh, 02/14/12, adj32_025)
! (3 ) Add LINVH_BFGS (nab, 25/03/12 )
!******************************************************************************
!
! References to F90 modules
USE DIRECTORY_ADJ_MOD, ONLY : OPTDATA_DIR, ADJTMP_DIR, DIAGADJ_DIR
USE LOGICAL_ADJ_MOD, ONLY : LADJ,LADJ_TRAN, LADJ_CHEM,
& LAERO_THERM, LFD_SPOT, LFD_GLOB,
& LSENS, L4DVAR, L3DVAR, LAPSRC,
& LBKCOV,LINVH,LINVH_BFGS,
& LLINOZ, LFDTEST, LISO,
& LICS, LRXNR, LADJDIAG, LJSAVE,
& LDCOSAT, LHMOD, LHOBS,
& LHMODIFF, LADJ_FORCE, LMODBIAS,
& LOBS_COUNT, LDOFS, LADJ_EMS,
& LDEL_CHKPT, LADJ_TRAJ, LITR,
& LDEVOC, LTES_PSO, LADJ_STRAT,
& LADJ_RRATE,
& LADJ_CL, LADJ_CL_NDEP, LADJ_CL_ACID
!=================================================================
! INIT_INPUT_ADJ begins here!
!=================================================================
! Initialize directories
OPTDATA_DIR = ''
DIAGADJ_DIR = ''
ADJTMP_DIR = ''
! Initialize logicals
LADJ = .FALSE.
LADJ_TRAN = .FALSE.
LADJ_CHEM = .FALSE.
LAERO_THERM = .FALSE.
LFD_SPOT = .FALSE.
LFD_GLOB = .FALSE.
LSENS = .FALSE.
L4DVAR = .FALSE.
L3DVAR = .FALSE.
LAPSRC = .FALSE.
LBKCOV = .FALSE.
LINVH = .FALSE.
LINVH_BFGS = .FALSE.
LISO = .FALSE.
!LLINOZ = .FALSE.
LFDTEST = .FALSE.
LADJ_EMS = .FALSE.
LICS = .FALSE.
LRXNR = .FALSE.
LADJDIAG = .FALSE.
LJSAVE = .FALSE.
LADJ_TRAJ = .FALSE.
LDCOSAT = .FALSE.
LHMOD = .FALSE.
LHOBS = .FALSE.
LHMODIFF = .FALSE.
LADJ_FORCE = .FALSE.
LMODBIAS = .FALSE.
LOBS_COUNT = .FALSE.
LDOFS = .FALSE.
LDEL_CHKPT = .FALSE.
LITR = .FALSE.
LDEVOC = .TRUE.
LTES_PSO = .FALSE.
LADJ_STRAT = .FALSE.
LADJ_RRATE = .FALSE.
LADJ_CL = .FALSE.
LADJ_CL_NDEP= .FALSE.
LADJ_CL_ACID= .FALSE.
! Initialize counters
CT1 = 0
CT2 = 0
CT3 = 0
! Return to calling program
END SUBROUTINE INIT_INPUT_ADJ
!------------------------------------------------------------------------------
SUBROUTINE READ_STRID_FILE
!
!******************************************************************************
! Subroutine READ_STRID_FILE reads the list of stratospheric production
! and loss rates from STR_ID file in run directory.
! (hml, 05/22/13)
!
! NOTES:
!******************************************************************************
!
! References to F90 modules
USE ADJ_ARRAYS_MOD, ONLY : NSTPL
USE ADJ_ARRAYS_MOD, ONLY : ID_PROD
USE ADJ_ARRAYS_MOD, ONLY : ID_LOSS
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_PROD
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_LOSS
USE ADJ_ARRAYS_MOD, ONLY : PROD_SF_DEFAULT
USE ADJ_ARRAYS_MOD, ONLY : LOSS_SF_DEFAULT
USE ADJ_ARRAYS_MOD, ONLY : PROD_NAME
USE ADJ_ARRAYS_MOD, ONLY : LOSS_NAME
USE ADJ_ARRAYS_MOD, ONLY : REG_PARAM_PROD
USE ADJ_ARRAYS_MOD, ONLY : REG_PARAM_LOSS
USE ADJ_ARRAYS_MOD, ONLY : PROD_ERROR
USE ADJ_ARRAYS_MOD, ONLY : LOSS_ERROR
USE FILE_MOD, ONLY : IOERROR, IU_STR
! local variables
INTEGER :: IOS
INTEGER :: T
INTEGER :: N
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
!=================================================================
! READ_STRID_FILE begins here!
!=================================================================
! Open STR_ID file containing list of 24x2 strat prod & loss
OPEN( IU_STR, FILE='STR_ID', STATUS='OLD', IOSTAT=IOS )
IF ( IOS /= 0 ) CALL IOERROR(IOS,IU_STR,'read_input_adj_strat:1')
READ_STR_ID = .TRUE.
! Read a header line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_STR_ID:1')
DO T = 1, NSTPL
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_strat_p')
! Save tracer number
READ( SUBSTRS(1), * ) ID_PROD(T)
! Save tracer name
PROD_NAME(T) = TRIM( SUBSTRS(2) )
! optimize this strat prod & loss?
READ( SUBSTRS(3), *) OPT_THIS_PROD(T)
! Defualt prod scaling factor for this strat tracer
READ( SUBSTRS(4), *) PROD_SF_DEFAULT(T)
! REG_PARAM for this strat tracer
READ( SUBSTRS(5), *) REG_PARAM_PROD(T)
! STR_ERROR for this strat tracer
READ( SUBSTRS(6), *) PROD_ERROR(T)
ENDDO
DO T = 1, NSTPL
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1,'read_strat_l')
! Save tracer number
READ( SUBSTRS(1), * ) ID_LOSS(T)
! Save tracer name
LOSS_NAME(T) = TRIM( SUBSTRS(2) )
! optimize this strat prod & loss?
READ( SUBSTRS(3), *) OPT_THIS_LOSS(T)
! Defualt loss scaling factor for this strat tracer
READ( SUBSTRS(4), *) LOSS_SF_DEFAULT(T)
! REG_PARAM for this strat tracer
READ( SUBSTRS(5), *) REG_PARAM_LOSS(T)
! STR_ERROR for this strat tracer
READ( SUBSTRS(6), *) LOSS_ERROR(T)
ENDDO
CLOSE(IU_STR)
READ_STR_ID = .FALSE.
! Return to calling program
END SUBROUTINE READ_STRID_FILE
!------------------------------------------------------------------------------
SUBROUTINE READ_RXNID_FILE
!
!******************************************************************************
! Subroutine READ_RXNID_FILE reads the list of kpp reactions
! from RXN_ID file in run directory.
! (hml, 05/22/13)
!
! NOTES:
!******************************************************************************
!
! References to F90 modules
USE FILE_MOD, ONLY : IOERROR, IU_RXN
USE ADJ_ARRAYS_MOD, ONLY : NRRATES
USE ADJ_ARRAYS_MOD, ONLY : ID_RRATES
USE ADJ_ARRAYS_MOD, ONLY : OPT_THIS_RATE
USE ADJ_ARRAYS_MOD, ONLY : RATE_SF_DEFAULT
USE ADJ_ARRAYS_MOD, ONLY : RRATES_NAME
USE ADJ_ARRAYS_MOD, ONLY : REG_PARAM_RATE
USE ADJ_ARRAYS_MOD, ONLY : RATE_ERROR
! local variables
INTEGER :: IOS
INTEGER :: N
INTEGER :: T
CHARACTER(LEN=255) :: SUBSTRS(MAXDIM)
!=================================================================
! READ_RXNID_FILE begins here!
!=================================================================
! Open RXN_ID file containing list of 297 reactions
OPEN( IU_RXN, FILE='RXN_ID', STATUS='OLD', IOSTAT=IOS )
IF ( IOS /= 0 ) CALL IOERROR(
& IOS,IU_RXN,'read_input_adj_rrate:1')
READ_RXN_ID = .TRUE.
! Read a header line
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_RXN_ID:1')
DO T = 1, NRRATES
! Split line into substrings
CALL SPLIT_ONE_LINE( SUBSTRS, N, -1, 'read_RXN_ID:2')
! Save tracer number
READ( SUBSTRS(1), * ) ID_RRATES(T)
! Save tracer name
RRATES_NAME(T) = TRIM( SUBSTRS(2) )
! Optimize this rate?
READ( SUBSTRS(3), * ) OPT_THIS_RATE(T)
! Default scaling factor for this rate
READ( SUBSTRS(4), * ) RATE_SF_DEFAULT(T)
! REG_PARAM for this rate
READ( SUBSTRS(5), * ) REG_PARAM_RATE(T)
! RATE_ERROR for this rate
READ( SUBSTRS(6), * ) RATE_ERROR(T)
ENDDO
CLOSE(IU_RXN)
READ_RXN_ID = .FALSE.
! Return to calling program
END SUBROUTINE READ_RXNID_FILE
!------------------------------------------------------------------------------
! End of module
END MODULE INPUT_ADJ_MOD