mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-08 03:18:58 +00:00
add merge data sets filter
This commit is contained in:
parent
e27573cca9
commit
7254072357
3
docs/changelog/add-merge-datasets-filter.md
Normal file
3
docs/changelog/add-merge-datasets-filter.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Adding MergeDataSets filter
|
||||||
|
|
||||||
|
The MergeDataSets filter can accept partitioned data sets and output a merged data set. It assumes that all partitions have the same coordinate systems. If a field is missing in a specific partition, the user-specified invalid value will be adopted and filled into the corresponding places of the merged field array.
|
@ -7,8 +7,6 @@
|
|||||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
// PURPOSE. See the above copyright notice for more information.
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
#include <vtkm/cont/MergePartitionedDataSet.h>
|
|
||||||
|
|
||||||
#include <vtkm/cont/Algorithm.h>
|
#include <vtkm/cont/Algorithm.h>
|
||||||
#include <vtkm/cont/ArrayCopy.h>
|
#include <vtkm/cont/ArrayCopy.h>
|
||||||
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
|
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
|
||||||
@ -17,15 +15,50 @@
|
|||||||
#include <vtkm/cont/CoordinateSystem.h>
|
#include <vtkm/cont/CoordinateSystem.h>
|
||||||
#include <vtkm/cont/DataSet.h>
|
#include <vtkm/cont/DataSet.h>
|
||||||
#include <vtkm/cont/Logging.h>
|
#include <vtkm/cont/Logging.h>
|
||||||
|
#include <vtkm/cont/MergePartitionedDataSet.h>
|
||||||
#include <vtkm/cont/PartitionedDataSet.h>
|
#include <vtkm/cont/PartitionedDataSet.h>
|
||||||
#include <vtkm/cont/UnknownCellSet.h>
|
#include <vtkm/cont/UnknownCellSet.h>
|
||||||
|
#include <vtkm/cont/internal/CastInvalidValue.h>
|
||||||
#include <vtkm/worklet/WorkletMapField.h>
|
#include <vtkm/worklet/WorkletMapField.h>
|
||||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||||
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct SetToInvalid : public vtkm::worklet::WorkletMapField
|
||||||
|
{
|
||||||
|
T InvalidValue;
|
||||||
|
SetToInvalid(T invalidValue)
|
||||||
|
: InvalidValue(invalidValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
typedef void ControlSignature(FieldInOut);
|
||||||
|
typedef void ExecutionSignature(_1);
|
||||||
|
template <typename ValueType>
|
||||||
|
VTKM_EXEC void operator()(ValueType& value) const
|
||||||
|
{
|
||||||
|
value = this->InvalidValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CopyWithOffsetWorklet : public vtkm::worklet::WorkletMapField
|
||||||
|
{
|
||||||
|
vtkm::Id OffsetValue;
|
||||||
|
VTKM_CONT
|
||||||
|
CopyWithOffsetWorklet(const vtkm::Id offset)
|
||||||
|
: OffsetValue(offset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
typedef void ControlSignature(FieldIn, FieldInOut);
|
||||||
|
typedef void ExecutionSignature(_1, _2);
|
||||||
|
VTKM_EXEC void operator()(const vtkm::Id originalValue, vtkm::Id& outputValue) const
|
||||||
|
{
|
||||||
|
outputValue = originalValue + this->OffsetValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void CountPointsAndCells(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
void CountPointsAndCells(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
||||||
vtkm::Id& numPointsTotal,
|
vtkm::Id& numPointsTotal,
|
||||||
vtkm::Id& numCellsTotal)
|
vtkm::Id& numCellsTotal)
|
||||||
@ -61,7 +94,8 @@ struct PassCellShapesNumIndices : vtkm::worklet::WorkletVisitCellsWithPoints
|
|||||||
void MergeShapes(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
void MergeShapes(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
||||||
vtkm::Id numCellsTotal,
|
vtkm::Id numCellsTotal,
|
||||||
vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||||
vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices)
|
vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||||
|
const vtkm::Id firstNonEmptyPartitionId)
|
||||||
{
|
{
|
||||||
vtkm::cont::Invoker invoke;
|
vtkm::cont::Invoker invoke;
|
||||||
|
|
||||||
@ -69,9 +103,14 @@ void MergeShapes(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
|||||||
numIndices.Allocate(numCellsTotal);
|
numIndices.Allocate(numCellsTotal);
|
||||||
|
|
||||||
vtkm::Id cellStartIndex = 0;
|
vtkm::Id cellStartIndex = 0;
|
||||||
for (vtkm::Id partitionId = 0; partitionId < partitionedDataSet.GetNumberOfPartitions();
|
for (vtkm::Id partitionId = firstNonEmptyPartitionId;
|
||||||
|
partitionId < partitionedDataSet.GetNumberOfPartitions();
|
||||||
++partitionId)
|
++partitionId)
|
||||||
{
|
{
|
||||||
|
if (partitionedDataSet.GetPartition(partitionId).GetNumberOfPoints() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
vtkm::cont::DataSet partition = partitionedDataSet.GetPartition(partitionId);
|
vtkm::cont::DataSet partition = partitionedDataSet.GetPartition(partitionId);
|
||||||
vtkm::Id numCellsPartition = partition.GetNumberOfCells();
|
vtkm::Id numCellsPartition = partition.GetNumberOfCells();
|
||||||
|
|
||||||
@ -113,7 +152,8 @@ struct PassCellIndices : vtkm::worklet::WorkletVisitCellsWithPoints
|
|||||||
void MergeIndices(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
void MergeIndices(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
|
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
|
||||||
vtkm::Id numIndicesTotal,
|
vtkm::Id numIndicesTotal,
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id>& indices)
|
vtkm::cont::ArrayHandle<vtkm::Id>& indices,
|
||||||
|
const vtkm::Id firstNonEmptyPartitionId)
|
||||||
{
|
{
|
||||||
vtkm::cont::Invoker invoke;
|
vtkm::cont::Invoker invoke;
|
||||||
|
|
||||||
@ -121,9 +161,14 @@ void MergeIndices(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
|||||||
|
|
||||||
vtkm::Id pointStartIndex = 0;
|
vtkm::Id pointStartIndex = 0;
|
||||||
vtkm::Id cellStartIndex = 0;
|
vtkm::Id cellStartIndex = 0;
|
||||||
for (vtkm::Id partitionId = 0; partitionId < partitionedDataSet.GetNumberOfPartitions();
|
for (vtkm::Id partitionId = firstNonEmptyPartitionId;
|
||||||
|
partitionId < partitionedDataSet.GetNumberOfPartitions();
|
||||||
++partitionId)
|
++partitionId)
|
||||||
{
|
{
|
||||||
|
if (partitionedDataSet.GetPartition(partitionId).GetNumberOfPoints() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
vtkm::cont::DataSet partition = partitionedDataSet.GetPartition(partitionId);
|
vtkm::cont::DataSet partition = partitionedDataSet.GetPartition(partitionId);
|
||||||
vtkm::Id numCellsPartition = partition.GetNumberOfCells();
|
vtkm::Id numCellsPartition = partition.GetNumberOfCells();
|
||||||
|
|
||||||
@ -139,22 +184,87 @@ void MergeIndices(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
|||||||
VTKM_ASSERT(cellStartIndex == (offsets.GetNumberOfValues() - 1));
|
VTKM_ASSERT(cellStartIndex == (offsets.GetNumberOfValues() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkm::cont::CellSetExplicit<> MergeCellSets(
|
vtkm::cont::CellSetSingleType<> MergeCellSetsSingleType(
|
||||||
|
const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
||||||
|
const vtkm::Id firstNonEmptyPartitionId)
|
||||||
|
{
|
||||||
|
vtkm::Id numCells = 0;
|
||||||
|
vtkm::Id numPoints = 0;
|
||||||
|
vtkm::Id numOfDataSet = partitionedDataSet.GetNumberOfPartitions();
|
||||||
|
std::vector<vtkm::Id> cellOffsets(numOfDataSet);
|
||||||
|
std::vector<vtkm::Id> pointOffsets(numOfDataSet);
|
||||||
|
//Mering cell set into single type
|
||||||
|
//checking the cell type to make sure how many points per cell
|
||||||
|
vtkm::IdComponent numberOfPointsPerCell =
|
||||||
|
partitionedDataSet.GetPartition(firstNonEmptyPartitionId)
|
||||||
|
.GetCellSet()
|
||||||
|
.GetNumberOfPointsInCell(0);
|
||||||
|
for (vtkm::Id partitionIndex = firstNonEmptyPartitionId; partitionIndex < numOfDataSet;
|
||||||
|
partitionIndex++)
|
||||||
|
{
|
||||||
|
if (partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cellOffsets[partitionIndex] = numCells;
|
||||||
|
numCells += partitionedDataSet.GetPartition(partitionIndex).GetNumberOfCells();
|
||||||
|
pointOffsets[partitionIndex] = numPoints;
|
||||||
|
numPoints += partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints();
|
||||||
|
}
|
||||||
|
//We assume all cells have same type, which should have been previously checked.
|
||||||
|
const vtkm::Id mergedConnSize = numCells * numberOfPointsPerCell;
|
||||||
|
// Calculating merged offsets for all domains
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> mergedConn;
|
||||||
|
mergedConn.Allocate(mergedConnSize);
|
||||||
|
for (vtkm::Id partitionIndex = firstNonEmptyPartitionId; partitionIndex < numOfDataSet;
|
||||||
|
partitionIndex++)
|
||||||
|
{
|
||||||
|
if (partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto cellSet = partitionedDataSet.GetPartition(partitionIndex).GetCellSet();
|
||||||
|
// Grabing the connectivity and copy it into the larger connectivity array
|
||||||
|
vtkm::cont::CellSetSingleType<> singleType =
|
||||||
|
cellSet.AsCellSet<vtkm::cont::CellSetSingleType<>>();
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id> connPerDataSet = singleType.GetConnectivityArray(
|
||||||
|
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
vtkm::Id copySize = connPerDataSet.GetNumberOfValues();
|
||||||
|
VTKM_ASSERT(copySize == cellSet.GetNumberOfCells() * numberOfPointsPerCell);
|
||||||
|
// Mapping connectivity array per data into proper region of merged connectivity array
|
||||||
|
// and also adjust the value in merged connectivity array
|
||||||
|
vtkm::cont::Invoker invoker;
|
||||||
|
invoker(CopyWithOffsetWorklet{ pointOffsets[partitionIndex] },
|
||||||
|
connPerDataSet,
|
||||||
|
vtkm::cont::make_ArrayHandleView(
|
||||||
|
mergedConn, cellOffsets[partitionIndex] * numberOfPointsPerCell, copySize));
|
||||||
|
}
|
||||||
|
vtkm::cont::CellSetSingleType<> cellSet;
|
||||||
|
//Filling in the cellSet according to shapeId and number of points per cell.
|
||||||
|
vtkm::UInt8 cellShapeId =
|
||||||
|
partitionedDataSet.GetPartition(firstNonEmptyPartitionId).GetCellSet().GetCellShape(0);
|
||||||
|
cellSet.Fill(numPoints, cellShapeId, numberOfPointsPerCell, mergedConn);
|
||||||
|
return cellSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::cont::CellSetExplicit<> MergeCellSetsExplicit(
|
||||||
const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
||||||
vtkm::Id numPointsTotal,
|
vtkm::Id numPointsTotal,
|
||||||
vtkm::Id numCellsTotal)
|
vtkm::Id numCellsTotal,
|
||||||
|
const vtkm::Id firstNonEmptyPartitionId)
|
||||||
{
|
{
|
||||||
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
|
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
|
||||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
|
||||||
MergeShapes(partitionedDataSet, numCellsTotal, shapes, numIndices);
|
MergeShapes(partitionedDataSet, numCellsTotal, shapes, numIndices, firstNonEmptyPartitionId);
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
|
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
|
||||||
vtkm::Id numIndicesTotal;
|
vtkm::Id numIndicesTotal;
|
||||||
vtkm::cont::ConvertNumComponentsToOffsets(numIndices, offsets, numIndicesTotal);
|
vtkm::cont::ConvertNumComponentsToOffsets(numIndices, offsets, numIndicesTotal);
|
||||||
numIndices.ReleaseResources();
|
numIndices.ReleaseResources();
|
||||||
|
|
||||||
|
//Merging connectivity/indicies array
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> indices;
|
vtkm::cont::ArrayHandle<vtkm::Id> indices;
|
||||||
MergeIndices(partitionedDataSet, offsets, numIndicesTotal, indices);
|
MergeIndices(partitionedDataSet, offsets, numIndicesTotal, indices, firstNonEmptyPartitionId);
|
||||||
|
|
||||||
vtkm::cont::CellSetExplicit<> outCells;
|
vtkm::cont::CellSetExplicit<> outCells;
|
||||||
outCells.Fill(numPointsTotal, shapes, indices, offsets);
|
outCells.Fill(numPointsTotal, shapes, indices, offsets);
|
||||||
@ -276,102 +386,219 @@ vtkm::cont::UnknownArrayHandle MergeArray(vtkm::Id numPartitions,
|
|||||||
return mergedArray;
|
return mergedArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkm::cont::CoordinateSystem MergeCoordinateSystem(
|
vtkm::Id GetFirstEmptyPartition(const vtkm::cont::PartitionedDataSet& partitionedDataSet)
|
||||||
const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
|
||||||
vtkm::IdComponent coordId,
|
|
||||||
vtkm::Id numPointsTotal)
|
|
||||||
{
|
{
|
||||||
std::string coordName = partitionedDataSet.GetPartition(0).GetCoordinateSystem(coordId).GetName();
|
vtkm::Id numOfDataSet = partitionedDataSet.GetNumberOfPartitions();
|
||||||
auto hasField = [&](vtkm::Id partitionId, vtkm::Id& partitionSize) -> bool {
|
vtkm::Id firstNonEmptyPartitionId = -1;
|
||||||
vtkm::cont::DataSet partition = partitionedDataSet.GetPartition(partitionId);
|
for (vtkm::Id partitionIndex = 0; partitionIndex < numOfDataSet; partitionIndex++)
|
||||||
partitionSize = partition.GetNumberOfPoints();
|
{
|
||||||
// Should partitions match coordinates on name or coordinate id? They both should match, but
|
if (partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints() != 0)
|
||||||
// for now let's go by id and check the name.
|
|
||||||
if (partition.GetNumberOfCoordinateSystems() <= coordId)
|
|
||||||
{
|
{
|
||||||
VTKM_LOG_S(vtkm::cont::LogLevel::Warn,
|
firstNonEmptyPartitionId = partitionIndex;
|
||||||
"When merging partitions, partition "
|
break;
|
||||||
<< partitionId << " is missing coordinate system with index " << coordId);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (partition.GetCoordinateSystem(coordId).GetName() != coordName)
|
}
|
||||||
{
|
return firstNonEmptyPartitionId;
|
||||||
VTKM_LOG_S(vtkm::cont::LogLevel::Warn,
|
|
||||||
"When merging partitions, partition "
|
|
||||||
<< partitionId << " reported a coordinate system with name '"
|
|
||||||
<< partition.GetCoordinateSystem(coordId).GetName()
|
|
||||||
<< "' instead of expected name '" << coordName << "'");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
auto getField = [&](vtkm::Id partitionId) -> vtkm::cont::Field {
|
|
||||||
return partitionedDataSet.GetPartition(partitionId).GetCoordinateSystem(coordId);
|
|
||||||
};
|
|
||||||
vtkm::cont::UnknownArrayHandle mergedArray =
|
|
||||||
MergeArray(partitionedDataSet.GetNumberOfPartitions(), hasField, getField, numPointsTotal);
|
|
||||||
return vtkm::cont::CoordinateSystem{ coordName, mergedArray };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkm::cont::Field MergeField(const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
bool PartitionsAreSingleType(const vtkm::cont::PartitionedDataSet partitionedDataSet,
|
||||||
vtkm::IdComponent fieldId,
|
const vtkm::Id firstNonEmptyPartitionId)
|
||||||
vtkm::Id numPointsTotal,
|
|
||||||
vtkm::Id numCellsTotal)
|
|
||||||
{
|
{
|
||||||
vtkm::cont::Field referenceField = partitionedDataSet.GetPartition(0).GetField(fieldId);
|
vtkm::Id numOfDataSet = partitionedDataSet.GetNumberOfPartitions();
|
||||||
vtkm::Id totalSize = 0;
|
for (vtkm::Id partitionIndex = firstNonEmptyPartitionId; partitionIndex < numOfDataSet;
|
||||||
switch (referenceField.GetAssociation())
|
partitionIndex++)
|
||||||
{
|
{
|
||||||
case vtkm::cont::Field::Association::Points:
|
if (partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints() == 0)
|
||||||
totalSize = numPointsTotal;
|
|
||||||
break;
|
|
||||||
case vtkm::cont::Field::Association::Cells:
|
|
||||||
totalSize = numCellsTotal;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
|
||||||
"Skipping merge of field '" << referenceField.GetName()
|
|
||||||
<< "' because it has an unsupported association.");
|
|
||||||
return referenceField;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto hasField = [&](vtkm::Id partitionId, vtkm::Id& partitionSize) -> bool {
|
|
||||||
vtkm::cont::DataSet partition = partitionedDataSet.GetPartition(partitionId);
|
|
||||||
if (partition.HasField(referenceField.GetName(), referenceField.GetAssociation()))
|
|
||||||
{
|
{
|
||||||
partitionSize = partition.GetField(referenceField.GetName(), referenceField.GetAssociation())
|
continue;
|
||||||
.GetData()
|
|
||||||
.GetNumberOfValues();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else
|
auto cellSet = partitionedDataSet.GetPartition(partitionIndex).GetCellSet();
|
||||||
|
if (!cellSet.IsType<vtkm::cont::CellSetSingleType<>>())
|
||||||
{
|
{
|
||||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
|
||||||
"Partition " << partitionId << " does not have field "
|
|
||||||
<< referenceField.GetName());
|
|
||||||
switch (referenceField.GetAssociation())
|
|
||||||
{
|
|
||||||
case vtkm::cont::Field::Association::Points:
|
|
||||||
partitionSize = partition.GetNumberOfPoints();
|
|
||||||
break;
|
|
||||||
case vtkm::cont::Field::Association::Cells:
|
|
||||||
partitionSize = partition.GetNumberOfCells();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
partitionSize = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Make sure the cell type of each non-empty partition is same
|
||||||
|
//with tested one, and they also have the same number of points.
|
||||||
|
//We know that all cell sets are of type `CellSetSingleType<>` at this point.
|
||||||
|
//Polygons may have different number of points even with the same shape id.
|
||||||
|
//It is more efficient to `GetCellShape(0)` from `CellSetSingleType` compared with `CellSetExplicit`.
|
||||||
|
auto cellSetFirst = partitionedDataSet.GetPartition(firstNonEmptyPartitionId).GetCellSet();
|
||||||
|
vtkm::UInt8 cellShapeId = cellSetFirst.GetCellShape(0);
|
||||||
|
vtkm::IdComponent numPointsInCell = cellSetFirst.GetNumberOfPointsInCell(0);
|
||||||
|
for (vtkm::Id partitionIndex = firstNonEmptyPartitionId + 1; partitionIndex < numOfDataSet;
|
||||||
|
partitionIndex++)
|
||||||
|
{
|
||||||
|
auto cellSet = partitionedDataSet.GetPartition(partitionIndex).GetCellSet();
|
||||||
|
if (cellSet.GetCellShape(0) != cellShapeId ||
|
||||||
|
cellSet.GetNumberOfPointsInCell(0) != numPointsInCell)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckCoordsNames(const vtkm::cont::PartitionedDataSet partitionedDataSet,
|
||||||
|
const vtkm::Id firstNonEmptyPartitionId)
|
||||||
|
{
|
||||||
|
vtkm::IdComponent numCoords =
|
||||||
|
partitionedDataSet.GetPartition(firstNonEmptyPartitionId).GetNumberOfCoordinateSystems();
|
||||||
|
std::vector<std::string> coordsNames;
|
||||||
|
for (vtkm::IdComponent coordsIndex = 0; coordsIndex < numCoords; coordsIndex++)
|
||||||
|
{
|
||||||
|
coordsNames.push_back(partitionedDataSet.GetPartition(firstNonEmptyPartitionId)
|
||||||
|
.GetCoordinateSystemName(coordsIndex));
|
||||||
|
}
|
||||||
|
vtkm::Id numOfDataSet = partitionedDataSet.GetNumberOfPartitions();
|
||||||
|
for (vtkm::Id partitionIndex = firstNonEmptyPartitionId; partitionIndex < numOfDataSet;
|
||||||
|
partitionIndex++)
|
||||||
|
{
|
||||||
|
if (partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints() == 0)
|
||||||
|
{
|
||||||
|
//Skip the empty data sets in the partitioned data sets
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (numCoords != partitionedDataSet.GetPartition(partitionIndex).GetNumberOfCoordinateSystems())
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorExecution("Data sets have different number of coordinate systems");
|
||||||
|
}
|
||||||
|
for (vtkm::IdComponent coordsIndex = 0; coordsIndex < numCoords; coordsIndex++)
|
||||||
|
{
|
||||||
|
if (!partitionedDataSet.GetPartition(partitionIndex)
|
||||||
|
.HasCoordinateSystem(coordsNames[coordsIndex]))
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorExecution(
|
||||||
|
"Coordinates system name: " + coordsNames[coordsIndex] +
|
||||||
|
" in the first partition does not exist in other partitions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MergeFieldsAndAddIntoDataSet(vtkm::cont::DataSet& outputDataSet,
|
||||||
|
const vtkm::cont::PartitionedDataSet partitionedDataSet,
|
||||||
|
const vtkm::Id numPoints,
|
||||||
|
const vtkm::Id numCells,
|
||||||
|
const vtkm::Float64 invalidValue,
|
||||||
|
const vtkm::Id firstNonEmptyPartitionId)
|
||||||
|
{
|
||||||
|
// Merging selected fields and coordinates
|
||||||
|
// We get fields names in all partitions firstly
|
||||||
|
// The inserted map stores the field name and a index of the first partition that owns that field
|
||||||
|
vtkm::cont::Invoker invoke;
|
||||||
|
auto associationHash = [](vtkm::cont::Field::Association const& association) {
|
||||||
|
return static_cast<std::size_t>(association);
|
||||||
};
|
};
|
||||||
auto getField = [&](vtkm::Id partitionId) -> vtkm::cont::Field {
|
std::unordered_map<vtkm::cont::Field::Association,
|
||||||
return partitionedDataSet.GetPartition(partitionId)
|
std::unordered_map<std::string, vtkm::Id>,
|
||||||
.GetField(referenceField.GetName(), referenceField.GetAssociation());
|
decltype(associationHash)>
|
||||||
};
|
fieldsMap(2, associationHash);
|
||||||
vtkm::cont::UnknownArrayHandle mergedArray =
|
|
||||||
MergeArray(partitionedDataSet.GetNumberOfPartitions(), hasField, getField, totalSize);
|
vtkm::Id numOfDataSet = partitionedDataSet.GetNumberOfPartitions();
|
||||||
return vtkm::cont::Field{ referenceField.GetName(),
|
for (vtkm::Id partitionIndex = firstNonEmptyPartitionId; partitionIndex < numOfDataSet;
|
||||||
referenceField.GetAssociation(),
|
partitionIndex++)
|
||||||
mergedArray };
|
{
|
||||||
|
if (partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vtkm::IdComponent numFields =
|
||||||
|
partitionedDataSet.GetPartition(partitionIndex).GetNumberOfFields();
|
||||||
|
for (vtkm::IdComponent fieldIndex = 0; fieldIndex < numFields; fieldIndex++)
|
||||||
|
{
|
||||||
|
const vtkm::cont::Field& field =
|
||||||
|
partitionedDataSet.GetPartition(partitionIndex).GetField(fieldIndex);
|
||||||
|
auto association = field.GetAssociation();
|
||||||
|
bool isSupported = (association == vtkm::cont::Field::Association::Points ||
|
||||||
|
association == vtkm::cont::Field::Association::Cells);
|
||||||
|
if (!isSupported)
|
||||||
|
{
|
||||||
|
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||||
|
"Skipping merge of field '" << field.GetName()
|
||||||
|
<< "' because it has an unsupported association.");
|
||||||
|
}
|
||||||
|
//Do not store the field index again if it exists in fieldMap
|
||||||
|
if (fieldsMap[association].find(field.GetName()) != fieldsMap[association].end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fieldsMap[association][field.GetName()] = partitionIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Iterate all fields and create merged field arrays
|
||||||
|
for (auto fieldMapIter = fieldsMap.begin(); fieldMapIter != fieldsMap.end(); ++fieldMapIter)
|
||||||
|
{
|
||||||
|
auto fieldAssociation = fieldMapIter->first;
|
||||||
|
auto fieldNamesMap = fieldMapIter->second;
|
||||||
|
for (auto fieldNameIter = fieldNamesMap.begin(); fieldNameIter != fieldNamesMap.end();
|
||||||
|
++fieldNameIter)
|
||||||
|
{
|
||||||
|
std::string fieldName = fieldNameIter->first;
|
||||||
|
vtkm::Id partitionOwnsField = fieldNameIter->second;
|
||||||
|
const vtkm::cont::Field& field =
|
||||||
|
partitionedDataSet.GetPartition(partitionOwnsField).GetField(fieldName, fieldAssociation);
|
||||||
|
|
||||||
|
vtkm::cont::UnknownArrayHandle mergedFieldArray = field.GetData().NewInstanceBasic();
|
||||||
|
if (fieldAssociation == vtkm::cont::Field::Association::Points)
|
||||||
|
{
|
||||||
|
mergedFieldArray.Allocate(numPoints);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//We may add a new association (such as edges or faces) in future
|
||||||
|
VTKM_ASSERT(fieldAssociation == vtkm::cont::Field::Association::Cells);
|
||||||
|
mergedFieldArray.Allocate(numCells);
|
||||||
|
}
|
||||||
|
//Merging each field into the mergedField array
|
||||||
|
auto resolveType = [&](auto& concreteOut) {
|
||||||
|
vtkm::Id offset = 0;
|
||||||
|
for (vtkm::Id partitionIndex = firstNonEmptyPartitionId; partitionIndex < numOfDataSet;
|
||||||
|
++partitionIndex)
|
||||||
|
{
|
||||||
|
if (partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (partitionedDataSet.GetPartition(partitionIndex).HasField(fieldName, fieldAssociation))
|
||||||
|
{
|
||||||
|
vtkm::cont::UnknownArrayHandle in = partitionedDataSet.GetPartition(partitionIndex)
|
||||||
|
.GetField(fieldName, fieldAssociation)
|
||||||
|
.GetData();
|
||||||
|
vtkm::Id copySize = in.GetNumberOfValues();
|
||||||
|
auto viewOut = vtkm::cont::make_ArrayHandleView(concreteOut, offset, copySize);
|
||||||
|
vtkm::cont::ArrayCopy(in, viewOut);
|
||||||
|
offset += copySize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Creating invalid values for the partition that does not have the field
|
||||||
|
using ComponentType =
|
||||||
|
typename std::decay_t<decltype(concreteOut)>::ValueType::ComponentType;
|
||||||
|
ComponentType castInvalid =
|
||||||
|
vtkm::cont::internal::CastInvalidValue<ComponentType>(invalidValue);
|
||||||
|
vtkm::Id copySize = 0;
|
||||||
|
if (fieldAssociation == vtkm::cont::Field::Association::Points)
|
||||||
|
{
|
||||||
|
copySize = partitionedDataSet.GetPartition(partitionIndex).GetNumberOfPoints();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copySize = partitionedDataSet.GetPartition(partitionIndex).GetNumberOfCells();
|
||||||
|
}
|
||||||
|
auto viewOut = vtkm::cont::make_ArrayHandleView(concreteOut, offset, copySize);
|
||||||
|
invoke(SetToInvalid<ComponentType>{ castInvalid }, viewOut);
|
||||||
|
offset += copySize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mergedFieldArray.CastAndCallWithExtractedArray(resolveType);
|
||||||
|
outputDataSet.AddField(vtkm::cont::Field(fieldName, fieldAssociation, mergedFieldArray));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
@ -385,31 +612,54 @@ namespace cont
|
|||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
vtkm::cont::DataSet MergePartitionedDataSet(
|
vtkm::cont::DataSet MergePartitionedDataSet(
|
||||||
const vtkm::cont::PartitionedDataSet& partitionedDataSet)
|
const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
||||||
|
vtkm::Float64 invalidValue)
|
||||||
{
|
{
|
||||||
// verify correctnees of data
|
vtkm::cont::DataSet outputData;
|
||||||
VTKM_ASSERT(partitionedDataSet.GetNumberOfPartitions() > 0);
|
//The name of coordinates system in the first non-empty partition will be used in merged data set
|
||||||
|
vtkm::Id firstNonEmptyPartitionId = GetFirstEmptyPartition(partitionedDataSet);
|
||||||
|
if (firstNonEmptyPartitionId == -1)
|
||||||
|
{
|
||||||
|
return outputData;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Checking the name of coordinates system, if all partitions have different name with the firstNonEmptyPartitionId
|
||||||
|
//just throw the exception now
|
||||||
|
CheckCoordsNames(partitionedDataSet, firstNonEmptyPartitionId);
|
||||||
|
|
||||||
|
//Checking if all partitions have CellSetSingleType with the same cell type
|
||||||
|
bool allPartitionsAreSingleType =
|
||||||
|
PartitionsAreSingleType(partitionedDataSet, firstNonEmptyPartitionId);
|
||||||
|
|
||||||
vtkm::Id numPointsTotal;
|
vtkm::Id numPointsTotal;
|
||||||
vtkm::Id numCellsTotal;
|
vtkm::Id numCellsTotal;
|
||||||
CountPointsAndCells(partitionedDataSet, numPointsTotal, numCellsTotal);
|
CountPointsAndCells(partitionedDataSet, numPointsTotal, numCellsTotal);
|
||||||
|
|
||||||
vtkm::cont::DataSet outputData;
|
if (allPartitionsAreSingleType)
|
||||||
outputData.SetCellSet(MergeCellSets(partitionedDataSet, numPointsTotal, numCellsTotal));
|
{
|
||||||
|
outputData.SetCellSet(MergeCellSetsSingleType(partitionedDataSet, firstNonEmptyPartitionId));
|
||||||
vtkm::cont::DataSet partition0 = partitionedDataSet.GetPartition(0);
|
}
|
||||||
for (vtkm::IdComponent coordId = 0; coordId < partition0.GetNumberOfCoordinateSystems();
|
else
|
||||||
++coordId)
|
{
|
||||||
|
outputData.SetCellSet(MergeCellSetsExplicit(
|
||||||
|
partitionedDataSet, numPointsTotal, numCellsTotal, firstNonEmptyPartitionId));
|
||||||
|
}
|
||||||
|
//Merging fields and coordinate systems
|
||||||
|
MergeFieldsAndAddIntoDataSet(outputData,
|
||||||
|
partitionedDataSet,
|
||||||
|
numPointsTotal,
|
||||||
|
numCellsTotal,
|
||||||
|
invalidValue,
|
||||||
|
firstNonEmptyPartitionId);
|
||||||
|
//Labeling fields that belong to the coordinate system.
|
||||||
|
//There might be multiple coordinates systems, assuming all partitions have the same name of the coordinates system
|
||||||
|
vtkm::IdComponent numCoordsNames =
|
||||||
|
partitionedDataSet.GetPartition(firstNonEmptyPartitionId).GetNumberOfCoordinateSystems();
|
||||||
|
for (vtkm::IdComponent i = 0; i < numCoordsNames; i++)
|
||||||
{
|
{
|
||||||
outputData.AddCoordinateSystem(
|
outputData.AddCoordinateSystem(
|
||||||
MergeCoordinateSystem(partitionedDataSet, coordId, numPointsTotal));
|
partitionedDataSet.GetPartition(firstNonEmptyPartitionId).GetCoordinateSystemName(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vtkm::IdComponent fieldId = 0; fieldId < partition0.GetNumberOfFields(); ++fieldId)
|
|
||||||
{
|
|
||||||
outputData.AddField(MergeField(partitionedDataSet, fieldId, numPointsTotal, numCellsTotal));
|
|
||||||
}
|
|
||||||
|
|
||||||
return outputData;
|
return outputData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,20 +22,15 @@ class DataSet;
|
|||||||
class PartitionedDataSet;
|
class PartitionedDataSet;
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// \brief Functions to compute bounds for a single dataSset or partition dataset
|
/// \brief This function can merge multiple data sets into on data set.
|
||||||
///
|
/// This function assume all input partitions have the same coordinates systems.
|
||||||
/// These are utility functions that compute bounds for a single dataset or
|
/// If a field does not exist in a specific partition but exists in other partitions,
|
||||||
/// partitioned dataset. When VTK-m is operating in an distributed environment,
|
/// the invalide value will be used to fill the coresponding region of that field in the merged data set.
|
||||||
/// these are bounds on the local process. To get global bounds across all
|
|
||||||
/// ranks, use `vtkm::cont::BoundsGlobalCompute` instead.
|
|
||||||
///
|
|
||||||
/// Note that if the provided CoordinateSystem does not exists, empty bounds
|
|
||||||
/// are returned. Likewise, for PartitionedDataSet, partitions without the
|
|
||||||
/// chosen CoordinateSystem are skipped.
|
|
||||||
VTKM_CONT_EXPORT
|
VTKM_CONT_EXPORT
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
vtkm::cont::DataSet MergePartitionedDataSet(
|
vtkm::cont::DataSet MergePartitionedDataSet(
|
||||||
const vtkm::cont::PartitionedDataSet& partitionedDataSet);
|
const vtkm::cont::PartitionedDataSet& partitionedDataSet,
|
||||||
|
vtkm::Float64 invalidValue = vtkm::Nan64());
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
}
|
}
|
||||||
|
@ -83,5 +83,7 @@ static void MergePartitionedDataSetTest()
|
|||||||
|
|
||||||
int UnitTestMergePartitionedDataSet(int argc, char* argv[])
|
int UnitTestMergePartitionedDataSet(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
//More test cases can be found in the vtkm/filter/multi_block/testing/UnitTestMergeDataSetsFilter.cxx
|
||||||
|
//which is a filter that wraps MergePartitionedDataSet algorithm.
|
||||||
return vtkm::cont::testing::Testing::Run(MergePartitionedDataSetTest, argc, argv);
|
return vtkm::cont::testing::Testing::Run(MergePartitionedDataSetTest, argc, argv);
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,10 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
#include <vtkm/cont/ArrayCopyDevice.h>
|
#include <vtkm/cont/ArrayCopyDevice.h>
|
||||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||||
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
#include <vtkm/cont/MergePartitionedDataSet.h>
|
||||||
#include <vtkm/filter/contour/Slice.h>
|
#include <vtkm/filter/contour/Slice.h>
|
||||||
#include <vtkm/filter/contour/SliceMultiple.h>
|
#include <vtkm/filter/contour/SliceMultiple.h>
|
||||||
#include <vtkm/filter/multi_block/AmrArrays.h>
|
|
||||||
#include <vtkm/worklet/WorkletMapField.h>
|
#include <vtkm/worklet/WorkletMapField.h>
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
@ -34,121 +35,7 @@ public:
|
|||||||
typedef void ExecutionSignature(_1);
|
typedef void ExecutionSignature(_1);
|
||||||
VTKM_EXEC void operator()(vtkm::Id& value) const { value += this->OffsetValue; }
|
VTKM_EXEC void operator()(vtkm::Id& value) const { value += this->OffsetValue; }
|
||||||
};
|
};
|
||||||
// Original MergeContours code come from
|
|
||||||
// https://github.com/Alpine-DAV/ascent/blob/develop/src/libs/vtkh/filters/Slice.cpp#L517
|
|
||||||
class MergeContours
|
|
||||||
{
|
|
||||||
vtkm::cont::PartitionedDataSet DataSets;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MergeContours(vtkm::cont::PartitionedDataSet& dataSets)
|
|
||||||
: DataSets(dataSets)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
vtkm::cont::DataSet MergeDataSets()
|
|
||||||
{
|
|
||||||
vtkm::cont::DataSet res;
|
|
||||||
vtkm::Id numOfDataSet = this->DataSets.GetNumberOfPartitions();
|
|
||||||
vtkm::Id numCells = 0;
|
|
||||||
vtkm::Id numPoints = 0;
|
|
||||||
std::vector<vtkm::Id> cellOffsets(numOfDataSet);
|
|
||||||
std::vector<vtkm::Id> pointOffsets(numOfDataSet);
|
|
||||||
for (vtkm::Id i = 0; i < numOfDataSet; i++)
|
|
||||||
{
|
|
||||||
auto cellSet = this->DataSets.GetPartition(i).GetCellSet();
|
|
||||||
//We assume all cells are triangles here
|
|
||||||
if (!cellSet.IsType<vtkm::cont::CellSetSingleType<>>())
|
|
||||||
{
|
|
||||||
throw vtkm::cont::ErrorFilterExecution(
|
|
||||||
"Expected singletype cell set as the result of contour.");
|
|
||||||
}
|
|
||||||
cellOffsets[i] = numCells;
|
|
||||||
numCells += cellSet.GetNumberOfCells();
|
|
||||||
pointOffsets[i] = numPoints;
|
|
||||||
numPoints += this->DataSets.GetPartition(i).GetNumberOfPoints();
|
|
||||||
}
|
|
||||||
const vtkm::Id connSize = numCells * 3;
|
|
||||||
// Calculating merged offsets for all domains
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> conn;
|
|
||||||
conn.Allocate(connSize);
|
|
||||||
for (vtkm::Id i = 0; i < numOfDataSet; i++)
|
|
||||||
{
|
|
||||||
auto cellSet = this->DataSets.GetPartition(i).GetCellSet();
|
|
||||||
if (!cellSet.IsType<vtkm::cont::CellSetSingleType<>>())
|
|
||||||
{
|
|
||||||
throw vtkm::cont::ErrorFilterExecution(
|
|
||||||
"Expected singletype cell set as the result of contour.");
|
|
||||||
}
|
|
||||||
// Grabing the connectivity and copy it into the larger array
|
|
||||||
vtkm::cont::CellSetSingleType<> singleType =
|
|
||||||
cellSet.AsCellSet<vtkm::cont::CellSetSingleType<>>();
|
|
||||||
const vtkm::cont::ArrayHandle<vtkm::Id> connPerDataSet = singleType.GetConnectivityArray(
|
|
||||||
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
|
||||||
vtkm::Id copySize = connPerDataSet.GetNumberOfValues();
|
|
||||||
vtkm::Id start = 0;
|
|
||||||
vtkm::cont::Algorithm::CopySubRange(
|
|
||||||
connPerDataSet, start, copySize, conn, cellOffsets[i] * 3);
|
|
||||||
// We offset the connectiviy we just copied in so we references the
|
|
||||||
// correct points
|
|
||||||
if (cellOffsets[i] != 0)
|
|
||||||
{
|
|
||||||
vtkm::cont::Invoker invoker;
|
|
||||||
invoker(OffsetWorklet{ pointOffsets[i] },
|
|
||||||
vtkm::cont::make_ArrayHandleView(conn, cellOffsets[i] * 3, copySize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vtkm::cont::CellSetSingleType<> cellSet;
|
|
||||||
cellSet.Fill(numPoints, vtkm::CELL_SHAPE_TRIANGLE, 3, conn);
|
|
||||||
res.SetCellSet(cellSet);
|
|
||||||
// Merging selected fields and coordinates
|
|
||||||
vtkm::IdComponent numFields = this->DataSets.GetPartition(0).GetNumberOfFields();
|
|
||||||
for (vtkm::IdComponent i = 0; i < numFields; i++)
|
|
||||||
{
|
|
||||||
const vtkm::cont::Field& field = this->DataSets.GetPartition(0).GetField(i);
|
|
||||||
bool isSupported = (field.GetAssociation() == vtkm::cont::Field::Association::Points ||
|
|
||||||
field.GetAssociation() == vtkm::cont::Field::Association::Cells);
|
|
||||||
if (!isSupported)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
vtkm::cont::UnknownArrayHandle outFieldArray = field.GetData().NewInstanceBasic();
|
|
||||||
bool assocPoints = field.GetAssociation() == vtkm::cont::Field::Association::Points;
|
|
||||||
if (assocPoints)
|
|
||||||
{
|
|
||||||
outFieldArray.Allocate(numPoints);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
outFieldArray.Allocate(numCells);
|
|
||||||
}
|
|
||||||
auto resolveType = [&](auto& concreteOut) {
|
|
||||||
vtkm::Id offset = 0;
|
|
||||||
for (vtkm::Id partitionId = 0; partitionId < this->DataSets.GetNumberOfPartitions();
|
|
||||||
++partitionId)
|
|
||||||
{
|
|
||||||
vtkm::cont::UnknownArrayHandle in = this->DataSets.GetPartition(partitionId)
|
|
||||||
.GetField(field.GetName(), field.GetAssociation())
|
|
||||||
.GetData();
|
|
||||||
vtkm::Id copySize = in.GetNumberOfValues();
|
|
||||||
auto viewOut = vtkm::cont::make_ArrayHandleView(concreteOut, offset, copySize);
|
|
||||||
vtkm::cont::ArrayCopy(in, viewOut);
|
|
||||||
offset += copySize;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
outFieldArray.CastAndCallWithExtractedArray(resolveType);
|
|
||||||
res.AddField(vtkm::cont::Field(field.GetName(), field.GetAssociation(), outFieldArray));
|
|
||||||
}
|
|
||||||
//Labeling fields that belong to the coordinate system.
|
|
||||||
//There might be multiple coordinates systems, assuming all partitions have the same name of the coordinates system
|
|
||||||
vtkm::IdComponent numCoordsNames =
|
|
||||||
this->DataSets.GetPartition(0).GetNumberOfCoordinateSystems();
|
|
||||||
for (vtkm::IdComponent i = 0; i < numCoordsNames; i++)
|
|
||||||
{
|
|
||||||
res.AddCoordinateSystem(this->DataSets.GetPartition(0).GetCoordinateSystemName(i));
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
vtkm::cont::DataSet SliceMultiple::DoExecute(const vtkm::cont::DataSet& input)
|
vtkm::cont::DataSet SliceMultiple::DoExecute(const vtkm::cont::DataSet& input)
|
||||||
{
|
{
|
||||||
vtkm::cont::PartitionedDataSet slices;
|
vtkm::cont::PartitionedDataSet slices;
|
||||||
@ -165,8 +52,8 @@ vtkm::cont::DataSet SliceMultiple::DoExecute(const vtkm::cont::DataSet& input)
|
|||||||
{
|
{
|
||||||
//Since the slice filter have already selected fields
|
//Since the slice filter have already selected fields
|
||||||
//the mergeCountours will copy all existing fields
|
//the mergeCountours will copy all existing fields
|
||||||
MergeContours merger(slices);
|
vtkm::cont::DataSet mergedResults =
|
||||||
vtkm::cont::DataSet mergedResults = merger.MergeDataSets();
|
vtkm::cont::MergePartitionedDataSet(slices, vtkm::Float64(0));
|
||||||
return mergedResults;
|
return mergedResults;
|
||||||
}
|
}
|
||||||
return slices.GetPartition(0);
|
return slices.GetPartition(0);
|
||||||
|
@ -9,10 +9,12 @@
|
|||||||
##============================================================================
|
##============================================================================
|
||||||
set(multi_block_headers
|
set(multi_block_headers
|
||||||
AmrArrays.h
|
AmrArrays.h
|
||||||
|
MergeDataSets.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(multi_block_sources
|
set(multi_block_sources
|
||||||
AmrArrays.cxx
|
AmrArrays.cxx
|
||||||
|
MergeDataSets.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
vtkm_library(
|
vtkm_library(
|
||||||
|
32
vtkm/filter/multi_block/MergeDataSets.cxx
Normal file
32
vtkm/filter/multi_block/MergeDataSets.cxx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/MergePartitionedDataSet.h>
|
||||||
|
#include <vtkm/filter/multi_block/MergeDataSets.h>
|
||||||
|
namespace vtkm
|
||||||
|
{
|
||||||
|
namespace filter
|
||||||
|
{
|
||||||
|
namespace multi_block
|
||||||
|
{
|
||||||
|
vtkm::cont::PartitionedDataSet MergeDataSets::DoExecutePartitions(
|
||||||
|
const vtkm::cont::PartitionedDataSet& input)
|
||||||
|
{
|
||||||
|
vtkm::cont::DataSet mergedResult =
|
||||||
|
vtkm::cont::MergePartitionedDataSet(input, this->GetInvalidValue());
|
||||||
|
return vtkm::cont::PartitionedDataSet(mergedResult);
|
||||||
|
}
|
||||||
|
vtkm::cont::DataSet MergeDataSets::DoExecute(const vtkm::cont::DataSet&)
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorFilterExecution("MergeDataSets only works for a PartitionedDataSet");
|
||||||
|
}
|
||||||
|
} // namespace multi_block
|
||||||
|
} // namespace filter
|
||||||
|
} // namespace vtkm
|
46
vtkm/filter/multi_block/MergeDataSets.h
Normal file
46
vtkm/filter/multi_block/MergeDataSets.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
#ifndef vtk_m_filter_multi_block_MergeDataSets_h
|
||||||
|
#define vtk_m_filter_multi_block_MergeDataSets_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
#include <vtkm/filter/Filter.h>
|
||||||
|
#include <vtkm/filter/multi_block/vtkm_filter_multi_block_export.h>
|
||||||
|
|
||||||
|
namespace vtkm
|
||||||
|
{
|
||||||
|
namespace filter
|
||||||
|
{
|
||||||
|
namespace multi_block
|
||||||
|
{
|
||||||
|
/// \brief Merging multiple data sets into one data set.
|
||||||
|
///
|
||||||
|
/// This filter merges multiple data sets into one data set. We assume that the input data sets
|
||||||
|
/// have the same coordinate system. If there are missing fields in a specific data set,
|
||||||
|
// the filter uses the InvalidValue specified by the user to fill in the associated position of the field array.
|
||||||
|
class VTKM_FILTER_MULTI_BLOCK_EXPORT MergeDataSets : public vtkm::filter::Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void SetInvalidValue(vtkm::Float64 invalidValue) { this->InvalidValue = invalidValue; };
|
||||||
|
vtkm::Float64 GetInvalidValue() { return this->InvalidValue; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inputDataSet) override;
|
||||||
|
|
||||||
|
vtkm::cont::PartitionedDataSet DoExecutePartitions(
|
||||||
|
const vtkm::cont::PartitionedDataSet& input) override;
|
||||||
|
|
||||||
|
vtkm::Float64 InvalidValue = vtkm::Nan64();
|
||||||
|
};
|
||||||
|
} // namespace multi_block
|
||||||
|
} // namesapce filter
|
||||||
|
} // namespace vtkm
|
||||||
|
|
||||||
|
#endif //vtk_m_filter_multi_block_MergeDataSets_h
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
set(libraries
|
set(libraries
|
||||||
vtkm_filter_multi_block
|
vtkm_filter_multi_block
|
||||||
|
vtkm_filter_geometry_refinement
|
||||||
vtkm_source
|
vtkm_source
|
||||||
vtkm_rendering
|
vtkm_rendering
|
||||||
vtkm_rendering_testing
|
vtkm_rendering_testing
|
||||||
@ -18,9 +19,13 @@ set(libraries
|
|||||||
set(unit_tests
|
set(unit_tests
|
||||||
RenderTestAmrArrays.cxx
|
RenderTestAmrArrays.cxx
|
||||||
)
|
)
|
||||||
|
set(unit_tests_device
|
||||||
|
UnitTestMergeDataSetsFilter.cxx
|
||||||
|
)
|
||||||
|
|
||||||
vtkm_unit_tests(
|
vtkm_unit_tests(
|
||||||
SOURCES ${unit_tests}
|
SOURCES ${unit_tests}
|
||||||
|
DEVICE_SOURCES ${unit_tests_device}
|
||||||
LIBRARIES ${libraries}
|
LIBRARIES ${libraries}
|
||||||
USE_VTKM_JOB_POOL
|
USE_VTKM_JOB_POOL
|
||||||
)
|
)
|
||||||
|
623
vtkm/filter/multi_block/testing/UnitTestMergeDataSetsFilter.cxx
Normal file
623
vtkm/filter/multi_block/testing/UnitTestMergeDataSetsFilter.cxx
Normal file
@ -0,0 +1,623 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleBasic.h>
|
||||||
|
#include <vtkm/cont/DataSetBuilderExplicit.h>
|
||||||
|
#include <vtkm/cont/DataSetBuilderUniform.h>
|
||||||
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
#include <vtkm/filter/geometry_refinement/Triangulate.h>
|
||||||
|
#include <vtkm/filter/multi_block/MergeDataSets.h>
|
||||||
|
#include <vtkm/worklet/WorkletMapField.h>
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct SetPointValuesV4Worklet : public vtkm::worklet::WorkletMapField
|
||||||
|
{
|
||||||
|
using ControlSignature = void(FieldIn, FieldOut);
|
||||||
|
using ExecutionSignature = void(_1, _2);
|
||||||
|
template <typename CoordinatesType, typename V4Type>
|
||||||
|
VTKM_EXEC void operator()(const CoordinatesType& coordinates, V4Type& vec4) const
|
||||||
|
{
|
||||||
|
vec4 = {
|
||||||
|
coordinates[0] * 0.1, coordinates[1] * 0.1, coordinates[2] * 0.1, coordinates[0] * 0.1
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct SetPointValuesV1Worklet : public vtkm::worklet::WorkletMapField
|
||||||
|
{
|
||||||
|
using ControlSignature = void(FieldIn, FieldOut);
|
||||||
|
using ExecutionSignature = void(_1, _2);
|
||||||
|
template <typename CoordinatesType, typename ScalarType>
|
||||||
|
VTKM_EXEC void operator()(const CoordinatesType& coordinates, ScalarType& value) const
|
||||||
|
{
|
||||||
|
value = (coordinates[0] + coordinates[1] + coordinates[2]) * 0.1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
vtkm::cont::DataSet CreateSingleCellSetData(vtkm::Vec3f coordinates[4])
|
||||||
|
{
|
||||||
|
const int connectivitySize = 6;
|
||||||
|
vtkm::Id pointId[connectivitySize] = { 0, 1, 2, 1, 2, 3 };
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
|
||||||
|
connectivity.Allocate(connectivitySize);
|
||||||
|
for (vtkm::Id i = 0; i < connectivitySize; ++i)
|
||||||
|
{
|
||||||
|
connectivity.WritePortal().Set(i, pointId[i]);
|
||||||
|
}
|
||||||
|
vtkm::cont::CellSetSingleType<> cellSet;
|
||||||
|
cellSet.Fill(4, vtkm::CELL_SHAPE_TRIANGLE, 3, connectivity);
|
||||||
|
vtkm::cont::DataSet dataSet;
|
||||||
|
dataSet.AddCoordinateSystem(
|
||||||
|
vtkm::cont::make_CoordinateSystem("coords", coordinates, 4, vtkm::CopyFlag::On));
|
||||||
|
dataSet.SetCellSet(cellSet);
|
||||||
|
|
||||||
|
std::vector<vtkm::Float32> pointvar(4);
|
||||||
|
std::iota(pointvar.begin(), pointvar.end(), 15.f);
|
||||||
|
std::vector<vtkm::Float32> cellvar(connectivitySize / 3);
|
||||||
|
std::iota(cellvar.begin(), cellvar.end(), 132.f);
|
||||||
|
dataSet.AddPointField("pointVar", pointvar);
|
||||||
|
dataSet.AddCellField("cellVar", cellvar);
|
||||||
|
return dataSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkm::cont::DataSet CreateUniformData(vtkm::Vec2f origin)
|
||||||
|
{
|
||||||
|
vtkm::cont::DataSetBuilderUniform dsb;
|
||||||
|
vtkm::Id2 dimensions(3, 2);
|
||||||
|
vtkm::cont::DataSet dataSet = dsb.Create(dimensions, origin, vtkm::Vec2f(1, 1));
|
||||||
|
constexpr vtkm::Id nVerts = 6;
|
||||||
|
constexpr vtkm::Float32 var[nVerts] = { 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f };
|
||||||
|
dataSet.AddPointField("pointVar", var, nVerts);
|
||||||
|
constexpr vtkm::Float32 cellvar[2] = { 100.1f, 200.1f };
|
||||||
|
dataSet.AddCellField("cellVar", cellvar, 2);
|
||||||
|
return dataSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestUniformSameFieldsSameDataTypeSingleCellSet()
|
||||||
|
{
|
||||||
|
std::cout << "TestUniformSameFieldsSameDataTypeSingleCellSet" << std::endl;
|
||||||
|
const int nVerts = 4;
|
||||||
|
vtkm::Vec3f coordinates1[nVerts] = { vtkm::Vec3f(0.0, 0.0, 0.0),
|
||||||
|
vtkm::Vec3f(1.0, 0.0, 0.0),
|
||||||
|
vtkm::Vec3f(0.0, 1.0, 0.0),
|
||||||
|
vtkm::Vec3f(1.0, 1.0, 0.0) };
|
||||||
|
vtkm::cont::DataSet dataSet1 = CreateSingleCellSetData(coordinates1);
|
||||||
|
vtkm::Vec3f coordinates2[nVerts] = { vtkm::Vec3f(1.0, 0.0, 0.0),
|
||||||
|
vtkm::Vec3f(2.0, 0.0, 0.0),
|
||||||
|
vtkm::Vec3f(1.0, 1.0, 0.0),
|
||||||
|
vtkm::Vec3f(2.0, 1.0, 0.0) };
|
||||||
|
vtkm::cont::DataSet dataSet2 = CreateSingleCellSetData(coordinates2);
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets;
|
||||||
|
inputDataSets.AppendPartition(dataSet1);
|
||||||
|
inputDataSets.AppendPartition(dataSet2);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets);
|
||||||
|
//Validating result cell sets
|
||||||
|
auto cellSet = result.GetPartition(0).GetCellSet();
|
||||||
|
vtkm::cont::CellSetSingleType<> singleType = cellSet.AsCellSet<vtkm::cont::CellSetSingleType<>>();
|
||||||
|
VTKM_TEST_ASSERT(singleType.GetCellShapeAsId() == 5, "Wrong cellShape Id");
|
||||||
|
VTKM_TEST_ASSERT(cellSet.GetNumberOfCells() == 4, "Wrong numberOfCells");
|
||||||
|
VTKM_TEST_ASSERT(cellSet.GetNumberOfPoints() == 8, "Wrong numberOfPoints");
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id> connectivityArray = singleType.GetConnectivityArray(
|
||||||
|
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> validateConnArray =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 1, 2, 1, 2, 3, 4, 5, 6, 5, 6, 7 });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(connectivityArray, validateConnArray));
|
||||||
|
//Validating result fields
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>({ 15.0, 16.0, 17.0, 18.0, 15.0, 16.0, 17.0, 18.0 });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validateCellVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>({ 132, 133, 132, 133 });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result.GetPartition(0).GetField("pointVar").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0).GetField("cellVar").GetData(), validateCellVar),
|
||||||
|
"wrong cellVar values");
|
||||||
|
//Validating result coordinates
|
||||||
|
vtkm::cont::CoordinateSystem coords = result.GetPartition(0).GetCoordinateSystem();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> resultCoords =
|
||||||
|
coords.GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Vec3f>>();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> validateCoords =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Vec3f>({ { 0, 0, 0 },
|
||||||
|
{ 1, 0, 0 },
|
||||||
|
{ 0, 1, 0 },
|
||||||
|
{ 1, 1, 0 },
|
||||||
|
{ 1, 0, 0 },
|
||||||
|
{ 2, 0, 0 },
|
||||||
|
{ 1, 1, 0 },
|
||||||
|
{ 2, 1, 0 } });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(resultCoords, validateCoords),
|
||||||
|
"wrong validateCoords values");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestUniformSameFieldsSameDataType()
|
||||||
|
{
|
||||||
|
std::cout << "TestUniformSameFieldsSameDataType" << std::endl;
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets;
|
||||||
|
vtkm::cont::DataSet dataSet0 = CreateUniformData(vtkm::Vec2f(0.0, 0.0));
|
||||||
|
vtkm::cont::DataSet dataSet1 = CreateUniformData(vtkm::Vec2f(3.0, 0.0));
|
||||||
|
inputDataSets.AppendPartition(dataSet0);
|
||||||
|
inputDataSets.AppendPartition(dataSet1);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets);
|
||||||
|
//validating cellsets
|
||||||
|
auto cellSet = result.GetPartition(0).GetCellSet();
|
||||||
|
vtkm::cont::CellSetExplicit<> explicitType = cellSet.AsCellSet<vtkm::cont::CellSetExplicit<>>();
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id> connectivityArray = explicitType.GetConnectivityArray(
|
||||||
|
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8> shapesArray =
|
||||||
|
explicitType.GetShapesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray =
|
||||||
|
explicitType.GetOffsetsArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> validateConnectivity =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 1, 4, 3, 1, 2, 5, 4, 6, 7, 10, 9, 7, 8, 11, 10 });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::UInt8> validateShapes =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::UInt8>({ 9, 9, 9, 9 });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> validateOffsets =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 4, 8, 12, 16 });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(connectivityArray, validateConnectivity),
|
||||||
|
"wrong connectivity array");
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(shapesArray, validateShapes),
|
||||||
|
"wrong connectivity array");
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(offsetsArray, validateOffsets),
|
||||||
|
"wrong connectivity array");
|
||||||
|
// validating fields
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>(
|
||||||
|
{ 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f, 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validateCellVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>({ 100.1f, 200.1f, 100.1f, 200.1f });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result.GetPartition(0).GetField("pointVar").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0).GetField("cellVar").GetData(), validateCellVar),
|
||||||
|
"wrong cellVar values");
|
||||||
|
//validating coordinates
|
||||||
|
vtkm::cont::CoordinateSystem coords = result.GetPartition(0).GetCoordinateSystem();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> resultCoords =
|
||||||
|
coords.GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Vec3f>>();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> validateCoords =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Vec3f>({ { 0, 0, 0 },
|
||||||
|
{ 1, 0, 0 },
|
||||||
|
{ 2, 0, 0 },
|
||||||
|
{ 0, 1, 0 },
|
||||||
|
{ 1, 1, 0 },
|
||||||
|
{ 2, 1, 0 },
|
||||||
|
{ 3, 0, 0 },
|
||||||
|
{ 4, 0, 0 },
|
||||||
|
{ 5, 0, 0 },
|
||||||
|
{ 3, 1, 0 },
|
||||||
|
{ 4, 1, 0 },
|
||||||
|
{ 5, 1, 0 } });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(resultCoords, validateCoords),
|
||||||
|
"wrong validateCoords values");
|
||||||
|
}
|
||||||
|
void TestTriangleSameFieldsSameDataType()
|
||||||
|
{
|
||||||
|
std::cout << "TestTriangleSameFieldsSameDataType" << std::endl;
|
||||||
|
vtkm::cont::PartitionedDataSet input;
|
||||||
|
vtkm::cont::DataSetBuilderUniform dsb;
|
||||||
|
vtkm::Id3 dimensions(3, 2, 1);
|
||||||
|
vtkm::cont::DataSet dataSet0 = dsb.Create(dimensions,
|
||||||
|
vtkm::make_Vec<vtkm::FloatDefault>(0, 0, 0),
|
||||||
|
vtkm::make_Vec<vtkm::FloatDefault>(1, 1, 0));
|
||||||
|
constexpr vtkm::Id nVerts = 6;
|
||||||
|
constexpr vtkm::Float32 var[nVerts] = { 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f };
|
||||||
|
dataSet0.AddPointField("pointVar", var, nVerts);
|
||||||
|
constexpr vtkm::Float32 cellvar[2] = { 100.1f, 200.1f };
|
||||||
|
dataSet0.AddCellField("cellVar", cellvar, 2);
|
||||||
|
vtkm::filter::geometry_refinement::Triangulate triangulate;
|
||||||
|
auto tranDataSet0 = triangulate.Execute(dataSet0);
|
||||||
|
vtkm::cont::DataSet dataSet1 = dsb.Create(dimensions,
|
||||||
|
vtkm::make_Vec<vtkm::FloatDefault>(3, 0, 0),
|
||||||
|
vtkm::make_Vec<vtkm::FloatDefault>(1, 1, 0));
|
||||||
|
constexpr vtkm::Float32 var1[nVerts] = { 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f };
|
||||||
|
dataSet1.AddPointField("pointVar", var1, nVerts);
|
||||||
|
constexpr vtkm::Float32 cellvar1[2] = { 100.1f, 200.1f };
|
||||||
|
dataSet1.AddCellField("cellVar", cellvar1, 2);
|
||||||
|
auto tranDataSet1 = triangulate.Execute(dataSet1);
|
||||||
|
input.AppendPartition(tranDataSet0);
|
||||||
|
input.AppendPartition(tranDataSet1);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
auto result = mergeDataSets.Execute(input);
|
||||||
|
//validating results
|
||||||
|
auto cellSet = result.GetPartition(0).GetCellSet();
|
||||||
|
vtkm::cont::CellSetSingleType<> singleType = cellSet.AsCellSet<vtkm::cont::CellSetSingleType<>>();
|
||||||
|
VTKM_TEST_ASSERT(singleType.GetCellShapeAsId() == 5, "Wrong cellShape Id");
|
||||||
|
VTKM_TEST_ASSERT(cellSet.GetNumberOfCells() == 8, "Wrong numberOfCells");
|
||||||
|
VTKM_TEST_ASSERT(cellSet.GetNumberOfPoints() == 12, "Wrong numberOfPoints");
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id> connectivityArray = singleType.GetConnectivityArray(
|
||||||
|
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> validateConnArray = vtkm::cont::make_ArrayHandle<vtkm::Id>(
|
||||||
|
{ 0, 1, 4, 0, 4, 3, 1, 2, 5, 1, 5, 4, 6, 7, 10, 6, 10, 9, 7, 8, 11, 7, 11, 10 });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(connectivityArray, validateConnArray));
|
||||||
|
//Validating result fields
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>(
|
||||||
|
{ 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f, 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validateCellVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>(
|
||||||
|
{ 100.1f, 100.1f, 200.1f, 200.1f, 100.1f, 100.1f, 200.1f, 200.1f });
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result.GetPartition(0).GetField("pointVar").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0).GetField("cellVar").GetData(), validateCellVar),
|
||||||
|
"wrong cellVar values");
|
||||||
|
//Validating result coordinates
|
||||||
|
vtkm::cont::CoordinateSystem coords = result.GetPartition(0).GetCoordinateSystem();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> resultCoords =
|
||||||
|
coords.GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Vec3f>>();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> validateCoords =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Vec3f>({ { 0, 0, 0 },
|
||||||
|
{ 1, 0, 0 },
|
||||||
|
{ 2, 0, 0 },
|
||||||
|
{ 0, 1, 0 },
|
||||||
|
{ 1, 1, 0 },
|
||||||
|
{ 2, 1, 0 },
|
||||||
|
{ 3, 0, 0 },
|
||||||
|
{ 4, 0, 0 },
|
||||||
|
{ 5, 0, 0 },
|
||||||
|
{ 3, 1, 0 },
|
||||||
|
{ 4, 1, 0 },
|
||||||
|
{ 5, 1, 0 } });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(resultCoords, validateCoords),
|
||||||
|
"wrong validateCoords values");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestDiffCellsSameFieldsSameDataType()
|
||||||
|
{
|
||||||
|
std::cout << "TestDiffCellsSameFieldsSameDataType" << std::endl;
|
||||||
|
vtkm::Vec3f coordinates1[4] = { vtkm::Vec3f(0.0, 0.0, 0.0),
|
||||||
|
vtkm::Vec3f(1.0, 0.0, 0.0),
|
||||||
|
vtkm::Vec3f(0.0, 1.0, 0.0),
|
||||||
|
vtkm::Vec3f(1.0, 1.0, 0.0) };
|
||||||
|
vtkm::cont::DataSet dataSet0 = CreateSingleCellSetData(coordinates1);
|
||||||
|
vtkm::cont::DataSet dataSet1 = CreateUniformData(vtkm::Vec2f(3.0, 0.0));
|
||||||
|
vtkm::cont::PartitionedDataSet input;
|
||||||
|
input.AppendPartition(dataSet0);
|
||||||
|
input.AppendPartition(dataSet1);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
auto result = mergeDataSets.Execute(input);
|
||||||
|
//validating cellsets
|
||||||
|
auto cellSet = result.GetPartition(0).GetCellSet();
|
||||||
|
vtkm::cont::CellSetExplicit<> explicitType = cellSet.AsCellSet<vtkm::cont::CellSetExplicit<>>();
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id> connectivityArray = explicitType.GetConnectivityArray(
|
||||||
|
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::UInt8> shapesArray =
|
||||||
|
explicitType.GetShapesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray =
|
||||||
|
explicitType.GetOffsetsArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> validateConnectivity =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 1, 2, 1, 2, 3, 4, 5, 8, 7, 5, 6, 9, 8 });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::UInt8> validateShapes =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::UInt8>({ 5, 5, 9, 9 });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> validateOffsets =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 3, 6, 10, 14 });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(connectivityArray, validateConnectivity),
|
||||||
|
"wrong connectivity array");
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(shapesArray, validateShapes),
|
||||||
|
"wrong connectivity array");
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(offsetsArray, validateOffsets),
|
||||||
|
"wrong connectivity array");
|
||||||
|
// Validating fields
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>(
|
||||||
|
{ 15.f, 16.f, 17.f, 18.f, 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validateCellVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>({ 132.0f, 133.0f, 100.1f, 200.1f });
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result.GetPartition(0).GetField("pointVar").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0).GetField("cellVar").GetData(), validateCellVar),
|
||||||
|
"wrong cellVar values");
|
||||||
|
//Validating coordinates
|
||||||
|
vtkm::cont::CoordinateSystem coords = result.GetPartition(0).GetCoordinateSystem();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> resultCoords =
|
||||||
|
coords.GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Vec3f>>();
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> validateCoords =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Vec3f>({ { 0, 0, 0 },
|
||||||
|
{ 1, 0, 0 },
|
||||||
|
{ 0, 1, 0 },
|
||||||
|
{ 1, 1, 0 },
|
||||||
|
{ 3, 0, 0 },
|
||||||
|
{ 4, 0, 0 },
|
||||||
|
{ 5, 0, 0 },
|
||||||
|
{ 3, 1, 0 },
|
||||||
|
{ 4, 1, 0 },
|
||||||
|
{ 5, 1, 0 } });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(resultCoords, validateCoords), "Wrong coords values");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestDifferentCoords()
|
||||||
|
{
|
||||||
|
std::cout << "TestDifferentCoords" << std::endl;
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets;
|
||||||
|
vtkm::cont::DataSet dataSet0 = CreateUniformData(vtkm::Vec2f(0.0, 0.0));
|
||||||
|
vtkm::Vec3f coordinates[6];
|
||||||
|
dataSet0.AddCoordinateSystem(
|
||||||
|
vtkm::cont::make_CoordinateSystem("coordsExtra", coordinates, 6, vtkm::CopyFlag::On));
|
||||||
|
vtkm::cont::DataSet dataSet1 = CreateUniformData(vtkm::Vec2f(3.0, 0.0));
|
||||||
|
inputDataSets.AppendPartition(dataSet0);
|
||||||
|
inputDataSets.AppendPartition(dataSet1);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets);
|
||||||
|
}
|
||||||
|
catch (vtkm::cont::ErrorExecution& e)
|
||||||
|
{
|
||||||
|
VTKM_TEST_ASSERT(e.GetMessage().find("Data sets have different number of coordinate systems") !=
|
||||||
|
std::string::npos);
|
||||||
|
}
|
||||||
|
vtkm::cont::DataSetBuilderUniform dsb;
|
||||||
|
vtkm::Id2 dimensions(3, 2);
|
||||||
|
vtkm::cont::DataSet dataSet2 = dsb.Create(dimensions, vtkm::Vec2f(0.0, 0.0), vtkm::Vec2f(1, 1));
|
||||||
|
constexpr vtkm::Float32 var2[6] = { 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f };
|
||||||
|
dataSet2.AddPointField("pointVarExtra", var2, 6);
|
||||||
|
constexpr vtkm::Float32 cellvar2[2] = { 100.1f, 200.1f };
|
||||||
|
dataSet2.AddCellField("cellVarExtra", cellvar2, 2);
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets2;
|
||||||
|
inputDataSets2.AppendPartition(dataSet1);
|
||||||
|
inputDataSets2.AppendPartition(dataSet2);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets2);
|
||||||
|
}
|
||||||
|
catch (vtkm::cont::ErrorExecution& e)
|
||||||
|
{
|
||||||
|
VTKM_TEST_ASSERT(e.GetMessage().find("Coordinates system name:") != std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSameFieldsDifferentDataType()
|
||||||
|
{
|
||||||
|
std::cout << "TestSameFieldsDifferentDataType" << std::endl;
|
||||||
|
vtkm::cont::DataSetBuilderUniform dsb;
|
||||||
|
vtkm::Id2 dimensions(3, 2);
|
||||||
|
vtkm::cont::DataSet dataSet1 = dsb.Create(dimensions, vtkm::Vec2f(0.0, 0.0), vtkm::Vec2f(1, 1));
|
||||||
|
constexpr vtkm::Float32 var[6] = { 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f };
|
||||||
|
dataSet1.AddPointField("pointVar", var, 6);
|
||||||
|
constexpr vtkm::Float32 cellvar[2] = { 100.1f, 200.1f };
|
||||||
|
dataSet1.AddCellField("cellVar", cellvar, 2);
|
||||||
|
vtkm::cont::DataSet dataSet2 = dsb.Create(dimensions, vtkm::Vec2f(0.0, 0.0), vtkm::Vec2f(1, 1));
|
||||||
|
constexpr vtkm::Id var2[6] = { 10, 20, 30, 40, 50, 60 };
|
||||||
|
dataSet2.AddPointField("pointVar", var2, 6);
|
||||||
|
constexpr vtkm::Id cellvar2[2] = { 100, 200 };
|
||||||
|
dataSet2.AddCellField("cellVar", cellvar2, 2);
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets;
|
||||||
|
inputDataSets.AppendPartition(dataSet1);
|
||||||
|
inputDataSets.AppendPartition(dataSet2);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets);
|
||||||
|
//Validating fields in results, they will use the first partition's field type
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>(
|
||||||
|
{ 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validateCellVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>({ 100.1f, 200.1f, 100.0f, 200.0f });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result.GetPartition(0).GetField("pointVar").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0).GetField("cellVar").GetData(), validateCellVar),
|
||||||
|
"wrong cellVar values");
|
||||||
|
}
|
||||||
|
void TestMissingFieldsAndSameFieldName()
|
||||||
|
{
|
||||||
|
std::cout << "TestMissingFieldsAndSameFieldName" << std::endl;
|
||||||
|
vtkm::cont::DataSetBuilderUniform dsb;
|
||||||
|
vtkm::Id2 dimensions(3, 2);
|
||||||
|
vtkm::cont::DataSet dataSet1 = dsb.Create(dimensions, vtkm::Vec2f(0.0, 0.0), vtkm::Vec2f(1, 1));
|
||||||
|
constexpr vtkm::Float32 pointVar[6] = { 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f };
|
||||||
|
vtkm::cont::DataSet dataSet2 = dsb.Create(dimensions, vtkm::Vec2f(0.0, 0.0), vtkm::Vec2f(1, 1));
|
||||||
|
constexpr vtkm::Id cellvar[2] = { 100, 200 };
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets;
|
||||||
|
dataSet1.AddPointField("pointVar", pointVar, 6);
|
||||||
|
dataSet2.AddCellField("cellVar", cellvar, 2);
|
||||||
|
//For testing the case where one field is associated with point in one partition
|
||||||
|
//and one field (with a same name) is associated with cell in another partition
|
||||||
|
dataSet1.AddPointField("fieldSameName", pointVar, 6);
|
||||||
|
dataSet2.AddCellField("fieldSameName", cellvar, 2);
|
||||||
|
//For testing the case where one partition have point field and a cell field with the same name.
|
||||||
|
dataSet1.AddPointField("fieldSameName2", pointVar, 6);
|
||||||
|
dataSet2.AddPointField("fieldSameName2", pointVar, 6);
|
||||||
|
dataSet2.AddCellField("fieldSameName2", cellvar, 2);
|
||||||
|
inputDataSets.AppendPartition(dataSet1);
|
||||||
|
inputDataSets.AppendPartition(dataSet2);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
mergeDataSets.SetInvalidValue(vtkm::Float64(0));
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets);
|
||||||
|
//Validating fields in results, they will use InvalidValues for missing fields
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar1 =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>(
|
||||||
|
{ 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar2 =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>(
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar3 =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>(
|
||||||
|
{ 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f, 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> validateCellVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 0, 100, 200 });
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(
|
||||||
|
result.GetPartition(0).GetField("pointVar", vtkm::cont::Field::Association::Points).GetData(),
|
||||||
|
validatePointVar1),
|
||||||
|
"wrong pointVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(
|
||||||
|
result.GetPartition(0).GetField("cellVar", vtkm::cont::Field::Association::Cells).GetData(),
|
||||||
|
validateCellVar),
|
||||||
|
"wrong cellVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0)
|
||||||
|
.GetField("fieldSameName", vtkm::cont::Field::Association::Points)
|
||||||
|
.GetData(),
|
||||||
|
validatePointVar1),
|
||||||
|
"wrong fieldSameName values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0)
|
||||||
|
.GetField("fieldSameName", vtkm::cont::Field::Association::Cells)
|
||||||
|
.GetData(),
|
||||||
|
validateCellVar),
|
||||||
|
"wrong fieldSameName values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0)
|
||||||
|
.GetField("fieldSameName2", vtkm::cont::Field::Association::Points)
|
||||||
|
.GetData(),
|
||||||
|
validatePointVar3),
|
||||||
|
"wrong fieldSameName2 values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0)
|
||||||
|
.GetField("fieldSameName2", vtkm::cont::Field::Association::Cells)
|
||||||
|
.GetData(),
|
||||||
|
validateCellVar),
|
||||||
|
"wrong fieldSameName2 values");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCustomizedVecField()
|
||||||
|
{
|
||||||
|
std::cout << "TestCustomizedVecField" << std::endl;
|
||||||
|
vtkm::cont::DataSetBuilderUniform dsb;
|
||||||
|
vtkm::Id2 dimensions(3, 2);
|
||||||
|
vtkm::cont::DataSet dataSet1 = dsb.Create(dimensions, vtkm::Vec2f(0.0, 0.0), vtkm::Vec2f(1, 1));
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 4>> pointVar1Vec4;
|
||||||
|
pointVar1Vec4.Allocate(6);
|
||||||
|
vtkm::cont::Invoker invoker;
|
||||||
|
invoker(SetPointValuesV4Worklet{}, dataSet1.GetCoordinateSystem().GetData(), pointVar1Vec4);
|
||||||
|
dataSet1.AddPointField("pointVarV4", pointVar1Vec4);
|
||||||
|
vtkm::cont::DataSet dataSet2 = dsb.Create(dimensions, vtkm::Vec2f(3.0, 0.0), vtkm::Vec2f(1, 1));
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 4>> pointVar2Vec4;
|
||||||
|
pointVar2Vec4.Allocate(6);
|
||||||
|
invoker(SetPointValuesV4Worklet{}, dataSet2.GetCoordinateSystem().GetData(), pointVar2Vec4);
|
||||||
|
dataSet2.AddPointField("pointVarV4", pointVar2Vec4);
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets;
|
||||||
|
inputDataSets.AppendPartition(dataSet1);
|
||||||
|
inputDataSets.AppendPartition(dataSet2);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets);
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 4>> validatePointVar;
|
||||||
|
//Set point validatePointVar array based on coordinates.
|
||||||
|
invoker(SetPointValuesV4Worklet{},
|
||||||
|
result.GetPartition(0).GetCoordinateSystem().GetData(),
|
||||||
|
validatePointVar);
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result.GetPartition(0).GetField("pointVarV4").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestMoreThanTwoPartitions()
|
||||||
|
{
|
||||||
|
std::cout << "TestMoreThanTwoPartitions" << std::endl;
|
||||||
|
vtkm::cont::DataSetBuilderUniform dsb;
|
||||||
|
vtkm::Id2 dimensions(3, 2);
|
||||||
|
vtkm::cont::Invoker invoker;
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets;
|
||||||
|
for (vtkm::Id i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
for (vtkm::Id j = 0; j < 5; j++)
|
||||||
|
{
|
||||||
|
vtkm::cont::DataSet dataSet = dsb.Create(
|
||||||
|
dimensions,
|
||||||
|
vtkm::Vec2f(static_cast<vtkm::FloatDefault>(i), static_cast<vtkm::FloatDefault>(j)),
|
||||||
|
vtkm::Vec2f(1, 1));
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float64> pointVarArray;
|
||||||
|
invoker(SetPointValuesV1Worklet{}, dataSet.GetCoordinateSystem().GetData(), pointVarArray);
|
||||||
|
dataSet.AddPointField("pointVar", pointVarArray);
|
||||||
|
inputDataSets.AppendPartition(dataSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets);
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float64> validatePointVar;
|
||||||
|
invoker(SetPointValuesV1Worklet{},
|
||||||
|
result.GetPartition(0).GetCoordinateSystem().GetData(),
|
||||||
|
validatePointVar);
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result.GetPartition(0).GetField("pointVar").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestEmptyPartitions()
|
||||||
|
{
|
||||||
|
std::cout << "TestEmptyPartitions" << std::endl;
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets;
|
||||||
|
vtkm::cont::DataSet dataSet1 = CreateUniformData(vtkm::Vec2f(0.0, 0.0));
|
||||||
|
vtkm::cont::DataSet dataSet2;
|
||||||
|
inputDataSets.AppendPartition(dataSet1);
|
||||||
|
inputDataSets.AppendPartition(dataSet2);
|
||||||
|
vtkm::filter::multi_block::MergeDataSets mergeDataSets;
|
||||||
|
auto result = mergeDataSets.Execute(inputDataSets);
|
||||||
|
//Validating data sets
|
||||||
|
VTKM_TEST_ASSERT(result.GetNumberOfPartitions() == 1, "Wrong number of partitions");
|
||||||
|
auto cellSet = result.GetPartition(0).GetCellSet();
|
||||||
|
VTKM_TEST_ASSERT(cellSet.GetNumberOfCells() == 2, "Wrong numberOfCells");
|
||||||
|
VTKM_TEST_ASSERT(cellSet.GetNumberOfPoints() == 6, "Wrong numberOfPoints");
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validatePointVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>({ 10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f });
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Float32> validateCellVar =
|
||||||
|
vtkm::cont::make_ArrayHandle<vtkm::Float32>({ 100.1f, 200.1f });
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result.GetPartition(0).GetField("pointVar").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result.GetPartition(0).GetField("cellVar").GetData(), validateCellVar),
|
||||||
|
"wrong cellVar values");
|
||||||
|
vtkm::cont::PartitionedDataSet inputDataSets2;
|
||||||
|
inputDataSets2.AppendPartition(dataSet2);
|
||||||
|
inputDataSets2.AppendPartition(dataSet1);
|
||||||
|
auto result2 = mergeDataSets.Execute(inputDataSets2);
|
||||||
|
VTKM_TEST_ASSERT(result2.GetNumberOfPartitions() == 1, "Wrong number of partitions");
|
||||||
|
cellSet = result2.GetPartition(0).GetCellSet();
|
||||||
|
VTKM_TEST_ASSERT(cellSet.GetNumberOfCells() == 2, "Wrong numberOfCells");
|
||||||
|
VTKM_TEST_ASSERT(cellSet.GetNumberOfPoints() == 6, "Wrong numberOfPoints");
|
||||||
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(result2.GetPartition(0).GetField("pointVar").GetData(),
|
||||||
|
validatePointVar),
|
||||||
|
"wrong pointVar values");
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_ArrayHandles(result2.GetPartition(0).GetField("cellVar").GetData(), validateCellVar),
|
||||||
|
"wrong cellVar values");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestMergeDataSetsFilter()
|
||||||
|
{
|
||||||
|
//same cell type (triangle), same field name, same data type, cellset is single type
|
||||||
|
TestUniformSameFieldsSameDataTypeSingleCellSet();
|
||||||
|
//same cell type (square), same field name, same data type
|
||||||
|
TestUniformSameFieldsSameDataType();
|
||||||
|
//same cell type (triangle), same field name, same data type
|
||||||
|
TestTriangleSameFieldsSameDataType();
|
||||||
|
//same cell type (square), same field name, different data type
|
||||||
|
TestSameFieldsDifferentDataType();
|
||||||
|
//different coordinates name
|
||||||
|
TestDifferentCoords();
|
||||||
|
//different cell types, same field name, same type
|
||||||
|
TestDiffCellsSameFieldsSameDataType();
|
||||||
|
//test multiple partitions
|
||||||
|
TestMoreThanTwoPartitions();
|
||||||
|
//some partitions have missing fields
|
||||||
|
TestMissingFieldsAndSameFieldName();
|
||||||
|
//test empty partitions
|
||||||
|
TestEmptyPartitions();
|
||||||
|
//test customized types
|
||||||
|
TestCustomizedVecField();
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
int UnitTestMergeDataSetsFilter(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::Run(TestMergeDataSetsFilter, argc, argv);
|
||||||
|
}
|
@ -10,3 +10,4 @@ TEST_DEPENDS
|
|||||||
vtkm_source
|
vtkm_source
|
||||||
vtkm_rendering
|
vtkm_rendering
|
||||||
vtkm_rendering_testing
|
vtkm_rendering_testing
|
||||||
|
vtkm_filter_geometry_refinement
|
||||||
|
Loading…
Reference in New Issue
Block a user