CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

Parallel Programming question about IPstream and OPstream

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   December 23, 2018, 21:02
Default Parallel Programming question about IPstream and OPstream
  #1
Senior Member
 
zhangyan's Avatar
 
Yan Zhang
Join Date: May 2014
Posts: 120
Rep Power: 12
zhangyan is on a distinguished road
Hi everyone,

I met a question about message sending and receiving.

What I want to do is:
each slave sends a fvPatchScalarField to master, and do some manipulation in master, then send other fvPatchScalarField back to each slave.

Here is my first attempt:
Code:
forAll(input_.boundaryField(), patchi)
{
    const fvPatchScalarField& inputFaces = input_.boundaryField()[patchi];
    fvPatchScalarField& resultFaces = result_.boundaryFieldRef()[patchi];

    if (Pstream::master())
    {
        List<autoPtr<IPstream>> IPL(nProc - 1);
        List<autoPtr<OPstream>> OPL(nProc - 1);
        for(label iProc = 1; iProc < nProc; iProc++)
        {
            IPL[iProc - 1].set(new IPstream(Pstream::commsTypes::blocking, iProc));
            OPL[iProc - 1].set(new OPstream(Pstream::commsTypes::blocking, iProc));
        }

        //update master
        forAll(inputFaces, facei)
        {
            getResult
            (
                inputFaces[facei],
                resultFaces[facei]
            );
        }
            
        // update each slave
        for(label iProc = 1; iProc < nProc; iProc++)
        {
            scalarField inputFacesTemp;
            IPL[iProc - 1]()() >> inputFacesTemp;
            scalarField resultFacesTemp(inputFacesTemp.size());
            forAll(inputFacesTemp, facei)
            {
                getResult
                (
                    inputFacesTemp[facei],
                    resultFacesTemp[facei]
                );
            }
            OPL[iProc - 1]()() << resultFacesTemp;
        }
    }
    else
    {
        OPstream(blocking,Pstream::masterNo())() 
            << dynamic_cast<scalarField&>(inputFaces);
        IPstream(blocking,Pstream::masterNo())()
            >> dynamic_cast<scalarField&>(resultFaces);
    }
}
However, after decomposition, the patch numbers in each processor maybe not equal. This will cause error because of the first line of my code, where the loop times are equal to the patch numbers of each processor.
Let us suppose patch numbers in master is 4, and patch numbers in slave1 is 5.
Then in master, the loop times is 4. It should receive 4 scalarFields and send 4 scalarFields in master.
But in slave1, it will send 5 scalarFields and receive 5 scalarFields.
Send and receive do not match!


Here is my second try (simplified, scalar on behalf of scalarField):
Code:
#include "fvCFD.H"

int main(int argc, char *argv[])
{
    #include "setRootCaseLists.H"

    label nProc = Pstream::nProcs();
    if (Pstream::master())
    {
        List<List<autoPtr<IPstream>>> IPL(nProc - 1);
        List<List<autoPtr<OPstream>>> OPL(nProc - 1);

        for(label iProc = 1; iProc < nProc; iProc++)
        {
            IPL[iProc - 1].resize(5);
            OPL[iProc - 1].resize(5);
            
            for(label i = 1; i < IPL[iProc - 1].size(); i++)
            {
                IPL[iProc - 1][i].set(new IPstream(Pstream::commsTypes::blocking, iProc));
                OPL[iProc - 1][i].set(new OPstream(Pstream::commsTypes::nonBlocking, iProc));
                scalar b;
                IPL[iProc - 1][i]()() >> b;
                Info << "b===" << b <<endl;
                OPL[iProc - 1][i]()() << b;
                Info << "send b over !!!"  <<endl;
            }
        }
    }
    else
    {
        for(label i = 1; i < 5; i++)
        {
            Pout << "I am in proc ID: ===" << Pstream::myProcNo()
                 << "i ===" << i <<endl;
            scalar a = Pstream::myProcNo();
            OPstream(Pstream::commsTypes::blocking, Pstream::masterNo())() << a;
            scalar c;
            IPstream(Pstream::commsTypes::blocking, Pstream::masterNo())() >> c;
            Pout << "c===" << c <<endl;
        }
    }

    Info<< "End\n" << endl;

    return 0;
}
But the above code doesn't work well. It gets stuck after the first time of "send b over".

Could anyone help me?
__________________
https://openfoam.top
zhangyan is offline   Reply With Quote

Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Using IPstream and OPstream Novel OpenFOAM Programming & Development 0 April 7, 2017 03:29


All times are GMT -4. The time now is 03:01.