dune-grid  2.2.1
dofadmin.hh
Go to the documentation of this file.
1 #ifndef DUNE_ALBERTA_DOFADMIN_HH
2 #define DUNE_ALBERTA_DOFADMIN_HH
3 
6 
7 #if HAVE_ALBERTA
8 
9 namespace Dune
10 {
11 
12  namespace Alberta
13  {
14 
15  // External Forward Declarations
16  // -----------------------------
17 
18  template< int dim >
19  class MeshPointer;
20 
21 
22 
23  // DofAccess
24  // ---------
25 
26  template< int dim, int codim >
27  class DofAccess
28  {
29  static const int codimtype = CodimType< dim, codim >::value;
30 
31  public:
32  static const int numSubEntities = NumSubEntities< dim, codim >::value;
33 
34  static const int dimension = dim;
35  static const int codimension = codim;
36 
38 
40  : node_( -1 )
41  {}
42 
43  explicit DofAccess ( const DofSpace *dofSpace )
44  {
45  assert( dofSpace );
46  node_ = dofSpace->admin->mesh->node[ codimtype ];
47  index_ = dofSpace->admin->n0_dof[ codimtype ];
48  }
49 
50  int operator() ( const Element *element, int subEntity, int i ) const
51  {
52  assert( element );
53  assert( node_ != -1 );
54  assert( subEntity < numSubEntities );
55  return element->dof[ node_ + subEntity ][ index_ + i ];
56  }
57 
58  int operator() ( const Element *element, int subEntity ) const
59  {
60  return (*this)( element, subEntity, 0 );
61  }
62 
63  int operator() ( const ElementInfo &elementInfo, int subEntity, int i ) const
64  {
65  return (*this)( elementInfo.el(), subEntity, i );
66  }
67 
68  int operator() ( const ElementInfo &elementInfo, int subEntity ) const
69  {
70  return (*this)( elementInfo.el(), subEntity );
71  }
72 
73  private:
74  int node_;
75  int index_;
76  };
77 
78 
79 
80  // HierarchyDofNumbering
81  // ---------------------
82 
83  template< int dim >
85  {
87 
88  public:
89  static const int dimension = dim;
90 
93 
94  private:
95  static const int nNodeTypes = N_NODE_TYPES;
96 
97  template< int codim >
98  struct CreateDofSpace;
99 
100  template< int codim >
101  struct CacheDofSpace;
102 
103  typedef std::pair< int, int > Cache;
104 
105  public:
107  {}
108 
109  private:
110  HierarchyDofNumbering ( const This & );
111  This &operator= ( const This & );
112 
113  public:
115  {
116  release();
117  }
118 
119  int operator() ( const Element *element, int codim, unsigned int subEntity ) const
120  {
121  assert( !(*this) == false );
122  assert( (codim >= 0) && (codim <= dimension) );
123  const Cache &cache = cache_[ codim ];
124  return element->dof[ cache.first + subEntity ][ cache.second ];
125  }
126 
127  int operator() ( const ElementInfo &element, int codim, unsigned int subEntity ) const
128  {
129  return (*this)( element.el(), codim, subEntity );
130  }
131 
132  operator bool () const
133  {
134  return (bool)mesh_;
135  }
136 
137  const DofSpace *dofSpace ( int codim ) const
138  {
139  assert( *this );
140  assert( (codim >= 0) && (codim <= dimension) );
141  return dofSpace_[ codim ];
142  }
143 
144  const DofSpace *emptyDofSpace () const
145  {
146  assert( *this );
147  return emptySpace_;
148  }
149 
150  const MeshPointer &mesh () const
151  {
152  return mesh_;
153  }
154 
155  int size ( int codim ) const
156  {
157  return dofSpace( codim )->admin->size;
158  }
159 
160  void create ( const MeshPointer &mesh );
161 
162  void release ()
163  {
164  if( *this )
165  {
166  for( int codim = 0; codim <= dimension; ++codim )
167  freeDofSpace( dofSpace_[ codim ] );
168  freeDofSpace( emptySpace_ );
169  mesh_ = MeshPointer();
170  }
171  }
172 
173  private:
174  static const DofSpace *createEmptyDofSpace ( const MeshPointer &mesh );
175  static const DofSpace *createDofSpace ( const MeshPointer &mesh,
176  const std::string &name,
177  const int (&ndof)[ nNodeTypes ],
178  const bool periodic = false );
179  static void freeDofSpace ( const DofSpace *dofSpace );
180 
181  MeshPointer mesh_;
182  const DofSpace *emptySpace_;
183  const DofSpace *dofSpace_[ dimension+1 ];
184  Cache cache_[ dimension+1 ];
185  };
186 
187 
188 
189  template< int dim >
190  inline void
192  {
193  release();
194 
195  if( !mesh )
196  return;
197 
198  mesh_ = mesh;
199  ForLoop< CreateDofSpace, 0, dimension >::apply( mesh_, dofSpace_ );
200  ForLoop< CacheDofSpace, 0, dimension >::apply( dofSpace_, cache_ );
201 
202  emptySpace_ = createEmptyDofSpace( mesh_ );
203  for( int i = 0; i < nNodeTypes; ++i )
204  assert( emptySpace_->admin->n_dof[ i ] == 0 );
205  }
206 
207 
208 
209  template< int dim >
210  inline const DofSpace *
212  {
213  int ndof[ nNodeTypes ];
214  for( int i = 0; i < nNodeTypes; ++i )
215  ndof[ i ] = 0;
216  std::string name = "Empty";
217  return createDofSpace( mesh, name, ndof );
218  }
219 
220 
221 #if DUNE_ALBERTA_VERSION >= 0x300
222  template< int dim >
223  inline const DofSpace *
224  HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh,
225  const std::string &name,
226  const int (&ndof)[ nNodeTypes ],
227  const bool periodic )
228  {
229  const ALBERTA FLAGS flags
230  = ADM_PRESERVE_COARSE_DOFS | (periodic ? ADM_PERIODIC : 0);
231  return ALBERTA get_dof_space ( mesh, name.c_str(), ndof, flags );
232  }
233 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
234 
235 #if DUNE_ALBERTA_VERSION == 0x200
236  template< int dim >
237  inline const DofSpace *
238  HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh,
239  const std::string &name,
240  const int (&ndof)[ nNodeTypes ],
241  const bool periodic )
242  {
243  return ALBERTA get_fe_space( mesh, name.c_str(), ndof, NULL, 1 );
244  }
245 #endif // #if DUNE_ALBERTA_VERSION == 0x200
246 
247 
248 #if DUNE_ALBERTA_VERSION >= 0x300
249  template< int dim >
250  inline void
251  HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace )
252  {
253  ALBERTA free_fe_space( dofSpace );
254  }
255 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
256 
257 #if DUNE_ALBERTA_VERSION == 0x200
258  template< int dim >
259  inline void
260  HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace )
261  {
262  // the const cast is needed due to a bug in ALBERTA 2.0
263  ALBERTA free_fe_space( const_cast< DofSpace * >( dofSpace ) );
264  }
265 #endif // #if DUNE_ALBERTA_VERSION == 0x200
266 
267 
268 
269  // HierarchyDofNumbering::CreateDofSpace
270  // -------------------------------------
271 
272  template< int dim >
273  template< int codim >
275  {
276  static void apply ( const MeshPointer &mesh, const DofSpace *(&dofSpace)[ dim+1 ] )
277  {
278  int ndof[ nNodeTypes ];
279  for( int i = 0; i < nNodeTypes; ++i )
280  ndof[ i ] = 0;
281  ndof[ CodimType< dim, codim >::value ] = 1;
282 
283  std::string name = "Codimension ";
284  name += (char)(codim + '0');
285 
286  dofSpace[ codim ] = createDofSpace( mesh, name, ndof );
287  assert( dofSpace[ codim ] );
288  }
289  };
290 
291 
292 
293  // HierarchyDofNumbering::CacheDofSpace
294  // ------------------------------------
295 
296  template< int dim >
297  template< int codim >
299  {
300  static void apply ( const DofSpace *(&dofSpace)[ dim+1 ], Cache (&cache)[ dim+1 ] )
301  {
302  assert( dofSpace[ codim ] );
303  const int codimtype = CodimType< dim, codim >::value;
304  cache[ codim ].first = dofSpace[ codim ]->mesh->node[ codimtype ];
305  cache[ codim ].second = dofSpace[ codim ]->admin->n0_dof[ codimtype ];
306  }
307  };
308 
309  } // namespace Alberta
310 
311 } // namespace Dune
312 
313 #endif // #if HAVE_ALBERTA
314 
315 #endif // #ifndef DUNE_ALBERTA_DOFADMIN_HH