Comms update on GGI AMG interface
This commit is contained in:
parent
5f5860e3c4
commit
07de8431c1
11 changed files with 322 additions and 258 deletions
|
@ -258,6 +258,12 @@ bool Foam::ggiFvPatch::localParallel() const
|
|||
}
|
||||
|
||||
|
||||
const Foam::mapDistribute& Foam::ggiFvPatch::map() const
|
||||
{
|
||||
return ggiPolyPatch_.map();
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarListList& Foam::ggiFvPatch::weights() const
|
||||
{
|
||||
if (ggiPolyPatch_.master())
|
||||
|
|
|
@ -171,6 +171,9 @@ public:
|
|||
//- Is the patch localised on a single processor
|
||||
virtual bool localParallel() const;
|
||||
|
||||
//- Return mapDistribute
|
||||
virtual const mapDistribute& map() const;
|
||||
|
||||
//- Return weights. Master side returns own weights and
|
||||
// slave side returns weights from master
|
||||
virtual const scalarListList& weights() const;
|
||||
|
|
|
@ -34,6 +34,7 @@ Author
|
|||
#include "fvMesh.H"
|
||||
#include "fvBoundaryMesh.H"
|
||||
#include "foamTime.H"
|
||||
#include "mapDistribute.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
@ -302,6 +303,12 @@ bool Foam::regionCoupleFvPatch::localParallel() const
|
|||
}
|
||||
|
||||
|
||||
const Foam::mapDistribute& Foam::regionCoupleFvPatch::map() const
|
||||
{
|
||||
return rcPolyPatch_.map();
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarListList& Foam::regionCoupleFvPatch::weights() const
|
||||
{
|
||||
if (rcPolyPatch_.master())
|
||||
|
|
|
@ -180,6 +180,9 @@ public:
|
|||
//- Is the patch localised on a single processor
|
||||
virtual bool localParallel() const;
|
||||
|
||||
//- Return mapDistribute
|
||||
const mapDistribute& map() const;
|
||||
|
||||
//- Return weights. Master side returns own weights and
|
||||
// slave side returns weights from master
|
||||
virtual const scalarListList& weights() const;
|
||||
|
|
|
@ -46,6 +46,10 @@ SourceFiles
|
|||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
|
||||
class mapDistribute;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ggiLduInterface Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
@ -111,6 +115,9 @@ public:
|
|||
//- Is the patch localised on a single processor
|
||||
virtual bool localParallel() const = 0;
|
||||
|
||||
//- Return mapDistribute
|
||||
virtual const mapDistribute& map() const = 0;
|
||||
|
||||
//- Return weights
|
||||
virtual const scalarListList& weights() const = 0;
|
||||
|
||||
|
|
|
@ -839,30 +839,67 @@ Foam::ggiAMGInterface::ggiAMGInterface
|
|||
// Re-pack singly linked list of processor master faces
|
||||
// and pass to other processors
|
||||
|
||||
// First index: master proc
|
||||
// Second index: slave proc
|
||||
// List contents: global faces in order
|
||||
labelListListList crissCrossList(Pstream::nProcs());
|
||||
|
||||
labelListList& crissList = crissCrossList[Pstream::myProcNo()];
|
||||
|
||||
crissList.setSize(Pstream::nProcs());
|
||||
|
||||
forAll (crissList, procI)
|
||||
{
|
||||
crissList[procI] = procMasterFacesLL[procI];
|
||||
}
|
||||
|
||||
Pstream::gatherList(crissCrossList);
|
||||
Pstream::scatterList(crissCrossList);
|
||||
|
||||
procMasterFaces_.setSize(Pstream::nProcs());
|
||||
|
||||
forAll (procMasterFaces_, procI)
|
||||
// Copy self
|
||||
procMasterFaces_[Pstream::myProcNo()] =
|
||||
procMasterFacesLL[Pstream::myProcNo()];
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
procMasterFaces_[procI] =
|
||||
crissCrossList[procI][Pstream::myProcNo()];
|
||||
const List<labelPair> schedule =
|
||||
fineGgiInterface_.map().schedule();
|
||||
|
||||
// Do the comms
|
||||
forAll (schedule, i)
|
||||
{
|
||||
const label sendProc = schedule[i].first();
|
||||
const label recvProc = schedule[i].second();
|
||||
|
||||
if (Pstream::myProcNo() == sendProc)
|
||||
{
|
||||
OPstream toNbr(Pstream::scheduled, recvProc);
|
||||
toNbr << labelList(procMasterFacesLL[recvProc]);
|
||||
}
|
||||
else if (Pstream::myProcNo() == recvProc)
|
||||
{
|
||||
IPstream fromNbr(Pstream::scheduled, sendProc);
|
||||
|
||||
procMasterFaces_[sendProc] = labelList(fromNbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("...")
|
||||
<< "My proc number " << Pstream::myProcNo()
|
||||
<< " is neither a sender nor a receiver: "
|
||||
<< schedule[i]
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // First index: master proc
|
||||
// // Second index: slave proc
|
||||
// // List contents: global faces in order
|
||||
// labelListListList crissCrossList(Pstream::nProcs());
|
||||
|
||||
// labelListList& crissList = crissCrossList[Pstream::myProcNo()];
|
||||
|
||||
// crissList.setSize(Pstream::nProcs());
|
||||
|
||||
// forAll (crissList, procI)
|
||||
// {
|
||||
// crissList[procI] = procMasterFacesLL[procI];
|
||||
// }
|
||||
|
||||
// Pstream::gatherList(crissCrossList);
|
||||
// Pstream::scatterList(crissCrossList);
|
||||
|
||||
// forAll (procMasterFaces_, procI)
|
||||
// {
|
||||
// procMasterFaces_[procI] =
|
||||
// crissCrossList[procI][Pstream::myProcNo()];
|
||||
// }
|
||||
}
|
||||
// Agglomerate slave
|
||||
else
|
||||
|
|
|
@ -509,17 +509,6 @@ void Foam::ggiPolyPatch::calcSendReceive() const
|
|||
}
|
||||
|
||||
|
||||
const Foam::mapDistribute& Foam::ggiPolyPatch::map() const
|
||||
{
|
||||
if (!mapPtr_)
|
||||
{
|
||||
calcSendReceive();
|
||||
}
|
||||
|
||||
return *mapPtr_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::ggiPolyPatch::clearGeom() const
|
||||
{
|
||||
deleteDemandDrivenData(reconFaceCellCentresPtr_);
|
||||
|
@ -530,6 +519,10 @@ void Foam::ggiPolyPatch::clearGeom() const
|
|||
// HJ, 23/Jun/2011
|
||||
deleteDemandDrivenData(remoteZoneAddressingPtr_);
|
||||
|
||||
// localParallel depends on geometry - must be cleared!
|
||||
// HR, 11/Jul/2013
|
||||
deleteDemandDrivenData(localParallelPtr_);
|
||||
|
||||
deleteDemandDrivenData(mapPtr_);
|
||||
}
|
||||
|
||||
|
@ -543,7 +536,6 @@ void Foam::ggiPolyPatch::clearOut() const
|
|||
|
||||
deleteDemandDrivenData(zoneAddressingPtr_);
|
||||
deleteDemandDrivenData(patchToPatchPtr_);
|
||||
deleteDemandDrivenData(localParallelPtr_);
|
||||
}
|
||||
|
||||
|
||||
|
@ -826,6 +818,17 @@ const Foam::ggiZoneInterpolation& Foam::ggiPolyPatch::patchToPatch() const
|
|||
}
|
||||
|
||||
|
||||
const Foam::mapDistribute& Foam::ggiPolyPatch::map() const
|
||||
{
|
||||
if (!mapPtr_)
|
||||
{
|
||||
calcSendReceive();
|
||||
}
|
||||
|
||||
return *mapPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::vectorField& Foam::ggiPolyPatch::reconFaceCellCentres() const
|
||||
{
|
||||
if (!reconFaceCellCentresPtr_)
|
||||
|
|
|
@ -138,9 +138,6 @@ class ggiPolyPatch
|
|||
//- Calculate send and receive addressing
|
||||
void calcSendReceive() const;
|
||||
|
||||
//- Return mapDistribute
|
||||
const mapDistribute& map() const;
|
||||
|
||||
|
||||
// Memory management
|
||||
|
||||
|
@ -335,6 +332,9 @@ public:
|
|||
//- Is the patch localised on a single processor
|
||||
bool localParallel() const;
|
||||
|
||||
//- Return mapDistribute
|
||||
const mapDistribute& map() const;
|
||||
|
||||
//- Return reference to patch-to-patch interpolation
|
||||
// Used only for addressing
|
||||
const ggiZoneInterpolation& patchToPatch() const;
|
||||
|
|
|
@ -226,7 +226,7 @@ void Foam::regionCouplePolyPatch::calcPatchToPatch() const
|
|||
SMALL, // Non-overlapping face tolerances
|
||||
SMALL,
|
||||
true, // Rescale weighting factors
|
||||
ggiInterpolation::BB_OCTREE // Octree search, MB.
|
||||
reject_ // Quick rejection algorithm, default BB_OCTREE
|
||||
);
|
||||
|
||||
// Abort immediately if uncovered faces are present and the option
|
||||
|
@ -378,7 +378,7 @@ void Foam::regionCouplePolyPatch::calcSendReceive() const
|
|||
// (of the calc-call) they will be set to zero-sized array
|
||||
// HJ, 4/Jun/2011
|
||||
|
||||
if (receiveAddrPtr_ || sendAddrPtr_)
|
||||
if (mapPtr_)
|
||||
{
|
||||
FatalErrorIn("void regionCouplePolyPatch::calcSendReceive() const")
|
||||
<< "Send-receive addressing already calculated"
|
||||
|
@ -399,74 +399,129 @@ void Foam::regionCouplePolyPatch::calcSendReceive() const
|
|||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Master will receive and store the maps
|
||||
if (Pstream::master())
|
||||
{
|
||||
receiveAddrPtr_ = new labelListList(Pstream::nProcs());
|
||||
labelListList& rAddr = *receiveAddrPtr_;
|
||||
// Gather send and receive addressing (to master)
|
||||
|
||||
sendAddrPtr_ = new labelListList(Pstream::nProcs());
|
||||
labelListList& sAddr = *sendAddrPtr_;
|
||||
|
||||
// Insert master
|
||||
rAddr[0] = zoneAddressing();
|
||||
|
||||
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||
{
|
||||
// Note: must use normal comms because the size of the
|
||||
// communicated lists is unknown on the receiving side
|
||||
// HJ, 4/Jun/2011
|
||||
|
||||
// Opt: reconsider mode of communication
|
||||
IPstream ip(Pstream::scheduled, procI);
|
||||
|
||||
rAddr[procI] = labelList(ip);
|
||||
|
||||
sAddr[procI] = labelList(ip);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create dummy pointers: only master processor stores maps
|
||||
receiveAddrPtr_ = new labelListList();
|
||||
sendAddrPtr_ = new labelListList();
|
||||
|
||||
// Send information to master
|
||||
// Get patch-to-zone addressing
|
||||
const labelList& za = zoneAddressing();
|
||||
const labelList& ra = remoteZoneAddressing();
|
||||
|
||||
// Note: must use normal comms because the size of the
|
||||
// communicated lists is unknown on the receiving side
|
||||
// HJ, 4/Jun/2011
|
||||
// Make a zone-sized field and fill it in with proc markings for processor
|
||||
// that holds and requires the data
|
||||
labelField zoneProcID(zone().size(), -1);
|
||||
|
||||
// Opt: reconsider mode of communication
|
||||
OPstream op(Pstream::scheduled, Pstream::masterNo());
|
||||
|
||||
// Send local and remote addressing to master
|
||||
op << za << ra;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelListList& Foam::regionCouplePolyPatch::receiveAddr() const
|
||||
{
|
||||
if (!receiveAddrPtr_)
|
||||
forAll (za, zaI)
|
||||
{
|
||||
calcSendReceive();
|
||||
zoneProcID[za[zaI]] = Pstream::myProcNo();
|
||||
}
|
||||
|
||||
return *receiveAddrPtr_;
|
||||
}
|
||||
reduce(zoneProcID, maxOp<labelField>());
|
||||
|
||||
const labelList& shadowRza = shadow().remoteZoneAddressing();
|
||||
|
||||
const Foam::labelListList& Foam::regionCouplePolyPatch::sendAddr() const
|
||||
{
|
||||
if (!sendAddrPtr_)
|
||||
// Find out where my zone data is coming from
|
||||
labelList nRecv(Pstream::nProcs(), 0);
|
||||
|
||||
// Note: only visit the data from the local zone
|
||||
forAll (shadowRza, shadowRzaI)
|
||||
{
|
||||
calcSendReceive();
|
||||
nRecv[zoneProcID[shadowRza[shadowRzaI]]]++;
|
||||
}
|
||||
|
||||
return *sendAddrPtr_;
|
||||
// Make a receiving sub-map
|
||||
// It tells me which data I will receive from which processor and
|
||||
// where I need to put it into the remoteZone data before the mapping
|
||||
labelListList constructMap(Pstream::nProcs());
|
||||
|
||||
// Size the receiving list
|
||||
forAll (nRecv, procI)
|
||||
{
|
||||
constructMap[procI].setSize(nRecv[procI]);
|
||||
}
|
||||
|
||||
// Reset counters for processors
|
||||
nRecv = 0;
|
||||
|
||||
forAll (shadowRza, shadowRzaI)
|
||||
{
|
||||
label recvProc = zoneProcID[shadowRza[shadowRzaI]];
|
||||
|
||||
constructMap[recvProc][nRecv[recvProc]] = shadowRza[shadowRzaI];
|
||||
|
||||
nRecv[recvProc]++;
|
||||
}
|
||||
|
||||
// Make the sending sub-map
|
||||
// It tells me which data is required from me to be sent to which
|
||||
// processor
|
||||
|
||||
// Algorithm
|
||||
// - expand the local zone faces with indices into a size of local zone
|
||||
// - go through remote zone addressing on all processors
|
||||
// - find out who hits my faces
|
||||
labelList localZoneIndices(zone().size(), -1);
|
||||
|
||||
forAll (za, zaI)
|
||||
{
|
||||
localZoneIndices[za[zaI]] = zaI;
|
||||
}
|
||||
|
||||
labelListList shadowToReceiveAddr(Pstream::nProcs());
|
||||
|
||||
// Get the list of what my shadow needs to receive from my zone
|
||||
// on all other processors
|
||||
shadowToReceiveAddr[Pstream::myProcNo()] = shadowRza;
|
||||
Pstream::gatherList(shadowToReceiveAddr);
|
||||
Pstream::scatterList(shadowToReceiveAddr);
|
||||
|
||||
// Now local zone indices contain the index of a local face that will
|
||||
// provide the data. For faces that are not local, the index will be -1
|
||||
|
||||
// Find out where my zone data is going to
|
||||
|
||||
// Make a sending sub-map
|
||||
// It tells me which data I will send to which processor
|
||||
labelListList sendMap(Pstream::nProcs());
|
||||
|
||||
// Collect local labels to be sent to each processor
|
||||
forAll (shadowToReceiveAddr, procI)
|
||||
{
|
||||
const labelList& curProcSend = shadowToReceiveAddr[procI];
|
||||
|
||||
// Find out how much of my data is going to this processor
|
||||
label nProcSend = 0;
|
||||
|
||||
forAll (curProcSend, sendI)
|
||||
{
|
||||
if (localZoneIndices[curProcSend[sendI]] > -1)
|
||||
{
|
||||
nProcSend++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nProcSend > 0)
|
||||
{
|
||||
// Collect the indices
|
||||
labelList& curSendMap = sendMap[procI];
|
||||
|
||||
curSendMap.setSize(nProcSend);
|
||||
|
||||
// Reset counter
|
||||
nProcSend = 0;
|
||||
|
||||
forAll (curProcSend, sendI)
|
||||
{
|
||||
if (localZoneIndices[curProcSend[sendI]] > -1)
|
||||
{
|
||||
curSendMap[nProcSend] =
|
||||
localZoneIndices[curProcSend[sendI]];
|
||||
nProcSend++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map will return the object of the size of remote zone
|
||||
// HJ, 9/May/2016
|
||||
mapPtr_ = new mapDistribute(zone().size(), sendMap, constructMap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -492,18 +547,19 @@ void Foam::regionCouplePolyPatch::clearGeom() const
|
|||
{
|
||||
clearDeltas();
|
||||
|
||||
deleteDemandDrivenData(reconFaceCellCentresPtr_);
|
||||
|
||||
// Remote addressing and send-receive maps depend on the local
|
||||
// position. Therefore, it needs to be recalculated at mesh motion.
|
||||
// Local zone addressing does not change with mesh motion
|
||||
// HJ, 23/Jun/2011
|
||||
deleteDemandDrivenData(remoteZoneAddressingPtr_);
|
||||
|
||||
deleteDemandDrivenData(receiveAddrPtr_);
|
||||
deleteDemandDrivenData(sendAddrPtr_);
|
||||
|
||||
// localParallel depends on geometry - must be cleared!
|
||||
// HR, 11/Jul/2013
|
||||
deleteDemandDrivenData(localParallelPtr_);
|
||||
|
||||
deleteDemandDrivenData(mapPtr_);
|
||||
}
|
||||
|
||||
|
||||
|
@ -511,6 +567,9 @@ void Foam::regionCouplePolyPatch::clearOut() const
|
|||
{
|
||||
clearGeom();
|
||||
|
||||
shadowIndex_ = -1;
|
||||
zoneIndex_ = -1;
|
||||
|
||||
deleteDemandDrivenData(zoneAddressingPtr_);
|
||||
deleteDemandDrivenData(patchToPatchPtr_);
|
||||
}
|
||||
|
@ -535,6 +594,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
master_(false),
|
||||
isWall_(false),
|
||||
bridgeOverlap_(false),
|
||||
reject_(ggiZoneInterpolation::BB_OCTREE),
|
||||
shadowIndex_(-1),
|
||||
zoneIndex_(-1),
|
||||
patchToPatchPtr_(NULL),
|
||||
|
@ -542,8 +602,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
remoteZoneAddressingPtr_(NULL),
|
||||
reconFaceCellCentresPtr_(NULL),
|
||||
localParallelPtr_(NULL),
|
||||
receiveAddrPtr_(NULL),
|
||||
sendAddrPtr_(NULL)
|
||||
mapPtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -560,7 +619,8 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
const bool attached,
|
||||
const bool master,
|
||||
const bool isWall,
|
||||
const bool bridgeOverlap
|
||||
const bool bridgeOverlap,
|
||||
const ggiZoneInterpolation::quickReject reject
|
||||
)
|
||||
:
|
||||
coupledPolyPatch(name, size, start, index, bm),
|
||||
|
@ -571,6 +631,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
master_(master),
|
||||
isWall_(isWall),
|
||||
bridgeOverlap_(bridgeOverlap),
|
||||
reject_(reject),
|
||||
shadowIndex_(-1),
|
||||
zoneIndex_(-1),
|
||||
patchToPatchPtr_(NULL),
|
||||
|
@ -578,8 +639,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
remoteZoneAddressingPtr_(NULL),
|
||||
reconFaceCellCentresPtr_(NULL),
|
||||
localParallelPtr_(NULL),
|
||||
receiveAddrPtr_(NULL),
|
||||
sendAddrPtr_(NULL)
|
||||
mapPtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -599,6 +659,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
master_(dict.lookup("master")),
|
||||
isWall_(dict.lookup("isWall")),
|
||||
bridgeOverlap_(dict.lookup("bridgeOverlap")),
|
||||
reject_(ggiZoneInterpolation::BB_OCTREE),
|
||||
shadowIndex_(-1),
|
||||
zoneIndex_(-1),
|
||||
patchToPatchPtr_(NULL),
|
||||
|
@ -606,9 +667,16 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
remoteZoneAddressingPtr_(NULL),
|
||||
reconFaceCellCentresPtr_(NULL),
|
||||
localParallelPtr_(NULL),
|
||||
receiveAddrPtr_(NULL),
|
||||
sendAddrPtr_(NULL)
|
||||
{}
|
||||
mapPtr_(NULL)
|
||||
{
|
||||
if (dict.found("quickReject"))
|
||||
{
|
||||
reject_ = ggiZoneInterpolation::quickRejectNames_.read
|
||||
(
|
||||
dict.lookup("quickReject")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
||||
|
@ -624,6 +692,8 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
attached_(pp.attached_),
|
||||
master_(pp.master_),
|
||||
isWall_(pp.isWall_),
|
||||
bridgeOverlap_(pp.bridgeOverlap_),
|
||||
reject_(pp.reject_),
|
||||
shadowIndex_(-1),
|
||||
zoneIndex_(-1),
|
||||
patchToPatchPtr_(NULL),
|
||||
|
@ -631,8 +701,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
remoteZoneAddressingPtr_(NULL),
|
||||
reconFaceCellCentresPtr_(NULL),
|
||||
localParallelPtr_(NULL),
|
||||
receiveAddrPtr_(NULL),
|
||||
sendAddrPtr_(NULL)
|
||||
mapPtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -652,6 +721,8 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
attached_(pp.attached_),
|
||||
master_(pp.master_),
|
||||
isWall_(pp.isWall_),
|
||||
bridgeOverlap_(pp.bridgeOverlap_),
|
||||
reject_(pp.reject_),
|
||||
shadowIndex_(-1),
|
||||
zoneIndex_(-1),
|
||||
patchToPatchPtr_(NULL),
|
||||
|
@ -659,8 +730,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
|||
remoteZoneAddressingPtr_(NULL),
|
||||
reconFaceCellCentresPtr_(NULL),
|
||||
localParallelPtr_(NULL),
|
||||
receiveAddrPtr_(NULL),
|
||||
sendAddrPtr_(NULL)
|
||||
mapPtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -911,6 +981,17 @@ Foam::regionCouplePolyPatch::patchToPatch() const
|
|||
}
|
||||
|
||||
|
||||
const Foam::mapDistribute& Foam::regionCouplePolyPatch::map() const
|
||||
{
|
||||
if (!mapPtr_)
|
||||
{
|
||||
calcSendReceive();
|
||||
}
|
||||
|
||||
return *mapPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::vectorField&
|
||||
Foam::regionCouplePolyPatch::reconFaceCellCentres() const
|
||||
{
|
||||
|
@ -940,6 +1021,11 @@ void Foam::regionCouplePolyPatch::initAddressing()
|
|||
// Calculate transforms for correct GGI cut
|
||||
calcTransforms();
|
||||
|
||||
if (master())
|
||||
{
|
||||
shadow().calcTransforms();
|
||||
}
|
||||
|
||||
// Force zone addressing and remote zone addressing
|
||||
// (uses GGI interpolator)
|
||||
zoneAddressing();
|
||||
|
@ -949,7 +1035,7 @@ void Foam::regionCouplePolyPatch::initAddressing()
|
|||
if (Pstream::parRun() && !localParallel())
|
||||
{
|
||||
// Calculate send addressing
|
||||
sendAddr();
|
||||
map();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1019,7 +1105,7 @@ void Foam::regionCouplePolyPatch::initMovePoints(const pointField& p)
|
|||
if (Pstream::parRun() && !localParallel())
|
||||
{
|
||||
// Calculate send addressing
|
||||
sendAddr();
|
||||
map();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ SourceFiles
|
|||
#include "ggiInterpolation.H"
|
||||
#include "faceZone.H"
|
||||
#include "Switch.H"
|
||||
#include "mapDistribute.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
@ -81,6 +82,12 @@ class regionCouplePolyPatch
|
|||
//- Use bridging to fix overlap error in interpolation
|
||||
Switch bridgeOverlap_;
|
||||
|
||||
//- Quick reject algorithm
|
||||
ggiZoneInterpolation::quickReject reject_;
|
||||
|
||||
|
||||
// Demand-driven data
|
||||
|
||||
//- Shadow patch index. Delayed evaluation for construction
|
||||
mutable label shadowIndex_;
|
||||
|
||||
|
@ -108,11 +115,8 @@ class regionCouplePolyPatch
|
|||
// Used for parallel optimisation
|
||||
mutable bool* localParallelPtr_;
|
||||
|
||||
//- List of zone faces indices received from each processor
|
||||
mutable labelListList* receiveAddrPtr_;
|
||||
|
||||
//- List of zone faces indices to send to each processor
|
||||
mutable labelListList* sendAddrPtr_;
|
||||
//- Map-distribute comms tool
|
||||
mutable mapDistribute* mapPtr_;
|
||||
|
||||
|
||||
// Private member functions
|
||||
|
@ -145,13 +149,6 @@ class regionCouplePolyPatch
|
|||
void calcSendReceive() const;
|
||||
|
||||
|
||||
//- Return receive addressing
|
||||
const labelListList& receiveAddr() const;
|
||||
|
||||
//- Return send addressing
|
||||
const labelListList& sendAddr() const;
|
||||
|
||||
|
||||
// Memory management
|
||||
|
||||
//- Clear delta coefficients
|
||||
|
@ -232,7 +229,9 @@ public:
|
|||
const bool attached,
|
||||
const bool master,
|
||||
const bool isWall,
|
||||
const bool bridgeOverlap
|
||||
const bool bridgeOverlap,
|
||||
const ggiZoneInterpolation::quickReject
|
||||
reject = ggiZoneInterpolation::BB_OCTREE
|
||||
);
|
||||
|
||||
//- Construct from dictionary
|
||||
|
@ -292,8 +291,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
//-Destructor
|
||||
virtual ~regionCouplePolyPatch();
|
||||
|
||||
|
||||
|
@ -382,6 +380,9 @@ public:
|
|||
//- Is the patch localised on a single processor
|
||||
bool localParallel() const;
|
||||
|
||||
//- Return mapDistribute
|
||||
const mapDistribute& map() const;
|
||||
|
||||
//- Return reference to patch-to-patch interpolation
|
||||
const ggiZoneInterpolation& patchToPatch() const;
|
||||
|
||||
|
|
|
@ -39,22 +39,6 @@ Foam::tmp<Foam::Field<Type> > Foam::regionCouplePolyPatch::fastExpand
|
|||
{
|
||||
// Check and expand the field from patch size to zone size
|
||||
// with communication
|
||||
|
||||
// Algorithm:
|
||||
// 1) Master processor holds maps of all zone addressing (data provided)
|
||||
// and all remote zone addressing (data required)
|
||||
// 2) Each processor will send the locally active data to the master
|
||||
// 3) Master assembles all the data
|
||||
// 4) Master sends to all processors the data they need to receive
|
||||
//
|
||||
// Notes:
|
||||
// A) If the size of zone addressing is zero, data is not sent
|
||||
// B) Communicated data on each processor has the size of live faces
|
||||
// C) Expanded data will be equal to actual data from other processors
|
||||
// only for the faces marked in remote; for other faces, it will be
|
||||
// equal to zero
|
||||
// D) On processor zero, complete data is available
|
||||
// HJ, 4/Jun/2011
|
||||
if (ff.size() != size())
|
||||
{
|
||||
FatalErrorIn
|
||||
|
@ -80,127 +64,54 @@ Foam::tmp<Foam::Field<Type> > Foam::regionCouplePolyPatch::fastExpand
|
|||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Replaced old comms algorithm. HJ, 31/May/2016
|
||||
// HJ, 4/Jun/2011
|
||||
|
||||
// This function requires send-receive-addressing, but usage is not
|
||||
// symmetric across processors. Hence trigger re-calculate at this point
|
||||
// HR, 10/Jul/2013
|
||||
if (Pstream::parRun() && !localParallel())
|
||||
{
|
||||
receiveAddr();
|
||||
shadow().receiveAddr();
|
||||
map();
|
||||
shadow().map();
|
||||
}
|
||||
|
||||
// Expand the field to zone size
|
||||
// New version: mapDistribute
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
// Optimised mapDistribute
|
||||
|
||||
// Prepare return field: expand the field to zone size
|
||||
tmp<Field<Type> > texpandField
|
||||
(
|
||||
new Field<Type>(zone().size(), pTraits<Type>::zero)
|
||||
new Field<Type>(ff)
|
||||
);
|
||||
|
||||
Field<Type>& expandField = texpandField();
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
// Insert master processor
|
||||
const labelList& za = zoneAddressing();
|
||||
map().distribute(expandField);
|
||||
|
||||
forAll (za, i)
|
||||
{
|
||||
expandField[za[i]] = ff[i];
|
||||
}
|
||||
|
||||
// Master receives and inserts data from all processors for which
|
||||
// receiveAddr contains entries
|
||||
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||
{
|
||||
const labelList& curRAddr = receiveAddr()[procI];
|
||||
|
||||
if (!curRAddr.empty())
|
||||
{
|
||||
Field<Type> receiveBuf(curRAddr.size());
|
||||
|
||||
// Opt: reconsider mode of communication
|
||||
IPstream::read
|
||||
(
|
||||
Pstream::blocking,
|
||||
procI,
|
||||
reinterpret_cast<char*>(receiveBuf.begin()),
|
||||
receiveBuf.byteSize()
|
||||
);
|
||||
|
||||
// Insert received information
|
||||
forAll (curRAddr, i)
|
||||
{
|
||||
expandField[curRAddr[i]] = receiveBuf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expanded field complete, send required data to other processors
|
||||
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||
{
|
||||
const labelList& curSAddr = shadow().sendAddr()[procI];
|
||||
|
||||
if (!curSAddr.empty())
|
||||
{
|
||||
Field<Type> sendBuf(curSAddr.size());
|
||||
|
||||
forAll (curSAddr, i)
|
||||
{
|
||||
sendBuf[i] = expandField[curSAddr[i]];
|
||||
}
|
||||
|
||||
// Opt: reconsider mode of communication
|
||||
OPstream::write
|
||||
(
|
||||
Pstream::blocking,
|
||||
procI,
|
||||
reinterpret_cast<const char*>(sendBuf.begin()),
|
||||
sendBuf.byteSize()
|
||||
);
|
||||
}
|
||||
}
|
||||
return texpandField;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send local data to master and receive remote data
|
||||
// If patch is empty, communication is avoided
|
||||
// HJ, 4/Jun/2011
|
||||
if (size())
|
||||
{
|
||||
// Opt: reconsider mode of communication
|
||||
OPstream::write
|
||||
// Serial. Expand the field to zone size
|
||||
|
||||
tmp<Field<Type> > texpandField
|
||||
(
|
||||
Pstream::blocking,
|
||||
Pstream::masterNo(),
|
||||
reinterpret_cast<const char*>(ff.begin()),
|
||||
ff.byteSize()
|
||||
new Field<Type>(zone().size()) // filled with nans
|
||||
);
|
||||
}
|
||||
Field<Type>& expandField = texpandField();
|
||||
|
||||
// Prepare to receive remote data
|
||||
const labelList& rza = shadow().remoteZoneAddressing();
|
||||
const labelList& zAddr = zoneAddressing();
|
||||
|
||||
if (!rza.empty())
|
||||
forAll (zAddr, i)
|
||||
{
|
||||
Field<Type> receiveBuf(rza.size());
|
||||
|
||||
// Opt: reconsider mode of communication
|
||||
IPstream::read
|
||||
(
|
||||
Pstream::blocking,
|
||||
Pstream::masterNo(),
|
||||
reinterpret_cast<char*>(receiveBuf.begin()),
|
||||
receiveBuf.byteSize()
|
||||
);
|
||||
|
||||
// Insert the data into expanded field
|
||||
forAll (rza, i)
|
||||
{
|
||||
expandField[rza[i]] = receiveBuf[i];
|
||||
}
|
||||
}
|
||||
expandField[zAddr[i]] = ff[i];
|
||||
}
|
||||
|
||||
return texpandField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Reference in a new issue