Line data Source code
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 : #pragma once
11 :
12 : // MOOSE includes
13 : #include "MooseUtils.h"
14 : #include "MooseError.h"
15 : #include "MooseTypes.h"
16 : #include "MultiMooseEnum.h"
17 : #include "ExecFlagEnum.h"
18 : #include "Conversion.h"
19 : #include "DataFileUtils.h"
20 :
21 : #include "libmesh/parameters.h"
22 :
23 : #ifdef LIBMESH_HAVE_FPARSER
24 : #include "libmesh/fparser.hh"
25 : #else
26 : template <typename T>
27 : class FunctionParserBase
28 : {
29 : }
30 : #endif
31 :
32 : #include <tuple>
33 : #include <unordered_map>
34 : #include <mutex>
35 : #include <optional>
36 : #include <filesystem>
37 : #include <regex>
38 :
39 : #include <gtest/gtest.h>
40 :
41 : // Forward declarations
42 : class Action;
43 : class ActionFactory;
44 : class Factory;
45 : class FEProblemBase;
46 : class InputParameters;
47 : class MooseEnum;
48 : class MooseObject;
49 : class MultiMooseEnum;
50 : class Problem;
51 : namespace hit
52 : {
53 : class Node;
54 : }
55 : namespace Moose
56 : {
57 : class Builder;
58 : }
59 : class CommandLine;
60 :
61 : /**
62 : * The main MOOSE class responsible for handling user-defined
63 : * parameters in almost every MOOSE system.
64 : */
65 : class InputParameters : public libMesh::Parameters
66 : {
67 : public:
68 : InputParameters(const InputParameters & rhs);
69 : InputParameters(const Parameters & rhs);
70 :
71 179581659 : virtual ~InputParameters() = default;
72 :
73 : virtual void clear() override;
74 :
75 : /**
76 : * Structure for storing information about a command line parameter
77 : */
78 : struct CommandLineMetadata
79 : {
80 : enum ArgumentType
81 : {
82 : NONE,
83 : OPTIONAL,
84 : REQUIRED
85 : };
86 :
87 : /// The syntax for the parameter
88 : std::string syntax;
89 : /// The switches for the parameter (i.e., [-t, --timing])
90 : std::vector<std::string> switches;
91 : /// The type of argument
92 : ArgumentType argument_type;
93 : /// Whether or not the argument is required
94 : bool required;
95 : /// Whether or not the parameter was set by the CommandLine
96 : bool set_by_command_line = false;
97 : /// Whether or not the parameter is global (passed to MultiApps)
98 : bool global = false;
99 : };
100 :
101 : /**
102 : * Class that is used as a parameter to setHitNode() that allows only
103 : * relevant classes to set the hit node
104 : */
105 : class SetHitNodeKey
106 : {
107 : friend class Action;
108 : friend class ActionFactory;
109 : friend class Moose::Builder;
110 : friend class Factory;
111 : friend class FEProblemBase;
112 : friend class InputParameters;
113 : FRIEND_TEST(InputParametersTest, fileNames);
114 5460996 : SetHitNodeKey() {}
115 : SetHitNodeKey(const SetHitNodeKey &) {}
116 : };
117 :
118 : /**
119 : * Class that is used as a parameter to setHitNode(param) that allows only
120 : * relevant classes to set the hit node
121 : */
122 : class SetParamHitNodeKey
123 : {
124 : friend class Moose::Builder;
125 : FRIEND_TEST(InputParametersTest, fileNames);
126 2735539 : SetParamHitNodeKey() {}
127 : SetParamHitNodeKey(const SetParamHitNodeKey &) {}
128 : };
129 :
130 : /**
131 : * Determines whether or not the given type is a type that is supported for
132 : * a command line parameter.
133 : *
134 : * In particular, whether or not CommandLine::populateCommandLineParams
135 : * supports extracting these types.
136 : */
137 : template <typename T>
138 : struct isValidCommandLineType
139 : {
140 : static constexpr bool value =
141 : std::is_same_v<T, std::string> || std::is_same_v<T, std::vector<std::string>> ||
142 : std::is_same_v<T, Real> || std::is_same_v<T, unsigned int> || std::is_same_v<T, int> ||
143 : std::is_same_v<T, bool> || std::is_same_v<T, MooseEnum>;
144 : };
145 :
146 : /**
147 : * This method adds a description of the class that will be displayed
148 : * in the input file syntax dump
149 : */
150 : void addClassDescription(const std::string & doc_string);
151 :
152 : /**
153 : * Returns the class description
154 : */
155 : std::string getClassDescription() const;
156 :
157 : /**
158 : * Override from libMesh to set user-defined attributes on our parameter
159 : */
160 : virtual void set_attributes(const std::string & name, bool inserted_only) override;
161 :
162 : /**
163 : * @return The deprecated parameter message for the given parameter, if any
164 : */
165 : std::optional<std::string> queryDeprecatedParamMessage(const std::string & name) const;
166 :
167 : /// This functions is called in set as a 'callback' to avoid code duplication
168 : template <typename T>
169 : void setHelper(const std::string & name);
170 :
171 : /**
172 : * Returns a writable reference to the named parameters. Note: This is not a virtual
173 : * function! Use caution when comparing to the parent class implementation
174 : * @param name The name of the parameter to set
175 : * @param quiet_mode When true the parameter is kept with set_by_add_param=true,
176 : * this is generally not needed.
177 : *
178 : * "quite_mode" returns a writable reference to the named parameter, without setting
179 : * set_by_add_param to false. Using this method of set will make the parameter to continue to
180 : * behave if its value where set ONLY by addParam and not by any other method.
181 : *
182 : * This was added for handling parameters in the Output objects that have behavior dependent
183 : * on whether the user modified the parameters.
184 : *
185 : */
186 : template <typename T>
187 : T & set(const std::string & name, bool quiet_mode = false);
188 :
189 : /**
190 : * Given a series of parameters names and values, sets each name to
191 : * the corresponding value. Any number of name, value pairs can be
192 : * supplied.
193 : *
194 : * Note that each \p value must be of the correct type for the
195 : * parameter of that name, not merely of a type convertible to the
196 : * correct type.
197 : *
198 : * @param name The name of the first parameter to set
199 : */
200 : template <typename T, typename... Ts>
201 : void setParameters(const std::string & name, const T & value, Ts... extra_input_parameters);
202 :
203 : /**
204 : * Runs a range on the supplied parameter if it exists and throws an error if that check fails.
205 : * @returns Optional of whether or not the error is a user error (false = developer error) and
206 : * the associated error
207 : *
208 : * If \p include_param_path = true, include the parameter path in the error message
209 : */
210 : ///@{
211 : template <typename T, typename UP_T>
212 : std::optional<std::pair<bool, std::string>> rangeCheck(const std::string & full_name,
213 : const std::string & short_name,
214 : InputParameters::Parameter<T> * param,
215 : const bool include_param_path = true);
216 : template <typename T, typename UP_T>
217 : std::optional<std::pair<bool, std::string>>
218 : rangeCheck(const std::string & full_name,
219 : const std::string & short_name,
220 : InputParameters::Parameter<std::vector<T>> * param,
221 : const bool include_param_path = true);
222 : ///@}
223 : /**
224 : * Verifies that the requested parameter exists and is not NULL and returns it to the caller.
225 : * The template parameter must be a pointer or an error will be thrown.
226 : */
227 : template <typename T>
228 : T getCheckedPointerParam(const std::string & name, const std::string & error_string = "") const;
229 :
230 : /**
231 : * This method adds a parameter and documentation string to the InputParameters
232 : * object that will be extracted from the input file. If the parameter is
233 : * missing in the input file, an error will be thrown
234 : */
235 : template <typename T>
236 : void addRequiredParam(const std::string & name, const std::string & doc_string);
237 :
238 : /**
239 : * This version of addRequiredParam is here for a consistent use with MooseEnums. Use of
240 : * this function for any other type will throw an error.
241 : */
242 : template <typename T>
243 : void
244 : addRequiredParam(const std::string & name, const T & moose_enum, const std::string & doc_string);
245 :
246 : ///@{
247 : /**
248 : * These methods add an optional parameter and a documentation string to the InputParameters
249 : * object. The first version of this function takes a default value which is used if the parameter
250 : * is not found in the input file. The second method will leave the parameter uninitialized but
251 : * can be checked with "isParamValid" before use.
252 : */
253 : template <typename T, typename S>
254 : void addParam(const std::string & name, const S & value, const std::string & doc_string);
255 : template <typename T>
256 : void addParam(const std::string & name, const std::string & doc_string);
257 : ///@}
258 :
259 : /**
260 : * Enable support for initializer lists as default arguments for container type.
261 : */
262 : template <typename T>
263 22017988 : void addParam(const std::string & name,
264 : const std::initializer_list<typename T::value_type> & value,
265 : const std::string & doc_string)
266 : {
267 44035976 : addParam<T>(name, T{value}, doc_string);
268 22017988 : }
269 :
270 : ///@{
271 : // BEGIN RANGE CHECKED PARAMETER METHODS
272 : /**
273 : * These methods add an range checked parameters. A lower and upper bound can be supplied and the
274 : * supplied parameter will be checked to fall within that range.
275 : */
276 : template <typename T>
277 : void addRequiredRangeCheckedParam(const std::string & name,
278 : const std::string & parsed_function,
279 : const std::string & doc_string);
280 : template <typename T>
281 : void addRangeCheckedParam(const std::string & name,
282 : const T & value,
283 : const std::string & parsed_function,
284 : const std::string & doc_string);
285 : template <typename T>
286 : void addRangeCheckedParam(const std::string & name,
287 : const std::string & parsed_function,
288 : const std::string & doc_string);
289 : // END RANGE CHECKED PARAMETER METHODS
290 : ///@}
291 :
292 : /**
293 : * These methods add an option parameter and with a customer type to the InputParameters object.
294 : * The custom type will be output in YAML dumps and can be used within the GUI application.
295 : */
296 : template <typename T>
297 : void addRequiredCustomTypeParam(const std::string & name,
298 : const std::string & custom_type,
299 : const std::string & doc_string);
300 : template <typename T>
301 : void addCustomTypeParam(const std::string & name,
302 : const T & value,
303 : const std::string & custom_type,
304 : const std::string & doc_string);
305 : template <typename T>
306 : void addCustomTypeParam(const std::string & name,
307 : const std::string & custom_type,
308 : const std::string & doc_string);
309 : template <typename T>
310 : void addDeprecatedCustomTypeParam(const std::string & name,
311 : const std::string & custom_type,
312 : const std::string & doc_string,
313 : const std::string & deprecation_msg);
314 :
315 : /**
316 : * These method add a parameter to the InputParameters object which can be retrieved like any
317 : * other parameter. This parameter however is not printed in the Input file syntax dump or web
318 : * page dump so does not take a documentation string. The first version of this function takes an
319 : * optional default value.
320 : */
321 : template <typename T>
322 : void addPrivateParam(const std::string & name, const T & value);
323 : template <typename T>
324 : void addPrivateParam(const std::string & name);
325 :
326 : /**
327 : * Add parameters for retrieval from the command line.
328 : *
329 : * NOTE: This ONLY works for App objects! This is not valid for normal MOOSE objects!
330 : *
331 : * @param name The name of the parameter
332 : * @param syntax Space separated list of command-line switch syntax that can set this option
333 : * @param doc_string Documentation. This will be shown for --help
334 : */
335 : template <typename T>
336 : void addRequiredCommandLineParam(const std::string & name,
337 : const std::string & syntax,
338 : const std::string & doc_string);
339 : template <typename T>
340 : void addCommandLineParam(const std::string & name,
341 : const std::string & syntax,
342 : const std::string & doc_string);
343 : template <typename T>
344 : void addCommandLineParam(const std::string & name,
345 : const std::string & syntax,
346 : const T & value,
347 : const std::string & doc_string);
348 : template <typename T>
349 2 : void addCommandLineParam(const std::string & name,
350 : const std::string & syntax,
351 : const std::initializer_list<typename T::value_type> & value,
352 : const std::string & doc_string)
353 : {
354 4 : addCommandLineParam<T>(name, syntax, T{value}, doc_string);
355 2 : }
356 :
357 : /**
358 : * Add a command line parameter with an optional value.
359 : *
360 : * This is a deprecated option and only remains for two parameters:
361 : * "mesh_only" and "recover". There are issues with command line
362 : * parameters with optional values because if a value following
363 : * one of these is a hit cli parameter, we don't know if we should
364 : * apply it to the optional option or as a hit parameter.
365 : *
366 : * It is also allowed for "run" as we take all arguments past
367 : * --run and pass to python.
368 : *
369 : * @param name The name of the parameer
370 : * @param syntax Space separated list of command-line switch syntax that can set this option
371 : * @param value The default value to assign
372 : * @param doc_string Documentation. This will be shown for --help
373 : */
374 : template <typename T>
375 : void addOptionalValuedCommandLineParam(const std::string & name,
376 : const std::string & syntax,
377 : const T & value,
378 : const std::string & doc_string);
379 :
380 : /**
381 : * Sets the command line parameter with \p name as global.
382 : *
383 : * Global here means that it will be passed to all child MultiApps.
384 : */
385 : void setGlobalCommandLineParam(const std::string & name);
386 :
387 : /**
388 : * @param name The name of the parameter
389 : * @param value The default value of this parameter if it requires one
390 : * @param doc_string Documentation. This will be shown for --help
391 : * @param deprecation_message The message that will will print about why this param was
392 : * deprecated. It might mention the "new way".
393 : */
394 : template <typename T>
395 : void addDeprecatedParam(const std::string & name,
396 : const T & value,
397 : const std::string & doc_string,
398 : const std::string & deprecation_message);
399 :
400 : template <typename T>
401 : void addDeprecatedParam(const std::string & name,
402 : const std::string & doc_string,
403 : const std::string & deprecation_message);
404 :
405 : /**
406 : * This method checks to make sure that we aren't adding a parameter with the same name but a
407 : * different type. It
408 : * throws a MooseError if an inconsistent type is detected. While this state is supported by
409 : * libMesh it brings
410 : * nothing but blood and tears for those who try ;)
411 : *
412 : * @param name the name of the parameter
413 : */
414 : template <typename T>
415 : void checkConsistentType(const std::string & name) const;
416 :
417 : /**
418 : * @return Whether or not the parameter \p name is a command line parameter
419 : */
420 : bool isCommandLineParameter(const std::string & name) const;
421 :
422 : /**
423 : * @return Queries for the command line metadata for the parameter \p name
424 : *
425 : * Will return an empty optional if the parameter is not a command line param.
426 : */
427 : std::optional<InputParameters::CommandLineMetadata>
428 : queryCommandLineMetadata(const std::string & name) const;
429 :
430 : /**
431 : * @return The command line metadata for the parameter \p name.
432 : */
433 : const InputParameters::CommandLineMetadata &
434 : getCommandLineMetadata(const std::string & name) const;
435 :
436 : /**
437 : * Class that is used as a parameter to commandLineParamSet() that allows only
438 : * the CommandLine to set that a parmeter is set by the command line
439 : */
440 : class CommandLineParamSetKey
441 : {
442 : friend class CommandLine;
443 : FRIEND_TEST(InputParametersTest, commandLineParamSetNotCLParam);
444 457591 : CommandLineParamSetKey() {}
445 : CommandLineParamSetKey(const CommandLineParamSetKey &) {}
446 : };
447 : /**
448 : * Marks the command line parameter \p name as set by the CommandLine.
449 : *
450 : * Protected by the CommandLineParamSetKey so that only the CommandLine can call this.
451 : */
452 : void commandLineParamSet(const std::string & name, const CommandLineParamSetKey);
453 :
454 : /**
455 : * Get the documentation string for a parameter
456 : */
457 : const std::string & getDescription(const std::string & name) const;
458 :
459 : /**
460 : * This method takes a space delimited list of parameter names and adds them to the specified
461 : * group name.
462 : * This information is used in the GUI to group parameters into logical sections.
463 : */
464 : void addParamNamesToGroup(const std::string & space_delim_names, const std::string group_name);
465 :
466 : /**
467 : * This method renames a parameter group
468 : * @param old_name previous name of the parameter group
469 : * @param new_name new name of the parameter group
470 : */
471 : void renameParameterGroup(const std::string & old_name, const std::string & new_name);
472 :
473 : /**
474 : * This method retrieves the group name for the passed parameter name if one exists. Otherwise an
475 : * empty string is returned.
476 : */
477 : std::string getGroupName(const std::string & param_name) const;
478 :
479 : /**
480 : * This method suppresses an inherited parameter so that it isn't required or valid
481 : * in the derived class. The parameter is added to the private parameter list.
482 : * Suppressing a parameter can have dire consequences.
483 : * Use at your own risk!
484 : */
485 : template <typename T>
486 : void suppressParameter(const std::string & name);
487 :
488 : /**
489 : * Changes the parameter to be required.
490 : * @param name The parameter name
491 : */
492 : template <typename T>
493 : void makeParamRequired(const std::string & name);
494 :
495 : /**
496 : * Changes the parameter to not be required.
497 : * @param name The parameter name
498 : */
499 : template <typename T>
500 : void makeParamNotRequired(const std::string & name);
501 :
502 : /**
503 : * This method adds a coupled variable name pair. The parser will look for variable
504 : * name pair in the input file and can return a reference to the storage location
505 : * for the coupled variable if found
506 : */
507 : void addCoupledVar(const std::string & name, const std::string & doc_string);
508 :
509 : /**
510 : * This method adds a deprecated coupled variable name pair. The parser will look for variable
511 : * name pair in the input file and can return a reference to the storage location
512 : * for the coupled variable if found. The doc string for the deprecated variable will be
513 : * constructed from the doc string for the new variable. A deprecation message will also be
514 : * automatically generated
515 : */
516 : void addDeprecatedCoupledVar(const std::string & old_name,
517 : const std::string & new_name,
518 : const std::string & removal_date = "");
519 :
520 : /**
521 : * This method adds a coupled variable name pair. The parser will look for variable
522 : * name pair in the input file and can return a reference to the storage location
523 : * for the coupled variable if found
524 : *
525 : * Also - you can provide a default value for this variable in the case that an actual variable is
526 : * not provided.
527 : */
528 : void addCoupledVar(const std::string & name, const Real value, const std::string & doc_string);
529 :
530 : /**
531 : * This method adds a coupled variable name pair. The parser will look for variable
532 : * name pair in the input file and can return a reference to the storage location
533 : * for the coupled variable if found
534 : *
535 : * Also - you can provide a vector of values for this variable in the case that an actual variable
536 : * is not provided.
537 : */
538 : void addCoupledVar(const std::string & name,
539 : const std::vector<Real> & value,
540 : const std::string & doc_string);
541 :
542 : ///@{
543 : /**
544 : * These methods add a coupled variable name pair. The parser will look for variable
545 : * name pair in the input file and can return a reference to the storage location
546 : * for the coupled variable if found.
547 : *
548 : * This version of the method will build a vector if the given the base_name and num_name
549 : * parameters exist
550 : * in the input file:
551 : * e.g.
552 : * [./foo]
553 : * ...
554 : * some_base = base_
555 : * some_num = 5
556 : * [../]
557 : *
558 : * # The coupling parameter will be passed this vector: "base_0 base_1 base_2 base_3 base_4"
559 : */
560 : void addCoupledVarWithAutoBuild(const std::string & name,
561 : const std::string & base_name,
562 : const std::string & num_name,
563 : const std::string & doc_string);
564 : void addRequiredCoupledVarWithAutoBuild(const std::string & name,
565 : const std::string & base_name,
566 : const std::string & num_name,
567 : const std::string & doc_string);
568 : ///@}
569 :
570 : /**
571 : * Utility functions for retrieving one of the MooseTypes variables into the common "string" base
572 : * class.
573 : * Scalar and Vector versions are supplied
574 : */
575 : std::string getMooseType(const std::string & name) const;
576 : std::vector<std::string> getVecMooseType(const std::string & name) const;
577 :
578 : /**
579 : * @returns Whether or not these parameters are for a MooseBase object, that is,
580 : * one with a name and type.
581 : *
582 : * Needed so that we can produce richer errors from within InputParameters
583 : * that have the context of the underlying object, if possible.
584 : */
585 : bool isMooseBaseObject() const;
586 : /**
587 : * @returns The underlying owning object type, for MooseBase objects with parameters
588 : */
589 : const std::string & getObjectType() const;
590 : /**
591 : * @returns The underlying owning object name, for MooseBase objects with parameters
592 : */
593 : const std::string & getObjectName() const;
594 :
595 : /**
596 : * This method adds a coupled variable name pair. The parser will look for variable
597 : * name pair in the input file and can return a reference to the storage location
598 : * for the coupled variable. If the coupled variable is not supplied in the input
599 : * file, and error is thrown.
600 : *
601 : * Version 2: An auto built vector will be built from the base_name and num_name param. See
602 : * addCoupledVar for an example
603 : */
604 : void addRequiredCoupledVar(const std::string & name, const std::string & doc_string);
605 :
606 : /**
607 : * Returns the documentation string for the specified parameter name
608 : */
609 : std::string getDocString(const std::string & name) const;
610 :
611 : /**
612 : * Set the doc string of a parameter.
613 : *
614 : * This method is generally used from within the validParams function to modify the documentation
615 : * for an
616 : * existing parameter, such as a parameter that is supplied from an interface class.
617 : */
618 : void setDocString(const std::string & name, const std::string & doc);
619 :
620 : /**
621 : * Returns the documentation unit string for the specified parameter name
622 : */
623 : std::string getDocUnit(const std::string & name) const;
624 :
625 : /**
626 : * Set the unit string of a parameter.
627 : *
628 : * This method is only used within MooseDocs and the input syntax dump in order to provide a
629 : * developer-expected unit for software quality assurance purposes.
630 : */
631 : void setDocUnit(const std::string & name, const std::string & doc_unit);
632 :
633 : /**
634 : * Returns a boolean indicating whether the specified parameter is required or not
635 : */
636 : bool isParamRequired(const std::string & name) const;
637 :
638 : /**
639 : * Forces parameter of given name to be not required regardless of type
640 : */
641 : void makeParamNotRequired(const std::string & name);
642 :
643 : /**
644 : * This method returns parameters that have been initialized in one fashion or another,
645 : * i.e. The value was supplied as a default argument or read and properly converted from
646 : * the input file
647 : */
648 : bool isParamValid(const std::string & name) const;
649 :
650 : /**
651 : * Returns whether or not the parameter was set due to addParam. If not then it was either set
652 : * programmatically
653 : * or was read through the input file.
654 : */
655 : bool isParamSetByAddParam(const std::string & name) const;
656 :
657 : /**
658 : * Returns True if the parameters is deprecated.
659 : */
660 : bool isParamDeprecated(const std::string & name) const;
661 :
662 : /**
663 : * This method returns true if all of the parameters in this object are valid
664 : * (i.e. isParamValid(name) == true - for all parameters)
665 : */
666 : bool areAllRequiredParamsValid() const;
667 :
668 : /**
669 : * Prints the type of the requested parameter by name
670 : */
671 : std::string type(const std::string & name) const;
672 :
673 : /**
674 : * Returns a Boolean indicating whether the specified parameter is private or not
675 : */
676 : bool isPrivate(const std::string & name) const;
677 :
678 : /**
679 : * Declare the given parameters as controllable
680 : */
681 : void declareControllable(const std::string & name, std::set<ExecFlagType> execute_flags = {});
682 :
683 : /**
684 : * Marker a parameter that has been changed by the Control system (this is for output purposes)
685 : */
686 : void markControlled(const std::string & name);
687 :
688 : /**
689 : * Returns a Boolean indicating whether the specified parameter is controllable
690 : */
691 : bool isControllable(const std::string & name) const;
692 :
693 : /**
694 : * Return the allowed execute flags for a controllable parameter
695 : */
696 : const std::set<ExecFlagType> & getControllableExecuteOnTypes(const std::string & name) const;
697 :
698 : /**
699 : * This method must be called from every base "Moose System" to create linkage with the Action
700 : * System.
701 : * See "Moose.C" for the registerMooseObjectTask() calls.
702 : */
703 : void registerBase(const std::string & value);
704 :
705 : /**
706 : * @return Whether or not the object has a registered base
707 : *
708 : * The base is registered with registerBase()
709 : */
710 : bool hasBase() const;
711 :
712 : /**
713 : * @return The base system of the object these parameters are for, if any
714 : *
715 : * Set via registerBase().
716 : */
717 : const std::string & getBase() const;
718 :
719 : /**
720 : * This method is used to define the MOOSE system name that is used by the TheWarehouse object
721 : * for storing objects to be retrieved for execution. The base class of every object class
722 : * that will be called for execution (e.g., UserObject objects) should call this method.
723 : *
724 : * This is different from registerBase because the name supplied to registerBase is used to
725 : * associate syntax, but the objects created often go to the same objects for execution, as is
726 : * the case for Postprocessor object which are executed with UserObjects.
727 : *
728 : * See the AttribSystem object for use Attribute.h/C.
729 : */
730 : void registerSystemAttributeName(const std::string & value);
731 :
732 : /**
733 : * Get the system attribute name if it was registered. Otherwise throw an error.
734 : * See the AttribSystem object for use Attribute.h/C.
735 : */
736 : const std::string & getSystemAttributeName() const;
737 :
738 : /**
739 : * This method is here to indicate which Moose types a particular Action may build. It takes a
740 : * space delimited list of registered MooseObjects. TODO: For now we aren't actually checking
741 : * this list when we build objects. Since individual actions can do whatever they want it's not
742 : * exactly trivial to check this without changing the user API. This function properly restricts
743 : * the syntax and YAML dumps.
744 : */
745 : void registerBuildableTypes(const std::string & names);
746 :
747 : /**
748 : * Tells MOOSE about a RelationshipManager that this object needs. RelationshipManagers
749 : * handle element "ghosting", "non-local DOF access" and "sparsity pattern" relationships.
750 : *
751 : * Basically: if this object needs non-local (ie non-current-element) data access then you
752 : * probably need a relationship manager
753 : *
754 : * @param name The name of the RelationshipManager type
755 : * @param rm_type The type (GEOMETRIC/ALGEBRAIC) of the RelationshipManger. Note: You can use
756 : * boolean logic to to "or" RelationshipManagerTypes together to make a RelationshipManager that
757 : * is multi-typed.
758 : * @param input_parameter_callback This is a function pointer that will get called to fill in the
759 : * RelationShipManager's InputParameters. See MooseTypes.h for the signature of this function.
760 : */
761 : void addRelationshipManager(
762 : const std::string & name,
763 : Moose::RelationshipManagerType rm_type,
764 : Moose::RelationshipManagerInputParameterCallback input_parameter_callback = nullptr);
765 :
766 : /**
767 : * Clears all currently registered RelationshipManagers
768 : */
769 29297 : void clearRelationshipManagers() { _buildable_rm_types.clear(); }
770 :
771 : /**
772 : * Returns the list of buildable types as a std::vector<std::string>
773 : */
774 : const std::vector<std::string> & getBuildableTypes() const;
775 :
776 : /**
777 : * Returns the list of buildable (or required) RelationshipManager object types for this object.
778 : */
779 : const std::vector<std::tuple<std::string,
780 : Moose::RelationshipManagerType,
781 : Moose::RelationshipManagerInputParameterCallback>> &
782 : getBuildableRelationshipManagerTypes() const;
783 :
784 : ///@{
785 : /**
786 : * Mutators for controlling whether or not the outermost level of syntax will be collapsed when
787 : * printed.
788 : */
789 : void collapseSyntaxNesting(bool collapse);
790 : bool collapseSyntaxNesting() const;
791 : ///@}
792 :
793 : ///@{
794 : /**
795 : * Mutators for controlling whether or not the outermost level of syntax will be collapsed when
796 : * printed.
797 : */
798 : void mooseObjectSyntaxVisibility(bool visibility);
799 : bool mooseObjectSyntaxVisibility() const;
800 : ///@}
801 :
802 : ///@{
803 : /**
804 : * Copy and Copy/Add operators for the InputParameters object
805 : */
806 : using Parameters::operator=;
807 : using Parameters::operator+=;
808 : InputParameters & operator=(const InputParameters & rhs);
809 : InputParameters & operator+=(const InputParameters & rhs);
810 : ///@}
811 :
812 : /**
813 : * This function checks parameters stored in the object to make sure they are in the correct
814 : * state as the user expects:
815 : * Required parameters are verified as valid meaning that they were either initialized when
816 : * they were created, or were read from an input file or some other valid source
817 : */
818 : void checkParams(const std::string & parsing_syntax);
819 :
820 : /**
821 : * Finalizes the parameters, which must be done before constructing any objects
822 : * with these parameters (to be called in the corresponding factories).
823 : * typed parameters.
824 : *
825 : * This calls checkParams() and sets up the absolute paths for all file name.
826 : */
827 : void finalize(const std::string & parsing_syntax);
828 :
829 : /**
830 : * @return A file base to associate with these parameters.
831 : *
832 : * Optionally, an input parameter can be provided via \p param_name.
833 : *
834 : * If the parameter is provided, we have the following options:
835 : * - The parameter itself has a hit node set (context for that parameter)
836 : * - The InputParameters object has a hit node set (context for all parameters)
837 : * - Neither of the above and we die
838 : *
839 : * In the event that a the parameter is set via command line, this will
840 : * attempt to look at the parameter's parents to find a suitable context.
841 : */
842 : std::filesystem::path
843 : getFileBase(const std::optional<std::string> & param_name = std::optional<std::string>()) const;
844 :
845 : /**
846 : * Methods returning iterators to the coupled variables names stored in this
847 : * InputParameters object
848 : */
849 1621597 : inline std::set<std::string>::const_iterator coupledVarsBegin() const
850 : {
851 1621597 : return _coupled_vars.begin();
852 : }
853 2202797 : inline std::set<std::string>::const_iterator coupledVarsEnd() const
854 : {
855 2202797 : return _coupled_vars.end();
856 : }
857 :
858 : /**
859 : * Return the coupled variable parameter names.
860 : */
861 4713 : const std::set<std::string> & getCoupledVariableParamNames() const { return _coupled_vars; }
862 :
863 : /**
864 : * Return the new to deprecated variable name map
865 : */
866 385799 : const std::unordered_map<std::string, std::string> & getNewToDeprecatedVarMap() const
867 : {
868 385799 : return _new_to_deprecated_coupled_vars;
869 : }
870 :
871 : /// Return whether a parameter has a range check
872 : bool isRangeChecked(const std::string & param_name) const;
873 :
874 : /// Return the range check function for any parameter (empty string if it is not range checked)
875 : std::string rangeCheckedFunction(const std::string & name) const;
876 :
877 : /// Return whether a parameter has a default
878 : bool hasDefault(const std::string & param_name) const;
879 :
880 : /**
881 : * Return whether or not the coupled variable exists
882 : * @param coupling_name The name of the coupled variable to test for
883 : * @return True if the variable exists in the coupled variables for this InputParameters object
884 : */
885 : bool hasCoupledValue(const std::string & coupling_name) const;
886 :
887 : /**
888 : * Return whether or not the requested parameter has a default coupled value.
889 : *
890 : * @param coupling_name The name of the coupling parameter to get the default value for.
891 : */
892 : bool hasDefaultCoupledValue(const std::string & coupling_name) const;
893 :
894 : /**
895 : * Get the default value for an optionally coupled variable.
896 : *
897 : * @param coupling_name The name of the coupling parameter to get the default value for.
898 : * @param i By default 0, in general the index of the requested coupled default value.
899 : */
900 : Real defaultCoupledValue(const std::string & coupling_name, unsigned int i = 0) const;
901 :
902 : /**
903 : * Get the number of defaulted coupled value entries
904 : *
905 : * @param coupling_name The name of the coupling parameter to get the default value for.
906 : */
907 : unsigned int numberDefaultCoupledValues(const std::string & coupling_name) const;
908 :
909 : /**
910 : * Set the default value for an optionally coupled variable (called by the Parser).
911 : *
912 : * @param coupling_name The name of the coupling parameter to get the default value for.
913 : * @param value Default value to set.
914 : * @param i By default 0, in general the index of the requested coupled default value.
915 : */
916 : void defaultCoupledValue(const std::string & coupling_name, Real value, unsigned int i = 0);
917 :
918 : /**
919 : * Returns the auto build vectors for all parameters.
920 : */
921 : std::map<std::string, std::pair<std::string, std::string>> getAutoBuildVectors() const;
922 :
923 : // BEGIN APPLY PARAMETER METHODS
924 : /**
925 : * Method for applying common parameters
926 : * @param common The set of parameters to apply to the parameters stored in this object
927 : * @param exclude A vector of parameters to exclude
928 : *
929 : * In order to apply common parameter 4 statements must be satisfied
930 : * (1) A local parameter must exist with the same name as common parameter
931 : * (2) Common parameter must be valid
932 : * (3) Local parameter must be invalid OR not have been set from its default
933 : * (4) Both cannot be private (unless \p allow_private = true)
934 : *
935 : * Output objects have a set of common parameters that are passed
936 : * down to each of the output objects created. This method is used for
937 : * applying those common parameters.
938 : *
939 : * @see CommonOutputAction AddOutputAction
940 : */
941 : void applyParameters(const InputParameters & common,
942 : const std::vector<std::string> & exclude = {},
943 : const bool allow_private = false);
944 :
945 : /**
946 : * Method for applying common parameters
947 : * @param common The set of parameters to apply to the parameters stored in this object
948 : * @param include A vector of parameters to apply
949 : *
950 : * In order to apply common parameter 4 statements must be satisfied
951 : * (1) A local parameter must exist with the same name as common parameter
952 : * (2) Common parameter must valid
953 : * (3) Local parameter must be invalid OR not have been set from its default
954 : * (4) Both cannot be private
955 : *
956 : * Output objects have a set of common parameters that are passed
957 : * down to each of the output objects created. This method is used for
958 : * applying those common parameters.
959 : *
960 : * @see CommonOutputAction AddOutputAction
961 : */
962 : void applySpecificParameters(const InputParameters & common,
963 : const std::vector<std::string> & include,
964 : bool allow_private = false);
965 :
966 : /**
967 : * Apply values from a single parameter in common, to a single parameter stored in this object
968 : * @param common The set of InputParameters from which to extract parameters from
969 : * @param common_name The name within common from which to get the parameter values
970 : *
971 : * In order to apply common parameter 4 statements must be satisfied
972 : * (1) A local parameter must exist with the same name as common parameter
973 : * (2) Common parameter must valid
974 : * (3) Local parameter must be invalid OR not have been set from its default
975 : * (except if override_default is set)
976 : * (4) Both cannot be private
977 : */
978 : void applyParameter(const InputParameters & common,
979 : const std::string & common_name,
980 : bool allow_private = false,
981 : bool override_default = false);
982 : // END APPLY PARAMETER METHODS
983 :
984 : /**
985 : * Apply properties of a single coupled variable in common, to a single coupled variable stored in
986 : * this object
987 : * @param common The set of InputParameters from which to extract the coupled variable's
988 : * properties
989 : * @param var_name The name of the coupled variable whose properties are to be applied
990 : *
991 : * In order to apply the properties, both the local parameters and the common parameters must
992 : * have a coupled variable with name var_name
993 : */
994 : void applyCoupledVar(const InputParameters & common, const std::string & var_name);
995 :
996 : /**
997 : * Deprecated method. Use isParamSetByUser() instead.
998 : */
999 : bool paramSetByUser(const std::string & name) const;
1000 :
1001 : /**
1002 : * Method returns true if the parameter was set by the user
1003 : * @param name The parameter name
1004 : */
1005 : bool isParamSetByUser(const std::string & name) const;
1006 :
1007 : /**
1008 : * Method returns true if the parameter is defined for any type. If the
1009 : * type is known, use have_parameter<T>() instead.
1010 : * @param name The parameter name
1011 : */
1012 : bool isParamDefined(const std::string & name) const;
1013 :
1014 : ///@{
1015 : /*
1016 : * These methods are here to retrieve parameters for scalar and vector types respectively. We will
1017 : * throw errors
1018 : * when returning most scalar and vector types.
1019 : */
1020 : template <typename T>
1021 : static const T & getParamHelper(const std::string & name, const InputParameters & pars);
1022 : ///@}
1023 :
1024 : using Parameters::get;
1025 :
1026 : /// Combine two vector parameters into a single vector of pairs
1027 : template <typename R1,
1028 : typename R2,
1029 : typename V1 = typename std::conditional<std::is_same<R1, MooseEnumItem>::value,
1030 : MultiMooseEnum,
1031 : std::vector<R1>>::type,
1032 : typename V2 = typename std::conditional<std::is_same<R2, MooseEnumItem>::value,
1033 : MultiMooseEnum,
1034 : std::vector<R2>>::type>
1035 : std::vector<std::pair<R1, R2>> get(const std::string & param1, const std::string & param2) const;
1036 :
1037 : /**
1038 : * @returns list of all parameters
1039 : */
1040 : std::set<std::string> getParametersList() const;
1041 :
1042 : /**
1043 : * Return list of controllable parameters
1044 : */
1045 : std::set<std::string> getControllableParameters() const;
1046 :
1047 : /**
1048 : * Return names of parameters within a group.
1049 : */
1050 : std::set<std::string> getGroupParameters(const std::string & group) const;
1051 :
1052 : /**
1053 : * Provide a set of reserved values for a parameter. These are values that are in addition
1054 : * to the normal set of values the parameter can take.
1055 : */
1056 : void setReservedValues(const std::string & name, const std::set<std::string> & reserved);
1057 :
1058 : /**
1059 : * Get a set of reserved parameter values.
1060 : * Returns a set by value since we can return an empty set.
1061 : */
1062 : std::set<std::string> reservedValues(const std::string & name) const;
1063 :
1064 : /**
1065 : * @return A string representing the location (i.e. filename,linenum) in the input text for the
1066 : * block containing parameters for this object.
1067 : */
1068 : std::string blockLocation() const;
1069 :
1070 : /**
1071 : * @return A string representing the full HIT parameter path from the input file (e.g.
1072 : * "Mesh/foo") for the block containing parameters for this object.
1073 : */
1074 : std::string blockFullpath() const;
1075 :
1076 : /**
1077 : * @return The hit node associated with setting the parameter \p param, if any
1078 : */
1079 : const hit::Node * getHitNode(const std::string & param) const;
1080 : /**
1081 : * Sets the hit node associated with the parameter \p param to \p node
1082 : *
1083 : * Is protected to be called by only the Builder via the SetParamHitNodeKey.
1084 : */
1085 : void setHitNode(const std::string & param, const hit::Node & node, const SetParamHitNodeKey);
1086 :
1087 : /**
1088 : * @return A string representing the location in the input text the parameter originated from
1089 : * (i.e. filename,linenum) for the given param
1090 : */
1091 : std::string inputLocation(const std::string & param) const;
1092 :
1093 : /**
1094 : * @return A string representing the full HIT parameter path from the input file (e.g.
1095 : * "Mesh/foo/bar" for param "bar") for the given param.
1096 : */
1097 : std::string paramFullpath(const std::string & param) const;
1098 :
1099 : /**
1100 : * Returns a prefix containing the parameter name and location (if available)
1101 : */
1102 : std::string paramLocationPrefix(const std::string & param) const;
1103 :
1104 : /**
1105 : * @return A message used as a prefix for output relating to a parameter.
1106 : *
1107 : * Will first prefix with a path to the parameter, or the parameter that
1108 : * resulted in the creation of these parameters, if available. The message
1109 : * will then be prefixed with the block path to the parameter, if available.
1110 : */
1111 : template <typename... Args>
1112 : std::string paramMessage(const std::string & param, Args... args) const;
1113 :
1114 : /**
1115 : * Emits an error prefixed with the object information, if available.
1116 : */
1117 : template <typename... Args>
1118 : [[noreturn]] void mooseError(Args &&... args) const;
1119 :
1120 : /**
1121 : * Emits a parameter error prefixed with the parameter location and
1122 : * object information if available.
1123 : */
1124 : template <typename... Args>
1125 : [[noreturn]] void paramError(const std::string & param, Args... args) const;
1126 :
1127 : /**
1128 : * @return A string representing the raw, unmodified token text for the given param.
1129 : * This is only set if this parameter is parsed from hit
1130 : */
1131 : std::string rawParamVal(const std::string & param) const;
1132 :
1133 : /**
1134 : * Informs this object that values for this parameter set from the input file or from the command
1135 : * line should be ignored
1136 : */
1137 : template <typename T>
1138 : void ignoreParameter(const std::string & name);
1139 :
1140 : /**
1141 : * Whether to ignore the value of an input parameter set in the input file or from the command
1142 : * line.
1143 : */
1144 : bool shouldIgnore(const std::string & name);
1145 :
1146 : /**
1147 : * @returns True if the parameter with name \p name is of type T.
1148 : */
1149 : template <typename T>
1150 : bool isType(const std::string & name) const;
1151 :
1152 : /**
1153 : * Determine the actual variable name from the given variable \emph parameter name
1154 : * @param var_param_name the name of the variable parameter, e.g. 'variable'
1155 : * @param moose_object_with_var_param_name the name of the moose object holding the variable
1156 : * parameter. Used for potential error messaging
1157 : */
1158 : std::string varName(const std::string & var_param_name,
1159 : const std::string & moose_object_with_var_param_name) const;
1160 :
1161 : /**
1162 : * Rename a parameter and provide a new documentation string
1163 : * @param old_name The old name of the parameter
1164 : * @param new_name The new name of the parameter
1165 : * @param new_docstring The new documentation string for the parameter
1166 : * If left empty, uses the old docstring for the renamed parameter
1167 : */
1168 : void renameParam(const std::string & old_name,
1169 : const std::string & new_name,
1170 : const std::string & new_docstring);
1171 :
1172 : /**
1173 : * Rename a coupled variable and provide a new documentation string
1174 : * @param old_name The old name of the coupled variable
1175 : * @param new_name The new name of the coupled variable
1176 : * @param new_docstring The new documentation string for the coupled variable
1177 : */
1178 : void renameCoupledVar(const std::string & old_name,
1179 : const std::string & new_name,
1180 : const std::string & new_docstring);
1181 :
1182 : void deprecateParam(const std::string & old_name,
1183 : const std::string & new_name,
1184 : const std::string & removal_date);
1185 :
1186 : void deprecateCoupledVar(const std::string & old_name,
1187 : const std::string & new_name,
1188 : const std::string & removal_date);
1189 :
1190 : /**
1191 : * Checks whether the provided name is a renamed parameter name. If so we return the 'new' name.
1192 : * If not we return the incoming name
1193 : * @param name The name to check for whether it is a renamed name
1194 : * @return The new name if the incoming \p name is a renamed name, else \p name
1195 : */
1196 : std::string checkForRename(const std::string & name) const;
1197 :
1198 : /**
1199 : * A wrapper around the \p Parameters base class method. Checks for parameter rename before
1200 : * calling the base class method
1201 : * @param name The name to query the parameter values map with
1202 : * @return The parameter value corresponding to the (possibly renamed) name
1203 : */
1204 : template <typename T>
1205 : const T & get(std::string_view name) const;
1206 :
1207 : /**
1208 : * A wrapper around the \p Parameters base class method. Checks for parameter rename before
1209 : * calling the base class method. This method tells whether a parameter with a known type is
1210 : * defined. If the type is unknown, use isParamDefined().
1211 : * @param name The name to query the parameter values map with
1212 : * @return Whether there is a key in the parameter values map corresponding to the (possibly
1213 : * renamed) name
1214 : */
1215 : template <typename T>
1216 : bool have_parameter(std::string_view name) const;
1217 :
1218 : /**
1219 : * A routine to transfer a parameter from one class' validParams to another
1220 : * @param source_param The parameters list holding the param we would like to transfer
1221 : * @param name The name of the parameter to transfer
1222 : * @param new_description A new description of the parameter. If unspecified, uses the
1223 : * source_params'
1224 : */
1225 : template <typename T>
1226 : void transferParam(const InputParameters & source_param,
1227 : const std::string & name,
1228 : const std::string & new_name = "",
1229 : const std::string & new_description = "");
1230 :
1231 : /**
1232 : * Return all the aliased names associated with \p param_name. The returned container will always
1233 : * contain \p param_name itself. Other aliases in addition to \p param_name will include the base
1234 : * class parameter name if \p param_name is the derived class parameter name, or deprecated names
1235 : * that \p param_name is meant to replace.
1236 : * @param param_name The name of the parameter that we want to lookup aliases for. This parameter
1237 : * name must exist in our metadata and parameter names to values map, e.g. this parameter must
1238 : * represent the derived class parameter name if a base class parameter has been renamed or the
1239 : * blessed parameter name in situations where associated parameter names have been deprecated
1240 : * @return All aliases which logically resolve-to/are-associated-with \p param_name, including \p
1241 : * param_name itself
1242 : */
1243 : std::vector<std::string> paramAliases(const std::string & param_name) const;
1244 :
1245 : /**
1246 : * @return The hit node that represents the syntax responsible for creating
1247 : * these parameters, if any
1248 : */
1249 24365353 : const hit::Node * getHitNode() const { return _hit_node; }
1250 : /**
1251 : * Sets the hit node that represents the syntax responsible for creating
1252 : * these parameters
1253 : *
1254 : * Is protected to be called by only the ActionFactory, Builder, and Factory
1255 : * via the SetHitNodeKey.
1256 : */
1257 5460996 : void setHitNode(const hit::Node & node, const SetHitNodeKey) { _hit_node = &node; }
1258 :
1259 : /**
1260 : * @return Whether or not finalize() has been called
1261 : */
1262 : bool isFinalized() const { return _finalized; }
1263 :
1264 : /**
1265 : * @return The DataFileName path for the parameter \p name (if any).
1266 : */
1267 : std::optional<Moose::DataFileUtils::Path> queryDataFileNamePath(const std::string & name) const;
1268 :
1269 : private:
1270 : // Private constructor so that InputParameters can only be created in certain places.
1271 : InputParameters();
1272 :
1273 : /**
1274 : * Method to terminate the recursive setParameters definition
1275 : */
1276 57399 : void setParameters() {}
1277 :
1278 : template <typename T>
1279 : static constexpr bool isFunctorNameType();
1280 :
1281 : /**
1282 : * Appends description of what a functor is to a doc string.
1283 : */
1284 : template <typename T>
1285 : std::string appendFunctorDescription(const std::string & doc_string) const;
1286 :
1287 : /**
1288 : * Private method for setting deprecated coupled variable documentation strings
1289 : */
1290 : void setDeprecatedVarDocString(const std::string & new_name, const std::string & doc_string);
1291 :
1292 : void renameParamInternal(const std::string & old_name,
1293 : const std::string & new_name,
1294 : const std::string & docstring,
1295 : const std::string & removal_date);
1296 :
1297 : void renameCoupledVarInternal(const std::string & old_name,
1298 : const std::string & new_name,
1299 : const std::string & docstring,
1300 : const std::string & removal_date);
1301 :
1302 : /**
1303 : * Get the context associated with a parameter for a message.
1304 : * @param param The parameter name
1305 : * @return Pair that is the string prefix for the parameter (fullpath) and a pointer to the best
1306 : * hit node that can be associated with the parameter (if any)
1307 : */
1308 : std::pair<std::string, const hit::Node *> paramMessageContext(const std::string & param) const;
1309 : /**
1310 : * Get a prefix for messages associated with a parameter.
1311 : *
1312 : * Will include the best file path possible for the parameter and the parameter's fullpath.
1313 : */
1314 : std::string paramMessagePrefix(const std::string & param) const;
1315 :
1316 : struct Metadata
1317 : {
1318 : std::string _doc_string;
1319 : /// The developer-designated unit of the parameter for use in documentation
1320 : std::string _doc_unit;
1321 : /// The custom type that will be printed in the YAML dump for a parameter if supplied
1322 : std::string _custom_type;
1323 : /// The data pertaining to a command line parameter (empty if not a command line param)
1324 : std::optional<CommandLineMetadata> _cl_data;
1325 : /// The searched path information pertaining to a DataFileName parameter
1326 : std::optional<Moose::DataFileUtils::Path> _data_file_name_path;
1327 : /// The names of the parameters organized into groups
1328 : std::string _group;
1329 : /// The map of functions used for range checked parameters
1330 : std::string _range_function;
1331 : /// directions for auto build vectors (base_, 5) -> "base_0 base_1 base_2 base_3 base_4")
1332 : std::pair<std::string, std::string> _autobuild_vecs;
1333 : /// True for parameters that are required (i.e. will cause an abort if not supplied)
1334 : bool _required = false;
1335 : /**
1336 : * Whether the parameter is either explicitly set or provided a default value when added
1337 : * Note: We do not store MooseEnum names in valid params, instead we ask MooseEnums whether
1338 : * they are valid or not.
1339 : */
1340 : bool _valid = false;
1341 : /// The set of parameters that will NOT appear in the the dump of the parser tree
1342 : bool _is_private = false;
1343 : bool _have_coupled_default = false;
1344 : /// The default value for optionally coupled variables
1345 : std::vector<Real> _coupled_default = {0};
1346 : /// True if a parameters value was set by addParam, and not set again.
1347 : bool _set_by_add_param = false;
1348 : /// The reserved option names for a parameter
1349 : std::set<std::string> _reserved_values;
1350 : /// If non-empty, this parameter is deprecated.
1351 : std::string _deprecation_message;
1352 : /// Original location of parameter node; used for error messages
1353 : const hit::Node * _hit_node;
1354 : /// True if the parameters is controllable
1355 : bool _controllable = false;
1356 : /// Controllable execute flag restriction
1357 : std::set<ExecFlagType> _controllable_flags;
1358 : /// whether user setting of this parameter should be ignored
1359 : bool _ignore = false;
1360 : };
1361 :
1362 14913260 : Metadata & at(const std::string & param_name)
1363 : {
1364 14913260 : const auto param = checkForRename(param_name);
1365 14913260 : if (_params.count(param) == 0)
1366 0 : mooseError("param '", param, "' not present in InputParams");
1367 29826520 : return _params[param];
1368 14913260 : }
1369 16124742 : const Metadata & at(const std::string & param_name) const
1370 : {
1371 16124742 : const auto param = checkForRename(param_name);
1372 16124742 : if (_params.count(param) == 0)
1373 0 : mooseError("param '", param, "' not present in InputParams");
1374 32249484 : return _params.at(param);
1375 16124742 : }
1376 :
1377 : /**
1378 : * Toggle the availability of the copy constructor
1379 : *
1380 : * When MooseObject is created via the Factory this flag is set to false, so when a MooseObject is
1381 : * created if
1382 : * the constructor is not a const reference an error is produced. This method allows the
1383 : * InputParameterWarehouse
1384 : * to disable copying.
1385 : */
1386 8370358 : void allowCopy(bool status) { _allow_copy = status; }
1387 :
1388 : /**
1389 : * Make sure the parameter name doesn't have any invalid characters.
1390 : */
1391 : void checkParamName(const std::string & name) const;
1392 :
1393 : /**
1394 : * This method is called when adding a Parameter with a default value, can be specialized for
1395 : * non-matching types.
1396 : */
1397 : template <typename T, typename S>
1398 : void setParamHelper(const std::string & name, T & l_value, const S & r_value);
1399 :
1400 : /**
1401 : * Helper for all of the addCommandLineParam() calls, which sets up _cl_data in the metadata
1402 : *
1403 : * @param name The parameter name
1404 : * @param syntax The parameter syntax
1405 : * @param required Whether or not the parameter is required
1406 : * @param value_required Whethre or not the parameter requires a value
1407 : */
1408 : template <typename T>
1409 : void addCommandLineParamHelper(const std::string & name,
1410 : const std::string & syntax,
1411 : const bool required,
1412 : const bool value_required);
1413 :
1414 : /**
1415 : * Internal helper for calling back to mooseError(), ideally from the underlying
1416 : * MooseBase object if it is available (for more context)
1417 : */
1418 : [[noreturn]] void callMooseError(std::string msg,
1419 : const bool with_prefix = true,
1420 : const hit::Node * node = nullptr) const;
1421 :
1422 : /// The actual parameter data. Each Metadata object contains attributes for the corresponding
1423 : /// parameter.
1424 : std::map<std::string, Metadata> _params;
1425 :
1426 : /// The coupled variables set
1427 : std::set<std::string> _coupled_vars;
1428 :
1429 : /// The class description for the owning object. This string is used in many places including
1430 : /// mouse-over events, and external documentation produced from the source code.
1431 : std::string _class_description;
1432 :
1433 : /// The parameter is used to restrict types that can be built. Typically this is used for
1434 : /// MooseObjectAction derived Actions.
1435 : std::vector<std::string> _buildable_types;
1436 :
1437 : /// The RelationshipManagers that this object may either build or require.
1438 : /// The optional second argument may be supplied to "downgrade" the functionality of the corresponding
1439 : /// relationship manager (e.g. An AlgebraicRelationshipManager could be only used as a
1440 : /// GeometricRelationshipManager for a given simulation).
1441 : std::vector<std::tuple<std::string,
1442 : Moose::RelationshipManagerType,
1443 : Moose::RelationshipManagerInputParameterCallback>>
1444 : _buildable_rm_types;
1445 :
1446 : /// This parameter collapses one level of nesting in the syntax blocks. It is used
1447 : /// in conjunction with MooseObjectAction derived Actions.
1448 : bool _collapse_nesting;
1449 :
1450 : /// This parameter hides derived MOOSE object types from appearing in syntax dumps
1451 : bool _moose_object_syntax_visibility;
1452 :
1453 : /// Flag for disabling deprecated parameters message, this is used by applyParameters to avoid
1454 : /// dumping messages.
1455 : bool _show_deprecated_message;
1456 :
1457 : /// A flag for toggling the error message in the copy constructor.
1458 : bool _allow_copy;
1459 :
1460 : /// A map from deprecated coupled variable names to the new blessed name
1461 : std::unordered_map<std::string, std::string> _new_to_deprecated_coupled_vars;
1462 :
1463 : /// A map from base-class/deprecated parameter names to derived-class/blessed parameter names and
1464 : /// the deprecation messages in the case that the "old" parameter name is a deprecated parameter
1465 : /// name. The deprecation message will be empty if the "old" parameter name represents a base
1466 : /// class parameter name
1467 : std::map<std::string, std::pair<std::string, std::string>> _old_to_new_name_and_dep;
1468 :
1469 : /// A map from derived-class/blessed parameter names to associated base-class/deprecated parameter
1470 : /// names
1471 : std::multimap<std::string, std::string> _new_to_old_names;
1472 :
1473 : /// The hit node representing the syntax that created these parameters, if any
1474 : const hit::Node * _hit_node;
1475 :
1476 : /// Whether or not we've called finalize() on these parameters yet
1477 : bool _finalized;
1478 :
1479 : // These are the only objects allowed to _create_ InputParameters
1480 : friend InputParameters emptyInputParameters();
1481 : friend class InputParameterWarehouse;
1482 : friend class Parser;
1483 : // for the printInputFile function in the action warehouse
1484 : friend class ActionWarehouse;
1485 : };
1486 :
1487 : template <typename T>
1488 : void
1489 838975665 : InputParameters::setHelper(const std::string & /*name*/)
1490 : {
1491 838975665 : }
1492 :
1493 : // Template and inline function implementations
1494 : template <typename T>
1495 : T &
1496 838975665 : InputParameters::set(const std::string & name_in, bool quiet_mode)
1497 : {
1498 838975665 : const auto name = checkForRename(name_in);
1499 :
1500 838975665 : checkParamName(name);
1501 838975665 : checkConsistentType<T>(name);
1502 :
1503 838975665 : T & result = this->Parameters::set<T>(name);
1504 :
1505 838975665 : if (quiet_mode)
1506 26822685 : _params[name]._set_by_add_param = true;
1507 :
1508 838975665 : setHelper<T>(name);
1509 :
1510 838975665 : return result;
1511 838975665 : }
1512 :
1513 : template <typename T, typename... Ts>
1514 : void
1515 57399 : InputParameters::setParameters(const std::string & name,
1516 : const T & value,
1517 : Ts... extra_input_parameters)
1518 : {
1519 57399 : this->set<T>(name) = value;
1520 57399 : this->setParameters(extra_input_parameters...);
1521 57399 : }
1522 :
1523 : template <typename T, typename UP_T>
1524 : std::optional<std::pair<bool, std::string>>
1525 1361108 : InputParameters::rangeCheck(const std::string & full_name,
1526 : const std::string & short_name,
1527 : InputParameters::Parameter<std::vector<T>> * param,
1528 : const bool include_param_path)
1529 : {
1530 : mooseAssert(param, "Parameter is NULL");
1531 :
1532 1361108 : if (!isParamValid(short_name))
1533 757399 : return {};
1534 :
1535 603709 : const auto & range_function = _params[short_name]._range_function;
1536 603709 : if (range_function.empty())
1537 540291 : return {};
1538 :
1539 : /**
1540 : * Automatically detect the variables used in the range checking expression.
1541 : * We allow the following variables (where snam is the short_name of the parameter)
1542 : *
1543 : * snam : tests every component in the vector
1544 : * 'snam > 0'
1545 : * snam_size : the size of the vector
1546 : * 'snam_size = 5'
1547 : * snam_i : where i is a number from 0 to sname_size-1 tests a specific component
1548 : * 'snam_0 > snam_1'
1549 : */
1550 63418 : FunctionParserBase<UP_T> fp;
1551 63418 : std::vector<std::string> vars;
1552 63418 : if (fp.ParseAndDeduceVariables(range_function, vars) != -1) // -1 for success
1553 : return {{false,
1554 1 : "Error parsing expression '" + range_function + "' for parameter " + short_name + ""}};
1555 :
1556 : // Fparser parameter buffer
1557 63417 : std::vector<UP_T> parbuf(vars.size());
1558 :
1559 : // parameter vector
1560 63417 : const std::vector<T> & value = param->set();
1561 :
1562 : // iterate over all vector values (maybe ;)
1563 63417 : bool need_to_iterate = false;
1564 63417 : unsigned int i = 0;
1565 : do
1566 : {
1567 : // set parameters
1568 128324 : for (unsigned int j = 0; j < vars.size(); j++)
1569 : {
1570 64210 : if (vars[j] == short_name)
1571 : {
1572 63943 : if (value.size() == 0)
1573 5 : return {{true, "Range checking empty vector '" + range_function + "'"}};
1574 :
1575 63938 : parbuf[j] = value[i];
1576 63938 : need_to_iterate = true;
1577 : }
1578 267 : else if (vars[j] == short_name + "_size")
1579 80 : parbuf[j] = value.size();
1580 : else
1581 : {
1582 187 : if (vars[j].substr(0, short_name.size() + 1) != short_name + "_")
1583 1 : return {{false, "Error parsing expression '" + range_function + "'"}};
1584 186 : std::istringstream iss(vars[j]);
1585 186 : iss.seekg(short_name.size() + 1);
1586 :
1587 : size_t index;
1588 186 : if (iss >> index && iss.eof())
1589 : {
1590 185 : if (index >= value.size())
1591 : return {{true,
1592 5 : "Error parsing expression '" + range_function + "'; out of range variable '" +
1593 5 : vars[j] + "'"}};
1594 180 : parbuf[j] = value[index];
1595 : }
1596 : else
1597 : return {{false,
1598 1 : "Error parsing expression '" + range_function + "'; invalid variable '" +
1599 1 : vars[j] + "'"}};
1600 186 : }
1601 : }
1602 :
1603 : // ensure range-checked input file parameter comparison functions
1604 : // do absolute floating point comparisons instead of using a default epsilon.
1605 64114 : auto tmp_eps = fp.epsilon();
1606 64114 : fp.setEpsilon(0);
1607 64114 : UP_T result = fp.Eval(&parbuf[0]);
1608 64114 : fp.setEpsilon(tmp_eps);
1609 :
1610 : // test function using the parameters determined above
1611 64114 : if (fp.EvalError())
1612 0 : return {{false, "Error evaluating expression '" + range_function + "'"}};
1613 :
1614 64114 : if (!result)
1615 : {
1616 28 : std::ostringstream oss;
1617 28 : oss << "Range check failed";
1618 28 : if (include_param_path)
1619 0 : oss << " for parameter " << full_name;
1620 28 : oss << "; expression = '" << range_function << "'";
1621 28 : if (need_to_iterate)
1622 4 : oss << ", component " << i;
1623 28 : return {{true, oss.str()}};
1624 28 : }
1625 :
1626 64086 : } while (need_to_iterate && ++i < value.size());
1627 :
1628 63377 : return {};
1629 63418 : }
1630 :
1631 : template <typename T, typename UP_T>
1632 : std::optional<std::pair<bool, std::string>>
1633 17212313 : InputParameters::rangeCheck(const std::string & full_name,
1634 : const std::string & short_name,
1635 : InputParameters::Parameter<T> * param,
1636 : const bool include_param_path)
1637 : {
1638 : mooseAssert(param, "Parameter is NULL");
1639 :
1640 17212313 : if (!isParamValid(short_name))
1641 2813186 : return {};
1642 :
1643 14399127 : const auto & range_function = _params[short_name]._range_function;
1644 14399127 : if (range_function.empty())
1645 12678172 : return {};
1646 :
1647 : // Parse the expression
1648 1720955 : FunctionParserBase<UP_T> fp;
1649 1720955 : if (fp.Parse(range_function, short_name) != -1) // -1 for success
1650 : return {{false,
1651 1 : "Error parsing expression '" + range_function + "'" + " for parameter " + short_name}};
1652 :
1653 : // ensure range-checked input file parameter comparison functions
1654 : // do absolute floating point comparisons instead of using a default epsilon.
1655 1720954 : auto tmp_eps = fp.epsilon();
1656 1720954 : fp.setEpsilon(0);
1657 : // We require a non-const value for the implicit upscaling of the parameter type
1658 1720954 : std::vector<UP_T> value(1, param->set());
1659 1720954 : UP_T result = fp.Eval(&value[0]);
1660 1720954 : fp.setEpsilon(tmp_eps);
1661 :
1662 1720954 : if (fp.EvalError())
1663 : return {{true,
1664 : "Error evaluating expression '" + range_function + "' for parameter " + short_name +
1665 0 : "; perhaps you used the wrong variable name?"}};
1666 :
1667 1720954 : if (!result)
1668 : {
1669 13 : std::ostringstream oss;
1670 13 : oss << "Range check failed";
1671 13 : if (include_param_path)
1672 12 : oss << " for parameter " << full_name;
1673 13 : oss << "; expression = '" << range_function << "', value = " << value[0];
1674 13 : return {{true, oss.str()}};
1675 13 : }
1676 :
1677 1720941 : return {};
1678 1720955 : }
1679 :
1680 : template <typename T>
1681 : T
1682 23655407 : InputParameters::getCheckedPointerParam(const std::string & name_in,
1683 : const std::string & error_string) const
1684 : {
1685 23655407 : const auto name = checkForRename(name_in);
1686 :
1687 23655407 : T param = this->get<T>(name);
1688 :
1689 : // Note: You will receive a compile error on this line if you attempt to pass a non-pointer
1690 : // template type to this method
1691 23655407 : if (!param)
1692 12 : mooseError("Parameter ", name, " is NULL.\n", error_string);
1693 47310790 : return this->get<T>(name);
1694 23655395 : }
1695 :
1696 : template <typename T>
1697 : void
1698 42700736 : InputParameters::addRequiredParam(const std::string & name, const std::string & doc_string)
1699 : {
1700 42700736 : checkParamName(name);
1701 42700736 : checkConsistentType<T>(name);
1702 :
1703 42700736 : InputParameters::insert<T>(name);
1704 42700736 : auto & metadata = _params[name];
1705 42700736 : metadata._required = true;
1706 : if constexpr (isFunctorNameType<T>())
1707 1394810 : metadata._doc_string = appendFunctorDescription<T>(doc_string);
1708 : else
1709 41305926 : metadata._doc_string = doc_string;
1710 42700736 : }
1711 :
1712 : template <typename T>
1713 : void
1714 : InputParameters::addRequiredParam(const std::string & /*name*/,
1715 : const T & /*value*/,
1716 : const std::string & /*doc_string*/)
1717 : {
1718 : mooseError("You cannot call addRequiredParam and supply a default value for this type, please "
1719 : "use addParam instead");
1720 : }
1721 :
1722 : template <typename T, typename S>
1723 : void
1724 372319272 : InputParameters::addParam(const std::string & name, const S & value, const std::string & doc_string)
1725 : {
1726 372319272 : checkParamName(name);
1727 372319272 : checkConsistentType<T>(name);
1728 :
1729 372319272 : T & l_value = InputParameters::set<T>(name);
1730 372319272 : auto & metadata = _params[name];
1731 : if constexpr (isFunctorNameType<T>())
1732 1001087 : metadata._doc_string = appendFunctorDescription<T>(doc_string);
1733 : else
1734 371318185 : metadata._doc_string = doc_string;
1735 :
1736 : // Set the parameter now
1737 372319272 : setParamHelper(name, l_value, value);
1738 :
1739 : /* Indicate the default value, as set via addParam, is being used. The parameter is removed from
1740 : the list whenever
1741 : it changes, see set_attributes */
1742 372319272 : metadata._set_by_add_param = true;
1743 372319272 : }
1744 :
1745 : template <typename T>
1746 : void
1747 138738912 : InputParameters::addParam(const std::string & name, const std::string & doc_string)
1748 : {
1749 138738912 : checkParamName(name);
1750 138738909 : checkConsistentType<T>(name);
1751 :
1752 138738909 : InputParameters::insert<T>(name);
1753 : if constexpr (isFunctorNameType<T>())
1754 740736 : _params[name]._doc_string = appendFunctorDescription<T>(doc_string);
1755 : else
1756 137998173 : _params[name]._doc_string = doc_string;
1757 138738909 : }
1758 :
1759 : template <typename T, typename S>
1760 : void
1761 370436988 : InputParameters::setParamHelper(const std::string & /*name*/, T & l_value, const S & r_value)
1762 : {
1763 370436988 : l_value = r_value;
1764 370436988 : }
1765 :
1766 : template <typename T>
1767 : void
1768 5108630 : InputParameters::addCommandLineParamHelper(const std::string & name,
1769 : const std::string & syntax,
1770 : const bool required,
1771 : const bool value_required)
1772 : {
1773 : static_assert(isValidCommandLineType<T>::value,
1774 : "This type is not a supported command line parameter type. See "
1775 : "CommandLine::populateCommandLineParams to add it as a supported type.");
1776 :
1777 5108630 : auto & cl_data = at(name)._cl_data;
1778 5108630 : cl_data = CommandLineMetadata();
1779 :
1780 : // Split up the syntax by whitespace
1781 5108630 : std::vector<std::string> syntax_split;
1782 10217260 : MooseUtils::tokenize(syntax, syntax_split, 1, " \t\n\v\f\r");
1783 :
1784 : // Set the single syntax string as the combined syntax with removed whitespace
1785 5108630 : cl_data->syntax = MooseUtils::stringJoin(syntax_split);
1786 : mooseAssert(cl_data->syntax.size(), "Empty token");
1787 :
1788 : // Set the switches; only parse those that begin with "-" as we also
1789 : // provide examples within the syntax
1790 12438946 : for (const auto & val : syntax_split)
1791 7330317 : if (val.rfind("-", 0) == 0)
1792 : {
1793 5519414 : if (!std::regex_search(val, std::regex("^\\-+[a-zA-Z]")))
1794 1 : mooseError("The switch '",
1795 : val,
1796 : "' for the command line parameter '",
1797 : name,
1798 : "' is invalid. It must begin with an alphabetical character.");
1799 :
1800 5519413 : cl_data->switches.push_back(val);
1801 5519413 : libMesh::add_command_line_name(val);
1802 : }
1803 :
1804 5108629 : cl_data->required = required;
1805 5108629 : cl_data->global = false;
1806 :
1807 : // No arguments needed for a boolean parameter
1808 : if constexpr (std::is_same_v<T, bool>)
1809 : {
1810 : (void)value_required; // purposely unused; doesn't take a value
1811 3422218 : cl_data->argument_type = CommandLineMetadata::ArgumentType::NONE;
1812 : }
1813 : // MooseEnums require a value
1814 : else if constexpr (std::is_same_v<T, MooseEnum>)
1815 : {
1816 : (void)value_required; // purposely unused; always required
1817 136924 : cl_data->argument_type = CommandLineMetadata::ArgumentType::REQUIRED;
1818 : }
1819 : // The user didn't specify a default, so a value is required
1820 1549487 : else if (value_required)
1821 1344102 : cl_data->argument_type = CommandLineMetadata::ArgumentType::REQUIRED;
1822 : // Otherwise, it's optional (user specified a default)
1823 : else
1824 205385 : cl_data->argument_type = CommandLineMetadata::ArgumentType::OPTIONAL;
1825 5108630 : }
1826 :
1827 : template <typename T>
1828 : void
1829 664922 : InputParameters::addRequiredRangeCheckedParam(const std::string & name,
1830 : const std::string & parsed_function,
1831 : const std::string & doc_string)
1832 : {
1833 664922 : addRequiredParam<T>(name, doc_string);
1834 664922 : _params[name]._range_function = parsed_function;
1835 664922 : }
1836 :
1837 : template <typename T>
1838 : void
1839 8921039 : InputParameters::addRangeCheckedParam(const std::string & name,
1840 : const T & value,
1841 : const std::string & parsed_function,
1842 : const std::string & doc_string)
1843 : {
1844 8921039 : addParam<T>(name, value, doc_string);
1845 8921039 : _params[name]._range_function = parsed_function;
1846 8921039 : }
1847 :
1848 : template <typename T>
1849 : void
1850 1599805 : InputParameters::addRangeCheckedParam(const std::string & name,
1851 : const std::string & parsed_function,
1852 : const std::string & doc_string)
1853 : {
1854 1599805 : addParam<T>(name, doc_string);
1855 1599805 : _params[name]._range_function = parsed_function;
1856 1599805 : }
1857 :
1858 : template <typename T>
1859 : void
1860 164211 : InputParameters::addRequiredCustomTypeParam(const std::string & name,
1861 : const std::string & custom_type,
1862 : const std::string & doc_string)
1863 : {
1864 164211 : addRequiredParam<T>(name, doc_string);
1865 164211 : _params[name]._custom_type = custom_type;
1866 164211 : }
1867 :
1868 : template <typename T>
1869 : void
1870 111587 : InputParameters::addCustomTypeParam(const std::string & name,
1871 : const T & value,
1872 : const std::string & custom_type,
1873 : const std::string & doc_string)
1874 : {
1875 111587 : addParam<T>(name, value, doc_string);
1876 111587 : _params[name]._custom_type = custom_type;
1877 111587 : }
1878 :
1879 : template <typename T>
1880 : void
1881 189172 : InputParameters::addCustomTypeParam(const std::string & name,
1882 : const std::string & custom_type,
1883 : const std::string & doc_string)
1884 : {
1885 189172 : addParam<T>(name, doc_string);
1886 189172 : _params[name]._custom_type = custom_type;
1887 189172 : }
1888 :
1889 : template <typename T>
1890 : void
1891 174772 : InputParameters::addDeprecatedCustomTypeParam(const std::string & name,
1892 : const std::string & custom_type,
1893 : const std::string & doc_string,
1894 : const std::string & deprecation_message)
1895 : {
1896 174772 : _show_deprecated_message = false;
1897 174772 : addParam<T>(name, doc_string);
1898 174772 : auto & metadata = _params[name];
1899 174772 : metadata._custom_type = custom_type;
1900 :
1901 174772 : metadata._deprecation_message = deprecation_message;
1902 174772 : _show_deprecated_message = true;
1903 174772 : }
1904 :
1905 : template <typename T>
1906 : void
1907 188210045 : InputParameters::addPrivateParam(const std::string & name)
1908 : {
1909 188210045 : checkParamName(name);
1910 188210045 : checkConsistentType<T>(name);
1911 :
1912 188210045 : InputParameters::insert<T>(name);
1913 188210045 : _params[name]._is_private = true;
1914 188210045 : }
1915 :
1916 : template <typename T>
1917 : void
1918 321789786 : InputParameters::addPrivateParam(const std::string & name, const T & value)
1919 : {
1920 321789786 : checkParamName(name);
1921 321789786 : checkConsistentType<T>(name);
1922 :
1923 321789786 : InputParameters::set<T>(name) = value;
1924 321789786 : auto & metadata = _params[name];
1925 321789786 : metadata._is_private = true;
1926 321789786 : metadata._set_by_add_param = true;
1927 321789786 : }
1928 :
1929 : template <typename T>
1930 : void
1931 1 : InputParameters::addRequiredCommandLineParam(const std::string & name,
1932 : const std::string & syntax,
1933 : const std::string & doc_string)
1934 : {
1935 : static_assert(!std::is_same_v<T, bool>, "Cannot be used for a bool");
1936 :
1937 1 : addRequiredParam<T>(name, doc_string);
1938 1 : addCommandLineParamHelper<T>(name, syntax, /* required = */ true, /* value_required = */ true);
1939 1 : }
1940 :
1941 : template <typename T>
1942 : void
1943 4424212 : InputParameters::addCommandLineParam(const std::string & name,
1944 : const std::string & syntax,
1945 : const std::string & doc_string)
1946 : {
1947 : static_assert(!std::is_same_v<T, MooseEnum>,
1948 : "addCommandLineParam() without a value cannot be used with a MooseEnum because a "
1949 : "MooseEnum requires initialization");
1950 :
1951 4424212 : auto constexpr is_bool = std::is_same_v<T, bool>;
1952 : if constexpr (is_bool)
1953 3216836 : addParam<T>(name, false, doc_string);
1954 : else
1955 1207376 : addParam<T>(name, doc_string);
1956 :
1957 4424212 : addCommandLineParamHelper<T>(
1958 : name, syntax, /* required = */ false, /* value_required = */ !is_bool);
1959 4424211 : }
1960 :
1961 : template <typename T>
1962 : void
1963 479032 : InputParameters::addCommandLineParam(const std::string & name,
1964 : const std::string & syntax,
1965 : const T & value,
1966 : const std::string & doc_string)
1967 : {
1968 : if constexpr (std::is_same_v<T, bool>)
1969 : mooseAssert(!value, "Default for bool must be false");
1970 :
1971 479032 : addParam<T>(name, value, doc_string);
1972 479032 : addCommandLineParamHelper<T>(name, syntax, /* required = */ false, /* value_required = */ true);
1973 479032 : }
1974 :
1975 : template <typename T>
1976 : void
1977 205385 : InputParameters::addOptionalValuedCommandLineParam(const std::string & name,
1978 : const std::string & syntax,
1979 : const T & value,
1980 : const std::string & doc_string)
1981 : {
1982 : mooseAssert(name == "mesh_only" || name == "recover" || name == "run",
1983 : "Not supported for new parameters");
1984 : static_assert(!std::is_same_v<T, bool>, "Cannot be used for a bool (does not take a value)");
1985 205385 : addParam<T>(name, value, doc_string);
1986 205385 : addCommandLineParamHelper<T>(name, syntax, /* required = */ false, /* value_required = */ false);
1987 205385 : }
1988 :
1989 : template <typename T>
1990 : void
1991 1902734285 : InputParameters::checkConsistentType(const std::string & name_in) const
1992 : {
1993 1902734285 : const auto name = checkForRename(name_in);
1994 :
1995 : // If we don't currently have the Parameter, can't be any inconsistency
1996 1902734285 : InputParameters::const_iterator it = _values.find(name);
1997 1902734285 : if (it == _values.end())
1998 1775033153 : return;
1999 :
2000 : // Now, if we already have the Parameter, but it doesn't have the
2001 : // right type, throw an error.
2002 127701132 : if (!this->Parameters::have_parameter<T>(name))
2003 0 : mooseError("Attempting to set parameter \"",
2004 : name,
2005 : "\" with type (",
2006 : libMesh::demangle(typeid(T).name()),
2007 : ")\nbut the parameter already exists as type (",
2008 0 : it->second->type(),
2009 : ")");
2010 1902734285 : }
2011 :
2012 : template <typename T>
2013 : void
2014 9968353 : InputParameters::suppressParameter(const std::string & name_in)
2015 : {
2016 9968353 : const auto name = checkForRename(name_in);
2017 9968353 : if (!this->have_parameter<T>(name))
2018 1 : mooseError("Unable to suppress nonexistent parameter: ", name);
2019 :
2020 9968352 : auto & metadata = _params[name];
2021 9968352 : metadata._required = false;
2022 9968352 : metadata._is_private = true;
2023 9968352 : metadata._controllable = false;
2024 9968353 : }
2025 :
2026 : template <typename T>
2027 : void
2028 3184 : InputParameters::ignoreParameter(const std::string & name_in)
2029 : {
2030 3184 : const auto name = checkForRename(name_in);
2031 3184 : suppressParameter<T>(name);
2032 3184 : _params[name]._ignore = true;
2033 3184 : }
2034 :
2035 : template <typename T>
2036 : void
2037 74791 : InputParameters::makeParamRequired(const std::string & name_in)
2038 : {
2039 74791 : const auto name = checkForRename(name_in);
2040 :
2041 74791 : if (!this->have_parameter<T>(name))
2042 2 : mooseError("Unable to require nonexistent parameter: ", name);
2043 :
2044 74789 : _params[name]._required = true;
2045 74791 : }
2046 :
2047 : template <typename T>
2048 : void
2049 230924 : InputParameters::makeParamNotRequired(const std::string & name_in)
2050 : {
2051 230924 : const auto name = checkForRename(name_in);
2052 :
2053 230924 : if (!this->have_parameter<T>(name))
2054 0 : mooseError("Unable to un-require nonexistent parameter: ", name);
2055 :
2056 230924 : _params[name]._required = false;
2057 230924 : }
2058 :
2059 : template <typename T>
2060 : void
2061 5196520 : InputParameters::addDeprecatedParam(const std::string & name,
2062 : const T & value,
2063 : const std::string & doc_string,
2064 : const std::string & deprecation_message)
2065 : {
2066 5196520 : _show_deprecated_message = false;
2067 : mooseAssert(!_old_to_new_name_and_dep.count(name),
2068 : "Attempting to deprecate via addDeprecatedParam the parameter, '"
2069 : << name << "', already deprecated via deprecateParam or renamed via renameParam");
2070 5196520 : addParam<T>(name, value, doc_string);
2071 :
2072 5196520 : _params[name]._deprecation_message = deprecation_message;
2073 5196520 : _show_deprecated_message = true;
2074 5196520 : }
2075 :
2076 : template <typename T>
2077 : void
2078 2745285 : InputParameters::addDeprecatedParam(const std::string & name,
2079 : const std::string & doc_string,
2080 : const std::string & deprecation_message)
2081 : {
2082 2745285 : _show_deprecated_message = false;
2083 : mooseAssert(!_old_to_new_name_and_dep.count(name),
2084 : "Attempting to deprecate via addDeprecatedParam the parameter, '"
2085 : << name << "', already deprecated via deprecateParam or renamed via renameParam");
2086 2745285 : addParam<T>(name, doc_string);
2087 :
2088 2745285 : _params[name]._deprecation_message = deprecation_message;
2089 2745285 : _show_deprecated_message = true;
2090 2745285 : }
2091 :
2092 : // Forward declare MooseEnum specializations for add*Param
2093 : template <>
2094 : void InputParameters::addRequiredParam<MooseEnum>(const std::string & name,
2095 : const MooseEnum & moose_enum,
2096 : const std::string & doc_string);
2097 :
2098 : template <>
2099 : void InputParameters::addRequiredParam<MultiMooseEnum>(const std::string & name,
2100 : const MultiMooseEnum & moose_enum,
2101 : const std::string & doc_string);
2102 :
2103 : template <>
2104 : void InputParameters::addRequiredParam<std::vector<MooseEnum>>(
2105 : const std::string & name,
2106 : const std::vector<MooseEnum> & moose_enums,
2107 : const std::string & doc_string);
2108 :
2109 : template <>
2110 : void InputParameters::addRequiredParam<std::vector<MultiMooseEnum>>(
2111 : const std::string & name,
2112 : const std::vector<MultiMooseEnum> & moose_enums,
2113 : const std::string & doc_string);
2114 :
2115 : template <>
2116 : void InputParameters::addParam<MooseEnum>(const std::string & /*name*/,
2117 : const std::string & /*doc_string*/);
2118 :
2119 : template <>
2120 : void InputParameters::addParam<MultiMooseEnum>(const std::string & /*name*/,
2121 : const std::string & /*doc_string*/);
2122 :
2123 : template <>
2124 : void InputParameters::addParam<std::vector<MooseEnum>>(const std::string & /*name*/,
2125 : const std::string & /*doc_string*/);
2126 :
2127 : template <>
2128 : void InputParameters::addParam<std::vector<MultiMooseEnum>>(const std::string & /*name*/,
2129 : const std::string & /*doc_string*/);
2130 :
2131 : template <>
2132 : void
2133 : InputParameters::addRequiredParam<std::vector<MultiMooseEnum>>(const std::string & /*name*/,
2134 : const std::string & /*doc_string*/);
2135 :
2136 : template <>
2137 : void InputParameters::addPrivateParam<MooseEnum>(const std::string & /*name*/);
2138 :
2139 : template <>
2140 : void InputParameters::addPrivateParam<MultiMooseEnum>(const std::string & /*name*/);
2141 :
2142 : template <>
2143 : void InputParameters::addDeprecatedParam<MooseEnum>(const std::string & /*name*/,
2144 : const std::string & /*doc_string*/,
2145 : const std::string & /*deprecation_message*/);
2146 :
2147 : template <>
2148 : void
2149 : InputParameters::addDeprecatedParam<MultiMooseEnum>(const std::string & /*name*/,
2150 : const std::string & /*doc_string*/,
2151 : const std::string & /*deprecation_message*/);
2152 :
2153 : template <>
2154 : void InputParameters::addDeprecatedParam<std::vector<MooseEnum>>(
2155 : const std::string & /*name*/,
2156 : const std::string & /*doc_string*/,
2157 : const std::string & /*deprecation_message*/);
2158 :
2159 : // Forward declare specializations for setParamHelper
2160 : template <>
2161 : void InputParameters::setParamHelper<PostprocessorName, Real>(const std::string & name,
2162 : PostprocessorName & l_value,
2163 : const Real & r_value);
2164 :
2165 : template <>
2166 : void InputParameters::setParamHelper<PostprocessorName, int>(const std::string & name,
2167 : PostprocessorName & l_value,
2168 : const int & r_value);
2169 :
2170 : template <>
2171 : void InputParameters::setParamHelper<FunctionName, Real>(const std::string & /*name*/,
2172 : FunctionName & l_value,
2173 : const Real & r_value);
2174 :
2175 : template <>
2176 : void InputParameters::setParamHelper<FunctionName, int>(const std::string & /*name*/,
2177 : FunctionName & l_value,
2178 : const int & r_value);
2179 :
2180 : template <>
2181 : void InputParameters::setParamHelper<MaterialPropertyName, Real>(const std::string & /*name*/,
2182 : MaterialPropertyName & l_value,
2183 : const Real & r_value);
2184 :
2185 : template <>
2186 : void InputParameters::setParamHelper<MaterialPropertyName, int>(const std::string & /*name*/,
2187 : MaterialPropertyName & l_value,
2188 : const int & r_value);
2189 :
2190 : template <>
2191 : void InputParameters::setParamHelper<MooseFunctorName, Real>(const std::string & /*name*/,
2192 : MooseFunctorName & l_value,
2193 : const Real & r_value);
2194 :
2195 : template <>
2196 : void InputParameters::setParamHelper<MooseFunctorName, int>(const std::string & /*name*/,
2197 : MooseFunctorName & l_value,
2198 : const int & r_value);
2199 :
2200 : template <typename T>
2201 : const T &
2202 44191980 : InputParameters::getParamHelper(const std::string & name_in, const InputParameters & pars)
2203 : {
2204 44191980 : const auto name = pars.checkForRename(name_in);
2205 :
2206 44191980 : if (!pars.isParamValid(name))
2207 2 : pars.mooseError("The parameter \"", name, "\" is being retrieved before being set.");
2208 :
2209 88383956 : return pars.get<T>(name);
2210 44191980 : }
2211 :
2212 : // Declare specializations so we don't fall back on the generic
2213 : // implementation, but the definition will be in InputParameters.C so
2214 : // we won't need to bring in *MooseEnum header files here.
2215 : template <>
2216 : const MooseEnum & InputParameters::getParamHelper<MooseEnum>(const std::string & name,
2217 : const InputParameters & pars);
2218 :
2219 : template <>
2220 : const MultiMooseEnum &
2221 : InputParameters::getParamHelper<MultiMooseEnum>(const std::string & name,
2222 : const InputParameters & pars);
2223 :
2224 : template <typename R1, typename R2, typename V1, typename V2>
2225 : std::vector<std::pair<R1, R2>>
2226 146121 : InputParameters::get(const std::string & param1_in, const std::string & param2_in) const
2227 : {
2228 146121 : const auto param1 = checkForRename(param1_in);
2229 146121 : const auto param2 = checkForRename(param2_in);
2230 :
2231 146121 : const auto & v1 = get<V1>(param1);
2232 146121 : const auto & v2 = get<V2>(param2);
2233 :
2234 146121 : auto controllable = getControllableParameters();
2235 146121 : if (controllable.count(param1) || controllable.count(param2))
2236 2 : mooseError("Parameters ",
2237 : param1,
2238 : " and/or ",
2239 : param2 + " are controllable parameters and cannot be retireved using "
2240 : "the MooseObject::getParam/InputParameters::get methods for pairs");
2241 :
2242 146120 : if (v1.size() != v2.size())
2243 11 : paramError(param1,
2244 : "Vector parameters ",
2245 : param1,
2246 : "(size: ",
2247 : v1.size(),
2248 : ") and " + param2,
2249 : "(size: ",
2250 : v2.size(),
2251 : ") are of different lengths \n");
2252 :
2253 146111 : std::vector<std::pair<R1, R2>> parameter_pairs;
2254 146111 : auto i1 = v1.begin();
2255 146111 : auto i2 = v2.begin();
2256 202878 : for (; i1 != v1.end() && i2 != v2.end(); ++i1, ++i2)
2257 56767 : parameter_pairs.emplace_back(std::make_pair(*i1, *i2));
2258 292222 : return parameter_pairs;
2259 146117 : }
2260 :
2261 : InputParameters emptyInputParameters();
2262 :
2263 : template <typename T>
2264 : bool
2265 88624 : InputParameters::isType(const std::string & name_in) const
2266 : {
2267 88624 : const auto name = checkForRename(name_in);
2268 :
2269 88624 : if (!_params.count(name))
2270 0 : mooseError("Parameter \"", name, "\" is not valid.");
2271 177248 : return have_parameter<T>(name);
2272 88624 : }
2273 :
2274 : template <typename T>
2275 : const T &
2276 209079879 : InputParameters::get(std::string_view name_in) const
2277 : {
2278 209079879 : const auto name = checkForRename(std::string(name_in));
2279 :
2280 418159758 : return Parameters::get<T>(name);
2281 209079879 : }
2282 :
2283 : template <typename T>
2284 : bool
2285 3626145455 : InputParameters::have_parameter(std::string_view name_in) const
2286 : {
2287 3626145455 : const auto name = checkForRename(std::string(name_in));
2288 :
2289 7252290910 : return Parameters::have_parameter<T>(name);
2290 3626145455 : }
2291 :
2292 : template <typename T>
2293 : void
2294 2154879 : InputParameters::transferParam(const InputParameters & source_params,
2295 : const std::string & name_in,
2296 : const std::string & new_name,
2297 : const std::string & new_description)
2298 : {
2299 2154879 : const auto name = source_params.checkForRename(std::string(name_in));
2300 2154879 : const auto p_name = new_name.empty() ? name_in : new_name;
2301 2154879 : if (!source_params.have_parameter<T>(name) && !source_params.hasCoupledValue(name))
2302 0 : mooseError("The '",
2303 : name_in,
2304 : "' parameter could not be transferred because it does not exist with type '",
2305 : MooseUtils::prettyCppType<T>(),
2306 : "' in the source parameters");
2307 2154879 : if (name != name_in)
2308 0 : mooseWarning("The transferred parameter " + name_in + " is deprecated in favor of " + name +
2309 : " in the source parameters. The new name should likely be used for the parameter "
2310 : "transfer instead.");
2311 4309758 : const std::string description =
2312 4309758 : new_description.empty() ? source_params.getDescription(name) : new_description;
2313 :
2314 2154879 : if (source_params.isParamRequired(name))
2315 : {
2316 : // Check for a variable parameter
2317 5 : if (source_params.hasCoupledValue(name))
2318 1 : addRequiredCoupledVar(p_name, description);
2319 : // Enums parameters have a default list of options
2320 : else if constexpr (std::is_same_v<MooseEnum, T> || std::is_same_v<MultiMooseEnum, T>)
2321 2 : addRequiredParam<T>(p_name, source_params.get<T>(name), description);
2322 2 : else if (source_params.isRangeChecked(name))
2323 1 : addRequiredRangeCheckedParam<T>(
2324 : p_name, source_params.rangeCheckedFunction(name), description);
2325 : else
2326 1 : addRequiredParam<T>(p_name, description);
2327 : }
2328 : else
2329 : {
2330 : // Check for a variable parameter
2331 2154874 : if (source_params.hasCoupledValue(name))
2332 : {
2333 3 : if (!source_params.hasDefaultCoupledValue(name))
2334 1 : addCoupledVar(p_name, description);
2335 2 : else if (source_params.numberDefaultCoupledValues(name) == 1)
2336 1 : addCoupledVar(p_name, source_params.defaultCoupledValue(name), description);
2337 : else
2338 : {
2339 1 : std::vector<Real> coupled_values;
2340 3 : for (const auto i : libMesh::make_range(source_params.numberDefaultCoupledValues(name)))
2341 2 : coupled_values.push_back(source_params.defaultCoupledValue(name, i));
2342 1 : addCoupledVar(p_name, coupled_values, description);
2343 1 : }
2344 : }
2345 2154871 : else if (source_params.isRangeChecked(name))
2346 : {
2347 2 : if (source_params.hasDefault(name))
2348 0 : addRangeCheckedParam<T>(p_name,
2349 : source_params.get<T>(name),
2350 : source_params.rangeCheckedFunction(name),
2351 : description);
2352 : else
2353 2 : addRangeCheckedParam<T>(p_name, source_params.rangeCheckedFunction(name), description);
2354 : }
2355 : else if constexpr (std::is_same_v<MooseEnum, T> || std::is_same_v<MultiMooseEnum, T>)
2356 372 : addParam<T>(p_name, source_params.get<T>(name), description);
2357 : else
2358 : {
2359 2154497 : if (source_params.hasDefault(name))
2360 2 : addParam<T>(p_name, source_params.get<T>(name), description);
2361 : else
2362 2154495 : addParam<T>(p_name, description);
2363 : }
2364 : }
2365 :
2366 : // Copy other attributes
2367 2154879 : if (source_params.isPrivate(name))
2368 1 : _params[p_name]._is_private = true;
2369 2154879 : if (source_params.isControllable(name))
2370 1 : _params[p_name]._controllable = true;
2371 2154879 : }
2372 :
2373 : template <typename... Args>
2374 : [[noreturn]] void
2375 72 : InputParameters::mooseError(Args &&... args) const
2376 : {
2377 72 : std::ostringstream oss;
2378 72 : moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
2379 88 : callMooseError(oss.str());
2380 16 : }
2381 :
2382 : template <typename... Args>
2383 : std::string
2384 213 : InputParameters::paramMessage(const std::string & param, Args... args) const
2385 : {
2386 213 : std::ostringstream oss;
2387 213 : moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
2388 426 : return paramMessagePrefix(param) + oss.str();
2389 213 : }
2390 :
2391 : template <typename... Args>
2392 : [[noreturn]] void
2393 1589 : InputParameters::paramError(const std::string & param, Args... args) const
2394 : {
2395 1589 : std::ostringstream oss;
2396 1589 : moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
2397 1589 : const auto [prefix, node] = paramMessageContext(param);
2398 :
2399 1589 : Moose::show_trace = false;
2400 1603 : callMooseError(prefix + oss.str(), false, node);
2401 : Moose::show_trace = true;
2402 14 : }
2403 :
2404 : namespace Moose
2405 : {
2406 : namespace internal
2407 : {
2408 : template <typename T>
2409 : constexpr T *
2410 : getNullptrExample()
2411 : {
2412 : return nullptr;
2413 : }
2414 :
2415 : #ifdef MOOSE_MFEM_ENABLED
2416 :
2417 : template <typename T>
2418 : constexpr bool
2419 : isMFEMFunctorNameTypeHelper(T *)
2420 : {
2421 : return std::is_same_v<T, MFEMScalarCoefficientName> ||
2422 : std::is_same_v<T, MFEMVectorCoefficientName>;
2423 : }
2424 :
2425 : template <typename T, typename A>
2426 : constexpr bool
2427 : isMFEMFunctorNameTypeHelper(std::vector<T, A> *)
2428 : {
2429 : return isMFEMFunctorNameTypeHelper(getNullptrExample<T>());
2430 : }
2431 :
2432 : #endif
2433 :
2434 : template <typename T>
2435 : constexpr bool
2436 : isScalarFunctorNameTypeHelper(T *)
2437 : {
2438 : return std::is_same_v<T, MooseFunctorName>
2439 : #ifdef MOOSE_MFEM_ENABLED
2440 : || std::is_same_v<T, MFEMScalarCoefficientName>
2441 : #endif
2442 : ;
2443 : }
2444 :
2445 : template <typename T, typename A>
2446 : constexpr bool
2447 : isScalarFunctorNameTypeHelper(std::vector<T, A> *)
2448 : {
2449 : return isScalarFunctorNameTypeHelper(getNullptrExample<T>());
2450 : }
2451 :
2452 : template <typename T>
2453 : constexpr bool
2454 : isVectorFunctorNameTypeHelper(T *)
2455 : {
2456 : #ifdef MOOSE_MFEM_ENABLED
2457 : return std::is_same_v<T, MFEMVectorCoefficientName>;
2458 : #else
2459 : return false;
2460 : #endif
2461 : }
2462 :
2463 : template <typename T, typename A>
2464 : constexpr bool
2465 : isVectorFunctorNameTypeHelper(std::vector<T, A> *)
2466 : {
2467 : return isVectorFunctorNameTypeHelper(getNullptrExample<T>());
2468 : }
2469 :
2470 : template <typename T>
2471 : constexpr bool
2472 : isFunctorNameTypeHelper(T * ex)
2473 : {
2474 : return isScalarFunctorNameTypeHelper(ex) || isVectorFunctorNameTypeHelper(ex);
2475 : }
2476 : }
2477 : }
2478 :
2479 : template <typename T>
2480 : constexpr bool
2481 : InputParameters::isFunctorNameType()
2482 : {
2483 : return Moose::internal::isFunctorNameTypeHelper(Moose::internal::getNullptrExample<T>());
2484 : }
2485 :
2486 : template <typename T>
2487 : std::string
2488 3136633 : InputParameters::appendFunctorDescription(const std::string & doc_string) const
2489 : {
2490 3136633 : auto numeric_value_type = []()
2491 : {
2492 : if constexpr (Moose::internal::isScalarFunctorNameTypeHelper(
2493 : Moose::internal::getNullptrExample<T>()))
2494 3041356 : return "number";
2495 : else if constexpr (Moose::internal::isVectorFunctorNameTypeHelper(
2496 : Moose::internal::getNullptrExample<T>()))
2497 95277 : return "numeric vector value (enclosed in curly braces)";
2498 : else
2499 : {
2500 : mooseAssert(false, "We control instantiations of this method");
2501 : return "";
2502 : }
2503 : };
2504 :
2505 : return MooseUtils::trim(doc_string, ". ") + ". A functor is any of the following: a variable, " +
2506 : (
2507 : #ifdef MOOSE_MFEM_ENABLED
2508 : Moose::internal::isMFEMFunctorNameTypeHelper(Moose::internal::getNullptrExample<T>())
2509 : ? "an MFEM"
2510 : :
2511 : #endif
2512 : "a functor") +
2513 9409899 : " material property, a function, a postprocessor or a " + numeric_value_type() + ".";
2514 : }
|