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(InterpolationMethodName);
87 registerParameter(IndicatorName);
88 registerParameter(MarkerName);
89 registerParameter(MultiAppName);
90 registerParameter(OutputName);
91 registerParameter(MaterialPropertyName);
92 registerParameter(MooseFunctorName);
93 registerParameter(MaterialName);
94 registerParameter(TagName);
95 registerParameter(MeshGeneratorName);
96 registerParameter(ExtraElementIDName);
97 registerParameter(ReporterValueName);
98 registerParameter(ComponentName);
99 registerParameter(PhysicsName);
100 registerParameter(PositionsName);
101 registerParameter(TimesName);
102 registerParameter(ExecutorName);
103 registerParameter(ParsedFunctionExpression);
104 registerParameter(NonlinearSystemName);
105 registerParameter(ConvergenceName);
106 registerParameter(LinearSystemName);
107 registerParameter(SolverSystemName);
108 #ifdef MOOSE_MFEM_ENABLED
109 registerParameter(MFEMScalarCoefficientName);
110 registerParameter(MFEMVectorCoefficientName);
111 registerParameter(MFEMMatrixCoefficientName);
112 registerParameter(MFEMFESpaceName);
113 registerParameter(MFEMSolverName);
114 #endif
115 
116 /*******************************************************************************/
117 /* Native type registration */
118 /* */
119 /* Registers for scalars, vectors, double vectors, and triple vectors */
120 /*******************************************************************************/
121 
122 registerParameter(double);
123 registerParameter(std::string);
124 registerParameter(short int);
125 registerParameter(int);
126 registerParameter(long int);
127 registerParameter(unsigned short);
128 registerParameter(unsigned int);
129 registerParameter(unsigned long);
130 registerParameter(unsigned long long);
131 
132 /*******************************************************************************/
133 /* Bool registration */
134 /*******************************************************************************/
135 
138 
139 /*******************************************************************************/
140 /* Helpers used across types */
141 /*******************************************************************************/
142 
145 const 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 
160 const 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(LIBMESH_DIM))
170  value(d) = Real(vec[d]);
171 };
172 
173 // Point
174 static auto point = registry.add<Point>([](Point & value, const hit::Field & field)
175  { set_scalar_component_value(value, field); });
176 // RealVectorValue
177 static 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
187 registerScalarParameter(CLIArgString);
188 // 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
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
221 static 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
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(LIBMESH_DIM))
242  for (const auto j : make_range(LIBMESH_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 
255 const 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(LIBMESH_DIM))
269  value[i](d) = vec[i * LIBMESH_DIM + d];
270 };
271 
272 // std::vector<Point>
273 static 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>
277 static 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>
286 static 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>
300 static 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>
322 static 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>
332 static 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 =
351  const auto single_split =
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 
377 const 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(LIBMESH_DIM))
413  value_entry[j](d) = vec_entry[j * LIBMESH_DIM + d];
414  }
415 };
416 
417 // std::vector<std::vector<Point>>
418 static auto doublevector_point = registry.add<std::vector<std::vector<Point>>>(
419  [](std::vector<std::vector<Point>> & value, const hit::Field & field)
421 // std::vector<std::vector<RealVectorValue>>
422 static auto doublevector_realvectorvalue = registry.add<std::vector<std::vector<RealVectorValue>>>(
423  [](std::vector<std::vector<RealVectorValue>> & value, const hit::Field & field)
425 
426 /*******************************************************************************/
427 /* Map registration */
428 /*******************************************************************************/
429 
430 registerMapParameter(std::string, unsigned int);
431 registerMapParameter(std::string, Real);
432 registerMapParameter(std::string, std::string);
433 registerMapParameter(unsigned int, unsigned int);
434 registerMapParameter(unsigned long, unsigned int);
435 registerMapParameter(unsigned long long, unsigned int);
436 
437 } // end of namespace detail
438 } // 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)
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:54
registerMapParameter(std::string, unsigned int)
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > RealEigenMatrix
Definition: MooseTypes.h:151
const auto set_scalar_component_value
Helper for setting a scalar component value (one with 3 real values)
std::vector< std::string > rsplit(const std::string &str, const std::string &delimiter, std::size_t max_count)
Definition: MooseUtils.C:1040
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:147
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type...
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count)
Definition: MooseUtils.C:1020
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
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:1140