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 "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 : #include "Checkpoint.h"
25 : #include "InputParameterWarehouse.h"
26 : #include "Registry.h"
27 : #include "CommandLine.h"
28 : #include "Split.h"
29 :
30 : #include <filesystem>
31 :
32 : #include "libmesh/string_to_enum.h"
33 : #include "libmesh/simple_range.h"
34 :
35 : using namespace libMesh;
36 :
37 : namespace ConsoleUtils
38 : {
39 :
40 : std::string
41 27707 : indent(unsigned int spaces)
42 : {
43 27707 : return std::string(spaces, ' ');
44 : }
45 :
46 : std::string
47 82267 : outputFrameworkInformation(const MooseApp & app)
48 : {
49 82267 : std::stringstream oss;
50 82267 : oss << std::left;
51 :
52 82267 : if (app.getSystemInfo() != NULL)
53 68897 : oss << app.getSystemInfo()->getInfo();
54 :
55 82267 : oss << "Input File(s):\n";
56 164791 : for (const auto & entry : app.getInputFileNames())
57 82524 : oss << " " << std::filesystem::absolute(entry).c_str() << "\n";
58 82267 : oss << "\n";
59 :
60 82267 : const auto & cl = std::as_const(*app.commandLine());
61 : // We skip the 0th argument of the main app, i.e., the name used to invoke the program
62 : const auto cl_range =
63 82267 : as_range(std::next(cl.getEntries().begin(), app.multiAppLevel() == 0), cl.getEntries().end());
64 :
65 82267 : std::stringstream args_oss;
66 631593 : for (const auto & entry : cl_range)
67 549326 : if (!entry.hit_param && !entry.subapp_name && entry.name != "-i")
68 339647 : args_oss << " " << cl.formatEntry(entry) << "\n";
69 82267 : if (args_oss.str().size())
70 78941 : oss << "Command Line Argument(s):\n" << args_oss.str() << "\n";
71 :
72 82267 : std::stringstream input_args_oss;
73 631593 : for (const auto & entry : cl_range)
74 549326 : if (entry.hit_param && !entry.subapp_name)
75 140301 : input_args_oss << " " << cl.formatEntry(entry) << "\n";
76 82267 : if (input_args_oss.str().size())
77 72319 : oss << "Command Line Input Argument(s):\n" << input_args_oss.str() << "\n";
78 :
79 82267 : const auto checkpoints = app.getOutputWarehouse().getOutputs<Checkpoint>();
80 82267 : if (checkpoints.size())
81 : {
82 68927 : oss << std::left << "Checkpoint:\n";
83 68927 : oss << checkpoints[0]->checkpointInfo().str();
84 68927 : oss << std::endl;
85 : }
86 :
87 82267 : oss << std::left << "Parallelism:\n"
88 : << std::setw(console_field_width)
89 82267 : << " Num Processors: " << static_cast<std::size_t>(app.n_processors()) << '\n'
90 : << std::setw(console_field_width)
91 82267 : << " Num Threads: " << static_cast<std::size_t>(libMesh::n_threads()) << std::endl;
92 :
93 164534 : return oss.str();
94 82267 : }
95 :
96 : std::string
97 50976 : outputMeshInformation(FEProblemBase & problem, bool verbose)
98 : {
99 50976 : std::stringstream oss;
100 50976 : oss << std::left;
101 :
102 50976 : const MooseMesh & mesh = problem.mesh();
103 :
104 50976 : const auto fe_backend = problem.feBackend();
105 :
106 50976 : if (verbose)
107 : {
108 50639 : oss << "\nMesh: " << '\n' << std::setw(console_field_width);
109 :
110 50639 : oss << " Parallel Type: " << (mesh.isDistributedMesh() ? "distributed" : "replicated");
111 50639 : if (fe_backend == Moose::FEBackend::LibMesh)
112 : {
113 50505 : bool forced = mesh.isParallelTypeForced();
114 50505 : bool pre_split = mesh.isSplit();
115 49879 : oss << (forced || pre_split ? " (" : "") << (forced ? "forced" : "")
116 626 : << (forced && pre_split ? ", " : "") << (pre_split ? "pre-split" : "")
117 101010 : << (forced || pre_split ? ")" : "");
118 : }
119 50639 : oss << '\n';
120 50639 : oss << std::setw(console_field_width) << " Mesh Dimension: " << mesh.dimension() << '\n'
121 50639 : << std::setw(console_field_width) << " Spatial Dimension: " << mesh.spatialDimension()
122 50639 : << '\n';
123 : }
124 :
125 : // Nodes, only associated with the mesh in libMesh
126 50976 : if (fe_backend == Moose::FEBackend::LibMesh)
127 : {
128 50842 : if (mesh.n_processors() > 1)
129 : {
130 24628 : dof_id_type nnodes = mesh.nNodes();
131 24628 : dof_id_type nnodes_local = mesh.nLocalNodes();
132 : oss << std::setw(console_field_width) << " Nodes:" << '\n'
133 24628 : << std::setw(console_field_width) << " Total:" << nnodes << '\n';
134 24628 : oss << std::setw(console_field_width) << " Local:" << nnodes_local << '\n';
135 24628 : dof_id_type min_nnodes = nnodes_local, max_nnodes = nnodes_local;
136 24628 : mesh.comm().min(min_nnodes);
137 24628 : mesh.comm().max(max_nnodes);
138 24628 : if (mesh.processor_id() == 0)
139 11566 : oss << std::setw(console_field_width) << " Min/Max/Avg:" << min_nnodes << '/'
140 11566 : << max_nnodes << '/' << nnodes / mesh.n_processors() << '\n';
141 : }
142 : else
143 26214 : oss << std::setw(console_field_width) << " Nodes:" << mesh.nNodes() << '\n';
144 : }
145 :
146 : // Elements
147 50976 : if (mesh.n_processors() > 1)
148 : {
149 24664 : dof_id_type nelems = mesh.nActiveElem();
150 24664 : dof_id_type nelems_local = mesh.nActiveLocalElem();
151 : oss << std::setw(console_field_width) << " Elems:" << '\n'
152 24664 : << std::setw(console_field_width) << " Total:" << nelems << '\n';
153 24664 : oss << std::setw(console_field_width) << " Local:" << nelems_local << '\n';
154 24664 : dof_id_type min_nelems = nelems_local, max_nelems = nelems_local;
155 24664 : mesh.comm().min(min_nelems);
156 24664 : mesh.comm().max(max_nelems);
157 24664 : if (mesh.processor_id() == 0)
158 11584 : oss << std::setw(console_field_width) << " Min/Max/Avg:" << min_nelems << '/' << max_nelems
159 11584 : << '/' << nelems / mesh.n_processors() << '\n';
160 : }
161 : else
162 26312 : oss << std::setw(console_field_width) << " Elems:" << mesh.nActiveElem() << '\n';
163 :
164 : // P-refinement
165 50976 : if (fe_backend == Moose::FEBackend::LibMesh)
166 : {
167 50842 : if (mesh.maxPLevel() > 0)
168 : oss << std::setw(console_field_width)
169 40 : << " Max p-Refinement Level: " << static_cast<std::size_t>(mesh.maxPLevel()) << '\n';
170 50842 : if (mesh.maxHLevel() > 0)
171 : oss << std::setw(console_field_width)
172 5989 : << " Max h-Refinement Level: " << static_cast<std::size_t>(mesh.maxHLevel()) << '\n';
173 : }
174 :
175 50976 : if (verbose)
176 : {
177 : oss << std::setw(console_field_width)
178 50639 : << " Num Subdomains: " << static_cast<std::size_t>(mesh.nSubdomains()) << '\n';
179 50639 : if (mesh.n_processors() > 1 && fe_backend == Moose::FEBackend::LibMesh)
180 : {
181 : oss << std::setw(console_field_width)
182 24454 : << " Num Partitions: " << static_cast<std::size_t>(mesh.nPartitions()) << '\n'
183 24454 : << std::setw(console_field_width) << " Partitioner: " << mesh.partitionerName()
184 24454 : << (mesh.isPartitionerForced() ? " (forced) " : "") << '\n';
185 24454 : if (mesh.skipPartitioning())
186 636 : oss << std::setw(console_field_width) << " Skipping all partitioning!" << '\n';
187 23818 : else if (mesh.skipNoncriticalPartitioning())
188 0 : oss << std::setw(console_field_width) << " Skipping noncritical partitioning!" << '\n';
189 : }
190 : }
191 :
192 50976 : oss << std::endl;
193 :
194 101952 : return oss.str();
195 50976 : }
196 :
197 : std::string
198 50976 : outputAuxiliarySystemInformation(FEProblemBase & problem)
199 : {
200 50976 : return outputSystemInformationHelper(problem.getAuxiliarySystem().system());
201 : }
202 :
203 : std::string
204 102172 : outputSystemInformationHelper(std::stringstream & oss, System & system)
205 : {
206 102172 : oss << std::left;
207 :
208 102172 : if (system.n_dofs())
209 : {
210 63641 : oss << std::setw(console_field_width) << " Num DOFs: " << system.n_dofs() << '\n'
211 63641 : << std::setw(console_field_width) << " Num Local DOFs: " << system.n_local_dofs() << '\n';
212 :
213 63641 : if (system.n_constrained_dofs())
214 : {
215 : oss << std::setw(console_field_width)
216 1165 : << " Num Constrained DOFs: " << system.n_constrained_dofs() << '\n'
217 : << std::setw(console_field_width)
218 1165 : << " Local Constrained DOFs: " << system.n_local_constrained_dofs() << '\n';
219 : }
220 :
221 63641 : std::streampos begin_string_pos = oss.tellp();
222 63641 : std::streampos curr_string_pos = begin_string_pos;
223 63641 : oss << std::setw(console_field_width) << " Variables: ";
224 145598 : for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
225 : {
226 81957 : const VariableGroup & vg_description(system.variable_group(vg));
227 :
228 81957 : if (vg_description.n_variables() > 1)
229 14197 : oss << "{ ";
230 81957 : if (vg_description.n_variables() > 10)
231 : {
232 : // when the number of variables in this group is larger than 10, we only output the first
233 : // and the last 5 variable names
234 3012 : for (unsigned int vn = 0; vn < 5; vn++)
235 : {
236 2510 : oss << "\"" << vg_description.name(vn) << "\" ";
237 2510 : curr_string_pos = oss.tellp();
238 2510 : insertNewline(oss, begin_string_pos, curr_string_pos);
239 : }
240 502 : oss << "... ";
241 502 : curr_string_pos = oss.tellp();
242 502 : insertNewline(oss, begin_string_pos, curr_string_pos);
243 3012 : for (unsigned int vn = vg_description.n_variables() - 5; vn < vg_description.n_variables();
244 : vn++)
245 : {
246 2510 : oss << "\"" << vg_description.name(vn) << "\" ";
247 2510 : curr_string_pos = oss.tellp();
248 2510 : insertNewline(oss, begin_string_pos, curr_string_pos);
249 : }
250 : }
251 : else
252 187283 : for (unsigned int vn = 0; vn < vg_description.n_variables(); vn++)
253 : {
254 105828 : oss << "\"" << vg_description.name(vn) << "\" ";
255 105828 : curr_string_pos = oss.tellp();
256 105828 : insertNewline(oss, begin_string_pos, curr_string_pos);
257 : }
258 :
259 81957 : if (vg_description.n_variables() > 1)
260 14197 : oss << "} ";
261 : }
262 63641 : oss << '\n';
263 :
264 63641 : begin_string_pos = oss.tellp();
265 63641 : curr_string_pos = begin_string_pos;
266 63641 : oss << std::setw(console_field_width) << " Finite Element Types: ";
267 : #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
268 145598 : for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
269 : {
270 : oss << "\""
271 81957 : << libMesh::Utility::enum_to_string<FEFamily>(
272 81957 : system.get_dof_map().variable_group(vg).type().family)
273 163914 : << "\" ";
274 81957 : curr_string_pos = oss.tellp();
275 81957 : insertNewline(oss, begin_string_pos, curr_string_pos);
276 : }
277 63641 : oss << '\n';
278 : #else
279 : for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
280 : {
281 : oss << "\""
282 : << libMesh::Utility::enum_to_string<FEFamily>(
283 : system.get_dof_map().variable_group(vg).type().family)
284 : << "\", \""
285 : << libMesh::Utility::enum_to_string<FEFamily>(
286 : system.get_dof_map().variable_group(vg).type().radial_family)
287 : << "\" ";
288 : curr_string_pos = oss.tellp();
289 : insertNewline(oss, begin_string_pos, curr_string_pos);
290 : }
291 : oss << '\n';
292 :
293 : begin_string_pos = oss.tellp();
294 : curr_string_pos = begin_string_pos;
295 : oss << std::setw(console_field_width) << " Infinite Element Mapping: ";
296 : for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
297 : {
298 : oss << "\""
299 : << libMesh::Utility::enum_to_string<InfMapType>(
300 : system.get_dof_map().variable_group(vg).type().inf_map)
301 : << "\" ";
302 : curr_string_pos = oss.tellp();
303 : insertNewline(oss, begin_string_pos, curr_string_pos);
304 : }
305 : oss << '\n';
306 : #endif
307 :
308 63641 : begin_string_pos = oss.tellp();
309 63641 : curr_string_pos = begin_string_pos;
310 63641 : oss << std::setw(console_field_width) << " Approximation Orders: ";
311 145598 : for (unsigned int vg = 0; vg < system.n_variable_groups(); vg++)
312 : {
313 : #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
314 : oss << "\""
315 163914 : << Utility::enum_to_string<Order>(system.get_dof_map().variable_group(vg).type().order)
316 163914 : << "\" ";
317 : #else
318 : oss << "\""
319 : << Utility::enum_to_string<Order>(system.get_dof_map().variable_group(vg).type().order)
320 : << "\", \""
321 : << Utility::enum_to_string<Order>(
322 : system.get_dof_map().variable_group(vg).type().radial_order)
323 : << "\" ";
324 : #endif
325 81957 : curr_string_pos = oss.tellp();
326 81957 : insertNewline(oss, begin_string_pos, curr_string_pos);
327 : }
328 63641 : oss << "\n" << std::endl;
329 : }
330 :
331 102172 : return oss.str();
332 : }
333 :
334 : std::string
335 51196 : outputSolverSystemInformation(FEProblemBase & problem, const unsigned int sys_num)
336 : {
337 51196 : std::stringstream oss;
338 51196 : oss << std::left;
339 :
340 102392 : return outputSystemInformationHelper(oss, problem.getSolverSystem(sys_num).system());
341 51196 : }
342 :
343 : std::string
344 50976 : outputSystemInformationHelper(System & system)
345 : {
346 50976 : std::stringstream oss;
347 :
348 101952 : return outputSystemInformationHelper(oss, system);
349 50976 : }
350 :
351 : std::string
352 95 : outputRelationshipManagerInformation(const MooseApp & app)
353 : {
354 95 : std::stringstream oss;
355 95 : oss << std::left;
356 :
357 95 : auto info_strings = app.getRelationshipManagerInfo();
358 95 : if (info_strings.size())
359 : {
360 597 : for (const auto & info_pair : info_strings)
361 : oss << std::setw(console_field_width)
362 1004 : << " " + MooseUtils::underscoreToCamelCase(MooseUtils::toLower(info_pair.first), true) +
363 : ":"
364 1004 : << info_pair.second << '\n';
365 95 : oss << std::endl;
366 : }
367 :
368 190 : return oss.str();
369 95 : }
370 :
371 : std::string
372 50639 : outputExecutionInformation(const MooseApp & app, FEProblemBase & problem)
373 : {
374 :
375 50639 : std::stringstream oss;
376 50639 : oss << std::left;
377 :
378 50639 : Executioner * exec = app.getExecutioner();
379 :
380 : oss << "Execution Information:\n"
381 50639 : << std::setw(console_field_width) << " Executioner: " << exec->type() << '\n';
382 :
383 50639 : std::string time_stepper = exec->getTimeStepperName();
384 50639 : if (time_stepper != "")
385 23388 : oss << std::setw(console_field_width) << " TimeStepper: " << time_stepper << '\n';
386 50639 : const auto time_integrator_names = exec->getTimeIntegratorNames();
387 50639 : if (!time_integrator_names.empty())
388 : oss << std::setw(console_field_width)
389 23388 : << " TimeIntegrator(s): " << MooseUtils::join(time_integrator_names, " ") << '\n';
390 :
391 : oss << std::setw(console_field_width)
392 101278 : << std::string(" Solver") +
393 101278 : (problem.feBackend() == Moose::FEBackend::LibMesh ? " Mode" : "") + ": ";
394 101498 : for (const std::size_t i : make_range(problem.numSolverSystems()))
395 101718 : oss << (problem.numSolverSystems() > 1 ? "[" + problem.getSolverSystemNames()[i] + "]: " : "")
396 50859 : << problem.solverTypeString(i) << " ";
397 50639 : oss << '\n';
398 :
399 : // Check for a selection of common PETSc pc options on the command line for
400 : // all solver systems and all field splits within each nonlinear system
401 50639 : std::string pc_desc;
402 101498 : for (const std::size_t i : make_range(problem.numSolverSystems()))
403 : {
404 101718 : std::vector<std::string> splits = {""};
405 50859 : if (problem.isSolverSystemNonlinear(i))
406 50116 : for (const auto & split : problem.getNonlinearSystemBase(i).getSplits().getObjects())
407 376 : splits.push_back("fieldsplit_" + split->name() + "_");
408 :
409 102094 : for (const std::string & split : splits)
410 : {
411 51235 : std::string pc_desc_split;
412 51235 : const std::string prefix = problem.solverParams(i)._prefix + split;
413 451286 : for (const auto & entry : std::as_const(*app.commandLine()).getEntries())
414 1198807 : if (entry.name == prefix + "pc_type" || entry.name == prefix + "sub_pc_type" ||
415 1198807 : entry.name == prefix + "pc_hypre_type" || entry.name == prefix + "pc_fieldsplit_type")
416 731 : pc_desc_split += entry.value ? *entry.value + " " : "unspecified ";
417 :
418 51235 : if (!pc_desc_split.empty() && prefix.size() > 1)
419 0 : pc_desc += "[" + prefix.substr(1, prefix.size() - 2) + "]: ";
420 51235 : pc_desc += pc_desc_split;
421 51235 : }
422 50859 : }
423 :
424 : // Alert the user any unoverridden options will still be picked up from the input file
425 50639 : if (!pc_desc.empty())
426 673 : pc_desc += "(see input file for unoverridden options)";
427 :
428 : // If there are no PETSc pc options on the command line, print the input file options
429 50639 : if (pc_desc.empty())
430 49966 : pc_desc = problem.getPetscOptions().pc_description;
431 :
432 50639 : if (!pc_desc.empty())
433 22384 : oss << std::setw(console_field_width) << " PETSc Preconditioner: " << pc_desc << '\n';
434 :
435 50639 : std::string mpc_desc;
436 100379 : for (const std::size_t i : make_range(problem.numNonlinearSystems()))
437 : {
438 49740 : MoosePreconditioner const * mpc = problem.getNonlinearSystemBase(i).getPreconditioner();
439 49740 : if (mpc)
440 : {
441 12385 : if (problem.numNonlinearSystems() > 1)
442 252 : mpc_desc += "[" + problem.getNonlinearSystemNames()[i] + "]: ";
443 12385 : mpc_desc += mpc->getParam<std::string>("_type") + " ";
444 12385 : if (mpc->name().find("_moose_auto") != std::string::npos)
445 8701 : mpc_desc += "(auto) ";
446 : }
447 : }
448 :
449 50639 : if (!mpc_desc.empty())
450 12259 : oss << std::setw(console_field_width) << " MOOSE Preconditioner: " << mpc_desc << '\n';
451 :
452 101278 : return oss.str();
453 152357 : }
454 :
455 : std::string
456 10 : outputOutputInformation(MooseApp & app)
457 : {
458 10 : std::stringstream oss;
459 10 : oss << std::left;
460 :
461 10 : const std::vector<Output *> outputs = app.getOutputWarehouse().getOutputs<Output>();
462 10 : oss << "Outputs:\n";
463 60 : for (const auto & out : outputs)
464 : {
465 : // Display the "execute_on" settings
466 50 : const MultiMooseEnum & execute_on = out->executeOn();
467 50 : oss << " " << std::setw(console_field_width - 2) << out->name() << "\"" << execute_on
468 50 : << "\"\n";
469 :
470 : // Display the advanced "execute_on" settings, only if they are different from "execute_on"
471 50 : if (out->isAdvanced())
472 : {
473 20 : const OutputOnWarehouse & adv_on = out->advancedExecuteOn();
474 140 : for (const auto & adv_it : adv_on)
475 120 : if (execute_on != adv_it.second)
476 140 : oss << " " << std::setw(console_field_width - 4) << adv_it.first + ":" << "\""
477 70 : << adv_it.second << "\"" << std::endl;
478 : }
479 : }
480 :
481 20 : return oss.str();
482 10 : }
483 :
484 : std::string
485 24 : outputPreSMOResidualInformation()
486 : {
487 24 : std::stringstream oss;
488 24 : oss << std::left;
489 :
490 24 : oss << COLOR_BLUE;
491 : oss << "Executioner/use_pre_smo_residual is set to true. The pre-SMO residual will be evaluated "
492 : "at the beginning of each time step before executing objects that could modify the "
493 : "solution, such as preset BCs, predictors, correctors, constraints, and certain user "
494 : "objects. The pre-SMO residuals will be prefixed with * and will be used in the relative "
495 24 : "convergence check.\n";
496 24 : oss << COLOR_DEFAULT;
497 :
498 48 : return oss.str();
499 24 : }
500 :
501 : std::string
502 50651 : outputLegacyInformation(MooseApp & app)
503 : {
504 50651 : std::stringstream oss;
505 50651 : oss << std::left;
506 :
507 50651 : if (app.parameters().get<bool>("use_legacy_material_output"))
508 : {
509 0 : oss << COLOR_RED << "LEGACY MODES ENABLED:" << COLOR_DEFAULT << '\n';
510 : oss << " This application uses the legacy material output option: material properties are "
511 : "output only on TIMESTEP_END, not INITIAL. To remove this message, set "
512 : "'use_legacy_material_output' to false in this application. If there are gold output "
513 : "files that contain material property output for which output occurs on INITIAL, then "
514 : "these will generate diffs due to zero values being stored, and these tests should be "
515 : "re-golded.\n"
516 0 : << COLOR_DEFAULT << std::endl;
517 : }
518 :
519 50651 : if (app.parameters().get<bool>("use_legacy_initial_residual_evaluation_behavior"))
520 : {
521 0 : oss << COLOR_RED << "LEGACY MODES ENABLED:" << COLOR_DEFAULT << '\n';
522 : oss << " This application uses the legacy initial residual evaluation behavior. The legacy "
523 : "behavior performs an often times redundant residual evaluation before the solution "
524 : "modifying objects are executed prior to the initial (0th nonlinear iteration) residual "
525 : "evaluation. The new behavior skips that redundant residual evaluation unless the "
526 : "parameter Executioner/use_pre_smo_residual is set to true. To remove this message and "
527 : "enable the new behavior, set the parameter "
528 : "'use_legacy_initial_residual_evaluation_behavior' to false in *App.C. Some tests that "
529 : "rely on the side effects of the legacy behavior may fail/diff and should be "
530 : "re-golded.\n"
531 0 : << COLOR_DEFAULT << std::endl;
532 : }
533 :
534 101302 : return oss.str();
535 50651 : }
536 :
537 : std::string
538 10 : outputDataFilePaths()
539 : {
540 10 : std::stringstream oss;
541 10 : oss << "Data File Paths:\n";
542 20 : for (const auto & [name, path] : Registry::getDataFilePaths())
543 10 : oss << " " << name << ": " << path << "\n";
544 30 : return oss.str() + "\n";
545 10 : }
546 :
547 : std::string
548 10 : outputDataFileParams(MooseApp & app)
549 : {
550 10 : std::map<std::string, std::string> values; // for A-Z sort
551 522 : for (const auto & object_name_params_pair : app.getInputParameterWarehouse().getInputParameters())
552 : {
553 512 : const auto & params = object_name_params_pair.second;
554 13332 : for (const auto & name_value_pair : *params)
555 : {
556 12820 : const auto & name = name_value_pair.first;
557 12820 : if (const auto path = params->queryDataFileNamePath(name))
558 40 : if (params->getHitNode(name))
559 12820 : values.emplace(params->paramFullpath(name), path->path);
560 : }
561 : }
562 :
563 10 : std::stringstream oss;
564 10 : oss << "Data File Parameters:\n";
565 20 : for (const auto & [param, value] : values)
566 10 : oss << " " << param << " = " << value << "\n";
567 30 : return oss.str() + '\n';
568 10 : }
569 :
570 : void
571 343412 : insertNewline(std::stringstream & oss, std::streampos & begin, std::streampos & curr)
572 : {
573 343412 : if (curr - begin > console_line_length)
574 : {
575 5658 : oss << "\n";
576 5658 : begin = oss.tellp();
577 5658 : oss << std::setw(console_field_width + 2) << ""; // "{ "
578 : }
579 343412 : }
580 :
581 : std::string
582 63368 : formatString(std::string message, const std::string & prefix)
583 : {
584 63368 : MooseUtils::indentMessage(prefix, message, COLOR_DEFAULT, true, " ");
585 63368 : std::stringstream stream;
586 63368 : std::streampos start = stream.tellp();
587 63368 : stream << message;
588 63368 : std::streampos end = stream.tellp();
589 63368 : insertNewline(stream, start, end);
590 63368 : auto formatted_string = stream.str();
591 : // no need to end with a line break
592 63368 : if (formatted_string.back() == '\n')
593 0 : formatted_string.pop_back();
594 126736 : return formatted_string;
595 63368 : }
596 :
597 : std::string
598 13181 : mooseObjectVectorToString(const std::vector<MooseObject *> & objs, const std::string & sep /*=""*/)
599 : {
600 13181 : std::string object_names = "";
601 13181 : if (objs.size())
602 : {
603 : // Gather all the object names
604 13181 : std::vector<std::string> names;
605 13181 : names.reserve(objs.size());
606 37916 : for (const auto & obj : objs)
607 : {
608 : mooseAssert(obj, "Trying to print a null object");
609 24735 : names.push_back(obj->name());
610 : }
611 :
612 13181 : object_names = MooseUtils::join(names, sep);
613 13181 : }
614 13181 : return object_names;
615 0 : }
616 :
617 : } // ConsoleUtils namespace
|