Line data Source code
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 :
19 : namespace Moose::ParameterRegistration
20 : {
21 :
22 : template <>
23 : void
24 201814 : setScalarValue(bool & value, const hit::Field & field)
25 : {
26 : // Handles non-quoted values
27 : try
28 : {
29 201814 : value = field.boolVal();
30 : }
31 : // Handles quoted values
32 96 : catch (hit::Error &)
33 : {
34 192 : const auto strval = field.param<std::string>();
35 96 : if (strval == "1")
36 1 : value = true;
37 95 : else if (strval == "0")
38 1 : value = false;
39 94 : else if (!hit::toBool(strval, &value))
40 2 : throw std::invalid_argument("invalid boolean syntax for parameter: " + field.path() + "='" +
41 3 : strval + "'");
42 97 : }
43 201813 : }
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 :
53 : static Moose::ParameterRegistry & registry = Moose::ParameterRegistry::get();
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 9764 : registerParameter(FileName);
66 1280 : registerParameter(FileNameNoExtension);
67 0 : registerParameter(RelativeFileName);
68 51 : registerParameter(DataFileName);
69 6777 : registerParameter(MeshFileName);
70 40 : registerParameter(MatrixFileName);
71 0 : registerParameter(OutFileBase);
72 199475 : registerParameter(NonlinearVariableName);
73 5677 : registerParameter(LinearVariableName);
74 0 : registerParameter(SolverVariableName);
75 46052 : registerParameter(AuxVariableName);
76 93900 : registerParameter(VariableName);
77 150538 : registerParameter(BoundaryName);
78 54803 : registerParameter(SubdomainName);
79 10687 : registerParameter(PostprocessorName);
80 1564 : registerParameter(VectorPostprocessorName);
81 1349 : registerParameter(MeshDivisionName);
82 49441 : registerParameter(FunctionName);
83 13 : registerParameter(DistributionName);
84 367 : registerParameter(SamplerName);
85 7187 : registerParameter(UserObjectName);
86 531 : registerParameter(IndicatorName);
87 2109 : registerParameter(MarkerName);
88 14095 : registerParameter(MultiAppName);
89 8803 : registerParameter(OutputName);
90 14357 : registerParameter(MaterialPropertyName);
91 21803 : registerParameter(MooseFunctorName);
92 141 : registerParameter(MaterialName);
93 6647 : registerParameter(TagName);
94 27878 : registerParameter(MeshGeneratorName);
95 904 : registerParameter(ExtraElementIDName);
96 3025 : registerParameter(ReporterValueName);
97 0 : registerParameter(ComponentName);
98 114 : registerParameter(PhysicsName);
99 976 : registerParameter(PositionsName);
100 56 : registerParameter(TimesName);
101 40 : registerParameter(ExecutorName);
102 929 : registerParameter(ParsedFunctionExpression);
103 1064 : registerParameter(NonlinearSystemName);
104 1671 : registerParameter(ConvergenceName);
105 2654 : registerParameter(LinearSystemName);
106 3228 : registerParameter(SolverSystemName);
107 : #ifdef MOOSE_MFEM_ENABLED
108 707 : registerParameter(MFEMScalarCoefficientName);
109 159 : registerParameter(MFEMVectorCoefficientName);
110 0 : registerParameter(MFEMMatrixCoefficientName);
111 : #endif
112 :
113 : /*******************************************************************************/
114 : /* Native type registration */
115 : /* */
116 : /* Registers for scalars, vectors, double vectors, and triple vectors */
117 : /*******************************************************************************/
118 :
119 294718 : registerParameter(double);
120 736285 : registerParameter(std::string);
121 1952 : registerParameter(short int);
122 3872 : registerParameter(int);
123 92 : registerParameter(long int);
124 15663 : registerParameter(unsigned short);
125 179207 : registerParameter(unsigned int);
126 3816 : registerParameter(unsigned long);
127 2 : registerParameter(unsigned long long);
128 :
129 : /*******************************************************************************/
130 : /* Bool registration */
131 : /*******************************************************************************/
132 :
133 201814 : registerScalarParameter(bool);
134 1572 : registerVectorParameter(bool);
135 :
136 : /*******************************************************************************/
137 : /* Helpers used across types */
138 : /*******************************************************************************/
139 :
140 : /// Helper for converting a string to a ReporterName, which requires splitting
141 : /// the string at the '/' delimiter
142 3087 : const auto convert_reporter_name = [](const std::string & val,
143 : const hit::Field & field) -> ReporterName
144 : {
145 3087 : const auto names = MooseUtils::rsplit(val, "/", 2);
146 3087 : if (names.size() != 2)
147 4 : throw std::invalid_argument("invalid syntax in ReporterName parameter " + field.fullpath() +
148 6 : ": supplied name '" + val + "' must contain the '/' delimiter");
149 6170 : return {names[0], names[1]};
150 3087 : };
151 :
152 : /*******************************************************************************/
153 : /* Component-typed scalar registration */
154 : /*******************************************************************************/
155 :
156 : /// Helper for setting a scalar component value (one with 3 real values)
157 29361 : const auto set_scalar_component_value = [](auto & value, const hit::Field & field)
158 : {
159 58722 : const auto vec = field.param<std::vector<double>>();
160 29361 : if (vec.size() != LIBMESH_DIM)
161 1 : 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 117440 : for (const auto d : make_range(LIBMESH_DIM))
167 88080 : value(d) = Real(vec[d]);
168 29361 : };
169 :
170 : // Point
171 8058 : static auto point = registry.add<Point>([](Point & value, const hit::Field & field)
172 8058 : { set_scalar_component_value(value, field); });
173 : // RealVectorValue
174 : static auto realvectorvalue =
175 21303 : registry.add<RealVectorValue>([](RealVectorValue & value, const hit::Field & field)
176 21303 : { 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 0 : registerScalarParameter(CLIArgString);
185 : // RealEigenVector
186 : static auto realeigenvector = registry.add<RealEigenVector>(
187 1984 : [](RealEigenVector & value, const hit::Field & field)
188 : {
189 3969 : const auto vec = field.param<std::vector<double>>();
190 1983 : value.resize(vec.size());
191 6417 : for (const auto i : index_range(vec))
192 4434 : value(i) = Real(vec[i]);
193 1983 : });
194 : // RealEigenVector
195 : static auto realeigenmatrix = registry.add<RealEigenMatrix>(
196 189 : [](RealEigenMatrix & value, const hit::Field & field)
197 : {
198 189 : value.resize(0, 0);
199 189 : std::vector<std::string> tokens;
200 567 : MooseUtils::tokenize(field.param<std::string>(), tokens, 1, ";");
201 :
202 554 : for (const auto i : index_range(tokens))
203 : {
204 367 : const auto token = MooseUtils::trim(tokens[i]);
205 367 : std::vector<Real> values;
206 734 : if (!MooseUtils::tokenizeAndConvert<Real>(token, values))
207 2 : throw std::invalid_argument("invalid syntax for parameter: " + field.fullpath() + "[" +
208 3 : std::to_string(i) + "]='" + token + "'");
209 366 : if (i == 0)
210 189 : value.resize(tokens.size(), values.size());
211 177 : else if (libMesh::cast_int<std::size_t>(value.cols()) != values.size())
212 1 : throw std::invalid_argument("matrix is not square for parameter " + field.fullpath());
213 1112 : for (const auto j : index_range(values))
214 747 : value(i, j) = values[j];
215 369 : }
216 189 : });
217 : // MooseEnum
218 442390 : static auto mooseenum = registry.add<MooseEnum>([](MooseEnum & value, const hit::Field & field)
219 1327182 : { value = field.param<std::string>(); });
220 : // MultiMooseEnum
221 : static auto multimooseenum = registry.add<MultiMooseEnum>(
222 34625 : [](MultiMooseEnum & value, const hit::Field & field)
223 138500 : { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
224 : // ExecFlagEnum
225 : static auto execflagenum = registry.add<ExecFlagEnum>(
226 59918 : [](ExecFlagEnum & value, const hit::Field & field)
227 239672 : { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
228 : // RealTensorValue
229 : static auto realtensorvalue = registry.add<RealTensorValue>(
230 42 : [](RealTensorValue & value, const hit::Field & field)
231 : {
232 85 : const auto vec = field.param<std::vector<double>>();
233 41 : if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
234 2 : throw std::invalid_argument("invalid RealTensorValue parameter '" + field.fullpath() +
235 4 : "': size is " + std::to_string(vec.size()) + " but should be " +
236 3 : std::to_string(LIBMESH_DIM * LIBMESH_DIM));
237 :
238 160 : for (const auto i : make_range(LIBMESH_DIM))
239 480 : for (const auto j : make_range(LIBMESH_DIM))
240 360 : value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
241 41 : });
242 : // ReporterName
243 : static auto reportername = registry.add<ReporterName>(
244 911 : [](ReporterName & value, const hit::Field & field)
245 2734 : { value = convert_reporter_name(field.param<std::string>(), field); });
246 :
247 : /*******************************************************************************/
248 : /* Component-typed vector registration */
249 : /*******************************************************************************/
250 :
251 : /// Helper for setting a vector component value (one with 3 real values)
252 8779 : const auto set_vector_component_value = [](auto & value, const hit::Field & field)
253 : {
254 8779 : value.clear();
255 17559 : const auto vec = field.param<std::vector<double>>();
256 :
257 8778 : if (vec.size() % LIBMESH_DIM)
258 5 : 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 8773 : const std::size_t size = vec.size() / LIBMESH_DIM;
263 8773 : value.resize(size);
264 30681 : for (const auto i : make_range(size))
265 87632 : for (const auto d : make_range(LIBMESH_DIM))
266 65724 : value[i](d) = vec[i * LIBMESH_DIM + d];
267 8778 : };
268 :
269 : // std::vector<Point>
270 : static auto vector_point =
271 8719 : registry.add<std::vector<Point>>([](std::vector<Point> & value, const hit::Field & field)
272 8719 : { set_vector_component_value(value, field); });
273 : // std::vector<RealVectorValue>
274 : static auto vector_realvectorvalue = registry.add<std::vector<RealVectorValue>>(
275 60 : [](std::vector<RealVectorValue> & value, const hit::Field & field)
276 60 : { 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 268 : [](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 536 : const auto vec = field.param<std::vector<std::string>>();
292 268 : value.resize(vec.size(), value[0]);
293 735 : for (const auto i : index_range(vec))
294 471 : value[i] = vec[i];
295 268 : });
296 : // std::vector<MooseEnum>
297 : static auto vector_multimooseenum = registry.add<std::vector<MultiMooseEnum>>(
298 19 : [](std::vector<MultiMooseEnum> & value, const hit::Field & field)
299 : {
300 : mooseAssert(!value.empty(), "Missing a value to initialize on");
301 :
302 76 : const auto tokens = MooseUtils::split(field.param<std::string>(), ";");
303 89 : for (const auto i : index_range(tokens))
304 : {
305 74 : const auto & entry = tokens[i];
306 148 : if (MooseUtils::trim(entry) == "")
307 8 : throw std::invalid_argument("entry " + std::to_string(i) + " in '" + field.fullpath() +
308 12 : "' is empty");
309 : }
310 15 : value.resize(tokens.size(), value[0]);
311 77 : for (const auto i : index_range(tokens))
312 : {
313 66 : std::vector<std::string> strvals;
314 66 : MooseUtils::tokenize<std::string>(tokens[i], strvals, 1, " ");
315 66 : value[i] = strvals;
316 66 : }
317 19 : });
318 : // std::vector<ReporterName>
319 : static auto vector_reportername = registry.add<std::vector<ReporterName>>(
320 1176 : [](std::vector<ReporterName> & value, const hit::Field & field)
321 : {
322 1176 : value.clear();
323 2352 : const auto names = field.param<std::vector<std::string>>();
324 1176 : value.resize(names.size());
325 3351 : for (const auto i : index_range(names))
326 2176 : value[i] = convert_reporter_name(names[i], field);
327 1176 : });
328 : // std::vector<CLIArgString>
329 : static auto vector_cliargstring = registry.add<std::vector<CLIArgString>>(
330 1877 : [](std::vector<CLIArgString> & value, const hit::Field & field)
331 : {
332 1877 : value.clear();
333 3754 : const auto strvals = field.param<std::vector<std::string>>();
334 1877 : if (strvals.empty())
335 4 : return;
336 :
337 : // slightly oversized if vectors have been split
338 1873 : value.resize(strvals.size());
339 :
340 : // Re-assemble vector parameters
341 1873 : unsigned int i_param = 0;
342 1873 : bool vector_param_detected = false;
343 5212 : for (const auto i : index_range(strvals))
344 : {
345 : // Look for a quote, both types
346 : const auto double_split =
347 6678 : MooseUtils::rsplit(strvals[i], "\"", std::numeric_limits<std::size_t>::max());
348 : const auto single_split =
349 6678 : MooseUtils::rsplit(strvals[i], "\'", std::numeric_limits<std::size_t>::max());
350 3339 : 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 1607 : if ((double_split.size() + single_split.size()) % 2 == 1)
354 234 : vector_param_detected = !vector_param_detected;
355 :
356 : // We're building a vector parameters, just append the text, rebuild the spaces
357 3339 : if (vector_param_detected)
358 390 : value[i_param] += strvals[i] + ' ';
359 : else
360 : {
361 2949 : value[i_param] += strvals[i];
362 2949 : i_param++;
363 : }
364 3339 : }
365 : // Use actual size after re-forming vector parameters
366 1873 : value.resize(i_param);
367 1877 : });
368 :
369 : /*******************************************************************************/
370 : /* Component-typed double vector registration */
371 : /*******************************************************************************/
372 :
373 : /// Helper for setting a double vector component value (one with 3 real values)
374 119 : const auto set_double_vector_component_value = [](auto & value, const hit::Field & field)
375 : {
376 238 : const auto strval = field.param<std::string>();
377 :
378 : // Split vector at delim ";" (substrings are not of type T yet)
379 119 : std::vector<std::string> tokens;
380 119 : MooseUtils::tokenize(strval, tokens, 1, ";");
381 119 : value.resize(tokens.size());
382 :
383 : // Split each token at spaces
384 119 : std::vector<std::vector<double>> vecvec(tokens.size());
385 355 : for (const auto i : index_range(tokens))
386 474 : if (!MooseUtils::tokenizeAndConvert<double>(tokens[i], vecvec[i]))
387 1 : throw std::invalid_argument("invalid format for parameter '" + field.fullpath() +
388 : "' at index " + std::to_string(i));
389 :
390 353 : for (const auto i : index_range(vecvec))
391 : {
392 236 : const auto & vec = vecvec[i];
393 236 : if (vec.size() % LIBMESH_DIM)
394 1 : 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 117 : value.resize(vecvec.size());
402 351 : for (const auto i : index_range(vecvec))
403 : {
404 234 : const auto & vec_entry = vecvec[i];
405 234 : auto & value_entry = value[i];
406 234 : const std::size_t size = vec_entry.size() / LIBMESH_DIM;
407 234 : value_entry.resize(size);
408 815 : for (const auto j : make_range(size))
409 2324 : for (const auto d : make_range(LIBMESH_DIM))
410 1743 : value_entry[j](d) = vec_entry[j * LIBMESH_DIM + d];
411 : }
412 123 : };
413 :
414 : // std::vector<std::vector<Point>>
415 : static auto doublevector_point = registry.add<std::vector<std::vector<Point>>>(
416 118 : [](std::vector<std::vector<Point>> & value, const hit::Field & field)
417 118 : { set_double_vector_component_value(value, field); });
418 : // std::vector<std::vector<RealVectorValue>>
419 : static auto doublevector_realvectorvalue = registry.add<std::vector<std::vector<RealVectorValue>>>(
420 1 : [](std::vector<std::vector<RealVectorValue>> & value, const hit::Field & field)
421 1 : { set_double_vector_component_value(value, field); });
422 :
423 : /*******************************************************************************/
424 : /* Map registration */
425 : /*******************************************************************************/
426 :
427 0 : registerMapParameter(std::string, unsigned int);
428 52 : registerMapParameter(std::string, Real);
429 359 : registerMapParameter(std::string, std::string);
430 13 : registerMapParameter(unsigned int, unsigned int);
431 13 : registerMapParameter(unsigned long, unsigned int);
432 13 : registerMapParameter(unsigned long long, unsigned int);
433 :
434 : } // end of namespace detail
435 : } // end of namespace Moose::ParameterRegistration
|