https://mooseframework.inl.gov
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 
10 #include "ParameterRegistration.h"
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 
22 template <>
23 void
24 setScalarValue(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 
50 namespace 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
65 registerParameter(FileName);
66 registerParameter(FileNameNoExtension);
67 registerParameter(RelativeFileName);
68 registerParameter(DataFileName);
69 registerParameter(MeshFileName);
70 registerParameter(MatrixFileName);
71 registerParameter(OutFileBase);
72 registerParameter(NonlinearVariableName);
73 registerParameter(LinearVariableName);
74 registerParameter(SolverVariableName);
75 registerParameter(AuxVariableName);
76 registerParameter(VariableName);
77 registerParameter(BoundaryName);
78 registerParameter(SubdomainName);
79 registerParameter(PostprocessorName);
80 registerParameter(VectorPostprocessorName);
81 registerParameter(MeshDivisionName);
82 registerParameter(FunctionName);
83 registerParameter(DistributionName);
84 registerParameter(SamplerName);
85 registerParameter(UserObjectName);
86 registerParameter(IndicatorName);
87 registerParameter(MarkerName);
88 registerParameter(MultiAppName);
89 registerParameter(OutputName);
90 registerParameter(MaterialPropertyName);
91 registerParameter(MooseFunctorName);
92 registerParameter(MaterialName);
93 registerParameter(TagName);
94 registerParameter(MeshGeneratorName);
95 registerParameter(ExtraElementIDName);
96 registerParameter(ReporterValueName);
97 registerParameter(ComponentName);
98 registerParameter(PhysicsName);
99 registerParameter(PositionsName);
100 registerParameter(TimesName);
101 registerParameter(ExecutorName);
102 registerParameter(ParsedFunctionExpression);
103 registerParameter(NonlinearSystemName);
104 registerParameter(ConvergenceName);
105 registerParameter(LinearSystemName);
106 registerParameter(SolverSystemName);
107 #ifdef MOOSE_MFEM_ENABLED
108 registerParameter(MFEMScalarCoefficientName);
109 registerParameter(MFEMVectorCoefficientName);
110 registerParameter(MFEMMatrixCoefficientName);
111 #endif
112 
113 /*******************************************************************************/
114 /* Native type registration */
115 /* */
116 /* Registers for scalars, vectors, double vectors, and triple vectors */
117 /*******************************************************************************/
118 
119 registerParameter(double);
120 registerParameter(std::string);
121 registerParameter(short int);
122 registerParameter(int);
123 registerParameter(long int);
124 registerParameter(unsigned short);
125 registerParameter(unsigned int);
126 registerParameter(unsigned long);
127 registerParameter(unsigned long long);
128 
129 /*******************************************************************************/
130 /* Bool registration */
131 /*******************************************************************************/
132 
135 
136 /*******************************************************************************/
137 /* Helpers used across types */
138 /*******************************************************************************/
139 
142 const auto convert_reporter_name = [](const std::string & val,
143  const hit::Field & field) -> ReporterName
144 {
145  const auto names = MooseUtils::rsplit(val, "/", 2);
146  if (names.size() != 2)
147  throw std::invalid_argument("invalid syntax in ReporterName parameter " + field.fullpath() +
148  ": supplied name '" + val + "' must contain the '/' delimiter");
149  return {names[0], names[1]};
150 };
151 
152 /*******************************************************************************/
153 /* Component-typed scalar registration */
154 /*******************************************************************************/
155 
157 const auto set_scalar_component_value = [](auto & value, const hit::Field & field)
158 {
159  const auto vec = field.param<std::vector<double>>();
160  if (vec.size() != LIBMESH_DIM)
161  throw std::invalid_argument("wrong number of values in " + MooseUtils::prettyCppType(&value) +
162  " parameter '" + field.fullpath() + "': was given " +
163  std::to_string(vec.size()) + " component(s) but should have " +
164  std::to_string(LIBMESH_DIM));
165 
166  for (const auto d : make_range(LIBMESH_DIM))
167  value(d) = Real(vec[d]);
168 };
169 
170 // Point
171 static auto point = registry.add<Point>([](Point & value, const hit::Field & field)
172  { set_scalar_component_value(value, field); });
173 // RealVectorValue
174 static auto realvectorvalue =
175  registry.add<RealVectorValue>([](RealVectorValue & value, const hit::Field & field)
176  { set_scalar_component_value(value, field); });
177 
178 /*******************************************************************************/
179 /* Custom scalar registration */
180 /*******************************************************************************/
181 
182 // We only support CLIArgString and std::vector<CLIArgString>, so this isn't
183 // added in the main MooseDerivativeString case
184 registerScalarParameter(CLIArgString);
185 // RealEigenVector
187  [](RealEigenVector & value, const hit::Field & field)
188  {
189  const auto vec = field.param<std::vector<double>>();
190  value.resize(vec.size());
191  for (const auto i : index_range(vec))
192  value(i) = Real(vec[i]);
193  });
194 // RealEigenVector
196  [](RealEigenMatrix & value, const hit::Field & field)
197  {
198  value.resize(0, 0);
199  std::vector<std::string> tokens;
200  MooseUtils::tokenize(field.param<std::string>(), tokens, 1, ";");
201 
202  for (const auto i : index_range(tokens))
203  {
204  const auto token = MooseUtils::trim(tokens[i]);
205  std::vector<Real> values;
206  if (!MooseUtils::tokenizeAndConvert<Real>(token, values))
207  throw std::invalid_argument("invalid syntax for parameter: " + field.fullpath() + "[" +
208  std::to_string(i) + "]='" + token + "'");
209  if (i == 0)
210  value.resize(tokens.size(), values.size());
211  else if (libMesh::cast_int<std::size_t>(value.cols()) != values.size())
212  throw std::invalid_argument("matrix is not square for parameter " + field.fullpath());
213  for (const auto j : index_range(values))
214  value(i, j) = values[j];
215  }
216  });
217 // MooseEnum
218 static auto mooseenum = registry.add<MooseEnum>([](MooseEnum & value, const hit::Field & field)
219  { value = field.param<std::string>(); });
220 // MultiMooseEnum
222  [](MultiMooseEnum & value, const hit::Field & field)
223  { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
224 // ExecFlagEnum
226  [](ExecFlagEnum & value, const hit::Field & field)
227  { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
228 // RealTensorValue
230  [](RealTensorValue & value, const hit::Field & field)
231  {
232  const auto vec = field.param<std::vector<double>>();
233  if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
234  throw std::invalid_argument("invalid RealTensorValue parameter '" + field.fullpath() +
235  "': size is " + std::to_string(vec.size()) + " but should be " +
236  std::to_string(LIBMESH_DIM * LIBMESH_DIM));
237 
238  for (const auto i : make_range(LIBMESH_DIM))
239  for (const auto j : make_range(LIBMESH_DIM))
240  value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
241  });
242 // ReporterName
244  [](ReporterName & value, const hit::Field & field)
245  { value = convert_reporter_name(field.param<std::string>(), field); });
246 
247 /*******************************************************************************/
248 /* Component-typed vector registration */
249 /*******************************************************************************/
250 
252 const auto set_vector_component_value = [](auto & value, const hit::Field & field)
253 {
254  value.clear();
255  const auto vec = field.param<std::vector<double>>();
256 
257  if (vec.size() % LIBMESH_DIM)
258  throw std::invalid_argument("wrong number of values in vector parameter '" + field.fullpath() +
259  "': size " + std::to_string(vec.size()) + " is not a multiple of " +
260  std::to_string(LIBMESH_DIM));
261 
262  const std::size_t size = vec.size() / LIBMESH_DIM;
263  value.resize(size);
264  for (const auto i : make_range(size))
265  for (const auto d : make_range(LIBMESH_DIM))
266  value[i](d) = vec[i * LIBMESH_DIM + d];
267 };
268 
269 // std::vector<Point>
270 static auto vector_point =
271  registry.add<std::vector<Point>>([](std::vector<Point> & value, const hit::Field & field)
272  { set_vector_component_value(value, field); });
273 // std::vector<RealVectorValue>
274 static auto vector_realvectorvalue = registry.add<std::vector<RealVectorValue>>(
275  [](std::vector<RealVectorValue> & value, const hit::Field & field)
276  { set_vector_component_value(value, field); });
277 
278 /*******************************************************************************/
279 /* Custom vector registration */
280 /*******************************************************************************/
281 
282 // std::vector<MooseEnum>
283 static auto vector_mooseenum = registry.add<std::vector<MooseEnum>>(
284  [](std::vector<MooseEnum> & value, const hit::Field & field)
285  {
286  mooseAssert(!value.empty(), "Missing a value to initialize on");
287 
288  // With MOOSE enums we need a default object so it should have been
289  // passed in the param pointer. We are only going to use the first
290  // item in the vector (value[0]) and ignore the rest.
291  const auto vec = field.param<std::vector<std::string>>();
292  value.resize(vec.size(), value[0]);
293  for (const auto i : index_range(vec))
294  value[i] = vec[i];
295  });
296 // std::vector<MooseEnum>
297 static auto vector_multimooseenum = registry.add<std::vector<MultiMooseEnum>>(
298  [](std::vector<MultiMooseEnum> & value, const hit::Field & field)
299  {
300  mooseAssert(!value.empty(), "Missing a value to initialize on");
301 
302  const auto tokens = MooseUtils::split(field.param<std::string>(), ";");
303  for (const auto i : index_range(tokens))
304  {
305  const auto & entry = tokens[i];
306  if (MooseUtils::trim(entry) == "")
307  throw std::invalid_argument("entry " + std::to_string(i) + " in '" + field.fullpath() +
308  "' is empty");
309  }
310  value.resize(tokens.size(), value[0]);
311  for (const auto i : index_range(tokens))
312  {
313  std::vector<std::string> strvals;
314  MooseUtils::tokenize<std::string>(tokens[i], strvals, 1, " ");
315  value[i] = strvals;
316  }
317  });
318 // std::vector<ReporterName>
319 static auto vector_reportername = registry.add<std::vector<ReporterName>>(
320  [](std::vector<ReporterName> & value, const hit::Field & field)
321  {
322  value.clear();
323  const auto names = field.param<std::vector<std::string>>();
324  value.resize(names.size());
325  for (const auto i : index_range(names))
326  value[i] = convert_reporter_name(names[i], field);
327  });
328 // std::vector<CLIArgString>
329 static auto vector_cliargstring = registry.add<std::vector<CLIArgString>>(
330  [](std::vector<CLIArgString> & value, const hit::Field & field)
331  {
332  value.clear();
333  const auto strvals = field.param<std::vector<std::string>>();
334  if (strvals.empty())
335  return;
336 
337  // slightly oversized if vectors have been split
338  value.resize(strvals.size());
339 
340  // Re-assemble vector parameters
341  unsigned int i_param = 0;
342  bool vector_param_detected = false;
343  for (const auto i : index_range(strvals))
344  {
345  // Look for a quote, both types
346  const auto double_split =
348  const auto single_split =
350  if (double_split.size() + single_split.size() >= 3)
351  // Either entering or exiting a vector parameter (>3 is entering another vector)
352  // Even and >2 number of quotes means both finished and started another vector parameter
353  if ((double_split.size() + single_split.size()) % 2 == 1)
354  vector_param_detected = !vector_param_detected;
355 
356  // We're building a vector parameters, just append the text, rebuild the spaces
357  if (vector_param_detected)
358  value[i_param] += strvals[i] + ' ';
359  else
360  {
361  value[i_param] += strvals[i];
362  i_param++;
363  }
364  }
365  // Use actual size after re-forming vector parameters
366  value.resize(i_param);
367  });
368 
369 /*******************************************************************************/
370 /* Component-typed double vector registration */
371 /*******************************************************************************/
372 
374 const auto set_double_vector_component_value = [](auto & value, const hit::Field & field)
375 {
376  const auto strval = field.param<std::string>();
377 
378  // Split vector at delim ";" (substrings are not of type T yet)
379  std::vector<std::string> tokens;
380  MooseUtils::tokenize(strval, tokens, 1, ";");
381  value.resize(tokens.size());
382 
383  // Split each token at spaces
384  std::vector<std::vector<double>> vecvec(tokens.size());
385  for (const auto i : index_range(tokens))
386  if (!MooseUtils::tokenizeAndConvert<double>(tokens[i], vecvec[i]))
387  throw std::invalid_argument("invalid format for parameter '" + field.fullpath() +
388  "' at index " + std::to_string(i));
389 
390  for (const auto i : index_range(vecvec))
391  {
392  const auto & vec = vecvec[i];
393  if (vec.size() % LIBMESH_DIM)
394  throw std::invalid_argument(
395  "wrong number of values in double-indexed vector component parameter '" +
396  field.fullpath() + "' at index " + std::to_string(i) + ": subcomponent size " +
397  std::to_string(vec.size()) + " is not a multiple of " + std::to_string(LIBMESH_DIM));
398  }
399 
400  // convert vector<vector<double>> to vector<vector<T>>
401  value.resize(vecvec.size());
402  for (const auto i : index_range(vecvec))
403  {
404  const auto & vec_entry = vecvec[i];
405  auto & value_entry = value[i];
406  const std::size_t size = vec_entry.size() / LIBMESH_DIM;
407  value_entry.resize(size);
408  for (const auto j : make_range(size))
409  for (const auto d : make_range(LIBMESH_DIM))
410  value_entry[j](d) = vec_entry[j * LIBMESH_DIM + d];
411  }
412 };
413 
414 // std::vector<std::vector<Point>>
415 static auto doublevector_point = registry.add<std::vector<std::vector<Point>>>(
416  [](std::vector<std::vector<Point>> & value, const hit::Field & field)
418 // std::vector<std::vector<RealVectorValue>>
419 static auto doublevector_realvectorvalue = registry.add<std::vector<std::vector<RealVectorValue>>>(
420  [](std::vector<std::vector<RealVectorValue>> & value, const hit::Field & field)
422 
423 /*******************************************************************************/
424 /* Map registration */
425 /*******************************************************************************/
426 
427 registerMapParameter(std::string, unsigned int);
428 registerMapParameter(std::string, Real);
429 registerMapParameter(std::string, std::string);
430 registerMapParameter(unsigned int, unsigned int);
431 registerMapParameter(unsigned long, unsigned int);
432 registerMapParameter(unsigned long long, unsigned int);
433 
434 } // end of namespace detail
435 } // end of namespace Moose::ParameterRegistration
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
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 ...
void setScalarValue(T &value, const hit::Field &field)
Converts the given field node into a scalar of the given type.
static Moose::ParameterRegistry & registry
Registry that allows for the typeless setting of a parameter value from a hit field.
const auto set_double_vector_component_value
Helper for setting a double vector component value (one with 3 real values)
auto max(const L &left, const R &right)
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
Python like split functions for strings.
Definition: MooseUtils.C:1027
std::vector< std::string > rsplit(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
Definition: MooseUtils.C:1047
TensorValue< Real > RealTensorValue
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
std::string trim(const std::string &str, const std::string &white_space=" \\\)
Standard scripting language trim function.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
registerMapParameter(std::string, unsigned int)
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > RealEigenMatrix
Definition: MooseTypes.h:149
const auto set_scalar_component_value
Helper for setting a scalar component value (one with 3 real values)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const auto convert_reporter_name
Helper for converting a string to a ReporterName, which requires splitting the string at the &#39;/&#39; deli...
char add(F &&f)
Add a parameter.
IntRange< T > make_range(T beg, T end)
const auto set_vector_component_value
Helper for setting a vector component value (one with 3 real values)
Eigen::Matrix< Real, Eigen::Dynamic, 1 > RealEigenVector
Definition: MooseTypes.h:146
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type...
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
Definition: MooseUtils.C:951
auto index_range(const T &sizable)
The Reporter system is comprised of objects that can contain any number of data values.
Definition: ReporterName.h:30
static ParameterRegistry & get()
Get the singleton registry.
std::string prettyCppType(const std::string &cpp_type)
Definition: MooseUtils.C:1147