CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Running, Solving & CFD (https://www.cfd-online.com/Forums/openfoam-solving/)
-   -   How to use gatherlist and scatterlist? (https://www.cfd-online.com/Forums/openfoam-solving/143108-how-use-gatherlist-scatterlist.html)

gxy200992243 October 16, 2014 18:41

How to use gatherlist and scatterlist?
 
Hi, everyone!

I am writing a parallel code. In my code, I have to search for cell label that satisfies certain criteria through the domain, combine the lists obtained by each processor and then distribute the combined list back to each processor.

I know the combination should be done by gatherlist() and the distribution should be done by scatterlist(), but there must be something wrong with my code or my understanding about gatherlist and scatterlist(). My code is like this.

List<label> mylist(100,0);
List<List<label> > t1_first(30,mylist);
List<List<List<label> > > gatherfirst(Pstream::nProcs(), t1_first);
for(label m=0;m<iMesh.C().size();m++)
{
//get the label value for each element in t1_first
//I have checked, the label values for t1_first is right
}
gatherfirst[Pstream::myProcNo()] = t1_first;//Do I need a loop over all the processors here?
Pstream::gatherList(gatherfirst);
Pstream::scatterList(gatherfirst);

Every label in gatherfirst is zero, which is wrong.

Can anyone help me with this problem?

Billions of thanks,

Xiangyu

lizzy January 27, 2021 09:12

Hi Gao,
I met a similar problem with you. Maybe it's too late to ask, but I wonder if you have solved it.

Many thanks,
Ran

dlahaye January 27, 2021 11:22

Possibly answer can be constructed from scanning below.

Print per processor data

// retrieve processor ID
label n=Pstream::nProcs();
printf(' my processor id = %d\n', n);

// print data on a given processor ID only as a first test
if (n==1) {
// print lower part
for (int i=0; i<matrix().lower().size(); ++i) {
Info<< matrix().lower[i] << endl;
}

// print upper part
for (int i=0; i<matrix().upper().size(); ++i) {
Info<< matrix().upper[i] << endl;
}
}

Parallel processing example: basic send and receive example

// get the number of processors
label n=Pstream::nProcs();

vector localV = vector::zero;

if (Pstream::myProcNo() == 0)
{
Random rnd(0);
localV = rnd.vector01();
List<vector> allV(n, vector::zero);

allV[0] = localV;
for(label i=1; i<n; i++)
{
// create the input stream from processor i
IPstream vStream(Pstream::blocking, i);
vStream >> allV[i];
}
// print the list of all vectors on the main proc
Info << allV << endl;
}
else
{
Random rnd(0);
localV = rnd.vector01();
// print the vector on the processor (so we can compare it later when we print it on the main proc)
Sout << "[" << Pstream::myProcNo() << "] V = " << localV << endl;

// create the stream to send to the main proc
OPstream vectorStream
(
Pstream::blocking, 0
);
vectorStream << localV;
}

Parallel processing example: read each local mesh and perf orm a gather: https://www.cfd-online.com/Forums/op...el-meshes.html

//- Get local mesh on processor
fvMesh mesh(refCast<const fvMesh>(obr_));

//- Gather the meshes into PtrList on master processor
PtrList<fvMesh> pMesh(Pstream::nProcs());
pMesh[Pstream::myProcNo()] = mesh;
Pstream::gatherList(pMesh);

Parallel processing example: taking cell centers created prior to decomposition and send them to screen: https://www.cfd-online.com/Forums/op...mputation.html


List<List<label> > processCellToGlobalAddr_;
List<label> globalCellToProcessAddr_;

if (Pstream::parRun())
{
processCellToGlobalAddr_.resize
(
Pstream::nProcs()
);

//read local cell addressing
labelIOList localCellProcAddr
(
IOobject
(
"cellProcAddressing",
localMesh.facesInstance(),
localMesh.meshSubDir,
localMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);

processCellToGlobalAddr_[Pstream::myProcNo()] = localCellProcAddr;

//send local cell addressing to master process
if (Pstream::master())
{
for (label jSlave=Pstream::firstSlave(); jSlave<=Pstream::lastSlave(); jSlave++)
{
IPstream fromSlave(Pstream::scheduled, jSlave);
label nSlaveCells = 0;
fromSlave >> nSlaveCells;
processCellToGlobalAddr_[jSlave].resize(nSlaveCells);
labelList& slaveCellProcAddr = processCellToGlobalAddr_[jSlave];
forAll(slaveCellProcAddr, iCell)
{
fromSlave >> slaveCellProcAddr[iCell];
}
}
}
else
{
OPstream toMaster (Pstream::scheduled, Pstream::masterNo());
toMaster << localCellProcAddr.size();

forAll(localCellProcAddr, iCell)
{
toMaster << localCellProcAddr[iCell];
}
}

//redistribute cell addressing to slave processes
if (Pstream::master())
{
for (label jSlave=Pstream::firstSlave(); jSlave<=Pstream::lastSlave(); jSlave++)
{
OPstream toSlave (Pstream::scheduled, jSlave);
forAll(processCellToGlobalAddr_, iProcess)
{
const labelList& thisProcessAddr = processCellToGlobalAddr_[iProcess];
const label nCells = thisProcessAddr.size();
toSlave << nCells;
forAll(thisProcessAddr, jCell)
{
toSlave << thisProcessAddr[jCell];
}
}
}
}
else
{
IPstream fromMaster(Pstream::scheduled, Pstream::masterNo());
forAll(processCellToGlobalAddr_, iProcess)
{
labelList& thisProcessAddr = processCellToGlobalAddr_[iProcess];
label nCells = 0;
fromMaster >> nCells;
thisProcessAddr.resize(nCells);
forAll(thisProcessAddr, jCell)
{
fromMaster >> thisProcessAddr[jCell];
}
}
}

//optional: create reverse addressing - from global cell id to local process cell id (or face id, or point id)
forAll(processCellToGlobalAddr_, jProc)
{
const labelList& jProcessAddr = processCellToGlobalAddr_[jProc];
forAll(jProcessAddr, iCell)
{
label iGlobalCell = jProcessAddr[iCell];
globalCellToProcessAddr_[iGlobalCell] = iCell;
}
}
}


All times are GMT -4. The time now is 14:42.