DUNE-FEM (unstable)

blockmapper.hh
1#ifndef DUNE_FEM_HPDG_SPACE_DISCONTINUOUSGALERKIN_BLOCKMAPPER_HH
2#define DUNE_FEM_HPDG_SPACE_DISCONTINUOUSGALERKIN_BLOCKMAPPER_HH
3
4#include <cassert>
5#include <cstddef>
6
7#include <algorithm>
8#include <functional>
9#include <limits>
10#include <type_traits>
11#include <utility>
12#include <vector>
13
15
16#include <dune/geometry/dimension.hh>
17
18#include <dune/grid/common/gridenums.hh>
19#include <dune/grid/utility/persistentcontainer.hh>
20
21#include <dune/fem/gridpart/common/gridpart.hh>
22#include <dune/fem/io/streams/streams.hh>
23#include <dune/fem/space/common/dofmanager.hh>
24#include <dune/fem/space/mapper/dofmapper.hh>
25
26#include <dune/fem/space/common/capabilities.hh>
27
28#include "datahandle.hh"
29#include "localdofstorage.hh"
30
31namespace Dune
32{
33
34 namespace Fem
35 {
36
37 namespace hpDG
38 {
39
40 // Internal forward declaration
41 // ----------------------------
42
43 template< class GridPart, class LocalKeys >
44 struct DiscontinuousGalerkinBlockMapper;
45
46
47
48#ifndef DOXYGEN
49
50 // DiscontinuousGalerkinBlockMapperTraits
51 // --------------------------------------
52
53 template< class GridPart, class LocalKeys >
54 struct DiscontinuousGalerkinBlockMapperTraits
55 {
56 using DofMapperType = DiscontinuousGalerkinBlockMapper< GridPart, LocalKeys >;
57 using ElementType = typename GridPart::template Codim< 0 >::EntityType;
58 using SizeType = std::size_t;
59 };
60
61#endif // #ifndef DOXYGEN
62
63
64
65 // DiscontinuousGalerkinBlockMapper
66 // --------------------------------
67
99 template< class GridPart, class LocalKeys >
101 : public AdaptiveDofMapper< DiscontinuousGalerkinBlockMapperTraits< GridPart, LocalKeys > >
102 {
105
106 public:
108 using SizeType = typename BaseType::SizeType;
111
113 using GridPartType = GridPart;
116
118 using LocalKeysType = LocalKeys;
120 using KeyType = typename LocalKeysType::KeyType;
121
122 private:
123 using DataHandleType = DataHandle< ThisType >;
124 friend class DataHandle< DiscontinuousGalerkinBlockMapper< GridPart, LocalKeys > >;
125
126 struct Reserve;
127 struct Resize;
128
129 using LocalDofStorageType = LocalDofStorage< GlobalKeyType >;
130
131 using GridType = typename GridPartType::GridType;
132 using GridElementType = typename GridType::template Codim< 0 >::Entity;
133
134 public:
137
142 template< class Function >
144 const LocalKeysType &localKeys,
145 const KeyType &value, Function function )
146 : gridPart_( gridPart ),
147 localKeys_( localKeys ),
148 key_( value ),
149 keys_( gridPart_.get().grid(), 0, std::make_pair( key_, key_ ) ),
150 size_( 0u ),
151 dofs_( gridPart_.get().grid(), 0 ),
152 dofManager_( DofManagerType::instance( gridPart.grid() ) )
153 {
154 auto first = gridPart.template begin< 0, All_Partition >();
155 auto last = gridPart.template end< 0, All_Partition >();
156 for( ; first != last; ++first )
157 {
158 const ElementType &element = *first;
159 const KeyType key = function( element );
160
161 const GridElementType &gridElement = gridEntity( element );
162 keys_[ gridElement ] = std::make_pair( key, key );
163
164 auto &dofs = dofs_[ gridElement ];
165 resize( dofs, localKeys.blocks( gridElement.type(), key ) );
166 }
167
168 dofManager_.get().addIndexSet( *this );
169 }
170
171 DiscontinuousGalerkinBlockMapper ( const GridPartType &gridPart,
172 const LocalKeysType &localKeys,
173 const KeyType &value )
174 : DiscontinuousGalerkinBlockMapper( gridPart, localKeys, value, [&value]( const ElementType & ){ return value; } )
175 {}
176
184 DiscontinuousGalerkinBlockMapper ( const ThisType & ) = delete;
185
187 DiscontinuousGalerkinBlockMapper ( ThisType && ) = default;
188
190 ThisType &operator= ( const ThisType & ) = delete;
191
193 ThisType &operator= ( ThisType && ) = default;
194
197#ifndef DOXYGEN
198
200 {
201 dofManager_.get().removeIndexSet( *this );
202 }
203
204#endif // #ifndef DOXYGEN
205
211 SizeType size () const { return size_; }
212
214 int maxNumDofs () const { return localKeys().maxBlocks(); }
215
217 SizeType numDofs ( const ElementType &element ) const
218 {
219 return numDofs( element, Codim< ElementType::codimension >() );
220 }
221
223 template< class Entity >
224 SizeType numEntityDofs ( const Entity &entity ) const
225 {
226 return numDofs( entity, Codim< Entity::codimension >() );
227 }
228
229 [[deprecated("Use onSubEntity method with char vector instead")]]
230 void onSubEntity ( const ElementType &element, int i, int c, std::vector< bool > &indices ) const
231 {
232 std::vector< char > _idx;
233 onSubEntity(element, i, c, _idx);
234 indices.resize( _idx.size() );
235 for (std::size_t i=0; i<_idx.size();++i)
236 _idx[i] = indices[i] > 0;
237 }
238 // this method returns which local dofs are attached to the given subentity.
239 // indices[locDofNr] =
240 // 0 : not attached, not equal to 0 : attached
241 // (so this method can still be used in the way the deprecated method was).
242 // New: In case the dof can be associated to a component of the
243 // space, the value returned is that component+1. In other
244 // cases (normal velocity for RT for example) the value is -1).
245 // So indices[i] is in [-1,dimRange+1]
246 void onSubEntity ( const ElementType &element, int i, int c, std::vector< char > &indices ) const
247 {
248 indices.resize( numDofs(element) );
249 if (c == 0)
250 std::fill(indices.begin(),indices.end(),1);
251 else
252 std::fill(indices.begin(),indices.end(),0);
253 }
254
256 static constexpr bool contains ( const int codim ) { return (codim == 0); }
257
259 static constexpr bool fixedDataSize ( int codim ) { return (codim != 0); }
260
262 template< class Function >
263 void mapEach ( const ElementType &element, Function function ) const
264 {
265 mapEach( element, function, Codim< ElementType::codimension >() );
266 }
267
269 template< class Entity, class Function >
270 void mapEachEntityDof ( const Entity &entity, Function function ) const
271 {
272 mapEach( entity, function, Codim< Entity::codimension >() );
273 }
274
276 SizeType numberOfHoles ( const int block ) const
277 {
278 assert( block == 0 );
279 return indices_.size();
280 }
281
283 GlobalKeyType oldIndex ( const int hole, const int block ) const
284 {
285 assert( block == 0 );
286 GlobalKeyType dof = indices_[ hole ].first;
288 return std::move( dof );
289 }
290
292 GlobalKeyType newIndex ( const int hole, const int block ) const
293 {
294 assert( block == 0 );
295 return indices_[ hole ].second;
296 }
297
299 static constexpr bool consecutive () { return true; }
300
302 static constexpr SizeType oldOffSet ( const int block ) { return 0u; }
303
305 static constexpr SizeType offSet ( const int block ) { return 0u; }
306
308 static constexpr SizeType numBlocks () { return 1u; }
309
317 template< class Element >
318 typename std::enable_if< (std::is_same< Element, ElementType >::value || std::is_same< Element, GridElementType >::value), const KeyType & >::type
319 key ( const Element &element ) const
320 {
321 return keys_[ gridEntity( element ) ].first;
322 }
323
325 void mark ( const KeyType &key, const ElementType &element )
326 {
327 assert( gridPart().indexSet().contains( element ) );
328 keys_[ gridEntity( element ) ].second = key;
329 }
330
332 KeyType getMark ( const ElementType &element ) const
333 {
334 assert( gridPart().indexSet().contains( element ) );
335 return keys_[ gridEntity( element ) ].second;
336 }
337
339 template< class Function >
340 bool adapt ( Function function );
341
343 bool adapt ()
344 {
345 auto function = []( const ElementType &,
346 const KeyType &, const KeyType &,
347 const std::vector< std::size_t > &,
348 const std::vector< std::size_t > & )
349 {};
350 return adapt( function );
351 }
352
360 const DofManagerType &dofManager () const { return dofManager_.get(); }
361
363 void insertEntity ( const GridElementType &gridElement )
364 {
365 resize( dofs_ );
366 resize( keys_, std::make_pair( key_, key_ ) );
367
368 resize( dofs_[ gridElement ], localKeys().blocks( gridElement.type(), key( gridElement ) ) );
369 }
370
372 void removeEntity ( const GridElementType &gridElement )
373 {
374 auto &dofs = dofs_[ gridElement ];
375
376 size_ = dofs.reserve( 0u, Reserve( size_ ) );
377 Resize function( holes_ );
378 for( auto dof : dofs )
379 function( dof );
380 }
381
383 void insertNewEntity ( const GridElementType &gridElement )
384 {
385 if( gridElement.isNew() )
386 {
387 resize( dofs_[ gridElement ], localKeys().blocks( gridElement.type(), key( gridElement ) ) );
388 assert( gridElement.hasFather() );
389 const GridElementType &father = gridElement.father();
390 insertNewEntity( father );
391 removeEntity( father );
392 }
393 else
394 {
395 auto &dofs = dofs_[ gridElement ];
396 resize( dofs, localKeys().blocks( gridElement.type(), key( gridElement ) ) );
397 for( auto dof : dofs )
398 {
399 auto iterator = std::lower_bound( holes_.begin(), holes_.end(), dof );
400 if( iterator != holes_.end() && *iterator == dof )
401 holes_.erase( iterator );
402 }
403 }
404 }
405
406 void resize ()
407 {
408 resize( dofs_ );
409 resize( keys_, std::make_pair( key_, key_ ) );
410
411 auto first = gridPart().template begin< 0, All_Partition >();
412 auto last = gridPart().template end< 0, All_Partition >();
413 for( ; first != last; ++first )
414 {
415 const ElementType &element = *first;
416 insertNewEntity( gridEntity( element ) );
417 }
418#if 0
419 auto &dofs = dofs_[ gridEntity( element ) ];
420 resize( dofs, localKeys().blocks( element.type(), key( element ) ) );
421#endif
422 }
423
425 bool compress ();
426
428 template< class Traits >
430 {
431 DUNE_THROW( NotImplemented, "Method write() not implemented yet" );
432 }
433
435 template< class Traits >
437 {
438 DUNE_THROW( NotImplemented, "Method read() not implemented yet" );
439 }
440
442 void backup () const
443 {
444 DUNE_THROW( NotImplemented, "Method backup() not implemented" );
445 }
446
448 void restore ()
449 {
450 DUNE_THROW( NotImplemented, "Method restore() not implemented" );
451 }
452
453 private:
454 bool compressed () const { return holes_.empty(); }
455
456 template< class Element, class Function >
457 void mapEach ( const Element &element, Function function, Codim< 0 > ) const
458 {
459 const auto &dofs = dofs_[ gridEntity( element ) ];
460 std::size_t size = dofs.size();
461 for( std::size_t i = 0; i < size; ++i )
462 function( i, dofs[ i ] );
463 }
464
465 template< class Entity, class Function, int codim >
466 void mapEach ( const Entity &entity, Function function, Codim< codim > ) const
467 {}
468
469 template< class Element >
470 SizeType numDofs ( const Element &element, Codim< 0 > ) const
471 {
472 return dofs_[ gridEntity( element ) ].size();
473 }
474
475 template< class Entity, int codim >
476 SizeType numDofs ( const Entity &entity, Codim< codim > ) const
477 {
478 return 0u;
479 }
480
481 void resize ( LocalDofStorageType &dofs, SizeType n )
482 {
483 size_ = dofs.reserve( n, Reserve( size_ ) );
484 dofs.resize( Resize( holes_ ) );
485 }
486
487 template< class T >
488 static void resize ( PersistentContainer< GridType, T > &container, const T &value = T() )
489 {
490 container.resize( value );
491 container.shrinkToFit();
492 }
493
494 const GridPartType &gridPart () const { return gridPart_.get(); }
495
496 const LocalKeysType &localKeys () const { return localKeys_.get(); }
497
498 std::reference_wrapper< const GridPartType > gridPart_;
499 std::reference_wrapper< const LocalKeysType > localKeys_;
500
501 const KeyType key_;
502 PersistentContainer< GridType, std::pair< KeyType, KeyType > > keys_;
503
504 SizeType size_;
506
507 std::vector< GlobalKeyType > holes_;
508 std::vector< std::pair< GlobalKeyType, GlobalKeyType > > indices_;
509
510 std::reference_wrapper< DofManagerType > dofManager_;
511 };
512
513
514
515 // DiscontinuousGalerkinBlockMapper::Reserve
516 // -----------------------------------------
517
518 template< class GridPart, class LocalKeys >
519 struct DiscontinuousGalerkinBlockMapper< GridPart, LocalKeys >::Reserve
520 {
521 explicit Reserve ( SizeType &size ) : size_( size ) {}
522
523 GlobalKeyType operator() () { return size_++; }
524
525 operator SizeType () const { return size_; }
526
527 private:
528 SizeType &size_;
529 };
530
531
532
533 // DiscontinuousGalerkinBlockMapper::Resize
534 // ----------------------------------------
535
536 template< class GridPart, class LocalKeys >
537 struct DiscontinuousGalerkinBlockMapper< GridPart, LocalKeys >::Resize
538 {
539 explicit Resize ( std::vector< GlobalKeyType > &holes )
540 : holes_( holes )
541 {
542 assert( std::is_sorted( holes_.begin(), holes_.end() ) );
543 }
544
545 ~Resize ()
546 {
547 assert( std::is_sorted( holes_.begin(), holes_.end() ) );
548 }
549
550 void operator() ( const GlobalKeyType &dof )
551 {
552 auto iterator = std::lower_bound( holes_.begin(), holes_.end(), dof );
553 if( iterator == holes_.end() || *iterator != dof )
554 holes_.insert( iterator, dof );
555 }
556
557 private:
558 std::vector< GlobalKeyType > &holes_;
559 };
560
561
562
563 // DiscontinuousGalerkinBlockMapper::adapt
564 // ---------------------------------------
565
566 template< class GridPart, class LocalKeys >
567 template< class Function >
569 {
570 DataHandleType dataHandle( *this );
571 gridPart().communicate( dataHandle, InteriorBorder_All_Interface, ForwardCommunication );
572
573 std::vector< std::size_t > origin, destination;
574 origin.reserve( maxNumDofs() );
575 destination.reserve( maxNumDofs() );
576
577 std::size_t count = 0;
578
579 auto first = gridPart().template begin< 0, All_Partition >();
580 auto last = gridPart().template end< 0, All_Partition >();
581 for( ; first != last; ++first )
582 {
583 const ElementType &element = *first;
584 const GridElementType &gridElement = gridEntity( element );
585 auto &keys = keys_[ gridElement ];
586 if( keys.first == keys.second )
587 continue;
588
589 // remember old state
590 const KeyType prior = keys.first;
591 auto &dofs = dofs_[ gridElement ];
592 origin.resize( dofs.size() );
593 std::copy( dofs.begin(), dofs.end(), origin.begin() );
594
595 // reset to new state
596 keys.first = keys.second;
597 resize( dofs, localKeys().blocks( gridElement.type(), keys.first ) );
598
599 // call function
600 destination.resize( dofs.size() );
601 std::copy( dofs.begin(), dofs.end(), destination.begin() );
602 function( element, prior, keys.first, origin, destination );
603
604 ++count;
605 }
606 return (count > 0u);
607 }
608
609
610
611 // DiscontinuousGalerkinBlockMapper::compress
612 // ------------------------------------------
613
614 template< class GridPart, class LocalKeys >
616 {
617 // resize persistent containers
618 resize( dofs_ );
619 resize( keys_, std::make_pair( key_, key_ ) );
620
621 for( auto &dofs : dofs_ )
622 dofs.resize( Resize( holes_ ) );
623
624 // check if compress is necessary
625 if( holes_.empty() )
626 {
627 indices_.clear();
628 return false;
629 }
630
631 // get number of dofs after compress
632 assert( size_ >= holes_.size() );
633 size_ -= holes_.size();
634
635 // remove trailing indices
636 auto iterator = std::lower_bound( holes_.begin(), holes_.end(), size_ );
637 holes_.erase( iterator, holes_.end() );
638
639 // initialize vector of old and new indices
640 auto assign = []( GlobalKeyType newIndex ) -> std::pair< GlobalKeyType, GlobalKeyType >
641 {
643 return std::make_pair( oldIndex, newIndex );
644 };
645 indices_.resize( holes_.size() );
646 std::transform( holes_.begin(), holes_.end(), indices_.begin(), assign );
647
648 // update local dof storages
649 std::size_t hole = 0u;
650 for( auto &dofs : dofs_ )
651 {
652 for( auto &dof : dofs )
653 {
654 if( dof >= size_ )
655 {
656 auto &indices = indices_.at( hole++ );
657 indices.first = dof;
658 dof = indices.second;
659 }
660 }
661 }
662
663 assert( hole == holes_.size() );
664 holes_.clear();
665
666 // replace all but markers currently used by default value
667 PersistentContainer< GridType, std::pair< KeyType, KeyType > > tmp( gridPart().grid(), 0, std::make_pair( key_, key_ ) );
668 auto first = gridPart().template begin< 0, All_Partition >();
669 auto last = gridPart().template end< 0, All_Partition >();
670 for( ; first != last; ++first )
671 {
672 const ElementType &element = *first;
673 const GridElementType &gridElement = gridEntity( element );
674 tmp[ gridElement ] = keys_[ gridElement ];
675 }
676 keys_.swap( tmp );
677
678 return true;
679 }
680
681 } // namespace hpDG
682
683 namespace Capabilities
684 {
685 // isConsecutiveIndexSet
686 // ---------------------
687
688 template< class GridPart, class LocalKeys >
689 struct isConsecutiveIndexSet< hpDG::DiscontinuousGalerkinBlockMapper< GridPart, LocalKeys > >
690 {
691 static const bool v = true;
692 };
693
694 // isAdaptiveDofMapper
695 // -------------------
696
697 template< class GridPart, class LocalKeys >
698 struct isAdaptiveDofMapper< hpDG::DiscontinuousGalerkinBlockMapper< GridPart, LocalKeys > >
699 {
700 static const bool v = true;
701 };
702
703 } // namespace Capabilities
704
705 } // namespace Fem
706
707} // namespace Dune
708
709#endif // #ifndef DUNE_FEM_HPDG_SPACE_DISCONTINUOUSGALERKIN_BLOCKMAPPER_HH
Wrapper class for entities.
Definition: entity.hh:66
Extended interface for adaptive DoF mappers.
Definition: dofmapper.hh:219
SizeType GlobalKeyType
at the moment this should be similar to SizeType
Definition: dofmapper.hh:230
BaseType::SizeType SizeType
type of size integer
Definition: dofmapper.hh:227
Definition: dofmanager.hh:786
Traits::ElementType ElementType
type of codimension 0 entities
Definition: dofmapper.hh:54
Abstract class representing a function.
Definition: function.hh:50
abstract interface for an input stream
Definition: streams.hh:190
abstract interface for an output stream
Definition: streams.hh:48
Default exception for dummy implementations.
Definition: exceptions.hh:263
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
@ ForwardCommunication
communicate as given in InterfaceType
Definition: gridenums.hh:171
@ InteriorBorder_All_Interface
send interior and border, receive all entities
Definition: gridenums.hh:88
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
Dune namespace.
Definition: alignedallocator.hh:13
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:447
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition: integersequence.hh:22
STL namespace.
Static tag representing a codimension.
Definition: dimension.hh:24
An -adaptive Dune::Fem::DofMapper.
Definition: blockmapper.hh:102
void backup() const
this mapper has no I/O capabilities
Definition: blockmapper.hh:442
static constexpr SizeType oldOffSet(const int block)
return 0 (this mapper has no offset)
Definition: blockmapper.hh:302
SizeType size() const
return number of dofs
Definition: blockmapper.hh:211
GlobalKeyType newIndex(const int hole, const int block) const
return new index of given hole during compression
Definition: blockmapper.hh:292
std::enable_if<(std::is_same< Element, ElementType >::value||std::is_same< Element, GridElementType >::value), constKeyType & >::type key(const Element &element) const
get key currently assigned to an entity
Definition: blockmapper.hh:319
typename LocalKeysType::KeyType KeyType
key type
Definition: blockmapper.hh:120
static constexpr bool consecutive()
return true (this mapper yields a consecutive DOF numbering)
Definition: blockmapper.hh:299
GridPart GridPartType
grid part type
Definition: blockmapper.hh:113
void write(OutStreamInterface< Traits > &)
this mapper has no I/O capabilities
Definition: blockmapper.hh:429
void mapEachEntityDof(const Entity &entity, Function function) const
map local dof to global key
Definition: blockmapper.hh:270
DiscontinuousGalerkinBlockMapper(const ThisType &)=delete
copy constructor
void mapEach(const ElementType &element, Function function) const
map local dof to global key
Definition: blockmapper.hh:263
LocalKeys LocalKeysType
basis function sets type
Definition: blockmapper.hh:118
SizeType numEntityDofs(const Entity &entity) const
return number of dofs for given element
Definition: blockmapper.hh:224
ThisType & operator=(const ThisType &)=delete
assignment operator
typename BaseType::ElementType ElementType
element type
Definition: blockmapper.hh:115
void insertNewEntity(const GridElementType &gridElement)
add DOFs for new element
Definition: blockmapper.hh:383
bool adapt()
please doc me
Definition: blockmapper.hh:343
void insertEntity(const GridElementType &gridElement)
add DOFs for element
Definition: blockmapper.hh:363
static constexpr bool fixedDataSize(int codim)
return true if number of dofs is fixed for given codimension
Definition: blockmapper.hh:259
const DofManagerType & dofManager() const
return DOF manager
Definition: blockmapper.hh:360
KeyType getMark(const ElementType &element) const
get key to be assigned to an entity after next call to adapt()
Definition: blockmapper.hh:332
bool compress()
compress DOF mapping
Definition: blockmapper.hh:615
DiscontinuousGalerkinBlockMapper(ThisType &&)=default
move constructor
typename BaseType::GlobalKeyType GlobalKeyType
global key type
Definition: blockmapper.hh:110
void read(InStreamInterface< Traits > &)
this mapper has no I/O capabilities
Definition: blockmapper.hh:436
SizeType numDofs(const ElementType &element) const
return number of dofs for given element
Definition: blockmapper.hh:217
int maxNumDofs() const
return upper bound for number of dofs
Definition: blockmapper.hh:214
SizeType numberOfHoles(const int block) const
return number of holes during compression
Definition: blockmapper.hh:276
static constexpr bool contains(const int codim)
return true if dofs are associated to codimension
Definition: blockmapper.hh:256
void removeEntity(const GridElementType &gridElement)
mark DOFs for removal
Definition: blockmapper.hh:372
GlobalKeyType oldIndex(const int hole, const int block) const
return old index of given hole during compression
Definition: blockmapper.hh:283
static constexpr SizeType offSet(const int block)
return 0 (this mapper has no offset)
Definition: blockmapper.hh:305
void restore()
this mapper has no I/O capabilities
Definition: blockmapper.hh:448
void mark(const KeyType &key, const ElementType &element)
set key to be assigned to an entity after next call to adapt()
Definition: blockmapper.hh:325
static constexpr SizeType numBlocks()
return 1 (this mapper has one block)
Definition: blockmapper.hh:308
typename BaseType::SizeType SizeType
size type
Definition: blockmapper.hh:108
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 12, 23:30, 2024)