https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ParameterRegistration.C
Go to the documentation of this file.
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
11
12#include "ParameterRegistry.h"
13#include "MooseTypes.h"
14#include "ReporterName.h"
15#include "MooseEnum.h"
16#include "MultiMooseEnum.h"
17#include "ExecFlagEnum.h"
18
20{
21
22template <>
23void
24setScalarValue(bool & value, const hit::Field & field)
25{
26 // Handles non-quoted values
27 try
28 {
29 value = field.boolVal();
30 }
31 // Handles quoted values
32 catch (hit::Error &)
33 {
34 const auto strval = field.param<std::string>();
35 if (strval == "1")
36 value = true;
37 else if (strval == "0")
38 value = false;
39 else if (!hit::toBool(strval, &value))
40 throw std::invalid_argument("invalid boolean syntax for parameter: " + field.path() + "='" +
41 strval + "'");
42 }
43}
44
45/*******************************************************************************/
46/* This contains the initialization time registration of all of the base */
47/* parameter types that are registered for use in the Builder for MOOSE. */
48/*******************************************************************************/
49
50namespace detail
51{
52
54
55/*******************************************************************************/
56/* Derivative string registration */
57/* */
58/* Registers for scalars, vectors, double vectors, and triple vectors */
59/* */
60/* See MooseDerivativeStringClass macro usage in MooseTypes.h */
61/* Please keep the ordering consistent */
62/*******************************************************************************/
63
64// Special cases that aren't included: CLIArgString
66registerParameter(FileNameNoExtension);
67registerParameter(RelativeFileName);
68registerParameter(DataFileName);
69registerParameter(MeshFileName);
70registerParameter(MatrixFileName);
71registerParameter(OutFileBase);
72registerParameter(NonlinearVariableName);
73registerParameter(LinearVariableName);
74registerParameter(SolverVariableName);
75registerParameter(AuxVariableName);
76registerParameter(VariableName);
77registerParameter(BoundaryName);
78registerParameter(SubdomainName);
79registerParameter(PostprocessorName);
80registerParameter(VectorPostprocessorName);
81registerParameter(MeshDivisionName);
82registerParameter(FunctionName);
83registerParameter(DistributionName);
84registerParameter(SamplerName);
85registerParameter(UserObjectName);
86registerParameter(InterpolationMethodName);
87registerParameter(IndicatorName);
89registerParameter(MultiAppName);
91registerParameter(MaterialPropertyName);
92registerParameter(MooseFunctorName);
93registerParameter(MaterialName);
95registerParameter(MeshGeneratorName);
96registerParameter(ExtraElementIDName);
97registerParameter(ReporterValueName);
98registerParameter(ComponentName);
99registerParameter(PhysicsName);
100registerParameter(PositionsName);
102registerParameter(ExecutorName);
103registerParameter(ParsedFunctionExpression);
104registerParameter(NonlinearSystemName);
105registerParameter(ConvergenceName);
106registerParameter(LinearSystemName);
107registerParameter(SolverSystemName);
108#ifdef MOOSE_MFEM_ENABLED
109registerParameter(MFEMScalarCoefficientName);
110registerParameter(MFEMVectorCoefficientName);
111registerParameter(MFEMMatrixCoefficientName);
112registerParameter(MFEMFESpaceName);
113registerParameter(MFEMSolverName);
114#endif
115
116/*******************************************************************************/
117/* Native type registration */
118/* */
119/* Registers for scalars, vectors, double vectors, and triple vectors */
120/*******************************************************************************/
121
123registerParameter(std::string);
127registerParameter(unsigned short);
128registerParameter(unsigned int);
129registerParameter(unsigned long);
130registerParameter(unsigned long long);
131
132/*******************************************************************************/
133/* Bool registration */
134/*******************************************************************************/
135
138
139/*******************************************************************************/
140/* Helpers used across types */
141/*******************************************************************************/
142
145const auto convert_reporter_name = [](const std::string & val,
146 const hit::Field & field) -> ReporterName
147{
148 const auto names = MooseUtils::rsplit(val, "/", 2);
149 if (names.size() != 2)
150 throw std::invalid_argument("invalid syntax in ReporterName parameter " + field.fullpath() +
151 ": supplied name '" + val + "' must contain the '/' delimiter");
152 return {names[0], names[1]};
153};
154
155/*******************************************************************************/
156/* Component-typed scalar registration */
157/*******************************************************************************/
158
160const auto set_scalar_component_value = [](auto & value, const hit::Field & field)
161{
162 const auto vec = field.param<std::vector<double>>();
163 if (vec.size() != LIBMESH_DIM)
164 throw std::invalid_argument("wrong number of values in " + MooseUtils::prettyCppType(&value) +
165 " parameter '" + field.fullpath() + "': was given " +
166 std::to_string(vec.size()) + " component(s) but should have " +
167 std::to_string(LIBMESH_DIM));
168
169 for (const auto d : make_range(Moose::dim))
170 value(d) = Real(vec[d]);
171};
172
173// Point
174static auto point = registry.add<Point>([](Point & value, const hit::Field & field)
175 { set_scalar_component_value(value, field); });
176// RealVectorValue
177static auto realvectorvalue =
178 registry.add<RealVectorValue>([](RealVectorValue & value, const hit::Field & field)
179 { set_scalar_component_value(value, field); });
180
181/*******************************************************************************/
182/* Custom scalar registration */
183/*******************************************************************************/
184
185// We only support CLIArgString and std::vector<CLIArgString>, so this isn't
186// added in the main MooseDerivativeString case
188// RealEigenVector
189static auto realeigenvector = registry.add<RealEigenVector>(
190 [](RealEigenVector & value, const hit::Field & field)
191 {
192 const auto vec = field.param<std::vector<double>>();
193 value.resize(vec.size());
194 for (const auto i : index_range(vec))
195 value(i) = Real(vec[i]);
196 });
197// RealEigenVector
198static auto realeigenmatrix = registry.add<RealEigenMatrix>(
199 [](RealEigenMatrix & value, const hit::Field & field)
200 {
201 value.resize(0, 0);
202 std::vector<std::string> tokens;
203 MooseUtils::tokenize(field.param<std::string>(), tokens, 1, ";");
204
205 for (const auto i : index_range(tokens))
206 {
207 const auto token = MooseUtils::trim(tokens[i]);
208 std::vector<Real> values;
209 if (!MooseUtils::tokenizeAndConvert<Real>(token, values))
210 throw std::invalid_argument("invalid syntax for parameter: " + field.fullpath() + "[" +
211 std::to_string(i) + "]='" + token + "'");
212 if (i == 0)
213 value.resize(tokens.size(), values.size());
214 else if (libMesh::cast_int<std::size_t>(value.cols()) != values.size())
215 throw std::invalid_argument("matrix is not square for parameter " + field.fullpath());
216 for (const auto j : index_range(values))
217 value(i, j) = values[j];
218 }
219 });
220// MooseEnum
221static auto mooseenum = registry.add<MooseEnum>([](MooseEnum & value, const hit::Field & field)
222 { value = field.param<std::string>(); });
223// MultiMooseEnum
225 [](MultiMooseEnum & value, const hit::Field & field)
226 { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
227// ExecFlagEnum
229 [](ExecFlagEnum & value, const hit::Field & field)
230 { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
231// RealTensorValue
232static auto realtensorvalue = registry.add<RealTensorValue>(
233 [](RealTensorValue & value, const hit::Field & field)
234 {
235 const auto vec = field.param<std::vector<double>>();
236 if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
237 throw std::invalid_argument("invalid RealTensorValue parameter '" + field.fullpath() +
238 "': size is " + std::to_string(vec.size()) + " but should be " +
239 std::to_string(LIBMESH_DIM * LIBMESH_DIM));
240
241 for (const auto i : make_range(Moose::dim))
242 for (const auto j : make_range(Moose::dim))
243 value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
244 });
245// ReporterName
247 [](ReporterName & value, const hit::Field & field)
248 { value = convert_reporter_name(field.param<std::string>(), field); });
249
250/*******************************************************************************/
251/* Component-typed vector registration */
252/*******************************************************************************/
253
255const auto set_vector_component_value = [](auto & value, const hit::Field & field)
256{
257 value.clear();
258 const auto vec = field.param<std::vector<double>>();
259
260 if (vec.size() % LIBMESH_DIM)
261 throw std::invalid_argument("wrong number of values in vector parameter '" + field.fullpath() +
262 "': size " + std::to_string(vec.size()) + " is not a multiple of " +
263 std::to_string(LIBMESH_DIM));
264
265 const std::size_t size = vec.size() / LIBMESH_DIM;
266 value.resize(size);
267 for (const auto i : make_range(size))
268 for (const auto d : make_range(Moose::dim))
269 value[i](d) = vec[i * LIBMESH_DIM + d];
270};
271
272// std::vector<Point>
273static auto vector_point =
274 registry.add<std::vector<Point>>([](std::vector<Point> & value, const hit::Field & field)
275 { set_vector_component_value(value, field); });
276// std::vector<RealVectorValue>
277static auto vector_realvectorvalue = registry.add<std::vector<RealVectorValue>>(
278 [](std::vector<RealVectorValue> & value, const hit::Field & field)
279 { set_vector_component_value(value, field); });
280
281/*******************************************************************************/
282/* Custom vector registration */
283/*******************************************************************************/
284
285// std::vector<MooseEnum>
286static auto vector_mooseenum = registry.add<std::vector<MooseEnum>>(
287 [](std::vector<MooseEnum> & value, const hit::Field & field)
288 {
289 mooseAssert(!value.empty(), "Missing a value to initialize on");
290
291 // With MOOSE enums we need a default object so it should have been
292 // passed in the param pointer. We are only going to use the first
293 // item in the vector (value[0]) and ignore the rest.
294 const auto vec = field.param<std::vector<std::string>>();
295 value.resize(vec.size(), value[0]);
296 for (const auto i : index_range(vec))
297 value[i] = vec[i];
298 });
299// std::vector<MooseEnum>
300static auto vector_multimooseenum = registry.add<std::vector<MultiMooseEnum>>(
301 [](std::vector<MultiMooseEnum> & value, const hit::Field & field)
302 {
303 mooseAssert(!value.empty(), "Missing a value to initialize on");
304
305 const auto tokens = MooseUtils::split(field.param<std::string>(), ";");
306 for (const auto i : index_range(tokens))
307 {
308 const auto & entry = tokens[i];
309 if (MooseUtils::trim(entry) == "")
310 throw std::invalid_argument("entry " + std::to_string(i) + " in '" + field.fullpath() +
311 "' is empty");
312 }
313 value.resize(tokens.size(), value[0]);
314 for (const auto i : index_range(tokens))
315 {
316 std::vector<std::string> strvals;
317 MooseUtils::tokenize<std::string>(tokens[i], strvals, 1, " ");
318 value[i] = strvals;
319 }
320 });
321// std::vector<ReporterName>
322static auto vector_reportername = registry.add<std::vector<ReporterName>>(
323 [](std::vector<ReporterName> & value, const hit::Field & field)
324 {
325 value.clear();
326 const auto names = field.param<std::vector<std::string>>();
327 value.resize(names.size());
328 for (const auto i : index_range(names))
329 value[i] = convert_reporter_name(names[i], field);
330 });
331// std::vector<CLIArgString>
332static auto vector_cliargstring = registry.add<std::vector<CLIArgString>>(
333 [](std::vector<CLIArgString> & value, const hit::Field & field)
334 {
335 value.clear();
336 const auto strvals = field.param<std::vector<std::string>>();
337 if (strvals.empty())
338 return;
339
340 // slightly oversized if vectors have been split
341 value.resize(strvals.size());
342
343 // Re-assemble vector parameters
344 unsigned int i_param = 0;
345 bool vector_param_detected = false;
346 for (const auto i : index_range(strvals))
347 {
348 // Look for a quote, both types
349 const auto double_split =
350 MooseUtils::rsplit(strvals[i], "\"", std::numeric_limits<std::size_t>::max());
351 const auto single_split =
352 MooseUtils::rsplit(strvals[i], "\'", std::numeric_limits<std::size_t>::max());
353 if (double_split.size() + single_split.size() >= 3)
354 // Either entering or exiting a vector parameter (>3 is entering another vector)
355 // Even and >2 number of quotes means both finished and started another vector parameter
356 if ((double_split.size() + single_split.size()) % 2 == 1)
357 vector_param_detected = !vector_param_detected;
358
359 // We're building a vector parameters, just append the text, rebuild the spaces
360 if (vector_param_detected)
361 value[i_param] += strvals[i] + ' ';
362 else
363 {
364 value[i_param] += strvals[i];
365 i_param++;
366 }
367 }
368 // Use actual size after re-forming vector parameters
369 value.resize(i_param);
370 });
371
372/*******************************************************************************/
373/* Component-typed double vector registration */
374/*******************************************************************************/
375
377const auto set_double_vector_component_value = [](auto & value, const hit::Field & field)
378{
379 const auto strval = field.param<std::string>();
380
381 // Split vector at delim ";" (substrings are not of type T yet)
382 std::vector<std::string> tokens;
383 MooseUtils::tokenize(strval, tokens, 1, ";");
384 value.resize(tokens.size());
385
386 // Split each token at spaces
387 std::vector<std::vector<double>> vecvec(tokens.size());
388 for (const auto i : index_range(tokens))
389 if (!MooseUtils::tokenizeAndConvert<double>(tokens[i], vecvec[i]))
390 throw std::invalid_argument("invalid format for parameter '" + field.fullpath() +
391 "' at index " + std::to_string(i));
392
393 for (const auto i : index_range(vecvec))
394 {
395 const auto & vec = vecvec[i];
396 if (vec.size() % LIBMESH_DIM)
397 throw std::invalid_argument(
398 "wrong number of values in double-indexed vector component parameter '" +
399 field.fullpath() + "' at index " + std::to_string(i) + ": subcomponent size " +
400 std::to_string(vec.size()) + " is not a multiple of " + std::to_string(LIBMESH_DIM));
401 }
402
403 // convert vector<vector<double>> to vector<vector<T>>
404 value.resize(vecvec.size());
405 for (const auto i : index_range(vecvec))
406 {
407 const auto & vec_entry = vecvec[i];
408 auto & value_entry = value[i];
409 const std::size_t size = vec_entry.size() / LIBMESH_DIM;
410 value_entry.resize(size);
411 for (const auto j : make_range(size))
412 for (const auto d : make_range(Moose::dim))
413 value_entry[j](d) = vec_entry[j * LIBMESH_DIM + d];
414 }
415};
416
417// std::vector<std::vector<Point>>
418static auto doublevector_point = registry.add<std::vector<std::vector<Point>>>(
419 [](std::vector<std::vector<Point>> & value, const hit::Field & field)
420 { set_double_vector_component_value(value, field); });
421// std::vector<std::vector<RealVectorValue>>
422static auto doublevector_realvectorvalue = registry.add<std::vector<std::vector<RealVectorValue>>>(
423 [](std::vector<std::vector<RealVectorValue>> & value, const hit::Field & field)
424 { set_double_vector_component_value(value, field); });
425
426/*******************************************************************************/
427/* Map registration */
428/*******************************************************************************/
429
430registerMapParameter(std::string, unsigned int);
431registerMapParameter(std::string, Real);
432registerMapParameter(std::string, std::string);
433registerMapParameter(unsigned int, unsigned int);
434registerMapParameter(unsigned long, unsigned int);
435registerMapParameter(unsigned long long, unsigned int);
436
437} // end of namespace detail
438} // end of namespace Moose::ParameterRegistration
std::array< Real, 2 > values
Definition MortarUtils.C:52
A MultiMooseEnum object to hold "execute_on" flags.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
Registry that allows for the typeless setting of a parameter value from a hit field.
char add(F &&f)
Add a parameter.
static ParameterRegistry & get()
Get the singleton registry.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type.
The Reporter system is comprised of objects that can contain any number of data values.
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count)
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
std::string trim(const std::string &str, const std::string &white_space=" \t\n\v\f\r")
Standard scripting language trim function.
std::string prettyCppType(const std::string &cpp_type)
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
std::vector< std::string > rsplit(const std::string &str, const std::string &delimiter, std::size_t max_count)
const auto convert_reporter_name
Helper for converting a string to a ReporterName, which requires splitting the string at the '/' deli...
const auto set_vector_component_value
Helper for setting a vector component value (one with 3 real values)
static Moose::ParameterRegistry & registry
registerMapParameter(std::string, unsigned int)
const auto set_scalar_component_value
Helper for setting a scalar component value (one with 3 real values)
const auto set_double_vector_component_value
Helper for setting a double vector component value (one with 3 real values)
void setScalarValue(T &value, const hit::Field &field)
Converts the given field node into a scalar of the given type.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition Moose.h:165