https://mooseframework.inl.gov
Loading...
Searching...
No Matches
CoreMeshGenerator.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "CoreMeshGenerator.h"
11
12#include "MooseApp.h"
13#include "MooseMeshUtils.h"
14#include "Factory.h"
15#include "libmesh/elem.h"
16#include "CSGZCylinder.h"
17
19
22{
24
25 params.addRequiredParam<std::vector<MeshGeneratorName>>(
26 "inputs",
27 "The AssemblyMeshGenerator and ControlDrumMeshGenerator objects that form the components of "
28 "the assembly.");
29
30 params.addParam<std::string>(
31 "dummy_assembly_name",
32 "dummy",
33 "The place holder name in \"inputs\" that indicates an empty position.");
34
35 params.addRequiredParam<std::vector<std::vector<unsigned int>>>(
36 "pattern",
37 "A double-indexed array starting with the upper-left corner where the index"
38 "represents the layout of input assemblies in the core lattice.");
39 params.addParam<bool>(
40 "mesh_periphery", false, "Determines if the core periphery should be meshed.");
41 MooseEnum periphery_mesher("triangle quad_ring", "triangle");
42 params.addParam<MooseEnum>("periphery_generator",
43 periphery_mesher,
44 "The meshgenerator to use when meshing the core boundary.");
45
46 // Periphery meshing interface
47 params.addRangeCheckedParam<Real>(
48 "outer_circle_radius", 0, "outer_circle_radius>=0", "Radius of outer circle boundary.");
49 params.addRangeCheckedParam<unsigned int>(
50 "outer_circle_num_segments",
51 0,
52 "outer_circle_num_segments>=0",
53 "Number of radial segments to subdivide outer circle boundary.");
54 params.addRangeCheckedParam<unsigned int>(
55 "periphery_num_layers",
56 1,
57 "periphery_num_layers>0",
58 "Number of layers to subdivide the periphery boundary.");
59 params.addParam<std::string>(
60 "periphery_block_name", RGMB::CORE_BLOCK_NAME_PREFIX, "Block name for periphery zone.");
61 params.addParam<subdomain_id_type>(
62 "periphery_region_id",
63 -1,
64 "ID for periphery zone for assignment of region_id extra element id.");
65 params.addRangeCheckedParam<Real>(
66 "desired_area",
67 0,
68 "desired_area>=0",
69 "Desired (maximum) triangle area, or 0 to skip uniform refinement");
70 params.addParam<std::string>(
71 "desired_area_func",
72 std::string(),
73 "Desired (local) triangle area as a function of x,y; omit to skip non-uniform refinement");
74 params.addParam<bool>("assign_control_drum_id",
75 true,
76 "Whether control drum id is assigned to the mesh as an extra integer.");
77 params.addParamNamesToGroup("periphery_block_name periphery_region_id outer_circle_radius "
78 "mesh_periphery periphery_generator",
79 "Periphery Meshing");
80 params.addParamNamesToGroup("outer_circle_num_segments desired_area desired_area_func",
81 "Periphery Meshing: PTMG specific");
82 params.addParamNamesToGroup("periphery_num_layers", "Periphery Meshing: PRMG specific");
83 // end meshing interface
84
85 params.addParam<bool>("extrude",
86 false,
87 "Determines if this is the final step in the geometry construction"
88 " and extrudes the 2D geometry to 3D. If this is true then this mesh "
89 "cannot be used in further mesh building in the Reactor workflow");
90
91 params.addClassDescription(
92 "This CoreMeshGenerator object is designed to generate a core-like "
93 "structure, with IDs, from a reactor geometry. "
94 "The core-like structure consists of a pattern of assembly-like "
95 "structures generated with AssemblyMeshGenerator and/or ControlDrumMeshGenerator "
96 "and is permitted to have \"empty\" locations. The size and spacing "
97 "of the assembly-like structures is defined, and "
98 "enforced by declaration in the ReactorMeshParams.");
99 // depletion id generation params are added
100 addDepletionIDParams(params);
101
102 // Declare that this generator has a generateCSG method
104
105 return params;
106}
107
109 : ReactorGeometryMeshBuilderBase(parameters),
110 _inputs(getParam<std::vector<MeshGeneratorName>>("inputs")),
111 _empty_key(getParam<std::string>("dummy_assembly_name")),
112 _pattern(getParam<std::vector<std::vector<unsigned int>>>("pattern")),
113 _extrude(getParam<bool>("extrude")),
114 _mesh_periphery(getParam<bool>("mesh_periphery")),
115 _periphery_meshgenerator(getParam<MooseEnum>("periphery_generator")),
116 _periphery_region_id(getParam<subdomain_id_type>("periphery_region_id")),
117 _outer_circle_radius(getParam<Real>("outer_circle_radius")),
118 _outer_circle_num_segments(getParam<unsigned int>("outer_circle_num_segments")),
119 _periphery_block_name(getParam<std::string>("periphery_block_name")),
120 _periphery_num_layers(getParam<unsigned int>("periphery_num_layers")),
121 _desired_area(getParam<Real>("desired_area")),
122 _desired_area_func(getParam<std::string>("desired_area_func"))
123{
124 // This sets it so that any mesh that is input with the name _empty_key is considered a "null"
125 // mesh, that is, whenever we try to get it with the standard getMesh() API we get a nullptr
126 // mesh instead. In the specific case of the CoreMeshGenerator, we use said "null" mesh to
127 // represent an empty position
129
130 // periphery meshing input checking
131 if (_mesh_periphery)
132 {
133 // missing required input
134 if (!parameters.isParamSetByUser("outer_circle_radius"))
135 {
136 paramError("outer_circle_radius",
137 "Outer circle radius must be specified when using periphery meshing.");
138 }
139 if (!parameters.isParamSetByUser("periphery_region_id"))
140 {
141 paramError("periphery_region_id",
142 "Periphery region id must be specified when using periphery meshing.");
143 }
144 // using PTMG-specific options with PRMG
145 if (_periphery_meshgenerator == "quad_ring")
146 {
147 if (parameters.isParamSetByUser("outer_circle_num_segments"))
148 {
149 paramError("outer_circle_num_segments",
150 "outer_circle_num_segments cannot be used with PRMG periphery mesher.");
151 }
152 if (parameters.isParamSetByUser("extra_circle_radii"))
153 {
154 paramError("extra_circle_radii",
155 "extra_circle_radii cannot be used with PRMG periphery mesher.");
156 }
157 if (parameters.isParamSetByUser("extra_circle_num_segments"))
158 {
159 paramError("extra_circle_num_segments",
160 "extra_circle_num_segments cannot be used with PRMG periphery mesher.");
161 }
162 }
163 // using PRMG-specific options with PTMG
164 else if (_periphery_meshgenerator == "triangle")
165 {
166 if (parameters.isParamSetByUser("periphery_num_layers"))
167 {
168 paramError("periphery_num_layers",
169 "periphery_num_layers cannot be used with PTMG periphery mesher.");
170 }
171 }
172 else
173 paramError("periphery_generator",
174 "Provided periphery meshgenerator has not been implemented.");
175 }
176
177 MeshGeneratorName first_nondummy_assembly = "";
178 MeshGeneratorName reactor_params = "";
179 bool assembly_homogenization = false;
180 bool pin_as_assembly = false;
181 std::map<subdomain_id_type, std::string> global_pin_map_type_to_name;
182 std::map<subdomain_id_type, std::string> assembly_map_type_to_name;
183 // Check that MG name for reactor params and assembly homogenization schemes are
184 // consistent across all assemblies, and there is no overlap in pin_type / assembly_type ids
185 for (const auto i : index_range(_inputs))
186 {
187 // Skip if assembly name is equal to dummy assembly name
188 if (_inputs[i] == _empty_key)
189 continue;
190
191 // Save properties of first non-dummy assembly to compare to other assemblies
192 if (first_nondummy_assembly == "")
193 {
194 first_nondummy_assembly = MeshGeneratorName(_inputs[i]);
195 reactor_params =
196 MeshGeneratorName(getMeshProperty<std::string>(RGMB::reactor_params_name, _inputs[i]));
197 assembly_homogenization = getMeshProperty<bool>(RGMB::is_homogenized, _inputs[i]);
198 pin_as_assembly = getMeshProperty<bool>(RGMB::is_single_pin, _inputs[i]);
199 }
200 if (getMeshProperty<std::string>(RGMB::reactor_params_name, _inputs[i]) != reactor_params)
201 mooseError("The name of all reactor_params objects should be identical across all pins in "
202 "the input assemblies.\n");
203 if ((getMeshProperty<bool>(RGMB::is_homogenized, _inputs[i]) != assembly_homogenization) &&
204 !getMeshProperty<bool>(RGMB::flexible_assembly_stitching, reactor_params))
205 mooseError("In order to stitch heterogeneous assemblies with homogeneous assemblies in "
206 "CoreMeshGenerator, ReactorMeshParams/flexible_assembly_stitching should be set "
207 "to true\n");
208
209 // Check assembly_types across constituent assemblies are uniquely defined
210 const auto assembly_type = getMeshProperty<subdomain_id_type>(RGMB::assembly_type, _inputs[i]);
211 if (assembly_map_type_to_name.find(assembly_type) != assembly_map_type_to_name.end() &&
212 assembly_map_type_to_name[assembly_type] != _inputs[i])
214 "Constituent assemblies have shared assembly_type ids but different names. Each uniquely "
215 "defined assembly in AssemblyMeshGenerator must have its own assembly_type id.");
216 assembly_map_type_to_name[assembly_type] = _inputs[i];
217
218 // If assembly is composed of pins, check pin_types across all constituent assemblies are
219 // uniquely defined
220 if (hasMeshProperty<std::vector<std::string>>(RGMB::pin_names, _inputs[i]))
221 {
222 const auto pin_names = getMeshProperty<std::vector<std::string>>(RGMB::pin_names, _inputs[i]);
223 for (const auto & input_pin_name : pin_names)
224 {
225 const auto pin_type = getMeshProperty<subdomain_id_type>(RGMB::pin_type, input_pin_name);
226 if (global_pin_map_type_to_name.find(pin_type) != global_pin_map_type_to_name.end() &&
227 global_pin_map_type_to_name[pin_type] != input_pin_name)
229 "Constituent pins within assemblies have shared pin_type ids but different names. "
230 "Each uniquely defined pin in AssemblyMeshGenerator must have its own pin_type id.");
231 global_pin_map_type_to_name[pin_type] = input_pin_name;
232 }
233 }
234 }
235
236 // Check that there is at least one non-dummy assemby defined in lattice
237 if (first_nondummy_assembly == "")
238 paramError("inputs", "At least one non-dummy assembly must be defined in input assembly names");
239
240 // Initialize ReactorMeshParams object stored in pin input
241 initializeReactorMeshParams(reactor_params);
242
243 _geom_type = getReactorParam<std::string>(RGMB::mesh_geometry);
244 _mesh_dimensions = getReactorParam<unsigned int>(RGMB::mesh_dimensions);
245
246 if (_extrude && _mesh_dimensions != 3)
247 paramError("extrude",
248 "In order to extrude this mesh, ReactorMeshParams/dim needs to be set to 3\n");
249 if (_extrude && (!hasReactorParam<boundary_id_type>(RGMB::top_boundary_id) ||
250 !hasReactorParam<boundary_id_type>(RGMB::bottom_boundary_id)))
251 mooseError("Both top_boundary_id and bottom_boundary_id must be provided in ReactorMeshParams "
252 "if using extruded geometry");
253 if (!hasReactorParam<boundary_id_type>(RGMB::radial_boundary_id))
254 mooseError("radial_boundary_id must be provided in ReactorMeshParams for CoreMeshGenerators");
255
256 if (parameters.isParamSetByUser("periphery_block_name") &&
257 getReactorParam<bool>(RGMB::region_id_as_block_name))
258 paramError("periphery_block_name",
259 "If ReactorMeshParams/region_id_as_block_name is set, periphery_block_name should "
260 "not be specified in CoreMeshGenerator");
261
262 std::size_t empty_pattern_loc = 0;
263 bool make_empty = false;
264 for (auto assembly : _inputs)
265 {
266 if (assembly != _empty_key)
267 {
268 ++empty_pattern_loc;
269 if (getMeshProperty<bool>(RGMB::extruded, assembly))
270 mooseError("Assemblies that have already been extruded cannot be used in CoreMeshGenerator "
271 "definition.\n");
272 }
273 else
274 {
275 // Found dummy assembly in input assembly names
276 make_empty = true;
277 for (const auto i : index_range(_pattern))
278 {
279 for (const auto j : index_range(_pattern[i]))
280 {
281 // Found dummy assembly in input lattice definition
282 if (_pattern[i][j] == empty_pattern_loc)
283 _empty_pos = true;
284 }
285 }
286 }
287 }
288
289 // No subgenerators will be called if option to bypass mesh generators is enabled
290 if (!getReactorParam<bool>(RGMB::bypass_meshgen))
291 {
292 // Check whether flexible stitching should be used for constituent assemblies and throw a
293 // warning if flexible stitching option is not enabled
294 if (!getReactorParam<bool>(RGMB::flexible_assembly_stitching) &&
296 mooseWarning("Constituent assemblies do not share the same number of nodes at the outer "
297 "boundary. In order to ensure that output mesh does not having hanging nodes, a "
298 "flexible stitching approach should be used by setting "
299 "ReactorMeshParams/flexible_assembly_stitching = true.");
300
301 // Declare that all of the meshes in the "inputs" parameter are to be used by
302 // a sub mesh generator.
303 declareMeshesForSub("inputs");
304
305 // Stitch assemblies into a hexagonal / Cartesian core lattice
306 {
307 // create a dummy assembly that is a renamed version of one of the inputs
308 if (make_empty)
309 {
310 {
311 if (assembly_homogenization)
312 {
313 auto params = _app.getFactory().getValidParams("SimpleHexagonGenerator");
314
315 params.set<Real>("hexagon_size") = getReactorParam<Real>(RGMB::assembly_pitch) / 2.0;
316 params.set<std::vector<subdomain_id_type>>("block_id") = {
318
319 addMeshSubgenerator("SimpleHexagonGenerator", std::string(_empty_key), params);
320 }
321 else
322 {
323 const auto adaptive_mg_name =
324 _geom_type == "Hex" ? "HexagonConcentricCircleAdaptiveBoundaryMeshGenerator"
325 : "CartesianConcentricCircleAdaptiveBoundaryMeshGenerator";
326 auto params = _app.getFactory().getValidParams(adaptive_mg_name);
327
328 const auto assembly_pitch = getReactorParam<Real>(RGMB::assembly_pitch);
329 if (_geom_type == "Hex")
330 {
331 params.set<Real>("hexagon_size") = assembly_pitch / 2.0;
332 params.set<std::vector<unsigned int>>("num_sectors_per_side") =
333 std::vector<unsigned int>(6, 2);
334 }
335 else
336 {
337 params.set<Real>("square_size") = assembly_pitch;
338 params.set<std::vector<unsigned int>>("num_sectors_per_side") =
339 std::vector<unsigned int>(4, 2);
340 }
341 params.set<std::vector<unsigned int>>("sides_to_adapt") = std::vector<unsigned int>{0};
342 params.set<std::vector<MeshGeneratorName>>("meshes_to_adapt_to") =
343 std::vector<MeshGeneratorName>{first_nondummy_assembly};
344 params.set<std::vector<subdomain_id_type>>("background_block_ids") =
345 std::vector<subdomain_id_type>{RGMB::DUMMY_ASSEMBLY_BLOCK_ID};
346
347 addMeshSubgenerator(adaptive_mg_name, std::string(_empty_key), params);
348 }
349 }
350 }
351 {
352 const auto patterned_mg_name =
353 _geom_type == "Hex" ? "PatternedHexMeshGenerator" : "PatternedCartesianMeshGenerator";
354 auto params = _app.getFactory().getValidParams(patterned_mg_name);
355
356 params.set<std::vector<std::string>>("id_name") = {"assembly_id"};
357 params.set<std::vector<MooseEnum>>("assign_type") = {
358 MooseEnum("cell", "cell")}; // give elems IDs relative to position in assembly
359 params.set<std::vector<MeshGeneratorName>>("inputs") = _inputs;
360 params.set<std::vector<std::vector<unsigned int>>>("pattern") = _pattern;
361 params.set<MooseEnum>("pattern_boundary") = "none";
362 params.set<bool>("generate_core_metadata") = !pin_as_assembly;
363 params.set<bool>("create_outward_interface_boundaries") = false;
364 params.set<bool>("assign_control_drum_id") = getParam<bool>("assign_control_drum_id");
365 if (make_empty)
366 {
367 params.set<std::vector<MeshGeneratorName>>("exclude_id") =
368 std::vector<MeshGeneratorName>{_empty_key};
369 }
370
371 const auto radial_boundary = getReactorParam<boundary_id_type>(RGMB::radial_boundary_id);
372 params.set<boundary_id_type>("external_boundary_id") = radial_boundary;
373 params.set<BoundaryName>("external_boundary_name") = RGMB::CORE_BOUNDARY_NAME;
374 params.set<double>("rotate_angle") = 0.0;
375 params.set<bool>("allow_unused_inputs") = true;
376
377 addMeshSubgenerator(patterned_mg_name, name() + "_pattern", params);
378 }
379 }
380 if (_empty_pos)
381 {
382 auto params = _app.getFactory().getValidParams("BlockDeletionGenerator");
383
384 params.set<std::vector<SubdomainName>>("block") = {
385 std::to_string(RGMB::DUMMY_ASSEMBLY_BLOCK_ID)};
386 params.set<MeshGeneratorName>("input") = name() + "_pattern";
387 params.set<BoundaryName>("new_boundary") = RGMB::CORE_BOUNDARY_NAME;
388
389 addMeshSubgenerator("BlockDeletionGenerator", name() + "_deleted", params);
390 }
391
392 std::string build_mesh_name;
393
394 // Remove outer assembly sidesets created during assembly generation
395 {
396 // Get outer boundaries of all constituent assemblies based on assembly_type,
397 // skipping all dummy assemblies
398 std::vector<BoundaryName> boundaries_to_delete = {};
399 for (const auto & pattern_x : _pattern)
400 {
401 for (const auto & pattern_idx : pattern_x)
402 {
403 const auto assembly_name = _inputs[pattern_idx];
404 if (assembly_name == _empty_key)
405 continue;
406 const auto assembly_id =
407 getMeshProperty<subdomain_id_type>(RGMB::assembly_type, assembly_name);
408 const BoundaryName boundary_name =
409 RGMB::ASSEMBLY_BOUNDARY_NAME_PREFIX + std::to_string(assembly_id);
410 if (!std::count(boundaries_to_delete.begin(), boundaries_to_delete.end(), boundary_name))
411 boundaries_to_delete.push_back(boundary_name);
412 }
413 }
414 auto params = _app.getFactory().getValidParams("BoundaryDeletionGenerator");
415
416 params.set<MeshGeneratorName>("input") =
417 _empty_pos ? name() + "_deleted" : name() + "_pattern";
418 params.set<std::vector<BoundaryName>>("boundary_names") = boundaries_to_delete;
419
420 build_mesh_name = name() + "_delbds";
421 addMeshSubgenerator("BoundaryDeletionGenerator", build_mesh_name, params);
422 }
423
424 for (auto assembly : _inputs)
425 {
426 if (assembly != _empty_key)
427 {
428 subdomain_id_type assembly_type =
429 getMeshProperty<subdomain_id_type>(RGMB::assembly_type, assembly);
430 if (!getMeshProperty<bool>(RGMB::is_control_drum, assembly))
431 {
432 // For assembly structures, store region ID and block names of assembly regions and
433 // constituent pins
434 const auto & pin_region_id_map = getMeshProperty<
435 std::map<subdomain_id_type, std::vector<std::vector<subdomain_id_type>>>>(
436 RGMB::pin_region_id_map, assembly);
437 for (auto pin = pin_region_id_map.begin(); pin != pin_region_id_map.end(); ++pin)
438 _pin_region_id_map.insert(
439 std::pair<subdomain_id_type, std::vector<std::vector<subdomain_id_type>>>(
440 pin->first, pin->second));
441
442 const auto & pin_block_name_map =
443 getMeshProperty<std::map<subdomain_id_type, std::vector<std::vector<std::string>>>>(
444 RGMB::pin_block_name_map, assembly);
445 for (auto pin = pin_block_name_map.begin(); pin != pin_block_name_map.end(); ++pin)
446 _pin_block_name_map.insert(
447 std::pair<subdomain_id_type, std::vector<std::vector<std::string>>>(pin->first,
448 pin->second));
449
450 // Define background and duct region ID map from constituent assemblies
451 if (_background_region_id_map.find(assembly_type) == _background_region_id_map.end())
452 {
453 // Store region ids and block names associated with duct and background regions for each
454 // assembly, in case block names need to be recovered from region ids after
455 // multiple assemblies have been stitched together into a core
456 std::vector<subdomain_id_type> background_region_ids =
457 getMeshProperty<std::vector<subdomain_id_type>>(RGMB::background_region_id,
458 assembly);
459 std::vector<std::vector<subdomain_id_type>> duct_region_ids =
460 getMeshProperty<std::vector<std::vector<subdomain_id_type>>>(RGMB::duct_region_ids,
461 assembly);
463 std::pair<subdomain_id_type, std::vector<subdomain_id_type>>(
464 assembly_type, background_region_ids));
465 _duct_region_id_map.insert(
466 std::pair<subdomain_id_type, std::vector<std::vector<subdomain_id_type>>>(
467 assembly_type, duct_region_ids));
468
469 std::vector<std::string> background_block_names =
470 getMeshProperty<std::vector<std::string>>(RGMB::background_block_name, assembly);
471 std::vector<std::vector<std::string>> duct_block_names =
472 getMeshProperty<std::vector<std::vector<std::string>>>(RGMB::duct_block_names,
473 assembly);
475 std::pair<subdomain_id_type, std::vector<std::string>>(assembly_type,
476 background_block_names));
478 std::pair<subdomain_id_type, std::vector<std::vector<std::string>>>(
479 assembly_type, duct_block_names));
480 }
481 }
482 else
483 {
484 // For control drum structures, store region ID and block name information of drum regions
485 const auto & drum_region_ids =
486 getMeshProperty<std::vector<std::vector<subdomain_id_type>>>(RGMB::drum_region_ids,
487 assembly);
488 _drum_region_id_map.insert(
489 std::pair<subdomain_id_type, std::vector<std::vector<subdomain_id_type>>>(
490 assembly_type, drum_region_ids));
491 std::vector<std::vector<std::string>> drum_block_names =
492 getMeshProperty<std::vector<std::vector<std::string>>>(RGMB::drum_block_names,
493 assembly);
495 std::pair<subdomain_id_type, std::vector<std::vector<std::string>>>(
496 assembly_type, drum_block_names));
497 }
498 }
499 }
500
501 // periphery meshing
502 if (_mesh_periphery)
503 {
504 std::string periphery_mg_name = (_periphery_meshgenerator == "triangle")
505 ? "PeripheralTriangleMeshGenerator"
506 : "PeripheralRingMeshGenerator";
507
508 // set up common options
509 auto params = _app.getFactory().getValidParams(periphery_mg_name);
510 params.set<MeshGeneratorName>("input") = name() + "_delbds";
511 params.set<Real>("peripheral_ring_radius") = _outer_circle_radius;
512 params.set<BoundaryName>("external_boundary_name") = "outside_periphery";
513 params.set<SubdomainName>("peripheral_ring_block_name") = RGMB::PERIPHERAL_RING_BLOCK_NAME;
514
515 // unique MG options
516 if (_periphery_meshgenerator == "triangle")
517 {
518 params.set<unsigned int>("peripheral_ring_num_segments") = _outer_circle_num_segments;
519 params.set<Real>("desired_area") = _desired_area;
520 params.set<std::string>("desired_area_func") = _desired_area_func;
521 }
522 else if (_periphery_meshgenerator == "quad_ring")
523 {
524 params.set<subdomain_id_type>("peripheral_ring_block_id") = RGMB::PERIPHERAL_RING_BLOCK_ID;
525 params.set<BoundaryName>("input_mesh_external_boundary") = RGMB::CORE_BOUNDARY_NAME;
526 params.set<unsigned int>("peripheral_layer_num") = _periphery_num_layers;
527 }
528
529 // finish periphery input
530 build_mesh_name = name() + "_periphery";
531 addMeshSubgenerator(periphery_mg_name, build_mesh_name, params);
532 }
533
534 if (_extrude && _mesh_dimensions == 3)
535 build_mesh_name = callExtrusionMeshSubgenerators(build_mesh_name);
536
537 // Store final mesh subgenerator
538 _build_mesh = &getMeshByName(build_mesh_name);
539 }
540 // If mesh generation should be bypassed, call getMeshes to resolve MeshGeneratorSystem
541 // dependencies
542 else
543 auto input_meshes = getMeshes("inputs");
544
545 // If we are in CSG only mode, store the CSGBase objects associated with input MG's
547 _input_csg_bases = getCSGBases("inputs");
548
550}
551
552void
554{
555 // Define metadata related to downstream function calls
556 if (_mesh_periphery)
557 {
560 }
561
562 // Determine constituent pin type ids and define lattice
563 std::vector<std::vector<int>> assembly_name_lattice;
564 std::vector<std::string> input_assembly_names;
565 std::vector<std::string> input_pin_names;
566
567 // Iterate through input assembly names and define constituent assemblies and pins
568 for (const auto i : index_range(_inputs))
569 {
570 const auto input_assembly_name = _inputs[i];
571 if (input_assembly_name != _empty_key)
572 {
573 input_assembly_names.push_back(input_assembly_name);
574 if (!getMeshProperty<bool>(RGMB::is_control_drum, input_assembly_name) &&
575 !getMeshProperty<bool>(RGMB::is_single_pin, input_assembly_name))
576 {
577 const auto pin_names =
578 getMeshProperty<std::vector<std::string>>(RGMB::pin_names, input_assembly_name);
579 for (const auto & pin_name : pin_names)
580 if (std::find(input_pin_names.begin(), input_pin_names.end(), pin_name) ==
581 input_pin_names.end())
582 input_pin_names.push_back(pin_name);
583 }
584 }
585 }
586
587 // Iterate through pattern and remap dummy assemblies with index -1
588 for (const auto i : index_range(_pattern))
589 {
590 std::vector<int> assembly_name_idx(_pattern[i].size());
591 for (const auto j : index_range(_pattern[i]))
592 {
593 const auto input_assembly_name = _inputs[_pattern[i][j]];
594 // Use an assembly type of -1 to represent a dummy assembly
595 if (input_assembly_name == _empty_key)
596 assembly_name_idx[j] = -1;
597 // Set index of assembly name based on `input_assembly_names` variable
598 else
599 {
600 const auto it = std::find(
601 input_assembly_names.begin(), input_assembly_names.end(), input_assembly_name);
602 assembly_name_idx[j] = it - input_assembly_names.begin();
603 }
604 }
605 assembly_name_lattice.push_back(assembly_name_idx);
606 }
607
608 declareMeshProperty(RGMB::pin_names, input_pin_names);
609 declareMeshProperty(RGMB::assembly_names, input_assembly_names);
610 declareMeshProperty(RGMB::assembly_lattice, assembly_name_lattice);
612}
613
614bool
616{
617 MeshGeneratorName first_nondummy_assembly = "";
618 bool assembly_homogenization = false;
619 unsigned int n_constituent_pins = 0;
620 unsigned int n_pin_sectors = 0;
621
622 // Loop through all non-dummy input assemblies. Flexible assembly stitching is needed if one of
623 // the following criteria are met:
624 // 1. The number of constituent pins within the assembly does not match with another assembly
625 // 2. The value of is_single_pin and is_homogenized metadata do not agree with another assembly
626 // 3. The number of sectors of the constituent pins of an assembly do not match with the
627 // constituent pins of another assembly
628 for (const auto i : index_range(_inputs))
629 {
630 // Skip if assembly name is equal to dummy assembly name
631 if (_inputs[i] == _empty_key)
632 continue;
633
634 // Compute total number of constituent pins in assembly, as well as the number of sectors per
635 // side for each pin Note: number of sectors per side is defined uniformly across constituent
636 // pins of an assembly, so only first one needs to be checked
637 unsigned int total_pins = 0;
638 unsigned int pin_sectors_per_side = 0;
639 if (!getMeshProperty<bool>(RGMB::is_single_pin, _inputs[i]))
640 {
641 const auto first_pin_name =
642 getMeshProperty<std::vector<std::string>>(RGMB::pin_names, _inputs[i])[0];
643 pin_sectors_per_side = getMeshProperty<std::vector<unsigned int>>("num_sectors_per_side_meta",
644 first_pin_name + "_2D")[0];
645 const auto pin_lattice =
646 getMeshProperty<std::vector<std::vector<int>>>(RGMB::pin_lattice, _inputs[i]);
647 for (const auto i : index_range(pin_lattice))
648 total_pins += pin_lattice[i].size();
649 }
650 else
651 {
652 if (getMeshProperty<bool>(RGMB::is_homogenized, _inputs[i]))
653 {
654 // Homogenized assembly
655 total_pins = 0;
656 pin_sectors_per_side = 0;
657 }
658 else
659 {
660 // Assembly with single constituent pin
661 total_pins = 1;
662 pin_sectors_per_side = getMeshProperty<std::vector<unsigned int>>(
663 "num_sectors_per_side_meta", _inputs[i] + "_2D")[0];
664 }
665 }
666
667 if (first_nondummy_assembly == "")
668 {
669 first_nondummy_assembly = MeshGeneratorName(_inputs[i]);
670 assembly_homogenization = getMeshProperty<bool>(RGMB::is_homogenized, _inputs[i]);
671 n_constituent_pins = total_pins;
672 n_pin_sectors = pin_sectors_per_side;
673 }
674 else
675 {
676 if (getMeshProperty<bool>(RGMB::is_homogenized, _inputs[i]) != assembly_homogenization)
677 {
678 mooseWarning("Detected mix of homogenized and heterogeneous assemblies between " +
679 first_nondummy_assembly + " and " + _inputs[i]);
680 return true;
681 }
682 if (total_pins != n_constituent_pins)
683 {
685 "Detected assemblies with different number of total constituent pins between " +
686 first_nondummy_assembly + " and " + _inputs[i]);
687 return true;
688 }
689 if (pin_sectors_per_side != n_pin_sectors)
690 {
691 mooseWarning("Constituent pins in " + first_nondummy_assembly + " and " + _inputs[i] +
692 " differ in terms of number of sectors per side");
693 return true;
694 }
695 }
696 }
697 return false;
698}
699
700std::unique_ptr<MeshBase>
702{
703 // Must be called to free the ReactorMeshParams mesh
705
706 // If bypass_mesh is true, return a null mesh. In this mode, an output mesh is not
707 // generated and only metadata is defined on the generator, so logic related to
708 // generation of output mesh will not be called
709 if (getReactorParam<bool>(RGMB::bypass_meshgen))
710 {
711 auto null_mesh = nullptr;
712 return null_mesh;
713 }
714 // This generate() method will be called once the subgenerators that we depend on are
715 // called. This is where we reassign subdomain ids/names in case they were merged
716 // when stitching assemblies into the core. This is also where we set region_id extra
717 // element integers, which has not been set yet for extruded geometries
718
719 // Define all extra element names and integers
720 std::string pin_type_id_name = "pin_type_id";
721 std::string assembly_type_id_name = "assembly_type_id";
722 std::string plane_id_name = "plane_id";
723 std::string region_id_name = "region_id";
724 std::string radial_id_name = "radial_id";
725 const std::string default_block_name = RGMB::CORE_BLOCK_NAME_PREFIX;
726
727 auto pin_type_id_int = getElemIntegerFromMesh(*(*_build_mesh), pin_type_id_name, true);
728 auto assembly_type_id_int = getElemIntegerFromMesh(*(*_build_mesh), assembly_type_id_name, true);
729 auto radial_id_int = getElemIntegerFromMesh(*(*_build_mesh), radial_id_name, true);
730 auto region_id_int = getElemIntegerFromMesh(*(*_build_mesh), region_id_name, true);
731 unsigned int plane_id_int = 0;
732 if (_extrude)
733 plane_id_int = getElemIntegerFromMesh(*(*_build_mesh), plane_id_name, true);
734
735 // Get next free block ID in mesh in case subdomain ids need to be remapped
736 auto next_block_id = MooseMeshUtils::getNextFreeSubdomainID(*(*(_build_mesh)));
737 std::map<std::string, SubdomainID> rgmb_name_id_map;
738
739 // Loop through all mesh elements and set region ids and reassign block IDs/names
740 // if they were merged during assembly stitching
741 for (auto & elem : (*_build_mesh)->active_element_ptr_range())
742 {
743 dof_id_type z_id = _extrude ? elem->get_extra_integer(plane_id_int) : 0;
744 dof_id_type pin_type_id = elem->get_extra_integer(pin_type_id_int);
745
746 if (_pin_region_id_map.find(pin_type_id) != _pin_region_id_map.end())
747 {
748 // Pin type element, get region ID from pin_type, z_id, and radial_idx
749 const dof_id_type radial_idx = elem->get_extra_integer(radial_id_int);
750 const auto elem_rid = _pin_region_id_map[pin_type_id][z_id][radial_idx];
751 elem->set_extra_integer(region_id_int, elem_rid);
752
753 // Set element block name and block id
754 bool has_block_names = !_pin_block_name_map[pin_type_id].empty();
755 auto elem_block_name = default_block_name;
756 if (has_block_names)
757 elem_block_name += "_" + _pin_block_name_map[pin_type_id][z_id][radial_idx];
758 else if (getReactorParam<bool>(RGMB::region_id_as_block_name))
759 elem_block_name += "_REG" + std::to_string(elem_rid);
760 if (elem->type() == TRI3 || elem->type() == PRISM6)
761 elem_block_name += RGMB::TRI_BLOCK_NAME_SUFFIX;
763 *(*_build_mesh), elem, rgmb_name_id_map, elem_block_name, next_block_id);
764 }
765 else if ((*_build_mesh)->subdomain_name(elem->subdomain_id()) ==
767 // periphery type element
768 {
769 // set region ID of core periphery element
770 elem->set_extra_integer(region_id_int, _periphery_region_id);
771 // set block name and block name of core periphery element
772 auto elem_block_name = _periphery_block_name;
773 if (getReactorParam<bool>(RGMB::region_id_as_block_name))
774 elem_block_name += "_REG" + std::to_string(_periphery_region_id);
775 if (elem->type() == TRI3 || elem->type() == PRISM6)
776 elem_block_name += RGMB::TRI_BLOCK_NAME_SUFFIX;
778 *(*_build_mesh), elem, rgmb_name_id_map, elem_block_name, next_block_id);
779 }
780 else
781 {
782 dof_id_type assembly_type_id = elem->get_extra_integer(assembly_type_id_int);
783 // Infer peripheral index of assembly background, assembly duct, or control drum regions from
784 // pin_type_id
785 unsigned int peripheral_idx = RGMB::MAX_PIN_TYPE_ID - pin_type_id;
786
787 // check if element is part of drum region
788 if (_drum_region_id_map.find(assembly_type_id) != _drum_region_id_map.end())
789 {
790 // Element is in a control drum region. Infer region id from assembly_type_id, z_id, and
791 // peripheral_index
792 const auto elem_rid = _drum_region_id_map[assembly_type_id][z_id][peripheral_idx];
793 elem->set_extra_integer(region_id_int, elem_rid);
794
795 // Set element block name and block id
796 auto elem_block_name = default_block_name;
797 if (getReactorParam<bool>(RGMB::region_id_as_block_name))
798 elem_block_name += "_REG" + std::to_string(elem_rid);
799 else
800 {
801 bool has_drum_block_name = !_drum_block_name_map[assembly_type_id].empty();
802 if (has_drum_block_name)
803 elem_block_name += "_" + _drum_block_name_map[assembly_type_id][z_id][peripheral_idx];
804 }
805 if (elem->type() == TRI3 || elem->type() == PRISM6)
806 elem_block_name += RGMB::TRI_BLOCK_NAME_SUFFIX;
808 *(*_build_mesh), elem, rgmb_name_id_map, elem_block_name, next_block_id);
809 }
810 else
811 {
812 // Element is in an assembly duct or background region since it doesn't
813 // have an assembly type id in the drum region map. Infer region id from
814 // assembly_type_id, z_id, and peripheral_index
815 bool is_background_region = peripheral_idx == 0;
816 const auto elem_rid =
817 (is_background_region
818 ? _background_region_id_map[assembly_type_id][z_id]
819 : _duct_region_id_map[assembly_type_id][z_id][peripheral_idx - 1]);
820 elem->set_extra_integer(region_id_int, elem_rid);
821
822 // Set element block name and block id
823 auto elem_block_name = default_block_name;
824 if (getReactorParam<bool>(RGMB::region_id_as_block_name))
825 elem_block_name += "_REG" + std::to_string(elem_rid);
826 else
827 {
828 if (is_background_region)
829 {
830 bool has_background_block_name = !_background_block_name_map[assembly_type_id].empty();
831 if (has_background_block_name)
832 elem_block_name += "_" + _background_block_name_map[assembly_type_id][z_id];
833 }
834 else
835 {
836 bool has_duct_block_names = !_duct_block_name_map[assembly_type_id].empty();
837 if (has_duct_block_names)
838 elem_block_name +=
839 "_" + _duct_block_name_map[assembly_type_id][z_id][peripheral_idx - 1];
840 }
841 }
842 if (elem->type() == TRI3 || elem->type() == PRISM6)
843 elem_block_name += RGMB::TRI_BLOCK_NAME_SUFFIX;
845 *(*_build_mesh), elem, rgmb_name_id_map, elem_block_name, next_block_id);
846 }
847 }
848 }
849
850 // Sideset 10000 does not get stitched properly when BlockDeletionGenerator
851 // is used for deleting dummy assemblies. This block copies missing sides
852 // into sideset 10000 from sideset RGMB::CORE_BOUNDARY_NAME
853 BoundaryInfo & boundary_info = (*_build_mesh)->get_boundary_info();
854 boundary_id_type source_id =
856 boundary_id_type target_id = 10000;
857 const auto sideset_map = boundary_info.get_sideset_map();
858
859 for (const auto & [elem, id_pair] : sideset_map)
860 {
861 const auto side_id = id_pair.first;
862 const auto sideset_id = id_pair.second;
863
864 // Filter all sides that belong to RGMB::CORE_BOUNDARY_NAME sideset
865 if (sideset_id == source_id)
866 {
867 auto mm_it = sideset_map.equal_range(elem);
868 bool found = false;
869 // Check if side is defined in sideset 10000
870 for (auto it = mm_it.first; it != mm_it.second; it++)
871 {
872 if (it->second.first == side_id && it->second.second == target_id)
873 found = true;
874 }
875 // Add side if not found in sideset 10000
876 if (!found)
877 boundary_info.add_side(elem, side_id, target_id);
878 }
879 }
880
881 if (getParam<bool>("generate_depletion_id"))
882 {
883 const MooseEnum option = getParam<MooseEnum>("depletion_id_type");
885 }
886
887 // Mark mesh as not prepared, as block ID's were re-assigned in this method
888 (*_build_mesh)->unset_is_prepared();
889
890 return std::move(*_build_mesh);
891}
892
893std::unique_ptr<CSG::CSGBase>
895{
896 // Must be called to free the ReactorMeshParams CSGBase object
898
899 auto csg_obj = std::make_unique<CSG::CSGBase>();
900
901 const auto dummy_univ_name = _empty_key + "_univ";
903 {
904 // Create universe with a single void cell with an empty region. This universe is used for
905 // defining dummy assemblies in the core lattice and the lattce outer universe for lattices
906 // that do not have a mesh periphery
907 const auto dummy_cell_name = _empty_key + "_cell";
908 const auto & dummy_univ = csg_obj->createUniverse(dummy_univ_name);
909 CSG::CSGRegion empty_region;
910 csg_obj->createCell(dummy_cell_name, empty_region, &dummy_univ);
911 }
912
913 // Combine all bases from AssemblyMG inputs into this base. We expect each AssemblyMG
914 // input to contain a root universe with a single cell that constrains the assembly based
915 // on the FEM boundary. Root universes from inputs are renamed to a new universe name.
916 // These universes and their cells will be discarded, so that only the infinite assembly
917 // universes are retained.
918 std::unordered_map<unsigned int, std::string> univ_id_names;
919 std::vector<std::string> univs_to_discard;
920 for (const auto i : index_range(_inputs))
921 {
922 if (_inputs[i] == _empty_key)
923 univ_id_names[i] = dummy_univ_name;
924 else
925 {
926 const auto input_univ_name_discard = _inputs[i] + "_root_univ";
927 const auto input_univ_name = _inputs[i] + "_univ";
928 csg_obj->joinOtherBase(std::move(*_input_csg_bases[i]), true, input_univ_name_discard);
929 univs_to_discard.push_back(input_univ_name_discard);
930 univ_id_names[i] = input_univ_name;
931 }
932 }
933
934 // Discard root universes of the input assemblies and their cells
935 for (const auto & univ_name : univs_to_discard)
936 {
937 const auto & universe_to_delete = csg_obj->getUniverseByName(univ_name);
938 const auto cells_to_delete = universe_to_delete.getAllCells();
939 csg_obj->deleteUniverse(universe_to_delete);
940 for (const auto & cell : cells_to_delete)
941 csg_obj->deleteCell(cell.get());
942 }
943
944 // Build the universe pattern for the assembly lattice from the input pattern
945 std::vector<std::vector<std::reference_wrapper<const CSG::CSGUniverse>>> universe_pattern;
946 for (const auto & row : _pattern)
947 {
948 std::vector<std::reference_wrapper<const CSG::CSGUniverse>> universe_row;
949 for (const auto & univ_id : row)
950 {
951 const auto & lattice_univ = csg_obj->getUniverseByName(univ_id_names[univ_id]);
952 universe_row.push_back(lattice_univ);
953 }
954 universe_pattern.push_back(universe_row);
955 }
956
957 const auto assembly_pitch = getReactorParam<Real>(RGMB::assembly_pitch);
958 auto & core_lattice = createRGMBLattice(assembly_pitch, universe_pattern, *csg_obj);
959
960 // Define universe that fills region outside of lattice. For an explicity
961 // defined outer ring, this is a material outer corresponding to the region ID
962 // of the ring region. Otherwise, the outer is defined as a universe containing a void cell
963 if (_mesh_periphery)
964 {
965 std::string region_name = "rgmb_region_" + std::to_string(_periphery_region_id);
966 csg_obj->setLatticeOuter(core_lattice, region_name);
967 }
968 else
969 {
970 const auto & outer_univ = csg_obj->getUniverseByName(dummy_univ_name);
971 csg_obj->setLatticeOuter(core_lattice, outer_univ);
972 }
973
974 // Define lattice cell, with the lattice surrounded by a bounding circle whose radius is
975 // determined by the mesh periphery radius. If no mesh periphery is defined, the radius will be (N
976 // + 1) times the assembly pitch of the lattice for hex lattices, where N is the number of rings
977 // for a hexagonal lattice. For Cartesian lattices, the radius will be (N / 2 * sqrt(2)) times the
978 // assembly pitch, where N is the number of assembly widths that span a square lattice. This
979 // ensures that the ring radius completely surrounds the underlying lattice.
980 std::string lat_cell_name = name() + "_lattice_cell";
981 const auto ring_radius = _mesh_periphery ? _outer_circle_radius
982 : (_geom_type == "Hex")
983 ? (universe_pattern.size() + 2) / 2. * assembly_pitch
984 : universe_pattern.size() / 2. * sqrt(2.) * assembly_pitch;
985 const auto ring_surf_name = name() + "_radial_ring";
986 std::unique_ptr<CSG::CSGSurface> ring_surf_ptr =
987 std::make_unique<CSG::CSGZCylinder>(ring_surf_name, 0, 0, ring_radius);
988 const auto & ring_surf = csg_obj->addSurface(std::move(ring_surf_ptr));
989 auto lat_cell_region = -ring_surf;
990
991 if (_mesh_dimensions == 3)
992 {
993 const auto surfaces_by_axial_region = getAxialPlaneSurfaces(*csg_obj);
994 const auto & lowest_axial_surf = surfaces_by_axial_region.front().get();
995 const auto & highest_axial_surf = surfaces_by_axial_region.back().get();
996 lat_cell_region = lat_cell_region & +lowest_axial_surf & -highest_axial_surf;
997 }
998 csg_obj->createCell(lat_cell_name, core_lattice, lat_cell_region);
999
1000 return csg_obj;
1001}
registerMooseObject("ReactorApp", CoreMeshGenerator)
void ErrorVector unsigned int
Mesh generator for defining a reactor core using a Cartesian or hexagonal lattice with the option to ...
unsigned int _mesh_dimensions
The number of dimensions the mesh is ultimately going to have (2 or 3, declared in the ReactorMeshPar...
const unsigned int _outer_circle_num_segments
Number of segments in the outer circle boundary.
bool _empty_pos
Whether empty positions are to be used in the pattern.
std::map< subdomain_id_type, std::vector< std::string > > _background_block_name_map
A mapping from assembly-type IDs to block names in the assembly background regions used when assignin...
CoreMeshGenerator(const InputParameters &parameters)
std::map< subdomain_id_type, std::vector< std::vector< std::string > > > _drum_block_name_map
A mapping from assembly-type IDs to block names in the drum regions used when assigning block names d...
const unsigned int _periphery_num_layers
Number of periphery layers.
const std::string _periphery_block_name
The subdomain name for the generated mesh outer boundary.
std::map< subdomain_id_type, std::vector< std::vector< std::string > > > _pin_block_name_map
A mapping from pin-type IDs to block names used when assigning block names during the assembly stitch...
std::string _geom_type
The geometry type for the reactor that is stored on the ReactorMeshParams object.
const bool _mesh_periphery
Whether the core periphery should be meshed.
std::unique_ptr< MeshBase > * _build_mesh
The final mesh that is generated by the subgenerators; This mesh is generated by the subgenerators wi...
bool constituentAssembliesNeedFlexibleStiching()
std::map< subdomain_id_type, std::vector< subdomain_id_type > > _background_region_id_map
A mapping from assembly-type IDs to region IDs in the assembly background regions used when assigning...
const bool _extrude
Whether this mesh should be extruded to 3-D, the core is always assumed to be the last.
const Real _outer_circle_radius
outer circle boundary radius
std::unique_ptr< CSG::CSGBase > generateCSG() override
static InputParameters validParams()
const Real _desired_area
Desired (maximum) triangle area.
const std::vector< MeshGeneratorName > _inputs
The names of the assemblies that compose the core.
const std::vector< std::vector< unsigned int > > _pattern
The 2D assembly layout of the core.
std::vector< std::unique_ptr< CSG::CSGBase > * > _input_csg_bases
List of pointers to all CSG bases created by input mesh generators.
const subdomain_id_type _periphery_region_id
"region_id" extra-element integer of the periphery mesh elements
std::map< subdomain_id_type, std::vector< std::vector< subdomain_id_type > > > _drum_region_id_map
A mapping from assembly-type IDs to region IDs in the drum regions used when assigning region IDs dur...
std::map< subdomain_id_type, std::vector< std::vector< std::string > > > _duct_block_name_map
A mapping from assembly-type IDs to block names in the assembly duct regions used when assigning bloc...
std::map< subdomain_id_type, std::vector< std::vector< subdomain_id_type > > > _pin_region_id_map
A mapping from pin-type IDs to region IDs used when assigning region IDs during the assembly stitchin...
std::string _desired_area_func
Desired (local) triangle area as a function of (x,y)
const MeshGeneratorName _empty_key
The name of "filler" assembly given in the input to represent an empty space in the core pattern.
const MooseEnum _periphery_meshgenerator
Which periphery meshgenerator to use.
std::unique_ptr< MeshBase > generate() override
std::map< subdomain_id_type, std::vector< std::vector< subdomain_id_type > > > _duct_region_id_map
A mapping from assembly-type IDs to region IDs in the assembly duct regions used when assigning regio...
InputParameters getValidParams(const std::string &name) const
bool isParamSetByUser(const std::string &name) const
T & set(const std::string &name, bool quiet_mode=false)
bool getCSGOnly() const
std::vector< std::unique_ptr< MeshBase > * > getMeshes(const std::string &param_name)
void addMeshSubgenerator(const std::string &type, const std::string &name, Ts... extra_input_parameters)
std::unique_ptr< MeshBase > & getMeshByName(const MeshGeneratorName &mesh_generator_name)
static void setHasGenerateCSG(InputParameters &params)
std::vector< std::unique_ptr< CSG::CSGBase > * > getCSGBases(const std::string &param_name)
void declareMeshesForSub(const std::string &param_name)
T & declareMeshProperty(const std::string &data_name, Args &&... args)
void declareNullMeshName(const MeshGeneratorName &name)
bool hasMeshProperty(const std::string &data_name, const std::string &prefix) const
const T & getMeshProperty(const std::string &data_name, const std::string &prefix)
Factory & getFactory()
MeshGeneratorSystem & getMeshGeneratorSystem()
const InputParameters & parameters() const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
void mooseWarning(Args &&... args) const
MooseApp & _app
A base class that contains common members for Reactor Geometry Mesh Builder mesh generators.
void initializeReactorMeshParams(const std::string reactor_param_name)
Initializes and checks validity of ReactorMeshParams mesh generator object.
std::vector< std::reference_wrapper< const CSG::CSGSurface > > getAxialPlaneSurfaces(CSG::CSGBase &csg_obj)
Get CSGSurfaces corresponding to axial planes of the extruded RGMB mesh.
static void addDepletionIDParams(InputParameters &parameters)
MeshGeneratorName callExtrusionMeshSubgenerators(const MeshGeneratorName input_mesh_name)
Calls mesh subgenerators related to extrusion, renaming of top / bottom boundaries,...
void freeReactorParamsMesh()
Releases the mesh obtained in _reactor_params_mesh.
void updateElementBlockNameId(MeshBase &input_mesh, Elem *elem, std::map< std::string, SubdomainID > &name_id_map, std::string elem_block_name, SubdomainID &next_free_id)
Updates the block names and ids of the element in an input mesh according to a map of block name to b...
void addDepletionId(MeshBase &input_mesh, const MooseEnum &option, const DepletionIDGenerationLevel generation_level, const bool extrude)
add depletion IDs
const CSG::CSGLattice & createRGMBLattice(const Real pitch, const std::vector< std::vector< std::reference_wrapper< const CSG::CSGUniverse > > > pattern, CSG::CSGBase &csg_obj)
Create CSG lattice for assembly and core lattices.
void freeReactorParamsCSG()
Releases the CSG base object obtained in _reactor_params_csg.
unsigned int getElemIntegerFromMesh(MeshBase &input_mesh, std::string extra_int_name, bool should_exist=false)
Initializes extra element integer from id name for a given mesh and throws an error if it should exis...
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
SubdomainID getNextFreeSubdomainID(MeshBase &input_mesh)
const subdomain_id_type PERIPHERAL_RING_BLOCK_ID
static const std::string peripheral_ring_radius
const subdomain_id_type MAX_PIN_TYPE_ID
static const std::string bottom_boundary_id
static const std::string is_single_pin
static const std::string pin_region_id_map
static const std::string pin_lattice
static const std::string peripheral_ring_region_id
static const std::string radial_boundary_id
const SubdomainName CORE_BLOCK_NAME_PREFIX
static const std::string is_control_drum
static const std::string bypass_meshgen
const subdomain_id_type DUMMY_ASSEMBLY_BLOCK_ID
static const std::string assembly_names
static const std::string top_boundary_id
static const std::string drum_region_ids
static const std::string assembly_type
static const std::string pin_block_name_map
const SubdomainName PERIPHERAL_RING_BLOCK_NAME
static const std::string duct_block_names
const SubdomainName TRI_BLOCK_NAME_SUFFIX
const BoundaryName ASSEMBLY_BOUNDARY_NAME_PREFIX
static const std::string assembly_pitch
static const std::string mesh_dimensions
static const std::string duct_region_ids
const BoundaryName CORE_BOUNDARY_NAME
static const std::string extruded
static const std::string background_region_id
static const std::string assembly_lattice
static const std::string flexible_assembly_stitching
static const std::string is_homogenized
static const std::string drum_block_names
static const std::string region_id_as_block_name
static const std::string background_block_name
static const std::string reactor_params_name
static const std::string pin_names
static const std::string mesh_geometry
static const std::string pin_type
const boundary_id_type side_id