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_save.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_utilities.hh"
23#include "pism/util/Profiling.hh"
24#include <memory>
25
26namespace pism {
27
28//! Computes the maximum time-step we can take and still hit all `-save_times`.
30
31 if (m_snapshots_filename.empty() or (not m_config->get_flag("time_stepping.hit_save_times"))) {
32 return MaxTimestep("reporting (-save_times)");
33 }
34
35 double eps = m_config->get_number("time_stepping.resolution");
36
38 "reporting (-save_times)");
39}
40
41//! Initializes the snapshot-saving mechanism.
44
45 m_snapshots_filename = m_config->get_string("output.snapshot.file");
46 auto save_times = m_config->get_string("output.snapshot.times");
47 m_snapshot_vars = output_variables(m_config->get_string("output.snapshot.size"));
48 m_split_snapshots = m_config->get_flag("output.snapshot.split");
49
50 {
51 bool filename_set = not m_snapshots_filename.empty();
52 bool times_set = not save_times.empty();
53
54 if (filename_set ^ times_set) {
56 "you need to set both output.snapshot.file and output.snapshot.times"
57 " to save snapshots.");
58 }
59
60 if (not (filename_set and times_set)) {
61 return;
62 }
63 }
64
65 try {
66 // parse
67 std::vector<double> times = m_time->parse_times(save_times);
68
69 // discard times before the beginning and after the end of the run
70 m_snapshot_times.clear();
71 for (const auto &t : times) {
72 if (t >= m_time->start() and t <= m_time->end()) {
73 m_snapshot_times.push_back(t);
74 }
75 }
76 } catch (RuntimeError &e) {
77 e.add_context("processing output.snapshot.times");
78 throw;
79 }
80
81 if (m_snapshot_times.empty()) {
83 "output.snapshot.times was set, but all requested times"
84 " are outside of the modeled time interval");
85 }
86
88 m_log->message(2, "saving snapshots to '%s+year.nc'; ", m_snapshots_filename.c_str());
89 } else {
90 m_log->message(2, "saving snapshots to '%s'; ", m_snapshots_filename.c_str());
91
92 if (not ends_with(m_snapshots_filename, ".nc")) {
93 m_log->message(2, "PISM WARNING: snapshots file name does not have the '.nc' suffix!\n");
94 }
95 }
96
97 m_log->message(2, "times requested: %s\n", save_times.c_str());
98}
99
100//! Writes a snapshot of the model state (if necessary)
102 // initialize to avoid compiler warning; this value is never used, because saving_after
103 // is only used if save_now == true, and in this case saving_after is guaranteed to be
104 // initialized. See the code below.
105 double saving_after = -1.0e30;
106
107 // determine if the user set the -save_times and -save_file options
108 if (m_snapshots_filename.empty()) {
109 return;
110 }
111
112 // do we need to save *now*?
113 if ((m_time->current() >= m_snapshot_times[m_current_snapshot]) and
115 saving_after = m_snapshot_times[m_current_snapshot];
116
117 while ((m_current_snapshot < m_snapshot_times.size()) and
118 (m_snapshot_times[m_current_snapshot] <= m_time->current())) {
120 }
121 } else {
122 // we don't need to save now, so just return
123 return;
124 }
125
126 // flush time-series buffers
128
129 const Profiling &profiling = m_ctx->profiling();
130
131 profiling.begin("io.snapshots");
132 std::string filename;
133 if (m_snapshot_file == nullptr) {
134 if (m_split_snapshots) {
135 auto date_without_spaces = replace_character(m_time->date(saving_after), ' ', '_');
136 filename =
137 pism::printf("%s_%s.nc", m_snapshots_filename.c_str(), date_without_spaces.c_str());
138 } else {
139 filename = m_snapshots_filename;
140 }
141
142 m_snapshot_file = std::make_shared<File>(
143 m_grid->com, filename, string_to_backend(m_config->get_string("output.format")),
145
147 }
148
149 {
150 m_log->message(2, "saving snapshot to %s at %s, for time-step goal %s\n", filename.c_str(),
151 m_time->date(m_time->current()).c_str(), m_time->date(saving_after).c_str());
154 }
155
156 if (m_split_snapshots) {
157 m_snapshot_file.reset();
158 }
159
160 profiling.end("io.snapshots");
161}
162
163} // end of namespace pism
unsigned int m_current_snapshot
Definition IceModel.hh:430
std::set< std::string > m_snapshot_vars
Definition IceModel.hh:429
std::string m_snapshots_filename
Definition IceModel.hh:425
VariableMetadata run_stats() const
Definition utilities.cc:91
bool m_split_snapshots
Definition IceModel.hh:427
void write_snapshot()
Writes a snapshot of the model state (if necessary)
const Time::Ptr m_time
Time manager.
Definition IceModel.hh:246
std::vector< double > m_snapshot_times
Definition IceModel.hh:428
std::shared_ptr< Context > m_ctx
Execution context.
Definition IceModel.hh:240
const Logger::Ptr m_log
Logger.
Definition IceModel.hh:244
void flush_timeseries()
Flush scalar time-series.
Definition output_ts.cc:124
Config::Ptr m_config
Configuration flags and parameters.
Definition IceModel.hh:238
virtual void save_variables(const File &file, OutputKind kind, const std::set< std::string > &variables, double time, io::Type default_diagnostics_type=io::PISM_FLOAT) const
Definition output.cc:150
std::shared_ptr< File > m_snapshot_file
Definition IceModel.hh:426
virtual std::set< std::string > output_variables(const std::string &keyword)
Assembles a list of diagnostics corresponding to an output file size.
MaxTimestep save_max_timestep(double my_t)
Computes the maximum time-step we can take and still hit all -save_times.
void init_snapshots()
Initializes the snapshot-saving mechanism.
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
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 begin(const char *name) const
Definition Profiling.cc:75
void end(const char *name) const
Definition Profiling.cc:91
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_READWRITE_MOVE
create a file for writing, move foo.nc to foo.nc~ if present
Definition IO_Flags.hh:74
MaxTimestep reporting_max_timestep(const std::vector< double > &times, double t, double eps, const std::string &description)
Definition output.cc:41
io::Backend string_to_backend(const std::string &backend)
Definition File.cc:56
bool ends_with(const std::string &str, const std::string &suffix)
Returns true if str ends with suffix and false otherwise.
std::string printf(const char *format,...)
std::string replace_character(const std::string &input, char from, char to)
void write_run_stats(const File &file, const pism::VariableMetadata &stats)
Definition output.cc:143