Пример #1
0
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())
        );
    }