source: trunk/WRF.COMMON/WRFV3/external/esmf_time_f90/ESMF_Calendar.F90 @ 3567

Last change on this file since 3567 was 2759, checked in by aslmd, 2 years ago

adding unmodified code from WRFV3.0.1.1, expurged from useless data +1M size

File size: 10.2 KB
Line 
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 Calendar Module
13      module ESMF_CalendarMod
14!
15!==============================================================================
16!
17! This file contains the Calendar class definition and all Calendar class
18! methods.
19!
20!------------------------------------------------------------------------------
21! INCLUDES
22#include <ESMF_TimeMgr.inc>
23
24!==============================================================================
25!BOPI
26! !MODULE: ESMF_CalendarMod
27!
28! !DESCRIPTION:
29! Part of Time Manager F90 API wrapper of C++ implemenation
30!
31! Defines F90 wrapper entry points for corresponding
32! C++ class { \tt ESMC\_Calendar} implementation
33!
34! See {\tt ../include/ESMC\_Calendar.h} for complete description
35!
36!------------------------------------------------------------------------------
37! !USES:
38      ! inherit from ESMF base class
39      use ESMF_BaseMod
40
41      ! inherit from base time class
42      use ESMF_BaseTimeMod
43
44      implicit none
45!
46!------------------------------------------------------------------------------
47! !PRIVATE TYPES:
48      private
49!------------------------------------------------------------------------------
50
51
52
53      INTEGER, PARAMETER :: MONTHS_PER_YEAR = 12
54      INTEGER, PARAMETER :: mday(MONTHS_PER_YEAR)   &
55                          = (/31,28,31,30,31,30,31,31,30,31,30,31/)
56      INTEGER, PARAMETER :: mdayleap(MONTHS_PER_YEAR) &
57                          = (/31,29,31,30,31,30,31,31,30,31,30,31/)
58      INTEGER, DIMENSION(365) :: daym
59      INTEGER, DIMENSION(366) :: daymleap
60      INTEGER :: mdaycum(0:MONTHS_PER_YEAR)
61      INTEGER :: mdayleapcum(0:MONTHS_PER_YEAR)
62      TYPE(ESMF_BaseTime), TARGET :: monthbdys(0:MONTHS_PER_YEAR)
63      TYPE(ESMF_BaseTime), TARGET :: monthbdysleap(0:MONTHS_PER_YEAR)
64
65
66!------------------------------------------------------------------------------
67!     ! ESMF_CalendarType
68!
69!     ! F90 "enum" type to match C++ ESMC_CalendarType enum
70
71      type ESMF_CalendarType
72      private
73        integer :: caltype
74      end type
75
76      type(ESMF_CalendarType), parameter :: &
77                               ESMF_CAL_GREGORIAN =  ESMF_CalendarType(1), &
78                               ESMF_CAL_JULIAN =     ESMF_CalendarType(2), &
79                           ! like Gregorian, except Feb always has 28 days
80                               ESMF_CAL_NOLEAP =     ESMF_CalendarType(3), &
81                           ! 12 months, 30 days each
82                               ESMF_CAL_360DAY =     ESMF_CalendarType(4), &
83                           ! user defined
84                               ESMF_CAL_GENERIC =    ESMF_CalendarType(5), &
85                           ! track base time seconds only
86                               ESMF_CAL_NOCALENDAR = ESMF_CalendarType(6)
87
88!------------------------------------------------------------------------------
89!     ! ESMF_Calendar
90!
91!     ! F90 class type to match C++ Calendar class in size only;
92!     !  all dereferencing within class is performed by C++ implementation
93!
94!------------------------------------------------------------------------------
95!
96!     ! ESMF_DaysPerYear
97!
98      type ESMF_DaysPerYear
99      private
100        integer :: D        ! whole days per year
101! Fractional days-per-year are not yet used in this implementation. 
102!        integer :: Dn       ! fractional days per year numerator
103!        integer :: Dd       ! fractional days per year denominator
104      end type              ! e.g. for Venus, D=0, Dn=926, Dd=1000
105!
106!------------------------------------------------------------------------------
107!     ! ESMF_Calendar
108!
109!
110      type ESMF_Calendar
111      private
112        type(ESMF_CalendarType) :: Type
113! TBH:  When NO_DT_COMPONENT_INIT is set, code that uses F95 compile-time
114! TBH:  initialization of components of derived types is not included. 
115! TBH:  Some older compilers, like PGI 5.x do not support this F95 feature. 
116#ifdef NO_DT_COMPONENT_INIT
117        logical :: Set
118#else
119        logical :: Set = .false.
120#endif
121        integer, dimension(MONTHS_PER_YEAR) :: DaysPerMonth
122        integer :: SecondsPerDay
123        integer :: SecondsPerYear
124        type(ESMF_DaysPerYear) :: DaysPerYear
125      end type
126
127!------------------------------------------------------------------------------
128! !PUBLIC DATA:
129   TYPE(ESMF_Calendar), public, save, pointer :: defaultCal   ! Default Calendar
130
131
132!
133!------------------------------------------------------------------------------
134! !PUBLIC TYPES:
135      public MONTHS_PER_YEAR
136      public mday
137      public mdayleap
138      public monthbdys
139      public monthbdysleap
140      public daym
141      public daymleap
142      public mdaycum
143      public mdayleapcum
144      public ESMF_CalendarType
145      public ESMF_CAL_GREGORIAN, ESMF_CAL_NOLEAP, &
146             ESMF_CAL_360DAY, ESMF_CAL_NOCALENDAR
147!      public ESMF_CAL_JULIAN
148!      public ESMF_CAL_GENERIC
149      public ESMF_Calendar
150
151!------------------------------------------------------------------------------
152!
153! !PUBLIC MEMBER FUNCTIONS:
154      public ESMF_CalendarCreate
155
156! Required inherited and overridden ESMF_Base class methods
157
158      public ESMF_CalendarInitialized ! Only in this implementation, intended
159                                      ! to be private within ESMF methods
160!EOPI
161
162!==============================================================================
163
164      contains
165
166
167!==============================================================================
168!BOP
169! !IROUTINE: ESMF_CalendarCreate - Create a new ESMF Calendar of built-in type
170
171! !INTERFACE:
172      ! Private name; call using ESMF_CalendarCreate()
173      function ESMF_CalendarCreate(name, calendartype, rc)
174
175! !RETURN VALUE:
176      type(ESMF_Calendar) :: ESMF_CalendarCreate
177
178! !ARGUMENTS:
179      character (len=*),       intent(in),  optional :: name
180      type(ESMF_CalendarType), intent(in)            :: calendartype
181      integer,                 intent(out), optional :: rc
182
183! !DESCRIPTION:
184!     Creates and sets a {\tt calendar} to the given built-in
185!     {\tt ESMF\_CalendarType}.
186!
187!     This is a private method; invoke via the public overloaded entry point
188!     {\tt ESMF\_CalendarCreate()}.
189!
190!     The arguments are:
191!     \begin{description}
192!     \item[{[name]}]
193!          The name for the newly created calendar.  If not specified, a
194!          default unique name will be generated: "CalendarNNN" where NNN
195!          is a unique sequence number from 001 to 999.
196!     \item[calendartype]
197!          The built-in {\tt ESMF\_CalendarType}.  Valid values are:
198!            {\tt ESMF\_CAL\_360DAY}, {\tt ESMF\_CAL\_GREGORIAN},
199!            {\tt ESMF\_CAL\_JULIANDAY}, {\tt ESMF\_CAL\_NOCALENDAR}, and
200!            {\tt ESMF\_CAL\_NOLEAP}.
201!          See the "Time Manager Reference" document for a description of
202!          each calendar type.
203!     \item[{[rc]}]
204!          Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
205!     \end{description}
206!   
207!EOP
208! !REQUIREMENTS:
209!     TMGn.n.n
210      type(ESMF_DaysPerYear) :: dayspy
211
212      if ( present(rc) ) rc = ESMF_FAILURE
213! Calendar type is hard-coded.  Use ESMF library if more flexibility is
214! needed. 
215#ifdef NO_LEAP_CALENDAR
216      if ( calendartype%caltype  /= ESMF_CAL_NOLEAP%caltype ) then
217         write(6,*) 'Not a valid calendar type for this implementation'
218         write(6,*) 'This implementation only allows ESMF_CAL_NOLEAP'
219         write(6,*) 'calender type set to     = ', calendartype%caltype
220         write(6,*) 'NO_LEAP calendar type is = ', ESMF_CAL_NOLEAP%caltype
221         return
222      end if
223      ESMF_CalendarCreate%Type = ESMF_CAL_NOLEAP
224#else
225      if ( calendartype%caltype  /= ESMF_CAL_GREGORIAN%caltype ) then
226         write(6,*) 'Not a valid calendar type for this implementation'
227         write(6,*) 'This implementation only allows ESMF_CAL_GREGORIAN'
228         write(6,*) 'calender type set to     = ', calendartype%caltype
229         write(6,*) 'GREGORIAN calendar type is = ', ESMF_CAL_GREGORIAN%caltype
230         return
231      end if
232      ESMF_CalendarCreate%Type = ESMF_CAL_GREGORIAN
233#endif
234! This is a bug on some systems -- need initial value set by compiler at
235! startup. 
236! However, note that some older compilers do not support compile-time
237! initialization of data members of Fortran derived data types.  For example,
238! PGI 5.x compilers do not support this F95 feature.  See
239! NO_DT_COMPONENT_INIT. 
240      ESMF_CalendarCreate%Set = .true.
241      ESMF_CalendarCreate%SecondsPerDay = SECONDS_PER_DAY
242! DaysPerYear and SecondsPerYear are incorrect for Gregorian calendars... 
243      dayspy%D = size(daym)
244!TBH:  TODO:  Replace DaysPerYear and SecondsPerYear with methods
245!TBH:  TODO:  since they only make sense for the NO_LEAP calendar! 
246      ESMF_CalendarCreate%DaysPerYear = dayspy
247      ESMF_CalendarCreate%SecondsPerYear = ESMF_CalendarCreate%SecondsPerDay &
248                                       * dayspy%D
249!TBH:  TODO:  use mdayleap for leap-year calendar
250      ESMF_CalendarCreate%DaysPerMonth(:) = mday(:)
251
252      if ( present(rc) ) rc = ESMF_SUCCESS
253
254      end function ESMF_CalendarCreate
255
256
257!==============================================================================
258!BOP
259! !IROUTINE: ESMF_CalendarInitialized - check if calendar was created
260
261! !INTERFACE:
262      function ESMF_CalendarInitialized(calendar)
263
264! !RETURN VALUE:
265      logical ESMF_CalendarInitialized
266
267! !ARGUMENTS:
268      type(ESMF_Calendar), intent(in)            :: calendar
269
270! !DESCRIPTION:
271!EOP
272! !REQUIREMENTS:
273!     TMGn.n.n
274! Note that return value from this function will be bogus for older compilers
275! that do not support compile-time initialization of data members of Fortran
276! derived data types.  For example, PGI 5.x compilers do not support this F95
277! feature.  At the moment, the call to this fuction is #ifdefd out when the
278! leap-year calendar is used so this is not an issue for WRF (see
279! NO_DT_COMPONENT_INIT). 
280        ESMF_CalendarInitialized = calendar%set
281
282     end function ESMF_CalendarInitialized
283
284      end module ESMF_CalendarMod
Note: See TracBrowser for help on using the repository browser.