/usr/include/dune/grid-glue/adapter/gridgluecommunicate.hh is in libdune-grid-glue-dev 2.4.0-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_GRIDGLUE_ADAPTER_GRIDGLUECOMMUNICATE_HH
#define DUNE_GRIDGLUE_ADAPTER_GRIDGLUECOMMUNICATE_HH
/**@file
@author Christian Engwer
@brief Describes the parallel communication interface class for Dune::GridGlue
*/
#include <dune/common/version.hh>
#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>
{
/** default constructor, required for dune-common RemoteIndices
\internal
*/
GlobalId() {
this->first.first = 0;
this->first.second = 0;
this->second = 0;
}
/** constructor from int, required for dune-common RemoteIndices
\internal
*/
GlobalId(int i) {
this->first.first = i;
this->first.second = i;
this->second = 0;
}
/** constructor
\param i rank of processor 1
\param j rank of processor 2
\param n local intersection index
*/
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;
}
/**
\brief describes the features of a data handle for
communication in parallel runs using the GridGlue::communicate methods.
Here the Barton-Nackman trick is used to interprete data handle objects
as its interface. Therefore usable data handle classes need to be
derived from this class.
\tparam DataHandleImp implementation of the users data handle
\tparam DataTypeImp type of data that are going to be communicated which is exported as \c DataType (for example double)
\ingroup GridGlueCommunication
*/
template <class DataHandleImp, class DataTypeImp>
class CommDataHandle
{
public:
//! data type of data to communicate
typedef DataTypeImp DataType;
protected:
// one should not create an explicit instance of this inteface object
CommDataHandle() {}
public:
/*! how many objects of type DataType have to be sent for a given intersection
Note: Both sender and receiver side need to know this size.
*/
template<class RISType>
size_t size (RISType& i) const
{
CHECK_INTERFACE_IMPLEMENTATION((asImp().size(i)));
return asImp().size(i);
}
/** @brief pack data from user to message buffer
@param buff message buffer provided by the grid
@param e entity for which date should be packed to buffer
@param i Intersection for which data should be packed to buffer
*/
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)));
}
/*! unpack data from message buffer to user
n is the number of objects sent by the sender
@param buff message buffer provided by the grid
@param e entity for which date should be unpacked from buffer
@param i Intersection for which data is received
@param n number of data written to buffer for this entity before
*/
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:
//! Barton-Nackman trick
DataHandleImp& asImp () {
return static_cast<DataHandleImp &> (*this);
}
//! Barton-Nackman trick
const DataHandleImp& asImp () const
{
return static_cast<const DataHandleImp &>(*this);
}
}; // end class CommDataHandleIF
/**
Streaming MessageBuffer for the GridGlue communication
\ingroup GridGlueCommunication
*/
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(( 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(( 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;
};
/**
\brief forward gather scatter to user defined CommInfo class
- implements the ParallelIndexset gather/scatter interface
- redirects all calls to the GridGlueCommDataHandleIF gather/scatter methods
*/
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;
/**
\brief collects all GridGlue data requried for communication
\ingroup GridGlueCommunication
*/
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
/**
* \brief specialization of the CommPolicy struct, required for the ParallelIndexsets
* \internal
*/
template<typename GG, class DataHandleImp, class DataTypeImp>
struct CommPolicy< ::Dune::GridGlue::CommInfo<GG, DataHandleImp, DataTypeImp> >
{
/**
* @brief The type of the GridGlueCommInfo
*/
typedef ::Dune::GridGlue::CommInfo<GG, DataHandleImp, DataTypeImp> Type;
/**
* @brief The datatype that should be communicated.
*/
typedef DataTypeImp IndexedType;
/**
* @brief Each intersection can communicate a different number of objects.
*/
// typedef SizeOne IndexedTypeFlag;
typedef VariableSize IndexedTypeFlag;
/**
* @brief Get the number of objects at an intersection.
*/
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
|