DUNE PDELab (2.7)

dofadmin.hh
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
9#include <dune/grid/albertagrid/misc.hh>
11
12#if HAVE_ALBERTA
13
14namespace 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
provides a wrapper for ALBERTA's el_info structure
decltype(auto) apply(F &&f, ArgTuple &&args)
Apply function with arguments given as tuple.
Definition: apply.hh:46
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:267
Dune namespace.
Definition: alignedallocator.hh:14
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)