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