https://mooseframework.inl.gov
TableOutput.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "TableOutput.h"
11 
12 // MOOSE includes
13 #include "Conversion.h"
14 #include "FEProblem.h"
15 #include "Executioner.h"
16 #include "MooseApp.h"
17 #include "MooseVariableScalar.h"
18 #include "PetscSupport.h"
19 #include "Postprocessor.h"
20 #include "SystemBase.h"
21 
22 #include "libmesh/dof_map.h"
23 #include "libmesh/string_to_enum.h"
24 
27 {
28  // Base class parameters
30  params += AdvancedOutput::enableOutputTypes("postprocessor scalar vector_postprocessor reporter");
31 
32  // Option for writing vector_postprocessor time file
33  params.addParam<bool>("time_data",
34  false,
35  "When true and VectorPostprocessor data exists, write "
36  "a csv file containing the timestep and time "
37  "information.");
38 
39  // Add option for appending file on restart
40  params.addParam<bool>("append_restart", false, "Append existing file on restart");
41 
42  params.addParam<bool>(
43  "time_column",
44  true,
45  "Whether or not the 'time' column should be written for Postprocessor CSV files");
46 
47  MooseEnum new_row_detection_columns("time all", "time");
48  new_row_detection_columns.addDocumentation(
49  "time",
50  "If the time for a new row would match the previous row's time within 'new_row_tolerance', "
51  "do not add the row.");
52  new_row_detection_columns.addDocumentation(
53  "all",
54  "If all columns for a new row would match the previous row's columns within "
55  "'new_row_tolerance', do not add the row.");
56  params.addParam<MooseEnum>("new_row_detection_columns",
57  new_row_detection_columns,
58  "Columns to check for duplicate rows; duplicate rows are not output.");
59  params.addParam<Real>("new_row_tolerance",
61  "The independent variable tolerance for determining when a new row should "
62  "be added to the table (Note: This value must be set independently for "
63  "Postprocessor output to type=Console and type=CSV file separately.");
64  params.addParamNamesToGroup("new_row_detection_columns new_row_tolerance time_data time_column",
65  "Table formatting");
66 
67  return params;
68 }
69 
70 void
72  const std::string & param)
73 {
74  ExecFlagEnum & execute_on = params.set<ExecFlagEnum>(param, true);
76  params.setDocString(param, execute_on.getDocString());
77 }
78 
80  : AdvancedOutput(parameters),
81  _tables_restartable(getParam<bool>("append_restart")),
82  _postprocessor_table(_tables_restartable
83  ? declareRestartableData<FormattedTable>("postprocessor_table")
84  : declareRecoverableData<FormattedTable>("postprocessor_table")),
85  _vector_postprocessor_time_tables(
86  _tables_restartable ? declareRestartableData<std::map<std::string, FormattedTable>>(
87  "vector_postprocessor_time_table")
88  : declareRecoverableData<std::map<std::string, FormattedTable>>(
89  "vector_postprocessor_time_table")),
90  _scalar_table(_tables_restartable ? declareRestartableData<FormattedTable>("scalar_table")
91  : declareRecoverableData<FormattedTable>("scalar_table")),
92  _reporter_table(_tables_restartable ? declareRestartableData<FormattedTable>("reporter_table")
93  : declareRecoverableData<FormattedTable>("reporter_table")),
94  _all_data_table(_tables_restartable ? declareRestartableData<FormattedTable>("all_data_table")
95  : declareRecoverableData<FormattedTable>("all_data_table")),
96  _check_all_columns_for_new_row(getParam<MooseEnum>("new_row_detection_columns") == "all"),
97  _new_row_tol(getParam<Real>("new_row_tolerance")),
98  _time_data(getParam<bool>("time_data")),
99  _time_column(getParam<bool>("time_column"))
100 
101 {
102  // Set a Boolean indicating whether or not we will output the time column
106 }
107 
108 void
110 {
113 
116 }
117 
118 bool
120 {
121  if (table.empty())
122  return true;
123 
124  // Check time column; all options will output row if time is new
125  const Real old_time = table.getLastTime();
126  const Real new_time = getOutputTime();
127  if (!MooseUtils::absoluteFuzzyEqual(old_time, new_time, _new_row_tol))
128  return true;
129 
130  // Check PP columns if that option enabled
132  {
133  bool all_columns_are_identical = true;
134  for (const auto & pp_name : getPostprocessorOutput())
135  {
136  const Real old_pp_value = table.getLastData(pp_name);
137  const Real new_pp_value = _problem_ptr->getPostprocessorValueByName(pp_name);
138  if (!MooseUtils::absoluteFuzzyEqual(old_pp_value, new_pp_value, _new_row_tol))
139  {
140  all_columns_are_identical = false;
141  break;
142  }
143  }
144  return !all_columns_are_identical;
145  }
146  else
147  return false;
148 }
149 
150 void
152 {
153  table.addRow(getOutputTime());
154 
155  for (const auto & pp_name : getPostprocessorOutput())
156  table.addData(pp_name, _problem_ptr->getPostprocessorValueByName(pp_name));
157 }
158 
159 void
161 {
162  // List of VPP objects with output
163  const std::set<std::string> & vpps = getVectorPostprocessorOutput();
164 
165  for (const auto & combined_name : getReporterOutput())
166  {
167  ReporterName r_name(combined_name);
168 
169  outputReporter<bool>(r_name);
170  outputReporter<unsigned short int>(r_name);
171  outputReporter<unsigned int>(r_name);
172  outputReporter<unsigned long int>(r_name);
173  outputReporter<unsigned long long int>(r_name);
174  outputReporter<short int>(r_name);
175  outputReporter<int>(r_name);
176  outputReporter<long int>(r_name);
177  outputReporter<long long int>(r_name);
178  outputReporter<float>(r_name);
179  outputReporter<long double>(r_name);
180  outputReporter<char>(r_name);
181  outputReporter<std::string>(r_name);
182 
183  // Need to check for reals because PPs and VPPs might have already been outputted
184  if (!hasPostprocessorByName(r_name.getObjectName()) &&
185  vpps.find(r_name.getObjectName()) == vpps.end())
186  outputReporter<Real>(r_name);
187  }
188 }
189 
190 void
192 {
193  // List of VPP objects with output
194  const std::set<std::string> & out = getVectorPostprocessorOutput();
195 
196  for (const auto & r_name : _reporter_data.getReporterNames())
197  {
198  const std::string & vpp_name = r_name.getObjectName();
199  const std::string & vec_name = r_name.getValueName();
200  const bool vpp_out = out.find(vpp_name) != out.end();
201  if (vpp_out && (_reporter_data.hasReporterValue<VectorPostprocessorValue>(r_name)))
202  {
203  auto insert_pair =
205 
206  FormattedTable & table = insert_pair.first->second;
207  table.outputTimeColumn(false);
208 
209  const auto & vector = _reporter_data.getReporterValue<VectorPostprocessorValue>(r_name);
210  table.addData(vec_name, vector);
211 
212  if (_time_data)
213  {
215  t_table.addData("timestep", _t_step, _time);
216  }
217  }
218  }
219 }
220 
221 void
223 {
224  // List of scalar variables
225  const std::set<std::string> & out = getScalarOutput();
226 
227  // Loop through each variable
228  for (const auto & out_name : out)
229  {
230  // Get reference to the variable (0 is for TID)
231  MooseVariableScalar & scalar_var = _problem_ptr->getScalarVariable(0, out_name);
232 
233  // Make sure the value of the variable is in sync with the solution vector
234  scalar_var.reinit();
235 
236  // Next we need to make sure all processors agree on the value of
237  // the variable - not all processors may be able to see all
238  // scalars!
239 
240  // Make a copy rather than taking a reference to the MooseArray,
241  // because if a processor can't see that scalar variable's values
242  // then we'll need to do our own communication of them.
243  VariableValue value(scalar_var.sln());
244  auto value_size = value.size();
245 
246  // libMesh *does* currently guarantee that all processors can
247  // calculate all scalar DoF indices, so this is a const reference
248  const std::vector<dof_id_type> & dof_indices = scalar_var.dofIndices();
249  auto dof_size = dof_indices.size();
250  bool need_release = false;
251 
252  // In dbg mode, if we don't see a scalar we might not even have
253  // its array allocated to full length yet.
254  if (dof_size > value_size)
255  {
256  value.resize(dof_size);
257  need_release = true;
258  }
259 
260  // Finally, let's just let the owners broadcast their values.
261  // There's probably lots of room to optimize this communication
262  // via merging broadcasts and making them asynchronous, but this
263  // code path shouldn't be hit often enough for that to matter.
264 
265  const DofMap & dof_map = scalar_var.sys().dofMap();
266  for (decltype(dof_size) i = 0; i < dof_size; ++i)
267  {
268  const processor_id_type pid = dof_map.dof_owner(dof_indices[i]);
269  this->comm().broadcast(value[i], pid);
270  }
271 
272  // If the variable has a single component, simply output the value with the name
273  if (dof_size == 1)
274  {
275  _scalar_table.addData(out_name, value[0], getOutputTime());
276  _all_data_table.addData(out_name, value[0], getOutputTime());
277  }
278 
279  // Multi-component variables are appended with the component index
280  else
281  for (decltype(dof_size) i = 0; i < dof_size; ++i)
282  {
283  std::ostringstream os;
284  os << out_name << "_" << i;
287  }
288 
289  // If we ended up reallocating, we'll need to release memory or leak it
290  if (need_release)
291  value.release();
292  }
293 }
294 
295 void
297 {
300  for (auto & pair : _vector_postprocessor_tables)
301  pair.second.clear();
302  for (auto & pair : _vector_postprocessor_time_tables)
303  pair.second.clear();
306 }
const std::set< std::string > & getPostprocessorOutput()
The list of postprocessor names that are set for output.
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:380
processor_id_type dof_owner(const dof_id_type dof) const
void setDocString(const std::string &name, const std::string &doc)
Set the doc string of a parameter.
void reinit(bool reinit_for_derivative_reordering=false)
Fill out the VariableValue arrays from the system solution vector.
static constexpr Real TOLERANCE
void addData(const std::string &name, const T &value)
Method for adding data to the output table.
FormattedTable & _postprocessor_table
Table containing postprocessor data.
Definition: TableOutput.h:89
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
Definition: ExecFlagEnum.h:82
int & _t_step
The current time step.
Definition: Output.h:220
bool empty() const
Returns a boolean value based on whether the FormattedTable contains data or not. ...
std::basic_ostream< charT, traits > * os
Definition: InfixIterator.h:33
static void addMultiAppFixedPointIterationEndExecFlag(InputParameters &params, const std::string &param)
Adds the exec flag MULTIAPP_FIXED_POINT_ITERATION_END to a parameter.
Definition: TableOutput.C:71
const std::set< std::string > & getVectorPostprocessorOutput()
The list of VectorPostprocessor names that are set for output.
std::pair< typename M::iterator, bool > moose_try_emplace(M &m, const typename M::key_type &k, Args &&... args)
Function to mirror the behavior of the C++17 std::map::try_emplace() method (no hint).
Definition: Moose.h:93
void outputTimeColumn(bool output_time)
Set whether or not to output time column.
virtual void outputVectorPostprocessors() override
Populates the tables with VectorPostprocessor values.
Definition: TableOutput.C:191
const std::set< std::string > & getReporterOutput()
The list of Reporter names that are set for output.
uint8_t processor_id_type
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
Definition: SystemBase.C:1165
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
const std::set< std::string > & getScalarOutput()
The list of scalar variables names that are set for output.
const T & getReporterValue(const ReporterName &reporter_name, const MooseObject &consumer, const ReporterMode &mode, const std::size_t time_index=0) const
Method for returning read only references to Reporter values.
Definition: ReporterData.h:388
TableOutput(const InputParameters &parameters)
Class constructor.
Definition: TableOutput.C:79
bool hasPostprocessorByName(const PostprocessorName &name) const
Determine if the Postprocessor data exists.
FormattedTable & _scalar_table
Table containing scalar aux variables.
Definition: TableOutput.h:98
const bool _time_column
Enable/disable output of time column for Postprocessors.
Definition: TableOutput.h:116
FEProblemBase * _problem_ptr
Pointer the the FEProblemBase object for output object (use this)
Definition: Output.h:185
virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the scalar variable reference from whichever system contains it.
void clear()
Definition: TableOutput.C:296
virtual const std::vector< dof_id_type > & dofIndices() const
Get local DoF indices.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
std::string getDocString() const
Generate a documentation string for the "execute_on" parameter.
Definition: ExecFlagEnum.C:40
virtual void outputReporters() override
Populates the tables with Reporter values.
Definition: TableOutput.C:160
const std::string & getObjectName() const
Return the object name that produces the Reporter value.
Definition: ReporterName.C:41
static InputParameters enableOutputTypes(const std::string &names=std::string())
A method for enabling individual output type control.
This class is used for building, formatting, and outputting tables of numbers.
const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name, std::size_t t_index=0) const
Get a read-only reference to the value associated with a Postprocessor that exists.
const bool _time_data
Enable/disable VecptorPostprocessor time data file.
Definition: TableOutput.h:113
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
Real getLastTime() const
Retrieve the last time (or independent variable) value.
std::set< ReporterName > getReporterNames() const
Return a list of all reporter names.
Definition: ReporterData.C:62
virtual void outputPostprocessors() override
Populates the tables with postprocessor values.
Definition: TableOutput.C:109
const ReporterData & _reporter_data
Storage for Reporter values.
FormattedTable & _all_data_table
Table containing postprocessor values, scalar aux variables, and Real Reporters.
Definition: TableOutput.h:104
Based class for output objects.
OutputTools< Real >::VariableValue VariableValue
Definition: MooseTypes.h:314
std::vector< Real > VectorPostprocessorValue
Definition: MooseTypes.h:203
const bool _check_all_columns_for_new_row
If true, new postprocessor rows can be added if any column has a new value.
Definition: TableOutput.h:107
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
OStreamProxy out
const ExecFlagType EXEC_MULTIAPP_FIXED_POINT_ITERATION_END
Definition: Moose.C:36
Class for scalar variables (they are different).
void outputPostprocessorsRow(FormattedTable &table)
Outputs a new postprocessor row.
Definition: TableOutput.C:151
FormattedTable & _reporter_table
Table containing Real Reporter values.
Definition: TableOutput.h:101
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
bool hasReporterValue(const ReporterName &reporter_name) const
Return True if a Reporter value with the given type and name have been created.
Definition: ReporterData.h:445
const Real _new_row_tol
Tolerance used when deciding whether or not to add a new row to the table.
Definition: TableOutput.h:110
void addRow(Real time)
Force a new row in the table with the passed in time.
static InputParameters validParams()
SystemBase & sys()
Get the system this variable is part of.
T & getLastData(const std::string &name) const
Retrieve Data for last value of given name.
const VariableValue & sln() const
Real & _time
The current time for output purposes.
Definition: Output.h:214
virtual Real getOutputTime()
Get the time that will be used for stream/file outputting.
Definition: PetscOutput.C:273
std::map< std::string, FormattedTable > _vector_postprocessor_tables
Formatted tables for outputting vector postprocessor data. One per VectorPostprocessor.
Definition: TableOutput.h:92
bool shouldOutputPostprocessorsRow(const FormattedTable &table)
Checks to see if a new postprocessor row should be added.
Definition: TableOutput.C:119
The Reporter system is comprised of objects that can contain any number of data values.
Definition: ReporterName.h:30
virtual void outputScalarVariables() override
Populates the tables with scalar aux variables.
Definition: TableOutput.C:222
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...
std::map< std::string, FormattedTable > & _vector_postprocessor_time_tables
Table for vector postprocessor time data.
Definition: TableOutput.h:95
static InputParameters validParams()
Definition: TableOutput.C:26