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 )
167 : gridPart_( gridPart ), baseMapper_( baseMapper )
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 // adaptation interface
248
249 bool consecutive () const { return false; }
250
251 int numBlocks () const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
252 SizeType offSet ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
253 SizeType oldOffSet ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
254 SizeType numberOfHoles ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
255 SizeType oldIndex ( SizeType hole, int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
256 SizeType newIndex ( SizeType hole, int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
257
258 // update
259
260 // TODO: default comm interface should come out of space
261 void update ( const InterfaceType commInterface = InteriorBorder_All_Interface )
262 {
263 std::size_t baseSize = baseMapper().size();
264 mapping_.resize( baseSize );
265
266 std::vector< std::tuple< int, std::size_t, std::size_t > > masters( baseSize );
267 for( std::size_t i = 0; i < baseSize; ++i )
268 masters[ i ] = std::make_tuple( -1, i, i );
269
270 const int rank = gridPart().comm().rank();
271 __GhostDofMapper::BuildDataHandle< BaseMapper > dataHandle( rank, baseMapper_, masters );
272
273 gridPart().communicate( dataHandle, commInterface, ForwardCommunication );
274 // at this point all shared DoFs are assigned to their master rank
275 // all other DoFs (with rank -1) are not shared at all
276
277 // assign indices to interiors
278 interiorSize_ = ghostSize_ = 0;
279 for( const auto &m : masters )
280 {
281 if( (std::get< 0 >( m ) == -1) || (std::get< 0 >( m ) == rank ) )
282 mapping_[ std::get< 2 >( m ) ] = interiorSize_++;
283 else
284 masters[ ghostSize_++ ] = m;
285 }
286 masters.resize( ghostSize_ );
287
288 // sort the masters (by the first two components) to find duplicate ghosts
289 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 ))); };
290 std::sort( masters.begin(), masters.end(), less );
291
292 // assign indices to ghosts
293 ghostSize_ = 0;
294 std::tuple< int, std::size_t, std::size_t > current( -1, 0, 0 );
295 for( const auto &m : masters )
296 {
297 if( less( current, m ) )
298 {
299 current = m;
300 std::get< 2 >( current ) = interiorSize_ + ghostSize_++;
301 }
302 mapping_[ std::get< 2 >( m ) ] = std::get< 2 >( current );
303 }
304 }
305
306 const GridPartType &gridPart () const { return gridPart_; }
307 const BaseMapperType &baseMapper () const { return baseMapper_; }
308
309 const std::vector< GlobalKeyType > &mapping () const { return mapping_; }
310
311 private:
312 const GridPartType &gridPart_;
313 BaseMapperType &baseMapper_;
314 std::vector< GlobalKeyType > mapping_;
315 SizeType interiorSize_, ghostSize_;
316 };
317
318
319
320 // Capabilities for IndexSetDofMapper
321 // ----------------------------------
322
323 namespace Capabilities
324 {
325
326 template< class GridPart, class BaseMapper, class GlobalKey >
327 struct isAdaptiveDofMapper< GhostDofMapper< GridPart, BaseMapper, GlobalKey > >
328 {
329 static const bool v = false;
330 };
331
332 template< class GridPart, class BaseMapper, class GlobalKey >
333 struct isConsecutiveIndexSet< GhostDofMapper< GridPart, BaseMapper, GlobalKey > >
334 {
335 static const bool v = true;
336 };
337
338 } // namespace Capabilities
339
340
341
342 // AuxiliaryDofs for GhostDofMapper
343 // ----------------------------
344
345 template< class GridPart, class BaseMapper, class GlobalKey >
346 class AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > >
347 {
348 typedef AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > > ThisType;
349
350 public:
351 typedef GridPart GridPartType;
352 typedef GhostDofMapper< GridPart, BaseMapper, GlobalKey > MapperType;
353
354 typedef typename MapperType::GlobalKeyType GlobalKeyType;
355 typedef typename MapperType::SizeType SizeType;
356
357 typedef __GhostDofMapper::ConstIterator< GlobalKeyType > ConstIteratorType;
358
359 explicit AuxiliaryDofs ( const MapperType &mapper )
360 : mapper_( mapper )
361 {}
362
363 AuxiliaryDofs ( const GridPartType &gridPart, const MapperType &mapper )
364 : AuxiliaryDofs( mapper )
365 {}
366
368 GlobalKeyType operator [] ( int index ) const { return mapper().interiorSize() + index; }
369
371 SizeType size () const { return mapper().ghostSize()+1; }
372
374 SizeType primarySize () const { return mapper().interiorSize(); }
375
376 ConstIteratorType begin () const { return ConstIteratorType( mapper().interiorSize() ); }
377 ConstIteratorType end () const { return ConstIteratorType( mapper().interiorSize() + mapper().ghostSize() ); }
378
380 bool contains ( GlobalKeyType index ) const { return (static_cast< SizeType >( index ) >= mapper().interiorSize()); }
381
382 void rebuild () {}
383
384 const MapperType &mapper () const { return mapper_; }
385 const GridPartType &gridPart () const { return mapper().gridPart(); }
386
387 private:
388 const MapperType &mapper_;
389 };
390
391
400 template <class GridPart, class BaseMapper, class GlobalKey, class F>
401 static void forEachPrimaryDof( const AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > >& auxiliaryDofs, F&& f )
402 {
403 const size_t size = auxiliaryDofs.mapper().interiorSize();
404 for( size_t dof = 0 ; dof<size; ++dof )
405 {
406 // apply action to primary dof
407 f( dof );
408 }
409 }
410
411
412
413
414 // PrimaryDofs for AuxiliaryDofs< GhostDofMapper >
415 // ------------------------------------------
416
417 template< class GridPart, class BaseMapper, class GlobalKey >
418 struct PrimaryDofs< AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > > >
419 {
420 typedef AuxiliaryDofs< GridPart, GhostDofMapper< GridPart, BaseMapper, GlobalKey > > AuxiliaryDofsType;
421
422 typedef typename AuxiliaryDofsType::GlobalKeyType GlobalKeyType;
423 typedef typename AuxiliaryDofsType::GridPartType GridPartType;
424 typedef typename AuxiliaryDofsType::MapperType MapperType;
425 typedef typename AuxiliaryDofsType::SizeType SizeType;
426
427 typedef __GhostDofMapper::ConstIterator< GlobalKeyType > ConstIteratorType;
428
429 [[deprecated("Use forEachPrimaryDof instead!")]]
430 explicit PrimaryDofs ( const AuxiliaryDofsType &auxiliaryDofs )
431 : mapper_( auxiliaryDofs.mapper() )
432 {}
433
434 ConstIteratorType begin () const { return ConstIteratorType( 0 ); }
435 ConstIteratorType end () const { return ConstIteratorType( size() ); }
436
437 SizeType size () const { return mapper().interiorSize(); }
438
439 const MapperType &mapper () const { return mapper_; }
440 const GridPartType &gridPart () const { return mapper().gridPart(); }
441
442 private:
443 const MapperType &mapper_;
444 };
445
446 } // namespace Fem
447
448} // namespace Dune
449
450#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:401
#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
@ InteriorBorder_All_Interface
send interior and border, receive all entities
Definition: gridenums.hh:88
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 (Jul 27, 22:29, 2024)