Line data Source code
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 "CommonOutputAction.h"
12 : #include "MooseApp.h"
13 : #include "FEProblem.h"
14 : #include "MooseObjectAction.h"
15 : #include "ActionFactory.h"
16 : #include "Output.h"
17 : #include "OutputWarehouse.h"
18 : #include "MooseUtils.h"
19 :
20 : // Extrnal includes
21 : #include "tinydir.h"
22 : #include "pcrecpp.h"
23 : #include <libgen.h>
24 : #include <sys/types.h>
25 : #include <sys/stat.h>
26 : #include <unistd.h>
27 :
28 : registerMooseAction("MooseApp", CommonOutputAction, "common_output");
29 : registerMooseAction("MooseApp", CommonOutputAction, "add_output");
30 : registerMooseAction("MooseApp", CommonOutputAction, "add_reporter");
31 :
32 : const ReporterName CommonOutputAction::perf_graph_json_reporter("perf_graph_json", "graph");
33 :
34 : InputParameters
35 69457 : CommonOutputAction::validParams()
36 : {
37 69457 : InputParameters params = Action::validParams();
38 138914 : params.addClassDescription("Adds short-cut syntax and common parameters to the Outputs block.");
39 :
40 : // Short-cut methods for typical output objects
41 208371 : params.addParam<bool>(
42 138914 : "exodus", false, "Output the results using the default settings for Exodus output.");
43 208371 : params.addParam<bool>(
44 138914 : "nemesis", false, "Output the results using the default settings for Nemesis output");
45 208371 : params.addParam<bool>(
46 138914 : "console", true, "Output the results using the default settings for Console output");
47 208371 : params.addParam<bool>("csv",
48 138914 : false,
49 : "Output the scalar variable and postprocessors to a *.csv "
50 : "file using the default CSV output.");
51 208371 : params.addParam<bool>("xml",
52 138914 : false,
53 : "Output the vector postprocessors to a *.xml "
54 : "file using the default XML output.");
55 208371 : params.addParam<bool>("json",
56 138914 : false,
57 : "Output Reporter values to a *.json "
58 : "file using the default JSON output.");
59 208371 : params.addParam<bool>(
60 138914 : "vtk", false, "Output the results using the default settings for VTKOutput output");
61 208371 : params.addParam<bool>(
62 138914 : "xda", false, "Output the results using the default settings for XDA/XDR output (ascii)");
63 208371 : params.addParam<bool>(
64 138914 : "xdr", false, "Output the results using the default settings for XDA/XDR output (binary)");
65 208371 : params.addParam<bool>(
66 138914 : "gmv", false, "Output the results using the default settings for GMV output");
67 208371 : params.addParam<bool>(
68 138914 : "tecplot", false, "Output the results using the default settings for Tecplot output");
69 208371 : params.addParam<bool>(
70 : "gnuplot",
71 138914 : false,
72 : "Output the scalar and postprocessor results using the default settings for GNUPlot output");
73 208371 : params.addParam<bool>(
74 138914 : "solution_history", false, "Print a solution history file (.slh) using the default settings");
75 277828 : params.addParam<bool>("progress", false, "Print a progress bar");
76 277828 : params.addParam<bool>("dofmap", false, "Create the dof map .json output file");
77 277828 : params.addParam<bool>("controls", false, "Enable the screen output of Control systems.");
78 :
79 : // Common parameters
80 :
81 : // Note: Be sure that objects that share these parameters utilize the same defaults
82 277828 : params.addParam<bool>("color", true, "Set to false to turn off all coloring in all outputs");
83 277828 : params.addParam<std::string>("file_base",
84 : "Common file base name to be utilized with all output objects");
85 277828 : params.addParam<std::vector<std::string>>("output_if_base_contains",
86 : "If this is supplied then output will only be done in "
87 : "the case that the output base contains one of these "
88 : "strings. This is helpful in outputting only a subset "
89 : "of outputs when using MultiApps.");
90 208371 : params.addParam<unsigned int>(
91 138914 : "time_step_interval", 1, "The interval (number of time steps) at which output occurs");
92 208371 : params.addParam<std::vector<Real>>("sync_times",
93 138914 : std::vector<Real>(),
94 : "Times at which the output and solution is forced to occur");
95 208371 : params.addParam<Real>(
96 138914 : "minimum_time_interval", 0.0, "The minimum simulation time between output steps");
97 208371 : params.addParam<bool>(
98 138914 : "append_date", false, "When true the date and time are appended to the output filename.");
99 277828 : params.addParam<std::string>("append_date_format",
100 : "The format of the date/time to append (see "
101 : "http://www.cplusplus.com/reference/ctime/"
102 : "strftime).");
103 :
104 277828 : params.addParam<std::vector<VariableName>>(
105 : "hide",
106 : {},
107 : "A list of the variables and postprocessors that should NOT be output to the Exodus "
108 : "file (may include Variables, ScalarVariables, and Postprocessor names).");
109 208371 : params.addParam<std::vector<VariableName>>(
110 : "show",
111 : {},
112 : "A list of the variables and postprocessors that should be output to the Exodus file "
113 : "(may include Variables, ScalarVariables, and Postprocessor names).");
114 :
115 : // Add the 'execute_on' input parameter
116 69457 : ExecFlagEnum exec_enum = Output::getDefaultExecFlagEnum();
117 208371 : exec_enum = {EXEC_INITIAL, EXEC_TIMESTEP_END};
118 208371 : params.addParam<ExecFlagEnum>("execute_on", exec_enum, exec_enum.getDocString());
119 :
120 : // Add special Console flags
121 347285 : params.addDeprecatedParam<bool>(
122 138914 : "print_perf_log", false, "Use perf_graph instead!", "Use perf_graph instead!");
123 :
124 208371 : params.addParam<bool>(
125 138914 : "perf_graph", false, "Enable printing of the performance graph to the screen (Console)");
126 :
127 277828 : params.addParam<bool>("perf_graph_live", true, "Enables printing of live progress messages");
128 208371 : params.addParam<Real>(
129 138914 : "perf_graph_live_time_limit", 5.0, "Time (in seconds) to wait before printing a message.");
130 208371 : params.addParam<unsigned int>(
131 138914 : "perf_graph_live_mem_limit", 100, "Memory (in MB) to cause a message to be printed.");
132 277828 : params.addParam<bool>("perf_graph_json", false, "Output the perf graph in JSON");
133 277828 : params.addParam<FileName>("perf_graph_json_file", "Path to a .json file to store the perf graph");
134 :
135 208371 : params.addParam<bool>("print_mesh_changed_info",
136 138914 : false,
137 : "When true, each time the mesh is changed the mesh information is printed");
138 208371 : params.addParam<bool>("print_linear_residuals",
139 138914 : true,
140 : "Enable printing of linear residuals to the screen (Console)");
141 208371 : params.addParam<bool>("print_nonlinear_residuals",
142 138914 : true,
143 : "Enable printing of nonlinear residuals to the screen (Console)");
144 208371 : params.addParam<bool>("print_nonlinear_converged_reason",
145 138914 : true,
146 : "Enable/disable printing of the nonlinear solver convergence reason to the "
147 : "screen. This parameter only affects the output of the third-party solver "
148 : "(e.g. PETSc), not MOOSE itself.");
149 208371 : params.addParam<bool>("print_linear_converged_reason",
150 138914 : true,
151 : "Enable/disable printing of the linear solver convergence reason to the "
152 : "screen. This parameter only affects the output of the third-party solver "
153 : "(e.g. PETSc), not MOOSE itself.");
154 :
155 138914 : params.addParam<bool>(
156 : "solution_invalidity_history",
157 138914 : true,
158 : "Enable printing of the time history of the solution invalidity occurrences "
159 : "to the screen (console)");
160 :
161 : // Return object
162 138914 : return params;
163 138914 : }
164 :
165 69252 : CommonOutputAction::CommonOutputAction(const InputParameters & params)
166 207756 : : Action(params), _action_params(_action_factory.getValidParams("AddOutputAction"))
167 : {
168 69252 : }
169 :
170 : void
171 195758 : CommonOutputAction::act()
172 : {
173 195758 : if (_current_task == "common_output")
174 : {
175 : // Store the common output parameters in the OutputWarehouse
176 69062 : _app.getOutputWarehouse().setCommonParameters(&_pars);
177 :
178 : // Create the actions for the short-cut methods
179 : #ifdef LIBMESH_HAVE_EXODUS_API
180 207186 : if (getParam<bool>("exodus"))
181 107973 : create("Exodus", "exodus");
182 : #else
183 : if (getParam<bool>("exodus"))
184 : mooseWarning("Exodus output requested but not enabled through libMesh");
185 : #endif
186 :
187 : #ifdef LIBMESH_HAVE_NEMESIS_API
188 207186 : if (getParam<bool>("nemesis"))
189 771 : create("Nemesis", "nemesis");
190 : #else
191 : if (getParam<bool>("nemesis"))
192 : mooseWarning("Nemesis output requested but not enabled through libMesh");
193 : #endif
194 :
195 : // Only create a Console if screen output was not created
196 207186 : if (getParam<bool>("console") && !hasConsole())
197 203481 : create("Console", "console");
198 :
199 207186 : if (getParam<bool>("csv"))
200 36291 : create("CSV", "csv");
201 :
202 207186 : if (getParam<bool>("xml"))
203 180 : create("XMLOutput", "xml");
204 :
205 207186 : if (getParam<bool>("json"))
206 411 : create("JSON", "json");
207 :
208 : #ifdef LIBMESH_HAVE_VTK
209 207186 : if (getParam<bool>("vtk"))
210 273 : create("VTK", "vtk");
211 : #else
212 : if (getParam<bool>("vtk"))
213 : mooseWarning("VTK output requested but not enabled through libMesh");
214 : #endif
215 :
216 207186 : if (getParam<bool>("xda"))
217 390 : create("XDA", "xda");
218 :
219 207186 : if (getParam<bool>("xdr"))
220 156 : create("XDR", "xdr");
221 :
222 207186 : if (getParam<bool>("gmv"))
223 114 : create("GMV", "gmv");
224 :
225 207186 : if (getParam<bool>("tecplot"))
226 117 : create("Tecplot", "tecplot");
227 :
228 207186 : if (getParam<bool>("gnuplot"))
229 39 : create("Gnuplot", "gnuplot");
230 :
231 207186 : if (getParam<bool>("solution_history"))
232 39 : create("SolutionHistory", "solution_history");
233 :
234 207186 : if (getParam<bool>("progress"))
235 30 : create("Progress", "progress");
236 :
237 207186 : if (getParam<bool>("dofmap"))
238 78 : create("DOFMap", "dofmap");
239 :
240 : // Helper for looking through a pair of [parameters, param name]
241 : // to find a true boolean parameter, returning the pair that was found
242 : const auto find_param =
243 138114 : [](const std::vector<std::pair<const InputParameters *, std::string>> & options)
244 : {
245 138114 : std::optional<std::string> from_param_name;
246 138114 : const InputParameters * from_params = nullptr;
247 310107 : for (const auto & [params, param_name] : options)
248 237916 : if (params->template get<bool>(param_name))
249 : {
250 65923 : from_param_name = param_name;
251 65923 : from_params = params;
252 65923 : break;
253 : }
254 276228 : return std::make_pair(from_param_name, from_params);
255 138114 : };
256 :
257 : {
258 69062 : const auto [from_param_name, from_params] =
259 276248 : find_param({{¶meters(), "controls"}, {&_app.parameters(), "show_controls"}});
260 69062 : if (from_param_name)
261 60 : create("ControlOutput", *from_param_name, from_params);
262 69062 : }
263 :
264 207186 : if (!_app.getParam<bool>("no_timing"))
265 : {
266 276208 : auto [from_param_name, from_params] = find_param({{¶meters(), "perf_graph"},
267 0 : {¶meters(), "print_perf_log"},
268 345260 : {&_app.parameters(), "timing"}});
269 69052 : if (from_param_name)
270 197709 : create("PerfGraphOutput", *from_param_name, from_params);
271 :
272 26 : const auto add_perf_graph_json = [this](const std::string & from_param_name,
273 : const std::string & set_param_name,
274 : const std::string & set_param_value)
275 : {
276 : // To avoid this reporter value appearing in all other JSON output
277 26 : _common_reporter_names.push_back(perf_graph_json_reporter);
278 :
279 52 : auto params = _factory.getValidParams("JSON");
280 78 : params.set<std::vector<ReporterName>>("reporters") = {perf_graph_json_reporter};
281 78 : params.set<ExecFlagEnum>("execute_on") = {EXEC_FINAL};
282 78 : params.set<ExecFlagEnum>("execute_system_information_on") = {EXEC_NONE};
283 26 : params.set<std::string>(set_param_name) = set_param_value;
284 26 : params.set<bool>("distributed") = false;
285 26 : if (set_param_name == "file_base")
286 26 : params.set<bool>("append_date") = false;
287 78 : create("JSON", from_param_name, ¶meters(), ¶ms, from_param_name);
288 104 : };
289 :
290 207156 : if (getParam<bool>("perf_graph_json"))
291 78 : add_perf_graph_json("perf_graph_json", "file_base_suffix", "perf_graph");
292 207156 : if (isParamValid("perf_graph_json_file"))
293 : {
294 34 : const auto & file = getParam<FileName>("perf_graph_json_file");
295 17 : if (MooseUtils::getExtension(file, true) != "json")
296 8 : paramError("perf_graph_json_file", "File must end with .json");
297 13 : const auto file_stripped = MooseUtils::stripExtension(file, true);
298 39 : add_perf_graph_json("perf_graph_json_file", "file_base", file_stripped);
299 13 : }
300 :
301 207144 : if (!getParam<bool>("perf_graph_live"))
302 : {
303 0 : if (!from_param_name)
304 0 : perfGraph().setActive(false);
305 0 : perfGraph().disableLivePrint();
306 : }
307 69048 : }
308 : else
309 : {
310 10 : perfGraph().setActive(false);
311 10 : perfGraph().disableLivePrint();
312 : }
313 :
314 138116 : perfGraph().setLiveTimeLimit(getParam<Real>("perf_graph_live_time_limit"));
315 138116 : perfGraph().setLiveMemoryLimit(getParam<unsigned int>("perf_graph_live_mem_limit"));
316 :
317 207174 : if (getParam<bool>("solution_invalidity_history"))
318 : {
319 207144 : create("SolutionInvalidityOutput", "solution_invalidity_history");
320 : }
321 :
322 207174 : if (!getParam<bool>("color"))
323 185 : Moose::setColorConsole(false);
324 : }
325 126696 : else if (_current_task == "add_output")
326 : {
327 : // More like remove output. This can't be done during the "common_output" task because the
328 : // finite element problem is not yet constructed
329 :
330 443934 : if (!getParam<bool>("console") || (isParamValid("print_nonlinear_converged_reason") &&
331 253638 : !getParam<bool>("print_nonlinear_converged_reason")))
332 73 : Moose::PetscSupport::dontAddNonlinearConvergedReason(*_problem);
333 :
334 443934 : if (!getParam<bool>("console") || (isParamValid("print_linear_converged_reason") &&
335 253638 : !getParam<bool>("print_linear_converged_reason")))
336 83 : Moose::PetscSupport::dontAddLinearConvergedReason(*_problem);
337 : }
338 63264 : else if (_current_task == "add_reporter")
339 : {
340 316310 : if (!_app.getParam<bool>("no_timing") &&
341 379508 : (getParam<bool>("perf_graph_json") || isParamValid("perf_graph_json_file")))
342 : {
343 78 : auto params = _factory.getValidParams("PerfGraphReporter");
344 26 : params.set<ExecFlagEnum>("execute_on") = EXEC_FINAL;
345 52 : _problem->addReporter("PerfGraphReporter", perf_graph_json_reporter.getObjectName(), params);
346 26 : }
347 : }
348 : else
349 0 : mooseError("unrecognized task ", _current_task, " in CommonOutputAction.");
350 333868 : }
351 :
352 : void
353 251778 : CommonOutputAction::create(const std::string & object_type,
354 : const std::optional<std::string> & param_name,
355 : const InputParameters * const from_params /* = nullptr */,
356 : const InputParameters * const apply_params /* = nullptr */,
357 : const std::optional<std::string> & object_name /* = {} */)
358 : {
359 : // Create our copy of the parameters
360 251778 : auto params = _action_params;
361 :
362 : // Set the 'type =' parameters for the desired object
363 251778 : params.set<std::string>("type") = object_type;
364 :
365 : // Create the complete object name (uses lower case of type)
366 251778 : std::string name;
367 251778 : if (object_name)
368 26 : name = *object_name;
369 : else
370 : {
371 251752 : name = object_type;
372 251752 : std::transform(name.begin(), name.end(), name.begin(), ::tolower);
373 : }
374 :
375 : // Create the action
376 : std::shared_ptr<MooseObjectAction> action = std::static_pointer_cast<MooseObjectAction>(
377 503556 : _action_factory.create("AddOutputAction", name, params));
378 251778 : auto & object_params = action->getObjectParams();
379 :
380 : // Set flag indicating that the object to be created was created with short-cut syntax
381 251778 : object_params.set<bool>("_built_by_moose") = true;
382 :
383 : // Apply any additional parameters
384 251778 : if (apply_params)
385 26 : object_params.applyParameters(*apply_params);
386 :
387 : // Associate all action output object errors with param_name
388 : // If from_params is specified, it means to associate it with parameters other than parameters()
389 251778 : if (param_name)
390 : {
391 251778 : const InputParameters & associated_params = from_params ? *from_params : parameters();
392 251778 : associateWithParameter(associated_params, *param_name, object_params);
393 : }
394 :
395 : // Add the action to the warehouse
396 251778 : _awh.addActionBlock(action);
397 251778 : }
398 :
399 : bool
400 69032 : CommonOutputAction::hasConsole()
401 : {
402 :
403 : // Loop through all of the actions for adding output objects
404 207096 : for (ActionIterator it = _awh.actionBlocksWithActionBegin("add_output");
405 564036 : it != _awh.actionBlocksWithActionEnd("add_output");
406 118980 : it++)
407 : {
408 120185 : MooseObjectAction * moa = dynamic_cast<MooseObjectAction *>(*it);
409 120185 : if (!moa)
410 70856 : continue;
411 :
412 49329 : const std::string & type = moa->getMooseObjectType();
413 49329 : InputParameters & params = moa->getObjectParams();
414 49329 : if (type.compare("Console") == 0 && params.get<bool>("output_screen"))
415 1205 : return true;
416 : }
417 :
418 67827 : return false;
419 : }
|