www.mooseframework.org
Parser.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 // MOOSE includes
16 #include "MooseUtils.h"
17 #include "MooseInit.h"
18 #include "InputParameters.h"
19 #include "ActionFactory.h"
20 #include "Action.h"
21 #include "Factory.h"
22 #include "MooseObjectAction.h"
23 #include "ActionWarehouse.h"
24 #include "EmptyAction.h"
25 #include "FEProblem.h"
26 #include "MooseMesh.h"
27 #include "Executioner.h"
28 #include "MooseApp.h"
29 #include "MooseEnum.h"
30 #include "MultiMooseEnum.h"
31 #include "MultiApp.h"
32 #include "GlobalParamsAction.h"
33 #include "SyntaxTree.h"
34 #include "InputFileFormatter.h"
35 #include "YAMLFormatter.h"
36 #include "MooseTypes.h"
37 #include "CommandLine.h"
38 #include "JsonSyntaxTree.h"
39 #include "SystemInfo.h"
40 #include "MooseUtils.h"
41 
42 #include "libmesh/parallel.h"
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 
57  _app(app),
58  _factory(app.getFactory()),
59  _action_wh(action_wh),
60  _action_factory(app.getActionFactory()),
61  _syntax(_action_wh.syntax()),
62  _syntax_formatter(nullptr),
63  _sections_read(false),
64  _current_params(nullptr),
65  _current_error_stream(nullptr)
66 {
67 }
68 
70 
71 bool
72 isSectionActive(std::string path, hit::Node * root)
73 {
74  hit::Node * n = root->find(path);
75  while (n)
76  {
77  hit::Node * section = n->parent();
78  if (section)
79  {
80  auto actives = section->find("active");
81  auto inactives = section->find("inactive");
82 
83  // only check current level, not nested ones
84  if (actives && actives->type() == hit::NodeType::Field && actives->parent() == section)
85  {
86  auto vars = section->param<std::vector<std::string>>("active");
87  bool have_var = false;
88  for (auto & var : vars)
89  if (n->path() == hit::pathNorm(var))
90  have_var = true;
91  if (!have_var)
92  return false;
93  }
94  // only check current level, not nested ones
95  if (inactives && inactives->type() == hit::NodeType::Field && inactives->parent() == section)
96  {
97  auto vars = section->param<std::vector<std::string>>("inactive");
98  for (auto & var : vars)
99  if (n->path() == hit::pathNorm(var))
100  return false;
101  }
102  }
103  n = section;
104  }
105  return true;
106 }
107 
108 class DupParamWalker : public hit::Walker
109 {
110 public:
111  DupParamWalker(std::string fname) : _fname(fname) {}
112  void walk(const std::string & fullpath, const std::string & /*nodepath*/, hit::Node * n) override
113  {
114  std::string prefix = n->type() == hit::NodeType::Field ? "parameter" : "section";
115 
116  if (_have.count(fullpath) > 0)
117  {
118  auto existing = _have[fullpath];
119  if (_duplicates.count(fullpath) == 0)
120  {
121  errors.push_back(
122  errormsg(_fname, existing, prefix, " '", fullpath, "' supplied multiple times"));
123  _duplicates.insert(fullpath);
124  }
125  errors.push_back(errormsg(_fname, n, prefix, " '", fullpath, "' supplied multiple times"));
126  }
127  _have[n->fullpath()] = n;
128  }
129 
130  std::vector<std::string> errors;
131 
132 private:
133  std::string _fname;
134  std::set<std::string> _duplicates;
135  std::map<std::string, hit::Node *> _have;
136 };
137 
138 std::vector<std::string>
139 findSimilar(std::string param, std::vector<std::string> options)
140 {
141  std::vector<std::string> candidates;
142  if (options.size() == 0)
143  return candidates;
144 
145  int mindist = MooseUtils::levenshteinDist(options[0], param);
146  for (auto & opt : options)
147  {
148  int dist = MooseUtils::levenshteinDist(opt, param);
149  // magic number heuristics to get similarity distance cutoff
150  int dist_cutoff = 1 + param.size() / 5;
151  if (dist > dist_cutoff || dist > mindist)
152  continue;
153 
154  if (dist < mindist)
155  {
156  mindist = dist;
157  candidates.clear();
158  }
159  candidates.push_back(opt);
160  }
161  return candidates;
162 }
163 
164 std::vector<std::string>
165 Parser::listValidParams(std::string & section_name)
166 {
167  bool dummy;
168  std::string registered_identifier = _syntax.isAssociated(section_name, &dummy);
169  auto iters = _syntax.getActions(registered_identifier);
170 
171  std::vector<std::string> paramlist;
172  for (auto it = iters.first; it != iters.second; ++it)
173  {
174  auto params = _action_factory.getValidParams(it->second._action);
175  for (const auto & it : params)
176  paramlist.push_back(it.first);
177  }
178  return paramlist;
179 }
180 
181 class UnusedWalker : public hit::Walker
182 {
183 public:
184  UnusedWalker(std::string fname, std::set<std::string> used, Parser & p)
185  : _fname(fname), _used(used), _parser(p)
186  {
187  }
188 
189  void walk(const std::string & fullpath, const std::string & nodename, hit::Node * n) override
190  {
191  // the line() > 0 check allows us to skip nodes that were merged into this tree (i.e. CLI
192  // args) because their unused params are checked+reported independently of the ones in the
193  // main tree.
194  if (!_used.count(fullpath) && nodename != "active" && nodename != "inactive" &&
195  isSectionActive(fullpath, n->root()) && n->line() > 0)
196  {
197  auto section_name = fullpath.substr(0, fullpath.rfind("/"));
198  auto paramlist = _parser.listValidParams(section_name);
199  auto candidates = findSimilar(nodename, paramlist);
200  if (candidates.size() > 0)
201  errors.push_back(errormsg(_fname,
202  n,
203  "unused parameter '",
204  fullpath,
205  "'\n",
206  " Did you mean '",
207  candidates[0],
208  "'?"));
209  else
210  errors.push_back(errormsg(_fname, n, "unused parameter '", fullpath, "'"));
211  }
212  }
213 
214  std::vector<std::string> errors;
215 
216 private:
217  std::string _fname;
218  std::set<std::string> _used;
220 };
221 
222 class BadActiveWalker : public hit::Walker
223 {
224 public:
225  BadActiveWalker(std::string fname) : _fname(fname) {}
226  void walk(const std::string & /*fullpath*/,
227  const std::string & /*nodepath*/,
228  hit::Node * section) override
229  {
230  auto actives = section->find("active");
231  auto inactives = section->find("inactive");
232 
233  if (actives && inactives && actives->type() == hit::NodeType::Field &&
234  inactives->type() == hit::NodeType::Field && actives->parent() == inactives->parent())
235  {
236  errors.push_back(
237  errormsg(_fname, section, "'active' and 'inactive' parameters both provided in section"));
238  return;
239  }
240 
241  // ensures we don't recheck deeper nesting levels
242  if (actives && actives->type() == hit::NodeType::Field && actives->parent() == section)
243  {
244  auto vars = section->param<std::vector<std::string>>("active");
245  std::string msg = "";
246  for (auto & var : vars)
247  {
248  if (!section->find(var))
249  msg += var + ", ";
250  }
251  if (msg.size() > 0)
252  {
253  msg = msg.substr(0, msg.size() - 2);
254  errors.push_back(errormsg(_fname,
255  section,
256  "variables listed as active (",
257  msg,
258  ") in section '",
259  section->fullpath(),
260  "' not found in input"));
261  }
262  }
263  // ensures we don't recheck deeper nesting levels
264  if (inactives && inactives->type() == hit::NodeType::Field && inactives->parent() == section)
265  {
266  auto vars = section->param<std::vector<std::string>>("inactive");
267  std::string msg = "";
268  for (auto & var : vars)
269  {
270  if (!section->find(var))
271  msg += var + ", ";
272  }
273  if (msg.size() > 0)
274  {
275  msg = msg.substr(0, msg.size() - 2);
276  errors.push_back(errormsg(_fname,
277  section,
278  "variables listed as inactive (",
279  msg,
280  ") in section '",
281  section->fullpath(),
282  "' not found in input"));
283  }
284  }
285  }
286  std::vector<std::string> errors;
287 
288 private:
289  std::string _fname;
290 };
291 
292 std::string
293 Parser::getFileName(bool stripLeadingPath) const
294 {
295  if (!stripLeadingPath)
296  return _input_filename;
297 
298  std::string filename;
299  size_t pos = _input_filename.find_last_of('/');
300  if (pos != std::string::npos)
301  filename = _input_filename.substr(pos + 1);
302  else
303  filename = _input_filename;
304 
305  return filename;
306 }
307 
308 void
309 Parser::walkRaw(std::string /*fullpath*/, std::string /*nodepath*/, hit::Node * n)
310 {
311  InputParameters active_list_params = validParams<Action>();
313 
314  std::string section_name = n->fullpath();
315  std::string curr_identifier = n->fullpath();
316 
317  // Before we retrieve any actions or build any objects, make sure that the section they are in
318  // is active
319  if (!isSectionActive(curr_identifier, _root.get()))
320  return;
321 
322  // Extract the block parameters before constructing the action
323  // There may be more than one Action registered for a given section in which case we need to
324  // build them all
325  bool is_parent;
326  std::string registered_identifier = _syntax.isAssociated(section_name, &is_parent);
327 
328  // We need to retrieve a list of Actions associated with the current identifier
329  std::pair<std::multimap<std::string, Syntax::ActionInfo>::iterator,
330  std::multimap<std::string, Syntax::ActionInfo>::iterator>
331  iters = _syntax.getActions(registered_identifier);
332 
333  if (iters.first == iters.second)
334  {
336  n,
337  "section '",
338  curr_identifier,
339  "' does not have an associated \"Action\".\nDid you misspell it?"));
340  }
341 
342  for (auto it = iters.first; it != iters.second; ++it)
343  {
344  if (is_parent)
345  continue;
346  if (_syntax.isDeprecatedSyntax(registered_identifier))
348  errormsg(getFileName(), n, "\"[", registered_identifier, "]\" is deprecated."));
349 
350  params = _action_factory.getValidParams(it->second._action);
351 
352  params.set<ActionWarehouse *>("awh") = &_action_wh;
353 
354  extractParams(curr_identifier, params);
355 
356  // Add the parsed syntax to the parameters object for consumption by the Action
357  params.set<std::string>("task") = it->second._task;
358  params.set<std::string>("registered_identifier") = registered_identifier;
359  params.addPrivateParam<std::string>("parser_syntax", curr_identifier);
360 
361  // Create the Action
362  std::shared_ptr<Action> action_obj =
363  _action_factory.create(it->second._action, MooseUtils::shortName(curr_identifier), params);
364 
365  // extract the MooseObject params if necessary
366  std::shared_ptr<MooseObjectAction> object_action =
367  std::dynamic_pointer_cast<MooseObjectAction>(action_obj);
368  if (object_action)
369  {
370  extractParams(curr_identifier, object_action->getObjectParams());
371  object_action->getObjectParams()
372  .set<std::vector<std::string>>("control_tags")
373  .push_back(MooseUtils::baseName(curr_identifier));
374  }
375 
376  // add it to the warehouse
377  _action_wh.addActionBlock(action_obj);
378  }
379 }
380 
381 void
382 Parser::walk(const std::string & fullpath, const std::string & nodepath, hit::Node * n)
383 {
384  // skip sections that were manually processed first.
385  for (auto & sec : _secs_need_first)
386  if (nodepath == sec)
387  return;
388  walkRaw(fullpath, nodepath, n);
389 }
390 
391 std::string
392 Parser::hitCLIFilter(std::string appname, int argc, char * argv[])
393 {
394  std::string hit_text;
395  bool afterDoubleDash = false;
396  for (int i = 1; i < argc; i++)
397  {
398  std::string arg(argv[i]);
399 
400  // all args after a "--" are hit parameters
401  if (arg == "--")
402  {
403  afterDoubleDash = true;
404  continue;
405  } // otherwise try to guess if a hit params have started by looking for "=" and "/"
406  else if (arg.find("=", 0) != std::string::npos)
407  afterDoubleDash = true;
408 
409  // skip arguments with no equals sign
410  if (arg.find("=", 0) == std::string::npos)
411  continue;
412  // skip cli flags (i.e. start with dash)
413  else if (arg.find("-", 0) == 0)
414  continue;
415  // skip over args that don't look like or are before hit parameters
416  else if (!afterDoubleDash)
417  continue;
418  else if (appname == "main")
419  {
420  auto pos = arg.find(":", 0);
421  if (pos == 0) // trim leading colon
422  arg = arg.substr(pos + 1, arg.size() - pos - 1);
423  else if (pos != std::string::npos && pos < arg.find("=", 0)) // param is for non-main subapp
424  continue;
425  }
426  else if (appname != "main") // app we are loading is a multiapp subapp
427  {
428  std::string name;
429  std::string num;
430  pcrecpp::RE("(.*?)" // Match the multiapp name
431  "(\\d+)" // math the multiapp number
432  )
433  .FullMatch(appname, &name, &num);
434  auto pos = arg.find(":", 0);
435  if (pos == 0)
436  ; // cli param is ":" prefixed meaning global for all main+subapps
437  else if (pos == std::string::npos) // param is for main app - skip
438  continue;
439  else if (arg.substr(0, pos) != appname &&
440  arg.substr(0, pos) != name) // param is for different multiapp - skip
441  {
442  _app.commandLine()->markHitParam(i);
443  continue;
444  }
445  arg = arg.substr(pos + 1, arg.size() - pos - 1); // trim off subapp name prefix
446  }
447 
448  try
449  {
450  hit::check("CLI_ARG", arg);
451  hit_text += " " + arg;
452  // handle case where bash ate quotes around an empty string after the "="
453  if (arg.find("=", 0) == arg.size() - 1)
454  hit_text += "''";
455  _app.commandLine()->markHitParamUsed(i);
456  }
457  catch (hit::ParseError & err)
458  {
459  // bash might have eaten quotes around a hit string value or vector
460  // so try quoting after the "=" and reparse
461  auto quoted = arg;
462  auto pos = quoted.find("=", 0);
463  if (pos != std::string::npos)
464  quoted = arg.substr(0, pos + 1) + "'" + arg.substr(pos + 1, quoted.size() - pos) + "'";
465  try
466  {
467  hit::check("CLI_ARG", quoted);
468  hit_text += " " + quoted;
469  _app.commandLine()->markHitParamUsed(i);
470  }
471  catch (hit::ParseError & err)
472  {
473  mooseError("invalid hit in arg '", arg, "': ", err.what());
474  }
475  }
476  }
477  return hit_text;
478 }
479 
480 void
481 Parser::parse(const std::string & input_filename)
482 {
483  // Save the filename
484  char abspath[PATH_MAX + 1];
485  realpath(input_filename.c_str(), abspath);
486  _input_filename = std::string(abspath);
487 
488  // vector for initializing active blocks
489  std::vector<std::string> all = {"__all__"};
490 
491  MooseUtils::checkFileReadable(_input_filename, true);
492 
493  std::ifstream f(_input_filename);
494  std::string input((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
495 
496  try
497  {
498  _root.reset(hit::parse(_input_filename, input));
499 
500  int argc = _app.commandLine()->argc();
501  char ** argv = _app.commandLine()->argv();
502  auto cli_input = hitCLIFilter(_app.name(), argc, argv);
503 
504  _cli_root.reset(hit::parse("CLI_ARGS", cli_input));
505  hit::explode(_cli_root.get());
506  hit::explode(_root.get());
507  hit::merge(_cli_root.get(), _root.get());
508  }
509  catch (hit::ParseError & err)
510  {
511  mooseError(err.what());
512  }
513 
514  // expand ${bla} parameter values and mark/include variables used in expansions as "used". This
515  // MUST occur before parameter extraction - otherwise parameters will get wrong values.
516  ExpandWalker exw(_input_filename);
517  _root->walk(&exw);
518  for (auto & var : exw.used)
519  _extracted_vars.insert(var);
520  for (auto & msg : exw.errors)
521  _errmsg += msg + "\n";
522 
523  // do as much error checking as early as possible so that errors are more useful instead
524  // of surprising and disconnected from what caused them.
525  DupParamWalker dw(_input_filename);
526  BadActiveWalker bw(_input_filename);
527  _root->walk(&dw, hit::NodeType::Field);
528  _root->walk(&bw, hit::NodeType::Section);
529  for (auto & msg : dw.errors)
530  _errmsg += msg + "\n";
531  for (auto & msg : bw.errors)
532  _errmsg += msg + "\n";
533 
534  if (_errmsg.size() > 0)
536 
537  // There are a few order dependent actions that have to be built first in
538  // order for the parser and application to function properly:
539  //
540  // SetupDebugAction: This action can contain an option for monitoring the parser progress. It must
541  // be parsed first to capture all of the parsing output.
542  //
543  // GlobalParamsAction: This action is checked during the parameter extraction routines of all
544  // subsequent blocks. It must be parsed early since it must exist during
545  // subsequent parameter extraction.
546  //
547  // DynamicObjectRegistration: This action must be built before any MooseObjectActions are built.
548  // This is because we retrieve valid parameters from the Factory
549  // during parse time. Objects must be registered before
550  // validParameters can be retrieved.
551  _secs_need_first = {
552  _syntax.getSyntaxByAction("SetupDebugAction", "setup_debug"),
553  _syntax.getSyntaxByAction("GlobalParamsAction", "set_global_params"),
554  _syntax.getSyntaxByAction("DynamicObjectRegistrationAction", "dynamic_object_registration"),
555  };
556 
557  // walk all the sections extracting paramters from each into InputParameters objects
558  for (auto & sec : _secs_need_first)
559  {
560  auto n = _root->find(sec);
561  if (n)
562  walkRaw(n->parent()->fullpath(), n->path(), n);
563  }
564  _root->walk(this, hit::NodeType::Section);
565 }
566 
567 // Checks the input and the way it has been used and emits any errors/warnings.
568 // This has to be a separate function because for we don't know if some parameters were unused
569 // until all the multiapps/subapps have been fully initialized - which isn't complete until
570 // *after* all the other member functions on Parser have been run. So this is here to be
571 // externally called at the right time.
572 void
573 Parser::errorCheck(const Parallel::Communicator & comm, bool warn_unused, bool err_unused)
574 {
575  // this if guard is important in case the simulation was not configured via parsed input text -
576  // e.g. configured programatically.
577  if (!_root || !_cli_root)
578  return;
579 
581  UnusedWalker uwcli("CLI_ARG", _extracted_vars, *this);
582 
583  _root->walk(&uw);
584  _cli_root->walk(&uwcli);
585 
586  auto cli = _app.commandLine();
587  if (warn_unused)
588  {
589  for (auto arg : cli->unused(comm))
590  _warnmsg +=
591  errormsg("CLI_ARG", nullptr, "unused command line parameter '", cli->argv()[arg], "'") +
592  "\n";
593  for (auto & msg : uwcli.errors)
594  _warnmsg += msg + "\n";
595  for (auto & msg : uw.errors)
596  _warnmsg += msg + "\n";
597  }
598  else if (err_unused)
599  {
600  for (auto arg : cli->unused(comm))
601  _errmsg +=
602  errormsg("CLI_ARG", nullptr, "unused command line parameter '", cli->argv()[arg], "'") +
603  "\n";
604  for (auto & msg : uwcli.errors)
605  _errmsg += msg + "\n";
606  for (auto & msg : uw.errors)
607  _errmsg += msg + "\n";
608  }
609 
610  if (_warnmsg.size() > 0)
612  if (_errmsg.size() > 0)
614 }
615 
616 void
618 {
619  switch (type)
620  {
621  case INPUT_FILE:
622  _syntax_formatter = libmesh_make_unique<InputFileFormatter>(dump_mode);
623  break;
624  case YAML:
625  _syntax_formatter = libmesh_make_unique<YAMLFormatter>(dump_mode);
626  break;
627  default:
628  mooseError("Unrecognized Syntax Formatter requested");
629  break;
630  }
631 }
632 
633 void
635 {
636  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
637 
638  for (const auto & iter : _syntax.getAssociatedTypes())
639  root.addSyntaxType(iter.first, iter.second);
640 
641  for (const auto & iter : _syntax.getAssociatedActions())
642  {
643  Syntax::ActionInfo act_info = iter.second;
649  if (act_info._task == "")
650  act_info._task = _action_factory.getTaskName(act_info._action);
651 
652  all_names.push_back(std::make_pair(iter.first, act_info));
653  }
654 
655  for (const auto & act_names : all_names)
656  {
657  const auto & act_info = act_names.second;
658  const std::string & action = act_info._action;
659  const std::string & task = act_info._task;
660  const std::string act_name = act_names.first;
661  InputParameters action_obj_params = _action_factory.getValidParams(action);
662  bool params_added = root.addParameters("",
663  act_name,
664  false,
665  action,
666  true,
667  &action_obj_params,
668  _syntax.getLineInfo(act_name, action, ""),
669  "");
670 
671  if (params_added)
672  {
673  auto tasks = _action_factory.getTasksByAction(action);
674  for (auto & t : tasks)
675  {
676  auto info = _action_factory.getLineInfo(action, t);
677  root.addActionTask(act_name, action, t, info);
678  }
679  }
680 
686  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
687  action_obj_params.get<bool>("isObjectAction"))
688  {
690  moose_obj != _factory.registeredObjectsEnd();
691  ++moose_obj)
692  {
693  InputParameters moose_obj_params = (moose_obj->second)();
694  // Now that we know that this is a MooseObjectAction we need to see if it has been
695  // restricted
696  // in any way by the user.
697  const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
698 
699  // See if the current Moose Object syntax belongs under this Action's block
700  if ((buildable_types.empty() || // Not restricted
701  std::find(buildable_types.begin(), buildable_types.end(), moose_obj->first) !=
702  buildable_types.end()) && // Restricted but found
703  moose_obj_params.have_parameter<std::string>("_moose_base") && // Has a registered base
704  _syntax.verifyMooseObjectTask(moose_obj_params.get<std::string>("_moose_base"),
705  task) && // and that base is associated
706  action_obj_params.mooseObjectSyntaxVisibility()) // and the Action says it's visible
707  {
708  std::string name;
709  size_t pos = 0;
710  bool is_action_params = false;
711  bool is_type = false;
712  if (act_name[act_name.size() - 1] == '*')
713  {
714  pos = act_name.size();
715 
716  if (!action_obj_params.collapseSyntaxNesting())
717  name = act_name.substr(0, pos - 1) + moose_obj->first;
718  else
719  {
720  name = act_name.substr(0, pos - 1) + "/<type>/" + moose_obj->first;
721  is_action_params = true;
722  }
723  }
724  else
725  {
726  name = act_name + "/<type>/" + moose_obj->first;
727  is_type = true;
728  }
729 
730  moose_obj_params.set<std::string>("type") = moose_obj->first;
731 
732  auto lineinfo = _factory.getLineInfo(moose_obj->first);
733  std::string classname = _factory.associatedClassName(moose_obj->first);
734  root.addParameters(act_name,
735  name,
736  is_type,
737  moose_obj->first,
738  is_action_params,
739  &moose_obj_params,
740  lineinfo,
741  classname);
742  }
743  }
744  }
745  }
746  root.addGlobal();
747 }
748 
749 void
750 Parser::buildFullTree(const std::string & search_string)
751 {
752  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
753 
754  for (const auto & iter : _syntax.getAssociatedActions())
755  {
756  Syntax::ActionInfo act_info = iter.second;
762  if (act_info._task == "")
763  act_info._task = _action_factory.getTaskName(act_info._action);
764 
765  all_names.push_back(std::pair<std::string, Syntax::ActionInfo>(iter.first, act_info));
766  }
767 
768  for (const auto & act_names : all_names)
769  {
770  InputParameters action_obj_params = _action_factory.getValidParams(act_names.second._action);
771  _syntax_formatter->insertNode(
772  act_names.first, act_names.second._action, true, &action_obj_params);
773 
774  const std::string & task = act_names.second._task;
775  std::string act_name = act_names.first;
776 
782  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
783  action_obj_params.get<bool>("isObjectAction"))
784  {
786  moose_obj != _factory.registeredObjectsEnd();
787  ++moose_obj)
788  {
789  InputParameters moose_obj_params = (moose_obj->second)();
794  const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
795 
796  // See if the current Moose Object syntax belongs under this Action's block
797  if ((buildable_types.empty() || // Not restricted
798  std::find(buildable_types.begin(), buildable_types.end(), moose_obj->first) !=
799  buildable_types.end()) && // Restricted but found
800  moose_obj_params.have_parameter<std::string>("_moose_base") && // Has a registered base
801  _syntax.verifyMooseObjectTask(moose_obj_params.get<std::string>("_moose_base"),
802  task) && // and that base is associated
803  action_obj_params.mooseObjectSyntaxVisibility()) // and the Action says it's visible
804  {
805  std::string name;
806  size_t pos = 0;
807  bool is_action_params = false;
808  if (act_name[act_name.size() - 1] == '*')
809  {
810  pos = act_name.size();
811 
812  if (!action_obj_params.collapseSyntaxNesting())
813  name = act_name.substr(0, pos - 1) + moose_obj->first;
814  else
815  {
816  name = act_name.substr(0, pos - 1) + "/<type>/" + moose_obj->first;
817  is_action_params = true;
818  }
819  }
820  else
821  {
822  name = act_name + "/<type>/" + moose_obj->first;
823  }
824 
825  moose_obj_params.set<std::string>("type") = moose_obj->first;
826 
827  _syntax_formatter->insertNode(
828  name, moose_obj->first, is_action_params, &moose_obj_params);
829  }
830  }
831  }
832  }
833 
834  // Do not change to _console, we need this printed to the stdout in all cases
835  Moose::out << _syntax_formatter->print(search_string) << std::flush;
836 }
837 
838 /**************************************************************************************************
839  **************************************************************************************************
840  * Parameter Extraction Routines *
841  **************************************************************************************************
842  **************************************************************************************************/
843 using std::string;
844 
845 // Template Specializations for retrieving special types from the input file
846 template <>
847 void Parser::setScalarParameter<RealVectorValue, RealVectorValue>(
848  const std::string & full_name,
849  const std::string & short_name,
850  InputParameters::Parameter<RealVectorValue> * param,
851  bool in_global,
852  GlobalParamsAction * global_block);
853 
854 template <>
855 void Parser::setScalarParameter<Point, Point>(const std::string & full_name,
856  const std::string & short_name,
857  InputParameters::Parameter<Point> * param,
858  bool in_global,
859  GlobalParamsAction * global_block);
860 
861 template <>
862 void Parser::setScalarParameter<PostprocessorName, PostprocessorName>(
863  const std::string & full_name,
864  const std::string & short_name,
865  InputParameters::Parameter<PostprocessorName> * param,
866  bool in_global,
867  GlobalParamsAction * global_block);
868 
869 template <>
870 void Parser::setScalarParameter<MooseEnum, MooseEnum>(const std::string & full_name,
871  const std::string & short_name,
872  InputParameters::Parameter<MooseEnum> * param,
873  bool in_global,
874  GlobalParamsAction * global_block);
875 
876 template <>
877 void Parser::setScalarParameter<MultiMooseEnum, MultiMooseEnum>(
878  const std::string & full_name,
879  const std::string & short_name,
880  InputParameters::Parameter<MultiMooseEnum> * param,
881  bool in_global,
882  GlobalParamsAction * global_block);
883 
884 template <>
885 void Parser::setScalarParameter<RealTensorValue, RealTensorValue>(
886  const std::string & full_name,
887  const std::string & short_name,
888  InputParameters::Parameter<RealTensorValue> * param,
889  bool in_global,
890  GlobalParamsAction * global_block);
891 
892 // Vectors
893 template <>
894 void Parser::setVectorParameter<RealVectorValue, RealVectorValue>(
895  const std::string & full_name,
896  const std::string & short_name,
897  InputParameters::Parameter<std::vector<RealVectorValue>> * param,
898  bool in_global,
899  GlobalParamsAction * global_block);
900 
901 template <>
902 void
903 Parser::setVectorParameter<Point, Point>(const std::string & full_name,
904  const std::string & short_name,
905  InputParameters::Parameter<std::vector<Point>> * param,
906  bool in_global,
907  GlobalParamsAction * global_block);
908 
909 template <>
910 void Parser::setVectorParameter<MooseEnum, MooseEnum>(
911  const std::string & full_name,
912  const std::string & short_name,
913  InputParameters::Parameter<std::vector<MooseEnum>> * param,
914  bool in_global,
915  GlobalParamsAction * global_block);
916 
917 template <>
918 void Parser::setVectorParameter<VariableName, VariableName>(
919  const std::string & full_name,
920  const std::string & short_name,
921  InputParameters::Parameter<std::vector<VariableName>> * param,
922  bool in_global,
923  GlobalParamsAction * global_block);
924 
925 void
926 Parser::extractParams(const std::string & prefix, InputParameters & p)
927 {
928  std::ostringstream error_stream;
929  static const std::string global_params_task = "set_global_params";
930  static const std::string global_params_block_name =
931  _syntax.getSyntaxByAction("GlobalParamsAction", global_params_task);
932 
933  ActionIterator act_iter = _action_wh.actionBlocksWithActionBegin(global_params_task);
934  GlobalParamsAction * global_params_block = nullptr;
935 
936  // We are grabbing only the first
937  if (act_iter != _action_wh.actionBlocksWithActionEnd(global_params_task))
938  global_params_block = dynamic_cast<GlobalParamsAction *>(*act_iter);
939 
940  // Set a pointer to the current InputParameters object being parsed so that it can be referred
941  // to
942  // in the extraction routines
943  _current_params = &p;
944  _current_error_stream = &error_stream;
945  for (const auto & it : p)
946  {
947  bool found = false;
948  bool in_global = false;
949  std::string orig_name = prefix + "/" + it.first;
950  std::string full_name = orig_name;
951 
952  // Mark parameters appearing in the input file or command line
953  if (_root->find(full_name) && _root->find(full_name)->type() == hit::NodeType::Field)
954  {
955  p.set_attributes(it.first, false);
956  _extracted_vars.insert(
957  full_name); // Keep track of all variables extracted from the input file
958  found = true;
959  }
960  // Wait! Check the GlobalParams section
961  else if (global_params_block)
962  {
963  full_name = global_params_block_name + "/" + it.first;
964  if (_root->find(full_name))
965  {
966  p.set_attributes(it.first, false);
967  _extracted_vars.insert(
968  full_name); // Keep track of all variables extracted from the input file
969  found = true;
970  in_global = true;
971  }
972  }
973 
974  if (!found)
975  {
982  // In the case where we have OutFileName but it wasn't actually found in the input filename,
983  // we will populate it with the actual parsed filename which is available here in the
984  // parser.
985 
986  InputParameters::Parameter<OutFileBase> * scalar_p =
987  dynamic_cast<InputParameters::Parameter<OutFileBase> *>(it.second);
988  if (scalar_p)
989  {
990  std::string input_file_name = getFileName();
991  mooseAssert(input_file_name != "", "Input Filename is nullptr");
992  size_t pos = input_file_name.find_last_of('.');
993  mooseAssert(pos != std::string::npos, "Unable to determine suffix of input file name");
994  scalar_p->set() = input_file_name.substr(0, pos) + "_out";
995  p.set_attributes(it.first, false);
996  }
997  }
998  else
999  {
1000  if (p.isPrivate(it.first))
1001  mooseError("The parameter '",
1002  full_name,
1003  "' is a private parameter and should not be used in an input file.");
1004 
1005  auto par = it.second;
1006  auto short_name = it.first;
1007 
1008 #define setscalarvaltype(ptype, base, range) \
1009  else if (par->type() == demangle(typeid(ptype).name())) \
1010  setScalarValueTypeParameter<ptype, range, base>( \
1011  full_name, \
1012  short_name, \
1013  dynamic_cast<InputParameters::Parameter<ptype> *>(par), \
1014  in_global, \
1015  global_params_block)
1016 #define setscalar(ptype, base) \
1017  else if (par->type() == demangle(typeid(ptype).name())) \
1018  setScalarParameter<ptype, base>(full_name, \
1019  short_name, \
1020  dynamic_cast<InputParameters::Parameter<ptype> *>(par), \
1021  in_global, \
1022  global_params_block)
1023 #define setfpath(ptype) \
1024  else if (par->type() == demangle(typeid(ptype).name())) \
1025  setFilePathParam<ptype>(full_name, \
1026  short_name, \
1027  dynamic_cast<InputParameters::Parameter<ptype> *>(par), \
1028  p, \
1029  in_global, \
1030  global_params_block)
1031 #define setvector(ptype, base) \
1032  else if (par->type() == demangle(typeid(std::vector<ptype>).name())) \
1033  setVectorParameter<ptype, base>( \
1034  full_name, \
1035  short_name, \
1036  dynamic_cast<InputParameters::Parameter<std::vector<ptype>> *>(par), \
1037  in_global, \
1038  global_params_block)
1039 #define setvectorfpath(ptype) \
1040  else if (par->type() == demangle(typeid(std::vector<ptype>).name())) \
1041  setVectorFilePathParam<ptype>( \
1042  full_name, \
1043  short_name, \
1044  dynamic_cast<InputParameters::Parameter<std::vector<ptype>> *>(par), \
1045  p, \
1046  in_global, \
1047  global_params_block)
1048 #define setvectorvector(ptype) \
1049  else if (par->type() == demangle(typeid(std::vector<std::vector<ptype>>).name())) \
1050  setDoubleIndexParameter<ptype>( \
1051  full_name, \
1052  short_name, \
1053  dynamic_cast<InputParameters::Parameter<std::vector<std::vector<ptype>>> *>(par), \
1054  in_global, \
1055  global_params_block)
1056 
1060  // built-ins
1061  // NOTE: Similar dynamic casting is done in InputParameters.C, please update appropriately
1062  if (false)
1063  ;
1064  setscalarvaltype(Real, double, Real);
1065  setscalarvaltype(int, int, long);
1066  setscalarvaltype(long, int, long);
1067  setscalarvaltype(unsigned int, int, long);
1068 
1069  setscalar(bool, bool);
1070  setscalar(SubdomainID, int);
1071  setscalar(BoundaryID, int);
1072 
1073  // string and string-subclass types
1074  setscalar(string, string);
1075  setscalar(SubdomainName, string);
1076  setscalar(BoundaryName, string);
1077  setfpath(FileName);
1078  setfpath(MeshFileName);
1079  setfpath(FileNameNoExtension);
1080  setscalar(OutFileBase, string);
1081  setscalar(VariableName, string);
1082  setscalar(NonlinearVariableName, string);
1083  setscalar(AuxVariableName, string);
1084  setscalar(FunctionName, string);
1085  setscalar(UserObjectName, string);
1086  setscalar(VectorPostprocessorName, string);
1087  setscalar(IndicatorName, string);
1088  setscalar(MarkerName, string);
1089  setscalar(MultiAppName, string);
1090  setscalar(OutputName, string);
1091  setscalar(MaterialPropertyName, string);
1092  setscalar(MaterialName, string);
1093  setscalar(DistributionName, string);
1094  setscalar(SamplerName, string);
1095 
1096  setscalar(PostprocessorName, PostprocessorName);
1097 
1098  // Moose Compound Scalars
1099  setscalar(RealVectorValue, RealVectorValue);
1100  setscalar(Point, Point);
1101  setscalar(MooseEnum, MooseEnum);
1102  setscalar(MultiMooseEnum, MultiMooseEnum);
1103  setscalar(RealTensorValue, RealTensorValue);
1104 
1105  // vector types
1106  setvector(Real, double);
1107  setvector(int, int);
1108  setvector(long, int);
1109  setvector(unsigned int, int);
1110 
1111 // We need to be able to parse 8-byte unsigned types when
1112 // libmesh is configured --with-dof-id-bytes=8. Officially,
1113 // libmesh uses uint64_t in that scenario, which is usually
1114 // equivalent to 'unsigned long long'. Note that 'long long'
1115 // has been around since C99 so most C++ compilers support it,
1116 // but presumably uint64_t is the "most standard" way to get a
1117 // 64-bit unsigned type, so we'll stick with that here.
1118 #if LIBMESH_DOF_ID_BYTES == 8
1119  setvector(uint64_t, int);
1120 #endif
1121 
1122  setvector(SubdomainID, int);
1123  setvector(BoundaryID, int);
1124  setvector(RealVectorValue, double);
1125  setvector(Point, Point);
1126  setvector(MooseEnum, MooseEnum);
1127 
1128  setvector(string, string);
1129  setvectorfpath(FileName);
1130  setvectorfpath(FileNameNoExtension);
1131  setvectorfpath(MeshFileName);
1132  setvector(SubdomainName, string);
1133  setvector(BoundaryName, string);
1134  setvector(NonlinearVariableName, string);
1135  setvector(AuxVariableName, string);
1136  setvector(FunctionName, string);
1137  setvector(UserObjectName, string);
1138  setvector(IndicatorName, string);
1139  setvector(MarkerName, string);
1140  setvector(MultiAppName, string);
1141  setvector(PostprocessorName, string);
1142  setvector(VectorPostprocessorName, string);
1143  setvector(OutputName, string);
1144  setvector(MaterialPropertyName, string);
1145  setvector(MaterialName, string);
1146  setvector(DistributionName, string);
1147  setvector(SamplerName, string);
1148 
1149  setvector(VariableName, VariableName);
1150 
1151  // Double indexed types
1152  setvectorvector(Real);
1153  setvectorvector(int);
1154  setvectorvector(long);
1155  setvectorvector(unsigned int);
1156 
1157 // See vector type explanation
1158 #if LIBMESH_DOF_ID_BYTES == 8
1159  setvectorvector(uint64_t);
1160 #endif
1161 
1162  setvectorvector(SubdomainID);
1163  setvectorvector(BoundaryID);
1164  setvectorvector(string);
1165  setvectorvector(FileName);
1166  setvectorvector(FileNameNoExtension);
1167  setvectorvector(MeshFileName);
1168  setvectorvector(SubdomainName);
1169  setvectorvector(BoundaryName);
1170  setvectorvector(VariableName);
1171  setvectorvector(NonlinearVariableName);
1172  setvectorvector(AuxVariableName);
1173  setvectorvector(FunctionName);
1174  setvectorvector(UserObjectName);
1175  setvectorvector(IndicatorName);
1176  setvectorvector(MarkerName);
1177  setvectorvector(MultiAppName);
1178  setvectorvector(PostprocessorName);
1179  setvectorvector(VectorPostprocessorName);
1180  setvectorvector(MarkerName);
1181  setvectorvector(OutputName);
1182  setvectorvector(MaterialPropertyName);
1183  setvectorvector(MaterialName);
1184  setvectorvector(DistributionName);
1185  setvectorvector(SamplerName);
1186  else
1187  {
1188  mooseError("unsupported type '", par->type(), "' for input parameter '", full_name, "'");
1189  }
1190 
1191 #undef setscalarValueType
1192 #undef setscalar
1193 #undef setvector
1194 #undef setvectorvector
1195  }
1196  }
1197 
1198  // All of the parameters for this object have been extracted. See if there are any errors
1199  if (!error_stream.str().empty())
1200  mooseError(error_stream.str());
1201 
1202  // Here we will see if there are any auto build vectors that need to be created
1203  const std::map<std::string, std::pair<std::string, std::string>> & auto_build_vectors =
1204  p.getAutoBuildVectors();
1205  for (const auto & it : auto_build_vectors)
1206  {
1207  // We'll autogenerate values iff the requested vector is not valid but both the base and
1208  // number
1209  // are valid
1210  const std::string & base_name = it.second.first;
1211  const std::string & num_repeat = it.second.second;
1212 
1213  if (!p.isParamValid(it.first) && p.isParamValid(base_name) && p.isParamValid(num_repeat))
1214  {
1215  unsigned int vec_size = p.get<unsigned int>(num_repeat);
1216  const std::string & name = p.get<std::string>(base_name);
1217 
1218  std::vector<VariableName> variable_names(vec_size);
1219  for (unsigned int i = 0; i < vec_size; ++i)
1220  {
1221  std::ostringstream oss;
1222  oss << name << i;
1223  variable_names[i] = oss.str();
1224  }
1225 
1226  // Finally set the autogenerated vector into the InputParameters object
1227  p.set<std::vector<VariableName>>(it.first) = variable_names;
1228  }
1229  }
1230 }
1231 
1232 template <typename T, typename Base>
1233 void
1234 Parser::setScalarParameter(const std::string & full_name,
1235  const std::string & short_name,
1236  InputParameters::Parameter<T> * param,
1237  bool in_global,
1238  GlobalParamsAction * global_block)
1239 {
1240 
1241  try
1242  {
1243  param->set() = _root->param<Base>(full_name);
1244  }
1245  catch (hit::Error & err)
1246  {
1247  // handle the case where the user put a number inside quotes - we really shouldn't allow this,
1248  // but "backwards compatibility" :-(
1249  auto & t = typeid(T);
1250  if (t == typeid(int) || t == typeid(unsigned int) || t == typeid(SubdomainID) ||
1251  t == typeid(BoundaryID))
1252  {
1253  try
1254  {
1255  auto v = std::stoi(_root->param<std::string>(full_name));
1256  param->set() = *reinterpret_cast<T *>(&v);
1257  }
1258  catch (...)
1259  {
1261  _root->find(full_name),
1262  "invalid integer syntax for parameter: ",
1263  full_name,
1264  "=",
1265  _root->param<std::string>(full_name)));
1266  }
1267  }
1268  else if (t == typeid(double))
1269  {
1270  try
1271  {
1272  auto v = std::stod(_root->param<std::string>(full_name));
1273  param->set() = *reinterpret_cast<T *>(&v);
1274  }
1275  catch (...)
1276  {
1278  _root->find(full_name),
1279  "invalid float syntax for parameter: ",
1280  full_name,
1281  "=",
1282  _root->param<std::string>(full_name)));
1283  }
1284  }
1285  else
1286  throw;
1287  }
1288 
1289  if (in_global)
1290  {
1291  global_block->remove(short_name);
1292  global_block->setScalarParam<T>(short_name) = param->get();
1293  }
1294 }
1295 
1296 template <typename T>
1297 void
1298 Parser::setFilePathParam(const std::string & full_name,
1299  const std::string & short_name,
1300  InputParameters::Parameter<T> * param,
1301  InputParameters & params,
1302  bool in_global,
1303  GlobalParamsAction * global_block)
1304 {
1305  std::string prefix;
1306  std::string postfix = _root->param<std::string>(full_name);
1307  size_t pos = _input_filename.find_last_of('/');
1308  if (pos != std::string::npos && postfix[0] != '/' && !postfix.empty())
1309  prefix = _input_filename.substr(0, pos + 1);
1310 
1311  params.set<std::string>("_raw_" + short_name) = postfix;
1312  param->set() = prefix + postfix;
1313 
1314  if (in_global)
1315  {
1316  global_block->remove(short_name);
1317  global_block->setScalarParam<T>(short_name) = param->get();
1318  }
1319 }
1320 
1321 template <typename T, typename UP_T, typename Base>
1322 void
1323 Parser::setScalarValueTypeParameter(const std::string & full_name,
1324  const std::string & short_name,
1325  InputParameters::Parameter<T> * param,
1326  bool in_global,
1327  GlobalParamsAction * global_block)
1328 {
1329  setScalarParameter<T, Base>(full_name, short_name, param, in_global, global_block);
1330 
1331  // If this is a range checked param, we need to make sure that the value falls within the
1332  // requested range
1333  mooseAssert(_current_params, "Current params is nullptr");
1334 
1335  _current_params->rangeCheck<T, UP_T>(full_name, short_name, param, *_current_error_stream);
1336 }
1337 
1338 template <typename T, typename Base>
1339 void
1340 Parser::setVectorParameter(const std::string & full_name,
1341  const std::string & short_name,
1342  InputParameters::Parameter<std::vector<T>> * param,
1343  bool in_global,
1344  GlobalParamsAction * global_block)
1345 {
1346  std::vector<T> vec;
1347  if (_root->find(full_name))
1348  {
1349  auto tmp = _root->param<std::vector<Base>>(full_name);
1350  for (auto val : tmp)
1351  vec.push_back(val);
1352  }
1353 
1354  param->set() = vec;
1355 
1356  if (in_global)
1357  {
1358  global_block->remove(short_name);
1359  global_block->setVectorParam<T>(short_name).resize(param->get().size());
1360  for (unsigned int i = 0; i < vec.size(); ++i)
1361  global_block->setVectorParam<T>(short_name)[i] = param->get()[i];
1362  }
1363 }
1364 
1365 template <typename T>
1366 void
1367 Parser::setVectorFilePathParam(const std::string & full_name,
1368  const std::string & short_name,
1369  InputParameters::Parameter<std::vector<T>> * param,
1370  InputParameters & params,
1371  bool in_global,
1372  GlobalParamsAction * global_block)
1373 {
1374  std::vector<T> vec;
1375  std::vector<std::string> rawvec;
1376  if (_root->find(full_name))
1377  {
1378  auto tmp = _root->param<std::vector<std::string>>(full_name);
1379  for (auto val : tmp)
1380  {
1381  std::string prefix;
1382  std::string postfix = val;
1383  size_t pos = _input_filename.find_last_of('/');
1384  if (pos != std::string::npos && postfix[0] != '/')
1385  prefix = _input_filename.substr(0, pos + 1);
1386  rawvec.push_back(postfix);
1387  vec.push_back(prefix + postfix);
1388  }
1389  }
1390 
1391  params.set<std::vector<std::string>>("_raw_" + short_name) = rawvec;
1392  param->set() = vec;
1393 
1394  if (in_global)
1395  {
1396  global_block->remove(short_name);
1397  global_block->setVectorParam<T>(short_name).resize(param->get().size());
1398  for (unsigned int i = 0; i < vec.size(); ++i)
1399  global_block->setVectorParam<T>(short_name)[i] = param->get()[i];
1400  }
1401 }
1402 
1403 template <typename T>
1404 void
1405 Parser::setDoubleIndexParameter(const std::string & full_name,
1406  const std::string & short_name,
1407  InputParameters::Parameter<std::vector<std::vector<T>>> * param,
1408  bool in_global,
1409  GlobalParamsAction * global_block)
1410 {
1411  // Get the full string assigned to the variable full_name
1412  std::string buffer = _root->param<std::string>(full_name);
1413 
1414  // split vector at delim ;
1415  // NOTE: the substrings are _not_ of type T yet
1416  std::vector<std::string> first_tokenized_vector;
1417  MooseUtils::tokenize(buffer, first_tokenized_vector, 1, ";");
1418  param->set().resize(first_tokenized_vector.size());
1419 
1420  for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1421  if (!MooseUtils::tokenizeAndConvert<T>(first_tokenized_vector[j], param->set()[j]))
1422  mooseError("Reading parameter ", short_name, " failed.");
1423 
1424  if (in_global)
1425  {
1426  global_block->remove(short_name);
1427  global_block->setDoubleIndexParam<T>(short_name).resize(first_tokenized_vector.size());
1428  for (unsigned j = 0; j < first_tokenized_vector.size(); ++j)
1429  {
1430  global_block->setDoubleIndexParam<T>(short_name)[j].resize(param->get()[j].size());
1431  for (unsigned int i = 0; i < param->get()[j].size(); ++i)
1432  global_block->setDoubleIndexParam<T>(short_name)[j][i] = param->get()[j][i];
1433  }
1434  }
1435 }
1436 
1437 template <typename T>
1438 void
1439 Parser::setScalarComponentParameter(const std::string & full_name,
1440  const std::string & short_name,
1441  InputParameters::Parameter<T> * param,
1442  bool in_global,
1443  GlobalParamsAction * global_block)
1444 {
1445  auto vec = _root->param<std::vector<double>>(full_name);
1446 
1447  if (vec.size() != LIBMESH_DIM)
1448  mooseError(std::string("Error in Scalar Component parameter ") + full_name + ": size is ",
1449  vec.size(),
1450  ", should be ",
1451  LIBMESH_DIM);
1452 
1453  T value;
1454  for (unsigned int i = 0; i < vec.size(); ++i)
1455  value(i) = Real(vec[i]);
1456 
1457  param->set() = value;
1458  if (in_global)
1459  {
1460  global_block->remove(short_name);
1461  global_block->setScalarParam<T>(short_name) = value;
1462  }
1463 }
1464 
1465 template <typename T>
1466 void
1467 Parser::setVectorComponentParameter(const std::string & full_name,
1468  const std::string & short_name,
1469  InputParameters::Parameter<std::vector<T>> * param,
1470  bool in_global,
1471  GlobalParamsAction * global_block)
1472 {
1473  auto vec = _root->param<std::vector<double>>(full_name);
1474 
1475  if (vec.size() % LIBMESH_DIM)
1476  mooseError(std::string("Error in Vector Component parameter ") + full_name + ": size is ",
1477  vec.size(),
1478  ", should be a multiple of ",
1479  LIBMESH_DIM);
1480 
1481  std::vector<T> values;
1482  for (unsigned int i = 0; i < vec.size() / LIBMESH_DIM; ++i)
1483  {
1484  T value;
1485  for (int j = 0; j < LIBMESH_DIM; ++j)
1486  value(j) = Real(vec[i * LIBMESH_DIM + j]);
1487  values.push_back(value);
1488  }
1489 
1490  param->set() = values;
1491 
1492  if (in_global)
1493  {
1494  global_block->remove(short_name);
1495  global_block->setVectorParam<T>(short_name).resize(vec.size(), values[0]);
1496  for (unsigned int i = 0; i < vec.size() / LIBMESH_DIM; ++i)
1497  global_block->setVectorParam<T>(short_name)[i] = values[0];
1498  }
1499 }
1500 
1501 template <>
1502 void
1503 Parser::setScalarParameter<RealVectorValue, RealVectorValue>(
1504  const std::string & full_name,
1505  const std::string & short_name,
1506  InputParameters::Parameter<RealVectorValue> * param,
1507  bool in_global,
1508  GlobalParamsAction * global_block)
1509 {
1510  setScalarComponentParameter(full_name, short_name, param, in_global, global_block);
1511 }
1512 
1513 template <>
1514 void
1515 Parser::setScalarParameter<Point, Point>(const std::string & full_name,
1516  const std::string & short_name,
1517  InputParameters::Parameter<Point> * param,
1518  bool in_global,
1519  GlobalParamsAction * global_block)
1520 {
1521  setScalarComponentParameter(full_name, short_name, param, in_global, global_block);
1522 }
1523 
1524 template <>
1525 void
1526 Parser::setScalarParameter<MooseEnum, MooseEnum>(const std::string & full_name,
1527  const std::string & short_name,
1528  InputParameters::Parameter<MooseEnum> * param,
1529  bool in_global,
1530  GlobalParamsAction * global_block)
1531 {
1532  MooseEnum current_param = param->get();
1533 
1534  std::string value = _root->param<std::string>(full_name);
1535 
1536  param->set() = value;
1537  if (in_global)
1538  {
1539  global_block->remove(short_name);
1540  global_block->setScalarParam<MooseEnum>(short_name) = current_param;
1541  }
1542 }
1543 
1544 template <>
1545 void
1546 Parser::setScalarParameter<MultiMooseEnum, MultiMooseEnum>(
1547  const std::string & full_name,
1548  const std::string & short_name,
1549  InputParameters::Parameter<MultiMooseEnum> * param,
1550  bool in_global,
1551  GlobalParamsAction * global_block)
1552 {
1553  MultiMooseEnum current_param = param->get();
1554 
1555  auto vec = _root->param<std::vector<std::string>>(full_name);
1556 
1557  std::string raw_values;
1558  for (unsigned int i = 0; i < vec.size(); ++i)
1559  raw_values += ' ' + vec[i];
1560 
1561  param->set() = raw_values;
1562 
1563  if (in_global)
1564  {
1565  global_block->remove(short_name);
1566  global_block->setScalarParam<MultiMooseEnum>(short_name) = current_param;
1567  }
1568 }
1569 
1570 template <>
1571 void
1572 Parser::setScalarParameter<RealTensorValue, RealTensorValue>(
1573  const std::string & full_name,
1574  const std::string & short_name,
1575  InputParameters::Parameter<RealTensorValue> * param,
1576  bool in_global,
1577  GlobalParamsAction * global_block)
1578 {
1579  auto vec = _root->param<std::vector<double>>(full_name);
1580  if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
1581  mooseError(std::string("Error in RealTensorValue parameter ") + full_name + ": size is ",
1582  vec.size(),
1583  ", should be ",
1584  LIBMESH_DIM * LIBMESH_DIM);
1585 
1586  RealTensorValue value;
1587  for (int i = 0; i < LIBMESH_DIM; ++i)
1588  for (int j = 0; j < LIBMESH_DIM; ++j)
1589  value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
1590 
1591  param->set() = value;
1592  if (in_global)
1593  {
1594  global_block->remove(short_name);
1595  global_block->setScalarParam<RealTensorValue>(short_name) = value;
1596  }
1597 }
1598 
1599 // Specialization for coupling a Real value where a postprocessor would be needed in MOOSE
1600 template <>
1601 void
1602 Parser::setScalarParameter<PostprocessorName, PostprocessorName>(
1603  const std::string & full_name,
1604  const std::string & short_name,
1605  InputParameters::Parameter<PostprocessorName> * param,
1606  bool in_global,
1607  GlobalParamsAction * global_block)
1608 {
1609  PostprocessorName pps_name = _root->param<std::string>(full_name);
1610  param->set() = pps_name;
1611 
1612  Real real_value = -std::numeric_limits<Real>::max();
1613  std::istringstream ss(pps_name);
1614 
1615  if (ss >> real_value && ss.eof())
1616  _current_params->setDefaultPostprocessorValue(short_name, real_value);
1617 
1618  if (in_global)
1619  {
1620  global_block->remove(short_name);
1621  global_block->setScalarParam<PostprocessorName>(short_name) = pps_name;
1622  }
1623 }
1624 
1625 template <>
1626 void
1627 Parser::setVectorParameter<RealVectorValue, RealVectorValue>(
1628  const std::string & full_name,
1629  const std::string & short_name,
1630  InputParameters::Parameter<std::vector<RealVectorValue>> * param,
1631  bool in_global,
1632  GlobalParamsAction * global_block)
1633 {
1634  setVectorComponentParameter(full_name, short_name, param, in_global, global_block);
1635 }
1636 
1637 template <>
1638 void
1639 Parser::setVectorParameter<Point, Point>(const std::string & full_name,
1640  const std::string & short_name,
1641  InputParameters::Parameter<std::vector<Point>> * param,
1642  bool in_global,
1643  GlobalParamsAction * global_block)
1644 {
1645  setVectorComponentParameter(full_name, short_name, param, in_global, global_block);
1646 }
1647 
1648 template <>
1649 void
1650 Parser::setVectorParameter<MooseEnum, MooseEnum>(
1651  const std::string & full_name,
1652  const std::string & short_name,
1653  InputParameters::Parameter<std::vector<MooseEnum>> * param,
1654  bool in_global,
1655  GlobalParamsAction * global_block)
1656 {
1657  std::vector<MooseEnum> enum_values = param->get();
1658  std::vector<std::string> values(enum_values.size());
1659  for (unsigned int i = 0; i < values.size(); ++i)
1660  values[i] = static_cast<std::string>(enum_values[i]);
1661 
1666  std::vector<std::string> vec;
1667  if (_root->find(full_name))
1668  {
1669  vec = _root->param<std::vector<std::string>>(full_name);
1670  param->set().resize(vec.size(), enum_values[0]);
1671  }
1672 
1673  for (unsigned int i = 0; i < vec.size(); ++i)
1674  param->set()[i] = vec[i];
1675 
1676  if (in_global)
1677  {
1678  global_block->remove(short_name);
1679  global_block->setVectorParam<MooseEnum>(short_name).resize(vec.size(), enum_values[0]);
1680  for (unsigned int i = 0; i < vec.size(); ++i)
1681  global_block->setVectorParam<MooseEnum>(short_name)[i] = values[0];
1682  }
1683 }
1684 
1689 template <>
1690 void
1691 Parser::setVectorParameter<VariableName, VariableName>(
1692  const std::string & full_name,
1693  const std::string & short_name,
1694  InputParameters::Parameter<std::vector<VariableName>> * param,
1695  bool /*in_global*/,
1696  GlobalParamsAction * /*global_block*/)
1697 {
1698  auto vec = _root->param<std::vector<std::string>>(full_name);
1699  std::vector<VariableName> var_names(vec.size());
1700 
1701  bool has_var_names = false;
1702  for (unsigned int i = 0; i < vec.size(); ++i)
1703  {
1704  VariableName var_name = vec[i];
1705 
1706  Real real_value;
1707  std::istringstream ss(var_name);
1708 
1709  // If we are able to convert this value into a Real, then set a default coupled value
1710  if (ss >> real_value && ss.eof())
1711  /* FIXME: the real_value is assigned to defaultCoupledValue overriding the value assigned
1712  * before. Currently there is no functionality to separately assign the correct
1713  * "real_value[i]" in InputParameters.*/
1714  _current_params->defaultCoupledValue(short_name, real_value);
1715  else
1716  {
1717  var_names[i] = var_name;
1718  has_var_names = true;
1719  }
1720  }
1721 
1722  if (has_var_names)
1723  {
1724  param->set().resize(vec.size());
1725 
1726  for (unsigned int i = 0; i < vec.size(); ++i)
1727  if (var_names[i] == "")
1728  mooseError("MOOSE does not currently support a coupled vector where some parameters are "
1729  "reals and others are variables");
1730  else
1731  param->set()[i] = var_names[i];
1732  }
1733 }
FileLineInfo getLineInfo(const std::string &name) const
Gets file and line information where an object was initially registered.
Definition: Factory.C:136
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: Parser.C:1234
void addSyntaxType(const std::string &path, const std::string type)
Add an associated type to a block.
void setScalarValueTypeParameter(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< T > *param, bool in_global, GlobalParamsAction *global_block)
Definition: Parser.C:1323
MooseApp & _app
The MooseApp this Parser is part of.
Definition: Parser.h:267
void walkRaw(std::string fullpath, std::string nodepath, hit::Node *n)
Definition: Parser.C:309
InputParameters validParams< EmptyAction >()
Definition: EmptyAction.C:19
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 ...
Definition: MooseUtils.h:350
VectorValue< Real > RealVectorValue
Definition: Assembly.h:40
const std::multimap< std::string, ActionInfo > & getAssociatedActions() const
Definition: Syntax.h:108
std::list< Action * >::iterator ActionIterator
alias to hide implementation details
std::string _warnmsg
Definition: Parser.h:297
std::vector< std::string > errors
Definition: Parser.C:286
registeredMooseObjectIterator registeredObjectsEnd()
Access to registered object iterator (end)
Definition: Factory.h:310
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:74
subdomain_id_type SubdomainID
Definition: MooseTypes.h:77
void addActionTask(const std::string &path, const std::string &action, const std::string &task, const FileLineInfo &lineinfo)
Add a task to the tree.
std::set< std::string > _used
Definition: Parser.C:218
std::vector< std::string > _secs_need_first
Definition: Parser.h:264
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:252
SyntaxFormatterType
Definition: Parser.h:123
void mooseError(Args &&...args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:182
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
std::string associatedClassName(const std::string &name) const
Get the associated class name for an object name.
Definition: Factory.C:148
void mooseDeprecated(Args &&...args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:202
Parser & _parser
Definition: Parser.C:219
Base class for MOOSE-based applications.
Definition: MooseApp.h:58
Storage for action instances.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void walk(const std::string &fullpath, const std::string &nodepath, hit::Node *n)
Definition: Parser.C:382
virtual ~Parser()
Definition: Parser.C:69
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
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: Parser.C:926
Syntax & _syntax
Reference to an object that defines input file syntax.
Definition: Parser.h:275
std::map< std::string, paramsPtr >::iterator registeredMooseObjectIterator
alias for registered Object iterator
Definition: Factory.h:137
bool isSectionActive(std::string path, hit::Node *root)
Definition: Parser.C:72
const std::string & name() const
Get the name of the object.
Definition: MooseApp.h:70
std::set< std::string > _duplicates
Definition: Parser.C:134
std::vector< T > & setVectorParam(const std::string &name)
Holds the syntax in a Json::Value tree.
std::vector< std::vector< T > > & setDoubleIndexParam(const std::string &name)
std::string _action
Definition: Syntax.h:31
std::string shortName(const std::string &name)
Function for stripping name after the file / in parser block.
Definition: MooseUtils.C:325
std::string getFileName(bool stripLeadingPath=true) const
Return the filename that was parsed.
Definition: Parser.C:293
bool verifyMooseObjectTask(const std::string &base, const std::string &task) const
Definition: Syntax.C:231
std::string _input_filename
The input file name that is used for parameter extraction.
Definition: Parser.h:281
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true)
Checks to see if a file is readable (exists and permissions)
Definition: MooseUtils.C:121
void setDefaultPostprocessorValue(const std::string &name, const PostprocessorValue &value)
Set the default value for a postprocessor added with addPostprocessor.
std::string isAssociated(const std::string &real_id, bool *is_parent)
Method for determining whether a piece of syntax is associated with an Action TODO: I need a better n...
Definition: Syntax.C:159
std::string _fname
Definition: Parser.C:133
void initSyntaxFormatter(SyntaxFormatterType type, bool dump_mode)
Creates a syntax formatter for printing.
Definition: Parser.C:617
std::unique_ptr< hit::Node > _cli_root
Definition: Parser.h:262
std::vector< std::string > listValidParams(std::string &section_name)
Definition: Parser.C:165
std::string hitCLIFilter(std::string appname, int argc, char *argv[])
Definition: Parser.C:392
BadActiveWalker(std::string fname)
Definition: Parser.C:225
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: Parser.C:1405
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.
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:137
std::shared_ptr< CommandLine > commandLine()
Get the command line.
Definition: MooseApp.h:265
std::map< std::string, hit::Node * > _have
Definition: Parser.C:135
T & setScalarParam(const std::string &name)
An inteface for the _console for outputting to the Console object.
unsigned int get(unsigned int i) const
Indexing operator Operator to retrieve an item from the MultiMooseEnum.
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: Parser.C:1340
std::pair< std::multimap< std::string, ActionInfo >::iterator, std::multimap< std::string, ActionInfo >::iterator > getActions(const std::string &name)
Definition: Syntax.C:225
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:37
std::string getSyntaxByAction(const std::string &action, const std::string &task)
Definition: Syntax.C:143
std::vector< std::string > errors
Definition: Parser.C:214
std::unique_ptr< SyntaxTree > _syntax_formatter
Object for holding the syntax parse tree.
Definition: Parser.h:278
Parser(MooseApp &app, ActionWarehouse &action_wh)
Definition: Parser.C:55
std::string _errmsg
Definition: Parser.h:296
std::set< std::string > _extracted_vars
The set of all variables extracted from the input file.
Definition: Parser.h:284
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...
registeredMooseObjectIterator registeredObjectsBegin()
Access to registered object iterator (begin)
Definition: Factory.h:305
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: Parser.C:1467
ActionWarehouse & _action_wh
Action warehouse that will be filled by actions.
Definition: Parser.h:271
std::string getTaskName(const std::string &action)
Definition: ActionFactory.C:95
std::ostringstream * _current_error_stream
The current stream object used for capturing errors during extraction.
Definition: Parser.h:293
Real defaultCoupledValue(const std::string &coupling_name) const
Get the default value for an optionally coupled variable.
void setVectorFilePathParam(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< std::vector< T >> *param, InputParameters &params, bool in_global, GlobalParamsAction *global_block)
Sets an input parameter representing a vector of file paths using input file data.
Definition: Parser.C:1367
std::string _task
Definition: Syntax.h:32
MatType type
std::string baseName(const std::string &name)
Function for string the information before the final / in a parser block.
Definition: MooseUtils.C:331
void walk(const std::string &fullpath, const std::string &, hit::Node *n) override
Definition: Parser.C:112
PetscInt n
std::string errormsg(std::string, hit::Node *)
Definition: Parser.h:39
DupParamWalker(std::string fname)
Definition: Parser.C:111
std::unique_ptr< hit::Node > _root
Definition: Parser.h:263
void setFilePathParam(const std::string &full_name, const std::string &short_name, InputParameters::Parameter< T > *param, InputParameters &params, bool in_global, GlobalParamsAction *global_block)
Sets an input parameter representing a file path using input file data.
Definition: Parser.C:1298
void errorCheck(const Parallel::Communicator &comm, bool warn_unused, bool err_unused)
Definition: Parser.C:573
const std::multimap< std::string, std::string > & getAssociatedTypes() const
Get a multimap of registered associations of syntax with type.
Definition: Syntax.h:80
MPI_Comm comm
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters parameters)
Definition: ActionFactory.C:26
void addGlobal()
Add the global section to the output.
int levenshteinDist(const std::string &s1, const std::string &s2)
Computes and returns the Levenshtein distance between strings s1 and s2.
Definition: MooseUtils.C:46
ActionIterator actionBlocksWithActionEnd(const std::string &task)
InputParameters * _current_params
The current parameter object for which parameters are being extracted.
Definition: Parser.h:290
void buildJsonSyntaxTree(JsonSyntaxTree &tree) const
Use MOOSE Factories to construct a parameter tree for documentation or echoing input.
Definition: Parser.C:634
void walk(const std::string &fullpath, const std::string &nodename, hit::Node *n) override
Definition: Parser.C:189
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
UnusedWalker(std::string fname, std::set< std::string > used, Parser &p)
Definition: Parser.C:184
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...
TensorValue< Real > RealTensorValue
Definition: Assembly.h:45
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: Parser.C:1439
Factory & _factory
The Factory associated with that MooseApp.
Definition: Parser.h:269
const std::vector< std::string > & getBuildableTypes() const
Returns the list of buildable types as a std::vector<std::string>
ActionFactory & _action_factory
The Factory that builds actions.
Definition: Parser.h:273
std::vector< std::string > findSimilar(std::string param, std::vector< std::string > options)
Definition: Parser.C:139
FileLineInfo getLineInfo(const std::string &name, const std::string &task) const
Gets file and line information where an action was registered.
std::set< std::string > getTasksByAction(const std::string &action) const
void parse(const std::string &input_filename)
Parse an input file consisting of hit syntax and setup objects in the MOOSE derived application...
Definition: Parser.C:481
std::string _fname
Definition: Parser.C:217
Class for parsing input files.
Definition: Parser.h:120
std::vector< std::string > errors
Definition: Parser.C:130
void walk(const std::string &, const std::string &, hit::Node *section) override
Definition: Parser.C:226
InputParameters validParams< Action >()
Definition: Action.C:23
void buildFullTree(const std::string &search_string)
Use MOOSE Factories to construct a full parse tree for documentation or echoing input.
Definition: Parser.C:750
std::string _fname
Definition: Parser.C:289
boundary_id_type BoundaryID
Definition: MooseTypes.h:75
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 mooseWarning(Args &&...args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:194