void Foam::cyclicFaPatch::calcTransforms() { if (size() > 0) { pointField half0Ctrs(size()/2); pointField half1Ctrs(size()/2); for (label i=0; i<size()/2; i++) { half0Ctrs[i] = this->edgeCentres()[i]; half1Ctrs[i] = this->edgeCentres()[i+size()/2]; } vectorField half0Normals(size()/2); vectorField half1Normals(size()/2); vectorField eN = edgeNormals()*magEdgeLengths(); scalar maxMatchError = 0; label errorEdge = -1; for (label edgei = 0; edgei < size()/2; edgei++) { half0Normals[edgei] = eN[edgei]; label nbrEdgei = edgei + size()/2; half1Normals[edgei] = eN[nbrEdgei]; scalar magLe = mag(half0Normals[edgei]); scalar nbrMagLe = mag(half1Normals[edgei]); scalar avLe = (magLe + nbrMagLe)/2.0; if (magLe < ROOTVSMALL && nbrMagLe < ROOTVSMALL) { // Undetermined normal. Use dummy normal to force separation // check. (note use of sqrt(VSMALL) since that is how mag // scales) half0Normals[edgei] = point(1, 0, 0); half1Normals[edgei] = half0Normals[edgei]; } else if ( mag(magLe - nbrMagLe)/avLe > matchTol_ ) { // Error in area matching. Find largest error maxMatchError = Foam::max(maxMatchError, mag(magLe - nbrMagLe)/avLe); errorEdge = edgei; } else { half0Normals[edgei] /= magLe; half1Normals[edgei] /= nbrMagLe; } } // Check for error in edge matching if (maxMatchError > matchTol_) { label nbrEdgei = errorEdge + size()/2; scalar magLe = mag(half0Normals[errorEdge]); scalar nbrMagLe = mag(half1Normals[errorEdge]); scalar avLe = (magLe + nbrMagLe)/2.0; FatalErrorIn ( "cyclicFaPatch::calcTransforms()" ) << "edge " << errorEdge << " area does not match neighbour " << nbrEdgei << " by " << 100*mag(magLe - nbrMagLe)/avLe << "% -- possible edge ordering problem." << endl << "patch:" << name() << " my area:" << magLe << " neighbour area:" << nbrMagLe << " matching tolerance:" << matchTol_ << endl << "Mesh edge:" << start() + errorEdge << endl << "Neighbour edge:" << start() + nbrEdgei << endl << "Other errors also exist, only the largest is reported. " << "Please rerun with cyclic debug flag set" << " for more information." << exit(FatalError); } // Calculate transformation tensors calcTransformTensors ( half0Ctrs, half1Ctrs, half0Normals, half1Normals ); // Check transformation tensors if (!parallel()) { if (forwardT().size() > 1 || reverseT().size() > 1) { SeriousErrorIn ( "void cyclicFaPatch::calcTransforms()" ) << "Transformation tensor is not constant for the cyclic " << "patch. Please reconsider your setup and definition of " << "cyclic boundaries." << endl; } } } }
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()) ); }