DUNE-FEM (unstable)

ghost.hh
1#ifndef DUNE_FEM_SPACE_MAPPER_GHOST_HH
2#define DUNE_FEM_SPACE_MAPPER_GHOST_HH
3
4#include <cstddef>
5
6#include <algorithm>
7#include <tuple>
8#include <type_traits>
9#include <utility>
10#include <vector>
11
13#include <dune/grid/common/gridenums.hh>
14
15#include <dune/fem/gridpart/common/indexset.hh>
16#include <dune/fem/space/mapper/capabilities.hh>
17#include <dune/fem/storage/envelope.hh>
18
19namespace Dune
20{
21
22 namespace Fem
23 {
24
25 // External Forward Declarations
26 // -----------------------------
27
28 template< class GridPart, class Mapper >
29 class AuxiliaryDofs;
30
31 template< class AuxiliaryDofs >
32 struct PrimaryDofs;
33
34
35
36 namespace __GhostDofMapper
37 {
38
39 // BuildDataHandle
40 // ---------------
41
42 template< class BaseMapper >
43 struct BuildDataHandle
44 : public CommDataHandleIF< BuildDataHandle< BaseMapper >, std::pair< int, std::size_t > >
45 {
46 typedef std::pair< int, std::size_t > Data;
47
48 explicit BuildDataHandle ( int rank, const BaseMapper &baseMapper, std::vector< std::tuple< int, std::size_t, std::size_t > > &masters )
49 : rank_( rank ), baseMapper_( baseMapper ), masters_( masters )
50 {}
51
52 bool contains ( int dim, int codim ) const { return baseMapper_.contains( codim ); }
53 bool fixedSize ( int dim, int codim ) const { return baseMapper_.fixedDataSize( codim ); }
54
55 template< class Buffer, class Entity >
56 void gather ( Buffer &buffer, const Entity &entity ) const
57 {
58 baseMapper_.mapEachEntityDof( entity, [ this, &buffer ] ( int, auto index ) {
59 std::get< 0 >( masters_[ index ] ) = rank_;
60 buffer.write( Data( std::get< 0 >( masters_[ index ] ), std::get< 1 >( masters_[ index ] ) ) );
61 } );
62 }
63
64 template< class Buffer, class Entity >
65 void scatter ( Buffer &buffer, const Entity &entity, std::size_t n )
66 {
67 assert( n == size( entity ) );
68
69 baseMapper_.mapEachEntityDof( entity, [ this, &buffer ] ( int, auto index ) {
70 Data remote( -1, index );
71 buffer.read( remote );
72 assert( remote.first >= 0 );
73
74 auto &local = masters_[ index ];
75 if( (std::get< 0 >( local ) < 0) || (remote.first < std::get< 0 >( local )) )
76 std::tie( std::get< 0 >( local ), std::get< 1 >( local ) ) = remote;
77 } );
78 }
79
80 template< class Entity >
81 std::size_t size ( const Entity &entity ) const
82 {
83 return baseMapper_.numEntityDofs( entity );
84 }
85
86 protected:
87 int rank_;
88 const BaseMapper &baseMapper_;
89 std::vector< std::tuple< int, std::size_t, std::size_t > > &masters_;
90 };
91
92
93
94 // ConstIterator
95 // -------------
96
97 template< class Index >
98 class ConstIterator
99 {
100 typedef ConstIterator< Index > ThisType;
101
102 public:
103 typedef std::random_access_iterator_tag iterator_category;
104 typedef Index value_type;
105 typedef Index difference_type;
106 typedef Envelope< Index > pointer;
107 typedef Index reference;
108
109 ConstIterator () noexcept = default;
110 explicit ConstIterator ( Index index ) noexcept : index_( index ) {}
111
112 Index operator* () const noexcept { return index_; }
113 Envelope< Index > operator-> () const noexcept { return Envelope< Index >( index_ ); }
114
115 Index operator[] ( Index n ) const noexcept { return index_ + n; }
116
117 bool operator== ( const ThisType &other ) const noexcept { return (index_ == other.index_); }
118 bool operator!= ( const ThisType &other ) const noexcept { return (index_ != other.index_); }
119
120 ThisType &operator++ () noexcept { ++index_; return *this; }
121 ThisType operator++ ( int ) noexcept { ThisType copy( *this ); ++(*this); return copy; }
122
123 ThisType &operator-- () noexcept { --index_; return *this; }
124 ThisType operator-- ( int ) noexcept { ThisType copy( *this ); --(*this); return copy; }
125
126 ThisType &operator+= ( Index n ) noexcept { index_ += n; return *this; }
127 ThisType &operator-= ( Index n ) noexcept { index_ -= n; return *this; }
128
129 ThisType operator+ ( Index n ) const noexcept { return ThisType( index_ + n ); }
130 ThisType operator- ( Index n ) const noexcept { return ThisType( index_ - n ); }
131
132 friend ThisType operator+ ( Index n, const ThisType &i ) noexcept { return i + n; }
133
134 Index operator- ( const ThisType &other ) const noexcept { return (index_ - other.index_); }
135
136 bool operator< ( const ThisType &other ) const noexcept { return (index_ < other.index_); }
137 bool operator<= ( const ThisType &other ) const noexcept { return (index_ <= other.index_); }
138 bool operator>= ( const ThisType &other ) const noexcept { return (index_ >= other.index_); }
139 bool operator> ( const ThisType &other ) const noexcept { return (index_ > other.index_); }
140
141 private:
142 Index index_ = 0;
143 };
144
145 } // namespace __GhostDofMapper
146
147
148
149 // GhostDofMapper
150 // --------------
151
152 template< class GridPart, class BaseMapper, class GlobalKey = std::size_t >
153 class GhostDofMapper
154 {
155 typedef GhostDofMapper< GridPart, BaseMapper, GlobalKey > ThisType;
156
157 public:
158 typedef GridPart GridPartType;
159 typedef BaseMapper BaseMapperType;
160
161 typedef std::size_t SizeType;
162 typedef GlobalKey GlobalKeyType;
163
164 typedef typename BaseMapperType::ElementType ElementType;
165
166 GhostDofMapper ( const GridPartType &gridPart, BaseMapperType &baseMapper, const InterfaceType commInterface )
167 : gridPart_( gridPart ), baseMapper_( baseMapper ), commInterface_(commInterface)
168 {
169 update();
170 }
171
172 GhostDofMapper ( const ThisType & ) = delete;
173 GhostDofMapper ( ThisType && ) = delete;
174
175 ThisType &operator= ( const ThisType & ) = delete;
176 ThisType &operator= ( ThisType && ) = delete;
177
178 template< class Functor >
179 void mapEach ( const ElementType &element, Functor f ) const
180 {
181 baseMapper().mapEach( element, [ this, &f ] ( auto local, auto i ) { f( local, mapping_[ i ] ); } );
182 }
183
184 void map ( const ElementType &element, std::vector< GlobalKeyType > &indices ) const
185 {
186 indices.resize( numDofs( element ) );
187 mapEach( element, [ &indices ] ( int local, GlobalKeyType global ) { indices[ local ] = global; } );
188 }
189
190 [[deprecated("Use onSubEntity method with char vector instead")]]
191 void onSubEntity ( const ElementType &element, int i, int c, std::vector< bool > &indices ) const
192 {
193 std::vector< char > _idx;
194 onSubEntity(element, i, c, _idx);
195 indices.resize( _idx.size() );
196 for (std::size_t i=0; i<_idx.size();++i)
197 _idx[i] = indices[i] > 0;
198 }
199 // this method returns which local dofs are attached to the given subentity.
200 // indices[locDofNr] =
201 // 0 : not attached, not equal to 0 : attached
202 // (so this method can still be used in the way the deprecated method was).
203 // New: In case the dof can be associated to a component of the
204 // space, the value returned is that component+1. In other
205 // cases (normal velocity for RT for example) the value is -1).
206 // So indices[i] is in [-1,dimRange+1]
207 void onSubEntity ( const ElementType &element, int i, int c, std::vector< char > &indices ) const
208 {
209 baseMapper().onSubEntity( element, i, c, indices );
210 }
211
212 unsigned int maxNumDofs () const { return baseMapper().maxNumDofs(); }
213 unsigned int numDofs ( const ElementType &element ) const { return baseMapper().numDofs( element ); }
214
215 // assignment of DoFs to entities
216
217 template< class Entity, class Functor >
218 void mapEachEntityDof ( const Entity &entity, Functor f ) const
219 {
220 baseMapper().mapEachEntityDof( entity, [ this, &f ] ( auto local, auto i ) { f( local, mapping_[ i ] ); } );
221 }
222
223 template< class Entity >
224 void mapEntityDofs ( const Entity &entity, std::vector< GlobalKeyType > &indices ) const
225 {
226 indices.resize( numEntityDofs( entity ) );
227 mapEachEntityDof( entity, [ &indices ] ( int local, GlobalKeyType global ) { indices[ local ] = global; } );
228 }
229
230 template< class Entity >
231 unsigned int numEntityDofs ( const Entity &entity ) const
232 {
233 return baseMapper().numEntityDofs( entity );
234 }
235
236 // global information
237
238 bool contains ( int codim ) const { return baseMapper().contains( codim ); }
239
240 bool fixedDataSize ( int codim ) const { return baseMapper().fixedDataSize( codim ); }
241
242 SizeType interiorSize () const { return interiorSize_; }
243 SizeType ghostSize () const { return ghostSize_; }
244
245 SizeType size () const { return interiorSize() + ghostSize(); }
246
247 InterfaceType communicationInterface() const { return commInterface_; }
248
249 // adaptation interface
250
251 bool consecutive () const { return false; }
252
253 int numBlocks () const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
254 SizeType offSet ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
255 SizeType oldOffSet ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
256 SizeType numberOfHoles ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
257 SizeType oldIndex ( SizeType hole, int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
258 SizeType newIndex ( SizeType hole, int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
259
260 // update
261
262 void update ()
263 {
264 std::size_t baseSize = baseMapper().size();
265 mapping_.resize( baseSize );
266
267 std::vector< std::tuple< int, std::size_t, std::size_t > > masters( baseSize );
268 for( std::size_t i = 0; i < baseSize; ++i )
269 masters[ i ] = std::make_tuple( -1, i, i );
270
271 const int rank = gridPart().comm().rank();
272 __GhostDofMapper::BuildDataHandle< BaseMapper > dataHandle( rank, baseMapper_, masters );
273
274 gridPart().communicate( dataHandle, communicationInterface(), ForwardCommunication );
275 // at this point all shared DoFs are assigned to their master rank
276 // all other DoFs (with rank -1) are not shared at all
277
278 // assign indices to interiors
279 interiorSize_ = ghostSize_ = 0;
280 for( const auto &m : masters )
281 {
282 if( (std::get< 0 >( m ) == -1) || (std::get< 0 >( m ) == rank ) )
283 mapping_[ std::get< 2 >( m ) ] = interiorSize_++;
284 else
285 masters[ ghostSize_++ ] = m;
286 }
287 masters.resize( ghostSize_ );
288
289 // sort the masters (by the first two components) to find duplicate ghosts
290 const auto less = [] ( auto a, auto b ) { return (std::get< 0 >( a ) < std::get< 0 >( b )) || ((std::get< 0 >( a ) == std::get< 0 >( b )) && (std::get< 1 >( a ) < std::get< 1 >( b ))); };
291 std::sort( masters.begin(), masters.end(), less );
292
293 // assign indices to ghosts
294 ghostSize_ = 0;
295 std::tuple< int, std::size_t, std::size_t > current( -1, 0, 0 );
296 for( const auto &m : masters )
297 {
298 if( less( current, m ) )
299 {
300 current = m;
301 std::get< 2 >( current ) = interiorSize_ + ghostSize_++;
302 }
303 mapping_[ std::get< 2 >( m ) ] = std::get< 2 >( current );
304 }
305 }
306
307 const GridPartType &gridPart () const { return gridPart_; }
308 const BaseMapperType &baseMapper () const { return baseMapper_; }
309
310 const std::vector< GlobalKeyType > &mapping () const { return mapping_; }
311
312 private:
313 const GridPartType &gridPart_;
314 BaseMapperType &baseMapper_;
315 const InterfaceType commInterface_;
316 std::vector< GlobalKeyType > mapping_;
317 SizeType interiorSize_, ghostSize_;
318 };
319
320
321
322 // Capabilities for IndexSetDofMapper
323 // ----------------------------------
324
325 namespace Capabilities
326 {
327
328 template< class GridPart, class BaseMapper, class GlobalKey >
329 struct isAdaptiveDofMapper< GhostDofMapper< GridPart, BaseMapper, GlobalKey > >
330 {
331 static const bool v = false;
332 };
333
334 template< class GridPart, class BaseMapper, class GlobalKey >
335 struct isConsecutiveIndexSet< GhostDofMapper< GridPart, BaseMapper, GlobalKey > >
336 {
337 static const bool v = true;
338 };
339
340 } // namespace Capabilities
341
342
343
344 // AuxiliaryDofs for GhostDofMapper
345 // ----------------------------
346
347 template< class GridPart, class BaseMapper, class GlobalKey >
348 class AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > >
349 {
350 typedef AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > > ThisType;
351
352 public:
353 typedef GridPart GridPartType;
354 typedef GhostDofMapper< GridPart, BaseMapper, GlobalKey > MapperType;
355
356 typedef typename MapperType::GlobalKeyType GlobalKeyType;
357 typedef typename MapperType::SizeType SizeType;
358
359 typedef __GhostDofMapper::ConstIterator< GlobalKeyType > ConstIteratorType;
360
361 explicit AuxiliaryDofs ( const MapperType &mapper )
362 : mapper_( mapper )
363 {}
364
365 AuxiliaryDofs ( const GridPartType &gridPart, const MapperType &mapper )
366 : AuxiliaryDofs( mapper )
367 {}
368
370 GlobalKeyType operator [] ( int index ) const { return mapper().interiorSize() + index; }
371
373 SizeType size () const { return mapper().ghostSize()+1; }
374
376 SizeType primarySize () const { return mapper().interiorSize(); }
377
378 ConstIteratorType begin () const { return ConstIteratorType( mapper().interiorSize() ); }
379 ConstIteratorType end () const { return ConstIteratorType( mapper().interiorSize() + mapper().ghostSize() ); }
380
382 bool contains ( GlobalKeyType index ) const { return (static_cast< SizeType >( index ) >= mapper().interiorSize()); }
383
384 void rebuild () {}
385
386 const MapperType &mapper () const { return mapper_; }
387 const GridPartType &gridPart () const { return mapper().gridPart(); }
388
389 private:
390 const MapperType &mapper_;
391 };
392
393
402 template <class GridPart, class BaseMapper, class GlobalKey, class F>
403 static void forEachPrimaryDof( const AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > >& auxiliaryDofs, F&& f )
404 {
405 const size_t size = auxiliaryDofs.mapper().interiorSize();
406 for( size_t dof = 0 ; dof<size; ++dof )
407 {
408 // apply action to primary dof
409 f( dof );
410 }
411 }
412
413
414
415
416 // PrimaryDofs for AuxiliaryDofs< GhostDofMapper >
417 // ------------------------------------------
418
419 template< class GridPart, class BaseMapper, class GlobalKey >
420 struct PrimaryDofs< AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > > >
421 {
422 typedef AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > > AuxiliaryDofsType;
423
424 typedef typename AuxiliaryDofsType::GlobalKeyType GlobalKeyType;
425 typedef typename AuxiliaryDofsType::GridPartType GridPartType;
426 typedef typename AuxiliaryDofsType::MapperType MapperType;
427 typedef typename AuxiliaryDofsType::SizeType SizeType;
428
429 typedef __GhostDofMapper::ConstIterator< GlobalKeyType > ConstIteratorType;
430
431 [[deprecated("Use forEachPrimaryDof instead!")]]
432 explicit PrimaryDofs ( const AuxiliaryDofsType &auxiliaryDofs )
433 : mapper_( auxiliaryDofs.mapper() )
434 {}
435
436 ConstIteratorType begin () const { return ConstIteratorType( 0 ); }
437 ConstIteratorType end () const { return ConstIteratorType( size() ); }
438
439 SizeType size () const { return mapper().interiorSize(); }
440
441 const MapperType &mapper () const { return mapper_; }
442 const GridPartType &gridPart () const { return mapper().gridPart(); }
443
444 private:
445 const MapperType &mapper_;
446 };
447
448 } // namespace Fem
449
450} // namespace Dune
451
452#endif // #ifndef DUNE_FEM_SPACE_MAPPER_GHOST_HH
void scatter(MessageBufferImp &buff, const EntityType &e, size_t n)
unpack data from message buffer to user.
Definition: datahandleif.hh:143
void gather(MessageBufferImp &buff, const EntityType &e) const
pack data from user to message buffer
Definition: datahandleif.hh:129
In parallel computations the dofs of a discrete function are made up by all primary dofs....
Definition: auxiliarydofs.hh:46
Describes the parallel communication interface class for MessageBuffers and DataHandles.
GridPart GridPartType
type of grid part
Definition: auxiliarydofs.hh:53
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
Mapper MapperType
type of used mapper
Definition: auxiliarydofs.hh:56
IndexType primarySize() const
return number of primaryDofs
Definition: auxiliarydofs.hh:134
static void forEachPrimaryDof(const AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > > &auxiliaryDofs, F &&f)
Apply action encoded in Functor f to all primary dofs.
Definition: ghost.hh:403
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
InterfaceType
Parameter to be used for the communication functions.
Definition: gridenums.hh:86
@ 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
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 13, 23:29, 2024)