Loading...
Searching...
No Matches
gridgluecommunicate.hh
Go to the documentation of this file.
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-GPL-2.0-only-with-dune-grid-glue-exception
#ifndef DUNE_GRIDGLUE_ADAPTER_GRIDGLUECOMMUNICATE_HH
#define DUNE_GRIDGLUE_ADAPTER_GRIDGLUECOMMUNICATE_HH
#include <type_traits>
#include <dune/common/bartonnackmanifcheck.hh>
#include <dune/common/parallel/communicator.hh>
#include <dune/grid/common/datahandleif.hh>
#include <dune/grid/common/gridenums.hh>
namespace Dune {
namespace GridGlue {
typedef std::pair<int, int> RankPair;
struct GlobalId : public std::pair<RankPair, unsigned int>
{
GlobalId() {
this->first.first = 0;
this->first.second = 0;
this->second = 0;
}
GlobalId(int i) {
this->first.first = i;
this->first.second = i;
this->second = 0;
}
GlobalId(int i, int j, unsigned int n) {
this->first.first = std::min(i,j);
this->first.second = std::max(i,j);
this->second = n;
}
};
inline std::ostream& operator<<(std::ostream& os, const GlobalId & id)
{
os << "("
<< id.first.first << "," << id.first.second << ","
<< id.second << ")";
return os;
}
template <class DataHandleImp, class DataTypeImp>
class CommDataHandle
{
public:
typedef DataTypeImp DataType;
protected:
// one should not create an explicit instance of this interface object
CommDataHandle() {}
public:
template<class RISType>
size_t size (RISType& i) const
{
CHECK_INTERFACE_IMPLEMENTATION((asImp().size(i)));
return asImp().size(i);
}
template<class MessageBufferImp, class EntityType, class RISType>
void gather (MessageBufferImp& buff, const EntityType& e, const RISType & i) const
{
MessageBufferIF<MessageBufferImp> buffIF(buff);
CHECK_AND_CALL_INTERFACE_IMPLEMENTATION((asImp().gather(buffIF,e,i)));
}
template<class MessageBufferImp, class EntityType, class RISType>
void scatter (MessageBufferImp& buff, const EntityType& e, const RISType & i, size_t n)
{
MessageBufferIF<MessageBufferImp> buffIF(buff);
CHECK_AND_CALL_INTERFACE_IMPLEMENTATION((asImp().scatter(buffIF,e,i,n)));
}
private:
DataHandleImp& asImp () {
return static_cast<DataHandleImp &> (*this);
}
const DataHandleImp& asImp () const
{
return static_cast<const DataHandleImp &>(*this);
}
}; // end class CommDataHandleIF
template<typename DT>
class StreamingMessageBuffer {
public:
typedef DT value_type;
// Constructor
StreamingMessageBuffer (DT *p)
{
a=p;
i=0;
j=0;
}
// write data to message buffer, acts like a stream !
template<class Y>
void write (const Y& data)
{
static_assert(std::is_same<DT,Y>::value, "DataType mismatch");
a[i++] = data;
}
// read data from message buffer, acts like a stream !
template<class Y>
void read (Y& data) const
{
static_assert(std::is_same<DT,Y>::value, "DataType mismatch");
data = a[j++];
}
size_t counter() const { return i; }
void clear()
{
i = 0;
j = 0;
}
// we need access to these variables in an assertion
#ifdef NDEBUG
private:
#endif
DT *a;
size_t i;
mutable size_t j;
};
template<int dir>
class CommunicationOperator
{
public:
template<class CommInfo>
static const typename CommInfo::DataType& gather(const CommInfo& commInfo, size_t i, size_t j = 0)
{
// get Intersection
typedef typename CommInfo::GridGlue::Intersection Intersection;
Intersection ris(commInfo.gridglue->getIntersection(i));
// fill buffer if we have a new intersection
if (j == 0)
{
commInfo.mbuffer.clear();
if (dir == Dune::ForwardCommunication)
{
// read from grid0
if(ris.self())
commInfo.data->gather(commInfo.mbuffer, ris.inside(), ris);
}
else // (dir == Dune::BackwardCommunication)
{
// read from grid1
if(ris.neighbor())
commInfo.data->gather(commInfo.mbuffer, ris.outside(), ris.flip());
}
}
// return the j'th value in the buffer
assert(j < commInfo.mbuffer.i);
return commInfo.buffer[j];
}
template<class CommInfo>
static void scatter(CommInfo& commInfo, const typename CommInfo::DataType& v, std::size_t i, std::size_t j = 0)
{
// extract GridGlue objects...
typedef typename CommInfo::GridGlue::Intersection Intersection;
Intersection ris(commInfo.gridglue->getIntersection(i));
// get size if we have a new intersection
if (j == 0)
{
commInfo.mbuffer.clear();
commInfo.currentsize = commInfo.data->size(ris);
}
// write entry to buffer
commInfo.buffer[j] = v;
// write back the buffer if we are at the end of this intersection
if (j == commInfo.currentsize-1)
{
if (dir == Dune::ForwardCommunication)
{
// write to grid1
if(ris.neighbor())
commInfo.data->scatter(commInfo.mbuffer, ris.outside(), ris.flip(), commInfo.currentsize);
}
else // (dir == Dune::BackwardCommunication)
{
// write to grid0
if(ris.self())
commInfo.data->scatter(commInfo.mbuffer, ris.inside(), ris, commInfo.currentsize);
}
assert(commInfo.mbuffer.j <= commInfo.currentsize);
}
}
};
typedef CommunicationOperator<Dune::ForwardCommunication> ForwardOperator;
typedef CommunicationOperator<Dune::BackwardCommunication> BackwardOperator;
template <typename GG, class DataHandleImp, class DataTypeImp>
struct CommInfo
{
typedef DataTypeImp value_type;
typedef GG GridGlue;
typedef DataTypeImp DataType;
CommInfo() : buffer(100), mbuffer(&buffer[0])
{}
// tunnel information to the policy and the operators
const GridGlue * gridglue;
::Dune::GridGlue::CommDataHandle<DataHandleImp, DataTypeImp> * data;
// state variables
std::vector<DataType> buffer;
mutable ::Dune::GridGlue::StreamingMessageBuffer<DataType> mbuffer;
size_t currentsize;
Dune::CommunicationDirection dir;
};
} // end namespace GridGlue
#if HAVE_MPI
template<typename GG, class DataHandleImp, class DataTypeImp>
struct CommPolicy< ::Dune::GridGlue::CommInfo<GG, DataHandleImp, DataTypeImp> >
{
typedef ::Dune::GridGlue::CommInfo<GG, DataHandleImp, DataTypeImp> Type;
typedef DataTypeImp IndexedType;
// typedef SizeOne IndexedTypeFlag;
typedef VariableSize IndexedTypeFlag;
static size_t getSize(const Type& commInfo, size_t i)
{
// get Intersection
typedef typename Type::GridGlue::Intersection Intersection;
Intersection ris(commInfo.gridglue->getIntersection(i));
// ask data handle for size
return commInfo.data->size(ris);
}
};
#endif
} // end namespace Dune
#endif
Dune
Definition gridglue.hh:37
Dune::GridGlue
Definition gridglue.hh:38
Dune::GridGlue::BackwardOperator
CommunicationOperator< Dune::BackwardCommunication > BackwardOperator
Definition gridgluecommunicate.hh:264
Dune::GridGlue::ForwardOperator
CommunicationOperator< Dune::ForwardCommunication > ForwardOperator
Definition gridgluecommunicate.hh:263
Dune::GridGlue::RankPair
std::pair< int, int > RankPair
Definition gridgluecommunicate.hh:24
Dune::GridGlue::operator<<
std::ostream & operator<<(std::ostream &os, const GlobalId &id)
Definition gridgluecommunicate.hh:55
Dune::GridGlue::Intersection
The intersection of two entities of the two patches of a GridGlue.
Definition intersection.hh:257
Dune::GridGlue::Intersection::flip
Intersection< P0, P1, O, I > flip() const
Return a copy of the intersection with inside and outside switched.
Definition intersection.hh:474
Dune::GridGlue::Intersection::self
bool self() const
For parallel computations: Return true if inside() entity exists locally.
Definition intersection.hh:384
Dune::GridGlue::Intersection::inside
InsideEntity inside(unsigned int parentId=0) const
Return element on the inside of this intersection.
Definition intersection.hh:315
Dune::GridGlue::Intersection::neighbor
size_t neighbor(unsigned int g=0) const
Return number of embeddings into local grid0 (grid1) entities.
Definition intersection.hh:390
Dune::GridGlue::Intersection::outside
OutsideEntity outside(unsigned int parentId=0) const
Return element on the outside of this intersection.
Definition intersection.hh:324
Dune::GridGlue::GlobalId
Definition gridgluecommunicate.hh:26
Dune::GridGlue::GlobalId::GlobalId
GlobalId(int i)
Definition gridgluecommunicate.hh:38
Dune::GridGlue::GlobalId::GlobalId
GlobalId()
Definition gridgluecommunicate.hh:30
Dune::GridGlue::GlobalId::GlobalId
GlobalId(int i, int j, unsigned int n)
Definition gridgluecommunicate.hh:48
Dune::GridGlue::CommDataHandle
describes the features of a data handle for communication in parallel runs using the GridGlue::commun...
Definition gridgluecommunicate.hh:77
Dune::GridGlue::CommDataHandle::size
size_t size(RISType &i) const
Definition gridgluecommunicate.hh:92
Dune::GridGlue::CommDataHandle::scatter
void scatter(MessageBufferImp &buff, const EntityType &e, const RISType &i, size_t n)
Definition gridgluecommunicate.hh:118
Dune::GridGlue::CommDataHandle::gather
void gather(MessageBufferImp &buff, const EntityType &e, const RISType &i) const
pack data from user to message buffer
Definition gridgluecommunicate.hh:104
Dune::GridGlue::CommDataHandle::DataType
DataTypeImp DataType
data type of data to communicate
Definition gridgluecommunicate.hh:80
Dune::GridGlue::CommDataHandle::CommDataHandle
CommDataHandle()
Definition gridgluecommunicate.hh:84
Dune::GridGlue::StreamingMessageBuffer::j
size_t j
Definition gridgluecommunicate.hh:183
Dune::GridGlue::StreamingMessageBuffer::StreamingMessageBuffer
StreamingMessageBuffer(DT *p)
Definition gridgluecommunicate.hh:146
Dune::GridGlue::StreamingMessageBuffer::a
DT * a
Definition gridgluecommunicate.hh:181
Dune::GridGlue::StreamingMessageBuffer::counter
size_t counter() const
Definition gridgluecommunicate.hh:169
Dune::GridGlue::StreamingMessageBuffer::write
void write(const Y &data)
Definition gridgluecommunicate.hh:155
Dune::GridGlue::StreamingMessageBuffer::read
void read(Y &data) const
Definition gridgluecommunicate.hh:163
Dune::GridGlue::StreamingMessageBuffer::value_type
DT value_type
Definition gridgluecommunicate.hh:143
Dune::GridGlue::StreamingMessageBuffer::i
size_t i
Definition gridgluecommunicate.hh:182
Dune::GridGlue::StreamingMessageBuffer::clear
void clear()
Definition gridgluecommunicate.hh:171
Dune::GridGlue::CommunicationOperator
forward gather scatter to user defined CommInfo class
Definition gridgluecommunicate.hh:194
Dune::GridGlue::CommunicationOperator::scatter
static void scatter(CommInfo &commInfo, const typename CommInfo::DataType &v, std::size_t i, std::size_t j=0)
Definition gridgluecommunicate.hh:227
Dune::GridGlue::CommunicationOperator::gather
static const CommInfo::DataType & gather(const CommInfo &commInfo, size_t i, size_t j=0)
Definition gridgluecommunicate.hh:197
Dune::GridGlue::CommInfo
collects all GridGlue data required for communication
Definition gridgluecommunicate.hh:272
Dune::GridGlue::CommInfo::dir
Dune::CommunicationDirection dir
Definition gridgluecommunicate.hh:288
Dune::GridGlue::CommInfo::value_type
DataTypeImp value_type
Definition gridgluecommunicate.hh:273
Dune::GridGlue::CommInfo::DataType
DataTypeImp DataType
Definition gridgluecommunicate.hh:275
Dune::GridGlue::CommInfo::data
::Dune::GridGlue::CommDataHandle< DataHandleImp, DataTypeImp > * data
Definition gridgluecommunicate.hh:282
Dune::GridGlue::CommInfo::GridGlue
GG GridGlue
Definition gridgluecommunicate.hh:274
Dune::GridGlue::CommInfo::currentsize
size_t currentsize
Definition gridgluecommunicate.hh:287
Dune::GridGlue::CommInfo::CommInfo
CommInfo()
Definition gridgluecommunicate.hh:277
Dune::GridGlue::CommInfo::mbuffer
mutable ::Dune::GridGlue::StreamingMessageBuffer< DataType > mbuffer
Definition gridgluecommunicate.hh:286
Dune::GridGlue::CommInfo::gridglue
const GridGlue * gridglue
Definition gridgluecommunicate.hh:281
Dune::GridGlue::CommInfo::buffer
std::vector< DataType > buffer
Definition gridgluecommunicate.hh:285
Dune::CommPolicy< ::Dune::GridGlue::CommInfo< GG, DataHandleImp, DataTypeImp > >::getSize
static size_t getSize(const Type &commInfo, size_t i)
Get the number of objects at an intersection.
Definition gridgluecommunicate.hh:320
Dune::CommPolicy< ::Dune::GridGlue::CommInfo< GG, DataHandleImp, DataTypeImp > >::IndexedType
DataTypeImp IndexedType
The datatype that should be communicated.
Definition gridgluecommunicate.hh:309
Dune::CommPolicy< ::Dune::GridGlue::CommInfo< GG, DataHandleImp, DataTypeImp > >::Type
::Dune::GridGlue::CommInfo< GG, DataHandleImp, DataTypeImp > Type
The type of the GridGlueCommInfo.
Definition gridgluecommunicate.hh:304
Dune::CommPolicy< ::Dune::GridGlue::CommInfo< GG, DataHandleImp, DataTypeImp > >::IndexedTypeFlag
VariableSize IndexedTypeFlag
Each intersection can communicate a different number of objects.
Definition gridgluecommunicate.hh:315
GridGlue::getIntersection
Intersection getIntersection(int i) const
Definition gridglue.hh:388