dune-spgrid  2.7
mesh.hh
Go to the documentation of this file.
1 #ifndef DUNE_SPGRID_MESH_HH
2 #define DUNE_SPGRID_MESH_HH
3 
4 #include <array>
5 #include <type_traits>
6 
8 
12 
13 namespace Dune
14 {
15 
16  // SPMesh
17  // ------
18 
19  template< int dim >
20  class SPMesh
21  {
22  typedef SPMesh< dim > This;
23 
24  public:
25  static const int dimension = dim;
26 
28 
29  explicit SPMesh ( const MultiIndex &width );
30 
31  SPMesh ( const MultiIndex &begin, const MultiIndex &end );
32 
33  const This &operator+= ( const MultiIndex &shift );
34  const This &operator-= ( const MultiIndex &shift );
35 
36  const MultiIndex &begin () const { return bound( 0 ); }
37  const MultiIndex &end () const { return bound( 1 ); }
38 
39  const MultiIndex &bound ( int b ) const { assert( (b == 0) || (b == 1) ); return bound_[ b ]; }
40 
41  int bound ( const SPNormalId< dimension > &id ) const { return bound( id.face() & 1 )[ id.axis() ]; }
42 
43  bool empty () const;
44 
45  template< class Refinement >
46  typename std::enable_if< Refinement::dimension == dim, SPMesh< dim > >::type
47  refine ( const Refinement &refinement ) const;
48 
49  This grow ( int size ) const;
50  This grow ( const MultiIndex &size ) const;
51 
52  This intersect ( const This &other ) const;
53 
54  std::pair< This, This > split ( const int dir, const int leftWeight, const int rightWeight ) const;
55 
56  int volume () const;
57 
58  MultiIndex width () const;
59  int width ( const int i ) const;
60 
61  static This unitMesh ();
62 
63  private:
64  std::array< MultiIndex, 2 > bound_;
65  };
66 
67 
68 
69  // Implementation of SPMesh
70  // ------------------------
71 
72  template< int dim >
74  {
75  bound_[ 0 ] = MultiIndex::zero();
76  bound_[ 1 ] = width;
77  }
78 
79 
80  template< int dim >
81  SPMesh< dim >::SPMesh ( const MultiIndex &begin, const MultiIndex &end )
82  {
83  bound_[ 0 ] = begin;
84  bound_[ 1 ] = end;
85  }
86 
87 
88  template< int dim >
89  inline const typename SPMesh< dim >::This &
91  {
92  for( int b = 0; b < 2; ++b )
93  bound_[ b ] += shift;
94  return *this;
95  }
96 
97 
98  template< int dim >
99  inline const typename SPMesh< dim >::This &
101  {
102  for( int b = 0; b < 2; ++b )
103  bound_[ b ] -= shift;
104  return *this;
105  }
106 
107 
108  template< int dim >
109  inline bool SPMesh< dim >::empty () const
110  {
111  bool empty = false;
112  for( int i = 0; i < dimension; ++i )
113  empty |= (end()[ i ] < begin()[ i ]);
114  return empty;
115  }
116 
117 
118  template< int dim >
119  template< class Refinement >
120  inline typename std::enable_if< Refinement::dimension == dim, SPMesh< dim > >::type
121  SPMesh< dim >::refine ( const Refinement &refinement ) const
122  {
123  MultiIndex childBegin, childEnd;
124  for( int i = 0; i < dimension; ++i )
125  {
126  const int factor = refinement.factor( i );
127  childBegin[ i ] = factor * begin()[ i ];
128  childEnd[ i ] = factor * end()[ i ];
129  }
130  return This( childBegin, childEnd );
131  }
132 
133 
134  template< int dim >
135  inline typename SPMesh< dim >::This SPMesh< dim >::grow ( int size ) const
136  {
137  MultiIndex begin, end;
138  for( int i = 0; i < dim; ++i )
139  {
140  begin[ i ] = begin()[ i ] - size;
141  end[ i ] = end()[ i ] + size;
142  }
143  return This( begin, end );
144  }
145 
146 
147  template< int dim >
148  inline typename SPMesh< dim >::This
149  SPMesh< dim >::grow ( const MultiIndex &size ) const
150  {
151  return This( begin() - size, end() + size );
152  }
153 
154 
155  template< int dim >
156  inline typename SPMesh< dim >::This
157  SPMesh< dim >::intersect ( const This &other ) const
158  {
159  return This( std::max( begin(), other.begin() ), std::min( end(), other.end() ) );
160  }
161 
162 
163  template< int dim >
164  inline std::pair< typename SPMesh< dim >::This, typename SPMesh< dim >::This >
165  SPMesh< dim >::split ( const int dir, const int leftFraction, const int rightFraction ) const
166  {
167  const MultiIndex &lbegin = begin();
168  const MultiIndex &rend = end();
169 
170  assert( (dir >= 0) && (dir < dimension) );
171  const int width = (rend[ dir ] - lbegin[ dir ]);
172  const int leftWidth = (leftFraction * width) / (leftFraction + rightFraction);
173 
174  MultiIndex lend = rend;
175  MultiIndex rbegin = lbegin;
176  rbegin[ dir ] = lend[ dir ] = lbegin[ dir ] + leftWidth;
177 
178  return std::make_pair( This( lbegin, lend ), This( rbegin, rend ) );
179  }
180 
181 
182  template< int dim >
183  inline int SPMesh< dim >::volume () const
184  {
185  const MultiIndex &w = width();
186  int volume = 1;
187  for( int i = 0; i < dimension; ++i )
188  volume *= w[ i ];
189  return volume;
190  }
191 
192 
193  template< int dim >
195  {
196  MultiIndex w;
197  for( int i = 0; i < dimension; ++i )
198  w[ i ] = width( i );
199  return w;
200  }
201 
202 
203  template< int dim >
204  inline int SPMesh< dim >::width ( const int i ) const
205  {
206  //return std::max( end()[ i ] - begin()[ i ], 0 );
207  return end()[ i ] - begin()[ i ];
208  }
209 
210 
211  template< int dim >
212  inline typename SPMesh< dim >::This
214  {
215  MultiIndex w;
216  for( int i = 0; i < dimension; ++i )
217  w[ i ] = 1;
218  return This( w );
219  }
220 
221 
222 
223  // Auxilliary functions for SPMesh
224  // -------------------------------
225 
226  template< class char_type, class traits, int dim >
227  inline std::basic_ostream< char_type, traits > &
228  operator<< ( std::basic_ostream< char_type, traits > &out, const SPMesh< dim > &mesh )
229  {
230  return out << "[ " << mesh.begin() << ", " << mesh.end() << " [";
231  }
232 
233 
234  template< int dim >
235  inline SPMesh< dim >
236  operator+ ( const SPMesh< dim > &mesh, const SPMultiIndex< dim > &shift )
237  {
238  SPMesh< dim > copy( mesh );
239  return copy += shift;
240  }
241 
242 
243  template< int dim >
244  inline SPMesh< dim >
245  operator- ( const SPMesh< dim > &mesh, const SPMultiIndex< dim > &shift )
246  {
247  SPMesh< dim > copy( mesh );
248  return copy -= shift;
249  }
250 
251 } // namespace Dune
252 
253 #endif // #ifndef DUNE_SPGRID_MESH_HH
Definition: iostream.hh:7
SPMesh< dim > operator-(const SPMesh< dim > &mesh, const SPMultiIndex< dim > &shift)
Definition: mesh.hh:245
SPMesh< dim > operator+(const SPMesh< dim > &mesh, const SPMultiIndex< dim > &shift)
Definition: mesh.hh:236
std::basic_ostream< char_type, traits > & operator<<(std::basic_ostream< char_type, traits > &out, const SPCube< ct, dim > &cube)
Definition: cube.hh:148
Definition: mesh.hh:21
MultiIndex width() const
Definition: mesh.hh:194
int volume() const
Definition: mesh.hh:183
const MultiIndex & bound(int b) const
Definition: mesh.hh:39
This intersect(const This &other) const
Definition: mesh.hh:157
int bound(const SPNormalId< dimension > &id) const
Definition: mesh.hh:41
static This unitMesh()
Definition: mesh.hh:213
This grow(int size) const
Definition: mesh.hh:135
std::enable_if< Refinement::dimension==dim, SPMesh< dim > >::type refine(const Refinement &refinement) const
Definition: mesh.hh:121
This grow(const MultiIndex &size) const
Definition: mesh.hh:149
std::pair< This, This > split(const int dir, const int leftWeight, const int rightWeight) const
Definition: mesh.hh:165
bool empty() const
Definition: mesh.hh:109
const MultiIndex & end() const
Definition: mesh.hh:37
const This & operator+=(const MultiIndex &shift)
Definition: mesh.hh:90
SPMesh(const MultiIndex &begin, const MultiIndex &end)
Definition: mesh.hh:81
const This & operator-=(const MultiIndex &shift)
Definition: mesh.hh:100
SPMesh(const MultiIndex &width)
Definition: mesh.hh:73
int width(const int i) const
Definition: mesh.hh:204
const MultiIndex & begin() const
Definition: mesh.hh:36
static const int dimension
Definition: mesh.hh:25
SPMultiIndex< dimension > MultiIndex
Definition: mesh.hh:27