Skip to content
Snippets Groups Projects
polyMesh.C 26.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
    Mark Olesen's avatar
    Mark Olesen committed
        \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
    
         \\/     M anipulation  |
    -------------------------------------------------------------------------------
    License
        This file is part of OpenFOAM.
    
        OpenFOAM is free software; you can redistribute it and/or modify it
        under the terms of the GNU General Public License as published by the
        Free Software Foundation; either version 2 of the License, or (at your
        option) any later version.
    
        OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
        ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        for more details.
    
        You should have received a copy of the GNU General Public License
        along with OpenFOAM; if not, write to the Free Software Foundation,
        Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    
    \*---------------------------------------------------------------------------*/
    
    #include "polyMesh.H"
    #include "Time.H"
    #include "cellIOList.H"
    #include "SubList.H"
    #include "wedgePolyPatch.H"
    #include "emptyPolyPatch.H"
    #include "globalMeshData.H"
    #include "processorPolyPatch.H"
    #include "OSspecific.H"
    #include "demandDrivenData.H"
    
    
    mattijs's avatar
    mattijs committed
    #include "pointMesh.H"
    
    
    // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
    
    
    defineTypeNameAndDebug(Foam::polyMesh, 0);
    
    
    
    Foam::word Foam::polyMesh::defaultRegion = "region0";
    Foam::word Foam::polyMesh::meshSubDir = "polyMesh";
    
    
    // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
    
    void Foam::polyMesh::calcDirections() const
    {
        for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
        {
    
    mattijs's avatar
    mattijs committed
            solutionD_[cmpt] = 1;
    
    mattijs's avatar
    mattijs committed
        // Knock out empty and wedge directions. Note:they will be present on all
        // domains.
    
    
        label nEmptyPatches = 0;
    
    mattijs's avatar
    mattijs committed
        label nWedgePatches = 0;
    
    mattijs's avatar
    mattijs committed
        vector emptyDirVec = vector::zero;
        vector wedgeDirVec = vector::zero;
    
    
        forAll(boundaryMesh(), patchi)
        {
    
    mattijs's avatar
    mattijs committed
            if (boundaryMesh()[patchi].size())
    
    mattijs's avatar
    mattijs committed
                if (isA<emptyPolyPatch>(boundaryMesh()[patchi]))
    
    mattijs's avatar
    mattijs committed
                    emptyDirVec += sum(cmptMag(boundaryMesh()[patchi].faceAreas()));
                }
                else if (isA<wedgePolyPatch>(boundaryMesh()[patchi]))
                {
                    const wedgePolyPatch& wpp = refCast<const wedgePolyPatch>
                    (
                        boundaryMesh()[patchi]
                    );
    
                    nWedgePatches++;
                    wedgeDirVec += cmptMag(wpp.centreNormal());
    
    mattijs's avatar
    mattijs committed
            reduce(emptyDirVec, sumOp<vector>());
    
    mattijs's avatar
    mattijs committed
            emptyDirVec /= mag(emptyDirVec);
    
    
            for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
            {
    
    mattijs's avatar
    mattijs committed
                if (emptyDirVec[cmpt] > 1e-6)
    
    mattijs's avatar
    mattijs committed
                    solutionD_[cmpt] = -1;
    
    mattijs's avatar
    mattijs committed
                    solutionD_[cmpt] = 1;
                }
            }
        }
    
    
        // Knock out wedge directions
    
        geometricD_ = solutionD_;
    
        if (nWedgePatches)
        {
            reduce(wedgeDirVec, sumOp<vector>());
    
            wedgeDirVec /= mag(wedgeDirVec);
    
            for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
            {
                if (wedgeDirVec[cmpt] > 1e-6)
                {
                    geometricD_[cmpt] = -1;
                }
                else
                {
                    geometricD_[cmpt] = 1;
    
                }
            }
        }
    }
    
    
    // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
    
    Foam::polyMesh::polyMesh(const IOobject& io)
    :
        objectRegistry(io),
        primitiveMesh(),
        points_
        (
            IOobject
            (
                "points",
                time().findInstance(meshDir(), "points"),
                meshSubDir,
                *this,
                IOobject::MUST_READ,
                IOobject::NO_WRITE
            )
        ),
        faces_
        (
            IOobject
            (
                "faces",
                time().findInstance(meshDir(), "faces"),
                meshSubDir,
                *this,
                IOobject::MUST_READ,
                IOobject::NO_WRITE
            )
        ),
        owner_
        (
            IOobject
            (
                "owner",
                time().findInstance(meshDir(), "faces"),
                meshSubDir,
                *this,
                IOobject::READ_IF_PRESENT,
                IOobject::NO_WRITE
            )
        ),
        neighbour_
        (
            IOobject
            (
                "neighbour",
                time().findInstance(meshDir(), "faces"),
                meshSubDir,
                *this,
                IOobject::READ_IF_PRESENT,
                IOobject::NO_WRITE
            )
        ),
        clearedPrimitives_(false),
        boundary_
        (
            IOobject
            (
                "boundary",
                time().findInstance(meshDir(), "boundary"),
                meshSubDir,
                *this,
                IOobject::MUST_READ,
                IOobject::NO_WRITE
            ),
            *this
        ),
        bounds_(points_),
    
    mattijs's avatar
    mattijs committed
        geometricD_(Vector<label>::zero),
        solutionD_(Vector<label>::zero),
    
        pointZones_
        (
            IOobject
            (
                "pointZones",
                time().findInstance
                (
                    meshDir(),
                    "pointZones",
                    IOobject::READ_IF_PRESENT
                ),
                meshSubDir,
                *this,
                IOobject::READ_IF_PRESENT,
                IOobject::NO_WRITE
            ),
            *this
        ),
        faceZones_
        (
            IOobject
            (
                "faceZones",
                time().findInstance
                (
                    meshDir(),
                    "faceZones",
                    IOobject::READ_IF_PRESENT
                ),
                meshSubDir,
                *this,
                IOobject::READ_IF_PRESENT,
                IOobject::NO_WRITE
            ),
            *this
        ),
        cellZones_
        (
            IOobject
            (
                "cellZones",
                time().findInstance
                (
                    meshDir(),
                    "cellZones",
                    IOobject::READ_IF_PRESENT
                ),
                meshSubDir,
                *this,
                IOobject::READ_IF_PRESENT,
                IOobject::NO_WRITE
            ),
            *this
        ),
        globalMeshDataPtr_(NULL),
        moving_(false),
        changing_(false),
        curMotionTimeIndex_(time().timeIndex()),
        oldPointsPtr_(NULL)
    {
        if (exists(owner_.objectPath()))
        {
            initMesh();
        }
        else
        {
    
            cellIOList cLst
    
            (
                IOobject
                (
                    "cells",
                    time().findInstance(meshDir(), "cells"),
                    meshSubDir,
                    *this,
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE
                )
            );
    
            // Set the primitive mesh
    
            initMesh(cLst);
    
    
            owner_.write();
            neighbour_.write();
        }
    
        // Calculate topology for the patches (processor-processor comms etc.)
        boundary_.updateMesh();
    
        // Calculate the geometry for the patches (transformation tensors etc.)
        boundary_.calcGeometry();
    
        // Warn if global empty mesh (constructs globalData!)
        if (globalData().nTotalPoints() == 0)
        {
            WarningIn("polyMesh(const IOobject&)")
                << "no points in mesh" << endl;
        }
        if (globalData().nTotalCells() == 0)
        {
            WarningIn("polyMesh(const IOobject&)")
                << "no cells in mesh" << endl;
        }
    }
    
    
    
    mattijs's avatar
    mattijs committed
    Foam::polyMesh::polyMesh
    (
        const IOobject& io,
    
        const Xfer<pointField>& points,
        const Xfer<faceList>& faces,
        const Xfer<labelList>& owner,
        const Xfer<labelList>& neighbour,
    
    mattijs's avatar
    mattijs committed
        const bool syncPar
    )
    :
        objectRegistry(io),
        primitiveMesh(),
        points_
        (
            IOobject
            (
                "points",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            points
        ),
        faces_
        (
            IOobject
            (
                "faces",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            faces
        ),
        owner_
        (
            IOobject
            (
                "owner",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            owner
        ),
        neighbour_
        (
            IOobject
            (
                "neighbour",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            neighbour
        ),
        clearedPrimitives_(false),
        boundary_
        (
            IOobject
            (
                "boundary",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            *this,
            0
        ),
        bounds_(points_, syncPar),
    
    mattijs's avatar
    mattijs committed
        geometricD_(Vector<label>::zero),
        solutionD_(Vector<label>::zero),
    
    mattijs's avatar
    mattijs committed
        pointZones_
        (
            IOobject
            (
                "pointZones",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            *this,
            0
        ),
        faceZones_
        (
            IOobject
            (
                "faceZones",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            *this,
            0
        ),
        cellZones_
        (
            IOobject
            (
                "cellZones",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            *this,
            0
        ),
        globalMeshDataPtr_(NULL),
        moving_(false),
        changing_(false),
        curMotionTimeIndex_(time().timeIndex()),
        oldPointsPtr_(NULL)
    {
        // Check if the faces and cells are valid
        forAll (faces_, faceI)
        {
            const face& curFace = faces_[faceI];
    
            if (min(curFace) < 0 || max(curFace) > points_.size())
            {
                FatalErrorIn
                (
                    "polyMesh::polyMesh\n"
                    "(\n"
                    "    const IOobject& io,\n"
                    "    const pointField& points,\n"
                    "    const faceList& faces,\n"
                    "    const cellList& cells\n"
                    ")\n"
                )   << "Face " << faceI << "contains vertex labels out of range: "
                    << curFace << " Max point index = " << points_.size()
                    << abort(FatalError);
            }
        }
    
        // Set the primitive mesh
        initMesh();
    }
    
    
    Foam::polyMesh::polyMesh
    (
        const IOobject& io,
    
        const Xfer<pointField>& points,
        const Xfer<faceList>& faces,
        const Xfer<cellList>& cells,
    
    mattijs's avatar
    mattijs committed
        const bool syncPar
    )
    :
        objectRegistry(io),
        primitiveMesh(),
        points_
        (
            IOobject
            (
                "points",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            points
        ),
        faces_
        (
            IOobject
            (
                "faces",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            faces
        ),
        owner_
        (
            IOobject
            (
                "owner",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            0
        ),
        neighbour_
        (
            IOobject
            (
                "neighbour",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            0
        ),
        clearedPrimitives_(false),
        boundary_
        (
            IOobject
            (
                "boundary",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            *this,
            0
        ),
        bounds_(points_, syncPar),
    
    mattijs's avatar
    mattijs committed
        geometricD_(Vector<label>::zero),
        solutionD_(Vector<label>::zero),
    
    mattijs's avatar
    mattijs committed
        pointZones_
        (
            IOobject
            (
                "pointZones",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            *this,
            0
        ),
        faceZones_
        (
            IOobject
            (
                "faceZones",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            *this,
            0
        ),
        cellZones_
        (
            IOobject
            (
                "cellZones",
                instance(),
                meshSubDir,
                *this,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            *this,
            0
        ),
        globalMeshDataPtr_(NULL),
        moving_(false),
        changing_(false),
        curMotionTimeIndex_(time().timeIndex()),
        oldPointsPtr_(NULL)
    {
        // Check if faces are valid
        forAll (faces_, faceI)
        {
            const face& curFace = faces_[faceI];
    
            if (min(curFace) < 0 || max(curFace) > points_.size())
            {
                FatalErrorIn
                (
                    "polyMesh::polyMesh\n"
                    "(\n"
                    "    const IOobject&,\n"
    
                    "    const Xfer<pointField>&,\n"
                    "    const Xfer<faceList>&,\n"
                    "    const Xfer<cellList>&\n"
    
    mattijs's avatar
    mattijs committed
                    ")\n"
                )   << "Face " << faceI << "contains vertex labels out of range: "
                    << curFace << " Max point index = " << points_.size()
                    << abort(FatalError);
            }
        }
    
    
        // transfer in cell list
        cellList cLst(cells);
    
    mattijs's avatar
    mattijs committed
    
        // Check if cells are valid
        forAll (cLst, cellI)
        {
            const cell& curCell = cLst[cellI];
    
            if (min(curCell) < 0 || max(curCell) > faces_.size())
            {
                FatalErrorIn
                (
                    "polyMesh::polyMesh\n"
                    "(\n"
                    "    const IOobject&,\n"
    
                    "    const Xfer<pointField>&,\n"
                    "    const Xfer<faceList>&,\n"
                    "    const Xfer<cellList>&\n"
    
    mattijs's avatar
    mattijs committed
                    ")\n"
                )   << "Cell " << cellI << "contains face labels out of range: "
                    << curCell << " Max face index = " << faces_.size()
                    << abort(FatalError);
            }
        }
    
        // Set the primitive mesh
    
        initMesh(cLst);
    
    mattijs's avatar
    mattijs committed
    }
    
    
    void Foam::polyMesh::resetPrimitives
    (
    
        const Xfer<pointField>& points,
        const Xfer<faceList>& faces,
        const Xfer<labelList>& owner,
        const Xfer<labelList>& neighbour,
    
    mattijs's avatar
    mattijs committed
        const labelList& patchSizes,
        const labelList& patchStarts,
        const bool validBoundary
    )
    {
        // Clear addressing. Keep geometric props for mapping.
        clearAddressing();
    
        // Take over new primitive data.
    
        // Optimized to avoid overwriting data at all
        if (&points)
        {
            points_.transfer(points());
            bounds_ = boundBox(points_, validBoundary);
        }
    
        if (&faces)
        {
            faces_.transfer(faces());
        }
    
        if (&owner)
        {
            owner_.transfer(owner());
        }
    
        if (&neighbour)
        {
            neighbour_.transfer(neighbour());
        }
    
    mattijs's avatar
    mattijs committed
    
    
        // Reset patch sizes and starts
        forAll(boundary_, patchI)
        {
            boundary_[patchI] = polyPatch
            (
                boundary_[patchI].name(),
                patchSizes[patchI],
                patchStarts[patchI],
                patchI,
                boundary_
            );
        }
    
    
        // Flags the mesh files as being changed
        setInstance(time().timeName());
    
        // Check if the faces and cells are valid
        forAll (faces_, faceI)
        {
            const face& curFace = faces_[faceI];
    
            if (min(curFace) < 0 || max(curFace) > points_.size())
            {
                FatalErrorIn
                (
                    "polyMesh::polyMesh::resetPrimitives\n"
                    "(\n"
    
                    "    const Xfer<pointField>&,\n"
                    "    const Xfer<faceList>&,\n"
                    "    const Xfer<labelList>& owner,\n"
                    "    const Xfer<labelList>& neighbour,\n"
    
    mattijs's avatar
    mattijs committed
                    "    const labelList& patchSizes,\n"
                    "    const labelList& patchStarts\n"
                    ")\n"
                )   << "Face " << faceI << " contains vertex labels out of range: "
                    << curFace << " Max point index = " << points_.size()
                    << abort(FatalError);
            }
        }
    
    
    
        // Set the primitive mesh from the owner_, neighbour_.
        // Works out from patch end where the active faces stop.
    
    mattijs's avatar
    mattijs committed
        initMesh();
    
    
        if (validBoundary)
        {
            // Note that we assume that all the patches stay the same and are
            // correct etc. so we can already use the patches to do
            // processor-processor comms.
    
            // Calculate topology for the patches (processor-processor comms etc.)
            boundary_.updateMesh();
    
            // Calculate the geometry for the patches (transformation tensors etc.)
            boundary_.calcGeometry();
    
            // Warn if global empty mesh (constructs globalData!)
            if (globalData().nTotalPoints() == 0 || globalData().nTotalCells() == 0)
            {
                FatalErrorIn
                (
                    "polyMesh::polyMesh::resetPrimitives\n"
                    "(\n"
    
                    "    const Xfer<pointField>&,\n"
                    "    const Xfer<faceList>&,\n"
                    "    const Xfer<labelList>& owner,\n"
                    "    const Xfer<labelList>& neighbour,\n"
    
    mattijs's avatar
    mattijs committed
                    "    const labelList& patchSizes,\n"
                    "    const labelList& patchStarts\n"
                    ")\n"
                )
                    << "no points or no cells in mesh" << endl;
            }
        }
    }
    
    
    
    // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
    
    Foam::polyMesh::~polyMesh()
    {
        clearOut();
        resetMotion();
    }
    
    
    // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
    
    const Foam::fileName& Foam::polyMesh::dbDir() const
    {
        if (objectRegistry::dbDir() == defaultRegion)
        {
            return parent().dbDir();
        }
        else
        {
            return objectRegistry::dbDir();
        }
    }
    
    
    Foam::fileName Foam::polyMesh::meshDir() const
    {
        return dbDir()/meshSubDir;
    }
    
    
    const Foam::fileName& Foam::polyMesh::pointsInstance() const
    {
        return points_.instance();
    }
    
    
    const Foam::fileName& Foam::polyMesh::facesInstance() const
    {
        return faces_.instance();
    }
    
    
    
    mattijs's avatar
    mattijs committed
    const Foam::Vector<Foam::label>& Foam::polyMesh::geometricD() const
    
    mattijs's avatar
    mattijs committed
        if (geometricD_.x() == 0)
    
    mattijs's avatar
    mattijs committed
        return geometricD_;
    
    }
    
    
    Foam::label Foam::polyMesh::nGeometricD() const
    {
    
    mattijs's avatar
    mattijs committed
        return cmptSum(geometricD() + Vector<label>::one)/2;
    }
    
    mattijs's avatar
    mattijs committed
    const Foam::Vector<Foam::label>& Foam::polyMesh::solutionD() const
    {
        if (solutionD_.x() == 0)
    
    mattijs's avatar
    mattijs committed
            calcDirections();
    
    mattijs's avatar
    mattijs committed
        return solutionD_;
    
    }
    
    
    Foam::label Foam::polyMesh::nSolutionD() const
    {
    
    mattijs's avatar
    mattijs committed
        return cmptSum(solutionD() + Vector<label>::one)/2;
    
    }
    
    
    // Add boundary patches. Constructor helper
    void Foam::polyMesh::addPatches
    (
        const List<polyPatch*>& p,
        const bool validBoundary
    )
    {
    
        {
            FatalErrorIn
            (
                "void polyMesh::addPatches(const List<polyPatch*>&, const bool)"
            )   << "boundary already exists"
                << abort(FatalError);
        }
    
    
    mattijs's avatar
    mattijs committed
        // Reset valid directions
        geometricD_ = Vector<label>::zero;
        solutionD_ = Vector<label>::zero;
    
    
        boundary_.setSize(p.size());
    
        // Copy the patch pointers
        forAll (p, pI)
        {
            boundary_.set(pI, p[pI]);
        }
    
        // parallelData depends on the processorPatch ordering so force
        // recalculation. Problem: should really be done in removeBoundary but
        // there is some info in parallelData which might be interesting inbetween
        // removeBoundary and addPatches.
        deleteDemandDrivenData(globalMeshDataPtr_);
    
        if (validBoundary)
        {
            // Calculate topology for the patches (processor-processor comms etc.)
            boundary_.updateMesh();
    
            // Calculate the geometry for the patches (transformation tensors etc.)
            boundary_.calcGeometry();
    
            boundary_.checkDefinition();
        }
    }
    
    
    // Add mesh zones. Constructor helper
    void Foam::polyMesh::addZones
    (
        const List<pointZone*>& pz,
        const List<faceZone*>& fz,
        const List<cellZone*>& cz
    )
    {
    
        if (pointZones().size() || faceZones().size() || cellZones().size())
    
        {
            FatalErrorIn
            (
                "void addZones\n"
                "(\n"
    
                "    const List<pointZone*>&,\n"
                "    const List<faceZone*>&,\n"
                "    const List<cellZone*>&\n"
    
                ")"
            )   << "point, face or cell zone already exists"
                << abort(FatalError);
        }
    
        // Point zones
        if (pz.size())
        {
            pointZones_.setSize(pz.size());
    
            // Copy the zone pointers
            forAll (pz, pI)
            {
                pointZones_.set(pI, pz[pI]);
            }
    
            pointZones_.writeOpt() = IOobject::AUTO_WRITE;
        }
    
        // Face zones
        if (fz.size())
        {
            faceZones_.setSize(fz.size());
    
            // Copy the zone pointers
            forAll (fz, fI)
            {
                faceZones_.set(fI, fz[fI]);
            }
    
            faceZones_.writeOpt() = IOobject::AUTO_WRITE;
        }
    
        // Cell zones
        if (cz.size())
        {
            cellZones_.setSize(cz.size());
    
            // Copy the zone pointers
            forAll (cz, cI)
            {
                cellZones_.set(cI, cz[cI]);
            }
    
            cellZones_.writeOpt() = IOobject::AUTO_WRITE;
        }
    }
    
    
    const Foam::pointField& Foam::polyMesh::points() const
    {
        if (clearedPrimitives_)
        {
            FatalErrorIn("const pointField& polyMesh::points() const")
                << "points deallocated"
                << abort(FatalError);
        }
    
        return points_;
    }
    
    
    const Foam::faceList& Foam::polyMesh::faces() const
    {
        if (clearedPrimitives_)
        {
            FatalErrorIn("const faceList& polyMesh::faces() const")
                << "faces deallocated"
                << abort(FatalError);
        }
    
        return faces_;
    }
    
    
    const Foam::labelList& Foam::polyMesh::faceOwner() const
    {
        return owner_;
    }
    
    
    const Foam::labelList& Foam::polyMesh::faceNeighbour() const
    {
        return neighbour_;
    }
    
    
    // Return old mesh motion points
    const Foam::pointField& Foam::polyMesh::oldPoints() const
    {
        if (!oldPointsPtr_)
        {
            if (debug)
            {