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 : // MOOSE includes
11 : #include "BatchMeshGeneratorAction.h"
12 : #include "ActionFactory.h"
13 :
14 : #include "MooseMesh.h"
15 : #include "MeshGenerator.h"
16 : #include "Factory.h"
17 : #include "MooseApp.h"
18 : #include "MooseUtils.h"
19 :
20 : #include "hit/hit.h"
21 :
22 : registerMooseAction("MooseApp", BatchMeshGeneratorAction, "add_mesh_generator");
23 :
24 : InputParameters
25 431 : BatchMeshGeneratorAction::validParams()
26 : {
27 431 : InputParameters params = Action::validParams();
28 :
29 431 : params.set<std::string>("type") = "BatchMeshGeneratorAction";
30 :
31 431 : params.addClassDescription("Batch generate meshes using actions.");
32 431 : params.addRequiredParam<std::string>("mesh_generator_type",
33 : "Type of the mesh generator to be batch generated.");
34 431 : params.addRequiredParam<std::string>("mesh_name_prefix",
35 : "Prefix name of the meshes to be batch generated.");
36 :
37 1293 : params.addParam<std::vector<std::string>>("batch_scalar_input_param_names",
38 862 : std::vector<std::string>(),
39 : "Names of the scalar input parameters to be altered.");
40 : MultiMooseEnum default_types(
41 : "BOOL REAL SHORT USHORT INT UINT LONG ULONG LONGLONG ULONGLONG DOFIDTYPE BDRYIDTYPE SDIDTYPE "
42 : "STRING SDNAME BDRYNAME MGNAME MFNAME ENUM REALVECTORVALUE POINT",
43 431 : "");
44 431 : params.addParam<MultiMooseEnum>(
45 : "batch_scalar_input_param_types",
46 : default_types,
47 : "Types of the scalar input parameters to be altered in each generator of the batch.");
48 431 : params.addParam<std::vector<std::vector<std::string>>>(
49 : "batch_scalar_input_param_values",
50 : {},
51 : "Values of the scalar input parameters to be assigned.");
52 :
53 1293 : params.addParam<std::vector<std::string>>("batch_vector_input_param_names",
54 862 : std::vector<std::string>(),
55 : "Name of the vector input parameters to be altered.");
56 431 : params.addParam<MultiMooseEnum>("batch_vector_input_param_types",
57 : default_types,
58 : "Type of the vector input parameters to be altered.");
59 431 : params.addParam<std::vector<std::vector<std::vector<std::string>>>>(
60 : "batch_vector_input_param_values",
61 : {},
62 : "Values of the vector input parameters to be assigned.");
63 :
64 431 : MooseEnum multi_batch_params_method("corresponding cartesian_product", "cartesian_product");
65 431 : params.addParam<MooseEnum>("multi_batch_params_method",
66 : multi_batch_params_method,
67 862 : "Method to generate multiple batch parameters.Options: " +
68 862 : multi_batch_params_method.getRawNames());
69 :
70 431 : params.addParam<std::vector<std::string>>(
71 : "fixed_scalar_input_param_names", {}, "Names of the input parameters to be fixed.");
72 431 : params.addParam<MultiMooseEnum>("fixed_scalar_input_param_types",
73 : default_types,
74 : "Types of the input parameters to be fixed.");
75 431 : params.addParam<std::vector<std::string>>(
76 : "fixed_scalar_input_param_values", {}, "Values of the input parameters to be fixed.");
77 431 : params.addParam<std::vector<std::string>>(
78 : "fixed_vector_input_param_names", {}, "Names of the input vector parameters to be fixed.");
79 431 : params.addParam<MultiMooseEnum>("fixed_vector_input_param_types",
80 : default_types,
81 : "Types of the input vector parameters to be fixed.");
82 431 : params.addParam<std::vector<std::vector<std::string>>>(
83 : "fixed_vector_input_param_values", {}, "Values of the input vector parameters to be fixed.");
84 1293 : params.addParam<bool>("use_decomposed_index",
85 862 : false,
86 : "Whether to use the decomposed index for the mesh name (only effective for "
87 : "the cartesian_product method).");
88 :
89 431 : params.addParamNamesToGroup("batch_scalar_input_param_names batch_scalar_input_param_types "
90 : "batch_scalar_input_param_values "
91 : "batch_vector_input_param_names batch_vector_input_param_types "
92 : "batch_vector_input_param_values",
93 : "Batch Input");
94 431 : params.addParamNamesToGroup("fixed_scalar_input_param_names fixed_scalar_input_param_types "
95 : "fixed_scalar_input_param_values "
96 : "fixed_vector_input_param_names fixed_vector_input_param_types "
97 : "fixed_vector_input_param_values",
98 : "Fixed Input");
99 :
100 862 : return params;
101 431 : }
102 :
103 228 : BatchMeshGeneratorAction::BatchMeshGeneratorAction(const InputParameters & params)
104 : : Action(params),
105 : InputParametersChecksUtils<BatchMeshGeneratorAction>(this),
106 228 : _mesh_generator_type(getParam<std::string>("mesh_generator_type")),
107 228 : _mesh_name_prefix(getParam<std::string>("mesh_name_prefix")),
108 228 : _batch_scalar_input_param_names(
109 : getParam<std::vector<std::string>>("batch_scalar_input_param_names")),
110 548 : _batch_scalar_input_param_types(isParamValid("batch_scalar_input_param_types")
111 320 : ? getParam<MultiMooseEnum>("batch_scalar_input_param_types")
112 : .template getSetValueIDs<ParameterType>()
113 : : std::vector<ParameterType>()),
114 228 : _batch_scalar_input_param_values(
115 : getParam<std::vector<std::vector<std::string>>>("batch_scalar_input_param_values")),
116 228 : _batch_vector_input_param_names(
117 : getParam<std::vector<std::string>>("batch_vector_input_param_names")),
118 576 : _batch_vector_input_param_types(isParamValid("batch_vector_input_param_types")
119 348 : ? getParam<MultiMooseEnum>("batch_vector_input_param_types")
120 : .template getSetValueIDs<ParameterType>()
121 : : std::vector<ParameterType>()),
122 228 : _batch_vector_input_param_values(getParam<std::vector<std::vector<std::vector<std::string>>>>(
123 : "batch_vector_input_param_values")),
124 456 : _multi_batch_params_method(getParam<MooseEnum>("multi_batch_params_method")
125 228 : .template getEnum<MultiBatchParamsMethod>()),
126 228 : _fixed_scalar_input_param_names(
127 : getParam<std::vector<std::string>>("fixed_scalar_input_param_names")),
128 466 : _fixed_scalar_input_param_types(isParamValid("fixed_scalar_input_param_types")
129 238 : ? getParam<MultiMooseEnum>("fixed_scalar_input_param_types")
130 : .template getSetValueIDs<ParameterType>()
131 : : std::vector<ParameterType>()),
132 228 : _fixed_scalar_input_param_values(
133 : getParam<std::vector<std::string>>("fixed_scalar_input_param_values")),
134 228 : _fixed_vector_input_param_names(
135 : getParam<std::vector<std::string>>("fixed_vector_input_param_names")),
136 632 : _fixed_vector_input_param_types(isParamValid("fixed_vector_input_param_types")
137 404 : ? getParam<MultiMooseEnum>("fixed_vector_input_param_types")
138 : .template getSetValueIDs<ParameterType>()
139 : : std::vector<ParameterType>()),
140 228 : _fixed_vector_input_param_values(
141 : getParam<std::vector<std::vector<std::string>>>("fixed_vector_input_param_values")),
142 456 : _use_decomposed_index(getParam<bool>("use_decomposed_index"))
143 : {
144 : // Sanity check for the fixed input parameters
145 228 : checkVectorParamAndMultiMooseEnumLength<std::string>("fixed_scalar_input_param_names",
146 : "fixed_scalar_input_param_types");
147 : const auto fixed_scalar_real_compound_num =
148 224 : std::count_if(_fixed_scalar_input_param_types.begin(),
149 : _fixed_scalar_input_param_types.end(),
150 396 : [this](const ParameterType & type) { return isCompoundRealScalarType(type); });
151 224 : if (fixed_scalar_real_compound_num > 0)
152 : {
153 14 : if (_fixed_scalar_input_param_types.size() +
154 14 : (Moose::dim - 1) * fixed_scalar_real_compound_num !=
155 14 : _fixed_scalar_input_param_values.size())
156 4 : paramError("fixed_scalar_input_param_values",
157 : "This parameter must have a size that is consistent with "
158 : "fixed_scalar_input_param_names. Note that each REALVECTORVALUE or POINT type "
159 : "parameter must be represented as ",
160 4 : std::to_string(Moose::dim),
161 : " separate values instead of 1.");
162 : // Rearrange _fixed_scalar_input_param_values so that each compound real scalar value is in one
163 : // single string
164 10 : auto fixed_scalar_input_param_values_tmp(_fixed_scalar_input_param_values);
165 10 : _fixed_scalar_input_param_values.resize(_fixed_scalar_input_param_types.size());
166 10 : unsigned int raw_value_ct = 0;
167 30 : for (const auto i : index_range(_fixed_scalar_input_param_types))
168 : {
169 20 : if (isCompoundRealScalarType(_fixed_scalar_input_param_types[i]))
170 : {
171 : // In that case, the string element needs to contain three elements separated by spaces
172 50 : _fixed_scalar_input_param_values[i] = MooseUtils::join(
173 10 : fixed_scalar_input_param_values_tmp.begin() + raw_value_ct,
174 20 : fixed_scalar_input_param_values_tmp.begin() + raw_value_ct + Moose::dim,
175 10 : " ");
176 10 : raw_value_ct += Moose::dim;
177 : }
178 : else
179 : {
180 10 : _fixed_scalar_input_param_values[i] = fixed_scalar_input_param_values_tmp[raw_value_ct];
181 10 : raw_value_ct += 1;
182 : }
183 : }
184 10 : }
185 : else
186 210 : checkVectorParamsSameLength<std::string, std::string>("fixed_scalar_input_param_names",
187 : "fixed_scalar_input_param_values");
188 :
189 216 : checkVectorParamAndMultiMooseEnumLength<std::string>("fixed_vector_input_param_names",
190 : "fixed_vector_input_param_types");
191 : // The compound real scalar value type does not alter the length of
192 : // 'fixed_vector_input_param_values'
193 212 : checkVectorParamsSameLength<std::string, std::vector<std::string>>(
194 : "fixed_vector_input_param_names", "fixed_vector_input_param_values");
195 : // But we still need to process the affected elements
196 262 : for (const auto i : index_range(_fixed_vector_input_param_types))
197 : {
198 54 : if (isCompoundRealScalarType(_fixed_vector_input_param_types[i]))
199 : {
200 : // Ensure that each compound real scalar value is represented as Moose::dim Real values
201 0 : if (_fixed_vector_input_param_values[i].size() % Moose::dim != 0)
202 0 : paramError("fixed_vector_input_param_values",
203 : "This parameter must have a size that is consistent with "
204 : "fixed_vector_input_param_names. Note that each REALVECTORVALUE or POINT type "
205 : "parameter must be represented as ",
206 0 : std::to_string(Moose::dim),
207 : " separate values instead of 1.");
208 0 : auto unit_fixed_vector_input_param_values_tmp(_fixed_vector_input_param_values[i]);
209 0 : _fixed_vector_input_param_values[i].resize(unit_fixed_vector_input_param_values_tmp.size() /
210 : Moose::dim);
211 0 : for (const auto j : index_range(_fixed_vector_input_param_values[i]))
212 0 : _fixed_vector_input_param_values[i][j] = MooseUtils::join(
213 0 : unit_fixed_vector_input_param_values_tmp.begin() + j * Moose::dim,
214 0 : unit_fixed_vector_input_param_values_tmp.begin() + j * Moose::dim + Moose::dim,
215 0 : " ");
216 0 : }
217 : }
218 :
219 : // Sanity check for the batch input parameters
220 208 : checkVectorParamAndMultiMooseEnumLength<std::string>("batch_scalar_input_param_names",
221 : "batch_scalar_input_param_types");
222 : // The compound real scalar value type does not alter the length of
223 : // 'batch_scalar_input_param_values'
224 204 : checkVectorParamsSameLength<std::string, std::vector<std::string>>(
225 : "batch_scalar_input_param_names", "batch_scalar_input_param_values");
226 : // But we still need to process the affected elements
227 338 : for (const auto i : index_range(_batch_scalar_input_param_types))
228 : {
229 142 : if (isCompoundRealScalarType(_batch_scalar_input_param_types[i]))
230 : {
231 : // Ensure that each compound real scalar value is represented as Moose::dim Real values
232 14 : if (_batch_scalar_input_param_values[i].size() % Moose::dim != 0)
233 4 : paramError("batch_scalar_input_param_values",
234 : "This parameter must have a size that is consistent with "
235 : "batch_scalar_input_param_names. Note that each REALVECTORVALUE or POINT type "
236 : "parameter must be represented as ",
237 4 : std::to_string(Moose::dim),
238 : " separate values instead of 1.");
239 10 : auto unit_batch_scalar_input_param_values_tmp(_batch_scalar_input_param_values[i]);
240 10 : _batch_scalar_input_param_values[i].resize(unit_batch_scalar_input_param_values_tmp.size() /
241 : 3);
242 50 : for (const auto j : index_range(_batch_scalar_input_param_values[i]))
243 200 : _batch_scalar_input_param_values[i][j] = MooseUtils::join(
244 40 : unit_batch_scalar_input_param_values_tmp.begin() + j * Moose::dim,
245 80 : unit_batch_scalar_input_param_values_tmp.begin() + j * Moose::dim + Moose::dim,
246 40 : " ");
247 10 : }
248 : }
249 :
250 196 : checkVectorParamAndMultiMooseEnumLength<std::string>("batch_vector_input_param_names",
251 : "batch_vector_input_param_types");
252 : /// The compound real scalar value type does not alter the length of 'batch_vector_input_param_values'
253 192 : checkVectorParamsSameLength<std::string, std::vector<std::vector<std::string>>>(
254 : "batch_vector_input_param_names", "batch_vector_input_param_values");
255 : // But we still need to process the affected elements
256 320 : for (const auto i : index_range(_batch_vector_input_param_types))
257 : {
258 136 : if (isCompoundRealScalarType(_batch_vector_input_param_types[i]))
259 : {
260 48 : for (const auto j : index_range(_batch_vector_input_param_values[i]))
261 : {
262 : // Ensure that each compound real scalar value is represented as Moose::dim Real values
263 38 : if (_batch_vector_input_param_values[i][j].size() % Moose::dim != 0)
264 4 : paramError("batch_vector_input_param_values",
265 : "This parameter must have a size that is consistent with "
266 : "batch_vector_input_param_names. Note that each REALVECTORVALUE or POINT type "
267 : "parameter must be represented as ",
268 : Moose::dim,
269 : " separate values instead of 1.");
270 34 : auto unit_batch_vector_input_param_values_tmp(_batch_vector_input_param_values[i][j]);
271 68 : _batch_vector_input_param_values[i][j].resize(
272 34 : unit_batch_vector_input_param_values_tmp.size() / 3);
273 136 : for (const auto k : index_range(_batch_vector_input_param_values[i][j]))
274 510 : _batch_vector_input_param_values[i][j][k] = MooseUtils::join(
275 102 : unit_batch_vector_input_param_values_tmp.begin() + k * Moose::dim,
276 204 : unit_batch_vector_input_param_values_tmp.begin() + k * Moose::dim + Moose::dim,
277 102 : " ");
278 34 : }
279 : }
280 : }
281 :
282 : // At least we want this action to create one mesh generator
283 184 : if (_batch_scalar_input_param_names.empty() && _batch_vector_input_param_names.empty())
284 4 : mooseError("BatchMeshGeneratorAction: " + _name +
285 : ", batch_scalar_input_param_names and batch_vector_input_param_names cannot be "
286 : "empty at the same time.");
287 :
288 : // If the previous check is passed, batch_params_sizes will not be empty
289 : // But we need to check if any element of the batch_params_values are empty
290 180 : std::set<unsigned int> batch_params_sizes;
291 310 : for (const auto & unit_batch_scalar_param_values : _batch_scalar_input_param_values)
292 : {
293 134 : if (unit_batch_scalar_param_values.empty())
294 4 : paramError("batch_scalar_input_param_values",
295 : "this parameter cannot contain empty elements.");
296 130 : batch_params_sizes.emplace(unit_batch_scalar_param_values.size());
297 : }
298 304 : for (const auto & unit_batch_vector_param_values : _batch_vector_input_param_values)
299 : {
300 132 : if (unit_batch_vector_param_values.empty())
301 4 : paramError("batch_vector_input_param_values",
302 : "this parameter cannot contain empty elements.");
303 128 : batch_params_sizes.emplace(unit_batch_vector_param_values.size());
304 : }
305 :
306 : // Then for the corresponding method, the sizes of the batch_params_values should be the same
307 224 : if (_multi_batch_params_method == MultiBatchParamsMethod::corresponding &&
308 52 : batch_params_sizes.size() > 1)
309 4 : mooseError("BatchMeshGeneratorAction: " + _name +
310 : ", elements of batch_scalar_input_param_values and batch_vector_input_param_values "
311 : "must have the same size in corresponding mode.");
312 :
313 : // Decomposed index cannot be used with the corresponding method
314 168 : if (_use_decomposed_index && _multi_batch_params_method == MultiBatchParamsMethod::corresponding)
315 4 : paramError("use_decomposed_index",
316 : "Decomposed index cannot be used with the corresponding method.");
317 : // Check the parameter types are given correctly here so that we do not need to do it when setting
318 : // the values.
319 164 : auto set_params = _app.getFactory().getValidParams(_mesh_generator_type);
320 : // batch scalar input parameters
321 164 : checkInputParametersTypes(set_params,
322 : "batch_scalar_input_param_names",
323 164 : _batch_scalar_input_param_names,
324 164 : _batch_scalar_input_param_types);
325 : // fix scalar input parameters
326 164 : checkInputParametersTypes(set_params,
327 : "fixed_scalar_input_param_names",
328 164 : _fixed_scalar_input_param_names,
329 164 : _fixed_scalar_input_param_types);
330 : // batch vector input parameters
331 164 : checkInputParametersTypes(set_params,
332 : "batch_vector_input_param_names",
333 164 : _batch_vector_input_param_names,
334 164 : _batch_vector_input_param_types,
335 164 : true);
336 : // fix vector input parameters
337 160 : checkInputParametersTypes(set_params,
338 : "fixed_vector_input_param_names",
339 160 : _fixed_vector_input_param_names,
340 160 : _fixed_vector_input_param_types,
341 160 : true);
342 160 : }
343 :
344 : void
345 160 : BatchMeshGeneratorAction::act()
346 : {
347 160 : if (_current_task == "add_mesh_generator")
348 160 : addMeshGenerators();
349 160 : }
350 :
351 : void
352 160 : BatchMeshGeneratorAction::addMeshGenerators()
353 : {
354 160 : std::vector<std::vector<std::string>> processed_batch_scalar_input_param_values;
355 160 : std::vector<std::vector<std::vector<std::string>>> processed_batch_vector_input_param_values;
356 : // generate the decomposed indices for the cartesian product method
357 160 : std::vector<std::vector<unsigned int>> processed_batch_indices;
358 160 : if (_multi_batch_params_method == MultiBatchParamsMethod::corresponding)
359 : {
360 40 : processed_batch_scalar_input_param_values = _batch_scalar_input_param_values;
361 40 : processed_batch_vector_input_param_values = _batch_vector_input_param_values;
362 40 : if (_use_decomposed_index)
363 : {
364 0 : processed_batch_indices.push_back(std::vector<unsigned int>(
365 0 : processed_batch_vector_input_param_values.empty()
366 0 : ? processed_batch_scalar_input_param_values.front().size()
367 0 : : processed_batch_vector_input_param_values.front().size()));
368 0 : std::iota(processed_batch_indices.back().begin(), processed_batch_indices.back().end(), 0);
369 : }
370 : }
371 : else // cartesian_product
372 : {
373 : // We basically need to reconstruct the corresponding parameters based on the cartesian product
374 : // algorithm
375 210 : for (const auto i : index_range(_batch_scalar_input_param_values))
376 : {
377 : // For the first element, just copy the parameters
378 90 : if (processed_batch_scalar_input_param_values.empty())
379 : {
380 70 : processed_batch_scalar_input_param_values.push_back(_batch_scalar_input_param_values[i]);
381 70 : if (_use_decomposed_index)
382 : {
383 20 : processed_batch_indices.push_back(
384 40 : std::vector<unsigned int>(_batch_scalar_input_param_values[i].size()));
385 40 : std::iota(
386 40 : processed_batch_indices.back().begin(), processed_batch_indices.back().end(), 0);
387 : }
388 : }
389 : else
390 : {
391 20 : const unsigned int num_new_batch_params = _batch_scalar_input_param_values[i].size();
392 : const unsigned int num_processed_batch_params =
393 20 : processed_batch_scalar_input_param_values.front().size();
394 : // All the elements in the processed_batch_scalar_input_param_values need to be duplicated
395 : // for num_new_batch_params times
396 20 : for (auto & unit_processed_batch_scalar_input_param_values :
397 60 : processed_batch_scalar_input_param_values)
398 : {
399 20 : auto temp_params = unit_processed_batch_scalar_input_param_values;
400 40 : for (unsigned int j = 1; j < num_new_batch_params; j++)
401 : {
402 40 : unit_processed_batch_scalar_input_param_values.insert(
403 40 : unit_processed_batch_scalar_input_param_values.end(),
404 : temp_params.begin(),
405 : temp_params.end());
406 : }
407 20 : }
408 20 : if (_use_decomposed_index)
409 : {
410 : // Same as the composed indices
411 20 : for (auto & unit_processed_batch_indices : processed_batch_indices)
412 : {
413 10 : auto temp_indices = unit_processed_batch_indices;
414 20 : for (unsigned int j = 1; j < num_new_batch_params; j++)
415 : {
416 20 : unit_processed_batch_indices.insert(
417 20 : unit_processed_batch_indices.end(), temp_indices.begin(), temp_indices.end());
418 : }
419 10 : }
420 : }
421 :
422 : // Then, add a new element to the processed_batch_scalar_input_param_values by repeating
423 : // each element in _batch_scalar_input_param_values[i] for num_processed_batch_params times
424 20 : processed_batch_scalar_input_param_values.push_back({});
425 20 : for (const auto & unit_batch_scalar_input_param_values :
426 80 : _batch_scalar_input_param_values[i])
427 120 : for (unsigned int j = 0; j < num_processed_batch_params; j++)
428 80 : processed_batch_scalar_input_param_values.back().push_back(
429 : unit_batch_scalar_input_param_values);
430 20 : if (_use_decomposed_index)
431 : {
432 : // Same as the composed indices
433 10 : processed_batch_indices.push_back({});
434 10 : for (const auto & unit_batch_scalar_input_param_values_index :
435 40 : index_range(_batch_scalar_input_param_values[i]))
436 60 : for (unsigned int j = 0; j < num_processed_batch_params; j++)
437 40 : processed_batch_indices.back().push_back(unit_batch_scalar_input_param_values_index);
438 : }
439 : }
440 : }
441 190 : for (const auto i : index_range(_batch_vector_input_param_values))
442 : {
443 : // For the first element, just copy the parameters
444 70 : if (processed_batch_vector_input_param_values.empty())
445 : {
446 60 : if (processed_batch_scalar_input_param_values.empty())
447 : {
448 : // if no batch scalar input parameters are used
449 : // we just need to initiate the processed_batch_vector_input_param_values as the first one
450 : // to fill
451 50 : processed_batch_vector_input_param_values.push_back(_batch_vector_input_param_values[i]);
452 50 : if (_use_decomposed_index)
453 : {
454 10 : processed_batch_indices.push_back(
455 20 : std::vector<unsigned int>(_batch_vector_input_param_values[i].size()));
456 20 : std::iota(
457 20 : processed_batch_indices.back().begin(), processed_batch_indices.back().end(), 0);
458 : }
459 : }
460 : else
461 : {
462 10 : processed_batch_vector_input_param_values.push_back({});
463 : // if there are batch scalar input parameters, then each element needs to be duplicated
464 : // for that amount of times
465 10 : for (const auto & unit_batch_vector_input_param_values :
466 40 : _batch_vector_input_param_values[i])
467 60 : for (unsigned int j = 0; j < processed_batch_scalar_input_param_values.front().size();
468 : j++)
469 40 : processed_batch_vector_input_param_values.back().push_back(
470 : unit_batch_vector_input_param_values);
471 : // Then the scalar input parameters need to be duplicated for the number of elements in
472 : // the processed_batch_vector_input_param_values
473 10 : for (auto & unit_processed_batch_scalar_input_param_values :
474 30 : processed_batch_scalar_input_param_values)
475 : {
476 10 : auto temp_params = unit_processed_batch_scalar_input_param_values;
477 40 : for (unsigned int j = 1; j < processed_batch_vector_input_param_values.back().size();
478 : j++)
479 : {
480 60 : unit_processed_batch_scalar_input_param_values.insert(
481 60 : unit_processed_batch_scalar_input_param_values.end(),
482 : temp_params.begin(),
483 : temp_params.end());
484 : }
485 10 : }
486 10 : if (_use_decomposed_index)
487 : {
488 : // Add the indices for the first batch vector input parameter
489 10 : processed_batch_indices.push_back({});
490 10 : for (const auto & unit_batch_vector_input_param_values_index :
491 40 : index_range(_batch_vector_input_param_values[i]))
492 60 : for (unsigned int j = 0; j < processed_batch_indices.front().size(); j++)
493 80 : processed_batch_indices.back().push_back(
494 40 : unit_batch_vector_input_param_values_index);
495 : // Duplicate the indices for the batch scalar input parameters
496 20 : for (unsigned int k = 1; k < processed_batch_indices.size(); k++)
497 : {
498 10 : auto & unit_processed_batch_indices = processed_batch_indices[k - 1];
499 10 : auto temp_indices = unit_processed_batch_indices;
500 20 : for (unsigned int j = 1; j < _batch_vector_input_param_values[i].size(); j++)
501 : {
502 20 : unit_processed_batch_indices.insert(
503 20 : unit_processed_batch_indices.end(), temp_indices.begin(), temp_indices.end());
504 : }
505 10 : }
506 : }
507 : }
508 : }
509 : else
510 : {
511 10 : const unsigned int num_new_batch_params = _batch_vector_input_param_values[i].size();
512 : const unsigned int num_processed_batch_params =
513 10 : processed_batch_vector_input_param_values.front().size();
514 : // All the elements in the processed_batch_vector_input_param_values need to be duplicated
515 : // for num_new_batch_params times
516 10 : for (auto & unit_processed_batch_vector_input_param_values :
517 30 : processed_batch_vector_input_param_values)
518 : {
519 10 : auto temp_params = unit_processed_batch_vector_input_param_values;
520 20 : for (unsigned int j = 1; j < num_new_batch_params; j++)
521 : {
522 20 : unit_processed_batch_vector_input_param_values.insert(
523 20 : unit_processed_batch_vector_input_param_values.end(),
524 : temp_params.begin(),
525 : temp_params.end());
526 : }
527 10 : }
528 10 : if (_use_decomposed_index)
529 : {
530 : // Same for the decomposed indices
531 20 : for (auto & unit_processed_batch_indices : processed_batch_indices)
532 : {
533 10 : auto temp_indices = unit_processed_batch_indices;
534 20 : for (unsigned int j = 1; j < num_new_batch_params; j++)
535 : {
536 20 : unit_processed_batch_indices.insert(
537 20 : unit_processed_batch_indices.end(), temp_indices.begin(), temp_indices.end());
538 : }
539 10 : }
540 : }
541 : // if there are also batch scalar input parameters, it also needs to be duplicated
542 10 : for (auto & unit_processed_batch_scalar_input_param_values :
543 20 : processed_batch_scalar_input_param_values)
544 : {
545 0 : auto temp_params = unit_processed_batch_scalar_input_param_values;
546 0 : for (unsigned int j = 1; j < num_new_batch_params; j++)
547 : {
548 0 : unit_processed_batch_scalar_input_param_values.insert(
549 0 : unit_processed_batch_scalar_input_param_values.end(),
550 : temp_params.begin(),
551 : temp_params.end());
552 : }
553 0 : }
554 : // Then, add a new element to the processed_batch_vector_input_param_values by repeating
555 : // each element in _batch_vector_input_param_values[i] for num_processed_batch_params times
556 10 : processed_batch_vector_input_param_values.push_back({});
557 10 : for (const auto & unit_batch_vector_input_param_values :
558 40 : _batch_vector_input_param_values[i])
559 60 : for (unsigned int j = 0; j < num_processed_batch_params; j++)
560 40 : processed_batch_vector_input_param_values.back().push_back(
561 : unit_batch_vector_input_param_values);
562 10 : if (_use_decomposed_index)
563 : {
564 : // Same for the decomposed indices
565 10 : processed_batch_indices.push_back({});
566 10 : for (const auto & unit_batch_vector_input_param_values_index :
567 40 : index_range(_batch_vector_input_param_values[i]))
568 60 : for (unsigned int j = 0; j < num_processed_batch_params; j++)
569 40 : processed_batch_indices.back().push_back(unit_batch_vector_input_param_values_index);
570 : }
571 : }
572 : }
573 : }
574 :
575 : // Now, we can add the mesh generators by looping through the processed params
576 : const unsigned int num_batch_params =
577 160 : processed_batch_vector_input_param_values.empty()
578 80 : ? processed_batch_scalar_input_param_values.front().size()
579 240 : : processed_batch_vector_input_param_values.front().size();
580 750 : for (const auto i : make_range(num_batch_params))
581 : {
582 590 : auto params = _app.getFactory().getValidParams(_mesh_generator_type);
583 1070 : for (const auto j : index_range(_batch_scalar_input_param_values))
584 480 : setScalarParams(params,
585 480 : _batch_scalar_input_param_names[j],
586 480 : _batch_scalar_input_param_types[j],
587 480 : processed_batch_scalar_input_param_values[j][i]);
588 980 : for (const auto j : index_range(_batch_vector_input_param_values))
589 390 : setVectorParams(params,
590 390 : _batch_vector_input_param_names[j],
591 390 : _batch_vector_input_param_types[j],
592 390 : processed_batch_vector_input_param_values[j][i]);
593 1580 : for (const auto j : index_range(_fixed_scalar_input_param_names))
594 990 : setScalarParams(params,
595 990 : _fixed_scalar_input_param_names[j],
596 990 : _fixed_scalar_input_param_types[j],
597 990 : _fixed_scalar_input_param_values[j]);
598 780 : for (const auto j : index_range(_fixed_vector_input_param_names))
599 190 : setVectorParams(params,
600 190 : _fixed_vector_input_param_names[j],
601 190 : _fixed_vector_input_param_types[j],
602 190 : _fixed_vector_input_param_values[j]);
603 :
604 590 : std::string mesh_index;
605 590 : if (_use_decomposed_index)
606 360 : for (const auto & process_batch_index : processed_batch_indices)
607 240 : mesh_index += '_' + std::to_string(process_batch_index[i]);
608 : else
609 470 : mesh_index = "_" + std::to_string(i);
610 :
611 590 : _app.getMeshGeneratorSystem().addMeshGenerator(
612 590 : _mesh_generator_type, _mesh_name_prefix + mesh_index, params);
613 590 : }
614 160 : }
615 :
616 : void
617 1470 : BatchMeshGeneratorAction::setScalarParams(InputParameters & params,
618 : const std::string & param_name,
619 : const ParameterType & param_type,
620 : const std::string & param_value) const
621 : {
622 1470 : switch (param_type)
623 : {
624 40 : case (ParameterType::REAL):
625 40 : params.set<Real>(param_name) = MooseUtils::convert<Real>(param_value);
626 40 : break;
627 0 : case (ParameterType::SHORT):
628 0 : params.set<short>(param_name) = MooseUtils::convert<short>(param_value);
629 0 : break;
630 0 : case (ParameterType::USHORT):
631 0 : params.set<unsigned short>(param_name) = MooseUtils::convert<unsigned short>(param_value);
632 0 : break;
633 0 : case (ParameterType::INT):
634 0 : params.set<int>(param_name) = MooseUtils::convert<int>(param_value);
635 0 : break;
636 480 : case (ParameterType::UINT):
637 480 : params.set<unsigned int>(param_name) = MooseUtils::convert<unsigned int>(param_value);
638 480 : break;
639 0 : case (ParameterType::LONG):
640 0 : params.set<long>(param_name) = MooseUtils::convert<long>(param_value);
641 0 : break;
642 0 : case (ParameterType::ULONG):
643 0 : params.set<unsigned long>(param_name) = MooseUtils::convert<unsigned long>(param_value);
644 0 : break;
645 0 : case (ParameterType::LONGLONG):
646 0 : params.set<long long>(param_name) = MooseUtils::convert<long long>(param_value);
647 0 : break;
648 0 : case (ParameterType::ULONGLONG):
649 0 : params.set<unsigned long long>(param_name) =
650 0 : MooseUtils::convert<unsigned long long>(param_value);
651 0 : break;
652 0 : case (ParameterType::DOFIDTYPE):
653 0 : params.set<dof_id_type>(param_name) = MooseUtils::convert<dof_id_type>(param_value);
654 0 : break;
655 0 : case (ParameterType::BDRYIDTYPE):
656 0 : params.set<boundary_id_type>(param_name) = MooseUtils::convert<boundary_id_type>(param_value);
657 0 : break;
658 0 : case (ParameterType::SDIDTYPE):
659 0 : params.set<subdomain_id_type>(param_name) =
660 0 : MooseUtils::convert<subdomain_id_type>(param_value);
661 0 : break;
662 490 : case (ParameterType::ENUM):
663 490 : params.set<MooseEnum>(param_name) = param_value;
664 490 : break;
665 0 : case (ParameterType::STRING):
666 0 : params.set<std::string>(param_name) = param_value;
667 0 : break;
668 0 : case (ParameterType::SDNAME):
669 0 : params.set<SubdomainName>(param_name) = param_value;
670 0 : break;
671 0 : case (ParameterType::BDRYNAME):
672 0 : params.set<BoundaryName>(param_name) = param_value;
673 0 : break;
674 140 : case (ParameterType::MGNAME):
675 140 : params.set<MeshGeneratorName>(param_name) = param_value;
676 140 : break;
677 20 : case (ParameterType::MFNAME):
678 20 : params.set<MeshFileName>(param_name) = param_value;
679 20 : break;
680 240 : case (ParameterType::BOOL):
681 240 : hit::toBool(param_value, ¶ms.set<bool>(param_name));
682 240 : break;
683 60 : case (ParameterType::REALVECTORVALUE):
684 60 : params.set<RealVectorValue>(param_name) =
685 60 : convertStringToCompoundRealScalar<RealVectorValue>(param_value);
686 60 : break;
687 0 : case (ParameterType::POINT):
688 0 : params.set<Point>(param_name) = convertStringToCompoundRealScalar<Point>(param_value);
689 0 : break;
690 1470 : default:
691 : mooseAssert(false,
692 : "impossible situation."); // as we use MultiMooseEnum to ensure the type is valid
693 : }
694 1470 : }
695 :
696 : void
697 580 : BatchMeshGeneratorAction::setVectorParams(InputParameters & params,
698 : const std::string & param_name,
699 : const ParameterType & param_type,
700 : const std::vector<std::string> & param_value) const
701 : {
702 580 : switch (param_type)
703 : {
704 120 : case (ParameterType::REAL):
705 120 : convertAndSetNumericVector<Real>(params, param_name, param_value);
706 120 : break;
707 0 : case (ParameterType::SHORT):
708 0 : convertAndSetNumericVector<short>(params, param_name, param_value);
709 0 : break;
710 120 : case (ParameterType::USHORT):
711 120 : convertAndSetNumericVector<unsigned short>(params, param_name, param_value);
712 120 : break;
713 0 : case (ParameterType::INT):
714 0 : convertAndSetNumericVector<int>(params, param_name, param_value);
715 0 : break;
716 120 : case (ParameterType::UINT):
717 120 : convertAndSetNumericVector<unsigned int>(params, param_name, param_value);
718 120 : break;
719 0 : case (ParameterType::LONG):
720 0 : convertAndSetNumericVector<long>(params, param_name, param_value);
721 0 : break;
722 0 : case (ParameterType::ULONG):
723 0 : convertAndSetNumericVector<unsigned long>(params, param_name, param_value);
724 0 : break;
725 0 : case (ParameterType::LONGLONG):
726 0 : convertAndSetNumericVector<long long>(params, param_name, param_value);
727 0 : break;
728 0 : case (ParameterType::ULONGLONG):
729 0 : convertAndSetNumericVector<unsigned long long>(params, param_name, param_value);
730 0 : break;
731 30 : case (ParameterType::DOFIDTYPE):
732 30 : convertAndSetNumericVector<dof_id_type>(params, param_name, param_value);
733 30 : break;
734 0 : case (ParameterType::BDRYIDTYPE):
735 0 : convertAndSetNumericVector<boundary_id_type>(params, param_name, param_value);
736 0 : break;
737 0 : case (ParameterType::SDIDTYPE):
738 0 : convertAndSetNumericVector<subdomain_id_type>(params, param_name, param_value);
739 0 : break;
740 0 : case (ParameterType::ENUM):
741 0 : params.set<MultiMooseEnum>(param_name) = param_value;
742 0 : break;
743 0 : case (ParameterType::STRING):
744 0 : params.set<std::vector<std::string>>(param_name) = param_value;
745 0 : break;
746 80 : case (ParameterType::SDNAME):
747 80 : convertAndSetStringLikeVector<SubdomainName>(params, param_name, param_value);
748 80 : break;
749 80 : case (ParameterType::BDRYNAME):
750 80 : convertAndSetStringLikeVector<BoundaryName>(params, param_name, param_value);
751 80 : break;
752 0 : case (ParameterType::MGNAME):
753 0 : convertAndSetStringLikeVector<MeshGeneratorName>(params, param_name, param_value);
754 0 : break;
755 0 : case (ParameterType::MFNAME):
756 0 : convertAndSetStringLikeVector<MeshFileName>(params, param_name, param_value);
757 0 : break;
758 0 : case (ParameterType::BOOL):
759 : {
760 0 : std::vector<bool> values(param_value.size());
761 0 : std::transform(param_value.begin(),
762 : param_value.end(),
763 : values.begin(),
764 0 : [](const std::string & val)
765 : {
766 : bool tmp;
767 0 : hit::toBool(val, &tmp);
768 0 : return tmp;
769 : });
770 0 : params.set<std::vector<bool>>(param_name) = values;
771 0 : break;
772 0 : }
773 0 : case (ParameterType::REALVECTORVALUE):
774 0 : convertAndSetCompoundRealScalarVector<RealVectorValue>(params, param_name, param_value);
775 0 : break;
776 30 : case (ParameterType::POINT):
777 30 : convertAndSetCompoundRealScalarVector<Point>(params, param_name, param_value);
778 30 : break;
779 580 : default:
780 : mooseAssert(false,
781 : "impossible situation."); // as we use MultiMooseEnum to ensure the type is valid
782 : }
783 580 : }
784 :
785 : template <typename T>
786 : void
787 390 : BatchMeshGeneratorAction::convertAndSetNumericVector(
788 : InputParameters & params,
789 : const std::string & param_name,
790 : const std::vector<std::string> & param_value) const
791 : {
792 390 : std::vector<T> values(param_value.size());
793 390 : std::transform(param_value.begin(),
794 : param_value.end(),
795 : values.begin(),
796 490 : [](const std::string & val) { return MooseUtils::convert<T>(val); });
797 390 : params.set<std::vector<T>>(param_name) = values;
798 390 : }
799 :
800 : template <typename T>
801 : void
802 30 : BatchMeshGeneratorAction::convertAndSetCompoundRealScalarVector(
803 : InputParameters & params,
804 : const std::string & param_name,
805 : const std::vector<std::string> & param_value) const
806 : {
807 30 : std::vector<T> values(param_value.size());
808 30 : std::transform(param_value.begin(),
809 : param_value.end(),
810 : values.begin(),
811 90 : [this](const std::string & val)
812 90 : { return convertStringToCompoundRealScalar<T>(val); });
813 30 : params.set<std::vector<T>>(param_name) = values;
814 30 : }
815 :
816 : template <typename T>
817 : void
818 160 : BatchMeshGeneratorAction::convertAndSetStringLikeVector(
819 : InputParameters & params,
820 : const std::string & param_name,
821 : const std::vector<std::string> & param_value) const
822 : {
823 160 : std::vector<T> values(param_value.size());
824 160 : std::transform(param_value.begin(),
825 : param_value.end(),
826 : values.begin(),
827 400 : [](const std::string & val) { return T(val); });
828 160 : params.set<std::vector<T>>(param_name) = values;
829 160 : }
830 :
831 : void
832 652 : BatchMeshGeneratorAction::checkInputParametersTypes(const InputParameters & params,
833 : const std::string & action_input_param_name,
834 : const std::vector<std::string> & param_names,
835 : const std::vector<ParameterType> & param_types,
836 : const bool & is_vector) const
837 : {
838 1208 : for (const auto i : index_range(param_names))
839 : {
840 560 : switch (param_types[i])
841 : {
842 40 : case (ParameterType::REAL):
843 40 : checkInputParameterType<Real>(params, action_input_param_name, param_names[i], is_vector);
844 40 : break;
845 0 : case (ParameterType::SHORT):
846 0 : checkInputParameterType<short>(params, action_input_param_name, param_names[i], is_vector);
847 0 : break;
848 30 : case (ParameterType::USHORT):
849 30 : checkInputParameterType<unsigned short>(
850 30 : params, action_input_param_name, param_names[i], is_vector);
851 30 : break;
852 0 : case (ParameterType::INT):
853 0 : checkInputParameterType<int>(params, action_input_param_name, param_names[i], is_vector);
854 0 : break;
855 158 : case (ParameterType::UINT):
856 158 : checkInputParameterType<unsigned int>(
857 158 : params, action_input_param_name, param_names[i], is_vector);
858 154 : break;
859 0 : case (ParameterType::LONG):
860 0 : checkInputParameterType<long>(params, action_input_param_name, param_names[i], is_vector);
861 0 : break;
862 0 : case (ParameterType::ULONG):
863 0 : checkInputParameterType<unsigned long>(
864 0 : params, action_input_param_name, param_names[i], is_vector);
865 0 : break;
866 0 : case (ParameterType::LONGLONG):
867 0 : checkInputParameterType<long long>(
868 0 : params, action_input_param_name, param_names[i], is_vector);
869 0 : break;
870 0 : case (ParameterType::ULONGLONG):
871 0 : checkInputParameterType<unsigned long long>(
872 0 : params, action_input_param_name, param_names[i], is_vector);
873 0 : break;
874 10 : case (ParameterType::DOFIDTYPE):
875 10 : checkInputParameterType<dof_id_type>(
876 10 : params, action_input_param_name, param_names[i], is_vector);
877 10 : break;
878 0 : case (ParameterType::BDRYIDTYPE):
879 0 : checkInputParameterType<boundary_id_type>(
880 0 : params, action_input_param_name, param_names[i], is_vector);
881 0 : break;
882 0 : case (ParameterType::SDIDTYPE):
883 0 : checkInputParameterType<subdomain_id_type>(
884 0 : params, action_input_param_name, param_names[i], is_vector);
885 0 : break;
886 134 : case (ParameterType::ENUM):
887 134 : if (is_vector)
888 0 : checkInputParameterType<MultiMooseEnum>(
889 0 : params, action_input_param_name, param_names[i], false);
890 : else
891 134 : checkInputParameterType<MooseEnum>(
892 268 : params, action_input_param_name, param_names[i], false);
893 134 : break;
894 0 : case (ParameterType::STRING):
895 0 : checkInputParameterType<std::string>(
896 0 : params, action_input_param_name, param_names[i], is_vector);
897 0 : break;
898 20 : case (ParameterType::SDNAME):
899 20 : checkInputParameterType<SubdomainName>(
900 20 : params, action_input_param_name, param_names[i], is_vector);
901 20 : break;
902 20 : case (ParameterType::BDRYNAME):
903 20 : checkInputParameterType<BoundaryName>(
904 20 : params, action_input_param_name, param_names[i], is_vector);
905 20 : break;
906 40 : case (ParameterType::MGNAME):
907 40 : checkInputParameterType<MeshGeneratorName>(
908 40 : params, action_input_param_name, param_names[i], is_vector);
909 40 : break;
910 10 : case (ParameterType::MFNAME):
911 10 : checkInputParameterType<MeshFileName>(
912 10 : params, action_input_param_name, param_names[i], is_vector);
913 10 : break;
914 68 : case (ParameterType::BOOL):
915 68 : checkInputParameterType<bool>(params, action_input_param_name, param_names[i], is_vector);
916 68 : break;
917 20 : case (ParameterType::REALVECTORVALUE):
918 20 : checkInputParameterType<RealVectorValue>(
919 20 : params, action_input_param_name, param_names[i], is_vector);
920 20 : break;
921 10 : case (ParameterType::POINT):
922 10 : checkInputParameterType<Point>(params, action_input_param_name, param_names[i], is_vector);
923 10 : break;
924 556 : default:
925 : mooseAssert(
926 : false,
927 : "impossible situation."); // as we use MultiMooseEnum to ensure the type is valid
928 : }
929 : }
930 648 : }
931 :
932 : template <typename T>
933 : void
934 560 : BatchMeshGeneratorAction::checkInputParameterType(const InputParameters & params,
935 : const std::string & action_input_param_name,
936 : const std::string & param_name,
937 : const bool & is_vector) const
938 : {
939 1116 : if ((is_vector && !params.isType<std::vector<T>>(param_name)) ||
940 556 : (!is_vector && !params.isType<T>(param_name)))
941 4 : paramError(action_input_param_name,
942 : "the input parameter, " + param_name + ", has the wrong type. It should be " +
943 : params.type(param_name) + ".");
944 556 : }
945 :
946 : template <typename T>
947 : T
948 150 : BatchMeshGeneratorAction::convertStringToCompoundRealScalar(const std::string & str) const
949 : {
950 150 : const auto split_str = MooseUtils::split(str, " ");
951 : mooseAssert(split_str.size() == Moose::dim,
952 : "string used for compound real scalar conversion should contain three elements.");
953 150 : T ret(MooseUtils::convert<Real>(split_str[0]));
954 450 : for (const auto i :
955 150 : make_range(static_cast<std::remove_cv_t<decltype(Moose::dim)>>(1), Moose::dim))
956 300 : ret(i) = MooseUtils::convert<Real>(split_str[i]);
957 300 : return ret;
958 150 : }
959 :
960 : bool
961 748 : BatchMeshGeneratorAction::isCompoundRealScalarType(const ParameterType & param_type) const
962 : {
963 748 : const auto valid_types = {ParameterType::REALVECTORVALUE, ParameterType::POINT};
964 748 : return std::count(valid_types.begin(), valid_types.end(), param_type);
965 : }
|