tTime.hh - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
(HTM) git clone git://src.adamsgaard.dk/pism
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) LICENSE
---
tTime.hh (7678B)
---
1 // Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Constantine Khroulev
2 //
3 // This file is part of PISM.
4 //
5 // PISM is free software; you can redistribute it and/or modify it under the
6 // terms of the GNU General Public License as published by the Free Software
7 // Foundation; either version 3 of the License, or (at your option) any later
8 // version.
9 //
10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with PISM; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 #ifndef _PISMTIME_H_
20 #define _PISMTIME_H_
21
22 #include <vector>
23 #include <memory>
24
25 #include "pism/util/pism_utilities.hh"
26 #include "pism/util/Units.hh"
27 #include "pism/util/ConfigInterface.hh"
28
29 namespace pism {
30
31 std::string calendar_from_options(MPI_Comm com, const Config& config);
32
33 /**
34 * Returns 0 if `name` is a name of a supported calendar, 1 otherwise.
35 */
36 inline bool pism_is_valid_calendar_name(const std::string &name) {
37 // Calendar names from the CF Conventions document (except the
38 // 366_day (all_leap)):
39 if (name == "standard" ||
40 name == "gregorian" ||
41 name == "proleptic_gregorian" ||
42 name == "noleap" ||
43 name == "365_day" ||
44 name == "julian" ||
45 name == "360_day" ||
46 name == "none") {
47 return true;
48 }
49
50 return false;
51 }
52
53 //! \brief Time management class.
54 /*!
55 * This is to make it possible to switch between different implementations.
56 *
57 * For example: 365-day no-leap calendar for spinups
58 * Gregorian calendar for XX-century forcing runs
59 *
60 * This base class implements the 365-day no-leap version.
61 *
62 * We want to be able to count time since a particular date, so it is helpful
63 * to keep in mind that the year "1986" in this context is not the year of the
64 * Chernobyl disaster but a year 1986 years since some date.
65 */
66 class Time
67 {
68 public:
69 Time(Config::ConstPtr conf,
70 const std::string &calendar,
71 units::System::Ptr units_system);
72 virtual ~Time();
73
74 typedef std::shared_ptr<Time> Ptr;
75 typedef std::shared_ptr<const Time> ConstPtr;
76
77 //! \brief Sets the current time (in seconds since the reference time).
78 void set(double new_time);
79
80 void set_start(double new_start);
81
82 void set_end(double new_end);
83
84 //! \brief Advance by delta_t seconds.
85 void step(double delta_t);
86
87 //! \brief Current time, in seconds.
88 double current() const;
89
90 double start() const;
91
92 double end() const;
93
94 //! \brief Returns the calendar string.
95 std::string calendar() const;
96
97 //! \brief Returns the length of the current run, in years.
98 std::string run_length() const;
99
100 // Virtual methods:
101
102 //! \brief Intialize using command-line options.
103 virtual void init(const Logger &log);
104
105 virtual void init_from_input_file(const File &nc,
106 const std::string &time_name,
107 const Logger &log);
108
109 void init_calendar(const std::string &calendar);
110
111 std::vector<double> parse_times(const std::string &spec) const;
112
113 //! \brief Returns the CF- (and UDUNITS) compliant units string.
114 /*!
115 * This units string is saved in the output file. Always contains a reference
116 * date, even if it is not used by PISM.
117 */
118 virtual std::string CF_units_string() const;
119
120 //! \brief Internal time units.
121 /*!
122 * May or may not contain a reference date. (The base class Time does not
123 * use the reference date, while Time_Calendar does.)
124 */
125 virtual std::string units_string() const;
126
127 virtual std::string CF_units_to_PISM_units(const std::string &input) const;
128
129 //! \brief Returns time since the origin modulo period.
130 virtual double mod(double time, unsigned int period_years) const;
131
132 //! \brief Returns the fraction of a year passed since the last beginning of
133 //! a year. Only useful in codes with a "yearly cycle" (such as the PDD model).
134 virtual double year_fraction(double T) const;
135
136 //! \brief Convert the day number to the year fraction.
137 virtual double day_of_the_year_to_day_fraction(unsigned int day) const;
138
139 //! \brief Returns the model time in seconds corresponding to the
140 //! beginning of the year `T` falls into.
141 virtual double calendar_year_start(double T) const;
142
143 //! Increment time `T` by a given amount and return resulting model
144 //! time in seconds.
145 virtual double increment_date(double T, int years) const;
146
147 //! \brief Returns the date corresponding to time T.
148 virtual std::string date(double T) const;
149
150 //! \brief Returns current time, in years. Only for reporting.
151 virtual std::string date() const;
152
153 //! \brief Returns current time, in years. Only for debugging.
154 double current_years() const;
155
156 //! Date corresponding to the beginning of the run.
157 virtual std::string start_date() const;
158
159 //! Date corresponding to the end of the run.
160 virtual std::string end_date() const;
161
162 //! @brief Convert time interval from seconds to given units. Handle
163 //! 'years' using the year length corresponding to the calendar.
164 virtual double convert_time_interval(double T, const std::string &units) const;
165
166 //! Convert time interval length in years into seconds using the year length
167 //! corresponding to the chosen calendar.
168 double years_to_seconds(double input) const;
169
170 //! Convert time interval length in seconds into years using the year length
171 //! corresponding to the chosen calendar.
172 double seconds_to_years(double input) const;
173 protected:
174
175 std::vector<double> parse_list(const std::string &spec) const;
176 std::vector<double> parse_range(const std::string &spec) const;
177
178 void compute_times_simple(double time_start, double delta, double time_end,
179 std::vector<double> &result) const;
180
181 virtual bool process_ys(double &result);
182 virtual bool process_y(double &result);
183 virtual bool process_ye(double &result);
184
185 virtual void compute_times(double time_start, double delta, double time_end,
186 const std::string &keyword,
187 std::vector<double> &result) const;
188
189 virtual void parse_date(const std::string &spec, double *result) const;
190
191 virtual void parse_interval_length(const std::string &spec, std::string &keyword,
192 double *result) const;
193
194 protected:
195 const Config::ConstPtr m_config;
196 const units::System::Ptr m_unit_system;
197 units::Unit m_time_units;
198 double m_year_length; //!< number of seconds in a year, for "mod" and "year fraction"
199 double m_time_in_seconds, //!< current time, in seconds since the reference time
200 m_run_start, //!< run start time, in seconds since the reference time
201 m_run_end; //!< run end tim, in seconds since the reference time
202 std::string m_calendar_string; //!< CF calendar string
203 };
204
205 std::string reference_date_from_file(const File &nc,
206 const std::string &time_name);
207
208 //! Create a Time instance by processing command-line options.
209 Time::Ptr time_from_options(MPI_Comm com, Config::ConstPtr config, units::System::Ptr system);
210
211 //! Initialize time from command-line options or from and input file (set using the `-i` option).
212 void initialize_time(MPI_Comm com, const std::string &dimension_name,
213 const Logger &log, Time &time);
214
215 } // end of namespace pism
216
217 #endif /* _PISMTIME_H_ */