3 #ifndef DUNE_INTERFACE_HH
4 #define DUNE_INTERFACE_HH
32 class InterfaceBuilder
35 class RemoteIndicesStateError :
public InvalidStateException
38 virtual ~InterfaceBuilder()
85 template<
class R,
class T1,
class T2,
class Op,
bool send>
86 void buildInterface (
const R& remoteIndices,
87 const T1& sourceFlags,
const T2& destFlags,
98 class InterfaceInformation
114 std::size_t& operator[](
size_t i)
123 std::size_t operator[](
size_t i)
const
132 void reserve(
size_t size)
134 indices_ =
new std::size_t[size];
152 void add(std::size_t index)
154 assert(size_<maxSize_);
155 indices_[size_++]=index;
158 InterfaceInformation()
159 : size_(0), maxSize_(0), indices_(0)
162 virtual ~InterfaceInformation()
165 bool operator!=(
const InterfaceInformation& o)
const
170 bool operator==(
const InterfaceInformation& o)
const
174 for(std::size_t i=0; i< size_; ++i)
175 if(indices_[i]!=o.indices_[i])
192 std::size_t* indices_;
206 class Interface :
public InterfaceBuilder
214 typedef std::map<int,std::pair<InterfaceInformation,InterfaceInformation> > InformationMap;
232 template<
typename R,
typename T1,
typename T2>
233 void build(
const R& remoteIndices,
const T1& sourceFlags,
234 const T2& destFlags);
244 MPI_Comm communicator()
const;
254 const InformationMap& interfaces()
const;
256 Interface(MPI_Comm comm)
257 : communicator_(comm), interfaces_()
261 : communicator_(MPI_COMM_NULL), interfaces_()
276 if(communicator_!=o.communicator_)
278 if(interfaces_.size()!=o.interfaces_.size())
280 typedef InformationMap::const_iterator MIter;
282 for(MIter m=interfaces_.begin(), om=o.interfaces_.begin();
283 m!=interfaces_.end(); ++m, ++om)
285 if(om->first!=m->first)
287 if(om->second.first!=om->second.first)
289 if(om->second.second!=om->second.second)
298 virtual ~Interface();
311 InformationMap& interfaces();
314 MPI_Comm communicator_;
324 InformationMap interfaces_;
327 class InformationBuilder
330 InformationBuilder(InformationMap& interfaces)
331 : interfaces_(interfaces)
334 void reserve(
int proc,
int size)
337 interfaces_[proc].first.reserve(size);
339 interfaces_[proc].second.reserve(size);
341 void add(
int proc, std::size_t local)
344 interfaces_[proc].first.add(local);
346 interfaces_[proc].second.add(local);
351 InformationMap& interfaces_;
355 template<
class R,
class T1,
class T2,
class Op,
bool send>
356 void InterfaceBuilder::buildInterface(
const R& remoteIndices,
const T1& sourceFlags,
const T2& destFlags, Op& interfaceInformation)
const
359 if(!remoteIndices.isSynced())
360 DUNE_THROW(RemoteIndicesStateError,
"RemoteIndices is not in sync with the index set. Call RemoteIndices::rebuild first!");
362 typedef R RemoteIndices;
363 typedef typename RemoteIndices::RemoteIndexMap::const_iterator const_iterator;
365 const const_iterator end=remoteIndices.end();
369 MPI_Comm_rank(remoteIndices.communicator(), &rank);
372 for(const_iterator process=remoteIndices.begin(); process != end; ++process) {
375 typedef typename RemoteIndices::RemoteIndexList::const_iterator RemoteIterator;
376 const RemoteIterator remoteEnd = send ? process->second.first->end() :
377 process->second.second->end();
378 RemoteIterator remote = send ? process->second.first->begin() : process->second.second->begin();
380 while(remote!=remoteEnd) {
381 if( send ? destFlags.contains(remote->attribute()) :
382 sourceFlags.contains(remote->attribute())) {
385 if( send ? sourceFlags.contains(remote->localIndexPair().local().attribute()) :
386 destFlags.contains(remote->localIndexPair().local().attribute()))
391 interfaceInformation.reserve(process->first, size);
396 for(const_iterator process=remoteIndices.begin(); process != end; ++process) {
397 typedef typename RemoteIndices::RemoteIndexList::const_iterator RemoteIterator;
398 const RemoteIterator remoteEnd = send ? process->second.first->end() :
399 process->second.second->end();
400 RemoteIterator remote = send ? process->second.first->begin() : process->second.second->begin();
402 while(remote!=remoteEnd) {
403 if( send ? destFlags.contains(remote->attribute()) :
404 sourceFlags.contains(remote->attribute())) {
406 if( send ? sourceFlags.contains(remote->localIndexPair().local().attribute()) :
407 destFlags.contains(remote->localIndexPair().local().attribute()))
408 interfaceInformation.add(process->first,remote->localIndexPair().local().local());
415 inline MPI_Comm Interface::communicator()
const
417 return communicator_;
422 inline const std::map<int,std::pair<InterfaceInformation,InterfaceInformation> >& Interface::interfaces()
const
427 inline std::map<int,std::pair<InterfaceInformation,InterfaceInformation> >& Interface::interfaces()
432 inline void Interface::print()
const
434 typedef InformationMap::const_iterator const_iterator;
435 const const_iterator end=interfaces_.end();
437 MPI_Comm_rank(communicator(), &rank);
439 for(const_iterator infoPair=interfaces_.begin(); infoPair!=end; ++infoPair) {
441 std::cout<<rank<<
": send for process "<<infoPair->first<<
": ";
442 const InterfaceInformation& info(infoPair->second.first);
443 for(
size_t i=0; i < info.size(); i++)
444 std::cout<<info[i]<<
" ";
445 std::cout<<std::endl;
448 std::cout<<rank<<
": receive for process "<<infoPair->first<<
": ";
449 const InterfaceInformation& info(infoPair->second.second);
450 for(
size_t i=0; i < info.size(); i++)
451 std::cout<<info[i]<<
" ";
452 std::cout<<std::endl;
458 template<
typename R,
typename T1,
typename T2>
459 inline void Interface::build(
const R& remoteIndices,
const T1& sourceFlags,
462 communicator_=remoteIndices.communicator();
464 assert(interfaces_.empty());
467 InformationBuilder<true> sendInformation(interfaces_);
468 this->
template buildInterface<R,T1,T2,InformationBuilder<true>,
true>(remoteIndices, sourceFlags,
469 destFlags, sendInformation);
472 InformationBuilder<false> recvInformation(interfaces_);
473 this->
template buildInterface<R,T1,T2,InformationBuilder<false>,
false>(remoteIndices,sourceFlags,
474 destFlags, recvInformation);
477 inline void Interface::strip()
479 typedef InformationMap::iterator const_iterator;
480 for(const_iterator interfacePair = interfaces_.begin(); interfacePair != interfaces_.end();)
481 if(interfacePair->second.first.size()==0 && interfacePair->second.second.size()==0) {
482 interfacePair->second.first.free();
483 interfacePair->second.second.free();
484 const_iterator toerase=interfacePair++;
485 interfaces_.erase(toerase);
490 inline void Interface::free()
492 typedef InformationMap::iterator iterator;
493 typedef InformationMap::const_iterator const_iterator;
494 const const_iterator end = interfaces_.end();
495 for(iterator interfacePair = interfaces_.begin(); interfacePair != end; ++interfacePair) {
496 interfacePair->second.first.free();
497 interfacePair->second.second.free();
502 inline Interface::~Interface()
508 inline std::ostream&
operator<<(std::ostream& os,
const Interface& interface)
510 typedef Interface::InformationMap InfoMap;
511 typedef InfoMap::const_iterator Iter;
512 for(Iter i=interface.interfaces().begin(), end = interface.interfaces().end();
515 os<<i->first<<
": [ source=[";
516 for(std::size_t j=0; j < i->second.first.size(); ++j)
517 os<<i->second.first[j]<<
" ";
518 os<<
"] size="<<i->second.first.size()<<
", target=[";
519 for(std::size_t j=0; j < i->second.second.size(); ++j)
520 os<<i->second.second[j]<<
" ";
521 os<<
"] size="<<i->second.second.size()<<
"\n";