dune-fem  2.4.1-rc
compile.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_DOFMAPPER_COMPILE_HH
2 #define DUNE_FEM_DOFMAPPER_COMPILE_HH
3 
4 #include <algorithm>
5 
6 #include <dune/geometry/referenceelements.hh>
7 #include <dune/geometry/typeindex.hh>
8 
11 
12 namespace Dune
13 {
14 
15  namespace Fem
16  {
17 
18  // generateCodimensionCode
19  // -----------------------
20 
21  template< class Field, int dim >
22  inline DofMapperCode
23  generateCodimensionCode ( const Dune::ReferenceElement< Field, dim > &refElement, int codim )
24  {
25  unsigned int count = refElement.size( codim );
26  DofMapperCodeWriter code( count, count );
27  for( unsigned int i = 0; i < count; ++i )
28  {
29  code[ 4*i+0 ] = GlobalGeometryTypeIndex::index( refElement.type( i, codim ) );
30  code[ 4*i+1 ] = i;
31  code[ 4*i+2 ] = 1;
32  code[ 4*i+3 ] = i;
33  }
34  return code;
35  }
36 
37 
38 
39  // compile (for LocalCoefficients)
40  // -------------------------------
41 
42  template< class Field, int dim, class LocalCoefficients >
43  inline DofMapperCode
44  compile ( const Dune::ReferenceElement< Field, dim > &refElement,
45  const LocalCoefficients &localCoefficients )
46  {
47  const std::size_t numDofs = localCoefficients.size(); // total number of DoFs
48 
49  // count number of keys per subentity
50 
51  // total number of all sub-entities
52  unsigned int numSubEntities = 0;
53  for( int codim = 0; codim <= dim; ++codim )
54  numSubEntities += refElement.size( codim );
55  assert( numSubEntities > 0 );
56 
57  // form a "matrix" with variable lenght rows. This is the usual
58  // approach: pre-allocate the needed storage once and then
59  // insert the proper offsets into the row-pointer. After
60  // completion count[codim] is an array with one entry for each
61  // sub-entity for the given codim. It is initialized with zeros.
62  unsigned int *count[ dim+1 ];
63  count[ 0 ] = new unsigned int[ numSubEntities ];
64  assert( count[ 0 ] );
65  std::fill( count[ 0 ], count[ 0 ] + numSubEntities, (unsigned int)0 );
66  for( int codim = 0; codim < dim; ++codim )
67  count[ codim+1 ] = count[ codim ] + refElement.size( codim );
68 
69  // Now do the actual counting. After completion
70  // cound[codim][subEntity] will contain the number of DoFs
71  // attached to the particular sub-entity.
72  //
73  // numBlocks is the actual number of __USED__
74  // sub-entities. E.g. for continuous Lagrange-1 on a triangle numBlocks
75  // would be 3, after counting (only the vertices carry DoFs).
76  unsigned int numBlocks = 0;
77  for( std::size_t i = 0; i < numDofs; ++i )
78  {
79  const LocalKey &key = localCoefficients.localKey( i );
80 
81  const int codim = key.codim();
82  const int subEntity = key.subEntity();
83 
84  assert( (codim >= 0) && (codim <= dim) );
85  assert( (subEntity >= 0) && (subEntity < refElement.size( codim )) );
86 
87  if( count[ codim ][ subEntity ] == 0 )
88  ++numBlocks;
89  ++count[ codim ][ subEntity ];
90  }
91 
92  // format the code into subentity blocks
93  // result: count will hold the first local index in the block (0 = unused)
94  //
95  // I.e.: count[cd][subEntIdx] = local index offset for start of
96  // DoFs attached to sub entity
97 
98  DofMapperCodeWriter code( numBlocks, numDofs );
99 
100  unsigned int next = 0;
101  for( int codim = 0; codim <= dim; ++codim )
102  {
103  for( int i = 0; i < refElement.size( codim ); ++i )
104  {
105  const unsigned int cnt = count[ codim ][ i ];
106  if( cnt == 0 )
107  continue;
108 
109  code[ next++ ] = GlobalGeometryTypeIndex::index( refElement.type( i, codim ) );
110  code[ next++ ] = i;
111  code[ next++ ] = cnt;
112 
113  count[ codim ][ i ] = next;
114  next += cnt;
115  }
116  }
117 
118  // fill in the local indices
119  //
120  // Format of the code-array is described in code.hh
121  for( std::size_t i = 0; i < numDofs; ++i )
122  {
123  const LocalKey &key = localCoefficients.localKey( i );
124  const unsigned int block = count[ key.codim() ][ key.subEntity() ];
125  assert( block > 0 );
126  assert( (key.index() >= 0) && (key.index() < code[ block-1 ]) );
127  code[ block + key.index() ] = i;
128  }
129 
130  // clean up and return
131 
132  delete[] count[ 0 ];
133 
134  return code;
135  }
136 
137  } // namespace Fem
138 
139 } // namespace Dune
140 
141 #endif // #ifndef DUNE_FEM_DOFMAPPER_COMPILE_HH
unsigned int codim() const
Definition: localkey.hh:27
Definition: code.hh:150
DofMapperCode compile(const Dune::ReferenceElement< Field, dim > &refElement, const LocalCoefficients &localCoefficients)
Definition: compile.hh:44
Definition: coordinate.hh:4
unsigned int subEntity() const
Definition: localkey.hh:26
DofMapperCode generateCodimensionCode(const Dune::ReferenceElement< Field, dim > &refElement, int codim)
Definition: compile.hh:23
std::size_t size() const
Definition: code.hh:108
unsigned int index() const
Definition: localkey.hh:28
Definition: code.hh:17
Definition: localkey.hh:20