2 ! Earth System Modeling Framework
3 ! Copyright 2002-2003, University Corporation for Atmospheric Research,
4 ! Massachusetts Institute of Technology, Geophysical Fluid Dynamics
5 ! Laboratory, University of Michigan, National Centers for Environmental
6 ! Prediction, Los Alamos National Laboratory, Argonne National Laboratory,
7 ! NASA Goddard Space Flight Center.
8 ! Licensed under the University of Illinois-NCSA license.
10 !==============================================================================
15 !==============================================================================
17 ! This file contains the Clock class definition and all Clock class methods.
19 !------------------------------------------------------------------------------
21 #include <ESMF_TimeMgr.inc>
23 !==============================================================================
25 ! !MODULE: ESMF_ClockMod
28 ! Part of Time Manager F90 API wrapper of C++ implemenation
30 ! Defines F90 wrapper entry points for corresponding
31 ! C++ class {\tt ESMC\_Time} implementation
33 ! See {\tt ../include/ESMC\_Clock.h} for complete description
35 !------------------------------------------------------------------------------
37 ! inherit from ESMF base class
40 ! associated derived types
41 use ESMF_TimeIntervalMod ! , only : ESMF_TimeInterval, &
42 ! ESMF_TimeIntervalIsPositive
43 use ESMF_TimeMod ! , only : ESMF_Time
44 use ESMF_AlarmMod, only : ESMF_Alarm
48 !------------------------------------------------------------------------------
51 !------------------------------------------------------------------------------
54 ! ! F90 class type to match C++ Clock class in size only;
55 ! ! all dereferencing within class is performed by C++ implementation
57 ! internals for ESMF_Clock
59 type(ESMF_TimeInterval) :: TimeStep
60 type(ESMF_Time) :: StartTime
61 type(ESMF_Time) :: StopTime
62 type(ESMF_Time) :: RefTime
63 type(ESMF_Time) :: CurrTime
64 type(ESMF_Time) :: PrevTime
65 integer(ESMF_KIND_I8) :: AdvanceCount
68 ! Note: to mimic ESMF 2.1.0+, AlarmList is maintained
69 ! within ESMF_Clock even though copies of each alarm are
70 ! returned from ESMF_AlarmCreate() at the same time they
71 ! are copied into the AlarmList! This duplication is not
72 ! as hideous as it might be because the ESMF_Alarm type
73 ! has data members that are all POINTERs (thus the horrible
74 ! shallow-copy-masquerading-as-reference-copy hack works).
75 type(ESMF_Alarm), pointer, dimension(:) :: AlarmList
78 ! Actual public type: this bit allows easy mimic of "deep" ESMF_ClockCreate
80 ! NOTE: DO NOT ADD NON-POINTER STATE TO THIS DATA TYPE. It emulates ESMF
81 ! shallow-copy-masquerading-as-reference-copy.
83 type(ESMF_ClockInt), pointer :: clockint
86 !------------------------------------------------------------------------------
89 public ESMF_ClockInt ! needed on AIX but not PGI
90 !------------------------------------------------------------------------------
92 ! !PUBLIC MEMBER FUNCTIONS:
93 public ESMF_ClockCreate
94 public ESMF_ClockDestroy
96 ! public ESMF_ClockSetOLD
98 ! public ESMF_ClockGetAdvanceCount
99 ! public ESMF_ClockGetTimeStep
100 ! public ESMF_ClockSetTimeStep
101 ! public ESMF_ClockGetCurrTime
102 ! public ESMF_ClockSetCurrTime
103 ! public ESMF_ClockGetStartTime
104 ! public ESMF_ClockGetStopTime
105 ! public ESMF_ClockGetRefTime
106 ! public ESMF_ClockGetPrevTime
107 ! public ESMF_ClockGetCurrSimTime
108 ! public ESMF_ClockGetPrevSimTime
109 ! This must be public for ESMF_AlarmClockMod...
110 public ESMF_ClockAddAlarm
111 public ESMF_ClockGetAlarmList
112 ! public ESMF_ClockGetNumAlarms
113 ! public ESMF_ClockSyncToWallClock
114 public ESMF_ClockAdvance
115 public ESMF_ClockIsStopTime
116 public ESMF_ClockStopTimeDisable
118 ! Required inherited and overridden ESMF_Base class methods
120 ! public ESMF_ClockRead
121 ! public ESMF_ClockWrite
122 public ESMF_ClockValidate
123 public ESMF_ClockPrint
126 !==============================================================================
130 !==============================================================================
132 ! This section includes the Set methods.
134 !------------------------------------------------------------------------------
136 ! !IROUTINE: ESMF_ClockSetOLD - Initialize a clockint
139 subroutine ESMF_ClockSetOLD(clockint, TimeStep, StartTime, &
140 StopTime, RefTime, rc)
143 type(ESMF_ClockInt), intent(out) :: clockint
144 type(ESMF_TimeInterval), intent(in), optional :: TimeStep
145 type(ESMF_Time), intent(in) :: StartTime
146 type(ESMF_Time), intent(in) :: StopTime
147 type(ESMF_Time), intent(in), optional :: RefTime
148 integer, intent(out), optional :: rc
153 ! Initialize an {\tt ESMF\_Clock}
156 ! \begin{description}
158 ! The object instance to initialize
159 ! \item[{[TimeStep]}]
160 ! The {\tt ESMF\_Clock}'s time step interval
162 ! The {\tt ESMF\_Clock}'s starting time
164 ! The {\tt ESMF\_Clock}'s stopping time
166 ! The {\tt ESMF\_Clock}'s reference time
168 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
174 IF ( PRESENT(TimeStep) ) clockint%TimeStep = TimeStep
175 IF ( PRESENT(RefTime) )THEN
176 clockint%RefTime = RefTime
178 clockint%RefTime = StartTime
180 clockint%CurrTime = StartTime
181 clockint%StartTime = StartTime
182 clockint%StopTime = StopTime
183 clockint%NumAlarms = 0
184 clockint%AdvanceCount = 0
185 ALLOCATE(clockint%AlarmList(MAX_ALARMS))
186 ! TBH: This incredible hack can be removed once ESMF_*Validate()
187 ! TBH: can tell if a deep ESMF_* was created or not.
189 NULLIFY( clockint%AlarmList( i )%alarmint )
191 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
193 end subroutine ESMF_ClockSetOLD
196 ! !IROUTINE: ESMF_ClockSet - Set clock properties -- for compatibility with ESMF 2.0.1
199 subroutine ESMF_ClockSet(clock, TimeStep, StartTime, StopTime, &
200 RefTime, CurrTime, rc)
203 type(ESMF_Clock), intent(inout) :: clock
204 type(ESMF_TimeInterval), intent(in), optional :: TimeStep
205 type(ESMF_Time), intent(in), optional :: StartTime
206 type(ESMF_Time), intent(in), optional :: StopTime
207 type(ESMF_Time), intent(in), optional :: RefTime
208 type(ESMF_Time), intent(in), optional :: CurrTime
209 integer, intent(out), optional :: rc
214 ! Initialize an {\tt ESMF\_Clock}
217 ! \begin{description}
219 ! The object instance to initialize
220 ! \item[{[TimeStep]}]
221 ! The {\tt ESMF\_Clock}'s time step interval
223 ! The {\tt ESMF\_Clock}'s starting time
225 ! The {\tt ESMF\_Clock}'s stopping time
227 ! The {\tt ESMF\_Clock}'s reference time
229 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
236 IF ( PRESENT(TimeStep) ) THEN
237 CALL ESMF_ClockSetTimeStep ( clock, TimeStep, rc=ierr )
239 IF ( PRESENT(RefTime) ) clock%clockint%RefTime = RefTime
240 IF ( PRESENT(StartTime) ) clock%clockint%StartTime = StartTime
241 IF ( PRESENT(StopTime) ) clock%clockint%StopTime = StopTime
242 IF ( PRESENT(CurrTime) ) THEN
243 CALL ESMF_ClockSetCurrTime(clock, CurrTime, rc=ierr)
245 IF ( PRESENT(rc) ) rc = ierr
247 end subroutine ESMF_ClockSet
250 ! Create ESMF_Clock using ESMF 2.1.0+ semantics
251 FUNCTION ESMF_ClockCreate( name, TimeStep, StartTime, StopTime, &
254 type(ESMF_Clock) :: ESMF_ClockCreate
256 character (len=*), intent(in), optional :: name
257 type(ESMF_TimeInterval), intent(in), optional :: TimeStep
258 type(ESMF_Time), intent(in) :: StartTime
259 type(ESMF_Time), intent(in) :: StopTime
260 type(ESMF_Time), intent(in), optional :: RefTime
261 integer, intent(out), optional :: rc
263 type(ESMF_Clock) :: clocktmp
264 ! TBH: ignore allocate errors, for now
265 ALLOCATE( clocktmp%clockint )
266 CALL ESMF_ClockSetOLD( clocktmp%clockint, &
267 TimeStep= TimeStep, &
268 StartTime=StartTime, &
269 StopTime= StopTime, &
270 RefTime=RefTime, rc=rc )
271 ESMF_ClockCreate = clocktmp
272 END FUNCTION ESMF_ClockCreate
275 ! Deallocate memory for ESMF_Clock
276 SUBROUTINE ESMF_ClockDestroy( clock, rc )
277 TYPE(ESMF_Clock), INTENT(INOUT) :: clock
278 INTEGER, INTENT( OUT), OPTIONAL :: rc
279 ! TBH: ignore deallocate errors, for now
280 DEALLOCATE( clock%clockint%AlarmList )
281 DEALLOCATE( clock%clockint )
282 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
283 END SUBROUTINE ESMF_ClockDestroy
286 !------------------------------------------------------------------------------
288 ! !IROUTINE: ESMF_ClockGet - Get clock properties -- for compatibility with ESMF 2.0.1
291 subroutine ESMF_ClockGet(clock, StartTime, CurrTime, &
292 AdvanceCount, StopTime, TimeStep, &
297 type(ESMF_Clock), intent(in) :: clock
298 type(ESMF_Time), intent(out), optional :: StartTime
299 type(ESMF_Time), intent(out), optional :: CurrTime
300 type(ESMF_Time), intent(out), optional :: StopTime
301 type(ESMF_Time), intent(out), optional :: PrevTime
302 type(ESMF_Time), intent(out), optional :: RefTime
303 integer(ESMF_KIND_I8), intent(out), optional :: AdvanceCount
304 type(ESMF_TimeInterval), intent(out), optional :: TimeStep
305 integer, intent(out), optional :: rc
309 ! Returns the number of times the {\tt ESMF\_Clock} has been advanced
313 ! \begin{description}
315 ! The object instance to get the advance count from
320 ! \item[AdvanceCount]
321 ! The number of times the {\tt ESMF\_Clock} has been advanced
323 ! The {\tt ESMF\_Clock}'s stopping time
324 ! \item[{[TimeStep]}]
325 ! The {\tt ESMF\_Clock}'s time step interval
326 ! \item[{[PrevTime]}]
327 ! The {\tt ESMF\_Clock}'s previous current time
328 ! \item[{[PrevTime]}]
329 ! The {\tt ESMF\_Clock}'s reference time
331 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
339 IF ( PRESENT (StartTime) ) THEN
340 CALL ESMF_ClockGetStartTime( clock, StartTime=StartTime, rc=ierr )
342 IF ( PRESENT (CurrTime) ) THEN
343 CALL ESMF_ClockGetCurrTime( clock , CurrTime, ierr )
345 IF ( PRESENT (StopTime) ) THEN
346 CALL ESMF_ClockGetStopTime( clock , StopTime, ierr )
348 IF ( PRESENT (AdvanceCount) ) THEN
349 CALL ESMF_ClockGetAdvanceCount(clock, AdvanceCount, ierr)
351 IF ( PRESENT (TimeStep) ) THEN
352 CALL ESMF_ClockGetTimeStep(clock, TimeStep, ierr)
354 IF ( PRESENT (PrevTime) ) THEN
355 CALL ESMF_ClockGetPrevTime(clock, PrevTime, ierr)
357 IF ( PRESENT (RefTime) ) THEN
358 CALL ESMF_ClockGetRefTime(clock, RefTime, ierr)
361 IF ( PRESENT (rc) ) THEN
365 end subroutine ESMF_ClockGet
368 ! !IROUTINE: ESMF_ClockGetAdvanceCount - Get the clock's advance count
371 subroutine ESMF_ClockGetAdvanceCount(clock, AdvanceCount, rc)
374 type(ESMF_Clock), intent(in) :: clock
375 integer(ESMF_KIND_I8), intent(out) :: AdvanceCount
376 integer, intent(out), optional :: rc
379 ! Returns the number of times the {\tt ESMF\_Clock} has been advanced
383 ! \begin{description}
385 ! The object instance to get the advance count from
386 ! \item[AdvanceCount]
387 ! The number of times the {\tt ESMF\_Clock} has been advanced
389 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
396 AdvanceCount = clock%clockint%AdvanceCount
398 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
400 end subroutine ESMF_ClockGetAdvanceCount
402 !------------------------------------------------------------------------------
404 ! !IROUTINE: ESMF_ClockGetTimeStep - Get a clock's timestep interval
407 subroutine ESMF_ClockGetTimeStep(clock, TimeStep, rc)
410 type(ESMF_Clock), intent(in) :: clock
411 type(ESMF_TimeInterval), intent(out) :: TimeStep
412 integer, intent(out), optional :: rc
415 ! Get an {\tt ESMF\_Clock}'s timestep interval
418 ! \begin{description}
420 ! The object instance to get the time step from
424 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
431 TimeStep = clock%clockint%TimeStep
432 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
434 end subroutine ESMF_ClockGetTimeStep
436 !------------------------------------------------------------------------------
438 ! !IROUTINE: ESMF_ClockSetTimeStep - Set a clock's timestep interval
441 subroutine ESMF_ClockSetTimeStep(clock, TimeStep, rc)
444 type(ESMF_Clock), intent(inout) :: clock ! really INTENT(OUT)
445 type(ESMF_TimeInterval), intent(in) :: TimeStep
446 integer, intent(out), optional :: rc
449 ! Set an {\tt ESMF\_Clock}'s timestep interval
452 ! \begin{description}
454 ! The object instance to set the time step
458 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
465 clock%clockint%TimeStep = TimeStep
466 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
468 end subroutine ESMF_ClockSetTimeStep
470 !------------------------------------------------------------------------------
472 ! !IROUTINE: ESMF_ClockGetCurrTime - Get a clock's current time
475 subroutine ESMF_ClockGetCurrTime(clock, CurrTime, rc)
478 type(ESMF_Clock), intent(in) :: clock
479 type(ESMF_Time), intent(out) :: CurrTime
480 integer, intent(out), optional :: rc
483 ! Get an {\tt ESMF\_Clock}'s current time
486 ! \begin{description}
488 ! The object instance to get the current time from
492 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
499 CurrTime = clock%clockint%CurrTime
500 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
501 end subroutine ESMF_ClockGetCurrTime
503 !------------------------------------------------------------------------------
505 ! !IROUTINE: ESMF_ClockSetCurrTime - Set a clock's current time
508 subroutine ESMF_ClockSetCurrTime(clock, CurrTime, rc)
511 type(ESMF_Clock), intent(inout) :: clock ! really INTENT(OUT)
512 type(ESMF_Time), intent(in) :: CurrTime
513 integer, intent(out), optional :: rc
516 ! Set an {\tt ESMF\_Clock}'s current time
519 ! \begin{description}
521 ! The object instance to set the current time from
525 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
532 clock%clockint%CurrTime = CurrTime
533 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
535 end subroutine ESMF_ClockSetCurrTime
537 !------------------------------------------------------------------------------
539 ! !IROUTINE: ESMF_ClockGetStartTime - Get a clock's start time
542 subroutine ESMF_ClockGetStartTime(clock, StartTime, rc)
545 type(ESMF_Clock), intent(in) :: clock
546 type(ESMF_Time), intent(out) :: StartTime
547 integer, intent(out), optional :: rc
550 ! Get an {\tt ESMF\_Clock}'s start time
553 ! \begin{description}
555 ! The object instance to get the start time from
559 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
566 StartTime = clock%clockint%StartTime
567 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
569 end subroutine ESMF_ClockGetStartTime
571 !------------------------------------------------------------------------------
573 ! !IROUTINE: ESMF_ClockGetStopTime - Get a clock's stop time
576 subroutine ESMF_ClockGetStopTime(clock, StopTime, rc)
579 type(ESMF_Clock), intent(in) :: clock
580 type(ESMF_Time), intent(out) :: StopTime
581 integer, intent(out), optional :: rc
584 ! Get an {\tt ESMF\_Clock}'s stop time
587 ! \begin{description}
589 ! The object instance to get the stop time from
593 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
600 StopTime = clock%clockint%StopTime
601 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
603 end subroutine ESMF_ClockGetStopTime
605 !------------------------------------------------------------------------------
607 ! !IROUTINE: ESMF_ClockGetRefTime - Get a clock's reference time
610 subroutine ESMF_ClockGetRefTime(clock, RefTime, rc)
613 type(ESMF_Clock), intent(in) :: clock
614 type(ESMF_Time), intent(out) :: RefTime
615 integer, intent(out), optional :: rc
618 ! Get an {\tt ESMF\_Clock}'s reference time
621 ! \begin{description}
623 ! The object instance to get the reference time from
627 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
633 refTime = clock%clockint%RefTime
634 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
635 end subroutine ESMF_ClockGetRefTime
637 !------------------------------------------------------------------------------
639 ! !IROUTINE: ESMF_ClockGetPrevTime - Get a clock's previous current time
642 subroutine ESMF_ClockGetPrevTime(clock, PrevTime, rc)
645 type(ESMF_Clock), intent(in) :: clock
646 type(ESMF_Time), intent(out) :: PrevTime
647 integer, intent(out), optional :: rc
650 ! Get an {\tt ESMF\_Clock}'s previous current time
653 ! \begin{description}
655 ! The object instance to get the previous current time from
657 ! The previous current time
659 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
666 ! hack for bug in PGI 5.1-x
667 ! prevTime = Clock%clockint%CurrTime - Clock%clockint%TimeStep
668 prevTime = ESMF_TimeDec( Clock%clockint%CurrTime, &
669 Clock%clockint%TimeStep )
671 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
672 end subroutine ESMF_ClockGetPrevTime
674 !------------------------------------------------------------------------------
676 ! !IROUTINE: ESMF_ClockGetCurrSimTime - Get a clock's current simulation time
679 subroutine ESMF_ClockGetCurrSimTime(clock, CurrSimTime, rc)
682 type(ESMF_Clock), intent(in) :: clock
683 type(ESMF_TimeInterval), intent(out) :: CurrSimTime
684 integer, intent(out), optional :: rc
687 ! Get an {\tt ESMF\_Clock}'s current simulation time
690 ! \begin{description}
692 ! The object instance to get the current simulation time from
694 ! The current simulation time
696 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
702 CALL wrf_error_fatal( 'ESMF_ClockGetCurrSimTime not supported' )
703 end subroutine ESMF_ClockGetCurrSimTime
705 !------------------------------------------------------------------------------
707 ! !IROUTINE: ESMF_ClockGetPrevSimTime - Get a clock's previous simulation time
710 subroutine ESMF_ClockGetPrevSimTime(clock, PrevSimTime, rc)
713 type(ESMF_Clock), intent(in) :: clock
714 type(ESMF_TimeInterval), intent(out) :: PrevSimTime
715 integer, intent(out), optional :: rc
718 ! Get an {\tt ESMF\_Clock}'s previous simulation time
721 ! \begin{description}
723 ! The object instance to get the previous simulation time from
725 ! The previous simulation time
727 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
733 CALL wrf_error_fatal( 'ESMF_ClockGetPrevSimTime not supported' )
734 end subroutine ESMF_ClockGetPrevSimTime
736 !------------------------------------------------------------------------------
738 ! !IROUTINE: ESMF_ClockAddAlarm - Add an alarm to a clock's alarm list
741 subroutine ESMF_ClockAddAlarm(clock, Alarm, rc)
744 type(ESMF_Clock), intent(inout) :: clock
745 type(ESMF_Alarm), intent(inout) :: Alarm
746 integer, intent(out), optional :: rc
749 ! Add an {\tt ESMF\_Alarm} to an {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
752 ! \begin{description}
754 ! The object instance to add an {\tt ESMF\_Alarm} to
756 ! The {\tt ESMF\_Alarm} to add to the {\tt ESMF\_Clock}'s
757 ! {\tt ESMF\_Alarm} list
759 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
766 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
767 clock%clockint%NumAlarms = clock%clockint%NumAlarms + 1
768 IF ( clock%clockint%NumAlarms > SIZE (clock%clockint%AlarmList) ) THEN
769 CALL wrf_error_fatal ( 'ESMF_ClockAddAlarm: too many alarms' )
770 ELSE IF ( .NOT. ASSOCIATED( Alarm%alarmint ) ) THEN
771 CALL wrf_error_fatal ( &
772 'ESMF_ClockAddAlarm: alarm not created' )
774 IF ( Alarm%alarmint%RingTimeSet ) THEN
775 Alarm%alarmint%PrevRingTime = Alarm%alarmint%RingTime
777 !TBH: This has the nasty side-effect of forcing us to explicitly turn on
778 !TBH: alarms that are created with RingInterval only, if we want them to start
779 !TBH: ringing right away. And this is done (see
780 !TBH: COMPUTE_VORTEX_CENTER_ALARM). Straighten this out...
781 Alarm%alarmint%PrevRingTime = clock%clockint%CurrTime
783 Alarm%alarmint%Ringing = .FALSE.
785 ! finally, load the alarm into the list
786 clock%clockint%AlarmList(clock%clockint%NumAlarms) = Alarm
789 end subroutine ESMF_ClockAddAlarm
791 !------------------------------------------------------------------------------
793 ! !IROUTINE: ESMF_ClockGetAlarmList - Get a clock's alarm list
796 subroutine ESMF_ClockGetAlarmList(clock, AlarmList, rc)
799 type(ESMF_Clock), intent(in) :: clock
800 type(ESMF_Alarm), pointer :: AlarmList(:)
801 integer, intent(out), optional :: rc
804 ! Get an {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
807 ! \begin{description}
809 ! The object instance to get the {\tt ESMF\_Alarm} list from
811 ! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
813 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
820 AlarmList => clock%clockint%AlarmList
821 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
823 end subroutine ESMF_ClockGetAlarmList
825 !------------------------------------------------------------------------------
827 ! !IROUTINE: ESMF_ClockGetNumAlarms - Get the number of alarms in a clock's alarm list
830 subroutine ESMF_ClockGetNumAlarms(clock, NumAlarms, rc)
833 type(ESMF_Clock), intent(in) :: clock
834 integer, intent(out) :: NumAlarms
835 integer, intent(out), optional :: rc
838 ! Get the number of {\tt ESMF\_Alarm}s in an {\tt ESMF\_Clock}'s
839 ! {\tt ESMF\_Alarm} list
842 ! \begin{description}
844 ! The object instance to get the number of {\tt ESMF\_Alarm}s from
846 ! The number of {\tt ESMF\_Alarm}s in the {\tt ESMF\_Clock}'s
847 ! {\tt ESMF\_Alarm} list
849 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
856 NumAlarms = clock%clockint%NumAlarms
857 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
859 end subroutine ESMF_ClockGetNumAlarms
861 !------------------------------------------------------------------------------
863 ! !IROUTINE: ESMF_ClockSyncToWallClock - Set clock's current time to wall clock time
866 subroutine ESMF_ClockSyncToWallClock(clock, rc)
869 type(ESMF_Clock), intent(inout) :: clock
870 integer, intent(out), optional :: rc
873 ! Set an {\tt ESMF\_Clock}'s current time to wall clock time
876 ! \begin{description}
878 ! The object instance to synchronize to wall clock time
880 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
886 CALL wrf_error_fatal( 'ESMF_ClockSyncToWallClock not supported' )
887 end subroutine ESMF_ClockSyncToWallClock
889 !------------------------------------------------------------------------------
891 ! !IROUTINE: ESMF_ClockAdvance - Advance a clock's current time by one time step
894 subroutine ESMF_ClockAdvance(clock, RingingAlarmList, &
895 NumRingingAlarms, rc)
900 type(ESMF_Clock), intent(inout) :: clock
901 type(ESMF_Alarm), dimension(MAX_ALARMS), intent(out), optional :: &
903 integer, intent(out), optional :: NumRingingAlarms
904 integer, intent(out), optional :: rc
906 logical pred1, pred2, pred3
908 type(ESMF_Alarm) :: alarm
909 logical :: positive_timestep
912 ! Advance an {\tt ESMF\_Clock}'s current time by one time step
915 ! \begin{description}
917 ! The object instance to advance
918 ! \item[{[RingingAlarmList]}]
919 ! Return a list of any ringing alarms after the time step
920 ! \item[{[NumRingingAlarms]}]
921 ! The number of ringing alarms returned
923 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
929 ! hack for bug in PGI 5.1-x
930 ! clock%clockint%CurrTime = clock%clockint%CurrTime + &
931 ! clock%clockint%TimeStep
932 clock%clockint%CurrTime = ESMF_TimeInc( clock%clockint%CurrTime, &
933 clock%clockint%TimeStep )
934 positive_timestep = ESMF_TimeIntervalIsPositive( clock%clockint%TimeStep )
936 IF ( Present(NumRingingAlarms) ) NumRingingAlarms = 0
937 clock%clockint%AdvanceCount = clock%clockint%AdvanceCount + 1
939 alarm = clock%clockint%AlarmList(i)
940 ! TBH: This is really dangerous. We need to be able to NULLIFY
941 ! TBH: alarmint at compile-time (F95 synax) to make this safe.
942 !$$$TBH: see if F95 compile-time pointer-nullification is supported by all
943 !$$$TBH: compilers we support
944 IF ( ASSOCIATED( alarm%alarmint ) ) THEN
945 IF ( alarm%alarmint%Enabled ) THEN
946 IF ( alarm%alarmint%RingIntervalSet ) THEN
947 pred1 = .FALSE. ; pred2 = .FALSE. ; pred3 = .FALSE.
948 ! alarm cannot ring if clock has passed the alarms stop time
949 IF ( alarm%alarmint%StopTimeSet ) THEN
950 IF ( positive_timestep ) THEN
951 ! hack for bug in PGI 5.1-x
952 ! PRED1 = clock%clockint%CurrTime > alarm%alarmint%StopTime
953 PRED1 = ESMF_TimeGT( clock%clockint%CurrTime, &
954 alarm%alarmint%StopTime )
956 ! in this case time step is negative and stop time is
957 ! less than start time
958 ! PRED1 = clock%clockint%CurrTime < alarm%alarmint%StopTime
959 PRED1 = ESMF_TimeLT( clock%clockint%CurrTime, &
960 alarm%alarmint%StopTime )
963 ! one-shot alarm: check for ring time
964 ! TBH: Need to remove duplicated code. Need to enforce only one of
965 ! TBH: alarm%alarmint%RingTimeSet or alarm%alarmint%RingIntervalSet ever
966 ! TBH: being .TRUE. and simplify the logic. Also, the simpler
967 ! TBH: implementation in the duplicated code below should be sufficient.
968 IF ( alarm%alarmint%RingTimeSet ) THEN
969 IF ( positive_timestep ) THEN
970 ! hack for bug in PGI 5.1-x
971 ! PRED2 = ( alarm%alarmint%RingTime <= clock%clockint%CurrTime &
972 ! .AND. clock%clockint%CurrTime < alarm%alarmint%RingTime + &
973 ! clock%clockint%TimeStep )
974 PRED2 = ( ESMF_TimeLE( alarm%alarmint%RingTime, &
975 clock%clockint%CurrTime ) &
976 .AND. ESMF_TimeLT( clock%clockint%CurrTime, &
977 ESMF_TimeInc( alarm%alarmint%RingTime, &
978 clock%clockint%TimeStep ) ) )
980 ! in this case time step is negative and stop time is
981 ! less than start time
982 ! hack for bug in PGI 5.1-x
983 ! PRED2 = ( alarm%alarmint%RingTime >= clock%clockint%CurrTime &
984 ! .AND. clock%clockint%CurrTime > alarm%alarmint%RingTime + &
985 ! clock%clockint%TimeStep )
986 PRED2 = ( ESMF_TimeGE( alarm%alarmint%RingTime, &
987 clock%clockint%CurrTime ) &
988 .AND. ESMF_TimeGT( clock%clockint%CurrTime, &
989 ESMF_TimeInc( alarm%alarmint%RingTime, &
990 clock%clockint%TimeStep ) ) )
993 ! repeating alarm: check for ring interval
994 IF ( alarm%alarmint%RingIntervalSet ) THEN
995 IF ( positive_timestep ) THEN
996 ! hack for bug in PGI 5.1-x
997 ! PRED3 = ( alarm%alarmint%PrevRingTime + alarm%alarmint%RingInterval <= &
998 ! clock%clockint%CurrTime )
1000 PRED3 = ( ESMF_TimeLE( ESMF_TimeInc( &
1001 alarm%alarmint%PrevRingTime, &
1002 alarm%alarmint%RingInterval ), &
1003 clock%clockint%CurrTime ) )
1005 ! in this case time step is negative and stop time is
1006 ! less than start time
1007 ! ring interval must always be positive
1008 ! hack for bug in PGI 5.1-x
1009 ! PRED3 = ( alarm%alarmint%PrevRingTime - alarm%alarmint%RingInterval >= &
1010 ! clock%clockint%CurrTime )
1012 PRED3 = ( ESMF_TimeGE( ESMF_TimeDec( &
1013 alarm%alarmint%PrevRingTime, &
1014 alarm%alarmint%RingInterval ), &
1015 clock%clockint%CurrTime ) )
1018 IF ( ( .NOT. ( pred1 ) ) .AND. &
1019 ( ( pred2 ) .OR. ( pred3 ) ) ) THEN
1020 alarm%alarmint%Ringing = .TRUE.
1021 IF ( positive_timestep ) THEN
1022 ! hack for bug in PGI 5.1-x
1023 ! IF ( PRED3) alarm%alarmint%PrevRingTime = alarm%alarmint%PrevRingTime + &
1024 ! alarm%alarmint%RingInterval
1026 alarm%alarmint%PrevRingTime = &
1027 ESMF_TimeInc( alarm%alarmint%PrevRingTime, &
1028 alarm%alarmint%RingInterval )
1030 ! in this case time step is negative and stop time is
1031 ! less than start time
1032 ! ring interval must always be positive
1033 ! hack for bug in PGI 5.1-x
1034 ! IF ( PRED3) alarm%alarmint%PrevRingTime = alarm%alarmint%PrevRingTime - &
1035 ! alarm%alarmint%RingInterval
1037 alarm%alarmint%PrevRingTime = &
1038 ESMF_TimeDec( alarm%alarmint%PrevRingTime, &
1039 alarm%alarmint%RingInterval )
1041 IF ( PRESENT( RingingAlarmList ) .AND. &
1042 PRESENT ( NumRingingAlarms ) ) THEN
1043 NumRingingAlarms = NumRingingAlarms + 1
1044 RingingAlarmList( NumRingingAlarms ) = alarm
1047 ELSE IF ( alarm%alarmint%RingTimeSet ) THEN
1048 ! TBH: Need to remove duplicated code. Need to enforce only one of
1049 ! TBH: alarm%alarmint%RingTimeSet or alarm%alarmint%RingIntervalSet ever
1050 ! TBH: being .TRUE. and simplify the logic. Also, the simpler
1051 ! TBH: implementation in here should be sufficient.
1052 IF ( positive_timestep ) THEN
1053 ! hack for bug in PGI 5.1-x
1054 ! IF ( alarm%alarmint%RingTime <= clock%clockint%CurrTime ) THEN
1055 IF ( ESMF_TimeLE( alarm%alarmint%RingTime, &
1056 clock%clockint%CurrTime ) ) THEN
1057 alarm%alarmint%Ringing = .TRUE.
1058 IF ( PRESENT( RingingAlarmList ) .AND. &
1059 PRESENT ( NumRingingAlarms ) ) THEN
1060 NumRingingAlarms = NumRingingAlarms + 1
1061 RingingAlarmList( NumRingingAlarms ) = alarm
1065 ! in this case time step is negative and stop time is
1066 ! less than start time
1067 ! hack for bug in PGI 5.1-x
1068 ! IF ( alarm%alarmint%RingTime >= clock%clockint%CurrTime ) THEN
1069 IF ( ESMF_TimeGE( alarm%alarmint%RingTime, &
1070 clock%clockint%CurrTime ) ) THEN
1071 alarm%alarmint%Ringing = .TRUE.
1072 IF ( PRESENT( RingingAlarmList ) .AND. &
1073 PRESENT ( NumRingingAlarms ) ) THEN
1074 NumRingingAlarms = NumRingingAlarms + 1
1075 RingingAlarmList( NumRingingAlarms ) = alarm
1080 IF ( alarm%alarmint%StopTimeSet ) THEN
1081 ! TBH: what is this for???
1085 clock%clockint%AlarmList(i) = alarm
1087 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
1089 end subroutine ESMF_ClockAdvance
1091 !------------------------------------------------------------------------------
1093 ! !IROUTINE: ESMF_ClockStopTimeDisable - NOOP for compatibility with ESMF 2.1.0+
1096 subroutine ESMF_ClockStopTimeDisable(clock, rc)
1099 type(ESMF_Clock), intent(in) :: clock
1100 integer, intent(out), optional :: rc
1104 end subroutine ESMF_ClockStopTimeDisable
1106 !------------------------------------------------------------------------------
1108 ! !IROUTINE: ESMF_ClockIsStopTime - Has the clock reached its stop time ?
1111 function ESMF_ClockIsStopTime(clock, rc)
1114 logical :: ESMF_ClockIsStopTime
1117 type(ESMF_Clock), intent(in) :: clock
1118 integer, intent(out), optional :: rc
1119 logical :: positive_timestep
1122 ! Return true if {\tt ESMF\_Clock} has reached its stop time, false
1125 ! The arguments are:
1126 ! \begin{description}
1128 ! The object instance to check
1130 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1137 positive_timestep = ESMF_TimeIntervalIsPositive( clock%clockint%TimeStep )
1138 IF ( positive_timestep ) THEN
1139 ! hack for bug in PGI 5.1-x
1140 ! if ( clock%clockint%CurrTime .GE. clock%clockint%StopTime ) THEN
1141 if ( ESMF_TimeGE( clock%clockint%CurrTime, &
1142 clock%clockint%StopTime ) ) THEN
1143 ESMF_ClockIsStopTime = .TRUE.
1145 ESMF_ClockIsStopTime = .FALSE.
1148 ! hack for bug in PGI 5.1-x
1149 ! if ( clock%clockint%CurrTime .LE. clock%clockint%StopTime ) THEN
1150 if ( ESMF_TimeLE( clock%clockint%CurrTime, &
1151 clock%clockint%StopTime ) ) THEN
1152 ESMF_ClockIsStopTime = .TRUE.
1154 ESMF_ClockIsStopTime = .FALSE.
1157 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
1159 end function ESMF_ClockIsStopTime
1161 !------------------------------------------------------------------------------
1163 ! This section defines the overridden Read, Write, Validate and Print methods
1164 ! from the ESMF_Base class
1166 !------------------------------------------------------------------------------
1168 ! !IROUTINE: ESMF_ClockRead - Restores a clock
1171 subroutine ESMF_ClockRead(clock, TimeStep, StartTime, StopTime, &
1172 RefTime, CurrTime, PrevTime, AdvanceCount, &
1176 type(ESMF_Clock), intent(out) :: clock
1177 type(ESMF_TimeInterval), intent(in) :: TimeStep
1178 type(ESMF_Time), intent(in) :: StartTime
1179 type(ESMF_Time), intent(in) :: StopTime
1180 type(ESMF_Time), intent(in) :: RefTime
1181 type(ESMF_Time), intent(in) :: CurrTime
1182 type(ESMF_Time), intent(in) :: PrevTime
1183 integer(ESMF_KIND_I8), intent(in) :: AdvanceCount
1184 type(ESMF_Alarm), dimension(MAX_ALARMS), intent(in) :: AlarmList
1185 integer, intent(out), optional :: rc
1188 ! Restore an {\tt ESMF\_Clock}
1190 ! The arguments are:
1191 ! \begin{description}
1193 ! The object instance to restore
1195 ! The {\tt ESMF\_Clock}'s time step interval
1197 ! The {\tt ESMF\_Clock}'s starting time
1199 ! The {\tt ESMF\_Clock}'s stopping time
1201 ! The {\tt ESMF\_Clock}'s reference time
1203 ! The {\tt ESMF\_Clock}'s current time
1205 ! The {\tt ESMF\_Clock}'s previous time
1206 ! \item[AdvanceCount]
1207 ! The number of times the {\tt ESMF\_Clock} has been advanced
1209 ! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
1211 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1216 CALL wrf_error_fatal( 'ESMF_ClockRead not supported' )
1217 end subroutine ESMF_ClockRead
1219 !------------------------------------------------------------------------------
1221 ! !IROUTINE: ESMF_ClockWrite - Saves a clock
1224 subroutine ESMF_ClockWrite(clock, TimeStep, StartTime, StopTime, &
1225 RefTime, CurrTime, PrevTime, AdvanceCount, &
1229 type(ESMF_Clock), intent(in) :: clock
1230 type(ESMF_TimeInterval), intent(out) :: TimeStep
1231 type(ESMF_Time), intent(out) :: StartTime
1232 type(ESMF_Time), intent(out) :: StopTime
1233 type(ESMF_Time), intent(out) :: RefTime
1234 type(ESMF_Time), intent(out) :: CurrTime
1235 type(ESMF_Time), intent(out) :: PrevTime
1236 integer(ESMF_KIND_I8), intent(out) :: AdvanceCount
1237 type(ESMF_Alarm), dimension(MAX_ALARMS), intent(out) :: AlarmList
1238 integer, intent(out), optional :: rc
1241 ! Save an {\tt ESMF\_Clock}
1243 ! The arguments are:
1244 ! \begin{description}
1246 ! The object instance to save
1248 ! The {\tt ESMF\_Clock}'s time step interval
1250 ! The {\tt ESMF\_Clock}'s starting time
1252 ! The {\tt ESMF\_Clock}'s stopping time
1254 ! The {\tt ESMF\_Clock}'s reference time
1256 ! The {\tt ESMF\_Clock}'s current time
1258 ! The {\tt ESMF\_Clock}'s previous time
1259 ! \item[AdvanceCount]
1260 ! The number of times the {\tt ESMF\_Clock} has been advanced
1262 ! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
1264 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1269 CALL wrf_error_fatal( 'ESMF_ClockWrite not supported' )
1270 end subroutine ESMF_ClockWrite
1272 !------------------------------------------------------------------------------
1274 ! !IROUTINE: ESMF_ClockValidate - Validate a Clock's properties
1277 subroutine ESMF_ClockValidate(clock, opts, rc)
1280 type(ESMF_Clock), intent(in) :: clock
1281 character (len=*), intent(in), optional :: opts
1282 integer, intent(out), optional :: rc
1285 ! Perform a validation check on an {\tt ESMF\_Clock}'s properties
1287 ! The arguments are:
1288 ! \begin{description}
1290 ! {\tt ESMF\_Clock} to validate
1294 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1300 CALL wrf_error_fatal( 'ESMF_ClockValidate not supported' )
1301 end subroutine ESMF_ClockValidate
1303 !------------------------------------------------------------------------------
1305 ! !IROUTINE: ESMF_ClockPrint - Print out a Clock's properties
1308 subroutine ESMF_ClockPrint(clock, opts, rc)
1311 type(ESMF_Clock), intent(in) :: clock
1312 character (len=*), intent(in), optional :: opts
1313 integer, intent(out), optional :: rc
1316 ! To support testing/debugging, print out an {\tt ESMF\_Clock}'s
1319 ! The arguments are:
1320 ! \begin{description}
1322 ! {\tt ESMF\_Clock} to print out
1326 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1332 CALL wrf_error_fatal( 'ESMF_ClockPrint not supported' )
1333 end subroutine ESMF_ClockPrint
1335 !------------------------------------------------------------------------------
1337 end module ESMF_ClockMod