1 #include <ESMF_TimeMgr.inc>
3 ! Factor so abs(Sn) < Sd and ensure that signs of S and Sn match.
4 ! Also, enforce consistency.
5 ! YR and MM fields are ignored.
7 SUBROUTINE normalize_basetime( basetime )
9 USE WRF_ESMF_BaseTimeMod
11 TYPE(ESMF_BaseTime), INTENT(INOUT) :: basetime
13 INTEGER(ESMF_KIND_I8) :: Sn_simplified, Sd_simplified
14 INTEGER :: primes_to_check
17 !PRINT *,'DEBUG: BEGIN normalize_basetime()'
18 ! Consistency check...
19 IF ( basetime%Sd < 0 ) THEN
20 CALL wrf_error_fatal( &
21 'normalize_basetime: denominator of seconds cannot be negative' )
23 IF ( ( basetime%Sd == 0 ) .AND. ( basetime%Sn .NE. 0 ) ) THEN
24 CALL wrf_error_fatal( &
25 'normalize_basetime: denominator of seconds cannot be zero when numerator is non-zero' )
27 ! factor so abs(Sn) < Sd
28 IF ( basetime%Sd > 0 ) THEN
29 IF ( ABS( basetime%Sn ) .GE. basetime%Sd ) THEN
30 !PRINT *,'DEBUG: normalize_basetime() A1: S,Sn,Sd = ',basetime%S,basetime%Sn,basetime%Sd
31 basetime%S = basetime%S + ( basetime%Sn / basetime%Sd )
32 basetime%Sn = mod( basetime%Sn, basetime%Sd )
33 !PRINT *,'DEBUG: normalize_basetime() A2: S,Sn,Sd = ',basetime%S,basetime%Sn,basetime%Sd
35 ! change sign of Sn if it does not match S
36 IF ( ( basetime%S > 0 ) .AND. ( basetime%Sn < 0 ) ) THEN
37 !PRINT *,'DEBUG: normalize_basetime() B1: S,Sn,Sd = ',basetime%S,basetime%Sn,basetime%Sd
38 basetime%S = basetime%S - 1_ESMF_KIND_I8
39 basetime%Sn = basetime%Sn + basetime%Sd
40 !PRINT *,'DEBUG: normalize_basetime() B2: S,Sn,Sd = ',basetime%S,basetime%Sn,basetime%Sd
42 IF ( ( basetime%S < 0 ) .AND. ( basetime%Sn > 0 ) ) THEN
43 !PRINT *,'DEBUG: normalize_basetime() C1: S,Sn,Sd = ',basetime%S,basetime%Sn,basetime%Sd
44 basetime%S = basetime%S + 1_ESMF_KIND_I8
45 basetime%Sn = basetime%Sn - basetime%Sd
46 !PRINT *,'DEBUG: normalize_basetime() C2: S,Sn,Sd = ',basetime%S,basetime%Sn,basetime%Sd
51 !Simplify the fraction -- otherwise the fraction can get needlessly complicated and
53 IF ( ( basetime%Sd > 0 ) .AND. (basetime%Sn > 0 ) ) THEN
54 CALL simplify( basetime%Sn, basetime%Sd, Sn_simplified, Sd_simplified )
55 basetime%Sn = Sn_simplified
56 basetime%Sd = Sd_simplified
57 !If the numerator and denominator are both larger than 10000, after simplification
58 !using the first 9 primes, the chances increase that there is a common prime factor other
59 !than the 9 searched for in the standard simplify
60 !By only searching for more than 9 primes when the numerator and denominator are
61 !large, we avoid the additional computational expense of checking additional primes
62 !for a large number of cases
63 IF ( ( basetime%Sd > 10000 ) .AND. (basetime%Sn > 10000 ) ) THEN
65 CALL simplify_numprimes( basetime%Sn, basetime%Sd, Sn_simplified, Sd_simplified, &
67 basetime%Sn = Sn_simplified
68 basetime%Sd = Sd_simplified
73 !PRINT *,'DEBUG: END normalize_basetime()'
74 END SUBROUTINE normalize_basetime
78 ! A normalized time has time%basetime >= 0, time%basetime less than the current
79 ! year expressed as a timeInterval, and time%YR can take any value
80 SUBROUTINE normalize_time( time )
82 USE WRF_ESMF_BaseTimeMod
85 TYPE(ESMF_Time), INTENT(INOUT) :: time
86 INTEGER(ESMF_KIND_I8) :: nsecondsinyear
88 TYPE(ESMF_BaseTime) :: cmptime, zerotime
92 ! first, normalize basetime
93 ! this will force abs(Sn) < Sd and ensure that signs of S and Sn match
94 CALL normalize_basetime( time%basetime )
96 !$$$ add tests for these edge cases
98 ! next, underflow negative seconds into YEARS
99 ! time%basetime must end up non-negative
100 !$$$ push this down into ESMF_BaseTime constructor
104 DO WHILE ( time%basetime < zerotime )
105 time%YR = time%YR - 1
106 !$$$ push this down into ESMF_BaseTime constructor
107 cmptime%S = nsecondsinyear( time%YR )
110 time%basetime = time%basetime + cmptime
113 ! next, overflow seconds into YEARS
115 DO WHILE ( .NOT. done )
116 !$$$ push this down into ESMF_BaseTime constructor
117 cmptime%S = nsecondsinyear( time%YR )
120 IF ( time%basetime >= cmptime ) THEN
121 time%basetime = time%basetime - cmptime
122 time%YR = time%YR + 1
127 END SUBROUTINE normalize_time
131 SUBROUTINE normalize_timeint( timeInt )
132 USE WRF_ESMF_BaseTimeMod
133 USE WRF_ESMF_TimeIntervalMod
135 TYPE(ESMF_TimeInterval), INTENT(INOUT) :: timeInt
138 ! this will force abs(Sn) < Sd and ensure that signs of S and Sn match
139 ! YR and MM are ignored
140 CALL normalize_basetime( timeInt%basetime )
141 END SUBROUTINE normalize_timeint
146 FUNCTION signnormtimeint ( timeInt )
147 ! Compute the sign of a time interval.
148 ! YR and MM fields are *IGNORED*.
149 ! returns 1, 0, or -1 or exits if timeInt fields have inconsistent signs.
151 USE WRF_ESMF_BaseTimeMod
152 USE WRF_ESMF_TimeIntervalMod
154 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeInt
155 INTEGER :: signnormtimeint
156 LOGICAL :: positive, negative
161 ! Note that Sd is required to be non-negative. This is enforced in
162 ! normalize_timeint().
163 ! Note that Sn is required to be zero when Sd is zero. This is enforced
164 ! in normalize_timeint().
165 IF ( ( timeInt%basetime%S > 0 ) .OR. &
166 ( timeInt%basetime%Sn > 0 ) ) THEN
169 IF ( ( timeInt%basetime%S < 0 ) .OR. &
170 ( timeInt%basetime%Sn < 0 ) ) THEN
173 IF ( positive .AND. negative ) THEN
174 CALL wrf_error_fatal( &
175 'signnormtimeint: signs of fields cannot be mixed' )
176 ELSE IF ( positive ) THEN
178 ELSE IF ( negative ) THEN
181 END FUNCTION signnormtimeint
184 ! Exits with error message if timeInt is not normalized.
185 SUBROUTINE timeintchecknormalized( timeInt, msgstr )
186 USE WRF_ESMF_TimeIntervalMod
188 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeInt
189 CHARACTER(LEN=*), INTENT(IN) :: msgstr
191 CHARACTER(LEN=256) :: outstr
192 IF ( ( timeInt%YR /= 0 ) ) THEN
193 outstr = 'un-normalized TimeInterval not allowed: '//TRIM(msgstr)
194 CALL wrf_error_fatal( outstr )
196 END SUBROUTINE timeintchecknormalized
199 ! added from share/module_date_time in WRF.
200 FUNCTION nfeb ( year ) RESULT (num_days)
201 ! Compute the number of days in February for the given year
205 ! TBH: TODO: Replace this hack with run-time decision based on
206 ! TBH: TODO: passed-in calendar.
207 #ifdef NO_LEAP_CALENDAR
208 num_days = 28 ! By default, February has 28 days ...
210 num_days = 28 ! By default, February has 28 days ...
211 IF (MOD(year,4).eq.0) THEN
212 num_days = 29 ! But every four years, it has 29 days ...
213 IF (MOD(year,100).eq.0) THEN
214 num_days = 28 ! Except every 100 years, when it has 28 days ...
215 IF (MOD(year,400).eq.0) THEN
216 num_days = 29 ! Except every 400 years, when it has 29 days.
225 FUNCTION ndaysinyear ( year ) RESULT (num_diy)
226 ! Compute the number of days in the given year
228 INTEGER, INTENT(IN) :: year
236 IF ( nfeb( year ) .EQ. 29 ) THEN
242 END FUNCTION ndaysinyear
246 FUNCTION nsecondsinyear ( year ) RESULT (numseconds)
247 ! Compute the number of seconds in the given year
250 INTEGER, INTENT(IN) :: year
251 INTEGER(ESMF_KIND_I8) :: numseconds
252 INTEGER :: ndaysinyear
253 numseconds = SECONDS_PER_DAY * INT( ndaysinyear(year) , ESMF_KIND_I8 )
254 END FUNCTION nsecondsinyear
260 USE WRF_ESMF_BaseTimeMod
261 USE WRF_ESMF_CalendarMod, only : months_per_year, mday, daym, mdaycum, monthbdys, &
262 mdayleap, mdayleapcum, monthbdysleap, daymleap
267 !$$$ push this down into ESMF_BaseTime constructor
271 DO i = 1,MONTHS_PER_YEAR
276 mdaycum(i) = mdaycum(i-1) + mday(i)
277 !$$$ push this down into ESMF_BaseTime constructor
278 monthbdys(i)%S = SECONDS_PER_DAY * INT( mdaycum(i), ESMF_KIND_I8 )
284 !$$$ push this down into ESMF_BaseTime constructor
285 monthbdysleap(0)%S = 0
286 monthbdysleap(0)%Sn = 0
287 monthbdysleap(0)%Sd = 0
288 DO i = 1,MONTHS_PER_YEAR
293 mdayleapcum(i) = mdayleapcum(i-1) + mdayleap(i)
294 !$$$ push this down into ESMF_BaseTime constructor
295 monthbdysleap(i)%S = SECONDS_PER_DAY * INT( mdayleapcum(i), ESMF_KIND_I8 )
296 monthbdysleap(i)%Sn = 0
297 monthbdysleap(i)%Sd = 0
299 END SUBROUTINE initdaym
302 !$$$ useful, but not used at the moment...
303 SUBROUTINE compute_dayinyear(YR,MM,DD,dayinyear)
304 use WRF_ESMF_CalendarMod, only : mday
306 INTEGER, INTENT(IN) :: YR,MM,DD ! DD is day of month
307 INTEGER, INTENT(OUT) :: dayinyear
317 dayinyear = dayinyear + nfeb(YR)
319 dayinyear = dayinyear + mday(i)
322 dayinyear = dayinyear + DD
324 END SUBROUTINE compute_dayinyear
328 SUBROUTINE timegetmonth( time, MM )
330 USE WRF_ESMF_BaseTimeMod
332 USE WRF_ESMF_CalendarMod, only : MONTHS_PER_YEAR, monthbdys, monthbdysleap
334 TYPE(ESMF_Time), INTENT(IN) :: time
335 INTEGER, INTENT(OUT) :: MM
343 IF ( nfeb(time%YR) == 29 ) THEN
344 DO i = 1,MONTHS_PER_YEAR
345 IF ( ( time%basetime >= monthbdysleap(i-1) ) .AND. ( time%basetime < monthbdysleap(i) ) ) THEN
351 DO i = 1,MONTHS_PER_YEAR
352 IF ( ( time%basetime >= monthbdys(i-1) ) .AND. ( time%basetime < monthbdys(i) ) ) THEN
360 CALL wrf_error_fatal( 'timegetmonth: could not extract month of year from time' )
362 END SUBROUTINE timegetmonth
365 !$$$ may need to change dependencies in Makefile...
367 SUBROUTINE timegetdayofmonth( time, DD )
369 USE WRF_ESMF_BaseTimeMod
371 USE WRF_ESMF_CalendarMod, only : monthbdys, monthbdysleap
373 TYPE(ESMF_Time), INTENT(IN) :: time
374 INTEGER, INTENT(OUT) :: DD
378 TYPE(ESMF_BaseTime) :: tmpbasetime
380 tmpbasetime = time%basetime
382 CALL timegetmonth( time, MM )
383 IF ( nfeb(time%YR) == 29 ) THEN
384 tmpbasetime = time%basetime - monthbdysleap(MM-1)
386 tmpbasetime = time%basetime - monthbdys(MM-1)
389 DD = ( tmpbasetime%S / SECONDS_PER_DAY ) + 1
390 END SUBROUTINE timegetdayofmonth
393 ! Increment Time by number of seconds between start of year and start
396 ! Time is NOT normalized.
397 SUBROUTINE timeaddmonths( time, MM, ierr )
399 USE WRF_ESMF_BaseTimeMod
401 USE WRF_ESMF_CalendarMod, only : MONTHS_PER_YEAR, monthbdys, monthbdysleap
403 TYPE(ESMF_Time), INTENT(INOUT) :: time
404 INTEGER, INTENT(IN) :: MM
405 INTEGER, INTENT(OUT) :: ierr
409 ! PRINT *,'DEBUG: BEGIN timeaddmonths()'
411 ! time%basetime = time%basetime
413 IF ( ( MM < 1 ) .OR. ( MM > MONTHS_PER_YEAR ) ) THEN
416 IF ( nfeb(time%YR) == 29 ) THEN
417 time%basetime = time%basetime + monthbdysleap(MM-1)
419 time%basetime = time%basetime + monthbdys(MM-1)
423 END SUBROUTINE timeaddmonths
426 ! Increment Time by number of seconds in the current month.
427 ! Time is NOT normalized.
428 SUBROUTINE timeincmonth( time )
430 USE WRF_ESMF_BaseTimeMod
432 USE WRF_ESMF_CalendarMod, only : mday, mdayleap
434 TYPE(ESMF_Time), INTENT(INOUT) :: time
439 ! time%basetime%S = time%basetime%S
441 CALL timegetmonth( time, MM )
442 IF ( nfeb(time%YR) == 29 ) THEN
443 time%basetime%S = time%basetime%S + &
444 ( INT( mdayleap(MM), ESMF_KIND_I8 ) * SECONDS_PER_DAY )
446 time%basetime%S = time%basetime%S + &
447 ( INT( mday(MM), ESMF_KIND_I8 ) * SECONDS_PER_DAY )
450 END SUBROUTINE timeincmonth
454 ! Decrement Time by number of seconds in the previous month.
455 ! Time is NOT normalized.
456 SUBROUTINE timedecmonth( time )
458 USE WRF_ESMF_BaseTimeMod
460 USE WRF_ESMF_CalendarMod, only : mday, months_per_year, mdayleap
462 TYPE(ESMF_Time), INTENT(INOUT) :: time
467 ! time%basetime%S = time%basetime%S
469 CALL timegetmonth( time, MM ) ! current month, 1-12
470 ! find previous month
473 ! wrap around Jan -> Dec
476 IF ( nfeb(time%YR) == 29 ) THEN
477 time%basetime%S = time%basetime%S - &
478 ( INT( mdayleap(MM), ESMF_KIND_I8 ) * SECONDS_PER_DAY )
480 time%basetime%S = time%basetime%S - &
481 ( INT( mday(MM), ESMF_KIND_I8 ) * SECONDS_PER_DAY )
484 END SUBROUTINE timedecmonth
488 ! spaceship operator for Times
489 SUBROUTINE timecmp(time1, time2, retval )
491 USE WRF_ESMF_BaseTimeMod
494 INTEGER, INTENT(OUT) :: retval
497 TYPE(ESMF_Time), INTENT(IN) :: time1
498 TYPE(ESMF_Time), INTENT(IN) :: time2
499 IF ( time1%YR .GT. time2%YR ) THEN ; retval = 1 ; RETURN ; ENDIF
500 IF ( time1%YR .LT. time2%YR ) THEN ; retval = -1 ; RETURN ; ENDIF
501 CALL seccmp( time1%basetime%S, time1%basetime%Sn, time1%basetime%Sd, &
502 time2%basetime%S, time2%basetime%Sn, time2%basetime%Sd, &
504 END SUBROUTINE timecmp
508 ! spaceship operator for TimeIntervals
509 SUBROUTINE timeintcmp(timeint1, timeint2, retval )
511 USE WRF_ESMF_BaseTimeMod
512 USE WRF_ESMF_TimeIntervalMod
514 INTEGER, INTENT(OUT) :: retval
517 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint1
518 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint2
519 CALL timeintchecknormalized( timeint1, 'timeintcmp arg1' )
520 CALL timeintchecknormalized( timeint2, 'timeintcmp arg2' )
521 CALL seccmp( timeint1%basetime%S, timeint1%basetime%Sn, &
522 timeint1%basetime%Sd, &
523 timeint2%basetime%S, timeint2%basetime%Sn, &
524 timeint2%basetime%Sd, retval )
525 END SUBROUTINE timeintcmp
529 ! spaceship operator for seconds + Sn/Sd
530 SUBROUTINE seccmp(S1, Sn1, Sd1, S2, Sn2, Sd2, retval )
533 INTEGER, INTENT(OUT) :: retval
536 INTEGER(ESMF_KIND_I8), INTENT(IN) :: S1, Sn1, Sd1
537 INTEGER(ESMF_KIND_I8), INTENT(IN) :: S2, Sn2, Sd2
539 INTEGER(ESMF_KIND_I8) :: lcd, n1, n2
543 if ( ( n1 .ne. 0 ) .or. ( n2 .ne. 0 ) ) then
544 CALL compute_lcd( Sd1, Sd2, lcd )
545 if ( Sd1 .ne. 0 ) n1 = n1 * ( lcd / Sd1 )
546 if ( Sd2 .ne. 0 ) n2 = n2 * ( lcd / Sd2 )
549 if ( S1 .GT. S2 ) retval = 1
550 if ( S1 .LT. S2 ) retval = -1
551 IF ( S1 .EQ. S2 ) THEN
552 IF (n1 .GT. n2) retval = 1
553 IF (n1 .LT. n2) retval = -1
554 IF (n1 .EQ. n2) retval = 0
556 END SUBROUTINE seccmp
559 SUBROUTINE c_esmc_basetimeeq (time1, time2, outflag)
560 USE WRF_ESMF_AlarmMod
562 USE WRF_ESMF_BaseTimeMod
563 USE WRF_ESMF_CalendarMod
564 USE WRF_ESMF_ClockMod
565 USE WRF_ESMF_FractionMod
566 USE WRF_ESMF_TimeIntervalMod
569 logical, intent(OUT) :: outflag
570 type(ESMF_Time), intent(in) :: time1
571 type(ESMF_Time), intent(in) :: time2
573 CALL timecmp(time1,time2,res)
574 outflag = (res .EQ. 0)
575 END SUBROUTINE c_esmc_basetimeeq
576 SUBROUTINE c_esmc_basetimege(time1, time2, outflag)
577 USE WRF_ESMF_AlarmMod
579 USE WRF_ESMF_BaseTimeMod
580 USE WRF_ESMF_CalendarMod
581 USE WRF_ESMF_ClockMod
582 USE WRF_ESMF_FractionMod
583 USE WRF_ESMF_TimeIntervalMod
585 logical, intent(OUT) :: outflag
586 type(ESMF_Time), intent(in) :: time1
587 type(ESMF_Time), intent(in) :: time2
589 CALL timecmp(time1,time2,res)
590 outflag = (res .EQ. 1 .OR. res .EQ. 0)
591 END SUBROUTINE c_esmc_basetimege
592 SUBROUTINE c_esmc_basetimegt(time1, time2, outflag)
593 USE WRF_ESMF_AlarmMod
595 USE WRF_ESMF_BaseTimeMod
596 USE WRF_ESMF_CalendarMod
597 USE WRF_ESMF_ClockMod
598 USE WRF_ESMF_FractionMod
599 USE WRF_ESMF_TimeIntervalMod
602 logical, intent(OUT) :: outflag
603 type(ESMF_Time), intent(in) :: time1
604 type(ESMF_Time), intent(in) :: time2
606 CALL timecmp(time1,time2,res)
607 outflag = (res .EQ. 1)
608 END SUBROUTINE c_esmc_basetimegt
609 SUBROUTINE c_esmc_basetimele(time1, time2, outflag)
610 USE WRF_ESMF_AlarmMod
612 USE WRF_ESMF_BaseTimeMod
613 USE WRF_ESMF_CalendarMod
614 USE WRF_ESMF_ClockMod
615 USE WRF_ESMF_FractionMod
616 USE WRF_ESMF_TimeIntervalMod
619 logical, intent(OUT) :: outflag
620 type(ESMF_Time), intent(in) :: time1
621 type(ESMF_Time), intent(in) :: time2
623 CALL timecmp(time1,time2,res)
624 outflag = (res .EQ. -1 .OR. res .EQ. 0)
625 END SUBROUTINE c_esmc_basetimele
626 SUBROUTINE c_esmc_basetimelt(time1, time2, outflag)
627 USE WRF_ESMF_AlarmMod
629 USE WRF_ESMF_BaseTimeMod
630 USE WRF_ESMF_CalendarMod
631 USE WRF_ESMF_ClockMod
632 USE WRF_ESMF_FractionMod
633 USE WRF_ESMF_TimeIntervalMod
636 logical, intent(OUT) :: outflag
637 type(ESMF_Time), intent(in) :: time1
638 type(ESMF_Time), intent(in) :: time2
640 CALL timecmp(time1,time2,res)
641 outflag = (res .EQ. -1)
642 END SUBROUTINE c_esmc_basetimelt
643 SUBROUTINE c_esmc_basetimene(time1, time2, outflag)
644 USE WRF_ESMF_AlarmMod
646 USE WRF_ESMF_BaseTimeMod
647 USE WRF_ESMF_CalendarMod
648 USE WRF_ESMF_ClockMod
649 USE WRF_ESMF_FractionMod
650 USE WRF_ESMF_TimeIntervalMod
653 logical, intent(OUT) :: outflag
654 type(ESMF_Time), intent(in) :: time1
655 type(ESMF_Time), intent(in) :: time2
657 CALL timecmp(time1,time2,res)
658 outflag = (res .NE. 0)
659 END SUBROUTINE c_esmc_basetimene
661 SUBROUTINE c_esmc_basetimeinteq(timeint1, timeint2, outflag)
662 USE WRF_ESMF_TimeIntervalMod
664 LOGICAL, INTENT(OUT) :: outflag
665 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint1
666 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint2
668 CALL timeintcmp(timeint1,timeint2,res)
669 outflag = (res .EQ. 0)
670 END SUBROUTINE c_esmc_basetimeinteq
671 SUBROUTINE c_esmc_basetimeintne(timeint1, timeint2, outflag)
672 USE WRF_ESMF_TimeIntervalMod
674 LOGICAL, INTENT(OUT) :: outflag
675 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint1
676 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint2
678 CALL timeintcmp(timeint1,timeint2,res)
679 outflag = (res .NE. 0)
680 END SUBROUTINE c_esmc_basetimeintne
681 SUBROUTINE c_esmc_basetimeintlt(timeint1, timeint2, outflag)
682 USE WRF_ESMF_TimeIntervalMod
684 LOGICAL, INTENT(OUT) :: outflag
685 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint1
686 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint2
688 CALL timeintcmp(timeint1,timeint2,res)
689 outflag = (res .LT. 0)
690 END SUBROUTINE c_esmc_basetimeintlt
691 SUBROUTINE c_esmc_basetimeintgt(timeint1, timeint2, outflag)
692 USE WRF_ESMF_TimeIntervalMod
694 LOGICAL, INTENT(OUT) :: outflag
695 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint1
696 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint2
698 CALL timeintcmp(timeint1,timeint2,res)
699 outflag = (res .GT. 0)
700 END SUBROUTINE c_esmc_basetimeintgt
701 SUBROUTINE c_esmc_basetimeintle(timeint1, timeint2, outflag)
702 USE WRF_ESMF_TimeIntervalMod
704 LOGICAL, INTENT(OUT) :: outflag
705 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint1
706 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint2
708 CALL timeintcmp(timeint1,timeint2,res)
709 outflag = (res .LE. 0)
710 END SUBROUTINE c_esmc_basetimeintle
711 SUBROUTINE c_esmc_basetimeintge(timeint1, timeint2, outflag)
712 USE WRF_ESMF_TimeIntervalMod
714 LOGICAL, INTENT(OUT) :: outflag
715 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint1
716 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeint2
718 CALL timeintcmp(timeint1,timeint2,res)
719 outflag = (res .GE. 0)
720 END SUBROUTINE c_esmc_basetimeintge
722 SUBROUTINE compute_lcd( e1, e2, lcd )
725 INTEGER(ESMF_KIND_I8), INTENT(IN) :: e1, e2
726 INTEGER(ESMF_KIND_I8), INTENT(OUT) :: lcd
727 INTEGER, PARAMETER :: nprimes = 9
728 INTEGER(ESMF_KIND_I8), DIMENSION(nprimes), PARAMETER :: primes = (/2,3,5,7,11,13,17,19,23/)
730 INTEGER(ESMF_KIND_I8) d1, d2, p
733 IF ( d1 .EQ. 0 .AND. d2 .EQ. 0 ) THEN ; lcd = 1 ; RETURN ; ENDIF
734 IF ( d1 .EQ. 0 ) d1 = d2
735 IF ( d2 .EQ. 0 ) d2 = d1
736 IF ( d1 .EQ. d2 ) THEN ; lcd = d1 ; RETURN ; ENDIF
740 DO WHILE (lcd/p .NE. 0 .AND. &
741 mod(lcd/p,d1) .EQ. 0 .AND. mod(lcd/p,d2) .EQ. 0)
745 END SUBROUTINE compute_lcd
747 SUBROUTINE simplify( ni, di, no, do )
750 INTEGER(ESMF_KIND_I8), INTENT(IN) :: ni, di
751 INTEGER(ESMF_KIND_I8), INTENT(OUT) :: no, do
752 INTEGER, PARAMETER :: nprimes = 9
753 INTEGER(ESMF_KIND_I8), DIMENSION(nprimes), PARAMETER :: primes = (/2,3,5,7,11,13,17,19,23/)
754 INTEGER(ESMF_KIND_I8) :: pr, d, n
757 IF ( ni .EQ. 0 ) THEN
762 IF ( mod( di , ni ) .EQ. 0 ) THEN
772 DO WHILE ( keepgoing )
774 IF ( d/pr .NE. 0 .AND. n/pr .NE. 0 .AND. MOD(d,pr) .EQ. 0 .AND. MOD(n,pr) .EQ. 0 ) THEN
784 END SUBROUTINE simplify
787 ! Same as simplify above, but allows user to choose the number of primes to check
788 SUBROUTINE simplify_numprimes( ni, di, no, do, num_primes_to_check )
791 INTEGER(ESMF_KIND_I8), INTENT(IN) :: ni, di
792 INTEGER(ESMF_KIND_I8), INTENT(OUT) :: no, do
793 INTEGER, INTENT(IN) :: num_primes_to_check !Number of primes to check
794 INTEGER, PARAMETER :: nprimes = 62
795 INTEGER(ESMF_KIND_I8), DIMENSION(nprimes), PARAMETER :: primes = (/2,3,5,7,11,13,17,&
796 19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,&
797 137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,&
798 251,257,263,269,271,277,281,283,293/)
799 INTEGER(ESMF_KIND_I8) :: pr, d, n
802 INTEGER :: num_primes_to_check_final !Number of primes to check after being limited to max
803 !available number of primes
805 ! If the user chooses to check more primes than are currently specified in the subroutine
806 ! then use the maximum number of primes currently specified
807 num_primes_to_check_final = min(num_primes_to_check, nprimes)
809 IF ( ni .EQ. 0 ) THEN
814 IF ( mod( di , ni ) .EQ. 0 ) THEN
821 DO np = 1, num_primes_to_check_final
824 DO WHILE ( keepgoing )
826 IF ( d/pr .NE. 0 .AND. n/pr .NE. 0 .AND. MOD(d,pr) .EQ. 0 .AND. MOD(n,pr) .EQ. 0 ) THEN
836 END SUBROUTINE simplify_numprimes
840 !$$$ this should be named "c_esmc_timesum" or something less misleading
841 SUBROUTINE c_esmc_basetimesum( time1, timeinterval, timeOut )
843 USE WRF_ESMF_BaseTimeMod
844 USE WRF_ESMF_TimeIntervalMod
847 TYPE(ESMF_Time), INTENT(IN) :: time1
848 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeinterval
849 TYPE(ESMF_Time), INTENT(INOUT) :: timeOut
853 timeOut%basetime = timeOut%basetime + timeinterval%basetime
855 !jm Month has no meaning for a timeinterval; removed 20100319
859 DO m = 1, abs(timeinterval%MM)
860 IF ( timeinterval%MM > 0 ) THEN
861 CALL timeincmonth( timeOut )
863 CALL timedecmonth( timeOut )
868 timeOut%YR = timeOut%YR + timeinterval%YR
869 CALL normalize_time( timeOut )
870 END SUBROUTINE c_esmc_basetimesum
873 !$$$ this should be named "c_esmc_timedec" or something less misleading
874 SUBROUTINE c_esmc_basetimedec( time1, timeinterval, timeOut )
876 USE WRF_ESMF_BaseTimeMod
877 USE WRF_ESMF_TimeIntervalMod
880 TYPE(ESMF_Time), INTENT(IN) :: time1
881 TYPE(ESMF_TimeInterval), INTENT(IN) :: timeinterval
882 TYPE(ESMF_Time), INTENT(OUT) :: timeOut
884 TYPE (ESMF_TimeInterval) :: neginterval
885 neginterval = timeinterval
886 !$$$push this down into a unary negation operator on TimeInterval
887 neginterval%basetime%S = -neginterval%basetime%S
888 neginterval%basetime%Sn = -neginterval%basetime%Sn
889 neginterval%YR = -neginterval%YR
891 !jm month has no meaning for an interval; removed 20100319
893 neginterval%MM = -neginterval%MM
896 timeOut = time1 + neginterval
897 END SUBROUTINE c_esmc_basetimedec
900 !$$$ this should be named "c_esmc_timediff" or something less misleading
901 SUBROUTINE c_esmc_basetimediff( time1, time2, timeIntOut )
903 USE WRF_ESMF_BaseTimeMod
904 USE WRF_ESMF_TimeIntervalMod
907 TYPE(ESMF_Time), INTENT(IN) :: time1
908 TYPE(ESMF_Time), INTENT(IN) :: time2
909 TYPE(ESMF_TimeInterval), INTENT(OUT) :: timeIntOut
911 INTEGER(ESMF_KIND_I8) :: nsecondsinyear
913 CALL ESMF_TimeIntervalSet( timeIntOut )
914 timeIntOut%basetime = time1%basetime - time2%basetime
915 ! convert difference in years to basetime...
916 IF ( time1%YR > time2%YR ) THEN
917 DO yr = time2%YR, ( time1%YR - 1 )
918 timeIntOut%basetime%S = timeIntOut%basetime%S + nsecondsinyear( yr )
920 ELSE IF ( time2%YR > time1%YR ) THEN
921 DO yr = time1%YR, ( time2%YR - 1 )
922 timeIntOut%basetime%S = timeIntOut%basetime%S - nsecondsinyear( yr )
925 !$$$ add tests for multi-year differences
926 CALL normalize_timeint( timeIntOut )
927 END SUBROUTINE c_esmc_basetimediff
930 ! some extra wrf stuff
933 ! Convert fraction to string with leading sign.
934 ! If fraction simplifies to a whole number or if
935 ! denominator is zero, return empty string.
936 ! INTEGER*8 interface.
937 SUBROUTINE fraction_to_stringi8( numerator, denominator, frac_str )
940 INTEGER(ESMF_KIND_I8), INTENT(IN) :: numerator
941 INTEGER(ESMF_KIND_I8), INTENT(IN) :: denominator
942 CHARACTER (LEN=*), INTENT(OUT) :: frac_str
943 IF ( denominator > 0 ) THEN
944 IF ( mod( numerator, denominator ) /= 0 ) THEN
945 IF ( numerator > 0 ) THEN
946 WRITE(frac_str,FMT="('+',I2.2,'/',I2.2)") abs(numerator), denominator
948 WRITE(frac_str,FMT="('-',I2.2,'/',I2.2)") abs(numerator), denominator
950 ELSE ! includes numerator == 0 case
953 ELSE ! no-fraction case
956 END SUBROUTINE fraction_to_stringi8
959 ! Convert fraction to string with leading sign.
960 ! If fraction simplifies to a whole number or if
961 ! denominator is zero, return empty string.
963 SUBROUTINE fraction_to_string( numerator, denominator, frac_str )
966 INTEGER, INTENT(IN) :: numerator
967 INTEGER, INTENT(IN) :: denominator
968 CHARACTER (LEN=*), INTENT(OUT) :: frac_str
970 INTEGER(ESMF_KIND_I8) :: numerator_i8, denominator_i8
971 numerator_i8 = INT( numerator, ESMF_KIND_I8 )
972 denominator_i8 = INT( denominator, ESMF_KIND_I8 )
973 CALL fraction_to_stringi8( numerator_i8, denominator_i8, frac_str )
974 END SUBROUTINE fraction_to_string
977 SUBROUTINE print_a_time( time )
984 CALL ESMF_TimeGet( time, timeString=s, rc=rc )
985 print *,'Print a time|',TRIM(s),'|'
987 END SUBROUTINE print_a_time
989 SUBROUTINE print_a_timeinterval( time )
991 use WRF_ESMF_TimeIntervalMod
993 type(ESMF_TimeInterval) time
996 CALL ESMFold_TimeIntervalGetString( time, s, rc )
997 print *,'Print a time interval|',TRIM(s),'|'
999 END SUBROUTINE print_a_timeinterval