dune-geometry 3.0-git
hcube.cc
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_GEOMETRY_REFINEMENT_HCUBE_CC
4#define DUNE_GEOMETRY_REFINEMENT_HCUBE_CC
5
40#include <cassert>
41
42#include <dune/common/fvector.hh>
43#include <dune/common/iteratorfacades.hh>
44#include <dune/common/power.hh>
45
48
49#include "base.cc" // for RefinementTraits
50
51namespace Dune
52{
53 namespace RefinementImp
54 {
61 namespace HCube
62 {
72 template<int dimension_, class CoordType>
74 {
75 public:
76 enum { dimension = dimension_ };
77 //- Know yourself
79
80 template<int codimension>
81 struct Codim;
83 typedef FieldVector<CoordType, dimension> CoordVector;
85 typedef FieldVector<int, (1<<dimension)> IndexVector;
86
87 static unsigned nVertices(unsigned level);
88 static VertexIterator vBegin(unsigned level);
89 static VertexIterator vEnd(unsigned level);
90
91 static unsigned nElements(unsigned level);
92 static ElementIterator eBegin(unsigned level);
93 static ElementIterator eEnd(unsigned level);
94 };
95
96 template<int dimension, class CoordType>
97 template<int codimension>
98 struct RefinementImp<dimension, CoordType>::Codim
99 {
100 class SubEntityIterator;
102 };
103
104 template<int dimension, class CoordType>
105 unsigned
107 nVertices(unsigned level)
108 {
109 // return (2^level + 1)^dim
110 return Power<dimension>::eval((1u<<level)+1u);
111 }
112
113 template<int dimension, class CoordType>
116 vBegin(unsigned level)
117 {
118 return VertexIterator(0,level);
119 }
120
121 template<int dimension, class CoordType>
124 vEnd(unsigned level)
125 {
126 return VertexIterator(nVertices(level),level);
127 }
128
129 template<int dimension, class CoordType>
130 unsigned
132 nElements(unsigned level)
133 {
134 static_assert(dimension >= 0,
135 "Negative dimension given, what the heck is that supposed to mean?");
136 // return (2^level)^dim
137 return 1u<<(level*unsigned(dimension));
138 }
139
140 template<int dimension, class CoordType>
143 eBegin(unsigned level)
144 {
145 return ElementIterator(0,level);
146 }
147
148 template<int dimension, class CoordType>
151 eEnd(unsigned level)
152 {
153 return ElementIterator(nElements(level),level);
154 }
155
156 //
157 // The iterators
158 //
159
160#ifdef DOXYGEN
172 template<int dimension, class CoordType, int codimension>
174#else
175 template<int dimension, class CoordType, int codimension>
177#endif //DOXYGEN
178
179 // for vertices
180
181 template<int dimension, class CoordType>
182 class RefinementSubEntityIteratorSpecial<dimension, CoordType, dimension>
183 {
184 public:
186 typedef typename Refinement::template Codim<dimension>::SubEntityIterator Common;
187 typedef typename Refinement::CoordVector CoordVector;
188
189 CoordVector coords() const;
190
191 private:
192 const Common & asCommon() const
193 {
194 return *static_cast<const Common*>(this);
195 }
196 };
197
198 template<int dimension, class CoordType>
199 typename RefinementSubEntityIteratorSpecial<dimension, CoordType, dimension>::CoordVector
201 coords() const
202 {
203 std::array<unsigned int, dimension> v(asCommon().vertexCoord());
204 CoordVector c;
205 for (int d = 0; d < dimension; d++)
206 {
207 c[d] = v[d]*1.0 / (1 << asCommon()._level);
208 }
209 return c;
210 }
211
212 // for elements
213
214 template<int dimension, class CoordType>
215 class RefinementSubEntityIteratorSpecial<dimension, CoordType, 0>
216 {
217 public:
219 typedef typename Refinement::template Codim<0>::SubEntityIterator Common;
220 typedef typename Refinement::IndexVector IndexVector;
221 typedef typename Refinement::CoordVector CoordVector;
222
223 IndexVector vertexIndices() const;
224 CoordVector coords() const;
225
226 private:
227 const Common & asCommon() const
228 {
229 return *static_cast<const Common*>(this);
230 }
231 };
232
233 template<int dimension, class CoordType>
234 typename RefinementSubEntityIteratorSpecial<dimension, CoordType, 0>::IndexVector
236 vertexIndices() const
237 {
238 enum { nIndices = (1 << dimension) };
239
240 // cell index tuple
241 std::array<unsigned int, dimension> e(asCommon().cellCoord());
242
243 // vertices
244 IndexVector vec;
245 std::array<unsigned int, dimension> v;
246 for(int i = 0; i < nIndices; ++i)
247 {
248 for (int d = 0; d < dimension; d++)
249 {
250 v[d] = e[d];
251 if (i & (1 << d))
252 v[d]++;
253 }
254 // compute vertex index tuple from cell tuple
255 vec[nIndices-1-i] = asCommon().vertexIdx(v);
256 }
257 return vec;
258 }
259
260 template<int dimension, class CoordType>
263 coords() const
264 {
265 std::array<unsigned int, dimension> v(asCommon().cellCoord());
266 CoordVector c;
267 for (int d=0; d<dimension; d++)
268 {
269 c[d] = (v[d]*1.0 + 0.5) / (1<<asCommon()._level);
270 }
271 return c;
272 }
273
274 // common
275 template<int dimension, class CoordType>
276 template<int codimension>
277 class RefinementImp<dimension, CoordType>::Codim<codimension>::SubEntityIterator
278 : public ForwardIteratorFacade<typename RefinementImp<dimension,
279 CoordType>::template Codim<codimension>::SubEntityIterator, int>,
280 public RefinementSubEntityIteratorSpecial<dimension, CoordType, codimension>
281 {
282 public:
284 typedef typename Refinement::template Codim<codimension>::SubEntityIterator This;
285
286 SubEntityIterator(unsigned int index, unsigned int level);
287
288 bool equals(const This &other) const;
289 void increment();
290
291 int index() const;
292 Geometry geometry () const;
293 private:
294 friend class RefinementSubEntityIteratorSpecial<dimension, CoordType, codimension>;
295 unsigned int _index;
296 unsigned int _level;
297
298 std::array<unsigned int, dimension>
299 cellCoord(unsigned int idx) const
300 {
301 return idx2coord(idx, 1u<<_level);
302 }
303
304 std::array<unsigned int, dimension>
305 vertexCoord(unsigned int idx) const
306 {
307 return idx2coord(idx, (1u<<_level)+1u);
308 }
309
310 std::array<unsigned int, dimension>
311 cellCoord() const
312 {
313 return cellCoord(_index);
314 }
315
316 std::array<unsigned int, dimension>
317 vertexCoord() const
318 {
319 return vertexCoord(_index);
320 }
321
322 std::array<unsigned int, dimension>
323 idx2coord(unsigned int idx, unsigned int w) const
324 {
325 std::array<unsigned int, dimension> c;
326 for (unsigned int d = 0; d < dimension; d++)
327 {
328 c[d] = idx%w;
329 idx = idx/w;
330 }
331 return c;
332 }
333
334 unsigned int
335 coord2idx(std::array<unsigned int, dimension> c, unsigned int w) const
336 {
337 unsigned int i = 0;
338 for (unsigned int d = dimension; d > 0; d--)
339 {
340 i *= w;
341 i += c[d-1];
342 }
343 return i;
344 }
345
346 unsigned int
347 vertexIdx(std::array<unsigned int, dimension> c) const
348 {
349 return coord2idx(c, (1u<<_level)+1u);
350 }
351 };
352
353#ifndef DOXYGEN
354 template<int dimension, class CoordType>
355 template<int codimension>
356 RefinementImp<dimension, CoordType>::Codim<codimension>::SubEntityIterator::
357 SubEntityIterator(unsigned int index, unsigned int level)
358 : _index(index), _level(level)
359 {}
360
361 template<int dimension, class CoordType>
362 template<int codimension>
363 bool
364 RefinementImp<dimension, CoordType>::Codim<codimension>::SubEntityIterator::
365 equals(const This &other) const
366 {
367 return ((_index == other._index) && (_level == other._level));
368 }
369
370 template<int dimension, class CoordType>
371 template<int codimension>
372 void
373 RefinementImp<dimension, CoordType>::Codim<codimension>::SubEntityIterator::
374 increment()
375 {
376 ++_index;
377 }
378
379 template<int dimension, class CoordType>
380 template<int codimension>
381 int
382 RefinementImp<dimension, CoordType>::Codim<codimension>::SubEntityIterator::
383 index() const
384 {
385 return _index;
386 }
387
388 template<int dimension, class CoordType>
389 template<int codimension>
390 typename RefinementImp<dimension, CoordType>::template Codim<codimension>::Geometry
391 RefinementImp<dimension, CoordType>::Codim<codimension>::SubEntityIterator::geometry () const
392 {
393 std::array<unsigned int,dimension> intCoords = idx2coord(_index,1u<<_level);
394
395 Dune::FieldVector<CoordType,dimension> lower;
396 Dune::FieldVector<CoordType,dimension> upper;
397
398 assert(codimension == 0 or codimension == dimension);
399
400 if (codimension == 0) {
401 for (size_t j = 0; j < dimension; j++)
402 {
403 lower[j] = double(intCoords[j]) / double(1u<<_level);
404 upper[j] = double(intCoords[j] + 1) / double(1u<<_level);
405 }
406 } else {
407 for (size_t j = 0; j < dimension; j++)
408 lower[j] = upper[j] = double(intCoords[j]) / double(1u<<_level);
409 }
410
411 return typename RefinementImp<dimension,
412 CoordType>::template Codim<codimension>::Geometry(lower,upper);
413 }
414
415#endif // DOXYGEN
416
417 } // namespace HCube
418
419 // ///////////////////////
420 //
421 // The refinement traits
422 //
423
424#ifndef DOXYGEN
425 template<unsigned topologyId, class CoordType, unsigned coerceToId,
426 int dim>
427 struct Traits<
428 topologyId, CoordType, coerceToId, dim,
429 typename std::enable_if<
430 (dim >= 2 &&
431 (GenericGeometry::CubeTopology<dim>::type::id >> 1) ==
432 (topologyId >> 1) &&
433 (GenericGeometry::CubeTopology<dim>::type::id >> 1) ==
434 (coerceToId >> 1)
435 )>::type
436 >
437 {
438 typedef HCube::RefinementImp<dim, CoordType> Imp;
439 };
440#endif
441
442 } // namespace RefinementImp
443
444} // namespace Dune
445
446#endif // DUNE_GEOMETRY_REFINEMENT_HCUBE_CC
This file contains the parts independent of a particular Refinement implementation.
A geometry implementation for axis-aligned hypercubes.
Definition affinegeometry.hh:19
A geometry implementation for axis-aligned hypercubes.
Definition axisalignedcubegeometry.hh:49
Static tag representing a codimension.
Definition dimension.hh:22
Refinement implementation for hypercubes
Definition hcube.cc:74
static VertexIterator vBegin(unsigned level)
Definition hcube.cc:116
Codim< 0 >::SubEntityIterator ElementIterator
Definition hcube.cc:84
static ElementIterator eEnd(unsigned level)
Definition hcube.cc:151
FieldVector< int,(1<< dimension)> IndexVector
Definition hcube.cc:85
static unsigned nElements(unsigned level)
Definition hcube.cc:132
static VertexIterator vEnd(unsigned level)
Definition hcube.cc:124
Codim< dimension >::SubEntityIterator VertexIterator
Definition hcube.cc:82
FieldVector< CoordType, dimension > CoordVector
Definition hcube.cc:83
static unsigned nVertices(unsigned level)
Definition hcube.cc:107
RefinementImp< dimension, CoordType > Refinement
Definition hcube.cc:78
static ElementIterator eBegin(unsigned level)
Definition hcube.cc:143
Dune::AxisAlignedCubeGeometry< CoordType, dimension-codimension, dimension > Geometry
Definition hcube.cc:101
SubEntityIterator base class for hypercube refinement.
Definition hcube.cc:173
Refinement::template Codim< dimension >::SubEntityIterator Common
Definition hcube.cc:186
RefinementImp< dimension, CoordType > Refinement
Definition hcube.cc:218
Refinement::template Codim< 0 >::SubEntityIterator Common
Definition hcube.cc:219
SubEntityIterator(unsigned int index, unsigned int level)
RefinementImp< dimension, CoordType > Refinement
Definition hcube.cc:283
Refinement::template Codim< codimension >::SubEntityIterator This
Definition hcube.cc:284