// 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(); } }