void Foam::processorLduInterface::send ( const Pstream::commsTypes commsType, const UList<Type>& f ) const { label nBytes = f.byteSize(); if ( commsType == Pstream::commsTypes::blocking || commsType == Pstream::commsTypes::scheduled ) { OPstream::write ( commsType, neighbProcNo(), reinterpret_cast<const char*>(f.begin()), nBytes, tag(), comm() ); } else if (commsType == Pstream::commsTypes::nonBlocking) { resizeBuf(receiveBuf_, nBytes); IPstream::read ( commsType, neighbProcNo(), receiveBuf_.begin(), nBytes, tag(), comm() ); resizeBuf(sendBuf_, nBytes); memcpy(sendBuf_.begin(), f.begin(), nBytes); OPstream::write ( commsType, neighbProcNo(), sendBuf_.begin(), nBytes, tag(), comm() ); } else { FatalErrorInFunction << "Unsupported communications type " << int(commsType) << exit(FatalError); } }
void Foam::processorLduInterface::receive ( const Pstream::commsTypes commsType, UList<Type>& f ) const { if (commsType == Pstream::blocking || commsType == Pstream::scheduled) { IPstream::read ( commsType, neighbProcNo(), reinterpret_cast<char*>(f.begin()), f.byteSize(), tag() ); } else if (commsType == Pstream::nonBlocking) { memcpy(f.begin(), receiveBuf_.begin(), f.byteSize()); } else { FatalErrorIn("processorLduInterface::receive") << "Unsupported communications type " << commsType << exit(FatalError); } }
void Foam::processorLduInterface::compressedReceive ( const Pstream::commsTypes commsType, UList<Type>& f ) const { if (sizeof(scalar) != sizeof(float) && Pstream::floatTransfer && f.size()) { static const label nCmpts = sizeof(Type)/sizeof(scalar); label nm1 = (f.size() - 1)*nCmpts; label nlast = sizeof(Type)/sizeof(float); label nFloats = nm1 + nlast; label nBytes = nFloats*sizeof(float); if ( commsType == Pstream::commsTypes::blocking || commsType == Pstream::commsTypes::scheduled ) { resizeBuf(receiveBuf_, nBytes); IPstream::read ( commsType, neighbProcNo(), receiveBuf_.begin(), nBytes, tag(), comm() ); } else if (commsType != Pstream::commsTypes::nonBlocking) { FatalErrorInFunction << "Unsupported communications type " << int(commsType) << exit(FatalError); } const float *fArray = reinterpret_cast<const float*>(receiveBuf_.begin()); f.last() = reinterpret_cast<const Type&>(fArray[nm1]); scalar *sArray = reinterpret_cast<scalar*>(f.begin()); const scalar *slast = &sArray[nm1]; for (label i=0; i<nm1; i++) { sArray[i] = fArray[i] + slast[i%nCmpts]; } } else { this->receive<Type>(commsType, f); } }
void Foam::processorPolyPatch::initGeometry(PstreamBuffers& pBufs) { if (Pstream::parRun()) { UOPstream toNeighbProc(neighbProcNo(), pBufs); toNeighbProc << faceCentres() << faceAreas() << faceCellCentres(); } }
Foam::processorCyclicPolyPatch::processorCyclicPolyPatch ( const word& name, const dictionary& dict, const label index, const polyBoundaryMesh& bm ) : processorPolyPatch(name, dict, index, bm), tag_ ( Pstream::nProcs()*max(myProcNo(), neighbProcNo()) + min(myProcNo(), neighbProcNo()) ), referPatchName_(dict.lookup("referPatch")), referPatchID_(-1) { if (debug) { Pout<< "processorCyclicPolyPatch " << name << " uses tag " << tag_ << endl; } }
void Foam::processorPolyPatch::initGeometry() { if (Pstream::parRun()) { OPstream toNeighbProc ( Pstream::blocking, neighbProcNo(), 3*(sizeof(label) + size()*sizeof(vector) + sizeof(scalar)) ); toNeighbProc << faceCentres() << faceAreas() << faceCellCentres(); } }
Foam::processorGAMGInterface::processorGAMGInterface ( const lduInterface& fineInterface, const labelField& localRestrictAddressing, const labelField& neighbourRestrictAddressing ) : GAMGInterface ( fineInterface, localRestrictAddressing, neighbourRestrictAddressing ), fineProcInterface_(refCast<const processorLduInterface>(fineInterface)) { // Make a lookup table of entries for owner/neighbour HashTable<SLList<label>, label, Hash<label> > neighboursTable ( localRestrictAddressing.size() ); // Table of face-sets to be agglomerated HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable ( localRestrictAddressing.size() ); label nCoarseFaces = 0; forAll (localRestrictAddressing, ffi) { label curMaster = -1; label curSlave = -1; // Do switching on master/slave indexes based on the owner/neighbour of // the processor index such that both sides get the same answer. if (myProcNo() < neighbProcNo()) { // Master side curMaster = localRestrictAddressing[ffi]; curSlave = neighbourRestrictAddressing[ffi]; } else { // Slave side curMaster = neighbourRestrictAddressing[ffi]; curSlave = localRestrictAddressing[ffi]; } // Look for the master cell. If it has already got a face, // add the coefficient to the face. If not, create a new face. if (neighboursTable.found(curMaster)) { // Check all current neighbours to see if the current slave already // exists and if so, add the fine face to the agglomeration. SLList<label>& curNbrs = neighboursTable.find(curMaster)(); SLList<SLList<label> >& curFaceFaces = faceFaceTable.find(curMaster)(); bool nbrFound = false; SLList<label>::iterator nbrsIter = curNbrs.begin(); SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin(); for ( ; nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end(); ++nbrsIter, ++faceFacesIter ) { if (nbrsIter() == curSlave) { nbrFound = true; faceFacesIter().append(ffi); break; } } if (!nbrFound) { curNbrs.append(curSlave); curFaceFaces.append(ffi); // New coarse face created nCoarseFaces++; } } else { // This master has got no neighbours yet. Add a neighbour // and a coefficient, thus creating a new face neighboursTable.insert(curMaster, SLList<label>(curSlave)); faceFaceTable.insert(curMaster, SLList<SLList<label> >(ffi)); // New coarse face created nCoarseFaces++; } } // end for all fine faces
void Foam::processorLduInterface::compressedSend ( const Pstream::commsTypes commsType, const UList<Type>& f ) const { if (sizeof(scalar) != sizeof(float) && Pstream::floatTransfer && f.size()) { static const label nCmpts = sizeof(Type)/sizeof(scalar); label nm1 = (f.size() - 1)*nCmpts; label nlast = sizeof(Type)/sizeof(float); label nFloats = nm1 + nlast; label nBytes = nFloats*sizeof(float); const scalar *sArray = reinterpret_cast<const scalar*>(f.begin()); const scalar *slast = &sArray[nm1]; resizeBuf(sendBuf_, nBytes); float *fArray = reinterpret_cast<float*>(sendBuf_.begin()); for (register label i=0; i<nm1; i++) { fArray[i] = sArray[i] - slast[i%nCmpts]; } reinterpret_cast<Type&>(fArray[nm1]) = f.last(); if (commsType == Pstream::blocking || commsType == Pstream::scheduled) { OPstream::write ( commsType, neighbProcNo(), sendBuf_.begin(), nBytes, tag() ); } else if (commsType == Pstream::nonBlocking) { resizeBuf(receiveBuf_, nBytes); IPstream::read ( commsType, neighbProcNo(), receiveBuf_.begin(), receiveBuf_.size(), tag() ); OPstream::write ( commsType, neighbProcNo(), sendBuf_.begin(), nBytes, tag() ); } else { FatalErrorIn("processorLduInterface::compressedSend") << "Unsupported communications type " << commsType << exit(FatalError); } } else { this->send(commsType, f); } }
void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs) { if (Pstream::parRun()) { { UIPstream fromNeighbProc(neighbProcNo(), pBufs); fromNeighbProc >> neighbFaceCentres_ >> neighbFaceAreas_ >> neighbFaceCellCentres_; } // My normals vectorField faceNormals(size()); // Neighbour normals vectorField nbrFaceNormals(neighbFaceAreas_.size()); // Face match tolerances scalarField tols = calcFaceTol(*this, points(), faceCentres()); // Calculate normals from areas and check forAll(faceNormals, facei) { scalar magSf = mag(faceAreas()[facei]); scalar nbrMagSf = mag(neighbFaceAreas_[facei]); scalar avSf = (magSf + nbrMagSf)/2.0; if (magSf < ROOTVSMALL && nbrMagSf < ROOTVSMALL) { // Undetermined normal. Use dummy normal to force separation // check. (note use of sqrt(VSMALL) since that is how mag // scales) faceNormals[facei] = point(1, 0, 0); nbrFaceNormals[facei] = faceNormals[facei]; } else if (mag(magSf - nbrMagSf) > matchTolerance()*sqr(tols[facei])) { fileName nm ( boundaryMesh().mesh().time().path() /name()+"_faces.obj" ); Pout<< "processorPolyPatch::calcGeometry : Writing my " << size() << " faces to OBJ file " << nm << endl; writeOBJ(nm, *this, points()); OFstream ccStr ( boundaryMesh().mesh().time().path() /name() + "_faceCentresConnections.obj" ); Pout<< "processorPolyPatch::calcGeometry :" << " Dumping cell centre lines between" << " corresponding face centres to OBJ file" << ccStr.name() << endl; label vertI = 0; forAll(faceCentres(), faceI) { const point& c0 = neighbFaceCentres_[faceI]; const point& c1 = faceCentres()[faceI]; writeOBJ(ccStr, c0, c1, vertI); } FatalErrorIn ( "processorPolyPatch::calcGeometry()" ) << "face " << facei << " area does not match neighbour by " << 100*mag(magSf - nbrMagSf)/avSf << "% -- possible face ordering problem." << endl << "patch:" << name() << " my area:" << magSf << " neighbour area:" << nbrMagSf << " matching tolerance:" << matchTolerance()*sqr(tols[facei]) << endl << "Mesh face:" << start()+facei << " vertices:" << UIndirectList<point>(points(), operator[](facei))() << endl << "If you are certain your matching is correct" << " you can increase the 'matchTolerance' setting" << " in the patch dictionary in the boundary file." << endl << "Rerun with processor debug flag set for" << " more information." << exit(FatalError); } else {
void Foam::processorPolyPatch::calcGeometry() { if (Pstream::parRun()) { { IPstream fromNeighbProc ( Pstream::blocking, neighbProcNo(), 3*(sizeof(label) + size()*sizeof(vector) + sizeof(scalar)) ); fromNeighbProc >> neighbFaceCentres_ >> neighbFaceAreas_ >> neighbFaceCellCentres_; } // My normals vectorField faceNormals(size()); // Neighbour normals vectorField nbrFaceNormals(neighbFaceAreas_.size()); // Calculate normals from areas and check // Cache face areas const vectorField::subField localFaceAreas = faceAreas(); forAll (faceNormals, facei) { scalar magSf = mag(localFaceAreas[facei]); scalar nbrMagSf = mag(neighbFaceAreas_[facei]); scalar avSf = (magSf + nbrMagSf)/2.0; if (magSf < ROOTVSMALL && nbrMagSf < ROOTVSMALL) { // Undetermined normal. Use dummy normal to force separation // check. (note use of sqrt(VSMALL) since that is how mag // scales) faceNormals[facei] = point(1, 0, 0); nbrFaceNormals[facei] = faceNormals[facei]; } else if (mag(magSf - nbrMagSf)/avSf > polyPatch::matchTol_) { FatalErrorIn ( "processorPolyPatch::calcGeometry()" ) << "face " << facei << " area does not match neighbour by " << 100*mag(magSf - nbrMagSf)/avSf << "% -- possible face ordering problem." << endl << "patch: " << name() << " my area:" << magSf << " neighbour area: " << nbrMagSf << " matching tolerance: " << polyPatch::matchTol_ << endl << "Mesh face: " << start()+facei << " vertices: " << UIndirectList<point>(points(), operator[](facei))() << endl << "Rerun with processor debug flag set for" << " more information." << exit(FatalError); } else { faceNormals[facei] = localFaceAreas[facei]/magSf; nbrFaceNormals[facei] = neighbFaceAreas_[facei]/nbrMagSf; } } calcTransformTensors ( faceCentres(), neighbFaceCentres_, faceNormals, nbrFaceNormals, calcFaceTol(*this, points(), faceCentres()) ); }
Foam::processorGAMGInterface::processorGAMGInterface ( const label index, const lduInterfacePtrsList& coarseInterfaces, const lduInterface& fineInterface, const labelField& localRestrictAddressing, const labelField& neighbourRestrictAddressing, const label fineLevelIndex, const label coarseComm ) : GAMGInterface ( index, coarseInterfaces ), comm_(coarseComm), myProcNo_(refCast<const processorLduInterface>(fineInterface).myProcNo()), neighbProcNo_ ( refCast<const processorLduInterface>(fineInterface).neighbProcNo() ), forwardT_(refCast<const processorLduInterface>(fineInterface).forwardT()), tag_(refCast<const processorLduInterface>(fineInterface).tag()) { // From coarse face to coarse cell DynamicList<label> dynFaceCells(localRestrictAddressing.size()); // From fine face to coarse face DynamicList<label> dynFaceRestrictAddressing ( localRestrictAddressing.size() ); // From coarse cell pair to coarse face HashTable<label, labelPair, labelPair::Hash<> > cellsToCoarseFace ( 2*localRestrictAddressing.size() ); forAll(localRestrictAddressing, ffi) { labelPair cellPair; // Do switching on master/slave indexes based on the owner/neighbour of // the processor index such that both sides get the same answer. if (myProcNo() < neighbProcNo()) { // Master side cellPair = labelPair ( localRestrictAddressing[ffi], neighbourRestrictAddressing[ffi] ); } else { // Slave side cellPair = labelPair ( neighbourRestrictAddressing[ffi], localRestrictAddressing[ffi] ); } HashTable<label, labelPair, labelPair::Hash<> >::const_iterator fnd = cellsToCoarseFace.find(cellPair); if (fnd == cellsToCoarseFace.end()) { // New coarse face label coarseI = dynFaceCells.size(); dynFaceRestrictAddressing.append(coarseI); dynFaceCells.append(localRestrictAddressing[ffi]); cellsToCoarseFace.insert(cellPair, coarseI); } else { // Already have coarse face dynFaceRestrictAddressing.append(fnd()); } }