dune-geometry 2.8.0
Loading...
Searching...
No Matches
simplex.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_GRID_COMMON_REFINEMENT_SIMPLEX_CC
4#define DUNE_GRID_COMMON_REFINEMENT_SIMPLEX_CC
5
6// This file is part of DUNE, a Distributed and Unified Numerics Environment
7// This file is copyright (C) 2005 Jorrit Fahlke <jorrit@jorrit.de>
8// This file is licensed under version 2 of the GNU General Public License,
9// with a special "runtime exception." See COPYING at the top of the source
10// tree for the full licence.
11
249#include <algorithm>
250
251#include <dune/common/fvector.hh>
252#include <dune/common/power.hh>
253
256#include <dune/geometry/type.hh>
257
258#include "base.cc"
259
260namespace Dune {
261
262 namespace RefinementImp {
263
270 namespace Simplex {
271
272 // //////////////////
273 //
275 //
276
278
283 inline int factorial(int n)
284 {
285 int prod = 1;
286 for(int i = 1; i <= n; ++i)
287 prod *= i;
288 return prod;
289 }
290
295 inline int binomial(int upper, int lower)
296 {
298 if(lower < 0)
299 return 0;
300 int prod = 1;
301 for(int i = upper - lower; i < upper; ++i)
302 prod *= (i+1);
303 return prod / factorial(lower);
304 }
305
312 template<int dimension>
314 {
315 int index = 0;
316 for(int i = 0; i < dimension; ++i)
317 index += binomial(dimension-i + point[i]-1, dimension-i);
318 return index;
319 }
320
325 template<int n>
327 {
329 for(int i = 0; i < n; ++i)
330 perm[i] = i;
331
332 int base = 1;
333 for(int i = 1; i <= n; ++i)
334 base *= i;
335
336 for(int i = n; i > 0; --i) {
337 base /= i;
338 int d = m / base;
339 m %= base;
340 int t = perm[i-1]; perm[i-1] = perm[i-1-d]; perm[i-1-d] = t;
341 }
342 return perm;
343 }
344
345#if 0
347 // calculate the index of a permutation
348 template<int n>
349 int getPermIndex(const FieldVector<int, n>& test) // O(n^2)
350 {
351 int m = 0;
353 for(int i = 0; i < n; ++i)
354 perm[i] = i;
355
356 int base = 1;
357 for(int i = 1; i <= n; ++i)
358 base *= i;
359
360 for(int i = n; i > 0; --i) {
361 base /= i;
362 int d;
363 for(d = 0; d < i; ++d)
364 if(test[i-1] == perm[i-1-d])
365 break;
366 m += d * base;
367 int d = m / base;
368 m %= base;
369 perm[i-1-d] = perm[i-1];
370 }
371 }
372#endif
373
374 // map between the reference simplex and some arbitrary kuhn simplex (denoted by it's permutation)
382 template<int dimension, class CoordType>
383 FieldVector<CoordType, dimension>
388 {
389 for(int i = dimension - 1; i > 0; --i)
390 point[kuhn[i-1]] += point[kuhn[i]];
391 return point;
392 }
393
401 template<int dimension, class CoordType>
407 {
408 for(int i = 0; i < dimension - 1; ++i)
409 point[kuhn[i]] -= point[kuhn[i+1]];
410 return point;
411 }
412
413
415
416 // /////////////////////////////////////////
417 //
418 // refinement implementation for simplices
419 //
420
421 template<int dimension_, class CoordType>
423 {
424 public:
426 typedef CoordType ctype;
427
428 template<int codimension>
429 struct Codim;
434
435 static int nVertices(int nIntervals);
436 static VertexIterator vBegin(int nIntervals);
437 static VertexIterator vEnd(int nIntervals);
438
439 static int nElements(int nIntervals);
441 static ElementIterator eEnd(int nIntervals);
442 };
443
444 template<int dimension, class CoordType>
445 template<int codimension>
446 struct RefinementImp<dimension, CoordType>::Codim
447 {
448 class SubEntityIterator;
449 // We don't need the caching, but the uncached MultiLinearGeometry has bug FS#1209
451 };
452
453 template<int dimension, class CoordType>
454 int
457 {
458 return binomial(dimension + nIntervals, dimension);
459 }
460
461 template<int dimension, class CoordType>
468
469 template<int dimension, class CoordType>
476
477 template<int dimension, class CoordType>
478 int
484
485 template<int dimension, class CoordType>
492
493 template<int dimension, class CoordType>
500
501 // //////////////
502 //
503 // The iterator
504 //
505
506 template<int dimension, class CoordType, int codimension>
508
509 // vertices
510
511 template<int dimension, class CoordType>
512 class RefinementIteratorSpecial<dimension, CoordType, dimension>
513 {
514 public:
516 typedef typename Refinement::CoordVector CoordVector;
517 typedef typename Refinement::template Codim<dimension>::Geometry Geometry;
519
520 RefinementIteratorSpecial(int nIntervals, bool end = false);
521
522 void increment();
523 bool equals(const This &other) const;
524
525 CoordVector coords() const;
526 Geometry geometry () const;
527
528 int index() const;
529 protected:
531
532 int size;
534 };
535
536 template<int dimension, class CoordType>
540 {
541 vertex[0] = (end) ? size + 1 : 0;
542 for(int i = 1; i < dimension; ++ i)
543 vertex[i] = 0;
544 }
545
546 template<int dimension, class CoordType>
547 void
550 {
551 assert(vertex[0] <= size);
552 for(int i = dimension - 1; i >= 0; --i) {
553 ++vertex[i];
554 if(i == 0 || vertex[i] <= vertex[i-1])
555 break;
556 else
557 vertex[i] = 0;
558 }
559 }
560
561 template<int dimension, class CoordType>
562 bool
564 equals(const This &other) const
565 {
566 return size == other.size && vertex == other.vertex;
567 }
568
569 template<int dimension, class CoordType>
572 coords() const
573 {
575
576 CoordVector coords;
577 for(int i = 0; i < dimension; ++i)
578 coords[i] = CoordType(ref[i]) / size;
579 return coords;
580 }
581
582 template<int dimension, class CoordType>
585 {
586 std::vector<CoordVector> corners(1);
587 corners[0] = (CoordVector)vertex;
588 return Geometry(GeometryTypes::vertex, corners);
589 }
590
591 template<int dimension, class CoordType>
592 int
598
599 // elements
600
601 template<int dimension, class CoordType>
602 class RefinementIteratorSpecial<dimension, CoordType, 0>
603 {
604 public:
608 typedef typename Refinement::template Codim<0>::Geometry Geometry;
610
611 RefinementIteratorSpecial(int nIntervals, bool end = false);
612
613 void increment();
614 bool equals(const This &other) const;
615
616 IndexVector vertexIndices() const;
617 int index() const;
618 CoordVector coords() const;
619
620 Geometry geometry () const;
621
622 private:
623 CoordVector global(const CoordVector &local) const;
624
625 protected:
627 enum { nKuhnIntervals = Factorial<dimension>::factorial };
628
631 int size;
633 };
634
635 template<int dimension, class CoordType>
638 : kuhnIndex(0), size(nIntervals), index_(0)
639 {
640 for(int i = 0; i < dimension; ++i)
641 origin[i] = 0;
642 if(end) {
643 index_ = Refinement::nElements(nIntervals);
644 origin[0] = size;
645 }
646 }
647
648 template<int dimension, class CoordType>
649 void
652 {
653 assert(origin[0] < size);
654
655 ++index_;
656
657 while(1) {
658 ++kuhnIndex;
659 if(kuhnIndex == nKuhnIntervals) {
660 kuhnIndex = 0;
661 // increment origin
662 for(int i = dimension - 1; i >= 0; --i) {
663 ++origin[i];
664 if(i == 0 || origin[i] <= origin[i-1])
665 break;
666 else
667 origin[i] = 0;
668 }
669 }
670
671 // test whether the current simplex has any corner outside the kuhn0 simplex
673 Vertex corner = origin;
674 bool outside = false;
675 for(int i = 0; i < dimension; ++i) {
676 // next corner
677 ++corner[perm[i]];
678 if(perm[i] > 0)
679 if(corner[perm[i]] > corner[perm[i]-1]) {
680 outside = true;
681 break;
682 }
683 }
684 if(!outside)
685 return;
686 }
687 }
688
689 template<int dimension, class CoordType>
690 bool
692 equals(const This &other) const
693 {
694 return size == other.size && index_ == other.index_;
695 }
696
697 template<int dimension, class CoordType>
700 vertexIndices() const
701 {
704 Vertex vertex = origin;
705 indices[0] = pointIndex(vertex);
706 for(int i = 0; i < dimension; ++i) {
707 ++vertex[perm[i]];
708 indices[i+1] = pointIndex(vertex);
709 }
710 if (kuhnIndex%2 == 1)
711 for(int i = 0; i < (dimension+1)/2; ++i) {
712 int t = indices[i];
713 indices[i] = indices[dimension-i];
714 indices[dimension-i] = t;
715 }
716 return indices;
717 }
718
719 template<int dimension, class CoordType>
720 int
722 index() const
723 {
724 return index_;
725 }
726
727 template<int dimension, class CoordType>
735
736 template<int dimension, class CoordType>
739 {
740 std::vector<CoordVector> corners(dimension+1);
742 for(int i = 0; i <= dimension; ++i)
743 corners[i] = global(refelem.position(i, dimension));
744 return Geometry(refelem.type(), corners);
745 }
746
747 template<int dimension, class CoordType>
750 global(const CoordVector &local) const {
751 CoordVector v =
753 v += origin;
754 v /= (typename CoordVector::value_type)size;
756 }
757
758 // common
759
760 template<int dimension, class CoordType>
761 template<int codimension>
762 class RefinementImp<dimension, CoordType>::Codim<codimension>::SubEntityIterator
763 : public ForwardIteratorFacade<typename RefinementImp<dimension, CoordType>::template Codim<codimension>::SubEntityIterator, int>,
764 public RefinementIteratorSpecial<dimension, CoordType, codimension>
765 {
766 public:
768
769 SubEntityIterator(int nIntervals, bool end = false);
770 };
771
772#ifndef DOXYGEN
773
774 template<int dimension, class CoordType>
775 template<int codimension>
778 : RefinementIteratorSpecial<dimension, CoordType, codimension>(nIntervals, end)
779 {}
780
781#endif
782
783 } // namespace Simplex
784
785 } // namespace RefinementImp
786
787
788 namespace RefinementImp {
789
790 // ///////////////////////
791 //
792 // The refinement traits
793 //
794
795#ifndef DOXYGEN
796 template<unsigned topologyId, class CoordType, unsigned coerceToId,
797 int dim>
798 struct Traits<
799 topologyId, CoordType, coerceToId, dim,
800 typename std::enable_if<
801 ((GeometryTypes::simplex(dim).id() >> 1) ==
802 (topologyId >> 1) &&
803 (GeometryTypes::simplex(dim).id() >> 1) ==
804 (coerceToId >> 1)
805 )>::type
806 >
807 {
808 typedef Simplex::RefinementImp<dim, CoordType> Imp;
809 };
810#endif
811
812
813 } // namespace RefinementImp
814
815} // namespace Dune
816
817#endif //DUNE_GRID_COMMON_REFINEMENT_SIMPLEX_CC
A unique label for each type of element that can occur in a grid.
This file contains the parts independent of a particular Refinement implementation.
STL namespace.
int pointIndex(const FieldVector< int, dimension > &point)
calculate the index of a given gridpoint within a Kuhn0 simplex
Definition simplex.cc:313
FieldVector< int, n > getPermutation(int m)
Calculate permutation from it's index.
Definition simplex.cc:326
int factorial(int n)
Calculate n!
Definition simplex.cc:283
int binomial(int upper, int lower)
calculate
Definition simplex.cc:295
FieldVector< CoordType, dimension > referenceToKuhn(FieldVector< CoordType, dimension > point, const FieldVector< int, dimension > &kuhn)
Map from the reference simplex to some Kuhn simplex.
Definition simplex.cc:384
FieldVector< CoordType, dimension > kuhnToReference(FieldVector< CoordType, dimension > point, const FieldVector< int, dimension > &kuhn)
Map from some Kuhn simplex to the reference simplex.
Definition simplex.cc:403
static constexpr auto eval(const T &a)
int size() const
iterator end()
bool equals(const SLListConstIterator< T, A > &other) const
void increment()
size_type dim() const
std::ptrdiff_t index() const
const GlobalIndex & global() const
LocalIndex & local()
static const ReferenceElement & simplex()
get simplex reference elements
Definition referenceelements.hh:202
Static tag representing a codimension.
Definition dimension.hh:22
Implement a MultiLinearGeometry with additional caching.
Definition multilineargeometry.hh:495
Codim< dimension >::SubEntityIterator VertexIterator
Definition simplex.cc:430
FieldVector< int, dimension+1 > IndexVector
Definition simplex.cc:433
CoordType ctype
Definition simplex.cc:426
static int nVertices(int nIntervals)
Definition simplex.cc:456
static int nElements(int nIntervals)
Definition simplex.cc:480
static ElementIterator eEnd(int nIntervals)
Definition simplex.cc:496
static VertexIterator vEnd(int nIntervals)
Definition simplex.cc:472
Codim< 0 >::SubEntityIterator ElementIterator
Definition simplex.cc:432
static VertexIterator vBegin(int nIntervals)
Definition simplex.cc:464
static ElementIterator eBegin(int nIntervals)
Definition simplex.cc:488
FieldVector< CoordType, dimension > CoordVector
Definition simplex.cc:431
@ dimension
Definition simplex.cc:425
Dune::CachedMultiLinearGeometry< CoordType, dimension-codimension, dimension > Geometry
Definition simplex.cc:450
RefinementImp< dimension, CoordType > Refinement
Definition simplex.cc:515
Refinement::template Codim< dimension >::Geometry Geometry
Definition simplex.cc:517
RefinementIteratorSpecial< dimension, CoordType, dimension > This
Definition simplex.cc:518
FieldVector< int, dimension > Vertex
Definition simplex.cc:626
Refinement::template Codim< 0 >::Geometry Geometry
Definition simplex.cc:608
RefinementIteratorSpecial< dimension, CoordType, 0 > This
Definition simplex.cc:609
RefinementImp< dimension, CoordType > Refinement
Definition simplex.cc:605
RefinementImp< dimension, CoordType > Refinement
Definition simplex.cc:767
T min(T... args)