https://mooseframework.inl.gov
Loading...
Searching...
No Matches
JSONOutput.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// Moose includes
11#include "JSONOutput.h"
12#include "FEProblem.h"
13#include "MooseApp.h"
14#include "JsonIO.h"
15#include "Reporter.h"
16#include "TheWarehouse.h"
17#include "CommonOutputAction.h"
18
20
23{
25 params += AdvancedOutput::enableOutputTypes("system_information reporter");
26 params.addClassDescription("Output for Reporter values using JSON format.");
27 params.set<ExecFlagEnum>("execute_system_information_on", /*quite_mode=*/true) = EXEC_INITIAL;
28 params.addParam<bool>(
29 "use_legacy_reporter_output", false, "Use reporter output that does not group by object.");
30 params.addParam<bool>("one_file_per_timestep",
31 false,
32 "Create a unique output file for each time step of the simulation.");
33 params.addParam<std::vector<ReporterName>>(
34 "reporters", "Specific reporter values to output; if not set, all will be output");
35 params.addParam<bool>(
36 "distributed", true, "Whether or not to output distributed data (data not on rank 0)");
37 return params;
38}
39
41 : AdvancedOutput(parameters),
42 _reporter_data(_problem_ptr->getReporterData()),
43 _one_file_per_timestep(getParam<bool>("one_file_per_timestep")),
44 _reporters(queryParam<std::vector<ReporterName>>("reporters")),
45 _json(declareRestartableData<nlohmann::json>("json_out_str"))
46{
47}
48
49void
51{
52 if (_reporters && _reporters->size())
53 for (const auto & name : *_reporters)
55 paramError("reporters", "Reporter value '", name, "' was not found");
56}
57
58std::string
60{
61 std::ostringstream file_name;
62 file_name << _file_base;
63
65 file_name << '_' << std::setw(_padding) << std::setprecision(0) << std::setfill('0')
66 << std::right << timeStep();
67
68 if (processor_id() > 0)
69 {
70 int digits = MooseUtils::numDigits(n_processors());
71 file_name << ".json"
72 << "." << std::setw(digits) << std::setfill('0') << processor_id();
73 }
74 else
75 file_name << ".json";
76
77 return file_name.str();
78}
79
80void
82{
83 nlohmann::to_json(_json, _app);
84}
85
86void
93
94void
96{
97 // Get the reporter values that we should skip. The common output action can
98 // add JSON output objects for specific reporters, of which we don't want to
99 // include within the standard json output
100 std::set<ReporterName> skip_names;
101 const auto common_actions = _app.actionWarehouse().getActions<CommonOutputAction>();
102 if (common_actions.size())
103 {
104 mooseAssert(common_actions.size() == 1, "Should not be more than one");
105 const auto & action = *common_actions[0];
106 const auto & common_names = action.getCommonReporterNames();
107 skip_names.insert(common_names.begin(), common_names.end());
108 }
109
110 // Set of ReporterNames for output
111 std::set<ReporterName> r_names;
112 for (const std::string & c_name : getReporterOutput())
113 {
114 const ReporterName r_name(c_name);
115
116 // If specific values are requested, skip anything that isn't that value
117 if (_reporters)
118 {
119 if (std::find(_reporters->begin(), _reporters->end(), r_name) == _reporters->end())
120 continue;
121 }
122 // If all values are requested, skip those that should be skipped
123 else if (skip_names.count(r_name))
124 continue;
125
126 r_names.emplace(r_name);
127 }
128
129 // Is there ANY distributed data
130 _has_distributed = getParam<bool>("distributed") &&
131 std::any_of(r_names.begin(),
132 r_names.end(),
133 [this](const ReporterName & n)
134 {
135 return _reporter_data.hasReporterWithMode(
136 n.getObjectName(), REPORTER_MODE_DISTRIBUTED);
137 });
138 if (processor_id() == 0 || _has_distributed)
139 {
140 // Create the current output node
141 auto & current_node = _json["time_steps"].emplace_back();
142
143 // Add time/iteration information
144 current_node["time"] = _problem_ptr->time();
145 current_node["time_step"] = _problem_ptr->timeStep();
147 current_node["linear_iteration"] = _linear_iter;
149 current_node["nonlinear_iteration"] = _nonlinear_iter;
150
151 // Inject processor info
152 if (n_processors() > 1 && _has_distributed)
153 {
154 _json["part"] = processor_id();
155 _json["number_of_parts"] = n_processors();
156 }
157
158 // Add Reporter values to the current node
159 auto & r_node = _json["reporters"]; // non-accidental insert
160 for (const auto & r_name : r_names)
161 {
162 // If this value is produced in root mode and we're not on root, don't report this value
163 const auto & context = _reporter_data.getReporterContextBase(r_name);
164 if (context.getProducerModeEnum() == REPORTER_MODE_ROOT && processor_id() != 0)
165 continue;
166
167 // Create/get object node
168 auto obj_node_pair = r_node.emplace(r_name.getObjectName(), nlohmann::json());
169 auto & obj_node = *(obj_node_pair.first);
170
171 // Whether or not we should store this Reporter's value or have it be null
172 bool should_store = true;
173
174 // If the object node was created insert the class level information
175 if (obj_node_pair.second)
176 {
177 // Query the TheWarehouse for all Reporter objects with the given name. The attributes and
178 // QueryID are used to allow the TheWarehouse::queryInto method be called with the
179 // "show_all" option set to true. This returns all objects, regardless of "enabled" state,
180 // which is what is needed to ensure that output always happens, even if an object is
181 // disabled.
182 std::vector<Reporter *> objs;
183 auto attr = _problem_ptr->theWarehouse()
184 .query()
186 .condition<AttribName>(r_name.getObjectName())
187 .attributes();
188 auto qid = _problem_ptr->theWarehouse().queryID(attr);
189 _problem_ptr->theWarehouse().queryInto(qid, objs, true);
190
191 // There can now be multiple reporter objects with the same name, but
192 // there will only be one reporter that stores all the data.
193 if (!objs.empty())
194 {
195 auto & reporter = *objs.front();
196
197 // It is possible to have a Reporter value without a reporter objects (i.e., VPPs, PPs),
198 // which is why objs can be empty.
199 reporter.store(obj_node);
200
201 // GeneralReporters have the option to only store JSON data when the execute flag
202 // matches an execute flag that is within the GeneralReporter; this captures that
203 should_store = reporter.shouldStore();
204 }
205 }
206
207 // Create/get value node
208 auto value_node_pair = obj_node["values"].emplace(r_name.getValueName(), nlohmann::json());
209 // If the value node was created insert the value information
210 if (value_node_pair.second)
211 // Store value meta data
212 context.storeInfo(*value_node_pair.first);
213
214 // Insert reporter value
215 auto & node = current_node[r_name.getObjectName()][r_name.getValueName()];
216 if (should_store)
217 context.store(node);
218 else
219 node = "null";
220 }
221 }
222}
223
224void
226{
227 _has_distributed = false;
229 if (processor_id() == 0 || _has_distributed)
230 {
231 std::ofstream out(filename().c_str());
232 out << std::setw(4) << _json << std::endl;
233 }
234}
235
236template <>
237void
238dataStore(std::ostream & stream, nlohmann::json & json, void * /*context*/)
239{
240 stream << json;
241}
242
243template <>
244void
245dataLoad(std::istream & stream, nlohmann::json & json, void * /*context*/)
246{
247 stream >> json;
248}
void dataStore(std::ostream &stream, nlohmann::json &json, void *)
Definition JSONOutput.C:238
void dataLoad(std::istream &stream, nlohmann::json &json, void *)
Definition JSONOutput.C:245
registerMooseObjectAliased("MooseApp", JSONOutput, "JSON")
const ExecFlagType EXEC_INITIAL
Definition Moose.C:30
const ExecFlagType EXEC_LINEAR
Definition Moose.C:31
const ExecFlagType EXEC_NONLINEAR
Definition Moose.C:33
const ReporterMode REPORTER_MODE_ROOT
std::vector< const T * > getActions()
Retrieve all actions in a specific type ordered by their names.
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.
virtual void output()
A single call to this function should output all the necessary data for a single timestep.
static InputParameters validParams()
Meta-action for creating common output object parameters This action serves two purpose,...
A MultiMooseEnum object to hold "execute_on" flags.
const ReporterData & getReporterData() const
Provides const access the ReporterData object.
TheWarehouse & theWarehouse() const
virtual Real & time() const
virtual int & timeStep() const
unsigned int _padding
Number of digits to pad the extensions.
Definition FileOutput.h:83
std::string _file_base
The base filename from the input paramaters.
Definition FileOutput.h:89
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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 addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
virtual std::string filename() override
The filename for the output file.
Definition JSONOutput.C:59
virtual void initialSetup() override
Call init() method on setup.
Definition JSONOutput.C:50
const std::vector< ReporterName > *const _reporters
The names of the specific reporters to output (if any)
Definition JSONOutput.h:35
bool _has_distributed
True when distributed data exists for output.
Definition JSONOutput.h:41
virtual void timestepSetup() override
Gets called at the beginning of the timestep before this object is asked to do its job.
Definition JSONOutput.C:87
nlohmann::json & _json
The root JSON node for output.
Definition JSONOutput.h:38
const ReporterData & _reporter_data
Definition JSONOutput.h:28
const bool _one_file_per_timestep
Flag to create a file for each time step.
Definition JSONOutput.h:32
JSONOutput(const InputParameters &parameters)
Definition JSONOutput.C:40
static InputParameters validParams()
Definition JSONOutput.C:22
virtual void outputReporters() override
Output Reporter values.
Definition JSONOutput.C:95
virtual void output() override
A single call to this function should output all the necessary data for a single timestep.
Definition JSONOutput.C:225
virtual void outputSystemInformation() override
Definition JSONOutput.C:81
ActionWarehouse & actionWarehouse()
Return a writable reference to the ActionWarehouse associated with this app.
Definition MooseApp.h:217
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
bool isValueSet(const std::string &value) const
Methods for seeing if a value is set in the MultiMooseEnum.
FEProblemBase * _problem_ptr
Pointer the the FEProblemBase object for output object (use this)
Definition Output.h:185
virtual int timeStep()
Get the current time step.
Definition Output.C:387
PetscInt _nonlinear_iter
Current non-linear iteration returned from PETSc.
Definition PetscOutput.h:84
PetscInt _linear_iter
Current linear iteration returned from PETSc.
Definition PetscOutput.h:87
bool _on_nonlinear_residual
True if current output call is on the non-linear residual (used by time())
Definition PetscOutput.h:93
const ReporterContextBase & getReporterContextBase(const ReporterName &reporter_name) const
bool hasReporterValue(const ReporterName &reporter_name) const
Return True if a Reporter value with the given type and name have been created.
The Reporter system is comprised of objects that can contain any number of data values.
const ExecFlagEnum & _execute_enum
Execute settings for this object.
virtual void timestepSetup()
Gets called at the beginning of the timestep before this object is asked to do its job.
QueryCache & condition(Args &&... args)
Adds a new condition to the query.
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse.
std::vector< T * > & queryInto(const std::vector< std::unique_ptr< Attribute > > &conds, std::vector< T * > &results)
queryInto takes the given conditions (i.e.
std::size_t queryID(const std::vector< std::unique_ptr< Attribute > > &conds)
processor_id_type processor_id() const
processor_id_type n_processors() const