//============================================================================ // 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS). // Copyright 2017 UT-Battelle, LLC. // Copyright 2017 Los Alamos National Security. // // Under the terms of Contract DE-NA0003525 with NTESS, // 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 #include #include #include #include #include #include #include namespace { struct WorkletPointToCell : public vtkm::worklet::WorkletMapPointToCell { using ControlSignature = void(CellSetIn cellset, FieldOutCell numPoints); using ExecutionSignature = void(PointIndices, _2); using InputDomain = _1; template VTKM_EXEC void operator()(const PointIndicesType& pointIndices, vtkm::Id& numPoints) const { numPoints = pointIndices.GetNumberOfComponents(); } }; struct WorkletCellToPoint : public vtkm::worklet::WorkletMapCellToPoint { using ControlSignature = void(CellSetIn cellset, FieldOutPoint numCells); using ExecutionSignature = void(CellIndices, _2); using InputDomain = _1; template VTKM_EXEC void operator()(const CellIndicesType& cellIndices, vtkm::Id& numCells) const { numCells = cellIndices.GetNumberOfComponents(); } }; struct CellsOfPoint : public vtkm::worklet::WorkletMapCellToPoint { using ControlSignature = void(CellSetIn cellset, FieldInPoint offset, WholeArrayOut cellIds); using ExecutionSignature = void(CellIndices, _2, _3); using InputDomain = _1; template 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 std::vector ComputeCellToPointExpected(const CellSetType& cellset, const PermutationArrayHandleType& permutation) { vtkm::cont::ArrayHandle numIndices; vtkm::worklet::DispatcherMapTopology().Invoke(cellset, numIndices); std::cout << "\n"; vtkm::cont::ArrayHandle indexOffsets; vtkm::Id connectivityLength = vtkm::cont::DeviceAdapterAlgorithm::ScanExclusive( numIndices, indexOffsets); vtkm::cont::ArrayHandle connectivity; connectivity.Allocate(connectivityLength); vtkm::worklet::DispatcherMapTopology().Invoke(cellset, indexOffsets, connectivity); std::vector permutationMask(static_cast(cellset.GetNumberOfCells()), false); for (vtkm::Id i = 0; i < permutation.GetNumberOfValues(); ++i) { permutationMask[static_cast(permutation.GetPortalConstControl().Get(i))] = true; } vtkm::Id numberOfPoints = cellset.GetNumberOfPoints(); std::vector expected(static_cast(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(cellId)]) { ++expected[static_cast(i)]; } } } return expected; } template vtkm::cont::CellSetPermutation> TestCellSet( const CellSetType& cellset) { vtkm::Id numberOfCells = cellset.GetNumberOfCells() / 2; vtkm::cont::ArrayHandleCounting permutation(0, 2, numberOfCells); auto cs = vtkm::cont::make_CellSetPermutation(permutation, cellset); vtkm::cont::ArrayHandle result; std::cout << "\t\tTesting PointToCell\n"; vtkm::worklet::DispatcherMapTopology().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().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(i)], "incorrect result"); } return cs; } template 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>()); std::cout << "Testing CellSetStructured<3>\n"; dataset = maker.Make3DUniformDataSet1(); RunTests(dataset.GetCellSet().Cast>()); std::cout << "Testing CellSetExplicit\n"; dataset = maker.Make3DExplicitDataSetPolygonal(); RunTests(dataset.GetCellSet().Cast>()); std::cout << "Testing CellSetSingleType\n"; dataset = maker.Make3DExplicitDataSetCowNose(); RunTests(dataset.GetCellSet().Cast>()); } } // anonymous namespace int UnitTestCellSetPermutation(int, char* []) { return vtkm::cont::testing::Testing::Run(TestCellSetPermutation); }