From efb119ead02e5f0f6e079d10bab14fee26010cc0 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 15 Dec 2016 11:07:04 -0500 Subject: [PATCH 1/2] Sort the worklet headers, as they should be in alphabetical order. --- vtkm/worklet/CMakeLists.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vtkm/worklet/CMakeLists.txt b/vtkm/worklet/CMakeLists.txt index 1df3d764c..768698f52 100644 --- a/vtkm/worklet/CMakeLists.txt +++ b/vtkm/worklet/CMakeLists.txt @@ -19,15 +19,13 @@ ##============================================================================ set(headers - DispatcherMapField.h - DispatcherStreamingMapField.h - WorkletMapField.h - DispatcherMapTopology.h - WorkletMapTopology.h AverageByKey.h CellAverage.h CellDeepCopy.h Clip.h + DispatcherMapField.h + DispatcherMapTopology.h + DispatcherStreamingMapField.h ExternalFaces.h FieldHistogram.h FieldStatistics.h @@ -36,8 +34,8 @@ set(headers Magnitude.h MarchingCubes.h MarchingCubesDataTables.h - PointElevation.h PointAverage.h + PointElevation.h RemoveUnusedPoints.h ScatterCounting.h ScatterIdentity.h @@ -45,11 +43,13 @@ set(headers StreamLineUniformGrid.h TetrahedralizeExplicitGrid.h TetrahedralizeUniformGrid.h + Threshold.h TriangulateExplicitGrid.h TriangulateUniformGrid.h - Threshold.h VertexClustering.h WaveletCompressor.h + WorkletMapField.h + WorkletMapTopology.h ) #----------------------------------------------------------------------------- From f71f3ed011791a3da05e5826260982b7a979d1e0 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 15 Dec 2016 14:14:57 -0500 Subject: [PATCH 2/2] Allow the gradient filter to compute Vorticity and QCriterion. --- vtkm/filter/Gradient.h | 32 ++++++++- vtkm/filter/Gradient.hxx | 86 +++++++++++++++++++++++- vtkm/filter/ResultBase.h | 12 ++-- vtkm/filter/ResultDataSet.h | 12 ---- vtkm/filter/testing/UnitTestGradient.cxx | 24 ++++++- vtkm/worklet/CMakeLists.txt | 1 + vtkm/worklet/Vorticity.h | 82 ++++++++++++++++++++++ 7 files changed, 222 insertions(+), 27 deletions(-) create mode 100644 vtkm/worklet/Vorticity.h diff --git a/vtkm/filter/Gradient.h b/vtkm/filter/Gradient.h index 00b131c76..46683a53b 100644 --- a/vtkm/filter/Gradient.h +++ b/vtkm/filter/Gradient.h @@ -22,7 +22,6 @@ #define vtk_m_filter_Gradient_h #include -#include namespace vtkm { namespace filter { @@ -38,7 +37,7 @@ namespace filter { class Gradient : public vtkm::filter::FilterCell { public: - Gradient(): ComputePointGradient(false) {} + Gradient(); /// When this flag is on (default is off), the gradient filter will provide a /// point based gradients, which are significantly more costly since for each @@ -46,6 +45,30 @@ public: void SetComputePointGradient(bool enable) { ComputePointGradient=enable; } bool GetComputePointGradient() const { return ComputePointGradient; } + /// Add voriticity/curl field to the output data. The name of the array + /// will be Vorticity and will be a cell field unless \c ComputePointGradient + /// is enabled. The input array must have 3 components in order to + /// compute this. The default is off. + void SetComputeVorticity(bool enable) { ComputeVorticity=enable; } + bool GetComputeVorticity() const { return ComputeVorticity; } + + /// Add Q-criterion field to the output data. The name of the array + /// will be QCriterion and will be a cell field unless \c ComputePointGradient + /// is enabled. The input array must have 3 components in order to + /// compute this. The default is off. + void SetComputeQCriterion(bool enable) { ComputeQCriterion=enable; } + bool GetComputeQCriterion() const { return ComputeQCriterion; } + + void SetVorticityName( const std::string& name ) + { this->VorticityName = name; } + const std::string& GetVorticityName() const + { return this->VorticityName; } + + void SetQCriterionName( const std::string& name ) + { this->QCriterionName = name; } + const std::string& GetQCriterionName() const + { return this->QCriterionName; } + template vtkm::filter::ResultField DoExecute(const vtkm::cont::DataSet &input, @@ -56,6 +79,11 @@ public: private: bool ComputePointGradient; + bool ComputeVorticity; + bool ComputeQCriterion; + + std::string VorticityName; + std::string QCriterionName; }; template<> diff --git a/vtkm/filter/Gradient.hxx b/vtkm/filter/Gradient.hxx index 0d3f5a191..907057b04 100644 --- a/vtkm/filter/Gradient.hxx +++ b/vtkm/filter/Gradient.hxx @@ -22,8 +22,12 @@ #include +#include +#include + namespace { +//----------------------------------------------------------------------------- template struct PointGrad { @@ -53,12 +57,83 @@ struct PointGrad vtkm::cont::ArrayHandle< vtkm::Vec >* Result; }; - +//----------------------------------------------------------------------------- +template +inline +void add_field( vtkm::filter::ResultField& result, + const HandleType& handle, + const std::string name) +{ + const vtkm::cont::Field::AssociationEnum assoc = result.GetField().GetAssociation(); + if ((assoc == vtkm::cont::Field::ASSOC_WHOLE_MESH) || + (assoc == vtkm::cont::Field::ASSOC_POINTS)) + { + vtkm::cont::Field field(name, assoc, handle); + result.GetDataSet().AddField(field); + } + else + { + vtkm::cont::Field field(name, + assoc, + result.GetField().GetAssocCellSet(), + handle); + result.GetDataSet().AddField(field); + } } +//----------------------------------------------------------------------------- +template +inline +void add_extra_vec_fields( const vtkm::cont::ArrayHandle< vtkm::Vec< vtkm::Vec, 3>, S> &inField, + const vtkm::filter::Gradient* const filter, + vtkm::filter::ResultField& result, + const DeviceAdapter&) +{ + if(filter->GetComputeVorticity()) + { + vtkm::cont::ArrayHandle< vtkm::Vec > vorticity; + vtkm::worklet::DispatcherMapField< vtkm::worklet::Vorticity, DeviceAdapter > dispatcher; + dispatcher.Invoke(inField, vorticity); + + add_field(result, vorticity, filter->GetVorticityName()); + } + + if(filter->GetComputeQCriterion()) + { + vtkm::cont::ArrayHandle< T > qc; + vtkm::worklet::DispatcherMapField< vtkm::worklet::QCriterion, DeviceAdapter > dispatcher; + dispatcher.Invoke(inField, qc); + + add_field(result, qc, filter->GetQCriterionName()); + } +} + +template +inline +void add_extra_vec_fields( const vtkm::cont::ArrayHandle< T, S> &, + const vtkm::filter::Gradient* const, + vtkm::filter::ResultField&, + const DeviceAdapter&) +{ + //not a vector array handle so add nothing +} + +} //namespace + namespace vtkm { namespace filter { +//----------------------------------------------------------------------------- +Gradient::Gradient(): + ComputePointGradient(false), + ComputeVorticity(false), + ComputeQCriterion(false), + VorticityName("Vorticity"), + QCriterionName("QCriterion") + { + + } + //----------------------------------------------------------------------------- template &inField, const vtkm::filter::FieldMetadata &fieldMetadata, const vtkm::filter::PolicyBase& policy, - const DeviceAdapter&) + const DeviceAdapter& adapter) { if(!fieldMetadata.IsPointField()) { @@ -115,12 +190,17 @@ vtkm::filter::ResultField Gradient::DoExecute( fieldAssociation = vtkm::cont::Field::ASSOC_CELL_SET; } - return vtkm::filter::ResultField(input, + vtkm::filter::ResultField result(input, outArray, outputName, fieldAssociation, cells.GetName()); + //Add the vorticity and qcriterion fields if they are enabled to the result + add_extra_vec_fields(outArray, this, result, adapter); + + return result; + } diff --git a/vtkm/filter/ResultBase.h b/vtkm/filter/ResultBase.h index 629816716..33180352b 100644 --- a/vtkm/filter/ResultBase.h +++ b/vtkm/filter/ResultBase.h @@ -50,6 +50,10 @@ public: VTKM_CONT const vtkm::cont::DataSet &GetDataSet() const { return this->Data; } + /// Returns the results of the filter in terms of a writable \c DataSet. + VTKM_CONT + vtkm::cont::DataSet &GetDataSet() { return this->Data; } + protected: VTKM_CONT ResultBase(): Valid(false) { } @@ -71,14 +75,6 @@ protected: this->SetValid(true); } - /// Returns a writable reference to the data set. - /// - VTKM_CONT - vtkm::cont::DataSet &GetDataSetReference() - { - return this->Data; - } - private: bool Valid; vtkm::cont::DataSet Data; diff --git a/vtkm/filter/ResultDataSet.h b/vtkm/filter/ResultDataSet.h index 94dcb51dc..abd660dfe 100644 --- a/vtkm/filter/ResultDataSet.h +++ b/vtkm/filter/ResultDataSet.h @@ -45,18 +45,6 @@ public: VTKM_CONT ResultDataSet(const vtkm::cont::DataSet &dataSet) : ResultBase(dataSet) { } - - VTKM_CONT - const vtkm::cont::DataSet &GetDataSet() const - { - return this->ResultBase::GetDataSet(); - } - - VTKM_CONT - vtkm::cont::DataSet &GetDataSet() - { - return this->ResultBase::GetDataSetReference(); - } }; } diff --git a/vtkm/filter/testing/UnitTestGradient.cxx b/vtkm/filter/testing/UnitTestGradient.cxx index f6e5ddeed..a15714bf8 100644 --- a/vtkm/filter/testing/UnitTestGradient.cxx +++ b/vtkm/filter/testing/UnitTestGradient.cxx @@ -36,16 +36,26 @@ void TestCellGradientUniform3D() vtkm::filter::ResultField result; vtkm::filter::Gradient gradient; - gradient.SetOutputFieldName("gradient"); + gradient.SetOutputFieldName("Gradient"); + + gradient.SetComputeVorticity(true); //this wont work as we have a scalar field + gradient.SetComputeQCriterion(true); //this wont work as we have a scalar field result = gradient.Execute( dataSet, dataSet.GetField("pointvar")); - VTKM_TEST_ASSERT(result.GetField().GetName() == "gradient", + VTKM_TEST_ASSERT(result.GetField().GetName() == "Gradient", "Field was given the wrong name."); VTKM_TEST_ASSERT(result.GetField().GetAssociation() == vtkm::cont::Field::ASSOC_CELL_SET, "Field was given the wrong association."); + //verify that the vorticity and qcriterion fields don't exist + const vtkm::cont::DataSet& outputDS = result.GetDataSet(); + VTKM_TEST_ASSERT(outputDS.HasField("Vorticity") == false, + "scalar gradients can't generate vorticity"); + VTKM_TEST_ASSERT(outputDS.HasField("QCriterion") == false, + "scalar gradients can't generate qcriterion"); + vtkm::cont::ArrayHandle< vtkm::Vec > resultArrayHandle; const bool valid = result.FieldAs(resultArrayHandle); VTKM_TEST_ASSERT( valid, "result of gradient is not expected type"); @@ -89,6 +99,8 @@ void TestCellGradientUniform3DWithVectorField() vtkm::filter::ResultField result; vtkm::filter::Gradient gradient; gradient.SetOutputFieldName("vec_gradient"); + gradient.SetComputeVorticity(true); + gradient.SetComputeQCriterion(true); result = gradient.Execute( dataSet, dataSet.GetField("vec_pointvar")); @@ -99,6 +111,14 @@ void TestCellGradientUniform3DWithVectorField() vtkm::cont::Field::ASSOC_CELL_SET, "Field was given the wrong association."); + //verify that the vorticity and qcriterion fields DO exist + const vtkm::cont::DataSet& outputDS = result.GetDataSet(); + VTKM_TEST_ASSERT(outputDS.HasField("Vorticity") == true, + "vec gradients should generate vorticity"); + VTKM_TEST_ASSERT(outputDS.HasField("QCriterion") == true, + "vec gradients should generate qcriterion"); + + vtkm::cont::ArrayHandle< vtkm::Vec< vtkm::Vec, 3> > resultArrayHandle; const bool valid = result.FieldAs(resultArrayHandle); VTKM_TEST_ASSERT( valid, "result of gradient is not expected type"); diff --git a/vtkm/worklet/CMakeLists.txt b/vtkm/worklet/CMakeLists.txt index 768698f52..ab7ec1e20 100644 --- a/vtkm/worklet/CMakeLists.txt +++ b/vtkm/worklet/CMakeLists.txt @@ -47,6 +47,7 @@ set(headers TriangulateExplicitGrid.h TriangulateUniformGrid.h VertexClustering.h + Vorticity.h WaveletCompressor.h WorkletMapField.h WorkletMapTopology.h diff --git a/vtkm/worklet/Vorticity.h b/vtkm/worklet/Vorticity.h new file mode 100644 index 000000000..f765daffd --- /dev/null +++ b/vtkm/worklet/Vorticity.h @@ -0,0 +1,82 @@ +//============================================================================ +// 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 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ + +#ifndef vtk_m_worklet_Vorticity_h +#define vtk_m_worklet_Vorticity_h + +#include + +namespace vtkm { +namespace worklet { + +struct VorticityInputTypes + : vtkm::ListTagBase< + vtkm::Vec< vtkm::Vec, 3>, + vtkm::Vec< vtkm::Vec, 3> + > { }; + +struct Vorticity : public vtkm::worklet::WorkletMapField +{ + typedef void ControlSignature(FieldIn input, + FieldOut output); + typedef void ExecutionSignature(_1,_2); + typedef _1 InputDomain; + + VTKM_EXEC + template + void operator()(const InputType &input, OutputType &vorticity) const + { + vorticity[0] = input[2][1] - input[1][2]; + vorticity[1] = input[0][2] - input[2][0]; + vorticity[2] = input[1][0] - input[0][1]; + } +}; + +struct QCriterion : public vtkm::worklet::WorkletMapField +{ + typedef void ControlSignature(FieldIn input, + FieldOut output); + typedef void ExecutionSignature(_1,_2); + typedef _1 InputDomain; + + VTKM_EXEC + template + void operator()(const InputType &input, OutputType &qcriterion) const + { + OutputType t1 = + ((input[2][1] - input[1][2]) * (input[2][1] - input[1][2]) + + (input[1][0] - input[0][1]) * (input[1][0] - input[0][1]) + + (input[0][2] - input[2][0]) * (input[0][2] - input[2][0])) / 2.0f; + OutputType t2 = + input[0][0] * input[0][0] + input[1][1] * input[1][1] + + input[2][2] * input[2][2] + + ((input[1][0] + input[0][1]) * (input[1][0] + input[0][1]) + + (input[2][0] + input[0][2]) * (input[2][0] + input[0][2]) + + (input[2][1] + input[1][2]) * (input[2][1] + input[1][2])) / 2.0f; + + qcriterion = (t1 - t2) / 2.0f; + } + +}; + +} +} // namespace vtkm::worklet + +#endif \ No newline at end of file