void Foam::multiSolver::synchronizeParallel() const { if (Pstream::master()) { // Give go signal for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(); slave++ ) { OPstream toSlave(Pstream::blocking, slave); toSlave << true; } } else { // Recieve go signal { IPstream fromMaster(Pstream::blocking, Pstream::masterNo()); bool okayToGo(readBool(fromMaster)); } } }
void Foam::multiSolver::setUpParallel() { if (Pstream::master()) { fileNameList roots(Pstream::nProcs()); roots[0] = multiDictRegistry_.rootPath(); manageLocalRoot_ = true; // Receive from slaves for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(); slave++ ) { IPstream fromSlave(Pstream::blocking, slave); roots[slave] = fileName(fromSlave); } // Distribute for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(); slave++ ) { OPstream toSlave(Pstream::blocking, slave); if (roots[slave] != roots[slave - 1]) { toSlave << true; } else { toSlave << false; } } } else { // Send to master { OPstream toMaster(Pstream::blocking, Pstream::masterNo()); toMaster << fileName(multiDictRegistry_.rootPath()); } // Receive from master { IPstream fromMaster(Pstream::blocking, Pstream::masterNo()); manageLocalRoot_ = readBool(fromMaster); } } }
// Read mesh if available. Otherwise create empty mesh with same non-proc // patches as proc0 mesh. Requires all processors to have all patches // (and in same order). autoPtr<fvMesh> createMesh ( const Time& runTime, const word& regionName, const fileName& instDir, const bool haveMesh ) { //Pout<< "Create mesh for time = " // << runTime.timeName() << nl << endl; IOobject io ( regionName, instDir, runTime, IOobject::MUST_READ ); if (!haveMesh) { // Create dummy mesh. Only used on procs that don't have mesh. IOobject noReadIO(io); noReadIO.readOpt() = IOobject::NO_READ; fvMesh dummyMesh ( noReadIO, xferCopy(pointField()), xferCopy(faceList()), xferCopy(labelList()), xferCopy(labelList()), false ); // Add some dummy zones so upon reading it does not read them // from the undecomposed case. Should be done as extra argument to // regIOobject::readStream? List<pointZone*> pz ( 1, new pointZone ( "dummyPointZone", labelList(0), 0, dummyMesh.pointZones() ) ); List<faceZone*> fz ( 1, new faceZone ( "dummyFaceZone", labelList(0), boolList(0), 0, dummyMesh.faceZones() ) ); List<cellZone*> cz ( 1, new cellZone ( "dummyCellZone", labelList(0), 0, dummyMesh.cellZones() ) ); dummyMesh.addZones(pz, fz, cz); //Pout<< "Writing dummy mesh to " << dummyMesh.polyMesh::objectPath() // << endl; dummyMesh.write(); } //Pout<< "Reading mesh from " << io.objectPath() << endl; autoPtr<fvMesh> meshPtr(new fvMesh(io)); fvMesh& mesh = meshPtr(); // Sync patches // ~~~~~~~~~~~~ if (Pstream::master()) { // Send patches for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(); slave++ ) { OPstream toSlave(Pstream::scheduled, slave); toSlave << mesh.boundaryMesh(); } } else { // Receive patches IPstream fromMaster(Pstream::scheduled, Pstream::masterNo()); PtrList<entry> patchEntries(fromMaster); if (haveMesh) { // Check master names against mine const polyBoundaryMesh& patches = mesh.boundaryMesh(); forAll(patchEntries, patchI) { const entry& e = patchEntries[patchI]; const word type(e.dict().lookup("type")); const word& name = e.keyword(); if (type == processorPolyPatch::typeName) { break; } if (patchI >= patches.size()) { FatalErrorIn ( "createMesh(const Time&, const fileName&, const bool)" ) << "Non-processor patches not synchronised." << endl << "Processor " << Pstream::myProcNo() << " has only " << patches.size() << " patches, master has " << patchI << exit(FatalError); } if ( type != patches[patchI].type() || name != patches[patchI].name() ) { FatalErrorIn ( "createMesh(const Time&, const fileName&, const bool)" ) << "Non-processor patches not synchronised." << endl << "Master patch " << patchI << " name:" << type << " type:" << type << endl << "Processor " << Pstream::myProcNo() << " patch " << patchI << " has name:" << patches[patchI].name() << " type:" << patches[patchI].type() << exit(FatalError); } } } else { // Add patch List<polyPatch*> patches(patchEntries.size()); label nPatches = 0; forAll(patchEntries, patchI) { const entry& e = patchEntries[patchI]; const word type(e.dict().lookup("type")); const word& name = e.keyword(); if (type == processorPolyPatch::typeName) { break; } //Pout<< "Adding patch:" << nPatches // << " name:" << name << " type:" << type << endl; dictionary patchDict(e.dict()); patchDict.remove("nFaces"); patchDict.add("nFaces", 0); patchDict.remove("startFace"); patchDict.add("startFace", 0); patches[patchI] = polyPatch::New ( name, patchDict, nPatches++, mesh.boundaryMesh() ).ptr(); } patches.setSize(nPatches); mesh.addFvPatches(patches, false); // no parallel comms //// Write empty mesh now we have correct patches //meshPtr().write(); } }
// Read mesh if available. Otherwise create empty mesh with same non-proc // patches as proc0 mesh. Requires all processors to have all patches // (and in same order). autoPtr<fvMesh> createMesh ( const Time& runTime, const word& regionName, const fileName& instDir, const bool haveMesh ) { Pout<< "Create mesh for time = " << runTime.timeName() << nl << endl; IOobject io ( regionName, instDir, runTime, IOobject::MUST_READ ); if (!haveMesh) { // Create dummy mesh. Only used on procs that don't have mesh. fvMesh dummyMesh ( io, xferCopy(pointField()), xferCopy(faceList()), xferCopy(labelList()), xferCopy(labelList()), false ); Pout<< "Writing dummy mesh to " << dummyMesh.polyMesh::objectPath() << endl; dummyMesh.write(); } Pout<< "Reading mesh from " << io.objectPath() << endl; autoPtr<fvMesh> meshPtr(new fvMesh(io)); fvMesh& mesh = meshPtr(); // Determine patches. if (Pstream::master()) { // Send patches for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(); slave++ ) { OPstream toSlave(Pstream::blocking, slave); toSlave << mesh.boundaryMesh(); } } else { // Receive patches IPstream fromMaster(Pstream::blocking, Pstream::masterNo()); PtrList<entry> patchEntries(fromMaster); if (haveMesh) { // Check master names against mine const polyBoundaryMesh& patches = mesh.boundaryMesh(); forAll(patchEntries, patchI) { const entry& e = patchEntries[patchI]; const word type(e.dict().lookup("type")); const word& name = e.keyword(); if (type == processorPolyPatch::typeName) { break; } if (patchI >= patches.size()) { FatalErrorIn ( "createMesh(const Time&, const fileName&, const bool)" ) << "Non-processor patches not synchronised." << endl << "Processor " << Pstream::myProcNo() << " has only " << patches.size() << " patches, master has " << patchI << exit(FatalError); } if ( type != patches[patchI].type() || name != patches[patchI].name() ) { FatalErrorIn ( "createMesh(const Time&, const fileName&, const bool)" ) << "Non-processor patches not synchronised." << endl << "Master patch " << patchI << " name:" << type << " type:" << type << endl << "Processor " << Pstream::myProcNo() << " patch " << patchI << " has name:" << patches[patchI].name() << " type:" << patches[patchI].type() << exit(FatalError); } } } else { // Add patch List<polyPatch*> patches(patchEntries.size()); label nPatches = 0; forAll(patchEntries, patchI) { const entry& e = patchEntries[patchI]; const word type(e.dict().lookup("type")); const word& name = e.keyword(); if (type == processorPolyPatch::typeName) { break; } Pout<< "Adding patch:" << nPatches << " name:" << name << " type:" << type << endl; dictionary patchDict(e.dict()); patchDict.remove("nFaces"); patchDict.add("nFaces", 0); patchDict.remove("startFace"); patchDict.add("startFace", 0); patches[patchI] = polyPatch::New ( name, patchDict, nPatches++, mesh.boundaryMesh() ).ptr(); } patches.setSize(nPatches); mesh.addFvPatches(patches, false); // no parallel comms //// Write empty mesh now we have correct patches //meshPtr().write(); } }
Gather<T0>::Gather(const T0& localData, const bool redistribute) : List<T0>(0), nProcs_(max(1, Pstream::nProcs())) { this->setSize(nProcs_); // // Collect sizes on all processor // if (Pstream::parRun()) { if (Pstream::master()) { this->operator[](0) = localData; // Receive data for ( int slave = Pstream::firstSlave(), procIndex = 1; slave <= Pstream::lastSlave(); slave++, procIndex++ ) { IPstream fromSlave(Pstream::scheduled, slave); fromSlave >> this->operator[](procIndex); } // Send data for ( int slave = Pstream::firstSlave(), procIndex = 1; slave <= Pstream::lastSlave(); slave++, procIndex++ ) { OPstream toSlave(Pstream::scheduled, slave); if (redistribute) { toSlave << *this; } else { // Dummy send just to balance sends/receives toSlave << 0; } } } else { // Slave: send my local data to master { OPstream toMaster(Pstream::scheduled, Pstream::masterNo()); toMaster << localData; } // Receive data from master { IPstream fromMaster(Pstream::scheduled, Pstream::masterNo()); if (redistribute) { fromMaster >> *this; } else { label dummy; fromMaster >> dummy; } } }