https://mooseframework.inl.gov
Builder.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 // MOOSE includes
11 #include "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"
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 isSectionActive(std::string path, hit::Node * root)
63 {
64  hit::Node * n = root->find(path);
65  while (n)
66  {
67  hit::Node * section = n->parent();
68  if (section)
69  {
70  auto actives = section->find("active");
71  auto inactives = section->find("inactive");
72 
73  // only check current level, not nested ones
74  if (actives && actives->type() == hit::NodeType::Field && actives->parent() == section)
75  {
76  auto vars = section->param<std::vector<std::string>>("active");
77  bool have_var = false;
78  for (auto & var : vars)
79  if (n->path() == hit::pathNorm(var))
80  have_var = true;
81  if (!have_var)
82  return false;
83  }
84  // only check current level, not nested ones
85  if (inactives && inactives->type() == hit::NodeType::Field && inactives->parent() == section)
86  {
87  auto vars = section->param<std::vector<std::string>>("inactive");
88  for (auto & var : vars)
89  if (n->path() == hit::pathNorm(var))
90  return false;
91  }
92  }
93  n = section;
94  }
95  return true;
96 }
97 
98 std::vector<std::string>
99 findSimilar(std::string param, std::vector<std::string> options)
100 {
101  std::vector<std::string> candidates;
102  if (options.size() == 0)
103  return candidates;
104 
105  int mindist = MooseUtils::levenshteinDist(options[0], param);
106  for (auto & opt : options)
107  {
108  int dist = MooseUtils::levenshteinDist(opt, param);
109  // magic number heuristics to get similarity distance cutoff
110  int dist_cutoff = 1 + param.size() / 5;
111  if (dist > dist_cutoff || dist > mindist)
112  continue;
113 
114  if (dist < mindist)
115  {
116  mindist = dist;
117  candidates.clear();
118  }
119  candidates.push_back(opt);
120  }
121  return candidates;
122 }
123 
124 Builder::Builder(MooseApp & app, ActionWarehouse & action_wh, Parser & parser)
125  : ConsoleStreamInterface(app),
126  _app(app),
127  _factory(app.getFactory()),
128  _action_wh(action_wh),
129  _action_factory(app.getActionFactory()),
130  _syntax(_action_wh.syntax()),
131  _parser(parser),
132  _root(_parser.getRoot()),
133  _syntax_formatter(nullptr),
134  _current_params(nullptr)
135 {
136 }
137 
139 
142 {
144 
149  params.addParam<std::vector<std::string>>(
150  "active",
151  std::vector<std::string>({"__all__"}),
152  "If specified only the blocks named will be visited and made active");
153  params.addParam<std::vector<std::string>>(
154  "inactive",
155  std::vector<std::string>(),
156  "If specified blocks matching these identifiers will be skipped.");
157 
158  return params;
159 }
160 
161 std::vector<std::string>
162 Builder::listValidParams(std::string & section_name)
163 {
164  bool dummy;
165  std::string registered_identifier = _syntax.isAssociated(section_name, &dummy);
166  auto iters = _syntax.getActions(registered_identifier);
167 
168  std::vector<std::string> paramlist;
169  for (auto it = iters.first; it != iters.second; ++it)
170  {
171  auto params = _action_factory.getValidParams(it->second._action);
172  for (const auto & it : params)
173  paramlist.push_back(it.first);
174  }
175  return paramlist;
176 }
177 
178 void
179 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  if (!_used.count(fullpath) && nodename != "active" && nodename != "inactive" &&
185  isSectionActive(fullpath, n->root()) && n->line() > 0)
186  {
187  auto section_name = fullpath.substr(0, fullpath.rfind("/"));
188  auto paramlist = _builder.listValidParams(section_name);
189  auto candidates = findSimilar(nodename, paramlist);
190  if (candidates.size() > 0)
191  errors.emplace_back(
192  "unused parameter '" + fullpath + "'; did you mean '" + candidates[0] + "'?", n);
193  else
194  errors.emplace_back("unused parameter '" + fullpath + "'", n);
195  }
196 }
197 
198 std::string
199 Builder::getPrimaryFileName(bool strip_leading_path) const
200 {
201  const auto path = _parser.getLastInputFilePath();
202  return (strip_leading_path ? path.filename() : std::filesystem::absolute(path)).string();
203 }
204 
205 void
206 Builder::walkRaw(std::string /*fullpath*/, std::string /*nodepath*/, hit::Node * n)
207 {
208  InputParameters active_list_params = Action::validParams();
210 
211  const std::string section_name = n->fullpath();
212  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  if (!isSectionActive(curr_identifier, &_root))
217  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  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  if (const auto [begin, end] = _syntax.getActions(registered_identifier); begin == end)
227  {
228  _errors.emplace_back(
229  "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  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  std::set<const Syntax::ActionInfo *> processed_actions;
239  while (true)
240  {
241  // search for an unprocessed action
242  auto [begin, end] = _syntax.getActions(registered_identifier);
243  auto it = begin;
244  for (; it != end && processed_actions.count(&it->second); ++it)
245  ;
246 
247  // no more unprocessed actions
248  if (it == end)
249  break;
250 
251  // mark action as processed
252  processed_actions.insert(&it->second);
253 
254  if (is_parent)
255  continue;
256  if (_syntax.isDeprecatedSyntax(registered_identifier))
258  hit::errormsg(n, _syntax.deprecatedActionSyntaxMessage(registered_identifier)));
259 
260  params = _action_factory.getValidParams(it->second._action);
261  params.set<ActionWarehouse *>("awh") = &_action_wh;
262  params.setHitNode(*n, {});
263 
264  extractParams(curr_identifier, params);
265 
266  // Add the parsed syntax to the parameters object for consumption by the Action
267  params.set<std::string>("task") = it->second._task;
268  params.set<std::string>("registered_identifier") = registered_identifier;
269 
270  if (!(params.have_parameter<bool>("isObjectAction") && params.get<bool>("isObjectAction")))
271  params.set<std::vector<std::string>>("control_tags")
272  .push_back(MooseUtils::baseName(curr_identifier));
273 
274  // Create the Action
275  std::shared_ptr<Action> action_obj =
276  _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 =
282  if (object_action)
283  {
284  auto & object_params = object_action->getObjectParams();
285  object_params.setHitNode(*n, {});
286  extractParams(curr_identifier, object_params);
287  object_params.set<std::vector<std::string>>("control_tags")
288  .push_back(MooseUtils::baseName(curr_identifier));
289  }
290  // extract the Component params if necessary
291  std::shared_ptr<AddActionComponentAction> component_action =
293  if (component_action)
294  {
295  auto & component_params = component_action->getComponentParams();
296  component_params.setHitNode(*n, {});
297  extractParams(curr_identifier, component_params);
298  component_params.set<std::vector<std::string>>("control_tags")
299  .push_back(MooseUtils::baseName(curr_identifier));
300  }
301  }
302 
303  // add it to the warehouse
304  _action_wh.addActionBlock(action_obj);
305  }
306 }
307 
308 void
309 Builder::walk(const std::string & fullpath, const std::string & nodepath, hit::Node * n)
310 {
311  // skip sections that were manually processed first.
312  for (auto & sec : _secs_need_first)
313  if (nodepath == sec)
314  return;
315  walkRaw(fullpath, nodepath, n);
316 }
317 
318 void
320 {
321  // Pull in extracted variables from the parser (fparse stuff)
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  auto syntax = _syntax.getSyntaxByAction("SetupDebugAction");
339  std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
340 
341  syntax = _syntax.getSyntaxByAction("GlobalParamsAction");
342  std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
343 
344  syntax = _syntax.getSyntaxByAction("DynamicObjectRegistrationAction");
345  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  for (auto & sec : _secs_need_first)
349  if (auto n = _root.find(sec))
350  walkRaw(n->parent()->fullpath(), n->path(), n);
351 
352  // Walk for the remainder
353  _root.walk(this, hit::NodeType::Section);
354 
355  // Warn for all deprecated parameters together
356  if (_deprecated_params.size())
357  {
358  std::vector<std::string> messages;
359  for (const auto & param_message_pair : _deprecated_params)
360  messages.push_back(param_message_pair.second);
361  const auto message = MooseUtils::stringJoin(messages, "\n\n");
362 
363  const auto current_show_trace = Moose::show_trace;
364  Moose::show_trace = false;
365  moose::internal::mooseDeprecatedStream(Moose::out, false, true, message + "\n\n");
366  Moose::show_trace = current_show_trace;
367  }
368 
369  if (_errors.size())
371 }
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 Builder::errorCheck(const Parallel::Communicator & comm, bool warn_unused, bool err_unused)
380 {
381  // Nothing to do here
382  if (!warn_unused && !err_unused)
383  return;
384 
385  std::vector<hit::ErrorMessage> messages;
386 
387  {
388  UnusedWalker uw(_extracted_vars, *this);
389  _parser.getCommandLineRoot().walk(&uw);
390  Parser::appendErrorMessages(messages, uw.errors);
391  }
392 
393  {
394  UnusedWalker uw(_extracted_vars, *this);
395  _root.walk(&uw);
396  Parser::appendErrorMessages(messages, uw.errors);
397  }
398 
399  for (const auto & arg : _app.commandLine()->unusedHitParams(comm))
400  messages.emplace_back("unused command line parameter '" + arg + "'");
401 
402  if (messages.size())
403  {
404  const auto message = _parser.joinErrorMessages(messages);
405  if (warn_unused)
406  mooseUnused(message);
407  if (err_unused)
408  {
409  if (_parser.getThrowOnError())
410  _parser.parseError(messages);
411  else
412  mooseError(
413  message +
414  "\n\nAppend --allow-unused (or -w) on the command line to ignore unused parameters.");
415  }
416  }
417 }
418 
419 void
421 {
422  switch (type)
423  {
424  case INPUT_FILE:
425  _syntax_formatter = std::make_unique<InputFileFormatter>(dump_mode);
426  break;
427  case YAML:
428  _syntax_formatter = std::make_unique<YAMLFormatter>(dump_mode);
429  break;
430  default:
431  mooseError("Unrecognized Syntax Formatter requested");
432  break;
433  }
434 }
435 
436 void
438 {
439  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
440 
441  for (const auto & iter : _syntax.getAssociatedTypes())
442  root.addSyntaxType(iter.first, iter.second);
443 
444  // Build a list of all the actions appearing in the syntax
445  for (const auto & iter : _syntax.getAssociatedActions())
446  {
447  Syntax::ActionInfo act_info = iter.second;
453  if (act_info._task == "")
454  act_info._task = _action_factory.getTaskName(act_info._action);
455 
456  all_names.push_back(std::make_pair(iter.first, act_info));
457  }
458 
459  // Add all the actions to the JSON tree, except for ActionComponents (below)
460  for (const auto & act_names : all_names)
461  {
462  const auto & act_info = act_names.second;
463  const std::string & action = act_info._action;
464  const std::string & task = act_info._task;
465  const std::string syntax = act_names.first;
466  InputParameters action_obj_params = _action_factory.getValidParams(action);
467  bool params_added = root.addParameters("",
468  syntax,
469  false,
470  action,
471  true,
472  &action_obj_params,
473  _syntax.getLineInfo(syntax, action, ""),
474  "");
475 
476  if (params_added)
477  {
478  auto tasks = _action_factory.getTasksByAction(action);
479  for (auto & t : tasks)
480  {
481  auto info = _action_factory.getLineInfo(action, t);
482  root.addActionTask(syntax, action, t, info);
483  }
484  }
485 
491  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
492  action_obj_params.get<bool>("isObjectAction"))
493  {
494  for (auto & [moose_obj_name, obj] : _factory.registeredObjects())
495  {
496  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  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  if ((buildable_types.empty() || // Not restricted
504  std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
505  buildable_types.end()) && // Restricted but found
506  moose_obj_params.hasBase() && // Has a registered base
507  _syntax.verifyMooseObjectTask(moose_obj_params.getBase(),
508  task) && // and that base is associated
509  action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
510  )
511  {
512  std::string name;
513  size_t pos = 0;
514  bool is_action_params = false;
515  bool is_type = false;
516  if (syntax[syntax.size() - 1] == '*')
517  {
518  pos = syntax.size();
519 
520  if (!action_obj_params.collapseSyntaxNesting())
521  name = syntax.substr(0, pos - 1) + moose_obj_name;
522  else
523  {
524  name = syntax.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
525  is_action_params = true;
526  }
527  }
528  else
529  {
530  name = syntax + "/<type>/" + moose_obj_name;
531  is_type = true;
532  }
533  moose_obj_params.set<std::string>("type") = moose_obj_name;
534 
535  auto lineinfo = _factory.getLineInfo(moose_obj_name);
536  std::string classname = _factory.associatedClassName(moose_obj_name);
537  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  }
546  }
547 
548  // Same thing for ActionComponents, which, while they are not MooseObjects, should behave
549  // similarly syntax-wise
550  if (syntax != "ActionComponents/*")
551  continue;
552 
553  auto iters = _action_factory.getActionsByTask("list_component");
554 
555  for (auto it = iters.first; it != iters.second; ++it)
556  {
557  // Get the name and parameters
558  const auto component_name = it->second;
559  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  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  std::string name;
571  if (syntax[syntax.size() - 1] == '*')
572  {
573  size_t pos = syntax.size();
574  name = syntax.substr(0, pos - 1) + component_name;
575  }
576  component_params.set<std::string>("type") = component_name;
577 
578  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  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  }
590  }
591  }
592  }
593  root.addGlobal();
594 }
595 
596 void
597 Builder::buildFullTree(const std::string & search_string)
598 {
599  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
600 
601  for (const auto & iter : _syntax.getAssociatedActions())
602  {
603  Syntax::ActionInfo act_info = iter.second;
609  if (act_info._task == "")
610  act_info._task = _action_factory.getTaskName(act_info._action);
611 
612  all_names.push_back(std::pair<std::string, Syntax::ActionInfo>(iter.first, act_info));
613  }
614 
615  for (const auto & act_names : all_names)
616  {
617  InputParameters action_obj_params = _action_factory.getValidParams(act_names.second._action);
618  _syntax_formatter->insertNode(
619  act_names.first, act_names.second._action, true, &action_obj_params);
620 
621  const std::string & task = act_names.second._task;
622  std::string act_name = act_names.first;
623 
629  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
630  action_obj_params.get<bool>("isObjectAction"))
631  {
632  for (const auto & [moose_obj_name, obj] : _factory.registeredObjects())
633  {
634  auto moose_obj_params = obj->buildParameters();
639  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  if ((buildable_types.empty() || // Not restricted
643  std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
644  buildable_types.end()) && // Restricted but found
645  moose_obj_params.hasBase() && // Has a registered base
646  _syntax.verifyMooseObjectTask(moose_obj_params.getBase(),
647  task) && // and that base is associated
648  action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
649  )
650  {
651  std::string name;
652  size_t pos = 0;
653  bool is_action_params = false;
654  if (act_name[act_name.size() - 1] == '*')
655  {
656  pos = act_name.size();
657 
658  if (!action_obj_params.collapseSyntaxNesting())
659  name = act_name.substr(0, pos - 1) + moose_obj_name;
660  else
661  {
662  name = act_name.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
663  is_action_params = true;
664  }
665  }
666  else
667  {
668  name = act_name + "/<type>/" + moose_obj_name;
669  }
670 
671  moose_obj_params.set<std::string>("type") = moose_obj_name;
672 
673  _syntax_formatter->insertNode(name, moose_obj_name, is_action_params, &moose_obj_params);
674  }
675  }
676  }
677  }
678 
679  // Do not change to _console, we need this printed to the stdout in all cases
680  Moose::out << _syntax_formatter->print(search_string) << std::flush;
681 }
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 Builder::extractParams(const std::string & prefix, InputParameters & p)
845 {
846  std::ostringstream error_stream;
847  static const std::string global_params_task = "set_global_params";
848  static const std::string global_params_block_name =
849  _syntax.getSyntaxByAction("GlobalParamsAction").front();
850 
851  ActionIterator act_iter = _action_wh.actionBlocksWithActionBegin(global_params_task);
852  GlobalParamsAction * global_params_block = nullptr;
853 
854  // We are grabbing only the first
855  if (act_iter != _action_wh.actionBlocksWithActionEnd(global_params_task))
856  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  _current_params = &p;
861  for (const auto & it : p)
862  {
863  if (p.shouldIgnore(it.first))
864  continue;
865 
866  const hit::Node * node = nullptr;
867  bool found = false;
868  bool in_global = false;
869 
870  const auto found_param =
871  [this, &found, &node, &p](const std::string & param_name, const std::string & full_name)
872  {
873  found = true;
874  p.setHitNode(param_name, *node, {});
875  p.set_attributes(param_name, false);
876  _extracted_vars.insert(full_name);
877  };
878 
879  for (const auto & param_name : p.paramAliases(it.first))
880  {
881  std::string full_name = prefix + "/" + param_name;
882 
883  // Mark parameters appearing in the input file or command line
884  if (node = _root.find(full_name); node && node->type() == hit::NodeType::Field)
885  {
886  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  if (const auto deprecated_message = p.queryDeprecatedParamMessage(param_name))
891  _deprecated_params.emplace(param_name, *deprecated_message);
892  }
893  // Wait! Check the GlobalParams section
894  else if (global_params_block)
895  {
896  full_name = global_params_block_name + "/" + param_name;
897  if (node = _root.find(full_name); node)
898  {
899  found_param(param_name, full_name);
900  in_global = true;
901  }
902  }
903  if (found)
904  {
905 
906  if (p.isPrivate(param_name) && !in_global)
907  {
908  // Warn on private, just once
909  if (std::find_if(_errors.begin(),
910  _errors.end(),
911  [&node](const auto & err) { return err.node == node; }) == _errors.end())
912  _errors.emplace_back("parameter '" + full_name + "' is private and cannot be set",
913  node);
914  continue;
915  }
916  // avoid setting the parameter
917  else if (p.isPrivate(param_name) && in_global)
918  continue;
919 
920  auto & short_name = param_name;
921  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 
976  // built-ins
977  // NOTE: Similar dynamic casting is done in InputParameters.C, please update appropriately
978  if (false)
979  ;
980  setscalarvaltype(Real, double, Real);
981  setscalarvaltype(int, int, long);
982  setscalarvaltype(unsigned short, unsigned int, long);
983  setscalarvaltype(long, int, long);
984  setscalarvaltype(unsigned int, unsigned int, long);
985  setscalarvaltype(unsigned long, unsigned int, long);
986  setscalarvaltype(long int, int64_t, long);
987  setscalarvaltype(unsigned long long, unsigned int, long);
988 
989  setscalar(bool, bool);
990  setscalar(SubdomainID, int);
991  setscalar(BoundaryID, int);
992 
993  // string and string-subclass types
994  setscalar(string, string);
995  setscalar(SubdomainName, string);
996  setscalar(BoundaryName, string);
997  setscalar(FileName, string);
998  setscalar(MeshFileName, string);
999  setscalar(MatrixFileName, string);
1000  setscalar(FileNameNoExtension, string);
1001  setscalar(RelativeFileName, string);
1002  setscalar(DataFileName, string);
1003  setscalar(ComponentName, string);
1004  setscalar(PhysicsName, string);
1005  setscalar(OutFileBase, string);
1006  setscalar(VariableName, string);
1007  setscalar(NonlinearVariableName, string);
1008  setscalar(LinearVariableName, string);
1009  setscalar(SolverVariableName, string);
1010  setscalar(AuxVariableName, string);
1011  setscalar(FunctionName, string);
1012  setscalar(ConvergenceName, string);
1013  setscalar(MeshDivisionName, string);
1014  setscalar(UserObjectName, string);
1015  setscalar(VectorPostprocessorName, string);
1016  setscalar(IndicatorName, string);
1017  setscalar(MarkerName, string);
1018  setscalar(MultiAppName, string);
1019  setscalar(OutputName, string);
1020  setscalar(MaterialPropertyName, string);
1021  setscalar(MooseFunctorName, string);
1022  setscalar(MaterialName, string);
1023  setscalar(DistributionName, string);
1024  setscalar(PositionsName, string);
1025  setscalar(SamplerName, string);
1026  setscalar(TagName, string);
1027  setscalar(TimesName, string);
1028  setscalar(MeshGeneratorName, string);
1029  setscalar(ExtraElementIDName, string);
1030  setscalar(PostprocessorName, PostprocessorName);
1031  setscalar(ExecutorName, string);
1032  setscalar(NonlinearSystemName, string);
1033  setscalar(LinearSystemName, string);
1034  setscalar(SolverSystemName, string);
1035  setscalar(CLIArgString, string);
1036 #ifdef MOOSE_MFEM_ENABLED
1037  setscalar(MFEMScalarCoefficientName, string);
1038  setscalar(MFEMVectorCoefficientName, string);
1039  setscalar(MFEMMatrixCoefficientName, string);
1040 #endif
1041 
1042  // Moose Compound Scalars
1043  setscalar(RealVectorValue, RealVectorValue);
1044  setscalar(Point, Point);
1045  setscalar(RealEigenVector, RealEigenVector);
1046  setscalar(RealEigenMatrix, RealEigenMatrix);
1047  setscalar(MooseEnum, MooseEnum);
1048  setscalar(MultiMooseEnum, MultiMooseEnum);
1049  setscalar(RealTensorValue, RealTensorValue);
1050  setscalar(ExecFlagEnum, ExecFlagEnum);
1051  setscalar(ReporterName, string);
1052  setscalar(ReporterValueName, string);
1053  setscalar(ParsedFunctionExpression, string);
1054 
1055  // vector types
1056  setvector(bool, bool);
1057  setvector(Real, double);
1058  setvector(int, int);
1059  setvector(long, int);
1060  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  setvector(uint64_t, int);
1071 #endif
1072 
1073  setvector(SubdomainID, int);
1074  setvector(BoundaryID, int);
1075  setvector(RealVectorValue, RealVectorValue);
1076  setvector(Point, Point);
1077  setvector(MooseEnum, MooseEnum);
1078  setvector(MultiMooseEnum, MultiMooseEnum);
1079 
1080  setvector(string, string);
1081  setvector(FileName, string);
1082  setvector(FileNameNoExtension, string);
1083  setvector(RelativeFileName, string);
1084  setvector(DataFileName, string);
1085  setvector(MeshFileName, string);
1086  setvector(MatrixFileName, string);
1087  setvector(SubdomainName, string);
1088  setvector(BoundaryName, string);
1089  setvector(NonlinearVariableName, string);
1090  setvector(LinearVariableName, string);
1091  setvector(SolverVariableName, string);
1092  setvector(AuxVariableName, string);
1093  setvector(FunctionName, string);
1094  setvector(ConvergenceName, string);
1095  setvector(MeshDivisionName, string);
1096  setvector(UserObjectName, string);
1097  setvector(IndicatorName, string);
1098  setvector(MarkerName, string);
1099  setvector(MultiAppName, string);
1100  setvector(PostprocessorName, PostprocessorName);
1101  setvector(VectorPostprocessorName, string);
1102  setvector(OutputName, string);
1103  setvector(MaterialPropertyName, string);
1104  setvector(MooseFunctorName, string);
1105  setvector(MaterialName, string);
1106  setvector(DistributionName, string);
1107  setvector(SamplerName, string);
1108  setvector(TagName, string);
1109  setvector(VariableName, VariableName);
1110  setvector(MeshGeneratorName, string);
1111  setvector(ExtraElementIDName, string);
1112  setvector(ReporterName, string);
1113  setvector(CLIArgString, string);
1114  setvector(ComponentName, string);
1115  setvector(PhysicsName, string);
1116  setvector(PositionsName, string);
1117  setvector(TimesName, string);
1118  setvector(ReporterValueName, string);
1119  setvector(ExecutorName, string);
1120  setvector(NonlinearSystemName, string);
1121  setvector(LinearSystemName, string);
1122  setvector(SolverSystemName, string);
1123 #ifdef MOOSE_MFEM_ENABLED
1124  setvector(MFEMScalarCoefficientName, string);
1125  setvector(MFEMVectorCoefficientName, string);
1126  setvector(MFEMMatrixCoefficientName, string);
1127 #endif
1128 
1129  // map types
1130  setmap(string, unsigned int);
1131  setmap(string, Real);
1132  setmap(string, string);
1133  setmap(unsigned int, unsigned int);
1134  setmap(unsigned long, unsigned int);
1135  setmap(unsigned long long, unsigned int);
1136 
1137  // Double indexed types
1138  setvectorvector(Real);
1139  setvectorvector(int);
1140  setvectorvector(long);
1141  setvectorvector(unsigned int);
1142  setvectorvector(unsigned long long);
1143 
1144 // See vector type explanation
1145 #if LIBMESH_DOF_ID_BYTES == 8
1146  setvectorvector(uint64_t);
1147 #endif
1148 
1149  setvectorvector(SubdomainID);
1150  setvectorvector(BoundaryID);
1151  setvectorvector(Point);
1152  setvectorvector(string);
1153  setvectorvector(FileName);
1154  setvectorvector(FileNameNoExtension);
1155  setvectorvector(DataFileName);
1156  setvectorvector(MeshFileName);
1157  setvectorvector(MatrixFileName);
1158  setvectorvector(SubdomainName);
1159  setvectorvector(BoundaryName);
1160  setvectorvector(VariableName);
1161  setvectorvector(NonlinearVariableName);
1162  setvectorvector(LinearVariableName);
1163  setvectorvector(SolverVariableName);
1164  setvectorvector(AuxVariableName);
1165  setvectorvector(FunctionName);
1166  setvectorvector(ConvergenceName);
1167  setvectorvector(UserObjectName);
1168  setvectorvector(IndicatorName);
1169  setvectorvector(MarkerName);
1170  setvectorvector(MultiAppName);
1171  setvectorvector(PostprocessorName);
1172  setvectorvector(VectorPostprocessorName);
1173  setvectorvector(MarkerName);
1174  setvectorvector(OutputName);
1175  setvectorvector(MaterialPropertyName);
1176  setvectorvector(MooseFunctorName);
1177  setvectorvector(MaterialName);
1178  setvectorvector(DistributionName);
1179  setvectorvector(SamplerName);
1180  setvectorvector(TagName);
1181 #ifdef MOOSE_MFEM_ENABLED
1182  setvectorvector(MFEMScalarCoefficientName);
1183  setvectorvector(MFEMVectorCoefficientName);
1184  setvectorvector(MFEMMatrixCoefficientName);
1185 #endif
1186 
1187  // Triple indexed types
1188  setvectorvectorvector(Real);
1189  setvectorvectorvector(int);
1190  setvectorvectorvector(long);
1191  setvectorvectorvector(unsigned int);
1192  setvectorvectorvector(unsigned long long);
1193 
1194 // See vector type explanation
1195 #if LIBMESH_DOF_ID_BYTES == 8
1196  setvectorvectorvector(uint64_t);
1197 #endif
1198 
1199  setvectorvectorvector(SubdomainID);
1200  setvectorvectorvector(BoundaryID);
1201  setvectorvectorvector(string);
1202  setvectorvectorvector(FileName);
1203  setvectorvectorvector(FileNameNoExtension);
1204  setvectorvectorvector(DataFileName);
1205  setvectorvectorvector(MeshFileName);
1206  setvectorvectorvector(MatrixFileName);
1207  setvectorvectorvector(SubdomainName);
1208  setvectorvectorvector(BoundaryName);
1209  setvectorvectorvector(VariableName);
1210  setvectorvectorvector(NonlinearVariableName);
1211  setvectorvectorvector(LinearVariableName);
1212  setvectorvectorvector(AuxVariableName);
1213  setvectorvectorvector(FunctionName);
1214  setvectorvectorvector(UserObjectName);
1215  setvectorvectorvector(IndicatorName);
1216  setvectorvectorvector(MarkerName);
1217  setvectorvectorvector(MultiAppName);
1218  setvectorvectorvector(PostprocessorName);
1219  setvectorvectorvector(VectorPostprocessorName);
1220  setvectorvectorvector(MarkerName);
1221  setvectorvectorvector(OutputName);
1222  setvectorvectorvector(MaterialPropertyName);
1223  setvectorvectorvector(MooseFunctorName);
1224  setvectorvectorvector(MaterialName);
1225  setvectorvectorvector(DistributionName);
1226  setvectorvectorvector(SamplerName);
1227  else
1228  {
1230  {{"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  break;
1241  }
1242  }
1243 
1244  if (!found)
1245  {
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  dynamic_cast<InputParameters::Parameter<OutFileBase> *>(MooseUtils::get(it.second));
1258  if (scalar_p)
1259  {
1260  std::string input_file_name = getPrimaryFileName();
1261  mooseAssert(input_file_name != "", "Input Filename is nullptr");
1262  size_t pos = input_file_name.find_last_of('.');
1263  mooseAssert(pos != std::string::npos, "Unable to determine suffix of input file name");
1264  scalar_p->set() = input_file_name.substr(0, pos) + "_out";
1265  p.set_attributes(it.first, false);
1266  }
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  p.getAutoBuildVectors();
1273  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  const std::string & base_name = it.second.first;
1279  const std::string & num_repeat = it.second.second;
1280 
1281  if (!p.isParamValid(it.first) && p.isParamValid(base_name) && p.isParamValid(num_repeat))
1282  {
1283  unsigned int vec_size = p.get<unsigned int>(num_repeat);
1284  const std::string & name = p.get<std::string>(base_name);
1285 
1286  std::vector<VariableName> variable_names(vec_size);
1287  for (unsigned int i = 0; i < vec_size; ++i)
1288  {
1289  std::ostringstream oss;
1290  oss << name << i;
1291  variable_names[i] = oss.str();
1292  }
1293 
1294  // Finally set the autogenerated vector into the InputParameters object
1295  p.set<std::vector<VariableName>>(it.first) = variable_names;
1296  }
1297  }
1298 }
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 toBool<bool>(const std::string & s, bool & val)
1310 {
1311  return hit::toBool(s, &val);
1312 }
1313 
1314 template <typename T, typename Base>
1315 void
1316 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  auto node = _root.find(full_name, true);
1323  try
1324  {
1325  param->set() = node->param<Base>();
1326  }
1327  catch (hit::Error & err)
1328  {
1329  auto strval = node->param<std::string>();
1330 
1331  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  param->set() = MooseUtils::convert<T>(strval, true);
1340  }
1341  catch (std::invalid_argument & /*e*/)
1342  {
1343  const std::string format_type = (t == typeid(double)) ? "float" : "integer";
1344  _errors.emplace_back("invalid " + format_type + " syntax for parameter: " + full_name +
1345  "='" + strval + "'",
1346  node);
1347  }
1348  }
1349  else if constexpr (std::is_same_v<T, bool>)
1350  {
1351  if (!toBool(strval, param->set()))
1352  _errors.emplace_back(
1353  "invalid boolean syntax for parameter: " + full_name + "='" + strval + "'", node);
1354  }
1355  else
1356  throw;
1357  }
1358 
1359  if (in_global)
1360  {
1361  global_block->remove(short_name);
1362  global_block->setScalarParam<T>(short_name) = param->get();
1363  }
1364 }
1365 
1366 template <typename T, typename UP_T, typename Base>
1367 void
1368 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  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  const auto error = _current_params->rangeCheck<T, UP_T>(full_name, short_name, param);
1382  if (error)
1383  _errors.emplace_back(error->second, &node);
1384 }
1385 
1386 template <typename T, typename Base>
1387 void
1388 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  std::vector<T> vec;
1395  if (const auto node = _root.find(full_name))
1396  {
1397  try
1398  {
1399  auto tmp = node->param<std::vector<Base>>();
1400  for (auto val : tmp)
1401  vec.push_back(val);
1402  }
1403  catch (hit::Error & err)
1404  {
1406  return;
1407  }
1408  }
1409 
1410  param->set() = vec;
1411 
1412  if (in_global)
1413  {
1414  global_block->remove(short_name);
1415  global_block->setVectorParam<T>(short_name).resize(param->get().size());
1416  for (unsigned int i = 0; i < vec.size(); ++i)
1417  global_block->setVectorParam<T>(short_name)[i] = param->get()[i];
1418  }
1419 }
1420 
1421 template <typename KeyType, typename MappedType>
1422 void
1423 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  std::map<KeyType, MappedType> the_map;
1430 
1431  if (const auto node = _root.find(full_name))
1432  {
1433  try
1434  {
1435  const auto & string_vec = node->param<std::vector<std::string>>();
1436  auto it = string_vec.begin();
1437  while (it != string_vec.end())
1438  {
1439  const auto & string_key = *it;
1440  ++it;
1441  if (it == string_vec.end())
1442  {
1443  _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  return;
1449  }
1450  const auto & string_value = *it;
1451  ++it;
1452 
1453  std::pair<KeyType, MappedType> pr;
1454  // key
1455  try
1456  {
1457  pr.first = MooseUtils::convert<KeyType>(string_key, true);
1458  }
1459  catch (std::invalid_argument & /*e*/)
1460  {
1461  _errors.emplace_back("invalid " + MooseUtils::prettyCppType<KeyType>() +
1462  " syntax for map parameter '" + full_name +
1463  "' key: " + string_key,
1464  node);
1465  return;
1466  }
1467  // value
1468  try
1469  {
1470  pr.second = MooseUtils::convert<MappedType>(string_value, true);
1471  }
1472  catch (std::invalid_argument & /*e*/)
1473  {
1474  _errors.emplace_back("invalid " + MooseUtils::prettyCppType<MappedType>() +
1475  " syntax for map parameter '" + full_name +
1476  "' value: " + string_value,
1477  node);
1478  return;
1479  }
1480 
1481  auto insert_pr = the_map.insert(std::move(pr));
1482  if (!insert_pr.second)
1483  {
1484  _errors.emplace_back("Duplicate map entry for map parameter: '" + full_name + "'; key '" +
1485  string_key + "' appears multiple times",
1486  node);
1487  return;
1488  }
1489  }
1490  }
1491  catch (hit::Error & err)
1492  {
1494  return;
1495  }
1496  }
1497 
1498  param->set() = the_map;
1499 
1500  if (in_global)
1501  {
1502  global_block->remove(short_name);
1503  auto & global_map = global_block->setParam<std::map<KeyType, MappedType>>(short_name);
1504  for (const auto & pair : the_map)
1505  global_map.insert(pair);
1506  }
1507 }
1508 
1509 template <typename T>
1510 void
1511 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  auto & value = param->set();
1518 
1519  // Get the full string assigned to the variable full_name
1520  const auto node = _root.find(full_name, true);
1521  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  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  if (!value_string.empty())
1531  outer_string_vectors = MooseUtils::split(value_string, ";");
1532 
1533  const auto outer_vector_size = outer_string_vectors.size();
1534  value.resize(outer_vector_size);
1535 
1536  for (const auto j : index_range(outer_string_vectors))
1537  if (!MooseUtils::tokenizeAndConvert<T>(outer_string_vectors[j], value[j]))
1538  {
1539  _errors.emplace_back("invalid format for parameter " + full_name, node);
1540  return;
1541  }
1542 
1543  if (in_global)
1544  {
1545  global_block->remove(short_name);
1546  global_block->setDoubleIndexParam<T>(short_name).resize(outer_vector_size);
1547  for (const auto j : make_range(outer_vector_size))
1548  {
1549  global_block->setDoubleIndexParam<T>(short_name)[j].resize(value[j].size());
1550  for (const auto i : index_range(value[j]))
1551  global_block->setDoubleIndexParam<T>(short_name)[j][i] = value[j][i];
1552  }
1553  }
1554 }
1555 
1556 template <typename T>
1557 void
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  auto node = _root.find(full_name, true);
1567  const std::string buffer_raw = node->param<std::string>();
1568  // In case the parameter is empty
1569  if (buffer_raw.find_first_not_of(' ', 0) == std::string::npos)
1570  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  std::string buffer;
1575  buffer.push_back(buffer_raw[0]);
1576  if (buffer[0] == '|' || buffer[0] == ';')
1577  buffer = ' ' + buffer;
1578  for (std::string::size_type i = 1; i < buffer_raw.size(); i++)
1579  {
1580  if ((buffer_raw[i - 1] == '|' || buffer_raw[i - 1] == ';') &&
1581  (buffer_raw[i] == '|' || buffer_raw[i] == ';'))
1582  buffer.push_back(' ');
1583  buffer.push_back(buffer_raw[i]);
1584  }
1585  if (buffer.back() == '|' || buffer.back() == ';')
1586  buffer.push_back(' ');
1587 
1588  // split vector at delim | to get a series of 2D subvectors
1589  std::vector<std::string> first_tokenized_vector;
1590  std::vector<std::vector<std::string>> second_tokenized_vector;
1591  MooseUtils::tokenize(buffer, first_tokenized_vector, 1, "|");
1592  param->set().resize(first_tokenized_vector.size());
1593  second_tokenized_vector.resize(first_tokenized_vector.size());
1594  for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1595  {
1596  // Identify empty subvector first
1597  if (first_tokenized_vector[j].find_first_not_of(' ', 0) == std::string::npos)
1598  {
1599  param->set()[j].resize(0);
1600  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  MooseUtils::tokenize(first_tokenized_vector[j], second_tokenized_vector[j], 1, ";");
1605  param->set()[j].resize(second_tokenized_vector[j].size());
1606  for (unsigned k = 0; k < second_tokenized_vector[j].size(); ++k)
1607  if (!MooseUtils::tokenizeAndConvert<T>(second_tokenized_vector[j][k], param->set()[j][k]))
1608  {
1609  _errors.emplace_back("invalid format for '" + full_name + "'", node);
1610  return;
1611  }
1612  }
1613 
1614  if (in_global)
1615  {
1616  global_block->remove(short_name);
1617  global_block->setTripleIndexParam<T>(short_name).resize(first_tokenized_vector.size());
1618  for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1619  {
1620  global_block->setTripleIndexParam<T>(short_name)[j].resize(second_tokenized_vector[j].size());
1621  for (unsigned k = 0; k < second_tokenized_vector[j].size(); ++k)
1622  {
1623  global_block->setTripleIndexParam<T>(short_name)[j][k].resize(param->get()[j][k].size());
1624  for (unsigned int i = 0; i < param->get()[j][k].size(); ++i)
1625  global_block->setTripleIndexParam<T>(short_name)[j][k][i] = param->get()[j][k][i];
1626  }
1627  }
1628  }
1629 }
1630 
1631 template <typename T>
1632 void
1633 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  auto node = _root.find(full_name, true);
1640  std::vector<double> vec;
1641  try
1642  {
1643  vec = node->param<std::vector<double>>();
1644  }
1645  catch (hit::Error & err)
1646  {
1648  return;
1649  }
1650 
1651  if (vec.size() != LIBMESH_DIM)
1652  {
1653  _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  return;
1658  }
1659 
1660  T value;
1661  for (unsigned int i = 0; i < vec.size(); ++i)
1662  value(i) = Real(vec[i]);
1663 
1664  param->set() = value;
1665  if (in_global)
1666  {
1667  global_block->remove(short_name);
1668  global_block->setScalarParam<T>(short_name) = value;
1669  }
1670 }
1671 
1672 template <typename T>
1673 void
1674 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  auto node = _root.find(full_name, true);
1681  std::vector<double> vec;
1682  try
1683  {
1684  vec = node->param<std::vector<double>>();
1685  }
1686  catch (hit::Error & err)
1687  {
1689  return;
1690  }
1691 
1692  if (vec.size() % LIBMESH_DIM)
1693  {
1694  _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  return;
1699  }
1700 
1701  std::vector<T> values;
1702  for (unsigned int i = 0; i < vec.size() / LIBMESH_DIM; ++i)
1703  {
1704  T value;
1705  for (int j = 0; j < LIBMESH_DIM; ++j)
1706  value(j) = Real(vec[i * LIBMESH_DIM + j]);
1707  values.push_back(value);
1708  }
1709 
1710  param->set() = values;
1711 
1712  if (in_global)
1713  {
1714  global_block->remove(short_name);
1715  global_block->setVectorParam<T>(short_name).resize(vec.size(), values[0]);
1716  for (unsigned int i = 0; i < vec.size() / LIBMESH_DIM; ++i)
1717  global_block->setVectorParam<T>(short_name)[i] = values[0];
1718  }
1719 }
1720 
1721 template <typename T>
1722 void
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  auto node = _root.find(full_name, true);
1732  std::string buffer = node->param<std::string>();
1733 
1734  // split vector at delim ;
1735  // NOTE: the substrings are _not_ of type T yet
1736  std::vector<std::string> first_tokenized_vector;
1737  MooseUtils::tokenize(buffer, first_tokenized_vector, 1, ";");
1738  param->set().resize(first_tokenized_vector.size());
1739 
1740  // get a vector<vector<double>> first
1741  std::vector<std::vector<double>> vecvec(first_tokenized_vector.size());
1742  for (unsigned j = 0; j < vecvec.size(); ++j)
1743  if (!MooseUtils::tokenizeAndConvert<double>(first_tokenized_vector[j], vecvec[j]))
1744  {
1745  _errors.emplace_back("invalid format for parameter " + full_name, node);
1746  return;
1747  }
1748 
1749  for (const auto & vec : vecvec)
1750  if (vec.size() % LIBMESH_DIM)
1751  {
1752  _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  return;
1757  }
1758 
1759  // convert vector<vector<double>> to vector<vector<T>>
1760  std::vector<std::vector<T>> values(vecvec.size());
1761  for (unsigned int id_vec = 0; id_vec < vecvec.size(); ++id_vec)
1762  for (unsigned int i = 0; i < vecvec[id_vec].size() / LIBMESH_DIM; ++i)
1763  {
1764  T value;
1765  for (int j = 0; j < LIBMESH_DIM; ++j)
1766  value(j) = Real(vecvec[id_vec][i * LIBMESH_DIM + j]);
1767  values[id_vec].push_back(value);
1768  }
1769 
1770  param->set() = values;
1771 
1772  if (in_global)
1773  {
1774  global_block->remove(short_name);
1775  global_block->setDoubleIndexParam<T>(short_name).resize(vecvec.size());
1776  for (unsigned j = 0; j < vecvec.size(); ++j)
1777  {
1778  global_block->setDoubleIndexParam<T>(short_name)[j].resize(param->get()[j].size() /
1779  LIBMESH_DIM);
1780  for (unsigned int i = 0; i < param->get()[j].size() / LIBMESH_DIM; ++i)
1781  global_block->setDoubleIndexParam<T>(short_name)[j][i] = values[j][i];
1782  }
1783  }
1784 }
1785 
1786 template <>
1787 void
1788 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  setScalarComponentParameter(full_name, short_name, param, in_global, global_block);
1796 }
1797 
1798 template <>
1799 void
1800 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  setScalarComponentParameter(full_name, short_name, param, in_global, global_block);
1807 }
1808 
1809 template <>
1810 void
1811 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  std::vector<double> vec;
1819  try
1820  {
1821  vec = _root.param<std::vector<double>>(full_name);
1822  }
1823  catch (hit::Error & err)
1824  {
1825  Parser::appendErrorMessages(_errors, err);
1826  return;
1827  }
1828 
1829  RealEigenVector value(vec.size());
1830  for (unsigned int i = 0; i < vec.size(); ++i)
1831  value(i) = Real(vec[i]);
1832 
1833  param->set() = value;
1834  if (in_global)
1835  {
1836  global_block->remove(short_name);
1837  global_block->setScalarParam<RealEigenVector>(short_name) = value;
1838  }
1839 }
1840 
1841 template <>
1842 void
1843 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  auto node = _root.find(full_name, true);
1852  std::string buffer = node->param<std::string>();
1853 
1854  // split vector at delim ;
1855  // NOTE: the substrings are _not_ of type T yet
1856  std::vector<std::string> first_tokenized_vector;
1857  MooseUtils::tokenize(buffer, first_tokenized_vector, 1, ";");
1858 
1859  std::vector<std::vector<Real>> values(first_tokenized_vector.size());
1860 
1861  for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1862  {
1863  if (!MooseUtils::tokenizeAndConvert<Real>(first_tokenized_vector[j], values[j]) ||
1864  (j != 0 && values[j].size() != values[0].size()))
1865  {
1866  _errors.emplace_back("invalid format for parameter " + full_name, node);
1867  return;
1868  }
1869  }
1870 
1871  RealEigenMatrix value(values.size(), values[0].size());
1872  for (unsigned int i = 0; i < values.size(); ++i)
1873  for (unsigned int j = 0; j < values[i].size(); ++j)
1874  value(i, j) = values[i][j];
1875 
1876  param->set() = value;
1877  if (in_global)
1878  {
1879  global_block->remove(short_name);
1880  global_block->setScalarParam<RealEigenMatrix>(short_name) = value;
1881  }
1882 }
1883 
1884 template <>
1885 void
1886 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  MooseEnum current_param = param->get();
1893 
1894  std::string value = _root.param<std::string>(full_name);
1895 
1896  param->set() = value;
1897  if (in_global)
1898  {
1899  global_block->remove(short_name);
1900  global_block->setScalarParam<MooseEnum>(short_name) = current_param;
1901  }
1902 }
1903 
1904 template <>
1905 void
1906 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  MultiMooseEnum current_param = param->get();
1914 
1915  auto vec = _root.param<std::vector<std::string>>(full_name);
1916 
1917  std::string raw_values;
1918  for (unsigned int i = 0; i < vec.size(); ++i)
1919  raw_values += ' ' + vec[i];
1920 
1921  param->set() = raw_values;
1922 
1923  if (in_global)
1924  {
1925  global_block->remove(short_name);
1926  global_block->setScalarParam<MultiMooseEnum>(short_name) = current_param;
1927  }
1928 }
1929 
1930 template <>
1931 void
1932 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  ExecFlagEnum current_param = param->get();
1940  auto vec = _root.param<std::vector<std::string>>(full_name);
1941 
1942  std::string raw_values;
1943  for (unsigned int i = 0; i < vec.size(); ++i)
1944  raw_values += ' ' + vec[i];
1945 
1946  param->set() = raw_values;
1947 
1948  if (in_global)
1949  {
1950  global_block->remove(short_name);
1951  global_block->setScalarParam<ExecFlagEnum>(short_name) = current_param;
1952  }
1953 }
1954 
1955 template <>
1956 void
1957 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  auto node = _root.find(full_name, true);
1965  auto vec = node->param<std::vector<double>>();
1966  if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
1967  {
1968  _errors.emplace_back("invalid RealTensorValue parameter '" + full_name + "': size is " +
1969  std::to_string(vec.size()) + " but should be " +
1970  std::to_string(LIBMESH_DIM * LIBMESH_DIM),
1971  node);
1972  return;
1973  }
1974 
1976  for (int i = 0; i < LIBMESH_DIM; ++i)
1977  for (int j = 0; j < LIBMESH_DIM; ++j)
1978  value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
1979 
1980  param->set() = value;
1981  if (in_global)
1982  {
1983  global_block->remove(short_name);
1984  global_block->setScalarParam<RealTensorValue>(short_name) = value;
1985  }
1986 }
1987 
1988 // Specialization for coupling a Real value where a postprocessor would be needed in MOOSE
1989 template <>
1990 void
1991 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  PostprocessorName pps_name = _root.param<std::string>(full_name);
1999  param->set() = pps_name;
2000 
2001  if (in_global)
2002  {
2003  global_block->remove(short_name);
2004  global_block->setScalarParam<PostprocessorName>(short_name) = pps_name;
2005  }
2006 }
2007 
2008 template <>
2009 void
2010 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  auto node = _root.find(full_name, true);
2018  std::vector<std::string> names = MooseUtils::rsplit(node->param<std::string>(), "/", 2);
2019  if (names.size() != 2)
2020  _errors.emplace_back(
2021  "The supplied name ReporterName '" + full_name + "' must contain the '/' delimiter.", node);
2022  else
2023  param->set() = ReporterName(names[0], names[1]);
2024 }
2025 
2026 template <>
2027 void
2028 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  setVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2036 }
2037 
2038 template <>
2039 void
2040 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  setVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2047 }
2048 
2049 template <>
2050 void
2051 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  std::vector<MooseEnum> enum_values = param->get();
2059  std::vector<std::string> values(enum_values.size());
2060  for (unsigned int i = 0; i < values.size(); ++i)
2061  values[i] = static_cast<std::string>(enum_values[i]);
2062 
2067  std::vector<std::string> vec;
2068  if (auto node = _root.find(full_name, true))
2069  {
2070  vec = node->param<std::vector<std::string>>();
2071  param->set().resize(vec.size(), enum_values[0]);
2072  }
2073 
2074  for (unsigned int i = 0; i < vec.size(); ++i)
2075  param->set()[i] = vec[i];
2076 
2077  if (in_global)
2078  {
2079  global_block->remove(short_name);
2080  global_block->setVectorParam<MooseEnum>(short_name).resize(vec.size(), enum_values[0]);
2081  for (unsigned int i = 0; i < vec.size(); ++i)
2082  global_block->setVectorParam<MooseEnum>(short_name)[i] = values[0];
2083  }
2084 }
2085 
2086 template <>
2087 void
2088 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  const auto node = _root.find(full_name, true);
2096  const std::vector<MultiMooseEnum> & enum_values = param->get();
2097 
2098  // Get the full string assigned to the variable full_name
2099  std::string buffer = node->param<std::string>();
2100 
2101  bool has_empty = false;
2102  const auto first_tokenized_vector = MooseUtils::split(buffer, ";");
2103  for (const auto i : index_range(first_tokenized_vector))
2104  {
2105  const auto & entry = first_tokenized_vector[i];
2106  if (MooseUtils::trim(entry) == "")
2107  {
2108  has_empty = true;
2109  _errors.emplace_back("entry " + std::to_string(i) + " in '" + node->fullpath() + "' is empty",
2110  node);
2111  }
2112  }
2113 
2114  if (has_empty)
2115  return;
2116 
2117  param->set().resize(first_tokenized_vector.size(), enum_values[0]);
2118 
2119  std::vector<std::vector<std::string>> vecvec(first_tokenized_vector.size());
2120  for (const auto i : index_range(vecvec))
2121  {
2122  MooseUtils::tokenize<std::string>(first_tokenized_vector[i], vecvec[i], 1, " ");
2123  param->set()[i] = vecvec[i];
2124  }
2125 
2126  if (in_global)
2127  {
2128  global_block->remove(short_name);
2129  global_block->setVectorParam<MultiMooseEnum>(short_name).resize(vecvec.size(), enum_values[0]);
2130  for (unsigned int i = 0; i < vecvec.size(); ++i)
2131  global_block->setVectorParam<MultiMooseEnum>(short_name)[i] = vecvec[i];
2132  }
2133 }
2134 
2135 template <>
2136 void
2137 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  std::vector<std::string> pps_names = _root.param<std::vector<std::string>>(full_name);
2145  unsigned int n = pps_names.size();
2146  param->set().resize(n);
2147 
2148  for (unsigned int j = 0; j < n; ++j)
2149  param->set()[j] = pps_names[j];
2150 
2151  if (in_global)
2152  {
2153  global_block->remove(short_name);
2154  global_block->setVectorParam<PostprocessorName>(short_name).resize(n, "");
2155  for (unsigned int j = 0; j < n; ++j)
2156  global_block->setVectorParam<PostprocessorName>(short_name)[j] = pps_names[j];
2157  }
2158 }
2159 
2164 template <>
2165 void
2166 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  auto node = _root.find(full_name, true);
2174  auto vec = node->param<std::vector<std::string>>();
2175  auto strval = node->param<std::string>();
2176  std::vector<VariableName> var_names(vec.size());
2177 
2178  bool has_var_names = false;
2179  for (unsigned int i = 0; i < vec.size(); ++i)
2180  {
2181  VariableName var_name = vec[i];
2182 
2183  Real real_value;
2184  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  if (ss >> real_value && ss.eof())
2189  _current_params->defaultCoupledValue(short_name, real_value, i);
2190  else
2191  {
2192  var_names[i] = var_name;
2193  has_var_names = true;
2194  }
2195  }
2196 
2197  if (has_var_names)
2198  {
2199  param->set().resize(vec.size());
2200 
2201  for (unsigned int i = 0; i < vec.size(); ++i)
2202  if (var_names[i] == "")
2203  _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  param->set()[i] = var_names[i];
2209  }
2210 }
2211 
2212 template <>
2213 void
2214 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  auto node = _root.find(full_name, true);
2222  auto rnames = node->param<std::vector<std::string>>();
2223  param->set().resize(rnames.size());
2224 
2225  for (unsigned int i = 0; i < rnames.size(); ++i)
2226  {
2227  std::vector<std::string> names = MooseUtils::rsplit(rnames[i], "/", 2);
2228  if (names.size() != 2)
2229  _errors.emplace_back("the supplied name ReporterName '" + rnames[i] +
2230  "' must contain the '/' delimiter",
2231  node);
2232  else
2233  param->set()[i] = ReporterName(names[0], names[1]);
2234  }
2235 }
2236 
2237 template <>
2238 void
2239 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  auto rnames = _root.param<std::vector<std::string>>(full_name);
2248  param->set().resize(rnames.size()); // slightly oversized if vectors have been split
2249 
2250  // Skip empty parameter
2251  if (rnames.empty())
2252  return;
2253 
2254  // Re-assemble vector parameters
2255  unsigned int i_param = 0;
2256  bool vector_param_detected = false;
2257  for (unsigned int i = 0; i < rnames.size(); ++i)
2258  {
2259  // Look for a quote, both types
2260  std::vector<std::string> double_split =
2262  std::vector<std::string> single_split =
2264  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  if ((double_split.size() + single_split.size()) % 2 == 1)
2268  vector_param_detected = !vector_param_detected;
2269 
2270  // We're building a vector parameters, just append the text, rebuild the spaces
2271  if (vector_param_detected)
2272  param->set()[i_param] += rnames[i] + ' ';
2273  else
2274  {
2275  param->set()[i_param] += rnames[i];
2276  i_param++;
2277  }
2278  }
2279  // Use actual size after re-forming vector parameters
2280  param->set().resize(i_param);
2281 }
2282 
2283 template <>
2284 void
2285 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  setVectorVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2293 }
2294 } // end of namespace Moose
std::string name(const ElemQuality q)
OStreamProxy err
void build()
Parse an input file (or text string if provided) consisting of hit syntax and setup objects in the MO...
Definition: Builder.C:319
void addSyntaxType(const std::string &path, const std::string type)
Add an associated type to a block.
ActionFactory & _action_factory
The Factory that builds actions.
Definition: Builder.h:220
MooseApp & _app
The MooseApp this Parser is part of.
Definition: Builder.h:214
const std::multimap< std::string, std::string > & getAssociatedTypes() const
Get a multimap of registered associations of syntax with type.
Definition: Syntax.C:368
void walk(const std::string &fullpath, const std::string &nodename, hit::Node *n) override
Definition: Builder.C:179
bool show_trace
Set to true (the default) to print the stack trace with error and warning messages - false to omit it...
Definition: Moose.C:783
std::pair< std::multimap< std::string, ActionInfo >::const_iterator, std::multimap< std::string, ActionInfo >::const_iterator > getActions(const std::string &syntax) const
Returns a pair of multimap iterators to all the ActionInfo objects associated with a given piece of s...
Definition: Syntax.C:328
void walkRaw(std::string fullpath, std::string nodepath, hit::Node *n)
Definition: Builder.C:206
void parseError(std::vector< hit::ErrorMessage > messages) const
Helper for throwing an error with the given messages.
Definition: Parser.C:493
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
virtual std::string type() const=0
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
Parser & _parser
The front parser.
Definition: Builder.h:224
InputParameters & getComponentParams()
Return the parameters of the component.
void setTripleIndexParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< std::vector< std::vector< std::vector< T >>>> *param, bool in_global, GlobalParamsAction *global_block)
Template method for setting any triple indexed type parameter read from the input file or command lin...
Definition: Builder.C:1558
std::list< Action * >::iterator ActionIterator
alias to hide implementation details
const std::multimap< std::string, ActionInfo > & getAssociatedActions() const
Return all Syntax to Action associations.
Definition: Syntax.C:374
void setScalarValueTypeParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< T > *param, bool in_global, GlobalParamsAction *global_block, const hit::Node &node)
Definition: Builder.C:1368
void buildFullTree(const std::string &search_string)
Use MOOSE Factories to construct a full parse tree for documentation or echoing input.
Definition: Builder.C:597
MPI_Info info
void mooseObjectSyntaxVisibility(bool visibility)
Mutators for controlling whether or not the outermost level of syntax will be collapsed when printed...
InputParameters getValidParams(const std::string &name)
Definition: ActionFactory.C:94
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:333
void addActionTask(const std::string &path, const std::string &action, const std::string &task, const FileLineInfo &lineinfo)
Add a task to the tree.
std::shared_ptr< CommandLine > commandLine() const
Get the command line.
Definition: MooseApp.h:411
std::vector< std::string > _secs_need_first
The sections that we need to execute first (read during the final walk)
Definition: Builder.h:235
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
void setVectorVectorComponentParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< std::vector< std::vector< T >>> *param, bool in_global, GlobalParamsAction *global_block)
Template method for setting vector of several multivalue "scalar" type parameter read from the input ...
Definition: Builder.C:1723
std::string associatedClassName(const std::string &name) const
Get the associated class name for an object name.
Definition: Factory.C:272
std::pair< std::multimap< std::string, std::string >::const_iterator, std::multimap< std::string, std::string >::const_iterator > getActionsByTask(const std::string &task) const
Returns begin and end iterators in a multimap from tasks to actions names.
char ** vars
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
Definition: MooseUtils.h:1155
std::set< std::string > getTasksByAction(const std::string &action) const
std::string opt
const std::vector< std::string > & getBuildableTypes() const
Returns the list of buildable types as a std::vector<std::string>
InputParameters * _current_params
The current parameter object for which parameters are being extracted.
Definition: Builder.h:238
Builder(MooseApp &app, ActionWarehouse &action_wh, Parser &parser)
Definition: Builder.C:124
FileLineInfo getLineInfo(const std::string &syntax, const std::string &action, const std::string &task) const
Gets the file and line where the syntax/action/task combo was registered.
Definition: Syntax.C:380
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
void setScalarComponentParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< T > *param, bool in_global, GlobalParamsAction *global_block)
Template method for setting any multivalue "scalar" type parameter read from the input file or comman...
Definition: Builder.C:1633
Builder & _builder
Definition: Builder.h:50
static InputParameters validParams()
Parameters that are processed directly by the Parser and are valid anywhere in the input...
Definition: Builder.C:141
Base class for MOOSE-based applications.
Definition: MooseApp.h:96
void setMapParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< std::map< KeyType, MappedType >> *param, bool in_global, GlobalParamsAction *global_block)
Template method for setting any map type parameter read from the input file or command line...
Definition: Builder.C:1423
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
Storage for action instances.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
FileLineInfo getLineInfo(const std::string &name, const std::string &task) const
Gets file and line information where an action was registered.
const std::set< std::string > & getExtractedVars() const
Definition: Parser.h:206
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
bool toBool(const std::string &, T &)
Definition: Builder.C:1302
Action for creating component actions.
std::unique_ptr< SyntaxTree > _syntax_formatter
Object for holding the syntax parse tree.
Definition: Builder.h:229
std::vector< T > & setVectorParam(const std::string &name)
Holds the syntax in a Json::Value tree.
void extractParams(const std::string &prefix, InputParameters &p)
This function attempts to extract values from the input file based on the contents of the passed para...
Definition: Builder.C:844
std::vector< std::vector< T > > & setDoubleIndexParam(const std::string &name)
std::string _action
Definition: Syntax.h:26
FileLineInfo getLineInfo(const std::string &name) const
Gets file and line information where an object was initially registered.
Definition: Factory.C:260
std::optional< std::pair< bool, std::string > > rangeCheck(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< T > *param, const bool include_param_path=true)
Runs a range on the supplied parameter if it exists and throws an error if that check fails...
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:40
InputParameters emptyInputParameters()
std::vector< std::string > getSyntaxByAction(const std::string &action, const std::string &task="")
Retrieve the syntax associated with the passed in action type string.
Definition: Syntax.C:211
auto max(const L &left, const R &right)
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
Python like split functions for strings.
Definition: MooseUtils.C:1126
static void appendErrorMessages(std::vector< hit::ErrorMessage > &to, const std::vector< hit::ErrorMessage > &from)
Helper for accumulating errors from a walker into an accumulation of errors.
Definition: Parser.C:471
bool isDeprecatedSyntax(const std::string &syntax) const
Returns a Boolean indicating whether the syntax has been deprecated through a call to deprecateAction...
Definition: Syntax.C:205
std::vector< std::string > rsplit(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
Definition: MooseUtils.C:1146
TensorValue< Real > RealTensorValue
static InputParameters validParams()
Definition: Action.C:26
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
hit::Node & _root
The root node from the Parser.
Definition: Builder.h:226
std::set< std::string > _extracted_vars
The set of all variables extracted from the input file.
Definition: Builder.h:232
bool addParameters(const std::string &parent_path, const std::string &path, bool is_type, const std::string &action, bool is_action, InputParameters *params, const FileLineInfo &lineinfo, const std::string &classname)
Add parameters to the tree.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
static std::string joinErrorMessages(const std::vector< hit::ErrorMessage > &error_messages)
Helper for combining error messages into a single, newline separated message.
Definition: Parser.C:484
void mooseUnused(Args &&... args)
Warning message used to notify the users of unused parts of their input files Really used internally ...
Definition: MooseError.h:376
boundary_id_type BoundaryID
void initSyntaxFormatter(SyntaxFormatterType type, bool dump_mode)
Creates a syntax formatter for printing.
Definition: Builder.C:420
bool getThrowOnError() const
Definition: Parser.h:199
static InputParameters validParams()
Definition: EmptyAction.C:19
T & setScalarParam(const std::string &name)
An inteface for the _console for outputting to the Console object.
std::vector< std::vector< std::vector< T > > > & setTripleIndexParam(const std::string &name)
std::string trim(const std::string &str, const std::string &white_space=" \\\)
Standard scripting language trim function.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
void buildJsonSyntaxTree(JsonSyntaxTree &tree) const
Use MOOSE Factories to construct a parameter tree for documentation or echoing input.
Definition: Builder.C:437
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:384
void errorCheck(const libMesh::Parallel::Communicator &comm, bool warn_unused, bool err_unused)
Definition: Builder.C:379
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > RealEigenMatrix
Definition: MooseTypes.h:149
const auto & registeredObjects() const
Returns a reference to the map from names to RegistryEntryBase pointers.
Definition: Factory.h:147
std::string getPrimaryFileName(bool stripLeadingPath=true) const
Return the primary (first) filename that was parsed.
Definition: Builder.C:199
std::vector< hit::ErrorMessage > errors
Definition: Builder.h:46
void setScalarParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< T > *param, bool in_global, GlobalParamsAction *global_block)
Helper functions for setting parameters of arbitrary types - bodies are in the .C file since they are...
Definition: Builder.C:1316
void mooseDeprecatedStream(S &oss, const bool expired, const bool print_title, Args &&... args)
Definition: MooseError.h:275
std::vector< hit::ErrorMessage > _errors
The errors accumulated during the walk.
Definition: Builder.h:241
std::string isAssociated(const std::string &real_id, bool *is_parent, const std::map< std::string, std::set< std::string >> &alt_map={}) const
Method for determining whether a piece of syntax is associated with an Action an optional syntax map ...
Definition: Syntax.C:251
bool toBool< bool >(const std::string &s, bool &val)
Definition: Builder.C:1309
std::string getTaskName(const std::string &action)
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
std::string _task
Definition: Syntax.h:27
std::string baseName(const std::string &name)
Function for string the information before the final / in a parser block.
Definition: MooseUtils.C:614
unsigned int get(unsigned int i) const
Indexing operator Operator to retrieve the id of an item from the MultiMooseEnum. ...
void setDoubleIndexParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< std::vector< std::vector< T >>> *param, bool in_global, GlobalParamsAction *global_block)
Template method for setting any double indexed type parameter read from the input file or command lin...
Definition: Builder.C:1511
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Syntax & _syntax
Reference to an object that defines input file syntax.
Definition: Builder.h:222
std::set< std::string > _used
Definition: Builder.h:49
void setVectorParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< std::vector< T >> *param, bool in_global, GlobalParamsAction *global_block)
Template method for setting any vector type parameter read from the input file or command line...
Definition: Builder.C:1388
const hit::Node & getCommandLineRoot() const
Definition: Parser.C:457
IntRange< T > make_range(T beg, T end)
void addGlobal()
Add the global section to the output.
int levenshteinDist(const std::string &s1, const std::string &s2)
Computes and returns the Levenshtein distance between strings s1 and s2.
Definition: MooseUtils.C:172
bool verifyMooseObjectTask(const std::string &base, const std::string &task) const
Returns a Boolean indicating whether a task is associated with on of the MOOSE pluggable systems (BAS...
Definition: Syntax.C:334
void setVectorComponentParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< std::vector< T >> *param, bool in_global, GlobalParamsAction *global_block)
Template method for setting several multivalue "scalar" type parameter read from the input file or co...
Definition: Builder.C:1674
ActionIterator actionBlocksWithActionEnd(const std::string &task)
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
Factory & _factory
The Factory associated with that MooseApp.
Definition: Builder.h:216
Eigen::Matrix< Real, Eigen::Dynamic, 1 > RealEigenVector
Definition: MooseTypes.h:146
virtual ~Builder()
Definition: Builder.C:138
std::vector< std::string > listValidParams(std::string &section_name)
Definition: Builder.C:162
void setHitNode(const std::string &param, const hit::Node &node, const SetParamHitNodeKey)
Sets the hit node associated with the parameter param to node.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
std::filesystem::path getLastInputFilePath() const
Definition: Parser.h:185
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type...
std::vector< std::string > findSimilar(std::string param, std::vector< std::string > options)
Definition: Builder.C:99
T & setParam(const std::string &name)
std::unordered_map< std::string, std::string > _deprecated_params
Deprecation warnings.
Definition: Builder.h:244
ActionWarehouse & _action_wh
Action warehouse that will be filled by actions.
Definition: Builder.h:218
std::string deprecatedActionSyntaxMessage(const std::string syntax)
Returns the deprecation message for a given syntax that has been deprecated by deprecateActionSyntax...
Definition: Syntax.C:194
ActionIterator actionBlocksWithActionBegin(const std::string &task)
Iterators to the Actions in the warehouse.
void collapseSyntaxNesting(bool collapse)
Mutators for controlling whether or not the outermost level of syntax will be collapsed when printed...
std::set< MooseEnumItem >::const_iterator find(const MooseEnumItem &other) const
Locate an item.
bool isSectionActive(std::string path, hit::Node *root)
Definition: Builder.C:62
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
Definition: MooseUtils.C:1050
auto index_range(const T &sizable)
The Reporter system is comprised of objects that can contain any number of data values.
Definition: ReporterName.h:30
Class for parsing input files.
Definition: Parser.h:87
void remove(const std::string &name)
This function is here to remove parameters of a type so that global parameters can potentially use th...
void walk(const std::string &fullpath, const std::string &nodepath, hit::Node *n)
Definition: Builder.C:309