23 std::vector<const libMesh::Node *> & tentative_coarse_nodes,
24 std::set<const libMesh::Elem *> & fine_elements)
26 const auto elem_type = fine_elem.
type();
32 fine_elements.insert(&fine_elem);
37 const auto node_index = neigh->get_node_index(&interior_node);
42 fine_elements.insert(neigh);
43 for (
const auto neigh_two : neigh->neighbor_ptr_range())
47 const auto node_index_2 = neigh_two->get_node_index(&interior_node);
51 fine_elements.insert(neigh_two);
55 for (
const auto neigh_three : neigh_two->neighbor_ptr_range())
59 const auto node_index_3 = neigh_three->get_node_index(&interior_node);
61 fine_elements.insert(neigh_three);
70 for (
auto elem : fine_elements)
71 if (elem && fine_elem.
type() != elem_type)
77 if (fine_elements.size() != 4)
82 tentative_coarse_nodes.resize(4);
85 unsigned int neighbor_i = 0;
86 for (
auto neighbor : fine_elements)
88 const auto interior_node_number = neighbor->get_node_index(&interior_node);
89 unsigned int opposite_node_index = (interior_node_number + 2) % 4;
91 tentative_coarse_nodes[neighbor_i++] = neighbor->node_ptr(opposite_node_index);
96 (fine_elem.
vertex_average() - interior_node).cross(interior_node - reference_node);
97 reorderNodes(tentative_coarse_nodes, interior_node, reference_node, axis);
105 if (fine_elements.size() != 8)
108 tentative_coarse_nodes.resize(4);
113 const Elem * one_fine_elem =
nullptr;
114 unsigned int max_id = 0;
115 for (
const auto elem_ptr : fine_elements)
116 if (elem_ptr->id() > max_id)
118 max_id = elem_ptr->id();
119 one_fine_elem = elem_ptr;
121 const auto interior_node_index = one_fine_elem->get_node_index(&interior_node);
124 unsigned int an_interior_node_side = 0;
125 for (
const auto s : make_range(one_fine_elem->n_sides()))
126 if (one_fine_elem->is_node_on_side(interior_node_index, s))
128 an_interior_node_side = s;
133 const auto center_face_node_index =
134 one_fine_elem->opposite_node(interior_node_index, an_interior_node_side);
135 const auto center_face_node = one_fine_elem->node_ptr(center_face_node_index);
139 unsigned int neighbor_i = 0;
140 std::vector<const libMesh::Elem *> other_fine_elems;
141 for (
auto neighbor : fine_elements)
145 other_fine_elems.push_back(neighbor);
149 const auto interior_node_number = neighbor->get_node_index(&interior_node);
150 unsigned int opposite_node_index =
153 tentative_coarse_nodes[neighbor_i++] = neighbor->node_ptr(opposite_node_index);
158 if (neighbor_i != 4 || other_fine_elems.size() != 4)
162 auto cmp_node = [](
const Node * a,
const Node * b) {
return a->id() < b->id(); };
163 std::sort(tentative_coarse_nodes.begin(), tentative_coarse_nodes.end(), cmp_node);
169 reorderNodes(tentative_coarse_nodes, *center_face_node, clock_start, axis);
172 for (
const auto coarse_node_index : make_range(4))
175 const Elem * fine_elem =
nullptr;
176 for (
auto elem : fine_elements)
177 if (elem->get_node_index(tentative_coarse_nodes[coarse_node_index]) !=
183 mooseAssert(fine_elem,
"Search for fine element should have worked");
186 const Elem * fine_neighbor =
nullptr;
187 for (
auto neighbor : other_fine_elems)
194 fine_neighbor = neighbor;
203 const auto interior_node_index_neighbor = fine_neighbor->get_node_index(&interior_node);
204 tentative_coarse_nodes.push_back(fine_neighbor->node_ptr(
209 if (tentative_coarse_nodes.size() == 8)
224 mooseAssert(axis.
norm() != 0,
"Invalid rotation axis when ordering nodes");
225 mooseAssert(origin != clock_start,
"Invalid starting direction when ordering nodes");
230 auto start_clock = origin - clock_start;
231 start_clock /= start_clock.
norm();
234 std::vector<std::pair<unsigned int, libMesh::Real>> nodes_angles(nodes.size());
235 for (
const auto angle_i : index_range(nodes))
237 mooseAssert(nodes[angle_i],
"Nodes cant be nullptr");
238 auto vec = *nodes[angle_i] - origin;
240 const auto angle = atan2(vec.cross(start_clock) * axis, vec * start_clock);
241 nodes_angles[angle_i] = std::make_pair(angle_i, angle);
245 std::sort(nodes_angles.begin(),
247 [](
auto & left,
auto & right) { return left.second < right.second; });
250 std::vector<const libMesh::Node *> new_nodes(nodes.size());
251 for (
const auto & old_index : index_range(nodes))
252 new_nodes[old_index] = nodes[nodes_angles[old_index].first];
253 for (
const auto & index : index_range(nodes))
254 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...