Closed yantosca closed 3 years ago
Thanks for bringing this issue to our attention.
From the error output you sent, I believe that State_Chm
should be declared with INTENT(INOUT)
instead of INTENT(IN)
.
Ideally the model should be picking up the TO3 from the met fields, unless there is something going on that I’m not aware of. I am going to look into this now and hope to have some clarity on this soon.
So I did a test with gfortran 10.2.0. I made sure that State_Chm was INTENT(IN)
in COMPUTE_OVERHEAD_O3
. Then I put some debug print in both COMPUTE_OVERHEAD_O3
(in toms_mod.F90), and again in GET_OVERHEAD_O3_FOR_FASTJ
(in Interfaces/GCClassic/main.F90
). I ran it expecting an error (since we are trying to modify State_Chm
, which is read-only. But instead, I got this:
==============================================================================
---> DATE: 2019/07/01 UTC: 00:10 X-HRS: 0.166667
---> DATE: 2019/07/01 UTC: 00:20 X-HRS: 0.333333
### in compute_overhead_o3: use_o3_from_met
### sum to3_daily, sum_to3: 979499.37290954590 979499.37290954590
### SUM( State_Chm%TO3_DAILY ) in main: 979499.37290954590
- DO_STRAT_CHEM: Linearized strat chemistry at 2019/07/01 00:20
- LINOZ_CHEM3: Doing LINOZ
---> DATE: 2019/07/01 UTC: 00:30 X-HRS: 0.500000
---> DATE: 2019/07/01 UTC: 00:40 X-HRS: 0.666667
### in compute_overhead_o3: use_o3_from_met
### sum to3_daily, sum_to3: 979499.37290954590 979499.37290954590
### SUM( State_Chm%TO3_DAILY ) in main: 979499.37290954590
...
so that meant that State_Chm%TO3_DAILY
was getting set to the proper value of column overhead O3. Huh?
So this is my shot at an explanation. The routine COMPUTE_OVERHEAD_O3
is called from COMPUTE_OVERHEAD_O3_FOR_FASTJ
, which is an internal routine in Interfaces/GCClassic/main.F90
. The calling sequence is this:
!=====================================================================
! ***** C H E M I S T R Y *****
!=====================================================================
IF ( notDryRun ) THEN
IF ( Input_Opt%useTimers ) THEN
CALL Timer_Start( "All chemistry", RC )
ENDIF
! Get the overhead column O3 for use with FAST-J
! NOTE: Move to CHEMISTRY section. This now has to come after
! the call to HEMCO emissions driver EMISSIONS_RUN. (bmy, 3/20/15)
CALL Get_Overhead_O3_For_FastJ( Input_Opt, State_Grid, State_Met )
and the subroutine is this:
!------------------------------------------------------------------------------
! GEOS-Chem Global Chemical Transport Model !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: get_overhead_o3_for_fastj
!
! !DESCRIPTION: Internal subroutine GET\_OVERHEAD\_O3\_FOR\_FASTJ
!\\
!\\
! !INTERFACE:
!
SUBROUTINE Get_Overhead_O3_For_FastJ( Input_Opt, State_Grid, State_Met )
!
! !USES:
!
USE Input_Opt_Mod, ONLY : OptInput
USE State_Grid_Mod, ONLY : GrdState
USE State_Met_Mod, ONLY : MetState
!
! !INPUT PARAMETERS:
!
TYPE(OptInput), INTENT(IN) :: Input_Opt
TYPE(GrdState), INTENT(IN) :: State_Grid
TYPE(MetState), INTENT(IN) :: State_Met
!
! !REMARKS:
! This routine makes use of variables declared in above in the main program
! (which are visible in all sub-programs below the CONTAINS statement).
! .
! The original code was done in FAST-J routine "set_prof.F", but has been
! split off to facilitate development of the grid-independent model.
!
! !REVISION HISTORY:
! 07 Mar 2012 - R. Yantosca - Initial version
! See https://github.com/geoschem/geos-chem for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
!
! !LOCAL VARIABLES:
!
! FAST-J is only used for fullchem and offline aerosol, skip otherwise
IF ( ITS_A_FULLCHEM_SIM .or. ITS_AN_AEROSOL_SIM ) THEN
! Only execute this if we are doing chemistry
! and if it we are at a chemistry timestep
IF ( LCHEM .and. ITS_TIME_FOR_CHEM() ) THEN
! Get the overhead O3 column for FAST-J. Take either the
! TOMS O3 data or the column O3 directly from the met fields
CALL Compute_Overhead_O3( Input_Opt, State_Grid, State_Chm, DAY, &
Input_Opt%USE_O3_FROM_MET, &
State_Met%TO3, RC )
print*, '### SUM( State_Chm%TO3_DAILY ) in main: ', &
sum(state_chm%to3_daily)
ENDIF
ENDIF
END SUBROUTINE Get_Overhead_O3_For_FastJ
Note that we don't pass State_Chm
via an argument-to-dummy-variable (as we do for Input_Opt
, State_Met
, State_Grid
). In that case, GET_OVERHEAD_O3_FOR_FASTJ
is using the global variable State_Chm
, which is declared at the top of the main.F90
program. I believe that the compiler that I used then passes State_Chm to GET_OVERHEAD_O3_FOR_FASTJ
as a read/write variable (i.e. INTENT(INOUT)
). This might be because gfortran 10.2 skews more to the the F2018 standards than to strict F90. But older compilers (like your ifort12) might still throw an error.
Therefore, I believe the most robust thing to do is to pass State_Chm
as INTENT(INOUT)
to GET_OVERHEAD_O3_FOR_FASTJ
:
SUBROUTINE Get_Overhead_O3_For_FastJ( Input_Opt, State_Chm, &
State_Grid, State_Met, RC )
!
! !USES:
!
USE Input_Opt_Mod, ONLY : OptInput
USE State_Chm_Mod, ONLY : ChmState
USE State_Grid_Mod, ONLY : GrdState
USE State_Met_Mod, ONLY : MetState
!
! !INPUT PARAMETERS:
!
TYPE(OptInput), INTENT(IN) :: Input_Opt
TYPE(GrdState), INTENT(IN) :: State_Grid
TYPE(MetState), INTENT(IN) :: State_Met
!
! !INPUT/OUTPUT PARAMETERS:
!
TYPE(ChmState), INTENT(INOUT) :: State_Chm
!
! OUTPUT PARAMETERS:
!
INTEGER, INTENT(OUT) :: RC
.. etc...
and then also declare State_Chm
as INTENT(INOUT)
in GET_OVERHEAD_O3
in toms_mod.F90
:
SUBROUTINE COMPUTE_OVERHEAD_O3( Input_Opt, State_Grid, State_Chm, &
DAY, USE_O3_FROM_MET, TO3, &
RC )
!
! !USES:
!
USE HCO_Calc_Mod, ONLY : Hco_EvalFld
USE HCO_State_GC_Mod, ONLY : HcoState
USE Input_Opt_Mod, ONLY : OptInput
USE State_Grid_Mod, ONLY : GrdState
USE State_Chm_Mod, ONLY : ChmState
!
! !INPUT PARAMETERS:
!
TYPE(OptInput), INTENT(IN) :: Input_Opt ! Input Options
TYPE(GrdState), INTENT(IN) :: State_Grid ! Grid State
INTEGER, INTENT(IN) :: DAY ! Day of month
LOGICAL, INTENT(IN) :: USE_O3_FROM_MET ! Use TO3 rom met?
REAL(fp), INTENT(IN) :: TO3(State_Grid%NX, &
State_Grid%NY) ! Met TO3 [Dobsons]
!
! !INPUT/OUTPUT PARAMETERS
!
TYPE(ChmState), INTENT(INOUT) :: State_Chm ! Chemistry State
!
! !OUTPUT PARAMETERS:
!
INTEGER, INTENT(OUT) :: RC ! Success/failure?
!
... etc. ...
We can also pass back the RC flag so that we can stop the code in the main routine in case of error. That should be agnostic of compiler version.
I will push this to the dev/13.0.0-final branch, so that it goes into the final 13.0.0 release.
Good catch!!
This issue has been resolved with commit 1630a809ea822f39318b0e2b35badb2e71c38697. It will ship with the 13.0.0 final release version.
Tess Carter wrote: