Setup an alarm in a clock. The ringtime sent to AlarmCreate MUST be the next alarm time. If you send an arbitrary but proper ringtime from the past and the ring interval, the alarm will always go off on the next clock advance and this will cause serious problems. Even if it makes sense to initialize an alarm with some reference time and the alarm interval, that reference time has to be advance forward to be >= the current time. In the logic below we set an appropriate "NextAlarm" and then we make sure to advance it properly based on the ring interval.
69 type(ESMF_Clock) ,
intent(inout) :: clock
70 type(ESMF_Alarm) ,
intent(inout) :: alarm
71 character(len=*) ,
intent(in) :: option
72 integer ,
optional ,
intent(in) :: opt_n
73 integer ,
optional ,
intent(in) :: opt_ymd
74 integer ,
optional ,
intent(in) :: opt_tod
75 type(ESMF_Time) ,
optional ,
intent(in) :: RefTime
76 character(len=*) ,
optional ,
intent(in) :: alarmname
77 integer ,
intent(inout) :: rc
80 type(ESMF_Calendar) :: cal
83 integer :: cyy,cmm,cdd,csec
84 integer :: nyy,nmm,ndd,nsec
85 character(len=64) :: lalarmname
86 logical :: update_nextalarm
87 type(ESMF_Time) :: CurrTime
88 type(ESMF_Time) :: NextAlarm
89 type(ESMF_TimeInterval) :: AlarmInterval
90 character(len=*),
parameter :: subname =
'(AlarmInit): '
95 lalarmname =
'alarm_unknown'
96 if (
present(alarmname)) lalarmname = trim(alarmname)
98 if (
present(opt_tod)) ltod = opt_tod
100 if (
present(opt_ymd)) lymd = opt_ymd
103 if (trim(option) == optnsteps .or. trim(option) == optnstep .or. &
104 trim(option) == optnseconds .or. trim(option) == optnsecond .or. &
105 trim(option) == optnminutes .or. trim(option) == optnminute .or. &
106 trim(option) == optnhours .or. trim(option) == optnhour .or. &
107 trim(option) == optndays .or. trim(option) == optnday .or. &
108 trim(option) == optnmonths .or. trim(option) == optnmonth .or. &
109 trim(option) == optnyears .or. trim(option) == optnyear .or. &
110 trim(option) == optifdays0)
then
111 if (.not.
present(opt_n))
then
112 call esmf_logseterror(esmf_rc_arg_bad, &
113 msg=subname//trim(option)//
' requires opt_n', &
115 file=__file__, rctoreturn=rc)
119 call esmf_logseterror(esmf_rc_arg_bad, &
120 msg=subname//trim(option)//
' invalid opt_n', &
122 file=__file__, rctoreturn=rc)
127 call esmf_clockget(clock, currtime=currtime, rc=rc)
128 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
133 call esmf_timeget(currtime, yy=cyy, mm=cmm, dd=cdd, s=csec, rc=rc )
134 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
139 call esmf_timeget(currtime, yy=nyy, mm=nmm, dd=ndd, s=nsec, rc=rc )
140 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
146 if (
present(reftime))
then
153 call esmf_clockget(clock, calendar=cal, rc=rc)
154 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
160 selectcase (trim(option))
162 case (optnone, optnever)
163 call esmf_timeintervalset(alarminterval, yy=9999, rc=rc)
164 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
168 call esmf_timeset( nextalarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
169 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
173 update_nextalarm = .false.
176 if (.not.
present(opt_ymd))
then
177 call esmf_logseterror(esmf_rc_arg_bad, &
178 msg=subname//trim(option)//
' requires opt_ymd', &
180 file=__file__, rctoreturn=rc)
183 if (lymd < 0 .or. ltod < 0)
then
184 call esmf_logseterror(esmf_rc_arg_bad, &
185 msg=subname//trim(option)//
'opt_ymd, opt_tod invalid', &
187 file=__file__, rctoreturn=rc)
190 call esmf_timeintervalset(alarminterval, yy=9999, rc=rc)
191 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
195 call timeinit(nextalarm, lymd, cal, tod=ltod, desc=
"optDate", rc=rc)
196 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
200 update_nextalarm = .false.
203 if (.not.
present(opt_ymd))
then
204 call esmf_logseterror(esmf_rc_arg_bad, &
205 msg=subname//trim(option)//
' requires opt_ymd', &
207 file=__file__, rctoreturn=rc)
210 call esmf_timeintervalset(alarminterval, mm=1, rc=rc)
211 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
215 call esmf_timeset( nextalarm, yy=cyy, mm=cmm, dd=opt_n, s=0, calendar=cal, rc=rc )
216 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
220 update_nextalarm = .true.
222 case (optnsteps, optnstep)
223 call esmf_clockget(clock, timestep=alarminterval, rc=rc)
224 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
228 alarminterval = alarminterval * opt_n
229 update_nextalarm = .true.
231 case (optnseconds, optnsecond)
232 call esmf_timeintervalset(alarminterval, s=1, rc=rc)
233 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
237 alarminterval = alarminterval * opt_n
238 update_nextalarm = .true.
240 case (optnminutes, optnminute)
241 call esmf_timeintervalset(alarminterval, s=60, rc=rc)
242 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
246 alarminterval = alarminterval * opt_n
247 update_nextalarm = .true.
249 case (optnhours, optnhour)
250 call esmf_timeintervalset(alarminterval, s=3600, rc=rc)
251 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
255 alarminterval = alarminterval * opt_n
256 update_nextalarm = .true.
258 case (optndays, optnday)
259 call esmf_timeintervalset(alarminterval, d=1, rc=rc)
260 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
264 alarminterval = alarminterval * opt_n
265 update_nextalarm = .true.
267 case (optnmonths, optnmonth)
268 call esmf_timeintervalset(alarminterval, mm=1, rc=rc)
269 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
273 alarminterval = alarminterval * opt_n
274 update_nextalarm = .true.
277 call esmf_timeintervalset(alarminterval, mm=1, rc=rc)
278 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
282 call esmf_timeset( nextalarm, yy=cyy, mm=cmm, dd=1, s=0, calendar=cal, rc=rc )
283 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
287 update_nextalarm = .true.
289 case (optnyears, optnyear)
290 call esmf_timeintervalset(alarminterval, yy=1, rc=rc)
291 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
295 alarminterval = alarminterval * opt_n
296 update_nextalarm = .true.
299 call esmf_timeintervalset(alarminterval, yy=1, rc=rc)
300 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
304 call esmf_timeset( nextalarm, yy=cyy, mm=1, dd=1, s=0, calendar=cal, rc=rc )
305 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &
309 update_nextalarm = .true.
312 call esmf_logseterror(esmf_rc_arg_bad, &
313 msg=subname//
' unknown option: '//trim(option), &
315 file=__file__, rctoreturn=rc)
327 if (update_nextalarm)
then
328 nextalarm = nextalarm - alarminterval
329 do while (nextalarm <= currtime)
330 nextalarm = nextalarm + alarminterval
334 alarm = esmf_alarmcreate( name=lalarmname, clock=clock, ringtime=nextalarm, ringinterval=alarminterval, rc=rc)
335 if (esmf_logfounderror(rctocheck=rc, msg=esmf_logerr_passthru, &