dune-geometry 2.9.1
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// SPDX-FileCopyrightInfo: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_GRID_COMMON_REFINEMENT_SIMPLEX_CC
6#define DUNE_GRID_COMMON_REFINEMENT_SIMPLEX_CC
7
8// This file is part of DUNE, a Distributed and Unified Numerics Environment
9// This file is copyright (C) 2005 Jorrit Fahlke <jorrit@jorrit.de>
10// This file is licensed under version 2 of the GNU General Public License,
11// with a special "runtime exception." See COPYING at the top of the source
12// tree for the full licence.
13
251#include <algorithm>
252
253#include <dune/common/fvector.hh>
254#include <dune/common/math.hh>
255
258#include <dune/geometry/type.hh>
259
260#include "base.cc"
261
262namespace Dune {
263
264 namespace RefinementImp {
265
272 namespace Simplex {
273
274 // //////////////////
275 //
277 //
278
280
288 [[deprecated("Use factorial from dune-common's math.hh")]]
289 inline int factorial(int n)
290 {
291 int prod = 1;
292 for(int i = 1; i <= n; ++i)
293 prod *= i;
294 return prod;
295 }
296
304 [[deprecated("Use binomial from dune-common's math.hh")]]
305 inline int binomial(int upper, int lower)
306 {
307 lower = std::min( lower, upper - lower );
308 if(lower < 0)
309 return 0;
310 int prod = 1;
311 for(int i = upper - lower; i < upper; ++i)
312 prod *= (i+1);
313 return prod / Dune::factorial(lower);
314 }
315
322 template<int dimension>
323 int pointIndex(const FieldVector<int, dimension> &point)
324 {
325 int index = 0;
326 for(int i = 0; i < dimension; ++i)
327 index += Dune::binomial(dimension-i + point[i]-1, dimension-i);
328 return index;
329 }
330
335 template<int n>
336 FieldVector<int, n> getPermutation(int m)
337 {
338 FieldVector<int, n> perm;
339 for(int i = 0; i < n; ++i)
340 perm[i] = i;
341
342 int base = 1;
343 for(int i = 1; i <= n; ++i)
344 base *= i;
345
346 for(int i = n; i > 0; --i) {
347 base /= i;
348 int d = m / base;
349 m %= base;
350 int t = perm[i-1]; perm[i-1] = perm[i-1-d]; perm[i-1-d] = t;
351 }
352 return perm;
353 }
354
355#if 0
356 Has to be checked
357 // calculate the index of a permutation
358 template<int n>
359 int getPermIndex(const FieldVector<int, n>& test) // O(n^2)
360 {
361 int m = 0;
362 FieldVector<int, n> perm;
363 for(int i = 0; i < n; ++i)
364 perm[i] = i;
365
366 int base = 1;
367 for(int i = 1; i <= n; ++i)
368 base *= i;
369
370 for(int i = n; i > 0; --i) {
371 base /= i;
372 int d;
373 for(d = 0; d < i; ++d)
374 if(test[i-1] == perm[i-1-d])
375 break;
376 m += d * base;
377 int d = m / base;
378 m %= base;
379 perm[i-1-d] = perm[i-1];
380 }
381 }
382#endif
383
384 // map between the reference simplex and some arbitrary kuhn simplex (denoted by it's permutation)
392 template<int dimension, class CoordType>
393 FieldVector<CoordType, dimension>
395 FieldVector<CoordType, dimension> point,
397 const FieldVector<int, dimension> &kuhn)
398 {
399 for(int i = dimension - 1; i > 0; --i)
400 point[kuhn[i-1]] += point[kuhn[i]];
401 return point;
402 }
403
411 template<int dimension, class CoordType>
412 FieldVector<CoordType, dimension>
414 FieldVector<CoordType, dimension> point,
416 const FieldVector<int, dimension> &kuhn)
417 {
418 for(int i = 0; i < dimension - 1; ++i)
419 point[kuhn[i]] -= point[kuhn[i+1]];
420 return point;
421 }
422
423
425
426 // /////////////////////////////////////////
427 //
428 // refinement implementation for simplices
429 //
430
431 template<int dimension_, class CoordType>
433 {
434 public:
435 constexpr static int dimension = dimension_;
436 typedef CoordType ctype;
437
438 template<int codimension>
439 struct Codim;
441 typedef FieldVector<CoordType, dimension> CoordVector;
443 typedef FieldVector<int, dimension+1> IndexVector;
444
445 static int nVertices(int nIntervals);
446 static VertexIterator vBegin(int nIntervals);
447 static VertexIterator vEnd(int nIntervals);
448
449 static int nElements(int nIntervals);
450 static ElementIterator eBegin(int nIntervals);
451 static ElementIterator eEnd(int nIntervals);
452 };
453
454 template<int dimension, class CoordType>
455 template<int codimension>
456 struct RefinementImp<dimension, CoordType>::Codim
457 {
458 class SubEntityIterator;
459 // We don't need the caching, but the uncached MultiLinearGeometry has bug FS#1209
461 };
462
463 template<int dimension, class CoordType>
464 int
466 nVertices(int nIntervals)
467 {
468 return Dune::binomial(dimension + nIntervals, (int)dimension);
469 }
470
471 template<int dimension, class CoordType>
474 vBegin(int nIntervals)
475 {
476 return VertexIterator(nIntervals);
477 }
478
479 template<int dimension, class CoordType>
482 vEnd(int nIntervals)
483 {
484 return VertexIterator(nIntervals, true);
485 }
486
487 template<int dimension, class CoordType>
488 int
490 nElements(int nIntervals)
491 {
492 return Dune::power(nIntervals, int(dimension));
493 }
494
495 template<int dimension, class CoordType>
498 eBegin(int nIntervals)
499 {
500 return ElementIterator(nIntervals);
501 }
502
503 template<int dimension, class CoordType>
506 eEnd(int nIntervals)
507 {
508 return ElementIterator(nIntervals, true);
509 }
510
511 // //////////////
512 //
513 // The iterator
514 //
515
516 template<int dimension, class CoordType, int codimension>
518
519 // vertices
520
521 template<int dimension, class CoordType>
522 class RefinementIteratorSpecial<dimension, CoordType, dimension>
523 {
524 public:
527 typedef typename Refinement::template Codim<dimension>::Geometry Geometry;
529
530 RefinementIteratorSpecial(int nIntervals, bool end = false);
531
532 void increment();
533 bool equals(const This &other) const;
534
535 CoordVector coords() const;
536 Geometry geometry () const;
537
538 int index() const;
539 protected:
540 typedef FieldVector<int, dimension> Vertex;
541
542 int size;
544 };
545
546 template<int dimension, class CoordType>
548 RefinementIteratorSpecial(int nIntervals, bool end)
549 : size(nIntervals)
550 {
551 vertex[0] = (end) ? size + 1 : 0;
552 for(int i = 1; i < dimension; ++ i)
553 vertex[i] = 0;
554 }
555
556 template<int dimension, class CoordType>
557 void
560 {
561 assert(vertex[0] <= size);
562 for(int i = dimension - 1; i >= 0; --i) {
563 ++vertex[i];
564 if(i == 0 || vertex[i] <= vertex[i-1])
565 break;
566 else
567 vertex[i] = 0;
568 }
569 }
570
571 template<int dimension, class CoordType>
572 bool
574 equals(const This &other) const
575 {
576 return size == other.size && vertex == other.vertex;
577 }
578
579 template<int dimension, class CoordType>
582 coords() const
583 {
584 Vertex ref = kuhnToReference(vertex, getPermutation<dimension>(0));
585
586 CoordVector coords;
587 for(int i = 0; i < dimension; ++i)
588 coords[i] = CoordType(ref[i]) / size;
589 return coords;
590 }
591
592 template<int dimension, class CoordType>
595 {
596 std::vector<CoordVector> corners(1);
597 corners[0] = (CoordVector)vertex;
598 return Geometry(GeometryTypes::vertex, corners);
599 }
600
601 template<int dimension, class CoordType>
602 int
608
609 // elements
610
611 template<int dimension, class CoordType>
612 class RefinementIteratorSpecial<dimension, CoordType, 0>
613 {
614 public:
618 typedef typename Refinement::template Codim<0>::Geometry Geometry;
620
621 RefinementIteratorSpecial(int nIntervals, bool end = false);
622
623 void increment();
624 bool equals(const This &other) const;
625
626 IndexVector vertexIndices() const;
627 int index() const;
628 CoordVector coords() const;
629
630 Geometry geometry () const;
631
632 private:
633 CoordVector global(const CoordVector &local) const;
634
635 protected:
636 typedef FieldVector<int, dimension> Vertex;
637 constexpr static int nKuhnIntervals = Dune::factorial(dimension);
638
641 int size;
643 };
644
645 template<int dimension, class CoordType>
647 RefinementIteratorSpecial(int nIntervals, bool end)
648 : kuhnIndex(0), size(nIntervals), index_(0)
649 {
650 for(int i = 0; i < dimension; ++i)
651 origin[i] = 0;
652 if(end) {
653 index_ = Refinement::nElements(nIntervals);
654 origin[0] = size;
655 }
656 }
657
658 template<int dimension, class CoordType>
659 void
662 {
663 assert(origin[0] < size);
664
665 ++index_;
666
667 while(1) {
668 ++kuhnIndex;
669 if(kuhnIndex == nKuhnIntervals) {
670 kuhnIndex = 0;
671 // increment origin
672 for(int i = dimension - 1; i >= 0; --i) {
673 ++origin[i];
674 if(i == 0 || origin[i] <= origin[i-1])
675 break;
676 else
677 origin[i] = 0;
678 }
679 }
680
681 // test whether the current simplex has any corner outside the kuhn0 simplex
682 FieldVector<int, dimension> perm = getPermutation<dimension>(kuhnIndex);
683 Vertex corner = origin;
684 bool outside = false;
685 for(int i = 0; i < dimension; ++i) {
686 // next corner
687 ++corner[perm[i]];
688 if(perm[i] > 0)
689 if(corner[perm[i]] > corner[perm[i]-1]) {
690 outside = true;
691 break;
692 }
693 }
694 if(!outside)
695 return;
696 }
697 }
698
699 template<int dimension, class CoordType>
700 bool
702 equals(const This &other) const
703 {
704 return size == other.size && index_ == other.index_;
705 }
706
707 template<int dimension, class CoordType>
710 vertexIndices() const
711 {
712 IndexVector indices;
713 FieldVector<int, dimension> perm = getPermutation<dimension>(kuhnIndex);
714 Vertex vertex = origin;
715 indices[0] = pointIndex(vertex);
716 for(int i = 0; i < dimension; ++i) {
717 ++vertex[perm[i]];
718 indices[i+1] = pointIndex(vertex);
719 }
720 if (kuhnIndex%2 == 1)
721 for(int i = 0; i < (dimension+1)/2; ++i) {
722 int t = indices[i];
723 indices[i] = indices[dimension-i];
724 indices[dimension-i] = t;
725 }
726 return indices;
727 }
728
729 template<int dimension, class CoordType>
730 int
732 index() const
733 {
734 return index_;
735 }
736
737 template<int dimension, class CoordType>
740 coords() const
741 {
743 ::simplex().position(0,0));
744 }
745
746 template<int dimension, class CoordType>
749 {
750 std::vector<CoordVector> corners(dimension+1);
752 for(int i = 0; i <= dimension; ++i)
753 corners[i] = global(refelem.position(i, dimension));
754 return Geometry(refelem.type(), corners);
755 }
756
757 template<int dimension, class CoordType>
760 global(const CoordVector &local) const {
761 CoordVector v =
762 referenceToKuhn(local, getPermutation<dimension>(kuhnIndex));
763 v += origin;
764 v /= (typename CoordVector::value_type)size;
765 return kuhnToReference(v, getPermutation<dimension>(0));
766 }
767
768 // common
769
770 template<int dimension, class CoordType>
771 template<int codimension>
772 class RefinementImp<dimension, CoordType>::Codim<codimension>::SubEntityIterator
773 : public ForwardIteratorFacade<typename RefinementImp<dimension, CoordType>::template Codim<codimension>::SubEntityIterator, int>,
774 public RefinementIteratorSpecial<dimension, CoordType, codimension>
775 {
776 public:
778
779 SubEntityIterator(int nIntervals, bool end = false);
780 };
781
782#ifndef DOXYGEN
783
784 template<int dimension, class CoordType>
785 template<int codimension>
787 SubEntityIterator(int nIntervals, bool end)
788 : RefinementIteratorSpecial<dimension, CoordType, codimension>(nIntervals, end)
789 {}
790
791#endif
792
793 } // namespace Simplex
794
795 } // namespace RefinementImp
796
797
798 namespace RefinementImp {
799
800 // ///////////////////////
801 //
802 // The refinement traits
803 //
804
805#ifndef DOXYGEN
806 template<unsigned topologyId, class CoordType, unsigned coerceToId,
807 int dim>
808 struct Traits<
809 topologyId, CoordType, coerceToId, dim,
810 typename std::enable_if<
811 ((GeometryTypes::simplex(dim).id() >> 1) ==
812 (topologyId >> 1) &&
813 (GeometryTypes::simplex(dim).id() >> 1) ==
814 (coerceToId >> 1)
815 )>::type
816 >
817 {
818 typedef Simplex::RefinementImp<dim, CoordType> Imp;
819 };
820#endif
821
822
823 } // namespace RefinementImp
824
825} // namespace Dune
826
827#endif //DUNE_GRID_COMMON_REFINEMENT_SIMPLEX_CC
This file contains the parts independent of a particular Refinement implementation.
A unique label for each type of element that can occur in a grid.
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition type.hh:507
Definition affinegeometry.hh:21
int pointIndex(const FieldVector< int, dimension > &point)
calculate the index of a given gridpoint within a Kuhn0 simplex
Definition simplex.cc:323
FieldVector< int, n > getPermutation(int m)
Calculate permutation from it's index.
Definition simplex.cc:336
int factorial(int n)
Calculate n!
Definition simplex.cc:289
int binomial(int upper, int lower)
calculate
Definition simplex.cc:305
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:394
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:413
Class providing access to the singletons of the reference elements.
Definition referenceelements.hh:170
static const ReferenceElement & simplex()
get simplex reference elements
Definition referenceelements.hh:204
Static tag representing a codimension.
Definition dimension.hh:24
Implement a MultiLinearGeometry with additional caching.
Definition multilineargeometry.hh:526
Codim< dimension >::SubEntityIterator VertexIterator
Definition simplex.cc:440
FieldVector< int, dimension+1 > IndexVector
Definition simplex.cc:443
CoordType ctype
Definition simplex.cc:436
static int nVertices(int nIntervals)
Definition simplex.cc:466
static int nElements(int nIntervals)
Definition simplex.cc:490
static ElementIterator eEnd(int nIntervals)
Definition simplex.cc:506
static VertexIterator vEnd(int nIntervals)
Definition simplex.cc:482
Codim< 0 >::SubEntityIterator ElementIterator
Definition simplex.cc:442
static VertexIterator vBegin(int nIntervals)
Definition simplex.cc:474
static ElementIterator eBegin(int nIntervals)
Definition simplex.cc:498
FieldVector< CoordType, dimension > CoordVector
Definition simplex.cc:441
static constexpr int dimension
Definition simplex.cc:435
Dune::CachedMultiLinearGeometry< CoordType, dimension-codimension, dimension > Geometry
Definition simplex.cc:460
RefinementImp< dimension, CoordType > Refinement
Definition simplex.cc:525
Refinement::template Codim< dimension >::Geometry Geometry
Definition simplex.cc:527
RefinementIteratorSpecial< dimension, CoordType, dimension > This
Definition simplex.cc:528
FieldVector< int, dimension > Vertex
Definition simplex.cc:636
Refinement::template Codim< 0 >::Geometry Geometry
Definition simplex.cc:618
RefinementIteratorSpecial< dimension, CoordType, 0 > This
Definition simplex.cc:619
RefinementImp< dimension, CoordType > Refinement
Definition simplex.cc:615
RefinementImp< dimension, CoordType > Refinement
Definition simplex.cc:777