17 #include "libmesh/elem.h" 26 params.addRequiredParam<MeshGeneratorName>(
28 "The ReactorMeshParams MeshGenerator that is the basis for this component conformal mesh.");
31 "The integer ID for this pin type definition");
33 params.addRequiredRangeCheckedParam<
Real>(
34 "pitch",
"pitch>0.0",
"The pitch for the outermost boundary polygon");
36 params.addRangeCheckedParam<
unsigned int>(
37 "num_sectors",
"num_sectors>0",
"Number of azimuthal sectors in each quadrant");
39 params.addRangeCheckedParam<std::vector<Real>>(
42 "Radii of major concentric circles of the pin. If unspecified, no pin is present.");
44 params.addRangeCheckedParam<std::vector<Real>>(
47 "Apothem of the ducts. If unspecified, no duct is present.");
49 params.addRangeCheckedParam<std::vector<unsigned int>>(
51 std::vector<unsigned int>{1},
53 "The number of meshing intervals for each region starting at the center. Parameter should be " 55 "((length(ring_radii) + length(duct_halfpitch) + 1");
57 params.addParam<std::vector<std::vector<std::string>>>(
59 "Block names for each radial and axial zone. " 60 "Inner indexing is radial zones (pin/background/duct), outer indexing is axial");
62 params.addParam<std::vector<std::vector<subdomain_id_type>>>(
64 "IDs for each radial and axial zone for assignment of region_id extra element " 66 "Inner indexing is radial zones (pin/background/duct), outer indexing is axial");
68 params.addParam<
bool>(
"extrude",
70 "Determines if this is the final step in the geometry construction" 71 " and extrudes the 2D geometry to 3D. If this is true then this mesh " 72 "cannot be used in further mesh building in the Reactor workflow");
73 params.addParam<
bool>(
74 "homogenized",
false,
"Determines whether homogenized pin mesh should be generated");
75 params.addParam<
bool>(
76 "use_as_assembly",
false,
"Determines whether pin mesh should be used as an assembly mesh");
78 params.addParam<
bool>(
79 "quad_center_elements",
true,
"Whether the center elements are quad or triangular.");
80 params.addParamNamesToGroup(
"region_ids pin_type",
"ID assigment");
81 params.addParamNamesToGroup(
82 "mesh_intervals ring_radii num_sectors pin_type homogenized use_as_assembly",
83 "Pin specifications");
84 params.addParamNamesToGroup(
"mesh_intervals duct_halfpitch num_sectors",
"Duct specifications");
86 params.addClassDescription(
"This PinMeshGenerator object is designed to generate pin-like " 87 "structures, with IDs, from a reactor geometry. " 88 "Whether it be a square or hexagonal pin, they are divided into three " 89 "substructures - the innermost " 90 "radial pin regions, the single bridging background region, and the " 91 "square or hexagonal ducts regions.");
99 _pitch(getParam<
Real>(
"pitch")),
100 _num_sectors(isParamValid(
"num_sectors") ? getParam<unsigned
int>(
"num_sectors") : 0),
101 _ring_radii(isParamValid(
"ring_radii") ? getParam<
std::vector<
Real>>(
"ring_radii")
103 _duct_halfpitch(isParamValid(
"duct_halfpitch") ? getParam<
std::vector<
Real>>(
"duct_halfpitch")
105 _intervals(getParam<
std::vector<unsigned
int>>(
"mesh_intervals")),
106 _region_ids(isParamValid(
"region_ids")
109 _extrude(getParam<bool>(
"extrude")),
110 _quad_center(getParam<bool>(
"quad_center_elements")),
111 _homogenized(getParam<bool>(
"homogenized")),
112 _is_assembly(getParam<bool>(
"use_as_assembly"))
124 mooseError(
"Pitch defined in PinMeshGenerator must match assembly_pitch defined in " 125 "ReactorMeshParams if use_as_assembly is set to true");
130 "In order to extrude this mesh, ReactorMeshParams/dim needs to be set to 3\n");
133 mooseError(
"Both top_boundary_id and bottom_boundary_id must be provided in ReactorMeshParams " 134 "if using extruded geometry");
139 mooseError(
"Homogenization in PinMeshGenerator is only supported for hexagonal geometries");
140 const std::vector<std::string> disallowed_parameters = {
141 "num_sectors",
"ring_radii",
"duct_halfpitch",
"mesh_intervals"};
142 for (
const auto & parameter : disallowed_parameters)
145 "Parameter " + parameter +
" should not be defined for a homogenized pin mesh");
151 "Number of sectors must be assigned with parameter num_sectors for non-homogenized pins");
154 "The number of mesh intervals must be equal to the number of annular regions + the " 155 "number of duct regions + 1" 156 " for the region between the rings and ducts\n");
161 unsigned int n_axial_levels =
166 mooseError(
"The size of region IDs must be equal to the number of axial levels as defined in " 167 "the ReactorMeshParams object");
169 mooseError(
"The number of region IDs given needs to be one more than the number of " 170 "ring_radii + the number of duct_radii\n");
174 mooseError(
"Region IDs must be assigned with parameter region_ids");
180 "If ReactorMeshParams/region_id_as_block_name is set, block_names should not be " 181 "specified in PinMeshGenerator");
183 _block_names = getParam<std::vector<std::vector<std::string>>>(
"block_names");
185 mooseError(
"The size of block_names must match the size of region_ids");
188 mooseError(
"The size of block_names must match the size of region_ids");
194 std::string build_mesh_name;
204 bool skip_assembly_generation =
_is_assembly && use_flexible_stitching;
211 const auto boundary_name =
214 params.set<BoundaryName>(
"external_boundary_name") = boundary_name;
215 params.set<std::vector<subdomain_id_type>>(
"block_id") = {
221 params.set<std::vector<SubdomainName>>(
"block_name") = {block_name};
223 if (!skip_assembly_generation)
225 build_mesh_name =
name() +
"_2D";
232 std::vector<unsigned int> ring_intervals;
233 std::vector<subdomain_id_type> ring_blk_ids;
234 std::vector<SubdomainName> ring_blk_names;
235 unsigned int background_intervals = 1;
236 std::vector<subdomain_id_type> background_blk_ids;
237 std::vector<SubdomainName> background_blk_names;
238 std::vector<unsigned int> duct_intervals;
239 std::vector<subdomain_id_type> duct_blk_ids;
240 std::vector<SubdomainName> duct_blk_names;
244 const auto block_name =
251 ring_blk_ids.push_back(block_id);
252 ring_blk_names.push_back(block_name);
257 duct_blk_ids.push_back(block_id);
258 duct_blk_names.push_back(block_name);
263 background_blk_ids.push_back(block_id);
264 background_blk_names.push_back(block_name);
267 if (ring_intervals.size() > 0)
269 if (ring_intervals.front() != 1)
276 ring_blk_ids.insert(ring_blk_ids.begin(), ring_blk_ids.front());
277 ring_blk_names.insert(ring_blk_names.begin(), ring_blk_names.front());
283 ring_blk_ids.insert(ring_blk_ids.begin(), block_id);
284 ring_blk_names.insert(ring_blk_names.begin(), block_name);
296 if (background_intervals > 1)
303 background_blk_ids.insert(background_blk_ids.begin(), background_blk_ids.front());
304 background_blk_names.insert(background_blk_names.begin(), background_blk_names.front());
310 background_blk_ids.insert(background_blk_ids.begin(), block_id);
311 background_blk_names.insert(background_blk_names.begin(), block_name);
326 bool skip_assembly_generation =
329 if (!skip_assembly_generation)
336 params.
set<
bool>(
"preserve_volumes") =
true;
337 params.set<
bool>(
"quad_center_elements") =
_quad_center;
338 params.set<
MooseEnum>(
"polygon_size_style") =
"apothem";
339 params.set<
Real>(
"polygon_size") =
_pitch / 2.0;
345 params.set<BoundaryName>(
"external_boundary_name") = boundary_name;
347 params.set<
bool>(
"flat_side_up") = flat_side_up;
348 params.set<
bool>(
"create_outward_interface_boundaries") =
false;
351 params.set<
unsigned int>(
"num_sides") = num_sides;
352 params.set<std::vector<unsigned int>>(
"num_sectors_per_side") =
355 if (ring_intervals.size() > 0)
357 params.set<std::vector<Real>>(
"ring_radii") =
_ring_radii;
358 params.set<std::vector<subdomain_id_type>>(
"ring_block_ids") = ring_blk_ids;
359 params.set<std::vector<SubdomainName>>(
"ring_block_names") = ring_blk_names;
360 params.set<std::vector<unsigned int>>(
"ring_intervals") = ring_intervals;
363 params.set<std::vector<subdomain_id_type>>(
"background_block_ids") = background_blk_ids;
364 params.set<std::vector<SubdomainName>>(
"background_block_names") = background_blk_names;
365 params.set<
unsigned int>(
"background_intervals") = background_intervals;
367 if (duct_intervals.size() > 0)
369 params.set<
MooseEnum>(
"duct_sizes_style") =
"apothem";
371 params.set<std::vector<subdomain_id_type>>(
"duct_block_ids") = duct_blk_ids;
372 params.set<std::vector<SubdomainName>>(
"duct_block_names") = duct_blk_names;
373 params.set<std::vector<unsigned int>>(
"duct_intervals") = duct_intervals;
383 params.
set<MeshGeneratorName>(
"input") =
name() +
"_2D";
386 std::vector<BoundaryName> boundaries_to_delete = {};
388 boundaries_to_delete.insert(boundaries_to_delete.end(),
389 {std::to_string(10001 + i), std::to_string(15001 + i)});
390 params.set<std::vector<BoundaryName>>(
"boundary_names") = boundaries_to_delete;
392 build_mesh_name =
name() +
"_delbds";
403 build_mesh_name =
name() +
"_fpg_delbds";
407 if (hasMeshProperty<Real>(
"pitch_meta",
name() +
"_2D"))
408 copyMeshProperty<Real>(
"pitch_meta",
name() +
"_2D");
409 if (
hasMeshProperty<std::vector<unsigned int>>(
"num_sectors_per_side_meta",
name() +
"_2D"))
411 if (hasMeshProperty<Real>(
"max_radius_meta",
name() +
"_2D"))
412 copyMeshProperty<Real>(
"max_radius_meta",
name() +
"_2D");
413 if (hasMeshProperty<unsigned int>(
"background_intervals_meta",
name() +
"_2D"))
414 copyMeshProperty<unsigned int>(
"background_intervals_meta",
name() +
"_2D");
415 if (hasMeshProperty<dof_id_type>(
"node_id_background_meta",
name() +
"_2D"))
416 copyMeshProperty<dof_id_type>(
"node_id_background_meta",
name() +
"_2D");
420 else if (hasMeshProperty<Real>(
"pattern_pitch_meta",
name() +
"_2D"))
421 copyMeshProperty<Real>(
"pattern_pitch_meta",
name() +
"_2D");
437 SubdomainName outermost_block_name;
438 bool has_single_mesh_interval;
445 has_single_mesh_interval =
true;
451 has_single_mesh_interval =
false;
456 params.
set<std::vector<SubdomainName>>(
"block") = {outermost_block_name};
466 if (has_single_mesh_interval)
467 params.
set<std::vector<MeshGeneratorName>>(
"inputs") = {};
470 params.set<std::vector<MeshGeneratorName>>(
"inputs") = {
name() +
"_del_outer"};
471 params.set<std::vector<libMesh::Point>>(
"extra_positions") = {
libMesh::Point(0, 0, 0)};
472 params.set<std::vector<unsigned int>>(
"extra_positions_mg_indices") = {0};
474 params.set<
bool>(
"use_auto_area_func") =
true;
475 params.set<
bool>(
"verify_holes") =
false;
477 params.set<
unsigned int>(
"boundary_sectors") =
481 params.set<BoundaryName>(
"external_boundary_name") =
483 params.set<SubdomainName>(
"background_subdomain_name") =
493 params.
set<MeshGeneratorName>(
"input") =
name() +
"_fpg";
494 std::vector<BoundaryName> boundaries_to_delete = {};
495 if (!has_single_mesh_interval)
496 boundaries_to_delete.push_back(std::to_string(1));
497 params.set<std::vector<BoundaryName>>(
"boundary_names") = boundaries_to_delete;
508 std::map<subdomain_id_type, std::vector<std::vector<subdomain_id_type>>> region_id_map{
523 std::map<subdomain_id_type, std::vector<std::vector<subdomain_id_type>>>
pin_region_id_map;
526 region_id_map.begin()->first, region_id_map.begin()->second));
528 std::map<subdomain_id_type, std::vector<std::vector<std::string>>>
pin_block_name_map;
549 unsigned int n_axial_levels =
554 n_axial_levels, std::vector<subdomain_id_type>(
_ring_radii.size()));
556 n_axial_levels, std::vector<subdomain_id_type>(
_duct_halfpitch.size()));
557 std::vector<subdomain_id_type> background_region_ids(n_axial_levels);
559 for (
const auto axial_idx :
make_range(n_axial_levels))
566 for (
unsigned int duct_idx =
_ring_radii.size() + 1;
579 std::unique_ptr<MeshBase>
590 auto null_mesh =
nullptr;
596 if (hasMeshProperty<Real>(
"max_radius_meta",
name() +
"_2D"))
598 const auto max_radius_meta = getMeshProperty<Real>(
"max_radius_meta",
name() +
"_2D");
601 if (hasMeshProperty<unsigned int>(
"background_intervals_meta",
name() +
"_2D"))
603 const auto background_intervals_meta =
604 getMeshProperty<unsigned int>(
"background_intervals_meta",
name() +
"_2D");
605 setMeshProperty(
"background_intervals_meta", background_intervals_meta);
607 if (hasMeshProperty<dof_id_type>(
"node_id_background_meta",
name() +
"_2D"))
609 const auto node_id_background_meta =
610 getMeshProperty<dof_id_type>(
"node_id_background_meta",
name() +
"_2D");
620 std::string region_id_name =
"region_id";
621 std::string pin_type_id_name =
"pin_type_id";
622 std::string assembly_type_id_name =
"assembly_type_id";
623 std::string plane_id_name =
"plane_id";
624 std::string radial_id_name =
"radial_id";
625 const std::string default_block_name =
632 unsigned int plane_id_int = 0;
633 unsigned int assembly_type_id_int = 0;
641 std::map<std::string, SubdomainID> rgmb_name_id_map;
646 for (
auto & elem : (*_build_mesh)->active_element_ptr_range())
648 const auto base_block_id = elem->subdomain_id();
649 const auto base_block_name = (*_build_mesh)->subdomain_name(base_block_id);
653 if (!(base_block_name.find(prefix, 0) == 0))
656 std::string radial_str = base_block_name.substr(prefix.length());
660 const std::size_t found = radial_str.find(suffix);
661 if (found != std::string::npos)
662 radial_str.replace(found, suffix.length(),
"");
663 const unsigned int radial_idx = std::stoi(radial_str);
670 elem->set_extra_integer(region_id_int, elem_region_id);
671 elem->set_extra_integer(pin_type_id_int,
_pin_type);
672 elem->set_extra_integer(radial_id_int, radial_idx);
674 elem->set_extra_integer(assembly_type_id_int,
_pin_type);
677 auto elem_block_name = default_block_name;
679 elem_block_name +=
"_" +
_block_names[std::size_t(z_id)][radial_idx];
681 elem_block_name +=
"_REG" + std::to_string(elem_region_id);
682 if (elem->type() ==
TRI3 || elem->type() ==
PRISM6)
685 *(*
_build_mesh), elem, rgmb_name_id_map, elem_block_name, next_block_id);
689 (*_build_mesh)->set_isnt_prepared();
std::unique_ptr< MeshBase > & getMeshByName(const MeshGeneratorName &mesh_generator_name)
const SubdomainName ASSEMBLY_BLOCK_NAME_PREFIX
const subdomain_id_type _pin_type
The id number for this pin type.
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...
static const std::string duct_block_names
static const std::string background_region_id
T & setMeshProperty(const std::string &data_name, Args &&... args)
static const std::string assembly_type
PinMeshGenerator(const InputParameters ¶meters)
static const std::string region_id_as_block_name
unsigned int _mesh_dimensions
The number of dimensions the mesh is ultimately going to have (2 or 3, declared in the ReactorMeshPar...
static const std::string is_single_pin
void generateFlexibleAssemblyBoundaries()
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...
const subdomain_id_type PIN_BLOCK_ID_START
static const std::string mesh_geometry
void initializeReactorMeshParams(const std::string reactor_param_name)
Initializes and checks validity of ReactorMeshParams mesh generator object.
InputParameters getValidParams(const std::string &name) const
Mesh generator for defining a reactor pin with background and duct regions, with the option to be 2-D...
static const std::string background_block_name
static const std::string assembly_pitch
bool _homogenized
Whether the resulting pin mesh should be homogenized.
std::vector< unsigned int > _intervals
The number of mesh intervals in a radial division starting from the center.
static const std::string pin_type
registerMooseObject("ReactorApp", PinMeshGenerator)
static InputParameters validParams()
const SubdomainName TRI_BLOCK_NAME_SUFFIX
bool _quad_center
Whether the centermost elements in the pin should be quad elements as opposed to tri elements...
virtual const std::string & name() const
bool _has_block_names
Whether block names have been provided by user.
static const std::string pin_region_id_map
const BoundaryName PIN_BOUNDARY_NAME_PREFIX
bool isParamValid(const std::string &name) const
static const std::string extruded
const T & getReactorParam(const std::string ¶m_name)
Returns reference of parameter in ReactorMeshParams object.
static const std::string duct_halfpitches
static const std::string mesh_dimensions
void addMeshSubgenerator(const std::string &type, const std::string &name, Ts... extra_input_parameters)
MeshGeneratorName callExtrusionMeshSubgenerators(const MeshGeneratorName input_mesh_name)
Calls mesh subgenerators related to extrusion, renaming of top / bottom boundaries, and defining plane IDs.
static InputParameters validParams()
static const std::string pitch
static constexpr boundary_id_type PIN_BOUNDARY_ID_START
std::vector< std::vector< std::string > > _block_names
2-D vector (axial outer indexing, radial inner indexing) used to set block names of pin mesh elements...
const unsigned int _num_sectors
The number of azimuthal divisions.
const SubdomainName PIN_BLOCK_NAME_PREFIX
static const std::string top_boundary_id
void paramError(const std::string ¶m, Args... args) const
const bool _extrude
Whether this mesh should be extruded to 3-D, making it the final structure in the reactor mesh...
std::unique_ptr< MeshBase > generate() override
static const std::string is_homogenized
std::vector< Real > _ring_radii
The outer radii of concentric rings in the pin.
static const std::string is_control_drum
static const std::string pin_region_ids
static const std::string flexible_assembly_stitching
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Real _pitch
The face-to-face size of this pin.
static const std::string ring_radii
const subdomain_id_type PIN_BLOCK_ID_TRI_FLEXIBLE
static const std::string pin_block_names
const subdomain_id_type PIN_BLOCK_ID_TRI
static const std::string axial_mesh_intervals
IntRange< T > make_range(T beg, T end)
A base class that contains common members for Reactor Geometry Mesh Builder mesh generators.
const BoundaryName ASSEMBLY_BOUNDARY_NAME_PREFIX
void mooseError(Args &&... args) const
void freeReactorMeshParams()
Releases the mesh obtained in _reactor_params_mesh.
const InputParameters & parameters() const
T & declareMeshProperty(const std::string &data_name, Args &&... args)
std::string _mesh_geometry
The type of geometry that is being described (Square or Hex, declared in the ReactorMeshParams object...
static const std::string bypass_meshgen
bool _is_assembly
Whether the resulting pin mesh should also be used as an assembly mesh.
SubdomainID getNextFreeSubdomainID(MeshBase &input_mesh)
T & copyMeshProperty(const std::string &target_data_name, const std::string &source_data_name, const std::string &source_mesh)
static const std::string num_sectors_flexible_stitching
static const std::string duct_region_ids
void ErrorVector unsigned int
auto index_range(const T &sizable)
static const std::string bottom_boundary_id
std::unique_ptr< MeshBase > * _build_mesh
The final mesh that is generated by the subgenerators; This mesh is generated by the subgenerators wi...
static const std::string pin_block_name_map
const std::vector< Real > _duct_halfpitch
The inner apothem of any surrounding ducts in the pin.
std::vector< std::vector< subdomain_id_type > > _region_ids
2-D vector (axial outer indexing, radial inner indexing) used to set "region_id" extra-element intege...
static const std::string ring_region_ids