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(GradientMethodName);
88registerParameter(IndicatorName);
90registerParameter(MultiAppName);
92registerParameter(MaterialPropertyName);
93registerParameter(MooseFunctorName);
94registerParameter(MaterialName);
96registerParameter(MeshGeneratorName);
97registerParameter(ExtraElementIDName);
98registerParameter(ReporterValueName);
99registerParameter(ComponentName);
100registerParameter(PhysicsName);
101registerParameter(PositionsName);
103registerParameter(ExecutorName);
104registerParameter(ParsedFunctionExpression);
105registerParameter(NonlinearSystemName);
106registerParameter(ConvergenceName);
107registerParameter(LinearSystemName);
108registerParameter(SolverSystemName);
109#ifdef MOOSE_MFEM_ENABLED
110registerParameter(MFEMScalarCoefficientName);
111registerParameter(MFEMVectorCoefficientName);
112registerParameter(MFEMMatrixCoefficientName);
113registerParameter(MFEMFESpaceName);
114registerParameter(MFEMSolverName);
115registerParameter(MFEMKernelName);
116registerParameter(MFEMBoundaryConditionName);
117registerParameter(MFEMWeakFormName);
118#endif
119
120/*******************************************************************************/
121/* Native type registration */
122/* */
123/* Registers for scalars, vectors, double vectors, and triple vectors */
124/*******************************************************************************/
125
127registerParameter(std::string);
131registerParameter(unsigned short);
132registerParameter(unsigned int);
133registerParameter(unsigned long);
134registerParameter(unsigned long long);
135
136/*******************************************************************************/
137/* Bool registration */
138/*******************************************************************************/
139
142
143/*******************************************************************************/
144/* Helpers used across types */
145/*******************************************************************************/
146
149const auto convert_reporter_name = [](const std::string & val,
150 const hit::Field & field) -> ReporterName
151{
152 const auto names = MooseUtils::rsplit(val, "/", 2);
153 if (names.size() != 2)
154 throw std::invalid_argument("invalid syntax in ReporterName parameter " + field.fullpath() +
155 ": supplied name '" + val + "' must contain the '/' delimiter");
156 return {names[0], names[1]};
157};
158
159/*******************************************************************************/
160/* Component-typed scalar registration */
161/*******************************************************************************/
162
164const auto set_scalar_component_value = [](auto & value, const hit::Field & field)
165{
166 const auto vec = field.param<std::vector<double>>();
167 if (vec.size() != LIBMESH_DIM)
168 throw std::invalid_argument("wrong number of values in " + MooseUtils::prettyCppType(&value) +
169 " parameter '" + field.fullpath() + "': was given " +
170 std::to_string(vec.size()) + " component(s) but should have " +
171 std::to_string(LIBMESH_DIM));
172
173 for (const auto d : make_range(Moose::dim))
174 value(d) = Real(vec[d]);
175};
176
177// Point
178static auto point = registry.add<Point>([](Point & value, const hit::Field & field)
179 { set_scalar_component_value(value, field); });
180// RealVectorValue
181static auto realvectorvalue =
182 registry.add<RealVectorValue>([](RealVectorValue & value, const hit::Field & field)
183 { set_scalar_component_value(value, field); });
184
185/*******************************************************************************/
186/* Custom scalar registration */
187/*******************************************************************************/
188
189// We only support CLIArgString and std::vector<CLIArgString>, so this isn't
190// added in the main MooseDerivativeString case
192// RealEigenVector
193static auto realeigenvector = registry.add<RealEigenVector>(
194 [](RealEigenVector & value, const hit::Field & field)
195 {
196 const auto vec = field.param<std::vector<double>>();
197 value.resize(vec.size());
198 for (const auto i : index_range(vec))
199 value(i) = Real(vec[i]);
200 });
201// RealEigenVector
202static auto realeigenmatrix = registry.add<RealEigenMatrix>(
203 [](RealEigenMatrix & value, const hit::Field & field)
204 {
205 value.resize(0, 0);
206 std::vector<std::string> tokens;
207 MooseUtils::tokenize(field.param<std::string>(), tokens, 1, ";");
208
209 for (const auto i : index_range(tokens))
210 {
211 const auto token = MooseUtils::trim(tokens[i]);
212 std::vector<Real> values;
213 if (!MooseUtils::tokenizeAndConvert<Real>(token, values))
214 throw std::invalid_argument("invalid syntax for parameter: " + field.fullpath() + "[" +
215 std::to_string(i) + "]='" + token + "'");
216 if (i == 0)
217 value.resize(tokens.size(), values.size());
218 else if (libMesh::cast_int<std::size_t>(value.cols()) != values.size())
219 throw std::invalid_argument("matrix is not square for parameter " + field.fullpath());
220 for (const auto j : index_range(values))
221 value(i, j) = values[j];
222 }
223 });
224// MooseEnum
225static auto mooseenum = registry.add<MooseEnum>([](MooseEnum & value, const hit::Field & field)
226 { value = field.param<std::string>(); });
227// MultiMooseEnum
229 [](MultiMooseEnum & value, const hit::Field & field)
230 { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
231// ExecFlagEnum
233 [](ExecFlagEnum & value, const hit::Field & field)
234 { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
235// RealTensorValue
236static auto realtensorvalue = registry.add<RealTensorValue>(
237 [](RealTensorValue & value, const hit::Field & field)
238 {
239 const auto vec = field.param<std::vector<double>>();
240 if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
241 throw std::invalid_argument("invalid RealTensorValue parameter '" + field.fullpath() +
242 "': size is " + std::to_string(vec.size()) + " but should be " +
243 std::to_string(LIBMESH_DIM * LIBMESH_DIM));
244
245 for (const auto i : make_range(Moose::dim))
246 for (const auto j : make_range(Moose::dim))
247 value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
248 });
249// ReporterName
251 [](ReporterName & value, const hit::Field & field)
252 { value = convert_reporter_name(field.param<std::string>(), field); });
253
254/*******************************************************************************/
255/* Component-typed vector registration */
256/*******************************************************************************/
257
259const auto set_vector_component_value = [](auto & value, const hit::Field & field)
260{
261 value.clear();
262 const auto vec = field.param<std::vector<double>>();
263
264 if (vec.size() % LIBMESH_DIM)
265 throw std::invalid_argument("wrong number of values in vector parameter '" + field.fullpath() +
266 "': size " + std::to_string(vec.size()) + " is not a multiple of " +
267 std::to_string(LIBMESH_DIM));
268
269 const std::size_t size = vec.size() / LIBMESH_DIM;
270 value.resize(size);
271 for (const auto i : make_range(size))
272 for (const auto d : make_range(Moose::dim))
273 value[i](d) = vec[i * LIBMESH_DIM + d];
274};
275
276// std::vector<Point>
277static auto vector_point =
278 registry.add<std::vector<Point>>([](std::vector<Point> & value, const hit::Field & field)
279 { set_vector_component_value(value, field); });
280// std::vector<RealVectorValue>
281static auto vector_realvectorvalue = registry.add<std::vector<RealVectorValue>>(
282 [](std::vector<RealVectorValue> & value, const hit::Field & field)
283 { set_vector_component_value(value, field); });
284
285/*******************************************************************************/
286/* Custom vector registration */
287/*******************************************************************************/
288
289// std::vector<MooseEnum>
290static auto vector_mooseenum = registry.add<std::vector<MooseEnum>>(
291 [](std::vector<MooseEnum> & value, const hit::Field & field)
292 {
293 mooseAssert(!value.empty(), "Missing a value to initialize on");
294
295 // With MOOSE enums we need a default object so it should have been
296 // passed in the param pointer. We are only going to use the first
297 // item in the vector (value[0]) and ignore the rest.
298 const auto vec = field.param<std::vector<std::string>>();
299 value.resize(vec.size(), value[0]);
300 for (const auto i : index_range(vec))
301 value[i] = vec[i];
302 });
303// std::vector<MooseEnum>
304static auto vector_multimooseenum = registry.add<std::vector<MultiMooseEnum>>(
305 [](std::vector<MultiMooseEnum> & value, const hit::Field & field)
306 {
307 mooseAssert(!value.empty(), "Missing a value to initialize on");
308
309 const auto tokens = MooseUtils::split(field.param<std::string>(), ";");
310 for (const auto i : index_range(tokens))
311 {
312 const auto & entry = tokens[i];
313 if (MooseUtils::trim(entry) == "")
314 throw std::invalid_argument("entry " + std::to_string(i) + " in '" + field.fullpath() +
315 "' is empty");
316 }
317 value.resize(tokens.size(), value[0]);
318 for (const auto i : index_range(tokens))
319 {
320 std::vector<std::string> strvals;
321 MooseUtils::tokenize<std::string>(tokens[i], strvals, 1, " ");
322 value[i] = strvals;
323 }
324 });
325// std::vector<ReporterName>
326static auto vector_reportername = registry.add<std::vector<ReporterName>>(
327 [](std::vector<ReporterName> & value, const hit::Field & field)
328 {
329 value.clear();
330 const auto names = field.param<std::vector<std::string>>();
331 value.resize(names.size());
332 for (const auto i : index_range(names))
333 value[i] = convert_reporter_name(names[i], field);
334 });
335// std::vector<CLIArgString>
336static auto vector_cliargstring = registry.add<std::vector<CLIArgString>>(
337 [](std::vector<CLIArgString> & value, const hit::Field & field)
338 {
339 value.clear();
340 const auto strvals = field.param<std::vector<std::string>>();
341 if (strvals.empty())
342 return;
343
344 // slightly oversized if vectors have been split
345 value.resize(strvals.size());
346
347 // Re-assemble vector parameters
348 unsigned int i_param = 0;
349 bool vector_param_detected = false;
350 for (const auto i : index_range(strvals))
351 {
352 // Look for a quote, both types
353 const auto double_split =
354 MooseUtils::rsplit(strvals[i], "\"", std::numeric_limits<std::size_t>::max());
355 const auto single_split =
356 MooseUtils::rsplit(strvals[i], "\'", std::numeric_limits<std::size_t>::max());
357 if (double_split.size() + single_split.size() >= 3)
358 // Either entering or exiting a vector parameter (>3 is entering another vector)
359 // Even and >2 number of quotes means both finished and started another vector parameter
360 if ((double_split.size() + single_split.size()) % 2 == 1)
361 vector_param_detected = !vector_param_detected;
362
363 // We're building a vector parameters, just append the text, rebuild the spaces
364 if (vector_param_detected)
365 value[i_param] += strvals[i] + ' ';
366 else
367 {
368 value[i_param] += strvals[i];
369 i_param++;
370 }
371 }
372 // Use actual size after re-forming vector parameters
373 value.resize(i_param);
374 });
375
376/*******************************************************************************/
377/* Component-typed double vector registration */
378/*******************************************************************************/
379
381const auto set_double_vector_component_value = [](auto & value, const hit::Field & field)
382{
383 const auto strval = field.param<std::string>();
384
385 // Split vector at delim ";" (substrings are not of type T yet)
386 std::vector<std::string> tokens;
387 MooseUtils::tokenize(strval, tokens, 1, ";");
388 value.resize(tokens.size());
389
390 // Split each token at spaces
391 std::vector<std::vector<double>> vecvec(tokens.size());
392 for (const auto i : index_range(tokens))
393 if (!MooseUtils::tokenizeAndConvert<double>(tokens[i], vecvec[i]))
394 throw std::invalid_argument("invalid format for parameter '" + field.fullpath() +
395 "' at index " + std::to_string(i));
396
397 for (const auto i : index_range(vecvec))
398 {
399 const auto & vec = vecvec[i];
400 if (vec.size() % LIBMESH_DIM)
401 throw std::invalid_argument(
402 "wrong number of values in double-indexed vector component parameter '" +
403 field.fullpath() + "' at index " + std::to_string(i) + ": subcomponent size " +
404 std::to_string(vec.size()) + " is not a multiple of " + std::to_string(LIBMESH_DIM));
405 }
406
407 // convert vector<vector<double>> to vector<vector<T>>
408 value.resize(vecvec.size());
409 for (const auto i : index_range(vecvec))
410 {
411 const auto & vec_entry = vecvec[i];
412 auto & value_entry = value[i];
413 const std::size_t size = vec_entry.size() / LIBMESH_DIM;
414 value_entry.resize(size);
415 for (const auto j : make_range(size))
416 for (const auto d : make_range(Moose::dim))
417 value_entry[j](d) = vec_entry[j * LIBMESH_DIM + d];
418 }
419};
420
421// std::vector<std::vector<Point>>
422static auto doublevector_point = registry.add<std::vector<std::vector<Point>>>(
423 [](std::vector<std::vector<Point>> & value, const hit::Field & field)
424 { set_double_vector_component_value(value, field); });
425// std::vector<std::vector<RealVectorValue>>
426static auto doublevector_realvectorvalue = registry.add<std::vector<std::vector<RealVectorValue>>>(
427 [](std::vector<std::vector<RealVectorValue>> & value, const hit::Field & field)
428 { set_double_vector_component_value(value, field); });
429
430/*******************************************************************************/
431/* Map registration */
432/*******************************************************************************/
433
434registerMapParameter(std::string, unsigned int);
435registerMapParameter(std::string, Real);
436registerMapParameter(std::string, std::string);
437registerMapParameter(unsigned int, unsigned int);
438registerMapParameter(unsigned long, unsigned int);
439registerMapParameter(unsigned long long, unsigned int);
440
441} // end of namespace detail
442} // 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:175