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