Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ if(POLICY CMP0079)
cmake_policy(SET CMP0079 NEW)
endif()

# Add GEOS-Chem CMake helpers to MODULE_PATH
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/CMakeScripts)
include(GC-Helpers)
#-----------------------------------------------------------------------------
# Print header
#-----------------------------------------------------------------------------
Expand Down
158 changes: 158 additions & 0 deletions GeosCore/diagnostics_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ MODULE Diagnostics_mod
PUBLIC :: Set_Diagnostics_EndofTimestep
PUBLIC :: Zero_Diagnostics_StartofTimestep
PUBLIC :: Compute_Budget_Diagnostics
#ifdef ADJOINT
PUBLIC :: Set_SpcAdj_Diagnostic
#endif
!
! !PRIVATE MEMBER FUNCTIONS
!
Expand Down Expand Up @@ -125,6 +128,25 @@ SUBROUTINE Set_Diagnostics_EndofTimestep( Input_Opt, State_Chm, State_Diag, &
RETURN
ENDIF

#ifdef ADJOINT
!-----------------------------------------------------------------------
! Set species concentration diagnostic in units specified in state_diag_mod
!-----------------------------------------------------------------------
IF ( State_Diag%Archive_SpeciesAdj ) THEN
! if (Input_Opt%IS_FD_SPOT_THIS_PET) THEN
! write(*,*) 'Before diagnostic ', &
! State_Chm%SpeciesAdj(Input_Opt%IFD,Input_Opt%JFD,Input_Opt%LFD,Input_opt%NFD)
! ENDIF
CALL Set_SpcAdj_Diagnostic( Input_Opt, State_Chm, State_Diag, &
State_Grid, State_Met, RC )

! Trap potential errors
IF ( RC /= GC_SUCCESS ) THEN
ErrMsg = 'Error encountered setting species adoint diagnostic'
CALL GC_ERROR( ErrMsg, RC, ThisLoc )
ENDIF
ENDIF
#endif
!-----------------------------------------------------------------------
! Set total dry deposition flux
!-----------------------------------------------------------------------
Expand Down Expand Up @@ -312,6 +334,142 @@ SUBROUTINE Zero_Diagnostics_StartofTimestep( Input_Opt, State_Diag, RC )

END SUBROUTINE Zero_Diagnostics_StartofTimestep
!EOC
#ifdef ADJOINT
!------------------------------------------------------------------------------
! GEOS-Chem Global Chemical Transport Model !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: Set_SpcAdj_Diagnostic
!
! !DESCRIPTION: Subroutine Set_SpcAdj\_Diagnostic sets the passed species
! adjoint diagnostic array stored in State_Diag to the instantaneous
! State_Chm%SpeciesAdj values converted to the diagnostic unit stored in
! the State_Diag metadata.
!\\
!\\
! !INTERFACE:
!
SUBROUTINE Set_SpcAdj_Diagnostic( Input_Opt, State_Chm, State_Diag, &
State_Grid, State_Met, RC )
!
! !USES:
!
USE Input_Opt_Mod, ONLY : OptInput
USE State_Met_Mod, ONLY : MetState
USE State_Chm_Mod, ONLY : ChmState
USE State_Diag_Mod, ONLY : DgnMap
USE State_Diag_Mod, ONLY : DgnState
USE State_Grid_Mod, ONLY : GrdState
USE UnitConv_Mod, ONLY : Convert_Spc_Units
!
! !INPUT PARAMETERS:
!
TYPE(OptInput), INTENT(IN) :: Input_Opt ! Input Options object
TYPE(GrdState), INTENT(IN) :: State_Grid ! Grid state object
TYPE(MetState), INTENT(IN) :: State_Met ! Meteorology state object
!
! !INPUT/OUTPUT PARAMETERS:
!
TYPE(ChmState), INTENT(INOUT) :: State_Chm ! Chemistry State object
TYPE(DgnState), INTENT(INOUT) :: State_Diag ! Diagnostics State object
!
! !OUTPUT PARAMETERS:
!
INTEGER, INTENT(OUT) :: RC ! Success or failure?
!
! !REMARKS:
!
! !REVISION HISTORY:
! 15 Dec 2019 - C. Lee - Initial version
! 17 Dec 2020 - C. Lee - Updated to account for changes to Set_SpcConcs
!EOP
!------------------------------------------------------------------------------
!BOC
!
! !LOCAL VARIABLES:
!
! Scalars
LOGICAL :: Found
INTEGER :: D, I, J, L, N, S
REAL(fp) :: TmpVal, Conv

! Strings
CHARACTER(LEN=255) :: ErrMsg, ThisLoc, Units, OrigUnit

! Objects
TYPE(DgnMap), POINTER :: mapData

! Arrays
REAL(fp) :: TmpSpcArr(State_Grid%NX,State_Grid%NY, &
State_Grid%NZ,State_Chm%nSpecies)

!====================================================================
! Set_SpcAdj_Diagnostic begins here!
!====================================================================

! Assume success
RC = GC_SUCCESS
Found = .FALSE.
ThisLoc = ' -> Set_SpcAdj_Diagnostic (in GeosCore/diagnostics_mod.F90)'


! Verify that incoming State_Chm%Species units are kg/kg dry air.
IF ( TRIM( State_Chm%Spc_Units ) /= 'kg/kg dry' ) THEN
ErrMsg = 'Incorrect species units in Set_SpcConc_Diags_VVDry!'
CALL GC_Error( ErrMsg, RC, ThisLoc )
RETURN
ENDIF

!$OMP PARALLEL DO &
!$OMP DEFAULT( SHARED ) &
!$OMP PRIVATE( I, J, L, N )
DO N = 1, State_Chm%nSpecies
DO L = 1, State_Grid%NZ
DO J = 1, State_Grid%NY
DO I = 1, State_Grid%NX
! Forward code
! TmpSpcArr(I,J,L,N) = State_Chm%Species(I,J,L,N) * &
! ( AIRMW / State_Chm%SpcData(N)%Info%MW_g )
TmpSpcArr(I,J,L,N) = State_Chm%SpeciesAdj(I,J,L,N)
ENDDO
ENDDO
ENDDO
ENDDO
!$OMP END PARALLEL DO

!=======================================================================
! Copy species to SpeciesConc (concentrations diagnostic) [v/v dry]
!=======================================================================
IF ( Input_Opt%Is_Adjoint ) THEN

! Point to mapping obj specific to SpeciesConc diagnostic collection
mapData => State_Diag%Map_SpeciesConc

!$OMP PARALLEL DO &
!$OMP DEFAULT( SHARED ) &
!$OMP PRIVATE( N, S )
DO S = 1, mapData%nSlots
N = mapData%slot2id(S)
State_Diag%SpeciesAdj(:,:,:,S) = TmpSpcArr(:,:,:,N)
ENDDO
!$OMP END PARALLEL DO

! Free pointer
mapData => NULL()

ENDIF

! Error handling
IF ( RC /= GC_SUCCESS ) THEN
ErrMsg = 'Error converting species units for archiving diagnostics #2'
CALL GC_Error( ErrMsg, RC, ThisLoc )
RETURN
ENDIF

END SUBROUTINE Set_SpcAdj_Diagnostic
!EOC
#endif
!------------------------------------------------------------------------------
! GEOS-Chem Global Chemical Transport Model !
!------------------------------------------------------------------------------
Expand Down
7 changes: 7 additions & 0 deletions GeosCore/hco_interface_gc_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ SUBROUTINE HCOI_GC_Init( Input_Opt, State_Chm, State_Grid, &
! Set misc. parameter
!=======================================================================

#ifdef ADJOINT
if ( Input_Opt%amIRoot ) WRITE(*,*) 'Setting isAdjoint to ', Input_Opt%is_adjoint
HcoState%isAdjoint = Input_opt%is_adjoint
#endif
! Emission, chemistry and dynamics timestep in seconds
HcoState%TS_EMIS = GET_TS_EMIS()
HcoState%TS_CHEM = GET_TS_CHEM()
Expand Down Expand Up @@ -1180,6 +1184,9 @@ SUBROUTINE HCOI_GC_WriteDiagn( Input_Opt, Restart, RC )

USE Time_Mod, ONLY : Get_Year, Get_Month, Get_Day, GET_DAY_OF_YEAR
USE Time_Mod, ONLY : GET_HOUR, GET_MINUTE, GET_SECOND
#if defined( ADJOINT )
USE MAPL_CommsMod, ONLY : MAPL_AM_I_ROOT

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be in a MAPL ifdef so that GC-Classic does not execute it

#endif
!
! !INPUT/OUTPUT PARAMETERS:
!
Expand Down
13 changes: 13 additions & 0 deletions GeosCore/input_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -5600,6 +5600,19 @@ SUBROUTINE CHECK_TIME_STEPS( Input_Opt, State_Grid, RC)
TS_DYN = Input_Opt%TS_DYN
TS_RAD = Input_Opt%TS_RAD

! If we're doing the reverse integration
! multiply all the timesteps by -1 here
if (TS_DYN < 0) THEN
! TS_DYN and TS_CHEM should always be set to something valid...?
TS_DYN = TS_DYN * -1
TS_CHEM = TS_CHEM * -1
if (LTURB .or. LCONV) TS_CONV = TS_CONV * -1
if (LEMIS .or. LDRYD) TS_EMIS = TS_EMIS * -1
! I'm not sure which flag determins radiation on/off?
if (LCHEM) TS_RAD = TS_RAD * -1
endif


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For GC-Classic to build and run I needed to change this section to this:

    ! If we're doing the reverse integration                                              
    ! multiply all the timesteps by -1 here                                               
    IF ( TS_DYN < 0 ) THEN
       TS_CHEM = TS_CHEM * -1
       TS_EMIS = TS_EMIS * -1
       TS_CONV = TS_CONV * -1
       TS_DYN  = TS_DYN  * -1
       TS_RAD  = TS_RAD  * -1
    ENDIF

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise this looks good to go. If you could just push the update I will go ahead and merge. Thanks for your work on this!

! NUNIT is time step in minutes for unit conversion
TS_UNIT = -1

Expand Down
71 changes: 69 additions & 2 deletions GeosCore/mixing_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,10 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &
State_Grid%NZ)

! Strings
CHARACTER(LEN=255) :: ErrMsg, ThisLoc
CHARACTER(LEN=255) :: ErrMsg, ErrorMsg, ThisLoc
#ifdef ADJOINT
LOGICAL :: IS_ADJ
#endif

!=================================================================
! DO_TEND begins here!
Expand Down Expand Up @@ -339,13 +342,34 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &
ENDIF
ENDIF

#if defined( ADJOINT ) && defined ( DEBUG )
IF (Input_Opt%is_adjoint .and. Input_Opt%IS_FD_SPOT_THIS_PET) THEN
WRITE(*,*) ' SpcAdj(IFD,JFD) before unit converstion: ', &
State_Chm%SpeciesAdj(Input_Opt%IFD, Input_Opt%JFD, &
Input_Opt%LFD, Input_Opt%NFD)
WRITE(*,*) ' Spc(IFD,JFD) before unit converstion: ', &
State_Chm%Species(Input_Opt%IFD, Input_Opt%JFD, &
Input_Opt%LFD, Input_Opt%NFD)
ENDIF
#endif
! DO_TEND previously operated in units of kg. The species arrays are in
! v/v for mixing, hence needed to convert before and after.
! Now use units kg/m2 as State_Chm%SPECIES units in DO_TEND to
! remove area-dependency (ewl, 9/30/15)
CALL Convert_Spc_Units( Input_Opt, State_Chm, State_Grid, State_Met, &
'kg/m2', RC, OrigUnit=OrigUnit )

#if defined( ADJOINT ) && defined ( DEBUG )
IF (Input_Opt%is_adjoint .and. Input_Opt%IS_FD_SPOT_THIS_PET) THEN
WRITE(*,*) ' SpcAdj(IFD,JFD) after unit converstion: ', &
State_Chm%SpeciesAdj(Input_Opt%IFD, Input_Opt%JFD, &
Input_Opt%LFD, Input_Opt%NFD)
WRITE(*,*) ' Spc(IFD,JFD) after unit converstion: ', &
State_Chm%Species(Input_Opt%IFD, Input_Opt%JFD, &
Input_Opt%LFD, Input_Opt%NFD)
ENDIF
#endif

! Trap potential error
IF ( RC /= GC_SUCCESS ) THEN
MSG = 'Unit conversion error!'
Expand All @@ -359,6 +383,11 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &
ELSE
TS = GET_TS_DYN()
ENDIF
#ifdef ADJOINT
if (Input_Opt%Is_Adjoint) then
TS = TS * -1
endif
#endif

! First-time setup
IF ( FIRST ) THEN
Expand Down Expand Up @@ -470,7 +499,7 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &
! dry deposition and/or emissions
!--------------------------------------------------------------------
IF ( .NOT. DryDepSpec .AND. .NOT. EmisSpec ) CYCLE

! Loop over all grid boxes
DO J = 1, State_Grid%NY
DO I = 1, State_Grid%NX
Expand Down Expand Up @@ -603,6 +632,12 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &
State_Chm%Species(I,J,L,N) = FRAC * &
State_Chm%Species(I,J,L,N)

#ifdef ADJOINT
if (Input_Opt%Is_Adjoint) then
State_Chm%SpeciesAdj(I,J,L,N) = FRAC * &
State_Chm%SpeciesAdj(I,J,L,N)
endif
#endif
! Eventually add PARANOX loss. PNOXLOSS is in kg/m2/s.
! Make sure PARANOx loss is applied to tracers. (ckeller,
! 3/29/16).
Expand Down Expand Up @@ -688,6 +723,15 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &

! Flux: [kg/m2] = [kg m-2 s-1 ] x [s]
FLUX = TMP * TS
#ifdef ADJOINT
IF ( I .eq. Input_Opt%IFD .and. J .eq. Input_Opt%JFD .and. &
L .eq. Input_Opt%LFD .and. N .eq. Input_Opt%NFD) THEN
WRITE(*,*) ' GetHcoVal(IFD,JFD) = ', TMP, ' FLUX = ', FLUX
IF ( Input_Opt%is_adjoint ) THEN
WRITE(*,*) ' SpeciesAdj(FD) = ', State_Chm%SpeciesAdj(I,J,L,N)
ENDIF
ENDIF
#endif

! Add to species array
State_Chm%Species(I,J,L,N) = State_Chm%Species(I,J,L,N) &
Expand Down Expand Up @@ -785,6 +829,17 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &

ENDIF

#if defined( ADJOINT ) && defined ( DEBUG )
IF (Input_Opt%is_adjoint .and. Input_Opt%IS_FD_SPOT_THIS_PET) THEN
WRITE(*,*) ' SpcAdj(IFD,JFD) before unit converstion: ', &
State_Chm%SpeciesAdj(Input_Opt%IFD, Input_Opt%JFD, &
Input_Opt%LFD, Input_Opt%NFD)
WRITE(*,*) ' Spc(IFD,JFD) before unit converstion: ', &
State_Chm%Species(Input_Opt%IFD, Input_Opt%JFD, &
Input_Opt%LFD, Input_Opt%NFD)
ENDIF

#endif
! Convert State_Chm%Species back to original units
CALL Convert_Spc_Units( Input_Opt, State_Chm, State_Grid, State_Met, &
OrigUnit, RC )
Expand All @@ -793,6 +848,17 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &
CALL GC_Error( MSG, RC, 'DO_TEND in mixing_mod.F90' )
RETURN
ENDIF
#if defined( ADJOINT ) && defined ( DEBUG )
IF (Input_Opt%is_adjoint .and. Input_Opt%IS_FD_SPOT_THIS_PET) THEN
WRITE(*,*) ' SpcAdj(IFD,JFD) after unit converstion: ', &
State_Chm%SpeciesAdj(Input_Opt%IFD, Input_Opt%JFD, &
Input_Opt%LFD, Input_Opt%NFD)
WRITE(*,*) ' Spc(IFD,JFD) after unit converstion: ', &
State_Chm%Species(Input_Opt%IFD, Input_Opt%JFD, &
Input_Opt%LFD, Input_Opt%NFD)
ENDIF

#endif

!------------------------------------------------------------------------
! Emissions/dry deposition budget diagnostics - Part 2 of 2
Expand Down Expand Up @@ -834,5 +900,6 @@ SUBROUTINE DO_TEND( Input_Opt, State_Chm, State_Diag, State_Grid, &
DepFreq => NULL()

END SUBROUTINE DO_TEND

!EOC
END MODULE MIXING_MOD
Loading