DUNE-FEM (unstable)

parallel.hh
1#ifndef DUNE_FEM_SPACE_MAPPER_PARALLEL_HH
2#define DUNE_FEM_SPACE_MAPPER_PARALLEL_HH
3
4#include <cstddef>
5
6#include <algorithm>
7#include <tuple>
8#include <type_traits>
9#include <utility>
10#include <vector>
11
13
14#include <dune/fem/gridpart/common/indexset.hh>
15#include <dune/fem/space/common/auxiliarydofs.hh>
16#include <dune/fem/space/mapper/capabilities.hh>
17
18namespace Dune
19{
20
21 namespace Fem
22 {
23
24 namespace __ParallelDofMapper
25 {
26
27 // BuildDataHandle
28 // ---------------
29
30 template< class GridPart, class BaseMapper, class GlobalKey >
31 struct BuildDataHandle
32 : public CommDataHandleIF< BuildDataHandle< GridPart, BaseMapper, GlobalKey >, GlobalKey >
33 {
34 explicit BuildDataHandle ( const BaseMapper &baseMapper, const AuxiliaryDofs< GridPart, BaseMapper > &auxiliaryDofs, std::vector< GlobalKey > &mapping )
35 : baseMapper_( baseMapper ), auxiliaryDofs_( auxiliaryDofs ), mapping_( mapping )
36 {}
37
38 bool contains ( int dim, int codim ) const { return baseMapper_.contains( codim ); }
39 bool fixedSize ( int dim, int codim ) const { return false; }
40
41 template< class Buffer, class Entity >
42 void gather ( Buffer &buffer, const Entity &entity ) const
43 {
44 baseMapper_.mapEachEntityDof( entity, [ this, &buffer ] ( int, auto index ) {
45 if( !auxiliaryDofs_.contains( index ) )
46 buffer.write( mapping_[ index ] );
47 } );
48 }
49
50 template< class Buffer, class Entity >
51 void scatter ( Buffer &buffer, const Entity &entity, std::size_t n )
52 {
53 if( n == 0 )
54 return;
55
56 assert( n == static_cast< std::size_t >( baseMapper_.numEntityDofs( entity ) ) );
57 baseMapper_.mapEachEntityDof( entity, [ this, &buffer ] ( int, auto index ) {
58 assert( auxiliaryDofs_.contains( index ) );
59 buffer.read( mapping_[ index ] );
60 } );
61 }
62
63 template< class Entity >
64 std::size_t size ( const Entity &entity ) const
65 {
66 std::size_t size = 0;
67 baseMapper_.mapEachEntityDof( entity, [ this, &size ] ( int, auto index )
68 { size += static_cast< std::size_t >( !auxiliaryDofs_.contains( index ) ); } );
69 return size;
70 }
71
72 protected:
73 const BaseMapper &baseMapper_;
74 const AuxiliaryDofs< GridPart, BaseMapper > &auxiliaryDofs_;
75 std::vector< GlobalKey > &mapping_;
76 };
77
78 } // namespace __ParallelDofMapper
79
80
81
82 // ParallelDofMapper
83 // -----------------
84
85 template< class GridPart, class BaseMapper, class GlobalKey = std::size_t >
86 class ParallelDofMapper
87 {
88 typedef ParallelDofMapper< GridPart, BaseMapper, GlobalKey > ThisType;
89
90 public:
91 typedef GridPart GridPartType;
92 typedef BaseMapper BaseMapperType;
93
94 typedef std::size_t SizeType;
95 typedef GlobalKey GlobalKeyType;
96
97 typedef typename BaseMapperType::ElementType ElementType;
98
99 ParallelDofMapper ( const GridPartType &gridPart, const BaseMapperType &baseMapper, const InterfaceType commInterface )
100 : gridPart_( gridPart ), baseMapper_( baseMapper ), commInterface_( commInterface )
101 {
102 update();
103 }
104
105 ParallelDofMapper ( const ThisType & ) = delete;
106 ParallelDofMapper ( ThisType && ) = delete;
107
108 ThisType &operator= ( const ThisType & ) = delete;
109 ThisType &operator= ( ThisType && ) = delete;
110
111 template< class Functor >
112 void mapEach ( const ElementType &element, Functor f ) const
113 {
114 baseMapper().mapEach( element, [ this, f ] ( auto local, auto i ) { f( local, mapping_[ i ] ); } );
115 }
116
117 void map ( const ElementType &element, std::vector< GlobalKeyType > &indices ) const
118 {
119 indices.resize( numDofs( element ) );
120 mapEach( element, [ &indices ] ( int local, GlobalKeyType global ) { indices[ local ] = global; } );
121 }
122
123 [[deprecated("Use onSubEntity method with char vector instead")]]
124 void onSubEntity ( const ElementType &element, int i, int c, std::vector< bool > &indices ) const
125 {
126 std::vector< char > _idx;
127 onSubEntity(element, i, c, _idx);
128 indices.resize( _idx.size() );
129 for (std::size_t i=0; i<_idx.size();++i)
130 _idx[i] = indices[i] > 0;
131 }
132 // this method returns which local dofs are attached to the given subentity.
133 // indices[locDofNr] =
134 // 0 : not attached, not equal to 0 : attached
135 // (so this method can still be used in the way the deprecated method was).
136 // New: In case the dof can be associated to a component of the
137 // space, the value returned is that component+1. In other
138 // cases (normal velocity for RT for example) the value is -1).
139 // So indices[i] is in [-1,dimRange+1]
140 void onSubEntity ( const ElementType &element, int i, int c, std::vector< char > &indices ) const
141 {
142 baseMapper().onSubEntity( element, i, c, indices );
143 }
144
145 unsigned int maxNumDofs () const { return baseMapper().maxNumDofs(); }
146 unsigned int numDofs ( const ElementType &element ) const { return baseMapper().numDofs( element ); }
147
148 // assignment of DoFs to entities
149
150 template< class Entity, class Functor >
151 void mapEachEntityDof ( const Entity &entity, Functor f ) const
152 {
153 baseMapper().mapEachEntityDof( entity, [ this, f ] ( auto local, auto i ) { f( local, mapping_[ i ] ); } );
154 }
155
156 template< class Entity >
157 void mapEntityDofs ( const Entity &entity, std::vector< GlobalKeyType > &indices ) const
158 {
159 indices.resize( numEntityDofs( entity ) );
160 mapEachEntityDof( entity, [ &indices ] ( int local, GlobalKeyType global ) { indices[ local ] = global; } );
161 }
162
163 template< class Entity >
164 unsigned int numEntityDofs ( const Entity &entity ) const
165 {
166 return baseMapper().numEntityDofs( entity );
167 }
168
169 // global information
170
171 bool contains ( int codim ) const { return baseMapper().contains( codim ); }
172
173 bool fixedDataSize ( int codim ) const { return baseMapper().fixedDataSize( codim ); }
174
175 SizeType size () const { return size_; }
176
177 InterfaceType communicationInterface() const { return commInterface_; }
178
179 // adaptation interface
180
181 bool consecutive () const { return false; }
182
183 int numBlocks () const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
184 SizeType offSet ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
185 SizeType oldOffSet ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
186 SizeType numberOfHoles ( int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
187 SizeType oldIndex ( SizeType hole, int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
188 SizeType newIndex ( SizeType hole, int blk ) const { DUNE_THROW( NotImplemented, "Adaptive dof mapper interface not implemented." ); }
189
190 // update
191
192 void update ( )
193 {
194 AuxiliaryDofs< GridPartType, BaseMapperType > auxiliaryDofs( gridPart(), baseMapper() );
195 auxiliaryDofs.rebuild();
196 //auto primaryDofs = Dune::Fem::primaryDofs( auxiliaryDofs );
197
198 const auto primarySize = auxiliaryDofs.primarySize(); // primaryDofs.size();
199 size_ = primarySize; // primaryDofs.size();
200 offset_ = exScan( gridPart().comm(), size_ );
201 size_ = gridPart().comm().sum( size_ );
202
203 std::size_t baseSize = baseMapper().size();
204 mapping_.resize( baseSize );
205 GlobalKeyType next = static_cast< GlobalKeyType >( offset_ );
206 std::vector< GlobalKeyType >& mapping = mapping_;
207 auto mapNext = [&mapping, &next] (const auto i) { mapping[ i ] = next++; };
208 // for all primary dofs build mapping
209 forEachPrimaryDof( auxiliaryDofs, mapNext );
210 assert( next == static_cast< GlobalKeyType >( offset_ + primarySize ) );
211
212 __ParallelDofMapper::BuildDataHandle< GridPartType, BaseMapperType, GlobalKeyType > dataHandle( baseMapper(), auxiliaryDofs, mapping_ );
213 gridPart().communicate( dataHandle, communicationInterface(), ForwardCommunication );
214 }
215
216 const GridPartType &gridPart () const { return gridPart_; }
217 const BaseMapperType &baseMapper () const { return baseMapper_; }
218
219 const std::vector< GlobalKeyType > &mapping () const { return mapping_; }
220
221 private:
222 template< class Comm, class T >
223 static T exScan ( const Communication< Comm > &comm, T in )
224 {
225 return T( 0 );
226 }
227
228#if HAVE_MPI
229 template< class T >
230 static T exScan ( const Communication< MPI_Comm > &comm, T in )
231 {
232 T out( 0 );
233 MPI_Exscan( &in, &out, 1, MPITraits< T >::getType(), MPI_SUM, static_cast< MPI_Comm >( comm ) );
234 return out;
235 }
236#endif // #if HAVE_MPI
237
238 const GridPartType &gridPart_;
239 const BaseMapperType &baseMapper_;
240 const InterfaceType commInterface_;
241 std::vector< GlobalKeyType > mapping_;
242 SizeType offset_, size_;
243 };
244
245
246
247 // Capabilities for IndexSetDofMapper
248 // ----------------------------------
249
250 namespace Capabilities
251 {
252
253 template< class GridPart, class BaseMapper, class GlobalKey >
254 struct isAdaptiveDofMapper< ParallelDofMapper< GridPart, BaseMapper, GlobalKey > >
255 {
256 static const bool v = false;
257 };
258
259 template< class GridPart, class BaseMapper, class GlobalKey >
260 struct isConsecutiveIndexSet< ParallelDofMapper< GridPart, BaseMapper, GlobalKey > >
261 {
262 static const bool v = true;
263 };
264
265 } // namespace Capabilities
266
267 } // namespace Fem
268
269} // namespace Dune
270
271#endif // #ifndef DUNE_FEM_SPACE_MAPPER_PARALLEL_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
Describes the parallel communication interface class for MessageBuffers and DataHandles.
static void forEachPrimaryDof(const AuxiliaryDofs &auxiliaryDofs, F &&f)
Apply action encoded in Functor f to all primary dofs.
Definition: auxiliarydofs.hh:303
#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
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 21, 23:30, 2024)