14#include "tools/linalg/scalarproducts.hh"
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> >
35 static int const dim = Cell::dimension;
36 typedef typename Cell::Geometry::ctype
Scalar;
39 typedef GridTreeNode<Cell,LocalBoundingBoxType,localLowerSplittingBorder,LocalSplittingPolicy> This;
40 typedef LocalBoundingBoxType<Scalar,dim>
BoundingBox;
45 initialize(cells_, dir, reltol,
height, maxHeight);
46 if(isRootNode) cells = cells_;
51 GridTreeNode(This
const& node)
52 : cells(node.cells),
boundingBox(node.boundingBox), children(node.children)
57 if(children.first)
delete children.first;
58 if(children.second)
delete children.second;
60 typename std::vector<GPC const*>::iterator iter = cells.begin(), iend = cells.end();
61 for(;iter!=iend; ++iter)
delete *iter;
65 template <
class Gr
id,
class Scalar>
66 static This createRootNode(
Grid const& grid,
Scalar const maxH,
Scalar const reltol)
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>();
73 int cellIndex = 0, corners;
76 (cells_[cellIndex]) =
new GPC(*ci);
78 corners = ci->geometry().corners();
79 for(
int cornerId=0; cornerId<corners; ++cornerId)
boundingBox.update(ci->geometry().corner(cornerId));
89 return This(
boundingBox, cells_,
X, reltol, 0, maxH,
true);
96 if(children.first && children.second)
return ( children.first->checkInside(x) || children.second->checkInside(x) );
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)
102 if(simplex_ptr->checkInside((*iter)->geometry().local(x)))
return true;
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();
113 for(;iter!=iend; ++iter)
if((*iter)->checkInside((*iter)->geometry().local(x)))
return *iter;
118 void print(std::ostream &stream,
int const level)
const
122 stream <<
"Level: " << level << endl;
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;
130 void print(std::ostream &stream,
int const level,
int const printLevel )
const
132 if(level==printLevel){
133 print(stream, level);
136 if(children.first) children.first->print(stream,level+1,printLevel);
137 if(children.second) children.second->print(stream,level+1,printLevel);
140 int getTreeHeight()
const
142 return (children.first && children.second) ? 1+
std::max(children.first->getTreeHeight(),children.second->getTreeHeight()) : 0;
147 if(GeometricObject::intersects<LinAlg::EuclideanNorm>(ball,
boundingBox))
150 if(children.first && children.second)
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());
159 typename std::vector<GPC const*>::const_iterator iter=cells.begin(), iend=cells.end();
164 return std::vector<GPC const*>();
167 std::vector<GPC const*> cells;
169 std::pair<This*,This*> children ;
175 This operator=(This
const&);
179 if(cells_.size() > localLowerSplittingBorder && (
height<maxHeight)) createChildren(
boundingBox, cells_, changeDirection(dir), children, reltol,
height, maxHeight);
189 typedef GridTreeNode<typename GRID::LeafGridView::template Codim<0>::Entity,BoundingBoxType,lowerSplittingBorder,SplittingPolicy> NodeType;
193 typedef typename Grid::LeafGridView::template Codim<0>::Entity
Cell;
194 typedef typename Cell::Geometry::ctype
Scalar;
204 GridTree(
Grid const& grid,
Scalar const maxHeight,
Scalar const reltol = 0.2 ) : rootNode(NodeType::createRootNode(grid, maxHeight, reltol))
224 return rootNode.getTreeHeight();
230 for(
int level=0; level<h; ++level)
231 rootNode.print(std::cout,0,level);
236 return rootNode.boundingBox;
246 NodeType
const rootNode;
A wrapper class for access to protected constructors.
Stores a grid in a tree structure, allowing fast searches.
GridTree(GridTree< Grid, BoundingBoxType, lowerSplittingBorder, SplittingPolicy > const >)
Copy constructor.
BoundingBoxType< Scalar, Grid::dimension > BoundingBox
Grid::LeafGridView::template Codim< 0 >::Entity Cell
GridTree(Grid const &grid, Scalar const maxHeight, Scalar const reltol=0.2)
Constructor.
BoundingBox const & getBoundingBox() const
Cell::Geometry::ctype Scalar
Cell const * getCell(GlobalCoordinate const &x) const
bool contains(GlobalCoordinate const &x) const
true if tree contains a cell containing x, else false
Cell::Geometry::GlobalCoordinate GlobalCoordinate
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
std::pair< Dune::FieldVector< double, Cell::dimension >, Dune::FieldVector< double, Cell::dimension > > boundingBox(Cell const &cell)
Computes the bounding box of a cell.
LocalCoordinate::field_type checkInside(Dune::GeometryType const >, LocalCoordinate const &x)
Checks whether a point is inside or outside the reference element, and how much.
The default splitting policy.