DUNE-FEM (unstable)

auxiliarydofs.hh
1 #ifndef DUNE_FEM_SPACE_COMMON_AUXILIARYDOFS_HH
2 #define DUNE_FEM_SPACE_COMMON_AUXILIARYDOFS_HH
3 
4 #include <cassert>
5 #include <cstddef>
6 
7 #include <algorithm>
8 #include <iostream>
9 #include <limits>
10 #include <map>
11 #include <memory>
12 #include <set>
13 
16 #include <dune/common/ftraits.hh>
18 
19 #include <dune/grid/common/gridenums.hh>
21 
22 #include <dune/fem/storage/singletonlist.hh>
23 #include <dune/fem/misc/mpimanager.hh>
24 #include <dune/fem/space/common/commindexmap.hh>
25 #include <dune/fem/storage/envelope.hh>
26 
27 namespace Dune
28 {
29 
30  namespace Fem
31  {
32 
44  template< class GridPart, class Mapper >
46  {
48 
49  class LinkBuilder;
50 
51  public:
53  typedef GridPart GridPartType;
54 
56  typedef Mapper MapperType;
57 
58  protected:
59  typedef Fem :: CommunicationIndexMap IndexMapType;
60 
61  const GridPartType &gridPart_;
62  const MapperType &mapper_;
63 
64  // type of communication indices
65  IndexMapType auxiliarys_;
66 
67  public:
68  typedef typename IndexMapType :: IndexType IndexType;
69 
70  struct ConstIterator
71  {
72  typedef std::forward_iterator_tag iterator_category;
73  typedef const IndexType value_type;
74  typedef IndexType difference_type;
75  typedef IndexType* pointer;
76  typedef IndexType& reference;
77 
78  ConstIterator () = default;
79  ConstIterator ( const IndexMapType &auxiliarys, IndexType index ) : auxiliarys_( &auxiliarys ), index_( index ) {}
80 
81  const IndexType &operator* () const { return (*auxiliarys_)[ index_ ]; }
82  const IndexType *operator-> () const { return &(*auxiliarys_)[ index_ ]; }
83 
84  const IndexType &operator[] ( IndexType n ) const noexcept { return (*auxiliarys_)[ index_ + n ]; }
85 
86  bool operator== ( const ConstIterator &other ) const { return (index_ == other.index_); }
87  bool operator!= ( const ConstIterator &other ) const { return (index_ != other.index_); }
88 
89  ConstIterator &operator++ () { ++index_; return *this; }
90  ConstIterator operator++ ( int ) { ConstIterator copy( *this ); ++(*this); return copy; }
91 
92  ThisType &operator-- () noexcept { --index_; return *this; }
93  ThisType operator-- ( int ) noexcept { ThisType copy( *this ); --(*this); return copy; }
94 
95  ThisType &operator+= ( IndexType n ) noexcept { index_ += n; return *this; }
96  ThisType &operator-= ( IndexType n ) noexcept { index_ -= n; return *this; }
97 
98  ThisType operator+ ( IndexType n ) const noexcept { return ThisType( index_ + n ); }
99  ThisType operator- ( IndexType n ) const noexcept { return ThisType( index_ - n ); }
100 
101  friend ThisType operator+ ( IndexType n, const ThisType &i ) noexcept { return i + n; }
102 
103  IndexType operator- ( const ThisType &other ) const noexcept { return (index_ - other.index_); }
104 
105  bool operator< ( const ThisType &other ) const noexcept { return (index_ < other.index_); }
106  bool operator<= ( const ThisType &other ) const noexcept { return (index_ <= other.index_); }
107  bool operator>= ( const ThisType &other ) const noexcept { return (index_ >= other.index_); }
108  bool operator> ( const ThisType &other ) const noexcept { return (index_ > other.index_); }
109 
110  private:
111  const IndexMapType *auxiliarys_ = nullptr;
112  IndexType index_ = 0;
113  };
114 
115  AuxiliaryDofs ( const GridPartType &gridPart, const MapperType &mapper )
116  : gridPart_( gridPart ), mapper_( mapper )
117  {}
118 
119  AuxiliaryDofs ( const AuxiliaryDofs& ) = delete;
120 
122  IndexType operator [] ( const IndexType index ) const
123  {
124  return auxiliarys_[ index ];
125  }
126 
128  IndexType size () const
129  {
130  return auxiliarys_.size();
131  }
132 
134  IndexType primarySize () const
135  {
136  const IndexType last = auxiliarys_.size() - 1;
137  // last entry is the overall size, thus substract size - 1 from the
138  // overall number to obtain the number of primary dofs
139  return auxiliarys_[ last ] - last ;
140  }
141 
142  ConstIterator begin () const { return ConstIterator( auxiliarys_, 0 ); }
143  ConstIterator end () const { assert( size() > 0 ); return ConstIterator( auxiliarys_, size()-1 ); }
144 
146  bool contains ( IndexType index ) const { return std::binary_search( begin(), end(), index ); }
147 
148  [[deprecated("Use contains instead")]]
149  bool isSlave ( IndexType index ) const { return contains( index ); }
150 
151  void rebuild ()
152  {
153  std::set< IndexType > auxiliarySet;
154  buildMaps( auxiliarySet );
155  auxiliarys_.clear();
156  auxiliarys_.set( auxiliarySet );
157  }
158 
159  const GridPartType &gridPart () const { return gridPart_; }
160 
161  protected:
162  void buildMaps ( std::set< IndexType > &auxiliarySet )
163  {
164  // build linkage and index maps
165  for( int codim = 1; codim <= GridPartType::dimension; ++codim )
166  {
167  if( mapper_.contains( codim ) )
168  return buildCommunicatedMaps( auxiliarySet );
169  }
170  return buildDiscontinuousMaps( auxiliarySet );
171  }
172 
173  void buildDiscontinuousMaps ( std::set< IndexType > &auxiliarySet )
174  {
175  // if DoFs are only attached to codimension 0, we do not have to communicate
176  const auto idxpitype = GridPartType::indexSetPartitionType;
177  for( auto it = gridPart().template begin< 0, idxpitype >(), end = gridPart().template end< 0, idxpitype >(); it != end; ++it )
178  {
179  const auto& entity = *it;
180  if( entity.partitionType() != Dune::InteriorEntity )
181  mapper_.mapEachEntityDof( entity, [ &auxiliarySet ] ( IndexType, IndexType value ) { auxiliarySet.insert( value ); } );
182  }
183  // insert overall size at the end
184  auxiliarySet.insert( mapper_.size() );
185  }
186 
187  void buildCommunicatedMaps ( std::set< IndexType > &auxiliarySet )
188  {
189  // we have to skip communication when parallel program is executed only on one processor
190  // otherwise YaspGrid and Lagrange polorder=2 fails :(
191  if( gridPart().comm().size() > 1 )
192  {
193  try
194  {
195  LinkBuilder handle( auxiliarySet, gridPart(), mapper_ );
196  gridPart().communicate( handle, GridPartType::indexSetInterfaceType, ForwardCommunication );
197  }
198  catch( const Exception &e )
199  {
200  std::cerr << e << std::endl << "Exception thrown in: " << __FILE__ << " line:" << __LINE__ << std::endl;
201  std::abort();
202  }
203  }
204  // insert overall size at the end
205  auxiliarySet.insert( mapper_.size() );
206  }
207  };
208 
209 
210 
211  // AuxiliaryDofs::LinkBuilder
212  // ----------------------
213 
214  template< class GridPart, class Mapper >
215  class AuxiliaryDofs< GridPart, Mapper >::LinkBuilder
216  : public CommDataHandleIF< LinkBuilder, int > // int is data type to be communicated
217  {
218  public:
219  LinkBuilder( std::set< IndexType > &auxiliarySet, const GridPartType &gridPart, const MapperType &mapper )
220  : myRank_( gridPart.comm().rank() ), mySize_( gridPart.comm().size() ),
221  auxiliarySet_( auxiliarySet ), mapper_( mapper )
222  {}
223 
224  bool contains ( int dim, int codim ) const { return mapper_.contains( codim ); }
225  bool fixedSize ( int dim, int codim ) const { return false; }
226 
228  template< class MessageBuffer, class Entity >
229  void gather ( MessageBuffer &buffer, const Entity &entity ) const
230  {
231  // for sending ranks write rank
232  if( sendRank( entity ) )
233  buffer.write( myRank_ );
234  }
235 
240  template< class MessageBuffer, class EntityType >
241  void scatter ( MessageBuffer &buffer, const EntityType &entity, std::size_t n )
242  {
243  if( n == 1 )
244  {
245  int rank;
246  buffer.read( rank );
247 
248  assert( (rank >= 0) && (rank < mySize_) );
249 
250  // if entity in not interiorBorder insert anyway
251  if ( rank < myRank_ || ! sendRank( entity ) )
252  mapper_.mapEachEntityDof( entity, [this]( const int , const auto& value ){auxiliarySet_.insert( value );} );
253  }
254  }
255 
257  template< class Entity >
258  std::size_t size ( const Entity &entity ) const
259  {
260  return (sendRank( entity )) ? 1 : 0;
261  }
262 
263  protected:
264  template <class Entity>
265  bool sendRank(const Entity& entity) const
266  {
267  const PartitionType ptype = entity.partitionType();
268  return (ptype == InteriorEntity) || (ptype == BorderEntity);
269  }
270 
271  protected:
272  int myRank_, mySize_;
273  std::set< IndexType > &auxiliarySet_;
274  const MapperType &mapper_;
275  };
276 
277 
284  template <class AuxiliaryDofs, class F>
285  static void forEachAuxiliaryDof( const AuxiliaryDofs& auxiliaryDofs, F&& f )
286  {
287  // don't delete the last since this is the overall Size
288  const size_t auxiliarySize = auxiliaryDofs.size() - 1;
289  for(size_t auxiliary = 0; auxiliary<auxiliarySize; ++auxiliary)
290  {
291  // apply action to auxiliary dof
292  f( auxiliaryDofs[auxiliary] );
293  }
294  }
295 
302  template <class AuxiliaryDofs, class F>
303  static void forEachPrimaryDof( const AuxiliaryDofs& auxiliaryDofs, F&& f )
304  {
305  const size_t numAuxiliarys = auxiliaryDofs.size();
306  for( size_t auxiliary = 0, dof = 0 ; auxiliary < numAuxiliarys; ++auxiliary, ++dof )
307  {
308  const size_t nextAuxiliary = auxiliaryDofs[ auxiliary ];
309  for(; dof < nextAuxiliary; ++dof )
310  {
311  // apply action to primary dof
312  f( dof );
313  }
314  }
315  }
316 
317 
318  // PrimaryDofs
319  // -----------
320 
327  template< class AuxiliaryDofs >
328  struct PrimaryDofs;
329 
330  template< class GridPart, class Mapper >
331  struct PrimaryDofs< AuxiliaryDofs< GridPart, Mapper > >
332  {
333  typedef AuxiliaryDofs< GridPart, Mapper > AuxiliaryDofsType;
334  typedef typename AuxiliaryDofsType :: IndexType IndexType;
335 
336  struct ConstIterator
337  {
338  typedef std::forward_iterator_tag iterator_category;
339  typedef IndexType value_type;
340  typedef std::ptrdiff_t difference_type;
341  typedef Envelope< IndexType > pointer;
342  typedef IndexType reference;
343 
344  ConstIterator () = default;
345 
346  ConstIterator ( IndexType index, IndexType auxiliary )
347  : index_( index ), auxiliary_( auxiliary )
348  {}
349 
350  ConstIterator ( const AuxiliaryDofsType &auxiliaryDofs, IndexType index, IndexType auxiliary )
351  : auxiliaryDofs_( &auxiliaryDofs ), index_( index ), auxiliary_( auxiliary )
352  {
353  skipAuxiliarys();
354  }
355 
356  IndexType operator* () const { return index_; }
357  Envelope< IndexType > operator-> () const { return Envelope< IndexType >( index_ ); }
358 
359  bool operator== ( const ConstIterator &other ) const { return (index_ == other.index_); }
360  bool operator!= ( const ConstIterator &other ) const { return (index_ != other.index_); }
361 
362  ConstIterator &operator++ () { ++index_; skipAuxiliarys(); return *this; }
363  ConstIterator operator++ ( int ) { ConstIterator copy( *this ); ++(*this); return copy; }
364 
365  const AuxiliaryDofsType &auxiliaryDofs () const { assert( auxiliaryDofs_ ); return *auxiliaryDofs_; }
366 
367  bool contains( const IndexType index ) const { return ! auxiliaryDofs().contains( index ); }
368 
369  private:
370  void skipAuxiliarys ()
371  {
372  const IndexType aSize = auxiliaryDofs().size();
373  assert( auxiliary_ < aSize );
374  for( ; (index_ == auxiliaryDofs()[ auxiliary_ ]) && (++auxiliary_ != aSize); ++index_ )
375  continue;
376  }
377 
378  const AuxiliaryDofsType *auxiliaryDofs_ = nullptr;
379  IndexType index_ = 0, auxiliary_ = 0;
380  };
381 
382  [[deprecated("Use forEachPrimaryDof instead!")]]
383  explicit PrimaryDofs ( const AuxiliaryDofsType &auxiliaryDofs )
384  : auxiliaryDofs_( auxiliaryDofs )
385  {}
386 
387  ConstIterator begin () const { return ConstIterator( auxiliaryDofs_, 0, 0 ); }
388  ConstIterator end () const { return ConstIterator( auxiliaryDofs_[ auxiliaryDofs_.size()-1 ], auxiliaryDofs_.size() ); }
389 
390  IndexType size () const { return auxiliaryDofs_[ auxiliaryDofs_.size()-1 ] - (auxiliaryDofs_.size()-1); }
391 
392  private:
393  const AuxiliaryDofsType &auxiliaryDofs_;
394  };
395 
396 
397 
398  // primaryDofs
399  // -----------
400 
401  template< class AuxiliaryDofs >
402  [[deprecated("Use forEachPrimaryDof instead!" )]]
403  inline static PrimaryDofs< AuxiliaryDofs > primaryDofs ( const AuxiliaryDofs &auxiliaryDofs )
404  {
405  return PrimaryDofs< AuxiliaryDofs >( auxiliaryDofs );
406  }
407 
408  template< class AuxiliaryDofs >
409  [[deprecated("Use primaryDofs instead!" )]]
410  inline static PrimaryDofs< AuxiliaryDofs > masterDofs ( const AuxiliaryDofs &auxiliaryDofs )
411  {
412  return PrimaryDofs< AuxiliaryDofs >( auxiliaryDofs );
413  }
414 
416 
417  } // end namespace Fem
418 
419 } // end namespace Dune
420 #endif // #ifndef DUNE_FEM_SPACE_COMMON_AUXILIARYDOFS_HH
Wrapper class for entities.
Definition: entity.hh:66
PartitionType partitionType() const
Partition type of this entity.
Definition: entity.hh:127
In parallel computations the dofs of a discrete function are made up by all primary dofs....
Definition: auxiliarydofs.hh:46
Mapper interface.
Definition: mapper.hh:110
auto size() const
Return total number of entities in the entity set managed by the mapper.
Definition: mapper.hh:152
bool contains(const EntityType &e, IndexType &result) const
Returns true if the entity is contained in the index set and at the same time the array index is retu...
Definition: mapper.hh:167
Describes the parallel communication interface class for MessageBuffers and DataHandles.
A few common exception classes.
Type traits to determine the type of reals (when working with complex numbers)
Implements a generic iterator class for writing stl conformant iterators.
GridPart GridPartType
type of grid part
Definition: auxiliarydofs.hh:49
static void forEachAuxiliaryDof(const AuxiliaryDofs &auxiliaryDofs, F &&f)
Apply action encoded in Functor f to all auxiliary dofs.
Definition: auxiliarydofs.hh:285
bool contains(IndexType index) const
return true if index is contained, meaning it is a auxiliary dof
Definition: auxiliarydofs.hh:146
IndexType operator[](const IndexType index) const
return dof number of auxiliary for index
Definition: auxiliarydofs.hh:122
IndexType size() const
return number of auxiliary dofs
Definition: auxiliarydofs.hh:128
std::size_t size(const Entity &entity) const
return local dof size to be communicated
Definition: auxiliarydofs.hh:258
Mapper MapperType
type of used mapper
Definition: auxiliarydofs.hh:56
void scatter(MessageBuffer &buffer, const EntityType &entity, std::size_t n)
Definition: auxiliarydofs.hh:241
IndexType primarySize() const
return number of primaryDofs
Definition: auxiliarydofs.hh:134
static void forEachPrimaryDof(const AuxiliaryDofs &auxiliaryDofs, F &&f)
Apply action encoded in Functor f to all primary dofs.
Definition: auxiliarydofs.hh:303
void gather(MessageBuffer &buffer, const Entity &entity) const
read buffer and apply operation
Definition: auxiliarydofs.hh:229
PartitionType
Attributes used in the generic overlap model.
Definition: gridenums.hh:30
@ InteriorEntity
all interior entities
Definition: gridenums.hh:31
@ BorderEntity
on boundary between interior and overlap
Definition: gridenums.hh:32
@ ForwardCommunication
communicate as given in InterfaceType
Definition: gridenums.hh:171
concept MessageBuffer
Model of a message buffer.
Definition: messagebuffer.hh:17
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:259
EnableIfInterOperable< T1, T2, bool >::type operator>(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:683
EnableIfInterOperable< T1, T2, bool >::type operator<(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:637
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:237
EnableIfInterOperable< T1, T2, bool >::type operator>=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:705
EnableIfInterOperable< T1, T2, bool >::type operator<=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:660
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::bool_constant<((II==value)||...)> contains(std::integer_sequence< T, II... >, std::integral_constant< T, value >)
Checks whether or not a given sequence contains a value.
Definition: integersequence.hh:137
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
In parallel computations the dofs of a discrete function are made up by all primary dofs....
Definition: auxiliarydofs.hh:328
Traits for type conversions and type information.
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:264
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)