BUG: Fixing multiple processor patch problems in parallel transfer of

particles.
This commit is contained in:
graham
2010-06-01 16:09:08 +01:00
parent a0769d3dc6
commit 62b980f203
3 changed files with 87 additions and 35 deletions

View File

@ -27,6 +27,7 @@ License
#include "ListOps.H" #include "ListOps.H"
#include "Pstream.H" #include "Pstream.H"
#include "commSchedule.H" #include "commSchedule.H"
#include "boolList.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -42,6 +43,8 @@ Foam::labelList Foam::ProcessorTopology<Patch, ProcPatch>::procNeighbours
label maxNb = 0; label maxNb = 0;
boolList isNeighbourProc(Pstream::nProcs(), false);
forAll(patches, patchi) forAll(patches, patchi)
{ {
const Patch& patch = patches[patchi]; const Patch& patch = patches[patchi];
@ -51,19 +54,34 @@ Foam::labelList Foam::ProcessorTopology<Patch, ProcPatch>::procNeighbours
const ProcPatch& procPatch = const ProcPatch& procPatch =
refCast<const ProcPatch>(patch); refCast<const ProcPatch>(patch);
label pNeighbProcNo = procPatch.neighbProcNo();
if (!isNeighbourProc[pNeighbProcNo])
{
nNeighbours++; nNeighbours++;
maxNb = max(maxNb, procPatch.neighbProcNo()); maxNb = max(maxNb, procPatch.neighbProcNo());
isNeighbourProc[pNeighbProcNo] = true;
}
} }
} }
labelList neighbours(nNeighbours); labelList neighbours(nNeighbours, -1);
nNeighbours = 0;
forAll(isNeighbourProc, procI)
{
if (isNeighbourProc[procI])
{
neighbours[nNeighbours++] = procI;
}
}
procPatchMap_.setSize(maxNb + 1); procPatchMap_.setSize(maxNb + 1);
procPatchMap_ = -1; procPatchMap_ = -1;
nNeighbours = 0;
forAll(patches, patchi) forAll(patches, patchi)
{ {
const Patch& patch = patches[patchi]; const Patch& patch = patches[patchi];
@ -73,8 +91,6 @@ Foam::labelList Foam::ProcessorTopology<Patch, ProcPatch>::procNeighbours
const ProcPatch& procPatch = const ProcPatch& procPatch =
refCast<const ProcPatch>(patch); refCast<const ProcPatch>(patch);
neighbours[nNeighbours++] = procPatch.neighbProcNo();
// Construct reverse map // Construct reverse map
procPatchMap_[procPatch.neighbProcNo()] = patchi; procPatchMap_[procPatch.neighbProcNo()] = patchi;
} }

View File

@ -30,6 +30,9 @@ Description
*this[procI] gives the list of neighbouring processors. *this[procI] gives the list of neighbouring processors.
TODO: This does not currently correctly support multiple processor
patches connecting two processors.
SourceFiles SourceFiles
ProcessorTopology.C ProcessorTopology.C

View File

@ -102,8 +102,18 @@ template<class TrackingData>
void Foam::Cloud<ParticleType>::move(TrackingData& td) void Foam::Cloud<ParticleType>::move(TrackingData& td)
{ {
const globalMeshData& pData = polyMesh_.globalData(); const globalMeshData& pData = polyMesh_.globalData();
const labelList& processorPatches = pData.processorPatches(); const labelList& neighbourProcs = pData[Pstream::myProcNo()];
const labelList& processorPatchIndices = pData.processorPatchIndices(); const labelList& procPatches = pData.processorPatches();
const labelList& procPatchIndices = pData.processorPatchIndices();
const labelList& procPatchNeighbours = pData.processorPatchNeighbours();
const polyBoundaryMesh& pbm = pMesh().boundaryMesh();
labelList neighbourProcIndices(Pstream::nProcs(), -1);
forAll(neighbourProcs, i)
{
neighbourProcIndices[neighbourProcs[i]] = i;
}
// Initialise the stepFraction moved for the particles // Initialise the stepFraction moved for the particles
forAllIter(typename Cloud<ParticleType>, *this, pIter) forAllIter(typename Cloud<ParticleType>, *this, pIter)
@ -114,9 +124,19 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td)
// While there are particles to transfer // While there are particles to transfer
while (true) while (true)
{ {
// List of lists of particles to be transfered for all the processor // List of lists of particles to be transfered for all of the
// patches // neighbour processors
List<IDLList<ParticleType> > transferList(processorPatches.size()); List<IDLList<ParticleType> > particleTransferLists
(
neighbourProcs.size()
);
// List of destination processorPatches indices for all of the
// neighbour processors
List<DynamicList<label> > patchIndexTransferLists
(
neighbourProcs.size()
);
// Loop over all particles // Loop over all particles
forAllIter(typename Cloud<ParticleType>, *this, pIter) forAllIter(typename Cloud<ParticleType>, *this, pIter)
@ -134,15 +154,28 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td)
// boundary face // boundary face
if (Pstream::parRun() && p.facei_ >= pMesh().nInternalFaces()) if (Pstream::parRun() && p.facei_ >= pMesh().nInternalFaces())
{ {
label patchi = pMesh().boundaryMesh().whichPatch(p.facei_); label patchi = pbm.whichPatch(p.facei_);
label n = processorPatchIndices[patchi];
// ... and the face is on a processor patch // ... and the face is on a processor patch
// prepare it for transfer // prepare it for transfer
if (n != -1) if (procPatchIndices[patchi] != -1)
{ {
label n = neighbourProcIndices
[
refCast<const processorPolyPatch>
(
pbm[patchi]
).neighbProcNo()
];
p.prepareForParallelTransfer(patchi, td); p.prepareForParallelTransfer(patchi, td);
transferList[n].append(this->remove(&p));
particleTransferLists[n].append(this->remove(&p));
patchIndexTransferLists[n].append
(
procPatchNeighbours[patchi]
);
} }
} }
} }
@ -157,31 +190,30 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td)
break; break;
} }
// Allocate transfer buffers // Allocate transfer buffers
PstreamBuffers pBufs(Pstream::nonBlocking); PstreamBuffers pBufs(Pstream::nonBlocking);
// Stream into send buffers // Stream into send buffers
forAll(transferList, i) forAll(particleTransferLists, i)
{ {
if (transferList[i].size()) if (particleTransferLists[i].size())
{ {
UOPstream particleStream UOPstream particleStream
( (
refCast<const processorPolyPatch> neighbourProcs[i],
(
pMesh().boundaryMesh()[processorPatches[i]]
).neighbProcNo(),
pBufs pBufs
); );
particleStream << transferList[i]; particleStream
<< labelList(patchIndexTransferLists[i])
<< particleTransferLists[i];
} }
} }
// Set up transfers when in non-blocking mode. Returns sizes (in bytes) // Set up transfers when in non-blocking mode. Returns sizes (in bytes)
// to be sent/received. // to be sent/received.
labelListList allNTrans(Pstream::nProcs()); labelListList allNTrans(Pstream::nProcs());
pBufs.finishedSends(allNTrans); pBufs.finishedSends(allNTrans);
bool transfered = false; bool transfered = false;
@ -203,34 +235,35 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td)
break; break;
} }
// Retrieve from receive buffers // Retrieve from receive buffers
forAll(processorPatches, i) forAll(neighbourProcs, i)
{ {
label patchi = processorPatches[i]; label neighbProci = neighbourProcs[i];
const processorPolyPatch& procPatch = label nRec = allNTrans[neighbProci][Pstream::myProcNo()];
refCast<const processorPolyPatch>
(pMesh().boundaryMesh()[patchi]);
label neighbProci = procPatch.neighbProcNo(); if (nRec)
label nRecPs = allNTrans[neighbProci][Pstream::myProcNo()];
if (nRecPs)
{ {
UIPstream particleStream(neighbProci, pBufs); UIPstream particleStream(neighbProci, pBufs);
labelList receivePatchIndex(particleStream);
IDLList<ParticleType> newParticles IDLList<ParticleType> newParticles
( (
particleStream, particleStream,
typename ParticleType::iNew(*this) typename ParticleType::iNew(*this)
); );
label pI = 0;
forAllIter(typename Cloud<ParticleType>, newParticles, newpIter) forAllIter(typename Cloud<ParticleType>, newParticles, newpIter)
{ {
ParticleType& newp = newpIter(); ParticleType& newp = newpIter();
label patchi = procPatches[receivePatchIndex[pI++]];
newp.correctAfterParallelTransfer(patchi, td); newp.correctAfterParallelTransfer(patchi, td);
addParticle(newParticles.remove(&newp)); addParticle(newParticles.remove(&newp));
} }
} }