25 #include "libmesh/libmesh_config.h"
26 #include "libmesh/tree_node.h"
27 #include "libmesh/mesh_base.h"
28 #include "libmesh/elem.h"
35 template <
unsigned int N>
42 if (!this->bounds_node(nd))
51 if (nodes.size() == tgt_bin_size)
59 libmesh_assert_equal_to (children.size(), N);
61 bool was_inserted =
false;
62 for (
unsigned int c=0; c<N; c++)
63 if (children[c]->insert (nd))
70 template <
unsigned int N>
88 elements.push_back (elem);
90 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
95 this->contains_ifems =
true;
99 unsigned int element_count = cast_int<unsigned int>(elements.size());
103 if (elem_dimensions.size() > 1)
106 unsigned char highest_dim_elem = *elem_dimensions.rbegin();
107 for (
const Elem * other_elem : elements)
108 if (other_elem->dim() == highest_dim_elem)
114 if (element_count == tgt_bin_size)
122 libmesh_assert_equal_to (children.size(), N);
124 bool was_inserted =
false;
125 for (
unsigned int c=0; c<N; c++)
126 if (children[c]->insert (elem))
133 template <
unsigned int N>
145 unsigned int new_target_bin_size = tgt_bin_size;
146 if (level() >= target_bin_size_increase_level)
148 new_target_bin_size *= 2;
151 for (
unsigned int c=0; c<N; c++)
158 for (
const Node * node : nodes)
159 children[c]->insert(node);
162 for (
const Elem * elem : elements)
163 children[c]->insert(elem);
169 std::vector<const Node *>().swap(nodes);
170 std::vector<const Elem *>().swap(elements);
172 libmesh_assert_equal_to (nodes.capacity(), 0);
173 libmesh_assert_equal_to (elements.capacity(), 0);
178 template <
unsigned int N>
186 template <
unsigned int N>
188 Real relative_tol)
const
191 return bounds_point(*nd, relative_tol);
196 template <
unsigned int N>
198 Real relative_tol)
const
203 const Real tol = (max - min).
norm() * relative_tol;
205 if ((p(0) >= min(0) - tol)
206 && (p(0) <= max(0) + tol)
208 && (p(1) >= min(1) - tol)
209 && (p(1) <= max(1) + tol)
212 && (p(2) >= min(2) - tol)
213 && (p(2) <= max(2) + tol)
223 template <
unsigned int N>
240 const Real xc = .5*(xmin + xmax);
241 const Real yc = .5*(ymin + ymax);
242 const Real zc = .5*(zmin + zmax);
251 Point(xmax, yc, zc));
254 Point(xc, ymax, zc));
257 Point(xmax, ymax, zc));
260 Point(xc, yc, zmax));
263 Point(xmax, yc, zmax));
266 Point(xc, ymax, zmax));
269 Point(xmax, ymax, zmax));
271 libmesh_error_msg(
"c >= N! : " << c);
286 const Real xc = .5*(xmin + xmax);
287 const Real yc = .5*(ymin + ymax);
304 libmesh_error_msg(
"c >= N!");
317 const Real xc = .5*(xmin + xmax);
328 libmesh_error_msg(
"c >= N!");
335 libmesh_error_msg(
"Only implemented for Octrees, QuadTrees, and Binary Trees!");
341 template <
unsigned int N>
346 out_stream <<
"TreeNode Level: " << this->level() << std::endl;
348 for (
const Node * node : nodes)
349 out_stream <<
" " << node->id();
351 out_stream << std::endl << std::endl;
355 child->print_nodes();
360 template <
unsigned int N>
365 out_stream <<
"TreeNode Level: " << this->level() << std::endl;
367 for (
const auto & elem : elements)
368 out_stream <<
" " << elem;
370 out_stream << std::endl << std::endl;
374 child->print_elements();
379 template <
unsigned int N>
389 std::set<const Elem *> elements_set;
391 for (
const Node * node : nodes)
398 libmesh_assert_less (node_number, nodes_to_elem.size());
400 for (
const Elem * elem : nodes_to_elem[node_number])
401 elements_set.insert(elem);
405 std::vector<const Node *>().swap(nodes);
411 elements.reserve(elements_set.size());
413 for (
const auto & elem : elements_set)
415 elements.push_back(elem);
417 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
421 if (elem->infinite())
422 this->contains_ifems =
true;
429 child->transform_nodes_to_elements (nodes_to_elem);
434 template <
unsigned int N>
444 std::set<const Elem *> elements_set;
446 for (
const Node * node : nodes)
454 auto & my_elems = nodes_to_elem[node_number];
455 elements_set.insert(my_elems.begin(), my_elems.end());
459 std::vector<const Node *>().swap(nodes);
465 elements.reserve(elements_set.size());
467 for (
const auto & elem : elements_set)
469 elements.push_back(elem);
471 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
475 if (elem->infinite())
476 this->contains_ifems =
true;
483 child->transform_nodes_to_elements (nodes_to_elem);
488 template <
unsigned int N>
499 sum += child->n_active_bins();
507 template <
unsigned int N>
510 const std::set<subdomain_id_type> * allowed_subdomains,
511 Real relative_tol)
const
517 if (this->bounds_point(p, relative_tol) || this->contains_ifems)
519 for (
const auto & elem : elements)
520 if (!allowed_subdomains || allowed_subdomains->count(elem->subdomain_id()))
521 if (elem->active() && elem->contains_point(p, relative_tol))
528 return this->find_element_in_children(p,allowed_subdomains,
534 template <
unsigned int N>
537 std::set<const Elem *> & candidate_elements,
538 const std::set<subdomain_id_type> * allowed_subdomains,
539 Real relative_tol)
const
545 if (this->bounds_point(p, relative_tol) || this->contains_ifems)
547 for (
const auto & elem : elements)
548 if (!allowed_subdomains || allowed_subdomains->count(elem->subdomain_id()))
549 if (elem->active() && elem->contains_point(p, relative_tol))
550 candidate_elements.insert(elem);
553 this->find_elements_in_children(p, candidate_elements,
554 allowed_subdomains, relative_tol);
559 template <
unsigned int N>
561 const std::set<subdomain_id_type> * allowed_subdomains,
562 Real relative_tol)
const
567 auto searched_child = std::array<bool, N>();
572 if (children[c]->bounds_point(p, relative_tol))
575 children[c]->find_element(p,allowed_subdomains,
586 searched_child[c] =
true;
595 if (!searched_child[c])
598 children[c]->find_element(p,allowed_subdomains,
615 template <
unsigned int N>
617 std::set<const Elem *> & candidate_elements,
618 const std::set<subdomain_id_type> * allowed_subdomains,
619 Real relative_tol)
const
625 for (std::size_t c=0; c<children.size(); c++)
626 if (children[c]->bounds_point(p, relative_tol))
627 children[c]->find_elements(p, candidate_elements,
628 allowed_subdomains, relative_tol);