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