8#ifndef GRIDTREEPOLICY_HH_
9#define GRIDTREEPOLICY_HH_
14#include <dune/common/fvector.hh>
22 template <
class Scalar,
int dim>
24 SearchDetail(Scalar
const f, Scalar
const l, Scalar
const s,
Direction const dir) : first(f), last(l), split(s), delta(last-split), direction(dir)
27 template <
class BoundingBoxType>
30 split(0.5*(
boundingBox.coord[dir].first+
boundingBox.coord[dir].second)), delta(split-first), direction(dir)
33 Scalar
const first, last;
42 template <
class Scalar,
int dim,
class BoundingBoxType>
43 BoundingBoxType createBoundingBox(BoundingBoxType
const&
boundingBox, SearchDetail<Scalar,dim>
const& searchDetail,
bool const lower)
45 BoundingBoxType newBoundingBox;
46 if(lower) newBoundingBox.coord[searchDetail.direction].first =
boundingBox.coord[searchDetail.direction].first,
47 newBoundingBox.coord[searchDetail.direction].second = searchDetail.split;
48 else newBoundingBox.coord[searchDetail.direction].first = searchDetail.split,
49 newBoundingBox.coord[searchDetail.direction].second =
boundingBox.coord[searchDetail.direction].second;
51 size_t dir = (1+searchDetail.direction)%dim;
52 newBoundingBox.coord[dir].first =
boundingBox.coord[dir].first, newBoundingBox.coord[dir].second =
boundingBox.coord[dir].second;
53 dir = (2+searchDetail.direction)%dim;
54 newBoundingBox.coord[dir].first =
boundingBox.coord[dir].first, newBoundingBox.coord[dir].second =
boundingBox.coord[dir].second;
55 return newBoundingBox;
59 template <
class Cell,
class Partition>
60 void addCell(
Cell const& cell, SearchDetail<typename Cell::Geometry::ctype, Cell::dimension>
const searchDetail, Partition &partition)
62 bool left =
false, right =
false;
64 for(
int cornerId=0; cornerId<cell.geometry().corners(); ++cornerId)
65 (cell.geometry().corner(cornerId)[searchDetail.direction] < (searchDetail.split)) ? left = true : right =
true;
67 if(left) partition.first.push_back(&cell);
68 if(right) partition.second.push_back(&cell);
71 template <
class Partition>
72 void swapPartition(Partition &p1, Partition &p2)
74 std::swap(p1.first,p2.first);
75 std::swap(p1.second,p2.second);
78 template <
class Partition>
79 void clear(Partition &partition)
81 partition.first.clear();
82 partition.second.clear();
86 template <
class Partition>
87 size_t getDifference(Partition
const& partition)
89 return (
size_t) std::abs((
int)partition.first.size()-(
int)partition.second.size());
93 template <
class Partition,
class Scalar>
94 bool checkPartition(Partition
const& partition, Scalar
const difference)
96 return (getDifference(partition) < difference);
108template <
class Cell,
class BoundingBox>
110 static int const dim = Cell::dimension;
111 typedef typename Cell::Geometry::ctype
Scalar;
113 typedef std::pair<std::vector<GPC const*>, std::vector<GPC const*> >
Partition;
116 template <
class TreeNode>
121 Scalar const MINIMAL_DELTA = 0.01;
122 size_t const numberOfCells = cells_.size();
123 size_t const tolerance =
std::max((
size_t)std::fabs(numberOfCells*reltol), (
size_t)25);
124 SearchDetail<Scalar,dim> searchDetail(
boundingBox, dir);
128 size_t difference = getDifference(partition);
129 while(difference > tolerance && searchDetail.delta > MINIMAL_DELTA)
131 searchDetail.delta *= 0.5;
132 searchDetail.split += searchDetail.delta;
133 splitCells(searchDetail, cells_, tmpPartition);
134 if(checkPartition(tmpPartition, difference))
136 swapPartition(partition,tmpPartition);
137 difference = getDifference(partition);
143 searchDetail.split -= 2.*searchDetail.delta;
144 splitCells(searchDetail, cells_, tmpPartition);
145 if(checkPartition(tmpPartition, difference))
147 swapPartition(partition,tmpPartition);
148 difference = getDifference(partition);
150 else searchDetail.split += searchDetail.delta;
156 children.first =
new TreeNode(createBoundingBox(
boundingBox,searchDetail,
true), partition.first, changeDirection(searchDetail.direction), reltol, height+1, maxHeight);
157 children.second =
new TreeNode(createBoundingBox(
boundingBox,searchDetail,
false), partition.second, changeDirection(searchDetail.direction), reltol, height+1, maxHeight);
160 void splitCells(SearchDetail<Scalar,dim>
const& searchDetail, std::vector<GPC const*>
const& cells_,
Partition &partition)
const
162 typename std::vector<GPC const*>::const_iterator ci=cells_.begin(), cend=cells_.end();
163 for(;ci!=cend; ++ci) addCell(**ci, searchDetail, partition);
A wrapper class for access to protected constructors.
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
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.
The default splitting policy.
void createChildren(BoundingBox const &boundingBox, std::vector< GPC const * > const &cells_, Direction dir, std::pair< TreeNode *, TreeNode * > &children, Scalar const reltol, Scalar const height, Scalar const maxHeight)
GetProtectedConstructor< Cell > GPC
void splitCells(SearchDetail< Scalar, dim > const &searchDetail, std::vector< GPC const * > const &cells_, Partition &partition) const
Cell::Geometry::ctype Scalar
std::pair< std::vector< GPC const * >, std::vector< GPC const * > > Partition