152 _mesh_ptrs(getMeshes(
"inputs")),
153 _input_names(getParam<
std::vector<MeshGeneratorName>>(
"inputs")),
154 _pattern(getParam<
std::vector<
std::vector<unsigned
int>>>(
"pattern")),
155 _pattern_boundary(getParam<
MooseEnum>(
"pattern_boundary")),
156 _generate_core_metadata(getParam<bool>(
"generate_core_metadata")),
157 _background_intervals(getParam<unsigned
int>(
"background_intervals")),
158 _has_assembly_duct(isParamValid(
"duct_sizes")),
159 _duct_sizes(isParamValid(
"duct_sizes") ? getParam<
std::vector<Real>>(
"duct_sizes")
160 :
std::vector<Real>()),
162 _duct_intervals(isParamValid(
"duct_intervals")
163 ? getParam<
std::vector<unsigned
int>>(
"duct_intervals")
164 :
std::vector<unsigned
int>()),
165 _uniform_mesh_on_sides(getParam<bool>(
"uniform_mesh_on_sides")),
166 _generate_control_drum_positions_file(getParam<bool>(
"generate_control_drum_positions_file")),
167 _assign_control_drum_id(getParam<bool>(
"assign_control_drum_id")),
168 _rotate_angle(getParam<Real>(
"rotate_angle")),
169 _duct_block_ids(isParamValid(
"duct_block_ids")
170 ? getParam<
std::vector<subdomain_id_type>>(
"duct_block_ids")
171 :
std::vector<subdomain_id_type>()),
172 _duct_block_names(getParam<
std::vector<SubdomainName>>(
"duct_block_names")),
173 _external_boundary_id(isParamValid(
"external_boundary_id")
174 ? getParam<boundary_id_type>(
"external_boundary_id")
176 _external_boundary_name(getParam<BoundaryName>(
"external_boundary_name")),
177 _create_inward_interface_boundaries(getParam<bool>(
"create_inward_interface_boundaries")),
178 _create_outward_interface_boundaries(getParam<bool>(
"create_outward_interface_boundaries")),
181 _deform_non_circular_region(getParam<bool>(
"deform_non_circular_region")),
182 _use_reporting_id(isParamValid(
"id_name")),
183 _use_exclude_id(isParamValid(
"exclude_id")),
184 _use_interface_boundary_id_shift(isParamValid(
"interface_boundary_id_shift_pattern")),
185 _boundary_quad_elem_type(
187 _allow_unused_inputs(getParam<bool>(
"allow_unused_inputs"))
191 declareMeshProperty<bool>(
"is_control_drum_meta",
false);
192 declareMeshProperty<std::vector<Point>>(
"control_drum_positions", std::vector<Point>());
193 declareMeshProperty<std::vector<Real>>(
"control_drum_angles", std::vector<Real>());
194 declareMeshProperty<std::vector<std::vector<Real>>>(
"control_drums_azimuthal_meta",
195 std::vector<std::vector<Real>>());
196 declareMeshProperty<std::string>(
"position_file_name", getParam<std::string>(
"position_file"));
198 declareMeshProperty<bool>(
"hexagon_center_trimmability",
true);
199 declareMeshProperty<bool>(
"peripheral_modifier_compatible",
_pattern_boundary ==
"hexagon");
201 const unsigned int n_pattern_layers =
_pattern.size();
203 if (n_pattern_layers % 2 == 0)
206 "The length (layer number) of this parameter must be odd to ensure a hexagonal shape.");
207 if (n_pattern_layers == 1)
208 paramError(
"pattern",
"The length (layer number) of this parameter must be larger than unity.");
209 std::vector<unsigned int> pattern_max_array;
210 std::vector<unsigned int> pattern_1d;
211 for (
unsigned int i = 0; i <= n_pattern_layers / 2; i++)
213 pattern_max_array.push_back(*std::max_element(
_pattern[i].begin(),
_pattern[i].end()));
214 pattern_max_array.push_back(*std::max_element(
_pattern[n_pattern_layers - 1 - i].begin(),
215 _pattern[n_pattern_layers - 1 - i].end()));
216 pattern_1d.insert(pattern_1d.end(),
_pattern[i].begin(),
_pattern[i].end());
217 pattern_1d.insert(pattern_1d.end(),
218 _pattern[n_pattern_layers - 1 - i].begin(),
219 _pattern[n_pattern_layers - 1 - i].end());
220 if (
_pattern[i].size() != n_pattern_layers / 2 + i + 1 ||
221 _pattern[n_pattern_layers - 1 - i].size() != n_pattern_layers / 2 + i + 1)
224 "The two-dimentional array parameter pattern must have a correct hexagonal shape.");
226 if (*std::max_element(pattern_max_array.begin(), pattern_max_array.end()) >=
_input_names.size())
228 "Elements of this parameter must be smaller than the length of input_name.");
229 if (std::set<unsigned int>(pattern_1d.begin(), pattern_1d.end()).size() <
_input_names.size() &&
232 "All the meshes provided in inputs must be used in the lattice pattern. To bypass "
233 "this requirement, set 'allow_unused_inputs = true'");
243 "This parameter and duct_block_ids must be "
244 "provided simultaneously.");
253 "This parameter and duct_block_names must be provided simultaneously.");
257 for (
unsigned int i = 1; i <
_duct_sizes.size(); i++)
259 paramError(
"duct_sizes",
"This parameter must be strictly ascending.");
262 "This parameter, if provided, must have a length equal to length of duct_sizes.");
266 "This parameter, if provided, must have a length equal to length of duct_sizes.");
272 "This parameter and background_block_name must not be set when the "
273 "pattern_boundary is none.");
280 getParam<std::vector<std::vector<boundary_id_type>>>(
"interface_boundary_id_shift_pattern");
282 paramError(
"interface_boundary_id_shift_pattern",
283 "This parameter, if provided, should have the same two-dimensional array shape as "
284 "the 'pattern' parameter. First dimension does not match");
285 for (
const auto i : make_range(
_pattern.size()))
287 paramError(
"interface_boundary_id_shift_pattern",
288 "This parameter, if provided, should have the same two-dimensional array shape "
289 "as the 'pattern' parameter.");
292 declareMeshProperty<bool>(
"interface_boundaries",
false);
293 declareMeshProperty<std::set<boundary_id_type>>(
"interface_boundary_ids", {});
301 const auto input_assign_types = getParam<std::vector<MooseEnum>>(
"assign_type");
302 if (input_assign_types.size() != num_reporting_ids)
303 paramError(
"assign_type",
"This parameter must have a length equal to length of id_name.");
305 std::vector<std::string> manual_ids;
306 for (
const auto i : make_range(num_reporting_ids))
309 input_assign_types[i].getEnum<ReportingIDGeneratorUtils::AssignType>());
314 if (manual_ids.size() > 0 && !
isParamValid(
"id_pattern"))
315 paramError(
"id_pattern",
"required when 'manual' is defined in \"assign_type\"");
318 const auto input_id_patterns =
319 getParam<std::vector<std::vector<std::vector<dof_id_type>>>>(
"id_pattern");
320 if (input_id_patterns.size() != manual_ids.size())
322 "The number of patterns must be equal to the number of 'manual' types defined "
323 "in \"assign_type\".");
324 for (
unsigned int i = 0; i < manual_ids.size(); ++i)
331 std::vector<MeshGeneratorName> exclude_id_name =
332 getParam<std::vector<MeshGeneratorName>>(
"exclude_id");
336 for (
auto input_name : exclude_id_name)
353 std::vector<std::unique_ptr<ReplicatedMesh>> meshes(
_input_names.size());
356 meshes[i] = dynamic_pointer_cast<ReplicatedMesh>(std::move(*
_mesh_ptrs[i]));
361 "' is not a replicated mesh. Only replicated meshes are supported");
364 if (hasMeshProperty<bool>(
"flat_side_up",
_input_names[i]))
365 if (getMeshProperty<bool>(
"flat_side_up",
_input_names[i]))
369 "' has a flat side facing up, which is not supported.");
372 std::vector<Real> pitch_array;
373 std::vector<unsigned int> num_sectors_per_side_array;
374 std::vector<unsigned int> num_sectors_per_side_array_tmp;
375 std::vector<std::vector<Real>> control_drum_azimuthal_array;
376 std::vector<unsigned int> background_intervals_array;
377 std::vector<dof_id_type> node_id_background_array;
378 std::vector<Real> max_radius_array;
379 std::vector<bool> is_control_drum_array;
380 Real max_radius_global(0.0);
381 std::vector<Real> pattern_pitch_array;
388 if (!hasMeshProperty<Real>(
"pattern_pitch_meta",
_input_names[i]))
390 "In PatternedHexMeshGenerator ",
392 ": the unit hexagonal input mesh does not contain appropriate meta data "
393 "required for generating a core mesh. Involved input mesh: ",
395 "; metadata issue: 'pattern_pitch_meta' is missing. Note that "
396 "'generate_core_metadata' is set to true, which"
397 "means that the mesh generator is producing a core mesh by stitching the input "
398 "assembly meshes together. Therefore,"
399 "the input meshes must contain the metadata of assembly meshes, which can "
400 "usually be either automatically assigned "
401 "by using another PatternedHexMeshGenerator with 'generate_core_metadata' set as "
402 "false and 'pattern_boundary' set as hexagon, or manually assigned by "
403 "AddMetaDataGenerator.");
404 pattern_pitch_array.push_back(getMeshProperty<Real>(
"pattern_pitch_meta",
_input_names[i]));
406 if (pattern_pitch_array.back() == 0.0)
408 "In PatternedHexMeshGenerator ",
410 ": the unit hexagonal input mesh does not contain appropriate meta data "
411 "required for generating a core mesh. Involved input mesh: ",
413 "; metadata issue: 'pattern_pitch_meta' is zero. Note that "
414 "'generate_core_metadata' is set to true, which"
415 "means that the mesh generator is producing a core mesh by stitching the input "
416 "assembly meshes together. Therefore,"
417 "the input meshes must contain the metadata of assembly meshes, which can "
418 "usually be either automatically assigned "
419 "by using another PatternedHexMeshGenerator with 'generate_core_metadata' set as "
420 "false and 'pattern_boundary' set as hexagon, or manually assigned by "
421 "AddMetaDataGenerator.");
422 is_control_drum_array.push_back(
423 getMeshProperty<bool>(
"is_control_drum_meta",
_input_names[i]));
424 control_drum_azimuthal_array.push_back(
425 getMeshProperty<bool>(
"is_control_drum_meta",
_input_names[i])
427 : std::vector<Real>());
429 if (!MooseUtils::absoluteFuzzyEqual(
430 *std::max_element(pattern_pitch_array.begin(), pattern_pitch_array.end()),
431 *std::min_element(pattern_pitch_array.begin(), pattern_pitch_array.end())))
433 "In PatternedHexMeshGenerator ",
435 ": pattern_pitch metadata values of all input mesh generators must be identical "
436 "when pattern_boundary is 'none' and generate_core_metadata is true. Please check the "
437 "parameters of the mesh generators that produce the input meshes."
438 "Note that some of these mesh generators, such as "
439 "HexagonConcentricCircleAdaptiveBoundaryMeshGenerator and FlexiblePatternGenerator,"
440 "may have different definitions of hexagon size in their input parameters. Please refer "
441 "to the documentation of these mesh generators.",
455 "This parameter must be provided when pattern_boundary is hexagon.");
458 ? getParam<Real>(
"hexagon_size")
459 : getParam<Real>(
"hexagon_size") * std::cos(M_PI / 6.0));
464 if (!hasMeshProperty<Real>(
"pitch_meta",
_input_names[i]))
467 ": the unit hexagonal input mesh does not contain appropriate meta data "
468 "required for generating an assembly. Involved input mesh: ",
470 "; metadata issue: 'pitch_meta' is missing");
471 pitch_array.push_back(getMeshProperty<Real>(
"pitch_meta",
_input_names[i]));
473 num_sectors_per_side_array_tmp =
474 getMeshProperty<std::vector<unsigned int>>(
"num_sectors_per_side_meta",
_input_names[i]);
475 if (*std::max_element(num_sectors_per_side_array_tmp.begin(),
476 num_sectors_per_side_array_tmp.end()) !=
477 *std::min_element(num_sectors_per_side_array_tmp.begin(),
478 num_sectors_per_side_array_tmp.end()))
481 ": num_sectors_per_side metadata values of all six sides of each input mesh "
482 "generator must be identical.");
483 if (num_sectors_per_side_array_tmp.front() == 1 &&
_pattern_boundary ==
"hexagon")
486 "for each input mesh, the number of sectors on each side must be greater than unity.");
487 num_sectors_per_side_array.push_back(*num_sectors_per_side_array_tmp.begin());
488 background_intervals_array.push_back(
489 getMeshProperty<unsigned int>(
"background_intervals_meta",
_input_names[i]));
490 node_id_background_array.push_back(
491 getMeshProperty<dof_id_type>(
"node_id_background_meta",
_input_names[i]));
492 max_radius_array.push_back(getMeshProperty<Real>(
"max_radius_meta",
_input_names[i]));
494 max_radius_global = *max_element(max_radius_array.begin(), max_radius_array.end());
495 if (!MooseUtils::absoluteFuzzyEqual(*std::max_element(pitch_array.begin(), pitch_array.end()),
496 *std::min_element(pitch_array.begin(), pitch_array.end())))
499 ": pitch metadata values of all input mesh generators must be identical. Please "
501 "parameters of the mesh generators that produce the input meshes.",
504 if (*std::max_element(num_sectors_per_side_array.begin(), num_sectors_per_side_array.end()) !=
505 *std::min_element(num_sectors_per_side_array.begin(), num_sectors_per_side_array.end()))
507 "In PatternedHexMeshGenerator ",
509 ": num_sectors_per_side metadata values of all input mesh generators must be identical.");
512 std::vector<Real> extra_dist;
513 Real extra_dist_shift(0.0);
517 const Real extra_dist_tol =
_pattern_boundary ==
"hexagon" ? pitch_array.front() / 10.0 : 0.0;
518 const Real extra_dist_shift_0 =
_pattern_boundary ==
"hexagon" ? pitch_array.front() / 5.0 : 0.0;
519 std::vector<unsigned int> peripheral_duct_intervals;
524 for (
unsigned int i = 0; i <
_duct_sizes.size(); i++)
528 extra_dist.push_back(0.5 *
529 (
_duct_sizes[i] * 2.0 - pitch_array.front() / std::sqrt(3.0) *
530 (Real)((
_pattern.size() / 2) * 3 + 2)));
535 "The duct sizes should not exceed the size of the hexagonal boundary.");
540 extra_dist.push_back(0.5 * (
_pattern_pitch - pitch_array.front() / std::sqrt(3.0) *
541 (Real)((
_pattern.size() / 2) * 3 + 2)));
549 if (extra_dist.front() <= extra_dist_tol)
551 extra_dist_shift = extra_dist_shift_0 - extra_dist.front();
552 for (Real &
d : extra_dist)
553 d += extra_dist_shift;
557 : (pitch_array.front() / std::sqrt(3.0));
558 y_max_0 = pitch_array.front() / std::sqrt(3.0) + extra_dist.front();
559 y_max_n = y_max_0 - extra_dist_shift;
560 if (y_max_n <= y_min)
563 ": the assembly is cut off so much that the internal structure that should not "
564 "be altered is compromised.");
572 std::vector<std::set<boundary_id_type>> input_interface_boundary_ids;
573 input_interface_boundary_ids.resize(
_input_names.size());
578 if (!hasMeshProperty<bool>(
"interface_boundaries",
_input_names[i]))
579 mooseError(
"Metadata 'interface_boundaries' could not be found on the input mesh: ",
581 if (!getMeshProperty<bool>(
"interface_boundaries",
_input_names[i]))
582 mooseError(
"Interface boundary ids were not constructed in the input mesh",
585 mooseError(
"Metadata 'interface_boundary_ids' could not be found on the input mesh: ",
592 input_interface_boundary_ids[i] =
598 ? pitch_array.front()
600 std::vector<Real> control_drum_positions_x;
601 std::vector<Real> control_drum_positions_y;
602 std::vector<std::vector<Real>> control_drum_azimuthals;
604 std::unique_ptr<ReplicatedMesh> out_mesh;
606 for (
unsigned i = 0; i <
_pattern.size(); i++)
608 Real deltax = -x_mov * input_pitch / 2;
615 Real deltay = -(Real)(i)*input_pitch * std::sin(M_PI / 3);
617 for (
unsigned int j = 0; j <
_pattern[i].size(); j++)
619 const auto pattern =
_pattern[i][j];
620 ReplicatedMesh & pattern_mesh = *meshes[pattern];
628 control_drum_positions_x.push_back(deltax + j * input_pitch);
629 control_drum_positions_y.push_back(deltay);
630 control_drum_azimuthals.push_back(control_drum_azimuthal_array[pattern]);
633 if (j == 0 && i == 0)
635 out_mesh = dynamic_pointer_cast<ReplicatedMesh>(pattern_mesh.clone());
637 out_mesh->add_elem_integer(
640 is_control_drum_array[pattern] ? control_drum_azimuthals.size() : 0);
645 input_interface_boundary_ids[pattern]);
652 Real rotation_angle = std::numeric_limits<Real>::max();
653 Real orientation = std::numeric_limits<Real>::max();
654 unsigned int mesh_type = std::numeric_limits<unsigned int>::max();
655 bool on_periphery =
true;
657 if (j == 0 && i == 0)
659 rotation_angle = 60.;
663 else if (j == 0 && i ==
_pattern.size() - 1)
665 rotation_angle = 180.;
669 else if (j == 0 && i == (
_pattern.size() - 1) / 2)
671 rotation_angle = 120.;
675 else if (j ==
_pattern[i].size() - 1 && i == 0)
683 rotation_angle = -120.;
689 rotation_angle = -60.;
701 rotation_angle = 180.;
705 else if (j == 0 && i < (
_pattern.size() - 1) / 2)
707 rotation_angle = 60.;
711 else if (j == 0 && i > (
_pattern.size() - 1) / 2)
713 rotation_angle = 120.;
719 rotation_angle = -60.;
725 rotation_angle = -120.;
730 on_periphery =
false;
734 auto tmp_peripheral_mesh = dynamic_pointer_cast<ReplicatedMesh>(pattern_mesh.clone());
739 num_sectors_per_side_array,
740 peripheral_duct_intervals,
744 if (extra_dist_shift != 0)
745 cutOffPolyDeform(*tmp_peripheral_mesh, orientation, y_max_0, y_max_n, y_min, mesh_type);
751 input_interface_boundary_ids[pattern]);
753 if (i == 0 && j == 0)
754 out_mesh = std::move(tmp_peripheral_mesh);
759 const auto & increment_subdomain_map = tmp_peripheral_mesh->get_subdomain_name_map();
760 out_mesh->set_subdomain_name_map().insert(increment_subdomain_map.begin(),
761 increment_subdomain_map.end());
763 MeshTools::Modification::translate(
764 *tmp_peripheral_mesh, deltax + j * input_pitch, deltay, 0);
765 out_mesh->stitch_meshes(*tmp_peripheral_mesh,
778 pattern_mesh.add_elem_integer(
781 is_control_drum_array[pattern] ? control_drum_azimuthals.size() : 0);
784 MeshTools::Modification::translate(pattern_mesh, deltax + j * input_pitch, deltay, 0);
787 auto & main_subdomain_map = out_mesh->set_subdomain_name_map();
790 const auto & increment_subdomain_map = pattern_mesh.get_subdomain_name_map();
791 main_subdomain_map.insert(increment_subdomain_map.begin(), increment_subdomain_map.end());
793 std::set<SubdomainName> main_subdomain_map_name_list;
794 for (
auto const & id_name_pair : main_subdomain_map)
795 main_subdomain_map_name_list.emplace(id_name_pair.second);
796 if (main_subdomain_map.size() != main_subdomain_map_name_list.size())
797 paramError(
"inputs",
"The input meshes contain subdomain name maps with conflicts.");
802 input_interface_boundary_ids[pattern]);
804 out_mesh->stitch_meshes(pattern_mesh,
813 MeshTools::Modification::translate(pattern_mesh, -(deltax + j * input_pitch), -deltay, 0);
818 input_interface_boundary_ids[pattern],
824 auto side_list = out_mesh->get_boundary_info().build_side_list();
825 for (
auto & sl : side_list)
828 if (out_mesh->elem_ptr(std::get<0>(sl))->neighbor_ptr(std::get<1>(sl)) !=
nullptr)
829 out_mesh->get_boundary_info().remove_side(
830 out_mesh->elem_ptr(std::get<0>(sl)), std::get<1>(sl), std::get<2>(sl));
832 out_mesh->get_boundary_info().clear_boundary_node_ids();
834 out_mesh->get_boundary_info().build_node_list_from_side_list();
835 const auto node_list = out_mesh->get_boundary_info().build_node_list();
837 std::vector<Real> bd_x_list;
838 std::vector<Real> bd_y_list;
839 std::vector<std::pair<Real, dof_id_type>> node_azi_list;
841 const Real origin_x = origin_pt(0);
842 const Real origin_y = origin_pt(1);
844 MeshTools::Modification::translate(*out_mesh, -origin_x, -origin_y, 0);
848 const Real azi_tol = 1E-8;
849 for (
unsigned int i = 0; i < node_list.size(); ++i)
853 node_azi_list.push_back(
854 std::make_pair(atan2(out_mesh->node_ref(std::get<0>(node_list[i]))(1),
855 out_mesh->node_ref(std::get<0>(node_list[i]))(0)) *
857 std::get<0>(node_list[i])));
859 if (node_azi_list.back().first + 180.0 <= azi_tol)
860 node_azi_list.back().first = 180;
863 std::sort(node_azi_list.begin(), node_azi_list.end());
867 for (
unsigned int j = 1; j <= side_intervals; j++)
869 Real azi_corr_tmp = atan2((Real)j * 2.0 / (Real)side_intervals - 1.0, std::sqrt(3.0));
871 Real y_tmp = x_tmp * std::tan(azi_corr_tmp);
873 Point p_tmp = Point(x_tmp, y_tmp, 0.0);
874 out_mesh->add_point(p_tmp, node_azi_list[i * side_intervals + j - 1].second);
885 MeshTools::Modification::rotate(*out_mesh,
_rotate_angle, 0.0, 0.0);
891 const Real azi_tol = 1E-8;
892 std::vector<std::tuple<Real, Point, std::vector<Real>, dof_id_type>> control_drum_tmp;
893 std::vector<dof_id_type> control_drum_id_sorted;
894 for (
unsigned int i = 0; i < control_drum_positions_x.size(); ++i)
896 control_drum_positions_x[i] -= origin_x;
897 control_drum_positions_y[i] -= origin_y;
899 Real cd_angle = atan2(control_drum_positions_y[i], control_drum_positions_x[i]);
901 for (
unsigned int j = 0; j < control_drum_azimuthals[i].size(); j++)
904 control_drum_azimuthals[i][j] =
905 atan2(std::sin(control_drum_azimuthals[i][j] / 180.0 * M_PI),
906 std::cos(control_drum_azimuthals[i][j] / 180.0 * M_PI)) /
909 std::sort(control_drum_azimuthals[i].begin(), control_drum_azimuthals[i].end());
911 if (std::abs(cd_angle) < azi_tol)
913 else if (cd_angle < 0.0)
914 cd_angle += 2 * M_PI;
915 control_drum_tmp.push_back(
916 std::make_tuple(cd_angle,
917 Point(control_drum_positions_x[i], control_drum_positions_y[i], 0.0),
918 control_drum_azimuthals[i],
921 std::sort(control_drum_tmp.begin(), control_drum_tmp.end());
922 std::vector<Point> control_drum_positions;
923 std::vector<Real> control_drum_angles;
924 std::vector<std::vector<Real>> control_drums_azimuthal_meta;
925 for (
unsigned int i = 0; i < control_drum_tmp.size(); ++i)
927 control_drum_positions.push_back(std::get<1>(control_drum_tmp[i]));
928 control_drum_angles.push_back(std::get<0>(control_drum_tmp[i]));
929 control_drums_azimuthal_meta.push_back(std::get<2>(control_drum_tmp[i]));
930 control_drum_id_sorted.push_back(std::get<3>(control_drum_tmp[i]));
934 setMeshProperty(
"control_drums_azimuthal_meta", control_drums_azimuthal_meta);
938 unsigned int id = out_mesh->get_elem_integer_index(
"control_drum_id");
939 for (
const auto & elem : out_mesh->element_ptr_range())
941 dof_id_type unsorted_control_drum_id = elem->get_extra_integer(
id);
942 if (unsorted_control_drum_id != 0)
944 auto sorted_iter = std::find(control_drum_id_sorted.begin(),
945 control_drum_id_sorted.end(),
946 unsorted_control_drum_id);
947 elem->set_extra_integer(
id,
948 std::distance(control_drum_id_sorted.begin(), sorted_iter) + 1);
955 std::string position_file_name = getMeshProperty<std::string>(
"position_file_name",
name());
956 std::ofstream pos_file(position_file_name);
957 for (
unsigned int i = 0; i < control_drum_positions.size(); ++i)
958 pos_file << control_drum_positions[i](0) <<
" " << control_drum_positions[i](1) <<
" 0.0\n";
969 for (
const auto & elem : out_mesh->active_element_ptr_range())
972 if (elem->subdomain_id() == i)
989 out_mesh->get_boundary_info().sideset_name(
992 out_mesh->get_boundary_info().nodeset_name(
998 auto & new_sideset_map = out_mesh->get_boundary_info().set_sideset_name_map();
999 auto & new_nodeset_map = out_mesh->get_boundary_info().set_nodeset_name_map();
1000 for (
unsigned int i = 0; i < meshes.size(); i++)
1002 const auto input_sideset_map = meshes[i]->get_boundary_info().get_sideset_name_map();
1003 new_sideset_map.insert(input_sideset_map.begin(), input_sideset_map.end());
1004 const auto input_nodeset_map = meshes[i]->get_boundary_info().get_nodeset_name_map();
1005 new_nodeset_map.insert(input_nodeset_map.begin(), input_nodeset_map.end());
1009 const std::set<boundary_id_type> boundary_ids = out_mesh->get_boundary_info().get_boundary_ids();
1014 input_interface_boundary_ids,
1018 if (interface_boundary_ids.size() > 0)
1024 out_mesh->unset_is_prepared();
1025 auto mesh = dynamic_pointer_cast<MeshBase>(out_mesh);
1103 std::vector<std::pair<Real, Real>> & d_positions_outer,
1104 const Real extra_dist_in,
1105 const Real extra_dist_out,
1107 const unsigned int radial_index)
const
1109 positions_inner.resize(0);
1110 d_positions_outer.resize(0);
1139 positions_inner.push_back(
1140 std::make_pair(-pitch / 2.0,
1141 std::sqrt(3.0) * pitch / 6.0 +
1142 (radial_index != 0 ? std::sqrt(3.0) * pitch / 6.0 + extra_dist_in : 0.0)));
1143 positions_inner.push_back(std::make_pair(
1145 std::sqrt(3.0) * pitch / 4.0 +
1146 (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in : 0.0)));
1147 positions_inner.push_back(std::make_pair(
1148 0.0, std::sqrt(3.0) * pitch / 3.0 + (radial_index != 0 ? extra_dist_in : 0.0)));
1149 positions_inner.push_back(std::make_pair(
1150 pitch / 4.0 + (radial_index != 0 ? pitch / 12.0 + std::sqrt(3.0) * extra_dist_in / 3.0 : 0.0),
1151 std::sqrt(3.0) * pitch / 4.0 +
1152 (radial_index != 0 ? pitch * std::sqrt(3.0) / 12.0 + extra_dist_in : 0.0)));
1153 positions_inner.push_back(std::make_pair(
1154 pitch / 2.0 + (radial_index != 0 ? std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1155 std::sqrt(3.0) * pitch / 6.0 + (radial_index != 0 ? extra_dist_in / 2.0 : 0.0)));
1156 positions_inner.push_back(std::make_pair(
1157 pitch / 2.0 + (radial_index != 0 ? pitch / 8.0 + std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1158 0.0 + (radial_index != 0 ? std::sqrt(3.0) * pitch / 24.0 + extra_dist_in / 2.0 : 0.0)));
1159 positions_inner.push_back(std::make_pair(
1160 pitch / 2.0 + (radial_index != 0 ? pitch / 4.0 + std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1161 -std::sqrt(3.0) * pitch / 6.0 +
1162 (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in / 2.0 : 0.0)));
1163 positions_inner.push_back(std::make_pair(
1165 std::sqrt(3.0) * pitch / 4.0 +
1166 (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in : 0.0)));
1167 positions_inner.push_back(
1168 std::make_pair(pitch / 2.0,
1169 std::sqrt(3.0) * pitch / 6.0 +
1170 (radial_index != 0 ? std::sqrt(3.0) * pitch / 6.0 + extra_dist_in : 0.0)));
1172 d_positions_outer.push_back(
1174 std::sqrt(3.0) * pitch / 6.0 + extra_dist_out -
1175 (radial_index != 0 ? std::sqrt(3.0) * pitch / 6.0 + extra_dist_in : 0.0)));
1176 d_positions_outer.push_back(std::make_pair(
1178 std::sqrt(3.0) * pitch / 12.0 + extra_dist_out -
1179 (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in : 0.0)));
1180 d_positions_outer.push_back(
1181 std::make_pair(0.0, extra_dist_out - (radial_index != 0 ? extra_dist_in : 0.0)));
1182 d_positions_outer.push_back(std::make_pair(
1183 pitch / 12.0 + std::sqrt(3.0) * extra_dist_out / 3.0 -
1184 (radial_index != 0 ? pitch / 12.0 + std::sqrt(3.0) * extra_dist_in / 3.0 : 0.0),
1185 pitch * std::sqrt(3.0) / 12.0 + extra_dist_out -
1186 (radial_index != 0 ? pitch * std::sqrt(3.0) / 12.0 + extra_dist_in : 0.0)));
1187 d_positions_outer.push_back(
1188 std::make_pair(std::sqrt(3.0) * extra_dist_out / 2.0 -
1189 (radial_index != 0 ? std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1190 extra_dist_out / 2.0 - (radial_index != 0 ? extra_dist_in / 2.0 : 0.0)));
1191 d_positions_outer.push_back(std::make_pair(
1192 pitch / 8.0 + std::sqrt(3.0) * extra_dist_out / 2.0 -
1193 (radial_index != 0 ? pitch / 8.0 + std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1194 std::sqrt(3.0) * pitch / 24.0 + extra_dist_out / 2.0 -
1195 (radial_index != 0 ? std::sqrt(3.0) * pitch / 24.0 + extra_dist_in / 2.0 : 0.0)));
1196 d_positions_outer.push_back(std::make_pair(
1197 pitch / 4.0 + std::sqrt(3.0) * extra_dist_out / 2.0 -
1198 (radial_index != 0 ? pitch / 4.0 + std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1199 std::sqrt(3.0) * pitch / 12.0 + extra_dist_out / 2.0 -
1200 (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in / 2.0 : 0.0)));
1201 d_positions_outer.push_back(std::make_pair(
1203 std::sqrt(3.0) * pitch / 12.0 + extra_dist_out -
1204 (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in : 0.0)));
1205 d_positions_outer.push_back(
1207 std::sqrt(3.0) * pitch / 6.0 + extra_dist_out -
1208 (radial_index != 0 ? std::sqrt(3.0) * pitch / 6.0 + extra_dist_in : 0.0)));