diff --git a/docs/changelog/warp-scalar-worklet-filter.md b/docs/changelog/warp-scalar-worklet-filter.md new file mode 100644 index 000000000..102d30325 --- /dev/null +++ b/docs/changelog/warp-scalar-worklet-filter.md @@ -0,0 +1,7 @@ +Add a warpScalar worklet and filter + +This commit adds a worklet as well as a filter that modify point coordinates by moving points +along point normals by the scalar amount times the scalar factor. +It's a simpified version of the vtkWarpScalar class in VTK. Additionally the filter doesn't +modify the point coordinates, but creates a new point coordinates that have been warped. + diff --git a/vtkm/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt index 56fd4bb96..6199ce95c 100644 --- a/vtkm/filter/CMakeLists.txt +++ b/vtkm/filter/CMakeLists.txt @@ -63,6 +63,7 @@ set(headers Triangulate.h VectorMagnitude.h VertexClustering.h + WarpScalar.h WarpVector.h ) @@ -106,6 +107,7 @@ set(header_template_sources Triangulate.hxx VectorMagnitude.hxx VertexClustering.hxx + WarpScalar.hxx WarpVector.hxx ) diff --git a/vtkm/filter/WarpScalar.h b/vtkm/filter/WarpScalar.h new file mode 100644 index 000000000..5a591e7fa --- /dev/null +++ b/vtkm/filter/WarpScalar.h @@ -0,0 +1,163 @@ +//============================================================================ +// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 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. +//============================================================================ + +#ifndef vtk_m_filter_WarpScalar_h +#define vtk_m_filter_WarpScalar_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +/// \brief Modify points by moving points along point normals by the scalar +/// amount times the scalar factor. +/// +/// A filter that modifies point coordinates by moving points along point normals +/// by the scalar amount times the scalar factor. +/// It's a VTK-m version of the vtkWarpScalar in VTK. +/// Useful for creating carpet or x-y-z plots. +/// It doesn't modify the point coordinates, but creates a new point coordinates that have been warped. +class WarpScalar : public vtkm::filter::FilterField +{ +public: + VTKM_CONT + WarpScalar(vtkm::FloatDefault scaleAmount); + + //@{ + /// Choose the primary field to operate on. In the warp op A + B * + /// scaleAmount * scalarFactor, A is the primary field + VTKM_CONT + void SetPrimaryField( + const std::string& name, + vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) + { + this->SetActiveField(name, association); + } + //@} + + VTKM_CONT const std::string& GetPrimaryFieldName() const { return this->GetActiveFieldName(); } + + VTKM_CONT vtkm::cont::Field::Association GetPrimaryFieldAssociation() const + { + return this->GetActiveFieldAssociation(); + } + + //@{ + /// When set to true, filter uses a coordinate system as the primary field instead of the one selected + /// by name. Use SetPrimaryCoordinateSystem to select which coordinate system. + VTKM_CONT + void SetUseCoordinateSystemAsPrimaryField(bool flag) + { + this->SetUseCoordinateSystemAsField(flag); + } + VTKM_CONT + bool GetUseCoordinateSystemAsPrimaryField() const + { + return this->GetUseCoordinateSystemAsField(); + } + //@} + + //@{ + /// Select the coordinate system index to use as the primary field. This only has an effect when + /// UseCoordinateSystemAsPrimaryField is true. + VTKM_CONT + void SetPrimaryCoordinateSystem(vtkm::Id index) { this->SetActiveCoordinateSystem(index); } + VTKM_CONT + vtkm::Id GetPrimaryCoordinateSystemIndex() const + { + return this->GetActiveCoordinateSystemIndex(); + } + //@} + + //@{ + /// Choose the secondary field to operate on. In the warp op A + B * + /// scaleAmount * scalarFactor, B is the secondary field + VTKM_CONT + void SetNormalField( + const std::string& name, + vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) + { + this->NormalFieldName = name; + this->NormalFieldAssociation = association; + } + + VTKM_CONT const std::string& GetNormalFieldName() const { return this->NormalFieldName; } + + VTKM_CONT vtkm::cont::Field::Association GetNormalFieldAssociation() const + { + return this->NormalFieldAssociation; + } + //@} + + //@{ + /// Choose the scalar factor field to operate on. In the warp op A + B * + /// scaleAmount * scalarFactor, scalarFactor is the scalar factor field. + VTKM_CONT + void SetScarlarFactorField( + const std::string& name, + vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) + { + this->ScalarFactorFieldName = name; + this->ScalarFactorFieldAssociation = association; + } + + VTKM_CONT const std::string& GetScalarFactorFieldName() const + { + return this->ScalarFactorFieldName; + } + + VTKM_CONT vtkm::cont::Field::Association GetScalarFactorFieldAssociation() const + { + return this->ScalarFactorFieldAssociation; + } + //@} + + template + VTKM_CONT vtkm::cont::DataSet DoExecute( + const vtkm::cont::DataSet& input, + const vtkm::cont::ArrayHandle, StorageType>& field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + +private: + vtkm::worklet::WarpScalar Worklet; + std::string NormalFieldName; + vtkm::cont::Field::Association NormalFieldAssociation; + std::string ScalarFactorFieldName; + vtkm::cont::Field::Association ScalarFactorFieldAssociation; + vtkm::FloatDefault ScaleAmount; +}; + +template <> +class FilterTraits +{ +public: + // WarpScalar can only applies to Float and Double Vec3 arrays + using InputFieldTypeList = vtkm::TypeListTagFieldVec3; +}; +} +} + +#include + +#endif // vtk_m_filter_WarpScalar_h diff --git a/vtkm/filter/WarpScalar.hxx b/vtkm/filter/WarpScalar.hxx new file mode 100644 index 000000000..b47eb6e8a --- /dev/null +++ b/vtkm/filter/WarpScalar.hxx @@ -0,0 +1,69 @@ +//============================================================================ +// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 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 + +namespace vtkm +{ +namespace filter +{ + +//----------------------------------------------------------------------------- +inline VTKM_CONT WarpScalar::WarpScalar(vtkm::FloatDefault scaleAmount) + : vtkm::filter::FilterField() + , Worklet() + , NormalFieldName("normal") + , NormalFieldAssociation(vtkm::cont::Field::Association::ANY) + , ScalarFactorFieldName("scalarfactor") + , ScalarFactorFieldAssociation(vtkm::cont::Field::Association::ANY) + , ScaleAmount(scaleAmount) +{ + this->SetOutputFieldName("warpscalar"); +} + +//----------------------------------------------------------------------------- +template +inline VTKM_CONT vtkm::cont::DataSet WarpScalar::DoExecute( + const vtkm::cont::DataSet& inDataSet, + const vtkm::cont::ArrayHandle, StorageType>& field, + const vtkm::filter::FieldMetadata& fieldMetadata, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& device) +{ + using vecType = vtkm::Vec; + auto normalF = inDataSet.GetField(this->NormalFieldName, this->NormalFieldAssociation); + auto sfF = inDataSet.GetField(this->ScalarFactorFieldName, this->ScalarFactorFieldAssociation); + vtkm::cont::ArrayHandle result; + this->Worklet.Run(field, + vtkm::filter::ApplyPolicy(normalF, policy), + vtkm::filter::ApplyPolicy(sfF, policy), + this->ScaleAmount, + result, + device); + + return internal::CreateResult(inDataSet, + result, + this->GetOutputFieldName(), + fieldMetadata.GetAssociation(), + fieldMetadata.GetCellSetName()); +} +} +} diff --git a/vtkm/filter/WarpVector.h b/vtkm/filter/WarpVector.h index e7ba74b4d..a14a5ee15 100644 --- a/vtkm/filter/WarpVector.h +++ b/vtkm/filter/WarpVector.h @@ -31,7 +31,7 @@ namespace filter /// \brief Modify points by moving points along a vector then timing /// the scale factor /// -/// A functor that modify point coordinates by moving points along a vector +/// A filter that modifies point coordinates by moving points along a vector /// then timing a scale factor. It's a VTK-m version of the vtkWarpVector in VTK. /// Useful for showing flow profiles or mechanical deformation. /// This worklet does not modify the input points but generate new point @@ -62,7 +62,7 @@ public: } //@{ - /// When set to true, uses a coordinate system as the primary field instead of the one selected + /// When set to true, filter uses a coordinate system as the primary field instead of the one selected /// by name. Use SetPrimaryCoordinateSystem to select which coordinate system. VTKM_CONT void SetUseCoordinateSystemAsPrimaryField(bool flag) diff --git a/vtkm/filter/testing/CMakeLists.txt b/vtkm/filter/testing/CMakeLists.txt index e9e444d96..c4cca31ad 100644 --- a/vtkm/filter/testing/CMakeLists.txt +++ b/vtkm/filter/testing/CMakeLists.txt @@ -57,6 +57,7 @@ set(unit_tests UnitTestTriangulateFilter.cxx UnitTestVectorMagnitudeFilter.cxx UnitTestVertexClusteringFilter.cxx + UnitTestWarpScalarFilter.cxx UnitTestWarpVectorFilter.cxx ) diff --git a/vtkm/filter/testing/UnitTestWarpScalarFilter.cxx b/vtkm/filter/testing/UnitTestWarpScalarFilter.cxx new file mode 100644 index 000000000..f6867f308 --- /dev/null +++ b/vtkm/filter/testing/UnitTestWarpScalarFilter.cxx @@ -0,0 +1,146 @@ +//============================================================================ +// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 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 + +namespace +{ +const vtkm::Id dim = 5; +template +vtkm::cont::DataSet MakeWarpScalarTestDataSet() +{ + using vecType = vtkm::Vec; + vtkm::cont::DataSet dataSet; + + std::vector coordinates; + std::vector vec1; + std::vector scalarFactor; + for (vtkm::Id j = 0; j < dim; ++j) + { + T z = static_cast(j) / static_cast(dim - 1); + for (vtkm::Id i = 0; i < dim; ++i) + { + T x = static_cast(i) / static_cast(dim - 1); + T y = (x * x + z * z) / static_cast(2.0); + coordinates.push_back(vtkm::make_Vec(x, y, z)); + vec1.push_back(vtkm::make_Vec(x, y, y)); + scalarFactor.push_back(static_cast(j * dim + i)); + } + } + + dataSet.AddCoordinateSystem( + vtkm::cont::make_CoordinateSystem("coordinates", coordinates, vtkm::CopyFlag::On)); + + vtkm::cont::DataSetFieldAdd::AddPointField(dataSet, "vec1", vec1); + vtkm::cont::DataSetFieldAdd::AddPointField(dataSet, "scalarfactor", scalarFactor); + + vecType normal = vtkm::make_Vec(static_cast(0.0), static_cast(0.0), static_cast(1.0)); + vtkm::cont::ArrayHandleConstant vectorAH = + vtkm::cont::make_ArrayHandleConstant(normal, dim * dim); + vtkm::cont::DataSetFieldAdd::AddPointField(dataSet, "normal", vectorAH); + + return dataSet; +} + +class PolicyWarpScalar : public vtkm::filter::PolicyBase +{ +public: + using vecType = vtkm::Vec; + struct TypeListTagWarpScalarTags + : vtkm::ListTagBase::StorageTag, + vtkm::cont::ArrayHandle::StorageTag, + vtkm::cont::ArrayHandle::StorageTag> + { + }; + using FieldStorageList = TypeListTagWarpScalarTags; +}; + +void CheckResult(const vtkm::filter::WarpScalar& filter, const vtkm::cont::DataSet& result) +{ + VTKM_TEST_ASSERT(result.HasField("warpscalar", vtkm::cont::Field::Association::POINTS), + "Output filed warpscalar is missing"); + using vecType = vtkm::Vec; + vtkm::cont::ArrayHandle outputArray; + result.GetField("warpscalar", vtkm::cont::Field::Association::POINTS) + .GetData() + .CopyTo(outputArray); + auto outPortal = outputArray.GetPortalConstControl(); + + vtkm::cont::ArrayHandle sfArray; + result.GetField("scalarfactor", vtkm::cont::Field::Association::POINTS).GetData().CopyTo(sfArray); + auto sfPortal = sfArray.GetPortalConstControl(); + + for (vtkm::Id j = 0; j < dim; ++j) + { + vtkm::FloatDefault z = + static_cast(j) / static_cast(dim - 1); + for (vtkm::Id i = 0; i < dim; ++i) + { + vtkm::FloatDefault x = + static_cast(i) / static_cast(dim - 1); + vtkm::FloatDefault y = (x * x + z * z) / static_cast(2.0); + vtkm::FloatDefault targetZ = filter.GetUseCoordinateSystemAsPrimaryField() + ? z + static_cast(2 * sfPortal.Get(j * dim + i)) + : y + static_cast(2 * sfPortal.Get(j * dim + i)); + auto point = outPortal.Get(j * dim + i); + VTKM_TEST_ASSERT(point[0] == x, "Wrong result of x value for warp scalar"); + VTKM_TEST_ASSERT(point[1] == y, "Wrong result of y value for warp scalar"); + VTKM_TEST_ASSERT(point[2] == targetZ, "Wrong result of z value for warp scalar"); + } + } +} + +void TestWarpScalarFilter() +{ + std::cout << "Testing WarpScalar filter" << std::endl; + vtkm::cont::DataSet ds = MakeWarpScalarTestDataSet(); + vtkm::FloatDefault scale = 2; + + { + std::cout << " First field as coordinates" << std::endl; + vtkm::filter::WarpScalar filter(scale); + filter.SetUseCoordinateSystemAsPrimaryField(true); + filter.SetNormalField("normal"); + filter.SetScarlarFactorField("scalarfactor"); + vtkm::cont::DataSet result = filter.Execute(ds, PolicyWarpScalar()); + CheckResult(filter, result); + } + + { + std::cout << " First field as a vector" << std::endl; + vtkm::filter::WarpScalar filter(scale); + filter.SetPrimaryField("vec1"); + filter.SetNormalField("normal"); + filter.SetScarlarFactorField("scalarfactor"); + vtkm::cont::DataSet result = filter.Execute(ds, PolicyWarpScalar()); + CheckResult(filter, result); + } +} +} + +int UnitTestWarpScalarFilter(int, char* []) +{ + return vtkm::cont::testing::Testing::Run(TestWarpScalarFilter); +} diff --git a/vtkm/worklet/CMakeLists.txt b/vtkm/worklet/CMakeLists.txt index 8b8f203e1..58d8f2510 100644 --- a/vtkm/worklet/CMakeLists.txt +++ b/vtkm/worklet/CMakeLists.txt @@ -72,6 +72,7 @@ set(headers ThresholdPoints.h Triangulate.h VertexClustering.h + WarpScalar.h WarpVector.h WaveletCompressor.h WorkletMapField.h diff --git a/vtkm/worklet/WarpScalar.h b/vtkm/worklet/WarpScalar.h new file mode 100644 index 000000000..708fac2f2 --- /dev/null +++ b/vtkm/worklet/WarpScalar.h @@ -0,0 +1,100 @@ +//============================================================================ +// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 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. +//============================================================================ + +#ifndef vtk_m_worklet_WarpScalar_h +#define vtk_m_worklet_WarpScalar_h + +#include +#include +#include +#include + +#include + +namespace vtkm +{ +namespace worklet +{ +// A functor that modify points by moving points along point normals by the scalar +// amount times the scalar factor. It's a VTK-m version of the vtkWarpScalar in VTK. +// Useful for creating carpet or x-y-z plots. +// It doesn't modify the point coordinates, but creates a new point coordinates +// that have been warped. +class WarpScalar +{ +public: + class WarpScalarImp : public vtkm::worklet::WorkletMapField + { + public: + using ControlSignature = void(FieldIn, FieldIn, FieldIn, FieldOut); + using ExecutionSignature = void(_1, _2, _3, _4); + VTKM_CONT + WarpScalarImp(vtkm::FloatDefault scaleAmount) + : ScaleAmount(scaleAmount) + { + } + + VTKM_EXEC + void operator()(const vtkm::Vec& point, + const vtkm::Vec& normal, + const vtkm::FloatDefault& scaleFactor, + vtkm::Vec& result) const + { + result = point + this->ScaleAmount * scaleFactor * normal; + } + + template + VTKM_EXEC void operator()(const vtkm::Vec& point, + const vtkm::Vec& normal, + const T3& scaleFactor, + vtkm::Vec& result) const + { + result = point + static_cast(this->ScaleAmount * scaleFactor) * normal; + } + + + private: + vtkm::FloatDefault ScaleAmount; + }; + + // Execute the WarpScalar worklet given the points, vector and a scale factor. + // Scale factor can differs per point. + template + void Run(PointType point, + NormalType normal, + ScaleFactorType scaleFactor, + ScaleAmountType scale, + ResultType warpedPoint, + DeviceAdapter vtkmNotUsed(adapter)) + { + WarpScalarImp warpScalarImp(scale); + vtkm::worklet::DispatcherMapField dispatcher(warpScalarImp); + dispatcher.Invoke(point, normal, scaleFactor, warpedPoint); + } +}; +} +} // namespace vtkm::worklet + +#endif // vtk_m_worklet_WarpScalar_h diff --git a/vtkm/worklet/testing/CMakeLists.txt b/vtkm/worklet/testing/CMakeLists.txt index a9a6d84f8..291898d48 100644 --- a/vtkm/worklet/testing/CMakeLists.txt +++ b/vtkm/worklet/testing/CMakeLists.txt @@ -77,6 +77,7 @@ set(unit_tests UnitTestWorkletMapTopologyUniform.cxx UnitTestWorkletReduceByKey.cxx UnitTestVertexClustering.cxx + UnitTestWarpScalar.cxx UnitTestWarpVector.cxx UnitTestWaveletCompressor.cxx ) diff --git a/vtkm/worklet/testing/UnitTestWarpScalar.cxx b/vtkm/worklet/testing/UnitTestWarpScalar.cxx new file mode 100644 index 000000000..075000bf5 --- /dev/null +++ b/vtkm/worklet/testing/UnitTestWarpScalar.cxx @@ -0,0 +1,106 @@ +//============================================================================ +// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 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 + +namespace +{ +template +vtkm::cont::DataSet MakeWarpScalarTestDataSet() +{ + vtkm::cont::DataSet dataSet; + + std::vector> coordinates; + std::vector scaleFactor; + const vtkm::Id dim = 5; + for (vtkm::Id i = 0; i < dim; ++i) + { + T z = static_cast(i); + for (vtkm::Id j = 0; j < dim; ++j) + { + T x = static_cast(j); + T y = static_cast(j + 1); + coordinates.push_back(vtkm::make_Vec(x, y, z)); + scaleFactor.push_back(static_cast(i * dim + j)); + } + } + + dataSet.AddCoordinateSystem( + vtkm::cont::make_CoordinateSystem("coordinates", coordinates, vtkm::CopyFlag::On)); + vtkm::cont::DataSetFieldAdd::AddPointField(dataSet, "scalefactor", scaleFactor); + return dataSet; +} +} + +void TestWarpScalar() +{ + using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG; + std::cout << "Testing WarpScalar Worklet" << std::endl; + using vecType = vtkm::Vec; + + vtkm::cont::DataSet ds = MakeWarpScalarTestDataSet(); + + vtkm::FloatDefault scaleAmount = 2; + vtkm::cont::ArrayHandle result; + + vecType normal = vtkm::make_Vec(static_cast(0.0), + static_cast(0.0), + static_cast(1.0)); + auto coordinate = ds.GetCoordinateSystem().GetData(); + vtkm::Id nov = coordinate.GetNumberOfValues(); + vtkm::cont::ArrayHandleConstant normalAH = + vtkm::cont::make_ArrayHandleConstant(normal, nov); + + vtkm::cont::ArrayHandle scaleFactorArray; + auto scaleFactor = ds.GetField("scalefactor"); + scaleFactor.GetData().CopyTo(scaleFactorArray); + auto sFAPortal = scaleFactorArray.GetPortalControl(); + + vtkm::worklet::WarpScalar warpWorklet; + warpWorklet.Run( + ds.GetCoordinateSystem(), normalAH, scaleFactor, scaleAmount, result, DeviceAdapter()); + auto resultPortal = result.GetPortalConstControl(); + + for (vtkm::Id i = 0; i < nov; i++) + { + for (vtkm::Id j = 0; j < 3; j++) + { + vtkm::FloatDefault ans = + coordinate.GetPortalConstControl().Get(i)[static_cast(j)] + + scaleAmount * normal[static_cast(j)] * sFAPortal.Get(i); + VTKM_TEST_ASSERT(test_equal(ans, resultPortal.Get(i)[static_cast(j)]), + " Wrong result for WarpVector worklet"); + } + } +} + +int UnitTestWarpScalar(int, char* []) +{ + return vtkm::cont::testing::Testing::Run(TestWarpScalar); +}