Commit b966b7cd authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: static test methods for matching simple cell shapes

- (tet, pyr, hex) can be identified from their number of faces
  and vertices. For these common shapes can use static `test()`
  method instead of the virtual isA() method.

  This is much cheaper for calling on an individual basis since
  it avoids the overhead of constructing an object.

ENH: tetCell edge/reverseEdge (already had tetEdge)
parent b7c8a45d
......@@ -133,12 +133,9 @@ void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
<< endl;
// Construct shape recognizers
hexMatcher hex;
prismMatcher prism;
wedgeMatcher wedge;
pyrMatcher pyr;
tetWedgeMatcher tetWedge;
tetMatcher tet;
// Counters for different cell types
label nHex = 0;
......@@ -153,15 +150,15 @@ void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
for (label celli = 0; celli < mesh.nCells(); celli++)
{
if (hex.isA(mesh, celli))
if (hexMatcher::test(mesh, celli))
{
nHex++;
}
else if (tet.isA(mesh, celli))
else if (tetMatcher::test(mesh, celli))
{
nTet++;
}
else if (pyr.isA(mesh, celli))
else if (pyrMatcher::test(mesh, celli))
{
nPyr++;
}
......
......@@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -29,6 +30,71 @@ License
#include "primitiveMesh.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Check (6 quad)
static inline bool checkFaceSizeMatch(const UList<face>& faces)
{
if (faces.size() != 6) // facePerCell
{
return false;
}
for (const face& f : faces)
{
if (f.size() != 4) // quad
{
return false;
}
}
return true;
}
// Check (6 quad)
static inline bool checkFaceSizeMatch
(
const UList<face>& meshFaces,
const labelUList& cellFaces
)
{
if (cellFaces.size() != 6) // facePerCell
{
return false;
}
for (const label facei : cellFaces)
{
if (meshFaces[facei].size() != 4) // quad
{
return false;
}
}
return true;
}
} // End namespace Foam
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
bool Foam::hexMatcher::test(const UList<face>& faces)
{
return checkFaceSizeMatch(faces);
}
bool Foam::hexMatcher::test(const primitiveMesh& mesh, const label celli)
{
return checkFaceSizeMatch(mesh.faces(), mesh.cells()[celli]);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::hexMatcher::hexMatcher()
......@@ -241,53 +307,11 @@ Foam::label Foam::hexMatcher::faceHashValue() const
bool Foam::hexMatcher::faceSizeMatch
(
const faceList& faces,
const labelList& myFaces
const faceList& meshFaces,
const labelList& cellFaces
) const
{
if (myFaces.size() != facePerCell)
{
return false;
}
for (const label facei : myFaces)
{
const label size = faces[facei].size();
if (size != 4)
{
return false;
}
}
return true;
}
bool Foam::hexMatcher::isA(const primitiveMesh& mesh, const label celli)
{
return matchShape
(
true,
mesh.faces(),
mesh.faceOwner(),
celli,
mesh.cells()[celli]
);
}
bool Foam::hexMatcher::isA(const faceList& faces)
{
// Do as if mesh with one cell only
return matchShape
(
true,
faces, // all faces in mesh
labelList(faces.size(), Zero), // cell 0 is owner of all faces
0, // cell label
identity(faces.size()) // faces of cell 0
);
return checkFaceSizeMatch(meshFaces, cellFaces);
}
......
......@@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -84,6 +85,17 @@ public:
~hexMatcher() = default;
// Static Functions
//- Test if given list of faces satisfies criteria for HEX.
//- (6 quad)
static bool test(const UList<face>& faces);
//- Test if given cell satisfies criteria for HEX.
//- (6 quad)
static bool test(const primitiveMesh& mesh, const label celli);
// Member Functions
virtual label nVertPerCell() const
......@@ -114,9 +126,15 @@ public:
const labelList& myFaces
);
virtual bool isA(const primitiveMesh& mesh, const label celli);
virtual bool isA(const faceList& faces)
{
return hexMatcher::test(faces);
}
virtual bool isA(const faceList&);
virtual bool isA(const primitiveMesh& mesh, const label celli)
{
return hexMatcher::test(mesh, celli);
}
virtual bool matches
(
......
......@@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -31,6 +32,96 @@ License
#include "cellModel.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Check (4 tri, 1 quad)
static inline bool checkFaceSizeMatch(const UList<face>& faces)
{
if (faces.size() != 5) // facePerCell
{
return false;
}
int nTris = 0;
int nQuads = 0;
for (const face& f : faces)
{
const label size = f.size();
if (size == 3)
{
++nTris;
}
else if (size == 4)
{
++nQuads;
}
else
{
return false;
}
}
return (nTris == 4 && nQuads == 1);
}
// Check (4 tri, 1 quad)
static inline bool checkFaceSizeMatch
(
const UList<face>& meshFaces,
const labelUList& cellFaces
)
{
if (cellFaces.size() != 5) // facePerCell
{
return false;
}
int nTris = 0;
int nQuads = 0;
for (const label facei : cellFaces)
{
const label size = meshFaces[facei].size();
if (size == 3)
{
++nTris;
}
else if (size == 4)
{
++nQuads;
}
else
{
return false;
}
}
return (nTris == 4 && nQuads == 1);
}
} // End namespace Foam
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
bool Foam::pyrMatcher::test(const UList<face>& faces)
{
return checkFaceSizeMatch(faces);
}
bool Foam::pyrMatcher::test(const primitiveMesh& mesh, const label celli)
{
return checkFaceSizeMatch(mesh.faces(), mesh.cells()[celli]);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::pyrMatcher::pyrMatcher()
......@@ -211,64 +302,11 @@ Foam::label Foam::pyrMatcher::faceHashValue() const
bool Foam::pyrMatcher::faceSizeMatch
(
const faceList& faces,
const labelList& myFaces
const faceList& meshFaces,
const labelList& cellFaces
) const
{
if (myFaces.size() != 5)
{
return false;
}
label nTris = 0;
label nQuads = 0;
for (const label facei : myFaces)
{
const label size = faces[facei].size();
if (size == 3)
{
++nTris;
}
else if (size == 4)
{
++nQuads;
}
else
{
return false;
}
}
return (nTris == 4 && nQuads == 1);
}
bool Foam::pyrMatcher::isA(const primitiveMesh& mesh, const label celli)
{
return matchShape
(
true,
mesh.faces(),
mesh.faceOwner(),
celli,
mesh.cells()[celli]
);
}
bool Foam::pyrMatcher::isA(const faceList& faces)
{
// Do as if mesh with one cell only
return matchShape
(
true,
faces, // all faces in mesh
labelList(faces.size(), Zero), // cell 0 is owner of all faces
0, // cell label
identity(faces.size()) // faces of cell 0
);
return checkFaceSizeMatch(meshFaces, cellFaces);
}
......
......@@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -84,6 +85,17 @@ public:
~pyrMatcher() = default;
// Static Functions
//- Test if given list of faces satisfies criteria for PYR.
//- (4 tri, 1 quad)
static bool test(const UList<face>& faces);
//- Test if given cell satisfies criteria for PYR.
//- (4 tri, 1 quad)
static bool test(const primitiveMesh& mesh, const label celli);
// Member Functions
virtual label nVertPerCell() const
......@@ -114,9 +126,15 @@ public:
const labelList& myFaces
);
virtual bool isA(const primitiveMesh& mesh, const label celli);
virtual bool isA(const faceList& faces)
{
return pyrMatcher::test(faces);
}
virtual bool isA(const faceList&);
virtual bool isA(const primitiveMesh& mesh, const label celli)
{
return pyrMatcher::test(mesh, celli);
}
virtual bool matches
(
......
......@@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -31,6 +32,72 @@ License
#include "cellModel.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Check (4 tri)
static inline bool checkFaceSizeMatch(const UList<face>& faces)
{
if (faces.size() != 4) // facePerCell
{
return false;
}
for (const face& f : faces)
{
if (f.size() != 3) // tri
{
return false;
}
}
return true;
}
// Check (4 tri)
static inline bool checkFaceSizeMatch
(
const UList<face>& meshFaces,
const labelUList& cellFaces
)
{
if (cellFaces.size() != 4) // facePerCell
{
return false;
}
for (const label facei : cellFaces)
{
if (meshFaces[facei].size() != 3) // tri
{
return false;
}
}
return true;
}
} // End namespace Foam
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
bool Foam::tetMatcher::test(const UList<face>& faces)
{
return checkFaceSizeMatch(faces);
}
bool Foam::tetMatcher::test(const primitiveMesh& mesh, const label celli)
{
return checkFaceSizeMatch(mesh.faces(), mesh.cells()[celli]);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::tetMatcher::tetMatcher()
......@@ -180,53 +247,11 @@ Foam::label Foam::tetMatcher::faceHashValue() const
bool Foam::tetMatcher::faceSizeMatch
(
const faceList& faces,
const labelList& myFaces
const faceList& meshFaces,
const labelList& cellFaces
) const
{
if (myFaces.size() != 4)
{
return false;
}
for (const label facei : myFaces)
{
const label size = faces[facei].size();
if (size != 3)
{
return false;
}
}
return true;
}
bool Foam::tetMatcher::isA(const primitiveMesh& mesh, const label celli)
{
return matchShape
(
true,
mesh.faces(),
mesh.faceOwner(),
celli,
mesh.cells()[celli]
);
}
bool Foam::tetMatcher::isA(const faceList& faces)
{
// Do as if mesh with one cell only
return matchShape
(
true,
faces, // all faces in mesh
labelList(faces.size(), Zero), // cell 0 is owner of all faces
0, // cell label
identity(faces.size()) // faces of cell 0
);
return checkFaceSizeMatch(meshFaces, cellFaces);
}
......
......@@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -84,6 +85,17 @@ public:
~tetMatcher() = default;
// Static Functions
//- Test if given list of faces satisfies criteria for TET.
//- (4 tri)
static bool test(const UList<face>& faces);
//- Test if given cell satisfies criteria for TET.
//- (4 tri)
static bool test(const primitiveMesh& mesh, const label celli);
// Member Functions
virtual label nVertPerCell() const
......@@ -114,9 +126,15 @@ public:
const labelList& myFaces
);
virtual bool isA(const primitiveMesh& mesh, const label celli);
virtual bool isA(const primitiveMesh& mesh, const label celli)
{
return tetMatcher::test(mesh, celli);
}
virtual bool isA(const faceList&);
virtual bool isA(const faceList& faces)
{
return tetMatcher::test(faces);
}
virtual bool matches
(
......