11#include "libmesh/mesh_smoother_laplace.h"
16#include "libmesh/parsed_function.h"
17#include "libmesh/poly2tri_triangulator.h"
26 "num_sectors_per_side",
27 "num_sectors_per_side>0",
28 "Number of azimuthal sectors per polygon side (rotating counterclockwise from top right "
31 "background_intervals",
33 "background_intervals>0",
34 "Number of radial meshing intervals in background region (area "
35 "between rings and ducts) excluding the background's boundary layers.");
37 "background_radial_bias",
39 "background_radial_bias>0",
40 "Value used to create biasing in radial meshing for background region.");
42 "background_inner_boundary_layer_width",
44 "background_inner_boundary_layer_width>=0",
45 "Width of background region that is assigned to be the inner boundary layer.");
47 "background_inner_boundary_layer_intervals",
49 "background_inner_boundary_layer_intervals>0",
50 "Number of radial intervals of the background inner boundary layer");
52 "background_inner_boundary_layer_bias",
54 "background_inner_boundary_layer_bias>0",
55 "Growth factor used for mesh biasing of the background inner boundary layer.");
57 "background_outer_boundary_layer_width",
59 "background_outer_boundary_layer_width>=0",
60 "Width of background region that is assigned to be the outer boundary layer.");
62 "background_outer_boundary_layer_intervals",
64 "background_outer_boundary_layer_intervals>0",
65 "Number of radial intervals of the background outer boundary layer");
67 "background_outer_boundary_layer_bias",
69 "background_outer_boundary_layer_bias>0",
70 "Growth factor used for mesh biasing of the background outer boundary layer.");
71 params.
addParam<std::vector<subdomain_id_type>>(
72 "background_block_ids",
"Optional customized block id for the background block.");
73 params.
addParam<std::vector<SubdomainName>>(
74 "background_block_names",
"Optional customized block names for the background block.");
76 "duct_sizes",
"Distance(s) from polygon center to duct(s) inner boundaries.");
77 MooseEnum duct_sizes_style(
"apothem radius",
"radius");
81 "Style in which polygon center to duct inner boundary distance is "
82 "given (apothem = center to face, radius = center to vertex). Options: " +
83 duct_sizes_style.getRawNames());
87 "Number of meshing intervals in each enclosing duct excluding duct boundary layers.");
90 "duct_radial_biases>0",
91 "Values used to create biasing in radial meshing for duct regions.");
93 "duct_inner_boundary_layer_widths",
94 "duct_inner_boundary_layer_widths>=0",
95 "Widths of duct regions that are assigned to be the inner boundary layers.");
96 params.
addParam<std::vector<unsigned int>>(
97 "duct_inner_boundary_layer_intervals",
98 "Number of radial intervals of the duct inner boundary layers");
100 "duct_inner_boundary_layer_biases",
101 "duct_inner_boundary_layer_biases>0",
102 "Growth factors used for mesh biasing of the duct inner boundary layers.");
104 "duct_outer_boundary_layer_widths",
105 "duct_outer_boundary_layer_widths>=0",
106 "Widths of duct regions that are assigned to be the outer boundary layers.");
107 params.
addParam<std::vector<unsigned int>>(
108 "duct_outer_boundary_layer_intervals",
109 "Number of radial intervals of the duct outer boundary layers");
111 "duct_outer_boundary_layer_biases",
112 "duct_outer_boundary_layer_biases>0",
113 "Growth factors used for mesh biasing of the duct outer boundary layers.");
114 params.
addParam<std::vector<subdomain_id_type>>(
115 "duct_block_ids",
"Optional customized block ids for each duct geometry block.");
116 params.
addParam<std::vector<SubdomainName>>(
117 "duct_block_names",
"Optional customized block names for each duct geometry block.");
118 params.
addParam<
bool>(
"uniform_mesh_on_sides",
120 "Whether the side elements are reorganized to have a uniform size.");
121 params.
addParam<
unsigned int>(
"smoothing_max_it",
123 "Number of Laplacian smoothing iterations. This number is "
124 "disregarded when duct_sizes is present.");
128 "Whether to rotate the generated polygon mesh to ensure that one flat side faces up.");
131 "quad_center_elements",
false,
"Whether the center elements are quad or triangular.");
133 "center_quad_factor",
134 "center_quad_factor>0¢er_quad_factor<1",
135 "A fractional radius factor used to determine the radial positions of transition nodes in "
136 "the center region meshed by quad elements.");
137 params.
addParam<
bool>(
"replace_inner_ring_with_delaunay_mesh",
139 "True to replace the inner ring mesh with a Delaunay unstructured mesh");
141 "inner_ring_desired_area",
143 "Desired area as a function of x,y; omit to use the default constant area (square of the "
144 "smallest side length on the ring circle)");
147 "background_block_ids background_block_names duct_block_ids duct_block_names",
148 "Customized Subdomain/Boundary");
150 "uniform_mesh_on_sides",
151 "General Mesh Density");
153 "ring_radial_biases ring_inner_boundary_layer_biases ring_inner_boundary_layer_widths "
154 "ring_inner_boundary_layer_intervals ring_outer_boundary_layer_biases "
155 "ring_outer_boundary_layer_widths ring_outer_boundary_layer_intervals",
156 "Mesh Boundary Layers and Biasing Options");
158 "replace_inner_ring_with_delaunay_mesh inner_ring_desired_area ",
162 params.
addClassDescription(
"This PolygonConcentricCircleMeshGeneratorBase object is a base class "
163 "to be inherited for polygon mesh generators.");
171 _num_sides(isParamValid(
"num_sides")
172 ? getParam<unsigned
int>(
"num_sides")
173 : (isParamValid(
"hexagon_size") ? (unsigned
int)HEXAGON_NUM_SIDES
174 : (unsigned
int)SQUARE_NUM_SIDES)),
176 _duct_sizes(isParamValid(
"duct_sizes") ? getParam<
std::vector<Real>>(
"duct_sizes")
177 :
std::vector<Real>()),
178 _duct_intervals(isParamValid(
"duct_intervals")
179 ? getParam<
std::vector<unsigned
int>>(
"duct_intervals")
180 :
std::vector<unsigned
int>()),
181 _duct_radial_biases(isParamValid(
"duct_radial_biases")
182 ? getParam<
std::vector<Real>>(
"duct_radial_biases")
183 :
std::vector<Real>(_duct_intervals.size(), 1.0)),
184 _duct_inner_boundary_layer_params(
186 ? getParam<std::vector<Real>>(
"duct_inner_boundary_layer_widths")
190 ? getParam<std::vector<unsigned int>>(
"duct_inner_boundary_layer_intervals")
193 ? getParam<std::vector<Real>>(
"duct_inner_boundary_layer_biases")
195 _duct_outer_boundary_layer_params(
196 {isParamValid(
"duct_outer_boundary_layer_widths")
197 ? getParam<std::vector<Real>>(
"duct_outer_boundary_layer_widths")
198 :
std::vector<Real>(_duct_intervals.size(), 0.0),
200 isParamValid(
"duct_outer_boundary_layer_intervals")
201 ? getParam<
std::vector<unsigned
int>>(
"duct_outer_boundary_layer_intervals")
202 :
std::vector<unsigned
int>(_duct_intervals.size(), 0),
203 isParamValid(
"duct_outer_boundary_layer_biases")
204 ? getParam<
std::vector<Real>>(
"duct_outer_boundary_layer_biases")
205 :
std::vector<Real>(_duct_intervals.size(), 0.0)}),
206 _duct_block_ids(isParamValid(
"duct_block_ids")
207 ? getParam<
std::vector<subdomain_id_type>>(
"duct_block_ids")
208 :
std::vector<subdomain_id_type>()),
209 _duct_block_names(isParamValid(
"duct_block_names")
210 ? getParam<
std::vector<SubdomainName>>(
"duct_block_names")
211 :
std::vector<SubdomainName>()),
212 _has_rings(isParamValid(
"ring_radii")),
213 _has_ducts(isParamValid(
"duct_sizes")),
215 isParamValid(
"polygon_size_style")
216 ? getParam<
MooseEnum>(
"polygon_size_style").template getEnum<PolygonSizeStyle>()
217 : (isParamValid(
"hexagon_size_style")
218 ? getParam<
MooseEnum>(
"hexagon_size_style").template getEnum<PolygonSizeStyle>()
219 : getParam<
MooseEnum>(
"square_size_style")
220 .template getEnum<PolygonSizeStyle>())),
221 _polygon_size(isParamValid(
"polygon_size")
222 ? getParam<Real>(
"polygon_size")
223 : (isParamValid(
"hexagon_size") ? getParam<Real>(
"hexagon_size")
224 : (getParam<Real>(
"square_size") /
226 _num_sectors_per_side(getParam<
std::vector<unsigned
int>>(
"num_sectors_per_side")),
227 _background_intervals(getParam<unsigned
int>(
"background_intervals")),
230 _background_radial_bias(getParam<Real>(
"background_radial_bias")),
231 _background_inner_boundary_layer_params(
232 {getParam<Real>(
"background_inner_boundary_layer_width"),
234 getParam<Real>(
"background_inner_boundary_layer_width") > 0.0
235 ? getParam<unsigned int>(
"background_inner_boundary_layer_intervals")
237 getParam<Real>(
"background_inner_boundary_layer_bias")}),
239 {getParam<Real>(
"background_outer_boundary_layer_width"),
241 getParam<Real>(
"background_outer_boundary_layer_width") > 0.0
242 ? getParam<unsigned int>(
"background_outer_boundary_layer_intervals")
244 getParam<Real>(
"background_outer_boundary_layer_bias")}),
246 ?
getParam<
std::vector<subdomain_id_type>>(
"background_block_ids")
247 :
std::vector<subdomain_id_type>()),
249 ?
getParam<
std::vector<SubdomainName>>(
"background_block_names")
250 :
std::vector<SubdomainName>()),
258 :
std::vector<unsigned
int>()),
262 declareMeshProperty<bool>(
"flat_side_up", getParam<bool>(
"flat_side_up"));
263 declareMeshProperty<unsigned int>(
"background_intervals_meta", 0);
264 declareMeshProperty<Real>(
"pattern_pitch_meta", 0.0);
265 declareMeshProperty<std::vector<Real>>(
"azimuthal_angle_meta", std::vector<Real>());
266 declareMeshProperty<Real>(
"max_radius_meta", 0.0);
277 if (tri_order != quad_order)
285 if (tri_order != quad_order)
288 else if (tri_order != quad_order)
290 "the element types of triangular and quadrilateral elements must be compatible if "
291 "both types of elements are generated.");
296 paramError(
"sides_to_adapt",
"If provided, the generated mesh must be a hexagon or a square.");
300 declareMeshProperty<Real>(
"pitch_meta",
_pitch);
304 "If provided, the length of this parameter must be identical to the total number of "
308 paramError(
"outward_interface_boundary_names",
309 "If provided, the length of this parameter must be identical to the total number of "
311 const unsigned int num_total_background_layers =
316 "background_block_ids",
317 "This parameter must be either unset or have a unity length when ring_radii is "
318 "provided or the number of background intervals (including boundary layers) is unity.");
321 "background_block_names",
322 "This parameter must be either unset or have a unity length when ring_radii is "
323 "provided or the number of background intervals (including boundary layers) is unity.");
330 "This parameter must be either unset or have a length of two when ring_radii is not "
331 "provided and background intervals (including boundary layers) is not unity. It can "
332 "optionally to have a unity length if `quad_center_elements` is enabled.");
340 "This parameter must be either unset or have a length of two when ring_radii is not "
341 "provided and background intervals (including boundary layers) is not unity. It can "
342 "optionally have a unity length if `quad_center_elements` is enabled.");
345 "This parameter must have a length that is consistent with num_sides.");
348 paramError(
"num_sectors_per_side",
"This parameter must be even.");
351 if (!getParam<bool>(
"replace_inner_ring_with_delaunay_mesh") &&
354 "inner_ring_desired_area",
355 "This parameter should be set only when 'replace_inner_ring_with_delaunay_mesh=true'");
359 const unsigned int num_innermost_ring_layers =
369 (
_ring_intervals.size() + (
unsigned int)(num_innermost_ring_layers != 1)))
372 std::ostringstream debug_info;
375 debug_info <<
"ring_block_ids size is : " <<
_ring_block_ids.size() << std::endl;
376 debug_info <<
"ring_intervals size is : " <<
_ring_intervals.size() << std::endl;
377 debug_info <<
"number of innermost ring layers is : " << num_innermost_ring_layers
385 "This parameter must have the appropriate size if it is provided: "
386 "Since the number of the innermost ring layers (" +
387 std::to_string(num_innermost_ring_layers) +
388 " :first ring interval and inner/outer boundaries of the first ring) is more than "
389 "one, and we have non-quad central elements, the size of 'ring_block_ids' must be "
390 "equal to the size of 'ring_intervals' + 1.\n",
397 "This parameter must have the appropriate size if it is provided: "
398 "Since the number of the innermost ring layers (" +
399 std::to_string(num_innermost_ring_layers) +
400 " :first ring interval and inner/outer boundaries of the first ring) is more than "
401 "one, and we have quad central elements, the size of 'ring_block_ids' can be either"
402 "equal to the size of 'ring_intervals' or 'ring_intervals' + 1.\n",
413 (
_ring_intervals.size() + (
unsigned int)(num_innermost_ring_layers != 1)))
416 std::ostringstream debug_info;
419 debug_info <<
"ring_block_names size is : " <<
_ring_block_names.size() << std::endl;
420 debug_info <<
"ring_intervals size is : " <<
_ring_intervals.size() << std::endl;
421 debug_info <<
"number of innermost ring layers is : " << num_innermost_ring_layers
429 "This parameter must have the appropriate size if it is provided: "
430 "Since the number of the innermost ring layers (" +
431 std::to_string(num_innermost_ring_layers) +
432 " :first ring interval and inner/outer boundaries of the first ring) is more than "
433 "one, and we have non-quad central elements, the size of 'ring_block_names' must "
434 "be equal to the size of 'ring_intervals' + 1.\n",
441 "This parameter must have the appropriate size if it is provided: "
442 "Since the number of the innermost ring layers (" +
443 std::to_string(num_innermost_ring_layers) +
444 " :first ring interval and inner/outer boundaries of the first ring) is more than "
445 "one, and we have quad central elements, the size of 'ring_block_names' can be "
446 "either equal to the size of 'ring_intervals' or 'ring_intervals' + 1.\n",
450 for (
unsigned int i = 0; i <
_ring_radii.size(); i++)
461 paramError(
"ring_inner_boundary_layer_intervals",
462 "Ring inner boundary layer must have zero interval if its thickness is zero.");
466 paramError(
"ring_inner_boundary_layer_intervals",
467 "Ring inner boundary layer must have non-zero interval if its thickness is "
473 paramError(
"ring_outer_boundary_layer_intervals",
474 "Ring outer boundary layer must have zero interval if its thickness is zero.");
478 paramError(
"ring_outer_boundary_layer_intervals",
479 "Ring outer boundary layer must have non-zero interval if its thickness is "
484 paramError(
"ring_inner_boundary_layer_widths",
485 "Summation of ring_inner_boundary_layer_widths and "
486 "ring_outer_boundary_layer_widths cannot exceeds the ring layer width.");
491 paramError(
"duct_sizes",
"This parameter and duct_intervals must have the same length.");
493 paramError(
"duct_sizes",
"This parameter and duct_radial_biases must have the same length.");
496 "This parameter must have the same length as duct_intervals if set.");
499 "This parameter must have the same length as duct_intervals if set.");
507 "The inner and outer duct boundary layer parameters must have the same sizes as "
512 for (
unsigned int i = 0; i <
_duct_sizes.size(); i++)
514 for (
unsigned int i = 1; i <
_duct_sizes.size(); i++)
516 paramError(
"duct_sizes",
"This parameter must be strictly ascending.");
520 "This parameter must be positive and ensures no overlapping with rings.");
523 "This parameter must ensure that ducts are smaller than the polygon size.");
525 paramError(
"duct_intervals",
"Elements of this parameter must be positive.");
527 for (
unsigned int i = 0; i <
_duct_sizes.size(); i++)
532 for (
unsigned int i = 0; i <
_duct_sizes.size(); i++)
534 const Real layer_width =
546 paramError(
"duct_inner_boundary_layer_intervals",
547 "Duct inner boundary layer must have zero interval if its thickness is zero.");
551 paramError(
"duct_inner_boundary_layer_intervals",
552 "Duct inner boundary layer must have non-zero interval if its thickness is "
558 paramError(
"duct_outer_boundary_layer_intervals",
559 "Duct outer boundary layer must have zero interval if its thickness is zero.");
563 paramError(
"duct_outer_boundary_layer_intervals",
564 "Duct outer boundary layer must have non-zero interval if its thickness is "
569 paramError(
"duct_inner_boundary_layer_widths",
570 "Summation of duct_inner_boundary_layer_widths and "
571 "duct_outer_boundary_layer_widths cannot exceeds the duct layer width.");
578 const Real min_background_thickness =
586 min_background_thickness)
587 paramError(
"background_inner_boundary_layer_width",
588 "The summation of background_inner_boundary_layer_width and "
589 "background_outer_boundary_layer_width must be less than the minimum thickness of "
590 "the background region.");
596 "this parameter is only applicable if quad_center_elements is set true.");
598 declareMeshProperty<subdomain_id_type>(
599 "quad_center_block_id",
604 declareMeshProperty<subdomain_id_type>(
"quad_center_block_id",
605 libMesh::Elem::invalid_subdomain_id);
608 declareMeshProperty<bool>(
"interface_boundaries",
false);
609 declareMeshProperty<std::set<boundary_id_type>>(
"interface_boundary_ids", {});
612std::unique_ptr<MeshBase>
615 std::vector<std::unique_ptr<ReplicatedMesh>> input(
_input_ptrs.size());
618 input[i] = dynamic_pointer_cast<ReplicatedMesh>(std::move(*
_input_ptrs[i]));
620 mooseError(
"A non-replicated mesh input was supplied but replicated meshes are required.");
621 if ((
_order == 1 && (*input[i]->elements_begin())->default_order() != FIRST) ||
622 (
_order == 2 && (*input[i]->elements_begin())->default_order() == FIRST))
624 "The order of the input mesh to be adapted to does not match the order of the "
625 "mesh to be generated.");
628 unsigned int mesh_input_counter = 0;
630 std::vector<Real> azimuthal_list;
632 for (
unsigned int mesh_index = 0; mesh_index <
_num_sides; mesh_index++)
645 _num_sides == 6 ? ((Real)mesh_index * 60.0 - 150.0) : ((Real)mesh_index * 90.0 - 135.0);
646 Real upper_azi =
_num_sides == 6 ? ((Real)((mesh_index + 1) % 6) * 60.0 - 150.0)
647 : ((Real)((mesh_index + 1) % 4) * 90.0 - 135.0);
654 azimuthal_list.push_back(
656 ? ((Real)mesh_index * 60.0 - 150.0 +
659 : ((Real)mesh_index * 90.0 - 135.0 +
662 mesh_input_counter++;
669 azimuthal_list.push_back(
678 std::vector<Real> ring_radii_corr;
685 for (
unsigned int i = 0; i <
_ring_radii.size(); i++)
686 ring_radii_corr.push_back(
_ring_radii[i] * corr_factor);
690 if (ring_radii_corr.back() >=
_pitch / 2.0)
692 "Elements of this parameter must be smaller than polygon apothem (after volume "
693 "preserve correction if applicable).");
727 for (
unsigned int mesh_index = 1; mesh_index <
_num_sides; mesh_index++)
759 ReplicatedMesh other_mesh(*mesh_tmp);
760 MeshTools::Modification::rotate(other_mesh, 360.0 /
_num_sides * mesh_index, 0, 0);
761 mesh0->prepare_for_use();
762 other_mesh.prepare_for_use();
783 const Real angle_tol = 1.0e-5;
784 std::vector<std::pair<Real, unsigned int>> node_azi_list;
785 MeshTools::Modification::rotate(*mesh0, -(270.0 - 360.0 / (Real)
_num_sides), 0.0, 0.0);
786 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> side_list =
787 mesh0->get_boundary_info().build_side_list();
788 mesh0->get_boundary_info().build_node_list_from_side_list();
789 std::vector<std::tuple<dof_id_type, boundary_id_type>> node_list =
790 mesh0->get_boundary_info().build_node_list();
792 for (
unsigned int i = 0; i < node_list.size(); ++i)
796 node_azi_list.push_back(
797 std::make_pair(atan2((*mesh0->node_ptr(std::get<0>(node_list[i])))(1),
798 (*mesh0->node_ptr(std::get<0>(node_list[i])))(0)) *
800 std::get<0>(node_list[i])));
801 if (std::abs(node_azi_list.back().first + 180.0) <= angle_tol)
802 node_azi_list.back().first = 180.0;
805 std::sort(node_azi_list.begin(), node_azi_list.end());
812 Real x_tmp =
_pitch / 2.0;
813 Real y_tmp = x_tmp * std::tan(azi_corr_tmp);
816 Point p_tmp = Point(x_tmp, y_tmp, 0.0);
819 node_azi_list[std::accumulate(
825 MeshTools::Modification::rotate(*mesh0, (270.0 - 360.0 / (Real)
_num_sides), 0.0, 0.0);
837 unsigned int block_it = 0;
838 unsigned ring_block_num = 0;
839 std::vector<subdomain_id_type> block_ids_old;
840 std::vector<subdomain_id_type> block_ids_new;
841 std::vector<SubdomainName> block_names;
854 ? (SubdomainName)std::to_string(block_ids_new.back())
863 ? (SubdomainName)std::to_string(block_ids_new.back())
873 ? (SubdomainName)std::to_string(block_ids_new.back())
880 *mesh0, block_ids_old, block_ids_new, block_names,
"ConcentricCircleMeshGenerator");
886 mesh0->get_boundary_info().sideset_name(
889 mesh0->get_boundary_info().nodeset_name(
904 getParam<std::string>(
"ring_id_name"),
908 getParam<MooseEnum>(
"ring_id_assign_type") ==
"ring_wise",
916 std::set<boundary_id_type> boundary_ids = mesh0->get_boundary_info().get_boundary_ids();
917 std::set<boundary_id_type> interface_boundary_ids;
920 const unsigned int num_boundary_ids = boundary_ids.size();
921 for (
const auto i : make_range(num_boundary_ids))
924 auto it = boundary_ids.find(
id);
925 if (it != boundary_ids.end())
927 boundary_ids.erase(it);
928 interface_boundary_ids.insert(
id);
934 const unsigned int num_boundary_ids = boundary_ids.size();
935 for (
const auto i : make_range(num_boundary_ids))
938 auto it = boundary_ids.find(
id);
939 if (it != boundary_ids.end())
941 boundary_ids.erase(it);
942 interface_boundary_ids.insert(
id);
949 bool flat_side_up = getMeshProperty<bool>(
"flat_side_up",
name());
951 MeshTools::Modification::rotate(*mesh0, 180.0 / (Real)
_num_sides, 0.0, 0.0);
952 mesh0->unset_is_prepared();
954 if (
_has_rings && getParam<bool>(
"replace_inner_ring_with_delaunay_mesh"))
958 "Should not be set because the center elements of the inner ring will be replaced "
959 "by a Delaunay mesh with 'replace_inner_ring_with_delaunay_mesh=true'");
962 std::set<Elem *> deleteable_elems;
963 for (
auto & elem : mesh0->element_ptr_range())
964 if (elem->vertex_average().norm() < ring_radii_corr[0])
965 deleteable_elems.insert(elem);
968 BoundaryInfo & boundary_info = mesh0->get_boundary_info();
969 for (
auto & elem : deleteable_elems)
971 unsigned int n_sides = elem->n_sides();
972 for (
unsigned int n = 0; n != n_sides; ++n)
974 Elem * neighbor = elem->neighbor_ptr(n);
978 const unsigned int return_side = neighbor->which_neighbor_am_i(elem);
980 if (neighbor->neighbor_ptr(return_side) == elem)
982 neighbor->set_neighbor(return_side,
nullptr);
983 boundary_info.add_side(neighbor, return_side, boundary_id);
987 mesh0->delete_elem(elem);
992 Real min_side = std::numeric_limits<Real>::max();
993 for (
auto & elem : poly_mesh->element_ptr_range())
995 Real l = elem->volume();
1006 const auto desired_area = getParam<std::string>(
"inner_ring_desired_area");
1007 if (desired_area !=
"")
1019 poly2tri.
elem_type() = libMesh::ElemType::TRI6;
1021 poly2tri.
elem_type() = libMesh::ElemType::TRI7;
1026 for (
auto elem : poly_mesh->element_ptr_range())
1027 elem->subdomain_id() = block_ids_new[0];
1031 if (
_ring_intervals[0] != 1 && getParam<MooseEnum>(
"ring_id_assign_type") ==
"ring_wise")
1032 paramError(
"replace_inner_ring_with_delaunay_mesh",
1033 "Inner ring has multple intervals with each being assigned with a different "
1034 "ring id, replacing inner ring with Delaunay mesh will remove this ring id "
1035 "assign type. Either change 'ring_id_assign_type' to block_wise or set the "
1036 "first element of 'ring_intervals' to 1 or set "
1037 "'replace_inner_ring_with_delaunay_mesh' to false to avoid this error.");
1038 auto id_name = getParam<std::string>(
"ring_id_name");
1039 const auto extra_id_index = poly_mesh->add_elem_integer(id_name);
1040 for (
auto elem : poly_mesh->element_ptr_range())
1041 elem->set_extra_integer(extra_id_index, 1);
1046 auto id_name = getParam<std::string>(
"sector_id_name");
1047 const auto extra_id_index = poly_mesh->add_elem_integer(id_name);
1048 for (
auto elem : poly_mesh->element_ptr_range())
1049 elem->set_extra_integer(extra_id_index, 0);
1053 mesh0->stitch_meshes(*poly_mesh, boundary_id, 0, TOLERANCE,
true,
false);
1056 return dynamic_pointer_cast<MeshBase>(mesh0);
void ErrorVector unsigned int
This ConcentricCircleGeneratorBase object is a base class to be inherited for mesh generators that in...
unsigned short _order
Order of the elements to be generated.
const std::vector< Real > _ring_radial_biases
Bias values used to induce biasing to radial meshing in ring regions.
const boundary_id_type _interface_boundary_id_shift
Shift in default boundary IDs of interfaces to avert potential conflicts.
QUAD_ELEM_TYPE _quad_elem_type
Type of quadrilateral elements to be generated.
std::vector< subdomain_id_type > _ring_block_ids
Subdomain IDs of the ring regions.
const BoundaryName _external_boundary_name
Boundary Name of the mesh's external boundary.
multiBdryLayerParams _ring_inner_boundary_layer_params
Widths, fractions, radial sectors and growth factors of the inner boundary layers of the ring regions...
const std::vector< std::string > _inward_interface_boundary_names
Boundary Names of the mesh's inward interface boundaries.
const boundary_id_type _external_boundary_id
Boundary ID of the mesh's external boundary.
const bool _preserve_volumes
Volume preserving function is optional.
std::vector< SubdomainName > _ring_block_names
Subdomain Names of the ring regions.
const subdomain_id_type _block_id_shift
Shift in default subdomain IDs to avert potential conflicts with other meshes.
const std::vector< std::string > _outward_interface_boundary_names
Boundary Names of the mesh's outward interface boundaries.
multiBdryLayerParams _ring_outer_boundary_layer_params
Widths, fractions, radial sectors and growth factors of the outer boundary layers of the ring regions...
static InputParameters validParams()
const std::vector< unsigned int > _ring_intervals
Number of rings in each circle or in the enclosing square.
void ringBlockIdsNamesPreparer(unsigned int &block_counter, unsigned int &ring_block_num, std::vector< subdomain_id_type > &block_ids_old, std::vector< subdomain_id_type > &block_ids_new, std::vector< SubdomainName > &block_names) const
Prepare user-defined ring block IDs and names to replace the default ones.
const std::vector< Real > _ring_radii
Radii of concentric circles.
const bool _generate_side_specific_boundaries
Whether the side-specific external boundaries are generated or not.
void assignInterfaceBoundaryNames(ReplicatedMesh &mesh) const
Assign interface boundary names to the mesh if applicable.
const bool _create_inward_interface_boundaries
Whether inward interface boundaries are created.
void assignBlockIdsNames(ReplicatedMesh &mesh, std::vector< subdomain_id_type > &block_ids_old, std::vector< subdomain_id_type > &block_ids_new, std::vector< SubdomainName > &block_names, const std::string &generator_name) const
Assign block IDs and names to the mesh if applicable.
const bool _create_outward_interface_boundaries
Whether outward interface boundaries are created.
TRI_ELEM_TYPE _tri_elem_type
Type of triangular elements to be generated.
T & setMeshProperty(const std::string &data_name, Args &&... args)
T & declareMeshProperty(const std::string &data_name, Args &&... args)
const std::string & name() const
void paramError(const std::string ¶m, Args... args) const
bool isParamSetByUser(const std::string &name) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
bool isParamValid(const std::string &name) const
const std::vector< SubdomainName > _duct_block_names
Subdomain Names of the duct regions.
const bool _quad_center_elements
Whether the central elements need to be QUAD4.
const bool _has_ducts
Whether the generated mesh contains duct regions.
multiBdryLayerParams _duct_outer_boundary_layer_params
Widths, fractions, radial sectors and growth factors of the inner boundary layers of the duct regions...
bool _is_general_polygon
MeshMetaData: whether this produced mesh is a general polygon (or a hexagon)
const Real _center_quad_factor
A fractional radius factor used to determine the radial positions of transition nodes in the center r...
const std::vector< subdomain_id_type > _duct_block_ids
Subdomain IDs of the duct regions.
std::vector< SubdomainName > _background_block_names
Subdomain Names of the background regions.
singleBdryLayerParams _background_inner_boundary_layer_params
Width, fraction, radiation sectors and growth factor of the inner boundary layer of the background re...
std::vector< Real > _duct_sizes
Size parameters of the duct regions.
const bool _uniform_mesh_on_sides
Whether the nodes on the external boundary needs to be uniformly distributed.
const bool _has_rings
Whether the generated mesh contains ring regions.
singleBdryLayerParams _background_outer_boundary_layer_params
Width, fraction, radiation sectors and growth factor of the outer boundary layer of the background re...
std::vector< subdomain_id_type > _background_block_ids
Subdomain IDs of the background regions.
const Real _background_radial_bias
Bias value used to induce biasing to radial meshing in background region.
const PolygonSizeStyle _duct_sizes_style
Thickness of each enclosing duct.
const PolygonSizeStyle _polygon_size_style
Type of polygon size parameter.
const std::vector< unsigned int > _num_sectors_per_side
Mesh sector number of each polygon side.
const std::vector< unsigned int > _duct_intervals
Number of layers in each enclosing duct.
const Real _polygon_size
Polygon size parameter.
dof_id_type & _node_id_background_meta
MeshMetaData: maximum node id of the background region.
multiBdryLayerParams _duct_inner_boundary_layer_params
Widths, fractions, radial sectors and growth factors of the inner boundary layers of the duct regions...
const unsigned int _num_sides
Number of polygon sides.
const std::vector< Real > _duct_radial_biases
Bias values used to induce biasing to radial meshing in duct regions.
std::vector< std::unique_ptr< MeshBase > * > _input_ptrs
Pointers to input mesh pointers.
Real _pitch
Pitch size of the produced polygon.
const unsigned int _background_intervals
Numbers of radial intervals of the background regions.
bool & _is_control_drum_meta
MeshMetaData: whether this produced mesh is a control drum.
std::unique_ptr< MeshBase > generate() override
static InputParameters validParams()
const unsigned int _smoothing_max_it
Maximum smooth iteration number.
std::vector< std::vector< Real > > _azimuthal_angles_array
Azimuthal angles of all radial nodes for volume preservation.
const std::vector< unsigned int > _sides_to_adapt
Indices of the hexagon sides that need to adapt.
PolygonConcentricCircleMeshGeneratorBase(const InputParameters ¶meters)
std::vector< Real > azimuthalAnglesCollector(ReplicatedMesh &mesh, std::vector< Point > &boundary_points, const Real lower_azi=-30.0, const Real upper_azi=30.0, const unsigned int return_type=ANGLE_TANGENT, const unsigned int num_sides=6, const boundary_id_type bid=OUTER_SIDESET_ID, const bool calculate_origin=true, const Real input_origin_x=0.0, const Real input_origin_y=0.0, const Real tol=1.0E-10) const
Collects sorted azimuthal angles of the external boundary.
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
PolygonSizeStyle
An enum class for style of input polygon size.
static void addRingAndSectorIDParams(InputParameters ¶ms)
Add InputParameters which are used by ring and sector IDs.
void nodeCoordRotate(Real &x, Real &y, const Real theta) const
Calculates x and y coordinates after rotating by theta angle.
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
std::unique_ptr< ReplicatedMesh > buildSimpleSlice(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 pitch, 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 unsigned int side_number, const unsigned int side_index, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const bool quad_center_elements=false, const Real center_quad_factor=0.0, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const bool generate_side_specific_boundaries=true, const TRI_ELEM_TYPE tri_elem_type=TRI_ELEM_TYPE::TRI3, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4)
Creates a mesh of a slice that corresponds to a single side of the polygon to be generated.
virtual void smooth() override
virtual void set_refine_boundary_allowed(bool refine_bdy_allowed) override
virtual void set_desired_area_function(FunctionBase< Real > *desired) override
virtual void triangulate() override
TriangulationType & triangulation_type()
bool & smooth_after_generating()
void set_verify_hole_boundaries(bool v)
void set_interpolate_boundary_points(int n_points)
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
std::unique_ptr< ReplicatedMesh > buildBoundaryMesh(const MeshBase &input_mesh, const boundary_id_type boundary_id)
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
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.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< Real > widths
std::vector< unsigned int > intervals
std::vector< Real > biases
std::vector< Real > fractions