~fluidity-core/fluidity/exorcised

1 by hhiester
deleting initialisation as none of tools are used any longer.
1
/*  Copyright (C) 2006 Imperial College London and others.
2
    
3
    Please see the AUTHORS file in the main source directory for a full list
4
    of copyright holders.
5
6
    Dr Gerard Gorman
7
    Applied Modelling and Computation Group
8
    Department of Earth Science and Engineering
9
    Imperial College London
10
11
    g.gorman@imperial.ac.uk
12
    
13
    This library is free software; you can redistribute it and/or
14
    modify it under the terms of the GNU Lesser General Public
15
    License as published by the Free Software Foundation,
16
    version 2.1 of the License.
17
18
    This library is distributed in the hope that it will be useful,
19
    but WITHOUT ANY WARRANTY; without even the implied warranty of
20
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21
    Lesser General Public License for more details.
22
23
    You should have received a copy of the GNU Lesser General Public
24
    License along with this library; if not, write to the Free Software
25
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
26
    USA
27
*/
28
#ifndef CALENDAR_H
29
#define CALENDAR_H
30
31
#include "confdefs.h"
32
33
#include "c++debug.h"
34
35
#include <cassert>
36
#include <iostream>
37
#include <string>
38
39
#ifdef HAVE_LIBUDUNITS
40
extern "C"{
41
#include <udunits.h>
42
  // The udunits people forgot to include this in their header file
43
  // int utIsInit();
44
  extern int utIsInit PROTO(());
45
}
46
#endif
47
#include <stdlib.h>
48
49
  /* Adapted from the NetCDF CF-convention
50
     In order to calculate a new date and time given a base date, base
51
     time and a time increment one must know what calendar to use. For
52
     this purpose NetCDF CF-conventions recommend that the calendar be
53
     specified by the NetCDF attribute calendar which is assigned to
54
     the time coordinate variable. The values currently defined for
55
     calendar are:
56
57
     gregorian or standard: Mixed Gregorian/Julian calendar as defined
58
     by Udunits. This is the default.
59
60
     proleptic_gregorian: A Gregorian calendar extended to dates
61
     before 1582-10-15. That is, a year is a leap year if either (i)
62
     it is divisible by 4 but not by 100 or (ii) it is divisible by
63
     400.
64
65
     noleap or 365_day: Gregorian calendar without leap years, i.e.,
66
     all years are 365 days long.
67
68
     all_leap or 366_day: Gregorian calendar with every year being a
69
     leap year, i.e., all years are 366 days long.
70
71
     360_day: All years are 360 days divided into 30 day months. 
72
73
     julian: Julian calendar.
74
75
     none: No calendar. 
76
77
     The calendar attribute may be set to none in climate experiments
78
     that simulate a fixed time of year. The time of year is indicated
79
     by the date in the reference time of the units attribute. The
80
     time coordinate that might apply in a perpetual July experiment
81
     are given in the following example.
82
83
     Example 4.5. Perpetual time axis
84
     
85
variables:
86
  double time(time) ;
87
    time:long_name = "time" ;
88
    time:units = "days since 1-7-15 0:0:0" ;
89
    time:calendar = "none" ;
90
data:
91
  time = 0., 1., 2., ...;
92
      
93
94
95
     Here, all days simulate the conditions of 15th July, so it does
96
     not make sense to give them different dates. The time coordinates
97
     are interpreted as 0, 1, 2, etc. days since the start of the
98
     experiment.
99
100
     If none of the calendars defined above applies (e.g., calendars
101
     appropriate to a different paleoclimate era), a non-standard
102
     calendar can be defined. The lengths of each month are explicitly
103
     defined with the month_lengths attribute of the time axis:
104
105
     month_lengths: A vector of size 12, specifying the number of days
106
     in the months from January to December (in a non-leap year).
107
108
     leap_year: If leap years are included, then two other attributes
109
     of the time axis should also be defined:
110
111
     leap_month: An example of a leap year. It is assumed that all
112
     years that differ from this year by a multiple of four are also
113
     leap years. If this attribute is absent, it is assumed there are
114
     no leap years.
115
116
117
     A value in the range 1-12, specifying which month is lengthened
118
     by a day in leap years (1=January). If this attribute is not
119
     present, February (2) is assumed. This attribute is ignored if
120
     leap_year is not specified.
121
122
     The calendar attribute is not required when a non-standard
123
     calendar is being used. It is sufficient to define the calendar
124
     using the month_lengths attribute, along with leap_year, and
125
     leap_month as appropriate. However, the calendar attribute is
126
     allowed to take non-standard values and in that case defining the
127
     non-standard calendar using the appropriate attributes is
128
     required.
129
130
Example 4.6. Paleoclimate time axis
131
132
double time(time) ;
133
  time:long_name = "time" ;
134
  time:units = "days since 1-1-1 0:0:0" ;
135
  time:calendar = "126 kyr B.P." ;
136
  time:month_lengths = 34, 31, 32, 30, 29, 27, 28, 28, 28, 32, 32, 34 ;
137
	
138
     The mixed Gregorian/Julian calendar used by Udunits is explained
139
     in the following excerpt from the udunits(3) man page:
140
141
     The udunits(3) package uses a mixed Gregorian/Julian  calen-
142
     dar  system.   Dates  prior to 1582-10-15 are assumed to use
143
     the Julian calendar, which was introduced by  Julius  Caesar
144
     in 46 BCE and is based on a year that is exactly 365.25 days
145
     long.  Dates on and after 1582-10-15 are assumed to use  the
146
     Gregorian calendar, which was introduced on that date and is
147
     based on a year that is exactly 365.2425 days long.  (A year
148
     is  actually  approximately 365.242198781 days long.)  Seem-
149
     ingly strange behavior of the udunits(3) package can  result
150
     if  a user-given time interval includes the changeover date.
151
     For example, utCalendar() and utInvCalendar() can be used to
152
     show that 1582-10-15 *preceded* 1582-10-14 by 9 days.
153
     
154
     
155
     Due to problems caused by the discontinuity in the default mixed
156
     Gregorian/Julian calendar, we strongly recommend that this
157
     calendar should only be used when the time coordinate does not
158
     cross the discontinuity. For time coordinates that do cross the
159
     discontinuity the proleptic_gregorian calendar should be used
160
     instead.
161
  */
162
163
class Calendar{
164
  // This class aims to implement calander tools to conform to NetCDF
165
  // Climate and Forecast (CF) Metadata Conventions.
166
  //
167
  // http://www.cgd.ucar.edu/cms/eaton/cf-metadata/CF-1.0.html
168
 public:
169
  Calendar();
170
  Calendar(const Calendar&);
171
  const Calendar& operator=(const Calendar &);
172
173
  ~Calendar();
174
175
  int Convert(double from_value, double& to_value);
176
  int SetTransformation(std::string from_unit, std::string to_unit, std::string calendar);
177
  
178
 private:
179
#ifdef HAVE_LIBUDUNITS
180
  utUnit from_unit, to_unit;
181
#endif
182
  bool have_units;
183
  double slope, intercept;
184
  std::string calendar;
185
};
186
#endif