22#include "pism/util/Context.hh"
23#include "pism/util/Diagnostic.hh"
24#include "pism/util/Logger.hh"
25#include "pism/util/Time.hh"
26#include "pism/util/Units.hh"
27#include "pism/util/VariableMetadata.hh"
28#include "pism/util/error_handling.hh"
29#include "pism/util/io/OutputWriter.hh"
30#include "pism/util/pism_utilities.hh"
36 m_sys(grid->ctx()->unit_system()),
37 m_config(grid->ctx()->config()),
38 m_fill_value(m_config->get_number(
"output.fill_value")) {
64 out =
m_vars.at(0)[
"output_units"],
65 in =
m_vars.at(0)[
"units"];
66 return convert(
m_sys, x, out, in);
74 out =
m_vars.at(0)[
"output_units"],
75 in =
m_vars.at(0)[
"units"];
76 return convert(
m_sys, x, in, out);
115 "variable metadata index %d is out of bounds",
127 std::vector<std::string> names;
128 for (
const auto &v :
m_vars) {
129 names.push_back(v.get_name());
131 std::string all_names =
join(names,
",");
133 m_grid->ctx()->log()->message(3,
"- Computing %s...\n", all_names.c_str());
135 m_grid->ctx()->log()->message(3,
"- Done computing %s.\n", all_names.c_str());
142 m_config(grid->ctx()->config()),
143 m_sys(grid->ctx()->unit_system()),
144 m_variable(name, m_sys) {
151 m_variable[
"ancillary_variables"] = name +
"_aux";
160 const std::string &output_units) {
171 :
TSDiagnostic(grid, name), m_accumulator(0.0), m_v_previous(0.0), m_v_previous_set(false) {
196 const double t_s = (*m_requested_times)[
k - 1];
197 const double t_e = (*m_requested_times)[
k];
210 static const double epsilon = 1e-4;
233 const double t_s = (*m_requested_times)[
k - 1];
234 const double t_e = (*m_requested_times)[
k];
241 total_change =
m_accumulator + change * (t_e - t0) / (t1 - t0);
242 const double dt = t_e - t_s;
244 rate = total_change / dt;
249 rate = change / (t1 - t0);
282 static const double epsilon = 1e-4;
284 if (fabs(t1 - t0) < epsilon) {
294 const double v = this->
compute();
306 static const double epsilon = 1e-4;
308 if (fabs(t1 - t0) < epsilon) {
324 auto len = file.time_dimension_length();
329 double last_time = file.last_time_value();
331 if (last_time <
m_time.front()) {
337 bool with_bounds =
true;
338 auto time =
m_grid->ctx()->time()->metadata(with_bounds).get_name();
339 auto time_bounds =
m_grid->ctx()->time()->bounds_metadata().get_name();
344 file.write_array(time_bounds, {
m_start, 0 }, { (
unsigned int)
m_bounds.size() / 2, 2 },
352 if (not
m_config->get_flag(
"output.use_MKS")) {
354 std::string units =
metadata()[
"units"];
355 std::string output_units =
metadata()[
"output_units"];
357 bool use_output_units =
358 (not units.empty() and not output_units.empty() and units != output_units);
360 if (use_output_units) {
368 file.write_timeseries(
m_variable.
get_name(), { m_start }, { (unsigned int)m_values.size() },
383 std::shared_ptr<std::vector<double>> requested_times) {
389 m_start = output_file->time_dimension_length();
std::set< VariableMetadata > state() const
std::vector< VariableMetadata > m_vars
metadata corresponding to NetCDF variables
virtual std::shared_ptr< array::Array > compute_impl() const =0
virtual void reset_impl()
VariableMetadata & metadata(unsigned int N=0)
Get a metadata object corresponding to variable number N.
virtual std::set< VariableMetadata > state_impl() const
const grid::DistributedGridInfo & grid_info() const
const units::System::Ptr m_sys
the unit system
double to_internal(double x) const
virtual void write_state_impl(const OutputFile &output) const
void init(const File &input, unsigned int time)
virtual void update_impl(double dt)
Diagnostic(std::shared_ptr< const Grid > g)
double to_external(double x) const
unsigned int n_variables() const
Get the number of NetCDF variables corresponding to a diagnostic quantity.
std::shared_ptr< const Grid > m_grid
the grid
void write_state(const OutputFile &output) const
virtual void init_impl(const File &input, unsigned int time)
std::shared_ptr< array::Array > compute() const
Compute a diagnostic quantity and return a pointer to a newly-allocated Array.
High-level PISM I/O class.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
std::vector< double > m_values
void set_units(const std::string &units, const std::string &output_units)
std::shared_ptr< std::vector< double > > m_requested_times
requested times
unsigned int m_current_time
index into m_times
unsigned int m_start
starting index used when flushing the buffer
std::vector< double > m_bounds
size_t m_buffer_size
size of the buffer used to store data
VariableMetadata m_variable
TSDiagnostic(std::shared_ptr< const Grid > g, const std::string &name)
std::shared_ptr< const Config > m_config
Configuration flags and parameters.
std::shared_ptr< OutputFile > m_output_file
std::vector< double > m_time
virtual double compute()=0
const VariableMetadata & metadata() const
virtual void update_impl(double t0, double t1)=0
std::shared_ptr< const Grid > m_grid
the grid
void init(std::shared_ptr< OutputFile > output_file, std::shared_ptr< std::vector< double > > requested_times)
void update(double t0, double t1)
PISM's scalar time-series diagnostics.
void update_impl(double t0, double t1)
TSFluxDiagnostic(std::shared_ptr< const Grid > g, const std::string &name)
double m_accumulator
accumulator of changes (used to compute rates of change)
void update_impl(double t0, double t1)
TSRateDiagnostic(std::shared_ptr< const Grid > g, const std::string &name)
void evaluate(double t0, double t1, double change)
double m_v_previous
last two values, used to compute the change during a time step
Scalar diagnostic reporting the rate of change of a quantity modeled by PISM.
void evaluate(double t0, double t1, double v)
TSSnapshotDiagnostic(std::shared_ptr< const Grid > g, const std::string &name)
void update_impl(double t0, double t1)
void convert_doubles(double *data, size_t length) const
#define PISM_ERROR_LOCATION
std::string join(const std::vector< std::string > &strings, const std::string &separator)
Concatenate strings, inserting separator between elements.