https://mooseframework.inl.gov
ControlDrumMeshGenerator.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 
11 
14 #include "MooseApp.h"
15 #include "Factory.h"
16 #include "libmesh/elem.h"
17 #include "MooseMeshUtils.h"
19 
21 
24 {
26 
27  params.addRequiredParam<MeshGeneratorName>(
28  "reactor_params",
29  "The ReactorMeshParams MeshGenerator that is the basis for this component mesh.");
30  params.addRequiredParam<subdomain_id_type>(
31  "assembly_type",
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",
36  false,
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",
46  1,
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>>>(
61  "region_ids",
62  "IDs for each radial and axial zone for assignment of region_id extra element "
63  "id. "
64  "Inner indexing is radial zones (drum inner/drum/drum outer), outer indexing is axial");
65  params.addParam<std::vector<std::vector<std::string>>>(
66  "block_names",
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",
70  0.1,
71  "(in degrees) The absolute tolerance for which to shift an azimuthal node "
72  "to match the pad start/end angles");
73 
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");
80 
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");
86  // depletion id generation params are added
87  addDepletionIDParams(params);
88 
89  return params;
90 }
91 
93  : ReactorGeometryMeshBuilderBase(parameters),
94  _assembly_type(getParam<subdomain_id_type>("assembly_type")),
95  _drum_inner_radius(getParam<Real>("drum_inner_radius")),
96  _drum_outer_radius(getParam<Real>("drum_outer_radius")),
97  _extrude(getParam<bool>("extrude")),
98  _region_ids(getParam<std::vector<std::vector<subdomain_id_type>>>("region_ids"))
99 {
100  // Initialize ReactorMeshParams object
101  initializeReactorMeshParams(getParam<MeshGeneratorName>("reactor_params"));
102 
103  // Flexible stitching needs to be invoked in order to create control drum mesh
104  if (!getReactorParam<bool>(RGMB::flexible_assembly_stitching))
105  mooseError("'flexible_assembly_stitching' needs to be set to true in ReactorMeshParams in "
106  "order to use ControlDrumMeshGenerator");
107 
108  _geom_type = getReactorParam<std::string>(RGMB::mesh_geometry);
109  _mesh_dimensions = getReactorParam<unsigned int>(RGMB::mesh_dimensions);
110 
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");
114  const auto assembly_pitch = getReactorParam<Real>(RGMB::assembly_pitch);
115 
116  // Check drum pad parameters
117  if (isParamSetByUser("pad_start_angle"))
118  {
119  _pad_start_angle = getParam<Real>("pad_start_angle");
120  if (!isParamSetByUser("pad_end_angle"))
121  paramError("pad_start_angle",
122  "If 'pad_start_angle' is set, 'pad_end_angle' needs to also be set.");
123  _pad_end_angle = getParam<Real>("pad_end_angle");
124 
126  paramError("pad_start_angle",
127  "The difference between 'pad_end_angle' and 'pad_start_angle' must be between 0 "
128  "and 360 exclusive.");
129  _has_pad_region = true;
130  }
131  else
132  {
133  if (isParamSetByUser("pad_end_angle"))
134  paramError("pad_end_angle",
135  "If 'pad_end_angle' is set, 'pad_start_angle' needs to also be set.");
136  _has_pad_region = false;
137  }
138 
139  // Error checking for azimuthal node tolerance
140  const auto azimuthal_node_tolerance = getParam<Real>("azimuthal_node_tolerance");
141  if (!_has_pad_region && isParamSetByUser("azimuthal_node_tolerance"))
142  paramError("azimuthal_node_tolerance",
143  "This parameter is relevant only when pad start and end angles are defined");
144  if (_has_pad_region && MooseUtils::absoluteFuzzyGreaterEqual(2. * azimuthal_node_tolerance,
145  360. / (Real)num_sectors))
146  paramError("azimuthal_node_tolerance",
147  "Azimuthal node tolerance should be smaller than half the azimuthal interval size "
148  "as defined by 'num_azimuthal_sectors'");
149  if (_has_pad_region && MooseUtils::absoluteFuzzyGreaterEqual(2. * azimuthal_node_tolerance,
151  paramError("azimuthal_node_tolerance",
152  "Azimuthal node tolerance should be smaller than half the difference of the pad "
153  "angle range");
154 
155  // Check region IDs have correct size
156  const unsigned int n_radial_regions = _has_pad_region ? 4 : 3;
157  unsigned int n_axial_levels =
158  (_mesh_dimensions == 3)
159  ? getReactorParam<std::vector<unsigned int>>(RGMB::axial_mesh_intervals).size()
160  : 1;
161  if (_region_ids.size() != 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");
164  if (_region_ids[0].size() != n_radial_regions)
165  {
166  std::string err_msg =
167  "'region_ids' parameter does not have the correct number of elements per axial zone. ";
168  err_msg += _has_pad_region
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)";
173  paramError("region_ids", err_msg);
174  }
175 
176  // Check block names have the correct size
177  if (isParamValid("block_names"))
178  {
179  if (getReactorParam<bool>(RGMB::region_id_as_block_name))
180  paramError("block_names",
181  "If ReactorMeshParams/region_id_as_block_name is set, block_names should not be "
182  "specified in ControlDrumMeshGenerator");
183  _has_block_names = true;
184  _block_names = getParam<std::vector<std::vector<std::string>>>("block_names");
185  if (_region_ids.size() != _block_names.size())
186  mooseError("The size of block_names must match the size of region_ids");
187  for (const auto i : index_range(_region_ids))
188  if (_region_ids[i].size() != _block_names[i].size())
189  mooseError("The size of block_names must match the size of region_ids");
190  }
191  else
192  _has_block_names = false;
193 
194  // Check extrusion parameters
195  if (_extrude && _mesh_dimensions != 3)
196  paramError("extrude",
197  "In order to extrude this mesh, ReactorMeshParams/dim needs to be set to 3\n");
198  if (_extrude && (!hasReactorParam<boundary_id_type>(RGMB::top_boundary_id) ||
199  !hasReactorParam<boundary_id_type>(RGMB::bottom_boundary_id)))
200  mooseError("Both top_boundary_id and bottom_boundary_id must be provided in ReactorMeshParams "
201  "if using extruded geometry");
202 
203  // Define azimuthal angles explicitly based on num_azimuthal_sectors and manually add pad start
204  // angle and end angle if they are not contained within these angle intervals
205  std::vector<Real> azimuthal_angles;
206  const auto custom_start_angle = _has_pad_region ? _pad_start_angle : 0.;
207  const auto custom_end_angle =
208  _has_pad_region ? ((_pad_end_angle > 360) ? _pad_end_angle - 360. : _pad_end_angle) : 0.;
209  for (unsigned int i = 0; i < num_sectors; ++i)
210  {
211  Real current_azim_angle = (Real)i * 360. / (Real)num_sectors;
212  Real next_azim_angle = (Real)(i + 1) * 360. / (Real)num_sectors;
213  if (!_has_pad_region)
214  azimuthal_angles.push_back(current_azim_angle);
215  else
216  {
217  // When pad regions are involved, check if the current azimuthal node angle coincides with
218  // pad start/end angle to within tolerance. If it does, then shift the azimuthal node location
219  // to match the pad angle location. If it does not and the pad angle falls within the
220  // azimuthal sector, then create an additional node for the pad location
221  if (MooseUtils::absoluteFuzzyLessEqual(std::abs(current_azim_angle - custom_start_angle),
222  azimuthal_node_tolerance))
223  {
224  azimuthal_angles.push_back(custom_start_angle);
225  }
226  else if (MooseUtils::absoluteFuzzyLessEqual(std::abs(current_azim_angle - custom_end_angle),
227  azimuthal_node_tolerance))
228  {
229  azimuthal_angles.push_back(custom_end_angle);
230  }
231  else if (MooseUtils::absoluteFuzzyGreaterThan(custom_start_angle - current_azim_angle,
232  azimuthal_node_tolerance) &&
233  MooseUtils::absoluteFuzzyGreaterThan(next_azim_angle - custom_start_angle,
234  azimuthal_node_tolerance))
235  {
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);
240  }
241  else if (MooseUtils::absoluteFuzzyGreaterThan(custom_end_angle - current_azim_angle,
242  azimuthal_node_tolerance) &&
243  MooseUtils::absoluteFuzzyGreaterThan(next_azim_angle - custom_end_angle,
244  azimuthal_node_tolerance))
245  {
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);
250  }
251  else
252  azimuthal_angles.push_back(current_azim_angle);
253  }
254  }
255 
256  // Check drum radius parameters
258  paramError("drum_outer_radius", "Drum outer radius must be larger than the inner radius");
259  // Check if volume preserved radius of outer radius exceeds assembly halfpitch. In data driven
260  // mode, radius is assumed not to need volume preservation
261  auto radius_corrfac =
262  getReactorParam<bool>(RGMB::bypass_meshgen)
263  ? 1.0
265  if (_drum_outer_radius * radius_corrfac >= assembly_pitch / 2.)
266  paramError("drum_outer_radius",
267  "Volume-corrected outer radius of drum region must be smaller than half the "
268  "assembly pitch as "
269  "defined by 'ReactorMeshParams/assembly_pitch'");
270 
271  // No subgenerators will be called if option to bypass mesh generators is enabled
272  if (!getReactorParam<bool>(RGMB::bypass_meshgen))
273  {
274  const std::string block_name_prefix =
276 
277  {
278  // Invoke AdvancedConcentricCircleGenerator to define drum mesh without background region
279  auto params = _app.getFactory().getValidParams("AdvancedConcentricCircleGenerator");
280 
281  params.set<std::vector<Real>>("customized_azimuthal_angles") = azimuthal_angles;
282  params.set<std::vector<double>>("ring_radii") = {_drum_inner_radius, _drum_outer_radius};
283  params.set<std::vector<unsigned int>>("ring_intervals") = {drum_inner_intervals,
284  drum_intervals};
285  if (drum_inner_intervals > 1)
286  {
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"};
293  }
294  else
295  {
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"};
300  }
301  params.set<bool>("create_outward_interface_boundaries") = false;
302 
303  addMeshSubgenerator("AdvancedConcentricCircleGenerator", name() + "_accg", params);
304  }
305  {
306  // Invoke FlexiblePatternGenerator to triangulate drum background region
307  auto params = _app.getFactory().getValidParams("FlexiblePatternGenerator");
308 
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;
313  // `verify_holes` is set to false to prevent false positive instances of points outside of
314  // defined holes, which can create test failures on certain dev environments
315  params.set<bool>("verify_holes") = false;
316  params.set<MooseEnum>("boundary_type") = (_geom_type == "Hex") ? "HEXAGON" : "CARTESIAN";
317  params.set<unsigned int>("boundary_sectors") =
318  getReactorParam<unsigned int>(RGMB::num_sectors_flexible_stitching);
319  params.set<Real>("boundary_size") = assembly_pitch;
320  params.set<boundary_id_type>("external_boundary_id") =
322  params.set<BoundaryName>("external_boundary_name") =
324  params.set<SubdomainName>("background_subdomain_name") = block_name_prefix + "_R2_TRI";
325  params.set<subdomain_id_type>("background_subdomain_id") = RGMB::CONTROL_DRUM_BLOCK_ID_OUTER;
326 
327  addMeshSubgenerator("FlexiblePatternGenerator", name() + "_fpg", params);
328 
329  // Pass mesh meta-data defined in subgenerator constructor to this MeshGenerator
330  copyMeshProperty<bool>("is_control_drum_meta", name() + "_fpg");
331  copyMeshProperty<Real>("pattern_pitch_meta", name() + "_fpg");
332  }
333  std::string build_mesh_name = name() + "_delbds";
334  {
335  // Invoke BoundaryDeletionGenerator to delete extra sidesets created by
336  // AdvancedConcentricCircleGenerator
337  auto params = _app.getFactory().getValidParams("BoundaryDeletionGenerator");
338 
339  params.set<MeshGeneratorName>("input") = name() + "_fpg";
340  params.set<std::vector<BoundaryName>>("boundary_names") = {"0", "2"};
341 
342  addMeshSubgenerator("BoundaryDeletionGenerator", build_mesh_name, params);
343  }
344  if (_extrude && _mesh_dimensions == 3)
345  build_mesh_name = callExtrusionMeshSubgenerators(build_mesh_name);
346 
347  // Store final mesh subgenerator
348  _build_mesh = &getMeshByName(build_mesh_name);
349  }
350 
352 }
353 
354 void
356 {
357  // Declare metadata for use in downstream mesh generators
359  declareMeshProperty(RGMB::pitch, getReactorParam<Real>(RGMB::assembly_pitch));
364  std::vector<Real> drum_pad_angles =
365  _has_pad_region ? std::vector<Real>({_pad_start_angle, _pad_end_angle}) : std::vector<Real>();
367  std::vector<Real> drum_radii = std::vector<Real>({_drum_inner_radius, _drum_outer_radius});
371 }
372 
373 std::unique_ptr<MeshBase>
375 {
376  // Must be called to free the ReactorMeshParams mesh
378 
379  // If bypass_mesh is true, return a null mesh. In this mode, an output mesh is not
380  // generated and only metadata is defined on the generator, so logic related to
381  // generation of output mesh will not be called
382  if (getReactorParam<bool>(RGMB::bypass_meshgen))
383  {
384  auto null_mesh = nullptr;
385  return null_mesh;
386  }
387 
388  // This generate() method will be called once the subgenerators that we depend on are
389  // called. This is where we reassign subdomain ids/name in case they were merged when
390  // stitching pins into an assembly. This is also where we set region_id and
391  // assembly_type_id element integers.
392 
393  // Define all extra element names and integers
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 =
400 
401  auto pin_type_id_int = getElemIntegerFromMesh(*(*_build_mesh), pin_type_id_name);
402  auto region_id_int = getElemIntegerFromMesh(*(*_build_mesh), region_id_name);
403  auto assembly_type_id_int = getElemIntegerFromMesh(*(*_build_mesh), assembly_type_id_name);
404 
405  unsigned int plane_id_int = 0;
406  if (_extrude)
407  plane_id_int = getElemIntegerFromMesh(*(*_build_mesh), plane_id_name, true);
408 
409  // Get next free block ID in mesh in case subdomain ids need to be remapped
410  auto next_block_id = MooseMeshUtils::getNextFreeSubdomainID(*(*(_build_mesh)));
411  std::map<std::string, SubdomainID> rgmb_name_id_map;
412 
413  // Loop through all mesh elements and set region ids and reassign block IDs/names
414  // if they were merged during pin stitching
415  for (auto & elem : (*_build_mesh)->active_element_ptr_range())
416  {
417  elem->set_extra_integer(assembly_type_id_int, _assembly_type);
418  const dof_id_type z_id = _extrude ? elem->get_extra_integer(plane_id_int) : 0;
419 
420  // Assembly peripheral element (background / duct), set subdomains according
421  // to user preferences and set pin type id to RGMB::MAX_PIN_TYPE_ID - peripheral index
422  // Region id is inferred from z_id and peripheral_idx
423  const auto base_block_id = elem->subdomain_id();
424  const auto base_block_name = (*_build_mesh)->subdomain_name(base_block_id);
425 
426  // Check if block name has correct prefix
427  std::string prefix = RGMB::DRUM_BLOCK_NAME_PREFIX + std::to_string(_assembly_type) + "_R";
428  if (!(base_block_name.find(prefix, 0) == 0))
429  continue;
430 
431  // Radial index is integer value of substring after prefix
432  const unsigned int radial_idx = std::stoi(base_block_name.substr(prefix.length()));
433 
434  // Drum index distinguishes between elements in pad and ex-pad regions that have the same radial
435  // index
436  const unsigned int drum_idx =
437  getDrumIdxFromRadialIdx(radial_idx, elem->true_centroid()(0), elem->true_centroid()(1));
439  elem->set_extra_integer(pin_type_id_int, pin_type);
440 
441  const auto elem_rid = _region_ids[z_id][drum_idx];
442  elem->set_extra_integer(region_id_int, elem_rid);
443 
444  // Set element block name and block id
445  auto elem_block_name = default_block_name;
446  if (getReactorParam<bool>(RGMB::region_id_as_block_name))
447  elem_block_name += "_REG" + std::to_string(elem_rid);
448  else if (_has_block_names)
449  elem_block_name += "_" + _block_names[z_id][drum_idx];
450  if (elem->type() == TRI3 || elem->type() == PRISM6)
451  elem_block_name += RGMB::TRI_BLOCK_NAME_SUFFIX;
453  *(*_build_mesh), elem, rgmb_name_id_map, elem_block_name, next_block_id);
454  }
455 
456  if (getParam<bool>("generate_depletion_id"))
457  {
458  const MooseEnum option = getParam<MooseEnum>("depletion_id_type");
460  }
461 
462  // Mark mesh as not prepared, as block ID's were re-assigned in this method
463  (*_build_mesh)->set_isnt_prepared();
464 
465  return std::move(*_build_mesh);
466 }
467 
468 unsigned int
470  const Real elem_x,
471  const Real elem_y)
472 {
473  // By default, drum index will match radial index unless a pad region is defined
474  unsigned int drum_idx = radial_idx;
475  if (_has_pad_region)
476  {
477  if (radial_idx == 1)
478  {
479  // This is an element in the drum region, use drum angle to determine whether it belongs to
480  // pad or ex-pad region Note: drum angle of 0 degrees starts in positive y-direction and
481  // increments in clockwise direction, which is consistent
482  // with how AdvancedConcentricCircleMeshGenerator defines azimuthal angles
483  Real drum_angle = std::atan2(elem_x, elem_y) * 180. / M_PI;
484  if (drum_angle < 0)
485  drum_angle += 360;
486 
487  // If _pad_end_angle does not exceed 360 degrees, check if drum angle lies within
488  // _pad_start_angle and _pad_end_angle. Drum index needs to be incremented if element in
489  // ex-pad region
490  if (_pad_end_angle <= 360)
491  {
492  if ((drum_angle < _pad_start_angle) || (drum_angle > _pad_end_angle))
493  ++drum_idx;
494  }
495  else
496  {
497  // If _pad_end_angle exceeds 360 degrees, check two intervals - _pad_start_angle to 360, and
498  // 0 to _pad_end_angle - 360 Drum index needs to be incremented if element in ex-pad region
499  if ((drum_angle < _pad_start_angle) && (drum_angle > _pad_end_angle - 360.))
500  ++drum_idx;
501  }
502  }
503  else if (radial_idx == 2)
504  {
505  // Element is in outer drum region, drum index needs to be incremented to account for presence
506  // of ex-pad region
507  ++drum_idx;
508  }
509  }
510  return drum_idx;
511 }
std::unique_ptr< MeshBase > & getMeshByName(const MeshGeneratorName &mesh_generator_name)
static void addDepletionIDParams(InputParameters &parameters)
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...
T & set(const std::string &name, bool quiet_mode=false)
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
const SubdomainName TRI_BLOCK_NAME_SUFFIX
virtual const std::string & name() const
void mooseWarning(Args &&... args) const
Factory & getFactory()
TRI3
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 &param_name)
Returns reference of parameter in ReactorMeshParams object.
int8_t boundary_id_type
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 &param, 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
MooseApp & _app
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...
PRISM6
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 &parameters)
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.
uint8_t dof_id_type
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...