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