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