https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
70void
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
108void
117
118bool
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
150void
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
159void
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
190void
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();
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
221void
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;
285 _scalar_table.addData(os.str(), value[i], getOutputTime());
286 _all_data_table.addData(os.str(), value[i], getOutputTime());
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
295void
297{
301 for (auto & pair : _vector_postprocessor_tables)
302 pair.second.clear();
303 for (auto & pair : _vector_postprocessor_time_tables)
304 pair.second.clear();
307}
OutputTools< Real >::VariableValue VariableValue
Definition MooseTypes.h:348
std::vector< Real > VectorPostprocessorValue
Definition MooseTypes.h:231
const ExecFlagType EXEC_MULTIAPP_FIXED_POINT_ITERATION_END
Definition Moose.C:38
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:103
Based class for output objects.
const std::set< std::string > & getReporterOutput()
The list of Reporter names that are set for output.
static InputParameters enableOutputTypes(const std::string &names=std::string())
A method for enabling individual output type control.
const ReporterData & _reporter_data
Storage for Reporter values.
void clearLastExecuteTime()
Clears bookkeeping used to suppress duplicate EXEC_FINAL output at the same time.
static InputParameters validParams()
const std::set< std::string > & getScalarOutput()
The list of scalar variables names that are set for output.
const std::set< std::string > & getVectorPostprocessorOutput()
The list of VectorPostprocessor names that are set for output.
const std::set< std::string > & getPostprocessorOutput()
The list of postprocessor names that are set for output.
A MultiMooseEnum object to hold "execute_on" flags.
std::string getDocString() const
Generate a documentation string for the "execute_on" parameter.
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the scalar variable reference from whichever system contains it.
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.
This class is used for building, formatting, and outputting tables of numbers.
bool empty() const
Returns a boolean value based on whether the FormattedTable contains data or not.
void addData(const std::string &name, const T &value)
Method for adding data to the output table.
T & getLastData(const std::string &name) const
Retrieve Data for last value of given name.
Real getLastTime() const
Retrieve the last time (or independent variable) value.
void addRow(Real time)
Force a new row in the table with the passed in time.
void outputTimeColumn(bool output_time)
Set whether or not to output time column.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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...
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.
void setDocString(const std::string &name, const std::string &doc)
Set the doc string of a parameter.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
virtual const std::vector< dof_id_type > & dofIndices() const
Get local DoF indices.
SystemBase & sys()
Get the system this variable is part of.
Class for scalar variables (they are different).
const VariableValue & sln() const
void reinit(bool reinit_for_derivative_reordering=false)
Fill out the VariableValue arrays from the system solution vector.
FEProblemBase * _problem_ptr
Pointer the the FEProblemBase object for output object (use this)
Definition Output.h:185
int & _t_step
The current time step.
Definition Output.h:220
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.
bool hasPostprocessorByName(const PostprocessorName &name) const
Determine if the Postprocessor data exists.
std::set< ReporterName > getReporterNames() const
Return a list of all reporter names.
bool hasReporterValue(const ReporterName &reporter_name) const
Return True if a Reporter value with the given type and name have been created.
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.
The Reporter system is comprised of objects that can contain any number of data values.
const std::string & getObjectName() const
Return the object name that produces the Reporter value.
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
virtual void outputScalarVariables() override
Populates the tables with scalar aux variables.
FormattedTable & _reporter_table
Table containing Real Reporter values.
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 bool _time_column
Enable/disable output of time column for Postprocessors.
virtual void outputVectorPostprocessors() override
Populates the tables with VectorPostprocessor values.
FormattedTable & _scalar_table
Table containing scalar aux variables.
Definition TableOutput.h:98
const bool _check_all_columns_for_new_row
If true, new postprocessor rows can be added if any column has a new value.
TableOutput(const InputParameters &parameters)
Class constructor.
Definition TableOutput.C:79
std::map< std::string, FormattedTable > _vector_postprocessor_tables
Formatted tables for outputting vector postprocessor data. One per VectorPostprocessor.
Definition TableOutput.h:92
virtual void outputReporters() override
Populates the tables with Reporter values.
const Real _new_row_tol
Tolerance used when deciding whether or not to add a new row to the table.
static InputParameters validParams()
Definition TableOutput.C:26
virtual void outputPostprocessors() override
Populates the tables with postprocessor values.
FormattedTable & _postprocessor_table
Table containing postprocessor data.
Definition TableOutput.h:89
std::map< std::string, FormattedTable > & _vector_postprocessor_time_tables
Table for vector postprocessor time data.
Definition TableOutput.h:95
const bool _time_data
Enable/disable VecptorPostprocessor time data file.
bool shouldOutputPostprocessorsRow(const FormattedTable &table)
Checks to see if a new postprocessor row should be added.
FormattedTable & _all_data_table
Table containing postprocessor values, scalar aux variables, and Real Reporters.
void outputPostprocessorsRow(FormattedTable &table)
Outputs a new postprocessor row.
const Parallel::Communicator & comm() const
static constexpr Real TOLERANCE