! $Id$
!
! Earth System Modeling Framework
! Copyright 2002-2003, University Corporation for Atmospheric Research,
! Massachusetts Institute of Technology, Geophysical Fluid Dynamics
! Laboratory, University of Michigan, National Centers for Environmental
! Prediction, Los Alamos National Laboratory, Argonne National Laboratory,
! NASA Goddard Space Flight Center.
! Licensed under the GPL.
!
!==============================================================================
!
! ESMF Clock Module
module ESMF_ClockMod 8,4
!
!==============================================================================
!
! This file contains the Clock class definition and all Clock class methods.
!
!------------------------------------------------------------------------------
! INCLUDES
#include <ESMF_TimeMgr.inc>
!==============================================================================
!BOPI
! !MODULE: ESMF_ClockMod
!
! !DESCRIPTION:
! Part of Time Manager F90 API wrapper of C++ implemenation
!
! Defines F90 wrapper entry points for corresponding
! C++ class {\tt ESMC\_Time} implementation
!
! See {\tt ../include/ESMC\_Clock.h} for complete description
!
!------------------------------------------------------------------------------
! !USES:
! inherit from ESMF base class
use ESMF_BaseMod
! associated derived types
use ESMF_TimeIntervalMod
! , only : ESMF_TimeInterval
use ESMF_TimeMod
! , only : ESMF_Time
use ESMF_AlarmMod
, only : ESMF_Alarm
implicit none
!
!------------------------------------------------------------------------------
! !PRIVATE TYPES:
private
!------------------------------------------------------------------------------
! ! ESMF_Clock
!
! ! F90 class type to match C++ Clock class in size only;
! ! all dereferencing within class is performed by C++ implementation
! internals for ESMF_Clock
type ESMF_ClockInt
type(ESMF_TimeInterval) :: TimeStep
type(ESMF_Time) :: StartTime
type(ESMF_Time) :: StopTime
type(ESMF_Time) :: RefTime
type(ESMF_Time) :: CurrTime
type(ESMF_Time) :: PrevTime
integer(ESMF_KIND_I8) :: AdvanceCount
integer :: ClockMutex
integer :: NumAlarms
! Note: to mimic ESMF 2.1.0+, AlarmList is maintained
! within ESMF_Clock even though copies of each alarm are
! returned from ESMF_AlarmCreate() at the same time they
! are copied into the AlarmList! This duplication is not
! as hideous as it might be because the ESMF_Alarm type
! has data members that are all POINTERs (thus the horrible
! shallow-copy-masquerading-as-reference-copy hack works).
type(ESMF_Alarm), pointer, dimension(:) :: AlarmList
end type
! Actual public type: this bit allows easy mimic of "deep" ESMF_ClockCreate
! in ESMF 2.1.0+
! NOTE: DO NOT ADD NON-POINTER STATE TO THIS DATA TYPE. It emulates ESMF
! shallow-copy-masquerading-as-reference-copy.
type ESMF_Clock
type(ESMF_ClockInt), pointer :: clockint
end type
!------------------------------------------------------------------------------
! !PUBLIC TYPES:
public ESMF_Clock
public ESMF_ClockInt ! needed on AIX but not PGI
!------------------------------------------------------------------------------
!
! !PUBLIC MEMBER FUNCTIONS:
public ESMF_ClockCreate
public ESMF_ClockDestroy
public ESMF_ClockSet
! public ESMF_ClockSetOLD
public ESMF_ClockGet
! public ESMF_ClockGetAdvanceCount
! public ESMF_ClockGetTimeStep
! public ESMF_ClockSetTimeStep
! public ESMF_ClockGetCurrTime
! public ESMF_ClockSetCurrTime
! public ESMF_ClockGetStartTime
! public ESMF_ClockGetStopTime
! public ESMF_ClockGetRefTime
! public ESMF_ClockGetPrevTime
! public ESMF_ClockGetCurrSimTime
! public ESMF_ClockGetPrevSimTime
! This must be public for ESMF_AlarmClockMod...
public ESMF_ClockAddAlarm
public ESMF_ClockGetAlarmList
! public ESMF_ClockGetNumAlarms
! public ESMF_ClockSyncToWallClock
public ESMF_ClockAdvance
public ESMF_ClockIsStopTime
public ESMF_ClockStopTimeDisable
! Required inherited and overridden ESMF_Base class methods
! public ESMF_ClockRead
! public ESMF_ClockWrite
public ESMF_ClockValidate
public ESMF_ClockPrint
!EOPI
!------------------------------------------------------------------------------
! The following line turns the CVS identifier string into a printable variable.
character(*), parameter, private :: version = &
'$Id$'
!==============================================================================
contains
!==============================================================================
!
! This section includes the Set methods.
!
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockSetOLD - Initialize a clockint
! !INTERFACE:
subroutine ESMF_ClockSetOLD(clockint, TimeStep, StartTime, & 1
StopTime, RefTime, rc)
! !ARGUMENTS:
type(ESMF_ClockInt), intent(out) :: clockint
type(ESMF_TimeInterval), intent(in), optional :: TimeStep
type(ESMF_Time), intent(in) :: StartTime
type(ESMF_Time), intent(in) :: StopTime
type(ESMF_Time), intent(in), optional :: RefTime
integer, intent(out), optional :: rc
! Local
integer i
! !DESCRIPTION:
! Initialize an {\tt ESMF\_Clock}
!
! The arguments are:
! \begin{description}
! \item[clockint]
! The object instance to initialize
! \item[{[TimeStep]}]
! The {\tt ESMF\_Clock}'s time step interval
! \item[StartTime]
! The {\tt ESMF\_Clock}'s starting time
! \item[StopTime]
! The {\tt ESMF\_Clock}'s stopping time
! \item[{[RefTime]}]
! The {\tt ESMF\_Clock}'s reference time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.1, TMG3.4.4
!EOP
IF ( PRESENT(TimeStep) ) clockint%TimeStep = TimeStep
IF ( PRESENT(RefTime) )THEN
clockint%RefTime = RefTime
ELSE
clockint%RefTime = StartTime
END IF
clockint%CurrTime = StartTime
clockint%StartTime = StartTime
clockint%StopTime = StopTime
clockint%NumAlarms = 0
clockint%AdvanceCount = 0
ALLOCATE(clockint%AlarmList(MAX_ALARMS))
! TBH: This incredible hack can be removed once ESMF_*Validate()
! TBH: can tell if a deep ESMF_* was created or not.
DO i = 1, MAX_ALARMS
NULLIFY( clockint%AlarmList( i )%alarmint )
ENDDO
IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockSetOLD
! !IROUTINE: ESMF_ClockSet - Set clock properties -- for compatibility with ESMF 2.0.1
! !INTERFACE:
subroutine ESMF_ClockSet(clock, TimeStep, StartTime, StopTime, & 3,2
RefTime, CurrTime, rc)
! !ARGUMENTS:
type(ESMF_Clock), intent(inout) :: clock
type(ESMF_TimeInterval), intent(in), optional :: TimeStep
type(ESMF_Time), intent(in), optional :: StartTime
type(ESMF_Time), intent(in), optional :: StopTime
type(ESMF_Time), intent(in), optional :: RefTime
type(ESMF_Time), intent(in), optional :: CurrTime
integer, intent(out), optional :: rc
! Local
integer ierr
! !DESCRIPTION:
! Initialize an {\tt ESMF\_Clock}
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to initialize
! \item[{[TimeStep]}]
! The {\tt ESMF\_Clock}'s time step interval
! \item[StartTime]
! The {\tt ESMF\_Clock}'s starting time
! \item[StopTime]
! The {\tt ESMF\_Clock}'s stopping time
! \item[{[RefTime]}]
! The {\tt ESMF\_Clock}'s reference time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.1, TMG3.4.4
!EOP
ierr = ESMF_SUCCESS
IF ( PRESENT(TimeStep) ) THEN
CALL ESMF_ClockSetTimeStep
( clock, TimeStep, rc=ierr )
ENDIF
IF ( PRESENT(RefTime) ) clock%clockint%RefTime = RefTime
IF ( PRESENT(StartTime) ) clock%clockint%StartTime = StartTime
IF ( PRESENT(StopTime) ) clock%clockint%StopTime = StopTime
IF ( PRESENT(CurrTime) ) THEN
CALL ESMF_ClockSetCurrTime
(clock, CurrTime, rc=ierr)
ENDIF
IF ( PRESENT(rc) ) rc = ierr
end subroutine ESMF_ClockSet
! Create ESMF_Clock using ESMF 2.1.0+ semantics
FUNCTION ESMF_ClockCreate( name, TimeStep, StartTime, StopTime, & 3,1
RefTime, rc )
! return value
type(ESMF_Clock) :: ESMF_ClockCreate
! !ARGUMENTS:
character (len=*), intent(in), optional :: name
type(ESMF_TimeInterval), intent(in), optional :: TimeStep
type(ESMF_Time), intent(in) :: StartTime
type(ESMF_Time), intent(in) :: StopTime
type(ESMF_Time), intent(in), optional :: RefTime
integer, intent(out), optional :: rc
! locals
type(ESMF_Clock) :: clocktmp
! TBH: ignore allocate errors, for now
ALLOCATE( clocktmp%clockint )
CALL ESMF_ClockSetOLD
( clocktmp%clockint, &
TimeStep= TimeStep, &
StartTime=StartTime, &
StopTime= StopTime, &
RefTime=RefTime, rc=rc )
ESMF_ClockCreate = clocktmp
END FUNCTION ESMF_ClockCreate
! Deallocate memory for ESMF_Clock
SUBROUTINE ESMF_ClockDestroy( clock, rc )
TYPE(ESMF_Clock), INTENT(INOUT) :: clock
INTEGER, INTENT( OUT), OPTIONAL :: rc
! TBH: ignore deallocate errors, for now
DEALLOCATE( clock%clockint%AlarmList )
DEALLOCATE( clock%clockint )
IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
END SUBROUTINE ESMF_ClockDestroy
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGet - Get clock properties -- for compatibility with ESMF 2.0.1
! tcraig added alarmCount for ccsm4, consistent with ESMF3 interface
! !INTERFACE:
subroutine ESMF_ClockGet(clock, StartTime, CurrTime, & 60,8
AdvanceCount, StopTime, TimeStep, &
PrevTime, RefTime, AlarmCount, &
rc)
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_Time), intent(out), optional :: StartTime
type(ESMF_Time), intent(out), optional :: CurrTime
type(ESMF_Time), intent(out), optional :: StopTime
type(ESMF_Time), intent(out), optional :: PrevTime
type(ESMF_Time), intent(out), optional :: RefTime
integer(ESMF_KIND_I8), intent(out), optional :: AdvanceCount
integer, intent(out), optional :: AlarmCount
type(ESMF_TimeInterval), intent(out), optional :: TimeStep
integer, intent(out), optional :: rc
integer :: ierr
! !DESCRIPTION:
! Returns the number of times the {\tt ESMF\_Clock} has been advanced
! (time stepped)
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the advance count from
! \item[StartTime]
! The start time
! \item[CurrTime]
! The current time
! \item[AdvanceCount]
! The number of times the {\tt ESMF\_Clock} has been advanced
! \item[StopTime]
! The {\tt ESMF\_Clock}'s stopping time
! \item[{[TimeStep]}]
! The {\tt ESMF\_Clock}'s time step interval
! \item[{[PrevTime]}]
! The {\tt ESMF\_Clock}'s previous current time
! \item[{[PrevTime]}]
! The {\tt ESMF\_Clock}'s reference time
! \item[{[AlarmCount]}]
! The {\tt ESMF\_Clock}'s number of valid alarms
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
! !REQUIREMENTS:
! TMG3.5.1
!EOP
ierr = ESMF_SUCCESS
IF ( PRESENT (StartTime) ) THEN
CALL ESMF_ClockGetStartTime
( clock, StartTime=StartTime, rc=ierr )
ENDIF
IF ( PRESENT (CurrTime) ) THEN
CALL ESMF_ClockGetCurrTime
( clock , CurrTime, ierr )
ENDIF
IF ( PRESENT (StopTime) ) THEN
CALL ESMF_ClockGetStopTime
( clock , StopTime, ierr )
ENDIF
IF ( PRESENT (AdvanceCount) ) THEN
CALL ESMF_ClockGetAdvanceCount
(clock, AdvanceCount, ierr)
ENDIF
IF ( PRESENT (TimeStep) ) THEN
CALL ESMF_ClockGetTimeStep
(clock, TimeStep, ierr)
ENDIF
IF ( PRESENT (PrevTime) ) THEN
CALL ESMF_ClockGetPrevTime
(clock, PrevTime, ierr)
ENDIF
IF ( PRESENT (RefTime) ) THEN
CALL ESMF_ClockGetRefTime
(clock, RefTime, ierr)
ENDIF
IF ( PRESENT (AlarmCount) ) THEN
CALL ESMF_ClockGetNumAlarms
(clock, AlarmCount, ierr)
ENDIF
IF ( PRESENT (rc) ) THEN
rc = ierr
ENDIF
end subroutine ESMF_ClockGet
! !IROUTINE: ESMF_ClockGetAdvanceCount - Get the clock's advance count
! !INTERFACE:
subroutine ESMF_ClockGetAdvanceCount(clock, AdvanceCount, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
integer(ESMF_KIND_I8), intent(out) :: AdvanceCount
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Returns the number of times the {\tt ESMF\_Clock} has been advanced
! (time stepped)
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the advance count from
! \item[AdvanceCount]
! The number of times the {\tt ESMF\_Clock} has been advanced
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
! !REQUIREMENTS:
! TMG3.5.1
!EOP
AdvanceCount = clock%clockint%AdvanceCount
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetAdvanceCount
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetTimeStep - Get a clock's timestep interval
! !INTERFACE:
subroutine ESMF_ClockGetTimeStep(clock, TimeStep, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_TimeInterval), intent(out) :: TimeStep
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s timestep interval
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the time step from
! \item[TimeStep]
! The time step
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.5.2
!EOP
TimeStep = clock%clockint%TimeStep
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetTimeStep
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockSetTimeStep - Set a clock's timestep interval
! !INTERFACE:
subroutine ESMF_ClockSetTimeStep(clock, TimeStep, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(out) :: clock
type(ESMF_TimeInterval), intent(in) :: TimeStep
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Set an {\tt ESMF\_Clock}'s timestep interval
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to set the time step
! \item[TimeStep]
! The time step
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.4.2
!EOP
clock%clockint%TimeStep = TimeStep
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockSetTimeStep
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetCurrTime - Get a clock's current time
! !INTERFACE:
subroutine ESMF_ClockGetCurrTime(clock, CurrTime, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_Time), intent(out) :: CurrTime
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s current time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the current time from
! \item[CurrTime]
! The current time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.5.4
!EOP
CurrTime = clock%clockint%CurrTime
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetCurrTime
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockSetCurrTime - Set a clock's current time
! !INTERFACE:
subroutine ESMF_ClockSetCurrTime(clock, CurrTime, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(out) :: clock
type(ESMF_Time), intent(in) :: CurrTime
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Set an {\tt ESMF\_Clock}'s current time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to set the current time from
! \item[CurrTime]
! The current time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.4.3
!EOP
clock%clockint%CurrTime = CurrTime
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockSetCurrTime
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetStartTime - Get a clock's start time
! !INTERFACE:
subroutine ESMF_ClockGetStartTime(clock, StartTime, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_Time), intent(out) :: StartTime
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s start time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the start time from
! \item[StartTime]
! The start time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.5.3
!EOP
StartTime = clock%clockint%StartTime
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetStartTime
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetStopTime - Get a clock's stop time
! !INTERFACE:
subroutine ESMF_ClockGetStopTime(clock, StopTime, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_Time), intent(out) :: StopTime
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s stop time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the stop time from
! \item[StopTime]
! The stop time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.5.3
!EOP
StopTime = clock%clockint%StopTime
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetStopTime
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetRefTime - Get a clock's reference time
! !INTERFACE:
subroutine ESMF_ClockGetRefTime(clock, RefTime, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_Time), intent(out) :: RefTime
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s reference time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the reference time from
! \item[RefTime]
! The reference time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.5.3
!EOP
refTime = clock%clockint%RefTime
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetRefTime
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetPrevTime - Get a clock's previous current time
! !INTERFACE:
subroutine ESMF_ClockGetPrevTime(clock, PrevTime, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_Time), intent(out) :: PrevTime
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s previous current time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the previous current time from
! \item[PrevTime]
! The previous current time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.5.4
!EOP
prevTime = Clock%clockint%CurrTime - Clock%clockint%TimeStep
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetPrevTime
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetCurrSimTime - Get a clock's current simulation time
! !INTERFACE:
subroutine ESMF_ClockGetCurrSimTime(clock, CurrSimTime, rc),1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_TimeInterval), intent(out) :: CurrSimTime
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s current simulation time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the current simulation time from
! \item[CurrSimTime]
! The current simulation time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.5.5
!EOP
CALL wrf_error_fatal
( 'ESMF_ClockGetCurrSimTime not supported' )
end subroutine ESMF_ClockGetCurrSimTime
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetPrevSimTime - Get a clock's previous simulation time
! !INTERFACE:
subroutine ESMF_ClockGetPrevSimTime(clock, PrevSimTime, rc),1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_TimeInterval), intent(out) :: PrevSimTime
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s previous simulation time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the previous simulation time from
! \item[PrevSimTime]
! The previous simulation time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.5.5
!EOP
CALL wrf_error_fatal
( 'ESMF_ClockGetPrevSimTime not supported' )
end subroutine ESMF_ClockGetPrevSimTime
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockAddAlarm - Add an alarm to a clock's alarm list
! !INTERFACE:
subroutine ESMF_ClockAddAlarm(clock, Alarm, rc) 1,2
! !ARGUMENTS:
type(ESMF_Clock), intent(inout) :: clock
type(ESMF_Alarm), intent(inout) :: Alarm
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Add an {\tt ESMF\_Alarm} to an {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to add an {\tt ESMF\_Alarm} to
! \item[Alarm]
! The {\tt ESMF\_Alarm} to add to the {\tt ESMF\_Clock}'s
! {\tt ESMF\_Alarm} list
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG4.1, TMG4.2
!EOP
IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
clock%clockint%NumAlarms = clock%clockint%NumAlarms + 1
IF ( clock%clockint%NumAlarms > SIZE (clock%clockint%AlarmList) ) THEN
CALL wrf_error_fatal
( 'ESMF_ClockAddAlarm: too many alarms' )
ELSE IF ( .NOT. ASSOCIATED( Alarm%alarmint ) ) THEN
CALL wrf_error_fatal
( &
'ESMF_ClockAddAlarm: alarm not created' )
ELSE
!TBH: why do all this initialization here?
IF ( Alarm%alarmint%RingTimeSet ) THEN
Alarm%alarmint%PrevRingTime = Alarm%alarmint%RingTime - &
Alarm%alarmint%RingInterval
ELSE
Alarm%alarmint%PrevRingTime = clock%clockint%CurrTime
ENDIF
Alarm%alarmint%Ringing = .FALSE.
! finally, load the alarm into the list
clock%clockint%AlarmList(clock%clockint%NumAlarms) = Alarm
ENDIF
end subroutine ESMF_ClockAddAlarm
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetAlarmList - Get a clock's alarm list
! !INTERFACE:
subroutine ESMF_ClockGetAlarmList(clock, AlarmList, rc) 8
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_Alarm), pointer :: AlarmList(:)
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get an {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the {\tt ESMF\_Alarm} list from
! \item[AlarmList]
! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG4.3
!EOP
AlarmList => clock%clockint%AlarmList
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetAlarmList
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockGetNumAlarms - Get the number of alarms in a clock's alarm list
! !INTERFACE:
subroutine ESMF_ClockGetNumAlarms(clock, NumAlarms, rc) 1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
integer, intent(out) :: NumAlarms
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Get the number of {\tt ESMF\_Alarm}s in an {\tt ESMF\_Clock}'s
! {\tt ESMF\_Alarm} list
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to get the number of {\tt ESMF\_Alarm}s from
! \item[NumAlarms]
! The number of {\tt ESMF\_Alarm}s in the {\tt ESMF\_Clock}'s
! {\tt ESMF\_Alarm} list
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG4.3
!EOP
NumAlarms = clock%clockint%NumAlarms
IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockGetNumAlarms
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockSyncToWallClock - Set clock's current time to wall clock time
! !INTERFACE:
subroutine ESMF_ClockSyncToWallClock(clock, rc),1
! !ARGUMENTS:
type(ESMF_Clock), intent(inout) :: clock
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Set an {\tt ESMF\_Clock}'s current time to wall clock time
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to synchronize to wall clock time
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.4.5
!EOP
CALL wrf_error_fatal
( 'ESMF_ClockSyncToWallClock not supported' )
end subroutine ESMF_ClockSyncToWallClock
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockAdvance - Advance a clock's current time by one time step
! !INTERFACE:
subroutine ESMF_ClockAdvance(clock, RingingAlarmList, & 12,1
NumRingingAlarms, rc)
use ESMF_TimeMod
! !ARGUMENTS:
type(ESMF_Clock), intent(inout) :: clock
type(ESMF_Alarm), dimension(MAX_ALARMS), intent(out), optional :: &
RingingAlarmList
integer, intent(out), optional :: NumRingingAlarms
integer, intent(out), optional :: rc
! Local
logical pred1, pred2, pred3
integer i, n
type(ESMF_Alarm) :: alarm
!
! !DESCRIPTION:
! Advance an {\tt ESMF\_Clock}'s current time by one time step
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to advance
! \item[{[RingingAlarmList]}]
! Return a list of any ringing alarms after the time step
! \item[{[NumRingingAlarms]}]
! The number of ringing alarms returned
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMG3.4.1
!EOP
clock%clockint%CurrTime = clock%clockint%CurrTime + &
clock%clockint%TimeStep
IF ( Present(NumRingingAlarms) ) NumRingingAlarms = 0
clock%clockint%AdvanceCount = clock%clockint%AdvanceCount + 1
DO i = 1, MAX_ALARMS
alarm = clock%clockint%AlarmList(i)
! TBH: This is really dangerous. We need to be able to NULLIFY
! TBH: alarmint at compile-time (F95 synax) to make this safe.
!$$$TBH: see if F95 compile-time pointer-nullification is supported by all
!$$$TBH: compilers we support
IF ( ASSOCIATED( alarm%alarmint ) ) THEN
IF ( alarm%alarmint%Enabled ) THEN
IF ( alarm%alarmint%RingIntervalSet ) THEN
pred1 = .FALSE. ; pred2 = .FALSE. ; pred3 = .FALSE.
IF ( alarm%alarmint%StopTimeSet ) THEN
PRED1 = clock%clockint%CurrTime > alarm%alarmint%StopTime
ENDIF
IF ( alarm%alarmint%RingTimeSet ) THEN
PRED2 = ( alarm%alarmint%RingTime <= clock%clockint%CurrTime &
.AND. clock%clockint%CurrTime < alarm%alarmint%RingTime + &
clock%clockint%TimeStep )
ENDIF
IF ( alarm%alarmint%RingIntervalSet ) THEN
PRED3 = ( alarm%alarmint%PrevRingTime + alarm%alarmint%RingInterval <= &
clock%clockint%CurrTime )
ENDIF
IF ( ( .NOT. ( pred1 ) ) .AND. &
( ( pred2 ) .OR. ( pred3 ) ) ) THEN
alarm%alarmint%Ringing = .TRUE.
IF ( PRED3) alarm%alarmint%PrevRingTime = alarm%alarmint%PrevRingTime + &
alarm%alarmint%RingInterval
IF ( PRESENT( RingingAlarmList ) .AND. &
PRESENT ( NumRingingAlarms ) ) THEN
NumRingingAlarms = NumRingingAlarms + 1
RingingAlarmList( NumRingingAlarms ) = alarm
ENDIF
ENDIF
ELSE IF ( alarm%alarmint%RingTimeSet ) THEN
IF ( alarm%alarmint%RingTime <= clock%clockint%CurrTime ) THEN
alarm%alarmint%Ringing = .TRUE.
IF ( PRESENT( RingingAlarmList ) .AND. &
PRESENT ( NumRingingAlarms ) ) THEN
NumRingingAlarms = NumRingingAlarms + 1
RingingAlarmList( NumRingingAlarms ) = alarm
ENDIF
ENDIF
ENDIF
IF ( alarm%alarmint%StopTimeSet ) THEN
ENDIF
ENDIF
ENDIF
clock%clockint%AlarmList(i) = alarm
ENDDO
IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
end subroutine ESMF_ClockAdvance
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockStopTimeDisable - NOOP for compatibility with ESMF 2.1.0+
! !INTERFACE:
subroutine ESMF_ClockStopTimeDisable(clock, rc)
!
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
integer, intent(out), optional :: rc
rc = ESMF_SUCCESS
end subroutine ESMF_ClockStopTimeDisable
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockIsStopTime - Has the clock reached its stop time ?
! !INTERFACE:
function ESMF_ClockIsStopTime(clock, rc)
!
! !RETURN VALUE:
logical :: ESMF_ClockIsStopTime
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Return true if {\tt ESMF\_Clock} has reached its stop time, false
! otherwise
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to check
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
! !REQUIREMENTS:
! TMG3.5.6
!EOP
if ( clock%clockint%CurrTime .GE. clock%clockint%StopTime ) THEN
ESMF_ClockIsStopTime = .TRUE.
else
ESMF_ClockIsStopTime = .FALSE.
endif
IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
end function ESMF_ClockIsStopTime
!------------------------------------------------------------------------------
!
! This section defines the overridden Read, Write, Validate and Print methods
! from the ESMF_Base class
!
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockRead - Restores a clock
! !INTERFACE:
subroutine ESMF_ClockRead(clock, TimeStep, StartTime, StopTime, &,1
RefTime, CurrTime, PrevTime, AdvanceCount, &
AlarmList, rc)
! !ARGUMENTS:
type(ESMF_Clock), intent(out) :: clock
type(ESMF_TimeInterval), intent(in) :: TimeStep
type(ESMF_Time), intent(in) :: StartTime
type(ESMF_Time), intent(in) :: StopTime
type(ESMF_Time), intent(in) :: RefTime
type(ESMF_Time), intent(in) :: CurrTime
type(ESMF_Time), intent(in) :: PrevTime
integer(ESMF_KIND_I8), intent(in) :: AdvanceCount
type(ESMF_Alarm), dimension(MAX_ALARMS), intent(in) :: AlarmList
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Restore an {\tt ESMF\_Clock}
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to restore
! \item[TimeStep]
! The {\tt ESMF\_Clock}'s time step interval
! \item[StartTime]
! The {\tt ESMF\_Clock}'s starting time
! \item[StopTime]
! The {\tt ESMF\_Clock}'s stopping time
! \item[RefTime]
! The {\tt ESMF\_Clock}'s reference time
! \item[CurrTime]
! The {\tt ESMF\_Clock}'s current time
! \item[PrevTime]
! The {\tt ESMF\_Clock}'s previous time
! \item[AdvanceCount]
! The number of times the {\tt ESMF\_Clock} has been advanced
! \item[AlarmList]
! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
!EOP
CALL wrf_error_fatal
( 'ESMF_ClockRead not supported' )
end subroutine ESMF_ClockRead
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockWrite - Saves a clock
! !INTERFACE:
subroutine ESMF_ClockWrite(clock, TimeStep, StartTime, StopTime, &,1
RefTime, CurrTime, PrevTime, AdvanceCount, &
AlarmList, rc)
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
type(ESMF_TimeInterval), intent(out) :: TimeStep
type(ESMF_Time), intent(out) :: StartTime
type(ESMF_Time), intent(out) :: StopTime
type(ESMF_Time), intent(out) :: RefTime
type(ESMF_Time), intent(out) :: CurrTime
type(ESMF_Time), intent(out) :: PrevTime
integer(ESMF_KIND_I8), intent(out) :: AdvanceCount
type(ESMF_Alarm), dimension(MAX_ALARMS), intent(out) :: AlarmList
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Save an {\tt ESMF\_Clock}
!
! The arguments are:
! \begin{description}
! \item[clock]
! The object instance to save
! \item[TimeStep]
! The {\tt ESMF\_Clock}'s time step interval
! \item[StartTime]
! The {\tt ESMF\_Clock}'s starting time
! \item[StopTime]
! The {\tt ESMF\_Clock}'s stopping time
! \item[RefTime]
! The {\tt ESMF\_Clock}'s reference time
! \item[CurrTime]
! The {\tt ESMF\_Clock}'s current time
! \item[PrevTime]
! The {\tt ESMF\_Clock}'s previous time
! \item[AdvanceCount]
! The number of times the {\tt ESMF\_Clock} has been advanced
! \item[AlarmList]
! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
!EOP
CALL wrf_error_fatal
( 'ESMF_ClockWrite not supported' )
end subroutine ESMF_ClockWrite
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockValidate - Validate a Clock's properties
! !INTERFACE:
subroutine ESMF_ClockValidate(clock, opts, rc),1
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
character (len=*), intent(in), optional :: opts
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Perform a validation check on an {\tt ESMF\_Clock}'s properties
!
! The arguments are:
! \begin{description}
! \item[clock]
! {\tt ESMF\_Clock} to validate
! \item[{[opts]}]
! Validate options
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMGn.n.n
!EOP
CALL wrf_error_fatal
( 'ESMF_ClockValidate not supported' )
end subroutine ESMF_ClockValidate
!------------------------------------------------------------------------------
!BOP
! !IROUTINE: ESMF_ClockPrint - Print out a Clock's properties
! !INTERFACE:
subroutine ESMF_ClockPrint(clock, opts, rc),6
! !ARGUMENTS:
type(ESMF_Clock), intent(in) :: clock
character (len=*), intent(in), optional :: opts
integer, intent(out), optional :: rc
! !DESCRIPTION:
! To support testing/debugging, print out an {\tt ESMF\_Clock}'s
! properties.
!
! The arguments are:
! \begin{description}
! \item[clock]
! {\tt ESMF\_Clock} to print out
! \item[{[opts]}]
! Print options
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
! !REQUIREMENTS:
! TMGn.n.n
!EOP
type(ESMF_Time) :: start_time
type(ESMF_Time) :: stop_time
type(ESMF_Time) :: curr_time
type(ESMF_Time) :: ref_time
type(ESMF_TimeInterval) :: timestep
call ESMF_ClockGet
( clock, startTime=start_time, &
stoptime=stop_time, currTime=curr_time, &
refTime=ref_time, timeStep=timestep, rc=rc )
print *, 'Start time: '
call ESMF_TimePrint
( start_time )
print *, 'Stop time: '
call ESMF_TimePrint
( stop_time )
print *, 'Reference time: '
call ESMF_TimePrint
( ref_time )
print *, 'Current time: '
call ESMF_TimePrint
( curr_time )
print *, 'Time step: '
call ESMF_TimeIntervalPrint
( timestep)
end subroutine ESMF_ClockPrint
!------------------------------------------------------------------------------
end module ESMF_ClockMod