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