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 "MooseUtils.h"
12 : #include "MooseInit.h"
13 : #include "InputParameters.h"
14 : #include "ActionFactory.h"
15 : #include "Action.h"
16 : #include "Factory.h"
17 : #include "Parser.h"
18 : #include "MooseObjectAction.h"
19 : #include "AddActionComponentAction.h"
20 : #include "ActionWarehouse.h"
21 : #include "EmptyAction.h"
22 : #include "FEProblem.h"
23 : #include "MooseMesh.h"
24 : #include "Executioner.h"
25 : #include "MooseApp.h"
26 : #include "MooseEnum.h"
27 : #include "MultiMooseEnum.h"
28 : #include "MultiApp.h"
29 : #include "GlobalParamsAction.h"
30 : #include "SyntaxTree.h"
31 : #include "InputFileFormatter.h"
32 : #include "YAMLFormatter.h"
33 : #include "MooseTypes.h"
34 : #include "CommandLine.h"
35 : #include "JsonSyntaxTree.h"
36 : #include "SystemInfo.h"
37 : #include "MooseUtils.h"
38 : #include "Conversion.h"
39 : #include "Units.h"
40 : #include "ActionComponent.h"
41 : #include "Syntax.h"
42 :
43 : #include "libmesh/parallel.h"
44 : #include "libmesh/fparser.hh"
45 :
46 : // Regular expression includes
47 : #include "pcrecpp.h"
48 :
49 : // C++ includes
50 : #include <string>
51 : #include <map>
52 : #include <fstream>
53 : #include <iomanip>
54 : #include <algorithm>
55 : #include <cstdlib>
56 : #include <filesystem>
57 :
58 : namespace Moose
59 : {
60 :
61 : bool
62 1251146 : isSectionActive(std::string path, hit::Node * root)
63 : {
64 1251146 : hit::Node * n = root->find(path);
65 4227377 : while (n)
66 : {
67 3044948 : hit::Node * section = n->parent();
68 3044948 : if (section)
69 : {
70 3725038 : auto actives = section->find("active");
71 3725038 : auto inactives = section->find("inactive");
72 :
73 : // only check current level, not nested ones
74 1862519 : if (actives && actives->type() == hit::NodeType::Field && actives->parent() == section)
75 : {
76 167822 : auto vars = section->param<std::vector<std::string>>("active");
77 83911 : bool have_var = false;
78 215769 : for (auto & var : vars)
79 131858 : if (n->path() == hit::pathNorm(var))
80 24183 : have_var = true;
81 83911 : if (!have_var)
82 59728 : return false;
83 83911 : }
84 : // only check current level, not nested ones
85 1802791 : if (inactives && inactives->type() == hit::NodeType::Field && inactives->parent() == section)
86 : {
87 25898 : auto vars = section->param<std::vector<std::string>>("inactive");
88 21533 : for (auto & var : vars)
89 17573 : if (n->path() == hit::pathNorm(var))
90 8989 : return false;
91 12949 : }
92 : }
93 2976231 : n = section;
94 : }
95 1182429 : return true;
96 : }
97 :
98 : std::vector<std::string>
99 131 : findSimilar(std::string param, std::vector<std::string> options)
100 : {
101 131 : std::vector<std::string> candidates;
102 131 : if (options.size() == 0)
103 14 : return candidates;
104 :
105 117 : int mindist = MooseUtils::levenshteinDist(options[0], param);
106 4152 : for (auto & opt : options)
107 : {
108 4035 : int dist = MooseUtils::levenshteinDist(opt, param);
109 : // magic number heuristics to get similarity distance cutoff
110 4035 : int dist_cutoff = 1 + param.size() / 5;
111 4035 : if (dist > dist_cutoff || dist > mindist)
112 4031 : continue;
113 :
114 4 : if (dist < mindist)
115 : {
116 4 : mindist = dist;
117 4 : candidates.clear();
118 : }
119 4 : candidates.push_back(opt);
120 : }
121 117 : return candidates;
122 0 : }
123 :
124 68460 : Builder::Builder(MooseApp & app, ActionWarehouse & action_wh, Parser & parser)
125 : : ConsoleStreamInterface(app),
126 68460 : _app(app),
127 136920 : _factory(app.getFactory()),
128 68460 : _action_wh(action_wh),
129 68460 : _action_factory(app.getActionFactory()),
130 68460 : _syntax(_action_wh.syntax()),
131 68460 : _parser(parser),
132 68460 : _root(_parser.getRoot()),
133 68460 : _syntax_formatter(nullptr),
134 136920 : _current_params(nullptr)
135 : {
136 68460 : }
137 :
138 62854 : Builder::~Builder() {}
139 :
140 : InputParameters
141 7897804 : Builder::validParams()
142 : {
143 7897804 : InputParameters params = emptyInputParameters();
144 :
145 : /**
146 : * Add the "active" and "inactive" parameters so that all blocks in the input file
147 : * can selectively create lists of active/inactive sub-blocks.
148 : */
149 23693412 : params.addParam<std::vector<std::string>>(
150 : "active",
151 23693412 : std::vector<std::string>({"__all__"}),
152 : "If specified only the blocks named will be visited and made active");
153 15795608 : params.addParam<std::vector<std::string>>(
154 : "inactive",
155 15795608 : std::vector<std::string>(),
156 : "If specified blocks matching these identifiers will be skipped.");
157 :
158 7897804 : return params;
159 23693412 : }
160 :
161 : std::vector<std::string>
162 131 : Builder::listValidParams(std::string & section_name)
163 : {
164 : bool dummy;
165 131 : std::string registered_identifier = _syntax.isAssociated(section_name, &dummy);
166 131 : auto iters = _syntax.getActions(registered_identifier);
167 :
168 131 : std::vector<std::string> paramlist;
169 376 : for (auto it = iters.first; it != iters.second; ++it)
170 : {
171 245 : auto params = _action_factory.getValidParams(it->second._action);
172 4280 : for (const auto & it : params)
173 4035 : paramlist.push_back(it.first);
174 245 : }
175 262 : return paramlist;
176 131 : }
177 :
178 : void
179 2567976 : UnusedWalker::walk(const std::string & fullpath, const std::string & nodename, hit::Node * n)
180 : {
181 : // the line() > 0 check allows us to skip nodes that were merged into this tree (i.e. CLI
182 : // args) because their unused params are checked+reported independently of the ones in the
183 : // main tree.
184 70940 : if (!_used.count(fullpath) && nodename != "active" && nodename != "inactive" &&
185 2638916 : isSectionActive(fullpath, n->root()) && n->line() > 0)
186 : {
187 131 : auto section_name = fullpath.substr(0, fullpath.rfind("/"));
188 131 : auto paramlist = _builder.listValidParams(section_name);
189 131 : auto candidates = findSimilar(nodename, paramlist);
190 131 : if (candidates.size() > 0)
191 4 : errors.emplace_back(
192 8 : "unused parameter '" + fullpath + "'; did you mean '" + candidates[0] + "'?", n);
193 : else
194 127 : errors.emplace_back("unused parameter '" + fullpath + "'", n);
195 131 : }
196 2567976 : }
197 :
198 : std::string
199 2445 : Builder::getPrimaryFileName(bool strip_leading_path) const
200 : {
201 2445 : const auto path = _parser.getLastInputFilePath();
202 4890 : return (strip_leading_path ? path.filename() : std::filesystem::absolute(path)).string();
203 2445 : }
204 :
205 : void
206 1198027 : Builder::walkRaw(std::string /*fullpath*/, std::string /*nodepath*/, hit::Node * n)
207 : {
208 1198027 : InputParameters active_list_params = Action::validParams();
209 1198027 : InputParameters params = EmptyAction::validParams();
210 :
211 1198027 : const std::string section_name = n->fullpath();
212 1198027 : const std::string curr_identifier = n->fullpath();
213 :
214 : // Before we retrieve any actions or build any objects, make sure that the section they are in
215 : // is active
216 1198027 : if (!isSectionActive(curr_identifier, &_root))
217 15729 : return;
218 :
219 : // Extract the block parameters before constructing the action
220 : // There may be more than one Action registered for a given section in which case we need to
221 : // build them all
222 : bool is_parent;
223 1182298 : std::string registered_identifier = _syntax.isAssociated(section_name, &is_parent);
224 :
225 : // Make sure at least one action is associated with the current identifier
226 1182298 : if (const auto [begin, end] = _syntax.getActions(registered_identifier); begin == end)
227 : {
228 4 : _errors.emplace_back(
229 8 : "section '[" + curr_identifier +
230 : "]' does not have an associated Action; you likely misspelled the Action/section name "
231 : "or the app you are running does not support this Action/syntax",
232 : n);
233 4 : return;
234 : }
235 :
236 : // The DynamicObjecRegistrationAction changes the action multimap and would invalidate the
237 : // iterators returned by _syntax.getActions, that's why we have to loop in this awkward way.
238 1182294 : std::set<const Syntax::ActionInfo *> processed_actions;
239 : while (true)
240 : {
241 : // search for an unprocessed action
242 3046271 : auto [begin, end] = _syntax.getActions(registered_identifier);
243 3046271 : auto it = begin;
244 6189037 : for (; it != end && processed_actions.count(&it->second); ++it)
245 : ;
246 :
247 : // no more unprocessed actions
248 3046271 : if (it == end)
249 1182160 : break;
250 :
251 : // mark action as processed
252 1864111 : processed_actions.insert(&it->second);
253 :
254 1864111 : if (is_parent)
255 344468 : continue;
256 1519643 : if (_syntax.isDeprecatedSyntax(registered_identifier))
257 0 : mooseDeprecated(
258 0 : hit::errormsg(n, _syntax.deprecatedActionSyntaxMessage(registered_identifier)));
259 :
260 1519643 : params = _action_factory.getValidParams(it->second._action);
261 3039286 : params.set<ActionWarehouse *>("awh") = &_action_wh;
262 1519643 : params.setHitNode(*n, {});
263 :
264 1519643 : extractParams(curr_identifier, params);
265 :
266 : // Add the parsed syntax to the parameters object for consumption by the Action
267 4558917 : params.set<std::string>("task") = it->second._task;
268 1519639 : params.set<std::string>("registered_identifier") = registered_identifier;
269 :
270 1519639 : if (!(params.have_parameter<bool>("isObjectAction") && params.get<bool>("isObjectAction")))
271 1514932 : params.set<std::vector<std::string>>("control_tags")
272 757466 : .push_back(MooseUtils::baseName(curr_identifier));
273 :
274 : // Create the Action
275 : std::shared_ptr<Action> action_obj =
276 1519639 : _action_factory.create(it->second._action, curr_identifier, params);
277 :
278 : {
279 : // extract the MooseObject params if necessary
280 : std::shared_ptr<MooseObjectAction> object_action =
281 1519529 : std::dynamic_pointer_cast<MooseObjectAction>(action_obj);
282 1519529 : if (object_action)
283 : {
284 761950 : auto & object_params = object_action->getObjectParams();
285 761950 : object_params.setHitNode(*n, {});
286 761950 : extractParams(curr_identifier, object_params);
287 1523868 : object_params.set<std::vector<std::string>>("control_tags")
288 761934 : .push_back(MooseUtils::baseName(curr_identifier));
289 : }
290 : // extract the Component params if necessary
291 : std::shared_ptr<AddActionComponentAction> component_action =
292 1519513 : std::dynamic_pointer_cast<AddActionComponentAction>(action_obj);
293 1519513 : if (component_action)
294 : {
295 196 : auto & component_params = component_action->getComponentParams();
296 196 : component_params.setHitNode(*n, {});
297 196 : extractParams(curr_identifier, component_params);
298 392 : component_params.set<std::vector<std::string>>("control_tags")
299 196 : .push_back(MooseUtils::baseName(curr_identifier));
300 : }
301 1519513 : }
302 :
303 : // add it to the warehouse
304 1519513 : _action_wh.addActionBlock(action_obj);
305 3383486 : }
306 1245096 : }
307 :
308 : void
309 1198020 : Builder::walk(const std::string & fullpath, const std::string & nodepath, hit::Node * n)
310 : {
311 : // skip sections that were manually processed first.
312 4757031 : for (auto & sec : _secs_need_first)
313 3587549 : if (nodepath == sec)
314 28538 : return;
315 1169482 : walkRaw(fullpath, nodepath, n);
316 : }
317 :
318 : void
319 67893 : Builder::build()
320 : {
321 : // Pull in extracted variables from the parser (fparse stuff)
322 67893 : _extracted_vars = _parser.getExtractedVars();
323 :
324 : // There are a few order dependent actions that have to be built first in
325 : // order for the parser and application to function properly:
326 : //
327 : // SetupDebugAction: This action can contain an option for monitoring the parser progress. It must
328 : // be parsed first to capture all of the parsing output.
329 : //
330 : // GlobalParamsAction: This action is checked during the parameter extraction routines of all
331 : // subsequent blocks. It must be parsed early since it must exist during
332 : // subsequent parameter extraction.
333 : //
334 : // DynamicObjectRegistration: This action must be built before any MooseObjectActions are built.
335 : // This is because we retrieve valid parameters from the Factory
336 : // during parse time. Objects must be registered before
337 : // validParameters can be retrieved.
338 271572 : auto syntax = _syntax.getSyntaxByAction("SetupDebugAction");
339 67893 : std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
340 :
341 271572 : syntax = _syntax.getSyntaxByAction("GlobalParamsAction");
342 67893 : std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
343 :
344 271572 : syntax = _syntax.getSyntaxByAction("DynamicObjectRegistrationAction");
345 67893 : std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
346 :
347 : // Walk all the sections extracting paramters from each into InputParameters objects
348 271572 : for (auto & sec : _secs_need_first)
349 203679 : if (auto n = _root.find(sec))
350 28545 : walkRaw(n->parent()->fullpath(), n->path(), n);
351 :
352 : // Walk for the remainder
353 67893 : _root.walk(this, hit::NodeType::Section);
354 :
355 : // Warn for all deprecated parameters together
356 67759 : if (_deprecated_params.size())
357 : {
358 915 : std::vector<std::string> messages;
359 1993 : for (const auto & param_message_pair : _deprecated_params)
360 1078 : messages.push_back(param_message_pair.second);
361 915 : const auto message = MooseUtils::stringJoin(messages, "\n\n");
362 :
363 915 : const auto current_show_trace = Moose::show_trace;
364 915 : Moose::show_trace = false;
365 915 : moose::internal::mooseDeprecatedStream(Moose::out, false, true, message + "\n\n");
366 907 : Moose::show_trace = current_show_trace;
367 907 : }
368 :
369 67751 : if (_errors.size())
370 52 : _parser.parseError(_errors);
371 67699 : }
372 :
373 : // Checks the input and the way it has been used and emits any errors/warnings.
374 : // This has to be a separate function because for we don't know if some parameters were unused
375 : // until all the multiapps/subapps have been fully initialized - which isn't complete until
376 : // *after* all the other member functions on Parser have been run. So this is here to be
377 : // externally called at the right time.
378 : void
379 62840 : Builder::errorCheck(const Parallel::Communicator & comm, bool warn_unused, bool err_unused)
380 : {
381 : // Nothing to do here
382 62840 : if (!warn_unused && !err_unused)
383 0 : return;
384 :
385 62840 : std::vector<hit::ErrorMessage> messages;
386 :
387 : {
388 62840 : UnusedWalker uw(_extracted_vars, *this);
389 62840 : _parser.getCommandLineRoot().walk(&uw);
390 62840 : Parser::appendErrorMessages(messages, uw.errors);
391 62840 : }
392 :
393 : {
394 62840 : UnusedWalker uw(_extracted_vars, *this);
395 62840 : _root.walk(&uw);
396 62840 : Parser::appendErrorMessages(messages, uw.errors);
397 62840 : }
398 :
399 62844 : for (const auto & arg : _app.commandLine()->unusedHitParams(comm))
400 62844 : messages.emplace_back("unused command line parameter '" + arg + "'");
401 :
402 62840 : if (messages.size())
403 : {
404 90 : const auto message = _parser.joinErrorMessages(messages);
405 90 : if (warn_unused)
406 51 : mooseUnused(message);
407 90 : if (err_unused)
408 : {
409 39 : if (_parser.getThrowOnError())
410 0 : _parser.parseError(messages);
411 : else
412 39 : mooseError(
413 39 : message +
414 : "\n\nAppend --allow-unused (or -w) on the command line to ignore unused parameters.");
415 : }
416 51 : }
417 62801 : }
418 :
419 : void
420 20 : Builder::initSyntaxFormatter(SyntaxFormatterType type, bool dump_mode)
421 : {
422 20 : switch (type)
423 : {
424 0 : case INPUT_FILE:
425 0 : _syntax_formatter = std::make_unique<InputFileFormatter>(dump_mode);
426 0 : break;
427 20 : case YAML:
428 20 : _syntax_formatter = std::make_unique<YAMLFormatter>(dump_mode);
429 20 : break;
430 0 : default:
431 0 : mooseError("Unrecognized Syntax Formatter requested");
432 : break;
433 : }
434 20 : }
435 :
436 : void
437 183 : Builder::buildJsonSyntaxTree(JsonSyntaxTree & root) const
438 : {
439 183 : std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
440 :
441 4941 : for (const auto & iter : _syntax.getAssociatedTypes())
442 4758 : root.addSyntaxType(iter.first, iter.second);
443 :
444 : // Build a list of all the actions appearing in the syntax
445 21921 : for (const auto & iter : _syntax.getAssociatedActions())
446 : {
447 21738 : Syntax::ActionInfo act_info = iter.second;
448 : /**
449 : * If the task is nullptr that means we need to figure out which task goes with this syntax for
450 : * the purpose of building the Moose Object part of the tree. We will figure this out by asking
451 : * the ActionFactory for the registration info.
452 : */
453 21738 : if (act_info._task == "")
454 17111 : act_info._task = _action_factory.getTaskName(act_info._action);
455 :
456 21738 : all_names.push_back(std::make_pair(iter.first, act_info));
457 21738 : }
458 :
459 : // Add all the actions to the JSON tree, except for ActionComponents (below)
460 21921 : for (const auto & act_names : all_names)
461 : {
462 21738 : const auto & act_info = act_names.second;
463 21738 : const std::string & action = act_info._action;
464 21738 : const std::string & task = act_info._task;
465 21738 : const std::string syntax = act_names.first;
466 21738 : InputParameters action_obj_params = _action_factory.getValidParams(action);
467 43476 : bool params_added = root.addParameters("",
468 : syntax,
469 : false,
470 : action,
471 : true,
472 : &action_obj_params,
473 86952 : _syntax.getLineInfo(syntax, action, ""),
474 : "");
475 :
476 21738 : if (params_added)
477 : {
478 19111 : auto tasks = _action_factory.getTasksByAction(action);
479 49400 : for (auto & t : tasks)
480 : {
481 30289 : auto info = _action_factory.getLineInfo(action, t);
482 30289 : root.addActionTask(syntax, action, t, info);
483 30289 : }
484 19111 : }
485 :
486 : /**
487 : * We need to see if this action is inherited from MooseObjectAction. If it is, then we will
488 : * loop over all the Objects in MOOSE's Factory object to print them out if they have associated
489 : * bases matching the current task.
490 : */
491 34593 : if (action_obj_params.have_parameter<bool>("isObjectAction") &&
492 34593 : action_obj_params.get<bool>("isObjectAction"))
493 : {
494 19389618 : for (auto & [moose_obj_name, obj] : _factory.registeredObjects())
495 : {
496 19376763 : auto moose_obj_params = obj->buildParameters();
497 : // Now that we know that this is a MooseObjectAction we need to see if it has been
498 : // restricted
499 : // in any way by the user.
500 19376763 : const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
501 :
502 : // See if the current Moose Object syntax belongs under this Action's block
503 19376763 : if ((buildable_types.empty() || // Not restricted
504 0 : std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
505 0 : buildable_types.end()) && // Restricted but found
506 19376763 : moose_obj_params.hasBase() && // Has a registered base
507 19376763 : _syntax.verifyMooseObjectTask(moose_obj_params.getBase(),
508 38753526 : task) && // and that base is associated
509 409117 : action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
510 : )
511 : {
512 409117 : std::string name;
513 409117 : size_t pos = 0;
514 409117 : bool is_action_params = false;
515 409117 : bool is_type = false;
516 409117 : if (syntax[syntax.size() - 1] == '*')
517 : {
518 356383 : pos = syntax.size();
519 :
520 356383 : if (!action_obj_params.collapseSyntaxNesting())
521 356383 : name = syntax.substr(0, pos - 1) + moose_obj_name;
522 : else
523 : {
524 0 : name = syntax.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
525 0 : is_action_params = true;
526 : }
527 : }
528 : else
529 : {
530 52734 : name = syntax + "/<type>/" + moose_obj_name;
531 52734 : is_type = true;
532 : }
533 409117 : moose_obj_params.set<std::string>("type") = moose_obj_name;
534 :
535 409117 : auto lineinfo = _factory.getLineInfo(moose_obj_name);
536 409117 : std::string classname = _factory.associatedClassName(moose_obj_name);
537 409117 : root.addParameters(syntax,
538 : name,
539 : is_type,
540 : moose_obj_name,
541 : is_action_params,
542 : &moose_obj_params,
543 : lineinfo,
544 : classname);
545 409117 : }
546 19376763 : }
547 :
548 : // Same thing for ActionComponents, which, while they are not MooseObjects, should behave
549 : // similarly syntax-wise
550 12855 : if (syntax != "ActionComponents/*")
551 12672 : continue;
552 :
553 366 : auto iters = _action_factory.getActionsByTask("list_component");
554 :
555 549 : for (auto it = iters.first; it != iters.second; ++it)
556 : {
557 : // Get the name and parameters
558 366 : const auto component_name = it->second;
559 366 : auto component_params = _action_factory.getValidParams(component_name);
560 :
561 : // We currently do not have build-type restrictions on this action that adds
562 : // action-components
563 :
564 : // See if the current Moose Object syntax belongs under this Action's block
565 366 : if (action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
566 : )
567 : {
568 : // The logic for Components is a little simpler here for now because syntax like
569 : // Executioner/TimeIntegrator/type= do not exist for components
570 366 : std::string name;
571 366 : if (syntax[syntax.size() - 1] == '*')
572 : {
573 366 : size_t pos = syntax.size();
574 366 : name = syntax.substr(0, pos - 1) + component_name;
575 : }
576 366 : component_params.set<std::string>("type") = component_name;
577 :
578 1098 : auto lineinfo = _action_factory.getLineInfo(component_name, "list_component");
579 : // We add the parameters as for an object, because we want to fit them to be
580 : // added to json["AddActionComponentAction"]["subblock_types"]
581 366 : root.addParameters(syntax,
582 : /*syntax_path*/ name,
583 : /*is_type*/ false,
584 : "AddActionComponentAction",
585 : /*is_action=*/false,
586 : &component_params,
587 : lineinfo,
588 : component_name);
589 366 : }
590 366 : }
591 : }
592 34410 : }
593 183 : root.addGlobal();
594 183 : }
595 :
596 : void
597 20 : Builder::buildFullTree(const std::string & search_string)
598 : {
599 20 : std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
600 :
601 2408 : for (const auto & iter : _syntax.getAssociatedActions())
602 : {
603 2388 : Syntax::ActionInfo act_info = iter.second;
604 : /**
605 : * If the task is nullptr that means we need to figure out which task goes with this syntax for
606 : * the purpose of building the Moose Object part of the tree. We will figure this out by asking
607 : * the ActionFactory for the registration info.
608 : */
609 2388 : if (act_info._task == "")
610 1880 : act_info._task = _action_factory.getTaskName(act_info._action);
611 :
612 2388 : all_names.push_back(std::pair<std::string, Syntax::ActionInfo>(iter.first, act_info));
613 2388 : }
614 :
615 2408 : for (const auto & act_names : all_names)
616 : {
617 2388 : InputParameters action_obj_params = _action_factory.getValidParams(act_names.second._action);
618 4776 : _syntax_formatter->insertNode(
619 2388 : act_names.first, act_names.second._action, true, &action_obj_params);
620 :
621 2388 : const std::string & task = act_names.second._task;
622 2388 : std::string act_name = act_names.first;
623 :
624 : /**
625 : * We need to see if this action is inherited from MooseObjectAction. If it is, then we will
626 : * loop over all the Objects in MOOSE's Factory object to print them out if they have associated
627 : * bases matching the current task.
628 : */
629 3796 : if (action_obj_params.have_parameter<bool>("isObjectAction") &&
630 3796 : action_obj_params.get<bool>("isObjectAction"))
631 : {
632 2124416 : for (const auto & [moose_obj_name, obj] : _factory.registeredObjects())
633 : {
634 2123008 : auto moose_obj_params = obj->buildParameters();
635 : /**
636 : * Now that we know that this is a MooseObjectAction we need to see if it has been
637 : * restricted in any way by the user.
638 : */
639 2123008 : const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
640 :
641 : // See if the current Moose Object syntax belongs under this Action's block
642 2123008 : if ((buildable_types.empty() || // Not restricted
643 0 : std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
644 0 : buildable_types.end()) && // Restricted but found
645 2123008 : moose_obj_params.hasBase() && // Has a registered base
646 2123008 : _syntax.verifyMooseObjectTask(moose_obj_params.getBase(),
647 4246016 : task) && // and that base is associated
648 44938 : action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
649 : )
650 : {
651 44938 : std::string name;
652 44938 : size_t pos = 0;
653 44938 : bool is_action_params = false;
654 44938 : if (act_name[act_name.size() - 1] == '*')
655 : {
656 39170 : pos = act_name.size();
657 :
658 39170 : if (!action_obj_params.collapseSyntaxNesting())
659 39170 : name = act_name.substr(0, pos - 1) + moose_obj_name;
660 : else
661 : {
662 0 : name = act_name.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
663 0 : is_action_params = true;
664 : }
665 : }
666 : else
667 : {
668 5768 : name = act_name + "/<type>/" + moose_obj_name;
669 : }
670 :
671 44938 : moose_obj_params.set<std::string>("type") = moose_obj_name;
672 :
673 44938 : _syntax_formatter->insertNode(name, moose_obj_name, is_action_params, &moose_obj_params);
674 44938 : }
675 2123008 : }
676 : }
677 2388 : }
678 :
679 : // Do not change to _console, we need this printed to the stdout in all cases
680 20 : Moose::out << _syntax_formatter->print(search_string) << std::flush;
681 20 : }
682 :
683 : /**************************************************************************************************
684 : **************************************************************************************************
685 : * Parameter Extraction Routines *
686 : **************************************************************************************************
687 : **************************************************************************************************/
688 : using std::string;
689 :
690 : // Template Specializations for retrieving special types from the input file
691 : template <>
692 : void Builder::setScalarParameter<RealVectorValue, RealVectorValue>(
693 : const std::string & full_name,
694 : const std::string & short_name,
695 : InputParameters::Parameter<RealVectorValue> * param,
696 : bool in_global,
697 : GlobalParamsAction * global_block);
698 :
699 : template <>
700 : void Builder::setScalarParameter<Point, Point>(const std::string & full_name,
701 : const std::string & short_name,
702 : InputParameters::Parameter<Point> * param,
703 : bool in_global,
704 : GlobalParamsAction * global_block);
705 :
706 : template <>
707 : void Builder::setScalarParameter<RealEigenVector, RealEigenVector>(
708 : const std::string & full_name,
709 : const std::string & short_name,
710 : InputParameters::Parameter<RealEigenVector> * param,
711 : bool in_global,
712 : GlobalParamsAction * global_block);
713 :
714 : template <>
715 : void Builder::setScalarParameter<RealEigenMatrix, RealEigenMatrix>(
716 : const std::string & full_name,
717 : const std::string & short_name,
718 : InputParameters::Parameter<RealEigenMatrix> * param,
719 : bool in_global,
720 : GlobalParamsAction * global_block);
721 :
722 : template <>
723 : void Builder::setScalarParameter<PostprocessorName, PostprocessorName>(
724 : const std::string & full_name,
725 : const std::string & short_name,
726 : InputParameters::Parameter<PostprocessorName> * param,
727 : bool in_global,
728 : GlobalParamsAction * global_block);
729 :
730 : template <>
731 : void
732 : Builder::setScalarParameter<MooseEnum, MooseEnum>(const std::string & full_name,
733 : const std::string & short_name,
734 : InputParameters::Parameter<MooseEnum> * param,
735 : bool in_global,
736 : GlobalParamsAction * global_block);
737 :
738 : template <>
739 : void Builder::setScalarParameter<MultiMooseEnum, MultiMooseEnum>(
740 : const std::string & full_name,
741 : const std::string & short_name,
742 : InputParameters::Parameter<MultiMooseEnum> * param,
743 : bool in_global,
744 : GlobalParamsAction * global_block);
745 :
746 : template <>
747 : void Builder::setScalarParameter<ExecFlagEnum, ExecFlagEnum>(
748 : const std::string & full_name,
749 : const std::string & short_name,
750 : InputParameters::Parameter<ExecFlagEnum> * param,
751 : bool in_global,
752 : GlobalParamsAction * global_block);
753 :
754 : template <>
755 : void Builder::setScalarParameter<RealTensorValue, RealTensorValue>(
756 : const std::string & full_name,
757 : const std::string & short_name,
758 : InputParameters::Parameter<RealTensorValue> * param,
759 : bool in_global,
760 : GlobalParamsAction * global_block);
761 :
762 : template <>
763 : void Builder::setScalarParameter<ReporterName, std::string>(
764 : const std::string & full_name,
765 : const std::string & short_name,
766 : InputParameters::Parameter<ReporterName> * param,
767 : bool in_global,
768 : GlobalParamsAction * global_block);
769 :
770 : // Vectors
771 : template <>
772 : void Builder::setVectorParameter<RealVectorValue, RealVectorValue>(
773 : const std::string & full_name,
774 : const std::string & short_name,
775 : InputParameters::Parameter<std::vector<RealVectorValue>> * param,
776 : bool in_global,
777 : GlobalParamsAction * global_block);
778 :
779 : template <>
780 : void
781 : Builder::setVectorParameter<Point, Point>(const std::string & full_name,
782 : const std::string & short_name,
783 : InputParameters::Parameter<std::vector<Point>> * param,
784 : bool in_global,
785 : GlobalParamsAction * global_block);
786 :
787 : template <>
788 : void Builder::setVectorParameter<PostprocessorName, PostprocessorName>(
789 : const std::string & full_name,
790 : const std::string & short_name,
791 : InputParameters::Parameter<std::vector<PostprocessorName>> * param,
792 : bool in_global,
793 : GlobalParamsAction * global_block);
794 :
795 : template <>
796 : void Builder::setVectorParameter<MooseEnum, MooseEnum>(
797 : const std::string & full_name,
798 : const std::string & short_name,
799 : InputParameters::Parameter<std::vector<MooseEnum>> * param,
800 : bool in_global,
801 : GlobalParamsAction * global_block);
802 :
803 : template <>
804 : void Builder::setVectorParameter<MultiMooseEnum, MultiMooseEnum>(
805 : const std::string & full_name,
806 : const std::string & short_name,
807 : InputParameters::Parameter<std::vector<MultiMooseEnum>> * param,
808 : bool in_global,
809 : GlobalParamsAction * global_block);
810 :
811 : template <>
812 : void Builder::setVectorParameter<VariableName, VariableName>(
813 : const std::string & full_name,
814 : const std::string & short_name,
815 : InputParameters::Parameter<std::vector<VariableName>> * param,
816 : bool in_global,
817 : GlobalParamsAction * global_block);
818 :
819 : template <>
820 : void Builder::setVectorParameter<ReporterName, std::string>(
821 : const std::string & full_name,
822 : const std::string & short_name,
823 : InputParameters::Parameter<std::vector<ReporterName>> * param,
824 : bool in_global,
825 : GlobalParamsAction * global_block);
826 :
827 : template <>
828 : void Builder::setVectorParameter<CLIArgString, std::string>(
829 : const std::string & full_name,
830 : const std::string & short_name,
831 : InputParameters::Parameter<std::vector<CLIArgString>> * param,
832 : bool in_global,
833 : GlobalParamsAction * global_block);
834 :
835 : template <>
836 : void Builder::setDoubleIndexParameter<Point>(
837 : const std::string & full_name,
838 : const std::string & short_name,
839 : InputParameters::Parameter<std::vector<std::vector<Point>>> * param,
840 : bool in_global,
841 : GlobalParamsAction * global_block);
842 :
843 : void
844 2367568 : Builder::extractParams(const std::string & prefix, InputParameters & p)
845 : {
846 2367568 : std::ostringstream error_stream;
847 2478526 : static const std::string global_params_task = "set_global_params";
848 : static const std::string global_params_block_name =
849 2589484 : _syntax.getSyntaxByAction("GlobalParamsAction").front();
850 :
851 2367568 : ActionIterator act_iter = _action_wh.actionBlocksWithActionBegin(global_params_task);
852 2367568 : GlobalParamsAction * global_params_block = nullptr;
853 :
854 : // We are grabbing only the first
855 2367568 : if (act_iter != _action_wh.actionBlocksWithActionEnd(global_params_task))
856 188015 : global_params_block = dynamic_cast<GlobalParamsAction *>(*act_iter);
857 :
858 : // Set a pointer to the current InputParameters object being parsed so that it
859 : // can be referred to in the extraction routines
860 2367568 : _current_params = &p;
861 66821092 : for (const auto & it : p)
862 : {
863 64453544 : if (p.shouldIgnore(it.first))
864 2778 : continue;
865 :
866 64450766 : const hit::Node * node = nullptr;
867 64450766 : bool found = false;
868 64450766 : bool in_global = false;
869 :
870 : const auto found_param =
871 2735532 : [this, &found, &node, &p](const std::string & param_name, const std::string & full_name)
872 : {
873 2735532 : found = true;
874 2735532 : p.setHitNode(param_name, *node, {});
875 2735532 : p.set_attributes(param_name, false);
876 2735532 : _extracted_vars.insert(full_name);
877 2735532 : };
878 :
879 126341939 : for (const auto & param_name : p.paramAliases(it.first))
880 : {
881 64626563 : std::string full_name = prefix + "/" + param_name;
882 :
883 : // Mark parameters appearing in the input file or command line
884 64626563 : if (node = _root.find(full_name); node && node->type() == hit::NodeType::Field)
885 : {
886 2671115 : found_param(param_name, full_name);
887 :
888 : // Store a deprecated warning if one exists and we haven't for this parameter
889 : // TODO: This is pretty bad and only lets us skip per parameter name...
890 2671115 : if (const auto deprecated_message = p.queryDeprecatedParamMessage(param_name))
891 2671115 : _deprecated_params.emplace(param_name, *deprecated_message);
892 : }
893 : // Wait! Check the GlobalParams section
894 61955448 : else if (global_params_block)
895 : {
896 4598211 : full_name = global_params_block_name + "/" + param_name;
897 4598211 : if (node = _root.find(full_name); node)
898 : {
899 64417 : found_param(param_name, full_name);
900 64417 : in_global = true;
901 : }
902 : }
903 64626563 : if (found)
904 : {
905 :
906 2735532 : if (p.isPrivate(param_name) && !in_global)
907 : {
908 : // Warn on private, just once
909 8 : if (std::find_if(_errors.begin(),
910 : _errors.end(),
911 16 : [&node](const auto & err) { return err.node == node; }) == _errors.end())
912 8 : _errors.emplace_back("parameter '" + full_name + "' is private and cannot be set",
913 : node);
914 8 : continue;
915 8 : }
916 : // avoid setting the parameter
917 2735524 : else if (p.isPrivate(param_name) && in_global)
918 134 : continue;
919 :
920 2735390 : auto & short_name = param_name;
921 2735390 : libMesh::Parameters::Value * par = MooseUtils::get(it.second);
922 :
923 : #define setscalarvaltype(ptype, base, range) \
924 : else if (par->type() == demangle(typeid(ptype).name())) \
925 : setScalarValueTypeParameter<ptype, range, base>( \
926 : full_name, \
927 : short_name, \
928 : dynamic_cast<InputParameters::Parameter<ptype> *>(par), \
929 : in_global, \
930 : global_params_block, \
931 : *node)
932 : #define setscalar(ptype, base) \
933 : else if (par->type() == demangle(typeid(ptype).name())) \
934 : setScalarParameter<ptype, base>(full_name, \
935 : short_name, \
936 : dynamic_cast<InputParameters::Parameter<ptype> *>(par), \
937 : in_global, \
938 : global_params_block)
939 : #define setvector(ptype, base) \
940 : else if (par->type() == demangle(typeid(std::vector<ptype>).name())) \
941 : setVectorParameter<ptype, base>( \
942 : full_name, \
943 : short_name, \
944 : dynamic_cast<InputParameters::Parameter<std::vector<ptype>> *>(par), \
945 : in_global, \
946 : global_params_block)
947 : #define setmap(key_type, mapped_type) \
948 : else if (par->type() == demangle(typeid(std::map<key_type, mapped_type>).name())) \
949 : setMapParameter( \
950 : full_name, \
951 : short_name, \
952 : dynamic_cast<InputParameters::Parameter<std::map<key_type, mapped_type>> *>(par), \
953 : in_global, \
954 : global_params_block)
955 : #define setvectorvector(ptype) \
956 : else if (par->type() == demangle(typeid(std::vector<std::vector<ptype>>).name())) \
957 : setDoubleIndexParameter<ptype>( \
958 : full_name, \
959 : short_name, \
960 : dynamic_cast<InputParameters::Parameter<std::vector<std::vector<ptype>>> *>(par), \
961 : in_global, \
962 : global_params_block)
963 : #define setvectorvectorvector(ptype) \
964 : else if (par->type() == demangle(typeid(std::vector<std::vector<std::vector<ptype>>>).name())) \
965 : setTripleIndexParameter<ptype>( \
966 : full_name, \
967 : short_name, \
968 : dynamic_cast< \
969 : InputParameters::Parameter<std::vector<std::vector<std::vector<ptype>>>> *>(par), \
970 : in_global, \
971 : global_params_block)
972 :
973 : /**
974 : * Scalar types
975 : */
976 : // built-ins
977 : // NOTE: Similar dynamic casting is done in InputParameters.C, please update appropriately
978 : if (false)
979 : ;
980 2735390 : setscalarvaltype(Real, double, Real);
981 2499911 : setscalarvaltype(int, int, long);
982 2497652 : setscalarvaltype(unsigned short, unsigned int, long);
983 2484593 : setscalarvaltype(long, int, long);
984 2484593 : setscalarvaltype(unsigned int, unsigned int, long);
985 2317103 : setscalarvaltype(unsigned long, unsigned int, long);
986 2314433 : setscalarvaltype(long int, int64_t, long);
987 2314433 : setscalarvaltype(unsigned long long, unsigned int, long);
988 :
989 2314433 : setscalar(bool, bool);
990 2115373 : setscalar(SubdomainID, int);
991 2115373 : setscalar(BoundaryID, int);
992 :
993 : // string and string-subclass types
994 2113657 : setscalar(string, string);
995 1447362 : setscalar(SubdomainName, string);
996 1441196 : setscalar(BoundaryName, string);
997 1422406 : setscalar(FileName, string);
998 1421053 : setscalar(MeshFileName, string);
999 1414428 : setscalar(MatrixFileName, string);
1000 1414388 : setscalar(FileNameNoExtension, string);
1001 1413210 : setscalar(RelativeFileName, string);
1002 1413210 : setscalar(DataFileName, string);
1003 1413159 : setscalar(ComponentName, string);
1004 1413159 : setscalar(PhysicsName, string);
1005 1413159 : setscalar(OutFileBase, string);
1006 1413159 : setscalar(VariableName, string);
1007 1399069 : setscalar(NonlinearVariableName, string);
1008 1204023 : setscalar(LinearVariableName, string);
1009 1198346 : setscalar(SolverVariableName, string);
1010 1198346 : setscalar(AuxVariableName, string);
1011 1163252 : setscalar(FunctionName, string);
1012 1116404 : setscalar(ConvergenceName, string);
1013 1115258 : setscalar(MeshDivisionName, string);
1014 1113922 : setscalar(UserObjectName, string);
1015 1107227 : setscalar(VectorPostprocessorName, string);
1016 1105689 : setscalar(IndicatorName, string);
1017 1105197 : setscalar(MarkerName, string);
1018 1103190 : setscalar(MultiAppName, string);
1019 1089362 : setscalar(OutputName, string);
1020 1089362 : setscalar(MaterialPropertyName, string);
1021 1076130 : setscalar(MooseFunctorName, string);
1022 1057604 : setscalar(MaterialName, string);
1023 1057476 : setscalar(DistributionName, string);
1024 1057476 : setscalar(PositionsName, string);
1025 1057002 : setscalar(SamplerName, string);
1026 1056648 : setscalar(TagName, string);
1027 1055268 : setscalar(TimesName, string);
1028 1055212 : setscalar(MeshGeneratorName, string);
1029 1028988 : setscalar(ExtraElementIDName, string);
1030 1028883 : setscalar(PostprocessorName, PostprocessorName);
1031 1020653 : setscalar(ExecutorName, string);
1032 1020613 : setscalar(NonlinearSystemName, string);
1033 1020129 : setscalar(LinearSystemName, string);
1034 1020129 : setscalar(SolverSystemName, string);
1035 1018270 : setscalar(CLIArgString, string);
1036 : #ifdef MOOSE_MFEM_ENABLED
1037 672201 : setscalar(MFEMScalarCoefficientName, string);
1038 671743 : setscalar(MFEMVectorCoefficientName, string);
1039 671609 : setscalar(MFEMMatrixCoefficientName, string);
1040 : #endif
1041 :
1042 : // Moose Compound Scalars
1043 1017678 : setscalar(RealVectorValue, RealVectorValue);
1044 996502 : setscalar(Point, Point);
1045 988458 : setscalar(RealEigenVector, RealEigenVector);
1046 986476 : setscalar(RealEigenMatrix, RealEigenMatrix);
1047 986290 : setscalar(MooseEnum, MooseEnum);
1048 548972 : setscalar(MultiMooseEnum, MultiMooseEnum);
1049 514900 : setscalar(RealTensorValue, RealTensorValue);
1050 514861 : setscalar(ExecFlagEnum, ExecFlagEnum);
1051 455473 : setscalar(ReporterName, string);
1052 454536 : setscalar(ReporterValueName, string);
1053 454437 : setscalar(ParsedFunctionExpression, string);
1054 :
1055 : // vector types
1056 453508 : setvector(bool, bool);
1057 452240 : setvector(Real, double);
1058 399887 : setvector(int, int);
1059 398607 : setvector(long, int);
1060 398543 : setvector(unsigned int, int);
1061 :
1062 : // We need to be able to parse 8-byte unsigned types when
1063 : // libmesh is configured --with-dof-id-bytes=8. Officially,
1064 : // libmesh uses uint64_t in that scenario, which is usually
1065 : // equivalent to 'unsigned long long'. Note that 'long long'
1066 : // has been around since C99 so most C++ compilers support it,
1067 : // but presumably uint64_t is the "most standard" way to get a
1068 : // 64-bit unsigned type, so we'll stick with that here.
1069 : #if LIBMESH_DOF_ID_BYTES == 8
1070 389145 : setvector(uint64_t, int);
1071 : #endif
1072 :
1073 388155 : setvector(SubdomainID, int);
1074 385872 : setvector(BoundaryID, int);
1075 385710 : setvector(RealVectorValue, RealVectorValue);
1076 385651 : setvector(Point, Point);
1077 376951 : setvector(MooseEnum, MooseEnum);
1078 376684 : setvector(MultiMooseEnum, MultiMooseEnum);
1079 :
1080 376666 : setvector(string, string);
1081 317095 : setvector(FileName, string);
1082 308749 : setvector(FileNameNoExtension, string);
1083 308749 : setvector(RelativeFileName, string);
1084 308749 : setvector(DataFileName, string);
1085 308749 : setvector(MeshFileName, string);
1086 308721 : setvector(MatrixFileName, string);
1087 308721 : setvector(SubdomainName, string);
1088 261047 : setvector(BoundaryName, string);
1089 131270 : setvector(NonlinearVariableName, string);
1090 130284 : setvector(LinearVariableName, string);
1091 130284 : setvector(SolverVariableName, string);
1092 130284 : setvector(AuxVariableName, string);
1093 119698 : setvector(FunctionName, string);
1094 117557 : setvector(ConvergenceName, string);
1095 117032 : setvector(MeshDivisionName, string);
1096 117019 : setvector(UserObjectName, string);
1097 116834 : setvector(IndicatorName, string);
1098 116834 : setvector(MarkerName, string);
1099 116771 : setvector(MultiAppName, string);
1100 116609 : setvector(PostprocessorName, PostprocessorName);
1101 114211 : setvector(VectorPostprocessorName, string);
1102 114211 : setvector(OutputName, string);
1103 105475 : setvector(MaterialPropertyName, string);
1104 105032 : setvector(MooseFunctorName, string);
1105 101827 : setvector(MaterialName, string);
1106 101827 : setvector(DistributionName, string);
1107 101827 : setvector(SamplerName, string);
1108 101827 : setvector(TagName, string);
1109 98456 : setvector(VariableName, VariableName);
1110 20377 : setvector(MeshGeneratorName, string);
1111 18804 : setvector(ExtraElementIDName, string);
1112 18005 : setvector(ReporterName, string);
1113 16831 : setvector(CLIArgString, string);
1114 14954 : setvector(ComponentName, string);
1115 14954 : setvector(PhysicsName, string);
1116 14840 : setvector(PositionsName, string);
1117 14338 : setvector(TimesName, string);
1118 14338 : setvector(ReporterValueName, string);
1119 11412 : setvector(ExecutorName, string);
1120 11412 : setvector(NonlinearSystemName, string);
1121 10832 : setvector(LinearSystemName, string);
1122 8178 : setvector(SolverSystemName, string);
1123 : #ifdef MOOSE_MFEM_ENABLED
1124 4370 : setvector(MFEMScalarCoefficientName, string);
1125 4326 : setvector(MFEMVectorCoefficientName, string);
1126 4316 : setvector(MFEMMatrixCoefficientName, string);
1127 : #endif
1128 :
1129 : // map types
1130 6755 : setmap(string, unsigned int);
1131 6755 : setmap(string, Real);
1132 6695 : setmap(string, string);
1133 6328 : setmap(unsigned int, unsigned int);
1134 6307 : setmap(unsigned long, unsigned int);
1135 6286 : setmap(unsigned long long, unsigned int);
1136 :
1137 : // Double indexed types
1138 6265 : setvectorvector(Real);
1139 4196 : setvectorvector(int);
1140 4029 : setvectorvector(long);
1141 4016 : setvectorvector(unsigned int);
1142 3781 : setvectorvector(unsigned long long);
1143 :
1144 : // See vector type explanation
1145 : #if LIBMESH_DOF_ID_BYTES == 8
1146 3781 : setvectorvector(uint64_t);
1147 : #endif
1148 :
1149 3640 : setvectorvector(SubdomainID);
1150 3370 : setvectorvector(BoundaryID);
1151 3311 : setvectorvector(Point);
1152 3196 : setvectorvector(string);
1153 2609 : setvectorvector(FileName);
1154 2596 : setvectorvector(FileNameNoExtension);
1155 2583 : setvectorvector(DataFileName);
1156 2583 : setvectorvector(MeshFileName);
1157 2570 : setvectorvector(MatrixFileName);
1158 2570 : setvectorvector(SubdomainName);
1159 2085 : setvectorvector(BoundaryName);
1160 1992 : setvectorvector(VariableName);
1161 1992 : setvectorvector(NonlinearVariableName);
1162 1984 : setvectorvector(LinearVariableName);
1163 1984 : setvectorvector(SolverVariableName);
1164 1984 : setvectorvector(AuxVariableName);
1165 1984 : setvectorvector(FunctionName);
1166 1971 : setvectorvector(ConvergenceName);
1167 1971 : setvectorvector(UserObjectName);
1168 1958 : setvectorvector(IndicatorName);
1169 1945 : setvectorvector(MarkerName);
1170 1932 : setvectorvector(MultiAppName);
1171 1919 : setvectorvector(PostprocessorName);
1172 1906 : setvectorvector(VectorPostprocessorName);
1173 1893 : setvectorvector(MarkerName);
1174 1893 : setvectorvector(OutputName);
1175 1865 : setvectorvector(MaterialPropertyName);
1176 1852 : setvectorvector(MooseFunctorName);
1177 1793 : setvectorvector(MaterialName);
1178 1793 : setvectorvector(DistributionName);
1179 1793 : setvectorvector(SamplerName);
1180 1793 : setvectorvector(TagName);
1181 : #ifdef MOOSE_MFEM_ENABLED
1182 425 : setvectorvector(MFEMScalarCoefficientName);
1183 425 : setvectorvector(MFEMVectorCoefficientName);
1184 425 : setvectorvector(MFEMMatrixCoefficientName);
1185 : #endif
1186 :
1187 : // Triple indexed types
1188 633 : setvectorvectorvector(Real);
1189 458 : setvectorvectorvector(int);
1190 445 : setvectorvectorvector(long);
1191 432 : setvectorvectorvector(unsigned int);
1192 419 : setvectorvectorvector(unsigned long long);
1193 :
1194 : // See vector type explanation
1195 : #if LIBMESH_DOF_ID_BYTES == 8
1196 419 : setvectorvectorvector(uint64_t);
1197 : #endif
1198 :
1199 406 : setvectorvectorvector(SubdomainID);
1200 393 : setvectorvectorvector(BoundaryID);
1201 380 : setvectorvectorvector(string);
1202 234 : setvectorvectorvector(FileName);
1203 221 : setvectorvectorvector(FileNameNoExtension);
1204 208 : setvectorvectorvector(DataFileName);
1205 208 : setvectorvectorvector(MeshFileName);
1206 195 : setvectorvectorvector(MatrixFileName);
1207 195 : setvectorvectorvector(SubdomainName);
1208 182 : setvectorvectorvector(BoundaryName);
1209 169 : setvectorvectorvector(VariableName);
1210 169 : setvectorvectorvector(NonlinearVariableName);
1211 169 : setvectorvectorvector(LinearVariableName);
1212 169 : setvectorvectorvector(AuxVariableName);
1213 169 : setvectorvectorvector(FunctionName);
1214 156 : setvectorvectorvector(UserObjectName);
1215 143 : setvectorvectorvector(IndicatorName);
1216 130 : setvectorvectorvector(MarkerName);
1217 117 : setvectorvectorvector(MultiAppName);
1218 104 : setvectorvectorvector(PostprocessorName);
1219 91 : setvectorvectorvector(VectorPostprocessorName);
1220 78 : setvectorvectorvector(MarkerName);
1221 78 : setvectorvectorvector(OutputName);
1222 65 : setvectorvectorvector(MaterialPropertyName);
1223 52 : setvectorvectorvector(MooseFunctorName);
1224 39 : setvectorvectorvector(MaterialName);
1225 26 : setvectorvectorvector(DistributionName);
1226 13 : setvectorvectorvector(SamplerName);
1227 : else
1228 : {
1229 0 : _parser.parseError(
1230 0 : {{"unsupported type '" + par->type() + "' for input parameter '" + full_name + "'",
1231 : node}});
1232 : }
1233 :
1234 : #undef setscalarValueType
1235 : #undef setscalar
1236 : #undef setvector
1237 : #undef setvectorvectorvector
1238 : #undef setvectorvector
1239 : #undef setmap
1240 2735370 : break;
1241 : }
1242 129077289 : }
1243 :
1244 64450746 : if (!found)
1245 : {
1246 : /**
1247 : * Special case handling
1248 : * if the parameter wasn't found in the input file or the cli object the logic in this
1249 : * branch will execute
1250 : */
1251 :
1252 : // In the case where we have OutFileName but it wasn't actually found in the input filename,
1253 : // we will populate it with the actual parsed filename which is available here in the
1254 : // parser.
1255 :
1256 : InputParameters::Parameter<OutFileBase> * scalar_p =
1257 61715234 : dynamic_cast<InputParameters::Parameter<OutFileBase> *>(MooseUtils::get(it.second));
1258 61715234 : if (scalar_p)
1259 : {
1260 0 : std::string input_file_name = getPrimaryFileName();
1261 : mooseAssert(input_file_name != "", "Input Filename is nullptr");
1262 0 : size_t pos = input_file_name.find_last_of('.');
1263 : mooseAssert(pos != std::string::npos, "Unable to determine suffix of input file name");
1264 0 : scalar_p->set() = input_file_name.substr(0, pos) + "_out";
1265 0 : p.set_attributes(it.first, false);
1266 0 : }
1267 : }
1268 : }
1269 :
1270 : // Here we will see if there are any auto build vectors that need to be created
1271 : std::map<std::string, std::pair<std::string, std::string>> auto_build_vectors =
1272 2367548 : p.getAutoBuildVectors();
1273 2367550 : for (const auto & it : auto_build_vectors)
1274 : {
1275 : // We'll autogenerate values iff the requested vector is not valid but both the base and
1276 : // number
1277 : // are valid
1278 2 : const std::string & base_name = it.second.first;
1279 2 : const std::string & num_repeat = it.second.second;
1280 :
1281 2 : if (!p.isParamValid(it.first) && p.isParamValid(base_name) && p.isParamValid(num_repeat))
1282 : {
1283 2 : unsigned int vec_size = p.get<unsigned int>(num_repeat);
1284 2 : const std::string & name = p.get<std::string>(base_name);
1285 :
1286 2 : std::vector<VariableName> variable_names(vec_size);
1287 6 : for (unsigned int i = 0; i < vec_size; ++i)
1288 : {
1289 4 : std::ostringstream oss;
1290 4 : oss << name << i;
1291 4 : variable_names[i] = oss.str();
1292 4 : }
1293 :
1294 : // Finally set the autogenerated vector into the InputParameters object
1295 2 : p.set<std::vector<VariableName>>(it.first) = variable_names;
1296 2 : }
1297 : }
1298 2367548 : }
1299 :
1300 : template <typename T>
1301 : bool
1302 : toBool(const std::string & /*s*/, T & /*val*/)
1303 : {
1304 : return false;
1305 : }
1306 :
1307 : template <>
1308 : bool
1309 75 : toBool<bool>(const std::string & s, bool & val)
1310 : {
1311 75 : return hit::toBool(s, &val);
1312 : }
1313 :
1314 : template <typename T, typename Base>
1315 : void
1316 1710510 : Builder::setScalarParameter(const std::string & full_name,
1317 : const std::string & short_name,
1318 : InputParameters::Parameter<T> * param,
1319 : bool in_global,
1320 : GlobalParamsAction * global_block)
1321 : {
1322 1710510 : auto node = _root.find(full_name, true);
1323 : try
1324 : {
1325 4040083 : param->set() = node->param<Base>();
1326 : }
1327 7424 : catch (hit::Error & err)
1328 : {
1329 7424 : auto strval = node->param<std::string>();
1330 :
1331 3712 : auto & t = typeid(T);
1332 : // handle the case where the user put a number inside quotes
1333 : if constexpr (std::is_same_v<T, int> || std::is_same_v<T, unsigned int> ||
1334 : std::is_same_v<T, SubdomainID> || std::is_same_v<T, BoundaryID> ||
1335 : std::is_same_v<T, double>)
1336 : {
1337 : try
1338 : {
1339 3637 : param->set() = MooseUtils::convert<T>(strval, true);
1340 : }
1341 8 : catch (std::invalid_argument & /*e*/)
1342 : {
1343 4 : const std::string format_type = (t == typeid(double)) ? "float" : "integer";
1344 4 : _errors.emplace_back("invalid " + format_type + " syntax for parameter: " + full_name +
1345 : "='" + strval + "'",
1346 : node);
1347 4 : }
1348 : }
1349 : else if constexpr (std::is_same_v<T, bool>)
1350 : {
1351 75 : if (!toBool(strval, param->set()))
1352 0 : _errors.emplace_back(
1353 : "invalid boolean syntax for parameter: " + full_name + "='" + strval + "'", node);
1354 : }
1355 : else
1356 0 : throw;
1357 3712 : }
1358 :
1359 1710510 : if (in_global)
1360 : {
1361 9486 : global_block->remove(short_name);
1362 9486 : global_block->setScalarParam<T>(short_name) = param->get();
1363 : }
1364 1710510 : }
1365 :
1366 : template <typename T, typename UP_T, typename Base>
1367 : void
1368 420957 : Builder::setScalarValueTypeParameter(const std::string & full_name,
1369 : const std::string & short_name,
1370 : InputParameters::Parameter<T> * param,
1371 : bool in_global,
1372 : GlobalParamsAction * global_block,
1373 : const hit::Node & node)
1374 : {
1375 420957 : setScalarParameter<T, Base>(full_name, short_name, param, in_global, global_block);
1376 :
1377 : // If this is a range checked param, we need to make sure that the value falls within the
1378 : // requested range
1379 : mooseAssert(_current_params, "Current params is nullptr");
1380 :
1381 420957 : const auto error = _current_params->rangeCheck<T, UP_T>(full_name, short_name, param);
1382 420957 : if (error)
1383 12 : _errors.emplace_back(error->second, &node);
1384 420957 : }
1385 :
1386 : template <typename T, typename Base>
1387 : void
1388 354181 : Builder::setVectorParameter(const std::string & full_name,
1389 : const std::string & short_name,
1390 : InputParameters::Parameter<std::vector<T>> * param,
1391 : bool in_global,
1392 : GlobalParamsAction * global_block)
1393 : {
1394 354181 : std::vector<T> vec;
1395 354181 : if (const auto node = _root.find(full_name))
1396 : {
1397 : try
1398 : {
1399 708362 : auto tmp = node->param<std::vector<Base>>();
1400 896499 : for (auto val : tmp)
1401 542318 : vec.push_back(val);
1402 354181 : }
1403 0 : catch (hit::Error & err)
1404 : {
1405 0 : Parser::appendErrorMessages(_errors, err);
1406 0 : return;
1407 : }
1408 : }
1409 :
1410 354181 : param->set() = vec;
1411 :
1412 354181 : if (in_global)
1413 : {
1414 4421 : global_block->remove(short_name);
1415 4421 : global_block->setVectorParam<T>(short_name).resize(param->get().size());
1416 9858 : for (unsigned int i = 0; i < vec.size(); ++i)
1417 5437 : global_block->setVectorParam<T>(short_name)[i] = param->get()[i];
1418 : }
1419 354181 : }
1420 :
1421 : template <typename KeyType, typename MappedType>
1422 : void
1423 490 : Builder::setMapParameter(const std::string & full_name,
1424 : const std::string & short_name,
1425 : InputParameters::Parameter<std::map<KeyType, MappedType>> * param,
1426 : bool in_global,
1427 : GlobalParamsAction * global_block)
1428 : {
1429 490 : std::map<KeyType, MappedType> the_map;
1430 :
1431 490 : if (const auto node = _root.find(full_name))
1432 : {
1433 : try
1434 : {
1435 980 : const auto & string_vec = node->param<std::vector<std::string>>();
1436 490 : auto it = string_vec.begin();
1437 2510 : while (it != string_vec.end())
1438 : {
1439 1079 : const auto & string_key = *it;
1440 1079 : ++it;
1441 1079 : if (it == string_vec.end())
1442 : {
1443 4 : _errors.emplace_back(
1444 : "odd number of entries in string vector for map parameter '" + full_name +
1445 : "'; there must be " +
1446 : "an even number or else you will end up with a key without a value",
1447 : node);
1448 8 : return;
1449 : }
1450 1075 : const auto & string_value = *it;
1451 1075 : ++it;
1452 :
1453 1075 : std::pair<KeyType, MappedType> pr;
1454 : // key
1455 : try
1456 : {
1457 1075 : pr.first = MooseUtils::convert<KeyType>(string_key, true);
1458 : }
1459 0 : catch (std::invalid_argument & /*e*/)
1460 : {
1461 0 : _errors.emplace_back("invalid " + MooseUtils::prettyCppType<KeyType>() +
1462 : " syntax for map parameter '" + full_name +
1463 : "' key: " + string_key,
1464 : node);
1465 0 : return;
1466 : }
1467 : // value
1468 : try
1469 : {
1470 1075 : pr.second = MooseUtils::convert<MappedType>(string_value, true);
1471 : }
1472 4 : catch (std::invalid_argument & /*e*/)
1473 : {
1474 4 : _errors.emplace_back("invalid " + MooseUtils::prettyCppType<MappedType>() +
1475 : " syntax for map parameter '" + full_name +
1476 : "' value: " + string_value,
1477 : node);
1478 4 : return;
1479 : }
1480 :
1481 1071 : auto insert_pr = the_map.insert(std::move(pr));
1482 1071 : if (!insert_pr.second)
1483 : {
1484 0 : _errors.emplace_back("Duplicate map entry for map parameter: '" + full_name + "'; key '" +
1485 : string_key + "' appears multiple times",
1486 : node);
1487 0 : return;
1488 : }
1489 : }
1490 490 : }
1491 0 : catch (hit::Error & err)
1492 : {
1493 0 : Parser::appendErrorMessages(_errors, err);
1494 0 : return;
1495 : }
1496 : }
1497 :
1498 482 : param->set() = the_map;
1499 :
1500 482 : if (in_global)
1501 : {
1502 0 : global_block->remove(short_name);
1503 0 : auto & global_map = global_block->setParam<std::map<KeyType, MappedType>>(short_name);
1504 0 : for (const auto & pair : the_map)
1505 0 : global_map.insert(pair);
1506 : }
1507 490 : }
1508 :
1509 : template <typename T>
1510 : void
1511 5517 : Builder::setDoubleIndexParameter(const std::string & full_name,
1512 : const std::string & short_name,
1513 : InputParameters::Parameter<std::vector<std::vector<T>>> * param,
1514 : bool in_global,
1515 : GlobalParamsAction * global_block)
1516 : {
1517 5517 : auto & value = param->set();
1518 :
1519 : // Get the full string assigned to the variable full_name
1520 5517 : const auto node = _root.find(full_name, true);
1521 16551 : const auto value_string = MooseUtils::trim(node->param<std::string>());
1522 :
1523 : // split vector at delim ;
1524 : // NOTE: the substrings are _not_ of type T yet
1525 : // The zero length here is intentional, as we want something like:
1526 : // "abc; 123;" -> ["abc", "123", ""]
1527 5517 : std::vector<std::string> outer_string_vectors;
1528 : // With split, we will get a single entry if the string value is empty. However,
1529 : // that should represent an empty vector<vector>. Therefore, only split if we have values.
1530 5517 : if (!value_string.empty())
1531 16467 : outer_string_vectors = MooseUtils::split(value_string, ";");
1532 :
1533 5517 : const auto outer_vector_size = outer_string_vectors.size();
1534 5517 : value.resize(outer_vector_size);
1535 :
1536 15395 : for (const auto j : index_range(outer_string_vectors))
1537 19756 : if (!MooseUtils::tokenizeAndConvert<T>(outer_string_vectors[j], value[j]))
1538 : {
1539 0 : _errors.emplace_back("invalid format for parameter " + full_name, node);
1540 0 : return;
1541 : }
1542 :
1543 5517 : if (in_global)
1544 : {
1545 0 : global_block->remove(short_name);
1546 0 : global_block->setDoubleIndexParam<T>(short_name).resize(outer_vector_size);
1547 0 : for (const auto j : make_range(outer_vector_size))
1548 : {
1549 0 : global_block->setDoubleIndexParam<T>(short_name)[j].resize(value[j].size());
1550 0 : for (const auto i : index_range(value[j]))
1551 0 : global_block->setDoubleIndexParam<T>(short_name)[j][i] = value[j][i];
1552 : }
1553 : }
1554 5517 : }
1555 :
1556 : template <typename T>
1557 : void
1558 633 : Builder::setTripleIndexParameter(
1559 : const std::string & full_name,
1560 : const std::string & short_name,
1561 : InputParameters::Parameter<std::vector<std::vector<std::vector<T>>>> * param,
1562 : bool in_global,
1563 : GlobalParamsAction * global_block)
1564 : {
1565 : // Get the full string assigned to the variable full_name
1566 633 : auto node = _root.find(full_name, true);
1567 1266 : const std::string buffer_raw = node->param<std::string>();
1568 : // In case the parameter is empty
1569 633 : if (buffer_raw.find_first_not_of(' ', 0) == std::string::npos)
1570 0 : return;
1571 :
1572 : // Add a space between neighboring delim's, before the first delim if nothing is ahead of it, and
1573 : // after the last delim if nothing is behind it.
1574 633 : std::string buffer;
1575 633 : buffer.push_back(buffer_raw[0]);
1576 633 : if (buffer[0] == '|' || buffer[0] == ';')
1577 39 : buffer = ' ' + buffer;
1578 78565 : for (std::string::size_type i = 1; i < buffer_raw.size(); i++)
1579 : {
1580 80784 : if ((buffer_raw[i - 1] == '|' || buffer_raw[i - 1] == ';') &&
1581 2852 : (buffer_raw[i] == '|' || buffer_raw[i] == ';'))
1582 91 : buffer.push_back(' ');
1583 77932 : buffer.push_back(buffer_raw[i]);
1584 : }
1585 633 : if (buffer.back() == '|' || buffer.back() == ';')
1586 17 : buffer.push_back(' ');
1587 :
1588 : // split vector at delim | to get a series of 2D subvectors
1589 633 : std::vector<std::string> first_tokenized_vector;
1590 633 : std::vector<std::vector<std::string>> second_tokenized_vector;
1591 633 : MooseUtils::tokenize(buffer, first_tokenized_vector, 1, "|");
1592 633 : param->set().resize(first_tokenized_vector.size());
1593 633 : second_tokenized_vector.resize(first_tokenized_vector.size());
1594 2101 : for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1595 : {
1596 : // Identify empty subvector first
1597 1468 : if (first_tokenized_vector[j].find_first_not_of(' ', 0) == std::string::npos)
1598 : {
1599 82 : param->set()[j].resize(0);
1600 82 : continue;
1601 : }
1602 : // split each 2D subvector at delim ; to get 1D sub-subvectors
1603 : // NOTE: the 1D sub-subvectors are _not_ of type T yet
1604 1386 : MooseUtils::tokenize(first_tokenized_vector[j], second_tokenized_vector[j], 1, ";");
1605 1386 : param->set()[j].resize(second_tokenized_vector[j].size());
1606 4806 : for (unsigned k = 0; k < second_tokenized_vector[j].size(); ++k)
1607 6840 : if (!MooseUtils::tokenizeAndConvert<T>(second_tokenized_vector[j][k], param->set()[j][k]))
1608 : {
1609 0 : _errors.emplace_back("invalid format for '" + full_name + "'", node);
1610 0 : return;
1611 : }
1612 : }
1613 :
1614 633 : if (in_global)
1615 : {
1616 13 : global_block->remove(short_name);
1617 13 : global_block->setTripleIndexParam<T>(short_name).resize(first_tokenized_vector.size());
1618 52 : for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1619 : {
1620 39 : global_block->setTripleIndexParam<T>(short_name)[j].resize(second_tokenized_vector[j].size());
1621 130 : for (unsigned k = 0; k < second_tokenized_vector[j].size(); ++k)
1622 : {
1623 91 : global_block->setTripleIndexParam<T>(short_name)[j][k].resize(param->get()[j][k].size());
1624 273 : for (unsigned int i = 0; i < param->get()[j][k].size(); ++i)
1625 182 : global_block->setTripleIndexParam<T>(short_name)[j][k][i] = param->get()[j][k][i];
1626 : }
1627 : }
1628 : }
1629 633 : }
1630 :
1631 : template <typename T>
1632 : void
1633 29220 : Builder::setScalarComponentParameter(const std::string & full_name,
1634 : const std::string & short_name,
1635 : InputParameters::Parameter<T> * param,
1636 : bool in_global,
1637 : GlobalParamsAction * global_block)
1638 : {
1639 29220 : auto node = _root.find(full_name, true);
1640 29220 : std::vector<double> vec;
1641 : try
1642 : {
1643 58440 : vec = node->param<std::vector<double>>();
1644 : }
1645 0 : catch (hit::Error & err)
1646 : {
1647 0 : Parser::appendErrorMessages(_errors, err);
1648 0 : return;
1649 : }
1650 :
1651 29220 : if (vec.size() != LIBMESH_DIM)
1652 : {
1653 0 : _errors.emplace_back("wrong number of values in scalar component parameter '" + full_name +
1654 : "': " + short_name + " was given " + std::to_string(vec.size()) +
1655 : " components but should have " + std::to_string(LIBMESH_DIM),
1656 : node);
1657 0 : return;
1658 : }
1659 :
1660 29220 : T value;
1661 116880 : for (unsigned int i = 0; i < vec.size(); ++i)
1662 87660 : value(i) = Real(vec[i]);
1663 :
1664 29220 : param->set() = value;
1665 29220 : if (in_global)
1666 : {
1667 0 : global_block->remove(short_name);
1668 0 : global_block->setScalarParam<T>(short_name) = value;
1669 : }
1670 29220 : }
1671 :
1672 : template <typename T>
1673 : void
1674 8759 : Builder::setVectorComponentParameter(const std::string & full_name,
1675 : const std::string & short_name,
1676 : InputParameters::Parameter<std::vector<T>> * param,
1677 : bool in_global,
1678 : GlobalParamsAction * global_block)
1679 : {
1680 8759 : auto node = _root.find(full_name, true);
1681 8759 : std::vector<double> vec;
1682 : try
1683 : {
1684 17518 : vec = node->param<std::vector<double>>();
1685 : }
1686 0 : catch (hit::Error & err)
1687 : {
1688 0 : Parser::appendErrorMessages(_errors, err);
1689 0 : return;
1690 : }
1691 :
1692 8759 : if (vec.size() % LIBMESH_DIM)
1693 : {
1694 4 : _errors.emplace_back("wrong number of values in vector component parameter '" + full_name +
1695 : "': size " + std::to_string(vec.size()) + " is not a multiple of " +
1696 : std::to_string(LIBMESH_DIM),
1697 : node);
1698 4 : return;
1699 : }
1700 :
1701 8755 : std::vector<T> values;
1702 30611 : for (unsigned int i = 0; i < vec.size() / LIBMESH_DIM; ++i)
1703 : {
1704 21856 : T value;
1705 87424 : for (int j = 0; j < LIBMESH_DIM; ++j)
1706 65568 : value(j) = Real(vec[i * LIBMESH_DIM + j]);
1707 21856 : values.push_back(value);
1708 : }
1709 :
1710 8755 : param->set() = values;
1711 :
1712 8755 : if (in_global)
1713 : {
1714 0 : global_block->remove(short_name);
1715 0 : global_block->setVectorParam<T>(short_name).resize(vec.size(), values[0]);
1716 0 : for (unsigned int i = 0; i < vec.size() / LIBMESH_DIM; ++i)
1717 0 : global_block->setVectorParam<T>(short_name)[i] = values[0];
1718 : }
1719 8759 : }
1720 :
1721 : template <typename T>
1722 : void
1723 115 : Builder::setVectorVectorComponentParameter(
1724 : const std::string & full_name,
1725 : const std::string & short_name,
1726 : InputParameters::Parameter<std::vector<std::vector<T>>> * param,
1727 : bool in_global,
1728 : GlobalParamsAction * global_block)
1729 : {
1730 : // Get the full string assigned to the variable full_name
1731 115 : auto node = _root.find(full_name, true);
1732 230 : std::string buffer = node->param<std::string>();
1733 :
1734 : // split vector at delim ;
1735 : // NOTE: the substrings are _not_ of type T yet
1736 115 : std::vector<std::string> first_tokenized_vector;
1737 115 : MooseUtils::tokenize(buffer, first_tokenized_vector, 1, ";");
1738 115 : param->set().resize(first_tokenized_vector.size());
1739 :
1740 : // get a vector<vector<double>> first
1741 115 : std::vector<std::vector<double>> vecvec(first_tokenized_vector.size());
1742 345 : for (unsigned j = 0; j < vecvec.size(); ++j)
1743 460 : if (!MooseUtils::tokenizeAndConvert<double>(first_tokenized_vector[j], vecvec[j]))
1744 : {
1745 0 : _errors.emplace_back("invalid format for parameter " + full_name, node);
1746 0 : return;
1747 : }
1748 :
1749 345 : for (const auto & vec : vecvec)
1750 230 : if (vec.size() % LIBMESH_DIM)
1751 : {
1752 0 : _errors.emplace_back("wrong number of values in double-indexed vector component parameter '" +
1753 : full_name + "': size of subcomponent " + std::to_string(vec.size()) +
1754 : " is not a multiple of " + std::to_string(LIBMESH_DIM),
1755 : node);
1756 0 : return;
1757 : }
1758 :
1759 : // convert vector<vector<double>> to vector<vector<T>>
1760 115 : std::vector<std::vector<T>> values(vecvec.size());
1761 345 : for (unsigned int id_vec = 0; id_vec < vecvec.size(); ++id_vec)
1762 805 : for (unsigned int i = 0; i < vecvec[id_vec].size() / LIBMESH_DIM; ++i)
1763 : {
1764 575 : T value;
1765 2300 : for (int j = 0; j < LIBMESH_DIM; ++j)
1766 1725 : value(j) = Real(vecvec[id_vec][i * LIBMESH_DIM + j]);
1767 575 : values[id_vec].push_back(value);
1768 : }
1769 :
1770 115 : param->set() = values;
1771 :
1772 115 : if (in_global)
1773 : {
1774 115 : global_block->remove(short_name);
1775 115 : global_block->setDoubleIndexParam<T>(short_name).resize(vecvec.size());
1776 345 : for (unsigned j = 0; j < vecvec.size(); ++j)
1777 : {
1778 230 : global_block->setDoubleIndexParam<T>(short_name)[j].resize(param->get()[j].size() /
1779 : LIBMESH_DIM);
1780 345 : for (unsigned int i = 0; i < param->get()[j].size() / LIBMESH_DIM; ++i)
1781 115 : global_block->setDoubleIndexParam<T>(short_name)[j][i] = values[j][i];
1782 : }
1783 : }
1784 115 : }
1785 :
1786 : template <>
1787 : void
1788 21176 : Builder::setScalarParameter<RealVectorValue, RealVectorValue>(
1789 : const std::string & full_name,
1790 : const std::string & short_name,
1791 : InputParameters::Parameter<RealVectorValue> * param,
1792 : bool in_global,
1793 : GlobalParamsAction * global_block)
1794 : {
1795 21176 : setScalarComponentParameter(full_name, short_name, param, in_global, global_block);
1796 21176 : }
1797 :
1798 : template <>
1799 : void
1800 8044 : Builder::setScalarParameter<Point, Point>(const std::string & full_name,
1801 : const std::string & short_name,
1802 : InputParameters::Parameter<Point> * param,
1803 : bool in_global,
1804 : GlobalParamsAction * global_block)
1805 : {
1806 8044 : setScalarComponentParameter(full_name, short_name, param, in_global, global_block);
1807 8044 : }
1808 :
1809 : template <>
1810 : void
1811 1982 : Builder::setScalarParameter<RealEigenVector, RealEigenVector>(
1812 : const std::string & full_name,
1813 : const std::string & short_name,
1814 : InputParameters::Parameter<RealEigenVector> * param,
1815 : bool in_global,
1816 : GlobalParamsAction * global_block)
1817 : {
1818 1982 : std::vector<double> vec;
1819 : try
1820 : {
1821 1982 : vec = _root.param<std::vector<double>>(full_name);
1822 : }
1823 0 : catch (hit::Error & err)
1824 : {
1825 0 : Parser::appendErrorMessages(_errors, err);
1826 0 : return;
1827 0 : }
1828 :
1829 1982 : RealEigenVector value(vec.size());
1830 6414 : for (unsigned int i = 0; i < vec.size(); ++i)
1831 4432 : value(i) = Real(vec[i]);
1832 :
1833 1982 : param->set() = value;
1834 1982 : if (in_global)
1835 : {
1836 0 : global_block->remove(short_name);
1837 0 : global_block->setScalarParam<RealEigenVector>(short_name) = value;
1838 : }
1839 1982 : }
1840 :
1841 : template <>
1842 : void
1843 186 : Builder::setScalarParameter<RealEigenMatrix, RealEigenMatrix>(
1844 : const std::string & full_name,
1845 : const std::string & short_name,
1846 : InputParameters::Parameter<RealEigenMatrix> * param,
1847 : bool in_global,
1848 : GlobalParamsAction * global_block)
1849 : {
1850 : // Get the full string assigned to the variable full_name
1851 186 : auto node = _root.find(full_name, true);
1852 372 : std::string buffer = node->param<std::string>();
1853 :
1854 : // split vector at delim ;
1855 : // NOTE: the substrings are _not_ of type T yet
1856 186 : std::vector<std::string> first_tokenized_vector;
1857 372 : MooseUtils::tokenize(buffer, first_tokenized_vector, 1, ";");
1858 :
1859 186 : std::vector<std::vector<Real>> values(first_tokenized_vector.size());
1860 :
1861 547 : for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1862 : {
1863 1258 : if (!MooseUtils::tokenizeAndConvert<Real>(first_tokenized_vector[j], values[j]) ||
1864 175 : (j != 0 && values[j].size() != values[0].size()))
1865 : {
1866 0 : _errors.emplace_back("invalid format for parameter " + full_name, node);
1867 0 : return;
1868 : }
1869 : }
1870 :
1871 186 : RealEigenMatrix value(values.size(), values[0].size());
1872 547 : for (unsigned int i = 0; i < values.size(); ++i)
1873 1101 : for (unsigned int j = 0; j < values[i].size(); ++j)
1874 740 : value(i, j) = values[i][j];
1875 :
1876 186 : param->set() = value;
1877 186 : if (in_global)
1878 : {
1879 0 : global_block->remove(short_name);
1880 0 : global_block->setScalarParam<RealEigenMatrix>(short_name) = value;
1881 : }
1882 186 : }
1883 :
1884 : template <>
1885 : void
1886 437318 : Builder::setScalarParameter<MooseEnum, MooseEnum>(const std::string & full_name,
1887 : const std::string & short_name,
1888 : InputParameters::Parameter<MooseEnum> * param,
1889 : bool in_global,
1890 : GlobalParamsAction * global_block)
1891 : {
1892 437318 : MooseEnum current_param = param->get();
1893 :
1894 437318 : std::string value = _root.param<std::string>(full_name);
1895 :
1896 437318 : param->set() = value;
1897 437306 : if (in_global)
1898 : {
1899 47894 : global_block->remove(short_name);
1900 47894 : global_block->setScalarParam<MooseEnum>(short_name) = current_param;
1901 : }
1902 437306 : }
1903 :
1904 : template <>
1905 : void
1906 34072 : Builder::setScalarParameter<MultiMooseEnum, MultiMooseEnum>(
1907 : const std::string & full_name,
1908 : const std::string & short_name,
1909 : InputParameters::Parameter<MultiMooseEnum> * param,
1910 : bool in_global,
1911 : GlobalParamsAction * global_block)
1912 : {
1913 34072 : MultiMooseEnum current_param = param->get();
1914 :
1915 34072 : auto vec = _root.param<std::vector<std::string>>(full_name);
1916 :
1917 34072 : std::string raw_values;
1918 99197 : for (unsigned int i = 0; i < vec.size(); ++i)
1919 65125 : raw_values += ' ' + vec[i];
1920 :
1921 34072 : param->set() = raw_values;
1922 :
1923 34072 : if (in_global)
1924 : {
1925 0 : global_block->remove(short_name);
1926 0 : global_block->setScalarParam<MultiMooseEnum>(short_name) = current_param;
1927 : }
1928 34072 : }
1929 :
1930 : template <>
1931 : void
1932 59388 : Builder::setScalarParameter<ExecFlagEnum, ExecFlagEnum>(
1933 : const std::string & full_name,
1934 : const std::string & short_name,
1935 : InputParameters::Parameter<ExecFlagEnum> * param,
1936 : bool in_global,
1937 : GlobalParamsAction * global_block)
1938 : {
1939 59388 : ExecFlagEnum current_param = param->get();
1940 59388 : auto vec = _root.param<std::vector<std::string>>(full_name);
1941 :
1942 59388 : std::string raw_values;
1943 137876 : for (unsigned int i = 0; i < vec.size(); ++i)
1944 78488 : raw_values += ' ' + vec[i];
1945 :
1946 59388 : param->set() = raw_values;
1947 :
1948 59388 : if (in_global)
1949 : {
1950 110 : global_block->remove(short_name);
1951 110 : global_block->setScalarParam<ExecFlagEnum>(short_name) = current_param;
1952 : }
1953 59388 : }
1954 :
1955 : template <>
1956 : void
1957 39 : Builder::setScalarParameter<RealTensorValue, RealTensorValue>(
1958 : const std::string & full_name,
1959 : const std::string & short_name,
1960 : InputParameters::Parameter<RealTensorValue> * param,
1961 : bool in_global,
1962 : GlobalParamsAction * global_block)
1963 : {
1964 39 : auto node = _root.find(full_name, true);
1965 78 : auto vec = node->param<std::vector<double>>();
1966 39 : if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
1967 : {
1968 0 : _errors.emplace_back("invalid RealTensorValue parameter '" + full_name + "': size is " +
1969 0 : std::to_string(vec.size()) + " but should be " +
1970 0 : std::to_string(LIBMESH_DIM * LIBMESH_DIM),
1971 : node);
1972 0 : return;
1973 : }
1974 :
1975 39 : RealTensorValue value;
1976 156 : for (int i = 0; i < LIBMESH_DIM; ++i)
1977 468 : for (int j = 0; j < LIBMESH_DIM; ++j)
1978 351 : value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
1979 :
1980 39 : param->set() = value;
1981 39 : if (in_global)
1982 : {
1983 0 : global_block->remove(short_name);
1984 0 : global_block->setScalarParam<RealTensorValue>(short_name) = value;
1985 : }
1986 39 : }
1987 :
1988 : // Specialization for coupling a Real value where a postprocessor would be needed in MOOSE
1989 : template <>
1990 : void
1991 8230 : Builder::setScalarParameter<PostprocessorName, PostprocessorName>(
1992 : const std::string & full_name,
1993 : const std::string & short_name,
1994 : InputParameters::Parameter<PostprocessorName> * param,
1995 : bool in_global,
1996 : GlobalParamsAction * global_block)
1997 : {
1998 8230 : PostprocessorName pps_name = _root.param<std::string>(full_name);
1999 8230 : param->set() = pps_name;
2000 :
2001 8230 : if (in_global)
2002 : {
2003 0 : global_block->remove(short_name);
2004 0 : global_block->setScalarParam<PostprocessorName>(short_name) = pps_name;
2005 : }
2006 8230 : }
2007 :
2008 : template <>
2009 : void
2010 937 : Builder::setScalarParameter<ReporterName, std::string>(
2011 : const std::string & full_name,
2012 : const std::string & /*short_name*/,
2013 : InputParameters::Parameter<ReporterName> * param,
2014 : bool /*in_global*/,
2015 : GlobalParamsAction * /*global_block*/)
2016 : {
2017 937 : auto node = _root.find(full_name, true);
2018 2811 : std::vector<std::string> names = MooseUtils::rsplit(node->param<std::string>(), "/", 2);
2019 937 : if (names.size() != 2)
2020 4 : _errors.emplace_back(
2021 8 : "The supplied name ReporterName '" + full_name + "' must contain the '/' delimiter.", node);
2022 : else
2023 933 : param->set() = ReporterName(names[0], names[1]);
2024 937 : }
2025 :
2026 : template <>
2027 : void
2028 59 : Builder::setVectorParameter<RealVectorValue, RealVectorValue>(
2029 : const std::string & full_name,
2030 : const std::string & short_name,
2031 : InputParameters::Parameter<std::vector<RealVectorValue>> * param,
2032 : bool in_global,
2033 : GlobalParamsAction * global_block)
2034 : {
2035 59 : setVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2036 59 : }
2037 :
2038 : template <>
2039 : void
2040 8700 : Builder::setVectorParameter<Point, Point>(const std::string & full_name,
2041 : const std::string & short_name,
2042 : InputParameters::Parameter<std::vector<Point>> * param,
2043 : bool in_global,
2044 : GlobalParamsAction * global_block)
2045 : {
2046 8700 : setVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2047 8700 : }
2048 :
2049 : template <>
2050 : void
2051 267 : Builder::setVectorParameter<MooseEnum, MooseEnum>(
2052 : const std::string & full_name,
2053 : const std::string & short_name,
2054 : InputParameters::Parameter<std::vector<MooseEnum>> * param,
2055 : bool in_global,
2056 : GlobalParamsAction * global_block)
2057 : {
2058 267 : std::vector<MooseEnum> enum_values = param->get();
2059 267 : std::vector<std::string> values(enum_values.size());
2060 534 : for (unsigned int i = 0; i < values.size(); ++i)
2061 267 : values[i] = static_cast<std::string>(enum_values[i]);
2062 :
2063 : /**
2064 : * With MOOSE Enums we need a default object so it should have been passed in the param pointer.
2065 : * We are only going to use the first item in the vector (values[0]) and ignore the rest.
2066 : */
2067 267 : std::vector<std::string> vec;
2068 267 : if (auto node = _root.find(full_name, true))
2069 : {
2070 534 : vec = node->param<std::vector<std::string>>();
2071 267 : param->set().resize(vec.size(), enum_values[0]);
2072 : }
2073 :
2074 732 : for (unsigned int i = 0; i < vec.size(); ++i)
2075 469 : param->set()[i] = vec[i];
2076 :
2077 263 : if (in_global)
2078 : {
2079 0 : global_block->remove(short_name);
2080 0 : global_block->setVectorParam<MooseEnum>(short_name).resize(vec.size(), enum_values[0]);
2081 0 : for (unsigned int i = 0; i < vec.size(); ++i)
2082 0 : global_block->setVectorParam<MooseEnum>(short_name)[i] = values[0];
2083 : }
2084 263 : }
2085 :
2086 : template <>
2087 : void
2088 18 : Builder::setVectorParameter<MultiMooseEnum, MultiMooseEnum>(
2089 : const std::string & full_name,
2090 : const std::string & short_name,
2091 : InputParameters::Parameter<std::vector<MultiMooseEnum>> * param,
2092 : bool in_global,
2093 : GlobalParamsAction * global_block)
2094 : {
2095 18 : const auto node = _root.find(full_name, true);
2096 18 : const std::vector<MultiMooseEnum> & enum_values = param->get();
2097 :
2098 : // Get the full string assigned to the variable full_name
2099 36 : std::string buffer = node->param<std::string>();
2100 :
2101 18 : bool has_empty = false;
2102 36 : const auto first_tokenized_vector = MooseUtils::split(buffer, ";");
2103 98 : for (const auto i : index_range(first_tokenized_vector))
2104 : {
2105 80 : const auto & entry = first_tokenized_vector[i];
2106 160 : if (MooseUtils::trim(entry) == "")
2107 : {
2108 4 : has_empty = true;
2109 4 : _errors.emplace_back("entry " + std::to_string(i) + " in '" + node->fullpath() + "' is empty",
2110 : node);
2111 : }
2112 : }
2113 :
2114 18 : if (has_empty)
2115 4 : return;
2116 :
2117 14 : param->set().resize(first_tokenized_vector.size(), enum_values[0]);
2118 :
2119 14 : std::vector<std::vector<std::string>> vecvec(first_tokenized_vector.size());
2120 74 : for (const auto i : index_range(vecvec))
2121 : {
2122 64 : MooseUtils::tokenize<std::string>(first_tokenized_vector[i], vecvec[i], 1, " ");
2123 64 : param->set()[i] = vecvec[i];
2124 : }
2125 :
2126 10 : if (in_global)
2127 : {
2128 0 : global_block->remove(short_name);
2129 0 : global_block->setVectorParam<MultiMooseEnum>(short_name).resize(vecvec.size(), enum_values[0]);
2130 0 : for (unsigned int i = 0; i < vecvec.size(); ++i)
2131 0 : global_block->setVectorParam<MultiMooseEnum>(short_name)[i] = vecvec[i];
2132 : }
2133 18 : }
2134 :
2135 : template <>
2136 : void
2137 2398 : Builder::setVectorParameter<PostprocessorName, PostprocessorName>(
2138 : const std::string & full_name,
2139 : const std::string & short_name,
2140 : InputParameters::Parameter<std::vector<PostprocessorName>> * param,
2141 : bool in_global,
2142 : GlobalParamsAction * global_block)
2143 : {
2144 2398 : std::vector<std::string> pps_names = _root.param<std::vector<std::string>>(full_name);
2145 2398 : unsigned int n = pps_names.size();
2146 2398 : param->set().resize(n);
2147 :
2148 5990 : for (unsigned int j = 0; j < n; ++j)
2149 3592 : param->set()[j] = pps_names[j];
2150 :
2151 2398 : if (in_global)
2152 : {
2153 0 : global_block->remove(short_name);
2154 0 : global_block->setVectorParam<PostprocessorName>(short_name).resize(n, "");
2155 0 : for (unsigned int j = 0; j < n; ++j)
2156 0 : global_block->setVectorParam<PostprocessorName>(short_name)[j] = pps_names[j];
2157 : }
2158 2398 : }
2159 :
2160 : /**
2161 : * Specialization for coupling vectors. This routine handles default values and auto generated
2162 : * VariableValue vectors.
2163 : */
2164 : template <>
2165 : void
2166 78079 : Builder::setVectorParameter<VariableName, VariableName>(
2167 : const std::string & full_name,
2168 : const std::string & short_name,
2169 : InputParameters::Parameter<std::vector<VariableName>> * param,
2170 : bool /*in_global*/,
2171 : GlobalParamsAction * /*global_block*/)
2172 : {
2173 78079 : auto node = _root.find(full_name, true);
2174 156158 : auto vec = node->param<std::vector<std::string>>();
2175 234237 : auto strval = node->param<std::string>();
2176 78079 : std::vector<VariableName> var_names(vec.size());
2177 :
2178 78079 : bool has_var_names = false;
2179 165997 : for (unsigned int i = 0; i < vec.size(); ++i)
2180 : {
2181 87918 : VariableName var_name = vec[i];
2182 :
2183 : Real real_value;
2184 87918 : std::istringstream ss(var_name);
2185 :
2186 : // If we are able to convert this value into a Real, then set a default coupled value
2187 : // NOTE: parameter must be either all default or no defaults
2188 87918 : if (ss >> real_value && ss.eof())
2189 998 : _current_params->defaultCoupledValue(short_name, real_value, i);
2190 : else
2191 : {
2192 86920 : var_names[i] = var_name;
2193 86920 : has_var_names = true;
2194 : }
2195 87918 : }
2196 :
2197 78079 : if (has_var_names)
2198 : {
2199 77614 : param->set().resize(vec.size());
2200 :
2201 164538 : for (unsigned int i = 0; i < vec.size(); ++i)
2202 86924 : if (var_names[i] == "")
2203 4 : _errors.emplace_back("invalid value for '" + full_name +
2204 : "': coupled vectors where some parameters are reals and others "
2205 : "are variables are not supported",
2206 : node);
2207 : else
2208 86920 : param->set()[i] = var_names[i];
2209 : }
2210 78079 : }
2211 :
2212 : template <>
2213 : void
2214 1174 : Builder::setVectorParameter<ReporterName, std::string>(
2215 : const std::string & full_name,
2216 : const std::string & /*short_name*/,
2217 : InputParameters::Parameter<std::vector<ReporterName>> * param,
2218 : bool /*in_global*/,
2219 : GlobalParamsAction * /*global_block*/)
2220 : {
2221 1174 : auto node = _root.find(full_name, true);
2222 2348 : auto rnames = node->param<std::vector<std::string>>();
2223 1174 : param->set().resize(rnames.size());
2224 :
2225 3346 : for (unsigned int i = 0; i < rnames.size(); ++i)
2226 : {
2227 2172 : std::vector<std::string> names = MooseUtils::rsplit(rnames[i], "/", 2);
2228 2172 : if (names.size() != 2)
2229 0 : _errors.emplace_back("the supplied name ReporterName '" + rnames[i] +
2230 : "' must contain the '/' delimiter",
2231 : node);
2232 : else
2233 2172 : param->set()[i] = ReporterName(names[0], names[1]);
2234 2172 : }
2235 1174 : }
2236 :
2237 : template <>
2238 : void
2239 1877 : Builder::setVectorParameter<CLIArgString, std::string>(
2240 : const std::string & full_name,
2241 : const std::string & /*short_name*/,
2242 : InputParameters::Parameter<std::vector<CLIArgString>> * param,
2243 : bool /*in_global*/,
2244 : GlobalParamsAction * /*global_block*/)
2245 : {
2246 : // Parsed as a vector of string, the vectors parameters are being cut
2247 1877 : auto rnames = _root.param<std::vector<std::string>>(full_name);
2248 1877 : param->set().resize(rnames.size()); // slightly oversized if vectors have been split
2249 :
2250 : // Skip empty parameter
2251 1877 : if (rnames.empty())
2252 4 : return;
2253 :
2254 : // Re-assemble vector parameters
2255 1873 : unsigned int i_param = 0;
2256 1873 : bool vector_param_detected = false;
2257 5212 : for (unsigned int i = 0; i < rnames.size(); ++i)
2258 : {
2259 : // Look for a quote, both types
2260 : std::vector<std::string> double_split =
2261 6678 : MooseUtils::rsplit(rnames[i], "\"", std::numeric_limits<std::size_t>::max());
2262 : std::vector<std::string> single_split =
2263 6678 : MooseUtils::rsplit(rnames[i], "\'", std::numeric_limits<std::size_t>::max());
2264 3339 : if (double_split.size() + single_split.size() >= 3)
2265 : // Either entering or exiting a vector parameter (>3 is entering another vector)
2266 : // Even and >2 number of quotes means both finished and started another vector parameter
2267 1607 : if ((double_split.size() + single_split.size()) % 2 == 1)
2268 234 : vector_param_detected = !vector_param_detected;
2269 :
2270 : // We're building a vector parameters, just append the text, rebuild the spaces
2271 3339 : if (vector_param_detected)
2272 390 : param->set()[i_param] += rnames[i] + ' ';
2273 : else
2274 : {
2275 2949 : param->set()[i_param] += rnames[i];
2276 2949 : i_param++;
2277 : }
2278 3339 : }
2279 : // Use actual size after re-forming vector parameters
2280 1873 : param->set().resize(i_param);
2281 1877 : }
2282 :
2283 : template <>
2284 : void
2285 115 : Builder::setDoubleIndexParameter<Point>(
2286 : const std::string & full_name,
2287 : const std::string & short_name,
2288 : InputParameters::Parameter<std::vector<std::vector<Point>>> * param,
2289 : bool in_global,
2290 : GlobalParamsAction * global_block)
2291 : {
2292 115 : setVectorVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2293 115 : }
2294 : } // end of namespace Moose
|