mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Implement CellToPoint for CellSetPermutation
This commit is contained in:
parent
46aa74519a
commit
6ce8218d09
@ -22,30 +22,157 @@
|
|||||||
|
|
||||||
#include <vtkm/CellShape.h>
|
#include <vtkm/CellShape.h>
|
||||||
#include <vtkm/CellTraits.h>
|
#include <vtkm/CellTraits.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleCast.h>
|
||||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
#include <vtkm/cont/ArrayHandlePermutation.h>
|
||||||
#include <vtkm/cont/CellSet.h>
|
#include <vtkm/cont/CellSet.h>
|
||||||
|
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
|
||||||
|
#include <vtkm/internal/ConnectivityStructuredInternals.h>
|
||||||
|
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||||
|
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||||
|
|
||||||
#include <vtkm/exec/ConnectivityPermuted.h>
|
#include <vtkm/exec/ConnectivityPermuted.h>
|
||||||
|
|
||||||
|
#ifndef VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG
|
||||||
|
#define VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
namespace cont
|
namespace cont
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename OriginalCellSet, typename ValidCellArrayHandleType>
|
|
||||||
class CellSetPermutation;
|
|
||||||
|
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename OriginalCellSet, typename PermutationArrayHandleType>
|
struct WriteConnectivity : public vtkm::worklet::WorkletMapPointToCell
|
||||||
class CellSetGeneralPermutation : public CellSet
|
{
|
||||||
|
typedef void ControlSignature(CellSetIn cellset,
|
||||||
|
FieldInCell<IdType> offset,
|
||||||
|
WholeArrayOut<> connectivity);
|
||||||
|
typedef void ExecutionSignature(PointCount, PointIndices, _2, _3);
|
||||||
|
typedef _1 InputDomain;
|
||||||
|
|
||||||
|
template <typename PointIndicesType, typename OutPortalType>
|
||||||
|
VTKM_EXEC void operator()(vtkm::IdComponent pointcount,
|
||||||
|
const PointIndicesType& pointIndices,
|
||||||
|
vtkm::Id offset,
|
||||||
|
OutPortalType& connectivity) const
|
||||||
|
{
|
||||||
|
for (vtkm::IdComponent i = 0; i < pointcount; ++i)
|
||||||
|
{
|
||||||
|
connectivity.Set(offset++, pointIndices[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// default for CellSetExplicit and CellSetSingleType
|
||||||
|
template <typename CellSetPermutationType>
|
||||||
|
class PointToCell
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using NumIndicesArrayType = decltype(make_ArrayHandlePermutation(
|
||||||
|
std::declval<CellSetPermutationType>().GetValidCellIds(),
|
||||||
|
std::declval<CellSetPermutationType>().GetFullCellSet().GetNumIndicesArray(
|
||||||
|
vtkm::TopologyElementTagPoint(),
|
||||||
|
vtkm::TopologyElementTagCell())));
|
||||||
|
|
||||||
|
public:
|
||||||
|
using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<
|
||||||
|
VTKM_DEFAULT_STORAGE_TAG, // dummy, shapes array is not used
|
||||||
|
typename NumIndicesArrayType::StorageTag>;
|
||||||
|
|
||||||
|
template <typename Device>
|
||||||
|
static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
|
||||||
|
{
|
||||||
|
ConnectivityArrays conn;
|
||||||
|
conn.NumIndices =
|
||||||
|
NumIndicesArrayType(cellset.GetValidCellIds(),
|
||||||
|
cellset.GetFullCellSet().GetNumIndicesArray(
|
||||||
|
vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell()));
|
||||||
|
vtkm::Id connectivityLength = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(
|
||||||
|
vtkm::cont::make_ArrayHandleCast(conn.NumIndices, vtkm::Id()), conn.IndexOffsets);
|
||||||
|
conn.Connectivity.Allocate(connectivityLength);
|
||||||
|
vtkm::worklet::DispatcherMapTopology<WriteConnectivity, Device>().Invoke(
|
||||||
|
cellset, conn.IndexOffsets, conn.Connectivity);
|
||||||
|
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// specialization for CellSetStructured
|
||||||
|
template <vtkm::IdComponent DIMENSION, typename PermutationArrayHandleType>
|
||||||
|
class PointToCell<CellSetPermutation<CellSetStructured<DIMENSION>, PermutationArrayHandleType>>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using CellSetPermutationType =
|
||||||
|
CellSetPermutation<CellSetStructured<DIMENSION>, PermutationArrayHandleType>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<
|
||||||
|
VTKM_DEFAULT_STORAGE_TAG, // dummy, shapes array is not used
|
||||||
|
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
|
||||||
|
VTKM_DEFAULT_STORAGE_TAG,
|
||||||
|
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
|
||||||
|
|
||||||
|
template <typename Device>
|
||||||
|
static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
|
||||||
|
{
|
||||||
|
vtkm::Id numberOfCells = cellset.GetNumberOfCells();
|
||||||
|
vtkm::IdComponent numPointsInCell =
|
||||||
|
vtkm::internal::ConnectivityStructuredInternals<DIMENSION>::NUM_POINTS_IN_CELL;
|
||||||
|
vtkm::Id connectivityLength = numberOfCells * numPointsInCell;
|
||||||
|
|
||||||
|
ConnectivityArrays conn;
|
||||||
|
conn.NumIndices = make_ArrayHandleConstant(numPointsInCell, numberOfCells);
|
||||||
|
conn.IndexOffsets = ArrayHandleCounting<vtkm::Id>(0, numPointsInCell, numberOfCells);
|
||||||
|
conn.Connectivity.Allocate(connectivityLength);
|
||||||
|
vtkm::worklet::DispatcherMapTopology<WriteConnectivity, Device>().Invoke(
|
||||||
|
cellset, conn.IndexOffsets, conn.Connectivity);
|
||||||
|
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename CellSetPermutationType>
|
||||||
|
struct CellSetPermutationTraits;
|
||||||
|
|
||||||
|
template <typename OriginalCellSet_, typename PermutationArrayHandleType_>
|
||||||
|
struct CellSetPermutationTraits<CellSetPermutation<OriginalCellSet_, PermutationArrayHandleType_>>
|
||||||
|
{
|
||||||
|
using OriginalCellSet = OriginalCellSet_;
|
||||||
|
using PermutationArrayHandleType = PermutationArrayHandleType_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename OriginalCellSet_,
|
||||||
|
typename OriginalPermutationArrayHandleType,
|
||||||
|
typename PermutationArrayHandleType_>
|
||||||
|
struct CellSetPermutationTraits<
|
||||||
|
CellSetPermutation<CellSetPermutation<OriginalCellSet_, OriginalPermutationArrayHandleType>,
|
||||||
|
PermutationArrayHandleType_>>
|
||||||
|
{
|
||||||
|
using PreviousCellSet = CellSetPermutation<OriginalCellSet_, OriginalPermutationArrayHandleType>;
|
||||||
|
using PermutationArrayHandleType = vtkm::cont::ArrayHandlePermutation<
|
||||||
|
PermutationArrayHandleType_,
|
||||||
|
typename CellSetPermutationTraits<PreviousCellSet>::PermutationArrayHandleType>;
|
||||||
|
using OriginalCellSet = typename CellSetPermutationTraits<PreviousCellSet>::OriginalCellSet;
|
||||||
|
using Superclass = CellSetPermutation<OriginalCellSet, PermutationArrayHandleType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // internal
|
||||||
|
|
||||||
|
template <typename OriginalCellSetType_,
|
||||||
|
typename PermutationArrayHandleType_ =
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id, VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG>>
|
||||||
|
class CellSetPermutation : public CellSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using OriginalCellSetType = OriginalCellSetType_;
|
||||||
|
using PermutationArrayHandleType = PermutationArrayHandleType_;
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
CellSetGeneralPermutation(const PermutationArrayHandleType& validCellIds,
|
CellSetPermutation(const PermutationArrayHandleType& validCellIds,
|
||||||
const OriginalCellSet& cellset,
|
const OriginalCellSetType& cellset,
|
||||||
const std::string& name)
|
const std::string& name = std::string())
|
||||||
: CellSet(name)
|
: CellSet(name)
|
||||||
, ValidCellIds(validCellIds)
|
, ValidCellIds(validCellIds)
|
||||||
, FullCellSet(cellset)
|
, FullCellSet(cellset)
|
||||||
@ -53,7 +180,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
CellSetGeneralPermutation(const std::string& name)
|
CellSetPermutation(const std::string& name = std::string())
|
||||||
: CellSet(name)
|
: CellSet(name)
|
||||||
, ValidCellIds()
|
, ValidCellIds()
|
||||||
, FullCellSet()
|
, FullCellSet()
|
||||||
@ -61,130 +188,174 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
vtkm::Id GetNumberOfCells() const VTKM_OVERRIDE { return this->ValidCellIds.GetNumberOfValues(); }
|
const OriginalCellSetType& GetFullCellSet() const { return this->FullCellSet; }
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
vtkm::Id GetNumberOfPoints() const VTKM_OVERRIDE { return this->FullCellSet.GetNumberOfPoints(); }
|
const PermutationArrayHandleType& GetValidCellIds() const { return this->ValidCellIds; }
|
||||||
|
|
||||||
vtkm::Id GetNumberOfFaces() const VTKM_OVERRIDE { return -1; }
|
VTKM_CONT
|
||||||
|
vtkm::Id GetNumberOfCells() const override { return this->ValidCellIds.GetNumberOfValues(); }
|
||||||
|
|
||||||
vtkm::Id GetNumberOfEdges() const VTKM_OVERRIDE { return -1; }
|
VTKM_CONT
|
||||||
|
vtkm::Id GetNumberOfPoints() const override { return this->FullCellSet.GetNumberOfPoints(); }
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
vtkm::Id GetNumberOfFaces() const override { return -1; }
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
vtkm::Id GetNumberOfEdges() const override { return -1; }
|
||||||
|
|
||||||
|
VTKM_CONT
|
||||||
|
vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellIndex) const
|
||||||
|
{
|
||||||
|
return this->FullCellSet.GetNumberOfPointsInCell(
|
||||||
|
this->ValidCellIds.GetPortalConstControl().Get(cellIndex));
|
||||||
|
}
|
||||||
|
|
||||||
//This is the way you can fill the memory from another system without copying
|
//This is the way you can fill the memory from another system without copying
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
void Fill(const PermutationArrayHandleType& validCellIds, const OriginalCellSet& cellset)
|
void Fill(const PermutationArrayHandleType& validCellIds, const OriginalCellSetType& cellset)
|
||||||
{
|
{
|
||||||
ValidCellIds = validCellIds;
|
this->ValidCellIds = validCellIds;
|
||||||
FullCellSet = cellset;
|
this->FullCellSet = cellset;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TopologyElement>
|
VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagCell) const
|
||||||
VTKM_CONT vtkm::Id GetSchedulingRange(TopologyElement) const
|
|
||||||
{
|
{
|
||||||
VTKM_IS_TOPOLOGY_ELEMENT_TAG(TopologyElement);
|
|
||||||
return this->ValidCellIds.GetNumberOfValues();
|
return this->ValidCellIds.GetNumberOfValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagPoint) const
|
||||||
|
{
|
||||||
|
return this->FullCellSet.GetNumberOfPoints();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Device, typename FromTopology, typename ToTopology>
|
template <typename Device, typename FromTopology, typename ToTopology>
|
||||||
struct ExecutionTypes
|
struct ExecutionTypes;
|
||||||
|
|
||||||
|
template <typename Device>
|
||||||
|
struct ExecutionTypes<Device, vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell>
|
||||||
{
|
{
|
||||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||||
VTKM_IS_TOPOLOGY_ELEMENT_TAG(FromTopology);
|
|
||||||
VTKM_IS_TOPOLOGY_ELEMENT_TAG(ToTopology);
|
|
||||||
|
|
||||||
typedef typename PermutationArrayHandleType::template ExecutionTypes<Device>::PortalConst
|
using ExecPortalType =
|
||||||
ExecPortalType;
|
typename PermutationArrayHandleType::template ExecutionTypes<Device>::PortalConst;
|
||||||
|
using OrigExecObjectType = typename OriginalCellSetType::template ExecutionTypes<
|
||||||
|
Device,
|
||||||
|
vtkm::TopologyElementTagPoint,
|
||||||
|
vtkm::TopologyElementTagCell>::ExecObjectType;
|
||||||
|
|
||||||
typedef typename OriginalCellSet::template ExecutionTypes<Device, FromTopology, ToTopology>::
|
using ExecObjectType =
|
||||||
ExecObjectType OrigExecObjectType;
|
vtkm::exec::ConnectivityPermutedPointToCell<ExecPortalType, OrigExecObjectType>;
|
||||||
|
|
||||||
typedef vtkm::exec::ConnectivityPermuted<ExecPortalType, OrigExecObjectType> ExecObjectType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Device, typename FromTopology, typename ToTopology>
|
template <typename Device>
|
||||||
typename ExecutionTypes<Device, FromTopology, ToTopology>::ExecObjectType
|
struct ExecutionTypes<Device, vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint>
|
||||||
PrepareForInput(Device, FromTopology, ToTopology) const
|
|
||||||
{
|
{
|
||||||
// Developer's note: I looked into supporting cell to point connectivity in a permutation cell
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||||
// set and found it to be complex. It is not straightforward to implement this on top of the
|
|
||||||
// original cell set's cell to point because points could be attached to cells that do not
|
using ConnectiviyPortalType =
|
||||||
// exist in the permuted topology. Ultimately, you will probably have to rebuild these
|
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;
|
||||||
// connections in a way very similar to how CellSetExplicit already does it. In fact, the
|
using NumIndicesPortalType = typename vtkm::cont::ArrayHandle<
|
||||||
// easiest implementation will probably be to just convert to a CellSetExplicit and use that.
|
vtkm::IdComponent>::template ExecutionTypes<Device>::PortalConst;
|
||||||
// In fact, it may be possible to change this whole implementation to just be a subclass of
|
using IndexOffsetPortalType =
|
||||||
// CellSetExplicit with some fancy arrays for its point to cell arrays.
|
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;
|
||||||
throw vtkm::cont::ErrorBadType(
|
|
||||||
"CellSetPermutation currently only supports point to cell connectivity. "
|
using ExecObjectType = vtkm::exec::ConnectivityPermutedCellToPoint<ConnectiviyPortalType,
|
||||||
"To support other connectivity, convert to an explicit grid with the CellDeepCopy "
|
NumIndicesPortalType,
|
||||||
"worklet or the CleanGrid filter.");
|
IndexOffsetPortalType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Device>
|
||||||
|
VTKM_CONT typename ExecutionTypes<Device,
|
||||||
|
vtkm::TopologyElementTagPoint,
|
||||||
|
vtkm::TopologyElementTagCell>::ExecObjectType
|
||||||
|
PrepareForInput(Device device,
|
||||||
|
vtkm::TopologyElementTagPoint from,
|
||||||
|
vtkm::TopologyElementTagCell to) const
|
||||||
|
{
|
||||||
|
using ConnectivityType = typename ExecutionTypes<Device,
|
||||||
|
vtkm::TopologyElementTagPoint,
|
||||||
|
vtkm::TopologyElementTagCell>::ExecObjectType;
|
||||||
|
return ConnectivityType(this->ValidCellIds.PrepareForInput(device),
|
||||||
|
this->FullCellSet.PrepareForInput(device, from, to));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Device>
|
template <typename Device>
|
||||||
typename ExecutionTypes<Device,
|
VTKM_CONT typename ExecutionTypes<Device,
|
||||||
vtkm::TopologyElementTagPoint,
|
vtkm::TopologyElementTagCell,
|
||||||
vtkm::TopologyElementTagCell>::ExecObjectType
|
vtkm::TopologyElementTagPoint>::ExecObjectType
|
||||||
PrepareForInput(Device d, vtkm::TopologyElementTagPoint f, vtkm::TopologyElementTagCell t) const
|
PrepareForInput(Device device, vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) const
|
||||||
{
|
{
|
||||||
using FromTopology = vtkm::TopologyElementTagPoint;
|
if (!this->CellToPoint.ElementsValid)
|
||||||
using ToTopology = vtkm::TopologyElementTagCell;
|
{
|
||||||
using ConnectivityType =
|
auto pointToCell = internal::PointToCell<CellSetPermutation>::Get(*this, device);
|
||||||
typename ExecutionTypes<Device, FromTopology, ToTopology>::ExecObjectType;
|
internal::ComputeCellToPointConnectivity(
|
||||||
return ConnectivityType(this->ValidCellIds.PrepareForInput(d),
|
this->CellToPoint, pointToCell, this->GetNumberOfPoints(), device);
|
||||||
this->FullCellSet.PrepareForInput(d, f, t));
|
this->CellToPoint.BuildIndexOffsets(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
using ConnectivityType = typename ExecutionTypes<Device,
|
||||||
|
vtkm::TopologyElementTagCell,
|
||||||
|
vtkm::TopologyElementTagPoint>::ExecObjectType;
|
||||||
|
return ConnectivityType(this->CellToPoint.Connectivity.PrepareForInput(device),
|
||||||
|
this->CellToPoint.NumIndices.PrepareForInput(device),
|
||||||
|
this->CellToPoint.IndexOffsets.PrepareForInput(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintSummary(std::ostream& out) const VTKM_OVERRIDE
|
VTKM_CONT
|
||||||
|
void PrintSummary(std::ostream& out) const override
|
||||||
{
|
{
|
||||||
out << " CellSetGeneralPermutation of: " << std::endl;
|
out << "CellSetPermutation of: " << std::endl;
|
||||||
this->FullCellSet.PrintSummary(out);
|
this->FullCellSet.PrintSummary(out);
|
||||||
|
out << "Permutation Array: " << std::endl;
|
||||||
|
vtkm::cont::printSummary_ArrayHandle(this->ValidCellIds, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using CellToPointConnectivity = vtkm::cont::internal::ConnectivityExplicitInternals<
|
||||||
|
typename ArrayHandleConstant<vtkm::UInt8>::StorageTag>;
|
||||||
|
|
||||||
PermutationArrayHandleType ValidCellIds;
|
PermutationArrayHandleType ValidCellIds;
|
||||||
OriginalCellSet FullCellSet;
|
OriginalCellSetType FullCellSet;
|
||||||
|
mutable CellToPointConnectivity CellToPoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace internal
|
template <typename CellSetType,
|
||||||
|
typename PermutationArrayHandleType1,
|
||||||
#ifndef VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG
|
typename PermutationArrayHandleType2>
|
||||||
#define VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
|
class CellSetPermutation<CellSetPermutation<CellSetType, PermutationArrayHandleType1>,
|
||||||
#endif
|
PermutationArrayHandleType2>
|
||||||
|
: public internal::CellSetPermutationTraits<
|
||||||
template <typename OriginalCellSet,
|
CellSetPermutation<CellSetPermutation<CellSetType, PermutationArrayHandleType1>,
|
||||||
typename PermutationArrayHandleType =
|
PermutationArrayHandleType2>>::Superclass
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id, VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG>>
|
|
||||||
class CellSetPermutation
|
|
||||||
: public vtkm::cont::internal::CellSetGeneralPermutation<OriginalCellSet,
|
|
||||||
PermutationArrayHandleType>
|
|
||||||
{
|
{
|
||||||
VTKM_IS_CELL_SET(OriginalCellSet);
|
private:
|
||||||
VTKM_IS_ARRAY_HANDLE(PermutationArrayHandleType);
|
using Superclass = typename internal::CellSetPermutationTraits<CellSetPermutation>::Superclass;
|
||||||
|
|
||||||
typedef typename vtkm::cont::internal::CellSetGeneralPermutation<OriginalCellSet,
|
|
||||||
PermutationArrayHandleType>
|
|
||||||
ParentType;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
CellSetPermutation(const PermutationArrayHandleType& validCellIds,
|
CellSetPermutation(const PermutationArrayHandleType2& validCellIds,
|
||||||
const OriginalCellSet& cellset,
|
const CellSetPermutation<CellSetType, PermutationArrayHandleType1>& cellset,
|
||||||
const std::string& name = std::string())
|
const std::string& name = std::string())
|
||||||
: ParentType(validCellIds, cellset, name)
|
: Superclass(vtkm::cont::make_ArrayHandlePermutation(validCellIds, cellset.GetValidCellIds()),
|
||||||
|
cellset.GetFullCellSet(),
|
||||||
|
name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
CellSetPermutation(const std::string& name = std::string())
|
CellSetPermutation(const std::string& name = std::string())
|
||||||
: ParentType(name)
|
: Superclass(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
CellSetPermutation<OriginalCellSet, PermutationArrayHandleType>& operator=(
|
void Fill(const PermutationArrayHandleType2& validCellIds,
|
||||||
const CellSetPermutation<OriginalCellSet, PermutationArrayHandleType>& src)
|
const CellSetPermutation<CellSetType, PermutationArrayHandleType1>& cellset)
|
||||||
{
|
{
|
||||||
ParentType::operator=(src);
|
this->ValidCellIds = make_ArrayHandlePermutation(validCellIds, cellset.GetValidCellIds());
|
||||||
return *this;
|
this->FullCellSet = cellset.GetFullCellSet();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ set(unit_tests
|
|||||||
UnitTestArrayHandleConcatenate.cxx
|
UnitTestArrayHandleConcatenate.cxx
|
||||||
UnitTestArrayPortalToIterators.cxx
|
UnitTestArrayPortalToIterators.cxx
|
||||||
UnitTestCellSetExplicit.cxx
|
UnitTestCellSetExplicit.cxx
|
||||||
|
UnitTestCellSetPermutation.cxx
|
||||||
UnitTestContTesting.cxx
|
UnitTestContTesting.cxx
|
||||||
UnitTestDataSetBuilderExplicit.cxx
|
UnitTestDataSetBuilderExplicit.cxx
|
||||||
UnitTestDataSetBuilderRectilinear.cxx
|
UnitTestDataSetBuilderRectilinear.cxx
|
||||||
|
195
vtkm/cont/testing/UnitTestCellSetPermutation.cxx
Normal file
195
vtkm/cont/testing/UnitTestCellSetPermutation.cxx
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
//============================================================================
|
||||||
|
// Copyright (c) Kitware, Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
// See LICENSE.txt for details.
|
||||||
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
|
//
|
||||||
|
// Copyright 2017 Sandia Corporation.
|
||||||
|
// Copyright 2017 UT-Battelle, LLC.
|
||||||
|
// Copyright 2017 Los Alamos National Security.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// the U.S. Government retains certain rights in this software.
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||||
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||||
|
// this software.
|
||||||
|
//============================================================================
|
||||||
|
#include <vtkm/cont/CellSetPermutation.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||||
|
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||||
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||||
|
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct WorkletPointToCell : public vtkm::worklet::WorkletMapPointToCell
|
||||||
|
{
|
||||||
|
typedef void ControlSignature(CellSetIn cellset, FieldOutCell<IdType> numPoints);
|
||||||
|
typedef void ExecutionSignature(PointIndices, _2);
|
||||||
|
using InputDomain = _1;
|
||||||
|
|
||||||
|
template <typename PointIndicesType>
|
||||||
|
VTKM_EXEC void operator()(const PointIndicesType& pointIndices, vtkm::Id& numPoints) const
|
||||||
|
{
|
||||||
|
numPoints = pointIndices.GetNumberOfComponents();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WorkletCellToPoint : public vtkm::worklet::WorkletMapCellToPoint
|
||||||
|
{
|
||||||
|
typedef void ControlSignature(CellSetIn cellset, FieldOutPoint<IdType> numCells);
|
||||||
|
typedef void ExecutionSignature(CellIndices, _2);
|
||||||
|
using InputDomain = _1;
|
||||||
|
|
||||||
|
template <typename CellIndicesType>
|
||||||
|
VTKM_EXEC void operator()(const CellIndicesType& cellIndices, vtkm::Id& numCells) const
|
||||||
|
{
|
||||||
|
numCells = cellIndices.GetNumberOfComponents();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellsOfPoint : public vtkm::worklet::WorkletMapCellToPoint
|
||||||
|
{
|
||||||
|
typedef void ControlSignature(CellSetIn cellset,
|
||||||
|
FieldInPoint<IdType> offset,
|
||||||
|
WholeArrayOut<IdType> cellIds);
|
||||||
|
typedef void ExecutionSignature(CellIndices, _2, _3);
|
||||||
|
using InputDomain = _1;
|
||||||
|
|
||||||
|
template <typename CellIndicesType, typename CellIdsPortal>
|
||||||
|
VTKM_EXEC void operator()(const CellIndicesType& cellIndices,
|
||||||
|
vtkm::Id offset,
|
||||||
|
const CellIdsPortal& out) const
|
||||||
|
{
|
||||||
|
vtkm::IdComponent count = cellIndices.GetNumberOfComponents();
|
||||||
|
for (vtkm::IdComponent i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
out.Set(offset++, cellIndices[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename CellSetType, typename PermutationArrayHandleType>
|
||||||
|
std::vector<vtkm::Id> ComputeCellToPointExpected(const CellSetType& cellset,
|
||||||
|
const PermutationArrayHandleType& permutation)
|
||||||
|
{
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> numIndices;
|
||||||
|
vtkm::worklet::DispatcherMapTopology<WorkletCellToPoint>().Invoke(cellset, numIndices);
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> indexOffsets;
|
||||||
|
vtkm::Id connectivityLength =
|
||||||
|
vtkm::cont::DeviceAdapterAlgorithm<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::ScanExclusive(
|
||||||
|
numIndices, indexOffsets);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
|
||||||
|
connectivity.Allocate(connectivityLength);
|
||||||
|
vtkm::worklet::DispatcherMapTopology<CellsOfPoint>().Invoke(cellset, indexOffsets, connectivity);
|
||||||
|
|
||||||
|
std::vector<bool> permutationMask(static_cast<std::size_t>(cellset.GetNumberOfCells()), false);
|
||||||
|
for (vtkm::Id i = 0; i < permutation.GetNumberOfValues(); ++i)
|
||||||
|
{
|
||||||
|
permutationMask[static_cast<std::size_t>(permutation.GetPortalConstControl().Get(i))] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::Id numberOfPoints = cellset.GetNumberOfPoints();
|
||||||
|
std::vector<vtkm::Id> expected(static_cast<std::size_t>(numberOfPoints), 0);
|
||||||
|
for (vtkm::Id i = 0; i < numberOfPoints; ++i)
|
||||||
|
{
|
||||||
|
vtkm::Id offset = indexOffsets.GetPortalConstControl().Get(i);
|
||||||
|
vtkm::Id count = numIndices.GetPortalConstControl().Get(i);
|
||||||
|
for (vtkm::Id j = 0; j < count; ++j)
|
||||||
|
{
|
||||||
|
vtkm::Id cellId = connectivity.GetPortalConstControl().Get(offset++);
|
||||||
|
if (permutationMask[static_cast<std::size_t>(cellId)])
|
||||||
|
{
|
||||||
|
++expected[static_cast<std::size_t>(i)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CellSetType>
|
||||||
|
vtkm::cont::CellSetPermutation<CellSetType, vtkm::cont::ArrayHandleCounting<vtkm::Id>> TestCellSet(
|
||||||
|
const CellSetType& cellset)
|
||||||
|
{
|
||||||
|
vtkm::Id numberOfCells = cellset.GetNumberOfCells() / 2;
|
||||||
|
vtkm::cont::ArrayHandleCounting<vtkm::Id> permutation(0, 2, numberOfCells);
|
||||||
|
auto cs = vtkm::cont::make_CellSetPermutation(permutation, cellset);
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> result;
|
||||||
|
|
||||||
|
std::cout << "\t\tTesting PointToCell\n";
|
||||||
|
vtkm::worklet::DispatcherMapTopology<WorkletPointToCell>().Invoke(cs, result);
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(result.GetNumberOfValues() == numberOfCells,
|
||||||
|
"result length not equal to number of cells");
|
||||||
|
for (vtkm::Id i = 0; i < result.GetNumberOfValues(); ++i)
|
||||||
|
{
|
||||||
|
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(i) ==
|
||||||
|
cellset.GetNumberOfPointsInCell(permutation.GetPortalConstControl().Get(i)),
|
||||||
|
"incorrect result");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\t\tTesting CellToPoint\n";
|
||||||
|
vtkm::worklet::DispatcherMapTopology<WorkletCellToPoint>().Invoke(cs, result);
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(result.GetNumberOfValues() == cellset.GetNumberOfPoints(),
|
||||||
|
"result length not equal to number of points");
|
||||||
|
auto expected = ComputeCellToPointExpected(cellset, permutation);
|
||||||
|
for (vtkm::Id i = 0; i < result.GetNumberOfValues(); ++i)
|
||||||
|
{
|
||||||
|
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(i) == expected[static_cast<std::size_t>(i)],
|
||||||
|
"incorrect result");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename CellSetType>
|
||||||
|
void RunTests(const CellSetType& cellset)
|
||||||
|
{
|
||||||
|
std::cout << "\tTesting CellSetPermutation:\n";
|
||||||
|
auto p1 = TestCellSet(cellset);
|
||||||
|
std::cout << "\tTesting CellSetPermutation of CellSetPermutation:\n";
|
||||||
|
TestCellSet(p1);
|
||||||
|
std::cout << "----------------------------------------------------------\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCellSetPermutation()
|
||||||
|
{
|
||||||
|
vtkm::cont::DataSet dataset;
|
||||||
|
vtkm::cont::testing::MakeTestDataSet maker;
|
||||||
|
|
||||||
|
std::cout << "Testing CellSetStructured<2>\n";
|
||||||
|
dataset = maker.Make2DUniformDataSet1();
|
||||||
|
RunTests(dataset.GetCellSet().Cast<vtkm::cont::CellSetStructured<2>>());
|
||||||
|
|
||||||
|
std::cout << "Testing CellSetStructured<3>\n";
|
||||||
|
dataset = maker.Make3DUniformDataSet1();
|
||||||
|
RunTests(dataset.GetCellSet().Cast<vtkm::cont::CellSetStructured<3>>());
|
||||||
|
|
||||||
|
std::cout << "Testing CellSetExplicit\n";
|
||||||
|
dataset = maker.Make3DExplicitDataSetPolygonal();
|
||||||
|
RunTests(dataset.GetCellSet().Cast<vtkm::cont::CellSetExplicit<>>());
|
||||||
|
|
||||||
|
std::cout << "Testing CellSetSingleType\n";
|
||||||
|
dataset = maker.Make3DExplicitDataSetCowNose();
|
||||||
|
RunTests(dataset.GetCellSet().Cast<vtkm::cont::CellSetSingleType<>>());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
int UnitTestCellSetPermutation(int, char* [])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::Run(TestCellSetPermutation);
|
||||||
|
}
|
@ -21,9 +21,10 @@
|
|||||||
#ifndef vtk_m_exec_ConnectivityPermuted_h
|
#ifndef vtk_m_exec_ConnectivityPermuted_h
|
||||||
#define vtk_m_exec_ConnectivityPermuted_h
|
#define vtk_m_exec_ConnectivityPermuted_h
|
||||||
|
|
||||||
|
#include <vtkm/CellShape.h>
|
||||||
#include <vtkm/TopologyElementTag.h>
|
#include <vtkm/TopologyElementTag.h>
|
||||||
#include <vtkm/Types.h>
|
#include <vtkm/Types.h>
|
||||||
#include <vtkm/exec/ConnectivityStructured.h>
|
#include <vtkm/VecFromPortal.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
@ -31,28 +32,28 @@ namespace exec
|
|||||||
{
|
{
|
||||||
|
|
||||||
template <typename PermutationPortal, typename OriginalConnectivity>
|
template <typename PermutationPortal, typename OriginalConnectivity>
|
||||||
class ConnectivityPermuted
|
class ConnectivityPermutedPointToCell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename OriginalConnectivity::SchedulingRangeType SchedulingRangeType;
|
typedef typename OriginalConnectivity::SchedulingRangeType SchedulingRangeType;
|
||||||
|
|
||||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||||
VTKM_EXEC_CONT
|
VTKM_EXEC_CONT
|
||||||
ConnectivityPermuted()
|
ConnectivityPermutedPointToCell()
|
||||||
: Portal()
|
: Portal()
|
||||||
, Connectivity()
|
, Connectivity()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC_CONT
|
VTKM_EXEC_CONT
|
||||||
ConnectivityPermuted(const PermutationPortal& portal, const OriginalConnectivity& src)
|
ConnectivityPermutedPointToCell(const PermutationPortal& portal, const OriginalConnectivity& src)
|
||||||
: Portal(portal)
|
: Portal(portal)
|
||||||
, Connectivity(src)
|
, Connectivity(src)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC_CONT
|
VTKM_EXEC_CONT
|
||||||
ConnectivityPermuted(const ConnectivityPermuted& src)
|
ConnectivityPermutedPointToCell(const ConnectivityPermutedPointToCell& src)
|
||||||
: Portal(src.Portal)
|
: Portal(src.Portal)
|
||||||
, Connectivity(src.Connectivity)
|
, Connectivity(src.Connectivity)
|
||||||
{
|
{
|
||||||
@ -87,6 +88,47 @@ public:
|
|||||||
PermutationPortal Portal;
|
PermutationPortal Portal;
|
||||||
OriginalConnectivity Connectivity;
|
OriginalConnectivity Connectivity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ConnectivityPortalType,
|
||||||
|
typename NumIndicesPortalType,
|
||||||
|
typename IndexOffsetPortalType>
|
||||||
|
class ConnectivityPermutedCellToPoint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using SchedulingRangeType = vtkm::Id;
|
||||||
|
using IndicesType = vtkm::VecFromPortal<ConnectivityPortalType>;
|
||||||
|
using CellShapeTag = vtkm::CellShapeTagVertex;
|
||||||
|
|
||||||
|
ConnectivityPermutedCellToPoint() = default;
|
||||||
|
|
||||||
|
ConnectivityPermutedCellToPoint(const ConnectivityPortalType& connectivity,
|
||||||
|
const NumIndicesPortalType& numIndices,
|
||||||
|
const IndexOffsetPortalType& indexOffset)
|
||||||
|
: Connectivity(connectivity)
|
||||||
|
, NumIndices(numIndices)
|
||||||
|
, IndexOffset(indexOffset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
SchedulingRangeType GetNumberOfElements() const { return this->NumIndices.GetNumberOfValues(); }
|
||||||
|
|
||||||
|
VTKM_EXEC CellShapeTag GetCellShape(vtkm::Id) const { return CellShapeTag(); }
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
vtkm::IdComponent GetNumberOfIndices(vtkm::Id index) const { return this->NumIndices.Get(index); }
|
||||||
|
|
||||||
|
VTKM_EXEC IndicesType GetIndices(vtkm::Id index) const
|
||||||
|
{
|
||||||
|
return IndicesType(
|
||||||
|
this->Connectivity, this->NumIndices.Get(index), this->IndexOffset.Get(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConnectivityPortalType Connectivity;
|
||||||
|
NumIndicesPortalType NumIndices;
|
||||||
|
IndexOffsetPortalType IndexOffset;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
} // namespace vtkm::exec
|
} // namespace vtkm::exec
|
||||||
|
|
||||||
|
@ -159,14 +159,15 @@ struct FetchArrayTopologyMapInImplementation<
|
|||||||
|
|
||||||
template <typename PermutationPortal, vtkm::IdComponent NumDimensions>
|
template <typename PermutationPortal, vtkm::IdComponent NumDimensions>
|
||||||
struct FetchArrayTopologyMapInImplementation<
|
struct FetchArrayTopologyMapInImplementation<
|
||||||
vtkm::exec::ConnectivityPermuted<PermutationPortal,
|
vtkm::exec::ConnectivityPermutedPointToCell<
|
||||||
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
PermutationPortal,
|
||||||
vtkm::TopologyElementTagCell,
|
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
||||||
NumDimensions>>,
|
vtkm::TopologyElementTagCell,
|
||||||
|
NumDimensions>>,
|
||||||
vtkm::internal::ArrayPortalUniformPointCoordinates>
|
vtkm::internal::ArrayPortalUniformPointCoordinates>
|
||||||
|
|
||||||
{
|
{
|
||||||
typedef vtkm::exec::ConnectivityPermuted<
|
typedef vtkm::exec::ConnectivityPermutedPointToCell<
|
||||||
PermutationPortal,
|
PermutationPortal,
|
||||||
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
||||||
vtkm::TopologyElementTagCell,
|
vtkm::TopologyElementTagCell,
|
||||||
|
@ -347,18 +347,20 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Specialization for permuted structured connectivity types.
|
// Specialization for permuted structured connectivity types.
|
||||||
template <typename PermutationPortal,
|
template <typename PermutationPortal, vtkm::IdComponent Dimension>
|
||||||
typename FromTopology,
|
class ThreadIndicesTopologyMap<vtkm::exec::ConnectivityPermutedPointToCell<
|
||||||
typename ToTopology,
|
|
||||||
vtkm::IdComponent Dimension>
|
|
||||||
class ThreadIndicesTopologyMap<vtkm::exec::ConnectivityPermuted<
|
|
||||||
PermutationPortal,
|
PermutationPortal,
|
||||||
vtkm::exec::ConnectivityStructured<FromTopology, ToTopology, Dimension>>>
|
vtkm::exec::
|
||||||
|
ConnectivityStructured<vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell, Dimension>>>
|
||||||
{
|
{
|
||||||
using PermutedConnectivityType = vtkm::exec::ConnectivityPermuted<
|
using PermutedConnectivityType = vtkm::exec::ConnectivityPermutedPointToCell<
|
||||||
PermutationPortal,
|
PermutationPortal,
|
||||||
vtkm::exec::ConnectivityStructured<FromTopology, ToTopology, Dimension>>;
|
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
||||||
using ConnectivityType = vtkm::exec::ConnectivityStructured<FromTopology, ToTopology, Dimension>;
|
vtkm::TopologyElementTagCell,
|
||||||
|
Dimension>>;
|
||||||
|
using ConnectivityType = vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
||||||
|
vtkm::TopologyElementTagCell,
|
||||||
|
Dimension>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using IndicesFromType = typename ConnectivityType::IndicesType;
|
using IndicesFromType = typename ConnectivityType::IndicesType;
|
||||||
|
Loading…
Reference in New Issue
Block a user