search_kdtree.h
Go to the documentation of this file.
1 /*
2 This file is part of the Ristra portage project.
3 Please see the license file at the root of this repository, or at:
4  https://github.com/laristra/portage/blob/master/LICENSE
5 */
6 
7 #ifndef PORTAGE_SEARCH_SEARCH_KDTREE_H_
8 #define PORTAGE_SEARCH_SEARCH_KDTREE_H_
9 
10 #include <vector>
11 #include <memory>
12 
13 // portage includes
16 #include "portage/search/kdtree.h"
17 #include "wonton/support/Point.h"
18 
19 namespace Portage {
20 
31 template <int D, Entity_kind on_what,
32  typename SourceMeshType, typename TargetMeshType>
33 class SearchKDTree {
34  public:
35 
37  SearchKDTree() = delete;
38 
49  SearchKDTree(const SourceMeshType & source_mesh,
50  const TargetMeshType & target_mesh)
51  : sourceMesh_(source_mesh), targetMesh_(target_mesh) {}
52 
63  std::vector<int> operator() (const int entityId) const {
64  std::vector<int> candidates;
65  std::cerr << "Search not implemented for generic entity kind" << std::endl;
66  return candidates;
67  }
68 
69  private:
70  const SourceMeshType & sourceMesh_;
71  const TargetMeshType & targetMesh_;
72  std::shared_ptr<Portage::KDTree<D>> tree_;
73 }; // class SearchKDTree
74 
75 
76 
77 
79 
88 template <int D, typename SourceMeshType, typename TargetMeshType>
89 class SearchKDTree<D, Entity_kind::CELL, SourceMeshType, TargetMeshType> {
90  public:
91 
93  SearchKDTree() = delete;
94 
104  SearchKDTree(const SourceMeshType & source_mesh,
105  const TargetMeshType & target_mesh)
106  : sourceMesh_(source_mesh), targetMesh_(target_mesh) {
107 
108  const int numCells = sourceMesh_.num_owned_cells();
109  std::vector<Portage::IsotheticBBox<D>> bboxes;
110  bboxes.reserve(numCells);
111 
112  // find bounding boxes for all cells
113  for (int c = 0; c < numCells; ++c) {
114  std::vector<Wonton::Point<D>> cell_coord;
115  sourceMesh_.cell_get_coordinates(c, &cell_coord);
117  for (const auto& cc : cell_coord) {
118  bb.add(cc);
119  }
120  bboxes.emplace_back(bb);
121  }
122 
123  // create the k-d tree
124  tree_ = std::make_shared<Portage::KDTree<D>>(*Portage::KDTreeCreate(bboxes));
125 
126  } // SearchKDTree::SearchKDTree
127 
136  std::vector<int> operator() (const int cellId) const {
137  // find bounding box for target cell
138  std::vector<Wonton::Point<D>> cell_coord;
139  targetMesh_.cell_get_coordinates(cellId, &cell_coord);
141  for (const auto& cc : cell_coord)
142  bb.add(cc);
143 
144  // now see which sourceMesh cells have bounding boxes overlapping
145  // with target cell, using the kdtree - since Portage::Intersect does
146  // not take a shared_ptr, we have have to dereference and take
147  // address of tree_
148  std::vector<int> lcandidates;
149  Portage::Intersect(bb, &(*tree_), lcandidates);
150 
151  std::vector<int> candidates(lcandidates.begin(), lcandidates.end());
152  return candidates;
153  } // SearchKDTree::operator()
154 
155  private:
156  const SourceMeshType & sourceMesh_;
157  const TargetMeshType & targetMesh_;
158  std::shared_ptr<Portage::KDTree<D>> tree_;
159 }; // class SearchKDTree (CELL specialization)
160 
161 
162 
163 
165 
175 template <int D, typename SourceMeshType, typename TargetMeshType>
176 class SearchKDTree<D, Entity_kind::NODE, SourceMeshType, TargetMeshType> {
177  public:
178 
180  SearchKDTree() = delete;
181 
192  SearchKDTree(const SourceMeshType & source_mesh,
193  const TargetMeshType & target_mesh)
194  : sourceMesh_(source_mesh), targetMesh_(target_mesh) {
195 
196  const int numNodes = sourceMesh_.num_owned_nodes();
197  std::vector<Portage::IsotheticBBox<D>> bboxes;
198  bboxes.reserve(numNodes);
199 
200  // find bounding boxes for all cells
201  for (int n = 0; n < numNodes; ++n) {
202  std::vector<Wonton::Point<D>> dual_cell_coord;
203  sourceMesh_.dual_cell_get_coordinates(n, &dual_cell_coord);
205  for (const auto& cc : dual_cell_coord)
206  bb.add(cc);
207  bboxes.emplace_back(bb);
208  }
209 
210  // create the k-d tree
211  tree_ = std::make_shared<Portage::KDTree<D>>(*Portage::KDTreeCreate(bboxes));
212 
213  } // SearchKDTree::SearchKDTree
214 
216  // ~SearchKDTree() { if (tree_) delete tree_; }
217 
228  std::vector<int> operator() (const int nodeId) const {
229  // find bounding box for dual cell of target node
230  std::vector<Wonton::Point<D>> dual_cell_coord;
231  targetMesh_.dual_cell_get_coordinates(nodeId, &dual_cell_coord);
233  for (const auto& cc : dual_cell_coord)
234  bb.add(cc);
235 
236  // now see which sourceMesh dual cells have bounding boxes
237  // overlapping with dual cell of targetMesh, using the kdtree -
238  // since Portage::Intersect does not take a shared_ptr, we have have to
239  // dereference and take address of tree_
240  std::vector<int> lcandidates;
241  Portage::Intersect(bb, &(*tree_), lcandidates);
242 
243  std::vector<int> candidates(lcandidates.begin(), lcandidates.end());
244  return candidates;
245  } // SearchKDTree::operator()
246 
247  private:
248  const SourceMeshType & sourceMesh_;
249  const TargetMeshType & targetMesh_;
250  std::shared_ptr<Portage::KDTree<D>> tree_;
251 }; // class SearchKDTree (NODE specialization)
252 
253 } // namespace Portage
254 
255 #endif // PORTAGE_SEARCH_SEARCH_KDTREE_H_
A k-d tree search class that allows us to search for control volumes of entities from one mesh (sourc...
Definition: search_kdtree.h:33
SearchKDTree(const SourceMeshType &source_mesh, const TargetMeshType &target_mesh)
Builds the k-d tree for searching for intersection candidates.
Definition: search_kdtree.h:192
SearchKDTree(const SourceMeshType &source_mesh, const TargetMeshType &target_mesh)
Builds the k-d tree for searching for intersection candidates.
Definition: search_kdtree.h:104
SearchKDTree()=delete
Default constructor (disabled)
void add(const Point< D > &p)
Update the bounding box by adding an additional Point.
Definition: BoundBox.h:59
Definition: coredriver.h:42
std::vector< int > operator()(const int entityId) const
Find the source mesh entities whose control volumes potentially overlap control volumes of a given ta...
Definition: search_kdtree.h:63
An isothetic (axis-aligned) N-dimensional bounding box.
Definition: BoundBox.h:46
SearchKDTree(const SourceMeshType &source_mesh, const TargetMeshType &target_mesh)
Builds the k-d tree for searching for intersection candidates.
Definition: search_kdtree.h:49
KDTree< D > * KDTreeCreate(const std::vector< IsotheticBBox< D > > &bbox)
Definition: kdtree.h:189
void Intersect(const IsotheticBBox< D > &box, const KDTree< D > *kdtree, std::vector< int > &pfound)
Definition: kdtree.h:439