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_ */