Skip to content

Commit

Permalink
Add several updates introduced to GEOS-Chem 12.7.1 that are useful fo…
Browse files Browse the repository at this point in the history
…r CH4 inversions

(1) Update Get_Boundary_Conditions to apply background concentrations when BCs aren't found for a species

    To allow for nested grid simulations to proceed if a species isn't found in the
    boundary conditions file, we now apply the background species concentrations
    when the species cannot be found. The min, max, or background value applied
    for each species as boundary conditions will be printed to the log file. It
    is recommended that users check the log file to verify that the proper BCs
    are being read and applied.

    See also geoschem#268.

(2) Add EFY time cycle flag to HEMCO

    The EFY time cycle flag has been added to hco_config_mod.F90. This option
    will be used for meteorology fields to ensure the exact date is used (E),
    the data is found (F), and the simulation year is used (Y).

(3) Do not read FLASH_DENS and CONV_DEPTH fields in FlexGrid when lightning NOx extensionin HEMCO is off

    A shadow variable Input_Opt%DoLightNOx has been added and will be set to
    true or false depending on if the lightning NOx extension is turned on in
    HEMCO_Config.rc. When that option is off, the reading of FLASH_DENS and
    CONV_DEPTH in flexgrid_read_mod.F90 will be skipped (keeping those fields
    as all zeroes). This will avoid the requirement of having users download
    those data for simulations that do not require it.

    For more details, see geoschem#279.

Signed-off-by: Melissa Sulprizio <mpayer@seas.harvard.edu>
  • Loading branch information
msulprizio committed Oct 18, 2020
1 parent bd97d6c commit d13cde6
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 50 deletions.
38 changes: 29 additions & 9 deletions GeosCore/flexgrid_read_mod.F90
Expand Up @@ -1103,15 +1103,35 @@ SUBROUTINE FlexGrid_Read_A3mstE( YYYYMMDD, HHMMSS, Input_Opt, State_Grid, &
CALL Get_Met_3De( State_Grid, Qe, TRIM(v_name), t_index=t_index )
State_Met%PFLLSAN = Qe

! Read FLASH_DENS
v_name = "FLASH_DENS"
CALL Get_Met_2D( State_Grid, Q2, TRIM(v_name) )
State_Met%FLASH_DENS = Q2

! Read CONV_DEPTH
v_name = "CONV_DEPTH"
CALL Get_Met_2D( State_Grid, Q2, TRIM(v_name) )
State_Met%CONV_DEPTH = Q2
!======================================================================
! Get lightning fields from HEMCO when LightNOx extension is on
!======================================================================
IF ( Input_Opt%DoLightNOx) THEN

! Read FLASH_DENS
v_name = "FLASH_DENS"
CALL Get_Met_2D( State_Grid, Q2, TRIM(v_name) )
State_Met%FLASH_DENS = Q2

! Read CONV_DEPTH
v_name = "CONV_DEPTH"
CALL Get_Met_2D( State_Grid, Q2, TRIM(v_name) )
State_Met%CONV_DEPTH = Q2


ELSE

! Print message to log file
IF ( Input_Opt%amIRoot) THEN
Print*, ' - LightNOX extension is off. Skipping FLASH_DENS' // &
' and CONV_DEPTH fields in FlexGrid_Read_A3mstE.'
ENDIF

ENDIF

!=================================================================
! Diagnostics, cleanup and quit
!=================================================================

! Echo info
stamp = TimeStamp_String( YYYYMMDD, HHMMSS )
Expand Down
122 changes: 81 additions & 41 deletions GeosCore/hcoi_gc_main_mod.F90
Expand Up @@ -3000,6 +3000,24 @@ SUBROUTINE CheckSettings( am_I_Root, HcoConfig, Input_Opt, &

ENDIF

!-----------------------------------------------------------------------
! Lightning NOx extension
!
! The lightning NOx extension is only used in fullchem simulations. We
! will create a shadow field (Input_Opt%DoLightningNOx) to determine if
! the FLASH_DENS and CONV_DEPTH fields are needed in flexgrid_read_mod.F90
!-----------------------------------------------------------------------
IF ( Input_Opt%ITS_A_FULLCHEM_SIM ) THEN
ExtNr = GetExtNr( HcoConfig%ExtList, 'LightNOx' )
IF ( ExtNr <= 0 ) THEN
Input_Opt%DoLightNOx = .FALSE.
ELSE
Input_Opt%DoLightNOx = .TRUE.
ENDIF
ELSE
Input_Opt%DoLightNOx = .FALSE.
ENDIF

!-----------------------------------------------------------------------
! UV Albedo
!
Expand Down Expand Up @@ -4584,6 +4602,7 @@ SUBROUTINE Get_Boundary_Conditions( am_I_Root, Input_Opt, State_Chm, &
INTEGER :: I, J, L, N, NA ! lon, lat, lev, spc indexes
INTEGER :: t_index ! Time index
LOGICAL :: FOUND ! Found in restart file?
LOGICAL, SAVE :: FIRST = .TRUE. ! Is this the first routine call?
CHARACTER(LEN=60) :: Prefix ! utility string
CHARACTER(LEN=255) :: LOC ! routine location
CHARACTER(LEN=255) :: MSG ! message
Expand Down Expand Up @@ -4640,6 +4659,12 @@ SUBROUTINE Get_Boundary_Conditions( am_I_Root, Input_Opt, State_Chm, &
! units can be determined at any point by looking at
! State_Chm%Spc_Units. (ewl, 8/11/16)

! Print header for min/max concentration to log
IF ( Input_Opt%amIRoot ) THEN
WRITE( 6, 110 )
110 FORMAT( 'Min and Max of each species in BC file [mol/mol]:' )
ENDIF

! Initialize BCs to all zeroes
State_Chm%BoundaryCond = 0.e+0_fp

Expand Down Expand Up @@ -4667,71 +4692,86 @@ SUBROUTINE Get_Boundary_Conditions( am_I_Root, Input_Opt, State_Chm, &
! Check if BCs are found
IF ( FOUND ) THEN

! Print the min & max of each species as it is read from
! the BC file in mol/mol if debug is turned on in input.geos
IF ( Input_Opt%amIRoot ) THEN
IF ( FIRST .or. Input_Opt%LPRT ) THEN
WRITE( 6, 120 ) N, TRIM( SpcInfo%Name ), &
MINVAL( Ptr3D ), MAXVAL( Ptr3D )
120 FORMAT( 'Species ', i3, ', ', a8, ': Min = ', es15.9, &
' Max = ',es15.9)
ENDIF
ENDIF

! Copy data from file to State_Chm%BoundaryCond
! and convert from [mol/mol] to [kg/kg dry]
State_Chm%BoundaryCond(:,:,:,N) = Ptr3D(:,:,:) * MW_g / AIRMW

! Debug
! Print*, 'BCs found for ', TRIM( SpcInfo%Name ), &
! MINVAL(State_Chm%BoundaryCond(:,:,:,N)), &
! MAXVAL(State_Chm%BoundaryCond(:,:,:,N))

! Loop over grid boxes and apply BCs to the specified buffer zone
!$OMP PARALLEL DO &
!$OMP DEFAULT( SHARED ) &
!$OMP PRIVATE( I, J, L )
DO L = 1, State_Grid%NZ
ELSE

! First loop over all latitudes of the nested domain
DO J = 1, State_Grid%NY
! Print to log if debug is turned on in input.geos
IF ( Input_Opt%amIRoot ) THEN
IF ( FIRST .or. Input_Opt%LPRT ) THEN
WRITE( 6, 130 ) N, TRIM( SpcInfo%Name ), SpcInfo%BackgroundVV
130 FORMAT('Species ', i3, ', ', a9, ': Use background = ', es15.9)
ENDIF
ENDIF

! West BC
DO I = 1, State_Grid%WestBuffer
State_Chm%Species(I,J,L,N) = State_Chm%BoundaryCond(I,J,L,N)
ENDDO
! Use the background value stored in the species database
State_Chm%BoundaryCond(:,:,:,N) = SpcInfo%BackgroundVV &
* MW_g / AIRMW

! East BC
DO I = (State_Grid%NX-State_Grid%EastBuffer)+1, State_Grid%NX
State_Chm%Species(I,J,L,N) = State_Chm%BoundaryCond(I,J,L,N)
ENDDO
ENDIF

ENDDO
! Loop over grid boxes and apply BCs to the specified buffer zone
!$OMP PARALLEL DO &
!$OMP DEFAULT( SHARED ) &
!$OMP PRIVATE( I, J, L )
DO L = 1, State_Grid%NZ

! Then loop over the longitudes of the nested domain
DO I = 1+State_Grid%WestBuffer,(State_Grid%NX-State_Grid%EastBuffer)
! First loop over all latitudes of the nested domain
DO J = 1, State_Grid%NY

! South BC
DO J = 1, State_Grid%SouthBuffer
Spc(I,J,L,N) = State_Chm%BoundaryCond(I,J,L,N)
ENDDO
! West BC
DO I = 1, State_Grid%WestBuffer
State_Chm%Species(I,J,L,N) = State_Chm%BoundaryCond(I,J,L,N)
ENDDO

! North BC
DO J = (State_Grid%NY-State_Grid%NorthBuffer)+1, State_Grid%NY
Spc(I,J,L,N) = State_Chm%BoundaryCond(I,J,L,N)
ENDDO
! East BC
DO I = (State_Grid%NX-State_Grid%EastBuffer)+1, State_Grid%NX
State_Chm%Species(I,J,L,N) = State_Chm%BoundaryCond(I,J,L,N)
ENDDO

ENDDO
!OMP END PARALLEL DO

ELSE
! Then loop over the longitudes of the nested domain
DO I = 1+State_Grid%WestBuffer,(State_Grid%NX-State_Grid%EastBuffer)

MSG = 'No boundary condition found for '// TRIM( SpcInfo%Name )
CALL GC_Error( MSG, RC, LOC)
RETURN
! South BC
DO J = 1, State_Grid%SouthBuffer
Spc(I,J,L,N) = State_Chm%BoundaryCond(I,J,L,N)
ENDDO

ENDIF
! North BC
DO J = (State_Grid%NY-State_Grid%NorthBuffer)+1, State_Grid%NY
Spc(I,J,L,N) = State_Chm%BoundaryCond(I,J,L,N)
ENDDO
ENDDO

ENDDO
!OMP END PARALLEL DO

! Free pointer
SpcInfo => NULL()

ENDDO

! Echo output
STAMP = TIMESTAMP_STRING()
WRITE( 6, 110 ) STAMP
110 FORMAT( 'GET_BOUNDARY_CONDITIONS: Found All BCs at ', a )

IF ( Input_Opt%amIRoot ) THEN
STAMP = TIMESTAMP_STRING()
WRITE( 6, 140 ) STAMP
140 FORMAT( 'GET_BOUNDARY_CONDITIONS: Found All BCs at ', a )
ENDIF

END SUBROUTINE Get_Boundary_Conditions
!EOC
Expand Down
10 changes: 10 additions & 0 deletions HEMCO/Core/hco_config_mod.F90
Expand Up @@ -969,6 +969,7 @@ SUBROUTINE Config_ReadCont( am_I_Root, HcoConfig, IU_HCO, CFDIR, &
! - "RY" : range, always use simulation year
! - "E" : exact (read file once)
! - "EF" : exact, forced (error if not exist, read/query once)
! - "EFY": exact, always use simulation year
! - "EC" : exact (read/query continuously, e.g. for ESMF interface)
! - "ECF": exact, forced (error if not exist, read/query continuously)
! - "EY" : exact, always use simulation year
Expand Down Expand Up @@ -1018,6 +1019,10 @@ SUBROUTINE Config_ReadCont( am_I_Root, HcoConfig, IU_HCO, CFDIR, &
Dta%CycleFlag = HCO_CFLAG_EXACT
Dta%UpdtFlag = HCO_UFLAG_ONCE
Dta%MustFind = .TRUE.
ELSEIF ( TRIM(TmCycle) == "EFY" ) THEN
Dta%CycleFlag = HCO_CFLAG_EXACT
Dta%MustFind = .TRUE.
Dta%UseSimYear= .TRUE.
ELSEIF ( TRIM(TmCycle) == "EC" ) THEN
Dta%CycleFlag = HCO_CFLAG_EXACT
ELSEIF ( TRIM(TmCycle) == "ECF" ) THEN
Expand Down Expand Up @@ -1269,6 +1274,7 @@ SUBROUTINE Config_ReadCont( am_I_Root, HcoConfig, IU_HCO, CFDIR, &
! - "RY" : range, always use simulation year
! - "E" : exact (read file once)
! - "EF" : exact, forced (error if not exist, read/query once)
! - "EFY": exact, always use simulation year
! - "EC" : exact (read/query continuously, e.g. for ESMF interface)
! - "ECF": exact, forced (error if not exist, read/query continuously)
! - "EY" : exact, always use simulation year
Expand Down Expand Up @@ -1316,6 +1322,10 @@ SUBROUTINE Config_ReadCont( am_I_Root, HcoConfig, IU_HCO, CFDIR, &
Dta%CycleFlag = HCO_CFLAG_EXACT
Dta%UpdtFlag = HCO_UFLAG_ONCE
Dta%MustFind = .TRUE.
ELSEIF ( TRIM(TmCycle) == "EFY" ) THEN
Dta%CycleFlag = HCO_CFLAG_EXACT
Dta%MustFind = .TRUE.
Dta%UseSimYear= .TRUE.
ELSEIF ( TRIM(TmCycle) == "EC" ) THEN
Dta%CycleFlag = HCO_CFLAG_EXACT
ELSEIF ( TRIM(TmCycle) == "ECF" ) THEN
Expand Down

0 comments on commit d13cde6

Please sign in to comment.