Resurrect function to get face indices

Due to recent changes to remove static arrays that are not supported on
some devices, the function to return all the local point indices on a
face was removed. That left no way to get the structure of cell faces
short of pulling an internal data structure.

This change resurrects a function to get point indices for a face. The
interface for this method has necessarily changed, so I also changed the
corresponding function for getting edge indices.
This commit is contained in:
Kenneth Moreland 2018-03-22 22:37:33 -06:00
parent b6b0005996
commit 1fe7869211
5 changed files with 86 additions and 59 deletions

@ -41,7 +41,7 @@ public:
static constexpr vtkm::Int32 MAX_NUM_EDGES = 12;
public:
VTKM_EXEC vtkm::Int32 NumEdges(vtkm::Int32 i) const
VTKM_EXEC vtkm::Int32 NumEdges(vtkm::Int32 cellShapeId) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 numEdges[vtkm::NUMBER_OF_CELL_SHAPES] = {
// NumEdges
@ -61,10 +61,12 @@ public:
9, // 13: CELL_SHAPE_WEDGE
8 // 14: CELL_SHAPE_PYRAMID
};
return numEdges[i];
return numEdges[cellShapeId];
}
VTKM_EXEC vtkm::Int32 PointsInEdge(vtkm::Int32 i, vtkm::Int32 j, vtkm::Int32 k) const
VTKM_EXEC vtkm::Int32 PointsInEdge(vtkm::Int32 cellShapeId,
vtkm::Int32 edgeIndex,
vtkm::Int32 localPointIndex) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32
pointsInEdge[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_EDGES][2] = {
@ -117,7 +119,7 @@ public:
// clang-format on
};
return pointsInEdge[i][j][k];
return pointsInEdge[cellShapeId][edgeIndex][localPointIndex];
}
};
@ -157,57 +159,63 @@ static inline VTKM_EXEC vtkm::IdComponent CellEdgeNumberOfEdges(
}
template <typename CellShapeTag>
static inline VTKM_EXEC vtkm::Vec<vtkm::IdComponent, 2> CellEdgeLocalIndices(
vtkm::IdComponent numPoints,
vtkm::IdComponent edgeIndex,
CellShapeTag shape,
const vtkm::exec::FunctorBase& worklet)
static inline VTKM_EXEC vtkm::IdComponent CellEdgeLocalIndex(vtkm::IdComponent numPoints,
vtkm::IdComponent pointIndex,
vtkm::IdComponent edgeIndex,
CellShapeTag shape,
const vtkm::exec::FunctorBase& worklet)
{
VTKM_ASSUME(pointIndex >= 0);
VTKM_ASSUME(pointIndex < 2);
VTKM_ASSUME(edgeIndex >= 0);
VTKM_ASSUME(edgeIndex < detail::CellEdgeTables::MAX_NUM_EDGES);
if (edgeIndex >= vtkm::exec::CellEdgeNumberOfEdges(numPoints, shape, worklet))
{
worklet.RaiseError("Invalid edge number.");
return vtkm::Vec<vtkm::IdComponent, 2>(0);
return 0;
}
detail::CellEdgeTables table;
return vtkm::make_Vec(table.PointsInEdge(CellShapeTag::Id, edgeIndex, 0),
table.PointsInEdge(CellShapeTag::Id, edgeIndex, 1));
return table.PointsInEdge(CellShapeTag::Id, edgeIndex, pointIndex);
}
static inline VTKM_EXEC vtkm::Vec<vtkm::IdComponent, 2> CellEdgeLocalIndices(
vtkm::IdComponent numPoints,
vtkm::IdComponent edgeIndex,
vtkm::CellShapeTagPolygon,
const vtkm::exec::FunctorBase&)
static inline VTKM_EXEC vtkm::IdComponent CellEdgeLocalIndex(vtkm::IdComponent numPoints,
vtkm::IdComponent pointIndex,
vtkm::IdComponent edgeIndex,
vtkm::CellShapeTagPolygon,
const vtkm::exec::FunctorBase&)
{
VTKM_ASSUME(numPoints >= 3);
VTKM_ASSUME(pointIndex >= 0);
VTKM_ASSUME(pointIndex < 2);
VTKM_ASSUME(edgeIndex >= 0);
VTKM_ASSUME(edgeIndex < numPoints);
if (edgeIndex < numPoints - 1)
if (edgeIndex + pointIndex < numPoints)
{
return vtkm::Vec<vtkm::IdComponent, 2>(edgeIndex, edgeIndex + 1);
return edgeIndex + pointIndex;
}
else
{
return vtkm::Vec<vtkm::IdComponent, 2>(edgeIndex, 0);
return 0;
}
}
static inline VTKM_EXEC vtkm::Vec<vtkm::IdComponent, 2> CellEdgeLocalIndices(
vtkm::IdComponent numPoints,
vtkm::IdComponent edgeIndex,
vtkm::CellShapeTagGeneric shape,
const vtkm::exec::FunctorBase& worklet)
static inline VTKM_EXEC vtkm::IdComponent CellEdgeLocalIndex(vtkm::IdComponent numPoints,
vtkm::IdComponent pointIndex,
vtkm::IdComponent edgeIndex,
vtkm::CellShapeTagGeneric shape,
const vtkm::exec::FunctorBase& worklet)
{
VTKM_ASSUME(pointIndex >= 0);
VTKM_ASSUME(pointIndex < 2);
VTKM_ASSUME(edgeIndex >= 0);
VTKM_ASSUME(edgeIndex < detail::CellEdgeTables::MAX_NUM_EDGES);
if (shape.Id == vtkm::CELL_SHAPE_POLYGON)
{
return CellEdgeLocalIndices(numPoints, edgeIndex, vtkm::CellShapeTagPolygon(), worklet);
return CellEdgeLocalIndex(
numPoints, pointIndex, edgeIndex, vtkm::CellShapeTagPolygon(), worklet);
}
else
{
@ -215,11 +223,10 @@ static inline VTKM_EXEC vtkm::Vec<vtkm::IdComponent, 2> CellEdgeLocalIndices(
if (edgeIndex >= table.NumEdges(shape.Id))
{
worklet.RaiseError("Invalid edge number.");
return vtkm::Vec<vtkm::IdComponent, 2>(0);
return 0;
}
return vtkm::make_Vec(table.PointsInEdge(shape.Id, edgeIndex, 0),
table.PointsInEdge(shape.Id, edgeIndex, 1));
return table.PointsInEdge(shape.Id, edgeIndex, pointIndex);
}
}
@ -237,11 +244,10 @@ static inline VTKM_EXEC vtkm::Id2 CellEdgeCanonicalId(
const GlobalPointIndicesVecType& globalPointIndicesVec,
const vtkm::exec::FunctorBase& worklet)
{
vtkm::Vec<vtkm::IdComponent, 2> localPointIndices =
vtkm::exec::CellEdgeLocalIndices(numPoints, edgeIndex, shape, worklet);
vtkm::Id pointIndex0 = globalPointIndicesVec[localPointIndices[0]];
vtkm::Id pointIndex1 = globalPointIndicesVec[localPointIndices[1]];
vtkm::Id pointIndex0 =
globalPointIndicesVec[vtkm::exec::CellEdgeLocalIndex(numPoints, 0, edgeIndex, shape, worklet)];
vtkm::Id pointIndex1 =
globalPointIndicesVec[vtkm::exec::CellEdgeLocalIndex(numPoints, 1, edgeIndex, shape, worklet)];
if (pointIndex0 < pointIndex1)
{
return vtkm::Id2(pointIndex0, pointIndex1);

@ -40,7 +40,7 @@ public:
static constexpr vtkm::Int32 MAX_FACE_SIZE = 4;
static constexpr vtkm::Int32 MAX_NUM_FACES = 6;
VTKM_EXEC vtkm::Int32 NumFaces(vtkm::Int32 i) const
VTKM_EXEC vtkm::Int32 NumFaces(vtkm::Int32 cellShapeId) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 numFaces[vtkm::NUMBER_OF_CELL_SHAPES] = {
// NumFaces
@ -60,10 +60,10 @@ public:
5, // 13: CELL_SHAPE_WEDGE
5 // 14: CELL_SHAPE_PYRAMID
};
return numFaces[i];
return numFaces[cellShapeId];
}
VTKM_EXEC vtkm::Int32 NumPointsInFace(vtkm::Int32 i, vtkm::Int32 j) const
VTKM_EXEC vtkm::Int32 NumPointsInFace(vtkm::Int32 cellShapeId, vtkm::Int32 faceIndex) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32
numPointsInFace[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_FACES] = {
@ -84,10 +84,12 @@ public:
{ 3, 3, 4, 4, 4, -1 }, // 13: CELL_SHAPE_WEDGE
{ 4, 3, 3, 3, 3, -1 } // 14: CELL_SHAPE_PYRAMID
};
return numPointsInFace[i][j];
return numPointsInFace[cellShapeId][faceIndex];
}
VTKM_EXEC vtkm::Int32 PointsInFace(vtkm::Int32 i, vtkm::Int32 j, vtkm::Int32 k) const
VTKM_EXEC vtkm::Int32 PointsInFace(vtkm::Int32 cellShapeId,
vtkm::Int32 faceIndex,
vtkm::Int32 localPointIndex) const
{
// clang-format off
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 pointsInFace[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_FACES]
@ -141,7 +143,7 @@ public:
{ 2, 3, 4, -1 }, { 3, 0, 4, -1 },{ -1, -1, -1, -1 } }
// clang-format on
};
return pointsInFace[i][j][k];
return pointsInFace[cellShapeId][faceIndex][localPointIndex];
}
};
@ -191,6 +193,24 @@ static inline VTKM_EXEC vtkm::UInt8 CellFaceShape(vtkm::IdComponent faceIndex,
}
}
template <typename CellShapeTag>
static inline VTKM_EXEC vtkm::IdComponent CellFaceLocalIndex(vtkm::IdComponent pointIndex,
vtkm::IdComponent faceIndex,
CellShapeTag shape,
const vtkm::exec::FunctorBase& worklet)
{
vtkm::IdComponent numPointsInFace = vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, worklet);
if (numPointsInFace < 1)
{
// An invalid face. We should already have gotten an error from
// CellFaceNumberOfPoints.
return -1;
}
detail::CellFaceTables table;
return table.PointsInFace(shape.Id, faceIndex, pointIndex);
}
/// \brief Returns a canonical identifier for a cell face
///
/// Given information about a cell face and the global point indices for that cell, returns a

@ -71,7 +71,8 @@ struct TestCellFacesFunctor
std::set<EdgeType> edgeSet;
for (vtkm::IdComponent edgeIndex = 0; edgeIndex < numEdges; edgeIndex++)
{
EdgeType edge = vtkm::exec::CellEdgeLocalIndices(numPoints, edgeIndex, shape, workletProxy);
EdgeType edge(vtkm::exec::CellEdgeLocalIndex(numPoints, 0, edgeIndex, shape, workletProxy),
vtkm::exec::CellEdgeLocalIndex(numPoints, 1, edgeIndex, shape, workletProxy));
VTKM_TEST_ASSERT(edge[0] >= 0, "Bad index in edge.");
VTKM_TEST_ASSERT(edge[0] < numPoints, "Bad index in edge.");
VTKM_TEST_ASSERT(edge[1] >= 0, "Bad index in edge.");
@ -94,7 +95,6 @@ struct TestCellFacesFunctor
std::set<EdgeType> edgesFoundInFaces;
for (vtkm::IdComponent faceIndex = 0; faceIndex < numFaces; faceIndex++)
{
vtkm::exec::detail::CellFaceTables table;
const vtkm::IdComponent numPointsInFace =
vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, workletProxy);
@ -102,20 +102,22 @@ struct TestCellFacesFunctor
for (vtkm::IdComponent pointIndex = 0; pointIndex < numPointsInFace; pointIndex++)
{
VTKM_TEST_ASSERT(table.PointsInFace(shape.Id, faceIndex, pointIndex) >= 0,
"Invalid point index for face.");
VTKM_TEST_ASSERT(table.PointsInFace(shape.Id, faceIndex, pointIndex) <= numPoints,
"Invalid point index for face.");
vtkm::IdComponent localFaceIndex =
vtkm::exec::CellFaceLocalIndex(pointIndex, faceIndex, shape, workletProxy);
VTKM_TEST_ASSERT(localFaceIndex >= 0, "Invalid point index for face.");
VTKM_TEST_ASSERT(localFaceIndex < numPoints, "Invalid point index for face.");
EdgeType edge;
if (pointIndex < numPointsInFace - 1)
{
edge = EdgeType(table.PointsInFace(shape.Id, faceIndex, pointIndex),
table.PointsInFace(shape.Id, faceIndex, pointIndex + 1));
edge = EdgeType(
vtkm::exec::CellFaceLocalIndex(pointIndex, faceIndex, shape, workletProxy),
vtkm::exec::CellFaceLocalIndex(pointIndex + 1, faceIndex, shape, workletProxy));
}
else
{
edge = EdgeType(table.PointsInFace(shape.Id, faceIndex, 0),
table.PointsInFace(shape.Id, faceIndex, pointIndex));
edge =
EdgeType(vtkm::exec::CellFaceLocalIndex(0, faceIndex, shape, workletProxy),
vtkm::exec::CellFaceLocalIndex(pointIndex, faceIndex, shape, workletProxy));
}
MakeEdgeCanonical(edge);
VTKM_TEST_ASSERT(edgeSet.find(edge) != edgeSet.end(), "Edge in face not in cell's edges");
@ -158,7 +160,8 @@ struct TestCellFacesFunctor
std::set<EdgeType> edgeSet;
for (vtkm::IdComponent edgeIndex = 0; edgeIndex < numEdges; edgeIndex++)
{
EdgeType edge = vtkm::exec::CellEdgeLocalIndices(numPoints, edgeIndex, shape, workletProxy);
EdgeType edge(vtkm::exec::CellEdgeLocalIndex(numPoints, 0, edgeIndex, shape, workletProxy),
vtkm::exec::CellEdgeLocalIndex(numPoints, 1, edgeIndex, shape, workletProxy));
VTKM_TEST_ASSERT(edge[0] >= 0, "Bad index in edge.");
VTKM_TEST_ASSERT(edge[0] < numPoints, "Bad index in edge.");
VTKM_TEST_ASSERT(edge[1] >= 0, "Bad index in edge.");

@ -199,10 +199,10 @@ struct EdgesExtracter : public vtkm::worklet::WorkletMapPointToCell
}
else
{
vtkm::Vec<vtkm::IdComponent, 2> localEdgeIndices = vtkm::exec::CellEdgeLocalIndices(
pointIndices.GetNumberOfComponents(), visitIndex, shape, *this);
p1 = pointIndices[localEdgeIndices[0]];
p2 = pointIndices[localEdgeIndices[1]];
p1 = pointIndices[vtkm::exec::CellEdgeLocalIndex(
pointIndices.GetNumberOfComponents(), 0, visitIndex, shape, *this)];
p2 = pointIndices[vtkm::exec::CellEdgeLocalIndex(
pointIndices.GetNumberOfComponents(), 1, visitIndex, shape, *this)];
}
// These indices need to be arranged in a definite order, as they will later be sorted to
// detect duplicates

@ -315,11 +315,10 @@ struct ExternalFaces
shapeOut = vtkm::CELL_SHAPE_QUAD;
numFacePointsOut = 4;
vtkm::exec::detail::CellFaceTables table;
for (vtkm::IdComponent facePointIndex = 0; facePointIndex < numFacePoints; facePointIndex++)
{
faceConnectivity[facePointIndex] =
inCellIndices[table.PointsInFace(shape.Id, faceIndex, facePointIndex)];
inCellIndices[vtkm::exec::CellFaceLocalIndex(facePointIndex, faceIndex, shape, *this)];
}
}
@ -619,11 +618,10 @@ public:
typename CellSetType::IndicesType inCellIndices = cellSet.GetIndices(originCells[myIndex]);
vtkm::exec::detail::CellFaceTables table;
for (vtkm::IdComponent facePointIndex = 0; facePointIndex < numFacePoints; facePointIndex++)
{
connectivityOut[facePointIndex] =
inCellIndices[table.PointsInFace(shapeIn.Id, myFace, facePointIndex)];
inCellIndices[vtkm::exec::CellFaceLocalIndex(facePointIndex, myFace, shapeIn, *this)];
}
}