www.mooseframework.org
ConsoleUtils.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "ConsoleUtils.h"
12 
13 #include "AuxiliarySystem.h"
14 #include "Conversion.h"
15 #include "Executioner.h"
16 #include "MoosePreconditioner.h"
17 #include "FEProblem.h"
18 #include "MooseApp.h"
19 #include "MooseMesh.h"
20 #include "MooseObject.h"
21 #include "NonlinearSystem.h"
22 #include "OutputWarehouse.h"
23 #include "SystemInfo.h"
24 
25 #include "libmesh/string_to_enum.h"
26 
27 namespace ConsoleUtils
28 {
29 
30 std::string
31 indent(unsigned int spaces)
32 {
33  return std::string(spaces, ' ');
34 }
35 
36 std::string
38 {
39  std::stringstream oss;
40  oss << std::left;
41 
42  if (app.getSystemInfo() != NULL)
43  oss << app.getSystemInfo()->getInfo();
44 
45  oss << std::left << "Parallelism:\n"
46  << std::setw(console_field_width)
47  << " Num Processors: " << static_cast<std::size_t>(app.n_processors()) << '\n'
48  << std::setw(console_field_width)
49  << " Num Threads: " << static_cast<std::size_t>(libMesh::n_threads()) << std::endl;
50 
51  return oss.str();
52 }
53 
54 std::string
55 outputMeshInformation(FEProblemBase & problem, bool verbose)
56 {
57  std::stringstream oss;
58  oss << std::left;
59 
60  MooseMesh & moose_mesh = problem.mesh();
61  MeshBase & mesh = moose_mesh.getMesh();
62 
63  if (verbose)
64  {
65  bool forced = moose_mesh.isParallelTypeForced();
66  bool pre_split = moose_mesh.isSplit();
67 
68  // clang-format off
69  oss << "\nMesh: " << '\n'
70  << std::setw(console_field_width)
71  << " Parallel Type: " << (moose_mesh.isDistributedMesh() ? "distributed" : "replicated")
72  << (forced || pre_split ? " (" : "")
73  << (forced ? "forced" : "")
74  << (forced && pre_split ? ", " : "")
75  << (pre_split ? "pre-split" : "")
76  << (forced || pre_split ? ")" : "")
77  << '\n'
78  << std::setw(console_field_width) << " Mesh Dimension: " << mesh.mesh_dimension() << '\n'
79  << std::setw(console_field_width) << " Spatial Dimension: " << mesh.spatial_dimension()
80  << '\n';
81  // clang-format on
82  }
83 
84  if (mesh.n_processors() > 1)
85  {
86  dof_id_type nnodes = mesh.n_nodes();
87  dof_id_type nnodes_local = mesh.n_local_nodes();
88  oss << std::setw(console_field_width) << " Nodes:" << '\n'
89  << std::setw(console_field_width) << " Total:" << nnodes << '\n';
90  oss << std::setw(console_field_width) << " Local:" << nnodes_local << '\n';
91  dof_id_type min_nnodes = nnodes_local, max_nnodes = nnodes_local;
92  mesh.comm().min(min_nnodes);
93  mesh.comm().max(max_nnodes);
94  if (mesh.processor_id() == 0)
95  oss << std::setw(console_field_width) << " Min/Max/Avg:" << min_nnodes << '/' << max_nnodes
96  << '/' << nnodes / mesh.n_processors() << '\n';
97  }
98  else
99  oss << std::setw(console_field_width) << " Nodes:" << mesh.n_nodes() << '\n';
100 
101  if (mesh.n_processors() > 1)
102  {
103  dof_id_type nelems = mesh.n_active_elem();
104  dof_id_type nelems_local = mesh.n_active_local_elem();
105  oss << std::setw(console_field_width) << " Elems:" << '\n'
106  << std::setw(console_field_width) << " Total:" << nelems << '\n';
107  oss << std::setw(console_field_width) << " Local:" << nelems_local << '\n';
108  dof_id_type min_nelems = nelems_local, max_nelems = nelems_local;
109  mesh.comm().min(min_nelems);
110  mesh.comm().max(max_nelems);
111  if (mesh.processor_id() == 0)
112  oss << std::setw(console_field_width) << " Min/Max/Avg:" << min_nelems << '/' << max_nelems
113  << '/' << nelems / mesh.n_processors() << '\n';
114  }
115  else
116  oss << std::setw(console_field_width) << " Elems:" << mesh.n_active_elem() << '\n';
117 
118  if (verbose)
119  {
120 
121  oss << std::setw(console_field_width)
122  << " Num Subdomains: " << static_cast<std::size_t>(mesh.n_subdomains()) << '\n';
123  if (mesh.n_processors() > 1)
124  {
125  oss << std::setw(console_field_width)
126  << " Num Partitions: " << static_cast<std::size_t>(mesh.n_partitions()) << '\n'
127  << std::setw(console_field_width) << " Partitioner: " << moose_mesh.partitionerName()
128  << (moose_mesh.isPartitionerForced() ? " (forced) " : "") << '\n';
129  if (mesh.skip_partitioning())
130  oss << std::setw(console_field_width) << " Skipping all partitioning!" << '\n';
131  else if (mesh.skip_noncritical_partitioning())
132  oss << std::setw(console_field_width) << " Skipping noncritical partitioning!" << '\n';
133  }
134  }
135 
136  oss << std::endl;
137 
138  return oss.str();
139 }
140 
141 std::string
143 {
145 }
146 
147 std::string
148 outputSystemInformationHelper(std::stringstream & oss, System & system)
149 {
150  oss << std::left;
151 
152  if (system.n_dofs())
153  {
154  oss << std::setw(console_field_width) << " Num DOFs: " << system.n_dofs() << '\n'
155  << std::setw(console_field_width) << " Num Local DOFs: " << system.n_local_dofs() << '\n';
156 
157  if (system.n_constrained_dofs())
158  {
159  oss << std::setw(console_field_width)
160  << " Num Constrained DOFs: " << system.n_constrained_dofs() << '\n'
161  << std::setw(console_field_width)
162  << " Local Constrained DOFs: " << system.n_local_constrained_dofs() << '\n';
163  }
164 
165  std::streampos begin_string_pos = oss.tellp();
166  std::streampos curr_string_pos = begin_string_pos;
167  oss << std::setw(console_field_width) << " Variables: ";
168  for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
169  {
170  const VariableGroup & vg_description(system.variable_group(vg));
171 
172  if (vg_description.n_variables() > 1)
173  oss << "{ ";
174  if (vg_description.n_variables() > 10)
175  {
176  // when the number of variables in this group is larger than 10, we only output the first
177  // and the last 5 variable names
178  for (unsigned int vn = 0; vn < 5; vn++)
179  {
180  oss << "\"" << vg_description.name(vn) << "\" ";
181  curr_string_pos = oss.tellp();
182  insertNewline(oss, begin_string_pos, curr_string_pos);
183  }
184  oss << "... ";
185  curr_string_pos = oss.tellp();
186  insertNewline(oss, begin_string_pos, curr_string_pos);
187  for (unsigned int vn = vg_description.n_variables() - 5; vn < vg_description.n_variables();
188  vn++)
189  {
190  oss << "\"" << vg_description.name(vn) << "\" ";
191  curr_string_pos = oss.tellp();
192  insertNewline(oss, begin_string_pos, curr_string_pos);
193  }
194  }
195  else
196  for (unsigned int vn = 0; vn < vg_description.n_variables(); vn++)
197  {
198  oss << "\"" << vg_description.name(vn) << "\" ";
199  curr_string_pos = oss.tellp();
200  insertNewline(oss, begin_string_pos, curr_string_pos);
201  }
202 
203  if (vg_description.n_variables() > 1)
204  oss << "} ";
205  }
206  oss << '\n';
207 
208  begin_string_pos = oss.tellp();
209  curr_string_pos = begin_string_pos;
210  oss << std::setw(console_field_width) << " Finite Element Types: ";
211 #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
212  for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
213  {
214  oss << "\""
215  << libMesh::Utility::enum_to_string<FEFamily>(
216  system.get_dof_map().variable_group(vg).type().family)
217  << "\" ";
218  curr_string_pos = oss.tellp();
219  insertNewline(oss, begin_string_pos, curr_string_pos);
220  }
221  oss << '\n';
222 #else
223  for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
224  {
225  oss << "\""
226  << libMesh::Utility::enum_to_string<FEFamily>(
227  system.get_dof_map().variable_group(vg).type().family)
228  << "\", \""
229  << libMesh::Utility::enum_to_string<FEFamily>(
230  system.get_dof_map().variable_group(vg).type().radial_family)
231  << "\" ";
232  curr_string_pos = oss.tellp();
233  insertNewline(oss, begin_string_pos, curr_string_pos);
234  }
235  oss << '\n';
236 
237  begin_string_pos = oss.tellp();
238  curr_string_pos = begin_string_pos;
239  oss << std::setw(console_field_width) << " Infinite Element Mapping: ";
240  for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
241  {
242  oss << "\""
243  << libMesh::Utility::enum_to_string<InfMapType>(
244  system.get_dof_map().variable_group(vg).type().inf_map)
245  << "\" ";
246  curr_string_pos = oss.tellp();
247  insertNewline(oss, begin_string_pos, curr_string_pos);
248  }
249  oss << '\n';
250 #endif
251 
252  begin_string_pos = oss.tellp();
253  curr_string_pos = begin_string_pos;
254  oss << std::setw(console_field_width) << " Approximation Orders: ";
255  for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
256  {
257 #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
258  oss << "\""
259  << Utility::enum_to_string<Order>(system.get_dof_map().variable_group(vg).type().order)
260  << "\" ";
261 #else
262  oss << "\""
263  << Utility::enum_to_string<Order>(system.get_dof_map().variable_group(vg).type().order)
264  << "\", \""
265  << Utility::enum_to_string<Order>(
266  system.get_dof_map().variable_group(vg).type().radial_order)
267  << "\" ";
268 #endif
269  curr_string_pos = oss.tellp();
270  insertNewline(oss, begin_string_pos, curr_string_pos);
271  }
272  oss << "\n" << std::endl;
273  }
274 
275  return oss.str();
276 }
277 
278 std::string
279 outputNonlinearSystemInformation(FEProblemBase & problem, const unsigned int nl_sys_num)
280 {
281  std::stringstream oss;
282  oss << std::left;
283 
284  return outputSystemInformationHelper(oss, problem.getNonlinearSystemBase(nl_sys_num).system());
285 }
286 
287 std::string
289 {
290  std::stringstream oss;
291 
292  return outputSystemInformationHelper(oss, system);
293 }
294 
295 std::string
297 {
298  std::stringstream oss;
299  oss << std::left;
300 
301  auto info_strings = app.getRelationshipManagerInfo();
302  if (info_strings.size())
303  {
304  for (const auto & info_pair : info_strings)
305  oss << std::setw(console_field_width)
306  << " " + MooseUtils::underscoreToCamelCase(MooseUtils::toLower(info_pair.first), true) +
307  ":"
308  << info_pair.second << '\n';
309  oss << std::endl;
310  }
311 
312  return oss.str();
313 }
314 
315 std::string
317 {
318 
319  std::stringstream oss;
320  oss << std::left;
321 
322  Executioner * exec = app.getExecutioner();
323 
324  oss << "Execution Information:\n"
325  << std::setw(console_field_width) << " Executioner: " << demangle(typeid(*exec).name())
326  << '\n';
327 
328  std::string time_stepper = exec->getTimeStepperName();
329  if (time_stepper != "")
330  oss << std::setw(console_field_width) << " TimeStepper: " << time_stepper << '\n';
331  std::string time_integrator = exec->getTimeIntegratorName();
332  if (time_integrator != "")
333  oss << std::setw(console_field_width) << " TimeIntegrator: " << time_integrator << '\n';
334 
335  oss << std::setw(console_field_width) << " Solver Mode: " << problem.solverTypeString() << '\n';
336 
337  const std::string & pc_desc = problem.getPetscOptions().pc_description;
338  if (!pc_desc.empty())
339  oss << std::setw(console_field_width) << " PETSc Preconditioner: " << pc_desc << '\n';
340 
341  for (const auto i : make_range(problem.numNonlinearSystems()))
342  {
344  if (mpc)
345  {
346  oss << std::setw(console_field_width)
347  << " MOOSE Preconditioner" +
348  (problem.numNonlinearSystems() > 1 ? (" " + std::to_string(i)) : "") + ": "
349  << mpc->getParam<std::string>("_type");
350  if (mpc->name() == "_moose_auto")
351  oss << " (auto)";
352  oss << '\n';
353  }
354  oss << std::endl;
355  }
356 
357  return oss.str();
358 }
359 
360 std::string
362 {
363  std::stringstream oss;
364  oss << std::left;
365 
366  const std::vector<Output *> outputs = app.getOutputWarehouse().getOutputs<Output>();
367  oss << "Outputs:\n";
368  for (const auto & out : outputs)
369  {
370  // Display the "execute_on" settings
371  const MultiMooseEnum & execute_on = out->executeOn();
372  oss << " " << std::setw(console_field_width - 2) << out->name() << "\"" << execute_on
373  << "\"\n";
374 
375  // Display the advanced "execute_on" settings, only if they are different from "execute_on"
376  if (out->isAdvanced())
377  {
378  const OutputOnWarehouse & adv_on = out->advancedExecuteOn();
379  for (const auto & adv_it : adv_on)
380  if (execute_on != adv_it.second)
381  oss << " " << std::setw(console_field_width - 4) << adv_it.first + ":"
382  << "\"" << adv_it.second << "\"" << std::endl;
383  }
384  }
385 
386  return oss.str();
387 }
388 
389 std::string
391 {
392  std::stringstream oss;
393  oss << std::left;
394 
395  if (app.parameters().get<bool>("use_legacy_material_output"))
396  {
397  oss << COLOR_RED << "LEGACY MODES ENABLED:" << COLOR_DEFAULT << '\n';
398  oss << " This application uses the legacy material output option: material properties are "
399  "output only on TIMESTEP_END, not INITIAL. To remove this message, set "
400  "'use_legacy_material_output' to false in this application. If there are gold output "
401  "files that contain material property output for which output occurs on INITIAL, then "
402  "these will generate diffs due to zero values being stored, and these tests should be "
403  "re-golded.\n"
404  << COLOR_DEFAULT << std::endl;
405  }
406 
407  return oss.str();
408 }
409 
410 void
411 insertNewline(std::stringstream & oss, std::streampos & begin, std::streampos & curr)
412 {
413  if (curr - begin > console_line_length)
414  {
415  oss << "\n";
416  begin = oss.tellp();
417  oss << std::setw(console_field_width + 2) << ""; // "{ "
418  }
419 }
420 
421 std::string
422 formatString(std::string message, const std::string & prefix)
423 {
424  MooseUtils::indentMessage(prefix, message, COLOR_DEFAULT, true, " ");
425  std::stringstream stream;
426  std::streampos start = stream.tellp();
427  stream << message;
428  std::streampos end = stream.tellp();
429  insertNewline(stream, start, end);
430  auto formatted_string = stream.str();
431  // no need to end with a line break
432  if (formatted_string.back() == '\n')
433  formatted_string.pop_back();
434  return formatted_string;
435 }
436 
437 std::string
438 mooseObjectVectorToString(const std::vector<MooseObject *> & objs, const std::string & sep /*=""*/)
439 {
440  std::string object_names = "";
441  if (objs.size())
442  {
443  // Gather all the object names
444  std::vector<std::string> names;
445  names.reserve(objs.size());
446  for (const auto & obj : objs)
447  {
448  mooseAssert(obj, "Trying to print a null object");
449  names.push_back(obj->name());
450  }
451 
452  object_names = MooseUtils::join(names, sep);
453  }
454  return object_names;
455 }
456 
457 } // ConsoleUtils namespace
std::string indent(unsigned int spaces)
Create empty string for indenting.
Definition: ConsoleUtils.C:31
Moose::PetscSupport::PetscOptions & getPetscOptions()
Retrieve a writable reference the PETSc options (used by PetscSupport)
std::string mooseObjectVectorToString(const std::vector< MooseObject *> &objs, const std::string &sep=" ")
Routine to output the name of MooseObjects in a string.
Definition: ConsoleUtils.C:438
MoosePreconditioner const * getPreconditioner() const
std::string toLower(const std::string &name)
Convert supplied string to lower case.
Definition: MooseUtils.C:1045
unsigned int n_threads()
std::vector< std::pair< std::string, std::string > > getRelationshipManagerInfo() const
Returns the Relationship managers info suitable for printing.
Definition: MooseApp.C:2665
virtual std::size_t numNonlinearSystems() const override
std::string outputExecutionInformation(const MooseApp &app, FEProblemBase &problem)
Output execution information.
Definition: ConsoleUtils.C:316
std::string outputAuxiliarySystemInformation(FEProblemBase &problem)
Output the Auxiliary system information.
Definition: ConsoleUtils.C:142
InputParameters & parameters()
Get the parameters of the object.
Definition: MooseApp.h:126
bool isDistributedMesh() const
Returns the final Mesh distribution type.
Definition: MooseMesh.h:984
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
MeshBase & mesh
Base class for MOOSE-based applications.
Definition: MooseApp.h:69
std::vector< T * > getOutputs(const std::vector< OutputName > &names)
Return a vector of objects by names.
std::string outputOutputInformation(MooseApp &app)
Output the output information.
Definition: ConsoleUtils.C:361
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:56
static const unsigned int console_field_width
Width used for printing simulation information.
Definition: ConsoleUtils.h:30
std::string outputSystemInformationHelper(System &system)
Output system information.
Definition: ConsoleUtils.C:288
Base class for MOOSE preconditioners.
std::string outputMeshInformation(FEProblemBase &problem, bool verbose=true)
Output the mesh information.
Definition: ConsoleUtils.C:55
Based class for output objects.
Definition: Output.h:43
static const unsigned int console_line_length
Line length for printing simulation information.
Definition: ConsoleUtils.h:33
processor_id_type n_processors() const
bool isSplit() const
Definition: MooseMesh.h:1305
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3198
void indentMessage(const std::string &prefix, std::string &message, const char *color=COLOR_CYAN, bool dont_indent_first_line=true, const std::string &post_prefix=": ")
Indents the supplied message given the prefix and color.
Definition: MooseUtils.C:721
const SystemInfo * getSystemInfo() const
Get SystemInfo object.
Definition: MooseApp.h:564
void insertNewline(std::stringstream &oss, std::streampos &begin, std::streampos &curr)
Helper function function for stringstream formatting.
Definition: ConsoleUtils.C:411
bool isPartitionerForced() const
Tell the user if the partitioner was overriden for any reason.
Definition: MooseMesh.h:1004
std::string formatString(std::string message, const std::string &prefix)
Add new lines and prefixes to a string for pretty display in output NOTE: This makes a copy of the st...
Definition: ConsoleUtils.C:422
std::string getInfo() const
Definition: SystemInfo.C:26
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:88
std::string underscoreToCamelCase(const std::string &underscore_name, bool leading_upper_case)
Function for converting an underscore name to a camel case name.
Definition: MooseUtils.C:563
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
A helper warehouse class for storing the "execute_on" settings for the various output types...
Executioners are objects that do the actual work of solving your problem.
Definition: Executioner.h:30
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
virtual std::string solverTypeString()
Return solver type as a human readable string.
std::string outputFrameworkInformation(const MooseApp &app)
Outputs framework information.
Definition: ConsoleUtils.C:37
AuxiliarySystem & getAuxiliarySystem()
std::string demangle(const char *name)
Executioner * getExecutioner() const
Retrieve the Executioner for this App.
Definition: MooseApp.C:1482
virtual System & system() override
Get the reference to the libMesh system.
virtual System & system() override
Get the reference to the libMesh system.
OStreamProxy out
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
bool isParallelTypeForced() const
Tell the user if the distribution was overriden for any reason.
Definition: MooseMesh.h:989
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
const MooseEnum & partitionerName() const
Definition: MooseMesh.h:999
std::string pc_description
Preconditioner description.
Definition: PetscSupport.h:50
std::string outputLegacyInformation(MooseApp &app)
Output the legacy flag information.
Definition: ConsoleUtils.C:390
virtual std::string getTimeStepperName() const
The name of the TimeStepper This is an empty string for non-Transient executioners.
Definition: Executioner.h:105
std::string outputRelationshipManagerInformation(const MooseApp &app)
Output action RelationshipManager information.
Definition: ConsoleUtils.C:296
std::string join(const T &strings, const std::string &delimiter)
Python like join function for strings.
Definition: MooseUtils.h:130
OutputWarehouse & getOutputWarehouse()
Get the OutputWarehouse objects.
Definition: MooseApp.C:1772
virtual std::string getTimeIntegratorName() const
The name of the TimeIntegrator This is an empty string for non-Transient executioners.
Definition: Executioner.h:111
uint8_t dof_id_type
std::string outputNonlinearSystemInformation(FEProblemBase &problem, const unsigned int nl_sys_num)
Output the Nonlinear system information.
Definition: ConsoleUtils.C:279