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 "MooseObjectAction.h"
19 #include "ActionWarehouse.h"
20 #include "EmptyAction.h"
21 #include "FEProblem.h"
22 #include "MooseMesh.h"
23 #include "Executioner.h"
24 #include "MooseApp.h"
25 #include "MooseEnum.h"
26 #include "MultiMooseEnum.h"
27 #include "MultiApp.h"
28 #include "GlobalParamsAction.h"
29 #include "SyntaxTree.h"
30 #include "InputFileFormatter.h"
31 #include "YAMLFormatter.h"
32 #include "MooseTypes.h"
33 #include "CommandLine.h"
34 #include "JsonSyntaxTree.h"
35 #include "SystemInfo.h"
36 #include "MooseUtils.h"
37 #include "Conversion.h"
38 #include "Units.h"
39 #include "ActionComponent.h"
40 
41 #include "libmesh/parallel.h"
42 #include "libmesh/fparser.hh"
43 
44 // Regular expression includes
45 #include "pcrecpp.h"
46 
47 // C++ includes
48 #include <string>
49 #include <map>
50 #include <fstream>
51 #include <iomanip>
52 #include <algorithm>
53 #include <cstdlib>
54 #include <filesystem>
55 
56 namespace Moose
57 {
58 
59 bool
60 isSectionActive(std::string path, hit::Node * root)
61 {
62  hit::Node * n = root->find(path);
63  while (n)
64  {
65  hit::Node * section = n->parent();
66  if (section)
67  {
68  auto actives = section->find("active");
69  auto inactives = section->find("inactive");
70 
71  // only check current level, not nested ones
72  if (actives && actives->type() == hit::NodeType::Field && actives->parent() == section)
73  {
74  auto vars = section->param<std::vector<std::string>>("active");
75  bool have_var = false;
76  for (auto & var : vars)
77  if (n->path() == hit::pathNorm(var))
78  have_var = true;
79  if (!have_var)
80  return false;
81  }
82  // only check current level, not nested ones
83  if (inactives && inactives->type() == hit::NodeType::Field && inactives->parent() == section)
84  {
85  auto vars = section->param<std::vector<std::string>>("inactive");
86  for (auto & var : vars)
87  if (n->path() == hit::pathNorm(var))
88  return false;
89  }
90  }
91  n = section;
92  }
93  return true;
94 }
95 
96 std::vector<std::string>
97 findSimilar(std::string param, std::vector<std::string> options)
98 {
99  std::vector<std::string> candidates;
100  if (options.size() == 0)
101  return candidates;
102 
103  int mindist = MooseUtils::levenshteinDist(options[0], param);
104  for (auto & opt : options)
105  {
106  int dist = MooseUtils::levenshteinDist(opt, param);
107  // magic number heuristics to get similarity distance cutoff
108  int dist_cutoff = 1 + param.size() / 5;
109  if (dist > dist_cutoff || dist > mindist)
110  continue;
111 
112  if (dist < mindist)
113  {
114  mindist = dist;
115  candidates.clear();
116  }
117  candidates.push_back(opt);
118  }
119  return candidates;
120 }
121 
122 Builder::Builder(MooseApp & app, ActionWarehouse & action_wh, std::shared_ptr<Parser> parser)
123  : ConsoleStreamInterface(app),
124  _app(app),
125  _factory(app.getFactory()),
126  _action_wh(action_wh),
127  _action_factory(app.getActionFactory()),
128  _syntax(_action_wh.syntax()),
129  _parser(parser),
130  _syntax_formatter(nullptr),
131  _sections_read(false),
132  _current_params(nullptr),
133  _current_error_stream(nullptr)
134 {
135  mooseAssert(_parser, "Parser is not set");
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.push_back(hit::errormsg(
192  n, "unused parameter '", fullpath, "'\n", " Did you mean '", candidates[0], "'?"));
193  else
194  errors.push_back(hit::errormsg(n, "unused parameter '", fullpath, "'"));
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  std::string section_name = n->fullpath();
212  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  _errmsg += hit::errormsg(n,
229  "section '[",
230  curr_identifier,
231  "]' does not have an associated \"Action\".\n Common causes:\n"
232  "- you misspelled the Action/section name\n"
233  "- the app you are running does not support this Action/syntax") +
234  "\n";
235  return;
236  }
237 
238  // The DynamicObjecRegistrationAction changes the action multimap and would invalidate the
239  // iterators returned by _syntax.getActions, that's why we have to loop in this awkward way.
240  std::set<const Syntax::ActionInfo *> processed_actions;
241  while (true)
242  {
243  // search for an unprocessed action
244  auto [begin, end] = _syntax.getActions(registered_identifier);
245  auto it = begin;
246  for (; it != end && processed_actions.count(&it->second); ++it)
247  ;
248 
249  // no more unprocessed actions
250  if (it == end)
251  break;
252 
253  // mark action as processed
254  processed_actions.insert(&it->second);
255 
256  if (is_parent)
257  continue;
258  if (_syntax.isDeprecatedSyntax(registered_identifier))
260  hit::errormsg(n, _syntax.deprecatedActionSyntaxMessage(registered_identifier)));
261 
262  params = _action_factory.getValidParams(it->second._action);
263  params.set<ActionWarehouse *>("awh") = &_action_wh;
264  params.setHitNode(*n, {});
265 
266  extractParams(curr_identifier, params);
267 
268  // Add the parsed syntax to the parameters object for consumption by the Action
269  params.set<std::string>("task") = it->second._task;
270  params.set<std::string>("registered_identifier") = registered_identifier;
271 
272  if (!(params.have_parameter<bool>("isObjectAction") && params.get<bool>("isObjectAction")))
273  params.set<std::vector<std::string>>("control_tags")
274  .push_back(MooseUtils::baseName(curr_identifier));
275 
276  // Create the Action
277  std::shared_ptr<Action> action_obj =
278  _action_factory.create(it->second._action, curr_identifier, params);
279 
280  {
281  // extract the MooseObject params if necessary
282  std::shared_ptr<MooseObjectAction> object_action =
284  if (object_action)
285  {
286  auto & object_params = object_action->getObjectParams();
287  object_params.setHitNode(*n, {});
288  extractParams(curr_identifier, object_params);
289  object_params.set<std::vector<std::string>>("control_tags")
290  .push_back(MooseUtils::baseName(curr_identifier));
291  }
292  // extract the Component params if necessary
293  std::shared_ptr<AddActionComponentAction> component_action =
295  if (component_action)
296  {
297  auto & component_params = component_action->getComponentParams();
298  component_params.setHitNode(*n, {});
299  extractParams(curr_identifier, component_params);
300  component_params.set<std::vector<std::string>>("control_tags")
301  .push_back(MooseUtils::baseName(curr_identifier));
302  }
303  }
304 
305  // add it to the warehouse
306  _action_wh.addActionBlock(action_obj);
307  }
308 }
309 
310 void
311 Builder::walk(const std::string & fullpath, const std::string & nodepath, hit::Node * n)
312 {
313  // skip sections that were manually processed first.
314  for (auto & sec : _secs_need_first)
315  if (nodepath == sec)
316  return;
317  walkRaw(fullpath, nodepath, n);
318 }
319 
320 hit::Node *
322 {
323  mooseAssert(_parser, "Parser is not set");
324  return _parser->root();
325 }
326 
327 void
329 {
330  // add in command line arguments
331  const auto cli_input = _app.commandLine()->buildHitParams();
332  try
333  {
334  _cli_root.reset(hit::parse("CLI_ARGS", cli_input));
335  hit::explode(_cli_root.get());
336  hit::merge(_cli_root.get(), root());
337  }
338  catch (hit::ParseError & err)
339  {
340  mooseError(err.what());
341  }
342 
343  // expand ${bla} parameter values and mark/include variables used in expansions as "used". This
344  // MUST occur before parameter extraction - otherwise parameters will get wrong values.
345  hit::RawEvaler raw;
346  hit::EnvEvaler env;
347  hit::ReplaceEvaler repl;
348  FuncParseEvaler fparse_ev;
349  UnitsConversionEvaler units_ev;
350  hit::BraceExpander exw;
351  exw.registerEvaler("raw", raw);
352  exw.registerEvaler("env", env);
353  exw.registerEvaler("fparse", fparse_ev);
354  exw.registerEvaler("replace", repl);
355  exw.registerEvaler("units", units_ev);
356  root()->walk(&exw);
357  for (auto & var : exw.used)
358  _extracted_vars.insert(var);
359  for (auto & msg : exw.errors)
360  _errmsg += msg + "\n";
361 
362  // do as much error checking as early as possible so that errors are more useful instead
363  // of surprising and disconnected from what caused them.
364  DupParamWalker dw;
365  BadActiveWalker bw;
366  root()->walk(&dw, hit::NodeType::Field);
367  root()->walk(&bw, hit::NodeType::Section);
368  for (auto & msg : dw.errors)
369  _errmsg += msg + "\n";
370  for (auto & msg : bw.errors)
371  _errmsg += msg + "\n";
372 
373  // Print parse errors related to brace expansion early
374  if (_errmsg.size() > 0)
376 
377  // There are a few order dependent actions that have to be built first in
378  // order for the parser and application to function properly:
379  //
380  // SetupDebugAction: This action can contain an option for monitoring the parser progress. It must
381  // be parsed first to capture all of the parsing output.
382  //
383  // GlobalParamsAction: This action is checked during the parameter extraction routines of all
384  // subsequent blocks. It must be parsed early since it must exist during
385  // subsequent parameter extraction.
386  //
387  // DynamicObjectRegistration: This action must be built before any MooseObjectActions are built.
388  // This is because we retrieve valid parameters from the Factory
389  // during parse time. Objects must be registered before
390  // validParameters can be retrieved.
391  auto syntax = _syntax.getSyntaxByAction("SetupDebugAction");
392  std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
393 
394  syntax = _syntax.getSyntaxByAction("GlobalParamsAction");
395  std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
396 
397  syntax = _syntax.getSyntaxByAction("DynamicObjectRegistrationAction");
398  std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
399 
400  // walk all the sections extracting paramters from each into InputParameters objects
401  for (auto & sec : _secs_need_first)
402  {
403  auto n = root()->find(sec);
404  if (n)
405  walkRaw(n->parent()->fullpath(), n->path(), n);
406  }
407  root()->walk(this, hit::NodeType::Section);
408 
409  if (_errmsg.size() > 0)
411 }
412 
413 // Checks the input and the way it has been used and emits any errors/warnings.
414 // This has to be a separate function because for we don't know if some parameters were unused
415 // until all the multiapps/subapps have been fully initialized - which isn't complete until
416 // *after* all the other member functions on Parser have been run. So this is here to be
417 // externally called at the right time.
418 void
419 Builder::errorCheck(const Parallel::Communicator & comm, bool warn_unused, bool err_unused)
420 {
421  // this if guard is important in case the simulation was not configured via parsed input text -
422  // e.g. configured programatically.
423  if (!root() || !_cli_root)
424  return;
425 
426  UnusedWalker uw(_extracted_vars, *this);
427  UnusedWalker uwcli(_extracted_vars, *this);
428 
429  root()->walk(&uw);
430  _cli_root->walk(&uwcli);
431 
432  auto cli = _app.commandLine();
433  if (warn_unused)
434  {
435  for (const auto & arg : cli->unusedHitParams(comm))
436  _warnmsg +=
437  hit::errormsg("CLI_ARG", nullptr, "unused command line parameter '", arg, "'") + "\n";
438  for (auto & msg : uwcli.errors)
439  _warnmsg += msg + "\n";
440  for (auto & msg : uw.errors)
441  _warnmsg += msg + "\n";
442  }
443  else if (err_unused)
444  {
445  for (const auto & arg : cli->unusedHitParams(comm))
446  _errmsg +=
447  hit::errormsg("CLI_ARG", nullptr, "unused command line parameter '", arg, "'") + "\n";
448  for (auto & msg : uwcli.errors)
449  _errmsg += msg + "\n";
450  for (auto & msg : uw.errors)
451  _errmsg += msg + "\n";
452  }
453 
454  if (_warnmsg.size() > 0)
456  if (_errmsg.size() > 0)
457  mooseError(
458  _errmsg +
459  "\n\nAppend --allow-unused (or -w) on the command line to ignore unused parameters.");
460 }
461 
462 void
464 {
465  switch (type)
466  {
467  case INPUT_FILE:
468  _syntax_formatter = std::make_unique<InputFileFormatter>(dump_mode);
469  break;
470  case YAML:
471  _syntax_formatter = std::make_unique<YAMLFormatter>(dump_mode);
472  break;
473  default:
474  mooseError("Unrecognized Syntax Formatter requested");
475  break;
476  }
477 }
478 
479 void
481 {
482  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
483 
484  for (const auto & iter : _syntax.getAssociatedTypes())
485  root.addSyntaxType(iter.first, iter.second);
486 
487  // Build a list of all the actions appearing in the syntax
488  for (const auto & iter : _syntax.getAssociatedActions())
489  {
490  Syntax::ActionInfo act_info = iter.second;
496  if (act_info._task == "")
497  act_info._task = _action_factory.getTaskName(act_info._action);
498 
499  all_names.push_back(std::make_pair(iter.first, act_info));
500  }
501 
502  // Add all the actions to the JSON tree, except for ActionComponents (below)
503  for (const auto & act_names : all_names)
504  {
505  const auto & act_info = act_names.second;
506  const std::string & action = act_info._action;
507  const std::string & task = act_info._task;
508  const std::string syntax = act_names.first;
509  InputParameters action_obj_params = _action_factory.getValidParams(action);
510  bool params_added = root.addParameters("",
511  syntax,
512  false,
513  action,
514  true,
515  &action_obj_params,
516  _syntax.getLineInfo(syntax, action, ""),
517  "");
518 
519  if (params_added)
520  {
521  auto tasks = _action_factory.getTasksByAction(action);
522  for (auto & t : tasks)
523  {
524  auto info = _action_factory.getLineInfo(action, t);
525  root.addActionTask(syntax, action, t, info);
526  }
527  }
528 
534  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
535  action_obj_params.get<bool>("isObjectAction"))
536  {
537  for (auto & [moose_obj_name, obj] : _factory.registeredObjects())
538  {
539  auto moose_obj_params = obj->buildParameters();
540  // Now that we know that this is a MooseObjectAction we need to see if it has been
541  // restricted
542  // in any way by the user.
543  const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
544 
545  // See if the current Moose Object syntax belongs under this Action's block
546  if ((buildable_types.empty() || // Not restricted
547  std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
548  buildable_types.end()) && // Restricted but found
549  moose_obj_params.have_parameter<std::string>("_moose_base") && // Has a registered base
550  _syntax.verifyMooseObjectTask(moose_obj_params.get<std::string>("_moose_base"),
551  task) && // and that base is associated
552  action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
553  )
554  {
555  std::string name;
556  size_t pos = 0;
557  bool is_action_params = false;
558  bool is_type = false;
559  if (syntax[syntax.size() - 1] == '*')
560  {
561  pos = syntax.size();
562 
563  if (!action_obj_params.collapseSyntaxNesting())
564  name = syntax.substr(0, pos - 1) + moose_obj_name;
565  else
566  {
567  name = syntax.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
568  is_action_params = true;
569  }
570  }
571  else
572  {
573  name = syntax + "/<type>/" + moose_obj_name;
574  is_type = true;
575  }
576  moose_obj_params.set<std::string>("type") = moose_obj_name;
577 
578  auto lineinfo = _factory.getLineInfo(moose_obj_name);
579  std::string classname = _factory.associatedClassName(moose_obj_name);
580  root.addParameters(syntax,
581  name,
582  is_type,
583  moose_obj_name,
584  is_action_params,
585  &moose_obj_params,
586  lineinfo,
587  classname);
588  }
589  }
590 
591  // Same thing for ActionComponents, which, while they are not MooseObjects, should behave
592  // similarly syntax-wise
593  if (syntax != "ActionComponents/*")
594  continue;
595 
596  auto iters = _action_factory.getActionsByTask("list_component");
597 
598  for (auto it = iters.first; it != iters.second; ++it)
599  {
600  // Get the name and parameters
601  const auto component_name = it->second;
602  auto component_params = _action_factory.getValidParams(component_name);
603 
604  // We currently do not have build-type restrictions on this action that adds
605  // action-components
606 
607  // See if the current Moose Object syntax belongs under this Action's block
608  if (action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
609  )
610  {
611  // The logic for Components is a little simpler here for now because syntax like
612  // Executioner/TimeIntegrator/type= do not exist for components
613  std::string name;
614  if (syntax[syntax.size() - 1] == '*')
615  {
616  size_t pos = syntax.size();
617  name = syntax.substr(0, pos - 1) + component_name;
618  }
619  component_params.set<std::string>("type") = component_name;
620 
621  auto lineinfo = _action_factory.getLineInfo(component_name, "list_component");
622  // We add the parameters as for an object, because we want to fit them to be
623  // added to json["AddActionComponentAction"]["subblock_types"]
624  root.addParameters(syntax,
625  /*syntax_path*/ name,
626  /*is_type*/ false,
627  "AddActionComponentAction",
628  /*is_action=*/false,
629  &component_params,
630  lineinfo,
631  component_name);
632  }
633  }
634  }
635  }
636  root.addGlobal();
637 }
638 
639 void
640 Builder::buildFullTree(const std::string & search_string)
641 {
642  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
643 
644  for (const auto & iter : _syntax.getAssociatedActions())
645  {
646  Syntax::ActionInfo act_info = iter.second;
652  if (act_info._task == "")
653  act_info._task = _action_factory.getTaskName(act_info._action);
654 
655  all_names.push_back(std::pair<std::string, Syntax::ActionInfo>(iter.first, act_info));
656  }
657 
658  for (const auto & act_names : all_names)
659  {
660  InputParameters action_obj_params = _action_factory.getValidParams(act_names.second._action);
661  _syntax_formatter->insertNode(
662  act_names.first, act_names.second._action, true, &action_obj_params);
663 
664  const std::string & task = act_names.second._task;
665  std::string act_name = act_names.first;
666 
672  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
673  action_obj_params.get<bool>("isObjectAction"))
674  {
675  for (const auto & [moose_obj_name, obj] : _factory.registeredObjects())
676  {
677  auto moose_obj_params = obj->buildParameters();
682  const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
683 
684  // See if the current Moose Object syntax belongs under this Action's block
685  if ((buildable_types.empty() || // Not restricted
686  std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
687  buildable_types.end()) && // Restricted but found
688  moose_obj_params.have_parameter<std::string>("_moose_base") && // Has a registered base
689  _syntax.verifyMooseObjectTask(moose_obj_params.get<std::string>("_moose_base"),
690  task) && // and that base is associated
691  action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
692  )
693  {
694  std::string name;
695  size_t pos = 0;
696  bool is_action_params = false;
697  if (act_name[act_name.size() - 1] == '*')
698  {
699  pos = act_name.size();
700 
701  if (!action_obj_params.collapseSyntaxNesting())
702  name = act_name.substr(0, pos - 1) + moose_obj_name;
703  else
704  {
705  name = act_name.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
706  is_action_params = true;
707  }
708  }
709  else
710  {
711  name = act_name + "/<type>/" + moose_obj_name;
712  }
713 
714  moose_obj_params.set<std::string>("type") = moose_obj_name;
715 
716  _syntax_formatter->insertNode(name, moose_obj_name, is_action_params, &moose_obj_params);
717  }
718  }
719  }
720  }
721 
722  // Do not change to _console, we need this printed to the stdout in all cases
723  Moose::out << _syntax_formatter->print(search_string) << std::flush;
724 }
725 
726 /**************************************************************************************************
727  **************************************************************************************************
728  * Parameter Extraction Routines *
729  **************************************************************************************************
730  **************************************************************************************************/
731 using std::string;
732 
733 // Template Specializations for retrieving special types from the input file
734 template <>
735 void Builder::setScalarParameter<RealVectorValue, RealVectorValue>(
736  const std::string & full_name,
737  const std::string & short_name,
738  InputParameters::Parameter<RealVectorValue> * param,
739  bool in_global,
740  GlobalParamsAction * global_block);
741 
742 template <>
743 void Builder::setScalarParameter<Point, Point>(const std::string & full_name,
744  const std::string & short_name,
745  InputParameters::Parameter<Point> * param,
746  bool in_global,
747  GlobalParamsAction * global_block);
748 
749 template <>
750 void Builder::setScalarParameter<RealEigenVector, RealEigenVector>(
751  const std::string & full_name,
752  const std::string & short_name,
753  InputParameters::Parameter<RealEigenVector> * param,
754  bool in_global,
755  GlobalParamsAction * global_block);
756 
757 template <>
758 void Builder::setScalarParameter<RealEigenMatrix, RealEigenMatrix>(
759  const std::string & full_name,
760  const std::string & short_name,
761  InputParameters::Parameter<RealEigenMatrix> * param,
762  bool in_global,
763  GlobalParamsAction * global_block);
764 
765 template <>
766 void Builder::setScalarParameter<PostprocessorName, PostprocessorName>(
767  const std::string & full_name,
768  const std::string & short_name,
769  InputParameters::Parameter<PostprocessorName> * param,
770  bool in_global,
771  GlobalParamsAction * global_block);
772 
773 template <>
774 void
775 Builder::setScalarParameter<MooseEnum, MooseEnum>(const std::string & full_name,
776  const std::string & short_name,
777  InputParameters::Parameter<MooseEnum> * param,
778  bool in_global,
779  GlobalParamsAction * global_block);
780 
781 template <>
782 void Builder::setScalarParameter<MultiMooseEnum, MultiMooseEnum>(
783  const std::string & full_name,
784  const std::string & short_name,
785  InputParameters::Parameter<MultiMooseEnum> * param,
786  bool in_global,
787  GlobalParamsAction * global_block);
788 
789 template <>
790 void Builder::setScalarParameter<ExecFlagEnum, ExecFlagEnum>(
791  const std::string & full_name,
792  const std::string & short_name,
793  InputParameters::Parameter<ExecFlagEnum> * param,
794  bool in_global,
795  GlobalParamsAction * global_block);
796 
797 template <>
798 void Builder::setScalarParameter<RealTensorValue, RealTensorValue>(
799  const std::string & full_name,
800  const std::string & short_name,
801  InputParameters::Parameter<RealTensorValue> * param,
802  bool in_global,
803  GlobalParamsAction * global_block);
804 
805 template <>
806 void Builder::setScalarParameter<ReporterName, std::string>(
807  const std::string & full_name,
808  const std::string & short_name,
809  InputParameters::Parameter<ReporterName> * param,
810  bool in_global,
811  GlobalParamsAction * global_block);
812 
813 // Vectors
814 template <>
815 void Builder::setVectorParameter<RealVectorValue, RealVectorValue>(
816  const std::string & full_name,
817  const std::string & short_name,
818  InputParameters::Parameter<std::vector<RealVectorValue>> * param,
819  bool in_global,
820  GlobalParamsAction * global_block);
821 
822 template <>
823 void
824 Builder::setVectorParameter<Point, Point>(const std::string & full_name,
825  const std::string & short_name,
826  InputParameters::Parameter<std::vector<Point>> * param,
827  bool in_global,
828  GlobalParamsAction * global_block);
829 
830 template <>
831 void Builder::setVectorParameter<PostprocessorName, PostprocessorName>(
832  const std::string & full_name,
833  const std::string & short_name,
834  InputParameters::Parameter<std::vector<PostprocessorName>> * param,
835  bool in_global,
836  GlobalParamsAction * global_block);
837 
838 template <>
839 void Builder::setVectorParameter<MooseEnum, MooseEnum>(
840  const std::string & full_name,
841  const std::string & short_name,
842  InputParameters::Parameter<std::vector<MooseEnum>> * param,
843  bool in_global,
844  GlobalParamsAction * global_block);
845 
846 template <>
847 void Builder::setVectorParameter<MultiMooseEnum, MultiMooseEnum>(
848  const std::string & full_name,
849  const std::string & short_name,
850  InputParameters::Parameter<std::vector<MultiMooseEnum>> * param,
851  bool in_global,
852  GlobalParamsAction * global_block);
853 
854 template <>
855 void Builder::setVectorParameter<VariableName, VariableName>(
856  const std::string & full_name,
857  const std::string & short_name,
858  InputParameters::Parameter<std::vector<VariableName>> * param,
859  bool in_global,
860  GlobalParamsAction * global_block);
861 
862 template <>
863 void Builder::setVectorParameter<ReporterName, std::string>(
864  const std::string & full_name,
865  const std::string & short_name,
866  InputParameters::Parameter<std::vector<ReporterName>> * param,
867  bool in_global,
868  GlobalParamsAction * global_block);
869 
870 template <>
871 void Builder::setVectorParameter<CLIArgString, std::string>(
872  const std::string & full_name,
873  const std::string & short_name,
874  InputParameters::Parameter<std::vector<CLIArgString>> * param,
875  bool in_global,
876  GlobalParamsAction * global_block);
877 
878 template <>
879 void Builder::setDoubleIndexParameter<Point>(
880  const std::string & full_name,
881  const std::string & short_name,
882  InputParameters::Parameter<std::vector<std::vector<Point>>> * param,
883  bool in_global,
884  GlobalParamsAction * global_block);
885 
886 void
887 Builder::extractParams(const std::string & prefix, InputParameters & p)
888 {
889  std::ostringstream error_stream;
890  static const std::string global_params_task = "set_global_params";
891  static const std::string global_params_block_name =
892  _syntax.getSyntaxByAction("GlobalParamsAction").front();
893 
894  ActionIterator act_iter = _action_wh.actionBlocksWithActionBegin(global_params_task);
895  GlobalParamsAction * global_params_block = nullptr;
896 
897  // We are grabbing only the first
898  if (act_iter != _action_wh.actionBlocksWithActionEnd(global_params_task))
899  global_params_block = dynamic_cast<GlobalParamsAction *>(*act_iter);
900 
901  // Set a pointer to the current InputParameters object being parsed so that it can be referred
902  // to
903  // in the extraction routines
904  _current_params = &p;
905  _current_error_stream = &error_stream;
906  for (const auto & it : p)
907  {
908  if (p.shouldIgnore(it.first))
909  continue;
910 
911  bool found = false;
912  bool in_global = false;
913 
914  for (const auto & param_name : p.paramAliases(it.first))
915  {
916  std::string orig_name = prefix + "/" + param_name;
917  std::string full_name = orig_name;
918 
919  // Mark parameters appearing in the input file or command line
920  auto node = root()->find(full_name);
921  if (node && node->type() == hit::NodeType::Field)
922  {
923  p.setHitNode(param_name, *node, {});
924  p.set_attributes(param_name, false);
925  // Check if we have already printed the deprecated param message.
926  // If we haven't, add it to the tracker, and print it.
927  if (!_deprec_param_tracker.count(param_name))
928  if (p.attemptPrintDeprecated(param_name))
929  _deprec_param_tracker.insert(param_name);
930  _extracted_vars.insert(
931  full_name); // Keep track of all variables extracted from the input file
932  found = true;
933  }
934  // Wait! Check the GlobalParams section
935  else if (global_params_block)
936  {
937  full_name = global_params_block_name + "/" + param_name;
938  node = root()->find(full_name);
939  if (node)
940  {
941  p.setHitNode(param_name, *node, {});
942  p.set_attributes(param_name, false);
943  _extracted_vars.insert(
944  full_name); // Keep track of all variables extracted from the input file
945  found = true;
946  in_global = true;
947  }
948  }
949  if (found)
950  {
951  if (p.isPrivate(param_name) && !in_global)
952  mooseError("The parameter '",
953  full_name,
954  "' is a private parameter and should not be used in an input file.");
955  // avoid setting the parameter
956  else if (p.isPrivate(param_name) && in_global)
957  continue;
958 
959  auto & short_name = param_name;
960  libMesh::Parameters::Value * par = MooseUtils::get(it.second);
961 
962 #define setscalarvaltype(ptype, base, range) \
963  else if (par->type() == demangle(typeid(ptype).name())) \
964  setScalarValueTypeParameter<ptype, range, base>( \
965  full_name, \
966  short_name, \
967  dynamic_cast<InputParameters::Parameter<ptype> *>(par), \
968  in_global, \
969  global_params_block)
970 #define setscalar(ptype, base) \
971  else if (par->type() == demangle(typeid(ptype).name())) \
972  setScalarParameter<ptype, base>(full_name, \
973  short_name, \
974  dynamic_cast<InputParameters::Parameter<ptype> *>(par), \
975  in_global, \
976  global_params_block)
977 #define setvector(ptype, base) \
978  else if (par->type() == demangle(typeid(std::vector<ptype>).name())) \
979  setVectorParameter<ptype, base>( \
980  full_name, \
981  short_name, \
982  dynamic_cast<InputParameters::Parameter<std::vector<ptype>> *>(par), \
983  in_global, \
984  global_params_block)
985 #define setmap(key_type, mapped_type) \
986  else if (par->type() == demangle(typeid(std::map<key_type, mapped_type>).name())) \
987  setMapParameter( \
988  full_name, \
989  short_name, \
990  dynamic_cast<InputParameters::Parameter<std::map<key_type, mapped_type>> *>(par), \
991  in_global, \
992  global_params_block)
993 #define setvectorvector(ptype) \
994  else if (par->type() == demangle(typeid(std::vector<std::vector<ptype>>).name())) \
995  setDoubleIndexParameter<ptype>( \
996  full_name, \
997  short_name, \
998  dynamic_cast<InputParameters::Parameter<std::vector<std::vector<ptype>>> *>(par), \
999  in_global, \
1000  global_params_block)
1001 #define setvectorvectorvector(ptype) \
1002  else if (par->type() == demangle(typeid(std::vector<std::vector<std::vector<ptype>>>).name())) \
1003  setTripleIndexParameter<ptype>( \
1004  full_name, \
1005  short_name, \
1006  dynamic_cast< \
1007  InputParameters::Parameter<std::vector<std::vector<std::vector<ptype>>>> *>(par), \
1008  in_global, \
1009  global_params_block)
1010 
1014  // built-ins
1015  // NOTE: Similar dynamic casting is done in InputParameters.C, please update appropriately
1016  if (false)
1017  ;
1018  setscalarvaltype(Real, double, Real);
1019  setscalarvaltype(int, int, long);
1020  setscalarvaltype(unsigned short, unsigned int, long);
1021  setscalarvaltype(long, int, long);
1022  setscalarvaltype(unsigned int, unsigned int, long);
1023  setscalarvaltype(unsigned long, unsigned int, long);
1024  setscalarvaltype(long int, int64_t, long);
1025  setscalarvaltype(unsigned long long, unsigned int, long);
1026 
1027  setscalar(bool, bool);
1028  setscalar(SubdomainID, int);
1029  setscalar(BoundaryID, int);
1030 
1031  // string and string-subclass types
1032  setscalar(string, string);
1033  setscalar(SubdomainName, string);
1034  setscalar(BoundaryName, string);
1035  setscalar(FileName, string);
1036  setscalar(MeshFileName, string);
1037  setscalar(MatrixFileName, string);
1038  setscalar(FileNameNoExtension, string);
1039  setscalar(RelativeFileName, string);
1040  setscalar(DataFileName, string);
1041  setscalar(ComponentName, string);
1042  setscalar(PhysicsName, string);
1043  setscalar(OutFileBase, string);
1044  setscalar(VariableName, string);
1045  setscalar(NonlinearVariableName, string);
1046  setscalar(LinearVariableName, string);
1047  setscalar(SolverVariableName, string);
1048  setscalar(AuxVariableName, string);
1049  setscalar(FunctionName, string);
1050  setscalar(ConvergenceName, string);
1051  setscalar(MeshDivisionName, string);
1052  setscalar(UserObjectName, string);
1053  setscalar(VectorPostprocessorName, string);
1054  setscalar(IndicatorName, string);
1055  setscalar(MarkerName, string);
1056  setscalar(MultiAppName, string);
1057  setscalar(OutputName, string);
1058  setscalar(MaterialPropertyName, string);
1059  setscalar(MooseFunctorName, string);
1060  setscalar(MaterialName, string);
1061  setscalar(DistributionName, string);
1062  setscalar(PositionsName, string);
1063  setscalar(SamplerName, string);
1064  setscalar(TagName, string);
1065  setscalar(TimesName, string);
1066  setscalar(MeshGeneratorName, string);
1067  setscalar(ExtraElementIDName, string);
1068  setscalar(PostprocessorName, PostprocessorName);
1069  setscalar(ExecutorName, string);
1070  setscalar(NonlinearSystemName, string);
1071  setscalar(LinearSystemName, string);
1072  setscalar(SolverSystemName, string);
1073  setscalar(CLIArgString, string);
1074 #ifdef MOOSE_MFEM_ENABLED
1075  setscalar(MFEMScalarCoefficientName, string);
1076  setscalar(MFEMVectorCoefficientName, string);
1077  setscalar(MFEMMatrixCoefficientName, string);
1078 #endif
1079 
1080  // Moose Compound Scalars
1081  setscalar(RealVectorValue, RealVectorValue);
1082  setscalar(Point, Point);
1083  setscalar(RealEigenVector, RealEigenVector);
1084  setscalar(RealEigenMatrix, RealEigenMatrix);
1085  setscalar(MooseEnum, MooseEnum);
1086  setscalar(MultiMooseEnum, MultiMooseEnum);
1087  setscalar(RealTensorValue, RealTensorValue);
1088  setscalar(ExecFlagEnum, ExecFlagEnum);
1089  setscalar(ReporterName, string);
1090  setscalar(ReporterValueName, string);
1091  setscalar(ParsedFunctionExpression, string);
1092 
1093  // vector types
1094  setvector(bool, bool);
1095  setvector(Real, double);
1096  setvector(int, int);
1097  setvector(long, int);
1098  setvector(unsigned int, int);
1099 
1100 // We need to be able to parse 8-byte unsigned types when
1101 // libmesh is configured --with-dof-id-bytes=8. Officially,
1102 // libmesh uses uint64_t in that scenario, which is usually
1103 // equivalent to 'unsigned long long'. Note that 'long long'
1104 // has been around since C99 so most C++ compilers support it,
1105 // but presumably uint64_t is the "most standard" way to get a
1106 // 64-bit unsigned type, so we'll stick with that here.
1107 #if LIBMESH_DOF_ID_BYTES == 8
1108  setvector(uint64_t, int);
1109 #endif
1110 
1111  setvector(SubdomainID, int);
1112  setvector(BoundaryID, int);
1113  setvector(RealVectorValue, RealVectorValue);
1114  setvector(Point, Point);
1115  setvector(MooseEnum, MooseEnum);
1116  setvector(MultiMooseEnum, MultiMooseEnum);
1117 
1118  setvector(string, string);
1119  setvector(FileName, string);
1120  setvector(FileNameNoExtension, string);
1121  setvector(RelativeFileName, string);
1122  setvector(DataFileName, string);
1123  setvector(MeshFileName, string);
1124  setvector(MatrixFileName, string);
1125  setvector(SubdomainName, string);
1126  setvector(BoundaryName, string);
1127  setvector(NonlinearVariableName, string);
1128  setvector(LinearVariableName, string);
1129  setvector(SolverVariableName, string);
1130  setvector(AuxVariableName, string);
1131  setvector(FunctionName, string);
1132  setvector(ConvergenceName, string);
1133  setvector(MeshDivisionName, string);
1134  setvector(UserObjectName, string);
1135  setvector(IndicatorName, string);
1136  setvector(MarkerName, string);
1137  setvector(MultiAppName, string);
1138  setvector(PostprocessorName, PostprocessorName);
1139  setvector(VectorPostprocessorName, string);
1140  setvector(OutputName, string);
1141  setvector(MaterialPropertyName, string);
1142  setvector(MooseFunctorName, string);
1143  setvector(MaterialName, string);
1144  setvector(DistributionName, string);
1145  setvector(SamplerName, string);
1146  setvector(TagName, string);
1147  setvector(VariableName, VariableName);
1148  setvector(MeshGeneratorName, string);
1149  setvector(ExtraElementIDName, string);
1150  setvector(ReporterName, string);
1151  setvector(CLIArgString, string);
1152  setvector(ComponentName, string);
1153  setvector(PhysicsName, string);
1154  setvector(PositionsName, string);
1155  setvector(TimesName, string);
1156  setvector(ReporterValueName, string);
1157  setvector(ExecutorName, string);
1158  setvector(NonlinearSystemName, string);
1159  setvector(LinearSystemName, string);
1160  setvector(SolverSystemName, string);
1161 #ifdef MOOSE_MFEM_ENABLED
1162  setvector(MFEMScalarCoefficientName, string);
1163  setvector(MFEMVectorCoefficientName, string);
1164  setvector(MFEMMatrixCoefficientName, string);
1165 #endif
1166 
1167  // map types
1168  setmap(string, unsigned int);
1169  setmap(string, Real);
1170  setmap(string, string);
1171  setmap(unsigned int, unsigned int);
1172  setmap(unsigned long, unsigned int);
1173  setmap(unsigned long long, unsigned int);
1174 
1175  // Double indexed types
1176  setvectorvector(Real);
1177  setvectorvector(int);
1178  setvectorvector(long);
1179  setvectorvector(unsigned int);
1180  setvectorvector(unsigned long long);
1181 
1182 // See vector type explanation
1183 #if LIBMESH_DOF_ID_BYTES == 8
1184  setvectorvector(uint64_t);
1185 #endif
1186 
1187  setvectorvector(SubdomainID);
1188  setvectorvector(BoundaryID);
1189  setvectorvector(Point);
1190  setvectorvector(string);
1191  setvectorvector(FileName);
1192  setvectorvector(FileNameNoExtension);
1193  setvectorvector(DataFileName);
1194  setvectorvector(MeshFileName);
1195  setvectorvector(MatrixFileName);
1196  setvectorvector(SubdomainName);
1197  setvectorvector(BoundaryName);
1198  setvectorvector(VariableName);
1199  setvectorvector(NonlinearVariableName);
1200  setvectorvector(LinearVariableName);
1201  setvectorvector(SolverVariableName);
1202  setvectorvector(AuxVariableName);
1203  setvectorvector(FunctionName);
1204  setvectorvector(ConvergenceName);
1205  setvectorvector(UserObjectName);
1206  setvectorvector(IndicatorName);
1207  setvectorvector(MarkerName);
1208  setvectorvector(MultiAppName);
1209  setvectorvector(PostprocessorName);
1210  setvectorvector(VectorPostprocessorName);
1211  setvectorvector(MarkerName);
1212  setvectorvector(OutputName);
1213  setvectorvector(MaterialPropertyName);
1214  setvectorvector(MooseFunctorName);
1215  setvectorvector(MaterialName);
1216  setvectorvector(DistributionName);
1217  setvectorvector(SamplerName);
1218  setvectorvector(TagName);
1219 #ifdef MOOSE_MFEM_ENABLED
1220  setvectorvector(MFEMScalarCoefficientName);
1221  setvectorvector(MFEMVectorCoefficientName);
1222  setvectorvector(MFEMMatrixCoefficientName);
1223 #endif
1224 
1225  // Triple indexed types
1226  setvectorvectorvector(Real);
1227  setvectorvectorvector(int);
1228  setvectorvectorvector(long);
1229  setvectorvectorvector(unsigned int);
1230  setvectorvectorvector(unsigned long long);
1231 
1232 // See vector type explanation
1233 #if LIBMESH_DOF_ID_BYTES == 8
1234  setvectorvectorvector(uint64_t);
1235 #endif
1236 
1237  setvectorvectorvector(SubdomainID);
1238  setvectorvectorvector(BoundaryID);
1239  setvectorvectorvector(string);
1240  setvectorvectorvector(FileName);
1241  setvectorvectorvector(FileNameNoExtension);
1242  setvectorvectorvector(DataFileName);
1243  setvectorvectorvector(MeshFileName);
1244  setvectorvectorvector(MatrixFileName);
1245  setvectorvectorvector(SubdomainName);
1246  setvectorvectorvector(BoundaryName);
1247  setvectorvectorvector(VariableName);
1248  setvectorvectorvector(NonlinearVariableName);
1249  setvectorvectorvector(LinearVariableName);
1250  setvectorvectorvector(AuxVariableName);
1251  setvectorvectorvector(FunctionName);
1252  setvectorvectorvector(UserObjectName);
1253  setvectorvectorvector(IndicatorName);
1254  setvectorvectorvector(MarkerName);
1255  setvectorvectorvector(MultiAppName);
1256  setvectorvectorvector(PostprocessorName);
1257  setvectorvectorvector(VectorPostprocessorName);
1258  setvectorvectorvector(MarkerName);
1259  setvectorvectorvector(OutputName);
1260  setvectorvectorvector(MaterialPropertyName);
1261  setvectorvectorvector(MooseFunctorName);
1262  setvectorvectorvector(MaterialName);
1263  setvectorvectorvector(DistributionName);
1264  setvectorvectorvector(SamplerName);
1265  else
1266  {
1267  mooseError("unsupported type '", par->type(), "' for input parameter '", full_name, "'");
1268  }
1269 
1270 #undef setscalarValueType
1271 #undef setscalar
1272 #undef setvector
1273 #undef setvectorvectorvector
1274 #undef setvectorvector
1275 #undef setmap
1276  break;
1277  }
1278  }
1279 
1280  if (!found)
1281  {
1288  // In the case where we have OutFileName but it wasn't actually found in the input filename,
1289  // we will populate it with the actual parsed filename which is available here in the
1290  // parser.
1291 
1292  InputParameters::Parameter<OutFileBase> * scalar_p =
1293  dynamic_cast<InputParameters::Parameter<OutFileBase> *>(MooseUtils::get(it.second));
1294  if (scalar_p)
1295  {
1296  std::string input_file_name = getPrimaryFileName();
1297  mooseAssert(input_file_name != "", "Input Filename is nullptr");
1298  size_t pos = input_file_name.find_last_of('.');
1299  mooseAssert(pos != std::string::npos, "Unable to determine suffix of input file name");
1300  scalar_p->set() = input_file_name.substr(0, pos) + "_out";
1301  p.set_attributes(it.first, false);
1302  }
1303  }
1304  }
1305 
1306  // All of the parameters for this object have been extracted. See if there are any errors
1307  if (!error_stream.str().empty())
1308  mooseError(_errmsg + error_stream.str());
1309 
1310  // Here we will see if there are any auto build vectors that need to be created
1311  std::map<std::string, std::pair<std::string, std::string>> auto_build_vectors =
1312  p.getAutoBuildVectors();
1313  for (const auto & it : auto_build_vectors)
1314  {
1315  // We'll autogenerate values iff the requested vector is not valid but both the base and
1316  // number
1317  // are valid
1318  const std::string & base_name = it.second.first;
1319  const std::string & num_repeat = it.second.second;
1320 
1321  if (!p.isParamValid(it.first) && p.isParamValid(base_name) && p.isParamValid(num_repeat))
1322  {
1323  unsigned int vec_size = p.get<unsigned int>(num_repeat);
1324  const std::string & name = p.get<std::string>(base_name);
1325 
1326  std::vector<VariableName> variable_names(vec_size);
1327  for (unsigned int i = 0; i < vec_size; ++i)
1328  {
1329  std::ostringstream oss;
1330  oss << name << i;
1331  variable_names[i] = oss.str();
1332  }
1333 
1334  // Finally set the autogenerated vector into the InputParameters object
1335  p.set<std::vector<VariableName>>(it.first) = variable_names;
1336  }
1337  }
1338 }
1339 
1340 template <typename T>
1341 bool
1342 toBool(const std::string & /*s*/, T & /*val*/)
1343 {
1344  return false;
1345 }
1346 
1347 template <>
1348 bool
1349 toBool<bool>(const std::string & s, bool & val)
1350 {
1351  return hit::toBool(s, &val);
1352 }
1353 
1354 template <typename T, typename Base>
1355 void
1356 Builder::setScalarParameter(const std::string & full_name,
1357  const std::string & short_name,
1358  InputParameters::Parameter<T> * param,
1359  bool in_global,
1360  GlobalParamsAction * global_block)
1361 {
1362  try
1363  {
1364  param->set() = root()->param<Base>(full_name);
1365  }
1366  catch (hit::Error & err)
1367  {
1368  auto strval = root()->param<std::string>(full_name);
1369 
1370  // handle the case where the user put a number inside quotes
1371  auto & t = typeid(T);
1372  if (t == typeid(int) || t == typeid(unsigned int) || t == typeid(SubdomainID) ||
1373  t == typeid(BoundaryID) || t == typeid(double))
1374  {
1375  try
1376  {
1377  param->set() = MooseUtils::convert<T>(strval, true);
1378  }
1379  catch (std::invalid_argument & /*e*/)
1380  {
1381  const std::string format_type = (t == typeid(double)) ? "float" : "integer";
1382  _errmsg += hit::errormsg(root()->find(full_name),
1383  "invalid ",
1384  format_type,
1385  " syntax for parameter: ",
1386  full_name,
1387  "=",
1388  strval) +
1389  "\n";
1390  }
1391  }
1392  else if (t == typeid(bool))
1393  {
1394  bool isbool = toBool(strval, param->set());
1395  if (!isbool)
1396  _errmsg += hit::errormsg(root()->find(full_name),
1397  "invalid boolean syntax for parameter: ",
1398  full_name,
1399  "=",
1400  strval) +
1401  "\n";
1402  }
1403  else
1404  throw;
1405  }
1406 
1407  if (in_global)
1408  {
1409  global_block->remove(short_name);
1410  global_block->setScalarParam<T>(short_name) = param->get();
1411  }
1412 }
1413 
1414 template <typename T, typename UP_T, typename Base>
1415 void
1416 Builder::setScalarValueTypeParameter(const std::string & full_name,
1417  const std::string & short_name,
1418  InputParameters::Parameter<T> * param,
1419  bool in_global,
1420  GlobalParamsAction * global_block)
1421 {
1422  setScalarParameter<T, Base>(full_name, short_name, param, in_global, global_block);
1423 
1424  // If this is a range checked param, we need to make sure that the value falls within the
1425  // requested range
1426  mooseAssert(_current_params, "Current params is nullptr");
1427 
1428  _current_params->rangeCheck<T, UP_T>(full_name, short_name, param, *_current_error_stream);
1429 }
1430 
1431 template <typename T, typename Base>
1432 void
1433 Builder::setVectorParameter(const std::string & full_name,
1434  const std::string & short_name,
1435  InputParameters::Parameter<std::vector<T>> * param,
1436  bool in_global,
1437  GlobalParamsAction * global_block)
1438 {
1439  std::vector<T> vec;
1440  if (root()->find(full_name))
1441  {
1442  try
1443  {
1444  auto tmp = root()->param<std::vector<Base>>(full_name);
1445  for (auto val : tmp)
1446  vec.push_back(val);
1447  }
1448  catch (hit::Error & err)
1449  {
1450  _errmsg += hit::errormsg(root()->find(full_name), err.what()) + "\n";
1451  return;
1452  }
1453  }
1454 
1455  param->set() = vec;
1456 
1457  if (in_global)
1458  {
1459  global_block->remove(short_name);
1460  global_block->setVectorParam<T>(short_name).resize(param->get().size());
1461  for (unsigned int i = 0; i < vec.size(); ++i)
1462  global_block->setVectorParam<T>(short_name)[i] = param->get()[i];
1463  }
1464 }
1465 
1466 template <typename KeyType, typename MappedType>
1467 void
1468 Builder::setMapParameter(const std::string & full_name,
1469  const std::string & short_name,
1470  InputParameters::Parameter<std::map<KeyType, MappedType>> * param,
1471  bool in_global,
1472  GlobalParamsAction * global_block)
1473 {
1474  std::map<KeyType, MappedType> the_map;
1475  if (root()->find(full_name))
1476  {
1477  try
1478  {
1479  const auto & string_vec = root()->param<std::vector<std::string>>(full_name);
1480  auto it = string_vec.begin();
1481  while (it != string_vec.end())
1482  {
1483  const auto & string_key = *it;
1484  ++it;
1485  if (it == string_vec.end())
1486  {
1487  _errmsg +=
1488  hit::errormsg(root()->find(full_name),
1489  "odd number of entries in string vector for map parameter: ",
1490  full_name,
1491  ". There must be "
1492  "an even number or else you will end up with a key without a value!") +
1493  "\n";
1494  return;
1495  }
1496  const auto & string_value = *it;
1497  ++it;
1498 
1499  std::pair<KeyType, MappedType> pr;
1500  // key
1501  try
1502  {
1503  pr.first = MooseUtils::convert<KeyType>(string_key, true);
1504  }
1505  catch (std::invalid_argument & /*e*/)
1506  {
1507  _errmsg += hit::errormsg(root()->find(full_name),
1508  "invalid ",
1509  demangle(typeid(KeyType).name()),
1510  " syntax for map parameter ",
1511  full_name,
1512  " key: ",
1513  string_key) +
1514  "\n";
1515  return;
1516  }
1517  // value
1518  try
1519  {
1520  pr.second = MooseUtils::convert<MappedType>(string_value, true);
1521  }
1522  catch (std::invalid_argument & /*e*/)
1523  {
1524  _errmsg += hit::errormsg(root()->find(full_name),
1525  "invalid ",
1526  demangle(typeid(MappedType).name()),
1527  " syntax for map parameter ",
1528  full_name,
1529  " value: ",
1530  string_value) +
1531  "\n";
1532  return;
1533  }
1534 
1535  auto insert_pr = the_map.insert(std::move(pr));
1536  if (!insert_pr.second)
1537  {
1538  _errmsg += hit::errormsg(root()->find(full_name),
1539  "Duplicate map entry for map parameter: ",
1540  full_name,
1541  ". The key ",
1542  string_key,
1543  " appears multiple times.") +
1544  "\n";
1545  return;
1546  }
1547  }
1548  }
1549  catch (hit::Error & err)
1550  {
1551  _errmsg += hit::errormsg(root()->find(full_name), err.what()) + "\n";
1552  return;
1553  }
1554  }
1555 
1556  param->set() = the_map;
1557 
1558  if (in_global)
1559  {
1560  global_block->remove(short_name);
1561  auto & global_map = global_block->setParam<std::map<KeyType, MappedType>>(short_name);
1562  for (const auto & pair : the_map)
1563  global_map.insert(pair);
1564  }
1565 }
1566 
1567 template <typename T>
1568 void
1569 Builder::setDoubleIndexParameter(const std::string & full_name,
1570  const std::string & short_name,
1571  InputParameters::Parameter<std::vector<std::vector<T>>> * param,
1572  bool in_global,
1573  GlobalParamsAction * global_block)
1574 {
1575  auto & value = param->set();
1576 
1577  // Get the full string assigned to the variable full_name
1578  const auto value_string = MooseUtils::trim(root()->param<std::string>(full_name));
1579 
1580  // split vector at delim ;
1581  // NOTE: the substrings are _not_ of type T yet
1582  // The zero length here is intentional, as we want something like:
1583  // "abc; 123;" -> ["abc", "123", ""]
1584  std::vector<std::string> outer_string_vectors;
1585  // With split, we will get a single entry if the string value is empty. However,
1586  // that should represent an empty vector<vector>. Therefore, only split if we have values.
1587  if (!value_string.empty())
1588  outer_string_vectors = MooseUtils::split(value_string, ";");
1589 
1590  const auto outer_vector_size = outer_string_vectors.size();
1591  value.resize(outer_vector_size);
1592 
1593  for (const auto j : index_range(outer_string_vectors))
1594  if (!MooseUtils::tokenizeAndConvert<T>(outer_string_vectors[j], value[j]))
1595  {
1596  _errmsg +=
1597  hit::errormsg(root()->find(full_name), "invalid format for parameter ", full_name) + "\n";
1598  return;
1599  }
1600 
1601  if (in_global)
1602  {
1603  global_block->remove(short_name);
1604  global_block->setDoubleIndexParam<T>(short_name).resize(outer_vector_size);
1605  for (const auto j : make_range(outer_vector_size))
1606  {
1607  global_block->setDoubleIndexParam<T>(short_name)[j].resize(value[j].size());
1608  for (const auto i : index_range(value[j]))
1609  global_block->setDoubleIndexParam<T>(short_name)[j][i] = value[j][i];
1610  }
1611  }
1612 }
1613 
1614 template <typename T>
1615 void
1617  const std::string & full_name,
1618  const std::string & short_name,
1619  InputParameters::Parameter<std::vector<std::vector<std::vector<T>>>> * param,
1620  bool in_global,
1621  GlobalParamsAction * global_block)
1622 {
1623  // Get the full string assigned to the variable full_name
1624  const std::string buffer_raw = root()->param<std::string>(full_name);
1625  // In case the parameter is empty
1626  if (buffer_raw.find_first_not_of(' ', 0) == std::string::npos)
1627  return;
1628 
1629  // Add a space between neighboring delim's, before the first delim if nothing is ahead of it, and
1630  // after the last delim if nothing is behind it.
1631  std::string buffer;
1632  buffer.push_back(buffer_raw[0]);
1633  if (buffer[0] == '|' || buffer[0] == ';')
1634  buffer = ' ' + buffer;
1635  for (std::string::size_type i = 1; i < buffer_raw.size(); i++)
1636  {
1637  if ((buffer_raw[i - 1] == '|' || buffer_raw[i - 1] == ';') &&
1638  (buffer_raw[i] == '|' || buffer_raw[i] == ';'))
1639  buffer.push_back(' ');
1640  buffer.push_back(buffer_raw[i]);
1641  }
1642  if (buffer.back() == '|' || buffer.back() == ';')
1643  buffer.push_back(' ');
1644 
1645  // split vector at delim | to get a series of 2D subvectors
1646  std::vector<std::string> first_tokenized_vector;
1647  std::vector<std::vector<std::string>> second_tokenized_vector;
1648  MooseUtils::tokenize(buffer, first_tokenized_vector, 1, "|");
1649  param->set().resize(first_tokenized_vector.size());
1650  second_tokenized_vector.resize(first_tokenized_vector.size());
1651  for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1652  {
1653  // Identify empty subvector first
1654  if (first_tokenized_vector[j].find_first_not_of(' ', 0) == std::string::npos)
1655  {
1656  param->set()[j].resize(0);
1657  continue;
1658  }
1659  // split each 2D subvector at delim ; to get 1D sub-subvectors
1660  // NOTE: the 1D sub-subvectors are _not_ of type T yet
1661  MooseUtils::tokenize(first_tokenized_vector[j], second_tokenized_vector[j], 1, ";");
1662  param->set()[j].resize(second_tokenized_vector[j].size());
1663  for (unsigned k = 0; k < second_tokenized_vector[j].size(); ++k)
1664  if (!MooseUtils::tokenizeAndConvert<T>(second_tokenized_vector[j][k], param->set()[j][k]))
1665  {
1666  _errmsg +=
1667  hit::errormsg(root()->find(full_name), "invalid format for parameter ", full_name) +
1668  "\n";
1669  return;
1670  }
1671  }
1672 
1673  if (in_global)
1674  {
1675  global_block->remove(short_name);
1676  global_block->setTripleIndexParam<T>(short_name).resize(first_tokenized_vector.size());
1677  for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1678  {
1679  global_block->setTripleIndexParam<T>(short_name)[j].resize(second_tokenized_vector[j].size());
1680  for (unsigned k = 0; k < second_tokenized_vector[j].size(); ++k)
1681  {
1682  global_block->setTripleIndexParam<T>(short_name)[j][k].resize(param->get()[j][k].size());
1683  for (unsigned int i = 0; i < param->get()[j][k].size(); ++i)
1684  global_block->setTripleIndexParam<T>(short_name)[j][k][i] = param->get()[j][k][i];
1685  }
1686  }
1687  }
1688 }
1689 
1690 template <typename T>
1691 void
1692 Builder::setScalarComponentParameter(const std::string & full_name,
1693  const std::string & short_name,
1694  InputParameters::Parameter<T> * param,
1695  bool in_global,
1696  GlobalParamsAction * global_block)
1697 {
1698  std::vector<double> vec;
1699  try
1700  {
1701  vec = root()->param<std::vector<double>>(full_name);
1702  }
1703  catch (hit::Error & err)
1704  {
1705  _errmsg += hit::errormsg(root()->find(full_name), err.what()) + "\n";
1706  return;
1707  }
1708 
1709  if (vec.size() != LIBMESH_DIM)
1710  {
1711  _errmsg += hit::errormsg(root()->find(full_name),
1712  "wrong number of values in scalar component parameter ",
1713  full_name,
1714  ": ",
1715  short_name,
1716  " was given ",
1717  vec.size(),
1718  " components but should have ",
1719  LIBMESH_DIM) +
1720  "\n";
1721  return;
1722  }
1723 
1724  T value;
1725  for (unsigned int i = 0; i < vec.size(); ++i)
1726  value(i) = Real(vec[i]);
1727 
1728  param->set() = value;
1729  if (in_global)
1730  {
1731  global_block->remove(short_name);
1732  global_block->setScalarParam<T>(short_name) = value;
1733  }
1734 }
1735 
1736 template <typename T>
1737 void
1738 Builder::setVectorComponentParameter(const std::string & full_name,
1739  const std::string & short_name,
1740  InputParameters::Parameter<std::vector<T>> * param,
1741  bool in_global,
1742  GlobalParamsAction * global_block)
1743 {
1744  std::vector<double> vec;
1745  try
1746  {
1747  vec = root()->param<std::vector<double>>(full_name);
1748  }
1749  catch (hit::Error & err)
1750  {
1751  _errmsg += hit::errormsg(root()->find(full_name), err.what()) + "\n";
1752  return;
1753  }
1754 
1755  if (vec.size() % LIBMESH_DIM)
1756  {
1757  _errmsg += hit::errormsg(root()->find(full_name),
1758  "wrong number of values in vector component parameter ",
1759  full_name,
1760  ": size ",
1761  vec.size(),
1762  " is not a multiple of ",
1763  LIBMESH_DIM) +
1764  "\n";
1765  return;
1766  }
1767 
1768  std::vector<T> values;
1769  for (unsigned int i = 0; i < vec.size() / LIBMESH_DIM; ++i)
1770  {
1771  T value;
1772  for (int j = 0; j < LIBMESH_DIM; ++j)
1773  value(j) = Real(vec[i * LIBMESH_DIM + j]);
1774  values.push_back(value);
1775  }
1776 
1777  param->set() = values;
1778 
1779  if (in_global)
1780  {
1781  global_block->remove(short_name);
1782  global_block->setVectorParam<T>(short_name).resize(vec.size(), values[0]);
1783  for (unsigned int i = 0; i < vec.size() / LIBMESH_DIM; ++i)
1784  global_block->setVectorParam<T>(short_name)[i] = values[0];
1785  }
1786 }
1787 
1788 template <typename T>
1789 void
1791  const std::string & full_name,
1792  const std::string & short_name,
1793  InputParameters::Parameter<std::vector<std::vector<T>>> * param,
1794  bool in_global,
1795  GlobalParamsAction * global_block)
1796 {
1797  // Get the full string assigned to the variable full_name
1798  std::string buffer = root()->param<std::string>(full_name);
1799 
1800  // split vector at delim ;
1801  // NOTE: the substrings are _not_ of type T yet
1802  std::vector<std::string> first_tokenized_vector;
1803  MooseUtils::tokenize(buffer, first_tokenized_vector, 1, ";");
1804  param->set().resize(first_tokenized_vector.size());
1805 
1806  // get a vector<vector<double>> first
1807  std::vector<std::vector<double>> vecvec(first_tokenized_vector.size());
1808  for (unsigned j = 0; j < vecvec.size(); ++j)
1809  if (!MooseUtils::tokenizeAndConvert<double>(first_tokenized_vector[j], vecvec[j]))
1810  {
1811  _errmsg +=
1812  hit::errormsg(root()->find(full_name), "invalid format for parameter ", full_name) + "\n";
1813  return;
1814  }
1815 
1816  for (const auto & vec : vecvec)
1817  if (vec.size() % LIBMESH_DIM)
1818  {
1819  _errmsg +=
1820  hit::errormsg(root()->find(full_name),
1821  "wrong number of values in double-indexed vector component parameter ",
1822  full_name,
1823  ": size of subcomponent ",
1824  vec.size(),
1825  " is not a multiple of ",
1826  LIBMESH_DIM) +
1827  "\n";
1828  return;
1829  }
1830 
1831  // convert vector<vector<double>> to vector<vector<T>>
1832  std::vector<std::vector<T>> values(vecvec.size());
1833  for (unsigned int id_vec = 0; id_vec < vecvec.size(); ++id_vec)
1834  for (unsigned int i = 0; i < vecvec[id_vec].size() / LIBMESH_DIM; ++i)
1835  {
1836  T value;
1837  for (int j = 0; j < LIBMESH_DIM; ++j)
1838  value(j) = Real(vecvec[id_vec][i * LIBMESH_DIM + j]);
1839  values[id_vec].push_back(value);
1840  }
1841 
1842  param->set() = values;
1843 
1844  if (in_global)
1845  {
1846  global_block->remove(short_name);
1847  global_block->setDoubleIndexParam<T>(short_name).resize(vecvec.size());
1848  for (unsigned j = 0; j < vecvec.size(); ++j)
1849  {
1850  global_block->setDoubleIndexParam<T>(short_name)[j].resize(param->get()[j].size() /
1851  LIBMESH_DIM);
1852  for (unsigned int i = 0; i < param->get()[j].size() / LIBMESH_DIM; ++i)
1853  global_block->setDoubleIndexParam<T>(short_name)[j][i] = values[j][i];
1854  }
1855  }
1856 }
1857 
1858 template <>
1859 void
1860 Builder::setScalarParameter<RealVectorValue, RealVectorValue>(
1861  const std::string & full_name,
1862  const std::string & short_name,
1863  InputParameters::Parameter<RealVectorValue> * param,
1864  bool in_global,
1865  GlobalParamsAction * global_block)
1866 {
1867  setScalarComponentParameter(full_name, short_name, param, in_global, global_block);
1868 }
1869 
1870 template <>
1871 void
1872 Builder::setScalarParameter<Point, Point>(const std::string & full_name,
1873  const std::string & short_name,
1874  InputParameters::Parameter<Point> * param,
1875  bool in_global,
1876  GlobalParamsAction * global_block)
1877 {
1878  setScalarComponentParameter(full_name, short_name, param, in_global, global_block);
1879 }
1880 
1881 template <>
1882 void
1883 Builder::setScalarParameter<RealEigenVector, RealEigenVector>(
1884  const std::string & full_name,
1885  const std::string & short_name,
1886  InputParameters::Parameter<RealEigenVector> * param,
1887  bool in_global,
1888  GlobalParamsAction * global_block)
1889 {
1890  std::vector<double> vec;
1891  try
1892  {
1893  vec = root()->param<std::vector<double>>(full_name);
1894  }
1895  catch (hit::Error & err)
1896  {
1897  _errmsg += hit::errormsg(root()->find(full_name), err.what()) + "\n";
1898  return;
1899  }
1900 
1901  RealEigenVector value(vec.size());
1902  for (unsigned int i = 0; i < vec.size(); ++i)
1903  value(i) = Real(vec[i]);
1904 
1905  param->set() = value;
1906  if (in_global)
1907  {
1908  global_block->remove(short_name);
1909  global_block->setScalarParam<RealEigenVector>(short_name) = value;
1910  }
1911 }
1912 
1913 template <>
1914 void
1915 Builder::setScalarParameter<RealEigenMatrix, RealEigenMatrix>(
1916  const std::string & full_name,
1917  const std::string & short_name,
1918  InputParameters::Parameter<RealEigenMatrix> * param,
1919  bool in_global,
1920  GlobalParamsAction * global_block)
1921 {
1922  // Get the full string assigned to the variable full_name
1923  std::string buffer = root()->param<std::string>(full_name);
1924 
1925  // split vector at delim ;
1926  // NOTE: the substrings are _not_ of type T yet
1927  std::vector<std::string> first_tokenized_vector;
1928  MooseUtils::tokenize(buffer, first_tokenized_vector, 1, ";");
1929 
1930  std::vector<std::vector<Real>> values(first_tokenized_vector.size());
1931 
1932  for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1933  {
1934  if (!MooseUtils::tokenizeAndConvert<Real>(first_tokenized_vector[j], values[j]))
1935  {
1936  _errmsg +=
1937  hit::errormsg(root()->find(full_name), "invalid format for parameter ", full_name) + "\n";
1938  return;
1939  }
1940  if (j != 0 && values[j].size() != values[0].size())
1941  {
1942  _errmsg +=
1943  hit::errormsg(root()->find(full_name), "invalid format for parameter ", full_name) + "\n";
1944  return;
1945  }
1946  }
1947 
1948  RealEigenMatrix value(values.size(), values[0].size());
1949  for (unsigned int i = 0; i < values.size(); ++i)
1950  for (unsigned int j = 0; j < values[i].size(); ++j)
1951  value(i, j) = values[i][j];
1952 
1953  param->set() = value;
1954  if (in_global)
1955  {
1956  global_block->remove(short_name);
1957  global_block->setScalarParam<RealEigenMatrix>(short_name) = value;
1958  }
1959 }
1960 
1961 template <>
1962 void
1963 Builder::setScalarParameter<MooseEnum, MooseEnum>(const std::string & full_name,
1964  const std::string & short_name,
1965  InputParameters::Parameter<MooseEnum> * param,
1966  bool in_global,
1967  GlobalParamsAction * global_block)
1968 {
1969  MooseEnum current_param = param->get();
1970 
1971  std::string value = root()->param<std::string>(full_name);
1972 
1973  param->set() = value;
1974  if (in_global)
1975  {
1976  global_block->remove(short_name);
1977  global_block->setScalarParam<MooseEnum>(short_name) = current_param;
1978  }
1979 }
1980 
1981 template <>
1982 void
1983 Builder::setScalarParameter<MultiMooseEnum, MultiMooseEnum>(
1984  const std::string & full_name,
1985  const std::string & short_name,
1986  InputParameters::Parameter<MultiMooseEnum> * param,
1987  bool in_global,
1988  GlobalParamsAction * global_block)
1989 {
1990  MultiMooseEnum current_param = param->get();
1991 
1992  auto vec = root()->param<std::vector<std::string>>(full_name);
1993 
1994  std::string raw_values;
1995  for (unsigned int i = 0; i < vec.size(); ++i)
1996  raw_values += ' ' + vec[i];
1997 
1998  param->set() = raw_values;
1999 
2000  if (in_global)
2001  {
2002  global_block->remove(short_name);
2003  global_block->setScalarParam<MultiMooseEnum>(short_name) = current_param;
2004  }
2005 }
2006 
2007 template <>
2008 void
2009 Builder::setScalarParameter<ExecFlagEnum, ExecFlagEnum>(
2010  const std::string & full_name,
2011  const std::string & short_name,
2012  InputParameters::Parameter<ExecFlagEnum> * param,
2013  bool in_global,
2014  GlobalParamsAction * global_block)
2015 {
2016  ExecFlagEnum current_param = param->get();
2017  auto vec = root()->param<std::vector<std::string>>(full_name);
2018 
2019  std::string raw_values;
2020  for (unsigned int i = 0; i < vec.size(); ++i)
2021  raw_values += ' ' + vec[i];
2022 
2023  param->set() = raw_values;
2024 
2025  if (in_global)
2026  {
2027  global_block->remove(short_name);
2028  global_block->setScalarParam<ExecFlagEnum>(short_name) = current_param;
2029  }
2030 }
2031 
2032 template <>
2033 void
2034 Builder::setScalarParameter<RealTensorValue, RealTensorValue>(
2035  const std::string & full_name,
2036  const std::string & short_name,
2037  InputParameters::Parameter<RealTensorValue> * param,
2038  bool in_global,
2039  GlobalParamsAction * global_block)
2040 {
2041  auto vec = root()->param<std::vector<double>>(full_name);
2042  if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
2043  {
2044  _errmsg += hit::errormsg(root()->find(full_name),
2045  "invalid RealTensorValue parameter ",
2046  full_name,
2047  ": size is ",
2048  vec.size(),
2049  " but should be ",
2050  LIBMESH_DIM * LIBMESH_DIM) +
2051  "\n";
2052  return;
2053  }
2054 
2056  for (int i = 0; i < LIBMESH_DIM; ++i)
2057  for (int j = 0; j < LIBMESH_DIM; ++j)
2058  value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
2059 
2060  param->set() = value;
2061  if (in_global)
2062  {
2063  global_block->remove(short_name);
2064  global_block->setScalarParam<RealTensorValue>(short_name) = value;
2065  }
2066 }
2067 
2068 // Specialization for coupling a Real value where a postprocessor would be needed in MOOSE
2069 template <>
2070 void
2071 Builder::setScalarParameter<PostprocessorName, PostprocessorName>(
2072  const std::string & full_name,
2073  const std::string & short_name,
2074  InputParameters::Parameter<PostprocessorName> * param,
2075  bool in_global,
2076  GlobalParamsAction * global_block)
2077 {
2078  PostprocessorName pps_name = root()->param<std::string>(full_name);
2079  param->set() = pps_name;
2080 
2081  if (in_global)
2082  {
2083  global_block->remove(short_name);
2084  global_block->setScalarParam<PostprocessorName>(short_name) = pps_name;
2085  }
2086 }
2087 
2088 template <>
2089 void
2090 Builder::setScalarParameter<ReporterName, std::string>(
2091  const std::string & full_name,
2092  const std::string & /*short_name*/,
2093  InputParameters::Parameter<ReporterName> * param,
2094  bool /*in_global*/,
2095  GlobalParamsAction * /*global_block*/)
2096 {
2097  std::vector<std::string> names =
2098  MooseUtils::rsplit(root()->param<std::string>(full_name), "/", 2);
2099  if (names.size() != 2)
2100  _errmsg += hit::errormsg(root()->find(full_name),
2101  "The supplied name ReporterName '",
2102  full_name,
2103  "' must contain the '/' delimiter.");
2104  else
2105  param->set() = ReporterName(names[0], names[1]);
2106 }
2107 
2108 template <>
2109 void
2110 Builder::setVectorParameter<RealVectorValue, RealVectorValue>(
2111  const std::string & full_name,
2112  const std::string & short_name,
2113  InputParameters::Parameter<std::vector<RealVectorValue>> * param,
2114  bool in_global,
2115  GlobalParamsAction * global_block)
2116 {
2117  setVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2118 }
2119 
2120 template <>
2121 void
2122 Builder::setVectorParameter<Point, Point>(const std::string & full_name,
2123  const std::string & short_name,
2124  InputParameters::Parameter<std::vector<Point>> * param,
2125  bool in_global,
2126  GlobalParamsAction * global_block)
2127 {
2128  setVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2129 }
2130 
2131 template <>
2132 void
2133 Builder::setVectorParameter<MooseEnum, MooseEnum>(
2134  const std::string & full_name,
2135  const std::string & short_name,
2136  InputParameters::Parameter<std::vector<MooseEnum>> * param,
2137  bool in_global,
2138  GlobalParamsAction * global_block)
2139 {
2140  std::vector<MooseEnum> enum_values = param->get();
2141  std::vector<std::string> values(enum_values.size());
2142  for (unsigned int i = 0; i < values.size(); ++i)
2143  values[i] = static_cast<std::string>(enum_values[i]);
2144 
2149  std::vector<std::string> vec;
2150  if (root()->find(full_name))
2151  {
2152  vec = root()->param<std::vector<std::string>>(full_name);
2153  param->set().resize(vec.size(), enum_values[0]);
2154  }
2155 
2156  for (unsigned int i = 0; i < vec.size(); ++i)
2157  param->set()[i] = vec[i];
2158 
2159  if (in_global)
2160  {
2161  global_block->remove(short_name);
2162  global_block->setVectorParam<MooseEnum>(short_name).resize(vec.size(), enum_values[0]);
2163  for (unsigned int i = 0; i < vec.size(); ++i)
2164  global_block->setVectorParam<MooseEnum>(short_name)[i] = values[0];
2165  }
2166 }
2167 
2168 template <>
2169 void
2170 Builder::setVectorParameter<MultiMooseEnum, MultiMooseEnum>(
2171  const std::string & full_name,
2172  const std::string & short_name,
2173  InputParameters::Parameter<std::vector<MultiMooseEnum>> * param,
2174  bool in_global,
2175  GlobalParamsAction * global_block)
2176 {
2177  const std::vector<MultiMooseEnum> & enum_values = param->get();
2178 
2179  // Get the full string assigned to the variable full_name
2180  std::string buffer = root()->param<std::string>(full_name);
2181 
2182  std::vector<std::string> first_tokenized_vector = MooseUtils::split(buffer, ";");
2183  for (const auto & i : first_tokenized_vector)
2184  if (MooseUtils::trim(i) == "")
2185  mooseError("In " + full_name + ", one entry in the vector is empty. This is not allowed.");
2186 
2187  param->set().resize(first_tokenized_vector.size(), enum_values[0]);
2188 
2189  std::vector<std::vector<std::string>> vecvec(first_tokenized_vector.size());
2190  for (const auto i : index_range(vecvec))
2191  {
2192  MooseUtils::tokenize<std::string>(first_tokenized_vector[i], vecvec[i], 1, " ");
2193  param->set()[i] = vecvec[i];
2194  }
2195 
2196  if (in_global)
2197  {
2198  global_block->remove(short_name);
2199  global_block->setVectorParam<MultiMooseEnum>(short_name).resize(vecvec.size(), enum_values[0]);
2200  for (unsigned int i = 0; i < vecvec.size(); ++i)
2201  global_block->setVectorParam<MultiMooseEnum>(short_name)[i] = vecvec[i];
2202  }
2203 }
2204 
2205 template <>
2206 void
2207 Builder::setVectorParameter<PostprocessorName, PostprocessorName>(
2208  const std::string & full_name,
2209  const std::string & short_name,
2210  InputParameters::Parameter<std::vector<PostprocessorName>> * param,
2211  bool in_global,
2212  GlobalParamsAction * global_block)
2213 {
2214  std::vector<std::string> pps_names = root()->param<std::vector<std::string>>(full_name);
2215  unsigned int n = pps_names.size();
2216  param->set().resize(n);
2217 
2218  for (unsigned int j = 0; j < n; ++j)
2219  param->set()[j] = pps_names[j];
2220 
2221  if (in_global)
2222  {
2223  global_block->remove(short_name);
2224  global_block->setVectorParam<PostprocessorName>(short_name).resize(n, "");
2225  for (unsigned int j = 0; j < n; ++j)
2226  global_block->setVectorParam<PostprocessorName>(short_name)[j] = pps_names[j];
2227  }
2228 }
2229 
2234 template <>
2235 void
2236 Builder::setVectorParameter<VariableName, VariableName>(
2237  const std::string & full_name,
2238  const std::string & short_name,
2239  InputParameters::Parameter<std::vector<VariableName>> * param,
2240  bool /*in_global*/,
2241  GlobalParamsAction * /*global_block*/)
2242 {
2243  auto vec = root()->param<std::vector<std::string>>(full_name);
2244  auto strval = root()->param<std::string>(full_name);
2245  std::vector<VariableName> var_names(vec.size());
2246 
2247  bool has_var_names = false;
2248  for (unsigned int i = 0; i < vec.size(); ++i)
2249  {
2250  VariableName var_name = vec[i];
2251 
2252  Real real_value;
2253  std::istringstream ss(var_name);
2254 
2255  // If we are able to convert this value into a Real, then set a default coupled value
2256  // NOTE: parameter must be either all default or no defaults
2257  if (ss >> real_value && ss.eof())
2258  _current_params->defaultCoupledValue(short_name, real_value, i);
2259  else
2260  {
2261  var_names[i] = var_name;
2262  has_var_names = true;
2263  }
2264  }
2265 
2266  if (has_var_names)
2267  {
2268  param->set().resize(vec.size());
2269 
2270  for (unsigned int i = 0; i < vec.size(); ++i)
2271  if (var_names[i] == "")
2272  {
2273  _errmsg += hit::errormsg(root()->find(full_name),
2274  "invalid value for ",
2275  full_name,
2276  ":\n"
2277  " MOOSE does not currently support a coupled vector where "
2278  "some parameters are ",
2279  "reals and others are variables") +
2280  "\n";
2281  return;
2282  }
2283  else
2284  param->set()[i] = var_names[i];
2285  }
2286 }
2287 
2288 template <>
2289 void
2290 Builder::setVectorParameter<ReporterName, std::string>(
2291  const std::string & full_name,
2292  const std::string & /*short_name*/,
2293  InputParameters::Parameter<std::vector<ReporterName>> * param,
2294  bool /*in_global*/,
2295  GlobalParamsAction * /*global_block*/)
2296 {
2297  auto rnames = root()->param<std::vector<std::string>>(full_name);
2298  param->set().resize(rnames.size());
2299 
2300  for (unsigned int i = 0; i < rnames.size(); ++i)
2301  {
2302  std::vector<std::string> names = MooseUtils::rsplit(rnames[i], "/", 2);
2303  if (names.size() != 2)
2304  _errmsg += hit::errormsg(root()->find(full_name),
2305  "The supplied name ReporterName '",
2306  rnames[i],
2307  "' must contain the '/' delimiter.");
2308  else
2309  param->set()[i] = ReporterName(names[0], names[1]);
2310  }
2311 }
2312 
2313 template <>
2314 void
2315 Builder::setVectorParameter<CLIArgString, std::string>(
2316  const std::string & full_name,
2317  const std::string & /*short_name*/,
2318  InputParameters::Parameter<std::vector<CLIArgString>> * param,
2319  bool /*in_global*/,
2320  GlobalParamsAction * /*global_block*/)
2321 {
2322  // Parsed as a vector of string, the vectors parameters are being cut
2323  auto rnames = root()->param<std::vector<std::string>>(full_name);
2324  param->set().resize(rnames.size()); // slightly oversized if vectors have been split
2325 
2326  // Skip empty parameter
2327  if (rnames.empty())
2328  return;
2329 
2330  // Re-assemble vector parameters
2331  unsigned int i_param = 0;
2332  bool vector_param_detected = false;
2333  for (unsigned int i = 0; i < rnames.size(); ++i)
2334  {
2335  // Look for a quote, both types
2336  std::vector<std::string> double_split =
2338  std::vector<std::string> single_split =
2340  if (double_split.size() + single_split.size() >= 3)
2341  // Either entering or exiting a vector parameter (>3 is entering another vector)
2342  // Even and >2 number of quotes means both finished and started another vector parameter
2343  if ((double_split.size() + single_split.size()) % 2 == 1)
2344  vector_param_detected = !vector_param_detected;
2345 
2346  // We're building a vector parameters, just append the text, rebuild the spaces
2347  if (vector_param_detected)
2348  param->set()[i_param] += rnames[i] + ' ';
2349  else
2350  {
2351  param->set()[i_param] += rnames[i];
2352  i_param++;
2353  }
2354  }
2355  // Use actual size after re-forming vector parameters
2356  param->set().resize(i_param);
2357 }
2358 
2359 template <>
2360 void
2361 Builder::setDoubleIndexParameter<Point>(
2362  const std::string & full_name,
2363  const std::string & short_name,
2364  InputParameters::Parameter<std::vector<std::vector<Point>>> * param,
2365  bool in_global,
2366  GlobalParamsAction * global_block)
2367 {
2368  setVectorVectorComponentParameter(full_name, short_name, param, in_global, global_block);
2369 }
2370 
2371 } // end of namespace Moose
std::string name(const ElemQuality q)
OStreamProxy err
hit::Node * root()
Definition: Builder.C:321
void build()
Parse an input file (or text string if provided) consisting of hit syntax and setup objects in the MO...
Definition: Builder.C:328
ActionFactory & _action_factory
The Factory that builds actions.
Definition: Builder.h:230
MooseApp & _app
The MooseApp this Parser is part of.
Definition: Builder.h:224
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
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
std::unordered_set< std::string > _deprec_param_tracker
Tracks whether a deprecated param has had its warning message printed already.
Definition: Builder.h:252
void walkRaw(std::string fullpath, std::string nodepath, hit::Node *n)
Definition: Builder.C:206
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 ...
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:1616
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
std::vector< std::string > errors
Definition: Parser.h:67
void buildFullTree(const std::string &search_string)
Use MOOSE Factories to construct a full parse tree for documentation or echoing input.
Definition: Builder.C:640
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:92
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
std::shared_ptr< CommandLine > commandLine() const
Get the command line.
Definition: MooseApp.h:441
std::vector< std::string > _secs_need_first
Definition: Builder.h:221
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:1790
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:246
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:1692
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:1468
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.
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:1342
Action for creating component actions.
std::unique_ptr< SyntaxTree > _syntax_formatter
Object for holding the syntax parse tree.
Definition: Builder.h:237
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:887
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::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:39
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
std::vector< std::string > errors
Definition: Builder.h:46
void setScalarValueTypeParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< T > *param, bool in_global, GlobalParamsAction *global_block)
Definition: Builder.C:1416
const std::shared_ptr< Parser > _parser
The front parser.
Definition: Builder.h:234
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:24
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
std::string _warnmsg
Definition: Builder.h:256
std::set< std::string > _extracted_vars
The set of all variables extracted from the input file.
Definition: Builder.h:240
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void mooseUnused(Args &&... args)
Warning message used to notify the users of unused parts of their input files Really used internally ...
Definition: MooseError.h:345
boundary_id_type BoundaryID
constexpr auto merge(std::index_sequence< first... >, std::index_sequence< second... >)
Merge two index sequences into one.
void initSyntaxFormatter(SyntaxFormatterType type, bool dump_mode)
Creates a syntax formatter for printing.
Definition: Builder.C:463
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:480
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:353
void errorCheck(const libMesh::Parallel::Communicator &comm, bool warn_unused, bool err_unused)
Definition: Builder.C:419
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::string demangle(const char *name)
std::unique_ptr< hit::Node > _cli_root
Definition: Builder.h:217
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:1356
void rangeCheck(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< T > *param, std::ostream &oss=Moose::out)
Runs a range on the supplied parameter if it exists and throws an error if that check fails...
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:1349
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:1569
std::ostringstream * _current_error_stream
The current stream object used for capturing errors during extraction.
Definition: Builder.h:249
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::string _errmsg
Definition: Builder.h:255
Syntax & _syntax
Reference to an object that defines input file syntax.
Definition: Builder.h:232
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:1433
IntRange< T > make_range(T beg, T end)
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:1738
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:226
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...
Builder(MooseApp &app, ActionWarehouse &action_wh, std::shared_ptr< Parser > parser)
Definition: Builder.C:122
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:97
T & setParam(const std::string &name)
ActionWarehouse & _action_wh
Action warehouse that will be filled by actions.
Definition: Builder.h:228
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...
bool isSectionActive(std::string path, hit::Node *root)
Definition: Builder.C:60
void ErrorVector unsigned int
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
std::vector< std::string > errors
Definition: Parser.h:54
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:311