//============================================================================ // 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 #include #include #include #include #include #include #include #include #define CHECK_CALL(call) \ VTKM_TEST_ASSERT((call) == vtkm::ErrorCode::Success, "Call resulted in error.") namespace { static constexpr vtkm::IdComponent MAX_POINTS = 8; template void GetMinMaxPoints(CellShapeTag, vtkm::CellTraitsTagSizeFixed, vtkm::IdComponent& minPoints, vtkm::IdComponent& maxPoints) { // If this line fails, then MAX_POINTS is not large enough to support all // cell shapes. VTKM_STATIC_ASSERT((vtkm::CellTraits::NUM_POINTS <= MAX_POINTS)); minPoints = maxPoints = vtkm::CellTraits::NUM_POINTS; } template void GetMinMaxPoints(CellShapeTag, vtkm::CellTraitsTagSizeVariable, vtkm::IdComponent& minPoints, vtkm::IdComponent& maxPoints) { minPoints = 1; maxPoints = MAX_POINTS; } template struct TestInterpolateFunctor { using ComponentType = typename vtkm::VecTraits::ComponentType; template void DoTestWithField(CellShapeTag shape, const FieldVecType& fieldValues) const { vtkm::IdComponent numPoints = fieldValues.GetNumberOfComponents(); if (numPoints < 1) { return; } FieldType averageValue = vtkm::TypeTraits::ZeroInitialization(); for (vtkm::IdComponent pointIndex = 0; pointIndex < numPoints; pointIndex++) { averageValue = averageValue + fieldValues[pointIndex]; } averageValue = static_cast(1.0 / numPoints) * averageValue; for (vtkm::IdComponent pointIndex = 0; pointIndex < numPoints; pointIndex++) { vtkm::Vec3f pcoord; CHECK_CALL(vtkm::exec::ParametricCoordinatesPoint(numPoints, pointIndex, shape, pcoord)); FieldType interpolatedValue; CHECK_CALL(vtkm::exec::CellInterpolate(fieldValues, pcoord, shape, interpolatedValue)); VTKM_TEST_ASSERT(test_equal(fieldValues[pointIndex], interpolatedValue), "Interpolation at point not point value."); } vtkm::Vec3f pcoord; CHECK_CALL(vtkm::exec::ParametricCoordinatesCenter(numPoints, shape, pcoord)); FieldType interpolatedValue; CHECK_CALL(vtkm::exec::CellInterpolate(fieldValues, pcoord, shape, interpolatedValue)); VTKM_TEST_ASSERT(test_equal(averageValue, interpolatedValue), "Interpolation at center not average value."); } template void DoTestWithIndices(CellShapeTag shape, const IndexVecType& pointIndices, const FieldPortalType& fieldValues) const { vtkm::IdComponent numPoints = pointIndices.GetNumberOfComponents(); if (numPoints < 1) { return; } FieldType averageValue = vtkm::TypeTraits::ZeroInitialization(); for (vtkm::IdComponent pointIndex = 0; pointIndex < numPoints; pointIndex++) { averageValue = averageValue + fieldValues.Get(pointIndices[pointIndex]); } averageValue = static_cast(1.0 / numPoints) * averageValue; for (vtkm::IdComponent pointIndex = 0; pointIndex < numPoints; pointIndex++) { vtkm::Vec3f pcoord; CHECK_CALL(vtkm::exec::ParametricCoordinatesPoint(numPoints, pointIndex, shape, pcoord)); FieldType interpolatedValue; CHECK_CALL( vtkm::exec::CellInterpolate(pointIndices, fieldValues, pcoord, shape, interpolatedValue)); VTKM_TEST_ASSERT(test_equal(fieldValues.Get(pointIndices[pointIndex]), interpolatedValue), "Interpolation at point not point value."); } if (shape.Id != vtkm::CELL_SHAPE_POLY_LINE) { vtkm::Vec3f pcoord; CHECK_CALL(vtkm::exec::ParametricCoordinatesCenter(numPoints, shape, pcoord)); FieldType interpolatedValue; CHECK_CALL( vtkm::exec::CellInterpolate(pointIndices, fieldValues, pcoord, shape, interpolatedValue)); VTKM_TEST_ASSERT(test_equal(averageValue, interpolatedValue), "Interpolation at center not average value."); } } template void DoTest(CellShapeTag shape, vtkm::IdComponent numPoints) const { vtkm::VecVariable fieldValues; for (vtkm::IdComponent pointIndex = 0; pointIndex < numPoints; pointIndex++) { FieldType value = TestValue(pointIndex + 1, FieldType()); fieldValues.Append(value); } this->DoTestWithField(shape, fieldValues); vtkm::cont::ArrayHandle fieldArray; fieldArray.Allocate(41); SetPortal(fieldArray.WritePortal()); vtkm::VecVariable pointIndices; for (vtkm::IdComponent pointIndex = 0; pointIndex < numPoints; pointIndex++) { vtkm::Id globalIndex = (7 + (13 * pointIndex)) % 41; pointIndices.Append(globalIndex); } this->DoTestWithIndices(shape, pointIndices, fieldArray.ReadPortal()); } template void operator()(CellShapeTag) const { vtkm::IdComponent minPoints; vtkm::IdComponent maxPoints; GetMinMaxPoints( CellShapeTag(), typename vtkm::CellTraits::IsSizeFixed(), minPoints, maxPoints); for (vtkm::IdComponent numPoints = minPoints; numPoints <= maxPoints; numPoints++) { this->DoTest(CellShapeTag(), numPoints); } vtkm::CellShapeTagGeneric genericShape(CellShapeTag::Id); for (vtkm::IdComponent numPoints = minPoints; numPoints <= maxPoints; numPoints++) { this->DoTest(genericShape, numPoints); } } }; void TestInterpolate() { std::cout << "======== Float32 ==========================" << std::endl; vtkm::testing::Testing::TryAllCellShapes(TestInterpolateFunctor()); std::cout << "======== Float64 ==========================" << std::endl; vtkm::testing::Testing::TryAllCellShapes(TestInterpolateFunctor()); std::cout << "======== Vec ===================" << std::endl; vtkm::testing::Testing::TryAllCellShapes(TestInterpolateFunctor()); std::cout << "======== Vec ===================" << std::endl; vtkm::testing::Testing::TryAllCellShapes(TestInterpolateFunctor()); TestInterpolateFunctor testFunctor; vtkm::Vec3f origin = TestValue(0, vtkm::Vec3f()); vtkm::Vec3f spacing = TestValue(1, vtkm::Vec3f()); std::cout << "======== Uniform Point Coordinates 1D =====" << std::endl; testFunctor.DoTestWithField(vtkm::CellShapeTagLine(), vtkm::VecAxisAlignedPointCoordinates<1>(origin, spacing)); std::cout << "======== Uniform Point Coordinates 2D =====" << std::endl; testFunctor.DoTestWithField(vtkm::CellShapeTagQuad(), vtkm::VecAxisAlignedPointCoordinates<2>(origin, spacing)); std::cout << "======== Uniform Point Coordinates 3D =====" << std::endl; testFunctor.DoTestWithField(vtkm::CellShapeTagHexahedron(), vtkm::VecAxisAlignedPointCoordinates<3>(origin, spacing)); } } // anonymous namespace int UnitTestCellInterpolate(int argc, char* argv[]) { return vtkm::cont::testing::Testing::Run(TestInterpolate, argc, argv); }