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
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
27namespace 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
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 >
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:53
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
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:638
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:684
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:661
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:238
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:706
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:260
Dune namespace.
Definition: alignedallocator.hh:13
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
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
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.111.3 (Nov 21, 23:30, 2024)