コード例 #1
0
void Foam::fileFormats::OFSsurfaceFormatCore::writeHeader
(
    Ostream& os,
    const pointField& pointLst,
    const UList<surfZone>& zoneLst
)
{
    // just emit some information until we get a nice IOobject
    IOobject::writeBanner(os)
        << "// OpenFOAM Surface Format - written "
        << clock::dateTime().c_str() << nl
        << "// ~~~~~~~~~~~~~~~~~~~~~~~" << nl << nl
        << "// surfZones:" << nl;


    // treat a single zone as being unzoned
    if (zoneLst.size() <= 1)
    {
        os  << "0" << token::BEGIN_LIST << token::END_LIST << nl << nl;
    }
    else
    {
        os  << zoneLst.size() << nl << token::BEGIN_LIST << incrIndent << nl;

        forAll(zoneLst, zoneI)
        {
            zoneLst[zoneI].writeDict(os);
        }
        os  << decrIndent << token::END_LIST << nl << nl;
    }
コード例 #2
0
void Foam::AMIInterpolation::interpolateToTarget
(
    const UList<Type>& fld,
    const CombineOp& cop,
    List<Type>& result,
    const UList<Type>& defaultValues
) const
{
    if (fld.size() != srcAddress_.size())
    {
        FatalErrorInFunction
            << "Supplied field size is not equal to source patch size" << nl
            << "    source patch   = " << srcAddress_.size() << nl
            << "    target patch   = " << tgtAddress_.size() << nl
            << "    supplied field = " << fld.size()
            << abort(FatalError);
    }

    if (lowWeightCorrection_ > 0)
    {
        if (defaultValues.size() != tgtAddress_.size())
        {
            FatalErrorInFunction
                << "Employing default values when sum of weights falls below "
                << lowWeightCorrection_
                << " but supplied default field size is not equal to target "
                << "patch size" << nl
                << "    default values = " << defaultValues.size() << nl
                << "    target patch   = " << tgtAddress_.size() << nl
                << abort(FatalError);
        }
    }

    result.setSize(tgtAddress_.size());

    if (singlePatchProc_ == -1)
    {
        const mapDistribute& map = srcMapPtr_();

        List<Type> work(fld);
        map.distribute(work);

        forAll(result, facei)
        {
            if (tgtWeightsSum_[facei] < lowWeightCorrection_)
            {
                result[facei] = defaultValues[facei];
            }
            else
            {
                const labelList& faces = tgtAddress_[facei];
                const scalarList& weights = tgtWeights_[facei];

                forAll(faces, i)
                {
                    cop(result[facei], facei, work[faces[i]], weights[i]);
                }
            }
        }
    }
Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
(
    const Xfer< pointField >& pointLst,
    const Xfer< List<Face> >& faceLst,
    const UList<label>& zoneSizes,
    const UList<word>& zoneNames
)
:
    ParentType(pointLst, faceLst)
{
    if (zoneSizes.size())
    {
        if (zoneNames.size())
        {
            setZones(zoneSizes, zoneNames);
        }
        else
        {
            setZones(zoneSizes);
        }
    }
    else
    {
        setOneZone();
    }
}
コード例 #4
0
ファイル: syncTools.C プロジェクト: BarisCumhur/OpenFOAM-dev
void Foam::syncTools::swapBoundaryCellPositions
(
    const polyMesh& mesh,
    const UList<point>& cellData,
    List<point>& neighbourCellData
)
{
    if (cellData.size() != mesh.nCells())
    {
        FatalErrorInFunction
            << "Number of cell values " << cellData.size()
            << " is not equal to the number of cells in the mesh "
            << mesh.nCells() << abort(FatalError);
    }

    const polyBoundaryMesh& patches = mesh.boundaryMesh();

    label nBnd = mesh.nFaces()-mesh.nInternalFaces();

    neighbourCellData.setSize(nBnd);

    forAll(patches, patchI)
    {
        const polyPatch& pp = patches[patchI];
        const labelUList& faceCells = pp.faceCells();
        forAll(faceCells, i)
        {
            label bFaceI = pp.start()+i-mesh.nInternalFaces();
            neighbourCellData[bFaceI] = cellData[faceCells[i]];
        }
    }
コード例 #5
0
ファイル: scalarField.C プロジェクト: jpola/RapidCFD-dev
scalar sumProd(const UList<scalar>& f1, const UList<scalar>& f2)
{
    if (f1.size() && (f1.size() == f2.size()))
    {
        scalar SumProd = 0.0;
        TFOR_ALL_S_OP_F_OP_F(scalar, SumProd, +=, scalar, f1, *, scalar, f2)
        return SumProd;
    }
コード例 #6
0
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);
    }
}
コード例 #7
0
ファイル: exchange.C プロジェクト: jheylmun/OpenFOAM-dev
void Foam::Pstream::exchange
(
    const UList<Container>& sendBufs,
    const labelUList& recvSizes,
    List<Container>& recvBufs,
    const int tag,
    const label comm,
    const bool block
)
{
    if (!contiguous<T>())
    {
        FatalErrorInFunction
            << "Continuous data only." << sizeof(T) << Foam::abort(FatalError);
    }

    if (sendBufs.size() != UPstream::nProcs(comm))
    {
        FatalErrorInFunction
            << "Size of list " << sendBufs.size()
            << " does not equal the number of processors "
            << UPstream::nProcs(comm)
            << Foam::abort(FatalError);
    }

    recvBufs.setSize(sendBufs.size());

    recvBufs.setSize(sendBufs.size());

    if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
    {
        label startOfRequests = Pstream::nRequests();

        // Set up receives
        // ~~~~~~~~~~~~~~~

        forAll(recvSizes, proci)
        {
            label nRecv = recvSizes[proci];

            if (proci != Pstream::myProcNo(comm) && nRecv > 0)
            {
                recvBufs[proci].setSize(nRecv);
                UIPstream::read
                (
                    UPstream::commsTypes::nonBlocking,
                    proci,
                    reinterpret_cast<char*>(recvBufs[proci].begin()),
                    nRecv*sizeof(T),
                    tag,
                    comm
                );
            }
        }
コード例 #8
0
ファイル: VTKedgeFormat.C プロジェクト: 000861/OpenFOAM-2.1.x
void Foam::fileFormats::VTKedgeFormat::writeEdges
(
    Ostream& os,
    const UList<edge>& edgeLst
)
{
    os  << "LINES " << edgeLst.size() << ' ' << 3*edgeLst.size() << nl;

    forAll(edgeLst, edgeI)
    {
        const edge& e = edgeLst[edgeI];

        os  << "2 " << e[0] << ' ' << e[1] << nl;
    }
}
コード例 #9
0
// Construct as the bounding box of the given pointField
Foam::treeBoundBox::treeBoundBox
(
    const UList<point>& points,
    const UList<label>& meshPoints
)
:
    boundBox()
{
    if (points.empty() || meshPoints.empty())
    {
        WarningIn
        (
            "treeBoundBox::treeBoundBox"
            "(const UList<point>&, const UList<label>&)"
        )   << "cannot find bounding box for zero-sized pointField"
            << "returning zero" << endl;

        return;
    }

    min() = points[meshPoints[0]];
    max() = points[meshPoints[0]];

    for (label i = 1; i < meshPoints.size(); i++)
    {
        min() = ::Foam::min(min(), points[meshPoints[i]]);
        max() = ::Foam::max(max(), points[meshPoints[i]]);
    }
}
コード例 #10
0
ファイル: boundBox.C プロジェクト: EricAlex/OpenFOAM-dev
void Foam::boundBox::calculate(const UList<point>& points, const bool doReduce)
{
    if (points.empty())
    {
        min_ = Zero;
        max_ = Zero;

        if (doReduce && Pstream::parRun())
        {
            // Use values that get overwritten by reduce minOp, maxOp below
            min_ = point(VGREAT, VGREAT, VGREAT);
            max_ = point(-VGREAT, -VGREAT, -VGREAT);
        }
    }
    else
    {
        min_ = points[0];
        max_ = points[0];


        for (label i = 1; i < points.size(); i++)
        {
            min_ = ::Foam::min(min_, points[i]);
            max_ = ::Foam::max(max_, points[i]);
        }
    }

    // Reduce parallel information
    if (doReduce)
    {
        reduce(min_, minOp<point>());
        reduce(max_, maxOp<point>());
    }
}
コード例 #11
0
ファイル: DecoupledCoeffField.C プロジェクト: Brzous/WindFOAM
inline void Foam::DecoupledCoeffField<Type>::checkSize
(
    const UList<Type2>& f
) const
{
    if (f.size() != this->size())
    {
        FatalErrorIn
        (
            "void DecoupledCoeffField<Type>::checkSize("
            "const Field<Type2>& f) const"
        )   << "Incorrect field size: " << f.size()
            << " local size: " << size()
            << abort(FatalError);
    }
}
コード例 #12
0
ファイル: mergePoints.C プロジェクト: Kiiree/CONSELFcae-dev
Foam::label Foam::mergePoints
(
    const UList<Type>& points,
    const scalar mergeTol,
    const bool verbose,
    labelList& pointMap,
    const Type& origin
)
{
    Type compareOrigin = origin;

    if (origin == Type::max)
    {
        if (points.size())
        {
            compareOrigin = sum(points)/points.size();
        }
    }

    // Create a old to new point mapping array
    pointMap.setSize(points.size());
    pointMap = -1;

    if (points.empty())
    {
        return points.size();
    }

    // We're comparing distance squared to origin first.
    // Say if starting from two close points:
    //     x, y, z
    //     x+mergeTol, y+mergeTol, z+mergeTol
    // Then the magSqr of both will be
    //     x^2+y^2+z^2
    //     x^2+y^2+z^2 + 2*mergeTol*(x+z+y) + mergeTol^2*...
    // so the difference will be 2*mergeTol*(x+y+z)

    const scalar mergeTolSqr = Foam::sqr(scalar(mergeTol));

    // Sort points by magSqr
    const Field<Type> d(points - compareOrigin);

    List<scalar> magSqrD(d.size());
    forAll(d, pointI)
    {
        magSqrD[pointI] = magSqr(d[pointI]);
    }
コード例 #13
0
void Foam::globalIndex::gather
(
    const labelUList& off,
    const label comm,
    const labelList& procIDs,
    const UList<Type>& fld,
    List<Type>& allFld,
    const int tag,
    const Pstream::commsTypes commsType
)
{
    if (Pstream::myProcNo(comm) == procIDs[0])
    {
        allFld.setSize(off.last());

        // Assign my local data
        SubList<Type>(allFld, fld.size(), 0) = fld;

        if
        (
            commsType == Pstream::commsTypes::scheduled
         || commsType == Pstream::commsTypes::blocking
        )
        {
            for (label i = 1; i < procIDs.size(); i++)
            {
                SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);

                if (contiguous<Type>())
                {
                    IPstream::read
                    (
                        commsType,
                        procIDs[i],
                        reinterpret_cast<char*>(procSlot.begin()),
                        procSlot.byteSize(),
                        tag,
                        comm
                    );
                }
                else
                {
                    IPstream fromSlave
                    (
                        commsType,
                        procIDs[i],
                        0,
                        tag,
                        comm
                    );
                    fromSlave >> procSlot;
                }
            }
        }
        else
        {
            // nonBlocking

            if (!contiguous<Type>())
コード例 #14
0
ファイル: HashSet.C プロジェクト: 000861/OpenFOAM-2.1.x
Foam::HashSet<Key, Hash>::HashSet(const UList<Key>& lst)
:
    HashTable<nil, Key, Hash>(2*lst.size())
{
    forAll(lst, elemI)
    {
        this->insert(lst[elemI]);
    }
コード例 #15
0
void Foam::fileFormats::VTKsurfaceFormat<Face>::writeHeaderPolygons
(
    Ostream& os,
    const UList<Face>& faceLst
)
{
    label nNodes = 0;

    forAll(faceLst, faceI)
    {
        nNodes += faceLst[faceI].size();
    }

    os  << nl
        << "POLYGONS " << faceLst.size() << ' '
        << faceLst.size() + nNodes << nl;
}
コード例 #16
0
// Find cut cells
void Foam::cuttingPlane::calcCutCells
(
    const primitiveMesh& mesh,
    const scalarField& dotProducts,
    const UList<label>& cellIdLabels
)
{
    const labelListList& cellEdges = mesh.cellEdges();
    const edgeList& edges = mesh.edges();

    label listSize = cellEdges.size();
    if (&cellIdLabels)
    {
        listSize = cellIdLabels.size();
    }

    cutCells_.setSize(listSize);
    label cutcellI(0);

    // Find the cut cells by detecting any cell that uses points with
    // opposing dotProducts.
    for (label listI = 0; listI < listSize; ++listI)
    {
        label cellI = listI;
        if (&cellIdLabels)
        {
            cellI = cellIdLabels[listI];
        }

        const labelList& cEdges = cellEdges[cellI];

        label nCutEdges = 0;

        forAll(cEdges, i)
        {
            const edge& e = edges[cEdges[i]];

            if
            (
                (dotProducts[e[0]] < zeroish && dotProducts[e[1]] > positive)
             || (dotProducts[e[1]] < zeroish && dotProducts[e[0]] > positive)
            )
            {
                nCutEdges++;

                if (nCutEdges > 2)
                {
                    cutCells_[cutcellI++] = cellI;

                    break;
                }
            }
        }
    }

    // Set correct list size
    cutCells_.setSize(cutcellI);
}
コード例 #17
0
// remap action on triangulation
void Foam::sampledPatch::remapFaces
(
    const UList<label>& faceMap
)
{
    // recalculate the cells cut
    if (&faceMap && faceMap.size())
    {
        MeshStorage::remapFaces(faceMap);
    }
}
コード例 #18
0
Foam::List<T> Foam::transform
(
    const tensor& rotTensor,
    const UList<T>& field
)
{
    List<T> newField(field.size());

    forAll(field, i)
    {
        newField[i] = transform(rotTensor, field[i]);
    }
コード例 #19
0
Foam::pointField Foam::oldCyclicPolyPatch::calcFaceCentres
(
    const UList<face>& faces,
    const pointField& points
)
{
    pointField ctrs(faces.size());

    forAll(faces, facei)
    {
        ctrs[facei] = faces[facei].centre(points);
    }
コード例 #20
0
void Foam::processorLduInterface::send
(
    const Pstream::commsTypes commsType,
    const UList<Type>& f
) const
{
    if (commsType == Pstream::blocking || commsType == Pstream::scheduled)
    {
        OPstream::write
        (
            commsType,
            neighbProcNo(),
            reinterpret_cast<const char*>(f.begin()),
            f.byteSize(),
            tag()
        );
    }
    else if (commsType == Pstream::nonBlocking)
    {
        resizeBuf(receiveBuf_, f.size()*sizeof(Type));

        IPstream::read
        (
            commsType,
            neighbProcNo(),
            receiveBuf_.begin(),
            receiveBuf_.size(),
            tag()
        );

        resizeBuf(sendBuf_, f.byteSize());
        memcpy(sendBuf_.begin(), f.begin(), f.byteSize());

        OPstream::write
        (
            commsType,
            neighbProcNo(),
            sendBuf_.begin(),
            f.byteSize(),
            tag()
        );
    }
    else
    {
        FatalErrorIn("processorLduInterface::send")
            << "Unsupported communications type " << commsType
            << exit(FatalError);
    }
}
コード例 #21
0
// remap action on triangulation
void Foam::sampledPatch::remapFaces
(
    const UList<label>& faceMap
)
{
    // recalculate the cells cut
    if (&faceMap && faceMap.size())
    {
        MeshStorage::remapFaces(faceMap);
        patchFaceLabels_ = labelList
        (
            UIndirectList<label>(patchFaceLabels_, faceMap)
        );
    }
}
コード例 #22
0
void Foam::mapDistributeBase::flipAndCombine
(
    const UList<label>& map,
    const bool hasFlip,
    const UList<T>& rhs,
    const CombineOp& cop,
    const negateOp& negOp,
    List<T>& lhs
)
{
    if (hasFlip)
    {
        forAll(map, i)
        {
            if (map[i] > 0)
            {
                label index = map[i]-1;
                cop(lhs[index], rhs[i]);
            }
            else if (map[i] < 0)
            {
                label index = -map[i]-1;
                cop(lhs[index], negOp(rhs[i]));
            }
            else
            {
                FatalErrorInFunction
                    << "At index " << i << " out of " << map.size()
                    << " have illegal index " << map[i]
                    << " for field " << rhs.size() << " with flipMap"
                    << exit(FatalError);
            }
        }
    }
    else
    {
コード例 #23
0
Foam::label Foam::HashTable<T, Key, Hash>::erase(const UList<Key>& keys)
{
    const label nTotal = nElmts_;
    label count = 0;

    // Remove listed keys from this table - terminates early if possible
    for (label keyI = 0; count < nTotal && keyI < keys.size(); ++keyI)
    {
        if (erase(keys[keyI]))
        {
            count++;
        }
    }

    return count;
}
コード例 #24
0
void Foam::UnsortedMeshedSurface<Face>::setZones
(
    const UList<label>& sizes,
    const UList<word>& names
)
{
    zoneIds_.setSize(size());
    zoneToc_.setSize(sizes.size());

    label start = 0;
    forAll(zoneToc_, zoneI)
    {
        zoneToc_[zoneI] = surfZoneIdentifier(names[zoneI], zoneI);

        // assign sub-zone Ids
        SubList<label> subZone(zoneIds_, sizes[zoneI], start);
        subZone = zoneI;

        start += sizes[zoneI];
    }
コード例 #25
0
Foam::labelList Foam::findMatchingStrings
(
    const Matcher& matcher,
    const UList<StringType>& lst,
    const bool invert
)
{
    labelList indices(lst.size());

    label nElem = 0;
    forAll(lst, elemI)
    {
        if (matcher.match(lst[elemI]) ? !invert : invert)
        {
            indices[nElem++] = elemI;
        }
    }
    indices.setSize(nElem);

    return indices;
}
コード例 #26
0
void Foam::fileFormats::WRLsurfaceFormatCore::writeHeader
(
    Ostream& os,
    const pointField& pointLst,
    const label nFaces,
    const UList<surfZone>& zoneLst
)
{
    os  << "#VRML V2.0 utf8" << nl
        << nl
        << "# written " << clock::dateTime().c_str() << nl
        << "# points : " << pointLst.size() << nl
        << "# faces  : " << nFaces << nl
        << "# zones  : " << zoneLst.size() << nl;

    // Print zone names as comment
    forAll(zoneLst, zoneI)
    {
        os  << "#   " << zoneI << "  " << zoneLst[zoneI].name()
            << "  (nFaces: " << zoneLst[zoneI].size() << ")" << nl;
    }
}
コード例 #27
0
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);
    }
}
コード例 #28
0
bool Foam::mergePoints
(
    const UList<point>& points,
    const scalar mergeTol,
    const bool verbose,
    labelList& pointMap,
    List<point>& newPoints,
    const point& origin
)
{
    point compareOrigin = origin;

    if (origin == point(VGREAT, VGREAT, VGREAT))
    {
        if (points.size())
        {
            compareOrigin = sum(points)/points.size();
        }
    }

    // Create a old to new point mapping array
    pointMap.setSize(points.size());
    pointMap = -1;

    // Storage for merged points
    newPoints.setSize(points.size());

    if (points.empty())
    {
        return false;
    }


    const scalar mergeTolSqr = sqr(mergeTol);

    // Sort points by magSqr
    SortableList<scalar> sortedMagSqr(magSqr(points - compareOrigin));

    bool hasMerged = false;

    label newPointI = 0;


    // Handle 0th point separately (is always unique)
    label pointI = sortedMagSqr.indices()[0];
    pointMap[pointI] = newPointI;
    newPoints[newPointI++] = points[pointI];


    for (label sortI = 1; sortI < sortedMagSqr.size(); sortI++)
    {
        // Get original point index
        label pointI = sortedMagSqr.indices()[sortI];

        // Compare to previous points to find equal one.
        label equalPointI = -1;

        for
        (
            label prevSortI = sortI - 1;
            prevSortI >= 0
         && mag
            (
                sortedMagSqr[prevSortI]
             -  sortedMagSqr[sortI]
            ) <= mergeTolSqr;
            prevSortI--
        )
        {
            label prevPointI = sortedMagSqr.indices()[prevSortI];

            if (magSqr(points[pointI] - points[prevPointI]) <= mergeTolSqr)
            {
                // Found match.
                equalPointI = prevPointI;

                break;
            }
        }


        if (equalPointI != -1)
        {
            // Same coordinate as equalPointI. Map to same new point.
            pointMap[pointI] = pointMap[equalPointI];

            hasMerged = true;

            if (verbose)
            {
                Pout<< "Foam::mergePoints : Merging points "
                    << pointI << " and " << equalPointI
                    << " with coordinates:" << points[pointI]
                    << " and " << points[equalPointI]
                    << endl;
            }
        }
        else
        {
            // Differs. Store new point.
            pointMap[pointI] = newPointI;
            newPoints[newPointI++] = points[pointI];
        }
    }

    newPoints.setSize(newPointI);

    return hasMerged;
}
コード例 #29
0
ファイル: scalarField.C プロジェクト: jpola/RapidCFD-dev
tmp<scalarField> stabilise(const UList<scalar>& sf, const scalar s)
{
    tmp<scalarField> tRes(new scalarField(sf.size()));
    stabilise(tRes(), sf, s);
    return tRes;
}
コード例 #30
0
ファイル: matchPoints.C プロジェクト: EricAlex/OpenFOAM-dev
bool Foam::matchPoints
(
    const UList<point>& pts0,
    const UList<point>& pts1,
    const UList<scalar>& matchDistances,
    const bool verbose,
    labelList& from0To1,
    const point& origin
)
{
    from0To1.setSize(pts0.size());
    from0To1 = -1;

    bool fullMatch = true;

    point compareOrigin = origin;

    if (origin == point(VGREAT, VGREAT, VGREAT))
    {
        if (pts1.size())
        {
            compareOrigin = sum(pts1)/pts1.size();
        }
    }

    SortableList<scalar> pts0MagSqr(magSqr(pts0 - compareOrigin));

    SortableList<scalar> pts1MagSqr(magSqr(pts1 - compareOrigin));

    forAll(pts0MagSqr, i)
    {
        scalar dist0 = pts0MagSqr[i];

        label face0I = pts0MagSqr.indices()[i];

        scalar matchDist = matchDistances[face0I];

        label startI = findLower(pts1MagSqr, 0.99999*dist0 - 2*matchDist);

        if (startI == -1)
        {
            startI = 0;
        }


        // Go through range of equal mag and find nearest vector.
        scalar minDistSqr = VGREAT;
        label minFacei = -1;

        for
        (
            label j = startI;
            (
                (j < pts1MagSqr.size())
             && (pts1MagSqr[j] < 1.00001*dist0 + 2*matchDist)
            );
            j++
        )
        {
            label facei = pts1MagSqr.indices()[j];
            // Compare actual vectors
            scalar distSqr = magSqr(pts0[face0I] - pts1[facei]);

            if (distSqr <= sqr(matchDist) && distSqr < minDistSqr)
            {
                minDistSqr = distSqr;
                minFacei = facei;
            }
        }

        if (minFacei == -1)
        {
            fullMatch = false;

            if (verbose)
            {
                Pout<< "Cannot find point in pts1 matching point " << face0I
                    << " coord:" << pts0[face0I]
                    << " in pts0 when using tolerance " << matchDist << endl;

                // Go through range of equal mag and find equal vector.
                Pout<< "Searching started from:" << startI << " in pts1"
                    << endl;
                for
                (
                    label j = startI;
                    (
                        (j < pts1MagSqr.size())
                     && (pts1MagSqr[j] < 1.00001*dist0 + 2*matchDist)
                    );
                    j++
                )
                {
                    label facei = pts1MagSqr.indices()[j];

                    Pout<< "    Compared coord: " << pts1[facei]
                        << " at index " << j
                        << " with difference to point "
                        << mag(pts1[facei] - pts0[face0I]) << endl;
                }
            }
        }

        from0To1[face0I] = minFacei;
    }