84 _ring_radii(getRingParamValues<Real>(
"ring_radii")),
86 _ring_intervals(getRingParamValues<unsigned int>(
"ring_intervals")),
87 _ring_block_ids(getRingParamValues<subdomain_id_type>(
"ring_block_ids")),
89 isParamValid(
"ring_block_names")
90 ? (getParam<std::vector<std::vector<SubdomainName>>>(
"ring_block_names").size() == 1
91 ? std::vector<std::vector<SubdomainName>>(
93 getParam<std::vector<std::vector<SubdomainName>>>(
"ring_block_names")
95 : getParam<
std::vector<
std::vector<SubdomainName>>>(
"ring_block_names"))
96 :
std::vector<
std::vector<SubdomainName>>(3,
std::vector<SubdomainName>())),
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")
117 _external_boundary_name(isParamValid(
"external_boundary_name")
118 ? getParam<
std::string>(
"external_boundary_name")
120 _pin_id_name(isParamValid(
"pin_id_name") ? getParam<
std::string>(
"pin_id_name")
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))
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);
131 declareMeshProperty<Real>(
"max_radius_meta", 0.0);
132 declareMeshProperty<std::vector<unsigned int>>(
"num_sectors_per_side_meta",
141 for (
unsigned int i = 0; i < 3; i++)
143 paramError(
"ring_intervals",
"The parameter must be consistent with ring_radii.");
144 for (
unsigned int i = 0; i < 3; i++)
147 paramError(
"ring_block_ids",
"The parameter must be consistent with ring_radii if provided.");
150 paramError(
"ring_block_ids",
"The parameter must be consistent with ring_radii if provided.");
153 "The parameter must be consistent with ring_radii if provided.");
157 "The parameter must be consistent with ring_radii if provided.");
163 "If provided, the size of this parameter must be one if all sections have rings.");
167 "If provided, the size of this parameter must be one if no sections have rings "
168 "and background_intervals is one.");
172 "background_block_ids",
173 "If provided, the size of this parameter must be two if ring-free section exists.");
179 "If provided, the size of this parameter must be one if all sections have rings.");
183 "If provided, the size of this parameter must be one if no sections have rings "
184 "and background_intervals is one.");
188 "background_block_names",
189 "If provided, the size of this parameter must be two if ring-free section exists.");
195 "This parameter cannot be used when pin_id_name is not provided.");
200 "If pin_id_name is provided, this parameter must be provided with a length of three.");
207 "This parameter cannot translate the ring center out of the hexagon assembly region.");
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++)
222 if (tmp_block_names.size() != tmp_block_ids.size())
224 "The block name assignment must be compatible with the existing block ids.");
226 block_info.push_back(std::make_pair(
229 const subdomain_id_type max_ring_radii_size =
236 if (tmp_block_names.size() != tmp_block_ids.size())
238 "The block name assignment must be compatible with the existing block ids.");
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++)
262 std::vector<std::unique_ptr<ReplicatedMesh>> meshes;
263 for (
unsigned int i = 0; i < 3; i++)
278 getParam<std::string>(
"sector_id_name"),
284 getParam<std::string>(
"ring_id_name"),
288 getParam<MooseEnum>(
"ring_id_assign_type") ==
"ring_wise",
295 MeshTools::Modification::rotate(*meshes[i], 120.0 * (Real)i, 0, 0);
296 meshes[0]->stitch_meshes(*std::move(meshes[i]),
305 MeshTools::Modification::rotate(*meshes[0], 90, 0, 0);
307 MeshTools::Modification::rotate(*meshes[0], 270, 0, 0);
309 for (
const auto & block_info_pair : block_info)
310 meshes[0]->set_subdomain_name(block_info_pair.first, block_info_pair.second);
315 meshes[0]->get_boundary_info().sideset_name(
318 meshes[0]->get_boundary_info().nodeset_name(
322 meshes[0]->unset_is_prepared();
323 return dynamic_pointer_cast<MeshBase>(meshes[0]);
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)
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);
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) /
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) /
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);
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) /
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) /
379 std::vector<Real> azimuthal_list;
380 for (
unsigned int i = 0; i < num_sectors_per_side; i++)
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))) /
388 for (
unsigned int i = 0; i < num_sectors_per_side; i++)
390 azimuthal_list.push_back(
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))) /
397 for (
unsigned int i = 0; i < num_sectors_per_side * 2; i++)
399 azimuthal_list.push_back(azimuthal_list[i] + 180.0);
402 std::vector<Real> ring_radii_corr;
405 if (preserve_volumes)
408 for (
unsigned int i = 0; i < ring_radii.size(); i++)
409 ring_radii_corr.push_back(ring_radii[i] * corr_factor);
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)
415 "The radii of the rings cannot exceed the boundary of the diamond section.");
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)},
432 std::vector<unsigned int>(),
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,
443 node_id_background_meta,
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)},
465 std::vector<unsigned int>(),
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,
476 node_id_background_meta,
485 mesh0->stitch_meshes(*mesh1,
492 auto mesh2 = dynamic_pointer_cast<ReplicatedMesh>(mesh0->clone());
493 MeshTools::Modification::rotate(*mesh2, 0, 180.0, 0);
494 mesh0->stitch_meshes(*mesh2,
499 MeshTools::Modification::translate(*mesh0, side_length / 2.0 + ring_offset, 0, 0);
501 for (
const auto & elem : mesh0->element_ptr_range())
502 elem->subdomain_id() = block_ids_new[elem->subdomain_id() - 1];
503 mesh0->unset_has_cached_elem_data();
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 ...