16 #include "libmesh/elem.h" 27 params.addRequiredParam<MeshGeneratorName>(
29 "The ReactorMeshParams MeshGenerator that is the basis for this component mesh.");
32 "The assembly type integer ID to use for this control drum definition. " 33 "This parameter should be uniquely defined for each ControlDrumMeshGenerator " 34 "and AssemblyMeshGenerator structure in the RGMB workflow.");
35 params.addParam<
bool>(
"extrude",
37 "Determines if this is the final step in the geometry construction" 38 " and extrudes the 2D geometry to 3D. If this is true then this mesh " 39 "cannot be used in further mesh building in the Reactor workflow");
40 params.addRequiredRangeCheckedParam<
Real>(
41 "drum_inner_radius",
"drum_inner_radius>0",
"Inner radius of drum region");
42 params.addRequiredRangeCheckedParam<
Real>(
43 "drum_outer_radius",
"drum_outer_radius>0",
"Outer radius of drum region");
44 params.addRangeCheckedParam<
unsigned int>(
45 "drum_inner_intervals",
47 "drum_inner_intervals>0",
48 "Number of radial mesh intervals in region up to inner drum radius");
49 params.addRangeCheckedParam<
unsigned int>(
50 "drum_intervals", 1,
"drum_intervals>0",
"Number of radial mesh intervals in drum region");
51 params.addRangeCheckedParam<
Real>(
"pad_start_angle",
52 "pad_start_angle>=0 & pad_start_angle < 360",
53 "Starting angle of drum pad region");
54 params.addRangeCheckedParam<
Real>(
55 "pad_end_angle",
"pad_end_angle>0 & pad_end_angle < 720",
"Ending angle of drum pad region");
56 params.addRequiredRangeCheckedParam<
unsigned int>(
57 "num_azimuthal_sectors",
58 "num_azimuthal_sectors>2",
59 "Number of azimuthal sectors to sub-divide the drum region into");
60 params.addRequiredParam<std::vector<std::vector<subdomain_id_type>>>(
62 "IDs for each radial and axial zone for assignment of region_id extra element " 64 "Inner indexing is radial zones (drum inner/drum/drum outer), outer indexing is axial");
65 params.addParam<std::vector<std::vector<std::string>>>(
67 "Block names for each radial and axial zone. " 68 "Inner indexing is radial zones (drum inner/drum/drum outer), outer indexing is axial");
69 params.addParam<
Real>(
"azimuthal_node_tolerance",
71 "(in degrees) The absolute tolerance for which to shift an azimuthal node " 72 "to match the pad start/end angles");
74 params.addParamNamesToGroup(
"region_ids assembly_type",
"ID assigment");
75 params.addParamNamesToGroup(
"drum_inner_radius drum_outer_radius drum_inner_intervals " 76 "drum_intervals num_azimuthal_sectors",
77 "Drum specifications");
78 params.addParamNamesToGroup(
"pad_start_angle pad_end_angle azimuthal_node_tolerance",
79 "Control pad specifications");
81 params.addClassDescription(
82 "This ControlDrumMeshGenerator object is designed to generate " 83 "drum-like structures, with IDs, from a reactor geometry. " 84 "These structures can be used directly within CoreMeshGenerator to stitch" 85 "control drums into a core lattice alongside AssemblyMeshGenerator structures");
95 _drum_inner_radius(getParam<
Real>(
"drum_inner_radius")),
96 _drum_outer_radius(getParam<
Real>(
"drum_outer_radius")),
97 _extrude(getParam<bool>(
"extrude")),
105 mooseError(
"'flexible_assembly_stitching' needs to be set to true in ReactorMeshParams in " 106 "order to use ControlDrumMeshGenerator");
111 const auto drum_inner_intervals = getParam<unsigned int>(
"drum_inner_intervals");
112 const auto drum_intervals = getParam<unsigned int>(
"drum_intervals");
113 const auto num_sectors = getParam<unsigned int>(
"num_azimuthal_sectors");
122 "If 'pad_start_angle' is set, 'pad_end_angle' needs to also be set.");
127 "The difference between 'pad_end_angle' and 'pad_start_angle' must be between 0 " 128 "and 360 exclusive.");
135 "If 'pad_end_angle' is set, 'pad_start_angle' needs to also be set.");
140 const auto azimuthal_node_tolerance = getParam<Real>(
"azimuthal_node_tolerance");
143 "This parameter is relevant only when pad start and end angles are defined");
145 360. / (
Real)num_sectors))
147 "Azimuthal node tolerance should be smaller than half the azimuthal interval size " 148 "as defined by 'num_azimuthal_sectors'");
152 "Azimuthal node tolerance should be smaller than half the difference of the pad " 157 unsigned int n_axial_levels =
162 mooseError(
"The size of region IDs must be equal to the number of axial levels as defined in " 163 "the ReactorMeshParams object");
166 std::string err_msg =
167 "'region_ids' parameter does not have the correct number of elements per axial zone. ";
169 ?
"For control drums with a pad region, 4 radial IDs need to be provided per " 170 "axial zone (drum inner, drum pad, drum ex-pad, and drum outer)" 171 :
"For control drums with no pad region, 3 radial IDs need to be provided per " 172 "axial zone (drum inner, drum, and drum outer)";
181 "If ReactorMeshParams/region_id_as_block_name is set, block_names should not be " 182 "specified in ControlDrumMeshGenerator");
184 _block_names = getParam<std::vector<std::vector<std::string>>>(
"block_names");
186 mooseError(
"The size of block_names must match the size of region_ids");
189 mooseError(
"The size of block_names must match the size of region_ids");
197 "In order to extrude this mesh, ReactorMeshParams/dim needs to be set to 3\n");
200 mooseError(
"Both top_boundary_id and bottom_boundary_id must be provided in ReactorMeshParams " 201 "if using extruded geometry");
205 std::vector<Real> azimuthal_angles;
207 const auto custom_end_angle =
209 for (
unsigned int i = 0; i < num_sectors; ++i)
211 Real current_azim_angle = (
Real)i * 360. / (
Real)num_sectors;
212 Real next_azim_angle = (
Real)(i + 1) * 360. / (
Real)num_sectors;
214 azimuthal_angles.push_back(current_azim_angle);
222 azimuthal_node_tolerance))
224 azimuthal_angles.push_back(custom_start_angle);
227 azimuthal_node_tolerance))
229 azimuthal_angles.push_back(custom_end_angle);
232 azimuthal_node_tolerance) &&
234 azimuthal_node_tolerance))
236 mooseWarning(
"pad_start_angle not contained within drum azimuthal discretization so " 237 "additional azimuthal nodes are created to align mesh with this angle");
238 azimuthal_angles.push_back(current_azim_angle);
239 azimuthal_angles.push_back(custom_start_angle);
242 azimuthal_node_tolerance) &&
244 azimuthal_node_tolerance))
246 mooseWarning(
"pad_end_angle not contained within drum azimuthal discretization so " 247 "additional azimuthal nodes are created to align mesh with this angle");
248 azimuthal_angles.push_back(current_azim_angle);
249 azimuthal_angles.push_back(custom_end_angle);
252 azimuthal_angles.push_back(current_azim_angle);
258 paramError(
"drum_outer_radius",
"Drum outer radius must be larger than the inner radius");
261 auto radius_corrfac =
267 "Volume-corrected outer radius of drum region must be smaller than half the " 269 "defined by 'ReactorMeshParams/assembly_pitch'");
274 const std::string block_name_prefix =
281 params.
set<std::vector<Real>>(
"customized_azimuthal_angles") = azimuthal_angles;
283 params.set<std::vector<unsigned int>>(
"ring_intervals") = {drum_inner_intervals,
285 if (drum_inner_intervals > 1)
287 params.set<std::vector<subdomain_id_type>>(
"ring_block_ids") = {
291 params.set<std::vector<SubdomainName>>(
"ring_block_names") = {
292 block_name_prefix +
"_R0_TRI", block_name_prefix +
"_R0", block_name_prefix +
"_R1"};
296 params.set<std::vector<subdomain_id_type>>(
"ring_block_ids") = {
298 params.set<std::vector<SubdomainName>>(
"ring_block_names") = {block_name_prefix +
"_R0",
299 block_name_prefix +
"_R1"};
301 params.set<
bool>(
"create_outward_interface_boundaries") =
false;
309 params.
set<std::vector<MeshGeneratorName>>(
"inputs") = {
name() +
"_accg"};
310 params.set<std::vector<libMesh::Point>>(
"extra_positions") = {
libMesh::Point(0, 0, 0)};
311 params.set<std::vector<unsigned int>>(
"extra_positions_mg_indices") = {0};
312 params.set<
bool>(
"use_auto_area_func") =
true;
315 params.set<
bool>(
"verify_holes") =
false;
317 params.set<
unsigned int>(
"boundary_sectors") =
322 params.set<BoundaryName>(
"external_boundary_name") =
324 params.set<SubdomainName>(
"background_subdomain_name") = block_name_prefix +
"_R2_TRI";
330 copyMeshProperty<bool>(
"is_control_drum_meta",
name() +
"_fpg");
331 copyMeshProperty<Real>(
"pattern_pitch_meta",
name() +
"_fpg");
333 std::string build_mesh_name =
name() +
"_delbds";
339 params.
set<MeshGeneratorName>(
"input") =
name() +
"_fpg";
340 params.set<std::vector<BoundaryName>>(
"boundary_names") = {
"0",
"2"};
373 std::unique_ptr<MeshBase>
384 auto null_mesh =
nullptr;
394 std::string plane_id_name =
"plane_id";
395 std::string region_id_name =
"region_id";
396 std::string pin_type_id_name =
"pin_type_id";
397 std::string assembly_type_id_name =
"assembly_type_id";
398 const std::string default_block_name =
405 unsigned int plane_id_int = 0;
411 std::map<std::string, SubdomainID> rgmb_name_id_map;
415 for (
auto & elem : (*_build_mesh)->active_element_ptr_range())
423 const auto base_block_id = elem->subdomain_id();
424 const auto base_block_name = (*_build_mesh)->subdomain_name(base_block_id);
428 if (!(base_block_name.find(prefix, 0) == 0))
432 const unsigned int radial_idx = std::stoi(base_block_name.substr(prefix.length()));
436 const unsigned int drum_idx =
439 elem->set_extra_integer(pin_type_id_int,
pin_type);
442 elem->set_extra_integer(region_id_int, elem_rid);
445 auto elem_block_name = default_block_name;
447 elem_block_name +=
"_REG" + std::to_string(elem_rid);
450 if (elem->type() ==
TRI3 || elem->type() ==
PRISM6)
453 *(*
_build_mesh), elem, rgmb_name_id_map, elem_block_name, next_block_id);
456 if (getParam<bool>(
"generate_depletion_id"))
458 const MooseEnum option = getParam<MooseEnum>(
"depletion_id_type");
463 (*_build_mesh)->set_isnt_prepared();
474 unsigned int drum_idx = radial_idx;
483 Real drum_angle = std::atan2(elem_x, elem_y) * 180. / M_PI;
503 else if (radial_idx == 2)
std::unique_ptr< MeshBase > & getMeshByName(const MeshGeneratorName &mesh_generator_name)
static void addDepletionIDParams(InputParameters ¶meters)
static const std::string drum_radii
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 assembly_type
const bool _extrude
Whether this mesh should be extruded to 3-D, making it the final structure in the reactor mesh...
static const std::string region_id_as_block_name
const SubdomainName DRUM_BLOCK_NAME_PREFIX
static InputParameters validParams()
static const std::string is_single_pin
const subdomain_id_type CONTROL_DRUM_BLOCK_ID_PAD
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::unique_ptr< MeshBase > * _build_mesh
The final mesh that is generated by the subgenerators; This mesh is generated by the subgenerators wi...
static constexpr boundary_id_type ASSEMBLY_BOUNDARY_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
const subdomain_id_type CONTROL_DRUM_BLOCK_ID_OUTER
Mesh generator for defining a reactor control drum that can be used in a Cartesian or hexagonal latti...
void addDepletionId(MeshBase &input_mesh, const MooseEnum &option, const DepletionIDGenerationLevel generation_level, const bool extrude)
add depletion IDs
std::string _geom_type
The type of geometry that is being described (Square or Hex, declared in the ReactorMeshParams object...
static const std::string assembly_pitch
std::unique_ptr< MeshBase > generate() override
static const std::string pin_type
static InputParameters validParams()
const SubdomainName TRI_BLOCK_NAME_SUFFIX
virtual const std::string & name() const
void mooseWarning(Args &&... args) const
static const std::string drum_block_names
bool isParamValid(const std::string &name) const
static const std::string extruded
static const std::string drum_pad_angles
const T & getReactorParam(const std::string ¶m_name)
Returns reference of parameter in ReactorMeshParams object.
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.
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...
static const std::string pitch
bool _has_pad_region
Whether pad start and end angles are provided by user.
static const std::string top_boundary_id
void paramError(const std::string ¶m, Args... args) const
const Real _drum_outer_radius
The outer radius of drum region.
const subdomain_id_type CONTROL_DRUM_BLOCK_ID_INNER_TRI
static const std::string is_homogenized
static const std::string is_control_drum
bool _has_block_names
Whether block names have been provided by user.
unsigned int getDrumIdxFromRadialIdx(const unsigned int radial_idx, const Real elem_x, const Real elem_y)
Get drum index from radial index of mesh element, drum index is used to retrieve region ID and block ...
bool isParamSetByUser(const std::string &nm) const
static const std::string flexible_assembly_stitching
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const subdomain_id_type CONTROL_DRUM_BLOCK_ID_INNER
bool absoluteFuzzyLessEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
static const std::string axial_mesh_intervals
void generateMetadata()
Define metadata associated with ControlDrumMeshGenerator.
A base class that contains common members for Reactor Geometry Mesh Builder mesh generators.
bool absoluteFuzzyGreaterEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
const subdomain_id_type _assembly_type
The id number for the type of the assembly.
const BoundaryName ASSEMBLY_BOUNDARY_NAME_PREFIX
void mooseError(Args &&... args) const
Real _pad_start_angle
Starting angle of drum pad region.
void freeReactorMeshParams()
Releases the mesh obtained in _reactor_params_mesh.
T & declareMeshProperty(const std::string &data_name, Args &&... args)
static const std::string drum_region_ids
registerMooseObject("ReactorApp", ControlDrumMeshGenerator)
static const std::string bypass_meshgen
unsigned int _mesh_dimensions
The number of dimensions the mesh is ultimately going to have (2 or 3, declared in the ReactorMeshPar...
SubdomainID getNextFreeSubdomainID(MeshBase &input_mesh)
Real radiusCorrectionFactor(const std::vector< Real > &azimuthal_list, const bool full_circle=true, const unsigned int order=1, const bool is_first_value_vertex=true)
Makes radial correction to preserve ring area.
static const std::string num_sectors_flexible_stitching
ControlDrumMeshGenerator(const InputParameters ¶meters)
const subdomain_id_type MAX_PIN_TYPE_ID
auto index_range(const T &sizable)
static const std::string bottom_boundary_id
bool absoluteFuzzyGreaterThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Real _pad_end_angle
Ending angle of drum pad region.
const Real _drum_inner_radius
The inner radius of drum region.
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...