KASKADE 7 development version
mgtools.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2011 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef MGTOOLS_HH
14#define MGTOOLS_HH
15
16#include <limits>
17#include <memory>
18#include <vector>
19#include <map>
20#include <set>
21#include <stack>
22#include <iterator>
23#include <boost/signals2.hpp>
24
25#include "dune/grid/common/grid.hh"
26#include "dune/grid/common/entitypointer.hh"
27#include "dune/grid/common/entity.hh"
28#include "dune/grid/io/file/dgfparser/dgfparser.hh"
29#include "dune/istl/matrix.hh"
30#include "dune/istl/bcrsmatrix.hh"
31#include "dune/common/fmatrix.hh"
32#include "dune/common/iteratorfacades.hh"
33
34#include "fem/fixdune.hh"
35#include "fem/mllgeometry.hh"
36#include "fem/fetransfer.hh"
37
45using namespace Kaskade;
46
47template< class GridImp, class ValueType >
49: public Dune::ForwardIteratorFacade< FullHierarchicIterator<GridImp,ValueType>, ValueType >
50
51{
52public:
53 static const int codimension = 0 ;
54
55 typedef typename GridImp::template Codim<codimension>::LevelIterator LevelIterator ;
56 typedef typename GridImp::template Codim<codimension>::HierarchicIterator HierarchicIterator ;
57 typedef ValueType Entity ;
58
59 FullHierarchicIterator( GridImp const& grid_, int maxlevel_, bool end = false ) :
60 grid( &grid_ ), coarseGridIt( grid_.levelGridView(0).template begin<0>() ),
61 coarseGridEnd( grid_.levelGridView(0).template end<0>() ), hierIt( coarseGridIt->hbegin(maxlevel_) ),
62 hierEnd( coarseGridIt->hend(maxlevel_) ), maxlevel( maxlevel_ ), coarse(true)
63 {
64 if( end ) coarseGridIt = coarseGridEnd ;
65 }
66
68 grid(other.grid), coarseGridIt(other.coarseGridIt), coarseGridEnd(other.coarseGridEnd), hierIt(other.hierIt),
69 hierEnd(other.hierEnd), maxlevel(other.maxlevel), coarse(other.coarse)
70 {}
71
72 void increment()
73 {
74 if( coarse ) // last increment: ++coarseGridIt, now initialize new hierarchic iterator
75 {
76 if( maxlevel == 0 ) // special case, don't use hierIt
77 {
78 ++coarseGridIt ;
79 }
80 else
81 {
82 hierIt = coarseGridIt->hbegin(maxlevel) ;
83 hierEnd = coarseGridIt->hend(maxlevel) ;
84 coarse = false ;
85 }
86 }
87 else
88 {
89 ++hierIt ;
90 if( hierIt == hierEnd )
91 {
92 ++coarseGridIt ;
93 coarse = true ;
94 }
95 }
96 }
97
98 ValueType& dereference() const
99 {
100 if( coarse || maxlevel==0 ) return *coarseGridIt ;
101 return *hierIt ;
102 }
103
104 int level()
105 {
106 if( coarse || maxlevel==0 ) return 0 ;
107 return hierIt.level() ;
108 }
109
110 bool equals( FullHierarchicIterator const& rhs ) const
111 {
112 if( rhs.maxlevel != maxlevel || rhs.grid != grid ) return false ;
113 if( rhs.coarse == true && coarse == true ) return ( rhs.coarseGridIt == coarseGridIt ) ;
114 return ( rhs.coarseGridIt == coarseGridIt && rhs.hierIt == hierIt ) ;
115 }
116
117 // cast to Entity -- needed e.g. for TransferData
118 operator typename GridImp::template Codim<0>::Entity ()
119 {
120 if( coarse || maxlevel==0 ) return typename GridImp::template Codim<0>::Entity( coarseGridIt ) ;
121 return typename GridImp::template Codim<0>::Entity( hierIt ) ;
122 }
123
124private:
125 const GridImp* grid ;
126 LevelIterator coarseGridIt, coarseGridEnd ;
127 HierarchicIterator hierIt, hierEnd ;
128 int maxlevel ;
129 bool coarse ;
130};
131
132
142template< class Grid >
144{
145private:
146 static const int dim = Grid::dimension;
147 typedef typename Grid::template Codim<0>::LevelIterator ElementLevelIterator ;
148 typedef typename Grid::template Codim<0>::HierarchicIterator HierarchicIterator ;
149 typedef typename Grid::Traits::LevelIndexSet LevelIndexSet ;
150 typedef typename Grid::template Codim<0>::Entity Entity;
151
152public:
153 template <int cd>
154 struct Codim
155 {
156 template <Dune::PartitionIteratorType pitype>
158 {
160 };
161 };
162
163 typedef int IndexType;
165
166 HierarchicIndexSet( GridManager<Grid>& gridMan_, bool connectMe_ = true ) :
167 gridMan( gridMan_ ), grid(gridMan_.grid() ), maxlevel( gridMan_.maxLevel() ),connectMe( connectMe_ ), rtf(*this)
168 {
169 if( connectMe ) refConnection = gridMan.signals.informAboutRefinement.connect(0, rtf);
170 init() ;
171 update() ;
172 }
173
174 HierarchicIndexSet( GridManager<Grid>& gridMan_, int maxlevel_, bool connectMe_ = true ) :
175 gridMan( gridMan_ ), grid(gridMan_.grid() ), maxlevel( maxlevel_ ), connectMe(connectMe_), rtf(*this)
176 {
177 if( connectMe ) refConnection = gridMan.signals.informAboutRefinement.connect(0, rtf);
178 init();
179 update() ;
180 }
181
183 gridMan( other.gridMan ), grid(other.grid ), maxlevel( other.maxlevel ), connectMe(other.connectMe), rtf(*this)
184 {
185 if( connectMe ) refConnection = gridMan.signals.informAboutRefinement.connect(0, rtf);
186 init() ;
187 update() ;
188 }
189
191 {
192 gridMan = other.gridMan ;
193 grid = other.grid ;
194 maxlevel = other.maxlevel ;
195 connectMe = other.connectMe ;
196 if( connectMe ) refConnection = gridMan.signals.informAboutRefinement.connect(0, rtf);
197 init();
198 update() ;
199 }
200
202 {
203 refConnection.disconnect() ;
204 }
205
206public:
207
208 void init()
209 {
210 std::vector< std::vector<int> > tmp( maxlevel+1, std::vector<int>(1, -1) ) ;
211
212 if( indices.size() > 0 ) indices.clear() ;
213 if( numEntities.size() > 0 ) numEntities.clear() ;
214
215 indices.resize( 4, tmp ) ;
216 numEntities.resize( 4, 0 ) ;
217 }
218
220 void update( int maxlevel_ )
221 {
222 maxlevel = maxlevel_ ;
223 for( int i = 0 ; i < 4 ; i++ ) indices[i].resize( maxlevel+1, std::vector<int>(1,-1) ) ;
224 update() ;
225 }
226
227 void update( )
228 {
229 LevelIndexSet const& coarseLevelIndexSet = grid.levelIndexSet(0) ;
230
231 for( ElementLevelIterator it = grid.levelGridView( 0 ).template begin<0>();
232 it != grid.levelGridView( 0 ).template end<0>(); ++it )
233 {
234 // add father to index set, including sub-entities of all available codimensions
235 for( int codim = 0 ; codim <= dim ; codim++ )
236 {
237 int nSubentities = FixDuneDetail::GetNumberOfSubEntities<dim>::value( *it, codim ) ;
238 for( int k = 0 ; k < nSubentities ; k++ )
239 {
240 int subindex = FixDuneDetail::GetIndexOfSubEntity<dim>::value(*it, codim, k, coarseLevelIndexSet ) ;
241 if( subindex >= indices[codim][0].size() ) indices[codim][0].resize( subindex+1, -1 ) ;
242 if( indices[codim][0][subindex] == -1 )
243 {
244 indices[codim][0][subindex] = numEntities[codim] ;
245 numEntities[codim]++ ;
246 }
247 }
248 }
249
250 // traverse children with level <= maxlevel and add indices for all subentities
251 HierarchicIterator end = it->hend(maxlevel);
252 for( HierarchicIterator hi = it->hbegin(maxlevel); hi != end; ++hi)
253 {
254 int level = hi.level() ;
255 LevelIndexSet const& levelIndexSet = grid.levelIndexSet( level ) ;
256
257 for( int codim = 0 ; codim <= dim ; codim++ )
258 {
259 int nSubentities = FixDuneDetail::GetNumberOfSubEntities<dim>::value( *hi, codim ) ;
260 for( int k = 0 ; k < nSubentities ; k++ )
261 {
262 int subindex = FixDuneDetail::GetIndexOfSubEntity<dim>::value( *hi, codim, k, levelIndexSet ) ;
263 if( subindex >= indices[codim][level].size() ) indices[codim][level].resize( subindex+1, -1 ) ;
264 if( indices[codim][level][subindex] == -1 )
265 {
266 indices[codim][level][subindex] = numEntities[codim] ;
267 numEntities[codim]++ ;
268 }
269 }
270 }
271 }
272 }
273
274 // build vector of geometry types
275 if( geometryTypes.size() > 0 ) geometryTypes.clear() ;
276 geometryTypes.resize( numEntities.size(), std::vector<Dune::GeometryType>(0) ) ;
277 std::vector<Dune::GeometryType> geotmp ;
278 for( int codim = 0; codim <= dim ; codim++ )
279 {
280 for( int level = 0 ; level <= maxlevel ; level++ )
281 {
282 geotmp = grid.levelIndexSet(level).geomTypes(codim) ;
283 geometryTypes[codim].insert( geometryTypes[codim].end(), geotmp.begin(), geotmp.end() ) ;
284 }
285 std::sort( geometryTypes[codim].begin(), geometryTypes[codim].end() ) ;
286 std::vector<Dune::GeometryType>::iterator it
287 = std::unique( geometryTypes[codim].begin(), geometryTypes[codim].end() ) ;
288 geometryTypes[codim].resize( it-geometryTypes[codim].begin() ) ;
289 }
290 }
291
292
293 template<int cc>
294 int index( const typename Grid::Traits::template Codim<cc>::Entity &e ) const
295 {
296 int idx = grid.levelIndexSet(e.level()).index(e) ;
297 int level = e.level() ;
298 assert( level < indices[cc].size() ) ;
299 assert( idx < indices[cc][level].size() );
300 return indices[cc][level][idx] ;
301 }
302
303 template<class EntityType >
304 int index( const EntityType &e ) const
305 {
306 int idx = grid.levelIndexSet(e.level()).index(e) ;
307 int level = e.level() ;
308 assert( level < indices[EntityType::codimension].size() ) ;
309 assert( idx < indices[EntityType::codimension][level].size() );
310 return indices[EntityType::codimension][level][idx] ;
311 }
312
313 template<int cc>
314 int subIndex( const typename Grid::Traits::template Codim<0>::Entity &e, int i ) const
315 {
316 int sidx = grid.levelIndexSet(e.level()).template subIndex<cc>(e,i) ;
317 int level = e.level() ;
318 assert( level < indices[cc].size() ) ;
319 assert( sidx < indices[cc][level].size() ) ;
320 return indices[cc][level][sidx] ;
321 }
322
323 const std::vector<Dune::GeometryType>& geomTypes( int codim ) const
324 {
325 assert( codim < geometryTypes.size() ) ;
326 return geometryTypes[codim] ;
327 }
328
329 int size( Dune::GeometryType type ) const
330 {
331 int s=0 ;
332 for( int level = 0 ; level <= maxlevel ; level++ )
333 {
334 s += grid.levelIndexSet(level).size(type) ;
335 }
336 return s ;
337 }
338
339 int size( int codim ) const
340 {
341 assert( codim < numEntities.size() ) ;
342 return numEntities[codim] ;
343 }
344
345 template<class EntityType>
346 bool contains( const EntityType &e ) const
347 {
348 int level = e.level() ;
349 if( level > maxlevel ) return false ;
350 int lindex = grid.levelIndexSet(level).index(e) ;
351 int codim = EntityType::codimension ;
352 if( lindex > indices[codim][level].size() ) return false ;
353 if( indices[codim][level][lindex] > -1 ) return true ;
354 return false ;
355 }
356
357 // iterators
358 template<int cd, Dune::PartitionIteratorType pitype>
359 typename Codim<cd>::template Partition<pitype>::Iterator begin() const
360 {
361 return FullHierarchicIterator<Grid, Entity>( grid, maxlevel ) ;
362 }
363
364 template<int cd, Dune::PartitionIteratorType pitype>
365 typename Codim<cd>::template Partition<pitype>::Iterator end() const
366 {
367 return FullHierarchicIterator<Grid, Entity>( grid, maxlevel, true ) ;
368 }
369
370 // debug
371 void out(std::ostream& o) const
372 {
373 for( int i = 0 ; i < indices.size() ; i++ )
374 {
375 o << "\nCODIM " << i << "\n" ;
376 for( int j = 0 ; j < indices[i].size() ; j++ )
377 {
378 for( int k = 0 ; k < indices[i][j].size() ; k++ )
379 o << indices[i][j][k] << "\t" ;
380 o << "\n" ;
381 }
382 o << "\n" ;
383 }
384 }
385
386private:
387
388 struct ReactToRefinement
389 {
390 ReactToRefinement(Self &is_) : is(is_) {}
391
392 void operator()(typename GridSignals::Status const ref)
393 {
394 if(ref==GridSignals::AfterRefinement) is.update( is.gridMan.grid().maxLevel() ) ;
395 }
396
397 private:
398 Self& is ;
399 } ;
400
401 std::vector< std::vector< std::vector<int> > > indices ; //indices[codim][level][level_index] = hierarchic_index ;
402 std::vector< int > numEntities ;
403 GridManager<Grid>& gridMan ;
404 Grid const& grid ;
405
406 int maxlevel ;
407 bool connectMe ;
408 ReactToRefinement rtf;
409 boost::signals2::connection refConnection;
410
411 std::vector< std::vector<Dune::GeometryType> > geometryTypes ;
412};
413
414
415
416
417
449template<class Space, class Grid>
451{
452private:
454
455public:
456 MultilevelTransfer( GridManager<Grid>& gridMan_, int order_ = 1, int startlevel_ = 0 )
457 : gridMan( gridMan_ ), order(order_), startlevel(startlevel_)
458 {
459 MultilevelCoarseningPolicy multilevelCoarseningPolicy(startlevel) ;
460 typename Grid::LevelGridView gv = gridMan.grid().levelView(startlevel);
461
462 for( int level=startlevel ; level < gridMan.grid().maxLevel() ; level++ )
463 {
464 Space fatherSpace( gridMan, gridMan.grid().levelView(level+1), order ) ;
465
466 TransferData<Space,MultilevelCoarseningPolicy> transferData( fatherSpace, multilevelCoarseningPolicy );
467 matrices.push_back( transferData.transferMatrix().release() );
468 multilevelCoarseningPolicy.update(level+1) ;
469 }
470 }
471
473 {
474 for( int i = 0 ; i < matrices.size() ; i++ ) delete matrices[i] ;
475 }
476
477 void out(std::ostream& o) const
478 {
479 for( int level=startlevel ; level < gridMan.grid().maxLevel() ; level++ )
480 {
481 o << "prolongation " << level << "->" << level+1 << "\n" ;
482 matrices[level-startlevel]->out(o) ;
483 }
484 }
485
488 {
489 return matrices[level-startlevel] ;
490 }
491
493 template <class StorageValue>
494 std::unique_ptr<Dune::BlockVector<StorageValue> > apply(int level, Dune::BlockVector<StorageValue> const& oldCoeff) const
495 {
496 std::unique_ptr<Dune::BlockVector<StorageValue> > newCoeff = matrices[level-startlevel]->apply(oldCoeff) ;
497 return newCoeff ;
498 }
499
500private:
501 GridManager<Grid>& gridMan ;
502 int order ;
503 int startlevel ;
504 std::vector<typename TransferData<Space,MultilevelCoarseningPolicy>::TransferMatrix* > matrices ;
505} ;
506
507
508
509
510#endif
GridImp::template Codim< codimension >::LevelIterator LevelIterator
Definition: mgtools.hh:55
FullHierarchicIterator(GridImp const &grid_, int maxlevel_, bool end=false)
Definition: mgtools.hh:59
static const int codimension
Definition: mgtools.hh:53
ValueType & dereference() const
Definition: mgtools.hh:98
bool equals(FullHierarchicIterator const &rhs) const
Definition: mgtools.hh:110
GridImp::template Codim< codimension >::HierarchicIterator HierarchicIterator
Definition: mgtools.hh:56
FullHierarchicIterator(FullHierarchicIterator const &other)
Definition: mgtools.hh:67
int size(Dune::GeometryType type) const
Definition: mgtools.hh:329
int index(const typename Grid::Traits::template Codim< cc >::Entity &e) const
Definition: mgtools.hh:294
bool contains(const EntityType &e) const
Definition: mgtools.hh:346
HierarchicIndexSet(GridManager< Grid > &gridMan_, int maxlevel_, bool connectMe_=true)
Definition: mgtools.hh:174
void update(int maxlevel_)
update hierarchic index set, e.g. after grid change
Definition: mgtools.hh:220
int index(const EntityType &e) const
Definition: mgtools.hh:304
Codim< cd >::template Partition< pitype >::Iterator begin() const
Definition: mgtools.hh:359
int size(int codim) const
Definition: mgtools.hh:339
HierarchicIndexSet & operator=(const HierarchicIndexSet &other)
Definition: mgtools.hh:190
int subIndex(const typename Grid::Traits::template Codim< 0 >::Entity &e, int i) const
Definition: mgtools.hh:314
HierarchicIndexSet(GridManager< Grid > &gridMan_, bool connectMe_=true)
Definition: mgtools.hh:166
const std::vector< Dune::GeometryType > & geomTypes(int codim) const
Definition: mgtools.hh:323
HierarchicIndexSet(const HierarchicIndexSet &other)
Definition: mgtools.hh:182
void out(std::ostream &o) const
Definition: mgtools.hh:371
HierarchicIndexSet< Grid > Self
Definition: mgtools.hh:164
Codim< cd >::template Partition< pitype >::Iterator end() const
Definition: mgtools.hh:365
Grid const & grid() const
Returns a const reference on the owned grid.
Definition: gridmanager.hh:292
Matrix that transforms a data vector v_1 corresponding to the old grid to a data vector v_2 correspon...
Definition: fetransfer.hh:556
A class storing data collected before grid adaptation that is necessary to transfer FE functions....
Definition: fetransfer.hh:532
std::unique_ptr< TransferMatrix > transferMatrix() const
Create a TransferMatrix.
Definition: fetransfer.hh:727
MultilevelTransfer(GridManager< Grid > &gridMan_, int order_=1, int startlevel_=0)
Definition: mgtools.hh:456
TransferData< Space, MultilevelCoarseningPolicy >::TransferMatrix * operator[](int level) const
Access transfer matrix.
Definition: mgtools.hh:487
std::unique_ptr< Dune::BlockVector< StorageValue > > apply(int level, Dune::BlockVector< StorageValue > const &oldCoeff) const
Apply transfer matrix to coefficients.
Definition: mgtools.hh:494
void out(std::ostream &o) const
Definition: mgtools.hh:477
Tools for transfer of data between grids.
This file contains various utility functions that augment the basic functionality of Dune.
boost::signals2::signal< void(Status)> informAboutRefinement
A signal that is emitted thrice on grid modifications, once before adaptation takes place and twice a...
Definition: gridmanager.hh:74
Status
The argument type of the signal that is emitted before and after grid adaptation.
Definition: gridmanager.hh:64
Class for transformations between ancestors and their children.
FullHierarchicIterator< Grid, Entity > Iterator
Definition: mgtools.hh:159
policy class for LocalTransfer These two structures are used for determining whether to perform a "no...
Definition: fetransfer.hh:280