CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Combining Lists distributed amongst processors (https://www.cfd-online.com/Forums/openfoam-programming-development/77465-combining-lists-distributed-amongst-processors.html)

mchurchf June 23, 2010 13:06

Combining Lists distributed amongst processors
 
Hello,

I have set up a piece of code which searches my mesh for all the different distinct heights of cell centers. It is a simple block shaped mesh in which each layer is at a different height, so if there are 20 cells in the vertical direction then the list of heights is 20 elements long.

This works fine in serial. What I would like to do is extend this to parallel such that at the end of the search, each processor has a global list of distinct heights.

Is there a way to take each list of heights that each processor creates, collect them on the master processor, combine them into one global list, and give the global list back to each processor?

Thank you,

Matt

l_r_mcglashan June 24, 2010 05:35

Yes, I've done something really similar with lagrangian flamelets. The code is a mess but I can tidy it up and post it up if you like. Otherwise the outline of the approach I took is below:

Create a vector of stuff on each processor:

Code:

for(int i=0;i<mesh_.nCells();++i)
{
        stuff.push_back(mesh_.C().internalField()[i].component(heightDirection));
}

Then gather each list onto the master processor:

Code:

// Create lists of the variables on each processor so that they can be
// gathered onto the master processor later.
List<scalar> stuffList(stuff.size());

// Populate the above lists.
for(unsigned int I=0; I<someSize.size(); ++I)
{
    stuffList[I] = stuff[I];
}

// Create lists of the lists of the above variables, with size equal to the
// number of processors.
List< List<scalar> > gatheredStuff(Pstream::nProcs());

//  Populate and gather the stuff onto the master processor.
gatheredStuff[Pstream::myProcNo()] = stuffList;
Pstream::gatherList(gatheredStuff);

You can then go through vectors in a manner such as given below to get unique heights:

Code:

for(unsigned int i=0;i<stuff.size();++i)
{
        std::sort(stuff.begin(), stuff.end());
        stuff.erase(std::unique(stuff.begin(), stuff.end(), equalToTolerance), stuff.end());
}

You can then scatter a list onto each processor using either Pstream::scatterList or Pstream::listCombineScatter, depending on what you want to do.

mchurchf June 25, 2010 09:48

Laurence,

Thanks for the reply. It worked well!

Matt Churchfield

sippanspojk February 4, 2020 11:07

Quote:

Originally Posted by l_r_mcglashan (Post 264312)
Yes, I've done something really similar with lagrangian flamelets. The code is a mess but I can tidy it up and post it up if you like. Otherwise the outline of the approach I took is below:

Create a vector of stuff on each processor:

Code:

for(int i=0;i<mesh_.nCells();++i)
{
        stuff.push_back(mesh_.C().internalField()[i].component(heightDirection));
}

Then gather each list onto the master processor:

Code:

// Create lists of the variables on each processor so that they can be
// gathered onto the master processor later.
List<scalar> stuffList(stuff.size());

// Populate the above lists.
for(unsigned int I=0; I<someSize.size(); ++I)
{
    stuffList[I] = stuff[I];
}

// Create lists of the lists of the above variables, with size equal to the
// number of processors.
List< List<scalar> > gatheredStuff(Pstream::nProcs());

//  Populate and gather the stuff onto the master processor.
gatheredStuff[Pstream::myProcNo()] = stuffList;
Pstream::gatherList(gatheredStuff);

You can then go through vectors in a manner such as given below to get unique heights:

Code:

for(unsigned int i=0;i<stuff.size();++i)
{
        std::sort(stuff.begin(), stuff.end());
        stuff.erase(std::unique(stuff.begin(), stuff.end(), equalToTolerance), stuff.end());
}

You can then scatter a list onto each processor using either Pstream::scatterList or Pstream::listCombineScatter, depending on what you want to do.

Hi Laurence,

I am having a similar problem as Matthew had - I have written a function object that works perfectly in series and now I want to expand it to also work in parallel, but I have a hard time understanding how I should do it.

I've based my function on the "forces" function object and there they use:
Code:

    Pstream::listCombineGather(force_, plusEqOp<vectorField>());
    Pstream::listCombineScatter(force_);

I thought I should do something similar but I don't get how...

I would really appreciate your help on this.

Thanks,
David


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