KASKADE 7 development version
gridtree.hh
Go to the documentation of this file.
1/*
2 * gridtree.hh
3 *
4 * Created on: 16.12.2011
5 * Author: Lars
6 */
7
8#ifndef GRIDTREE_HH_
9#define GRIDTREE_HH_
10
11#include <algorithm>
12#include <utility>
13#include <vector>
14#include "tools/linalg/scalarproducts.hh"
15#include "gridtreepolicy.hh"
16
17
18
20
27template <class GRID, template <class,int> class BoundingBoxType=GeometricObject::BoundingBox, int lowerSplittingBorder=1000, template <class,class> class SplittingPolicy=BisectionPolicy>
28class GridTree {
29private:
31 template <class Cell, template <class,int> class LocalBoundingBoxType, int localLowerSplittingBorder, template <class,class> class LocalSplittingPolicy=BisectionPolicy>
32 class GridTreeNode : public LocalSplittingPolicy<Cell,LocalBoundingBoxType<typename Cell::Geometry::ctype, Cell::dimension> >
33 {
34 public:
35 static int const dim = Cell::dimension;
36 typedef typename Cell::Geometry::ctype Scalar;
37 typedef typename Cell::Geometry::GlobalCoordinate GlobalCoordinate;
39 typedef GridTreeNode<Cell,LocalBoundingBoxType,localLowerSplittingBorder,LocalSplittingPolicy> This;
40 typedef LocalBoundingBoxType<Scalar,dim> BoundingBox;
41
42 GridTreeNode(BoundingBox boundingBox_, std::vector<GPC const*> const& cells_, Direction dir, Scalar const reltol, Scalar const height, Scalar const maxHeight, bool isRootNode=false)
43 : boundingBox(boundingBox_)
44 {
45 initialize(cells_, dir, reltol, height, maxHeight);
46 if(isRootNode) cells = cells_;
48 isRoot=isRootNode;
49 }
50
51 GridTreeNode(This const& node)
52 : cells(node.cells), boundingBox(node.boundingBox), children(node.children)
53 {}
54
55 ~GridTreeNode()
56 {
57 if(children.first) delete children.first;
58 if(children.second) delete children.second;
59 if(isRoot){
60 typename std::vector<GPC const*>::iterator iter = cells.begin(), iend = cells.end();
61 for(;iter!=iend; ++iter) delete *iter;
62 }
63 }
64
65 template <class Grid, class Scalar>
66 static This createRootNode(Grid const& grid, Scalar const maxH, Scalar const reltol)
67 {
68 std::vector<GPC const*> cells_(grid.size(0));
69 typedef typename Grid::LeafGridView::template Codim<0>::Iterator CellIterator;
70 CellIterator ci = grid.leafGridView().template begin<0>(), cend = grid.leafGridView().template end<0>();
71 BoundingBox boundingBox(ci->geometry().corner(0));
72
73 int cellIndex = 0, corners;
74 for(;ci!=cend; ++ci)
75 {
76 (cells_[cellIndex]) = new GPC(*ci);
77 ++cellIndex;
78 corners = ci->geometry().corners();
79 for(int cornerId=0; cornerId<corners; ++cornerId) boundingBox.update(ci->geometry().corner(cornerId));
80 }
81 /*std::for_each(grid.leafGridView().begin<0>(), grid.leafGridView.end<0>(), [](Cell const &cell)
82 {
83 cells_[cellIndex] = &cell;
84 ++cellIndex;
85 int corners = cell.geometry().corners();
86 for(int cornerId=0; cornerId<corners; +cornerId) boundingBox.update(cell.geometry().corner(cornerId));
87 });*/
89 return This(boundingBox, cells_, X, reltol, 0, maxH, true);
90 }
91
92 bool checkInside(GlobalCoordinate const& x) const
93 {
94 if(!boundingBox.contains(x)) return false;
95
96 if(children.first && children.second) return ( children.first->checkInside(x) || children.second->checkInside(x) );
97
98 typename std::vector<GPC const*>::const_iterator iter=cells.begin(), iend=cells.end();
99 const Dune::GenericReferenceElement<double,3> *simplex_ptr = &Dune::GenericReferenceElements<double,3>::simplex();
100 for(;iter!=iend; ++iter)
101 {
102 if(simplex_ptr->checkInside((*iter)->geometry().local(x))) return true;
103 }
104 return false;
105 }
106
107 Cell const* getCell(GlobalCoordinate const& x) const
108 {
109 if(!boundingBox.contains(x)) return 0;
110 if(children.first && children.second) return (children.first->getCell(x)==0) ? children.second->getCell(x) : children.first->getCell(x);
111 typename std::vector<GPC const*>::const_iterator iter=cells.begin(), iend=cells.end();
112
113 for(;iter!=iend; ++iter) if((*iter)->checkInside((*iter)->geometry().local(x))) return *iter;
114 //else std::for_each(cells.begin(), cells.end(), [](Cell const* cell){ if(cell->checkInside(cell->geometry().local(x))) return cell; });
115 return 0;
116 }
117
118 void print(std::ostream &stream, int const level) const
119 {
120 using std::endl;
121 stream << endl;
122 stream << "Level: " << level << endl;
123 stream << boundingBox;
124 stream << "Number of cells: " << cells.size() << endl;
125 stream << "Has first child: " << (children.first!=0) << endl;
126 stream << "Has second child: " << (children.second!=0) << endl;
127 stream << endl;
128 }
129
130 void print(std::ostream &stream, int const level, int const printLevel ) const
131 {
132 if(level==printLevel){
133 print(stream, level);
134 return;
135 }
136 if(children.first) children.first->print(stream,level+1,printLevel);
137 if(children.second) children.second->print(stream,level+1,printLevel);
138 }
139
140 int getTreeHeight() const
141 {
142 return (children.first && children.second) ? 1+std::max(children.first->getTreeHeight(),children.second->getTreeHeight()) : 0;
143 }
144
145 std::vector<GPC const*> getCellsInBall(Ball<Scalar,dim> const& ball) const
146 {
147 if(GeometricObject::intersects<LinAlg::EuclideanNorm>(ball, boundingBox))
148 {
149 // if children exist delegate to them
150 if(children.first && children.second)
151 {
152 std::vector<GPC const*> result = children.first->getCellsInBall(ball),
153 tmp = children.second->getCellsInBall(ball);
154 result.insert(result.begin(), tmp.begin(), tmp.end());
155 return result;
156 }
157 else // else check list of cells
158 {
159 typename std::vector<GPC const*>::const_iterator iter=cells.begin(), iend=cells.end();
160
161 }
162 } // end if -> ball lies completely outside the bounding box
163 // else
164 return std::vector<GPC const*>();
165 }
166
167 std::vector<GPC const*> cells;
169 std::pair<This*,This*> children ;
170 private:
171 bool isRoot;
173 GridTreeNode();
175 This operator=(This const&);
176
177 void initialize(std::vector<GPC const*> const& cells_, Direction dir, Scalar const reltol, Scalar const height, Scalar const maxHeight)
178 {
179 if(cells_.size() > localLowerSplittingBorder && (height<maxHeight)) createChildren(boundingBox, cells_, changeDirection(dir), children, reltol, height, maxHeight);
180 else
181 {
182 children.first=0;
183 children.second=0;
184 cells = cells_;
185 }
186 }
187 };
188
189 typedef GridTreeNode<typename GRID::LeafGridView::template Codim<0>::Entity,BoundingBoxType,lowerSplittingBorder,SplittingPolicy> NodeType;
190
191public:
192 typedef GRID Grid;
193 typedef typename Grid::LeafGridView::template Codim<0>::Entity Cell;
194 typedef typename Cell::Geometry::ctype Scalar;
195 typedef typename Cell::Geometry::GlobalCoordinate GlobalCoordinate;
196 typedef BoundingBoxType<Scalar,Grid::dimension> BoundingBox;
197
199
204 GridTree(Grid const& grid, Scalar const maxHeight, Scalar const reltol = 0.2 ) : rootNode(NodeType::createRootNode(grid, maxHeight, reltol))
205 {}
206
209 {}
210
212
214 bool contains(GlobalCoordinate const& x) const{ return rootNode.checkInside(x); }
215
220 Cell const* getCell(GlobalCoordinate const& x) const{ return rootNode.getCell(x); }
221
222 int height() const
223 {
224 return rootNode.getTreeHeight();
225 }
226
227 void print() const
228 {
229 int h = height();
230 for(int level=0; level<h; ++level)
231 rootNode.print(std::cout,0,level);
232 }
233
235 {
236 return rootNode.boundingBox;
237 }
238
239// @TODO
240// std::vector<Cell const*> getCellsInBall(Ball<Scalar,Grid::dimension> &ball) const
241// {
242// return rootNode.getCellsInBall(ball);
243// }
244
245private:
246 NodeType const rootNode;
247};
248
249#endif /* GRIDTREE_HH_ */
A wrapper class for access to protected constructors.
Stores a grid in a tree structure, allowing fast searches.
Definition: gridtree.hh:28
GRID Grid
Definition: gridtree.hh:192
void print() const
Definition: gridtree.hh:227
GridTree(GridTree< Grid, BoundingBoxType, lowerSplittingBorder, SplittingPolicy > const &gt)
Copy constructor.
Definition: gridtree.hh:208
int height() const
Definition: gridtree.hh:222
BoundingBoxType< Scalar, Grid::dimension > BoundingBox
Definition: gridtree.hh:196
Grid::LeafGridView::template Codim< 0 >::Entity Cell
Definition: gridtree.hh:193
GridTree(Grid const &grid, Scalar const maxHeight, Scalar const reltol=0.2)
Constructor.
Definition: gridtree.hh:204
BoundingBox const & getBoundingBox() const
Definition: gridtree.hh:234
Cell::Geometry::ctype Scalar
Definition: gridtree.hh:194
Cell const * getCell(GlobalCoordinate const &x) const
Definition: gridtree.hh:220
bool contains(GlobalCoordinate const &x) const
true if tree contains a cell containing x, else false
Definition: gridtree.hh:214
~GridTree()
Definition: gridtree.hh:211
Cell::Geometry::GlobalCoordinate GlobalCoordinate
Definition: gridtree.hh:195
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
std::pair< Dune::FieldVector< double, Cell::dimension >, Dune::FieldVector< double, Cell::dimension > > boundingBox(Cell const &cell)
Computes the bounding box of a cell.
Definition: fixdune.hh:766
LocalCoordinate::field_type checkInside(Dune::GeometryType const &gt, LocalCoordinate const &x)
Checks whether a point is inside or outside the reference element, and how much.
Definition: fixdune.hh:741
The default splitting policy.