URI: 
       toutput_ts.cc - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
  HTML git clone git://src.adamsgaard.dk/pism
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
       toutput_ts.cc (4334B)
       ---
            1 /* Copyright (C) 2017, 2018, 2019 PISM Authors
            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 
           20 #include "IceModel.hh"
           21 
           22 #include "pism/util/pism_options.hh"
           23 #include "pism/util/pism_utilities.hh"
           24 
           25 namespace pism {
           26 
           27 /*!
           28  * Process -ts_vars shortcuts.
           29  */
           30 static std::set<std::string> process_ts_shortcuts(const Config &config,
           31                                                   const std::set<std::string> &input) {
           32   std::set<std::string> result = input;
           33 
           34   if (result.find("ismip6") != result.end()) {
           35     result.erase("ismip6");
           36     for (auto v : set_split(config.get_string("output.ISMIP6_ts_variables"), ',')) {
           37       result.insert(v);
           38     }
           39   }
           40 
           41   return result;
           42 }
           43 
           44 //! Initializes the code writing scalar time-series.
           45 void IceModel::init_timeseries() {
           46 
           47   m_ts_filename = m_config->get_string("output.timeseries.filename");
           48 
           49   auto times = m_config->get_string("output.timeseries.times");
           50   bool times_set = not times.empty();
           51 
           52   if (times_set xor not m_ts_filename.empty()) {
           53     throw RuntimeError(PISM_ERROR_LOCATION,
           54                        "you need to specity both -ts_file and -ts_times"
           55                        " to save scalar diagnostic time-series.");
           56   }
           57 
           58   if (m_ts_filename.empty()) {
           59     return;
           60   }
           61 
           62   try {
           63     *m_ts_times = m_time->parse_times(times);
           64   } catch (RuntimeError &e) {
           65     e.add_context("parsing the -ts_times argument %s", times.c_str());
           66     throw;
           67   }
           68 
           69   m_log->message(2, "  saving scalar time-series to '%s'\n", m_ts_filename.c_str());
           70   m_log->message(2, "  times requested: %s\n", times.c_str());
           71 
           72   m_ts_vars = set_split(m_config->get_string("output.timeseries.variables"), ',');
           73   if (not m_ts_vars.empty()) {
           74     m_ts_vars = process_ts_shortcuts(*m_config, m_ts_vars);
           75     m_log->message(2, "variables requested: %s\n", set_join(m_ts_vars, ",").c_str());
           76   }
           77 
           78   // prepare the output file
           79   {
           80     // default behavior is to move the file aside if it exists already; option allows appending
           81     bool append = m_config->get_flag("output.timeseries.append");
           82     IO_Mode mode = append ? PISM_READWRITE : PISM_READWRITE_MOVE;
           83     File file(m_grid->com, m_ts_filename, PISM_NETCDF3, mode);      // Use NetCDF-3 to write time-series.
           84     // add the last saved time to the list of requested times so that the first time is interpreted
           85     // as the end of a reporting time step
           86     if (append and file.dimension_length("time") > 0) {
           87       double
           88         epsilon = 1.0,          // one second
           89         t       = vector_max(file.read_dimension("time"));
           90 
           91       // add this time only if it is strictly before the first requested one
           92       if (t + epsilon < m_ts_times->front()) {
           93         m_ts_times->insert(m_ts_times->begin(), t);
           94       }
           95     }
           96 
           97     write_metadata(file, SKIP_MAPPING, PREPEND_HISTORY);
           98     write_run_stats(file);
           99 
          100     // initialize scalar diagnostics
          101     for (auto d : m_ts_diagnostics) {
          102       d.second->init(file, m_ts_times);
          103     }
          104   }
          105 }
          106 
          107 //! Computes the maximum time-step we can take and still hit all `-ts_times`.
          108 MaxTimestep IceModel::ts_max_timestep(double my_t) {
          109 
          110   if ((not m_config->get_flag("time_stepping.hit_ts_times")) or
          111       m_ts_diagnostics.empty()) {
          112     return MaxTimestep("reporting (-ts_times)");
          113   }
          114 
          115   return reporting_max_timestep(*m_ts_times, my_t, "reporting (-ts_times)");
          116 }
          117 
          118 //! Flush scalar time-series.
          119 void IceModel::flush_timeseries() {
          120   // flush all the time-series buffers:
          121   for (auto d : m_ts_diagnostics) {
          122     d.second->flush();
          123   }
          124 
          125   // update run_stats in the time series output file
          126   if (not m_ts_diagnostics.empty()) {
          127     File file(m_grid->com, m_ts_filename, PISM_NETCDF3, PISM_READWRITE);
          128     write_run_stats(file);
          129   }
          130 }
          131 
          132 } // end of namespace pism