Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
output_ts.cc
Go to the documentation of this file.
1/* Copyright (C) 2017, 2018, 2019, 2021, 2023, 2024 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 "pism/icemodel/IceModel.hh"
21
22#include "pism/util/pism_options.hh"
23#include "pism/util/pism_utilities.hh"
24
25namespace pism {
26
27/*!
28 * Process -ts_vars shortcuts.
29 */
30static 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.
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()) {
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()) {
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 auto mode = append ? io::PISM_READWRITE : io::PISM_READWRITE_MOVE;
83 File file(m_grid->com, m_ts_filename, io::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 std::string time_name = m_config->get_string("time.dimension_name");
87 if (append and file.dimension_length(time_name) > 0) {
88 auto time = io::read_1d_variable(file, time_name, m_time->units_string(), m_sys);
89 double
90 epsilon = m_config->get_number("time_stepping.resolution"), // usually one second
91 t = vector_max(time);
92
93 // add this time only if it is strictly before the first requested one
94 if (t + epsilon < m_ts_times->front()) {
95 m_ts_times->insert(m_ts_times->begin(), t);
96 }
97 }
98
100 write_run_stats(file, run_stats());
101
102 // initialize scalar diagnostics
103 for (auto d : m_ts_diagnostics) {
104 d.second->init(file, m_ts_times);
105 }
106 }
107}
108
109//! Computes the maximum time-step we can take and still hit all `-ts_times`.
111
112 if ((not m_config->get_flag("time_stepping.hit_ts_times")) or
113 m_ts_diagnostics.empty()) {
114 return MaxTimestep("reporting (-ts_times)");
115 }
116
117 double eps = m_config->get_number("time_stepping.resolution");
118
119 return reporting_max_timestep(*m_ts_times, my_t, eps,
120 "reporting (-ts_times)");
121}
122
123//! Flush scalar time-series.
125 // flush all the time-series buffers:
126 for (auto d : m_ts_diagnostics) {
127 d.second->flush();
128 }
129
130 // update run_stats in the time series output file
131 if (not m_ts_diagnostics.empty()) {
133 write_run_stats(file, run_stats());
134 }
135}
136
137} // end of namespace pism
std::string get_string(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
A class for storing and accessing PISM configuration flags and parameters.
unsigned int dimension_length(const std::string &name) const
Get the length of a dimension.
Definition File.cc:420
High-level PISM I/O class.
Definition File.hh:55
VariableMetadata run_stats() const
Definition utilities.cc:91
std::map< std::string, TSDiagnostic::Ptr > m_ts_diagnostics
Requested scalar diagnostics.
Definition IceModel.hh:419
const Time::Ptr m_time
Time manager.
Definition IceModel.hh:246
std::shared_ptr< std::vector< double > > m_ts_times
requested times for scalar time-series
Definition IceModel.hh:438
const Logger::Ptr m_log
Logger.
Definition IceModel.hh:244
MaxTimestep ts_max_timestep(double my_t)
Computes the maximum time-step we can take and still hit all -ts_times.
Definition output_ts.cc:110
void flush_timeseries()
Flush scalar time-series.
Definition output_ts.cc:124
Config::Ptr m_config
Configuration flags and parameters.
Definition IceModel.hh:238
const units::System::Ptr m_sys
Unit system.
Definition IceModel.hh:242
std::string m_ts_filename
file to write scalar time-series to
Definition IceModel.hh:436
std::set< std::string > m_ts_vars
Definition IceModel.hh:439
virtual void write_metadata(const File &file, MappingTreatment mapping_flag, HistoryTreatment history_flag) const
Write time-independent metadata to a file.
Definition output.cc:72
void init_timeseries()
Initializes the code writing scalar time-series.
Definition output_ts.cc:45
const std::shared_ptr< Grid > m_grid
Computational grid.
Definition IceModel.hh:236
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
void add_context(const std::string &message)
Add a message providing some context. This way we can (sort of) get a stack trace even though C++ exc...
#define PISM_ERROR_LOCATION
@ PISM_NETCDF3
Definition IO_Flags.hh:57
@ PISM_READWRITE_MOVE
create a file for writing, move foo.nc to foo.nc~ if present
Definition IO_Flags.hh:74
@ PISM_READWRITE
open an existing file for reading and writing
Definition IO_Flags.hh:70
std::vector< double > read_1d_variable(const File &file, const std::string &variable_name, const std::string &units, std::shared_ptr< units::System > unit_system)
MaxTimestep reporting_max_timestep(const std::vector< double > &times, double t, double eps, const std::string &description)
Definition output.cc:41
static std::set< std::string > process_ts_shortcuts(const Config &config, const std::set< std::string > &input)
Definition output_ts.cc:30
std::string set_join(const std::set< std::string > &input, const std::string &separator)
std::set< std::string > set_split(const std::string &input, char separator)
Transform a separator-separated list (a string) into a set of strings.
void write_run_stats(const File &file, const pism::VariableMetadata &stats)
Definition output.cc:143
double vector_max(const std::vector< double > &input)