DUNE PDELab (git)

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