PISM, A Parallel Ice Sheet Model
Time.hh
Go to the documentation of this file.
1 // Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 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 /**
32  * Returns 0 if `name` is a name of a supported calendar, 1 otherwise.
33  */
34 inline bool pism_is_valid_calendar_name(const std::string &name) {
35  // Calendar names from the CF Conventions document (except the
36  // 366_day (all_leap)):
37  return member(name, {"standard", "gregorian", "proleptic_gregorian",
38  "noleap", "365_day", "julian", "360_day"});
39 }
40 
41 //! \brief Time management class.
42 /*!
43  * This is to make it possible to switch between different implementations.
44  *
45  * For example: 365-day no-leap calendar for spinups
46  * Gregorian calendar for XX-century forcing runs
47  *
48  * This base class implements the 365-day no-leap version.
49  *
50  * We want to be able to count time since a particular date, so it is helpful
51  * to keep in mind that the year "1986" in this context is not the year of the
52  * Chernobyl disaster but a year 1986 years since some date.
53  */
54 class Time
55 {
56 public:
57  Time(MPI_Comm com, Config::ConstPtr config,
58  const Logger &log,
59  units::System::Ptr unit_system);
60  virtual ~Time() = default;
61 
62  typedef std::shared_ptr<Time> Ptr;
63  typedef std::shared_ptr<const Time> ConstPtr;
64 
65  //! \brief Sets the current time (in seconds since the reference time).
66  void set(double new_time);
67 
68  void set_start(double new_start);
69 
70  void set_end(double new_end);
71 
72  //! \brief Advance by delta_t seconds.
73  void step(double delta_t);
74 
75  //! \brief Current time, in seconds.
76  double current() const;
77 
78  double start() const;
79 
80  double end() const;
81 
82  //! \brief Returns the calendar string.
83  std::string calendar() const;
84 
85  //! \brief Returns the length of the current run, in years.
86  std::string run_length() const;
87 
88  void init_calendar(const std::string &calendar);
89 
90  std::vector<double> parse_times(const std::string &spec) const;
91 
92  //! Internal time units as a string.
93  std::string units_string() const;
94 
95  /*!
96  * Internal time units.
97  */
98  units::Unit units() const;
99 
100  //! \brief Returns the fraction of a year passed since the last beginning of
101  //! a year. Only useful in codes with a "yearly cycle" (such as the PDD model).
102  double year_fraction(double T) const;
103 
104  //! \brief Convert the day number to the year fraction.
105  double day_of_the_year_to_year_fraction(unsigned int day) const;
106 
107  //! \brief Returns the model time in seconds corresponding to the
108  //! beginning of the year `T` falls into.
109  double calendar_year_start(double T) const;
110 
111  //! Increment time `T` by a given amount and return resulting model
112  //! time in seconds.
113  double increment_date(double T, double years) const;
114 
115  //! \brief Returns the date corresponding to time T.
116  std::string date(double T) const;
117 
118  //! @brief Convert time interval from seconds to given units. Handle
119  //! 'years' using the year length corresponding to the calendar.
120  double convert_time_interval(double T, const std::string &units) const;
121 protected:
122 
123  std::vector<double> parse_list(const std::string &spec) const;
124  std::vector<double> parse_range(const std::string &spec) const;
125 
126  void compute_times_simple(double time_start, double delta, double time_end,
127  std::vector<double> &result) const;
128 
130 
131  struct Interval {
132  double dt;
134  };
135 
136  void compute_times(double time_start, double time_end,
137  const Interval &interval,
138  std::vector<double> &result) const;
139 
140  Interval parse_interval_length(const std::string &spec) const;
141 
142  //! Convert time interval length in years into seconds using the year length
143  //! corresponding to the chosen calendar.
144  double years_to_seconds(double input) const;
145 
146  //! Convert time interval length in seconds into years using the year length
147  //! corresponding to the chosen calendar.
148  double seconds_to_years(double input) const;
149 
150 protected:
154 
155  //! Time resolution, in seconds.
156  double m_t_eps;
157 
158  //! number of seconds in a year, for "mod" and "year fraction"
160 
161  //! current time, in seconds since the reference time
163 
164  //! run start time, in seconds since the reference time
165  double m_run_start;
166 
167  //! run end tim, in seconds since the reference time
168  double m_run_end;
169 
170  //! CF calendar string
171  std::string m_calendar_string;
172  // True if the calendar has constant year lengths (360_day, 365_day)
174 
175  void init_from_file(MPI_Comm com, const std::string &filename, const Logger &log,
176  bool set_start_time);
177 
178  void compute_times_monthly(std::vector<double> &result) const;
179 
180  void compute_times_yearly(std::vector<double> &result) const;
181 };
182 
183 void check_forcing_duration(const Time &time,
184  double forcing_start,
185  double forcing_end);
186 
187 
188 } // end of namespace pism
189 
190 #endif /* _PISMTIME_H_ */
std::shared_ptr< const Config > ConstPtr
A basic logging class.
Definition: Logger.hh:40
double increment_date(double T, double years) const
Definition: Time.cc:850
std::vector< double > parse_list(const std::string &spec) const
Definition: Time.cc:520
std::string run_length() const
Returns the length of the current run, in years.
Definition: Time.cc:500
std::shared_ptr< const Time > ConstPtr
Definition: Time.hh:63
virtual ~Time()=default
const Config::ConstPtr m_config
Definition: Time.hh:151
std::string units_string() const
Internal time units as a string.
Definition: Time.cc:476
void compute_times_monthly(std::vector< double > &result) const
Definition: Time.cc:854
double years_to_seconds(double input) const
Definition: Time.cc:418
void set(double new_time)
Sets the current time (in seconds since the reference time).
Definition: Time.cc:451
double convert_time_interval(double T, const std::string &units) const
Convert time interval from seconds to given units. Handle 'years' using the year length corresponding...
Definition: Time.cc:673
double m_year_length
number of seconds in a year, for "mod" and "year fraction"
Definition: Time.hh:159
void set_end(double new_end)
Definition: Time.cc:459
void compute_times_simple(double time_start, double delta, double time_end, std::vector< double > &result) const
Definition: Time.cc:649
void init_calendar(const std::string &calendar)
Definition: Time.cc:430
double start() const
Definition: Time.cc:468
double calendar_year_start(double T) const
Returns the model time in seconds corresponding to the beginning of the year T falls into.
Definition: Time.cc:841
void compute_times(double time_start, double time_end, const Interval &interval, std::vector< double > &result) const
Definition: Time.cc:911
IntervalType
Definition: Time.hh:129
@ MONTHLY
Definition: Time.hh:129
@ SIMPLE
Definition: Time.hh:129
@ YEARLY
Definition: Time.hh:129
double end() const
Definition: Time.cc:472
std::vector< double > parse_range(const std::string &spec) const
Definition: Time.cc:600
double m_run_end
run end tim, in seconds since the reference time
Definition: Time.hh:168
double year_fraction(double T) const
Returns the fraction of a year passed since the last beginning of a year. Only useful in codes with a...
Definition: Time.cc:818
double m_time_in_seconds
current time, in seconds since the reference time
Definition: Time.hh:162
Interval parse_interval_length(const std::string &spec) const
Definition: Time.cc:541
std::string m_calendar_string
CF calendar string.
Definition: Time.hh:171
bool m_simple_calendar
Definition: Time.hh:173
double seconds_to_years(double input) const
Definition: Time.cc:426
double current() const
Current time, in seconds.
Definition: Time.cc:464
std::shared_ptr< Time > Ptr
Definition: Time.hh:62
units::Unit units() const
Definition: Time.cc:480
std::vector< double > parse_times(const std::string &spec) const
Definition: Time.cc:509
Time(MPI_Comm com, Config::ConstPtr config, const Logger &log, units::System::Ptr unit_system)
Definition: Time.cc:687
void compute_times_yearly(std::vector< double > &result) const
Definition: Time.cc:886
double day_of_the_year_to_year_fraction(unsigned int day) const
Convert the day number to the year fraction.
Definition: Time.cc:504
void step(double delta_t)
Advance by delta_t seconds.
Definition: Time.cc:489
void set_start(double new_start)
Definition: Time.cc:455
std::string date(double T) const
Returns the date corresponding to time T.
Definition: Time.cc:832
double m_run_start
run start time, in seconds since the reference time
Definition: Time.hh:165
const units::System::Ptr m_unit_system
Definition: Time.hh:152
units::Unit m_time_units
Definition: Time.hh:153
std::string calendar() const
Returns the calendar string.
Definition: Time.cc:485
void init_from_file(MPI_Comm com, const std::string &filename, const Logger &log, bool set_start_time)
Sets the time from a NetCDF file with a time dimension (-time_file).
Definition: Time.cc:762
double m_t_eps
Time resolution, in seconds.
Definition: Time.hh:156
Time management class.
Definition: Time.hh:55
std::shared_ptr< System > Ptr
Definition: Units.hh:47
void check_forcing_duration(const Time &time, double forcing_start, double forcing_end)
Definition: Time.cc:932
bool member(const std::string &string, const std::set< std::string > &set)
bool pism_is_valid_calendar_name(const std::string &name)
Definition: Time.hh:34
IntervalType type
Definition: Time.hh:133