Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
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 const std::string &
1195 InputParameters::getDescription(const std::string & name_in) const
1196 {
1197  const auto name = checkForRename(name_in);
1198  auto it = _params.find(name);
1199  if (it == _params.end())
1200  mooseError("No parameter exists with the name ", name);
1201  return it->second._doc_string;
1202 }
1203 
1204 template <>
1205 void
1206 InputParameters::addRequiredParam<MooseEnum>(const std::string & name,
1207  const MooseEnum & moose_enum,
1208  const std::string & doc_string)
1209 {
1210  InputParameters::set<MooseEnum>(name) = moose_enum; // valid parameter is set by set_attributes
1211  auto & metadata = _params[name];
1212  metadata._required = true;
1213  metadata._doc_string = doc_string;
1214 }
1215 
1216 template <>
1217 void
1218 InputParameters::addRequiredParam<MultiMooseEnum>(const std::string & name,
1219  const MultiMooseEnum & moose_enum,
1220  const std::string & doc_string)
1221 {
1222  InputParameters::set<MultiMooseEnum>(name) =
1223  moose_enum; // valid parameter is set by set_attributes
1224  auto & metadata = _params[name];
1225  metadata._required = true;
1226  metadata._doc_string = doc_string;
1227 }
1228 
1229 template <>
1230 void
1231 InputParameters::addRequiredParam<std::vector<MooseEnum>>(
1232  const std::string & name,
1233  const std::vector<MooseEnum> & moose_enums,
1234  const std::string & doc_string)
1235 {
1236  InputParameters::set<std::vector<MooseEnum>>(name) =
1237  moose_enums; // valid parameter is set by set_attributes
1238  auto & metadata = _params[name];
1239  metadata._required = true;
1240  metadata._doc_string = doc_string;
1241 }
1242 
1243 template <>
1244 void
1245 InputParameters::addRequiredParam<std::vector<MultiMooseEnum>>(
1246  const std::string & name,
1247  const std::vector<MultiMooseEnum> & moose_enums,
1248  const std::string & doc_string)
1249 {
1250  mooseAssert(
1251  moose_enums.size() == 1,
1252  "Only 1 MultiMooseEnum is supported in addRequiredParam<std::vector<MultiMooseEnum>> for " +
1253  name);
1254  mooseAssert(!moose_enums[0].items().empty(),
1255  "The MultiMooseEnum in addRequiredParam<std::vector<MultiMooseEnum>> is empty for " +
1256  name);
1257  InputParameters::set<std::vector<MultiMooseEnum>>(name) =
1258  moose_enums; // valid parameter is set by set_attributes
1259  auto & metadata = _params[name];
1260  metadata._required = true;
1261  metadata._doc_string = doc_string;
1262 }
1263 
1264 template <>
1265 void
1266 InputParameters::addParam<MooseEnum>(const std::string & /*name*/,
1267  const std::string & /*doc_string*/)
1268 {
1269  mooseError("You must supply a MooseEnum object when using addParam, even if the parameter is not "
1270  "required!");
1271 }
1272 
1273 template <>
1274 void
1275 InputParameters::addParam<MultiMooseEnum>(const std::string & /*name*/,
1276  const std::string & /*doc_string*/)
1277 {
1278  mooseError("You must supply a MultiMooseEnum object when using addParam, even if the parameter "
1279  "is not required!");
1280 }
1281 
1282 template <>
1283 void
1284 InputParameters::addParam<std::vector<MooseEnum>>(const std::string & /*name*/,
1285  const std::string & /*doc_string*/)
1286 {
1287  mooseError("You must supply a vector of MooseEnum object(s) when using addParam, even if the "
1288  "parameter is not required!");
1289 }
1290 
1291 template <>
1292 void
1293 InputParameters::addParam<std::vector<MultiMooseEnum>>(const std::string & /*name*/,
1294  const std::string & /*doc_string*/)
1295 {
1296  mooseError(
1297  "You must supply a vector of MultiMooseEnum object(s) when using addParam, even if the "
1298  "parameter is not required!");
1299 }
1300 
1301 template <>
1302 void
1303 InputParameters::addRequiredParam<std::vector<MultiMooseEnum>>(const std::string & /*name*/,
1304  const std::string & /*doc_string*/)
1305 {
1306  mooseError("You must supply a vector of MultiMooseEnum object(s) when using addRequiredParam!");
1307 }
1308 
1309 template <>
1310 void
1311 InputParameters::addPrivateParam<MooseEnum>(const std::string & /*name*/)
1312 {
1313  mooseError("You must supply a MooseEnum object when using addPrivateParam, even if the parameter "
1314  "is not required!");
1315 }
1316 
1317 template <>
1318 void
1319 InputParameters::addPrivateParam<MultiMooseEnum>(const std::string & /*name*/)
1320 {
1321  mooseError("You must supply a MultiMooseEnum object when using addPrivateParam, even if the "
1322  "parameter is not required!");
1323 }
1324 
1325 template <>
1326 void
1327 InputParameters::addDeprecatedParam<MooseEnum>(const std::string & /*name*/,
1328  const std::string & /*doc_string*/,
1329  const std::string & /*deprecation_message*/)
1330 {
1331  mooseError("You must supply a MooseEnum object and the deprecation string when using "
1332  "addDeprecatedParam, even if the parameter is not required!");
1333 }
1334 
1335 template <>
1336 void
1337 InputParameters::addDeprecatedParam<MultiMooseEnum>(const std::string & /*name*/,
1338  const std::string & /*doc_string*/,
1339  const std::string & /*deprecation_message*/)
1340 {
1341  mooseError("You must supply a MultiMooseEnum object and the deprecation string when using "
1342  "addDeprecatedParam, even if the parameter is not required!");
1343 }
1344 
1345 template <>
1346 void
1347 InputParameters::addDeprecatedParam<std::vector<MooseEnum>>(
1348  const std::string & /*name*/,
1349  const std::string & /*doc_string*/,
1350  const std::string & /*deprecation_message*/)
1351 {
1352  mooseError("You must supply a vector of MooseEnum object(s) and the deprecation string when "
1353  "using addDeprecatedParam, even if the parameter is not required!");
1354 }
1355 
1356 std::string
1357 InputParameters::appendFunctorDescription(const std::string & doc_string) const
1358 {
1359  return MooseUtils::trim(doc_string, ". ") +
1360  ". A functor is any of the following: a variable, a functor material property, a "
1361  "function, a post-processor, or a number.";
1362 }
1363 
1364 template <>
1365 void
1366 InputParameters::setParamHelper<PostprocessorName, Real>(const std::string & /*name*/,
1367  PostprocessorName & l_value,
1368  const Real & r_value)
1369 {
1370  // Assign the default value so that it appears in the dump
1371  std::ostringstream oss;
1372  oss << r_value;
1373  l_value = oss.str();
1374 }
1375 
1376 template <>
1377 void
1378 InputParameters::setParamHelper<PostprocessorName, int>(const std::string & /*name*/,
1379  PostprocessorName & l_value,
1380  const int & r_value)
1381 {
1382  // Assign the default value so that it appears in the dump
1383  std::ostringstream oss;
1384  oss << r_value;
1385  l_value = oss.str();
1386 }
1387 
1388 template <>
1389 void
1390 InputParameters::setParamHelper<FunctionName, Real>(const std::string & /*name*/,
1391  FunctionName & l_value,
1392  const Real & r_value)
1393 {
1394  // Assign the default value so that it appears in the dump
1395  std::ostringstream oss;
1396  oss << r_value;
1397  l_value = oss.str();
1398 }
1399 
1400 template <>
1401 void
1402 InputParameters::setParamHelper<FunctionName, int>(const std::string & /*name*/,
1403  FunctionName & l_value,
1404  const int & r_value)
1405 {
1406  // Assign the default value so that it appears in the dump
1407  std::ostringstream oss;
1408  oss << r_value;
1409  l_value = oss.str();
1410 }
1411 
1412 template <>
1413 void
1414 InputParameters::setParamHelper<MaterialPropertyName, Real>(const std::string & /*name*/,
1415  MaterialPropertyName & l_value,
1416  const Real & r_value)
1417 {
1418  // Assign the default value so that it appears in the dump
1419  std::ostringstream oss;
1420  oss << r_value;
1421  l_value = oss.str();
1422 }
1423 
1424 template <>
1425 void
1426 InputParameters::setParamHelper<MaterialPropertyName, int>(const std::string & /*name*/,
1427  MaterialPropertyName & l_value,
1428  const int & r_value)
1429 {
1430  // Assign the default value so that it appears in the dump
1431  std::ostringstream oss;
1432  oss << r_value;
1433  l_value = oss.str();
1434 }
1435 
1436 template <>
1437 void
1438 InputParameters::setParamHelper<MooseFunctorName, Real>(const std::string & /*name*/,
1439  MooseFunctorName & l_value,
1440  const Real & r_value)
1441 {
1442  // Assign the default value so that it appears in the dump
1443  std::ostringstream oss;
1444  oss << r_value;
1445  l_value = oss.str();
1446 }
1447 
1448 template <>
1449 void
1450 InputParameters::setParamHelper<MooseFunctorName, int>(const std::string & /*name*/,
1451  MooseFunctorName & l_value,
1452  const int & r_value)
1453 {
1454  // Assign the default value so that it appears in the dump
1455  std::ostringstream oss;
1456  oss << r_value;
1457  l_value = oss.str();
1458 }
1459 
1460 template <>
1461 const MooseEnum &
1462 InputParameters::getParamHelper<MooseEnum>(const std::string & name_in,
1463  const InputParameters & pars,
1464  const MooseEnum *,
1465  const MooseBase * /* = nullptr */)
1466 {
1467  const auto name = pars.checkForRename(name_in);
1468  return pars.get<MooseEnum>(name);
1469 }
1470 
1471 template <>
1472 const MultiMooseEnum &
1473 InputParameters::getParamHelper<MultiMooseEnum>(const std::string & name_in,
1474  const InputParameters & pars,
1475  const MultiMooseEnum *,
1476  const MooseBase * /* = nullptr */)
1477 {
1478  const auto name = pars.checkForRename(name_in);
1479  return pars.get<MultiMooseEnum>(name);
1480 }
1481 
1482 void
1483 InputParameters::setReservedValues(const std::string & name_in,
1484  const std::set<std::string> & reserved)
1485 {
1486  const auto name = checkForRename(name_in);
1487  _params[name]._reserved_values = reserved;
1488 }
1489 
1490 std::set<std::string>
1491 InputParameters::reservedValues(const std::string & name_in) const
1492 {
1493  const auto name = checkForRename(name_in);
1494  auto it = _params.find(name);
1495  if (it == _params.end())
1496  return std::set<std::string>();
1497  return it->second._reserved_values;
1498 }
1499 
1500 std::string
1502 {
1503  if (const auto hit_node = getHitNode())
1504  return hit_node->fileLocation(/* with_column = */ false);
1505  return "";
1506 }
1507 
1508 std::string
1510 {
1511  if (const auto hit_node = getHitNode())
1512  return hit_node->fullpath();
1513  return "";
1514 }
1515 
1516 const hit::Node *
1517 InputParameters::getHitNode(const std::string & param) const
1518 {
1519  return at(param)._hit_node;
1520 }
1521 
1522 void
1523 InputParameters::setHitNode(const std::string & param,
1524  const hit::Node & node,
1526 {
1527  mooseAssert(node.type() == hit::NodeType::Field, "Must be a field");
1528  at(param)._hit_node = &node;
1529 }
1530 
1531 std::string
1532 InputParameters::inputLocation(const std::string & param) const
1533 {
1534  if (const auto hit_node = getHitNode(param))
1535  return hit_node->fileLocation(/* with_column = */ false);
1536  return "";
1537 }
1538 
1539 std::string
1540 InputParameters::paramFullpath(const std::string & param) const
1541 {
1542  if (const auto hit_node = getHitNode(param))
1543  return hit_node->fullpath();
1544  return "";
1545 }
1546 
1547 void
1548 InputParameters::checkParamName(const std::string & name) const
1549 {
1550  const static pcrecpp::RE valid("[\\w:/]+");
1551  if (!valid.FullMatch(name))
1552  mooseError("Invalid parameter name: '", name, "'");
1553 }
1554 
1555 bool
1556 InputParameters::shouldIgnore(const std::string & name_in)
1557 {
1558  const auto name = checkForRename(name_in);
1559  auto it = _params.find(name);
1560  if (it != _params.end())
1561  return it->second._ignore;
1562  mooseError("Parameter ", name, " does not exist");
1563 }
1564 
1565 std::set<std::string>
1566 InputParameters::getGroupParameters(const std::string & group) const
1567 {
1568  std::set<std::string> names;
1569  for (auto it = _params.begin(); it != _params.end(); ++it)
1570  if (it->second._group == group)
1571  names.emplace(it->first);
1572  return names;
1573 }
1574 
1575 std::set<std::string>
1577 {
1578  std::set<std::string> param_set;
1579  for (auto it = _params.begin(); it != _params.end(); ++it)
1580  param_set.emplace(it->first);
1581  return param_set;
1582 }
1583 
1584 std::set<std::string>
1586 {
1587  std::set<std::string> controllable;
1588  for (auto it = _params.begin(); it != _params.end(); ++it)
1589  if (it->second._controllable)
1590  controllable.emplace(it->first);
1591  return controllable;
1592 }
1593 
1594 std::string
1595 InputParameters::errorPrefix(const std::string & param) const
1596 {
1597  auto prefix = param + ":";
1598  if (!inputLocation(param).empty())
1599  prefix = inputLocation(param) + ": (" + paramFullpath(param) + ")";
1600  return prefix;
1601 }
1602 
1603 std::string
1604 InputParameters::rawParamVal(const std::string & param) const
1605 {
1606  if (const auto hit_node = getHitNode(param))
1607  return hit_node->strVal();
1608  return "";
1609 }
1610 
1611 std::string
1612 InputParameters::varName(const std::string & var_param_name,
1613  const std::string & moose_object_with_var_param_name) const
1614 {
1615  // Try the scalar version first
1616  std::string variable_name = getMooseType(var_param_name);
1617  if (variable_name == "")
1618  {
1619  auto vec = getVecMooseType(var_param_name);
1620 
1621  // Catch the (very unlikely) case where a user specifies
1622  // variable = '' (the empty string)
1623  // in their input file. This could happen if e.g. something goes
1624  // wrong with dollar bracket expression expansion.
1625  if (vec.empty())
1626  mooseError("Error constructing object '",
1627  moose_object_with_var_param_name,
1628  "' while retrieving value for '",
1629  var_param_name,
1630  "' parameter! Did you forget to set '",
1631  var_param_name,
1632  "' or set it to '' (empty string) by accident?");
1633 
1634  // When using vector variables, we are only going to use the first one in the list at the
1635  // interface level...
1636  variable_name = vec[0];
1637  }
1638 
1639  return variable_name;
1640 }
1641 
1642 void
1643 InputParameters::renameParamInternal(const std::string & old_name,
1644  const std::string & new_name,
1645  const std::string & docstring,
1646  const std::string & removal_date)
1647 {
1648  auto params_it = _params.find(old_name);
1649  if (params_it == _params.end())
1650  mooseError("Requested to rename parameter '",
1651  old_name,
1652  "' but that parameter name doesn't exist in the parameters object.");
1653  mooseAssert(params_it->second._deprecation_message.empty(),
1654  "Attempting to rename the parameter, '" << old_name << "', that is deprecated");
1655 
1656  auto new_metadata = std::move(params_it->second);
1657  if (!docstring.empty())
1658  new_metadata._doc_string = docstring;
1659  _params.emplace(new_name, std::move(new_metadata));
1660  _params.erase(params_it);
1661 
1662  auto values_it = _values.find(old_name);
1663  auto new_value = std::move(values_it->second);
1664  _values.emplace(new_name, std::move(new_value));
1665  _values.erase(values_it);
1666 
1667  std::string deprecation_message;
1668  if (!removal_date.empty())
1669  deprecation_message = "'" + old_name + "' has been deprecated and will be removed on " +
1670  removal_date + ". Please use '" + new_name + "' instead.";
1671 
1672  _old_to_new_name_and_dep.emplace(old_name, std::make_pair(new_name, deprecation_message));
1673  _new_to_old_names.emplace(new_name, old_name);
1674 }
1675 
1676 void
1677 InputParameters::renameCoupledVarInternal(const std::string & old_name,
1678  const std::string & new_name,
1679  const std::string & docstring,
1680  const std::string & removal_date)
1681 {
1682  auto coupled_vars_it = _coupled_vars.find(old_name);
1683  if (coupled_vars_it == _coupled_vars.end())
1684  mooseError("Requested to rename coupled variable '",
1685  old_name,
1686  "' but that coupled variable name doesn't exist in the parameters object.");
1687 
1688  _coupled_vars.insert(new_name);
1689  _coupled_vars.erase(coupled_vars_it);
1690 
1691  renameParamInternal(old_name, new_name, docstring, removal_date);
1692 }
1693 
1694 void
1695 InputParameters::renameParam(const std::string & old_name,
1696  const std::string & new_name,
1697  const std::string & new_docstring)
1698 {
1699  renameParamInternal(old_name, new_name, new_docstring, "");
1700 }
1701 
1702 void
1703 InputParameters::renameCoupledVar(const std::string & old_name,
1704  const std::string & new_name,
1705  const std::string & new_docstring)
1706 {
1707  renameCoupledVarInternal(old_name, new_name, new_docstring, "");
1708 }
1709 
1710 void
1711 InputParameters::deprecateParam(const std::string & old_name,
1712  const std::string & new_name,
1713  const std::string & removal_date)
1714 {
1715  renameParamInternal(old_name, new_name, "", removal_date);
1716 }
1717 
1718 void
1719 InputParameters::deprecateCoupledVar(const std::string & old_name,
1720  const std::string & new_name,
1721  const std::string & removal_date)
1722 {
1723  renameCoupledVarInternal(old_name, new_name, "", removal_date);
1724 }
1725 
1726 std::string
1727 InputParameters::checkForRename(const std::string & name) const
1728 {
1729  if (auto it = _old_to_new_name_and_dep.find(name); it != _old_to_new_name_and_dep.end())
1730  return it->second.first;
1731  else
1732  return name;
1733 }
1734 
1735 std::vector<std::string>
1736 InputParameters::paramAliases(const std::string & param_name) const
1737 {
1738  mooseAssert(_values.find(param_name) != _values.end(),
1739  "The parameter we are searching for aliases for should exist in our parameter map");
1740  std::vector<std::string> aliases = {param_name};
1741 
1742  for (const auto & pr : as_range(_new_to_old_names.equal_range(param_name)))
1743  aliases.push_back(pr.second);
1744 
1745  return aliases;
1746 }
1747 
1748 std::optional<Moose::DataFileUtils::Path>
1749 InputParameters::queryDataFileNamePath(const std::string & name) const
1750 {
1752 }
1753 
1754 void
1755 InputParameters::callMooseErrorHelper(const MooseBase & moose_base, const std::string & error)
1756 {
1757  moose_base.callMooseError(error, true);
1758 }
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 show_trace
Set to true (the default) to print the stack trace with error and warning messages - false to omit it...
Definition: Moose.C:763
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 trim(const std::string &str, const std::string &white_space=" \\\)
Standard scripting language trim function.
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:78
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)
std::string appendFunctorDescription(const std::string &doc_string) const
Appends description of what a functor is to a doc string.
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 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:760
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.