2 #ifndef DUNE_FEM_PETSCGHOSTARRAYBUILDER_HH 3 #define DUNE_FEM_PETSCGHOSTARRAYBUILDER_HH 5 #include <dune/grid/common/datahandleif.hh> 25 template<
typename,
typename >
class PetscDofCommunicator;
37 template<
typename SlaveProv
ider,
typename PDofMapping >
38 class PetscGhostArrayBuilder
40 typedef PetscGhostArrayBuilder< SlaveProvider, PDofMapping > ThisType;
42 typedef std::vector< std::pair< int, int > > StorageType;
45 template<
typename IT >
bool operator () ( IT a, IT b ) {
return a.first < b.first; }
49 typedef SlaveProvider SlaveProviderType;
50 typedef typename SlaveProviderType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
51 typedef PDofMapping PetscDofMappingType;
52 typedef PetscInt value_type;
53 static const int blockSize = DiscreteFunctionSpaceType::localBlockSize;
56 explicit PetscGhostArrayBuilder ( SlaveProviderType& slaveDofs,
57 PetscDofMappingType& petscDofMapping )
59 arrayNeedsUpdate_( true )
61 if( slaveDofs.space().gridPart().comm().size() > 1 )
65 PetscDofCommunicator< DiscreteFunctionSpaceType, ThisType > handle( slaveDofs.space(), petscDofMapping, *this );
66 slaveDofs.space().gridPart().communicate( handle, DiscreteFunctionSpaceType::GridPartType::indexSetInterfaceType, ForwardCommunication );
68 catch(
const Dune::Exception &e )
70 std::cerr << e << std::endl;
71 std::cerr <<
"Exception thrown in: " << __FILE__ <<
" line: " << __LINE__ << std::endl;
84 ~PetscGhostArrayBuilder ()
92 arrayNeedsUpdate_ =
true;
95 bool hasDuplicatedGhosts ()
const 97 std::map< int, bool > map;
98 for( StorageType::const_iterator it = vector_.begin(); it != vector_.end(); ++it )
100 if( map.find( it->second ) != map.end() )
101 std::cerr << it->second <<
" found more than once on rk " <<
MPIManager::rank() <<
"\n";
103 map[ it->second ] =
true;
105 return ( map.size() < vector_.size() );
114 value_type* array ()
const 120 const value_type& operator[] (
size_t i )
const {
return vector_[ i ].second; }
122 value_type& operator[] (
size_t i )
124 arrayNeedsUpdate_ =
true;
125 return vector_[ i ].second;
128 void push_back (
int index,
int value )
130 vector_.push_back( std::make_pair( index, value ) );
131 arrayNeedsUpdate_ =
true;
134 size_t size ()
const {
return vector_.size(); }
137 PetscGhostArrayBuilder (
const ThisType& );
138 ThisType& operator= (
const ThisType & );
139 PetscGhostArrayBuilder ();
141 void updateArray ()
const 143 if( arrayNeedsUpdate_ )
146 array_ =
new value_type[ blockSize * size() ];
147 std::sort( vector_.begin(), vector_.end(), StorageSort() );
148 for(
size_t block = 0; block < size(); ++block )
150 for(
size_t inBlock = 0; inBlock < static_cast< size_t >( blockSize ); ++inBlock )
152 array_[ block*blockSize + inBlock ] = ( vector_[ block ].second ) * blockSize + inBlock;
155 arrayNeedsUpdate_ =
false;
160 mutable StorageType vector_;
161 mutable value_type *array_;
162 mutable bool arrayNeedsUpdate_;
172 template<
typename DFSpace,
typename PGhostArrayBuilder >
173 class PetscDofCommunicator
174 :
public CommDataHandleIF< PetscDofCommunicator< DFSpace, PGhostArrayBuilder >, int >
176 typedef PetscDofCommunicator< DFSpace, PGhostArrayBuilder > ThisType;
177 typedef CommDataHandleIF< PetscDofCommunicator< DFSpace, PGhostArrayBuilder >,
int > BaseType;
181 typedef PGhostArrayBuilder PetscGhostArrayBuilderType;
182 typedef DFSpace DiscreteFunctionSpaceType;
183 typedef typename BaseType::DataType DataType;
184 typedef PetscSlaveDofProvider< DiscreteFunctionSpaceType > PetscSlaveDofProviderType ;
185 typedef typename PetscSlaveDofProviderType :: PetscDofMappingType PetscDofMappingType;
186 typedef typename DiscreteFunctionSpaceType::BlockMapperType BlockMapperType;
191 PetscDofCommunicator (
const DiscreteFunctionSpaceType &space,
192 PetscDofMappingType &petscDofMapping,
193 PetscGhostArrayBuilderType& ghostArrayBuilder )
195 mapper_( space_.blockMapper() ),
196 petscDofMapping_( petscDofMapping ),
197 ghostArrayBuilder_( ghostArrayBuilder ),
201 bool contains (
int dim,
int codim )
const 203 return mapper_.contains( codim );
206 bool fixedsize (
int dim,
int codim )
const 211 template<
typename MessageBuffer,
typename Entity >
212 void gather ( MessageBuffer &buffer,
const Entity &entity )
const 214 const int numDofs = mapper_.numEntityDofs( entity );
216 std::vector< int > slaveDofsWithIndex( 2*numDofs, -1 );
218 std::vector< size_t > globalDofs;
219 globalDofs.resize( numDofs );
220 AssignFunctor< std::vector< size_t> > functor( globalDofs );
221 mapper_.mapEachEntityDof( entity, functor );
223 for(
int i = 0; i < numDofs; ++i )
225 size_t &dof = globalDofs[i];
226 assert(
size_t( dof ) < petscDofMapping_.size() );
227 const int petscDof = petscDofMapping_.localSlaveMapping( dof );
230 if( petscDof < petscDofMapping_.numOwnedDofBlocks() )
232 const int petscGlobalDof = petscDofMapping_.processStartIndex() + petscDof;
235 slaveDofsWithIndex[ counter++ ] = i;
236 slaveDofsWithIndex[ counter++ ] = petscGlobalDof;
239 assert( counter % 2 == 0 );
242 buffer.write( counter );
244 assert(
size_t( counter ) <= slaveDofsWithIndex.size() );
245 for(
int i = 0; i < counter; ++i )
247 assert( slaveDofsWithIndex[ i ] != -1 );
248 buffer.write( slaveDofsWithIndex[ i ] );
252 template<
typename MessageBuffer,
typename EntityType >
253 void scatter ( MessageBuffer &buffer,
const EntityType &entity,
size_t n )
255 bool isDuplicate =
false;
256 int idx = space_.indexSet().index(entity);
257 if (duplicates_.find(idx) != duplicates_.end())
260 duplicates_.insert(idx);
262 int twiceNumSlaveDofs;
263 buffer.read( twiceNumSlaveDofs );
265 assert( twiceNumSlaveDofs % 2 == 0 );
266 assert( static_cast< size_t >( twiceNumSlaveDofs ) + 1 == n );
267 assert( twiceNumSlaveDofs + 1 ==
int( n ) );
270 const int numDofs = mapper_.numEntityDofs( entity );
271 std::vector< size_t > globalDofs;
272 globalDofs.resize( numDofs );
273 AssignFunctor< std::vector< size_t> > functor( globalDofs );
274 mapper_.mapEachEntityDof( entity, functor );
276 for(
size_t i = 0; i < size_t( twiceNumSlaveDofs/2 ); ++i )
279 buffer.read( index );
281 size_t &globalDof = globalDofs[ index ];
282 assert( petscDofMapping_.isSlave( globalDof ) );
284 buffer.read( petscDof );
286 ghostArrayBuilder_.push_back( globalDof, petscDof );
291 template<
typename Entity >
292 size_t size (
const Entity &entity )
const 296 const int numDofs = mapper_.numEntityDofs( entity );
298 std::vector< size_t > globalDofs;
299 globalDofs.resize( numDofs );
300 AssignFunctor< std::vector< size_t> > functor( globalDofs );
301 mapper_.mapEachEntityDof( entity, functor );
303 for(
int i = 0; i < numDofs; ++i )
305 if( !petscDofMapping_.isSlave( globalDofs[i] ) )
308 assert( size == 0 || size ==
size_t( numDofs ) );
314 PetscDofCommunicator ();
315 PetscDofCommunicator (
const ThisType& );
316 ThisType operator= (
const ThisType& );
319 const DiscreteFunctionSpaceType &space_;
320 const BlockMapperType &mapper_;
321 PetscDofMappingType &petscDofMapping_;
322 PetscGhostArrayBuilderType& ghostArrayBuilder_;
323 std::set<int> duplicates_;
332 #endif // #if HAVE_PETSC 334 #endif // DUNE_FEM_PETSCGHOSTARRAYBUILDER_HH
static int rank()
Definition: mpimanager.hh:116
Definition: coordinate.hh:4