22 "The input mesh to be modified. Note that this generator only works with " 23 "PatternedHex/CartesianMeshGenerator and its derived classes such as " 24 "HexIDPatternedMeshGenerator.");
26 "The external boundary of the input mesh.");
28 "Number of sectors of each side for the new mesh.");
30 "transition_layer_id",
32 "Optional customized block id for the transition layer block.");
33 params.
addParam<SubdomainName>(
"transition_layer_name",
35 "Optional customized block name for the transition layer block.");
37 "num_layers", 1,
"num_layers>0",
"Layers of elements for transition.");
38 params.
addParam<std::vector<std::string>>(
39 "extra_id_names_to_modify",
40 "Names of the element extra ids in the peripheral region that should be modified");
41 params.
addParam<std::vector<dof_id_type>>(
42 "new_extra_id_values_to_assign",
43 std::vector<dof_id_type>(),
44 "Values of the modified extra ids in the peripheral region.");
46 "PatternedCartPeripheralModifier and PatternedHexPeripheralModifier.");
54 _input_name(getParam<MeshGeneratorName>(
"input")),
55 _input_mesh_external_boundary(getParam<BoundaryName>(
"input_mesh_external_boundary")),
56 _new_num_sector(getParam<unsigned
int>(
"new_num_sector")),
58 _transition_layer_name(getParam<SubdomainName>(
"transition_layer_name")),
59 _num_layers(getParam<unsigned
int>(
"num_layers")),
60 _extra_id_names_to_modify(isParamValid(
"extra_id_names_to_modify")
61 ? getParam<
std::vector<
std::string>>(
"extra_id_names_to_modify")
62 :
std::vector<
std::string>()),
63 _new_extra_id_values_to_assign(
64 getParam<
std::vector<
dof_id_type>>(
"new_extra_id_values_to_assign")),
67 _mesh(getMeshByName(_input_name))
69 declareMeshProperty<Real>(
"pattern_pitch_meta", 0.0);
70 declareMeshProperty<bool>(
"is_control_drum_meta",
false);
73 "This parameter must have the same size as extra_id_names_to_modify.");
74 declareMeshProperty<bool>(
"peripheral_modifier_compatible",
false);
77 std::unique_ptr<MeshBase>
82 "pattern_pitch_meta", getMeshProperty<Real>(
"pattern_pitch_meta",
_input_name));
90 "External boundary does not exist in the input mesh");
91 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> side_list =
92 input_mesh->get_boundary_info().build_side_list();
93 input_mesh->get_boundary_info().build_node_list_from_side_list();
94 std::vector<std::tuple<dof_id_type, boundary_id_type>> node_list =
95 input_mesh->get_boundary_info().build_node_list();
97 if (!input_mesh->is_prepared())
98 input_mesh->find_neighbors();
100 const unsigned int n_extra_integer_input = input_mesh->n_elem_integers();
101 std::vector<std::string> extra_integer_names;
102 for (
unsigned int i = 0; i < n_extra_integer_input; i++)
103 extra_integer_names.push_back(input_mesh->get_elem_integer_name(i));
106 std::vector<bool> extra_id_modify_flags = std::vector<bool>(n_extra_integer_input,
false);
107 std::vector<dof_id_type> extra_modify_values = std::vector<dof_id_type>(n_extra_integer_input, 0);
112 "extra_id_names_to_modify",
113 "The parameter contains an extra element integer that does not exist in the input mesh.");
123 std::vector<dof_id_type> bid_elem_list;
124 std::vector<dof_id_type> new_bid_elem_list;
125 std::vector<dof_id_type> ext_node_list;
128 for (
unsigned int i = 0; i < side_list.size(); i++)
133 bid_elem_list.push_back(std::get<0>(side_list[i]));
135 const auto elem_type = input_mesh->elem_ptr(std::get<0>(side_list[i]))->type();
138 "The input mesh has non-QUAD4/QUAD8/QUAD9 elements in its peripheral area, " 139 "which is not supported.");
149 new_bid_elem_list.push_back(input_mesh->elem_ptr(std::get<0>(side_list[i]))
150 ->neighbor_ptr((std::get<1>(side_list[i]) + 2) % 4)
155 auto bid_elem_list_it = std::unique(bid_elem_list.begin(), bid_elem_list.end());
156 auto new_bid_elem_list_it = std::unique(new_bid_elem_list.begin(), new_bid_elem_list.end());
157 bid_elem_list.resize(std::distance(bid_elem_list.begin(), bid_elem_list_it));
158 new_bid_elem_list.resize(std::distance(new_bid_elem_list.begin(), new_bid_elem_list_it));
161 std::vector<std::pair<Point, std::vector<dof_id_type>>> del_elem_extra_ids;
163 for (
unsigned int i = 0; i < bid_elem_list.size(); i++)
165 const auto & tmp_elem_ptr = input_mesh->elem_ptr(bid_elem_list[i]);
169 del_elem_extra_ids.push_back(
170 std::make_pair(tmp_elem_ptr->true_centroid(), std::vector<dof_id_type>()));
171 for (
unsigned int j = 0;
j < n_extra_integer_input;
j++)
172 del_elem_extra_ids[i].second.push_back(
173 extra_id_modify_flags[
j] ? extra_modify_values[
j] : tmp_elem_ptr->get_extra_integer(
j));
175 input_mesh->delete_elem(tmp_elem_ptr);
179 del_elem_extra_ids.push_back(
182 input_mesh->find_neighbors();
184 BoundaryInfo & boundary_info = input_mesh->get_boundary_info();
185 for (
unsigned int i = 0; i < new_bid_elem_list.size(); i++)
188 for (
unsigned int j = 0;
j < input_mesh->elem_ptr(new_bid_elem_list[i])->n_sides();
j++)
190 if (input_mesh->elem_ptr(new_bid_elem_list[i])->neighbor_ptr(
j) ==
nullptr)
196 input_mesh->contract();
197 input_mesh->prepare_for_use();
203 for (
unsigned i_side = 0; i_side <
_num_sides; i_side++)
206 std::vector<Point> inner_pts;
212 MeshTools::Modification::rotate(*input_mesh_origin, -360.0 / (
Real)
_num_sides, 0, 0);
216 std::vector<Point> outer_pts;
217 const Point outer_end_1 = Point(pattern_pitch_meta / 2.0,
220 const Point outer_end_2 = Point(pattern_pitch_meta / 2.0,
224 const std::vector<Real> input_arg{0.0, 1.0};
225 const std::vector<Real> input_x{outer_end_1(0), outer_end_2(0)};
226 const std::vector<Real> input_y{outer_end_1(1), outer_end_2(1)};
227 std::unique_ptr<LinearInterpolation> linear_outer_x =
228 std::make_unique<LinearInterpolation>(input_arg, input_x);
229 std::unique_ptr<LinearInterpolation> linear_outer_y =
230 std::make_unique<LinearInterpolation>(input_arg, input_y);
258 std::vector<std::pair<Point, Point>> inner_midpts_pairs;
261 auto inner_pts_tmp(inner_pts);
265 inner_pts.push_back(inner_pts_tmp[i]);
270 const Point avgpt = 0.5 * (inner_pts_tmp[i - 1] + inner_pts_tmp[i + 1]);
272 inner_midpts_pairs.push_back(std::make_pair(avgpt, inner_pts_tmp[i]));
274 inner_pts_tmp.clear();
289 mesh->all_second_order();
291 mesh->all_complete_order();
294 if (inner_midpts_pairs.size())
296 mesh->get_boundary_info().build_node_list_from_side_list();
297 auto tl_node_list =
mesh->get_boundary_info().build_node_list();
298 std::vector<dof_id_type> bdry_node_ids;
299 std::vector<Point> bdry_node_pts;
300 for (
const auto & tl_node_tuple : tl_node_list)
304 bdry_node_ids.push_back(std::get<0>(tl_node_tuple));
305 bdry_node_pts.push_back(*(
mesh->node_ptr(std::get<0>(tl_node_tuple))));
308 KDTree ref_kd_tree(bdry_node_pts, 4);
309 for (
const auto & midpt_pair : inner_midpts_pairs)
311 std::vector<std::size_t> nn_id;
313 *(
mesh->node_ptr(bdry_node_ids[nn_id.front()])) = midpt_pair.second;
319 mesh->add_elem_integers(extra_integer_names,
true);
321 mesh->prepare_for_use();
331 ReplicatedMesh & mesh,
332 const std::vector<std::pair<Point, std::vector<dof_id_type>>> ref_extra_ids)
335 std::vector<Point> ref_pts;
336 for (
auto & pt_extra_id : ref_extra_ids)
337 ref_pts.push_back(pt_extra_id.first);
339 KDTree ref_kd_tree(ref_pts, 4);
341 for (
const auto & elem :
as_range(
mesh.active_elements_begin(),
mesh.active_elements_end()))
343 std::vector<std::size_t> nn_id;
345 for (
unsigned int i = 0; i < ref_extra_ids[nn_id.front()].second.size(); i++)
346 elem->set_extra_integer(i, ref_extra_ids[nn_id.front()].second[i]);
const MeshGeneratorName _input_name
Name of the input mesh that needs the modification.
T & setMeshProperty(const std::string &data_name, Args &&... args)
const std::vector< std::string > _extra_id_names_to_modify
Names of extra element integers in the input mesh that need to be retained or reassigned in the trans...
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh(unsigned int dim=libMesh::invalid_uint)
const subdomain_id_type _transition_layer_id
Block ID of the transition layer to be generated.
const BoundaryID INVALID_BOUNDARY_ID
boundary_id_type _input_mesh_external_bid
Boundary ID of the external boundary of the input mesh.
const std::vector< dof_id_type > _new_extra_id_values_to_assign
Customized values to be used to reassign the extra element integers in the transition layer...
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
static InputParameters validParams()
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.
PatternedPolygonPeripheralModifierBase(const InputParameters ¶meters)
unsigned int _num_sides
Number of sides of the mesh to be generated.
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
static InputParameters validParams()
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
void neighborSearch(const Point &query_point, unsigned int patch_size, std::vector< std::size_t > &return_index)
void paramError(const std::string ¶m, Args... args) const
const unsigned int _new_num_sector
Target number of mesh sectors on each side of the square.
std::unique_ptr< MeshBase > generate() override
std::unique_ptr< MeshBase > & _mesh
The main mesh used in this class.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const SubdomainName _transition_layer_name
Block name of the transition layer to be generated.
A base class that contains common members for Reactor module mesh generators.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const unsigned int _num_layers
Number of element layers of the transition layer to be generated.
void ErrorVector unsigned int
auto index_range(const T &sizable)
const BoundaryName _input_mesh_external_boundary
External boundary name of the input mesh.
void transferExtraElemIntegers(ReplicatedMesh &mesh, const std::vector< std::pair< Point, std::vector< dof_id_type >>> ref_extra_ids)
Assign extra element integers to the newly generated transition layer mesh based on the nearest eleme...