2 !==============================================================================
5 module WRF_ESMF_ClockMod
7 !==============================================================================
9 ! This file contains the Clock class definition and all Clock class methods.
11 !------------------------------------------------------------------------------
13 #include <ESMF_TimeMgr.inc>
15 !==============================================================================
17 ! !MODULE: WRF_ESMF_ClockMod
20 ! Part of Time Manager F90 API wrapper of C++ implemenation
22 ! Defines F90 wrapper entry points for corresponding
23 ! C++ class {\tt ESMC\_Time} implementation
25 ! See {\tt ../include/ESMC\_Clock.h} for complete description
27 !------------------------------------------------------------------------------
29 ! inherit from ESMF base class
32 ! associated derived types
33 use WRF_ESMF_TimeIntervalMod ! , only : ESMF_TimeInterval, &
34 ! ESMF_TimeIntervalIsPositive
35 use WRF_ESMF_TimeMod ! , only : ESMF_Time
36 use WRF_ESMF_AlarmMod, only : ESMF_Alarm
40 !------------------------------------------------------------------------------
43 !------------------------------------------------------------------------------
46 ! ! F90 class type to match C++ Clock class in size only;
47 ! ! all dereferencing within class is performed by C++ implementation
49 ! internals for ESMF_Clock
51 type(ESMF_TimeInterval) :: TimeStep
52 type(ESMF_Time) :: StartTime
53 type(ESMF_Time) :: StopTime
54 type(ESMF_Time) :: RefTime
55 type(ESMF_Time) :: CurrTime
56 type(ESMF_Time) :: PrevTime
57 integer(ESMF_KIND_I8) :: AdvanceCount
60 ! Note: to mimic ESMF 2.1.0+, AlarmList is maintained
61 ! within ESMF_Clock even though copies of each alarm are
62 ! returned from ESMF_AlarmCreate() at the same time they
63 ! are copied into the AlarmList! This duplication is not
64 ! as hideous as it might be because the ESMF_Alarm type
65 ! has data members that are all POINTERs (thus the horrible
66 ! shallow-copy-masquerading-as-reference-copy hack works).
67 type(ESMF_Alarm), pointer, dimension(:) :: AlarmList
70 ! Actual public type: this bit allows easy mimic of "deep" ESMF_ClockCreate
72 ! NOTE: DO NOT ADD NON-POINTER STATE TO THIS DATA TYPE. It emulates ESMF
73 ! shallow-copy-masquerading-as-reference-copy.
75 type(ESMF_ClockInt), pointer :: clockint
78 !------------------------------------------------------------------------------
81 public ESMF_ClockInt ! needed on AIX but not PGI
82 !------------------------------------------------------------------------------
84 ! !PUBLIC MEMBER FUNCTIONS:
85 public ESMF_ClockCreate
86 public ESMF_ClockDestroy
88 ! public ESMF_ClockSetOLD
90 ! public ESMF_ClockGetAdvanceCount
91 ! public ESMF_ClockGetTimeStep
92 ! public ESMF_ClockSetTimeStep
93 ! public ESMF_ClockGetCurrTime
94 ! public ESMF_ClockSetCurrTime
95 ! public ESMF_ClockGetStartTime
96 ! public ESMF_ClockGetStopTime
97 ! public ESMF_ClockGetRefTime
98 ! public ESMF_ClockGetPrevTime
99 ! public ESMF_ClockGetCurrSimTime
100 ! public ESMF_ClockGetPrevSimTime
101 ! This must be public for WRF_ESMF_AlarmClockMod...
102 public ESMF_ClockAddAlarm
103 public ESMF_ClockGetAlarmList
104 ! public ESMF_ClockGetNumAlarms
105 ! public ESMF_ClockSyncToWallClock
106 public ESMF_ClockAdvance
107 public ESMF_ClockIsStopTime
108 public ESMF_ClockStopTimeDisable
110 ! Required inherited and overridden ESMF_Base class methods
112 ! public ESMF_ClockRead
113 ! public ESMF_ClockWrite
114 public ESMF_ClockValidate
115 public ESMF_ClockPrint
118 !==============================================================================
122 !==============================================================================
124 ! This section includes the Set methods.
126 !------------------------------------------------------------------------------
128 ! !IROUTINE: ESMF_ClockSetOLD - Initialize a clockint
131 subroutine ESMF_ClockSetOLD(clockint, TimeStep, StartTime, &
132 StopTime, RefTime, rc)
135 type(ESMF_ClockInt), intent(out) :: clockint
136 type(ESMF_TimeInterval), intent(in), optional :: TimeStep
137 type(ESMF_Time), intent(in) :: StartTime
138 type(ESMF_Time), intent(in) :: StopTime
139 type(ESMF_Time), intent(in), optional :: RefTime
140 integer, intent(out), optional :: rc
145 ! Initialize an {\tt ESMF\_Clock}
148 ! \begin{description}
150 ! The object instance to initialize
151 ! \item[{[TimeStep]}]
152 ! The {\tt ESMF\_Clock}'s time step interval
154 ! The {\tt ESMF\_Clock}'s starting time
156 ! The {\tt ESMF\_Clock}'s stopping time
158 ! The {\tt ESMF\_Clock}'s reference time
160 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
166 IF ( PRESENT(TimeStep) ) clockint%TimeStep = TimeStep
167 IF ( PRESENT(RefTime) )THEN
168 clockint%RefTime = RefTime
170 clockint%RefTime = StartTime
172 clockint%CurrTime = StartTime
173 clockint%StartTime = StartTime
174 clockint%StopTime = StopTime
175 clockint%NumAlarms = 0
176 clockint%AdvanceCount = 0
177 ALLOCATE(clockint%AlarmList(MAX_ALARMS))
178 ! TBH: This incredible hack can be removed once ESMF_*Validate()
179 ! TBH: can tell if a deep ESMF_* was created or not.
181 NULLIFY( clockint%AlarmList( i )%alarmint )
183 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
185 end subroutine ESMF_ClockSetOLD
188 ! !IROUTINE: ESMF_ClockSet - Set clock properties -- for compatibility with ESMF 2.0.1
191 subroutine ESMF_ClockSet(clock, TimeStep, StartTime, StopTime, &
192 RefTime, CurrTime, rc)
195 type(ESMF_Clock), intent(inout) :: clock
196 type(ESMF_TimeInterval), intent(in), optional :: TimeStep
197 type(ESMF_Time), intent(in), optional :: StartTime
198 type(ESMF_Time), intent(in), optional :: StopTime
199 type(ESMF_Time), intent(in), optional :: RefTime
200 type(ESMF_Time), intent(in), optional :: CurrTime
201 integer, intent(out), optional :: rc
206 ! Initialize an {\tt ESMF\_Clock}
209 ! \begin{description}
211 ! The object instance to initialize
212 ! \item[{[TimeStep]}]
213 ! The {\tt ESMF\_Clock}'s time step interval
215 ! The {\tt ESMF\_Clock}'s starting time
217 ! The {\tt ESMF\_Clock}'s stopping time
219 ! The {\tt ESMF\_Clock}'s reference time
221 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
228 IF ( PRESENT(TimeStep) ) THEN
229 CALL ESMF_ClockSetTimeStep ( clock, TimeStep, rc=ierr )
231 IF ( PRESENT(RefTime) ) clock%clockint%RefTime = RefTime
232 IF ( PRESENT(StartTime) ) clock%clockint%StartTime = StartTime
233 IF ( PRESENT(StopTime) ) clock%clockint%StopTime = StopTime
234 IF ( PRESENT(CurrTime) ) THEN
235 CALL ESMF_ClockSetCurrTime(clock, CurrTime, rc=ierr)
237 IF ( PRESENT(rc) ) rc = ierr
239 end subroutine ESMF_ClockSet
242 ! Create ESMF_Clock using ESMF 2.1.0+ semantics
243 FUNCTION ESMF_ClockCreate( name, TimeStep, StartTime, StopTime, &
246 type(ESMF_Clock) :: ESMF_ClockCreate
248 character (len=*), intent(in), optional :: name
249 type(ESMF_TimeInterval), intent(in), optional :: TimeStep
250 type(ESMF_Time), intent(in) :: StartTime
251 type(ESMF_Time), intent(in) :: StopTime
252 type(ESMF_Time), intent(in), optional :: RefTime
253 integer, intent(out), optional :: rc
255 type(ESMF_Clock) :: clocktmp
256 ! TBH: ignore allocate errors, for now
257 ALLOCATE( clocktmp%clockint )
258 CALL ESMF_ClockSetOLD( clocktmp%clockint, &
259 TimeStep= TimeStep, &
260 StartTime=StartTime, &
261 StopTime= StopTime, &
262 RefTime=RefTime, rc=rc )
263 ESMF_ClockCreate = clocktmp
264 END FUNCTION ESMF_ClockCreate
267 ! Deallocate memory for ESMF_Clock
268 SUBROUTINE ESMF_ClockDestroy( clock, rc )
269 TYPE(ESMF_Clock), INTENT(INOUT) :: clock
270 INTEGER, INTENT( OUT), OPTIONAL :: rc
271 ! TBH: ignore deallocate errors, for now
272 DEALLOCATE( clock%clockint%AlarmList )
273 DEALLOCATE( clock%clockint )
274 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
275 END SUBROUTINE ESMF_ClockDestroy
278 !------------------------------------------------------------------------------
280 ! !IROUTINE: ESMF_ClockGet - Get clock properties -- for compatibility with ESMF 2.0.1
283 subroutine ESMF_ClockGet(clock, StartTime, CurrTime, &
284 AdvanceCount, StopTime, TimeStep, &
289 type(ESMF_Clock), intent(in) :: clock
290 type(ESMF_Time), intent(out), optional :: StartTime
291 type(ESMF_Time), intent(out), optional :: CurrTime
292 type(ESMF_Time), intent(out), optional :: StopTime
293 type(ESMF_Time), intent(out), optional :: PrevTime
294 type(ESMF_Time), intent(out), optional :: RefTime
295 integer(ESMF_KIND_I8), intent(out), optional :: AdvanceCount
296 type(ESMF_TimeInterval), intent(out), optional :: TimeStep
297 integer, intent(out), optional :: rc
301 ! Returns the number of times the {\tt ESMF\_Clock} has been advanced
305 ! \begin{description}
307 ! The object instance to get the advance count from
312 ! \item[AdvanceCount]
313 ! The number of times the {\tt ESMF\_Clock} has been advanced
315 ! The {\tt ESMF\_Clock}'s stopping time
316 ! \item[{[TimeStep]}]
317 ! The {\tt ESMF\_Clock}'s time step interval
318 ! \item[{[PrevTime]}]
319 ! The {\tt ESMF\_Clock}'s previous current time
320 ! \item[{[PrevTime]}]
321 ! The {\tt ESMF\_Clock}'s reference time
323 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
331 IF ( PRESENT (StartTime) ) THEN
332 CALL ESMF_ClockGetStartTime( clock, StartTime=StartTime, rc=ierr )
334 IF ( PRESENT (CurrTime) ) THEN
335 CALL ESMF_ClockGetCurrTime( clock , CurrTime, ierr )
337 IF ( PRESENT (StopTime) ) THEN
338 CALL ESMF_ClockGetStopTime( clock , StopTime, ierr )
340 IF ( PRESENT (AdvanceCount) ) THEN
341 CALL ESMF_ClockGetAdvanceCount(clock, AdvanceCount, ierr)
343 IF ( PRESENT (TimeStep) ) THEN
344 CALL ESMF_ClockGetTimeStep(clock, TimeStep, ierr)
346 IF ( PRESENT (PrevTime) ) THEN
347 CALL ESMF_ClockGetPrevTime(clock, PrevTime, ierr)
349 IF ( PRESENT (RefTime) ) THEN
350 CALL ESMF_ClockGetRefTime(clock, RefTime, ierr)
353 IF ( PRESENT (rc) ) THEN
357 end subroutine ESMF_ClockGet
360 ! !IROUTINE: ESMF_ClockGetAdvanceCount - Get the clock's advance count
363 subroutine ESMF_ClockGetAdvanceCount(clock, AdvanceCount, rc)
366 type(ESMF_Clock), intent(in) :: clock
367 integer(ESMF_KIND_I8), intent(out) :: AdvanceCount
368 integer, intent(out), optional :: rc
371 ! Returns the number of times the {\tt ESMF\_Clock} has been advanced
375 ! \begin{description}
377 ! The object instance to get the advance count from
378 ! \item[AdvanceCount]
379 ! The number of times the {\tt ESMF\_Clock} has been advanced
381 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
388 AdvanceCount = clock%clockint%AdvanceCount
390 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
392 end subroutine ESMF_ClockGetAdvanceCount
394 !------------------------------------------------------------------------------
396 ! !IROUTINE: ESMF_ClockGetTimeStep - Get a clock's timestep interval
399 subroutine ESMF_ClockGetTimeStep(clock, TimeStep, rc)
402 type(ESMF_Clock), intent(in) :: clock
403 type(ESMF_TimeInterval), intent(out) :: TimeStep
404 integer, intent(out), optional :: rc
407 ! Get an {\tt ESMF\_Clock}'s timestep interval
410 ! \begin{description}
412 ! The object instance to get the time step from
416 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
423 TimeStep = clock%clockint%TimeStep
424 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
426 end subroutine ESMF_ClockGetTimeStep
428 !------------------------------------------------------------------------------
430 ! !IROUTINE: ESMF_ClockSetTimeStep - Set a clock's timestep interval
433 subroutine ESMF_ClockSetTimeStep(clock, TimeStep, rc)
436 type(ESMF_Clock), intent(inout) :: clock ! really INTENT(OUT)
437 type(ESMF_TimeInterval), intent(in) :: TimeStep
438 integer, intent(out), optional :: rc
441 ! Set an {\tt ESMF\_Clock}'s timestep interval
444 ! \begin{description}
446 ! The object instance to set the time step
450 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
457 clock%clockint%TimeStep = TimeStep
458 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
460 end subroutine ESMF_ClockSetTimeStep
462 !------------------------------------------------------------------------------
464 ! !IROUTINE: ESMF_ClockGetCurrTime - Get a clock's current time
467 subroutine ESMF_ClockGetCurrTime(clock, CurrTime, rc)
470 type(ESMF_Clock), intent(in) :: clock
471 type(ESMF_Time), intent(out) :: CurrTime
472 integer, intent(out), optional :: rc
475 ! Get an {\tt ESMF\_Clock}'s current time
478 ! \begin{description}
480 ! The object instance to get the current time from
484 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
491 CurrTime = clock%clockint%CurrTime
492 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
493 end subroutine ESMF_ClockGetCurrTime
495 !------------------------------------------------------------------------------
497 ! !IROUTINE: ESMF_ClockSetCurrTime - Set a clock's current time
500 subroutine ESMF_ClockSetCurrTime(clock, CurrTime, rc)
503 type(ESMF_Clock), intent(inout) :: clock ! really INTENT(OUT)
504 type(ESMF_Time), intent(in) :: CurrTime
505 integer, intent(out), optional :: rc
508 ! Set an {\tt ESMF\_Clock}'s current time
511 ! \begin{description}
513 ! The object instance to set the current time from
517 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
524 clock%clockint%CurrTime = CurrTime
525 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
527 end subroutine ESMF_ClockSetCurrTime
529 !------------------------------------------------------------------------------
531 ! !IROUTINE: ESMF_ClockGetStartTime - Get a clock's start time
534 subroutine ESMF_ClockGetStartTime(clock, StartTime, rc)
537 type(ESMF_Clock), intent(in) :: clock
538 type(ESMF_Time), intent(out) :: StartTime
539 integer, intent(out), optional :: rc
542 ! Get an {\tt ESMF\_Clock}'s start time
545 ! \begin{description}
547 ! The object instance to get the start time from
551 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
558 StartTime = clock%clockint%StartTime
559 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
561 end subroutine ESMF_ClockGetStartTime
563 !------------------------------------------------------------------------------
565 ! !IROUTINE: ESMF_ClockGetStopTime - Get a clock's stop time
568 subroutine ESMF_ClockGetStopTime(clock, StopTime, rc)
571 type(ESMF_Clock), intent(in) :: clock
572 type(ESMF_Time), intent(out) :: StopTime
573 integer, intent(out), optional :: rc
576 ! Get an {\tt ESMF\_Clock}'s stop time
579 ! \begin{description}
581 ! The object instance to get the stop time from
585 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
592 StopTime = clock%clockint%StopTime
593 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
595 end subroutine ESMF_ClockGetStopTime
597 !------------------------------------------------------------------------------
599 ! !IROUTINE: ESMF_ClockGetRefTime - Get a clock's reference time
602 subroutine ESMF_ClockGetRefTime(clock, RefTime, rc)
605 type(ESMF_Clock), intent(in) :: clock
606 type(ESMF_Time), intent(out) :: RefTime
607 integer, intent(out), optional :: rc
610 ! Get an {\tt ESMF\_Clock}'s reference time
613 ! \begin{description}
615 ! The object instance to get the reference time from
619 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
625 refTime = clock%clockint%RefTime
626 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
627 end subroutine ESMF_ClockGetRefTime
629 !------------------------------------------------------------------------------
631 ! !IROUTINE: ESMF_ClockGetPrevTime - Get a clock's previous current time
634 subroutine ESMF_ClockGetPrevTime(clock, PrevTime, rc)
637 type(ESMF_Clock), intent(in) :: clock
638 type(ESMF_Time), intent(out) :: PrevTime
639 integer, intent(out), optional :: rc
642 ! Get an {\tt ESMF\_Clock}'s previous current time
645 ! \begin{description}
647 ! The object instance to get the previous current time from
649 ! The previous current time
651 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
658 ! hack for bug in PGI 5.1-x
659 ! prevTime = Clock%clockint%CurrTime - Clock%clockint%TimeStep
660 prevTime = ESMF_TimeDec( Clock%clockint%CurrTime, &
661 Clock%clockint%TimeStep )
663 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
664 end subroutine ESMF_ClockGetPrevTime
666 !------------------------------------------------------------------------------
668 ! !IROUTINE: ESMF_ClockGetCurrSimTime - Get a clock's current simulation time
671 subroutine ESMF_ClockGetCurrSimTime(clock, CurrSimTime, rc)
674 type(ESMF_Clock), intent(in) :: clock
675 type(ESMF_TimeInterval), intent(out) :: CurrSimTime
676 integer, intent(out), optional :: rc
679 ! Get an {\tt ESMF\_Clock}'s current simulation time
682 ! \begin{description}
684 ! The object instance to get the current simulation time from
686 ! The current simulation time
688 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
694 CALL wrf_error_fatal( 'ESMF_ClockGetCurrSimTime not supported' )
695 end subroutine ESMF_ClockGetCurrSimTime
697 !------------------------------------------------------------------------------
699 ! !IROUTINE: ESMF_ClockGetPrevSimTime - Get a clock's previous simulation time
702 subroutine ESMF_ClockGetPrevSimTime(clock, PrevSimTime, rc)
705 type(ESMF_Clock), intent(in) :: clock
706 type(ESMF_TimeInterval), intent(out) :: PrevSimTime
707 integer, intent(out), optional :: rc
710 ! Get an {\tt ESMF\_Clock}'s previous simulation time
713 ! \begin{description}
715 ! The object instance to get the previous simulation time from
717 ! The previous simulation time
719 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
725 CALL wrf_error_fatal( 'ESMF_ClockGetPrevSimTime not supported' )
726 end subroutine ESMF_ClockGetPrevSimTime
728 !------------------------------------------------------------------------------
730 ! !IROUTINE: ESMF_ClockAddAlarm - Add an alarm to a clock's alarm list
733 subroutine ESMF_ClockAddAlarm(clock, Alarm, rc)
736 type(ESMF_Clock), intent(inout) :: clock
737 type(ESMF_Alarm), intent(inout) :: Alarm
738 integer, intent(out), optional :: rc
741 ! Add an {\tt ESMF\_Alarm} to an {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
744 ! \begin{description}
746 ! The object instance to add an {\tt ESMF\_Alarm} to
748 ! The {\tt ESMF\_Alarm} to add to the {\tt ESMF\_Clock}'s
749 ! {\tt ESMF\_Alarm} list
751 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
758 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
759 clock%clockint%NumAlarms = clock%clockint%NumAlarms + 1
760 IF ( clock%clockint%NumAlarms > SIZE (clock%clockint%AlarmList) ) THEN
761 CALL wrf_error_fatal ( 'ESMF_ClockAddAlarm: too many alarms' )
762 ELSE IF ( .NOT. ASSOCIATED( Alarm%alarmint ) ) THEN
763 CALL wrf_error_fatal ( &
764 'ESMF_ClockAddAlarm: alarm not created' )
766 IF ( Alarm%alarmint%RingTimeSet ) THEN
767 Alarm%alarmint%PrevRingTime = Alarm%alarmint%RingTime
769 !TBH: This has the nasty side-effect of forcing us to explicitly turn on
770 !TBH: alarms that are created with RingInterval only, if we want them to start
771 !TBH: ringing right away. And this is done (see
772 !TBH: COMPUTE_VORTEX_CENTER_ALARM). Straighten this out...
773 Alarm%alarmint%PrevRingTime = clock%clockint%CurrTime
775 Alarm%alarmint%Ringing = .FALSE.
777 ! finally, load the alarm into the list
778 ! write(0,*)'ESMF_ClockAddAlarm ',clock%clockint%NumAlarms
779 clock%clockint%AlarmList(clock%clockint%NumAlarms) = Alarm
782 end subroutine ESMF_ClockAddAlarm
784 !------------------------------------------------------------------------------
786 ! !IROUTINE: ESMF_ClockGetAlarmList - Get a clock's alarm list
789 subroutine ESMF_ClockGetAlarmList(clock, AlarmList, rc)
792 type(ESMF_Clock), intent(in) :: clock
793 type(ESMF_Alarm), pointer :: AlarmList(:)
794 integer, intent(out), optional :: rc
797 ! Get an {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
800 ! \begin{description}
802 ! The object instance to get the {\tt ESMF\_Alarm} list from
804 ! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
806 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
813 AlarmList => clock%clockint%AlarmList
814 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
816 end subroutine ESMF_ClockGetAlarmList
818 !------------------------------------------------------------------------------
820 ! !IROUTINE: ESMF_ClockGetNumAlarms - Get the number of alarms in a clock's alarm list
823 subroutine ESMF_ClockGetNumAlarms(clock, NumAlarms, rc)
826 type(ESMF_Clock), intent(in) :: clock
827 integer, intent(out) :: NumAlarms
828 integer, intent(out), optional :: rc
831 ! Get the number of {\tt ESMF\_Alarm}s in an {\tt ESMF\_Clock}'s
832 ! {\tt ESMF\_Alarm} list
835 ! \begin{description}
837 ! The object instance to get the number of {\tt ESMF\_Alarm}s from
839 ! The number of {\tt ESMF\_Alarm}s in the {\tt ESMF\_Clock}'s
840 ! {\tt ESMF\_Alarm} list
842 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
849 NumAlarms = clock%clockint%NumAlarms
850 IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
852 end subroutine ESMF_ClockGetNumAlarms
854 !------------------------------------------------------------------------------
856 ! !IROUTINE: ESMF_ClockSyncToWallClock - Set clock's current time to wall clock time
859 subroutine ESMF_ClockSyncToWallClock(clock, rc)
862 type(ESMF_Clock), intent(inout) :: clock
863 integer, intent(out), optional :: rc
866 ! Set an {\tt ESMF\_Clock}'s current time to wall clock time
869 ! \begin{description}
871 ! The object instance to synchronize to wall clock time
873 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
879 CALL wrf_error_fatal( 'ESMF_ClockSyncToWallClock not supported' )
880 end subroutine ESMF_ClockSyncToWallClock
882 !------------------------------------------------------------------------------
884 ! !IROUTINE: ESMF_ClockAdvance - Advance a clock's current time by one time step
887 subroutine ESMF_ClockAdvance(clock, RingingAlarmList, &
888 NumRingingAlarms, rc)
893 type(ESMF_Clock), intent(inout) :: clock
894 type(ESMF_Alarm), dimension(MAX_ALARMS), intent(out), optional :: &
896 integer, intent(out), optional :: NumRingingAlarms
897 integer, intent(out), optional :: rc
899 logical pred1, pred2, pred3
901 type(ESMF_Alarm) :: alarm
902 logical :: positive_timestep
905 ! Advance an {\tt ESMF\_Clock}'s current time by one time step
908 ! \begin{description}
910 ! The object instance to advance
911 ! \item[{[RingingAlarmList]}]
912 ! Return a list of any ringing alarms after the time step
913 ! \item[{[NumRingingAlarms]}]
914 ! The number of ringing alarms returned
916 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
922 ! hack for bug in PGI 5.1-x
923 ! clock%clockint%CurrTime = clock%clockint%CurrTime + &
924 ! clock%clockint%TimeStep
925 clock%clockint%CurrTime = ESMF_TimeInc( clock%clockint%CurrTime, &
926 clock%clockint%TimeStep )
927 positive_timestep = ESMF_TimeIntervalIsPositive( clock%clockint%TimeStep )
929 IF ( Present(NumRingingAlarms) ) NumRingingAlarms = 0
930 clock%clockint%AdvanceCount = clock%clockint%AdvanceCount + 1
932 alarm = clock%clockint%AlarmList(i)
933 ! TBH: This is really dangerous. We need to be able to NULLIFY
934 ! TBH: alarmint at compile-time (F95 synax) to make this safe.
935 !$$$TBH: see if F95 compile-time pointer-nullification is supported by all
936 !$$$TBH: compilers we support
937 IF ( ASSOCIATED( alarm%alarmint ) ) THEN
938 IF ( alarm%alarmint%Enabled ) THEN
939 IF ( alarm%alarmint%RingIntervalSet ) THEN
940 pred1 = .FALSE. ; pred2 = .FALSE. ; pred3 = .FALSE.
941 ! alarm cannot ring if clock has passed the alarms stop time
942 IF ( alarm%alarmint%StopTimeSet ) THEN
943 IF ( positive_timestep ) THEN
944 ! hack for bug in PGI 5.1-x
945 ! PRED1 = clock%clockint%CurrTime > alarm%alarmint%StopTime
946 PRED1 = ESMF_TimeGT( clock%clockint%CurrTime, &
947 alarm%alarmint%StopTime )
949 ! in this case time step is negative and stop time is
950 ! less than start time
951 ! PRED1 = clock%clockint%CurrTime < alarm%alarmint%StopTime
952 PRED1 = ESMF_TimeLT( clock%clockint%CurrTime, &
953 alarm%alarmint%StopTime )
956 ! one-shot alarm: check for ring time
957 ! TBH: Need to remove duplicated code. Need to enforce only one of
958 ! TBH: alarm%alarmint%RingTimeSet or alarm%alarmint%RingIntervalSet ever
959 ! TBH: being .TRUE. and simplify the logic. Also, the simpler
960 ! TBH: implementation in the duplicated code below should be sufficient.
961 IF ( alarm%alarmint%RingTimeSet ) THEN
962 IF ( positive_timestep ) THEN
963 ! hack for bug in PGI 5.1-x
964 ! PRED2 = ( alarm%alarmint%RingTime <= clock%clockint%CurrTime &
965 ! .AND. clock%clockint%CurrTime < alarm%alarmint%RingTime + &
966 ! clock%clockint%TimeStep )
967 PRED2 = ( ESMF_TimeLE( alarm%alarmint%RingTime, &
968 clock%clockint%CurrTime ) &
969 .AND. ESMF_TimeLT( clock%clockint%CurrTime, &
970 ESMF_TimeInc( alarm%alarmint%RingTime, &
971 clock%clockint%TimeStep ) ) )
973 ! in this case time step is negative and stop time is
974 ! less than start time
975 ! hack for bug in PGI 5.1-x
976 ! PRED2 = ( alarm%alarmint%RingTime >= clock%clockint%CurrTime &
977 ! .AND. clock%clockint%CurrTime > alarm%alarmint%RingTime + &
978 ! clock%clockint%TimeStep )
979 PRED2 = ( ESMF_TimeGE( alarm%alarmint%RingTime, &
980 clock%clockint%CurrTime ) &
981 .AND. ESMF_TimeGT( clock%clockint%CurrTime, &
982 ESMF_TimeInc( alarm%alarmint%RingTime, &
983 clock%clockint%TimeStep ) ) )
986 ! repeating alarm: check for ring interval
987 IF ( alarm%alarmint%RingIntervalSet ) THEN
988 IF ( positive_timestep ) THEN
989 ! hack for bug in PGI 5.1-x
990 ! PRED3 = ( alarm%alarmint%PrevRingTime + alarm%alarmint%RingInterval <= &
991 ! clock%clockint%CurrTime )
993 PRED3 = ( ESMF_TimeLE( ESMF_TimeInc( &
994 alarm%alarmint%PrevRingTime, &
995 alarm%alarmint%RingInterval ), &
996 clock%clockint%CurrTime ) )
998 ! in this case time step is negative and stop time is
999 ! less than start time
1000 ! ring interval must always be positive
1001 ! hack for bug in PGI 5.1-x
1002 ! PRED3 = ( alarm%alarmint%PrevRingTime - alarm%alarmint%RingInterval >= &
1003 ! clock%clockint%CurrTime )
1005 PRED3 = ( ESMF_TimeGE( ESMF_TimeDec( &
1006 alarm%alarmint%PrevRingTime, &
1007 alarm%alarmint%RingInterval ), &
1008 clock%clockint%CurrTime ) )
1011 IF ( (.NOT. pred1) .AND. pred2 ) THEN
1012 alarm%alarmint%Ringing = .TRUE.
1013 alarm%alarmint%PrevRingTime = clock%clockint%CurrTime
1014 alarm%alarmint%RingTimeSet = .FALSE. !it is a one time alarm, it rang, now let it resort to interval
1015 IF ( PRESENT( RingingAlarmList ) .AND. &
1016 PRESENT ( NumRingingAlarms ) ) THEN
1017 NumRingingAlarms = NumRingingAlarms + 1
1018 RingingAlarmList( NumRingingAlarms ) = alarm
1020 ELSE IF ( (.NOT. pred1) .AND. pred3 ) THEN
1021 alarm%alarmint%Ringing = .TRUE.
1022 IF ( positive_timestep ) THEN
1023 ! hack for bug in PGI 5.1-x
1024 ! IF ( PRED3) alarm%alarmint%PrevRingTime = alarm%alarmint%PrevRingTime + &
1025 ! alarm%alarmint%RingInterval
1027 alarm%alarmint%PrevRingTime = &
1028 ESMF_TimeInc( alarm%alarmint%PrevRingTime, &
1029 alarm%alarmint%RingInterval )
1031 ! in this case time step is negative and stop time is
1032 ! less than start time
1033 ! ring interval must always be positive
1034 ! hack for bug in PGI 5.1-x
1035 ! IF ( PRED3) alarm%alarmint%PrevRingTime = alarm%alarmint%PrevRingTime - &
1036 ! alarm%alarmint%RingInterval
1038 alarm%alarmint%PrevRingTime = &
1039 ESMF_TimeDec( alarm%alarmint%PrevRingTime, &
1040 alarm%alarmint%RingInterval )
1042 IF ( PRESENT( RingingAlarmList ) .AND. &
1043 PRESENT ( NumRingingAlarms ) ) THEN
1044 NumRingingAlarms = NumRingingAlarms + 1
1045 RingingAlarmList( NumRingingAlarms ) = alarm
1048 ELSE IF ( alarm%alarmint%RingTimeSet ) THEN
1049 ! TBH: Need to remove duplicated code. Need to enforce only one of
1050 ! TBH: alarm%alarmint%RingTimeSet or alarm%alarmint%RingIntervalSet ever
1051 ! TBH: being .TRUE. and simplify the logic. Also, the simpler
1052 ! TBH: implementation in here should be sufficient.
1053 IF ( positive_timestep ) THEN
1054 ! hack for bug in PGI 5.1-x
1055 ! IF ( alarm%alarmint%RingTime <= clock%clockint%CurrTime ) THEN
1056 IF ( ESMF_TimeLE( alarm%alarmint%RingTime, &
1057 clock%clockint%CurrTime ) ) THEN
1058 alarm%alarmint%RingTimeSet = .FALSE. !it is a one time alarm, it rang, now let it resort to interval
1059 alarm%alarmint%Ringing = .TRUE.
1060 alarm%alarmint%PrevRingTime = clock%clockint%CurrTime
1061 IF ( PRESENT( RingingAlarmList ) .AND. &
1062 PRESENT ( NumRingingAlarms ) ) THEN
1063 NumRingingAlarms = NumRingingAlarms + 1
1064 RingingAlarmList( NumRingingAlarms ) = alarm
1068 ! in this case time step is negative and stop time is
1069 ! less than start time
1070 ! hack for bug in PGI 5.1-x
1071 ! IF ( alarm%alarmint%RingTime >= clock%clockint%CurrTime ) THEN
1072 IF ( ESMF_TimeGE( alarm%alarmint%RingTime, &
1073 clock%clockint%CurrTime ) ) THEN
1074 alarm%alarmint%RingTimeSet = .FALSE. !it is a one time alarm, it rang, now let it resort to interval
1075 alarm%alarmint%Ringing = .TRUE.
1076 alarm%alarmint%PrevRingTime = clock%clockint%CurrTime
1077 IF ( PRESENT( RingingAlarmList ) .AND. &
1078 PRESENT ( NumRingingAlarms ) ) THEN
1079 NumRingingAlarms = NumRingingAlarms + 1
1080 RingingAlarmList( NumRingingAlarms ) = alarm
1085 IF ( alarm%alarmint%StopTimeSet ) THEN
1086 ! TBH: what is this for???
1090 clock%clockint%AlarmList(i) = alarm
1092 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
1094 end subroutine ESMF_ClockAdvance
1096 !------------------------------------------------------------------------------
1098 ! !IROUTINE: ESMF_ClockStopTimeDisable - NOOP for compatibility with ESMF 2.1.0+
1101 subroutine ESMF_ClockStopTimeDisable(clock, rc)
1104 type(ESMF_Clock), intent(in) :: clock
1105 integer, intent(out), optional :: rc
1109 end subroutine ESMF_ClockStopTimeDisable
1111 !------------------------------------------------------------------------------
1113 ! !IROUTINE: ESMF_ClockIsStopTime - Has the clock reached its stop time ?
1116 function ESMF_ClockIsStopTime(clock, rc)
1119 logical :: ESMF_ClockIsStopTime
1122 type(ESMF_Clock), intent(in) :: clock
1123 integer, intent(out), optional :: rc
1124 logical :: positive_timestep
1127 ! Return true if {\tt ESMF\_Clock} has reached its stop time, false
1130 ! The arguments are:
1131 ! \begin{description}
1133 ! The object instance to check
1135 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1142 positive_timestep = ESMF_TimeIntervalIsPositive( clock%clockint%TimeStep )
1143 IF ( positive_timestep ) THEN
1144 ! hack for bug in PGI 5.1-x
1145 ! if ( clock%clockint%CurrTime .GE. clock%clockint%StopTime ) THEN
1146 if ( ESMF_TimeGE( clock%clockint%CurrTime, &
1147 clock%clockint%StopTime ) ) THEN
1148 ESMF_ClockIsStopTime = .TRUE.
1150 ESMF_ClockIsStopTime = .FALSE.
1153 ! hack for bug in PGI 5.1-x
1154 ! if ( clock%clockint%CurrTime .LE. clock%clockint%StopTime ) THEN
1155 if ( ESMF_TimeLE( clock%clockint%CurrTime, &
1156 clock%clockint%StopTime ) ) THEN
1157 ESMF_ClockIsStopTime = .TRUE.
1159 ESMF_ClockIsStopTime = .FALSE.
1162 IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
1164 end function ESMF_ClockIsStopTime
1166 !------------------------------------------------------------------------------
1168 ! This section defines the overridden Read, Write, Validate and Print methods
1169 ! from the ESMF_Base class
1171 !------------------------------------------------------------------------------
1173 ! !IROUTINE: ESMF_ClockRead - Restores a clock
1176 subroutine ESMF_ClockRead(clock, TimeStep, StartTime, StopTime, &
1177 RefTime, CurrTime, PrevTime, AdvanceCount, &
1181 type(ESMF_Clock), intent(out) :: clock
1182 type(ESMF_TimeInterval), intent(in) :: TimeStep
1183 type(ESMF_Time), intent(in) :: StartTime
1184 type(ESMF_Time), intent(in) :: StopTime
1185 type(ESMF_Time), intent(in) :: RefTime
1186 type(ESMF_Time), intent(in) :: CurrTime
1187 type(ESMF_Time), intent(in) :: PrevTime
1188 integer(ESMF_KIND_I8), intent(in) :: AdvanceCount
1189 type(ESMF_Alarm), dimension(MAX_ALARMS), intent(in) :: AlarmList
1190 integer, intent(out), optional :: rc
1193 ! Restore an {\tt ESMF\_Clock}
1195 ! The arguments are:
1196 ! \begin{description}
1198 ! The object instance to restore
1200 ! The {\tt ESMF\_Clock}'s time step interval
1202 ! The {\tt ESMF\_Clock}'s starting time
1204 ! The {\tt ESMF\_Clock}'s stopping time
1206 ! The {\tt ESMF\_Clock}'s reference time
1208 ! The {\tt ESMF\_Clock}'s current time
1210 ! The {\tt ESMF\_Clock}'s previous time
1211 ! \item[AdvanceCount]
1212 ! The number of times the {\tt ESMF\_Clock} has been advanced
1214 ! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
1216 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1221 CALL wrf_error_fatal( 'ESMF_ClockRead not supported' )
1222 end subroutine ESMF_ClockRead
1224 !------------------------------------------------------------------------------
1226 ! !IROUTINE: ESMF_ClockWrite - Saves a clock
1229 subroutine ESMF_ClockWrite(clock, TimeStep, StartTime, StopTime, &
1230 RefTime, CurrTime, PrevTime, AdvanceCount, &
1234 type(ESMF_Clock), intent(in) :: clock
1235 type(ESMF_TimeInterval), intent(out) :: TimeStep
1236 type(ESMF_Time), intent(out) :: StartTime
1237 type(ESMF_Time), intent(out) :: StopTime
1238 type(ESMF_Time), intent(out) :: RefTime
1239 type(ESMF_Time), intent(out) :: CurrTime
1240 type(ESMF_Time), intent(out) :: PrevTime
1241 integer(ESMF_KIND_I8), intent(out) :: AdvanceCount
1242 type(ESMF_Alarm), dimension(MAX_ALARMS), intent(out) :: AlarmList
1243 integer, intent(out), optional :: rc
1246 ! Save an {\tt ESMF\_Clock}
1248 ! The arguments are:
1249 ! \begin{description}
1251 ! The object instance to save
1253 ! The {\tt ESMF\_Clock}'s time step interval
1255 ! The {\tt ESMF\_Clock}'s starting time
1257 ! The {\tt ESMF\_Clock}'s stopping time
1259 ! The {\tt ESMF\_Clock}'s reference time
1261 ! The {\tt ESMF\_Clock}'s current time
1263 ! The {\tt ESMF\_Clock}'s previous time
1264 ! \item[AdvanceCount]
1265 ! The number of times the {\tt ESMF\_Clock} has been advanced
1267 ! The {\tt ESMF\_Clock}'s {\tt ESMF\_Alarm} list
1269 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1274 CALL wrf_error_fatal( 'ESMF_ClockWrite not supported' )
1275 end subroutine ESMF_ClockWrite
1277 !------------------------------------------------------------------------------
1279 ! !IROUTINE: ESMF_ClockValidate - Validate a Clock's properties
1282 subroutine ESMF_ClockValidate(clock, opts, rc)
1285 type(ESMF_Clock), intent(in) :: clock
1286 character (len=*), intent(in), optional :: opts
1287 integer, intent(out), optional :: rc
1290 ! Perform a validation check on an {\tt ESMF\_Clock}'s properties
1292 ! The arguments are:
1293 ! \begin{description}
1295 ! {\tt ESMF\_Clock} to validate
1299 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1305 CALL wrf_error_fatal( 'ESMF_ClockValidate not supported' )
1306 end subroutine ESMF_ClockValidate
1308 !------------------------------------------------------------------------------
1310 ! !IROUTINE: ESMF_ClockPrint - Print out a Clock's properties
1313 subroutine ESMF_ClockPrint(clock, opts, rc)
1316 type(ESMF_Clock), intent(in) :: clock
1317 character (len=*), intent(in), optional :: opts
1318 integer, intent(out), optional :: rc
1321 ! To support testing/debugging, print out an {\tt ESMF\_Clock}'s
1324 ! The arguments are:
1325 ! \begin{description}
1327 ! {\tt ESMF\_Clock} to print out
1331 ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
1337 CALL wrf_error_fatal( 'ESMF_ClockPrint not supported' )
1338 end subroutine ESMF_ClockPrint
1340 !------------------------------------------------------------------------------
1342 end module WRF_ESMF_ClockMod