22#include <boost/geometry/algorithms/distance.hpp>
23#include <boost/geometry/index/rtree.hpp>
24#include <boost/geometry/strategies/strategies.hpp>
26template <
int dim,
int spacedim>
33 template <
typename Value,
39 :
public boost::geometry::index::detail::rtree::visitor<
41 typename Options::parameters_type,
44 typename Options::node_tag,
51 boost::geometry::dimension<Box>::value>::active_cell_iterator>>
54 std::map<std::pair<types::global_cell_index, types::global_cell_index>,
55 std::vector<types::global_cell_index>> &parent_to_children);
61 typename boost::geometry::index::detail::rtree::internal_node<
63 typename Options::parameters_type,
66 typename Options::node_tag>::type;
71 using Leaf =
typename boost::geometry::index::detail::rtree::leaf<
73 typename Options::parameters_type,
76 typename Options::node_tag>::type;
121 boost::geometry::dimension<Box>::value>::active_cell_iterator>>
133 std::map<std::pair<types::global_cell_index, types::global_cell_index>,
134 std::vector<types::global_cell_index>>
140 template <
typename Value,
146 const Translator &translator,
147 const unsigned int target_level,
149 boost::geometry::dimension<Box>::value>::active_cell_iterator>>
151 std::vector<types::global_cell_index> &n_nodes_per_level_,
152 std::map<std::pair<types::global_cell_index, types::global_cell_index>,
153 std::vector<types::global_cell_index>> &parent_to_children)
154 : translator(translator)
157 , target_level(target_level)
158 , agglomerates(agglomerates_)
159 , n_nodes_per_level(n_nodes_per_level_)
160 , parent_node_to_children_nodes(parent_to_children)
165 template <
typename Value,
174 using elements_type =
175 typename boost::geometry::index::detail::rtree::elements_type<
178 const elements_type &elements =
179 boost::geometry::index::detail::rtree::elements(node);
181 if (
level < target_level)
183 size_t level_backup =
level;
186 for (
typename elements_type::const_iterator it = elements.begin();
187 it != elements.end();
190 boost::geometry::index::detail::rtree::apply_visitor(*
this,
194 level = level_backup;
196 else if (
level == target_level)
198 const auto offset = agglomerates.size();
199 agglomerates.resize(offset + 1);
200 size_t level_backup =
level;
203 for (
const auto &entry : elements)
205 boost::geometry::index::detail::rtree::apply_visitor(
206 *
this, *entry.second);
211 n_nodes_per_level[target_level]++;
213 level = level_backup;
215 else if (
level > target_level)
220 size_t level_backup =
level;
225 for (
const auto &entry : elements)
227 boost::geometry::index::detail::rtree::apply_visitor(
228 *
this, *entry.second);
232 n_nodes_per_level[level_backup]++;
234 n_nodes_per_level[level_backup] - 1;
236 parent_node_to_children_nodes[{n_nodes_per_level[level_backup - 1],
238 .push_back(node_idx);
240 level = level_backup;
246 template <
typename Value,
255 using elements_type =
256 typename boost::geometry::index::detail::rtree::elements_type<
258 const elements_type &elements =
259 boost::geometry::index::detail::rtree::elements(leaf);
261 if (
level == target_level)
265 const auto offset = agglomerates.size();
266 agglomerates.resize(offset + 1);
268 for (
const auto &it : elements)
269 agglomerates[node_counter].push_back(it.second);
272 n_nodes_per_level[target_level]++;
276 for (
const auto &it : elements)
277 agglomerates[node_counter].push_back(it.second);
280 if (
level == target_level + 1)
282 const unsigned int node_idx = n_nodes_per_level[
level];
284 parent_node_to_children_nodes[{n_nodes_per_level[
level - 1],
286 .push_back(node_idx);
287 n_nodes_per_level[
level]++;
299 template <
int dim,
typename RtreeType>
304 friend class ::AgglomerationHandler;
318 std::vector<typename Triangulation<dim>::active_cell_iterator>> &
337 inline const std::map<
338 std::pair<types::global_cell_index, types::global_cell_index>,
339 std::vector<types::global_cell_index>> &
357 std::vector<std::vector<typename Triangulation<dim>::active_cell_iterator>>
370 std::map<std::pair<types::global_cell_index, types::global_cell_index>,
371 std::vector<types::global_cell_index>>
377 template <
int dim,
typename RtreeType>
379 const RtreeType &tree,
380 const unsigned int extraction_level_)
381 : extraction_level(extraction_level_)
383 rtree =
const_cast<RtreeType *
>(&tree);
384 Assert(n_levels(*
rtree), ExcMessage(
"At least two levels are needed."));
389 template <
int dim,
typename RtreeType>
391 std::vector<typename Triangulation<dim>::active_cell_iterator>> &
395 ExcInternalError(
"You are trying to extract level " +
396 std::to_string(extraction_level) +
397 " of the tree, but it only has a total of " +
398 std::to_string(n_levels(*rtree)) +
401 boost::geometry::index::detail::rtree::utilities::view<RtreeType>;
402 RtreeView rtv(*rtree);
404 n_nodes_per_level.resize(rtv.depth() +
407 if (rtv.depth() == 0)
411 agglomerates_on_level.resize(1);
412 agglomerates_on_level[0].resize(1);
416 const unsigned int target_level =
420 typename RtreeView::options_type,
421 typename RtreeView::translator_type,
422 typename RtreeView::box_type,
423 typename RtreeView::allocators_type>
424 extractor_visitor(rtv.translator(),
426 agglomerates_on_level,
428 parent_node_to_children_nodes);
431 rtv.apply_visitor(extractor_visitor);
433 return agglomerates_on_level;
441 template <
int dim,
typename RtreeType>
445 return n_levels(*rtree);
450 template <
int dim,
typename RtreeType>
453 const unsigned int level)
const
455 return n_nodes_per_level[
level];
460 template <
int dim,
typename RtreeType>
461 inline const std::map<
462 std::pair<types::global_cell_index, types::global_cell_index>,
463 std::vector<types::global_cell_index>> &
466 Assert(parent_node_to_children_nodes.size(),
468 "The hierarchy has not been computed. Did you forget to call"
469 " extract_agglomerates() first?"));
470 return parent_node_to_children_nodes;
std::vector< std::vector< typename Triangulation< dim >::active_cell_iterator > > agglomerates_on_level
const unsigned int extraction_level
const std::map< std::pair< types::global_cell_index, types::global_cell_index >, std::vector< types::global_cell_index > > & get_hierarchy() const
std::map< std::pair< types::global_cell_index, types::global_cell_index >, std::vector< types::global_cell_index > > parent_node_to_children_nodes
types::global_cell_index get_n_nodes_per_level(const unsigned int level) const
unsigned int get_n_levels() const
CellsAgglomerator(const RtreeType &rtree, const unsigned int extraction_level)
const std::vector< std::vector< typename Triangulation< dim >::active_cell_iterator > > & extract_agglomerates()
std::vector< types::global_cell_index > n_nodes_per_level
#define Assert(cond, exc)
#define AssertThrow(cond, exc)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
unsigned int global_cell_index
typename boost::geometry::index::detail::rtree::internal_node< Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag >::type InternalNode
std::map< std::pair< types::global_cell_index, types::global_cell_index >, std::vector< types::global_cell_index > > & parent_node_to_children_nodes
const size_t target_level
const Translator & translator
void operator()(const InternalNode &node)
std::vector< types::global_cell_index > & n_nodes_per_level
std::vector< std::vector< typename Triangulation< boost::geometry::dimension< Box >::value >::active_cell_iterator > > & agglomerates
Rtree_visitor(const Translator &translator, const unsigned int target_level, std::vector< std::vector< typename Triangulation< boost::geometry::dimension< Box >::value >::active_cell_iterator > > &agglomerates_, std::vector< types::global_cell_index > &n_nodes_per_level, std::map< std::pair< types::global_cell_index, types::global_cell_index >, std::vector< types::global_cell_index > > &parent_to_children)
typename boost::geometry::index::detail::rtree::leaf< Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag >::type Leaf