KASKADE 7 development version
gridcombinatorics.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2023 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef GRIDCOMBINATORICS_HH
14#define GRIDCOMBINATORICS_HH
15
16#include <array>
17#include <cassert>
18#include <numeric>
19#include <utility>
20
21#include "dune/geometry/type.hh"
22#include "dune/geometry/referenceelements.hh"
23
24#include "fem/firstless.hh"
25
26namespace Kaskade
27{
40 template <class Map, class IndexSet, class LocalDofs>
41 size_t computeDofStartIndices(int dim, Map& map, IndexSet const& is, LocalDofs& localDof)
42 {
43 map.clear();
44 size_t n = 0;
45
46 for (int codim=0; codim<=dim; ++codim) {
47 for (size_t i=0; i<is.geomTypes(codim).size(); i++) {
48 Dune::GeometryType gt = is.geomTypes(codim)[i];
49 map[gt] = n;
50
51 n += is.size(gt) * localDof(gt);
52 }
53 }
54
55 return n;
56 }
57
58 //---------------------------------------------------------------------
59
61 namespace GridCombinatoricsDetail {
62
74 template <int d, class Idx>
75 void vIds(int c, int k, Idx idx)
76 {
77 // Dune::GeometryType gt(Dune::GeometryType::simplex);
78 // Dune::ReferenceSimplex<double,d> const& s = Dune::GenericReferenceElements<double,d>::simplices(gt);
79 auto const& s = Dune::ReferenceElements<double,d>::simplex();
80 assert(0<=k && k<s.size(c));
81 assert(s.size(k,c,d)==d-c+1);
82 for (int i=0; i<s.size(k,c,d); ++i, ++idx)
83 *idx = s.subEntity(k,c,i,d);
84 }
85
86 // Computes the local number of the vertex that lies in coordinate
87 // direction coord. The (barycentric) coordinate direction dim+1
88 // points towards the origin. See the Dune simplex numbering scheme.
89 inline int localVertexNumber(int dim, int coord)
90 {
91 return (coord+1) % (dim+1);
92 }
93
99 inline int barycentricDirection(int dim, int vertexNumber)
100 {
101 return (vertexNumber+dim) % (dim+1);
102 }
103
104 } // End of namespace GridCombinatoricsDetail
106
117 inline void vertexids(int d, int c, int k, int* idx)
118 {
119 switch(d) {
120 case 0:
121 idx[0] = 0;
122 break;
123 case 1:
124 GridCombinatoricsDetail::vIds<1>(c,k,idx);
125 break;
126 case 2:
127 GridCombinatoricsDetail::vIds<2>(c,k,idx);
128 break;
129 case 3:
130 GridCombinatoricsDetail::vIds<3>(c,k,idx);
131 break;
132 default:
133 assert("Not implemented for d>3!"==0);
134 abort();
135 }
136 }
137
145 template <int dimension>
147 {
148 public:
149 template <class IndexSet, class Cell>
150 GlobalBarycentricPermutation(IndexSet const& is, Cell const& cell)
151 {
152 for (int i=0; i<=dimension; ++i) // obtain global indices of the
153 gvid[i] = is.subIndex(cell,i,dimension); // cell's vertices
154 }
155
165 template <int codim>
166 std::array<int,dimension+1-codim> barycentricSubsetPermutation(int e) const
167 {
168 using namespace GridCombinatoricsDetail;
169
170 std::array<int,dimension+1-codim> vs;
171 vIds<dimension>(codim,e,begin(vs)); // get the cell-local vertex ids of our subentity's vertices
172
173 std::array<std::pair<size_t,int>,dimension+1-codim> vids; // the global and subentity-local vertex indices, sorted by global
174 for (int i=0; i<dimension+1-codim; ++i) // for each vertex of the subentity...
175 vids[i] = std::make_pair(gvid[vs[i]], // ... get the global index...
176 barycentricDirection(dimension,vs[i])); // ... and the barycentric coordinate direction
177 std::sort(begin(vids),end(vids),FirstLess()); // sort according to global index
178
179 std::array<int,dimension+1-codim> pi; // array for the permutation
180 std::iota(begin(pi),end(pi),0); // initialized by the identity
181 for (int i=0; i<dimension+1-codim; ++i) // enter the computed permutation
182 pi[i] = vids[i].second;
183
184 return pi;
185 }
186
193 template <class OutIter>
194 void barycentricSubsetPermutation(int e, int codim, OutIter out) const
195 {
196 switch(codim)
197 {
198 case 0: { auto pi0 = barycentricSubsetPermutation<0>(e); std::copy(begin(pi0),end(pi0),out); break; }
199 case 1: { auto pi1 = barycentricSubsetPermutation<1>(e); std::copy(begin(pi1),end(pi1),out); break; }
200 case 2: { auto pi2 = barycentricSubsetPermutation<2>(e); std::copy(begin(pi2),end(pi2),out); break; }
201// compilation error on line below in experiments/moreExamples/atp-1D
202// case 3: { auto pi3 = barycentricSubsetPermutation<3>(e); std::copy(begin(pi3),end(pi3),out); break; }
203 default: assert("Not implemented for codim>3!"==0); abort();
204 }
205 }
206
207 private:
208 std::array<int,dimension+1> gvid; // the global vertex ids of the cell's vertices
209 };
210
211
212} /* end of namespace Kaskade */
213#endif
A class for computing permutations of local vertex numbers of simplex subentities to a globally uniqu...
std::array< int, dimension+1-codim > barycentricSubsetPermutation(int e) const
Computes a permutation of barycentric coordinates to globally unique ordering.
GlobalBarycentricPermutation(IndexSet const &is, Cell const &cell)
void barycentricSubsetPermutation(int e, int codim, OutIter out) const
A dynamic interface to barycentricSubsetPermutation.
size_t computeDofStartIndices(int dim, Map &map, IndexSet const &is, LocalDofs &localDof)
For each codimension (i.e., type of subentity) computes the number of global ansatz functions as well...
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
Definition: gridBasics.hh:35
void vertexids(int d, int c, int k, int *idx)
Computes the d-c+1 local vertex indices of the vertices incident to the k-th subentity of codimension...
A comparator functor that supports sorting std::pair by their first component.
Definition: firstless.hh:22