| 1 | ! |
|---|
| 2 | ! Earth System Modeling Framework |
|---|
| 3 | ! Copyright 2002-2003, University Corporation for Atmospheric Research, |
|---|
| 4 | ! Massachusetts Institute of Technology, Geophysical Fluid Dynamics |
|---|
| 5 | ! Laboratory, University of Michigan, National Centers for Environmental |
|---|
| 6 | ! Prediction, Los Alamos National Laboratory, Argonne National Laboratory, |
|---|
| 7 | ! NASA Goddard Space Flight Center. |
|---|
| 8 | ! Licensed under the University of Illinois-NCSA license. |
|---|
| 9 | ! |
|---|
| 10 | !============================================================================== |
|---|
| 11 | ! |
|---|
| 12 | ! ESMF BaseTime Module |
|---|
| 13 | module ESMF_BaseTimeMod |
|---|
| 14 | ! |
|---|
| 15 | !============================================================================== |
|---|
| 16 | ! |
|---|
| 17 | ! This file contains the BaseTime class definition and all BaseTime class |
|---|
| 18 | ! methods. |
|---|
| 19 | ! |
|---|
| 20 | !------------------------------------------------------------------------------ |
|---|
| 21 | ! INCLUDES |
|---|
| 22 | |
|---|
| 23 | #include <ESMF_TimeMgr.inc> |
|---|
| 24 | ! |
|---|
| 25 | !=============================================================================== |
|---|
| 26 | !BOPI |
|---|
| 27 | ! !MODULE: ESMF_BaseTimeMod - Base ESMF time definition |
|---|
| 28 | ! |
|---|
| 29 | ! !DESCRIPTION: |
|---|
| 30 | ! Part of Time Manager F90 API wrapper of C++ implemenation |
|---|
| 31 | ! |
|---|
| 32 | ! This module serves only as the common Time definition inherited |
|---|
| 33 | ! by {\tt ESMF\_TimeInterval} and {\tt ESMF\_Time} |
|---|
| 34 | ! |
|---|
| 35 | ! See {\tt ../include/ESMC\_BaseTime.h} for complete description |
|---|
| 36 | ! |
|---|
| 37 | !------------------------------------------------------------------------------ |
|---|
| 38 | ! !USES: |
|---|
| 39 | use ESMF_BaseMod ! ESMF Base class |
|---|
| 40 | implicit none |
|---|
| 41 | ! |
|---|
| 42 | !------------------------------------------------------------------------------ |
|---|
| 43 | ! !PRIVATE TYPES: |
|---|
| 44 | private |
|---|
| 45 | !------------------------------------------------------------------------------ |
|---|
| 46 | ! ! ESMF_BaseTime |
|---|
| 47 | ! |
|---|
| 48 | ! ! Base class type to match C++ BaseTime class in size only; |
|---|
| 49 | ! ! all dereferencing within class is performed by C++ implementation |
|---|
| 50 | |
|---|
| 51 | type ESMF_BaseTime |
|---|
| 52 | integer(ESMF_KIND_I8) :: S ! whole seconds |
|---|
| 53 | integer(ESMF_KIND_I8) :: Sn ! fractional seconds, numerator |
|---|
| 54 | integer(ESMF_KIND_I8) :: Sd ! fractional seconds, denominator |
|---|
| 55 | end type |
|---|
| 56 | |
|---|
| 57 | !------------------------------------------------------------------------------ |
|---|
| 58 | ! !PUBLIC TYPES: |
|---|
| 59 | public ESMF_BaseTime |
|---|
| 60 | !------------------------------------------------------------------------------ |
|---|
| 61 | ! |
|---|
| 62 | ! !PUBLIC MEMBER FUNCTIONS: |
|---|
| 63 | ! |
|---|
| 64 | ! overloaded operators |
|---|
| 65 | public operator(+) |
|---|
| 66 | private ESMF_BaseTimeSum |
|---|
| 67 | public operator(-) |
|---|
| 68 | private ESMF_BaseTimeDifference |
|---|
| 69 | public operator(/) |
|---|
| 70 | private ESMF_BaseTimeQuotI |
|---|
| 71 | private ESMF_BaseTimeQuotI8 |
|---|
| 72 | public operator(.EQ.) |
|---|
| 73 | private ESMF_BaseTimeEQ |
|---|
| 74 | public operator(.NE.) |
|---|
| 75 | private ESMF_BaseTimeNE |
|---|
| 76 | public operator(.LT.) |
|---|
| 77 | private ESMF_BaseTimeLT |
|---|
| 78 | public operator(.GT.) |
|---|
| 79 | private ESMF_BaseTimeGT |
|---|
| 80 | public operator(.LE.) |
|---|
| 81 | private ESMF_BaseTimeLE |
|---|
| 82 | public operator(.GE.) |
|---|
| 83 | private ESMF_BaseTimeGE |
|---|
| 84 | |
|---|
| 85 | !============================================================================== |
|---|
| 86 | ! |
|---|
| 87 | ! INTERFACE BLOCKS |
|---|
| 88 | ! |
|---|
| 89 | !============================================================================== |
|---|
| 90 | interface operator(+) |
|---|
| 91 | module procedure ESMF_BaseTimeSum |
|---|
| 92 | end interface |
|---|
| 93 | interface operator(-) |
|---|
| 94 | module procedure ESMF_BaseTimeDifference |
|---|
| 95 | end interface |
|---|
| 96 | interface operator(/) |
|---|
| 97 | module procedure ESMF_BaseTimeQuotI,ESMF_BaseTimeQuotI8 |
|---|
| 98 | end interface |
|---|
| 99 | interface operator(.EQ.) |
|---|
| 100 | module procedure ESMF_BaseTimeEQ |
|---|
| 101 | end interface |
|---|
| 102 | interface operator(.NE.) |
|---|
| 103 | module procedure ESMF_BaseTimeNE |
|---|
| 104 | end interface |
|---|
| 105 | interface operator(.LT.) |
|---|
| 106 | module procedure ESMF_BaseTimeLT |
|---|
| 107 | end interface |
|---|
| 108 | interface operator(.GT.) |
|---|
| 109 | module procedure ESMF_BaseTimeGT |
|---|
| 110 | end interface |
|---|
| 111 | interface operator(.LE.) |
|---|
| 112 | module procedure ESMF_BaseTimeLE |
|---|
| 113 | end interface |
|---|
| 114 | interface operator(.GE.) |
|---|
| 115 | module procedure ESMF_BaseTimeGE |
|---|
| 116 | end interface |
|---|
| 117 | |
|---|
| 118 | |
|---|
| 119 | !============================================================================== |
|---|
| 120 | |
|---|
| 121 | contains |
|---|
| 122 | |
|---|
| 123 | !============================================================================== |
|---|
| 124 | |
|---|
| 125 | |
|---|
| 126 | ! Add two basetimes |
|---|
| 127 | FUNCTION ESMF_BaseTimeSum( basetime1, basetime2 ) |
|---|
| 128 | TYPE(ESMF_BaseTime) :: ESMF_BaseTimeSum |
|---|
| 129 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime1 |
|---|
| 130 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime2 |
|---|
| 131 | ! locals |
|---|
| 132 | INTEGER (ESMF_KIND_I8) :: Sn1, Sd1, Sn2, Sd2, lcd |
|---|
| 133 | ! PRINT *,'DEBUG: BEGIN ESMF_BaseTimeSum()' |
|---|
| 134 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): basetime1%S = ',basetime1%S |
|---|
| 135 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): basetime1%Sn = ',basetime1%Sn |
|---|
| 136 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): basetime1%Sd = ',basetime1%Sd |
|---|
| 137 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): basetime2%S = ',basetime2%S |
|---|
| 138 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): basetime2%Sn = ',basetime2%Sn |
|---|
| 139 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): basetime2%Sd = ',basetime2%Sd |
|---|
| 140 | ESMF_BaseTimeSum = basetime1 |
|---|
| 141 | ESMF_BaseTimeSum%S = ESMF_BaseTimeSum%S + basetime2%S |
|---|
| 142 | Sn1 = basetime1%Sn |
|---|
| 143 | Sd1 = basetime1%Sd |
|---|
| 144 | Sn2 = basetime2%Sn |
|---|
| 145 | Sd2 = basetime2%Sd |
|---|
| 146 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): Sn1 = ',Sn1 |
|---|
| 147 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): Sd1 = ',Sd1 |
|---|
| 148 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): Sn2 = ',Sn2 |
|---|
| 149 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): Sd2 = ',Sd2 |
|---|
| 150 | IF ( ( Sd1 .EQ. 0 ) .AND. ( Sd2 .EQ. 0 ) ) THEN |
|---|
| 151 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): no fractions' |
|---|
| 152 | ESMF_BaseTimeSum%Sn = 0 |
|---|
| 153 | ESMF_BaseTimeSum%Sd = 0 |
|---|
| 154 | ELSE IF ( ( Sd1 .NE. 0 ) .AND. ( Sd2 .EQ. 0 ) ) THEN |
|---|
| 155 | ESMF_BaseTimeSum%Sn = Sn1 |
|---|
| 156 | ESMF_BaseTimeSum%Sd = Sd1 |
|---|
| 157 | ELSE IF ( ( Sd1 .EQ. 0 ) .AND. ( Sd2 .NE. 0 ) ) THEN |
|---|
| 158 | ESMF_BaseTimeSum%Sn = Sn2 |
|---|
| 159 | ESMF_BaseTimeSum%Sd = Sd2 |
|---|
| 160 | ELSE IF ( ( Sd1 .NE. 0 ) .AND. ( Sd2 .NE. 0 ) ) THEN |
|---|
| 161 | CALL compute_lcd( Sd1 , Sd2 , lcd ) |
|---|
| 162 | ESMF_BaseTimeSum%Sd = lcd |
|---|
| 163 | ESMF_BaseTimeSum%Sn = (Sn1 * lcd / Sd1) + (Sn2 * lcd / Sd2) |
|---|
| 164 | ENDIF |
|---|
| 165 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): ESMF_BaseTimeSum%S = ',ESMF_BaseTimeSum%S |
|---|
| 166 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): ESMF_BaseTimeSum%Sn = ',ESMF_BaseTimeSum%Sn |
|---|
| 167 | ! PRINT *,'DEBUG: ESMF_BaseTimeSum(): ESMF_BaseTimeSum%Sd = ',ESMF_BaseTimeSum%Sd |
|---|
| 168 | CALL normalize_basetime( ESMF_BaseTimeSum ) |
|---|
| 169 | ! PRINT *,'DEBUG: END ESMF_BaseTimeSum()' |
|---|
| 170 | END FUNCTION ESMF_BaseTimeSum |
|---|
| 171 | |
|---|
| 172 | |
|---|
| 173 | ! Subtract two basetimes |
|---|
| 174 | FUNCTION ESMF_BaseTimeDifference( basetime1, basetime2 ) |
|---|
| 175 | TYPE(ESMF_BaseTime) :: ESMF_BaseTimeDifference |
|---|
| 176 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime1 |
|---|
| 177 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime2 |
|---|
| 178 | ! locals |
|---|
| 179 | TYPE(ESMF_BaseTime) :: neg2 |
|---|
| 180 | |
|---|
| 181 | neg2%S = -basetime2%S |
|---|
| 182 | neg2%Sn = -basetime2%Sn |
|---|
| 183 | neg2%Sd = basetime2%Sd |
|---|
| 184 | |
|---|
| 185 | ESMF_BaseTimeDifference = basetime1 + neg2 |
|---|
| 186 | |
|---|
| 187 | END FUNCTION ESMF_BaseTimeDifference |
|---|
| 188 | |
|---|
| 189 | |
|---|
| 190 | ! Divide basetime by 8-byte integer |
|---|
| 191 | FUNCTION ESMF_BaseTimeQuotI8( basetime, divisor ) |
|---|
| 192 | TYPE(ESMF_BaseTime) :: ESMF_BaseTimeQuotI8 |
|---|
| 193 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime |
|---|
| 194 | INTEGER(ESMF_KIND_I8), INTENT(IN) :: divisor |
|---|
| 195 | ! locals |
|---|
| 196 | INTEGER(ESMF_KIND_I8) :: d, n, dinit |
|---|
| 197 | |
|---|
| 198 | !PRINT *,'DEBUG ESMF_BaseTimeQuotI8() A: S,Sn,Sd = ', & |
|---|
| 199 | ! basetime%S,basetime%Sn,basetime%Sd |
|---|
| 200 | !PRINT *,'DEBUG ESMF_BaseTimeQuotI8() A: divisor = ', divisor |
|---|
| 201 | IF ( divisor == 0_ESMF_KIND_I8 ) THEN |
|---|
| 202 | CALL wrf_error_fatal( 'ESMF_BaseTimeQuotI8: divide by zero' ) |
|---|
| 203 | ENDIF |
|---|
| 204 | |
|---|
| 205 | !$$$ move to default constructor |
|---|
| 206 | ESMF_BaseTimeQuotI8%S = 0 |
|---|
| 207 | ESMF_BaseTimeQuotI8%Sn = 0 |
|---|
| 208 | ESMF_BaseTimeQuotI8%Sd = 0 |
|---|
| 209 | |
|---|
| 210 | ! convert to a fraction and divide by multipling the denonminator by |
|---|
| 211 | ! the divisor |
|---|
| 212 | IF ( basetime%Sd == 0 ) THEN |
|---|
| 213 | dinit = 1_ESMF_KIND_I8 |
|---|
| 214 | ELSE |
|---|
| 215 | dinit = basetime%Sd |
|---|
| 216 | ENDIF |
|---|
| 217 | n = basetime%S * dinit + basetime%Sn |
|---|
| 218 | d = dinit * divisor |
|---|
| 219 | !PRINT *,'DEBUG ESMF_BaseTimeQuotI8() B: n,d = ',n,d |
|---|
| 220 | CALL simplify( n, d, ESMF_BaseTimeQuotI8%Sn, ESMF_BaseTimeQuotI8%Sd ) |
|---|
| 221 | !PRINT *,'DEBUG ESMF_BaseTimeQuotI8() C: S,Sn,Sd = ', & |
|---|
| 222 | ! ESMF_BaseTimeQuotI8%S,ESMF_BaseTimeQuotI8%Sn,ESMF_BaseTimeQuotI8%Sd |
|---|
| 223 | CALL normalize_basetime( ESMF_BaseTimeQuotI8 ) |
|---|
| 224 | !PRINT *,'DEBUG ESMF_BaseTimeQuotI8() D: S,Sn,Sd = ', & |
|---|
| 225 | ! ESMF_BaseTimeQuotI8%S,ESMF_BaseTimeQuotI8%Sn,ESMF_BaseTimeQuotI8%Sd |
|---|
| 226 | END FUNCTION ESMF_BaseTimeQuotI8 |
|---|
| 227 | |
|---|
| 228 | ! Divide basetime by integer |
|---|
| 229 | FUNCTION ESMF_BaseTimeQuotI( basetime, divisor ) |
|---|
| 230 | TYPE(ESMF_BaseTime) :: ESMF_BaseTimeQuotI |
|---|
| 231 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime |
|---|
| 232 | INTEGER, INTENT(IN) :: divisor |
|---|
| 233 | IF ( divisor == 0 ) THEN |
|---|
| 234 | CALL wrf_error_fatal( 'ESMF_BaseTimeQuotI: divide by zero' ) |
|---|
| 235 | ENDIF |
|---|
| 236 | ESMF_BaseTimeQuotI = basetime / INT( divisor, ESMF_KIND_I8 ) |
|---|
| 237 | END FUNCTION ESMF_BaseTimeQuotI |
|---|
| 238 | |
|---|
| 239 | |
|---|
| 240 | ! .EQ. for two basetimes |
|---|
| 241 | FUNCTION ESMF_BaseTimeEQ( basetime1, basetime2 ) |
|---|
| 242 | LOGICAL :: ESMF_BaseTimeEQ |
|---|
| 243 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime1 |
|---|
| 244 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime2 |
|---|
| 245 | INTEGER :: retval |
|---|
| 246 | CALL seccmp( basetime1%S, basetime1%Sn, basetime1%Sd, & |
|---|
| 247 | basetime2%S, basetime2%Sn, basetime2%Sd, & |
|---|
| 248 | retval ) |
|---|
| 249 | ESMF_BaseTimeEQ = ( retval .EQ. 0 ) |
|---|
| 250 | END FUNCTION ESMF_BaseTimeEQ |
|---|
| 251 | |
|---|
| 252 | |
|---|
| 253 | ! .NE. for two basetimes |
|---|
| 254 | FUNCTION ESMF_BaseTimeNE( basetime1, basetime2 ) |
|---|
| 255 | LOGICAL :: ESMF_BaseTimeNE |
|---|
| 256 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime1 |
|---|
| 257 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime2 |
|---|
| 258 | INTEGER :: retval |
|---|
| 259 | CALL seccmp( basetime1%S, basetime1%Sn, basetime1%Sd, & |
|---|
| 260 | basetime2%S, basetime2%Sn, basetime2%Sd, & |
|---|
| 261 | retval ) |
|---|
| 262 | ESMF_BaseTimeNE = ( retval .NE. 0 ) |
|---|
| 263 | END FUNCTION ESMF_BaseTimeNE |
|---|
| 264 | |
|---|
| 265 | |
|---|
| 266 | ! .LT. for two basetimes |
|---|
| 267 | FUNCTION ESMF_BaseTimeLT( basetime1, basetime2 ) |
|---|
| 268 | LOGICAL :: ESMF_BaseTimeLT |
|---|
| 269 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime1 |
|---|
| 270 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime2 |
|---|
| 271 | INTEGER :: retval |
|---|
| 272 | CALL seccmp( basetime1%S, basetime1%Sn, basetime1%Sd, & |
|---|
| 273 | basetime2%S, basetime2%Sn, basetime2%Sd, & |
|---|
| 274 | retval ) |
|---|
| 275 | ESMF_BaseTimeLT = ( retval .LT. 0 ) |
|---|
| 276 | END FUNCTION ESMF_BaseTimeLT |
|---|
| 277 | |
|---|
| 278 | |
|---|
| 279 | ! .GT. for two basetimes |
|---|
| 280 | FUNCTION ESMF_BaseTimeGT( basetime1, basetime2 ) |
|---|
| 281 | LOGICAL :: ESMF_BaseTimeGT |
|---|
| 282 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime1 |
|---|
| 283 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime2 |
|---|
| 284 | INTEGER :: retval |
|---|
| 285 | CALL seccmp( basetime1%S, basetime1%Sn, basetime1%Sd, & |
|---|
| 286 | basetime2%S, basetime2%Sn, basetime2%Sd, & |
|---|
| 287 | retval ) |
|---|
| 288 | ESMF_BaseTimeGT = ( retval .GT. 0 ) |
|---|
| 289 | END FUNCTION ESMF_BaseTimeGT |
|---|
| 290 | |
|---|
| 291 | |
|---|
| 292 | ! .LE. for two basetimes |
|---|
| 293 | FUNCTION ESMF_BaseTimeLE( basetime1, basetime2 ) |
|---|
| 294 | LOGICAL :: ESMF_BaseTimeLE |
|---|
| 295 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime1 |
|---|
| 296 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime2 |
|---|
| 297 | INTEGER :: retval |
|---|
| 298 | CALL seccmp( basetime1%S, basetime1%Sn, basetime1%Sd, & |
|---|
| 299 | basetime2%S, basetime2%Sn, basetime2%Sd, & |
|---|
| 300 | retval ) |
|---|
| 301 | ESMF_BaseTimeLE = ( retval .LE. 0 ) |
|---|
| 302 | END FUNCTION ESMF_BaseTimeLE |
|---|
| 303 | |
|---|
| 304 | |
|---|
| 305 | ! .GE. for two basetimes |
|---|
| 306 | FUNCTION ESMF_BaseTimeGE( basetime1, basetime2 ) |
|---|
| 307 | LOGICAL :: ESMF_BaseTimeGE |
|---|
| 308 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime1 |
|---|
| 309 | TYPE(ESMF_BaseTime), INTENT(IN) :: basetime2 |
|---|
| 310 | INTEGER :: retval |
|---|
| 311 | CALL seccmp( basetime1%S, basetime1%Sn, basetime1%Sd, & |
|---|
| 312 | basetime2%S, basetime2%Sn, basetime2%Sd, & |
|---|
| 313 | retval ) |
|---|
| 314 | ESMF_BaseTimeGE = ( retval .GE. 0 ) |
|---|
| 315 | END FUNCTION ESMF_BaseTimeGE |
|---|
| 316 | |
|---|
| 317 | |
|---|
| 318 | end module ESMF_BaseTimeMod |
|---|