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 #include "MooseUtils.h"
11 #include "InputParameters.h"
12 #include "ActionFactory.h"
13 #include "Action.h"
14 #include "Factory.h"
15 #include "Parser.h"
16 #include "MooseObjectAction.h"
18 #include "ActionWarehouse.h"
19 #include "EmptyAction.h"
20 #include "MooseApp.h"
21 #include "GlobalParamsAction.h"
22 #include "SyntaxTree.h"
23 #include "InputFileFormatter.h"
24 #include "YAMLFormatter.h"
25 #include "MooseTypes.h"
26 #include "CommandLine.h"
27 #include "JsonSyntaxTree.h"
28 #include "Syntax.h"
29 #include "ParameterRegistry.h"
30 
31 #include "libmesh/parallel.h"
32 #include "libmesh/fparser.hh"
33 
34 #include <string>
35 #include <fstream>
36 #include <iomanip>
37 #include <algorithm>
38 #include <cstdlib>
39 #include <filesystem>
40 
41 namespace Moose
42 {
43 
44 bool
45 isSectionActive(const hit::Node & node)
46 {
47  const hit::Node * n = &node;
48  while (n)
49  {
50  const auto section = n->parent();
51  if (section)
52  {
53  // only check current level, not nested ones
54  if (const auto active = section->find("active");
55  active && active->type() == hit::NodeType::Field && active->parent() == section)
56  {
57  const auto vars = active->param<std::vector<std::string>>();
58  return std::find_if(vars.begin(),
59  vars.end(),
60  [&n](const auto & var)
61  { return n->path() == hit::pathNorm(var); }) != vars.end();
62  }
63  // only check current level, not nested ones
64  if (const auto inactive = section->find("inactive");
65  inactive && inactive->type() == hit::NodeType::Field && inactive->parent() == section)
66  {
67  const auto vars = inactive->param<std::vector<std::string>>();
68  return std::find_if(vars.begin(),
69  vars.end(),
70  [&n](const auto & var)
71  { return n->path() == hit::pathNorm(var); }) == vars.end();
72  }
73  }
74  n = section;
75  }
76  return true;
77 }
78 
79 std::vector<std::string>
80 findSimilar(const std::string & param, const std::vector<std::string> & options)
81 {
82  std::vector<std::string> candidates;
83  if (options.size() == 0)
84  return candidates;
85 
86  int mindist = MooseUtils::levenshteinDist(options[0], param);
87  for (const auto & opt : options)
88  {
89  const int dist = MooseUtils::levenshteinDist(opt, param);
90  // magic number heuristics to get similarity distance cutoff
91  const int dist_cutoff = 1 + param.size() / 5;
92  if (dist > dist_cutoff || dist > mindist)
93  continue;
94 
95  if (dist < mindist)
96  {
97  mindist = dist;
98  candidates.clear();
99  }
100  candidates.push_back(opt);
101  }
102  return candidates;
103 }
104 
105 Builder::Builder(MooseApp & app, ActionWarehouse & action_wh, Parser & parser)
106  : ConsoleStreamInterface(app),
107  _app(app),
108  _factory(app.getFactory()),
109  _action_wh(action_wh),
110  _action_factory(app.getActionFactory()),
111  _syntax(_action_wh.syntax()),
112  _parser(parser),
113  _root(_parser.getRoot()),
114  _syntax_formatter(nullptr)
115 {
116 }
117 
119 
122 {
124 
129  params.addParam<std::vector<std::string>>(
130  "active",
131  std::vector<std::string>({"__all__"}),
132  "If specified only the blocks named will be visited and made active");
133  params.addParam<std::vector<std::string>>(
134  "inactive",
135  std::vector<std::string>(),
136  "If specified blocks matching these identifiers will be skipped.");
137 
138  return params;
139 }
140 
141 std::vector<std::string>
142 Builder::listValidParams(std::string & section_name)
143 {
144  bool dummy;
145  std::string registered_identifier = _syntax.isAssociated(section_name, &dummy);
146  auto iters = _syntax.getActions(registered_identifier);
147 
148  std::vector<std::string> paramlist;
149  for (auto it = iters.first; it != iters.second; ++it)
150  {
151  auto params = _action_factory.getValidParams(it->second._action);
152  for (const auto & it : params)
153  paramlist.push_back(it.first);
154  }
155  return paramlist;
156 }
157 
158 void
159 UnusedWalker::walk(const std::string & fullpath, const std::string & nodename, hit::Node * n)
160 {
161  // the line() > 0 check allows us to skip nodes that were merged into this tree (i.e. CLI
162  // args) because their unused params are checked+reported independently of the ones in the
163  // main tree.
164  if (!_used.count(fullpath) && nodename != "active" && nodename != "inactive" &&
165  isSectionActive(*n) && n->line() > 0)
166  {
167  auto section_name = fullpath.substr(0, fullpath.rfind("/"));
168  const auto paramlist = _builder.listValidParams(section_name);
169  const auto candidates = findSimilar(nodename, paramlist);
170  if (candidates.size() > 0)
171  errors.emplace_back(
172  "unused parameter '" + fullpath + "'; did you mean '" + candidates[0] + "'?", n);
173  else
174  errors.emplace_back("unused parameter '" + fullpath + "'", n);
175  }
176 }
177 
178 std::string
179 Builder::getPrimaryFileName(bool strip_leading_path) const
180 {
181  const auto path = _parser.getLastInputFilePath();
182  return (strip_leading_path ? path.filename() : std::filesystem::absolute(path)).string();
183 }
184 
185 void
186 Builder::walkRaw(std::string /*fullpath*/, std::string /*nodepath*/, hit::Node * n)
187 {
188  InputParameters active_list_params = Action::validParams();
190 
191  const std::string section_name = n->fullpath();
192  const std::string curr_identifier = n->fullpath();
193 
194  // Before we retrieve any actions or build any objects, make sure that the section they are in
195  // is active
196  if (!isSectionActive(*n))
197  return;
198 
199  // Extract the block parameters before constructing the action
200  // There may be more than one Action registered for a given section in which case we need to
201  // build them all
202  bool is_parent;
203  std::string registered_identifier = _syntax.isAssociated(section_name, &is_parent);
204 
205  // Make sure at least one action is associated with the current identifier
206  if (const auto [begin, end] = _syntax.getActions(registered_identifier); begin == end)
207  {
208  _errors.emplace_back(
209  "section '[" + curr_identifier +
210  "]' does not have an associated Action; you likely misspelled the Action/section name "
211  "or the app you are running does not support this Action/syntax",
212  n);
213  return;
214  }
215 
216  // The DynamicObjecRegistrationAction changes the action multimap and would invalidate the
217  // iterators returned by _syntax.getActions, that's why we have to loop in this awkward way.
218  std::set<const Syntax::ActionInfo *> processed_actions;
219  while (true)
220  {
221  // search for an unprocessed action
222  auto [begin, end] = _syntax.getActions(registered_identifier);
223  auto it = begin;
224  for (; it != end && processed_actions.count(&it->second); ++it)
225  ;
226 
227  // no more unprocessed actions
228  if (it == end)
229  break;
230 
231  // mark action as processed
232  processed_actions.insert(&it->second);
233 
234  if (is_parent)
235  continue;
236  if (_syntax.isDeprecatedSyntax(registered_identifier))
238  hit::errormsg(n, _syntax.deprecatedActionSyntaxMessage(registered_identifier)));
239 
240  params = _action_factory.getValidParams(it->second._action);
241  params.set<ActionWarehouse *>("awh") = &_action_wh;
242  params.setHitNode(*n, {});
243 
244  extractParams(n, params);
245 
246  // Add the parsed syntax to the parameters object for consumption by the Action
247  params.set<std::string>("task") = it->second._task;
248  params.set<std::string>("registered_identifier") = registered_identifier;
249 
250  if (!(params.have_parameter<bool>("isObjectAction") && params.get<bool>("isObjectAction")))
251  params.set<std::vector<std::string>>("control_tags")
252  .push_back(MooseUtils::baseName(curr_identifier));
253 
254  // Create the Action
255  std::shared_ptr<Action> action_obj =
256  _action_factory.create(it->second._action, curr_identifier, params);
257 
258  {
259  // extract the MooseObject params if necessary
260  std::shared_ptr<MooseObjectAction> object_action =
262  if (object_action)
263  {
264  auto & object_params = object_action->getObjectParams();
265  object_params.setHitNode(*n, {});
266  extractParams(n, object_params);
267  object_params.set<std::vector<std::string>>("control_tags")
268  .push_back(MooseUtils::baseName(curr_identifier));
269  }
270  // extract the Component params if necessary
271  std::shared_ptr<AddActionComponentAction> component_action =
273  if (component_action)
274  {
275  auto & component_params = component_action->getComponentParams();
276  component_params.setHitNode(*n, {});
277  extractParams(n, component_params);
278  component_params.set<std::vector<std::string>>("control_tags")
279  .push_back(MooseUtils::baseName(curr_identifier));
280  }
281  }
282 
283  // add it to the warehouse
284  _action_wh.addActionBlock(action_obj);
285  }
286 }
287 
288 void
289 Builder::walk(const std::string & fullpath, const std::string & nodepath, hit::Node * n)
290 {
291  // skip sections that were manually processed first.
292  if (std::find(_secs_need_first.begin(), _secs_need_first.end(), nodepath) !=
293  _secs_need_first.end())
294  return;
295 
296  walkRaw(fullpath, nodepath, n);
297 }
298 
299 void
301 {
302  // Pull in extracted variables from the parser (fparse stuff)
304 
305  // There are a few order dependent actions that have to be built first in
306  // order for the parser and application to function properly
307  const auto need_action_syntax_first = [this](const auto & action_name)
308  {
309  const auto syntax = _syntax.getSyntaxByAction(action_name);
310  mooseAssert(syntax.size(), "Empty syntax");
311  std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
312  };
313 
314  // SetupDebugAction: This action can contain an option for monitoring the
315  // parser progress. It must be parsed first to capture all of the parsing
316  // output progress.
317  need_action_syntax_first("SetupDebugAction");
318 
319  // GlobalParamsAction: This action is checked during the parameter extraction
320  // routines of all subsequent blocks. It must be parsed early since it must
321  // exist during subsequent parameter extraction.
322  need_action_syntax_first("GlobalParamsAction");
323 
324  // DynamicObjectRegistration: This action must be built before any MooseObjectActions
325  // are built. This is because we retrieve valid parameters from the Factory
326  // during parse time. Objects must be registered before validParameters can be retrieved.
327  need_action_syntax_first("DynamicObjectRegistrationAction");
328 
329  // Walk all the sections extracting paramters from each into InputParameters objects
330  for (const auto & sec : _secs_need_first)
331  if (auto n = _root.find(sec))
332  walkRaw(n->parent()->fullpath(), n->path(), n);
333 
334  // Walk for the remainder
335  _root.walk(this, hit::NodeType::Section);
336 
337  // Warn for all deprecated parameters together
338  if (_deprecated_params.size())
339  {
340  std::vector<std::string> messages;
341  for (const auto & key_message_pair : _deprecated_params)
342  messages.push_back(key_message_pair.second);
343  const auto message = MooseUtils::stringJoin(messages, "\n\n");
344 
345  moose::internal::mooseDeprecatedStream(Moose::out, false, true, false, message + "\n\n");
346  }
347 
348  if (_errors.size())
350 }
351 
352 // Checks the input and the way it has been used and emits any errors/warnings.
353 // This has to be a separate function because for we don't know if some parameters were unused
354 // until all the multiapps/subapps have been fully initialized - which isn't complete until
355 // *after* all the other member functions on Parser have been run. So this is here to be
356 // externally called at the right time.
357 void
358 Builder::errorCheck(const Parallel::Communicator & comm, bool warn_unused, bool err_unused)
359 {
360  // Nothing to do here
361  if (!warn_unused && !err_unused)
362  return;
363 
364  std::vector<hit::ErrorMessage> messages;
365 
367  {
368  UnusedWalker uw(_extracted_vars, *this);
369  _parser.getCommandLineRoot().walk(&uw);
370  Parser::appendErrorMessages(messages, uw.errors);
371  }
372 
373  {
374  UnusedWalker uw(_extracted_vars, *this);
375  _root.walk(&uw);
376  Parser::appendErrorMessages(messages, uw.errors);
377  }
378 
379  for (const auto & arg : _app.commandLine()->unusedHitParams(comm))
380  messages.emplace_back("unused command line parameter '" + arg + "'");
381 
382  if (messages.size())
383  {
384  const auto message = _parser.joinErrorMessages(messages);
385  if (warn_unused)
386  mooseUnused(message);
387  if (err_unused)
388  {
389  if (_parser.getThrowOnError())
390  _parser.parseError(messages);
391  else
392  mooseError(
393  message +
394  "\n\nAppend --allow-unused (or -w) on the command line to ignore unused parameters.");
395  }
396  }
397 }
398 
399 void
401 {
402  switch (type)
403  {
404  case INPUT_FILE:
405  _syntax_formatter = std::make_unique<InputFileFormatter>(dump_mode);
406  break;
407  case YAML:
408  _syntax_formatter = std::make_unique<YAMLFormatter>(dump_mode);
409  break;
410  default:
411  mooseError("Unrecognized Syntax Formatter requested");
412  break;
413  }
414 }
415 
416 void
418 {
419  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
420 
421  for (const auto & iter : _syntax.getAssociatedTypes())
422  root.addSyntaxType(iter.first, iter.second);
423 
424  // Build a list of all the actions appearing in the syntax
425  for (const auto & iter : _syntax.getAssociatedActions())
426  {
427  Syntax::ActionInfo act_info = iter.second;
433  if (act_info._task == "")
434  act_info._task = _action_factory.getTaskName(act_info._action);
435 
436  all_names.push_back(std::make_pair(iter.first, act_info));
437  }
438 
439  // Add all the actions to the JSON tree, except for ActionComponents (below)
440  for (const auto & act_names : all_names)
441  {
442  const auto & act_info = act_names.second;
443  const std::string & action = act_info._action;
444  const std::string & task = act_info._task;
445  const std::string syntax = act_names.first;
446  InputParameters action_obj_params = _action_factory.getValidParams(action);
447  bool params_added = root.addParameters("",
448  syntax,
449  false,
450  action,
451  true,
452  &action_obj_params,
453  _syntax.getLineInfo(syntax, action, ""),
454  "");
455 
456  if (params_added)
457  {
458  auto tasks = _action_factory.getTasksByAction(action);
459  for (auto & t : tasks)
460  {
461  auto info = _action_factory.getLineInfo(action, t);
462  root.addActionTask(syntax, action, t, info);
463  }
464  }
465 
471  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
472  action_obj_params.get<bool>("isObjectAction"))
473  {
474  for (auto & [moose_obj_name, obj] : _factory.registeredObjects())
475  {
476  auto moose_obj_params = obj->buildParameters();
477  // Now that we know that this is a MooseObjectAction we need to see if it has been
478  // restricted
479  // in any way by the user.
480  const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
481 
482  // See if the current Moose Object syntax belongs under this Action's block
483  if ((buildable_types.empty() || // Not restricted
484  std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
485  buildable_types.end()) && // Restricted but found
486  moose_obj_params.hasBase() && // Has a registered base
487  _syntax.verifyMooseObjectTask(moose_obj_params.getBase(),
488  task) && // and that base is associated
489  action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
490  )
491  {
492  std::string name;
493  size_t pos = 0;
494  bool is_action_params = false;
495  bool is_type = false;
496  if (syntax[syntax.size() - 1] == '*')
497  {
498  pos = syntax.size();
499 
500  if (!action_obj_params.collapseSyntaxNesting())
501  name = syntax.substr(0, pos - 1) + moose_obj_name;
502  else
503  {
504  name = syntax.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
505  is_action_params = true;
506  }
507  }
508  else
509  {
510  name = syntax + "/<type>/" + moose_obj_name;
511  is_type = true;
512  }
513  moose_obj_params.set<std::string>("type") = moose_obj_name;
514 
515  auto lineinfo = _factory.getLineInfo(moose_obj_name);
516  std::string classname = _factory.associatedClassName(moose_obj_name);
517  root.addParameters(syntax,
518  name,
519  is_type,
520  moose_obj_name,
521  is_action_params,
522  &moose_obj_params,
523  lineinfo,
524  classname);
525  }
526  }
527 
528  // Same thing for ActionComponents, which, while they are not MooseObjects, should behave
529  // similarly syntax-wise
530  if (syntax != "ActionComponents/*")
531  continue;
532 
533  auto iters = _action_factory.getActionsByTask("list_component");
534 
535  for (auto it = iters.first; it != iters.second; ++it)
536  {
537  // Get the name and parameters
538  const auto component_name = it->second;
539  auto component_params = _action_factory.getValidParams(component_name);
540 
541  // We currently do not have build-type restrictions on this action that adds
542  // action-components
543 
544  // See if the current Moose Object syntax belongs under this Action's block
545  if (action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
546  )
547  {
548  // The logic for Components is a little simpler here for now because syntax like
549  // Executioner/TimeIntegrator/type= do not exist for components
550  std::string name;
551  if (syntax[syntax.size() - 1] == '*')
552  {
553  size_t pos = syntax.size();
554  name = syntax.substr(0, pos - 1) + component_name;
555  }
556  component_params.set<std::string>("type") = component_name;
557 
558  auto lineinfo = _action_factory.getLineInfo(component_name, "list_component");
559  // We add the parameters as for an object, because we want to fit them to be
560  // added to json["AddActionComponentAction"]["subblock_types"]
561  root.addParameters(syntax,
562  /*syntax_path*/ name,
563  /*is_type*/ false,
564  "AddActionComponentAction",
565  /*is_action=*/false,
566  &component_params,
567  lineinfo,
568  component_name);
569  }
570  }
571  }
572  }
573  root.addGlobal();
574 }
575 
576 void
577 Builder::buildFullTree(const std::string & search_string)
578 {
579  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
580 
581  for (const auto & iter : _syntax.getAssociatedActions())
582  {
583  Syntax::ActionInfo act_info = iter.second;
589  if (act_info._task == "")
590  act_info._task = _action_factory.getTaskName(act_info._action);
591 
592  all_names.push_back(std::pair<std::string, Syntax::ActionInfo>(iter.first, act_info));
593  }
594 
595  for (const auto & act_names : all_names)
596  {
597  InputParameters action_obj_params = _action_factory.getValidParams(act_names.second._action);
598  _syntax_formatter->insertNode(
599  act_names.first, act_names.second._action, true, &action_obj_params);
600 
601  const std::string & task = act_names.second._task;
602  std::string act_name = act_names.first;
603 
609  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
610  action_obj_params.get<bool>("isObjectAction"))
611  {
612  for (const auto & [moose_obj_name, obj] : _factory.registeredObjects())
613  {
614  auto moose_obj_params = obj->buildParameters();
619  const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
620 
621  // See if the current Moose Object syntax belongs under this Action's block
622  if ((buildable_types.empty() || // Not restricted
623  std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
624  buildable_types.end()) && // Restricted but found
625  moose_obj_params.hasBase() && // Has a registered base
626  _syntax.verifyMooseObjectTask(moose_obj_params.getBase(),
627  task) && // and that base is associated
628  action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
629  )
630  {
631  std::string name;
632  size_t pos = 0;
633  bool is_action_params = false;
634  if (act_name[act_name.size() - 1] == '*')
635  {
636  pos = act_name.size();
637 
638  if (!action_obj_params.collapseSyntaxNesting())
639  name = act_name.substr(0, pos - 1) + moose_obj_name;
640  else
641  {
642  name = act_name.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
643  is_action_params = true;
644  }
645  }
646  else
647  {
648  name = act_name + "/<type>/" + moose_obj_name;
649  }
650 
651  moose_obj_params.set<std::string>("type") = moose_obj_name;
652 
653  _syntax_formatter->insertNode(name, moose_obj_name, is_action_params, &moose_obj_params);
654  }
655  }
656  }
657  }
658 
659  // Do not change to _console, we need this printed to the stdout in all cases
660  Moose::out << _syntax_formatter->print(search_string) << std::flush;
661 }
662 
663 void
664 Builder::extractParams(const hit::Node * const section_node, InputParameters & p)
665 {
666  if (section_node)
667  mooseAssert(section_node->type() == hit::NodeType::Section, "Node type should be a section");
668 
669  for (const auto & [name, par_unique_ptr] : p)
670  {
671  if (p.shouldIgnore(name))
672  continue;
673 
674  const hit::Node * param_node = nullptr;
675 
676  for (const auto & param_name : p.paramAliases(name))
677  {
678  // Check for parameters under the given section, if a section
679  // node was provided
680  if (section_node)
681  {
682  if (const auto section_param_node = section_node->find(param_name);
683  section_param_node && section_param_node->type() == hit::NodeType::Field &&
684  section_param_node->parent() == section_node)
685  param_node = section_param_node;
686  }
687  // No node found within the given section, check [GlobalParams]
688  if (!param_node && queryGlobalParamsNode())
689  {
690  if (const auto global_node = queryGlobalParamsNode()->find(param_name);
691  global_node && global_node->type() == hit::NodeType::Field &&
692  global_node->parent() == queryGlobalParamsNode())
693  {
694  mooseAssert(isGlobal(*global_node), "Could not detect global-ness");
695  param_node = global_node;
696  }
697  }
698 
699  // Found it
700  if (param_node)
701  {
702  const auto fullpath = param_node->fullpath();
703  p.setHitNode(param_name, *param_node, {});
704  p.set_attributes(param_name, false);
705  _extracted_vars.insert(fullpath);
706 
707  const auto global = isGlobal(*param_node);
708 
709  // Check for deprecated parameters if the parameter is not a global param
710  if (!global)
711  if (const auto deprecated_message = p.queryDeprecatedParamMessage(param_name))
712  {
713  std::string key = "";
714  if (const auto object_type_ptr = p.queryObjectType())
715  key += *object_type_ptr + "_";
716  key += param_name;
717  _deprecated_params.emplace(key, *deprecated_message);
718  }
719 
720  // Private parameter, don't set
721  if (p.isPrivate(param_name))
722  {
723  // Error if it isn't global, just once
724  if (!global && std::find_if(_errors.begin(),
725  _errors.end(),
726  [&param_node](const auto & err)
727  { return err.node == param_node; }) == _errors.end())
728  _errors.emplace_back("parameter '" + fullpath + "' is private and cannot be set",
729  param_node);
730  continue;
731  }
732 
733  // Set the value, capturing errors
734  const auto param_field = dynamic_cast<const hit::Field *>(param_node);
735  mooseAssert(param_field, "Is not a field");
736  bool set_param = false;
737  try
738  {
739  ParameterRegistry::get().set(*par_unique_ptr, *param_field);
740  set_param = true;
741  }
742  catch (hit::Error & e)
743  {
744  _errors.emplace_back(e.message, param_node);
745  }
746  catch (std::exception & e)
747  {
748  _errors.emplace_back(e.what(), param_node);
749  }
750 
751  // Break if we failed here and don't perform extra checks
752  if (!set_param)
753  break;
754 
755  // Special setup for vector<VariableName>
756  if (auto cast_par = dynamic_cast<InputParameters::Parameter<std::vector<VariableName>> *>(
757  par_unique_ptr.get()))
758  if (const auto error = p.setupVariableNames(cast_par->set(), *param_node, {}))
759  _errors.emplace_back(*error, param_node);
760 
761  // Possibly perform a range check if this parameter has one
762  if (p.isRangeChecked(param_node->path()))
763  if (const auto error = p.parameterRangeCheck(
764  *par_unique_ptr, param_node->fullpath(), param_node->path(), true))
765  _errors.emplace_back(error->second, param_node);
766 
767  // Don't check the other alises since we've found it
768  break;
769  }
770  }
771 
772  // Special casing when the parameter was not found
773  if (!param_node)
774  {
775  // In the case where we have OutFileName but it wasn't actually found in the input filename,
776  // we will populate it with the actual parsed filename which is available here in the
777  // parser.
778  if (auto out_par_ptr =
779  dynamic_cast<InputParameters::Parameter<OutFileBase> *>(par_unique_ptr.get()))
780  {
781  const auto input_file_name = getPrimaryFileName();
782  mooseAssert(input_file_name.size(), "Input Filename is empty");
783  const auto pos = input_file_name.find_last_of('.');
784  mooseAssert(pos != std::string::npos, "Unable to determine suffix of input file name");
785  out_par_ptr->set() = input_file_name.substr(0, pos) + "_out";
786  p.set_attributes(name, false);
787  }
788  }
789  }
790 
791  // See if there are any auto build vectors that need to be created
792  for (const auto & [param_name, base_name_num_repeat_pair] : p.getAutoBuildVectors())
793  {
794  const auto & [base_name, num_repeat] = base_name_num_repeat_pair;
795  // We'll autogenerate values iff the requested vector is not valid but both the base and
796  // number are valid
797  if (!p.isParamValid(param_name) && p.isParamValid(base_name) && p.isParamValid(num_repeat))
798  {
799  const auto vec_size = p.get<unsigned int>(num_repeat);
800  const std::string & name = p.get<std::string>(base_name);
801 
802  std::vector<VariableName> variable_names(vec_size);
803  for (const auto i : index_range(variable_names))
804  {
805  std::ostringstream oss;
806  oss << name << i;
807  variable_names[i] = oss.str();
808  }
809 
810  // Finally set the autogenerated vector into the InputParameters object
811  p.set<std::vector<VariableName>>(param_name) = variable_names;
812  }
813  }
814 }
815 
816 void
817 Builder::extractParams(const std::string & prefix, InputParameters & p)
818 {
819  const auto node = _root.find(prefix);
820  extractParams((node && node->type() == hit::NodeType::Section) ? node : nullptr, p);
821 }
822 
823 bool
824 Builder::isGlobal(const hit::Node & node) const
825 {
826  const auto global_params_node = queryGlobalParamsNode();
827  return global_params_node && node.parent() == global_params_node;
828 }
829 
830 const hit::Node *
832 {
833  if (!_global_params_node)
834  {
835  const auto syntax = _syntax.getSyntaxByAction("GlobalParamsAction");
836  mooseAssert(syntax.size() == 1, "Unexpected GlobalParamsAction syntax size");
837  _global_params_node = _root.find(syntax.front());
838  }
839  return *_global_params_node;
840 }
841 
842 } // end of namespace Moose
std::string name(const ElemQuality q)
OStreamProxy err
void build()
Parse an input file (or text string if provided) consisting of hit syntax and setup objects in the MO...
Definition: Builder.C:300
void addSyntaxType(const std::string &path, const std::string type)
Add an associated type to a block.
ActionFactory & _action_factory
The Factory that builds actions.
Definition: Builder.h:139
MooseApp & _app
The MooseApp this Parser is part of.
Definition: Builder.h:133
const hit::Node * queryCommandLineRoot() const
Definition: Parser.h:138
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:159
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
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:40
void walkRaw(std::string fullpath, std::string nodepath, hit::Node *n)
Definition: Builder.C:186
void parseError(std::vector< hit::ErrorMessage > messages) const
Helper for throwing an error with the given messages.
Definition: Parser.C:493
Parser & _parser
The front parser.
Definition: Builder.h:143
InputParameters & getComponentParams()
Return the parameters of the component.
const std::multimap< std::string, ActionInfo > & getAssociatedActions() const
Return all Syntax to Action associations.
Definition: Syntax.C:374
void buildFullTree(const std::string &search_string)
Use MOOSE Factories to construct a full parse tree for documentation or echoing input.
Definition: Builder.C:577
MPI_Info info
void mooseObjectSyntaxVisibility(bool visibility)
Mutators for controlling whether or not the outermost level of syntax will be collapsed when printed...
void set(libMesh::Parameters::Value &value, const hit::Field &field) const
Sets a parameter value given a hit field.
InputParameters getValidParams(const std::string &name)
Definition: ActionFactory.C:94
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
void addActionTask(const std::string &path, const std::string &action, const std::string &task, const FileLineInfo &lineinfo)
Add a task to the tree.
std::shared_ptr< CommandLine > commandLine() const
Get the command line.
Definition: MooseApp.h:423
std::vector< std::string > _secs_need_first
The sections that we need to execute first (read during the final walk)
Definition: Builder.h:154
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.
std::string associatedClassName(const std::string &name) const
Get the associated class name for an object name.
Definition: Factory.C:296
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
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>
Builder(MooseApp &app, ActionWarehouse &action_wh, Parser &parser)
Definition: Builder.C:105
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.
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:121
Base class for MOOSE-based applications.
Definition: MooseApp.h:108
Storage for action instances.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
FileLineInfo getLineInfo(const std::string &name, const std::string &task) const
Gets file and line information where an action was registered.
const std::set< std::string > & getExtractedVars() const
Definition: Parser.h:206
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
Action for creating component actions.
std::unique_ptr< SyntaxTree > _syntax_formatter
Object for holding the syntax parse tree.
Definition: Builder.h:148
Holds the syntax in a Json::Value tree.
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:284
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:40
InputParameters emptyInputParameters()
void extractParams(const hit::Node *const section_node, InputParameters &p)
Attempt to extract values from input starting with the section in input in section_node based on the ...
Definition: Builder.C:664
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
static void appendErrorMessages(std::vector< hit::ErrorMessage > &to, const std::vector< hit::ErrorMessage > &from)
Helper for accumulating errors from a walker into an accumulation of errors.
Definition: Parser.C:471
bool isDeprecatedSyntax(const std::string &syntax) const
Returns a Boolean indicating whether the syntax has been deprecated through a call to deprecateAction...
Definition: Syntax.C:205
static InputParameters validParams()
Definition: Action.C:26
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
hit::Node & _root
The root node from the Parser.
Definition: Builder.h:145
std::set< std::string > _extracted_vars
The set of all variables extracted from the input file.
Definition: Builder.h:151
bool addParameters(const std::string &parent_path, const std::string &path, bool is_type, const std::string &action, bool is_action, InputParameters *params, const FileLineInfo &lineinfo, const std::string &classname)
Add parameters to the tree.
static std::string joinErrorMessages(const std::vector< hit::ErrorMessage > &error_messages)
Helper for combining error messages into a single, newline separated message.
Definition: Parser.C:484
void mooseUnused(Args &&... args)
Warning message used to notify the users of unused parts of their input files Really used internally ...
Definition: MooseError.h:354
void initSyntaxFormatter(SyntaxFormatterType type, bool dump_mode)
Creates a syntax formatter for printing.
Definition: Builder.C:400
bool getThrowOnError() const
Definition: Parser.h:199
static InputParameters validParams()
Definition: EmptyAction.C:19
void mooseDeprecatedStream(S &oss, const bool expired, const bool print_title, const bool show_trace, Args &&... args)
Definition: MooseError.h:252
An inteface for the _console for outputting to the Console object.
void buildJsonSyntaxTree(JsonSyntaxTree &tree) const
Use MOOSE Factories to construct a parameter tree for documentation or echoing input.
Definition: Builder.C:417
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:363
void errorCheck(const libMesh::Parallel::Communicator &comm, bool warn_unused, bool err_unused)
Definition: Builder.C:358
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:179
std::vector< hit::ErrorMessage > errors
Definition: Builder.h:46
bool isGlobal(const hit::Node &node) const
Definition: Builder.C:824
std::vector< hit::ErrorMessage > _errors
The errors accumulated during the walk.
Definition: Builder.h:157
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
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::map< std::string, std::string > _deprecated_params
Deprecation warnings (object type/param name) -> (message)
Definition: Builder.h:160
std::string baseName(const std::string &name)
Definition: MooseUtils.C:618
Syntax & _syntax
Reference to an object that defines input file syntax.
Definition: Builder.h:141
std::set< std::string > _used
Definition: Builder.h:49
const hit::Node & getCommandLineRoot() const
Definition: Parser.C:457
void addGlobal()
Add the global section to the output.
int levenshteinDist(const std::string &s1, const std::string &s2)
Definition: MooseUtils.C:176
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
std::vector< std::string > findSimilar(const std::string &param, const std::vector< std::string > &options)
Definition: Builder.C:80
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:135
virtual ~Builder()
Definition: Builder.C:118
std::vector< std::string > listValidParams(std::string &section_name)
Definition: Builder.C:142
void setHitNode(const std::string &param, const hit::Node &node, const SetParamHitNodeKey)
Sets the hit node associated with the parameter param to node.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
std::filesystem::path getLastInputFilePath() const
Definition: Parser.h:185
ActionWarehouse & _action_wh
Action warehouse that will be filled by actions.
Definition: Builder.h:137
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
void collapseSyntaxNesting(bool collapse)
Mutators for controlling whether or not the outermost level of syntax will be collapsed when printed...
const hit::Node * queryGlobalParamsNode() const
Get the [GlobalParams] section node if it exists.
Definition: Builder.C:831
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
auto index_range(const T &sizable)
Class for parsing input files.
Definition: Parser.h:87
static ParameterRegistry & get()
Get the singleton registry.
std::optional< const hit::Node * > _global_params_node
The hit Node for the [GlobalParams] block, if any If set (could be null), it means we have searched f...
Definition: Builder.h:164
bool isSectionActive(const hit::Node &node)
Definition: Builder.C:45
void walk(const std::string &fullpath, const std::string &nodepath, hit::Node *n)
Definition: Builder.C:289