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 447 : BatchMeshGeneratorAction::validParams()
26 : {
27 447 : InputParameters params = Action::validParams();
28 :
29 447 : params.set<std::string>("type") = "BatchMeshGeneratorAction";
30 :
31 447 : params.addClassDescription("Batch generate meshes using actions.");
32 447 : params.addRequiredParam<std::string>("mesh_generator_type",
33 : "Type of the mesh generator to be batch generated.");
34 447 : params.addRequiredParam<std::string>("mesh_name_prefix",
35 : "Prefix name of the meshes to be batch generated.");
36 :
37 1341 : params.addParam<std::vector<std::string>>("batch_scalar_input_param_names",
38 894 : 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 447 : "");
44 447 : 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 447 : 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 1341 : params.addParam<std::vector<std::string>>("batch_vector_input_param_names",
54 894 : std::vector<std::string>(),
55 : "Name of the vector input parameters to be altered.");
56 447 : params.addParam<MultiMooseEnum>("batch_vector_input_param_types",
57 : default_types,
58 : "Type of the vector input parameters to be altered.");
59 447 : 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 447 : MooseEnum multi_batch_params_method("corresponding cartesian_product", "cartesian_product");
65 447 : params.addParam<MooseEnum>("multi_batch_params_method",
66 : multi_batch_params_method,
67 894 : "Method to generate multiple batch parameters.Options: " +
68 894 : multi_batch_params_method.getRawNames());
69 :
70 447 : params.addParam<std::vector<std::string>>(
71 : "fixed_scalar_input_param_names", {}, "Names of the input parameters to be fixed.");
72 447 : params.addParam<MultiMooseEnum>("fixed_scalar_input_param_types",
73 : default_types,
74 : "Types of the input parameters to be fixed.");
75 447 : params.addParam<std::vector<std::string>>(
76 : "fixed_scalar_input_param_values", {}, "Values of the input parameters to be fixed.");
77 447 : params.addParam<std::vector<std::string>>(
78 : "fixed_vector_input_param_names", {}, "Names of the input vector parameters to be fixed.");
79 447 : params.addParam<MultiMooseEnum>("fixed_vector_input_param_types",
80 : default_types,
81 : "Types of the input vector parameters to be fixed.");
82 447 : params.addParam<std::vector<std::vector<std::string>>>(
83 : "fixed_vector_input_param_values", {}, "Values of the input vector parameters to be fixed.");
84 1341 : params.addParam<bool>("use_decomposed_index",
85 894 : false,
86 : "Whether to use the decomposed index for the mesh name (only effective for "
87 : "the cartesian_product method).");
88 :
89 447 : 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 447 : 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 894 : return params;
101 447 : }
102 :
103 244 : BatchMeshGeneratorAction::BatchMeshGeneratorAction(const InputParameters & params)
104 : : Action(params),
105 : InputParametersChecksUtils<BatchMeshGeneratorAction>(this),
106 244 : _mesh_generator_type(getParam<std::string>("mesh_generator_type")),
107 244 : _mesh_name_prefix(getParam<std::string>("mesh_name_prefix")),
108 244 : _batch_scalar_input_param_names(
109 : getParam<std::vector<std::string>>("batch_scalar_input_param_names")),
110 586 : _batch_scalar_input_param_types(isParamValid("batch_scalar_input_param_types")
111 342 : ? getParam<MultiMooseEnum>("batch_scalar_input_param_types")
112 : .template getSetValueIDs<ParameterType>()
113 : : std::vector<ParameterType>()),
114 244 : _batch_scalar_input_param_values(
115 : getParam<std::vector<std::vector<std::string>>>("batch_scalar_input_param_values")),
116 244 : _batch_vector_input_param_names(
117 : getParam<std::vector<std::string>>("batch_vector_input_param_names")),
118 616 : _batch_vector_input_param_types(isParamValid("batch_vector_input_param_types")
119 372 : ? getParam<MultiMooseEnum>("batch_vector_input_param_types")
120 : .template getSetValueIDs<ParameterType>()
121 : : std::vector<ParameterType>()),
122 244 : _batch_vector_input_param_values(getParam<std::vector<std::vector<std::vector<std::string>>>>(
123 : "batch_vector_input_param_values")),
124 488 : _multi_batch_params_method(getParam<MooseEnum>("multi_batch_params_method")
125 244 : .template getEnum<MultiBatchParamsMethod>()),
126 244 : _fixed_scalar_input_param_names(
127 : getParam<std::vector<std::string>>("fixed_scalar_input_param_names")),
128 499 : _fixed_scalar_input_param_types(isParamValid("fixed_scalar_input_param_types")
129 255 : ? getParam<MultiMooseEnum>("fixed_scalar_input_param_types")
130 : .template getSetValueIDs<ParameterType>()
131 : : std::vector<ParameterType>()),
132 244 : _fixed_scalar_input_param_values(
133 : getParam<std::vector<std::string>>("fixed_scalar_input_param_values")),
134 244 : _fixed_vector_input_param_names(
135 : getParam<std::vector<std::string>>("fixed_vector_input_param_names")),
136 676 : _fixed_vector_input_param_types(isParamValid("fixed_vector_input_param_types")
137 432 : ? getParam<MultiMooseEnum>("fixed_vector_input_param_types")
138 : .template getSetValueIDs<ParameterType>()
139 : : std::vector<ParameterType>()),
140 244 : _fixed_vector_input_param_values(
141 : getParam<std::vector<std::vector<std::string>>>("fixed_vector_input_param_values")),
142 488 : _use_decomposed_index(getParam<bool>("use_decomposed_index"))
143 : {
144 : // Sanity check for the fixed input parameters
145 244 : checkVectorParamAndMultiMooseEnumLength<std::string>("fixed_scalar_input_param_names",
146 : "fixed_scalar_input_param_types");
147 : const auto fixed_scalar_real_compound_num =
148 240 : std::count_if(_fixed_scalar_input_param_types.begin(),
149 : _fixed_scalar_input_param_types.end(),
150 422 : [this](const ParameterType & type) { return isCompoundRealScalarType(type); });
151 240 : if (fixed_scalar_real_compound_num > 0)
152 : {
153 15 : if (_fixed_scalar_input_param_types.size() +
154 15 : (Moose::dim - 1) * fixed_scalar_real_compound_num !=
155 15 : _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 11 : auto fixed_scalar_input_param_values_tmp(_fixed_scalar_input_param_values);
165 11 : _fixed_scalar_input_param_values.resize(_fixed_scalar_input_param_types.size());
166 11 : unsigned int raw_value_ct = 0;
167 33 : for (const auto i : index_range(_fixed_scalar_input_param_types))
168 : {
169 22 : 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 55 : _fixed_scalar_input_param_values[i] = MooseUtils::join(
173 11 : fixed_scalar_input_param_values_tmp.begin() + raw_value_ct,
174 22 : fixed_scalar_input_param_values_tmp.begin() + raw_value_ct + Moose::dim,
175 11 : " ");
176 11 : raw_value_ct += Moose::dim;
177 : }
178 : else
179 : {
180 11 : _fixed_scalar_input_param_values[i] = fixed_scalar_input_param_values_tmp[raw_value_ct];
181 11 : raw_value_ct += 1;
182 : }
183 : }
184 11 : }
185 : else
186 225 : checkVectorParamsSameLength<std::string, std::string>("fixed_scalar_input_param_names",
187 : "fixed_scalar_input_param_values");
188 :
189 232 : 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 228 : 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 283 : for (const auto i : index_range(_fixed_vector_input_param_types))
197 : {
198 59 : 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 224 : 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 220 : 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 367 : for (const auto i : index_range(_batch_scalar_input_param_types))
228 : {
229 155 : 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 15 : 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 11 : auto unit_batch_scalar_input_param_values_tmp(_batch_scalar_input_param_values[i]);
240 11 : _batch_scalar_input_param_values[i].resize(unit_batch_scalar_input_param_values_tmp.size() /
241 : 3);
242 55 : for (const auto j : index_range(_batch_scalar_input_param_values[i]))
243 220 : _batch_scalar_input_param_values[i][j] = MooseUtils::join(
244 44 : unit_batch_scalar_input_param_values_tmp.begin() + j * Moose::dim,
245 88 : unit_batch_scalar_input_param_values_tmp.begin() + j * Moose::dim + Moose::dim,
246 44 : " ");
247 11 : }
248 : }
249 :
250 212 : 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 208 : 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 346 : for (const auto i : index_range(_batch_vector_input_param_types))
257 : {
258 146 : if (isCompoundRealScalarType(_batch_vector_input_param_types[i]))
259 : {
260 52 : 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 41 : 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 37 : auto unit_batch_vector_input_param_values_tmp(_batch_vector_input_param_values[i][j]);
271 74 : _batch_vector_input_param_values[i][j].resize(
272 37 : unit_batch_vector_input_param_values_tmp.size() / 3);
273 148 : for (const auto k : index_range(_batch_vector_input_param_values[i][j]))
274 555 : _batch_vector_input_param_values[i][j][k] = MooseUtils::join(
275 111 : unit_batch_vector_input_param_values_tmp.begin() + k * Moose::dim,
276 222 : unit_batch_vector_input_param_values_tmp.begin() + k * Moose::dim + Moose::dim,
277 111 : " ");
278 37 : }
279 : }
280 : }
281 :
282 : // At least we want this action to create one mesh generator
283 200 : 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 196 : std::set<unsigned int> batch_params_sizes;
291 339 : for (const auto & unit_batch_scalar_param_values : _batch_scalar_input_param_values)
292 : {
293 147 : if (unit_batch_scalar_param_values.empty())
294 4 : paramError("batch_scalar_input_param_values",
295 : "this parameter cannot contain empty elements.");
296 143 : batch_params_sizes.emplace(unit_batch_scalar_param_values.size());
297 : }
298 330 : for (const auto & unit_batch_vector_param_values : _batch_vector_input_param_values)
299 : {
300 142 : if (unit_batch_vector_param_values.empty())
301 4 : paramError("batch_vector_input_param_values",
302 : "this parameter cannot contain empty elements.");
303 138 : 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 244 : if (_multi_batch_params_method == MultiBatchParamsMethod::corresponding &&
308 56 : 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 184 : 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 180 : auto set_params = _app.getFactory().getValidParams(_mesh_generator_type);
320 : // batch scalar input parameters
321 180 : checkInputParametersTypes(set_params,
322 : "batch_scalar_input_param_names",
323 180 : _batch_scalar_input_param_names,
324 180 : _batch_scalar_input_param_types);
325 : // fix scalar input parameters
326 180 : checkInputParametersTypes(set_params,
327 : "fixed_scalar_input_param_names",
328 180 : _fixed_scalar_input_param_names,
329 180 : _fixed_scalar_input_param_types);
330 : // batch vector input parameters
331 180 : checkInputParametersTypes(set_params,
332 : "batch_vector_input_param_names",
333 180 : _batch_vector_input_param_names,
334 180 : _batch_vector_input_param_types,
335 180 : true);
336 : // fix vector input parameters
337 176 : checkInputParametersTypes(set_params,
338 : "fixed_vector_input_param_names",
339 176 : _fixed_vector_input_param_names,
340 176 : _fixed_vector_input_param_types,
341 176 : true);
342 176 : }
343 :
344 : void
345 176 : BatchMeshGeneratorAction::act()
346 : {
347 176 : if (_current_task == "add_mesh_generator")
348 176 : addMeshGenerators();
349 176 : }
350 :
351 : void
352 176 : BatchMeshGeneratorAction::addMeshGenerators()
353 : {
354 176 : std::vector<std::vector<std::string>> processed_batch_scalar_input_param_values;
355 176 : 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 176 : std::vector<std::vector<unsigned int>> processed_batch_indices;
358 176 : if (_multi_batch_params_method == MultiBatchParamsMethod::corresponding)
359 : {
360 44 : processed_batch_scalar_input_param_values = _batch_scalar_input_param_values;
361 44 : processed_batch_vector_input_param_values = _batch_vector_input_param_values;
362 44 : 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 231 : for (const auto i : index_range(_batch_scalar_input_param_values))
376 : {
377 : // For the first element, just copy the parameters
378 99 : if (processed_batch_scalar_input_param_values.empty())
379 : {
380 77 : processed_batch_scalar_input_param_values.push_back(_batch_scalar_input_param_values[i]);
381 77 : if (_use_decomposed_index)
382 : {
383 22 : processed_batch_indices.push_back(
384 44 : std::vector<unsigned int>(_batch_scalar_input_param_values[i].size()));
385 44 : std::iota(
386 44 : processed_batch_indices.back().begin(), processed_batch_indices.back().end(), 0);
387 : }
388 : }
389 : else
390 : {
391 22 : const unsigned int num_new_batch_params = _batch_scalar_input_param_values[i].size();
392 : const unsigned int num_processed_batch_params =
393 22 : 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 22 : for (auto & unit_processed_batch_scalar_input_param_values :
397 66 : processed_batch_scalar_input_param_values)
398 : {
399 22 : auto temp_params = unit_processed_batch_scalar_input_param_values;
400 44 : for (unsigned int j = 1; j < num_new_batch_params; j++)
401 : {
402 44 : unit_processed_batch_scalar_input_param_values.insert(
403 44 : unit_processed_batch_scalar_input_param_values.end(),
404 : temp_params.begin(),
405 : temp_params.end());
406 : }
407 22 : }
408 22 : if (_use_decomposed_index)
409 : {
410 : // Same as the composed indices
411 22 : for (auto & unit_processed_batch_indices : processed_batch_indices)
412 : {
413 11 : auto temp_indices = unit_processed_batch_indices;
414 22 : for (unsigned int j = 1; j < num_new_batch_params; j++)
415 : {
416 22 : unit_processed_batch_indices.insert(
417 22 : unit_processed_batch_indices.end(), temp_indices.begin(), temp_indices.end());
418 : }
419 11 : }
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 22 : processed_batch_scalar_input_param_values.push_back({});
425 22 : for (const auto & unit_batch_scalar_input_param_values :
426 88 : _batch_scalar_input_param_values[i])
427 132 : for (unsigned int j = 0; j < num_processed_batch_params; j++)
428 88 : processed_batch_scalar_input_param_values.back().push_back(
429 : unit_batch_scalar_input_param_values);
430 22 : if (_use_decomposed_index)
431 : {
432 : // Same as the composed indices
433 11 : processed_batch_indices.push_back({});
434 11 : for (const auto & unit_batch_scalar_input_param_values_index :
435 44 : index_range(_batch_scalar_input_param_values[i]))
436 66 : for (unsigned int j = 0; j < num_processed_batch_params; j++)
437 44 : processed_batch_indices.back().push_back(unit_batch_scalar_input_param_values_index);
438 : }
439 : }
440 : }
441 209 : for (const auto i : index_range(_batch_vector_input_param_values))
442 : {
443 : // For the first element, just copy the parameters
444 77 : if (processed_batch_vector_input_param_values.empty())
445 : {
446 66 : 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 55 : processed_batch_vector_input_param_values.push_back(_batch_vector_input_param_values[i]);
452 55 : if (_use_decomposed_index)
453 : {
454 11 : processed_batch_indices.push_back(
455 22 : std::vector<unsigned int>(_batch_vector_input_param_values[i].size()));
456 22 : std::iota(
457 22 : processed_batch_indices.back().begin(), processed_batch_indices.back().end(), 0);
458 : }
459 : }
460 : else
461 : {
462 11 : 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 11 : for (const auto & unit_batch_vector_input_param_values :
466 44 : _batch_vector_input_param_values[i])
467 66 : for (unsigned int j = 0; j < processed_batch_scalar_input_param_values.front().size();
468 : j++)
469 44 : 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 11 : for (auto & unit_processed_batch_scalar_input_param_values :
474 33 : processed_batch_scalar_input_param_values)
475 : {
476 11 : auto temp_params = unit_processed_batch_scalar_input_param_values;
477 44 : for (unsigned int j = 1; j < processed_batch_vector_input_param_values.back().size();
478 : j++)
479 : {
480 66 : unit_processed_batch_scalar_input_param_values.insert(
481 66 : unit_processed_batch_scalar_input_param_values.end(),
482 : temp_params.begin(),
483 : temp_params.end());
484 : }
485 11 : }
486 11 : if (_use_decomposed_index)
487 : {
488 : // Add the indices for the first batch vector input parameter
489 11 : processed_batch_indices.push_back({});
490 11 : for (const auto & unit_batch_vector_input_param_values_index :
491 44 : index_range(_batch_vector_input_param_values[i]))
492 66 : for (unsigned int j = 0; j < processed_batch_indices.front().size(); j++)
493 88 : processed_batch_indices.back().push_back(
494 44 : unit_batch_vector_input_param_values_index);
495 : // Duplicate the indices for the batch scalar input parameters
496 22 : for (unsigned int k = 1; k < processed_batch_indices.size(); k++)
497 : {
498 11 : auto & unit_processed_batch_indices = processed_batch_indices[k - 1];
499 11 : auto temp_indices = unit_processed_batch_indices;
500 22 : for (unsigned int j = 1; j < _batch_vector_input_param_values[i].size(); j++)
501 : {
502 22 : unit_processed_batch_indices.insert(
503 22 : unit_processed_batch_indices.end(), temp_indices.begin(), temp_indices.end());
504 : }
505 11 : }
506 : }
507 : }
508 : }
509 : else
510 : {
511 11 : const unsigned int num_new_batch_params = _batch_vector_input_param_values[i].size();
512 : const unsigned int num_processed_batch_params =
513 11 : 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 11 : for (auto & unit_processed_batch_vector_input_param_values :
517 33 : processed_batch_vector_input_param_values)
518 : {
519 11 : auto temp_params = unit_processed_batch_vector_input_param_values;
520 22 : for (unsigned int j = 1; j < num_new_batch_params; j++)
521 : {
522 22 : unit_processed_batch_vector_input_param_values.insert(
523 22 : unit_processed_batch_vector_input_param_values.end(),
524 : temp_params.begin(),
525 : temp_params.end());
526 : }
527 11 : }
528 11 : if (_use_decomposed_index)
529 : {
530 : // Same for the decomposed indices
531 22 : for (auto & unit_processed_batch_indices : processed_batch_indices)
532 : {
533 11 : auto temp_indices = unit_processed_batch_indices;
534 22 : for (unsigned int j = 1; j < num_new_batch_params; j++)
535 : {
536 22 : unit_processed_batch_indices.insert(
537 22 : unit_processed_batch_indices.end(), temp_indices.begin(), temp_indices.end());
538 : }
539 11 : }
540 : }
541 : // if there are also batch scalar input parameters, it also needs to be duplicated
542 11 : for (auto & unit_processed_batch_scalar_input_param_values :
543 22 : 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 11 : processed_batch_vector_input_param_values.push_back({});
557 11 : for (const auto & unit_batch_vector_input_param_values :
558 44 : _batch_vector_input_param_values[i])
559 66 : for (unsigned int j = 0; j < num_processed_batch_params; j++)
560 44 : processed_batch_vector_input_param_values.back().push_back(
561 : unit_batch_vector_input_param_values);
562 11 : if (_use_decomposed_index)
563 : {
564 : // Same for the decomposed indices
565 11 : processed_batch_indices.push_back({});
566 11 : for (const auto & unit_batch_vector_input_param_values_index :
567 44 : index_range(_batch_vector_input_param_values[i]))
568 66 : for (unsigned int j = 0; j < num_processed_batch_params; j++)
569 44 : 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 176 : processed_batch_vector_input_param_values.empty()
578 88 : ? processed_batch_scalar_input_param_values.front().size()
579 264 : : processed_batch_vector_input_param_values.front().size();
580 825 : for (const auto i : make_range(num_batch_params))
581 : {
582 649 : auto params = _app.getFactory().getValidParams(_mesh_generator_type);
583 1177 : for (const auto j : index_range(_batch_scalar_input_param_values))
584 528 : setScalarParams(params,
585 528 : _batch_scalar_input_param_names[j],
586 528 : _batch_scalar_input_param_types[j],
587 528 : processed_batch_scalar_input_param_values[j][i]);
588 1078 : for (const auto j : index_range(_batch_vector_input_param_values))
589 429 : setVectorParams(params,
590 429 : _batch_vector_input_param_names[j],
591 429 : _batch_vector_input_param_types[j],
592 429 : processed_batch_vector_input_param_values[j][i]);
593 1738 : for (const auto j : index_range(_fixed_scalar_input_param_names))
594 1089 : setScalarParams(params,
595 1089 : _fixed_scalar_input_param_names[j],
596 1089 : _fixed_scalar_input_param_types[j],
597 1089 : _fixed_scalar_input_param_values[j]);
598 858 : for (const auto j : index_range(_fixed_vector_input_param_names))
599 209 : setVectorParams(params,
600 209 : _fixed_vector_input_param_names[j],
601 209 : _fixed_vector_input_param_types[j],
602 209 : _fixed_vector_input_param_values[j]);
603 :
604 649 : std::string mesh_index;
605 649 : if (_use_decomposed_index)
606 396 : for (const auto & process_batch_index : processed_batch_indices)
607 264 : mesh_index += '_' + std::to_string(process_batch_index[i]);
608 : else
609 517 : mesh_index = "_" + std::to_string(i);
610 :
611 649 : _app.getMeshGeneratorSystem().addMeshGenerator(
612 649 : _mesh_generator_type, _mesh_name_prefix + mesh_index, params);
613 649 : }
614 176 : }
615 :
616 : void
617 1617 : BatchMeshGeneratorAction::setScalarParams(InputParameters & params,
618 : const std::string & param_name,
619 : const ParameterType & param_type,
620 : const std::string & param_value) const
621 : {
622 1617 : switch (param_type)
623 : {
624 44 : case (ParameterType::REAL):
625 44 : params.set<Real>(param_name) = MooseUtils::convert<Real>(param_value);
626 44 : 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 528 : case (ParameterType::UINT):
637 528 : params.set<unsigned int>(param_name) = MooseUtils::convert<unsigned int>(param_value);
638 528 : 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 539 : case (ParameterType::ENUM):
663 539 : params.set<MooseEnum>(param_name) = param_value;
664 539 : 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 154 : case (ParameterType::MGNAME):
675 154 : params.set<MeshGeneratorName>(param_name) = param_value;
676 154 : break;
677 22 : case (ParameterType::MFNAME):
678 22 : params.set<MeshFileName>(param_name) = param_value;
679 22 : break;
680 264 : case (ParameterType::BOOL):
681 264 : hit::toBool(param_value, ¶ms.set<bool>(param_name));
682 264 : break;
683 66 : case (ParameterType::REALVECTORVALUE):
684 66 : params.set<RealVectorValue>(param_name) =
685 66 : convertStringToCompoundRealScalar<RealVectorValue>(param_value);
686 66 : break;
687 0 : case (ParameterType::POINT):
688 0 : params.set<Point>(param_name) = convertStringToCompoundRealScalar<Point>(param_value);
689 0 : break;
690 1617 : default:
691 : mooseAssert(false,
692 : "impossible situation."); // as we use MultiMooseEnum to ensure the type is valid
693 : }
694 1617 : }
695 :
696 : void
697 638 : 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 638 : switch (param_type)
703 : {
704 132 : case (ParameterType::REAL):
705 132 : convertAndSetNumericVector<Real>(params, param_name, param_value);
706 132 : break;
707 0 : case (ParameterType::SHORT):
708 0 : convertAndSetNumericVector<short>(params, param_name, param_value);
709 0 : break;
710 132 : case (ParameterType::USHORT):
711 132 : convertAndSetNumericVector<unsigned short>(params, param_name, param_value);
712 132 : break;
713 0 : case (ParameterType::INT):
714 0 : convertAndSetNumericVector<int>(params, param_name, param_value);
715 0 : break;
716 132 : case (ParameterType::UINT):
717 132 : convertAndSetNumericVector<unsigned int>(params, param_name, param_value);
718 132 : 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 33 : case (ParameterType::DOFIDTYPE):
732 33 : convertAndSetNumericVector<dof_id_type>(params, param_name, param_value);
733 33 : 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 88 : case (ParameterType::SDNAME):
747 88 : convertAndSetStringLikeVector<SubdomainName>(params, param_name, param_value);
748 88 : break;
749 88 : case (ParameterType::BDRYNAME):
750 88 : convertAndSetStringLikeVector<BoundaryName>(params, param_name, param_value);
751 88 : 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 33 : case (ParameterType::POINT):
777 33 : convertAndSetCompoundRealScalarVector<Point>(params, param_name, param_value);
778 33 : break;
779 638 : default:
780 : mooseAssert(false,
781 : "impossible situation."); // as we use MultiMooseEnum to ensure the type is valid
782 : }
783 638 : }
784 :
785 : template <typename T>
786 : void
787 429 : BatchMeshGeneratorAction::convertAndSetNumericVector(
788 : InputParameters & params,
789 : const std::string & param_name,
790 : const std::vector<std::string> & param_value) const
791 : {
792 429 : std::vector<T> values(param_value.size());
793 429 : std::transform(param_value.begin(),
794 : param_value.end(),
795 : values.begin(),
796 539 : [](const std::string & val) { return MooseUtils::convert<T>(val); });
797 429 : params.set<std::vector<T>>(param_name) = values;
798 429 : }
799 :
800 : template <typename T>
801 : void
802 33 : BatchMeshGeneratorAction::convertAndSetCompoundRealScalarVector(
803 : InputParameters & params,
804 : const std::string & param_name,
805 : const std::vector<std::string> & param_value) const
806 : {
807 33 : std::vector<T> values(param_value.size());
808 33 : std::transform(param_value.begin(),
809 : param_value.end(),
810 : values.begin(),
811 99 : [this](const std::string & val)
812 99 : { return convertStringToCompoundRealScalar<T>(val); });
813 33 : params.set<std::vector<T>>(param_name) = values;
814 33 : }
815 :
816 : template <typename T>
817 : void
818 176 : BatchMeshGeneratorAction::convertAndSetStringLikeVector(
819 : InputParameters & params,
820 : const std::string & param_name,
821 : const std::vector<std::string> & param_value) const
822 : {
823 176 : std::vector<T> values(param_value.size());
824 176 : std::transform(param_value.begin(),
825 : param_value.end(),
826 : values.begin(),
827 440 : [](const std::string & val) { return T(val); });
828 176 : params.set<std::vector<T>>(param_name) = values;
829 176 : }
830 :
831 : void
832 716 : 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 1326 : for (const auto i : index_range(param_names))
839 : {
840 614 : switch (param_types[i])
841 : {
842 44 : case (ParameterType::REAL):
843 44 : checkInputParameterType<Real>(params, action_input_param_name, param_names[i], is_vector);
844 44 : break;
845 0 : case (ParameterType::SHORT):
846 0 : checkInputParameterType<short>(params, action_input_param_name, param_names[i], is_vector);
847 0 : break;
848 33 : case (ParameterType::USHORT):
849 33 : checkInputParameterType<unsigned short>(
850 33 : params, action_input_param_name, param_names[i], is_vector);
851 33 : break;
852 0 : case (ParameterType::INT):
853 0 : checkInputParameterType<int>(params, action_input_param_name, param_names[i], is_vector);
854 0 : break;
855 173 : case (ParameterType::UINT):
856 173 : checkInputParameterType<unsigned int>(
857 173 : params, action_input_param_name, param_names[i], is_vector);
858 169 : 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 11 : case (ParameterType::DOFIDTYPE):
875 11 : checkInputParameterType<dof_id_type>(
876 11 : params, action_input_param_name, param_names[i], is_vector);
877 11 : 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 147 : case (ParameterType::ENUM):
887 147 : if (is_vector)
888 0 : checkInputParameterType<MultiMooseEnum>(
889 0 : params, action_input_param_name, param_names[i], false);
890 : else
891 147 : checkInputParameterType<MooseEnum>(
892 294 : params, action_input_param_name, param_names[i], false);
893 147 : 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 22 : case (ParameterType::SDNAME):
899 22 : checkInputParameterType<SubdomainName>(
900 22 : params, action_input_param_name, param_names[i], is_vector);
901 22 : break;
902 22 : case (ParameterType::BDRYNAME):
903 22 : checkInputParameterType<BoundaryName>(
904 22 : params, action_input_param_name, param_names[i], is_vector);
905 22 : break;
906 44 : case (ParameterType::MGNAME):
907 44 : checkInputParameterType<MeshGeneratorName>(
908 44 : params, action_input_param_name, param_names[i], is_vector);
909 44 : break;
910 11 : case (ParameterType::MFNAME):
911 11 : checkInputParameterType<MeshFileName>(
912 11 : params, action_input_param_name, param_names[i], is_vector);
913 11 : break;
914 74 : case (ParameterType::BOOL):
915 74 : checkInputParameterType<bool>(params, action_input_param_name, param_names[i], is_vector);
916 74 : break;
917 22 : case (ParameterType::REALVECTORVALUE):
918 22 : checkInputParameterType<RealVectorValue>(
919 22 : params, action_input_param_name, param_names[i], is_vector);
920 22 : break;
921 11 : case (ParameterType::POINT):
922 11 : checkInputParameterType<Point>(params, action_input_param_name, param_names[i], is_vector);
923 11 : break;
924 610 : default:
925 : mooseAssert(
926 : false,
927 : "impossible situation."); // as we use MultiMooseEnum to ensure the type is valid
928 : }
929 : }
930 712 : }
931 :
932 : template <typename T>
933 : void
934 614 : 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 1224 : if ((is_vector && !params.isType<std::vector<T>>(param_name)) ||
940 610 : (!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 610 : }
945 :
946 : template <typename T>
947 : T
948 165 : BatchMeshGeneratorAction::convertStringToCompoundRealScalar(const std::string & str) const
949 : {
950 165 : 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 165 : T ret(MooseUtils::convert<Real>(split_str[0]));
954 495 : for (const auto i :
955 165 : make_range(static_cast<std::remove_cv_t<decltype(Moose::dim)>>(1), Moose::dim))
956 330 : ret(i) = MooseUtils::convert<Real>(split_str[i]);
957 330 : return ret;
958 165 : }
959 :
960 : bool
961 804 : BatchMeshGeneratorAction::isCompoundRealScalarType(const ParameterType & param_type) const
962 : {
963 804 : const auto valid_types = {ParameterType::REALVECTORVALUE, ParameterType::POINT};
964 804 : return std::count(valid_types.begin(), valid_types.end(), param_type);
965 : }
|