Commit 7cf232ce authored by Mark OLESEN's avatar Mark OLESEN
Browse files

STYLE: split up cuttingPlane source files

parent 53b0bb07
......@@ -19,7 +19,9 @@ sampledSet/uniform/uniformSet.C
sampledSet/array/arraySet.C
sampledSet/shortestPath/shortestPathSet.C
surface/cuttingPlane/cuttingPlane.C
surface/cutting/cuttingPlane.C
surface/cutting/cuttingPlaneCuts.C
surface/cutting/cuttingPlaneWalk.C
surface/distanceSurface/distanceSurface.C
surface/isoSurface/isoSurface.C
surface/isoSurface/isoSurfaceCell.C
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 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 3 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, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cuttingPlane.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::cuttingPlane::debug(Foam::debug::debugSwitch("cuttingPlane", 0));
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cuttingPlane::cuttingPlane(const plane& pln)
:
plane(pln)
{}
Foam::cuttingPlane::cuttingPlane
(
const plane& pln,
const primitiveMesh& mesh,
const bool triangulate,
const bitSet& cellIdLabels
)
:
plane(pln)
{
performCut(mesh, triangulate, cellIdLabels);
}
Foam::cuttingPlane::cuttingPlane
(
const plane& pln,
const primitiveMesh& mesh,
const bool triangulate,
bitSet&& cellIdLabels
)
:
plane(pln)
{
performCut(mesh, triangulate, cellIdLabels);
}
Foam::cuttingPlane::cuttingPlane
(
const plane& pln,
const primitiveMesh& mesh,
const bool triangulate,
const labelUList& cellIdLabels
)
:
plane(pln)
{
performCut(mesh, triangulate, cellIdLabels);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::cuttingPlane::performCut
(
const primitiveMesh& mesh,
const bool triangulate,
bitSet&& cellIdLabels
)
{
MeshStorage::clear();
meshCells_.clear();
// Pre-populate with restriction
bitSet cellCuts(std::move(cellIdLabels));
if (cellCuts.size())
{
cellCuts.resize(mesh.nCells());
}
// For each mesh point, the encoded side (0,1,2) of the plane
PackedList<2> sides;
// Determine cells that are (likely) cut
// - some ambiguity when plane is exactly between cells
const label nFaceCuts = calcCellCuts(mesh, sides, cellCuts);
// Find closed loop from cell cuts
walkCellCuts(mesh, cellCuts, sides, triangulate, nFaceCuts);
}
void Foam::cuttingPlane::performCut
(
const primitiveMesh& mesh,
const bool triangulate,
const bitSet& cellIdLabels
)
{
bitSet subsetCells(cellIdLabels);
performCut(mesh, triangulate, std::move(subsetCells));
}
void Foam::cuttingPlane::performCut
(
const primitiveMesh& mesh,
const bool triangulate,
const labelUList& cellIdLabels
)
{
bitSet subsetCells;
if (notNull(cellIdLabels))
{
// Pre-populate with restriction
subsetCells.resize(mesh.nCells());
subsetCells.set(cellIdLabels);
}
performCut(mesh, triangulate, std::move(subsetCells));
}
void Foam::cuttingPlane::remapFaces(const labelUList& faceMap)
{
if (notNull(faceMap) && !faceMap.empty())
{
MeshStorage::remapFaces(faceMap);
List<label> remappedCells(faceMap.size());
forAll(faceMap, facei)
{
remappedCells[facei] = meshCells_[faceMap[facei]];
}
meshCells_.transfer(remappedCells);
}
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::cuttingPlane::operator=(const cuttingPlane& rhs)
{
if (this == &rhs)
{
FatalErrorInFunction
<< "Attempted assignment to self"
<< abort(FatalError);
}
static_cast<MeshStorage&>(*this) = rhs;
static_cast<plane&>(*this) = rhs;
meshCells_ = rhs.meshCells();
}
// ************************************************************************* //
......@@ -30,10 +30,6 @@ Description
No attempt at resolving degenerate cases.
Since the cut faces can be quite ugly, they will often be triangulated.
Note
When the cutting plane coincides with a mesh face, the cell edge on the
positive side of the plane is taken.
SourceFiles
cuttingPlane.C
......@@ -43,7 +39,6 @@ SourceFiles
#define cuttingPlane_H
#include "plane.H"
#include "pointField.H"
#include "faceList.H"
#include "bitSet.H"
#include "MeshedSurface.H"
......@@ -79,26 +74,31 @@ class cuttingPlane
//- Determine cut cells, possibly restricted to a list of cells
//
// \param sides [out] For each mesh point, the encoded side of the
// plane (0=BACK, 1=ONPLANE, 2=FRONT).
// \param cellCuts [in,out] On input an empty set (ie, no restriction)
// or subsetted cells. On output, the cells cut according to the
// planeSides detection.
// plane-sides detection.
//
// \return number of faces cut
label calcCellCuts
(
const primitiveMesh& mesh,
const PackedList<2>& planeSides,
PackedList<2>& sides,
bitSet& cellCuts
);
//- Walk the cell cuts to create faces
//
// \param planeSides [in] Used to determine edge cuts
// \param cellCuts [in] The cells to walk.
// \param sides [in] For each mesh point, the encoded side of the
// plane (0=BACK, 1=ONPLANE, 2=FRONT), which is used to determine
// the edge cuts
void walkCellCuts
(
const primitiveMesh& mesh,
const bitSet& cellCuts,
const PackedList<2>& planeSides,
const PackedList<2>& sides,
const bool triangulate,
const label nFaceCuts = 0
);
......@@ -115,20 +115,20 @@ protected:
// Protected Member Functions
//- Cut mesh with existing plane, restricted to a list of cells
// Reclaim memory for cellIdLabels
void performCut
(
const primitiveMesh& mesh,
const bool triangulate,
const bitSet& cellSelectionMask = bitSet()
bitSet&& cellIdLabels
);
//- Cut mesh with existing plane, restricted to a list of cells
// Reclaim memory for cellSelectionMask
void performCut
(
const primitiveMesh& mesh,
const bool triangulate,
bitSet&& cellSelectionMask
const bitSet& cellIdLabels = bitSet()
);
//- Cut mesh with existing plane, restricted to a list of cells
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 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 3 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, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cuttingPlane.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Check for face/plane intersection based on crossings
// Took (-1,0,+1) from plane::sign and packed as (0,1,2).
// Now use for left shift to obtain (1,2,4).
//
// Test accumulated value for an intersection with the plane.
inline bool intersectsFace
(
const PackedList<2>& sides,
const labelUList& indices
)
{
unsigned accum = 0u;
for (const label pointi : indices)
{
accum |= (1u << sides[pointi]);
}
// Accumulated value 3,5,6,7 indicates an intersection
return (accum == 3 || accum >= 5);
}
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::cuttingPlane::calcCellCuts
(
const primitiveMesh& mesh,
PackedList<2>& sides,
bitSet& cellCuts
)
{
const faceList& faces = mesh.faces();
const pointField& pts = mesh.points();
const label nCells = mesh.nCells();
const label nFaces = mesh.nFaces();
const label nInternFaces = mesh.nInternalFaces();
// Classify sides of plane (0=BACK, 1=ONPLANE, 2=FRONT) for each point
{
const plane& pln = *this;
const label len = pts.size();
sides.resize(len);
// From signed (-1,0,+1) to (0,1,2) for PackedList
for (label i=0; i < len; ++i)
{
sides.set(i, unsigned(1 + pln.sign(pts[i], SMALL)));
}
}
// Detect cells cuts from the face cuts
label nFaceCuts = 0;
// 1st face cut of cell
bitSet hasCut1(nCells);
// 2nd face cut of cell
bitSet hasCut2(nCells);
for (label facei = 0; facei < nInternFaces; ++facei)
{
if (intersectsFace(sides, faces[facei]))
{
const label own = mesh.faceOwner()[facei];
const label nei = mesh.faceNeighbour()[facei];
++nFaceCuts;
if (!hasCut1.set(own))
{
hasCut2.set(own);
}
if (!hasCut1.set(nei))
{
hasCut2.set(nei);
}
}
}
for (label facei = nInternFaces; facei < nFaces; ++facei)
{
if (intersectsFace(sides, faces[facei]))
{
const label own = mesh.faceOwner()[facei];
++nFaceCuts;
if (!hasCut1.set(own))
{
hasCut2.set(own);
}
}
}
hasCut1.clearStorage(); // Not needed now
if (cellCuts.size())
{
cellCuts.resize(nCells); // safety
cellCuts &= hasCut2; // restrict to cell subset
if (debug)
{
Pout<<"detected " << cellCuts.count() << "/" << nCells
<< " cells cut, subsetted from "
<< hasCut2.count() << "/" << nCells << " cells." << endl;
}
}
else
{
cellCuts = std::move(hasCut2);
if (debug)
{
Pout<<"detected " << cellCuts.count() << "/" << nCells
<< " cells cut." << endl;
}
}
if (debug && isA<fvMesh>(mesh))
{
const fvMesh& fvm = dynamicCast<const fvMesh&>(mesh);
volScalarField cCuts
(
IOobject
(
"cuttingPlane.cellCuts",
fvm.time().timeName(),
fvm.time(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
fvm,
dimensionedScalar(dimless, Zero)
);
auto& cCutsFld = cCuts.primitiveFieldRef();
for (const label celli : cellCuts)
{
cCutsFld[celli] = 1;
}
Pout<< "Writing cut types:" << cCuts.objectPath() << endl;
cCuts.write();
}
return nFaceCuts;
}
// ************************************************************************* //
......@@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -24,17 +24,9 @@ License
\*---------------------------------------------------------------------------*/
#include "cuttingPlane.H"
#include "fvMesh.H"
#include "volFields.H"
#include "meshTools.H"
#include "edgeHashes.H"
#include "HashOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::cuttingPlane::debug(Foam::debug::debugSwitch("cuttingPlane", 0));
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
......@@ -55,172 +47,11 @@ namespace Foam
return true;
}
// Classify sides of plane (0=BACK, 1=ONPLANE, 2=FRONT) for each point
inline PackedList<2> classifySides(const plane& pln, const pointField& pts)
{
const label len = pts.size();
PackedList<2> output(len);
// From signed (-1,0,+1) to (0,1,2) for PackedList
for (label i=0; i < len; ++i)
{
output.set(i, unsigned(1 + pln.sign(pts[i], SMALL)));
}
return output;
}
// Check for face/plane intersection based on crossings
// Took (-1,0,+1) from plane::sign and packed as (0,1,2).
// Now use for left shift to obtain (1,2,4).
//
// Test accumulated value for an intersection with the plane.
inline bool intersectsFace
(
const PackedList<2>& sides,
const labelUList& indices
)
{
unsigned accum = 0u;
for (const label pointi : indices)
{
accum |= (1u << sides[pointi]);
}
// Accumulated value 3,5,6,7 indicates an intersection
return (accum == 3 || accum >= 5);
}
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::cuttingPlane::calcCellCuts
(
const primitiveMesh& mesh,
const PackedList<2>& sides,
bitSet& cellCuts
)
{
const faceList& faces = mesh.faces();
const label nCells = mesh.nCells();
const label nFaces = mesh.nFaces();
const label nInternFaces = mesh.nInternalFaces();
// Detect cells cuts from the face cuts
label nFaceCuts = 0;
// 1st face cut of cell
bitSet hasCut1(nCells);
// 2nd face cut of cell
bitSet hasCut2(nCells);
for (label facei = 0; facei < nInternFaces; ++facei)
{
if (intersectsFace(sides, faces[facei]))
{
const label own = mesh.faceOwner()[facei];
const label nei = mesh.faceNeighbour()[facei];
++nFaceCuts;
if (!hasCut1.set(own))
{
hasCut2.set(own);
}
if (!hasCut1.set(nei))
{
hasCut2.set(nei);
}
}
}
for (label facei = nInternFaces; facei < nFaces; ++facei)
{
if (intersectsFace(sides, faces[facei]))
{
const label own = mesh.faceOwner()[facei];
++nFaceCuts;
if (!hasCut1.set(own))
{
hasCut2.set(own);
}
}
}
hasCut1.clearStorage(); // Not needed now
if (cellCuts.size())
{
cellCuts.resize(nCells); // safety
cellCuts &= hasCut2; // restrict to cell subset
if (debug)
{
Pout<<"detected " << cellCuts.count() << "/" << nCells
<< " cells cut, subsetted from "
<< hasCut2.count() << "/" << nCells << " cells." << endl;
}
}
else
{
cellCuts = std::move(hasCut2);