https://mooseframework.inl.gov
InputParameters.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 "InputParameters.h"
11 
12 // MOOSE includes
13 #include "MooseEnum.h"
14 #include "MooseTypes.h"
15 #include "MooseUtils.h"
16 #include "MultiMooseEnum.h"
17 #include "ExecFlagEnum.h"
18 #include "MooseObject.h"
19 
20 #include "libmesh/utility.h"
21 #include "libmesh/simple_range.h"
22 
23 #include "pcrecpp.h"
24 #include "hit/parse.h"
25 
26 #include <cmath>
27 #include <filesystem>
28 
31 {
32  InputParameters params;
33  return params;
34 }
35 
37  : Parameters(),
38  _collapse_nesting(false),
39  _moose_object_syntax_visibility(true),
40  _show_deprecated_message(true),
41  _allow_copy(true),
42  _hit_node(nullptr),
43  _finalized(false)
44 {
45 }
46 
48  : Parameters(), _show_deprecated_message(true), _allow_copy(true)
49 {
50  *this = rhs;
51 }
52 
53 InputParameters::InputParameters(const Parameters & rhs)
54  : _show_deprecated_message(true), _allow_copy(true)
55 {
56  _params.clear();
58  _collapse_nesting = false;
60 }
61 
62 void
64 {
66  _params.clear();
67  _coupled_vars.clear();
69  _collapse_nesting = false;
72  _allow_copy = true;
73  _block_fullpath = "";
74  _block_location = "";
76  _new_to_old_names.clear();
77  _hit_node = nullptr;
78  _finalized = false;
79 }
80 
81 void
82 InputParameters::addClassDescription(const std::string & doc_string)
83 {
84  _class_description = doc_string;
85 }
86 
87 void
88 InputParameters::set_attributes(const std::string & name_in, bool inserted_only)
89 {
90  const auto name = checkForRename(name_in);
91 
92  if (!inserted_only)
93  {
94  auto & metadata = _params[name];
101  metadata._set_by_add_param = false;
102 
103  // valid_params don't make sense for MooseEnums
104  if (!have_parameter<MooseEnum>(name) && !have_parameter<MultiMooseEnum>(name))
105  metadata._valid = true;
106  }
107 }
108 
109 bool
110 InputParameters::attemptPrintDeprecated(const std::string & name_in)
111 {
112  const auto name = checkForRename(name_in);
114  {
115  auto emit_deprecation_message =
116  [this](const auto & deprecated_name, const auto & deprecation_message)
117  {
118  // This is user-facing, no need for a backtrace
119  const auto current_show_trace = Moose::show_trace;
120  Moose::show_trace = false;
122  Moose::out, false, true, errorPrefix(deprecated_name), ":\n", deprecation_message, "\n");
123  Moose::show_trace = current_show_trace;
124  return true;
125  };
126 
127  if (_params.count(name) && !libmesh_map_find(_params, name)._deprecation_message.empty())
128  return emit_deprecation_message(name,
129  "The parameter '" + name + "' is deprecated.\n" +
130  libmesh_map_find(_params, name)._deprecation_message);
131  else if (auto it = _old_to_new_name_and_dep.find(name_in);
132  it != _old_to_new_name_and_dep.end() && !it->second.second.empty())
133  return emit_deprecation_message(name_in, it->second.second);
134  }
135  return false;
136 }
137 
138 std::string
140 {
141  return _class_description;
142 }
143 
146 {
147  // An error to help minimize the segmentation faults that occure when MooseObjects do not have the
148  // correct constructor
149  if (!rhs._allow_copy)
150  {
151  const std::string & name =
152  rhs.get<std::string>("_object_name"); // If _allow_parameter_copy is set then so is name
153  // (see InputParameterWarehouse::addInputParameters)
154  mooseError("Copying of the InputParameters object for the ",
155  name,
156  " object is not allowed.\n\nThe likely cause for this error ",
157  "is having a constructor that does not use a const reference, all constructors\nfor "
158  "MooseObject based classes should be as follows:\n\n",
159  " MyObject::MyObject(const InputParameters & parameters);");
160  }
161 
163 
164  _params = rhs._params;
165 
172  _allow_copy = rhs._allow_copy;
177  _hit_node = rhs._hit_node;
178  _finalized = false;
179 
180  return *this;
181 }
182 
185 {
186  Parameters::operator+=(rhs);
187 
188  // TODO: this is not a proper merge - if a particular parameter exists in both this and rhs,
189  // then we should actually smartly merge both metadata structs before storing in this.
190  for (auto it = rhs._params.begin(); it != rhs._params.end(); ++it)
191  _params[it->first] = it->second;
192 
193  _buildable_types.insert(
194  _buildable_types.end(), rhs._buildable_types.begin(), rhs._buildable_types.end());
195  _buildable_rm_types.insert(
196  _buildable_rm_types.end(), rhs._buildable_rm_types.begin(), rhs._buildable_rm_types.end());
197 
198  // Collapse nesting and moose object syntax hiding are not modified with +=
199  _coupled_vars.insert(rhs._coupled_vars.begin(), rhs._coupled_vars.end());
202 
204  rhs._old_to_new_name_and_dep.end());
205  _new_to_old_names.insert(rhs._new_to_old_names.begin(), rhs._new_to_old_names.end());
206  return *this;
207 }
208 
209 void
210 InputParameters::setDeprecatedVarDocString(const std::string & new_name,
211  const std::string & doc_string)
212 {
213  auto coupled_vars_it = _new_to_deprecated_coupled_vars.find(new_name);
214  if (coupled_vars_it != _new_to_deprecated_coupled_vars.end())
215  {
216  auto params_it = _params.find(coupled_vars_it->second);
217  if (params_it == _params.end())
218  mooseError("There must have been a mistake in the construction of the new to deprecated "
219  "coupled vars map because the old name ",
220  coupled_vars_it->second,
221  " doesn't exist in the parameters data.");
222 
223  params_it->second._doc_string = doc_string;
224  }
225 }
226 
227 void
228 InputParameters::addCoupledVar(const std::string & name, Real value, const std::string & doc_string)
229 {
230  addParam<std::vector<VariableName>>(name, doc_string);
231  _coupled_vars.insert(name);
232  auto & metadata = _params[name];
233  metadata._coupled_default.assign(1, value);
234  metadata._have_coupled_default = true;
235 
236  // Set the doc string for any associated deprecated coupled var
237  setDeprecatedVarDocString(name, doc_string);
238 }
239 
240 void
241 InputParameters::addCoupledVar(const std::string & name,
242  const std::vector<Real> & value,
243  const std::string & doc_string)
244 {
245  // std::vector<VariableName>(1, Moose::stringify(value)),
246  addParam<std::vector<VariableName>>(name, doc_string);
247  _coupled_vars.insert(name);
248  auto & metadata = _params[name];
249  metadata._coupled_default = value;
250  metadata._have_coupled_default = true;
251 
252  // Set the doc string for any associated deprecated coupled var
253  setDeprecatedVarDocString(name, doc_string);
254 }
255 
256 void
257 InputParameters::addCoupledVar(const std::string & name, const std::string & doc_string)
258 {
259  addParam<std::vector<VariableName>>(name, doc_string);
260  _coupled_vars.insert(name);
261 
262  // Set the doc string for any associated deprecated coupled var
263  setDeprecatedVarDocString(name, doc_string);
264 }
265 
266 void
267 InputParameters::addDeprecatedCoupledVar(const std::string & old_name,
268  const std::string & new_name,
269  const std::string & removal_date /*=""*/)
270 {
271  mooseDeprecated("Please use 'deprecateCoupledVar'");
272 
273  _show_deprecated_message = false;
274 
275  // Set the doc string if we are adding the deprecated var after the new var has already been added
276  auto params_it = _params.find(new_name);
277  std::string doc_string;
278  if (params_it != _params.end())
279  doc_string = params_it->second._doc_string;
280 
281  addParam<std::vector<VariableName>>(old_name, doc_string);
282  _coupled_vars.insert(old_name);
283  _new_to_deprecated_coupled_vars.emplace(new_name, old_name);
284 
285  std::string deprecation_message =
286  "The coupled variable parameter '" + old_name + "' has been deprecated";
287  if (!removal_date.empty())
288  deprecation_message += " and will be removed " + removal_date;
289  deprecation_message += ". Please use the '" + new_name + "' coupled variable parameter instead.";
290  _params[old_name]._deprecation_message = deprecation_message;
292 }
293 
294 void
296  const std::string & base_name,
297  const std::string & num_name,
298  const std::string & doc_string)
299 {
300  addParam<std::vector<VariableName>>(name, doc_string);
301  _coupled_vars.insert(name);
302  _params[name]._autobuild_vecs = std::make_pair(base_name, num_name);
303 
304  // Additionally there are two more parameters that need to be added:
305  addParam<std::string>(base_name, doc_string + " (base_name)");
306  addParam<unsigned int>(num_name, doc_string + " (num_name)");
307 }
308 
309 void
311  const std::string & base_name,
312  const std::string & num_name,
313  const std::string & doc_string)
314 {
315  addRequiredParam<std::vector<VariableName>>(name, doc_string);
316 
317  addCoupledVarWithAutoBuild(name, base_name, num_name, doc_string);
318 }
319 
320 void
321 InputParameters::addRequiredCoupledVar(const std::string & name, const std::string & doc_string)
322 {
323  addRequiredParam<std::vector<VariableName>>(name, doc_string);
324  _coupled_vars.insert(name);
325 }
326 
327 std::string
328 InputParameters::getDocString(const std::string & name_in) const
329 {
330  const auto name = checkForRename(name_in);
331 
332  std::string doc_string;
333  auto it = _params.find(name);
334  if (it != _params.end())
335  for (const auto & ch : it->second._doc_string)
336  {
337  if (ch == '\n')
338  doc_string += " ... ";
339  else
340  doc_string += ch;
341  }
342 
343  return doc_string;
344 }
345 
346 void
347 InputParameters::setDocString(const std::string & name_in, const std::string & doc)
348 {
349  const auto name = checkForRename(name_in);
350 
351  auto it = _params.find(name);
352  if (it == _params.end())
353  mooseError("Unable to set the documentation string (using setDocString) for the \"",
354  name,
355  "\" parameter, the parameter does not exist.");
356  it->second._doc_string = doc;
357 }
358 
359 std::string
360 InputParameters::getDocUnit(const std::string & name_in) const
361 {
362  const auto name = checkForRename(name_in);
363  return _params.at(name)._doc_unit;
364 }
365 
366 void
367 InputParameters::setDocUnit(const std::string & name_in, const std::string & doc_unit)
368 {
369  const auto name = checkForRename(name_in);
370  _params[name]._doc_unit = doc_unit;
371 }
372 
373 bool
374 InputParameters::isParamRequired(const std::string & name_in) const
375 {
376  const auto name = checkForRename(name_in);
377  return _params.count(name) > 0 && _params.at(name)._required;
378 }
379 
380 void
381 InputParameters::makeParamNotRequired(const std::string & name_in)
382 {
383  const auto name = checkForRename(name_in);
384 
385  if (_params.count(name))
386  _params[name]._required = false;
387 }
388 
389 bool
390 InputParameters::isParamValid(const std::string & name_in) const
391 {
392  const auto name = checkForRename(name_in);
393  if (have_parameter<MooseEnum>(name))
394  return get<MooseEnum>(name).isValid();
395  else if (have_parameter<std::vector<MooseEnum>>(name))
396  {
397  for (auto it = get<std::vector<MooseEnum>>(name).begin();
398  it != get<std::vector<MooseEnum>>(name).end();
399  ++it)
400  if (!it->isValid())
401  return false;
402  return true;
403  }
404  else if (have_parameter<MultiMooseEnum>(name))
405  return get<MultiMooseEnum>(name).isValid();
406  else if (have_parameter<std::vector<MultiMooseEnum>>(name))
407  {
408  for (auto it = get<std::vector<MultiMooseEnum>>(name).begin();
409  it != get<std::vector<MultiMooseEnum>>(name).end();
410  ++it)
411  if (!it->isValid())
412  return false;
413  return true;
414  }
415  else if (have_parameter<ExecFlagEnum>(name))
416  return get<ExecFlagEnum>(name).isValid();
417  else
418  return _params.count(name) > 0 && _params.at(name)._valid;
419 }
420 
421 bool
422 InputParameters::isParamSetByAddParam(const std::string & name_in) const
423 {
424  const auto name = checkForRename(name_in);
425  return _params.count(name) > 0 && _params.at(name)._set_by_add_param;
426 }
427 
428 bool
429 InputParameters::isParamDeprecated(const std::string & name_in) const
430 {
431  const auto name = checkForRename(name_in);
432  return _params.count(name) > 0 && !_params.at(name)._deprecation_message.empty();
433 }
434 
435 bool
437 {
438  for (const auto & it : *this)
439  if (isParamRequired(it.first) && !isParamValid(it.first))
440  return false;
441  return true;
442 }
443 
444 bool
445 InputParameters::isPrivate(const std::string & name_in) const
446 {
447  const auto name = checkForRename(name_in);
448  return _params.count(name) > 0 && _params.at(name)._is_private;
449 }
450 
451 void
452 InputParameters::declareControllable(const std::string & input_names,
453  std::set<ExecFlagType> execute_flags)
454 {
455  std::vector<std::string> names;
456  MooseUtils::tokenize<std::string>(input_names, names, 1, " ");
457  for (auto & name_in : names)
458  {
459  const auto name = checkForRename(name_in);
460  auto map_iter = _params.find(name);
461  if (map_iter != _params.end()) // error is handled by checkParams method
462  {
463  map_iter->second._controllable = true;
464  map_iter->second._controllable_flags = execute_flags;
465  }
466  else
467  mooseError("The input parameter '",
468  name,
469  "' does not exist, thus cannot be marked as controllable.");
470  }
471 }
472 
473 bool
474 InputParameters::isControllable(const std::string & name_in) const
475 {
476  const auto name = checkForRename(name_in);
477  return _params.count(name) > 0 && _params.at(name)._controllable;
478 }
479 
480 const std::set<ExecFlagType> &
481 InputParameters::getControllableExecuteOnTypes(const std::string & name_in) const
482 {
483  const auto name = checkForRename(name_in);
484  return at(name)._controllable_flags;
485 }
486 
487 void
488 InputParameters::registerBase(const std::string & value)
489 {
490  InputParameters::set<std::string>("_moose_base") = value;
491  _params["_moose_base"]._is_private = true;
492 }
493 
494 std::optional<std::string>
496 {
497  if (have_parameter<std::string>("_moose_base"))
498  return get<std::string>("_moose_base");
499  return {};
500 }
501 
502 void
504 {
505  InputParameters::set<std::string>("_moose_warehouse_system_name") = value;
506  _params["_moose_warehouse_system_name"]._is_private = true;
507 }
508 
509 const std::string &
511 {
512  mooseAssert(have_parameter<std::string>("_moose_warehouse_system_name"),
513  "SystemAttributeName is not available! Call 'registerSystemAttributeName' (usually "
514  "in the validParams function) before you try accessing it!");
515  return Parameters::get<std::string>("_moose_warehouse_system_name");
516 }
517 
518 void
519 InputParameters::registerBuildableTypes(const std::string & names)
520 {
521  _buildable_types.clear();
522  MooseUtils::tokenize(names, _buildable_types, 1, " \t\n\v\f\r"); // tokenize on whitespace
523 }
524 
525 void
527  const std::string & name,
529  Moose::RelationshipManagerInputParameterCallback input_parameter_callback)
530 {
531  _buildable_rm_types.emplace_back(name, rm_type, input_parameter_callback);
532 }
533 
534 const std::vector<std::string> &
536 {
537  return _buildable_types;
538 }
539 
540 const std::vector<std::tuple<std::string,
544 {
545  return _buildable_rm_types;
546 }
547 
548 void
550 {
551  _collapse_nesting = collapse;
552 }
553 
554 bool
556 {
557  return _collapse_nesting;
558 }
559 
560 void
562 {
563  _moose_object_syntax_visibility = visibility;
564 }
565 
566 bool
568 {
570 }
571 
572 #define dynamicCastRangeCheck(type, up_type, long_name, short_name, param, oss) \
573  do \
574  { \
575  libMesh::Parameters::Value * val = MooseUtils::get(param); \
576  InputParameters::Parameter<type> * scalar_p = \
577  dynamic_cast<InputParameters::Parameter<type> *>(val); \
578  if (scalar_p) \
579  rangeCheck<type, up_type>(long_name, short_name, scalar_p, oss); \
580  InputParameters::Parameter<std::vector<type>> * vector_p = \
581  dynamic_cast<InputParameters::Parameter<std::vector<type>> *>(val); \
582  if (vector_p) \
583  rangeCheck<type, up_type>(long_name, short_name, vector_p, oss); \
584  } while (0)
585 
586 #define checkMooseType(param_type, name) \
587  if (have_parameter<param_type>(name) || have_parameter<std::vector<param_type>>(name)) \
588  oss << inputLocation(param_name) << ": non-controllable type '" << type(name) \
589  << "' for parameter '" << paramFullpath(param_name) << "' marked controllable";
590 
591 void
592 InputParameters::checkParams(const std::string & parsing_syntax)
593 {
594  std::string parampath = blockFullpath() != "" ? blockFullpath() : parsing_syntax;
595  std::ostringstream oss;
596  // Required parameters
597  for (const auto & it : *this)
598  {
599  const auto param_name = checkForRename(it.first);
600  if (!isParamValid(param_name) && isParamRequired(param_name))
601  {
602  // check if an old, deprecated name exists for this parameter that may be specified
603  auto oit = _new_to_deprecated_coupled_vars.find(param_name);
604  if (oit != _new_to_deprecated_coupled_vars.end() && isParamValid(oit->second))
605  continue;
606 
607  oss << blockLocation() << ": missing required parameter '" << parampath + "/" + param_name
608  << "'\n";
609  oss << "\tDoc String: \"" + getDocString(param_name) + "\"" << std::endl;
610  }
611  }
612 
613  // Range checked parameters
614  for (const auto & it : *this)
615  {
616  std::string long_name(parampath + "/" + it.first);
617 
618  dynamicCastRangeCheck(Real, Real, long_name, it.first, it.second, oss);
619  dynamicCastRangeCheck(int, long, long_name, it.first, it.second, oss);
620  dynamicCastRangeCheck(long, long, long_name, it.first, it.second, oss);
621  dynamicCastRangeCheck(unsigned int, long, long_name, it.first, it.second, oss);
622  }
623 
624  // Controllable parameters
625  for (const auto & param_name : getControllableParameters())
626  {
627  if (isPrivate(param_name))
628  oss << inputLocation(param_name) << ": private parameter '" << paramFullpath(param_name)
629  << "' marked controllable";
630 
631  checkMooseType(NonlinearVariableName, param_name);
632  checkMooseType(AuxVariableName, param_name);
633  checkMooseType(VariableName, param_name);
634  checkMooseType(BoundaryName, param_name);
635  checkMooseType(SubdomainName, param_name);
636  checkMooseType(PostprocessorName, param_name);
637  checkMooseType(VectorPostprocessorName, param_name);
638  checkMooseType(UserObjectName, param_name);
639  checkMooseType(MaterialPropertyName, param_name);
640  }
641 
642  if (!oss.str().empty())
643  mooseError(oss.str());
644 }
645 
646 void
647 InputParameters::finalize(const std::string & parsing_syntax)
648 {
649  mooseAssert(!isFinalized(), "Already finalized");
650 
651  checkParams(parsing_syntax);
652 
653  // Helper for setting the absolute paths for each set file name parameter
654  const auto set_absolute_path = [this](const std::string & param_name, auto & value)
655  {
656  // We don't need to set a path if nothing is there
657  if (value.empty())
658  return;
659 
660  std::filesystem::path value_path = std::string(value);
661  // Is already absolute, nothing to do
662  if (value_path.is_absolute())
663  return;
664 
665  // The base by which to make things relative to
666  const auto file_base = getFileBase(param_name);
667  value = std::filesystem::absolute(file_base / value_path).c_str();
668  };
669 
670  // Set the absolute path for each file name typed parameter
671  for (const auto & [param_name, param_value] : *this)
672  {
673 #define set_if_filename(type) \
674  else if (auto type_value = dynamic_cast<Parameters::Parameter<type> *>(param_value.get())) \
675  set_absolute_path(param_name, type_value->set()); \
676  else if (auto type_values = dynamic_cast<Parameters::Parameter<std::vector<type>> *>( \
677  param_value.get())) for (auto & value : type_values->set()) \
678  set_absolute_path(param_name, value)
679 
680  if (false)
681  ;
682  // Note that we explicitly skip DataFileName here because we do not want absolute
683  // file paths for data files, as they're searched in the data directories
684  set_if_filename(FileName);
685  set_if_filename(FileNameNoExtension);
686  set_if_filename(MeshFileName);
687  set_if_filename(MatrixFileName);
688 #undef set_if_filename
689  // Set paths for data files
690  else if (auto data_file_name =
691  dynamic_cast<Parameters::Parameter<DataFileName> *>(param_value.get()))
692  {
693  Moose::DataFileUtils::Path found_path;
694  std::optional<std::string> error;
695 
696  // Catch this so that we can add additional error context if it fails (the param path)
697  const auto throw_on_error_before = Moose::_throw_on_error;
698  Moose::_throw_on_error = true;
699  try
700  {
701  found_path = Moose::DataFileUtils::getPath(data_file_name->get(), getFileBase(param_name));
702  }
703  catch (std::exception & e)
704  {
705  error = errorPrefix(param_name) + " " + e.what();
706  }
707  Moose::_throw_on_error = throw_on_error_before;
708 
709  if (error)
710  mooseError(*error);
711 
712  // Set the value to the absolute searched path
713  data_file_name->set() = found_path.path;
714  // And store the path in metadata so that we can dump it later
715  at(param_name)._data_file_name_path = found_path;
716  }
717  }
718 
719  _finalized = true;
720 }
721 
722 std::filesystem::path
723 InputParameters::getFileBase(const std::optional<std::string> & param_name) const
724 {
725  mooseAssert(!have_parameter<std::string>("_app_name"),
726  "Not currently setup to work with app FileName parameters");
727 
728  const hit::Node * hit_node = nullptr;
729 
730  // Context from the individual parameter
731  if (param_name)
732  hit_node = getHitNode(*param_name);
733  // Context from the parameters
734  if (!hit_node)
735  hit_node = getHitNode();
736  // No hit node, so use the cwd (no input files)
737  if (!hit_node)
738  return std::filesystem::current_path();
739 
740  // Find any context that isn't command line arguments
741  while (hit_node && hit_node->filename() == "CLI_ARGS")
742  hit_node = hit_node->parent();
743 
744  // Failed to find a node up the tree that isn't a command line argument
745  if (!hit_node)
746  {
747  std::string prefix = "";
748  if (param_name)
749  prefix = errorPrefix(*param_name) + " ";
750  mooseError(prefix,
751  "Input context was set via a command-line argument and does not have sufficient "
752  "context for "
753  "determining a file path.");
754  }
755 
756  return std::filesystem::absolute(std::filesystem::path(hit_node->filename()).parent_path());
757 }
758 
759 bool
760 InputParameters::isRangeChecked(const std::string & param_name) const
761 {
762  const auto name = checkForRename(param_name);
763  return !_params.find(name)->second._range_function.empty();
764 }
765 
766 std::string
767 InputParameters::rangeCheckedFunction(const std::string & param_name) const
768 {
769  const auto name = checkForRename(param_name);
770  return _params.at(name)._range_function;
771 }
772 
773 bool
774 InputParameters::hasDefault(const std::string & param_name) const
775 {
776  const auto name = checkForRename(param_name);
778  return true;
779  // If it has a default, it's already valid
780  else if (isParamSetByAddParam(name))
781  return true;
782  else if (isParamValid(name))
783  mooseError("No way to know if the parameter '", param_name, "' has a default");
784  else
785  return false;
786 }
787 
788 bool
789 InputParameters::hasCoupledValue(const std::string & coupling_name) const
790 {
791  return _coupled_vars.find(coupling_name) != _coupled_vars.end();
792 }
793 
794 bool
795 InputParameters::hasDefaultCoupledValue(const std::string & coupling_name) const
796 {
797  return _params.count(coupling_name) > 0 && _params.at(coupling_name)._have_coupled_default &&
798  _coupled_vars.count(coupling_name) > 0;
799 }
800 
801 void
802 InputParameters::defaultCoupledValue(const std::string & coupling_name, Real value, unsigned int i)
803 {
804  const auto actual_name = checkForRename(coupling_name);
805  _params[actual_name]._coupled_default.resize(i + 1);
806  _params[actual_name]._coupled_default[i] = value;
807  _params[actual_name]._have_coupled_default = true;
808 }
809 
810 Real
811 InputParameters::defaultCoupledValue(const std::string & coupling_name, unsigned int i) const
812 {
813  auto value_it = _params.find(coupling_name);
814 
815  if (value_it == _params.end() || !value_it->second._have_coupled_default)
816  mooseError("Attempted to retrieve default value for coupled variable '",
817  coupling_name,
818  "' when none was provided. \n\nThere are three reasons why this may have "
819  "occurred:\n 1. The other version of params.addCoupledVar() should be used in order "
820  "to provide a default value. \n 2. This should have been a required coupled "
821  "variable added with params.addRequiredCoupledVar() \n 3. The call to get the "
822  "coupled value should have been properly guarded with isCoupled()\n");
823 
824  return value_it->second._coupled_default.at(i);
825 }
826 
827 unsigned int
828 InputParameters::numberDefaultCoupledValues(const std::string & coupling_name) const
829 {
830  auto value_it = _params.find(coupling_name);
831  if (value_it == _params.end())
832  mooseError("Attempted to retrieve default value for coupled variable '",
833  coupling_name,
834  "' when none was provided.");
835  return value_it->second._coupled_default.size();
836 }
837 
838 std::map<std::string, std::pair<std::string, std::string>>
840 {
841  std::map<std::string, std::pair<std::string, std::string>> abv;
842  for (auto it = _params.begin(); it != _params.end(); ++it)
843  {
844  if (!it->second._autobuild_vecs.first.empty())
845  abv[it->first] = it->second._autobuild_vecs;
846  }
847  return abv;
848 }
849 
850 std::string
851 InputParameters::type(const std::string & name_in) const
852 {
853  const auto name = checkForRename(name_in);
854  if (!_values.count(name))
855  mooseError("Parameter \"", name, "\" not found.\n\n", *this);
856 
857  if (_coupled_vars.find(name) != _coupled_vars.end())
858  return "std::vector<VariableName>";
859  else if (_params.count(name) > 0 && !_params.at(name)._custom_type.empty())
860  return _params.at(name)._custom_type;
861  return _values.at(name)->type();
862 }
863 
864 std::string
865 InputParameters::getMooseType(const std::string & name_in) const
866 {
867  const auto name = checkForRename(name_in);
868  std::string var;
869 
870  if (have_parameter<VariableName>(name))
871  var = get<VariableName>(name);
872  else if (have_parameter<NonlinearVariableName>(name))
873  var = get<NonlinearVariableName>(name);
874  else if (have_parameter<LinearVariableName>(name))
875  var = get<LinearVariableName>(name);
876  else if (have_parameter<AuxVariableName>(name))
877  var = get<AuxVariableName>(name);
878  else if (have_parameter<PostprocessorName>(name))
879  var = get<PostprocessorName>(name);
880  else if (have_parameter<VectorPostprocessorName>(name))
881  var = get<VectorPostprocessorName>(name);
882  else if (have_parameter<FunctionName>(name))
883  var = get<FunctionName>(name);
884  else if (have_parameter<UserObjectName>(name))
885  var = get<UserObjectName>(name);
886  else if (have_parameter<MaterialPropertyName>(name))
887  var = get<MaterialPropertyName>(name);
888  else if (have_parameter<std::string>(name))
889  var = get<std::string>(name);
890 
891  return var;
892 }
893 
894 std::vector<std::string>
895 InputParameters::getVecMooseType(const std::string & name_in) const
896 {
897  const auto name = checkForRename(name_in);
898  std::vector<std::string> svars;
899 
900  if (have_parameter<std::vector<VariableName>>(name))
901  {
902  std::vector<VariableName> vars = get<std::vector<VariableName>>(name);
903  std::copy(vars.begin(), vars.end(), std::back_inserter(svars));
904  }
905  else if (have_parameter<std::vector<NonlinearVariableName>>(name))
906  {
907  std::vector<NonlinearVariableName> vars = get<std::vector<NonlinearVariableName>>(name);
908  std::copy(vars.begin(), vars.end(), std::back_inserter(svars));
909  }
910  else if (have_parameter<std::vector<AuxVariableName>>(name))
911  {
912  std::vector<AuxVariableName> vars = get<std::vector<AuxVariableName>>(name);
913  std::copy(vars.begin(), vars.end(), std::back_inserter(svars));
914  }
915  else if (have_parameter<std::vector<MaterialPropertyName>>(name))
916  {
917  std::vector<MaterialPropertyName> vars = get<std::vector<MaterialPropertyName>>(name);
918  std::copy(vars.begin(), vars.end(), std::back_inserter(svars));
919  }
920  else if (have_parameter<std::vector<std::string>>(name))
921  {
922  std::vector<std::string> vars = get<std::vector<std::string>>(name);
923  std::copy(vars.begin(), vars.end(), std::back_inserter(svars));
924  }
925 
926  return svars;
927 }
928 
929 void
930 InputParameters::addParamNamesToGroup(const std::string & space_delim_names,
931  const std::string group_name)
932 {
933  std::vector<std::string> elements;
934  MooseUtils::tokenize(space_delim_names, elements, 1, " \t\n\v\f\r"); // tokenize on whitespace
935 
936  // Since we don't require types (templates) for this method, we need
937  // to get a raw list of parameter names to compare against.
938  std::set<std::string> param_names;
939  for (const auto & it : *this)
940  param_names.insert(it.first);
941 
942  for (const auto & param_name : elements)
943  if (_params.count(param_name) > 0)
944  _params[param_name]._group = group_name;
945  else
946  mooseError("Unable to find a parameter with name: ",
947  param_name,
948  " when adding to group ",
949  group_name,
950  '.');
951 }
952 
953 void
954 InputParameters::renameParameterGroup(const std::string & old_name, const std::string & new_name)
955 {
956  for (auto & param : _params)
957  if (param.second._group == old_name)
958  param.second._group = new_name;
959 }
960 
961 void
963 {
964  auto & cl_data = at(checkForRename(name))._cl_data;
965  if (!cl_data)
966  mooseError("InputParameters::setGlobalCommandLineParam: The parameter '",
967  name,
968  "' is not a command line parameter");
969  cl_data->global = true;
970 }
971 
972 bool
973 InputParameters::isCommandLineParameter(const std::string & name) const
974 {
975  return at(checkForRename(name))._cl_data.has_value();
976 }
977 
978 std::optional<InputParameters::CommandLineMetadata>
979 InputParameters::queryCommandLineMetadata(const std::string & name) const
980 {
981  const auto & cl_data = at(checkForRename(name))._cl_data;
982  if (!cl_data)
983  return {};
984  return *cl_data;
985 }
986 
988 InputParameters::getCommandLineMetadata(const std::string & name) const
989 {
990  const auto & cl_data = at(checkForRename(name))._cl_data;
991  if (!cl_data)
992  mooseError("InputParameters::getCommandLineMetadata: The parameter '",
993  name,
994  "' is not a command line parameter");
995  return *cl_data;
996 }
997 
998 void
1000 {
1001  auto & cl_data = at(checkForRename(name))._cl_data;
1002  if (!cl_data)
1003  mooseError("InputParameters::commandLineParamSet: The parameter '",
1004  name,
1005  "' is not a command line parameter");
1006  cl_data->set_by_command_line = true;
1007 }
1008 
1009 std::string
1010 InputParameters::getGroupName(const std::string & param_name_in) const
1011 {
1012  const auto param_name = checkForRename(param_name_in);
1013  auto it = _params.find(param_name);
1014  if (it != _params.end())
1015  return it->second._group;
1016  return std::string();
1017 }
1018 
1019 void
1021  const std::vector<std::string> & exclude,
1022  const bool allow_private)
1023 {
1024  // If we're applying all of the things, also associate the top level hit node
1025  if (exclude.empty() && !getHitNode() && common.getHitNode())
1026  setHitNode(*common.getHitNode(), {});
1027 
1028  // Loop through the common parameters
1029  for (const auto & it : common)
1030  {
1031  // Common parameter name
1032  const std::string & common_name = it.first;
1033  // Continue to next parameter, if the current is in list of excluded parameters
1034  if (std::find(exclude.begin(), exclude.end(), common_name) != exclude.end())
1035  continue;
1036 
1037  applyParameter(common, common_name, allow_private);
1038  }
1039 
1040  // Loop through the coupled variables
1041  for (std::set<std::string>::const_iterator it = common.coupledVarsBegin();
1042  it != common.coupledVarsEnd();
1043  ++it)
1044  {
1045  // Variable name
1046  const std::string var_name = *it;
1047 
1048  // Continue to next variable, if the current is in list of excluded parameters
1049  if (std::find(exclude.begin(), exclude.end(), var_name) != exclude.end())
1050  continue;
1051 
1052  applyCoupledVar(common, var_name);
1053  }
1054 }
1055 
1056 void
1058  const std::vector<std::string> & include,
1059  bool allow_private)
1060 {
1061  // Loop through the common parameters
1062  for (const auto & it : common)
1063  {
1064 
1065  // Common parameter name
1066  const std::string & common_name = it.first;
1067 
1068  // Continue to next parameter, if the current is not in list of included parameters
1069  if (std::find(include.begin(), include.end(), common_name) == include.end())
1070  continue;
1071 
1072  applyParameter(common, common_name, allow_private);
1073  }
1074 
1075  // Loop through the coupled variables
1076  for (std::set<std::string>::const_iterator it = common.coupledVarsBegin();
1077  it != common.coupledVarsEnd();
1078  ++it)
1079  {
1080  // Variable name
1081  const std::string var_name = *it;
1082 
1083  // Continue to next variable, if the current is not in list of included parameters
1084  if (std::find(include.begin(), include.end(), var_name) == include.end())
1085  continue;
1086 
1087  applyCoupledVar(common, var_name);
1088  }
1089 }
1090 
1091 void
1092 InputParameters::applyCoupledVar(const InputParameters & common, const std::string & var_name)
1093 {
1094  // Disable the display of deprecated message when applying common parameters, this avoids a dump
1095  // of messages
1096  _show_deprecated_message = false;
1097 
1098  // If the local parameters has a coupled variable, populate it with the value from the common
1099  // parameters, if the common parameters has the coupled variable too
1100  if (hasCoupledValue(var_name))
1101  {
1102  if (common.hasDefaultCoupledValue(var_name))
1103  {
1104  // prepare a vector of default coupled values
1105  std::vector<Real> defaults(common.numberDefaultCoupledValues(var_name));
1106  for (unsigned int j = 0; j < common.numberDefaultCoupledValues(var_name); ++j)
1107  defaults[j] = common.defaultCoupledValue(var_name, j);
1108  addCoupledVar(var_name, defaults, common.getDocString(var_name));
1109  }
1110  else if (common.hasCoupledValue(var_name))
1111  addCoupledVar(var_name, common.getDocString(var_name));
1112  }
1113 
1114  // Enable deprecated message printing
1115  _show_deprecated_message = true;
1116 }
1117 
1118 void
1120  const std::string & common_name,
1121  bool allow_private,
1122  bool override_default)
1123 {
1124  // Disable the display of deprecated message when applying common parameters, this avoids a dump
1125  // of messages
1126  _show_deprecated_message = false;
1127 
1128  const auto local_name = checkForRename(common_name);
1129 
1130  // Extract the properties from the local parameter for the current common parameter name
1131  const bool local_exist = _values.find(local_name) != _values.end();
1132  const bool local_set = _params.count(local_name) > 0 && !_params[local_name]._set_by_add_param;
1133  const bool local_priv = allow_private ? false : isPrivate(local_name);
1134  const bool local_valid = isParamValid(local_name);
1135 
1136  // Extract the properties from the common parameter
1137  const bool common_exist = common._values.find(common_name) != common._values.end();
1138  const bool common_priv = allow_private ? false : common.isPrivate(common_name);
1139  const bool common_valid = common.isParamValid(common_name) || override_default;
1140 
1141  /* In order to apply a common parameter 4 statements must be satisfied
1142  * (1) A local parameter must exist with the same name as the common parameter
1143  * (2) Common parameter must be valid and exist
1144  * (3) Local parameter must be invalid OR not have been set from its default
1145  * (4) Both cannot be private
1146  */
1147  if (local_exist && common_exist && common_valid && (!local_valid || !local_set) &&
1148  (!common_priv || !local_priv))
1149  {
1150  remove(local_name);
1151  _values[local_name] = common._values.find(common_name)->second->clone();
1152  set_attributes(local_name, false);
1153  _params[local_name]._set_by_add_param =
1154  libmesh_map_find(common._params, common_name)._set_by_add_param;
1155  // Keep track of where this param came from if we can. This will enable us to
1156  // produce param errors from objects created within an action that link to
1157  // the parameter in the action
1158  at(local_name)._hit_node = common.getHitNode(common_name);
1159  }
1160  else if (!local_exist && !common_exist)
1161  mooseError("InputParameters::applyParameter(): Attempted to apply invalid parameter \"",
1162  common_name,
1163  "\"");
1164 
1165  // Enable deprecated message printing
1166  _show_deprecated_message = true;
1167 }
1168 
1170 bool
1171 InputParameters::paramSetByUser(const std::string & name) const
1172 {
1173  mooseDeprecated("paramSetByUser() is deprecated. Use isParamSetByUser() instead.");
1174  return isParamSetByUser(name);
1175 }
1176 
1177 bool
1178 InputParameters::isParamSetByUser(const std::string & name_in) const
1179 {
1180  const auto name = checkForRename(name_in);
1181  // Invalid; for sure not set by the user
1182  if (!isParamValid(name))
1183  return false;
1184  // Parameter is not located in the list (called Parameters::set)
1185  if (!_params.count(name))
1186  return false;
1187  // Special case for a command line option, which is a private parameter
1188  if (const auto cl_data = queryCommandLineMetadata(name))
1189  return cl_data->set_by_command_line;
1190  // Not a command line option, not set by addParam and not private
1191  return !_params.at(name)._set_by_add_param && !_params.at(name)._is_private;
1192 }
1193 
1194 bool
1195 InputParameters::isParamDefined(const std::string & name_in) const
1196 {
1197  const auto name = checkForRename(name_in);
1198  return _params.count(name) > 0;
1199 }
1200 
1201 const std::string &
1202 InputParameters::getDescription(const std::string & name_in) const
1203 {
1204  const auto name = checkForRename(name_in);
1205  auto it = _params.find(name);
1206  if (it == _params.end())
1207  mooseError("No parameter exists with the name ", name);
1208  return it->second._doc_string;
1209 }
1210 
1211 template <>
1212 void
1213 InputParameters::addRequiredParam<MooseEnum>(const std::string & name,
1214  const MooseEnum & moose_enum,
1215  const std::string & doc_string)
1216 {
1217  InputParameters::set<MooseEnum>(name) = moose_enum; // valid parameter is set by set_attributes
1218  auto & metadata = _params[name];
1219  metadata._required = true;
1220  metadata._doc_string = doc_string;
1221 }
1222 
1223 template <>
1224 void
1225 InputParameters::addRequiredParam<MultiMooseEnum>(const std::string & name,
1226  const MultiMooseEnum & moose_enum,
1227  const std::string & doc_string)
1228 {
1229  InputParameters::set<MultiMooseEnum>(name) =
1230  moose_enum; // valid parameter is set by set_attributes
1231  auto & metadata = _params[name];
1232  metadata._required = true;
1233  metadata._doc_string = doc_string;
1234 }
1235 
1236 template <>
1237 void
1238 InputParameters::addRequiredParam<std::vector<MooseEnum>>(
1239  const std::string & name,
1240  const std::vector<MooseEnum> & moose_enums,
1241  const std::string & doc_string)
1242 {
1243  InputParameters::set<std::vector<MooseEnum>>(name) =
1244  moose_enums; // valid parameter is set by set_attributes
1245  auto & metadata = _params[name];
1246  metadata._required = true;
1247  metadata._doc_string = doc_string;
1248 }
1249 
1250 template <>
1251 void
1252 InputParameters::addRequiredParam<std::vector<MultiMooseEnum>>(
1253  const std::string & name,
1254  const std::vector<MultiMooseEnum> & moose_enums,
1255  const std::string & doc_string)
1256 {
1257  mooseAssert(
1258  moose_enums.size() == 1,
1259  "Only 1 MultiMooseEnum is supported in addRequiredParam<std::vector<MultiMooseEnum>> for " +
1260  name);
1261  mooseAssert(!moose_enums[0].items().empty(),
1262  "The MultiMooseEnum in addRequiredParam<std::vector<MultiMooseEnum>> is empty for " +
1263  name);
1264  InputParameters::set<std::vector<MultiMooseEnum>>(name) =
1265  moose_enums; // valid parameter is set by set_attributes
1266  auto & metadata = _params[name];
1267  metadata._required = true;
1268  metadata._doc_string = doc_string;
1269 }
1270 
1271 template <>
1272 void
1273 InputParameters::addParam<MooseEnum>(const std::string & /*name*/,
1274  const std::string & /*doc_string*/)
1275 {
1276  mooseError("You must supply a MooseEnum object when using addParam, even if the parameter is not "
1277  "required!");
1278 }
1279 
1280 template <>
1281 void
1282 InputParameters::addParam<MultiMooseEnum>(const std::string & /*name*/,
1283  const std::string & /*doc_string*/)
1284 {
1285  mooseError("You must supply a MultiMooseEnum object when using addParam, even if the parameter "
1286  "is not required!");
1287 }
1288 
1289 template <>
1290 void
1291 InputParameters::addParam<std::vector<MooseEnum>>(const std::string & /*name*/,
1292  const std::string & /*doc_string*/)
1293 {
1294  mooseError("You must supply a vector of MooseEnum object(s) when using addParam, even if the "
1295  "parameter is not required!");
1296 }
1297 
1298 template <>
1299 void
1300 InputParameters::addParam<std::vector<MultiMooseEnum>>(const std::string & /*name*/,
1301  const std::string & /*doc_string*/)
1302 {
1303  mooseError(
1304  "You must supply a vector of MultiMooseEnum object(s) when using addParam, even if the "
1305  "parameter is not required!");
1306 }
1307 
1308 template <>
1309 void
1310 InputParameters::addRequiredParam<std::vector<MultiMooseEnum>>(const std::string & /*name*/,
1311  const std::string & /*doc_string*/)
1312 {
1313  mooseError("You must supply a vector of MultiMooseEnum object(s) when using addRequiredParam!");
1314 }
1315 
1316 template <>
1317 void
1318 InputParameters::addPrivateParam<MooseEnum>(const std::string & /*name*/)
1319 {
1320  mooseError("You must supply a MooseEnum object when using addPrivateParam, even if the parameter "
1321  "is not required!");
1322 }
1323 
1324 template <>
1325 void
1326 InputParameters::addPrivateParam<MultiMooseEnum>(const std::string & /*name*/)
1327 {
1328  mooseError("You must supply a MultiMooseEnum object when using addPrivateParam, even if the "
1329  "parameter is not required!");
1330 }
1331 
1332 template <>
1333 void
1334 InputParameters::addDeprecatedParam<MooseEnum>(const std::string & /*name*/,
1335  const std::string & /*doc_string*/,
1336  const std::string & /*deprecation_message*/)
1337 {
1338  mooseError("You must supply a MooseEnum object and the deprecation string when using "
1339  "addDeprecatedParam, even if the parameter is not required!");
1340 }
1341 
1342 template <>
1343 void
1344 InputParameters::addDeprecatedParam<MultiMooseEnum>(const std::string & /*name*/,
1345  const std::string & /*doc_string*/,
1346  const std::string & /*deprecation_message*/)
1347 {
1348  mooseError("You must supply a MultiMooseEnum object and the deprecation string when using "
1349  "addDeprecatedParam, even if the parameter is not required!");
1350 }
1351 
1352 template <>
1353 void
1354 InputParameters::addDeprecatedParam<std::vector<MooseEnum>>(
1355  const std::string & /*name*/,
1356  const std::string & /*doc_string*/,
1357  const std::string & /*deprecation_message*/)
1358 {
1359  mooseError("You must supply a vector of MooseEnum object(s) and the deprecation string when "
1360  "using addDeprecatedParam, even if the parameter is not required!");
1361 }
1362 
1363 template <>
1364 void
1365 InputParameters::setParamHelper<PostprocessorName, Real>(const std::string & /*name*/,
1366  PostprocessorName & l_value,
1367  const Real & r_value)
1368 {
1369  // Assign the default value so that it appears in the dump
1370  std::ostringstream oss;
1371  oss << r_value;
1372  l_value = oss.str();
1373 }
1374 
1375 template <>
1376 void
1377 InputParameters::setParamHelper<PostprocessorName, int>(const std::string & /*name*/,
1378  PostprocessorName & l_value,
1379  const int & r_value)
1380 {
1381  // Assign the default value so that it appears in the dump
1382  std::ostringstream oss;
1383  oss << r_value;
1384  l_value = oss.str();
1385 }
1386 
1387 template <>
1388 void
1389 InputParameters::setParamHelper<FunctionName, Real>(const std::string & /*name*/,
1390  FunctionName & l_value,
1391  const Real & r_value)
1392 {
1393  // Assign the default value so that it appears in the dump
1394  std::ostringstream oss;
1395  oss << r_value;
1396  l_value = oss.str();
1397 }
1398 
1399 template <>
1400 void
1401 InputParameters::setParamHelper<FunctionName, int>(const std::string & /*name*/,
1402  FunctionName & l_value,
1403  const int & r_value)
1404 {
1405  // Assign the default value so that it appears in the dump
1406  std::ostringstream oss;
1407  oss << r_value;
1408  l_value = oss.str();
1409 }
1410 
1411 template <>
1412 void
1413 InputParameters::setParamHelper<MaterialPropertyName, Real>(const std::string & /*name*/,
1414  MaterialPropertyName & l_value,
1415  const Real & r_value)
1416 {
1417  // Assign the default value so that it appears in the dump
1418  std::ostringstream oss;
1419  oss << r_value;
1420  l_value = oss.str();
1421 }
1422 
1423 template <>
1424 void
1425 InputParameters::setParamHelper<MaterialPropertyName, int>(const std::string & /*name*/,
1426  MaterialPropertyName & l_value,
1427  const int & r_value)
1428 {
1429  // Assign the default value so that it appears in the dump
1430  std::ostringstream oss;
1431  oss << r_value;
1432  l_value = oss.str();
1433 }
1434 
1435 template <>
1436 void
1437 InputParameters::setParamHelper<MooseFunctorName, Real>(const std::string & /*name*/,
1438  MooseFunctorName & l_value,
1439  const Real & r_value)
1440 {
1441  // Assign the default value so that it appears in the dump
1442  std::ostringstream oss;
1443  oss << r_value;
1444  l_value = oss.str();
1445 }
1446 
1447 template <>
1448 void
1449 InputParameters::setParamHelper<MooseFunctorName, int>(const std::string & /*name*/,
1450  MooseFunctorName & l_value,
1451  const int & r_value)
1452 {
1453  // Assign the default value so that it appears in the dump
1454  std::ostringstream oss;
1455  oss << r_value;
1456  l_value = oss.str();
1457 }
1458 
1459 template <>
1460 const MooseEnum &
1461 InputParameters::getParamHelper<MooseEnum>(const std::string & name_in,
1462  const InputParameters & pars,
1463  const MooseEnum *,
1464  const MooseBase * /* = nullptr */)
1465 {
1466  const auto name = pars.checkForRename(name_in);
1467  return pars.get<MooseEnum>(name);
1468 }
1469 
1470 template <>
1471 const MultiMooseEnum &
1472 InputParameters::getParamHelper<MultiMooseEnum>(const std::string & name_in,
1473  const InputParameters & pars,
1474  const MultiMooseEnum *,
1475  const MooseBase * /* = nullptr */)
1476 {
1477  const auto name = pars.checkForRename(name_in);
1478  return pars.get<MultiMooseEnum>(name);
1479 }
1480 
1481 void
1482 InputParameters::setReservedValues(const std::string & name_in,
1483  const std::set<std::string> & reserved)
1484 {
1485  const auto name = checkForRename(name_in);
1486  _params[name]._reserved_values = reserved;
1487 }
1488 
1489 std::set<std::string>
1490 InputParameters::reservedValues(const std::string & name_in) const
1491 {
1492  const auto name = checkForRename(name_in);
1493  auto it = _params.find(name);
1494  if (it == _params.end())
1495  return std::set<std::string>();
1496  return it->second._reserved_values;
1497 }
1498 
1499 std::string
1501 {
1502  if (const auto hit_node = getHitNode())
1503  return hit_node->fileLocation(/* with_column = */ false);
1504  return "";
1505 }
1506 
1507 std::string
1509 {
1510  if (const auto hit_node = getHitNode())
1511  return hit_node->fullpath();
1512  return "";
1513 }
1514 
1515 const hit::Node *
1516 InputParameters::getHitNode(const std::string & param) const
1517 {
1518  return at(param)._hit_node;
1519 }
1520 
1521 void
1522 InputParameters::setHitNode(const std::string & param,
1523  const hit::Node & node,
1525 {
1526  mooseAssert(node.type() == hit::NodeType::Field, "Must be a field");
1527  at(param)._hit_node = &node;
1528 }
1529 
1530 std::string
1531 InputParameters::inputLocation(const std::string & param) const
1532 {
1533  if (const auto hit_node = getHitNode(param))
1534  return hit_node->fileLocation(/* with_column = */ false);
1535  return "";
1536 }
1537 
1538 std::string
1539 InputParameters::paramFullpath(const std::string & param) const
1540 {
1541  if (const auto hit_node = getHitNode(param))
1542  return hit_node->fullpath();
1543  return "";
1544 }
1545 
1546 void
1547 InputParameters::checkParamName(const std::string & name) const
1548 {
1549  const static pcrecpp::RE valid("[\\w:/]+");
1550  if (!valid.FullMatch(name))
1551  mooseError("Invalid parameter name: '", name, "'");
1552 }
1553 
1554 bool
1555 InputParameters::shouldIgnore(const std::string & name_in)
1556 {
1557  const auto name = checkForRename(name_in);
1558  auto it = _params.find(name);
1559  if (it != _params.end())
1560  return it->second._ignore;
1561  mooseError("Parameter ", name, " does not exist");
1562 }
1563 
1564 std::set<std::string>
1565 InputParameters::getGroupParameters(const std::string & group) const
1566 {
1567  std::set<std::string> names;
1568  for (auto it = _params.begin(); it != _params.end(); ++it)
1569  if (it->second._group == group)
1570  names.emplace(it->first);
1571  return names;
1572 }
1573 
1574 std::set<std::string>
1576 {
1577  std::set<std::string> param_set;
1578  for (auto it = _params.begin(); it != _params.end(); ++it)
1579  param_set.emplace(it->first);
1580  return param_set;
1581 }
1582 
1583 std::set<std::string>
1585 {
1586  std::set<std::string> controllable;
1587  for (auto it = _params.begin(); it != _params.end(); ++it)
1588  if (it->second._controllable)
1589  controllable.emplace(it->first);
1590  return controllable;
1591 }
1592 
1593 std::string
1594 InputParameters::errorPrefix(const std::string & param) const
1595 {
1596  auto prefix = param + ":";
1597  if (!inputLocation(param).empty())
1598  prefix = inputLocation(param) + ": (" + paramFullpath(param) + ")";
1599  return prefix;
1600 }
1601 
1602 std::string
1603 InputParameters::rawParamVal(const std::string & param) const
1604 {
1605  if (const auto hit_node = getHitNode(param))
1606  return hit_node->strVal();
1607  return "";
1608 }
1609 
1610 std::string
1611 InputParameters::varName(const std::string & var_param_name,
1612  const std::string & moose_object_with_var_param_name) const
1613 {
1614  // Try the scalar version first
1615  std::string variable_name = getMooseType(var_param_name);
1616  if (variable_name == "")
1617  {
1618  auto vec = getVecMooseType(var_param_name);
1619 
1620  // Catch the (very unlikely) case where a user specifies
1621  // variable = '' (the empty string)
1622  // in their input file. This could happen if e.g. something goes
1623  // wrong with dollar bracket expression expansion.
1624  if (vec.empty())
1625  mooseError("Error constructing object '",
1626  moose_object_with_var_param_name,
1627  "' while retrieving value for '",
1628  var_param_name,
1629  "' parameter! Did you forget to set '",
1630  var_param_name,
1631  "' or set it to '' (empty string) by accident?");
1632 
1633  // When using vector variables, we are only going to use the first one in the list at the
1634  // interface level...
1635  variable_name = vec[0];
1636  }
1637 
1638  return variable_name;
1639 }
1640 
1641 void
1642 InputParameters::renameParamInternal(const std::string & old_name,
1643  const std::string & new_name,
1644  const std::string & docstring,
1645  const std::string & removal_date)
1646 {
1647  auto params_it = _params.find(old_name);
1648  if (params_it == _params.end())
1649  mooseError("Requested to rename parameter '",
1650  old_name,
1651  "' but that parameter name doesn't exist in the parameters object.");
1652  mooseAssert(params_it->second._deprecation_message.empty(),
1653  "Attempting to rename the parameter, '" << old_name << "', that is deprecated");
1654 
1655  auto new_metadata = std::move(params_it->second);
1656  if (!docstring.empty())
1657  new_metadata._doc_string = docstring;
1658  _params.emplace(new_name, std::move(new_metadata));
1659  _params.erase(params_it);
1660 
1661  auto values_it = _values.find(old_name);
1662  auto new_value = std::move(values_it->second);
1663  _values.emplace(new_name, std::move(new_value));
1664  _values.erase(values_it);
1665 
1666  std::string deprecation_message;
1667  if (!removal_date.empty())
1668  deprecation_message = "'" + old_name + "' has been deprecated and will be removed on " +
1669  removal_date + ". Please use '" + new_name + "' instead.";
1670 
1671  _old_to_new_name_and_dep.emplace(old_name, std::make_pair(new_name, deprecation_message));
1672  _new_to_old_names.emplace(new_name, old_name);
1673 }
1674 
1675 void
1676 InputParameters::renameCoupledVarInternal(const std::string & old_name,
1677  const std::string & new_name,
1678  const std::string & docstring,
1679  const std::string & removal_date)
1680 {
1681  auto coupled_vars_it = _coupled_vars.find(old_name);
1682  if (coupled_vars_it == _coupled_vars.end())
1683  mooseError("Requested to rename coupled variable '",
1684  old_name,
1685  "' but that coupled variable name doesn't exist in the parameters object.");
1686 
1687  _coupled_vars.insert(new_name);
1688  _coupled_vars.erase(coupled_vars_it);
1689 
1690  renameParamInternal(old_name, new_name, docstring, removal_date);
1691 }
1692 
1693 void
1694 InputParameters::renameParam(const std::string & old_name,
1695  const std::string & new_name,
1696  const std::string & new_docstring)
1697 {
1698  renameParamInternal(old_name, new_name, new_docstring, "");
1699 }
1700 
1701 void
1702 InputParameters::renameCoupledVar(const std::string & old_name,
1703  const std::string & new_name,
1704  const std::string & new_docstring)
1705 {
1706  renameCoupledVarInternal(old_name, new_name, new_docstring, "");
1707 }
1708 
1709 void
1710 InputParameters::deprecateParam(const std::string & old_name,
1711  const std::string & new_name,
1712  const std::string & removal_date)
1713 {
1714  renameParamInternal(old_name, new_name, "", removal_date);
1715 }
1716 
1717 void
1718 InputParameters::deprecateCoupledVar(const std::string & old_name,
1719  const std::string & new_name,
1720  const std::string & removal_date)
1721 {
1722  renameCoupledVarInternal(old_name, new_name, "", removal_date);
1723 }
1724 
1725 std::string
1726 InputParameters::checkForRename(const std::string & name) const
1727 {
1728  if (auto it = _old_to_new_name_and_dep.find(name); it != _old_to_new_name_and_dep.end())
1729  return it->second.first;
1730  else
1731  return name;
1732 }
1733 
1734 std::vector<std::string>
1735 InputParameters::paramAliases(const std::string & param_name) const
1736 {
1737  mooseAssert(_values.find(param_name) != _values.end(),
1738  "The parameter we are searching for aliases for should exist in our parameter map");
1739  std::vector<std::string> aliases = {param_name};
1740 
1741  for (const auto & pr : as_range(_new_to_old_names.equal_range(param_name)))
1742  aliases.push_back(pr.second);
1743 
1744  return aliases;
1745 }
1746 
1747 std::optional<Moose::DataFileUtils::Path>
1748 InputParameters::queryDataFileNamePath(const std::string & name) const
1749 {
1751 }
1752 
1753 void
1754 InputParameters::callMooseErrorHelper(const MooseBase & moose_base, const std::string & error)
1755 {
1756  moose_base.callMooseError(error, true);
1757 }
std::multimap< std::string, std::string > _new_to_old_names
A map from derived-class/blessed parameter names to associated base-class/deprecated parameter names...
std::string name(const ElemQuality q)
std::string getMooseType(const std::string &name) const
Utility functions for retrieving one of the MooseTypes variables into the common "string" base class...
bool isRangeChecked(const std::string &param_name) const
Return whether a parameter has a range check.
void renameParam(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
Rename a parameter and provide a new documentation string.
bool isParamDefined(const std::string &name) const
Method returns true if the parameter is defined for any type.
bool show_trace
Set to true (the default) to print the stack trace with error and warning messages - false to omit it...
Definition: Moose.C:761
const hit::Node * getHitNode(const std::string &param) const
void setGlobalCommandLineParam(const std::string &name)
Sets the command line parameter with name as global.
bool hasCoupledValue(const std::string &coupling_name) const
Return whether or not the coupled variable exists.
void isValid(MooseObject *obj)
Definition: TheWarehouse.C:287
bool _allow_copy
A flag for toggling the error message in the copy constructor.
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 ...
RelationshipManagerType
Main types of Relationship Managers.
Definition: MooseTypes.h:963
Base class for everything in MOOSE with a name and a type.
Definition: MooseBase.h:32
InputParameters & operator=(const InputParameters &rhs)
void setDocUnit(const std::string &name, const std::string &doc_unit)
Set the unit string of a parameter.
std::map< std::string, std::pair< std::string, std::string > > getAutoBuildVectors() const
Returns the auto build vectors for all parameters.
std::optional< std::string > getBase() const
std::set< std::string > getParametersList() const
void applySpecificParameters(const InputParameters &common, const std::vector< std::string > &include, bool allow_private=false)
Method for applying common parameters.
void setDocString(const std::string &name, const std::string &doc)
Set the doc string of a parameter.
bool isParamDeprecated(const std::string &name) const
Returns True if the parameters is deprecated.
const std::vector< std::tuple< std::string, Moose::RelationshipManagerType, Moose::RelationshipManagerInputParameterCallback > > & getBuildableRelationshipManagerTypes() const
Returns the list of buildable (or required) RelationshipManager object types for this object...
bool isControllable(const std::string &name) const
Returns a Boolean indicating whether the specified parameter is controllable.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
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 _block_location
original location of input block (i.e. filename,linenum) - used for nice error messages.
std::set< ExecFlagType > _controllable_flags
Controllable execute flag restriction.
const hit::Node * _hit_node
Original location of parameter node; used for error messages.
char ** vars
std::unordered_map< std::string, std::string > _new_to_deprecated_coupled_vars
A map from deprecated coupled variable names to the new blessed name.
std::string _block_fullpath
full HIT path of the block from the input file - used for nice error messages.
const std::vector< std::string > & getBuildableTypes() const
Returns the list of buildable types as a std::vector<std::string>
void setDeprecatedVarDocString(const std::string &new_name, const std::string &doc_string)
Private method for setting deprecated coupled variable documentation strings.
InputParameters & operator+=(const InputParameters &rhs)
std::optional< Moose::DataFileUtils::Path > _data_file_name_path
The searched path information pertaining to a DataFileName parameter.
void registerSystemAttributeName(const std::string &value)
This method is used to define the MOOSE system name that is used by the TheWarehouse object for stori...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void applyParameters(const InputParameters &common, const std::vector< std::string > &exclude={}, const bool allow_private=false)
Method for applying common parameters.
void renameCoupledVar(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
Rename a coupled variable and provide a new documentation string.
void applyCoupledVar(const InputParameters &common, const std::string &var_name)
Apply properties of a single coupled variable in common, to a single coupled variable stored in this ...
void registerBuildableTypes(const std::string &names)
This method is here to indicate which Moose types a particular Action may build.
bool attemptPrintDeprecated(const std::string &name)
Prints the deprecated parameter message, assuming we have the right flags set.
bool isPrivate(const std::string &name) const
Returns a Boolean indicating whether the specified parameter is private or not.
std::vector< std::string > paramAliases(const std::string &param_name) const
Return all the aliased names associated with param_name.
void addRelationshipManager(const std::string &name, Moose::RelationshipManagerType rm_type, Moose::RelationshipManagerInputParameterCallback input_parameter_callback=nullptr)
Tells MOOSE about a RelationshipManager that this object needs.
void renameParameterGroup(const std::string &old_name, const std::string &new_name)
This method renames a parameter group.
void finalize(const std::string &parsing_syntax)
Finalizes the parameters, which must be done before constructing any objects with these parameters (t...
void checkParamName(const std::string &name) const
Make sure the parameter name doesn&#39;t have any invalid characters.
void renameParamInternal(const std::string &old_name, const std::string &new_name, const std::string &docstring, const std::string &removal_date)
bool mooseObjectSyntaxVisibility() const
unsigned int numberDefaultCoupledValues(const std::string &coupling_name) const
Get the number of defaulted coupled value entries.
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
const std::string & getDescription(const std::string &name) const
Get the documentation string for a parameter.
Structure for storing information about a command line parameter.
bool isParamSetByAddParam(const std::string &name) const
Returns whether or not the parameter was set due to addParam.
void commandLineParamSet(const std::string &name, const CommandLineParamSetKey)
Marks the command line parameter name as set by the CommandLine.
bool _show_deprecated_message
Flag for disabling deprecated parameters message, this is used by applyParameters to avoid dumping me...
bool _collapse_nesting
This parameter collapses one level of nesting in the syntax blocks.
std::string getDocString(const std::string &name) const
Returns the documentation string for the specified parameter name.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void deprecateParam(const std::string &old_name, const std::string &new_name, const std::string &removal_date)
sideset clear()
Class that is used as a parameter to commandLineParamSet() that allows only the CommandLine to set th...
std::string getDocUnit(const std::string &name) const
Returns the documentation unit string for the specified parameter name.
bool shouldIgnore(const std::string &name)
Whether to ignore the value of an input parameter set in the input file or from the command line...
std::function< void(const InputParameters &, InputParameters &)> RelationshipManagerInputParameterCallback
The type for the callback to set RelationshipManager parameters.
Definition: MooseTypes.h:989
bool hasDefaultCoupledValue(const std::string &coupling_name) const
Return whether or not the requested parameter has a default coupled value.
bool areAllRequiredParamsValid() const
This method returns true if all of the parameters in this object are valid (i.e.
std::string rawParamVal(const std::string &param) const
Real defaultCoupledValue(const std::string &coupling_name, unsigned int i=0) const
Get the default value for an optionally coupled variable.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
void addDeprecatedCoupledVar(const std::string &old_name, const std::string &new_name, const std::string &removal_date="")
This method adds a deprecated coupled variable name pair.
std::string _class_description
The class description for the owning object.
const std::set< ExecFlagType > & getControllableExecuteOnTypes(const std::string &name) const
Return the allowed execute flags for a controllable parameter.
void renameCoupledVarInternal(const std::string &old_name, const std::string &new_name, const std::string &docstring, const std::string &removal_date)
std::string docstring(const std::string &desc)
Augment docstring if NEML2 is not enabled.
Definition: NEML2Utils.C:77
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
void deprecateCoupledVar(const std::string &old_name, const std::string &new_name, const std::string &removal_date)
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:353
void checkParams(const std::string &parsing_syntax)
This function checks parameters stored in the object to make sure they are in the correct state as th...
std::string inputLocation(const std::string &param) const
Representation of a data file path.
Definition: DataFileUtils.h:36
std::set< std::string > reservedValues(const std::string &name) const
Get a set of reserved parameter values.
void mooseDeprecatedStream(S &oss, const bool expired, const bool print_title, Args &&... args)
Definition: MooseError.h:239
void addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
void setReservedValues(const std::string &name, const std::set< std::string > &reserved)
Provide a set of reserved values for a parameter.
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
void makeParamNotRequired(const std::string &name)
Changes the parameter to not be required.
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
void callMooseError(std::string msg, const bool with_prefix) const
Calls moose error with the message msg.
Definition: MooseBase.C:33
infix_ostream_iterator< T, charT, traits > & operator=(T const &item)
Definition: InfixIterator.h:46
std::string varName(const std::string &var_param_name, const std::string &moose_object_with_var_param_name) const
Determine the actual variable name from the given variable parameter name.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool isFinalized() const
std::set< std::string > _coupled_vars
The coupled variables set.
std::vector< std::tuple< std::string, Moose::RelationshipManagerType, Moose::RelationshipManagerInputParameterCallback > > _buildable_rm_types
The RelationshipManagers that this object may either build or require.
void addRequiredCoupledVarWithAutoBuild(const std::string &name, const std::string &base_name, const std::string &num_name, const std::string &doc_string)
void addCoupledVarWithAutoBuild(const std::string &name, const std::string &base_name, const std::string &num_name, const std::string &doc_string)
These methods add a coupled variable name pair.
std::string getGroupName(const std::string &param_name) const
This method retrieves the group name for the passed parameter name if one exists. ...
std::string checkForRename(const std::string &name) const
Checks whether the provided name is a renamed parameter name.
Path getPath(std::string path, const std::optional< std::string > &base=std::optional< std::string >())
Get the data path for a given path, searching the registered data.
Definition: DataFileUtils.C:22
bool _finalized
Whether or not we&#39;ve called finalize() on these parameters yet.
std::string type(const std::string &name) const
Prints the type of the requested parameter by name.
std::string blockFullpath() const
bool isCommandLineParameter(const std::string &name) const
const hit::Node * _hit_node
The hit node representing the syntax that created these parameters, if any.
bool paramSetByUser(const std::string &name) const
Deprecated method.
std::optional< InputParameters::CommandLineMetadata > queryCommandLineMetadata(const std::string &name) const
bool isParamRequired(const std::string &name) const
Returns a boolean indicating whether the specified parameter is required or not.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
const std::string & getSystemAttributeName() const
Get the system attribute name if it was registered.
const InputParameters::CommandLineMetadata & getCommandLineMetadata(const std::string &name) const
std::vector< std::string > _buildable_types
The parameter is used to restrict types that can be built.
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...
bool _moose_object_syntax_visibility
This parameter hides derived MOOSE object types from appearing in syntax dumps.
virtual void clear() override
bool hasDefault(const std::string &param_name) const
Return whether a parameter has a default.
void setHitNode(const std::string &param, const hit::Node &node, const SetParamHitNodeKey)
Sets the hit node associated with the parameter param to node.
std::map< std::string, Metadata > _params
The actual parameter data.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type...
virtual void set_attributes(const std::string &name, bool inserted_only) override
Override from libMesh to set user-defined attributes on our parameter.
std::string blockLocation() const
std::string getClassDescription() const
Returns the class description.
std::string errorPrefix(const std::string &param) const
generate error message prefix with parameter name and location (if available)
InputParameters emptyInputParameters()
std::map< std::string, std::pair< std::string, std::string > > _old_to_new_name_and_dep
A map from base-class/deprecated parameter names to derived-class/blessed parameter names and the dep...
std::set< std::string > getControllableParameters() const
Return list of controllable parameters.
void applyParameter(const InputParameters &common, const std::string &common_name, bool allow_private=false, bool override_default=false)
Apply values from a single parameter in common, to a single parameter stored in this object...
std::optional< Moose::DataFileUtils::Path > queryDataFileNamePath(const std::string &name) const
std::vector< ElemQuality > valid(const ElemType t)
static void callMooseErrorHelper(const MooseBase &moose_base, const std::string &error)
std::filesystem::path getFileBase(const std::optional< std::string > &param_name=std::optional< std::string >()) const
std::vector< std::string > getVecMooseType(const std::string &name) const
const hit::Node * getHitNode() const
std::optional< CommandLineMetadata > _cl_data
The data pertaining to a command line parameter (empty if not a command line param) ...
bool _throw_on_error
Variable to turn on exceptions during mooseError(), should only be used within MOOSE unit tests or wh...
Definition: Moose.C:758
Metadata & at(const std::string &param_name)
void declareControllable(const std::string &name, std::set< ExecFlagType > execute_flags={})
Declare the given parameters as controllable.
std::string paramFullpath(const std::string &param) const
std::string rangeCheckedFunction(const std::string &name) const
Return the range check function for any parameter (empty string if it is not range checked) ...
bool collapseSyntaxNesting() const
Class that is used as a parameter to setHitNode(param) that allows only relevant classes to set the h...
ExecFlagEnum execute_flags
Storage for the registered execute flags.
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...
std::set< std::string > getGroupParameters(const std::string &group) const
Return names of parameters within a group.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.