Skip to content

Commit f6039c4

Browse files
committed
Provide consistency in setting of prevRingTime for alarms when changing ref time
This commit aims to provide consistency in the ringing behavior of alarms after a call to mpas_adjust_alarm_to_reference_time to alter the reference time for a recurring alarm. For simplicity of discussion, consider only a clock that is running forward in time. The objective of the mpas_adjust_alarm_to_reference_time routine is to set the prevRingTime (previous ring time) of a recurring alarm to (1) a time that differs from the specified reference time by an integer multiple of the alarm interval; and (2) the latest such time that is not after the current time on the clock. Prior to this commit, the logic in the mpas_adjust_alarm_to_reference_time routine resulted in one of two outcomes: (1) If the difference between the reference time and the current time is divisible by the alarm interval, the prevRingTime becomes the current time, as illustrated below. ring ring ring ring v v v v ----------------------------------------------------------- ^ now prevRingTime (2) Otherwise, the prevRingTime becomes the latest time before the current time that lies on an integer multiple of the alarm interval away from the reference time, as illustrated below. ring ring ring ring v v v v ----------------------------------------------------------- ^ ^ prevRingTime now To determine whether a recurring alarm is ringing, the alarm's interval is added to the alarm's prevRingTime. If the result is on or before the current time, the alarm is ringing; otherwise, if the result is later than the current time, the alarm is not ringing. As a consequence, outcome (1) from the mpas_adjust_alarm_to_reference_time leads to an alarm that is ringing after the call to the routine, while outcome(2) leads to an alarm that is not yet ringing. In order to rectify the inconsistency in whether an alarm is ringing depending on where its reference time is set relative to the current time, the prevRingTime for an alarm is always set to be at least one full alarm interval before the current time. Whether the difference between the current time and the reference time is evenly divisible by the alarm's ring interval or not, a query of the alarm's status immediately following the call to mpas_adjust_alarm_to_reference_time will always show that it is ringing. This commit makes changes to the logic for both a forward and a backward running clock in the mpas_adjust_alarm_to_reference_time routine, although it appears that no code actually makes use of a backward running clock at present. Note: At present, the logic is not quite as elegant as one might expect it should be. In future, if the interval_division routine handled negative intervals like the analog of (-2.75 % 1.0) => 0.25 then there may be no need for if-tests within blocks for each clock direction.
1 parent 3da684e commit f6039c4

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

src/framework/mpas_timekeeping.F

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,13 +1000,17 @@ subroutine mpas_adjust_alarm_to_reference_time(clock, alarmID, referenceTime, ie
10001000
! Local variables
10011001
type (MPAS_Alarm_type), pointer :: alarmPtr
10021002
type (MPAS_TimeInterval_type) :: searchInterval, searchRemainder
1003+
type (MPAS_TimeInterval_type) :: zeroInterval
10031004
integer (kind=I8KIND) :: nDivs
10041005
integer :: threadNum
10051006
integer :: ierr_tmp
10061007

1008+
10071009
ierr = 0
10081010
ierr_tmp = 0
10091011

1012+
call mpas_set_timeInterval(zeroInterval, S=0)
1013+
10101014
threadNum = mpas_threading_get_thread_num()
10111015

10121016
if ( threadNum == 0 ) then
@@ -1023,22 +1027,26 @@ subroutine mpas_adjust_alarm_to_reference_time(clock, alarmID, referenceTime, ie
10231027
if (now > referenceTime) then
10241028
searchInterval = now - referenceTime
10251029
call mpas_interval_division(referenceTime, searchInterval, alarmPtr % ringTimeInterval, nDivs, searchRemainder)
1026-
alarmPtr % prevRingTime = now - searchRemainder
10271030
else
10281031
searchInterval = referenceTime - now
10291032
call mpas_interval_division(referenceTime, searchInterval, alarmPtr % ringTimeInterval, nDivs, searchRemainder)
1030-
alarmPtr % prevRingTime = now - (alarmPtr % ringTimeInterval - searchRemainder)
1033+
if (searchRemainder /= zeroInterval) then
1034+
searchRemainder = alarmPtr % ringTimeInterval - searchRemainder
1035+
end if
10311036
endif
1032-
else ! MPAS_REVERSE
1037+
alarmPtr % prevRingTime = now - alarmPtr % ringTimeInterval - searchRemainder
1038+
else ! MPAS_BACKWARD
10331039
if (now < referenceTime) then
1034-
searchInterval = now - referenceTime
1040+
searchInterval = referenceTime - now
10351041
call mpas_interval_division(referenceTime, searchInterval, alarmPtr % ringTimeInterval, nDivs, searchRemainder)
1036-
alarmPtr % prevRingTime = now - searchRemainder
10371042
else
1038-
searchInterval = referenceTime - now
1043+
searchInterval = now - referenceTime
10391044
call mpas_interval_division(referenceTime, searchInterval, alarmPtr % ringTimeInterval, nDivs, searchRemainder)
1040-
alarmPtr % prevRingTime = now - (alarmPtr % ringTimeInterval - searchRemainder)
1045+
if (searchRemainder /= zeroInterval) then
1046+
searchRemainder = alarmPtr % ringTimeInterval - searchRemainder
1047+
end if
10411048
endif
1049+
alarmPtr % prevRingTime = now + alarmPtr % ringTimeInterval + searchRemainder
10421050
end if ! forward direction
10431051
!call mpas_print_alarm(clock, alarmID, ierr_tmp)
10441052
end if ! isRecurring

0 commit comments

Comments
 (0)