mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Permuted structured cellsets produce VecRectilinearPointCoordinates
Previously when you permuted a structured cellset you would get a permuted point coordinates. This would cause the Cell operations to take non optimal paths.
This commit is contained in:
parent
6da48cf3c1
commit
6ed4bc786f
@ -167,6 +167,42 @@ struct FetchArrayTopologyMapInImplementation<
|
||||
}
|
||||
};
|
||||
|
||||
template<typename PermutationPortal, vtkm::IdComponent NumDimensions>
|
||||
struct FetchArrayTopologyMapInImplementation<
|
||||
vtkm::exec::ConnectivityPermuted<PermutationPortal,
|
||||
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell,
|
||||
NumDimensions> >,
|
||||
vtkm::internal::ArrayPortalUniformPointCoordinates>
|
||||
|
||||
{
|
||||
typedef vtkm::exec::ConnectivityPermuted<PermutationPortal,
|
||||
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell,
|
||||
NumDimensions> > ConnectivityType;
|
||||
typedef vtkm::exec::arg::ThreadIndicesTopologyMap<ConnectivityType>
|
||||
ThreadIndicesType;
|
||||
|
||||
typedef vtkm::VecRectilinearPointCoordinates<NumDimensions> ValueType;
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC
|
||||
static ValueType Load(
|
||||
const ThreadIndicesType &indices,
|
||||
const vtkm::internal::ArrayPortalUniformPointCoordinates &field)
|
||||
{
|
||||
// This works because the logical cell index is the same as the logical
|
||||
// point index of the first point on the cell.
|
||||
|
||||
// we have a flat index but we need 3d rectilinear coordiantes, so we
|
||||
// need to take an flat index and convert to logical index
|
||||
return vtkm::exec::arg::detail::make_VecRectilinearPointCoordinates(
|
||||
field.GetOrigin(),
|
||||
field.GetSpacing(),
|
||||
indices.GetIndexLogical());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename ConnectivityType, typename ExecObjectType>
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <vtkm/exec/arg/ThreadIndicesBasic.h>
|
||||
|
||||
#include <vtkm/exec/ConnectivityStructured.h>
|
||||
#include <vtkm/exec/ConnectivityPermuted.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace exec {
|
||||
@ -69,18 +70,18 @@ class ThreadIndicesTopologyMap : public vtkm::exec::arg::ThreadIndicesBasic
|
||||
typedef vtkm::exec::arg::ThreadIndicesBasic Superclass;
|
||||
|
||||
public:
|
||||
typedef typename ConnectivityType::IndicesType IndicesFromType;
|
||||
typedef typename ConnectivityType::CellShapeTag CellShapeTag;
|
||||
using IndicesFromType = typename ConnectivityType::IndicesType;
|
||||
using CellShapeTag = typename ConnectivityType::CellShapeTag;
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
template<typename OutToInArrayType, typename VisitArrayType>
|
||||
VTKM_EXEC
|
||||
ThreadIndicesTopologyMap(vtkm::Id threadIndex,
|
||||
const OutToInArrayType& inToOut,
|
||||
const OutToInArrayType& outToIn,
|
||||
const VisitArrayType& visit,
|
||||
const ConnectivityType& connectivity,
|
||||
vtkm::Id globalThreadIndexOffset=0)
|
||||
: Superclass(threadIndex, inToOut.Get(threadIndex), visit.Get(threadIndex),
|
||||
: Superclass(threadIndex, outToIn.Get(threadIndex), visit.Get(threadIndex),
|
||||
globalThreadIndexOffset),
|
||||
CellShape(detail::CellShapeInitializer<CellShapeTag>::GetDefault())
|
||||
{
|
||||
@ -197,25 +198,23 @@ template<typename FromTopology,
|
||||
class ThreadIndicesTopologyMap<
|
||||
vtkm::exec::ConnectivityStructured<FromTopology,ToTopology,Dimension> >
|
||||
{
|
||||
typedef vtkm::exec::arg::ThreadIndicesBasic Superclass;
|
||||
typedef vtkm::exec::ConnectivityStructured<FromTopology,ToTopology,Dimension>
|
||||
ConnectivityType;
|
||||
using ConnectivityType = vtkm::exec::ConnectivityStructured<FromTopology,ToTopology,Dimension>;
|
||||
|
||||
public:
|
||||
typedef typename ConnectivityType::IndicesType IndicesFromType;
|
||||
typedef typename ConnectivityType::CellShapeTag CellShapeTag;
|
||||
typedef typename ConnectivityType::SchedulingRangeType LogicalIndexType;
|
||||
using IndicesFromType = typename ConnectivityType::IndicesType;
|
||||
using CellShapeTag = typename ConnectivityType::CellShapeTag;
|
||||
using LogicalIndexType = typename ConnectivityType::SchedulingRangeType;
|
||||
|
||||
template<typename OutToInArrayType, typename VisitArrayType>
|
||||
VTKM_EXEC
|
||||
ThreadIndicesTopologyMap(vtkm::Id threadIndex,
|
||||
const OutToInArrayType& inToOut,
|
||||
const OutToInArrayType& outToIn,
|
||||
const VisitArrayType& visit,
|
||||
const ConnectivityType& connectivity,
|
||||
vtkm::Id globalThreadIndexOffset=0)
|
||||
{
|
||||
|
||||
this->InputIndex = inToOut.Get(threadIndex);
|
||||
this->InputIndex = outToIn.Get(threadIndex);
|
||||
this->OutputIndex = threadIndex;
|
||||
this->VisitIndex = visit.Get(threadIndex);
|
||||
this->LogicalIndex = connectivity.FlatToLogicalToIndex(this->InputIndex);
|
||||
@ -373,6 +372,178 @@ private:
|
||||
vtkm::Id GlobalThreadIndexOffset;
|
||||
};
|
||||
|
||||
// Specialization for permuted structured connectivity types.
|
||||
template<typename PermutationPortal,
|
||||
typename FromTopology,
|
||||
typename ToTopology,
|
||||
vtkm::IdComponent Dimension>
|
||||
class ThreadIndicesTopologyMap<
|
||||
vtkm::exec::ConnectivityPermuted<PermutationPortal,
|
||||
vtkm::exec::ConnectivityStructured<FromTopology,ToTopology,Dimension> >
|
||||
>
|
||||
{
|
||||
using PermutedConnectivityType =
|
||||
vtkm::exec::ConnectivityPermuted<PermutationPortal,
|
||||
vtkm::exec::ConnectivityStructured<FromTopology,
|
||||
ToTopology,
|
||||
Dimension>
|
||||
>;
|
||||
using ConnectivityType = vtkm::exec::ConnectivityStructured<FromTopology,
|
||||
ToTopology,
|
||||
Dimension
|
||||
>;
|
||||
|
||||
public:
|
||||
using IndicesFromType = typename ConnectivityType::IndicesType;
|
||||
using CellShapeTag = typename ConnectivityType::CellShapeTag;
|
||||
using LogicalIndexType = typename ConnectivityType::SchedulingRangeType;
|
||||
|
||||
template<typename OutToInArrayType, typename VisitArrayType>
|
||||
VTKM_EXEC
|
||||
ThreadIndicesTopologyMap(vtkm::Id threadIndex,
|
||||
const OutToInArrayType& outToIn,
|
||||
const VisitArrayType& visit,
|
||||
const PermutedConnectivityType& permutation,
|
||||
vtkm::Id globalThreadIndexOffset=0)
|
||||
{
|
||||
this->InputIndex = outToIn.Get( threadIndex );
|
||||
this->OutputIndex = threadIndex;
|
||||
this->VisitIndex = visit.Get(threadIndex);
|
||||
|
||||
const vtkm::Id permutedIndex = permutation.Portal.Get( this->InputIndex );
|
||||
this->LogicalIndex = permutation.Connectivity.FlatToLogicalToIndex(permutedIndex);
|
||||
this->IndicesFrom = permutation.Connectivity.GetIndices(this->LogicalIndex);
|
||||
this->CellShape = permutation.Connectivity.GetCellShape(permutedIndex);
|
||||
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC
|
||||
ThreadIndicesTopologyMap(vtkm::Id threadIndex,
|
||||
vtkm::Id vtkmNotUsed(inIndex),
|
||||
vtkm::IdComponent visitIndex,
|
||||
const PermutedConnectivityType& permutation,
|
||||
vtkm::Id globalThreadIndexOffset=0)
|
||||
{
|
||||
this->InputIndex = threadIndex;
|
||||
this->OutputIndex = threadIndex;
|
||||
this->VisitIndex = visitIndex;
|
||||
|
||||
const vtkm::Id permutedIndex = permutation.Portal.Get( this->InputIndex );
|
||||
this->LogicalIndex = permutation.Connectivity.FlatToLogicalToIndex(permutedIndex);
|
||||
this->IndicesFrom = permutation.Connectivity.GetIndices(this->LogicalIndex);
|
||||
this->CellShape = permutation.Connectivity.GetCellShape(permutedIndex);
|
||||
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||
}
|
||||
|
||||
/// \brief The logical index into the input domain.
|
||||
///
|
||||
/// This is similar to \c GetIndex3D except the Vec size matches the actual
|
||||
/// dimensions of the data.
|
||||
///
|
||||
VTKM_EXEC
|
||||
LogicalIndexType GetIndexLogical() const
|
||||
{
|
||||
return this->LogicalIndex;
|
||||
}
|
||||
|
||||
/// \brief The index into the input domain.
|
||||
///
|
||||
/// This index refers to the input element (array value, cell, etc.) that
|
||||
/// this thread is being invoked for. This is the typical index used during
|
||||
/// fetches.
|
||||
///
|
||||
VTKM_EXEC
|
||||
vtkm::Id GetInputIndex() const
|
||||
{
|
||||
return this->InputIndex;
|
||||
}
|
||||
|
||||
/// \brief The 3D index into the input domain.
|
||||
///
|
||||
/// Overloads the implementation in the base class to return the 3D index
|
||||
/// for the input.
|
||||
///
|
||||
VTKM_EXEC
|
||||
vtkm::Id3 GetInputIndex3D() const
|
||||
{
|
||||
return detail::InflateTo3D(this->GetIndexLogical());
|
||||
}
|
||||
|
||||
/// \brief The index into the output domain.
|
||||
///
|
||||
/// This index refers to the output element (array value, cell, etc.) that
|
||||
/// this thread is creating. This is the typical index used during
|
||||
/// Fetch::Store.
|
||||
///
|
||||
VTKM_EXEC
|
||||
vtkm::Id GetOutputIndex() const
|
||||
{
|
||||
return this->OutputIndex;
|
||||
}
|
||||
|
||||
/// \brief The visit index.
|
||||
///
|
||||
/// When multiple output indices have the same input index, they are
|
||||
/// distinguished using the visit index.
|
||||
///
|
||||
VTKM_EXEC
|
||||
vtkm::IdComponent GetVisitIndex() const
|
||||
{
|
||||
return this->VisitIndex;
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
vtkm::Id GetGlobalIndex() const
|
||||
{
|
||||
return (this->GlobalThreadIndexOffset + this->OutputIndex);
|
||||
}
|
||||
|
||||
/// \brief The input indices of the "from" elements.
|
||||
///
|
||||
/// A topology map has "from" and "to" elements (for example from points to
|
||||
/// cells). For each worklet invocation, there is exactly one "to" element,
|
||||
/// but can be several "from" element. This method returns a Vec-like object
|
||||
/// containing the indices to the "from" elements.
|
||||
///
|
||||
VTKM_EXEC
|
||||
const IndicesFromType &GetIndicesFrom() const { return this->IndicesFrom; }
|
||||
|
||||
/// \brief The input indices of the "from" elements in pointer form.
|
||||
///
|
||||
/// Returns the same object as GetIndicesFrom except that it returns a
|
||||
/// pointer to the internally held object rather than a reference or copy.
|
||||
/// Since the from indices can be a sizeable Vec (8 entries is common), it is
|
||||
/// best not to have a bunch a copies. Thus, you can pass around a pointer
|
||||
/// instead. However, care should be taken to make sure that this object does
|
||||
/// not go out of scope, at which time the returned pointer becomes invalid.
|
||||
///
|
||||
VTKM_EXEC
|
||||
const IndicesFromType *GetIndicesFromPointer() const
|
||||
{
|
||||
return &this->IndicesFrom;
|
||||
}
|
||||
|
||||
/// \brief The shape of the input cell.
|
||||
///
|
||||
/// In topology maps that map from points to something, the indices make up
|
||||
/// the structure of a cell. Although the shape tag is not technically and
|
||||
/// index, it defines the meaning of the indices, so we put it here. (That
|
||||
/// and this class is the only convenient place to store it.)
|
||||
///
|
||||
VTKM_EXEC
|
||||
CellShapeTag GetCellShape() const { return this->CellShape; }
|
||||
|
||||
private:
|
||||
vtkm::Id InputIndex;
|
||||
vtkm::Id OutputIndex;
|
||||
vtkm::IdComponent VisitIndex;
|
||||
LogicalIndexType LogicalIndex;
|
||||
IndicesFromType IndicesFrom;
|
||||
CellShapeTag CellShape;
|
||||
vtkm::Id GlobalThreadIndexOffset;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::exec::arg
|
||||
|
Loading…
Reference in New Issue
Block a user