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