updated top-level README and version_decl for V4.4.2 (#1795)
[WRF.git] / external / esmf_time_f90 / ESMF_TimeInterval.F90
blob43ffd14fb24422694773c86286fd41e5c5ca052f
2 !==============================================================================
4 !     ESMF TimeInterval Module
5       module WRF_ESMF_TimeIntervalMod
7 !==============================================================================
9 ! This file contains the TimeInterval class definition and all TimeInterval
10 ! class methods.
12 !------------------------------------------------------------------------------
13 ! INCLUDES
14 #include <ESMF_TimeMgr.inc>
16 !===============================================================================
17 !BOPI
18 ! !MODULE: WRF_ESMF_TimeIntervalMod
20 ! !DESCRIPTION:
21 ! Part of Time Manager F90 API wrapper of C++ implemenation
23 ! Defines F90 wrapper entry points for corresponding
24 ! C++ implementaion of class {\tt ESMC\_TimeInterval}
26 ! See {\tt ../include/ESMC\_TimeInterval.h} for complete description
28 !------------------------------------------------------------------------------
29 ! !USES:
30       ! inherit from ESMF base class
31       use WRF_ESMF_BaseMod
33       ! inherit from base time class
34       use WRF_ESMF_BaseTimeMod
36       ! associated derived types
37       use WRF_ESMF_FractionMod, only : ESMF_Fraction
38       use WRF_ESMF_CalendarMod
40       implicit none
42 !------------------------------------------------------------------------------
43 ! !PRIVATE TYPES:
44       private
45 !------------------------------------------------------------------------------
46 !     ! ESMF_TimeInterval
48 !     ! F90 class type to match C++ TimeInterval class in size only;
49 !     !  all dereferencing within class is performed by C++ implementation
51       type ESMF_TimeInterval
52         ! time interval is expressed as basetime
53         type(ESMF_BaseTime) :: basetime  ! inherit base class
54         ! Relative year and month fields support monthly or yearly time 
55         ! intervals.  Many operations are undefined when these fields are 
56         ! non-zero!  
57         INTEGER :: YR                    ! relative year
58    !jm Month has no meaning for an interval; get rid of it, 20100319
59    !     INTEGER :: MM                    ! relative month
60       end type
62 !------------------------------------------------------------------------------
63 ! !PUBLIC TYPES:
64       public ESMF_TimeInterval
65 !------------------------------------------------------------------------------
67 ! !PUBLIC MEMBER FUNCTIONS:
68       public ESMF_TimeIntervalGet
69       public ESMF_TimeIntervalSet
70       public ESMFold_TimeIntervalGetString
71       public ESMF_TimeIntervalAbsValue
72       public ESMF_TimeIntervalNegAbsValue
74 ! Required inherited and overridden ESMF_Base class methods
76 !!!!!!!!! added 20051012, JM
77 !      public WRFADDITION_TimeIntervalDIVQuot 
78 !!!!!!!!! renamed to simplify testing 20060320, TH
79       public ESMF_TimeIntervalDIVQuot 
81       ! This convenience routine is only used by other modules in 
82       ! esmf_time_f90.  
83       public ESMF_TimeIntervalIsPositive
86 ! !PRIVATE MEMBER FUNCTIONS:
88 ! overloaded operator functions
90       public operator(/)
91       private ESMF_TimeIntervalQuotI
93       public operator(*)
94       private ESMF_TimeIntervalProdI
96 ! Inherited and overloaded from ESMF_BaseTime
98       public operator(+)
99       private ESMF_TimeIntervalSum
101       public operator(-)
102       private ESMF_TimeIntervalDiff
104       public operator(.EQ.)
105       private ESMF_TimeIntervalEQ
107       public operator(.NE.)
108       private ESMF_TimeIntervalNE
110       public operator(.LT.)
111       private ESMF_TimeIntervalLT
113       public operator(.GT.)
114       private ESMF_TimeIntervalGT
116       public operator(.LE.)
117       private ESMF_TimeIntervalLE
119       public operator(.GE.)
120       private ESMF_TimeIntervalGE
121 !EOPI
123 !==============================================================================
125 ! INTERFACE BLOCKS
127 !==============================================================================
128 !BOP
129 ! !INTERFACE:
130       interface operator(*)
132 ! !PRIVATE MEMBER FUNCTIONS:
133       module procedure ESMF_TimeIntervalProdI
135 ! !DESCRIPTION:
136 !     This interface overloads the * operator for the {\tt ESMF\_TimeInterval}
137 !     class
139 !EOP
140       end interface
142 !------------------------------------------------------------------------------
143 !BOP
144 ! !INTERFACE:
145       interface operator(/)
147 ! !PRIVATE MEMBER FUNCTIONS:
148       module procedure ESMF_TimeIntervalQuotI
150 ! !DESCRIPTION:
151 !     This interface overloads the / operator for the
152 !     {\tt ESMF\_TimeInterval} class
154 !EOP
155       end interface
157 !------------------------------------------------------------------------------
158 !BOP
159 ! !INTERFACE:
160       interface operator(+)
162 ! !PRIVATE MEMBER FUNCTIONS:
163       module procedure ESMF_TimeIntervalSum
165 ! !DESCRIPTION:
166 !     This interface overloads the + operator for the
167 !     {\tt ESMF\_TimeInterval} class
169 !EOP
170       end interface
172 !------------------------------------------------------------------------------
173 !BOP
174 ! !INTERFACE:
175       interface operator(-)
177 ! !PRIVATE MEMBER FUNCTIONS:
178       module procedure ESMF_TimeIntervalDiff
180 ! !DESCRIPTION:
181 !     This interface overloads the - operator for the
182 !     {\tt ESMF\_TimeInterval} class
184 !EOP
185       end interface
187 !------------------------------------------------------------------------------
188 !BOP
189 ! !INTERFACE:
190       interface operator(.EQ.)
192 ! !PRIVATE MEMBER FUNCTIONS:
193       module procedure ESMF_TimeIntervalEQ
195 ! !DESCRIPTION:
196 !     This interface overloads the .EQ. operator for the
197 !     {\tt ESMF\_TimeInterval} class
199 !EOP
200       end interface
202 !------------------------------------------------------------------------------
203 !BOP
204 ! !INTERFACE:
205       interface operator(.NE.)
207 ! !PRIVATE MEMBER FUNCTIONS:
208       module procedure ESMF_TimeIntervalNE
210 ! !DESCRIPTION:
211 !     This interface overloads the .NE. operator for the
212 !     {\tt ESMF\_TimeInterval} class
214 !EOP
215       end interface
217 !------------------------------------------------------------------------------
218 !BOP
219 ! !INTERFACE:
220       interface operator(.LT.)
222 ! !PRIVATE MEMBER FUNCTIONS:
223       module procedure ESMF_TimeIntervalLT
225 ! !DESCRIPTION:
226 !     This interface overloads the .LT. operator for the
227 !     {\tt ESMF\_TimeInterval} class
229 !EOP
230       end interface
232 !------------------------------------------------------------------------------
233 !BOP
234 ! !INTERFACE:
235       interface operator(.GT.)
237 ! !PRIVATE MEMBER FUNCTIONS:
238       module procedure ESMF_TimeIntervalGT
240 ! !DESCRIPTION:
241 !     This interface overloads the .GT. operator for the
242 !     {\tt ESMF\_TimeInterval} class
244 !EOP
245       end interface
247 !------------------------------------------------------------------------------
248 !BOP
249 ! !INTERFACE:
250       interface operator(.LE.)
252 ! !PRIVATE MEMBER FUNCTIONS:
253       module procedure ESMF_TimeIntervalLE
255 ! !DESCRIPTION:
256 !     This interface overloads the .LE. operator for the
257 !     {\tt ESMF\_TimeInterval} class
259 !EOP
260       end interface
262 !------------------------------------------------------------------------------
263 !BOP
264 ! !INTERFACE:
265       interface operator(.GE.)
267 ! !PRIVATE MEMBER FUNCTIONS:
268       module procedure ESMF_TimeIntervalGE
270 ! !DESCRIPTION:
271 !     This interface overloads the .GE. operator for the
272 !     {\tt ESMF\_TimeInterval} class
274 !EOP
275       end interface
277 !------------------------------------------------------------------------------
279 !==============================================================================
281       contains
283 !==============================================================================
285 ! Generic Get/Set routines which use F90 optional arguments
287 !------------------------------------------------------------------------------
288 !BOP
289 ! !IROUTINE: ESMF_TimeIntervalGet - Get value in user-specified units
291 ! !INTERFACE:
292       subroutine ESMF_TimeIntervalGet(timeinterval, D, d_r8, S, S_i8, Sn, Sd, &
293                                       TimeString, rc )
295 ! !ARGUMENTS:
296       type(ESMF_TimeInterval), intent(in) :: timeinterval
297       integer, intent(out), optional :: D
298       real(ESMF_KIND_R8),     intent(out), optional :: d_r8
299       integer(ESMF_KIND_I8),  intent(out), optional :: S_i8
300       integer, intent(out), optional :: S
301       integer, intent(out), optional :: Sn
302       integer, intent(out), optional :: Sd
303       character*(*), optional, intent(out) :: TimeString
304       integer, intent(out), optional :: rc
307 ! !DESCRIPTION:
308 !     Get the value of the {\tt ESMF\_TimeInterval} in units specified by the
309 !     user via F90 optional arguments.
311 !     Time manager represents and manipulates time internally with integers 
312 !     to maintain precision.  Hence, user-specified floating point values are
313 !     converted internally from integers.
315 !     See {\tt ../include/ESMC\_BaseTime.h} and
316 !     {\tt ../include/ESMC\_TimeInterval.h} for complete description.
317 !     
318 !     The arguments are:
319 !     \begin{description}
320 !     \item[timeinterval]
321 !          The object instance to query
322 !     \item[{[YY]}]
323 !          Integer years (>= 32-bit)
324 !     \item[{[YYl]}]
325 !          Integer years (large, >= 64-bit)
326 !     \item[{[MO]}]
327 !          Integer months (>= 32-bit)
328 !     \item[{[MOl]}]
329 !          Integer months (large, >= 64-bit)
330 !     \item[{[D]}]
331 !          Integer days (>= 32-bit)
332 !     \item[{[Dl]}]
333 !          Integer days (large, >= 64-bit)
334 !     \item[{[H]}]
335 !          Integer hours
336 !     \item[{[M]}]
337 !          Integer minutes
338 !     \item[{[S]}]
339 !          Integer seconds (>= 32-bit)
340 !     \item[{[Sl]}]
341 !          Integer seconds (large, >= 64-bit)
342 !     \item[{[MS]}]
343 !          Integer milliseconds
344 !     \item[{[US]}]
345 !          Integer microseconds
346 !     \item[{[NS]}]
347 !          Integer nanoseconds
348 !     \item[{[d\_]}]
349 !          Double precision days
350 !     \item[{[h\_]}]
351 !          Double precision hours
352 !     \item[{[m\_]}]
353 !          Double precision minutes
354 !     \item[{[s\_]}]
355 !          Double precision seconds
356 !     \item[{[ms\_]}]
357 !          Double precision milliseconds
358 !     \item[{[us\_]}]
359 !          Double precision microseconds
360 !     \item[{[ns\_]}]
361 !          Double precision nanoseconds
362 !     \item[{[Sn]}]
363 !          Integer fractional seconds - numerator
364 !     \item[{[Sd]}]
365 !          Integer fractional seconds - denominator
366 !     \item[{[rc]}]
367 !          Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
368 !     \end{description}
370 ! !REQUIREMENTS:
371 !     TMG1.1
373 ! Added argument to output double precision seconds, S_i8
374 ! William.Gustafson@pnl.gov; 9-May-2008
376 !EOP
377       INTEGER(ESMF_KIND_I8) :: seconds
378       INTEGER :: ierr
380       ierr = ESMF_SUCCESS
381       seconds = timeinterval%basetime%S
382       ! note that S is overwritten below (if present) if other args are also 
383       ! present
384       IF ( PRESENT(S) ) S = seconds
385       IF ( PRESENT(S_i8) ) S_i8 = seconds
386       IF ( PRESENT( D ) ) THEN
387         D = seconds / SECONDS_PER_DAY
388         IF ( PRESENT(S) )    S    = MOD( seconds, SECONDS_PER_DAY )
389         IF ( PRESENT(S_i8) ) S_i8 = MOD( seconds, SECONDS_PER_DAY )
390       ENDIF
391       IF ( PRESENT( d_r8 ) ) THEN
392         D_r8 = REAL( seconds, ESMF_KIND_R8 ) / &
393                REAL( SECONDS_PER_DAY, ESMF_KIND_R8 )
394         IF ( PRESENT(S) )    S    = MOD( seconds, SECONDS_PER_DAY )
395         IF ( PRESENT(S_i8) ) S_i8 = MOD( seconds, SECONDS_PER_DAY )
396       ENDIF
397       IF ( PRESENT(Sn) ) THEN
398         Sn = timeinterval%basetime%Sn
399       ENDIF
400       IF ( PRESENT(Sd) ) THEN
401         Sd = timeinterval%basetime%Sd
402       ENDIF
403       IF ( PRESENT( timeString ) ) THEN
404         CALL ESMFold_TimeIntervalGetString( timeinterval, timeString, rc=ierr )
405       ENDIF
406       IF ( PRESENT(rc) ) rc = ierr
407     
408       end subroutine ESMF_TimeIntervalGet
410 !------------------------------------------------------------------------------
411 !BOP
412 ! !IROUTINE: ESMF_TimeIntervalSet - Initialize via user-specified unit set
414 ! !INTERFACE:
415       subroutine ESMF_TimeIntervalSet(timeinterval, YY, YYl, MM, MOl, D, Dl, &
416                                       H, M, S, Sl, MS, US, NS, &
417                                       d_, h_, m_, s_, ms_, us_, ns_, &
418                                       Sn, Sd, rc)
420 ! !ARGUMENTS:
421       type(ESMF_TimeInterval), intent(out) :: timeinterval
422       integer, intent(in), optional :: YY
423       integer(ESMF_KIND_I8), intent(in), optional :: YYl
424       integer, intent(in), optional :: MM
425       integer(ESMF_KIND_I8), intent(in), optional :: MOl
426       integer, intent(in), optional :: D
427       integer(ESMF_KIND_I8), intent(in), optional :: Dl
428       integer, intent(in), optional :: H
429       integer, intent(in), optional :: M
430       integer, intent(in), optional :: S
431       integer(ESMF_KIND_I8), intent(in), optional :: Sl
432       integer, intent(in), optional :: MS
433       integer, intent(in), optional :: US
434       integer, intent(in), optional :: NS
435       double precision, intent(in), optional :: d_
436       double precision, intent(in), optional :: h_
437       double precision, intent(in), optional :: m_
438       double precision, intent(in), optional :: s_
439       double precision, intent(in), optional :: ms_
440       double precision, intent(in), optional :: us_
441       double precision, intent(in), optional :: ns_
442       integer, intent(in), optional :: Sn
443       integer, intent(in), optional :: Sd
444       integer, intent(out), optional :: rc
445       ! locals
446       INTEGER :: nfeb
448 ! !DESCRIPTION:
449 !     Set the value of the {\tt ESMF\_TimeInterval} in units specified by
450 !     the user via F90 optional arguments
452 !     Time manager represents and manipulates time internally with integers 
453 !     to maintain precision.  Hence, user-specified floating point values are
454 !     converted internally to integers.
456 !     See {\tt ../include/ESMC\_BaseTime.h} and
457 !     {\tt ../include/ESMC\_TimeInterval.h} for complete description.
459 !     The arguments are:
460 !     \begin{description}
461 !     \item[timeinterval]
462 !          The object instance to initialize
463 !     \item[{[YY]}]
464 !          Integer number of interval years (>= 32-bit)
465 !     \item[{[YYl]}]
466 !          Integer number of interval years (large, >= 64-bit)
467 !     \item[{[MM]}]
468 !          Integer number of interval months (>= 32-bit)
469 !     \item[{[MOl]}]
470 !          Integer number of interval months (large, >= 64-bit)
471 !     \item[{[D]}]
472 !          Integer number of interval days (>= 32-bit)
473 !     \item[{[Dl]}]
474 !          Integer number of interval days (large, >= 64-bit)
475 !     \item[{[H]}]
476 !          Integer hours
477 !     \item[{[M]}]
478 !          Integer minutes
479 !     \item[{[S]}]
480 !          Integer seconds (>= 32-bit)
481 !     \item[{[Sl]}]
482 !          Integer seconds (large, >= 64-bit)
483 !     \item[{[MS]}]
484 !          Integer milliseconds
485 !     \item[{[US]}]
486 !          Integer microseconds
487 !     \item[{[NS]}]
488 !          Integer nanoseconds
489 !     \item[{[d\_]}]
490 !          Double precision days
491 !     \item[{[h\_]}]
492 !          Double precision hours
493 !     \item[{[m\_]}]
494 !          Double precision minutes
495 !     \item[{[s\_]}]
496 !          Double precision seconds
497 !     \item[{[ms\_]}]
498 !          Double precision milliseconds
499 !     \item[{[us\_]}]
500 !          Double precision microseconds
501 !     \item[{[ns\_]}]
502 !          Double precision nanoseconds
503 !     \item[{[Sn]}]
504 !          Integer fractional seconds - numerator
505 !     \item[{[Sd]}]
506 !          Integer fractional seconds - denominator
507 !     \item[{[rc]}]
508 !          Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
509 !     \end{description}
511 ! !REQUIREMENTS:
512 !     TMGn.n.n
513 !EOP
515       IF ( PRESENT(rc) ) rc = ESMF_FAILURE
516       ! note that YR and MM are relative
517       timeinterval%YR = 0
518       IF ( PRESENT( YY ) ) THEN
519         timeinterval%YR = YY
520       ENDIF
521 !jm      timeinterval%MM = 0
522 !jm      IF ( PRESENT( MM ) ) THEN
523 !jm        timeinterval%MM = MM
524 !jm      ENDIF
525 !jm      ! Rollover months to years
526 !jm      IF      ( abs(timeinterval%MM) .GE. MONTHS_PER_YEAR ) THEN
527 !jm        timeinterval%YR = timeinterval%YR + timeinterval%MM/MONTHS_PER_YEAR
528 !jm        timeinterval%MM = mod(timeinterval%MM,MONTHS_PER_YEAR)
529 !jm      ENDIF
531       timeinterval%basetime%S = 0
532       ! For 365-day calendar, immediately convert years to days since we know 
533       ! how to do it in this case.  
534 !$$$ replace this hack with something saner...
535       IF ( nfeb( 2004 ) == 28 ) THEN
536         timeinterval%basetime%S = timeinterval%basetime%S + &
537           ( 365_ESMF_KIND_I8 * &
538             INT( timeinterval%YR, ESMF_KIND_I8 ) * SECONDS_PER_DAY )
539         timeinterval%YR = 0
540       ENDIF
541       IF ( PRESENT( D ) ) THEN
542         timeinterval%basetime%S = timeinterval%basetime%S + &
543           ( SECONDS_PER_DAY * INT( D, ESMF_KIND_I8 ) )
544       ENDIF
545 !$$$ Push H,M,S,Sn,Sd,MS down into BaseTime constructor from EVERYWHERE
546 !$$$ and THEN add ESMF scaling behavior when other args are present...  
547       IF ( PRESENT( H ) ) THEN
548         timeinterval%basetime%S = timeinterval%basetime%S + &
549           ( SECONDS_PER_HOUR * INT( H, ESMF_KIND_I8 ) )
550       ENDIF
551       IF ( PRESENT( M ) ) THEN
552         timeinterval%basetime%S = timeinterval%basetime%S + &
553           ( SECONDS_PER_MINUTE * INT( M, ESMF_KIND_I8 ) )
554       ENDIF
555       IF ( PRESENT( S ) ) THEN
556         timeinterval%basetime%S = timeinterval%basetime%S + &
557           INT( S, ESMF_KIND_I8 )
558       ENDIF
559       IF ( PRESENT( Sn ) .AND. ( .NOT. PRESENT( Sd ) ) ) THEN
560         CALL wrf_error_fatal( &
561           "ESMF_TimeIntervalSet:  Must specify Sd if Sn is specified")
562       ENDIF
563       IF ( PRESENT( Sd ) .AND. PRESENT( MS ) ) THEN
564         CALL wrf_error_fatal( &
565           "ESMF_TimeIntervalSet:  Must not specify both Sd and MS")
566       ENDIF
567       timeinterval%basetime%Sn = 0
568       timeinterval%basetime%Sd = 0
569       IF ( PRESENT( MS ) ) THEN
570         timeinterval%basetime%Sn = MS
571         timeinterval%basetime%Sd = 1000_ESMF_KIND_I8
572       ELSE IF ( PRESENT( Sd ) ) THEN
573         timeinterval%basetime%Sd = Sd
574         IF ( PRESENT( Sn ) ) THEN
575           timeinterval%basetime%Sn = Sn
576         ENDIF
577       ENDIF
578       CALL normalize_timeint( timeinterval )
580       IF ( PRESENT(rc) ) rc = ESMF_SUCCESS
582       end subroutine ESMF_TimeIntervalSet
584 !------------------------------------------------------------------------------
585 !BOP
586 ! !IROUTINE:  ESMFold_TimeIntervalGetString - Get time interval value in string format
588 ! !INTERFACE:
589       subroutine ESMFold_TimeIntervalGetString(timeinterval, TimeString, rc)
591 ! !ARGUMENTS:
592       type(ESMF_TimeInterval), intent(in) :: timeinterval
593       character*(*),  intent(out) :: TimeString
594       integer, intent(out), optional :: rc
595       ! locals
596       integer :: signnormtimeint
597       LOGICAL :: negative
598       INTEGER(ESMF_KIND_I8) :: iS, iSn, iSd, H, M, S
599       character (len=1) :: signstr
601 ! !DESCRIPTION:
602 !     Convert {\tt ESMF\_TimeInterval}'s value into string format
604 !     The arguments are:
605 !     \begin{description}
606 !     \item[timeinterval]
607 !          The object instance to convert
608 !     \item[TimeString]
609 !          The string to return
610 !     \item[{[rc]}]
611 !          Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
612 !     \end{description}
614 ! !REQUIREMENTS:
615 !     TMG1.5.9
616 !EOP
618 ! NOTE:  YR, MM, Sn, and Sd are not yet included in the returned string...  
619 !PRINT *,'DEBUG ESMFold_TimeIntervalGetString():  YR,MM,S,Sn,Sd = ', &
620 !        timeinterval%YR, &
621 !        timeinterval%MM, &
622 !        timeinterval%basetime%S, &
623 !        timeinterval%basetime%Sn, &
624 !        timeinterval%basetime%Sd
626       negative = ( signnormtimeint( timeInterval ) == -1 )
627       IF ( negative ) THEN
628         iS = -timeinterval%basetime%S
629         iSn = -timeinterval%basetime%Sn
630         signstr = '-'
631       ELSE
632         iS = timeinterval%basetime%S
633         iSn = timeinterval%basetime%Sn
634         signstr = ''
635       ENDIF 
636       iSd = timeinterval%basetime%Sd
638       H = mod( iS, SECONDS_PER_DAY ) / SECONDS_PER_HOUR
639       M = mod( iS, SECONDS_PER_HOUR) / SECONDS_PER_MINUTE
640       S = mod( iS, SECONDS_PER_MINUTE )
642 !$$$here...  need to print Sn and Sd when they are used ???
644       write(TimeString,FMT="(A,I10.10,'_',I3.3,':',I3.3,':',I3.3)") &
645         TRIM(signstr), ( iS / SECONDS_PER_DAY ), H, M, S
647 !write(0,*)'TimeIntervalGetString Sn ',timeinterval%basetime%Sn,' Sd ',timeinterval%basetime%Sd
649       rc = ESMF_SUCCESS
651       end subroutine ESMFold_TimeIntervalGetString
653 !------------------------------------------------------------------------------
654 !BOP
655 ! !IROUTINE:  ESMF_TimeIntervalAbsValue - Get the absolute value of a time interval
657 ! !INTERFACE:
658       function ESMF_TimeIntervalAbsValue(timeinterval)
660 ! !RETURN VALUE:
661       type(ESMF_TimeInterval) :: ESMF_TimeIntervalAbsValue
663 ! !ARGUMENTS:
664       type(ESMF_TimeInterval), intent(in) :: timeinterval
665 ! !LOCAL:
666       integer    :: rc
668 ! !DESCRIPTION:
669 !     Return a {\tt ESMF\_TimeInterval}'s absolute value.
671 !     The arguments are:
672 !     \begin{description}
673 !     \item[timeinterval]
674 !          The object instance to take the absolute value of.
675 !          Absolute value returned as value of function.
676 !     \end{description}
678 ! !REQUIREMENTS:
679 !     TMG1.5.8
680 !EOP
681       CALL timeintchecknormalized( timeinterval, 'ESMF_TimeIntervalAbsValue arg1' )
682       ESMF_TimeIntervalAbsValue = timeinterval
683 !$$$here...  move implementation into BaseTime
684       ESMF_TimeIntervalAbsValue%basetime%S  = &
685         abs(ESMF_TimeIntervalAbsValue%basetime%S)
686       ESMF_TimeIntervalAbsValue%basetime%Sn = &
687         abs(ESMF_TimeIntervalAbsValue%basetime%Sn )
689       end function ESMF_TimeIntervalAbsValue
691 !------------------------------------------------------------------------------
692 !BOP
693 ! !IROUTINE:  ESMF_TimeIntervalNegAbsValue - Get the negative absolute value of a time interval
695 ! !INTERFACE:
696       function ESMF_TimeIntervalNegAbsValue(timeinterval)
698 ! !RETURN VALUE:
699       type(ESMF_TimeInterval) :: ESMF_TimeIntervalNegAbsValue
701 ! !ARGUMENTS:
702       type(ESMF_TimeInterval), intent(in) :: timeinterval
703 ! !LOCAL:
704       integer    :: rc
706 ! !DESCRIPTION:
707 !     Return a {\tt ESMF\_TimeInterval}'s negative absolute value.
709 !     The arguments are:
710 !     \begin{description}
711 !     \item[timeinterval]
712 !          The object instance to take the negative absolute value of.
713 !          Negative absolute value returned as value of function.
714 !     \end{description}
716 ! !REQUIREMENTS:
717 !     TMG1.5.8
718 !EOP
719       CALL timeintchecknormalized( timeinterval, 'ESMF_TimeIntervalNegAbsValue arg1' )
720     
721       ESMF_TimeIntervalNegAbsValue = timeinterval
722 !$$$here...  move implementation into BaseTime
723       ESMF_TimeIntervalNegAbsValue%basetime%S  = &
724         -abs(ESMF_TimeIntervalNegAbsValue%basetime%S)
725       ESMF_TimeIntervalNegAbsValue%basetime%Sn = &
726         -abs(ESMF_TimeIntervalNegAbsValue%basetime%Sn )
728       end function ESMF_TimeIntervalNegAbsValue
730 !------------------------------------------------------------------------------
732 ! This section includes overloaded operators defined only for TimeInterval
733 ! (not inherited from BaseTime)
734 ! Note:  these functions do not have a return code, since F90 forbids more
735 ! than 2 arguments for arithmetic overloaded operators
737 !------------------------------------------------------------------------------
739 !!!!!!!!!!!!!!!!!! added jm 20051012
740 ! new WRF-specific function, Divide two time intervals and return the whole integer, without remainder
741       function ESMF_TimeIntervalDIVQuot(timeinterval1, timeinterval2)
743 ! !RETURN VALUE:
744       INTEGER :: ESMF_TimeIntervalDIVQuot 
746 ! !ARGUMENTS:
747       type(ESMF_TimeInterval), intent(in) :: timeinterval1
748       type(ESMF_TimeInterval), intent(in) :: timeinterval2
750 ! !LOCAL
751       INTEGER :: retval, isgn, rc
752       type(ESMF_TimeInterval) :: zero, i1,i2
754 ! !DESCRIPTION:
755 !     Returns timeinterval1 divided by timeinterval2 as a fraction quotient.
757 !     The arguments are:
758 !     \begin{description}
759 !     \item[timeinterval1]
760 !          The dividend
761 !     \item[timeinterval2]
762 !          The divisor
763 !     \end{description}
765 ! !REQUIREMENTS:
766 !     TMG1.5.5
767 !EOP
769       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalDIVQuot arg1' )
770       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalDIVQuot arg2' )
772       call ESMF_TimeIntervalSet( zero, rc=rc )
773       i1 = timeinterval1
774       i2 = timeinterval2
775       isgn = 1
776       if ( i1 .LT. zero ) then
777         i1 = ESMF_TimeIntervalProdI(i1, -1)
778         isgn = -isgn
779       endif
780       if ( i2 .LT. zero ) then
781         i2 = ESMF_TimeIntervalProdI(i2, -1)
782         isgn = -isgn
783       endif
784 ! repeated subtraction
785       retval = 0
786       DO WHILE (  i1 .GE. i2 )
787         i1 = i1 - i2
788         retval = retval + 1
789       ENDDO
790       retval = retval * isgn
792       ESMF_TimeIntervalDIVQuot = retval
794       end function ESMF_TimeIntervalDIVQuot
795 !!!!!!!!!!!!!!!!!!
799 !------------------------------------------------------------------------------
800 !BOP
801 ! !IROUTINE:  ESMF_TimeIntervalQuotI - Divide time interval by an integer, return time interval result 
803 ! !INTERFACE:
804       function ESMF_TimeIntervalQuotI(timeinterval, divisor)
806 ! !RETURN VALUE:
807       type(ESMF_TimeInterval) :: ESMF_TimeIntervalQuotI
809 ! !ARGUMENTS:
810       type(ESMF_TimeInterval), intent(in) :: timeinterval
811       integer, intent(in) :: divisor
813 ! !DESCRIPTION:
814 !     Divides a {\tt ESMF\_TimeInterval} by an integer divisor, returns
815 !     quotient as a {\tt ESMF\_TimeInterval}
817 !     The arguments are:
818 !     \begin{description}
819 !     \item[timeinterval]
820 !          The dividend
821 !     \item[divisor]
822 !          Integer divisor
823 !     \end{description}
825 ! !REQUIREMENTS:
826 !     TMG1.5.6, TMG5.3, TMG7.2
827 !EOP
829 !PRINT *,'DEBUG ESMF_TimeIntervalQuotI() A:  S,Sn,Sd = ', &
830 !  timeinterval%basetime%S,timeinterval%basetime%Sn,timeinterval%basetime%Sd
831 !PRINT *,'DEBUG ESMF_TimeIntervalQuotI() A:  divisor = ', divisor
833       CALL timeintchecknormalized( timeinterval, 'ESMF_TimeIntervalQuotI arg1' )
835       IF ( divisor == 0 ) THEN
836         CALL wrf_error_fatal( 'ESMF_TimeIntervalQuotI:  divide by zero' )
837       ENDIF
838       ESMF_TimeIntervalQuotI = timeinterval
839 !PRINT *,'DEBUG ESMF_TimeIntervalQuotI() B:  S,Sn,Sd = ', &
840 !  ESMF_TimeIntervalQuotI%basetime%S,ESMF_TimeIntervalQuotI%basetime%Sn,ESMF_TimeIntervalQuotI%basetime%Sd
841       ESMF_TimeIntervalQuotI%basetime = &
842         timeinterval%basetime / divisor
843 !PRINT *,'DEBUG ESMF_TimeIntervalQuotI() C:  S,Sn,Sd = ', &
844 !  ESMF_TimeIntervalQuotI%basetime%S,ESMF_TimeIntervalQuotI%basetime%Sn,ESMF_TimeIntervalQuotI%basetime%Sd
846       CALL normalize_timeint( ESMF_TimeIntervalQuotI )
847 !PRINT *,'DEBUG ESMF_TimeIntervalQuotI() D:  S,Sn,Sd = ', &
848 !  ESMF_TimeIntervalQuotI%basetime%S,ESMF_TimeIntervalQuotI%basetime%Sn,ESMF_TimeIntervalQuotI%basetime%Sd
850       end function ESMF_TimeIntervalQuotI
852 !------------------------------------------------------------------------------
853 !BOP
854 ! !IROUTINE:   ESMF_TimeIntervalProdI - Multiply a time interval by an integer
856 ! !INTERFACE:
857       function ESMF_TimeIntervalProdI(timeinterval, multiplier)
859 ! !RETURN VALUE:
860       type(ESMF_TimeInterval) :: ESMF_TimeIntervalProdI
862 ! !ARGUMENTS:
863       type(ESMF_TimeInterval), intent(in) :: timeinterval
864       integer, intent(in) :: multiplier
865 ! !LOCAL:
866       integer    :: rc
868 ! !DESCRIPTION:
869 !     Multiply a {\tt ESMF\_TimeInterval} by an integer, return product as a
870 !     {\tt ESMF\_TimeInterval}
872 !     The arguments are:
873 !     \begin{description}
874 !     \item[timeinterval]
875 !          The multiplicand
876 !     \item[mutliplier]
877 !          Integer multiplier
878 !     \end{description}
880 ! !REQUIREMENTS:
881 !     TMG1.5.7, TMG7.2
882 !EOP
883       CALL timeintchecknormalized( timeinterval, 'ESMF_TimeIntervalProdI arg1' )
885       CALL ESMF_TimeIntervalSet( ESMF_TimeIntervalProdI, rc=rc )
886 !$$$move this into overloaded operator(*) in BaseTime
887       ESMF_TimeIntervalProdI%basetime%S  = &
888         timeinterval%basetime%S * INT( multiplier, ESMF_KIND_I8 )
889       ESMF_TimeIntervalProdI%basetime%Sn = &
890         timeinterval%basetime%Sn * INT( multiplier, ESMF_KIND_I8 )
891       ! Don't multiply Sd
892       ESMF_TimeIntervalProdI%basetime%Sd = timeinterval%basetime%Sd
893       CALL normalize_timeint( ESMF_TimeIntervalProdI )
895       end function ESMF_TimeIntervalProdI
897 !------------------------------------------------------------------------------
899 ! This section includes the inherited ESMF_BaseTime class overloaded operators
901 !------------------------------------------------------------------------------
902 !BOP
903 ! !IROUTINE:  ESMF_TimeIntervalSum - Add two time intervals together
905 ! !INTERFACE:
906       function ESMF_TimeIntervalSum(timeinterval1, timeinterval2)
908 ! !RETURN VALUE:
909       type(ESMF_TimeInterval) :: ESMF_TimeIntervalSum
911 ! !ARGUMENTS:
912       type(ESMF_TimeInterval), intent(in) :: timeinterval1
913       type(ESMF_TimeInterval), intent(in) :: timeinterval2
914 ! !LOCAL:
915       integer                             :: rc
916 ! !DESCRIPTION:
917 !     Add two {\tt ESMF\_TimeIntervals}, return sum as a
918 !     {\tt ESMF\_TimeInterval}.  Maps overloaded (+) operator interface
919 !     function to {\tt ESMF\_BaseTime} base class.
921 !     The arguments are:
922 !     \begin{description}
923 !     \item[timeinterval1]
924 !          The augend 
925 !     \item[timeinterval2]
926 !          The addend
927 !     \end{description}
929 ! !REQUIREMENTS:
930 !     TMG1.5.4, TMG2.4.4, TMG2.4.5, TMG2.4.6, TMG5.1, TMG5.2, 
931 !                 TMG7.2
932 !EOP
933       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalSum arg1' )
934       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalSum arg2' )
936       ESMF_TimeIntervalSum = timeinterval1
937       ESMF_TimeIntervalSum%basetime = ESMF_TimeIntervalSum%basetime + &
938                                       timeinterval2%basetime
940       CALL normalize_timeint( ESMF_TimeIntervalSum )
942       end function ESMF_TimeIntervalSum
944 !------------------------------------------------------------------------------
945 !BOP
946 ! !IROUTINE:  ESMF_TimeIntervalDiff - Subtract one time interval from another
947    
948 ! !INTERFACE:
949       function ESMF_TimeIntervalDiff(timeinterval1, timeinterval2)
951 ! !RETURN VALUE:
952       type(ESMF_TimeInterval) :: ESMF_TimeIntervalDiff
954 ! !ARGUMENTS: 
955       type(ESMF_TimeInterval), intent(in) :: timeinterval1
956       type(ESMF_TimeInterval), intent(in) :: timeinterval2
957 ! !LOCAL:
958       integer                             :: rc
959 ! !DESCRIPTION:
960 !     Subtract timeinterval2 from timeinterval1, return remainder as a 
961 !     {\tt ESMF\_TimeInterval}.
962 !     Map overloaded (-) operator interface function to {\tt ESMF\_BaseTime}
963 !     base class.
965 !     The arguments are:
966 !     \begin{description}
967 !     \item[timeinterval1]
968 !          The minuend 
969 !     \item[timeinterval2]
970 !          The subtrahend
971 !     \end{description}
973 ! !REQUIREMENTS:
974 !     TMG1.5.4, TMG2.4.4, TMG2.4.5, TMG2.4.6, TMG5.1, TMG5.2, TMG7.2
975 !EOP
976       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalDiff arg1' )
977       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalDiff arg2' )
979       ESMF_TimeIntervalDiff = timeinterval1
980       ESMF_TimeIntervalDiff%basetime = ESMF_TimeIntervalDiff%basetime - &
981                                        timeinterval2%basetime
982       CALL normalize_timeint( ESMF_TimeIntervalDiff )
984       end function ESMF_TimeIntervalDiff
986 !------------------------------------------------------------------------------
987 !BOP
988 ! !IROUTINE: ESMF_TimeIntervalEQ - Compare two time intervals for equality
990 ! !INTERFACE:
991       function ESMF_TimeIntervalEQ(timeinterval1, timeinterval2)
993 ! !RETURN VALUE:
994       logical :: ESMF_TimeIntervalEQ
996 ! !ARGUMENTS:
997       type(ESMF_TimeInterval), intent(in) :: timeinterval1
998       type(ESMF_TimeInterval), intent(in) :: timeinterval2
1000 !DESCRIPTION:
1001 !     Return true if both given time intervals are equal, false otherwise.
1002 !     Maps overloaded (==) operator interface function to {\tt ESMF\_BaseTime}
1003 !     base class.
1005 !     The arguments are:
1006 !     \begin{description}
1007 !     \item[timeinterval1]
1008 !          First time interval to compare
1009 !     \item[timeinterval2]
1010 !          Second time interval to compare
1011 !     \end{description}
1013 ! !REQUIREMENTS:
1014 !     TMG1.5.3, TMG2.4.3, TMG7.2
1015 !EOP
1016       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalEQ arg1' )
1017       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalEQ arg2' )
1019 !$$$here...  move all this out of Meat.F90 ?  
1020       ! call ESMC_BaseTime base class function
1021       call c_ESMC_BaseTimeIntEQ(timeinterval1, timeinterval2, ESMF_TimeIntervalEQ)
1023       end function ESMF_TimeIntervalEQ
1025 !------------------------------------------------------------------------------
1026 !BOP
1027 ! !IROUTINE:  ESMF_TimeIntervalNE - Compare two time intervals for inequality
1029 ! !INTERFACE:
1030       function ESMF_TimeIntervalNE(timeinterval1, timeinterval2)
1032 ! !RETURN VALUE:
1033       logical :: ESMF_TimeIntervalNE
1035 ! !ARGUMENTS:
1036       type(ESMF_TimeInterval), intent(in) :: timeinterval1
1037       type(ESMF_TimeInterval), intent(in) :: timeinterval2
1039 ! !DESCRIPTION:
1040 !     Return true if both given time intervals are not equal, false otherwise.
1041 !     Maps overloaded (/=) operator interface function to {\tt ESMF\_BaseTime}
1042 !     base class.
1044 !     The arguments are:
1045 !     \begin{description}
1046 !     \item[timeinterval1]
1047 !          First time interval to compare
1048 !     \item[timeinterval2]
1049 !          Second time interval to compare
1050 !     \end{description}
1052 ! !REQUIREMENTS:
1053 !     TMG1.5.3, TMG2.4.3, TMG7.2
1054 !EOP
1055       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalNE arg1' )
1056       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalNE arg2' )
1058       ! call ESMC_BaseTime base class function
1059       call c_ESMC_BaseTimeIntNE(timeinterval1, timeinterval2, ESMF_TimeIntervalNE)
1061       end function ESMF_TimeIntervalNE
1063 !------------------------------------------------------------------------------
1064 !BOP
1065 ! !IROUTINE:  ESMF_TimeIntervalLT - Time interval 1 less than time interval 2 ?
1067 ! !INTERFACE:
1068       function ESMF_TimeIntervalLT(timeinterval1, timeinterval2)
1070 ! !RETURN VALUE:
1071       logical :: ESMF_TimeIntervalLT
1073 ! !ARGUMENTS:
1074       type(ESMF_TimeInterval), intent(in) :: timeinterval1
1075       type(ESMF_TimeInterval), intent(in) :: timeinterval2
1077 ! !DESCRIPTION:
1078 !     Return true if first time interval is less than second time interval,
1079 !     false otherwise. Maps overloaded (<) operator interface function to
1080 !     {\tt ESMF\_BaseTime} base class.
1082 !     The arguments are:
1083 !     \begin{description}
1084 !     \item[timeinterval1]
1085 !          First time interval to compare
1086 !     \item[timeinterval2]
1087 !          Second time interval to compare
1088 !     \end{description}
1090 ! !REQUIREMENTS:
1091 !     TMG1.5.3, TMG2.4.3, TMG7.2
1092 !EOP
1093       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalLT arg1' )
1094       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalLT arg2' )
1096       ! call ESMC_BaseTime base class function
1097       call c_ESMC_BaseTimeIntLT(timeinterval1, timeinterval2, ESMF_TimeIntervalLT)
1099       end function ESMF_TimeIntervalLT
1101 !------------------------------------------------------------------------------
1102 !BOP
1103 ! !IROUTINE:  ESMF_TimeIntervalGT - Time interval 1 greater than time interval 2?
1105 ! !INTERFACE:
1106       function ESMF_TimeIntervalGT(timeinterval1, timeinterval2)
1108 ! !RETURN VALUE:
1109       logical :: ESMF_TimeIntervalGT
1111 ! !ARGUMENTS:
1112       type(ESMF_TimeInterval), intent(in) :: timeinterval1
1113       type(ESMF_TimeInterval), intent(in) :: timeinterval2
1115 ! !DESCRIPTION:
1116 !     Return true if first time interval is greater than second time interval,
1117 !     false otherwise.  Maps overloaded (>) operator interface function to
1118 !     {\tt ESMF\_BaseTime} base class.
1120 !     The arguments are:
1121 !     \begin{description}
1122 !     \item[timeinterval1]
1123 !          First time interval to compare
1124 !     \item[timeinterval2]
1125 !          Second time interval to compare
1126 !     \end{description}
1128 ! !REQUIREMENTS:
1129 !     TMG1.5.3, TMG2.4.3, TMG7.2
1130 !EOP
1131       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalGT arg1' )
1132       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalGT arg2' )
1134       ! call ESMC_BaseTime base class function
1135       call c_ESMC_BaseTimeIntGT(timeinterval1, timeinterval2, ESMF_TimeIntervalGT)
1137       end function ESMF_TimeIntervalGT
1139 !------------------------------------------------------------------------------
1140 !BOP
1141 ! !IROUTINE:  ESMF_TimeIntervalLE - Time interval 1 less than or equal to time interval 2 ?
1143 ! !INTERFACE:
1144       function ESMF_TimeIntervalLE(timeinterval1, timeinterval2)
1146 ! !RETURN VALUE:
1147       logical :: ESMF_TimeIntervalLE
1149 ! !ARGUMENTS:
1150       type(ESMF_TimeInterval), intent(in) :: timeinterval1
1151       type(ESMF_TimeInterval), intent(in) :: timeinterval2
1153 ! !DESCRIPTION:
1154 !     Return true if first time interval is less than or equal to second time
1155 !     interval, false otherwise.
1156 !     Maps overloaded (<=) operator interface function to {\tt ESMF\_BaseTime}
1157 !     base class.
1159 !     The arguments are:
1160 !     \begin{description}
1161 !     \item[timeinterval1]
1162 !          First time interval to compare
1163 !     \item[timeinterval2]
1164 !          Second time interval to compare
1165 !     \end{description}
1167 ! !REQUIREMENTS:
1168 !     TMG1.5.3, TMG2.4.3, TMG7.2
1169 !EOP
1170       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalLE arg1' )
1171       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalLE arg2' )
1173       ! call ESMC_BaseTime base class function
1174       call c_ESMC_BaseTimeIntLE(timeinterval1, timeinterval2, ESMF_TimeIntervalLE)
1176       end function ESMF_TimeIntervalLE
1178 !------------------------------------------------------------------------------
1179 !BOP
1180 ! !IROUTINE:  ESMF_TimeIntervalGE - Time interval 1 greater than or equal to time interval 2 ?
1182 ! !INTERFACE:
1183       function ESMF_TimeIntervalGE(timeinterval1, timeinterval2)
1185 ! !RETURN VALUE:
1186       logical :: ESMF_TimeIntervalGE
1188 ! !ARGUMENTS:
1189       type(ESMF_TimeInterval), intent(in) :: timeinterval1
1190       type(ESMF_TimeInterval), intent(in) :: timeinterval2
1192 ! !DESCRIPTION:
1193 !     Return true if first time interval is greater than or equal to second
1194 !     time interval, false otherwise. Maps overloaded (>=) operator interface
1195 !     function to {\tt ESMF\_BaseTime} base class.
1197 !     The arguments are:
1198 !     \begin{description}
1199 !     \item[timeinterval1]
1200 !          First time interval to compare
1201 !     \item[timeinterval2]
1202 !          Second time interval to compare
1203 !     \end{description}
1205 ! !REQUIREMENTS:
1206 !     TMG1.5.3, TMG2.4.3, TMG7.2
1207 !EOP
1208       CALL timeintchecknormalized( timeinterval1, 'ESMF_TimeIntervalGE arg1' )
1209       CALL timeintchecknormalized( timeinterval2, 'ESMF_TimeIntervalGE arg2' )
1211       ! call ESMC_BaseTime base class function
1212       call c_ESMC_BaseTimeIntGE(timeinterval1, timeinterval2, ESMF_TimeIntervalGE)
1214       end function ESMF_TimeIntervalGE
1217 !------------------------------------------------------------------------------
1218 !BOP
1219 ! !IROUTINE:  ESMF_TimeIntervalIsPositive - Time interval greater than zero?
1221 ! !INTERFACE:
1222       function ESMF_TimeIntervalIsPositive(timeinterval)
1224 ! !RETURN VALUE:
1225       logical :: ESMF_TimeIntervalIsPositive
1227 ! !ARGUMENTS:
1228       type(ESMF_TimeInterval), intent(in) :: timeinterval
1230 ! !LOCALS:
1231       type(ESMF_TimeInterval) :: zerotimeint
1232       integer :: rcint
1234 ! !DESCRIPTION:
1235 !     Return true if time interval is greater than zero,  
1236 !     false otherwise. 
1238 !     The arguments are:
1239 !     \begin{description}
1240 !     \item[timeinterval]
1241 !          Time interval to compare
1242 !     \end{description}
1243 !EOP
1244       CALL timeintchecknormalized( timeinterval, &
1245                                    'ESMF_TimeIntervalIsPositive arg' )
1247       CALL ESMF_TimeIntervalSet ( zerotimeint, rc=rcint )
1248       IF ( rcint /= ESMF_SUCCESS ) THEN
1249         CALL wrf_error_fatal( &
1250           'ESMF_TimeIntervalIsPositive:  ESMF_TimeIntervalSet failed' )
1251       ENDIF
1252 ! hack for bug in PGI 5.1-x
1253 !      ESMF_TimeIntervalIsPositive = timeinterval > zerotimeint
1254       ESMF_TimeIntervalIsPositive = ESMF_TimeIntervalGT( timeinterval, &
1255                                                          zerotimeint )
1256       end function ESMF_TimeIntervalIsPositive
1258       end module WRF_ESMF_TimeIntervalMod