25 std::vector<const libMesh::Node *> & tentative_coarse_nodes,
26 std::set<const libMesh::Elem *> & fine_elements)
28 const auto elem_type = fine_elem.
type();
34 fine_elements.insert(&fine_elem);
39 const auto node_index = neigh->get_node_index(&interior_node);
44 fine_elements.insert(neigh);
45 for (
const auto neigh_two : neigh->neighbor_ptr_range())
49 const auto node_index_2 = neigh_two->get_node_index(&interior_node);
53 fine_elements.insert(neigh_two);
57 for (
const auto neigh_three : neigh_two->neighbor_ptr_range())
61 const auto node_index_3 = neigh_three->get_node_index(&interior_node);
63 fine_elements.insert(neigh_three);
72 for (
auto elem : fine_elements)
73 if (elem && fine_elem.
type() != elem_type)
79 if (fine_elements.size() != 4)
84 tentative_coarse_nodes.resize(4);
87 unsigned int neighbor_i = 0;
88 for (
auto neighbor : fine_elements)
90 const auto interior_node_number = neighbor->get_node_index(&interior_node);
91 unsigned int opposite_node_index = (interior_node_number + 2) % 4;
93 tentative_coarse_nodes[neighbor_i++] = neighbor->node_ptr(opposite_node_index);
98 (fine_elem.
vertex_average() - interior_node).cross(interior_node - reference_node);
99 reorderNodes(tentative_coarse_nodes, interior_node, reference_node, axis);
107 if (fine_elements.size() != 8)
110 tentative_coarse_nodes.resize(4);
115 const Elem * one_fine_elem =
nullptr;
116 unsigned int max_id = 0;
117 for (
const auto elem_ptr : fine_elements)
118 if (elem_ptr->id() > max_id)
120 max_id = elem_ptr->
id();
121 one_fine_elem = elem_ptr;
123 const auto interior_node_index = one_fine_elem->
get_node_index(&interior_node);
126 unsigned int an_interior_node_side = 0;
130 an_interior_node_side = s;
135 const auto center_face_node_index =
136 one_fine_elem->
opposite_node(interior_node_index, an_interior_node_side);
137 const auto center_face_node = one_fine_elem->
node_ptr(center_face_node_index);
141 unsigned int neighbor_i = 0;
142 std::vector<const libMesh::Elem *> other_fine_elems;
143 for (
auto neighbor : fine_elements)
147 other_fine_elems.push_back(neighbor);
151 const auto interior_node_number = neighbor->get_node_index(&interior_node);
152 unsigned int opposite_node_index =
155 tentative_coarse_nodes[neighbor_i++] = neighbor->node_ptr(opposite_node_index);
160 if (neighbor_i != 4 || other_fine_elems.size() != 4)
164 auto cmp_node = [](
const Node * a,
const Node * b) {
return a->
id() < b->id(); };
165 std::sort(tentative_coarse_nodes.begin(), tentative_coarse_nodes.end(), cmp_node);
171 reorderNodes(tentative_coarse_nodes, *center_face_node, clock_start, axis);
174 for (
const auto coarse_node_index :
make_range(4))
177 const Elem * fine_elem =
nullptr;
178 for (
auto elem : fine_elements)
179 if (elem->get_node_index(tentative_coarse_nodes[coarse_node_index]) !=
185 mooseAssert(fine_elem,
"Search for fine element should have worked");
188 const Elem * fine_neighbor =
nullptr;
189 for (
auto neighbor : other_fine_elems)
196 fine_neighbor = neighbor;
205 const auto interior_node_index_neighbor = fine_neighbor->
get_node_index(&interior_node);
206 tentative_coarse_nodes.push_back(fine_neighbor->
node_ptr(
211 if (tentative_coarse_nodes.size() == 8)
226 mooseAssert(axis.
norm() != 0,
"Invalid rotation axis when ordering nodes");
227 mooseAssert(origin != clock_start,
"Invalid starting direction when ordering nodes");
232 auto start_clock = origin - clock_start;
233 start_clock /= start_clock.
norm();
236 std::vector<std::pair<unsigned int, libMesh::Real>> nodes_angles(nodes.size());
239 mooseAssert(nodes[angle_i],
"Nodes cant be nullptr");
240 auto vec = *nodes[angle_i] - origin;
242 const auto angle = atan2(vec.cross(start_clock) * axis, vec * start_clock);
243 nodes_angles[angle_i] = std::make_pair(angle_i, angle);
247 std::sort(nodes_angles.begin(),
249 [](
auto & left,
auto & right) { return left.second < right.second; });
252 std::vector<const libMesh::Node *> new_nodes(nodes.size());
254 new_nodes[old_index] = nodes[nodes_angles[old_index].first];
256 nodes[index] = new_nodes[index];
bool getFineElementsFromInteriorNode(const libMesh::Node &interior_node, const libMesh::Node &reference_node, const libMesh::Elem &elem, std::vector< const libMesh::Node * > &tentative_coarse_nodes, std::set< const libMesh::Elem * > &fine_elements)
Utility routine to gather vertex nodes for, and elements contained in, for a coarse QUAD or HEX eleme...