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 : #include "MooseBaseErrorInterface.h"
13 :
14 : #include "MooseBase.h"
15 : #include "InputParameters.h"
16 : #include "MooseUtils.h"
17 : #include "MooseObjectParameterName.h"
18 :
19 : #include <string>
20 :
21 : #define usingMooseBaseParameterInterfaceMembers \
22 : using MooseBaseParameterInterface::parameters; \
23 : using MooseBaseParameterInterface::uniqueName; \
24 : using MooseBaseParameterInterface::isParamValid; \
25 : using MooseBaseParameterInterface::isParamSetByUser; \
26 : using MooseBaseParameterInterface::paramError; \
27 : using MooseBaseParameterInterface::_pars; \
28 : using MooseBaseParameterInterface::_factory; \
29 : using MooseBaseParameterInterface::_action_factory
30 :
31 : /**
32 : * Get canonical paramError prefix for param-related error/warning/info messages.
33 : *
34 : * Use this for building custom messages when the default paramError isn't
35 : * quite what you need.
36 : */
37 : std::string paramErrorPrefix(const InputParameters & params, const std::string & param);
38 :
39 : /**
40 : * Every object that can be built by the factory should be derived from this class.
41 : */
42 : class MooseBaseParameterInterface
43 : {
44 : public:
45 : MooseBaseParameterInterface(const MooseBase & base, const InputParameters & parameters);
46 :
47 4868950 : virtual ~MooseBaseParameterInterface() = default;
48 :
49 : /**
50 : * The unique parameter name of a valid parameter of this object for accessing parameter controls
51 : */
52 : MooseObjectParameterName uniqueParameterName(const std::string & parameter_name) const
53 : {
54 : return MooseObjectParameterName(
55 : _pars.get<std::string>("_moose_base"), _moose_base.name(), parameter_name);
56 : }
57 :
58 : /**
59 : * Get the parameters of the object
60 : * @return The parameters of the object
61 : */
62 35277174 : const InputParameters & parameters() const { return _pars; }
63 :
64 : /**
65 : * The unique name for accessing input parameters of this object in the InputParameterWarehouse
66 : */
67 2430841 : MooseObjectName uniqueName() const
68 : {
69 2430841 : return MooseObjectName(_pars.get<std::string>("_unique_name"));
70 : }
71 :
72 : /**
73 : * Retrieve a parameter for the object
74 : * @param name The name of the parameter
75 : * @return The value of the parameter
76 : */
77 : template <typename T>
78 : const T & getParam(const std::string & name) const;
79 :
80 : /**
81 : * Query a parameter for the object
82 : *
83 : * If the parameter is not valid, nullptr will be returned
84 : *
85 : * @param name The name of the parameter
86 : * @return A pointer to the parameter value, if it exists
87 : */
88 : template <typename T>
89 : const T * queryParam(const std::string & name) const;
90 :
91 : /**
92 : * Retrieve a renamed parameter for the object. This helper makes sure we
93 : * check both names before erroring, and that only one parameter is passed to avoid
94 : * silent errors
95 : * @param old_name the old name for the parameter
96 : * @param new_name the new name for the parameter
97 : */
98 : template <typename T>
99 : const T & getRenamedParam(const std::string & old_name, const std::string & new_name) const;
100 :
101 : /**
102 : * Retrieve two parameters and provide pair of parameters for the object
103 : * @param param1 The name of first parameter
104 : * @param param2 The name of second parameter
105 : * @return Vector of pairs of first and second parameters
106 : */
107 : template <typename T1, typename T2>
108 : std::vector<std::pair<T1, T2>> getParam(const std::string & param1,
109 : const std::string & param2) const;
110 :
111 : /**
112 : * Verifies that the requested parameter exists and is not NULL and returns it to the caller.
113 : * The template parameter must be a pointer or an error will be thrown.
114 : */
115 : template <typename T>
116 : T getCheckedPointerParam(const std::string & name, const std::string & error_string = "") const;
117 :
118 : /**
119 : * Test if the supplied parameter is valid
120 : * @param name The name of the parameter to test
121 : */
122 16781960 : inline bool isParamValid(const std::string & name) const { return _pars.isParamValid(name); }
123 :
124 : /**
125 : * Test if the supplied parameter is set by a user, as opposed to not set or set to default
126 : * @param nm The name of the parameter to test
127 : */
128 1931574 : inline bool isParamSetByUser(const std::string & nm) const { return _pars.isParamSetByUser(nm); }
129 :
130 : /**
131 : * Emits an error prefixed with the file and line number of the given param (from the input
132 : * file) along with the full parameter path+name followed by the given args as the message.
133 : * If this object's parameters were not created directly by the Parser, then this function falls
134 : * back to the normal behavior of mooseError - only printing a message using the given args.
135 : */
136 : template <typename... Args>
137 : [[noreturn]] void paramError(const std::string & param, Args... args) const;
138 :
139 : /**
140 : * Emits a warning prefixed with the file and line number of the given param (from the input
141 : * file) along with the full parameter path+name followed by the given args as the message.
142 : * If this object's parameters were not created directly by the Parser, then this function falls
143 : * back to the normal behavior of mooseWarning - only printing a message using the given args.
144 : */
145 : template <typename... Args>
146 : void paramWarning(const std::string & param, Args... args) const;
147 :
148 : /**
149 : * Emits an informational message prefixed with the file and line number of the given param
150 : * (from the input file) along with the full parameter path+name followed by the given args as
151 : * the message. If this object's parameters were not created directly by the Parser, then this
152 : * function falls back to the normal behavior of mooseInfo - only printing a message using
153 : * the given args.
154 : */
155 : template <typename... Args>
156 : void paramInfo(const std::string & param, Args... args) const;
157 :
158 : /**
159 : * Connect controllable parameter of this action with the controllable parameters of the
160 : * objects added by this action.
161 : * @param parameter Name of the controllable parameter of this action
162 : * @param object_type Type of the object added by this action.
163 : * @param object_name Name of the object added by this action.
164 : * @param object_parameter Name of the parameter of the object.
165 : */
166 : void connectControllableParams(const std::string & parameter,
167 : const std::string & object_type,
168 : const std::string & object_name,
169 : const std::string & object_parameter) const;
170 :
171 : protected:
172 : /// Parameters of this object, references the InputParameters stored in the InputParametersWarehouse
173 : const InputParameters & _pars;
174 :
175 : /// The Factory associated with the MooseApp
176 : Factory & _factory;
177 :
178 : /// Builds Actions
179 : ActionFactory & _action_factory;
180 :
181 : private:
182 : /// The MooseBase object that inherits this class
183 : const MooseBase & _moose_base;
184 :
185 : template <typename... Args>
186 1614 : std::string paramErrorMsg(const std::string & param, Args... args) const
187 : {
188 1614 : auto param_prefix = paramErrorPrefix(_pars, param);
189 :
190 : // With no input location information, append object info (name + type)
191 1614 : const std::string object_prefix =
192 3228 : _pars.inputLocation(param).empty() ? _moose_base.errorPrefix("parameter error") : "";
193 :
194 1614 : std::ostringstream oss;
195 1614 : moose::internal::mooseStreamAll(oss, std::forward<Args>(args)...);
196 1614 : std::string msg = oss.str();
197 :
198 : // Wrap error message to a separate line from param_prefix if it is about to
199 : // blow past 100 chars. But only wrap if the param_prefix is long enough (12
200 : // chars) for the wrap to buy us much extra length. We don't check object_prefix
201 : // here because it will go before the parameter error
202 1823 : if ((param_prefix.size() > 12 && msg.size() + param_prefix.size() > 99) ||
203 209 : msg.find("\n") != std::string::npos)
204 : {
205 1409 : if (param_prefix.size() > 0 && param_prefix[param_prefix.size() - 1] != ':')
206 1358 : param_prefix += ":";
207 1409 : return object_prefix + param_prefix + "\n " + MooseUtils::replaceAll(msg, "\n", "\n ");
208 : }
209 205 : return object_prefix + param_prefix + " " + msg;
210 1614 : }
211 : };
212 :
213 : template <typename T>
214 : const T &
215 39644802 : MooseBaseParameterInterface::getParam(const std::string & name) const
216 : {
217 39644802 : return InputParameters::getParamHelper(name, _pars, static_cast<T *>(0), &_moose_base);
218 : }
219 :
220 : template <typename T>
221 : const T *
222 2104 : MooseBaseParameterInterface::queryParam(const std::string & name) const
223 : {
224 2104 : return isParamValid(name) ? &getParam<T>(name) : nullptr;
225 : }
226 :
227 : template <typename T>
228 : const T &
229 47056 : MooseBaseParameterInterface::getRenamedParam(const std::string & old_name,
230 : const std::string & new_name) const
231 : {
232 : // this enables having a default on the new parameter but bypassing it with the old one
233 : // Most important: accept new parameter
234 47056 : if (isParamSetByUser(new_name) && !isParamValid(old_name))
235 45602 : return InputParameters::getParamHelper(new_name, _pars, static_cast<T *>(0), &_moose_base);
236 : // Second most: accept old parameter
237 1454 : else if (isParamValid(old_name) && !isParamSetByUser(new_name))
238 977 : return InputParameters::getParamHelper(old_name, _pars, static_cast<T *>(0), &_moose_base);
239 : // Third most: accept default for new parameter
240 477 : else if (isParamValid(new_name) && !isParamValid(old_name))
241 477 : return InputParameters::getParamHelper(new_name, _pars, static_cast<T *>(0), &_moose_base);
242 : // Refuse: no default, no value passed
243 0 : else if (!isParamValid(old_name) && !isParamValid(new_name))
244 0 : mooseError(_pars.blockFullpath() + ": parameter '" + new_name +
245 : "' is being retrieved without being set.\n"
246 : "Did you misspell it?");
247 : // Refuse: both old and new parameters set by user
248 : else
249 0 : mooseError(_pars.blockFullpath() + ": parameter '" + new_name +
250 : "' may not be provided alongside former parameter '" + old_name + "'");
251 : }
252 :
253 : template <typename... Args>
254 : [[noreturn]] void
255 1451 : MooseBaseParameterInterface::paramError(const std::string & param, Args... args) const
256 : {
257 1451 : Moose::show_trace = false;
258 1453 : _moose_base.callMooseError(paramErrorMsg(param, std::forward<Args>(args)...),
259 : /* with_prefix = */ false);
260 : Moose::show_trace = true;
261 : }
262 :
263 : template <typename... Args>
264 : void
265 76 : MooseBaseParameterInterface::paramWarning(const std::string & param, Args... args) const
266 : {
267 76 : mooseWarning(paramErrorMsg(param, std::forward<Args>(args)...));
268 60 : }
269 :
270 : template <typename... Args>
271 : void
272 87 : MooseBaseParameterInterface::paramInfo(const std::string & param, Args... args) const
273 : {
274 87 : mooseInfo(paramErrorMsg(param, std::forward<Args>(args)...));
275 87 : }
276 :
277 : template <typename T1, typename T2>
278 : std::vector<std::pair<T1, T2>>
279 62691 : MooseBaseParameterInterface::getParam(const std::string & param1, const std::string & param2) const
280 : {
281 62691 : return _pars.get<T1, T2>(param1, param2);
282 : }
283 :
284 : template <typename T>
285 : T
286 5275392 : MooseBaseParameterInterface::getCheckedPointerParam(const std::string & name,
287 : const std::string & error_string) const
288 : {
289 5275392 : return parameters().getCheckedPointerParam<T>(name, error_string);
290 : }
|