https://mooseframework.inl.gov
TriPinHexAssemblyGenerator.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 
12 #include "libmesh/mesh_smoother_laplace.h"
13 
14 #include <cmath>
15 
17 
20 {
22  params.addRequiredRangeCheckedParam<unsigned int>(
23  "num_sectors_per_side", "num_sectors_per_side>0", "Number of azimuthal sectors per side.");
24  params.addRangeCheckedParam<unsigned int>(
25  "background_intervals",
26  1,
27  "background_intervals>0",
28  "Number of radial meshing intervals in background "
29  "region (region around the rings/pins in the assembly).");
30  params.addRangeCheckedParam<std::vector<subdomain_id_type>>(
31  "background_block_ids",
32  "background_block_ids>0",
33  "Optional block ids for the background regions in the pins.");
34  params.addParam<std::vector<SubdomainName>>(
35  "background_block_names", "Optional block names for the background regions in the pins.");
36  params.addRangeCheckedParam<std::vector<std::vector<Real>>>(
37  "ring_radii", "ring_radii>0", "Radii of the three sets of major concentric circles (pins).");
38  params.addRangeCheckedParam<std::vector<std::vector<unsigned int>>>(
39  "ring_intervals",
40  "ring_intervals>0",
41  "Number of radial mesh intervals within each set of major concentric circles (pins).");
42  params.addRangeCheckedParam<std::vector<std::vector<subdomain_id_type>>>(
43  "ring_block_ids", "ring_block_ids>0", "Optional block ids for the ring (pin) regions.");
44  params.addParam<std::vector<std::vector<SubdomainName>>>(
45  "ring_block_names", "Optional block names for the ring (pin) regions.");
46  MooseEnum hexagon_size_style("apothem radius", "radius");
47  params.addParam<MooseEnum>("hexagon_size_style",
48  hexagon_size_style,
49  "Style in which hexagon size is given (apothem = center to face, "
50  "radius = center to vertex).");
52  "hexagon_size", "hexagon_size>0", "Size parameter of the hexagon assembly to be generated.");
53  params.addParam<Real>(
54  "ring_offset", 0.0, "Offset of the ring (pin) center, shared by all three.");
55  params.addParam<bool>(
56  "preserve_volumes",
57  true,
58  "Volume of concentric circles (pins) can be preserved using this function.");
59  MooseEnum assembly_orientation("pin_up pin_down", "pin_up");
60  params.addParam<MooseEnum>(
61  "assembly_orientation", assembly_orientation, "Orientation of the generated assembly.");
62  params.addRangeCheckedParam<boundary_id_type>("external_boundary_id",
63  "external_boundary_id>0",
64  "Optional customized external boundary id.");
65  params.addParam<std::string>("external_boundary_name",
66  "Optional customized external boundary name.");
67  params.addParam<std::string>(
68  "pin_id_name", "Name of extra integer ID to be assigned to each of the three pin domains.");
69  params.addParam<std::vector<dof_id_type>>(
70  "pin_id_values",
71  "Values of extra integer ID to be assigned to each of the three pin domains.");
72  params.addParamNamesToGroup("ring_block_ids ring_block_names background_block_ids "
73  "background_block_names external_boundary_id external_boundary_name",
74  "Customized Subdomain/Boundary ids/names");
76  params.addClassDescription(
77  "This TriPinHexAssemblyGenerator object generates a hexagonal assembly "
78  "mesh with three circular pins in a triangle at the center.");
79  return params;
80 }
81 
83  : PolygonMeshGeneratorBase(parameters),
84  _ring_radii(getRingParamValues<Real>("ring_radii")),
85  _has_rings({!_ring_radii[0].empty(), !_ring_radii[1].empty(), !_ring_radii[2].empty()}),
86  _ring_intervals(getRingParamValues<unsigned int>("ring_intervals")),
87  _ring_block_ids(getRingParamValues<subdomain_id_type>("ring_block_ids")),
88  _ring_block_names(
89  isParamValid("ring_block_names")
90  ? (getParam<std::vector<std::vector<SubdomainName>>>("ring_block_names").size() == 1
91  ? std::vector<std::vector<SubdomainName>>(
92  3,
93  getParam<std::vector<std::vector<SubdomainName>>>("ring_block_names")
94  .front())
95  : getParam<std::vector<std::vector<SubdomainName>>>("ring_block_names"))
96  : std::vector<std::vector<SubdomainName>>(3, std::vector<SubdomainName>())),
97  _hexagon_size_style(
98  getParam<MooseEnum>("hexagon_size_style").template getEnum<PolygonSizeStyle>()),
99  _side_length(_hexagon_size_style == PolygonSizeStyle::radius
100  ? getParam<Real>("hexagon_size")
101  : (getParam<Real>("hexagon_size") / cos(M_PI / 6.0))),
102  _ring_offset(getParam<Real>("ring_offset")),
103  _preserve_volumes(getParam<bool>("preserve_volumes")),
104  _assembly_orientation(
105  getParam<MooseEnum>("assembly_orientation").template getEnum<AssmOrient>()),
106  _num_sectors_per_side(getParam<unsigned int>("num_sectors_per_side")),
107  _background_intervals(getParam<unsigned int>("background_intervals")),
108  _background_block_ids(isParamValid("background_block_ids")
109  ? getParam<std::vector<subdomain_id_type>>("background_block_ids")
110  : std::vector<subdomain_id_type>()),
111  _background_block_names(isParamValid("background_block_names")
112  ? getParam<std::vector<SubdomainName>>("background_block_names")
113  : std::vector<SubdomainName>()),
114  _external_boundary_id(isParamValid("external_boundary_id")
115  ? getParam<boundary_id_type>("external_boundary_id")
116  : 0),
117  _external_boundary_name(isParamValid("external_boundary_name")
118  ? getParam<std::string>("external_boundary_name")
119  : std::string()),
120  _pin_id_name(isParamValid("pin_id_name") ? getParam<std::string>("pin_id_name")
121  : std::string()),
122  _pin_id_values(isParamValid("pin_id_values")
123  ? getParam<std::vector<dof_id_type>>("pin_id_values")
124  : std::vector<dof_id_type>()),
125  _node_id_background_meta(declareMeshProperty<dof_id_type>("node_id_background_meta", 0))
126 {
127  declareMeshProperty<Real>("pitch_meta", _side_length * std::sqrt(3.0));
128  declareMeshProperty<Real>("pattern_pitch_meta", _side_length * std::sqrt(3.0));
129  declareMeshProperty<bool>("is_control_drum_meta", false);
130  declareMeshProperty<unsigned int>("background_intervals_meta", _background_intervals);
131  declareMeshProperty<Real>("max_radius_meta", 0.0);
132  declareMeshProperty<std::vector<unsigned int>>("num_sectors_per_side_meta",
133  {_num_sectors_per_side,
134  _num_sectors_per_side,
135  _num_sectors_per_side,
136  _num_sectors_per_side,
137  _num_sectors_per_side,
138  _num_sectors_per_side});
139 
140  /* Parameter checks */
141  for (unsigned int i = 0; i < 3; i++)
142  if (_ring_intervals[i].size() != _ring_radii[i].size())
143  paramError("ring_intervals", "The parameter must be consistent with ring_radii.");
144  for (unsigned int i = 0; i < 3; i++)
145  {
146  if (!_has_rings[i] && !_ring_block_ids[i].empty())
147  paramError("ring_block_ids", "The parameter must be consistent with ring_radii if provided.");
148  else if (!_ring_block_ids[i].empty() &&
149  _ring_block_ids[i].size() != (_ring_radii[i].size() + (_ring_intervals[i][0] > 1)))
150  paramError("ring_block_ids", "The parameter must be consistent with ring_radii if provided.");
151  if (!_has_rings[i] && !_ring_block_names[i].empty())
152  paramError("ring_block_names",
153  "The parameter must be consistent with ring_radii if provided.");
154  else if (!_ring_block_names[i].empty() &&
155  _ring_block_names[i].size() != (_ring_radii[i].size() + (_ring_intervals[i][0] > 1)))
156  paramError("ring_block_names",
157  "The parameter must be consistent with ring_radii if provided.");
158  }
159  if (!_background_block_ids.empty())
160  {
161  if (_has_rings[0] && _has_rings[1] && _has_rings[2] && _background_block_ids.size() != 1)
162  paramError("background_block_ids",
163  "If provided, the size of this parameter must be one if all sections have rings.");
164  else if (!_has_rings[0] && !_has_rings[1] && !_has_rings[2] && _background_intervals == 1 &&
165  _background_block_ids.size() != 1)
166  paramError("background_block_ids",
167  "If provided, the size of this parameter must be one if no sections have rings "
168  "and background_intervals is one.");
169  else if ((!_has_rings[0] || !_has_rings[1] || !_has_rings[2]) &&
170  _background_block_ids.size() != 2)
171  paramError(
172  "background_block_ids",
173  "If provided, the size of this parameter must be two if ring-free section exists.");
174  }
175  if (!_background_block_names.empty())
176  {
177  if (_has_rings[0] && _has_rings[1] && _has_rings[2] && _background_block_names.size() != 1)
178  paramError("background_block_names",
179  "If provided, the size of this parameter must be one if all sections have rings.");
180  else if (!_has_rings[0] && !_has_rings[1] && !_has_rings[2] && _background_intervals == 1 &&
181  _background_block_names.size() != 1)
182  paramError("background_block_names",
183  "If provided, the size of this parameter must be one if no sections have rings "
184  "and background_intervals is one.");
185  else if ((!_has_rings[0] || !_has_rings[1] || !_has_rings[2]) &&
186  _background_block_names.size() != 2)
187  paramError(
188  "background_block_names",
189  "If provided, the size of this parameter must be two if ring-free section exists.");
190  }
191  if (_pin_id_name.empty())
192  {
193  if (!_pin_id_values.empty())
194  paramError("pin_id_values",
195  "This parameter cannot be used when pin_id_name is not provided.");
196  }
197  else if (_pin_id_values.size() != 3)
198  paramError(
199  "pin_id_values",
200  "If pin_id_name is provided, this parameter must be provided with a length of three.");
201 
202  // Just perform a simple and straightforward check for `ring_offset` here.
203  // A more comprehensive check for both `ring_offset` and `ring_radii` is done later.
204  if (std::abs(_ring_offset) >= _side_length / 2.0)
205  paramError(
206  "ring_offset",
207  "This parameter cannot translate the ring center out of the hexagon assembly region.");
208 }
209 
210 std::unique_ptr<MeshBase>
212 {
213  /* Pair specified block names and ids */
214  std::set<subdomain_id_type> tmp_block_ids;
215  std::set<SubdomainName> tmp_block_names;
216  std::vector<std::pair<subdomain_id_type, SubdomainName>> block_info;
217  for (unsigned int i = 0; i < 3; i++)
218  for (unsigned int j = 0; j < _ring_block_names[i].size(); j++)
219  {
220  tmp_block_names.emplace(_ring_block_names[i][j]);
221  tmp_block_ids.emplace(_ring_block_ids[i].empty() ? (j + 1) : _ring_block_ids[i][j]);
222  if (tmp_block_names.size() != tmp_block_ids.size())
223  paramError("ring_block_names",
224  "The block name assignment must be compatible with the existing block ids.");
225  else
226  block_info.push_back(std::make_pair(
227  _ring_block_ids[i].empty() ? (j + 1) : _ring_block_ids[i][j], _ring_block_names[i][j]));
228  }
229  const subdomain_id_type max_ring_radii_size =
230  std::max({_ring_radii[0].size(), _ring_radii[1].size(), _ring_radii[2].size()});
231  for (unsigned int i = 0; i < _background_block_names.size(); i++)
232  {
233  tmp_block_names.emplace(_background_block_names[i]);
234  tmp_block_ids.emplace(_background_block_ids.empty() ? (max_ring_radii_size + i)
235  : _background_block_ids[i]);
236  if (tmp_block_names.size() != tmp_block_ids.size())
237  paramError("background_block_names",
238  "The block name assignment must be compatible with the existing block ids.");
239  else
240  block_info.push_back(std::make_pair(_background_block_ids.empty() ? (max_ring_radii_size + i)
243  }
244  std::vector<std::vector<subdomain_id_type>> block_ids_new(3, std::vector<subdomain_id_type>());
245  for (unsigned int i = 0; i < 3; i++)
246  {
247  if (_has_rings[i])
248  {
249  for (unsigned int j = 0; j < (_ring_radii[i].size() + (_ring_intervals[i][0] > 1)); j++)
250  block_ids_new[i].push_back(_ring_block_ids[i].empty() ? j + 1 : _ring_block_ids[i][j]);
251  block_ids_new[i].push_back(_background_block_ids.empty() ? max_ring_radii_size + 1
252  : _background_block_ids.back());
253  }
254  else
255  {
256  block_ids_new[i].push_back(_background_block_ids.empty() ? (max_ring_radii_size + 1)
257  : _background_block_ids.front());
258  block_ids_new[i].push_back(_background_block_ids.empty() ? (max_ring_radii_size + 2)
259  : _background_block_ids.back());
260  }
261  }
262  std::vector<std::unique_ptr<ReplicatedMesh>> meshes;
263  for (unsigned int i = 0; i < 3; i++)
264  {
265  meshes.push_back(buildSinglePinSection(_side_length,
266  _ring_offset,
267  _ring_radii[i],
268  _ring_intervals[i],
269  _has_rings[i],
273  block_ids_new[i],
275  // add sector ids
276  if (isParamValid("sector_id_name"))
277  setSectorExtraIDs(*meshes[i],
278  getParam<std::string>("sector_id_name"),
279  4,
280  std::vector<unsigned int>(4, _num_sectors_per_side));
281  // add ring ids
282  if (isParamValid("ring_id_name") && _has_rings[i])
283  setRingExtraIDs(*meshes[i],
284  getParam<std::string>("ring_id_name"),
285  4,
286  std::vector<unsigned int>(4, _num_sectors_per_side),
287  _ring_intervals[i],
288  getParam<MooseEnum>("ring_id_assign_type") == "ring_wise",
289  false);
290 
291  if (!_pin_id_name.empty())
292  meshes[i]->add_elem_integer(_pin_id_name, true, _pin_id_values[i]);
293  if (i > 0)
294  {
295  MeshTools::Modification::rotate(*meshes[i], 120.0 * (Real)i, 0, 0);
296  meshes[0]->stitch_meshes(*std::move(meshes[i]),
299  TOLERANCE,
300  /*clear_stitched_boundary_ids=*/true);
301  }
302  }
303 
305  MeshTools::Modification::rotate(*meshes[0], 90, 0, 0);
306  else
307  MeshTools::Modification::rotate(*meshes[0], 270, 0, 0);
308  /* Add subdomain names */
309  for (const auto & block_info_pair : block_info)
310  meshes[0]->subdomain_name(block_info_pair.first) = block_info_pair.second;
311  if (_external_boundary_id > 0)
313  if (!_external_boundary_name.empty())
314  {
315  meshes[0]->get_boundary_info().sideset_name(
318  meshes[0]->get_boundary_info().nodeset_name(
321  }
322  meshes[0]->set_isnt_prepared();
323  return dynamic_pointer_cast<MeshBase>(meshes[0]);
324 }
325 
326 std::unique_ptr<ReplicatedMesh>
328  const Real side_length,
329  const Real ring_offset,
330  const std::vector<Real> ring_radii,
331  const std::vector<unsigned int> ring_intervals,
332  const bool has_rings,
333  const bool preserve_volumes,
334  const unsigned int num_sectors_per_side,
335  const unsigned int background_intervals,
336  const std::vector<subdomain_id_type> block_ids_new,
337  dof_id_type & node_id_background_meta)
338 {
339  // Each SinglePinSection, which has a diamond shape, is composed of four general slices.
340  // Considering symmetry, two unique general slices (0 and 1) need to be generated.
341  // For each slice, the center of the pin is one of its vertices; primary and secondary sides are
342  // the two sides that contain the pin center.
343  const Real secondary_side_length_0(side_length / 2.0 - ring_offset);
344  const Real secondary_side_length_1(
345  std::sqrt(side_length * side_length / 4.0 * 3.0 + ring_offset * ring_offset));
346  const Real primary_side_length_0(
347  std::sqrt(side_length * side_length / 4.0 * 3.0 + ring_offset * ring_offset));
348  const Real primary_side_length_1(side_length / 2.0 + ring_offset);
349  // Azimuthal angle is the included angle defined by the primary and secondary sides
350  const Real azimuthal_angle_0(
351  acos((secondary_side_length_0 * secondary_side_length_0 +
352  primary_side_length_0 * primary_side_length_0 - side_length * side_length) /
353  2.0 / primary_side_length_0 / secondary_side_length_0) /
354  M_PI * 180.0);
355  const Real azimuthal_angle_1(
356  acos((secondary_side_length_1 * secondary_side_length_1 +
357  primary_side_length_1 * primary_side_length_1 - side_length * side_length) /
358  2.0 / primary_side_length_1 / secondary_side_length_1) /
359  M_PI * 180.0);
360  // The primary side is parallel to y-axis by default (i.e., rotation_angle is zero). So the
361  // general slices need to be rotated before stitching,
362  const Real rotation_angle_0(azimuthal_angle_0 - 90.0);
363  const Real rotation_angle_1(azimuthal_angle_0 + azimuthal_angle_1 - 90.0);
364  // Alpha angle is the other included angle of the slice defined by the primary side and the third
365  // side.
366  const Real alpha_angle_0(
367  acos((primary_side_length_0 * primary_side_length_0 + side_length * side_length -
368  secondary_side_length_0 * secondary_side_length_0) /
369  2.0 / primary_side_length_0 / side_length) /
370  M_PI * 180.0);
371  const Real alpha_angle_1(
372  acos((primary_side_length_1 * primary_side_length_1 + side_length * side_length -
373  secondary_side_length_1 * secondary_side_length_1) /
374  2.0 / primary_side_length_1 / side_length) /
375  M_PI * 180.0);
376 
377  // azimuthal_list is a list of azimuthal intervals of the mesh to support radius correction to
378  // ensure preserved volume.
379  std::vector<Real> azimuthal_list;
380  for (unsigned int i = 0; i < num_sectors_per_side; i++)
381  {
382  azimuthal_list.push_back(
383  atan((Real)i * side_length / num_sectors_per_side * sin(alpha_angle_0 / 180.0 * M_PI) /
384  (primary_side_length_0 -
385  (Real)i * side_length / num_sectors_per_side * cos(alpha_angle_0 / 180.0 * M_PI))) /
386  M_PI * 180.0);
387  }
388  for (unsigned int i = 0; i < num_sectors_per_side; i++)
389  {
390  azimuthal_list.push_back(
391  azimuthal_angle_0 +
392  atan((Real)i * side_length / num_sectors_per_side * sin(alpha_angle_1 / 180.0 * M_PI) /
393  (primary_side_length_1 -
394  (Real)i * side_length / num_sectors_per_side * cos(alpha_angle_1 / 180.0 * M_PI))) /
395  M_PI * 180.0);
396  }
397  for (unsigned int i = 0; i < num_sectors_per_side * 2; i++)
398  {
399  azimuthal_list.push_back(azimuthal_list[i] + 180.0);
400  }
401 
402  std::vector<Real> ring_radii_corr;
403  if (has_rings)
404  {
405  if (preserve_volumes)
406  {
407  const Real corr_factor = PolygonalMeshGenerationUtils::radiusCorrectionFactor(azimuthal_list);
408  for (unsigned int i = 0; i < ring_radii.size(); i++)
409  ring_radii_corr.push_back(ring_radii[i] * corr_factor);
410  }
411  else
412  ring_radii_corr = ring_radii;
413  if (ring_radii_corr.back() > (side_length / 2.0 - std::abs(ring_offset)) * std::sqrt(3.0) / 2.0)
414  paramError("ring_radii",
415  "The radii of the rings cannot exceed the boundary of the diamond section.");
416  }
417 
418  // build the first slice of the polygon.
419  auto mesh0 = buildGeneralSlice(
420  ring_radii_corr,
421  ring_intervals,
422  std::vector<Real>(ring_radii_corr.size(), 1.0),
423  {std::vector<Real>(ring_radii_corr.size(), 0.0),
424  std::vector<Real>(ring_radii_corr.size(), 0.0),
425  std::vector<unsigned int>(ring_radii_corr.size(), 0),
426  std::vector<Real>(ring_radii_corr.size(), 1.0)},
427  {std::vector<Real>(ring_radii_corr.size(), 0.0),
428  std::vector<Real>(ring_radii_corr.size(), 0.0),
429  std::vector<unsigned int>(ring_radii_corr.size(), 0),
430  std::vector<Real>(ring_radii_corr.size(), 1.0)},
431  std::vector<Real>(),
432  std::vector<unsigned int>(),
433  std::vector<Real>(),
434  {std::vector<Real>(), std::vector<Real>(), std::vector<unsigned int>(), std::vector<Real>()},
435  {std::vector<Real>(), std::vector<Real>(), std::vector<unsigned int>(), std::vector<Real>()},
436  primary_side_length_0,
437  secondary_side_length_0,
438  num_sectors_per_side,
439  background_intervals,
440  1.0,
441  {0.0, 0.0, 0, 1.0},
442  {0.0, 0.0, 0, 1.0},
443  node_id_background_meta,
444  azimuthal_angle_0,
445  std::vector<Real>(),
446  /* side_index = */ 1,
447  false,
448  0.0,
449  rotation_angle_0,
450  false);
451 
452  auto mesh1 = buildGeneralSlice(
453  ring_radii_corr,
454  ring_intervals,
455  std::vector<Real>(ring_radii_corr.size(), 1.0),
456  {std::vector<Real>(ring_radii_corr.size(), 0.0),
457  std::vector<Real>(ring_radii_corr.size(), 0.0),
458  std::vector<unsigned int>(ring_radii_corr.size(), 0),
459  std::vector<Real>(ring_radii_corr.size(), 1.0)},
460  {std::vector<Real>(ring_radii_corr.size(), 0.0),
461  std::vector<Real>(ring_radii_corr.size(), 0.0),
462  std::vector<unsigned int>(ring_radii_corr.size(), 0),
463  std::vector<Real>(ring_radii_corr.size(), 1.0)},
464  std::vector<Real>(),
465  std::vector<unsigned int>(),
466  std::vector<Real>(),
467  {std::vector<Real>(), std::vector<Real>(), std::vector<unsigned int>(), std::vector<Real>()},
468  {std::vector<Real>(), std::vector<Real>(), std::vector<unsigned int>(), std::vector<Real>()},
469  primary_side_length_1,
470  secondary_side_length_1,
471  num_sectors_per_side,
472  background_intervals,
473  1.0,
474  {0.0, 0.0, 0, 1.0},
475  {0.0, 0.0, 0, 1.0},
476  node_id_background_meta,
477  azimuthal_angle_1,
478  std::vector<Real>(),
479  /* side_index = */ 1,
480  false,
481  0.0,
482  rotation_angle_1,
483  false);
484 
485  mesh0->stitch_meshes(*mesh1,
486  SLICE_BEGIN,
487  SLICE_END,
488  TOLERANCE,
489  /*clear_stitched_boundary_ids=*/true);
491 
492  auto mesh2 = dynamic_pointer_cast<ReplicatedMesh>(mesh0->clone());
493  MeshTools::Modification::rotate(*mesh2, 0, 180.0, 0);
494  mesh0->stitch_meshes(*mesh2,
495  SLICE_END,
496  SLICE_END,
497  TOLERANCE,
498  /*clear_stitched_boundary_ids=*/true);
499  MeshTools::Modification::translate(*mesh0, side_length / 2.0 + ring_offset, 0, 0);
500 
501  for (const auto & elem : mesh0->element_ptr_range())
502  elem->subdomain_id() = block_ids_new[elem->subdomain_id() - 1];
503 
504  return mesh0;
505 }
std::unique_ptr< ReplicatedMesh > buildGeneralSlice(std::vector< Real > ring_radii, const std::vector< unsigned int > ring_layers, const std::vector< Real > ring_radial_biases, const multiBdryLayerParams &ring_inner_boundary_layer_params, const multiBdryLayerParams &ring_outer_boundary_layer_params, std::vector< Real > ducts_center_dist, const std::vector< unsigned int > ducts_layers, const std::vector< Real > duct_radial_biases, const multiBdryLayerParams &duct_inner_boundary_layer_params, const multiBdryLayerParams &duct_outer_boundary_layer_params, const Real primary_side_length, const Real secondary_side_length, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const Real background_radial_bias, const singleBdryLayerParams &background_inner_boundary_layer_params, const singleBdryLayerParams &background_outer_boundary_layer_params, dof_id_type &node_id_background_meta, const Real azimuthal_angle, const std::vector< Real > azimuthal_tangent, const unsigned int side_index, const bool quad_center_elements, const Real center_quad_factor, const Real rotation_angle, const bool generate_side_specific_boundaries=true)
Creates a mesh of a general polygon slice with a triangular shape and circular regions on one of its ...
const std::string _external_boundary_name
Boundary name of mesh&#39;s external boundary.
registerMooseObject("ReactorApp", TriPinHexAssemblyGenerator)
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sin(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tan
void setSectorExtraIDs(MeshBase &mesh, const std::string id_name, const unsigned int num_sides, const std::vector< unsigned int > num_sectors_per_side)
assign sector extra ids to polygon mesh
const std::vector< std::vector< unsigned int > > _ring_intervals
Numbers of radial layers in each ring region in the three diamond sections.
enum TriPinHexAssemblyGenerator::AssmOrient _assembly_orientation
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const std::vector< subdomain_id_type > _background_block_ids
Block ids of the background region.
const unsigned int _num_sectors_per_side
Mesh sector number of each polygon side.
const std::vector< std::vector< SubdomainName > > _ring_block_names
Block names of the ring regions in the three diamond sections.
const Real _ring_offset
Offset distance of the circle centers from the center of each diamond section.
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
const bool _preserve_volumes
Whether the radii need to be corrected for polygonization during meshing.
void changeBoundaryId(const boundary_id_type old_id, const boundary_id_type new_id, bool delete_prev)
bool isParamValid(const std::string &name) const
const std::vector< dof_id_type > _pin_id_values
Values of extra integer ID to be assigned to each of the three pin domains.
This TriPinHexAssemblyGenerator object is a base class to be inherited for polygon mesh generators...
static InputParameters validParams()
int8_t boundary_id_type
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
void setRingExtraIDs(MeshBase &mesh, const std::string id_name, const unsigned int num_sides, const std::vector< unsigned int > num_sectors_per_side, const std::vector< unsigned int > ring_intervals, const bool ring_wise_id, const bool quad_center_elements)
assign ring extra ids to polygon mesh
const unsigned int _background_intervals
Numbers of radial intervals of the background regions.
const std::vector< std::vector< Real > > _ring_radii
Radii of concentric circles in the three diamond sections.
const std::vector< bool > _has_rings
Whether the generated mesh contains ring regions.
dof_id_type & _node_id_background_meta
MeshMetaData: maximum node id of the background region.
void paramError(const std::string &param, Args... args) const
const std::vector< std::vector< subdomain_id_type > > _ring_block_ids
Block ids of the ring regions in the three diamond sections.
static void addRingAndSectorIDParams(InputParameters &params)
Add InputParameters which are used by ring and sector IDs.
std::unique_ptr< MeshBase > generate() override
const boundary_id_type _external_boundary_id
Boundary ID of mesh&#39;s external boundary.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string ring_radii
const std::vector< SubdomainName > _background_block_names
Block names of the background region.
const Real _side_length
Length of the side of the hexagon.
std::unique_ptr< ReplicatedMesh > buildSinglePinSection(const Real side_length, const Real ring_offset, const std::vector< Real > ring_radii, const std::vector< unsigned int > ring_intervals, const bool has_rings, const bool preserve_volumes, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const std::vector< subdomain_id_type > block_ids_new, dof_id_type &node_id_background_meta)
Generates a single-pin diamond section mesh, which is one-third of the triple-pin hexagonal assembly ...
A base class that contains common members for Reactor module mesh generators.
TriPinHexAssemblyGenerator(const InputParameters &parameters)
const std::string _pin_id_name
Name of extra integer ID to be assigned to each of the three pin domains.
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
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.
uint8_t dof_id_type
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
static InputParameters validParams()