Dune Core Modules (unstable)

level.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_LEVEL_HH
6#define DUNE_ALBERTA_LEVEL_HH
7
8#include <cassert>
9#include <cstdlib>
10
12#include <dune/grid/albertagrid/dofadmin.hh>
13#include <dune/grid/albertagrid/dofvector.hh>
14
15#if HAVE_ALBERTA
16
17namespace Dune
18{
19
20 // AlbertaGridLevelProvider
21 // ------------------------
22
23 template< int dim >
24 class AlbertaGridLevelProvider
25 {
26 typedef AlbertaGridLevelProvider< dim > This;
27
28 typedef unsigned char Level;
29
30 typedef Alberta::DofVectorPointer< Level > DofVectorPointer;
31 typedef Alberta::DofAccess< dim, 0 > DofAccess;
32
33 typedef Alberta::FillFlags< dim > FillFlags;
34
35 static const Level isNewFlag = (1 << 7);
36 static const Level levelMask = (1 << 7) - 1;
37
38 class SetLocal;
39 class CalcMaxLevel;
40
41 template< Level flags >
42 struct ClearFlags;
43
44 struct Interpolation;
45
46 public:
47 typedef Alberta::ElementInfo< dim > ElementInfo;
48 typedef Alberta::MeshPointer< dim > MeshPointer;
49 typedef Alberta::HierarchyDofNumbering< dim > DofNumbering;
50
51 Level operator() ( const Alberta::Element *element ) const
52 {
53 const Level *array = (Level *)level_;
54 return array[ dofAccess_( element, 0 ) ] & levelMask;
55 }
56
57 Level operator() ( const ElementInfo &elementInfo ) const
58 {
59 return (*this)( elementInfo.el() );
60 }
61
62 bool isNew ( const Alberta::Element *element ) const
63 {
64 const Level *array = (Level *)level_;
65 return ((array[ dofAccess_( element, 0 ) ] & isNewFlag) != 0);
66 }
67
68 bool isNew ( const ElementInfo &elementInfo ) const
69 {
70 return isNew( elementInfo.el() );
71 }
72
73 Level maxLevel () const
74 {
75 CalcMaxLevel calcFromCache;
76 level_.forEach( calcFromCache );
77#ifndef NDEBUG
78 CalcMaxLevel calcFromGrid;
79 mesh().leafTraverse( calcFromGrid, FillFlags::nothing );
80 assert( calcFromCache.maxLevel() == calcFromGrid.maxLevel() );
81#endif
82 return calcFromCache.maxLevel();;
83 }
84
85 MeshPointer mesh () const
86 {
87 return MeshPointer( level_.dofSpace()->mesh );
88 }
89
90 void markAllOld ()
91 {
92 ClearFlags< isNewFlag > clearIsNew;
93 level_.forEach( clearIsNew );
94 }
95
96 void create ( const DofNumbering &dofNumbering )
97 {
98 const Alberta::DofSpace *const dofSpace = dofNumbering.dofSpace( 0 );
99 dofAccess_ = DofAccess( dofSpace );
100
101 level_.create( dofSpace, "Element level" );
102 assert( level_ );
103 level_.template setupInterpolation< Interpolation >();
104
105 SetLocal setLocal( level_ );
106 mesh().hierarchicTraverse( setLocal, FillFlags::nothing );
107 }
108
109 void release ()
110 {
111 level_.release();
112 dofAccess_ = DofAccess();
113 }
114
115 private:
116 DofVectorPointer level_;
117 DofAccess dofAccess_;
118 };
119
120
121
122 // AlbertaGridLevelProvider::SetLocal
123 // ----------------------------------
124
125 template< int dim >
126 class AlbertaGridLevelProvider< dim >::SetLocal
127 {
128 DofVectorPointer level_;
129 DofAccess dofAccess_;
130
131 public:
132 explicit SetLocal ( const DofVectorPointer &level )
133 : level_( level ),
134 dofAccess_( level.dofSpace() )
135 {}
136
137 void operator() ( const Alberta::ElementInfo< dim > &elementInfo ) const
138 {
139 Level *const array = (Level *)level_;
140 array[ dofAccess_( elementInfo, 0 ) ] = elementInfo.level();
141 }
142 };
143
144
145
146 // AlbertaGridLevelProvider::CalcMaxLevel
147 // --------------------------------------
148
149 template< int dim >
150 class AlbertaGridLevelProvider< dim >::CalcMaxLevel
151 {
152 Level maxLevel_;
153
154 public:
155 CalcMaxLevel ()
156 : maxLevel_( 0 )
157 {}
158
159 void operator() ( const Level &dof )
160 {
161 maxLevel_ = std::max( maxLevel_, Level( dof & levelMask ) );
162 }
163
164 void operator() ( const Alberta::ElementInfo< dim > &elementInfo )
165 {
166 maxLevel_ = std::max( maxLevel_, Level( elementInfo.level() ) );
167 }
168
169 Level maxLevel () const
170 {
171 return maxLevel_;
172 }
173 };
174
175
176
177 // AlbertaGridLevelProvider::ClearFlags
178 // ------------------------------------
179
180 template< int dim >
181 template< typename AlbertaGridLevelProvider< dim >::Level flags >
182 struct AlbertaGridLevelProvider< dim >::ClearFlags
183 {
184 void operator() ( Level &dof ) const
185 {
186 dof &= ~flags;
187 }
188 };
189
190
191
192 // AlbertaGridLevelProvider::Interpolation
193 // ---------------------------------------
194
195 template< int dim >
196 struct AlbertaGridLevelProvider< dim >::Interpolation
197 {
198 static const int dimension = dim;
199
200 typedef Alberta::Patch< dimension > Patch;
201
202 static void interpolateVector ( const DofVectorPointer &dofVector,
203 const Patch &patch )
204 {
205 const DofAccess dofAccess( dofVector.dofSpace() );
206 Level *array = (Level *)dofVector;
207
208 for( int i = 0; i < patch.count(); ++i )
209 {
210 const Alberta::Element *const father = patch[ i ];
211 assert( (array[ dofAccess( father, 0 ) ] & levelMask) < levelMask );
212 const Level childLevel = (array[ dofAccess( father, 0 ) ] + 1) | isNewFlag;
213 for( int i = 0; i < 2; ++i )
214 {
215 const Alberta::Element *child = father->child[ i ];
216 array[ dofAccess( child, 0 ) ] = childLevel;
217 }
218 }
219 }
220 };
221
222}
223
224#endif // #if HAVE_ALBERTA
225
226#endif
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
provides a wrapper for ALBERTA's mesh structure
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 22, 23:30, 2024)