From 7d0ee16fd199c7b714a7dd77f132072e4d63e37c Mon Sep 17 00:00:00 2001 From: Roxana Bujack Date: Wed, 4 Sep 2019 09:27:39 -0600 Subject: [PATCH 001/108] add the real double radius for scaling --- vtkm/filter/ComputeMoments.h | 9 ++- vtkm/filter/ComputeMoments.hxx | 2 +- vtkm/worklet/moments/ComputeMoments.h | 80 ++++++++++++++++----------- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/vtkm/filter/ComputeMoments.h b/vtkm/filter/ComputeMoments.h index d9ace508d..c4fe68aae 100644 --- a/vtkm/filter/ComputeMoments.h +++ b/vtkm/filter/ComputeMoments.h @@ -28,12 +28,17 @@ public: const vtkm::filter::FieldMetadata& fieldMetadata, const vtkm::filter::PolicyBase&); - VTKM_CONT void SetRadius(vtkm::Vec _radius) { this->Radius = _radius; } + VTKM_CONT void SetRadiusDiscrete(vtkm::Vec _radius) + { + this->RadiusDiscrete = _radius; + } + VTKM_CONT void SetRadiusReal(vtkm::Vec _radius) { this->RadiusReal = _radius; } VTKM_CONT void SetOrder(vtkm::Int32 _order) { this->Order = _order; } private: - vtkm::Vec Radius = { 1, 1, 1 }; + vtkm::Vec RadiusDiscrete = { 1, 1, 1 }; + vtkm::Vec RadiusReal = { 1, 1, 1 }; vtkm::Int32 Order = 0; }; } diff --git a/vtkm/filter/ComputeMoments.hxx b/vtkm/filter/ComputeMoments.hxx index 532bc20f6..9ec47221a 100644 --- a/vtkm/filter/ComputeMoments.hxx +++ b/vtkm/filter/ComputeMoments.hxx @@ -39,7 +39,7 @@ inline VTKM_CONT vtkm::cont::DataSet ComputeMoments::DoExecute( vtkm::cont::DataSet output; output.CopyStructure(input); - auto worklet = vtkm::worklet::moments::ComputeMoments(this->Radius); + auto worklet = vtkm::worklet::moments::ComputeMoments(this->RadiusDiscrete, this->RadiusReal); worklet.Run(input.GetCellSet(this->GetActiveCellSetIndex()), field, this->Order, output); diff --git a/vtkm/worklet/moments/ComputeMoments.h b/vtkm/worklet/moments/ComputeMoments.h index 8a8d201db..8cd4534ca 100644 --- a/vtkm/worklet/moments/ComputeMoments.h +++ b/vtkm/worklet/moments/ComputeMoments.h @@ -32,13 +32,17 @@ namespace moments struct ComputeMoments2D : public vtkm::worklet::WorkletPointNeighborhood { public: - ComputeMoments2D(const vtkm::Vec& _radius, int _p, int _q) - : Radius(_radius) + ComputeMoments2D(const vtkm::Vec& _radiusDiscrete, + const vtkm::Vec& _radiusReal, + int _p, + int _q) + : RadiusDiscrete(_radiusDiscrete) + , RadiusReal(_radiusReal) , p(_p) , q(_q) { - assert(_radius[0] >= 1); - assert(_radius[1] >= 1); + assert(_radiusReal[0] >= 1); + assert(_radiusReal[1] >= 1); assert(_p >= 0); assert(_q >= 0); @@ -55,22 +59,22 @@ public: { // TODO: type safety and numerical precision auto sum = vtkm::TypeTraits::ZeroInitialization(); - vtkm::Vec recp{ 1.0 / Radius[0], 1.0 / Radius[1] }; + vtkm::Vec recp{ 1.0 / RadiusReal[0], 1.0 / RadiusReal[1] }; // Clamp the radius to the dataset bounds (discard out-of-bounds points). - const auto minRadius = boundary.ClampNeighborIndex(-this->Radius); - const auto maxRadius = boundary.ClampNeighborIndex(this->Radius); + const auto minRadius = boundary.ClampNeighborIndex(-this->RadiusDiscrete); + const auto maxRadius = boundary.ClampNeighborIndex(this->RadiusDiscrete); for (vtkm::IdComponent j = minRadius[1]; j <= maxRadius[1]; ++j) { - if (j > -this->Radius[1] && boundary.IJK[1] + j == 0) + if (j > -this->RadiusDiscrete[1] && boundary.IJK[1] + j == 0) { // Don't double count samples that exist on other nodes: continue; } for (vtkm::IdComponent i = minRadius[0]; i <= maxRadius[0]; ++i) { - if (i > -this->Radius[0] && boundary.IJK[0] + i == 0) + if (i > -this->RadiusDiscrete[0] && boundary.IJK[0] + i == 0) { // Don't double count samples that exist on other nodes: continue; } @@ -89,7 +93,8 @@ public: } private: - const vtkm::Vec Radius; + const vtkm::Vec RadiusDiscrete; + const vtkm::Vec RadiusReal; const int p; const int q; }; @@ -97,15 +102,20 @@ private: struct ComputeMoments3D : public vtkm::worklet::WorkletPointNeighborhood { public: - ComputeMoments3D(const vtkm::Vec& _radius, int _p, int _q, int _r) - : Radius(_radius) + ComputeMoments3D(vtkm::Vec& _radiusDiscrete, + vtkm::Vec& _radiusReal, + int _p, + int _q, + int _r) + : RadiusDiscrete(_radiusDiscrete) + , RadiusReal(_radiusReal) , p(_p) , q(_q) , r(_r) { - assert(_radius[0] >= 1); - assert(_radius[1] >= 1); - assert(_radius[2] >= 1); + assert(_radiusReal[0] >= 1); + assert(_radiusReal[1] >= 1); + assert(_radiusReal[2] >= 1); assert(_p >= 0); assert(_q >= 0); @@ -123,31 +133,31 @@ public: { // TODO: type safety and numerical precision auto sum = vtkm::TypeTraits::ZeroInitialization(); - const vtkm::Vec recp{ 1.0 / this->Radius[0], - 1.0 / this->Radius[1], - 1.0 / this->Radius[2] }; + const vtkm::Vec recp{ 1.0 / this->RadiusReal[0], + 1.0 / this->RadiusReal[1], + 1.0 / this->RadiusReal[2] }; // Clamp the radius to the dataset bounds (discard out-of-bounds points). - const auto minRadius = boundary.ClampNeighborIndex(-this->Radius); - const auto maxRadius = boundary.ClampNeighborIndex(this->Radius); + const auto minRadius = boundary.ClampNeighborIndex(-this->RadiusDiscrete); + const auto maxRadius = boundary.ClampNeighborIndex(this->RadiusDiscrete); for (vtkm::IdComponent k = minRadius[2]; k <= maxRadius[2]; ++k) { - if (k > -this->Radius[2] && boundary.IJK[2] + k == 0) + if (k > -this->RadiusDiscrete[2] && boundary.IJK[2] + k == 0) { // Don't double count samples that exist on other nodes: continue; } for (vtkm::IdComponent j = minRadius[1]; j <= maxRadius[1]; ++j) { - if (j > -this->Radius[1] && boundary.IJK[1] + j == 0) + if (j > -this->RadiusDiscrete[1] && boundary.IJK[1] + j == 0) { // Don't double count samples that exist on other nodes: continue; } for (vtkm::IdComponent i = minRadius[0]; i <= maxRadius[0]; ++i) { - if (i > -this->Radius[0] && boundary.IJK[0] + i == 0) + if (i > -this->RadiusDiscrete[0] && boundary.IJK[0] + i == 0) { // Don't double count samples that exist on other nodes: continue; } @@ -168,7 +178,8 @@ public: } private: - const vtkm::Vec& Radius; + const vtkm::Vec& RadiusDiscrete; + const vtkm::Vec& RadiusReal; const int p; const int q; const int r; @@ -177,8 +188,9 @@ private: class ComputeMoments { public: - ComputeMoments(vtkm::Vec _radius) - : Radius(_radius) + ComputeMoments(vtkm::Vec& _radiusDiscrete, vtkm::Vec& _radiusReal) + : RadiusDiscrete(_radiusDiscrete) + , RadiusReal(_radiusReal) { } @@ -188,7 +200,8 @@ public: template void operator()(const vtkm::cont::CellSetStructured<2>& input, const vtkm::cont::ArrayHandle& pixels, - vtkm::Vec Radius, + vtkm::Vec RadiusDiscrete, + vtkm::Vec RadiusReal, int maxOrder, vtkm::cont::DataSet& output) const { @@ -203,7 +216,7 @@ public: vtkm::cont::ArrayHandle moments; - DispatcherType dispatcher(WorkletType{ Radius, p, q }); + DispatcherType dispatcher(WorkletType{ RadiusDiscrete, RadiusReal, p, q }); dispatcher.Invoke(input, pixels, moments); std::string fieldName = std::string("index") + std::string(p, '0') + std::string(q, '1'); @@ -218,7 +231,8 @@ public: template void operator()(const vtkm::cont::CellSetStructured<3>& input, const vtkm::cont::ArrayHandle& pixels, - vtkm::Vec Radius, + vtkm::Vec RadiusDiscrete, + vtkm::Vec RadiusReal, int maxOrder, vtkm::cont::DataSet& output) const { @@ -236,7 +250,7 @@ public: vtkm::cont::ArrayHandle moments; - DispatcherType dispatcher(WorkletType{ Radius, p, q, r }); + DispatcherType dispatcher(WorkletType{ RadiusDiscrete, RadiusReal, p, q, r }); dispatcher.Invoke(input, pixels, moments); std::string fieldName = std::string("index") + std::string(p, '0') + @@ -258,11 +272,13 @@ public: vtkm::cont::DataSet& output) const { input.ResetCellSetList(vtkm::cont::CellSetListTagStructured()) - .CastAndCall(ResolveDynamicCellSet(), pixels, this->Radius, maxOrder, output); + .CastAndCall( + ResolveDynamicCellSet(), pixels, this->RadiusDiscrete, this->RadiusReal, maxOrder, output); } private: - const vtkm::Vec Radius = { 1, 1, 1 }; + const vtkm::Vec RadiusDiscrete = { 1, 1, 1 }; + const vtkm::Vec RadiusReal = { 1, 1, 1 }; }; } } From b991d3c6bacb86039b318121644fdbf84ba5ad0b Mon Sep 17 00:00:00 2001 From: Roxana Bujack Date: Wed, 11 Sep 2019 08:14:18 -0600 Subject: [PATCH 002/108] merge style differences --- vtkm/filter/ComputeMoments.h | 1 + 1 file changed, 1 insertion(+) diff --git a/vtkm/filter/ComputeMoments.h b/vtkm/filter/ComputeMoments.h index c4fe68aae..5d25ce2c6 100644 --- a/vtkm/filter/ComputeMoments.h +++ b/vtkm/filter/ComputeMoments.h @@ -32,6 +32,7 @@ public: { this->RadiusDiscrete = _radius; } + VTKM_CONT void SetRadiusReal(vtkm::Vec _radius) { this->RadiusReal = _radius; } VTKM_CONT void SetOrder(vtkm::Int32 _order) { this->Order = _order; } From 82d2e440ae204790c138dd065d52cc42afc3f1b9 Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Wed, 11 Sep 2019 09:33:19 -0700 Subject: [PATCH 003/108] trying to fix the unnecessarily complicated and ridiculous world of git. --- vtkm/io/reader/VTKDataSetReaderBase.h | 247 +++++++++++++++----------- 1 file changed, 139 insertions(+), 108 deletions(-) diff --git a/vtkm/io/reader/VTKDataSetReaderBase.h b/vtkm/io/reader/VTKDataSetReaderBase.h index aa3bf2026..59504048e 100644 --- a/vtkm/io/reader/VTKDataSetReaderBase.h +++ b/vtkm/io/reader/VTKDataSetReaderBase.h @@ -248,19 +248,19 @@ inline vtkm::cont::DynamicCellSet CreateCellSetStructured(const vtkm::Id3& dim) { if (dim[0] > 1 && dim[1] > 1 && dim[2] > 1) { - vtkm::cont::CellSetStructured<3> cs("cells"); + vtkm::cont::CellSetStructured<3> cs; cs.SetPointDimensions(vtkm::make_Vec(dim[0], dim[1], dim[2])); return cs; } else if (dim[0] > 1 && dim[1] > 1 && dim[2] <= 1) { - vtkm::cont::CellSetStructured<2> cs("cells"); + vtkm::cont::CellSetStructured<2> cs; cs.SetPointDimensions(vtkm::make_Vec(dim[0], dim[1])); return cs; } else if (dim[0] > 1 && dim[1] <= 1 && dim[2] <= 1) { - vtkm::cont::CellSetStructured<1> cs("cells"); + vtkm::cont::CellSetStructured<1> cs; cs.SetPointDimensions(dim[0]); return cs; } @@ -335,8 +335,8 @@ protected: std::size_t numPoints; this->DataFile->Stream >> numPoints >> dataType >> std::ws; - vtkm::cont::VariantArrayHandle points; - this->DoReadArrayVariant(dataType, numPoints, 3, points); + vtkm::cont::VariantArrayHandle points = + this->DoReadArrayVariant(vtkm::cont::Field::Association::POINTS, dataType, numPoints, 3); this->DataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", points)); } @@ -416,59 +416,39 @@ protected: this->DataFile->Stream >> size; while (!this->DataFile->Stream.eof()) { - std::string name; - vtkm::cont::ArrayHandle empty; - vtkm::cont::VariantArrayHandle data(empty); - this->DataFile->Stream >> tag; if (tag == "SCALARS") { - this->ReadScalars(size, name, data); + this->ReadScalars(association, size); } else if (tag == "COLOR_SCALARS") { - this->ReadColorScalars(size, name); + this->ReadColorScalars(association, size); } else if (tag == "LOOKUP_TABLE") { - this->ReadLookupTable(name); + this->ReadLookupTable(); } else if (tag == "VECTORS" || tag == "NORMALS") { - this->ReadVectors(size, name, data); + this->ReadVectors(association, size); } else if (tag == "TEXTURE_COORDINATES") { - this->ReadTextureCoordinates(size, name, data); + this->ReadTextureCoordinates(association, size); } else if (tag == "TENSORS") { - this->ReadTensors(size, name, data); + this->ReadTensors(association, size); } else if (tag == "FIELD") { - this->ReadFields(name); + this->ReadFields(association, size); } else { break; } - - if (data.GetNumberOfValues() > 0) - { - switch (association) - { - case vtkm::cont::Field::Association::POINTS: - this->DataSet.AddField(vtkm::cont::Field(name, association, data)); - break; - case vtkm::cont::Field::Association::CELL_SET: - vtkm::cont::CastAndCall(data, PermuteCellData(this->CellsPermutation, data)); - this->DataSet.AddField(vtkm::cont::Field(name, association, "cells", data)); - break; - default: - break; - } - } } } } @@ -478,6 +458,8 @@ protected: this->CellsPermutation = permutation; } + vtkm::cont::ArrayHandle GetCellsPermutation() const { return this->CellsPermutation; } + void TransferDataFile(VTKDataSetReaderBase& reader) { reader.DataFile.swap(this->DataFile); @@ -495,7 +477,7 @@ private: this->DataFile->Stream.open(this->DataFile->FileName.c_str(), std::ios_base::in | std::ios_base::binary); } - catch (std::ifstream::failure& e) + catch (std::ifstream::failure&) { std::string message("could not open file \"" + this->DataFile->FileName + "\""); throw vtkm::io::ErrorIO(message); @@ -563,11 +545,32 @@ private: virtual void Read() = 0; - void ReadScalars(std::size_t numElements, - std::string& dataName, - vtkm::cont::VariantArrayHandle& data) + void AddField(const std::string& name, + vtkm::cont::Field::Association association, + vtkm::cont::VariantArrayHandle& data) { - std::string dataType, lookupTableName; + if (data.GetNumberOfValues() > 0) + { + switch (association) + { + case vtkm::cont::Field::Association::POINTS: + case vtkm::cont::Field::Association::WHOLE_MESH: + this->DataSet.AddField(vtkm::cont::Field(name, association, data)); + break; + case vtkm::cont::Field::Association::CELL_SET: + this->DataSet.AddField(vtkm::cont::Field(name, association, data)); + break; + default: + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Not recording field '" << name << "' because it has an unknown association"); + break; + } + } + } + + void ReadScalars(vtkm::cont::Field::Association association, std::size_t numElements) + { + std::string dataName, dataType, lookupTableName; vtkm::IdComponent numComponents = 1; this->DataFile->Stream >> dataName >> dataType; std::string tag; @@ -588,67 +591,100 @@ private: internal::parseAssert(tag == "LOOKUP_TABLE"); this->DataFile->Stream >> lookupTableName >> std::ws; - this->DoReadArrayVariant(dataType, numElements, numComponents, data); + vtkm::cont::VariantArrayHandle data = + this->DoReadArrayVariant(association, dataType, numElements, numComponents); + this->AddField(dataName, association, data); } - void ReadColorScalars(std::size_t numElements, std::string& dataName) + void ReadColorScalars(vtkm::cont::Field::Association association, std::size_t numElements) { VTKM_LOG_S(vtkm::cont::LogLevel::Warn, "Support for COLOR_SCALARS is not implemented. Skipping."); - std::size_t numValues; - this->DataFile->Stream >> dataName >> numValues >> std::ws; - this->SkipArray(numElements * numValues, vtkm::io::internal::ColorChannel8()); + std::string dataName; + vtkm::IdComponent numComponents; + this->DataFile->Stream >> dataName >> numComponents >> std::ws; + std::string dataType = this->DataFile->IsBinary ? "unsigned_char" : "float"; + vtkm::cont::VariantArrayHandle data = + this->DoReadArrayVariant(association, dataType, numElements, numComponents); + this->AddField(dataName, association, data); } - void ReadLookupTable(std::string& dataName) + void ReadLookupTable() { VTKM_LOG_S(vtkm::cont::LogLevel::Warn, "Support for LOOKUP_TABLE is not implemented. Skipping."); + std::string dataName; std::size_t numEntries; this->DataFile->Stream >> dataName >> numEntries >> std::ws; this->SkipArray(numEntries, vtkm::Vec()); } - void ReadTextureCoordinates(std::size_t numElements, - std::string& dataName, - vtkm::cont::VariantArrayHandle& data) + void ReadTextureCoordinates(vtkm::cont::Field::Association association, std::size_t numElements) { + std::string dataName; vtkm::IdComponent numComponents; std::string dataType; this->DataFile->Stream >> dataName >> numComponents >> dataType >> std::ws; - this->DoReadArrayVariant(dataType, numElements, numComponents, data); + vtkm::cont::VariantArrayHandle data = + this->DoReadArrayVariant(association, dataType, numElements, numComponents); + this->AddField(dataName, association, data); } - void ReadVectors(std::size_t numElements, - std::string& dataName, - vtkm::cont::VariantArrayHandle& data) + void ReadVectors(vtkm::cont::Field::Association association, std::size_t numElements) { + std::string dataName; std::string dataType; this->DataFile->Stream >> dataName >> dataType >> std::ws; - this->DoReadArrayVariant(dataType, numElements, 3, data); + vtkm::cont::VariantArrayHandle data = + this->DoReadArrayVariant(association, dataType, numElements, 3); + this->AddField(dataName, association, data); } - void ReadTensors(std::size_t numElements, - std::string& dataName, - vtkm::cont::VariantArrayHandle& data) + void ReadTensors(vtkm::cont::Field::Association association, std::size_t numElements) { + std::string dataName; std::string dataType; this->DataFile->Stream >> dataName >> dataType >> std::ws; - this->DoReadArrayVariant(dataType, numElements, 9, data); + vtkm::cont::VariantArrayHandle data = + this->DoReadArrayVariant(association, dataType, numElements, 9); + this->AddField(dataName, association, data); + } + + void ReadFields(vtkm::cont::Field::Association association, std::size_t expectedNumElements) + { + std::string dataName; + vtkm::Id numArrays; + this->DataFile->Stream >> dataName >> numArrays >> std::ws; + for (vtkm::Id i = 0; i < numArrays; ++i) + { + std::size_t numTuples; + vtkm::IdComponent numComponents; + std::string arrayName, dataType; + this->DataFile->Stream >> arrayName >> numComponents >> numTuples >> dataType >> std::ws; + if (numTuples == expectedNumElements) + { + vtkm::cont::VariantArrayHandle data = + this->DoReadArrayVariant(association, dataType, numTuples, numComponents); + this->AddField(arrayName, association, data); + } + else + { + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Field " << arrayName + << "'s size does not match expected number of elements. Skipping"); + } + } } protected: - //ReadFields needs to be protected so that derived readers can skip - //VisIt header fields - void ReadFields(std::string& dataName, std::vector* visitBounds = nullptr) + void ReadGlobalFields(std::vector* visitBounds = nullptr) { - VTKM_LOG_S(vtkm::cont::LogLevel::Warn, "Support for FIELD is not implemented. Skipping."); - + std::string dataName; vtkm::Id numArrays; this->DataFile->Stream >> dataName >> numArrays >> std::ws; for (vtkm::Id i = 0; i < numArrays; ++i) @@ -666,6 +702,8 @@ protected: } else { + VTKM_LOG_S(vtkm::cont::LogLevel::Info, + "Support for global field " << arrayName << " not implemented. Skipping."); this->DoSkipArrayVariant(dataType, numTuples, numComponents); } } @@ -702,9 +740,11 @@ private: { public: ReadArrayVariant(VTKDataSetReaderBase* reader, + vtkm::cont::Field::Association association, std::size_t numElements, vtkm::cont::VariantArrayHandle& data) : SkipArrayVariant(reader, numElements) + , Association(association) , Data(&data) { } @@ -714,7 +754,25 @@ private: { std::vector buffer(this->NumElements); this->Reader->ReadArray(buffer); - *this->Data = internal::CreateVariantArrayHandle(buffer); + if ((this->Association != vtkm::cont::Field::Association::CELL_SET) || + (this->Reader->GetCellsPermutation().GetNumberOfValues() < 1)) + { + *this->Data = internal::CreateVariantArrayHandle(buffer); + } + else + { + // If we are reading data associated with a cell set, we need to (sometimes) permute the + // data due to differences between VTK and VTK-m cell shapes. + auto permutation = this->Reader->GetCellsPermutation().GetPortalConstControl(); + vtkm::Id outSize = permutation.GetNumberOfValues(); + std::vector permutedBuffer(static_cast(outSize)); + for (vtkm::Id outIndex = 0; outIndex < outSize; outIndex++) + { + std::size_t inIndex = static_cast(permutation.Get(outIndex)); + permutedBuffer[static_cast(outIndex)] = buffer[inIndex]; + } + *this->Data = internal::CreateVariantArrayHandle(permutedBuffer); + } } template @@ -726,6 +784,7 @@ private: } private: + vtkm::cont::Field::Association Association; vtkm::cont::VariantArrayHandle* Data; }; @@ -755,14 +814,20 @@ protected: } } - void DoReadArrayVariant(std::string dataType, - std::size_t numElements, - vtkm::IdComponent numComponents, - vtkm::cont::VariantArrayHandle& data) + vtkm::cont::VariantArrayHandle DoReadArrayVariant(vtkm::cont::Field::Association association, + std::string dataType, + std::size_t numElements, + vtkm::IdComponent numComponents) { + // Create empty data to start so that the return can check if data were actually read + vtkm::cont::ArrayHandle empty; + vtkm::cont::VariantArrayHandle data(empty); + vtkm::io::internal::DataType typeId = vtkm::io::internal::DataTypeId(dataType); vtkm::io::internal::SelectTypeAndCall( - typeId, numComponents, ReadArrayVariant(this, numElements, data)); + typeId, numComponents, ReadArrayVariant(this, association, numElements, data)); + + return data; } template @@ -906,10 +971,15 @@ protected: // Skipping INFORMATION is tricky. The reader needs to be aware of the types of the // information, which is not provided in the file. // Here we will just skip until an empty line is found. - std::string line; - while (this->DataFile->Stream.good() && line != "\n") + // However, if there are no keys, then there is nothing to read (and the stream tends + // to skip over empty lines. + if (numKeys > 0) { - std::getline(this->DataFile->Stream, line); + std::string line; + do + { + std::getline(this->DataFile->Stream, line); + } while (this->DataFile->Stream.good() && !line.empty()); } } else @@ -918,45 +988,6 @@ protected: } } -private: - class PermuteCellData - { - public: - PermuteCellData(const vtkm::cont::ArrayHandle& permutation, - vtkm::cont::VariantArrayHandle& data) - : Permutation(permutation) - , Data(&data) - { - } - - template - void operator()(const ArrayHandleType& handle) const - { - VTKM_IS_ARRAY_HANDLE(ArrayHandleType); - using T = typename ArrayHandleType::ValueType; - - if (this->Permutation.GetNumberOfValues() < 1) - { - return; - } - vtkm::cont::ArrayHandle out; - out.Allocate(this->Permutation.GetNumberOfValues()); - - auto permutationPortal = this->Permutation.GetPortalConstControl(); - auto inPortal = handle.GetPortalConstControl(); - auto outPortal = out.GetPortalControl(); - for (vtkm::Id i = 0; i < out.GetNumberOfValues(); ++i) - { - outPortal.Set(i, inPortal.Get(permutationPortal.Get(i))); - } - *this->Data = vtkm::cont::VariantArrayHandle(out); - } - - private: - const vtkm::cont::ArrayHandle Permutation; - vtkm::cont::VariantArrayHandle* Data; - }; - protected: std::unique_ptr DataFile; vtkm::cont::DataSet DataSet; From 9c41daa2bd42aa4c9d6532d5bf824a4b2a676b09 Mon Sep 17 00:00:00 2001 From: Roxana Bujack Date: Thu, 12 Sep 2019 14:17:20 -0600 Subject: [PATCH 004/108] change input to spacing and radius to make it more intuitive --- vtkm/filter/ComputeMoments.h | 11 +-- vtkm/filter/ComputeMoments.hxx | 2 +- vtkm/worklet/moments/ComputeMoments.h | 108 +++++++++++++------------- 3 files changed, 61 insertions(+), 60 deletions(-) diff --git a/vtkm/filter/ComputeMoments.h b/vtkm/filter/ComputeMoments.h index 5d25ce2c6..e6c0b464d 100644 --- a/vtkm/filter/ComputeMoments.h +++ b/vtkm/filter/ComputeMoments.h @@ -28,18 +28,15 @@ public: const vtkm::filter::FieldMetadata& fieldMetadata, const vtkm::filter::PolicyBase&); - VTKM_CONT void SetRadiusDiscrete(vtkm::Vec _radius) - { - this->RadiusDiscrete = _radius; - } + VTKM_CONT void SetRadius(double _radius) { this->Radius = _radius; } - VTKM_CONT void SetRadiusReal(vtkm::Vec _radius) { this->RadiusReal = _radius; } + VTKM_CONT void SetSpacing(vtkm::Vec _spacing) { this->Spacing = _spacing; } VTKM_CONT void SetOrder(vtkm::Int32 _order) { this->Order = _order; } private: - vtkm::Vec RadiusDiscrete = { 1, 1, 1 }; - vtkm::Vec RadiusReal = { 1, 1, 1 }; + double Radius = 1; + vtkm::Vec Spacing = { 1, 1, 1 }; vtkm::Int32 Order = 0; }; } diff --git a/vtkm/filter/ComputeMoments.hxx b/vtkm/filter/ComputeMoments.hxx index 9ec47221a..9cc5e965c 100644 --- a/vtkm/filter/ComputeMoments.hxx +++ b/vtkm/filter/ComputeMoments.hxx @@ -39,7 +39,7 @@ inline VTKM_CONT vtkm::cont::DataSet ComputeMoments::DoExecute( vtkm::cont::DataSet output; output.CopyStructure(input); - auto worklet = vtkm::worklet::moments::ComputeMoments(this->RadiusDiscrete, this->RadiusReal); + auto worklet = vtkm::worklet::moments::ComputeMoments(this->Spacing, this->Radius); worklet.Run(input.GetCellSet(this->GetActiveCellSetIndex()), field, this->Order, output); diff --git a/vtkm/worklet/moments/ComputeMoments.h b/vtkm/worklet/moments/ComputeMoments.h index 8cd4534ca..14fade5f6 100644 --- a/vtkm/worklet/moments/ComputeMoments.h +++ b/vtkm/worklet/moments/ComputeMoments.h @@ -32,17 +32,15 @@ namespace moments struct ComputeMoments2D : public vtkm::worklet::WorkletPointNeighborhood { public: - ComputeMoments2D(const vtkm::Vec& _radiusDiscrete, - const vtkm::Vec& _radiusReal, - int _p, - int _q) - : RadiusDiscrete(_radiusDiscrete) - , RadiusReal(_radiusReal) + ComputeMoments2D(const vtkm::Vec& _spacing, const double _radius, int _p, int _q) + : Spacing(_spacing) + , Radius(_radius) , p(_p) , q(_q) { - assert(_radiusReal[0] >= 1); - assert(_radiusReal[1] >= 1); + assert(_spacing[0] > 1e-10); + assert(_spacing[1] > 1e-10); + assert(_spacing[2] > 1e-10); assert(_p >= 0); assert(_q >= 0); @@ -59,28 +57,31 @@ public: { // TODO: type safety and numerical precision auto sum = vtkm::TypeTraits::ZeroInitialization(); - vtkm::Vec recp{ 1.0 / RadiusReal[0], 1.0 / RadiusReal[1] }; + // vtkm::Vec recp{ 1.0 / RadiusReal[0], 1.0 / RadiusReal[1] }; + vtkm::Vec RadiusDiscrete = { this->Radius / (this->Spacing[0] - 1e-10), + this->Radius / (this->Spacing[1] - 1e-10), + this->Radius / (this->Spacing[2] - 1e-10) }; // Clamp the radius to the dataset bounds (discard out-of-bounds points). - const auto minRadius = boundary.ClampNeighborIndex(-this->RadiusDiscrete); - const auto maxRadius = boundary.ClampNeighborIndex(this->RadiusDiscrete); + const auto minRadius = boundary.ClampNeighborIndex(-RadiusDiscrete); + const auto maxRadius = boundary.ClampNeighborIndex(RadiusDiscrete); for (vtkm::IdComponent j = minRadius[1]; j <= maxRadius[1]; ++j) { - if (j > -this->RadiusDiscrete[1] && boundary.IJK[1] + j == 0) + if (j > -RadiusDiscrete[1] && boundary.IJK[1] + j == 0) { // Don't double count samples that exist on other nodes: continue; } for (vtkm::IdComponent i = minRadius[0]; i <= maxRadius[0]; ++i) { - if (i > -this->RadiusDiscrete[0] && boundary.IJK[0] + i == 0) + if (i > -RadiusDiscrete[0] && boundary.IJK[0] + i == 0) { // Don't double count samples that exist on other nodes: continue; } - const vtkm::Float64 r0 = i * recp[0]; - const vtkm::Float64 r1 = j * recp[1]; + const vtkm::Float64 r0 = i * 1. / RadiusDiscrete[0]; + const vtkm::Float64 r1 = j * 1. / RadiusDiscrete[1]; if (r0 * r0 + r1 * r1 <= 1) { @@ -89,12 +90,13 @@ public: } } - moment = T(sum * recp[0] * recp[1]); + moment = T(sum * Spacing[0] * Spacing[1]); } private: - const vtkm::Vec RadiusDiscrete; - const vtkm::Vec RadiusReal; + vtkm::Vec RadiusDiscrete; + const double Radius; + const vtkm::Vec& Spacing; const int p; const int q; }; @@ -102,20 +104,20 @@ private: struct ComputeMoments3D : public vtkm::worklet::WorkletPointNeighborhood { public: - ComputeMoments3D(vtkm::Vec& _radiusDiscrete, - vtkm::Vec& _radiusReal, + ComputeMoments3D(const vtkm::Vec& _spacing, + const double _radius, int _p, int _q, int _r) - : RadiusDiscrete(_radiusDiscrete) - , RadiusReal(_radiusReal) + : Spacing(_spacing) + , Radius(_radius) , p(_p) , q(_q) , r(_r) { - assert(_radiusReal[0] >= 1); - assert(_radiusReal[1] >= 1); - assert(_radiusReal[2] >= 1); + assert(_spacing[0] > 1e-10); + assert(_spacing[1] > 1e-10); + assert(_spacing[2] > 1e-10); assert(_p >= 0); assert(_q >= 0); @@ -133,38 +135,41 @@ public: { // TODO: type safety and numerical precision auto sum = vtkm::TypeTraits::ZeroInitialization(); - const vtkm::Vec recp{ 1.0 / this->RadiusReal[0], - 1.0 / this->RadiusReal[1], - 1.0 / this->RadiusReal[2] }; + // const vtkm::Vec recp{ 1.0 / this->RadiusReal[0], + // 1.0 / this->RadiusReal[1], + // 1.0 / this->RadiusReal[2] }; + vtkm::Vec RadiusDiscrete = { this->Radius / (this->Spacing[0] - 1e-10), + this->Radius / (this->Spacing[1] - 1e-10), + this->Radius / (this->Spacing[2] - 1e-10) }; // Clamp the radius to the dataset bounds (discard out-of-bounds points). - const auto minRadius = boundary.ClampNeighborIndex(-this->RadiusDiscrete); - const auto maxRadius = boundary.ClampNeighborIndex(this->RadiusDiscrete); + const auto minRadius = boundary.ClampNeighborIndex(-RadiusDiscrete); + const auto maxRadius = boundary.ClampNeighborIndex(RadiusDiscrete); for (vtkm::IdComponent k = minRadius[2]; k <= maxRadius[2]; ++k) { - if (k > -this->RadiusDiscrete[2] && boundary.IJK[2] + k == 0) + if (k > -RadiusDiscrete[2] && boundary.IJK[2] + k == 0) { // Don't double count samples that exist on other nodes: continue; } for (vtkm::IdComponent j = minRadius[1]; j <= maxRadius[1]; ++j) { - if (j > -this->RadiusDiscrete[1] && boundary.IJK[1] + j == 0) + if (j > -RadiusDiscrete[1] && boundary.IJK[1] + j == 0) { // Don't double count samples that exist on other nodes: continue; } for (vtkm::IdComponent i = minRadius[0]; i <= maxRadius[0]; ++i) { - if (i > -this->RadiusDiscrete[0] && boundary.IJK[0] + i == 0) + if (i > -RadiusDiscrete[0] && boundary.IJK[0] + i == 0) { // Don't double count samples that exist on other nodes: continue; } - const vtkm::Float64 r0 = i * recp[0]; - const vtkm::Float64 r1 = j * recp[1]; - const vtkm::Float64 r2 = k * recp[2]; + const vtkm::Float64 r0 = i * 1. / RadiusDiscrete[0]; + const vtkm::Float64 r1 = j * 1. / RadiusDiscrete[1]; + const vtkm::Float64 r2 = k * 1. / RadiusDiscrete[2]; if (r0 * r0 + r1 * r1 + r2 * r2 <= 1) { @@ -174,12 +179,12 @@ public: } } - moment = T(sum * recp[0] * recp[1] * recp[2]); + moment = T(sum * Spacing[0] * Spacing[1] * Spacing[2]); } private: - const vtkm::Vec& RadiusDiscrete; - const vtkm::Vec& RadiusReal; + const double Radius; + const vtkm::Vec& Spacing; const int p; const int q; const int r; @@ -188,9 +193,9 @@ private: class ComputeMoments { public: - ComputeMoments(vtkm::Vec& _radiusDiscrete, vtkm::Vec& _radiusReal) - : RadiusDiscrete(_radiusDiscrete) - , RadiusReal(_radiusReal) + ComputeMoments(vtkm::Vec& _spacing, const double _radius) + : Spacing(_spacing) + , Radius(_radius) { } @@ -200,8 +205,8 @@ public: template void operator()(const vtkm::cont::CellSetStructured<2>& input, const vtkm::cont::ArrayHandle& pixels, - vtkm::Vec RadiusDiscrete, - vtkm::Vec RadiusReal, + vtkm::Vec Spacing, + double Radius, int maxOrder, vtkm::cont::DataSet& output) const { @@ -216,7 +221,7 @@ public: vtkm::cont::ArrayHandle moments; - DispatcherType dispatcher(WorkletType{ RadiusDiscrete, RadiusReal, p, q }); + DispatcherType dispatcher(WorkletType{ Spacing, Radius, p, q }); dispatcher.Invoke(input, pixels, moments); std::string fieldName = std::string("index") + std::string(p, '0') + std::string(q, '1'); @@ -231,8 +236,8 @@ public: template void operator()(const vtkm::cont::CellSetStructured<3>& input, const vtkm::cont::ArrayHandle& pixels, - vtkm::Vec RadiusDiscrete, - vtkm::Vec RadiusReal, + vtkm::Vec Spacing, + double Radius, int maxOrder, vtkm::cont::DataSet& output) const { @@ -250,7 +255,7 @@ public: vtkm::cont::ArrayHandle moments; - DispatcherType dispatcher(WorkletType{ RadiusDiscrete, RadiusReal, p, q, r }); + DispatcherType dispatcher(WorkletType{ Spacing, Radius, p, q, r }); dispatcher.Invoke(input, pixels, moments); std::string fieldName = std::string("index") + std::string(p, '0') + @@ -272,13 +277,12 @@ public: vtkm::cont::DataSet& output) const { input.ResetCellSetList(vtkm::cont::CellSetListTagStructured()) - .CastAndCall( - ResolveDynamicCellSet(), pixels, this->RadiusDiscrete, this->RadiusReal, maxOrder, output); + .CastAndCall(ResolveDynamicCellSet(), pixels, this->Spacing, this->Radius, maxOrder, output); } private: - const vtkm::Vec RadiusDiscrete = { 1, 1, 1 }; - const vtkm::Vec RadiusReal = { 1, 1, 1 }; + const double Radius = 1; + const vtkm::Vec Spacing = { 1, 1, 1 }; }; } } From 2d455bbef8cb49a08cfe793fcf654833d93b3589 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 13 Sep 2019 08:12:03 -0400 Subject: [PATCH 005/108] Document what the Tangle source will generate --- vtkm/source/Tangle.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/vtkm/source/Tangle.h b/vtkm/source/Tangle.h index b6c607b8d..637ae75a0 100644 --- a/vtkm/source/Tangle.h +++ b/vtkm/source/Tangle.h @@ -17,7 +17,18 @@ namespace vtkm { namespace source { -class Tangle : public vtkm::source::Source +/** + * @brief The Tangle source creates a uniform dataset. + * + * This class generates a predictable uniform grid dataset with an + * interesting set of point and cell scalar arrays, which is useful + * for testing and benchmarking. + * + * The Execute method creates a complete structured dataset that have a + * point field named 'nodevar', and a cell field named 'cellvar'. + * +**/ +class VTKM_SOURCE_EXPORT Tangle final : public vtkm::source::Source { public: VTKM_CONT @@ -26,7 +37,6 @@ public: { } - VTKM_SOURCE_EXPORT vtkm::cont::DataSet Execute() const; private: @@ -35,4 +45,4 @@ private: } //namespace source } //namespace vtkm -#endif //VTKM_TANGLE_H +#endif //vtk_m_source_Tangle_h From 257dc1f84e636ce72acb79849e7a8c369f5b20ea Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 13 Sep 2019 08:12:58 -0400 Subject: [PATCH 006/108] Sources have a more consistent API and internal style. `vtkm::source::Source` now uses virtual inheritance for the `Execute` method. This will allow us to enforce that all vtkm::source have a consistent calling convention. To make the code inside filters and sources more similar the base `vtkm::source::Source` class has a `vtkm::cont::Invoker` as a member variable. This will allow sources to use the `this->Invoke()` pattern that filters use to launch worklets. --- vtkm/source/CMakeLists.txt | 6 +- vtkm/source/Source.cxx | 24 ++ vtkm/source/Source.h | 13 +- vtkm/source/Tangle.cxx | 8 +- vtkm/source/testing/CMakeLists.txt | 19 ++ .../testing/UnitTestWaveletSource.cxx} | 6 +- vtkm/worklet/CMakeLists.txt | 1 - vtkm/worklet/WaveletGenerator.h | 285 ------------------ vtkm/worklet/testing/CMakeLists.txt | 1 - 9 files changed, 63 insertions(+), 300 deletions(-) create mode 100644 vtkm/source/Source.cxx create mode 100644 vtkm/source/testing/CMakeLists.txt rename vtkm/{worklet/testing/UnitTestWaveletGenerator.cxx => source/testing/UnitTestWaveletSource.cxx} (95%) delete mode 100644 vtkm/worklet/WaveletGenerator.h diff --git a/vtkm/source/CMakeLists.txt b/vtkm/source/CMakeLists.txt index 599030946..07e78e47b 100644 --- a/vtkm/source/CMakeLists.txt +++ b/vtkm/source/CMakeLists.txt @@ -14,6 +14,7 @@ set(headers ) set(device_sources + Source.cxx Tangle.cxx ) @@ -22,4 +23,7 @@ vtkm_library(NAME vtkm_source HEADERS ${headers} ) -target_link_libraries(vtkm_source PUBLIC vtkm_worklet) +target_link_libraries(vtkm_source PUBLIC vtkm_cont) + +#----------------------------------------------------------------------------- +add_subdirectory(testing) diff --git a/vtkm/source/Source.cxx b/vtkm/source/Source.cxx new file mode 100644 index 000000000..de1ffb067 --- /dev/null +++ b/vtkm/source/Source.cxx @@ -0,0 +1,24 @@ +//============================================================================ +// 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 + +namespace vtkm +{ +namespace source +{ + +//Fix the vtable for Source to be in the vtkm_source library +Source::Source() = default; +Source::~Source() = default; + + +} // namespace source +} // namespace vtkm diff --git a/vtkm/source/Source.h b/vtkm/source/Source.h index 02bc7b22a..2179f3f47 100644 --- a/vtkm/source/Source.h +++ b/vtkm/source/Source.h @@ -12,21 +12,26 @@ #define vtk_m_source_Source_h #include +#include #include - namespace vtkm { namespace source { -class Source +class VTKM_SOURCE_EXPORT Source { public: VTKM_CONT - Source() {} + Source(); VTKM_CONT - ~Source() {} + virtual ~Source(); + + virtual vtkm::cont::DataSet Execute() const = 0; + +protected: + vtkm::cont::Invoker Invoke; }; } // namespace source diff --git a/vtkm/source/Tangle.cxx b/vtkm/source/Tangle.cxx index f537f84c7..bb5a0b6ef 100644 --- a/vtkm/source/Tangle.cxx +++ b/vtkm/source/Tangle.cxx @@ -8,8 +8,8 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ +#include #include -#include namespace vtkm { @@ -71,7 +71,6 @@ public: }; } // namespace tangle -VTKM_SOURCE_EXPORT vtkm::cont::DataSet Tangle::Execute() const { vtkm::cont::DataSet dataSet; @@ -83,9 +82,8 @@ vtkm::cont::DataSet Tangle::Execute() const vtkm::cont::ArrayHandle pointFieldArray; vtkm::cont::ArrayHandleIndex vertexCountImplicitArray(vdims[0] * vdims[1] * vdims[2]); - vtkm::worklet::DispatcherMapField tangleFieldDispatcher( - tangle::TangleField(vdims, mins, maxs)); - tangleFieldDispatcher.Invoke(vertexCountImplicitArray, pointFieldArray); + + this->Invoke(tangle::TangleField{ vdims, mins, maxs }, vertexCountImplicitArray, pointFieldArray); vtkm::Id numCells = Dims[0] * Dims[1] * Dims[2]; vtkm::cont::ArrayHandle cellFieldArray; diff --git a/vtkm/source/testing/CMakeLists.txt b/vtkm/source/testing/CMakeLists.txt new file mode 100644 index 000000000..340c1f142 --- /dev/null +++ b/vtkm/source/testing/CMakeLists.txt @@ -0,0 +1,19 @@ +##============================================================================ +## 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. +##============================================================================ + +set(unit_tests + UnitTestWaveletSource.cxx + ) + +vtkm_unit_tests( + SOURCES ${unit_tests} + LIBRARIES vtkm_source + ALL_BACKENDS +) diff --git a/vtkm/worklet/testing/UnitTestWaveletGenerator.cxx b/vtkm/source/testing/UnitTestWaveletSource.cxx similarity index 95% rename from vtkm/worklet/testing/UnitTestWaveletGenerator.cxx rename to vtkm/source/testing/UnitTestWaveletSource.cxx index ff2a24128..bb5bd2410 100644 --- a/vtkm/worklet/testing/UnitTestWaveletGenerator.cxx +++ b/vtkm/source/testing/UnitTestWaveletSource.cxx @@ -8,7 +8,7 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include #include @@ -18,8 +18,8 @@ void WaveletGeneratorTest() vtkm::cont::Timer timer; timer.Start(); - vtkm::worklet::WaveletGenerator gen; - vtkm::cont::DataSet ds = gen.GenerateDataSet(); + vtkm::source::Wavelet source; + vtkm::cont::DataSet ds = source.Execute(); double time = timer.GetElapsedTime(); diff --git a/vtkm/worklet/CMakeLists.txt b/vtkm/worklet/CMakeLists.txt index 2f6307180..616b6179f 100644 --- a/vtkm/worklet/CMakeLists.txt +++ b/vtkm/worklet/CMakeLists.txt @@ -82,7 +82,6 @@ set(headers WarpScalar.h WarpVector.h WaveletCompressor.h - WaveletGenerator.h WorkletMapField.h WorkletMapTopology.h WorkletPointNeighborhood.h diff --git a/vtkm/worklet/WaveletGenerator.h b/vtkm/worklet/WaveletGenerator.h deleted file mode 100644 index 05a54a127..000000000 --- a/vtkm/worklet/WaveletGenerator.h +++ /dev/null @@ -1,285 +0,0 @@ -//============================================================================ -// 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_worklet_waveletgenerator_h -#define vtk_m_worklet_waveletgenerator_h - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -namespace vtkm -{ -namespace worklet -{ - -namespace wavelet -{ -template -struct Worker : public vtkm::exec::FunctorBase -{ - using OutputHandleType = vtkm::cont::ArrayHandle; - using OutputPortalType = decltype(std::declval().PrepareForOutput(0, Device())); - using Vec3F = vtkm::Vec3f; - - Vec3F Center; - Vec3F Spacing; - Vec3F Frequency; - Vec3F Magnitude; - Vec3F MinimumPoint; - Vec3F Scale; - vtkm::Id3 Offset; - vtkm::Id3 Dims; - vtkm::FloatDefault MaximumValue; - vtkm::FloatDefault Temp2; - OutputPortalType Portal; - - VTKM_CONT - Worker(OutputHandleType& output, - const Vec3F& center, - const Vec3F& spacing, - const Vec3F& frequency, - const Vec3F& magnitude, - const Vec3F& minimumPoint, - const Vec3F& scale, - const vtkm::Id3& offset, - const vtkm::Id3& dims, - vtkm::FloatDefault maximumValue, - vtkm::FloatDefault temp2) - : Center(center) - , Spacing(spacing) - , Frequency(frequency) - , Magnitude(magnitude) - , MinimumPoint(minimumPoint) - , Scale(scale) - , Offset(offset) - , Dims(dims) - , MaximumValue(maximumValue) - , Temp2(temp2) - , Portal(output.PrepareForOutput((dims[0] * dims[1] * dims[2]), Device{})) - { - } - - VTKM_EXEC - void operator()(const vtkm::Id3& ijk) const - { - // map ijk to the point location, accounting for spacing: - const Vec3F loc = Vec3F(ijk + this->Offset) * this->Spacing; - - // Compute the distance from the center of the gaussian: - const Vec3F scaledLoc = (this->Center - loc) * this->Scale; - vtkm::FloatDefault gaussSum = vtkm::Dot(scaledLoc, scaledLoc); - - const Vec3F periodicContribs{ - this->Magnitude[0] * vtkm::Sin(this->Frequency[0] * scaledLoc[0]), - this->Magnitude[1] * vtkm::Sin(this->Frequency[1] * scaledLoc[1]), - this->Magnitude[2] * vtkm::Cos(this->Frequency[2] * scaledLoc[2]), - }; - - // The vtkRTAnalyticSource documentation says the periodic contributions - // should be multiplied in, but the implementation adds them. We'll do as - // they do, not as they say. - const vtkm::FloatDefault scalar = this->MaximumValue * vtkm::Exp(-gaussSum * this->Temp2) + - periodicContribs[0] + periodicContribs[1] + periodicContribs[2]; - - // Compute output location - // (see ConnectivityStructuredInternals<3>::LogicalToFlatPointIndex) - const vtkm::Id scalarIdx = ijk[0] + this->Dims[0] * (ijk[1] + this->Dims[1] * ijk[2]); - this->Portal.Set(scalarIdx, scalar); - } -}; - -struct runWorker -{ - template - inline bool operator()(Device, const vtkm::Id3 dims, Args... args) const - { - using Algo = vtkm::cont::DeviceAdapterAlgorithm; - Worker worker{ args... }; - Algo::Schedule(worker, dims); - return true; - } -}; -} - -/** - * @brief The WaveletGenerator class creates a dataset similar to VTK's - * vtkRTAnalyticSource. - * - * This class generates a predictable structured dataset with a smooth yet - * interesting set of scalars, which is useful for testing and benchmarking. - * - * The GenerateDataSet method can be used to create a complete structured - * dataset, while GenerateField will generate the scalar point field only. - * - * The scalars are computed as: - * - * ``` - * MaxVal * Gauss + MagX * sin(FrqX*x) + MagY * sin(FrqY*y) + MagZ * cos(FrqZ*z) - * ``` - * - * The dataset properties are determined by: - * - `Minimum/MaximumExtent`: The logical point extents of the dataset. - * - `Spacing`: The distance between points of the dataset. - * - `Center`: The center of the dataset. - * - * The scalar functions is control via: - * - `Center`: The center of a Gaussian contribution to the scalars. - * - `StandardDeviation`: The unscaled width of a Gaussian contribution. - * - `MaximumValue`: Upper limit of the scalar range. - * - `Frequency`: The Frq[XYZ] parameters of the periodic contributions. - * - `Magnitude`: The Mag[XYZ] parameters of the periodic contributions. - * - * By default, the following parameters are used: - * - `Extents`: { -10, -10, -10 } `-->` { 10, 10, 10 } - * - `Spacing`: { 1, 1, 1 } - * - `Center`: { 0, 0, 0 } - * - `StandardDeviation`: 0.5 - * - `MaximumValue`: 255 - * - `Frequency`: { 60, 30, 40 } - * - `Magnitude`: { 10, 18, 5 } - */ -class WaveletGenerator -{ - using Vec3F = vtkm::Vec3f; - - Vec3F Center; - Vec3F Spacing; - Vec3F Frequency; - Vec3F Magnitude; - vtkm::Id3 MinimumExtent; - vtkm::Id3 MaximumExtent; - FloatDefault MaximumValue; - FloatDefault StandardDeviation; - -public: - VTKM_CONT - WaveletGenerator() - : Center{ 0. } - , Spacing{ 1. } - , Frequency{ 60., 30., 40. } - , Magnitude{ 10., 18., 5. } - , MinimumExtent{ -10 } - , MaximumExtent{ 10 } - , MaximumValue{ 255. } - , StandardDeviation{ 0.5 } - { - } - - VTKM_CONT void SetCenter(const vtkm::Vec& center) { this->Center = center; } - - VTKM_CONT void SetSpacing(const vtkm::Vec& spacing) { this->Spacing = spacing; } - - VTKM_CONT void SetFrequency(const vtkm::Vec& frequency) - { - this->Frequency = frequency; - } - - VTKM_CONT void SetMagnitude(const vtkm::Vec& magnitude) - { - this->Magnitude = magnitude; - } - - VTKM_CONT void SetMinimumExtent(const vtkm::Id3& minExtent) { this->MinimumExtent = minExtent; } - - VTKM_CONT void SetMaximumExtent(const vtkm::Id3& maxExtent) { this->MaximumExtent = maxExtent; } - - VTKM_CONT void SetExtent(const vtkm::Id3& minExtent, const vtkm::Id3& maxExtent) - { - this->MinimumExtent = minExtent; - this->MaximumExtent = maxExtent; - } - - VTKM_CONT void SetMaximumValue(const vtkm::FloatDefault& maxVal) { this->MaximumValue = maxVal; } - - VTKM_CONT void SetStandardDeviation(const vtkm::FloatDefault& stdev) - { - this->StandardDeviation = stdev; - } - - VTKM_CONT vtkm::cont::DataSet GenerateDataSet( - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) const - { - VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); - - // Create points: - const vtkm::Id3 dims{ this->MaximumExtent - this->MinimumExtent + vtkm::Id3{ 1 } }; - const Vec3F origin{ this->MinimumExtent }; - vtkm::cont::CoordinateSystem coords{ "coords", dims, origin, this->Spacing }; - - // And cells: - vtkm::cont::CellSetStructured<3> cellSet; - cellSet.SetPointDimensions(dims); - - // Scalars, too - vtkm::cont::Field field = this->GenerateField("scalars", device); - - // Compile the dataset: - vtkm::cont::DataSet dataSet; - dataSet.AddCoordinateSystem(coords); - dataSet.SetCellSet(cellSet); - dataSet.AddField(field); - - return dataSet; - } - - VTKM_CONT vtkm::cont::Field GenerateField( - const std::string& name, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) const - { - VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); - - const vtkm::Id3 dims{ this->MaximumExtent - this->MinimumExtent + vtkm::Id3{ 1 } }; - Vec3F minPt = Vec3F(this->MinimumExtent) * this->Spacing; - vtkm::FloatDefault temp2 = 1.f / (2.f * this->StandardDeviation * this->StandardDeviation); - Vec3F scale{ ComputeScaleFactor(this->MinimumExtent[0], this->MaximumExtent[0]), - ComputeScaleFactor(this->MinimumExtent[1], this->MaximumExtent[1]), - ComputeScaleFactor(this->MinimumExtent[2], this->MaximumExtent[2]) }; - - - vtkm::cont::ArrayHandle output; - vtkm::cont::TryExecuteOnDevice(device, - wavelet::runWorker{}, - dims, - output, - this->Center, - this->Spacing, - this->Frequency, - this->Magnitude, - minPt, - scale, - this->MinimumExtent, - dims, - this->MaximumValue, - temp2); - return vtkm::cont::make_FieldPoint(name, output); - } - -private: - static vtkm::FloatDefault ComputeScaleFactor(vtkm::Id min, vtkm::Id max) - { - return (min < max) ? (1.f / static_cast(max - min)) - : static_cast(1.); - } -}; -} -} // end namespace vtkm::worklet - -#endif // vtk_m_worklet_waveletgenerator_h diff --git a/vtkm/worklet/testing/CMakeLists.txt b/vtkm/worklet/testing/CMakeLists.txt index 1e6342d9e..9996c2e03 100644 --- a/vtkm/worklet/testing/CMakeLists.txt +++ b/vtkm/worklet/testing/CMakeLists.txt @@ -82,7 +82,6 @@ set(unit_tests UnitTestWarpScalar.cxx UnitTestWarpVector.cxx UnitTestWaveletCompressor.cxx - UnitTestWaveletGenerator.cxx UnitTestZFPCompressor.cxx ) From 7e01edb01797dc3291f44baf7b0eb351ecc81f44 Mon Sep 17 00:00:00 2001 From: Allison Vacanti Date: Fri, 13 Sep 2019 11:42:33 -0400 Subject: [PATCH 007/108] Ensure that Portal::Set isn't defined for read-only portals. This patch removes (or conditionally removes) the Set method from portals that are read-only so that IsWritableArrayHandle will work as expected. The ArrayPortal doxygen has been updated to reflect this. The remaining exceptions are `ArrayPortalVirtual` and `ArrayPortalMultiplexer`, since their mutability cannot be determined at compile time. --- vtkm/cont/ArrayHandleCompositeVector.h | 14 ++++++- vtkm/cont/ArrayHandleConcatenate.h | 17 +++++++- vtkm/cont/ArrayHandleExtractComponent.h | 7 +++- vtkm/cont/ArrayHandleGroupVec.h | 7 +++- vtkm/cont/ArrayHandlePermutation.h | 7 +++- vtkm/cont/ArrayHandleReverse.h | 7 +++- vtkm/cont/ArrayHandleStreaming.h | 7 +++- vtkm/cont/ArrayHandleSwizzle.h | 6 ++- vtkm/cont/ArrayHandleTransform.h | 28 +++---------- vtkm/cont/ArrayHandleView.h | 7 +++- vtkm/cont/ArrayHandleZip.h | 52 ++++++++----------------- vtkm/cont/ArrayPortal.h | 9 ++++- 12 files changed, 91 insertions(+), 77 deletions(-) diff --git a/vtkm/cont/ArrayHandleCompositeVector.h b/vtkm/cont/ArrayHandleCompositeVector.h index dac2df378..0b5ed9038 100644 --- a/vtkm/cont/ArrayHandleCompositeVector.h +++ b/vtkm/cont/ArrayHandleCompositeVector.h @@ -17,6 +17,8 @@ #include +#include + #include namespace vtkm @@ -373,11 +375,18 @@ struct ArraySizeValidator } }; +template +using AllPortalsAreWritable = + typename brigand::all>::type; + } // end namespace compvec template class VTKM_ALWAYS_EXPORT ArrayPortalCompositeVector { + using Writable = compvec::AllPortalsAreWritable; + public: using ValueType = typename compvec::GetValueType::ValueType; @@ -459,8 +468,9 @@ public: return result; } - VTKM_EXEC_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { SetImpl<0, PortalTuple>::Exec(this->Portals, value, index); } diff --git a/vtkm/cont/ArrayHandleConcatenate.h b/vtkm/cont/ArrayHandleConcatenate.h index 9d3cfed89..074097689 100644 --- a/vtkm/cont/ArrayHandleConcatenate.h +++ b/vtkm/cont/ArrayHandleConcatenate.h @@ -22,6 +22,10 @@ namespace internal template class VTKM_ALWAYS_EXPORT ArrayPortalConcatenate { + using WritableP1 = vtkm::internal::PortalSupportsSets; + using WritableP2 = vtkm::internal::PortalSupportsSets; + using Writable = std::integral_constant; + public: using ValueType = typename PortalType1::ValueType; @@ -58,18 +62,27 @@ public: ValueType Get(vtkm::Id index) const { if (index < this->portal1.GetNumberOfValues()) + { return this->portal1.Get(index); + } else + { return this->portal2.Get(index - this->portal1.GetNumberOfValues()); + } } - VTKM_EXEC_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { if (index < this->portal1.GetNumberOfValues()) + { this->portal1.Set(index, value); + } else + { this->portal2.Set(index - this->portal1.GetNumberOfValues(), value); + } } VTKM_EXEC_CONT diff --git a/vtkm/cont/ArrayHandleExtractComponent.h b/vtkm/cont/ArrayHandleExtractComponent.h index 5b4af37ca..625368f71 100644 --- a/vtkm/cont/ArrayHandleExtractComponent.h +++ b/vtkm/cont/ArrayHandleExtractComponent.h @@ -23,6 +23,8 @@ namespace internal template class VTKM_ALWAYS_EXPORT ArrayPortalExtractComponent { + using Writable = vtkm::internal::PortalSupportsSets; + public: using VectorType = typename PortalType::ValueType; using Traits = vtkm::VecTraits; @@ -58,8 +60,9 @@ public: return Traits::GetComponent(this->Portal.Get(index), this->Component); } - VTKM_EXEC_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { VectorType vec = this->Portal.Get(index); Traits::SetComponent(vec, this->Component, value); diff --git a/vtkm/cont/ArrayHandleGroupVec.h b/vtkm/cont/ArrayHandleGroupVec.h index 048b2441b..a0a911679 100644 --- a/vtkm/cont/ArrayHandleGroupVec.h +++ b/vtkm/cont/ArrayHandleGroupVec.h @@ -25,6 +25,8 @@ namespace internal template class VTKM_ALWAYS_EXPORT ArrayPortalGroupVec { + using Writable = vtkm::internal::PortalSupportsSets; + public: static constexpr vtkm::IdComponent NUM_COMPONENTS = N_COMPONENTS; using SourcePortalType = PortalType; @@ -79,8 +81,9 @@ public: } VTKM_SUPPRESS_EXEC_WARNINGS - VTKM_EXEC_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { vtkm::Id sourceIndex = index * NUM_COMPONENTS; for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++) diff --git a/vtkm/cont/ArrayHandlePermutation.h b/vtkm/cont/ArrayHandlePermutation.h index b66ca015d..4a9f6b248 100644 --- a/vtkm/cont/ArrayHandlePermutation.h +++ b/vtkm/cont/ArrayHandlePermutation.h @@ -24,6 +24,8 @@ namespace internal template class VTKM_ALWAYS_EXPORT ArrayPortalPermutation { + using Writable = vtkm::internal::PortalSupportsSets; + public: using ValueType = typename ValuePortalType::ValueType; @@ -69,8 +71,9 @@ public: } VTKM_SUPPRESS_EXEC_WARNINGS - VTKM_EXEC - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC void Set(vtkm::Id index, const ValueType& value) const { vtkm::Id permutedIndex = this->IndexPortal.Get(index); this->ValuePortal.Set(permutedIndex, value); diff --git a/vtkm/cont/ArrayHandleReverse.h b/vtkm/cont/ArrayHandleReverse.h index 6799c1b43..32c14a8a9 100644 --- a/vtkm/cont/ArrayHandleReverse.h +++ b/vtkm/cont/ArrayHandleReverse.h @@ -26,6 +26,8 @@ namespace internal template class VTKM_ALWAYS_EXPORT ArrayPortalReverse { + using Writable = vtkm::internal::PortalSupportsSets; + public: using ValueType = typename PortalType::ValueType; @@ -56,8 +58,9 @@ public: return this->portal.Get(portal.GetNumberOfValues() - index - 1); } - VTKM_EXEC_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { this->portal.Set(portal.GetNumberOfValues() - index - 1, value); } diff --git a/vtkm/cont/ArrayHandleStreaming.h b/vtkm/cont/ArrayHandleStreaming.h index b4f13f9e8..8e090cfe7 100644 --- a/vtkm/cont/ArrayHandleStreaming.h +++ b/vtkm/cont/ArrayHandleStreaming.h @@ -23,6 +23,8 @@ namespace internal template class VTKM_ALWAYS_EXPORT ArrayPortalStreaming { + using Writable = vtkm::internal::PortalSupportsSets

; + public: using PortalType = P; using ValueType = typename PortalType::ValueType; @@ -66,8 +68,9 @@ public: return this->InputPortal.Get(this->BlockIndex * this->BlockSize + index); } - VTKM_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_CONT void Set(vtkm::Id index, const ValueType& value) const { this->InputPortal.Set(this->BlockIndex * this->BlockSize + index, value); } diff --git a/vtkm/cont/ArrayHandleSwizzle.h b/vtkm/cont/ArrayHandleSwizzle.h index 4f9400e04..ab7a727bf 100644 --- a/vtkm/cont/ArrayHandleSwizzle.h +++ b/vtkm/cont/ArrayHandleSwizzle.h @@ -117,6 +117,7 @@ template ; + using Writable = vtkm::internal::PortalSupportsSets; public: using MapType = typename Traits::MapType; @@ -154,8 +155,9 @@ public: return result; } - VTKM_EXEC_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { if (Traits::AllCompsUsed) { // No need to prefetch the value, all values overwritten diff --git a/vtkm/cont/ArrayHandleTransform.h b/vtkm/cont/ArrayHandleTransform.h index f18d96dc1..80886eb28 100644 --- a/vtkm/cont/ArrayHandleTransform.h +++ b/vtkm/cont/ArrayHandleTransform.h @@ -90,16 +90,6 @@ public: VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const { return this->Functor(this->Portal.Get(index)); } - VTKM_SUPPRESS_EXEC_WARNINGS - VTKM_EXEC_CONT - void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const - { -#if !(defined(VTKM_MSVC) && defined(VTKM_CUDA)) - VTKM_ASSERT(false && - "Cannot write to read-only transform array. (No inverse transform given.)"); -#endif - } - VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT const PortalType& GetPortal() const { return this->Portal; } @@ -120,6 +110,8 @@ template { + using Writable = vtkm::internal::PortalSupportsSets; + public: using Superclass = ArrayPortalTransform; using PortalType = PortalType_; @@ -147,11 +139,11 @@ public: } VTKM_SUPPRESS_EXEC_WARNINGS - VTKM_EXEC_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { - using call_supported_t = typename vtkm::internal::PortalSupportsSets::type; - this->Set(call_supported_t(), index, value); + this->Portal.Set(index, this->InverseFunctor(value)); } VTKM_SUPPRESS_EXEC_WARNINGS @@ -160,14 +152,6 @@ public: private: InverseFunctorType InverseFunctor; - - VTKM_SUPPRESS_EXEC_WARNINGS - VTKM_EXEC_CONT - inline void Set(std::true_type, vtkm::Id index, const ValueType& value) const - { - this->Portal.Set(index, this->InverseFunctor(value)); - } - VTKM_EXEC_CONT inline void Set(std::false_type, vtkm::Id, const ValueType&) const {} }; } } diff --git a/vtkm/cont/ArrayHandleView.h b/vtkm/cont/ArrayHandleView.h index e84c5a6e6..7b29708e7 100644 --- a/vtkm/cont/ArrayHandleView.h +++ b/vtkm/cont/ArrayHandleView.h @@ -26,6 +26,8 @@ namespace internal template class ArrayPortalView { + using Writable = vtkm::internal::PortalSupportsSets; + public: using ValueType = typename TargetPortalType::ValueType; @@ -59,8 +61,9 @@ public: ValueType Get(vtkm::Id index) const { return this->TargetPortal.Get(index + this->StartIndex); } VTKM_SUPPRESS_EXEC_WARNINGS - VTKM_EXEC_CONT - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const { this->TargetPortal.Set(index + this->StartIndex, value); } diff --git a/vtkm/cont/ArrayHandleZip.h b/vtkm/cont/ArrayHandleZip.h index cdd79a77c..fdd2ff05c 100644 --- a/vtkm/cont/ArrayHandleZip.h +++ b/vtkm/cont/ArrayHandleZip.h @@ -26,6 +26,14 @@ namespace internal template class ArrayPortalZip { + using ReadableP1 = vtkm::internal::PortalSupportsGets; + using ReadableP2 = vtkm::internal::PortalSupportsGets; + using WritableP1 = vtkm::internal::PortalSupportsSets; + using WritableP2 = vtkm::internal::PortalSupportsSets; + + using Readable = std::integral_constant; + using Writable = std::integral_constant; + public: using ValueType = ValueType_; using T = typename ValueType::FirstType; @@ -64,23 +72,19 @@ public: VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->PortalFirst.GetNumberOfValues(); } - VTKM_EXEC - ValueType Get(vtkm::Id index) const + template ::type> + VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const noexcept { - using call_supported_t1 = typename vtkm::internal::PortalSupportsGets::type; - using call_supported_t2 = typename vtkm::internal::PortalSupportsGets::type; - - return vtkm::make_Pair(this->GetFirst(call_supported_t1(), index), - this->GetSecond(call_supported_t2(), index)); + return vtkm::make_Pair(this->PortalFirst.Get(index), this->PortalSecond.Get(index)); } - VTKM_EXEC - void Set(vtkm::Id index, const ValueType& value) const + template ::type> + VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const noexcept { - using call_supported_t1 = typename vtkm::internal::PortalSupportsSets::type; - using call_supported_t2 = typename vtkm::internal::PortalSupportsSets::type; - this->SetFirst(call_supported_t1(), index, value.first); - this->SetSecond(call_supported_t2(), index, value.second); + this->PortalFirst.Set(index, value.first); + this->PortalSecond.Set(index, value.second); } VTKM_EXEC_CONT @@ -90,28 +94,6 @@ public: const PortalTypeSecond& GetSecondPortal() const { return this->PortalSecond; } private: - VTKM_EXEC inline T GetFirst(std::true_type, vtkm::Id index) const noexcept - { - return this->PortalFirst.Get(index); - } - VTKM_EXEC inline T GetFirst(std::false_type, vtkm::Id) const noexcept { return T{}; } - VTKM_EXEC inline U GetSecond(std::true_type, vtkm::Id index) const noexcept - { - return this->PortalSecond.Get(index); - } - VTKM_EXEC inline U GetSecond(std::false_type, vtkm::Id) const noexcept { return U{}; } - - VTKM_EXEC inline void SetFirst(std::true_type, vtkm::Id index, const T& value) const noexcept - { - this->PortalFirst.Set(index, value); - } - VTKM_EXEC inline void SetFirst(std::false_type, vtkm::Id, const T&) const noexcept {} - VTKM_EXEC inline void SetSecond(std::true_type, vtkm::Id index, const U& value) const noexcept - { - this->PortalSecond.Set(index, value); - } - VTKM_EXEC inline void SetSecond(std::false_type, vtkm::Id, const U&) const noexcept {} - PortalTypeFirst PortalFirst; PortalTypeSecond PortalSecond; }; diff --git a/vtkm/cont/ArrayPortal.h b/vtkm/cont/ArrayPortal.h index 55cca922d..0e8f49d57 100644 --- a/vtkm/cont/ArrayPortal.h +++ b/vtkm/cont/ArrayPortal.h @@ -45,6 +45,12 @@ namespace cont /// Although portals are defined in the execution environment, they are also /// used in the control environment for accessing data on the host. /// +/// Since utilities like IsWritableArrayHandle checks for the existence of a Set +/// method on a portal, if the portal is backed by a read-only ArrayHandle, the +/// Set method must not be defined. If the portal may or may not be writable +/// (e.g., ArrayHandleCast may be casting a read-only OR read-write array), the +/// Set method may be conditionally removed using SFINAE. +/// template class ArrayPortal { @@ -65,8 +71,7 @@ public: ValueType Get(vtkm::Id index) const; /// Sets a value in the array. If it is not possible to set a value in the - /// array, this method may error out (for example with a VTKM_ASSERT). In - /// this case the behavior is undefined. + /// array, this method must not be defined. /// VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const; From 63f24380989a249c840ea98133a6abbf81649c01 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 13 Sep 2019 10:07:41 -0400 Subject: [PATCH 008/108] Add vtkm::source::Wavelet as a new source The Wavelet source creates a dataset similar to VTK's vtkRTAnalyticSource. --- benchmarking/BenchmarkFilters.cxx | 8 +- benchmarking/CMakeLists.txt | 2 +- .../testing/UnitTestSplitSharpEdgesFilter.cxx | 8 +- vtkm/source/CMakeLists.txt | 2 + vtkm/source/Wavelet.cxx | 183 ++++++++++++++++++ vtkm/source/Wavelet.h | 111 +++++++++++ vtkm/source/testing/UnitTestWaveletSource.cxx | 8 +- .../worklet/testing/UnitTestOrientNormals.cxx | 8 +- 8 files changed, 311 insertions(+), 19 deletions(-) create mode 100644 vtkm/source/Wavelet.cxx create mode 100644 vtkm/source/Wavelet.h diff --git a/benchmarking/BenchmarkFilters.cxx b/benchmarking/BenchmarkFilters.cxx index d0d37f8ee..dfe03e3bb 100644 --- a/benchmarking/BenchmarkFilters.cxx +++ b/benchmarking/BenchmarkFilters.cxx @@ -46,8 +46,8 @@ #include +#include #include -#include #include #include // for std::tolower @@ -1357,10 +1357,10 @@ int BenchmarkBody(int argc, char** argv, const vtkm::cont::InitializeResult& con { std::cout << "Generating " << waveletDim << "x" << waveletDim << "x" << waveletDim << " wavelet...\n"; - vtkm::worklet::WaveletGenerator gen; - gen.SetExtent({ 0 }, { waveletDim }); + vtkm::source::Wavelet source; + source.SetExtent({ 0 }, { waveletDim }); - InputDataSet = gen.GenerateDataSet(config.Device); + InputDataSet = source.Execute(); } if (tetra) diff --git a/benchmarking/CMakeLists.txt b/benchmarking/CMakeLists.txt index cc95b4da3..201492b01 100644 --- a/benchmarking/CMakeLists.txt +++ b/benchmarking/CMakeLists.txt @@ -42,7 +42,7 @@ set(benchmarks ) foreach (benchmark ${benchmarks}) - add_benchmark(NAME ${benchmark} FILE ${benchmark}.cxx LIBS vtkm_filter) + add_benchmark(NAME ${benchmark} FILE ${benchmark}.cxx LIBS vtkm_source vtkm_filter) endforeach () if(TARGET vtkm_rendering) diff --git a/vtkm/filter/testing/UnitTestSplitSharpEdgesFilter.cxx b/vtkm/filter/testing/UnitTestSplitSharpEdgesFilter.cxx index 1d842c2c6..601ea1219 100644 --- a/vtkm/filter/testing/UnitTestSplitSharpEdgesFilter.cxx +++ b/vtkm/filter/testing/UnitTestSplitSharpEdgesFilter.cxx @@ -15,7 +15,7 @@ #include #include -#include +#include namespace { @@ -115,13 +115,11 @@ vtkm::cont::DataSet Make3DExplicitSimpleCube() vtkm::cont::DataSet Make3DWavelet() { - vtkm::worklet::WaveletGenerator wavelet; - wavelet.SetMinimumExtent({ -25 }); - wavelet.SetMaximumExtent({ 25 }); + vtkm::source::Wavelet wavelet({ -25 }, { 25 }); wavelet.SetFrequency({ 60, 30, 40 }); wavelet.SetMagnitude({ 5 }); - vtkm::cont::DataSet result = wavelet.GenerateDataSet(); + vtkm::cont::DataSet result = wavelet.Execute(); return result; } diff --git a/vtkm/source/CMakeLists.txt b/vtkm/source/CMakeLists.txt index 07e78e47b..c9ab20243 100644 --- a/vtkm/source/CMakeLists.txt +++ b/vtkm/source/CMakeLists.txt @@ -11,11 +11,13 @@ set(headers Source.h Tangle.h + Wavelet.h ) set(device_sources Source.cxx Tangle.cxx + Wavelet.cxx ) vtkm_library(NAME vtkm_source diff --git a/vtkm/source/Wavelet.cxx b/vtkm/source/Wavelet.cxx new file mode 100644 index 000000000..8d00ccf22 --- /dev/null +++ b/vtkm/source/Wavelet.cxx @@ -0,0 +1,183 @@ +//============================================================================ +// 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 + +namespace +{ +inline vtkm::FloatDefault computeScaleFactor(vtkm::Id min, vtkm::Id max) +{ + return (min < max) ? (1.f / static_cast(max - min)) + : static_cast(1.); +} +} +namespace vtkm +{ +namespace source +{ +namespace wavelet +{ +template +struct Worker : public vtkm::exec::FunctorBase +{ + using OutputHandleType = vtkm::cont::ArrayHandle; + using OutputPortalType = decltype(std::declval().PrepareForOutput(0, Device())); + using Vec3F = vtkm::Vec3f; + + Vec3F Center; + Vec3F Spacing; + Vec3F Frequency; + Vec3F Magnitude; + Vec3F MinimumPoint; + Vec3F Scale; + vtkm::Id3 Offset; + vtkm::Id3 Dims; + vtkm::FloatDefault MaximumValue; + vtkm::FloatDefault Temp2; + OutputPortalType Portal; + + VTKM_CONT + Worker(OutputHandleType& output, + const Vec3F& center, + const Vec3F& spacing, + const Vec3F& frequency, + const Vec3F& magnitude, + const Vec3F& minimumPoint, + const Vec3F& scale, + const vtkm::Id3& offset, + const vtkm::Id3& dims, + vtkm::FloatDefault maximumValue, + vtkm::FloatDefault temp2) + : Center(center) + , Spacing(spacing) + , Frequency(frequency) + , Magnitude(magnitude) + , MinimumPoint(minimumPoint) + , Scale(scale) + , Offset(offset) + , Dims(dims) + , MaximumValue(maximumValue) + , Temp2(temp2) + , Portal(output.PrepareForOutput((dims[0] * dims[1] * dims[2]), Device{})) + { + } + + VTKM_EXEC + void operator()(const vtkm::Id3& ijk) const + { + // map ijk to the point location, accounting for spacing: + const Vec3F loc = Vec3F(ijk + this->Offset) * this->Spacing; + + // Compute the distance from the center of the gaussian: + const Vec3F scaledLoc = (this->Center - loc) * this->Scale; + vtkm::FloatDefault gaussSum = vtkm::Dot(scaledLoc, scaledLoc); + + const Vec3F periodicContribs{ + this->Magnitude[0] * vtkm::Sin(this->Frequency[0] * scaledLoc[0]), + this->Magnitude[1] * vtkm::Sin(this->Frequency[1] * scaledLoc[1]), + this->Magnitude[2] * vtkm::Cos(this->Frequency[2] * scaledLoc[2]), + }; + + // The vtkRTAnalyticSource documentation says the periodic contributions + // should be multiplied in, but the implementation adds them. We'll do as + // they do, not as they say. + const vtkm::FloatDefault scalar = this->MaximumValue * vtkm::Exp(-gaussSum * this->Temp2) + + periodicContribs[0] + periodicContribs[1] + periodicContribs[2]; + + // Compute output location + // (see ConnectivityStructuredInternals<3>::LogicalToFlatPointIndex) + const vtkm::Id scalarIdx = ijk[0] + this->Dims[0] * (ijk[1] + this->Dims[1] * ijk[2]); + this->Portal.Set(scalarIdx, scalar); + } +}; + +struct runWorker +{ + template + inline bool operator()(Device, const vtkm::Id3 dims, Args... args) const + { + using Algo = vtkm::cont::DeviceAdapterAlgorithm; + Worker worker{ args... }; + Algo::Schedule(worker, dims); + return true; + } +}; +} // namespace wavelet + +Wavelet::Wavelet(vtkm::Id3 minExtent, vtkm::Id3 maxExtent) + : Center{ minExtent - ((minExtent - maxExtent) / 2) } + , Spacing{ 1. } + , Frequency{ 60., 30., 40. } + , Magnitude{ 10., 18., 5. } + , MinimumExtent{ minExtent } + , MaximumExtent{ maxExtent } + , MaximumValue{ 255. } + , StandardDeviation{ 0.5 } +{ +} + +vtkm::cont::DataSet Wavelet::Execute() const +{ + VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); + + // Create points: + const vtkm::Id3 dims{ this->MaximumExtent - this->MinimumExtent + vtkm::Id3{ 1 } }; + const vtkm::Vec3f origin{ this->MinimumExtent }; + vtkm::cont::CoordinateSystem coords{ "coordinates", dims, origin, this->Spacing }; + + // And cells: + vtkm::cont::CellSetStructured<3> cellSet; + cellSet.SetPointDimensions(dims); + + // Compile the dataset: + vtkm::cont::DataSet dataSet; + dataSet.AddCoordinateSystem(coords); + dataSet.SetCellSet(cellSet); + + // Scalars, too + vtkm::cont::Field field = this->GeneratePointField("scalars"); + dataSet.AddField(field); + + return dataSet; +} + +vtkm::cont::Field Wavelet::GeneratePointField(const std::string& name) const +{ + VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); + + const vtkm::Id3 dims{ this->MaximumExtent - this->MinimumExtent + vtkm::Id3{ 1 } }; + vtkm::Vec3f minPt = vtkm::Vec3f(this->MinimumExtent) * this->Spacing; + vtkm::FloatDefault temp2 = 1.f / (2.f * this->StandardDeviation * this->StandardDeviation); + vtkm::Vec3f scale{ computeScaleFactor(this->MinimumExtent[0], this->MaximumExtent[0]), + computeScaleFactor(this->MinimumExtent[1], this->MaximumExtent[1]), + computeScaleFactor(this->MinimumExtent[2], this->MaximumExtent[2]) }; + + + vtkm::cont::ArrayHandle output; + vtkm::cont::TryExecuteOnDevice(this->Invoke.GetDevice(), + wavelet::runWorker{}, + dims, + output, + this->Center, + this->Spacing, + this->Frequency, + this->Magnitude, + minPt, + scale, + this->MinimumExtent, + dims, + this->MaximumValue, + temp2); + return vtkm::cont::make_FieldPoint(name, output); +} + +} // namespace source +} // namespace vtkm diff --git a/vtkm/source/Wavelet.h b/vtkm/source/Wavelet.h new file mode 100644 index 000000000..bfc6fff41 --- /dev/null +++ b/vtkm/source/Wavelet.h @@ -0,0 +1,111 @@ +//============================================================================ +// 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_source_Wavelet_h +#define vtk_m_source_Wavelet_h + +#include + +namespace vtkm +{ +namespace source +{ +/** + * @brief The Wavelet source creates a dataset similar to VTK's + * vtkRTAnalyticSource. + * + * This class generates a predictable structured dataset with a smooth yet + * interesting set of scalars, which is useful for testing and benchmarking. + * + * The Execute method creates a complete structured dataset that have a + * point field names 'scalars' + * + * The scalars are computed as: + * + * ``` + * MaxVal * Gauss + MagX * sin(FrqX*x) + MagY * sin(FrqY*y) + MagZ * cos(FrqZ*z) + * ``` + * + * The dataset properties are determined by: + * - `Minimum/MaximumExtent`: The logical point extents of the dataset. + * - `Spacing`: The distance between points of the dataset. + * - `Center`: The center of the dataset. + * + * The scalar functions is control via: + * - `Center`: The center of a Gaussian contribution to the scalars. + * - `StandardDeviation`: The unscaled width of a Gaussian contribution. + * - `MaximumValue`: Upper limit of the scalar range. + * - `Frequency`: The Frq[XYZ] parameters of the periodic contributions. + * - `Magnitude`: The Mag[XYZ] parameters of the periodic contributions. + * + * By default, the following parameters are used: + * - `Extents`: { -10, -10, -10 } `-->` { 10, 10, 10 } + * - `Spacing`: { 1, 1, 1 } + * - `Center`: { 0, 0, 0 } + * - `StandardDeviation`: 0.5 + * - `MaximumValue`: 255 + * - `Frequency`: { 60, 30, 40 } + * - `Magnitude`: { 10, 18, 5 } + */ +class VTKM_SOURCE_EXPORT Wavelet final : public vtkm::source::Source +{ +public: + VTKM_CONT + Wavelet(vtkm::Id3 minExtent = { -10 }, vtkm::Id3 maxExtent = { 10 }); + + VTKM_CONT void SetCenter(const vtkm::Vec& center) { this->Center = center; } + + VTKM_CONT void SetSpacing(const vtkm::Vec& spacing) { this->Spacing = spacing; } + + VTKM_CONT void SetFrequency(const vtkm::Vec& frequency) + { + this->Frequency = frequency; + } + + VTKM_CONT void SetMagnitude(const vtkm::Vec& magnitude) + { + this->Magnitude = magnitude; + } + + VTKM_CONT void SetMinimumExtent(const vtkm::Id3& minExtent) { this->MinimumExtent = minExtent; } + + VTKM_CONT void SetMaximumExtent(const vtkm::Id3& maxExtent) { this->MaximumExtent = maxExtent; } + + VTKM_CONT void SetExtent(const vtkm::Id3& minExtent, const vtkm::Id3& maxExtent) + { + this->MinimumExtent = minExtent; + this->MaximumExtent = maxExtent; + } + + VTKM_CONT void SetMaximumValue(const vtkm::FloatDefault& maxVal) { this->MaximumValue = maxVal; } + + VTKM_CONT void SetStandardDeviation(const vtkm::FloatDefault& stdev) + { + this->StandardDeviation = stdev; + } + + vtkm::cont::DataSet Execute() const; + +private: + vtkm::cont::Field GeneratePointField(const std::string& name) const; + + vtkm::Vec3f Center; + vtkm::Vec3f Spacing; + vtkm::Vec3f Frequency; + vtkm::Vec3f Magnitude; + vtkm::Id3 MinimumExtent; + vtkm::Id3 MaximumExtent; + vtkm::FloatDefault MaximumValue; + vtkm::FloatDefault StandardDeviation; +}; +} //namespace source +} //namespace vtkm + +#endif //vtk_m_source_Wavelet_h diff --git a/vtkm/source/testing/UnitTestWaveletSource.cxx b/vtkm/source/testing/UnitTestWaveletSource.cxx index bb5bd2410..20081e5cc 100644 --- a/vtkm/source/testing/UnitTestWaveletSource.cxx +++ b/vtkm/source/testing/UnitTestWaveletSource.cxx @@ -13,7 +13,7 @@ #include #include -void WaveletGeneratorTest() +void WaveletSourceTest() { vtkm::cont::Timer timer; timer.Start(); @@ -27,7 +27,7 @@ void WaveletGeneratorTest() std::cout << "Default wavelet took " << time << "s.\n"; { - auto coords = ds.GetCoordinateSystem("coords"); + auto coords = ds.GetCoordinateSystem("coordinates"); auto data = coords.GetData(); VTKM_TEST_ASSERT(test_equal(data.GetNumberOfValues(), 9261), "Incorrect number of points."); } @@ -63,7 +63,7 @@ void WaveletGeneratorTest() } } -int UnitTestWaveletGenerator(int argc, char* argv[]) +int UnitTestWaveletSource(int argc, char* argv[]) { - return vtkm::cont::testing::Testing::Run(WaveletGeneratorTest, argc, argv); + return vtkm::cont::testing::Testing::Run(WaveletSourceTest, argc, argv); } diff --git a/vtkm/worklet/testing/UnitTestOrientNormals.cxx b/vtkm/worklet/testing/UnitTestOrientNormals.cxx index 0ab38a96c..ce09be028 100644 --- a/vtkm/worklet/testing/UnitTestOrientNormals.cxx +++ b/vtkm/worklet/testing/UnitTestOrientNormals.cxx @@ -37,7 +37,7 @@ #include #include -#include +#include #include @@ -59,12 +59,10 @@ struct TestPolicy : public vtkm::filter::PolicyBase VTKM_CONT vtkm::cont::DataSet CreateDataSet(bool pointNormals, bool cellNormals) { - vtkm::worklet::WaveletGenerator wavelet; - wavelet.SetMinimumExtent({ -25 }); - wavelet.SetMaximumExtent({ 25 }); + vtkm::source::Wavelet wavelet({ -25 }, { 25 }); wavelet.SetFrequency({ 20, 15, 25 }); wavelet.SetMagnitude({ 5 }); - auto dataSet = wavelet.GenerateDataSet(); + auto dataSet = wavelet.Execute(); // Cut a contour vtkm::filter::Contour contour; From eb3d86654875e46eb801e675611ff78bc44b7cd2 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 13 Sep 2019 11:08:14 -0400 Subject: [PATCH 009/108] Add a test explicitly for vtkm::source::Tangle --- vtkm/source/testing/CMakeLists.txt | 1 + vtkm/source/testing/UnitTestTangleSource.cxx | 87 ++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 vtkm/source/testing/UnitTestTangleSource.cxx diff --git a/vtkm/source/testing/CMakeLists.txt b/vtkm/source/testing/CMakeLists.txt index 340c1f142..cb2db6f86 100644 --- a/vtkm/source/testing/CMakeLists.txt +++ b/vtkm/source/testing/CMakeLists.txt @@ -9,6 +9,7 @@ ##============================================================================ set(unit_tests + UnitTestTangleSource.cxx UnitTestWaveletSource.cxx ) diff --git a/vtkm/source/testing/UnitTestTangleSource.cxx b/vtkm/source/testing/UnitTestTangleSource.cxx new file mode 100644 index 000000000..aac1a17aa --- /dev/null +++ b/vtkm/source/testing/UnitTestTangleSource.cxx @@ -0,0 +1,87 @@ +//============================================================================ +// 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 + +void TangleSourceTest() +{ + vtkm::cont::Timer timer; + timer.Start(); + + vtkm::source::Tangle source(vtkm::Id3{ 20, 20, 20 }); + vtkm::cont::DataSet ds = source.Execute(); + + + double time = timer.GetElapsedTime(); + + std::cout << "Default wavelet took " << time << "s.\n"; + + { + auto coords = ds.GetCoordinateSystem("coordinates"); + auto data = coords.GetData(); + VTKM_TEST_ASSERT(test_equal(data.GetNumberOfValues(), 9261), "Incorrect number of points."); + } + + { + auto cells = ds.GetCellSet(); + VTKM_TEST_ASSERT(test_equal(cells.GetNumberOfCells(), 8000), "Incorrect number of cells."); + } + + // check the cell scalars + { + using ScalarHandleType = vtkm::cont::ArrayHandle; + + auto field = ds.GetCellField("cellvar"); + auto dynData = field.GetData(); + VTKM_TEST_ASSERT(dynData.IsType(), "Invalid scalar handle type."); + ScalarHandleType handle = dynData.Cast(); + auto data = handle.GetPortalConstControl(); + + VTKM_TEST_ASSERT(test_equal(data.GetNumberOfValues(), 8000), "Incorrect number of elements."); + + for (vtkm::Id i = 0; i < 8000; ++i) + { + VTKM_TEST_ASSERT(test_equal(data.Get(i), i), "Incorrect scalar value."); + } + } + + // Spot check some node scalars + { + using ScalarHandleType = vtkm::cont::ArrayHandle; + + auto field = ds.GetPointField("nodevar"); + auto dynData = field.GetData(); + VTKM_TEST_ASSERT(dynData.IsType(), "Invalid scalar handle type."); + ScalarHandleType handle = dynData.Cast(); + auto data = handle.GetPortalConstControl(); + + VTKM_TEST_ASSERT(test_equal(data.GetNumberOfValues(), 9261), "Incorrect number of scalars."); + + VTKM_TEST_ASSERT(test_equal(data.Get(0), 24.46), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(16), 16.1195), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(21), 20.5988), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(256), 8.58544), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(1024), 1.56976), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(1987), 1.04074), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(2048), 0.95236), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(3110), 6.39556), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(4097), 2.62186), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(6599), 7.79722), "Incorrect scalar value."); + VTKM_TEST_ASSERT(test_equal(data.Get(7999), 7.94986), "Incorrect scalar value."); + } +} + +int UnitTestTangleSource(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(TangleSourceTest, argc, argv); +} From 62357dea0faaf32eccc3f246c5289d1c7265741e Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 13 Sep 2019 14:45:49 -0400 Subject: [PATCH 010/108] Tangle source has better runtime performance By leveraging WorkletVisitPointsWithCells we can get already pre-computed i,j,k locations helping with performance In addition we have made the algorithm easier to read by leveraging VTK-m Vec types. --- vtkm/source/Tangle.cxx | 103 ++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 59 deletions(-) diff --git a/vtkm/source/Tangle.cxx b/vtkm/source/Tangle.cxx index bb5a0b6ef..2ecd897d6 100644 --- a/vtkm/source/Tangle.cxx +++ b/vtkm/source/Tangle.cxx @@ -17,51 +17,39 @@ namespace source { namespace tangle { -class TangleField : public vtkm::worklet::WorkletMapField +class TangleField : public vtkm::worklet::WorkletVisitPointsWithCells { public: - using ControlSignature = void(FieldIn vertexId, FieldOut v); - using ExecutionSignature = void(_1, _2); + using ControlSignature = void(CellSetIn, FieldOut v); + using ExecutionSignature = void(ThreadIndices, _2); using InputDomain = _1; - const vtkm::Id xdim, ydim, zdim; - const vtkm::FloatDefault xmin, ymin, zmin, xmax, ymax, zmax; - const vtkm::Id cellsPerLayer; + const vtkm::Vec3f CellDimsf; + const vtkm::Vec3f Mins; + const vtkm::Vec3f Maxs; VTKM_CONT - TangleField(const vtkm::Id3 dims, - const vtkm::FloatDefault mins[3], - const vtkm::FloatDefault maxs[3]) - : xdim(dims[0]) - , ydim(dims[1]) - , zdim(dims[2]) - , xmin(mins[0]) - , ymin(mins[1]) - , zmin(mins[2]) - , xmax(maxs[0]) - , ymax(maxs[1]) - , zmax(maxs[2]) - , cellsPerLayer((xdim) * (ydim)) + TangleField(const vtkm::Id3& cdims, const vtkm::Vec3f& mins, const vtkm::Vec3f& maxs) + : CellDimsf(static_cast(cdims[0]), + static_cast(cdims[1]), + static_cast(cdims[2])) + , Mins(mins) + , Maxs(maxs) { } - VTKM_EXEC - void operator()(const vtkm::Id& vertexId, vtkm::Float32& v) const + template + VTKM_EXEC void operator()(const ThreadIndexType& threadIndex, vtkm::Float32& v) const { - const vtkm::Id x = vertexId % (xdim); - const vtkm::Id y = (vertexId / (xdim)) % (ydim); - const vtkm::Id z = vertexId / cellsPerLayer; + //We are operating on a 3d structured grid. This means that the threadIndex has + //efficiently computed the i,j,k of the point current point for us + const vtkm::Id3 ijk = threadIndex.GetInputIndex3D(); + const vtkm::Vec3f xyzf = static_cast(ijk) / this->CellDimsf; - const vtkm::FloatDefault fx = - static_cast(x) / static_cast(xdim - 1); - const vtkm::FloatDefault fy = - static_cast(y) / static_cast(xdim - 1); - const vtkm::FloatDefault fz = - static_cast(z) / static_cast(xdim - 1); - - const vtkm::Float32 xx = 3.0f * vtkm::Float32(xmin + (xmax - xmin) * (fx)); - const vtkm::Float32 yy = 3.0f * vtkm::Float32(ymin + (ymax - ymin) * (fy)); - const vtkm::Float32 zz = 3.0f * vtkm::Float32(zmin + (zmax - zmin) * (fz)); + const vtkm::Vec3f_32 values = 3.0f * vtkm::Vec3f_32(Mins + (Maxs - Mins) * xyzf); + const vtkm::Float32& xx = values[0]; + const vtkm::Float32& yy = values[1]; + const vtkm::Float32& zz = values[2]; v = (xx * xx * xx * xx - 5.0f * xx * xx + yy * yy * yy * yy - 5.0f * yy * yy + zz * zz * zz * zz - 5.0f * zz * zz + 11.8f) * @@ -73,36 +61,33 @@ public: vtkm::cont::DataSet Tangle::Execute() const { + VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); + vtkm::cont::DataSet dataSet; - const vtkm::Id3 vdims{ this->Dims + vtkm::Id3{ 1, 1, 1 } }; + const vtkm::Id3 pdims{ this->Dims + vtkm::Id3{ 1, 1, 1 } }; + const vtkm::Vec3f mins = { -1.0f, -1.0f, -1.0f }; + const vtkm::Vec3f maxs = { 1.0f, 1.0f, 1.0f }; - vtkm::FloatDefault mins[3] = { -1.0f, -1.0f, -1.0f }; - vtkm::FloatDefault maxs[3] = { 1.0f, 1.0f, 1.0f }; - - vtkm::cont::ArrayHandle pointFieldArray; - vtkm::cont::ArrayHandleIndex vertexCountImplicitArray(vdims[0] * vdims[1] * vdims[2]); - - this->Invoke(tangle::TangleField{ vdims, mins, maxs }, vertexCountImplicitArray, pointFieldArray); - - vtkm::Id numCells = Dims[0] * Dims[1] * Dims[2]; - vtkm::cont::ArrayHandle cellFieldArray; - vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleCounting(0, 1, numCells), - cellFieldArray); - - vtkm::Vec3f origin(0.0f, 0.0f, 0.0f); - vtkm::Vec3f spacing(1.0f / static_cast(Dims[0]), - 1.0f / static_cast(Dims[1]), - 1.0f / static_cast(Dims[2])); - - vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing); - dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates)); - - static constexpr vtkm::IdComponent ndim = 3; - vtkm::cont::CellSetStructured cellSet; - cellSet.SetPointDimensions(vdims); + vtkm::cont::CellSetStructured<3> cellSet; + cellSet.SetPointDimensions(pdims); dataSet.SetCellSet(cellSet); + vtkm::cont::ArrayHandle pointFieldArray; + this->Invoke(tangle::TangleField{ this->Dims, mins, maxs }, cellSet, pointFieldArray); + + vtkm::cont::ArrayHandle cellFieldArray; + vtkm::cont::ArrayCopy( + vtkm::cont::make_ArrayHandleCounting(0, 1, cellSet.GetNumberOfCells()), + cellFieldArray); + + const vtkm::Vec3f origin(0.0f, 0.0f, 0.0f); + const vtkm::Vec3f spacing(1.0f / static_cast(this->Dims[0]), + 1.0f / static_cast(this->Dims[1]), + 1.0f / static_cast(this->Dims[2])); + + vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(pdims, origin, spacing); + dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates)); dataSet.AddField(vtkm::cont::make_FieldPoint("nodevar", pointFieldArray)); dataSet.AddField(vtkm::cont::make_FieldCell("cellvar", cellFieldArray)); From 5c69f1bae938915fd6e123eed97fca8e8037c3aa Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 13 Sep 2019 15:07:40 -0400 Subject: [PATCH 011/108] Update Wavelet to use WorkletVisitPointsWithCells The Wavelet worklet doesn't need a custom scheduler but can use WorkletVisitPointsWithCells --- vtkm/source/Wavelet.cxx | 78 +++++++++++++++-------------------------- vtkm/source/Wavelet.h | 3 +- 2 files changed, 30 insertions(+), 51 deletions(-) diff --git a/vtkm/source/Wavelet.cxx b/vtkm/source/Wavelet.cxx index 8d00ccf22..6c0fc042b 100644 --- a/vtkm/source/Wavelet.cxx +++ b/vtkm/source/Wavelet.cxx @@ -25,11 +25,13 @@ namespace source { namespace wavelet { -template -struct Worker : public vtkm::exec::FunctorBase + +struct WaveletField : public vtkm::worklet::WorkletVisitPointsWithCells { - using OutputHandleType = vtkm::cont::ArrayHandle; - using OutputPortalType = decltype(std::declval().PrepareForOutput(0, Device())); + using ControlSignature = void(CellSetIn, FieldOut v); + using ExecutionSignature = void(ThreadIndices, _2); + using InputDomain = _1; + using Vec3F = vtkm::Vec3f; Vec3F Center; @@ -42,20 +44,17 @@ struct Worker : public vtkm::exec::FunctorBase vtkm::Id3 Dims; vtkm::FloatDefault MaximumValue; vtkm::FloatDefault Temp2; - OutputPortalType Portal; - VTKM_CONT - Worker(OutputHandleType& output, - const Vec3F& center, - const Vec3F& spacing, - const Vec3F& frequency, - const Vec3F& magnitude, - const Vec3F& minimumPoint, - const Vec3F& scale, - const vtkm::Id3& offset, - const vtkm::Id3& dims, - vtkm::FloatDefault maximumValue, - vtkm::FloatDefault temp2) + WaveletField(const Vec3F& center, + const Vec3F& spacing, + const Vec3F& frequency, + const Vec3F& magnitude, + const Vec3F& minimumPoint, + const Vec3F& scale, + const vtkm::Id3& offset, + const vtkm::Id3& dims, + vtkm::FloatDefault maximumValue, + vtkm::FloatDefault temp2) : Center(center) , Spacing(spacing) , Frequency(frequency) @@ -66,13 +65,14 @@ struct Worker : public vtkm::exec::FunctorBase , Dims(dims) , MaximumValue(maximumValue) , Temp2(temp2) - , Portal(output.PrepareForOutput((dims[0] * dims[1] * dims[2]), Device{})) { } - VTKM_EXEC - void operator()(const vtkm::Id3& ijk) const + template + VTKM_EXEC void operator()(const ThreadIndexType& threadIndex, vtkm::FloatDefault& scalar) const { + const vtkm::Id3 ijk = threadIndex.GetInputIndex3D(); + // map ijk to the point location, accounting for spacing: const Vec3F loc = Vec3F(ijk + this->Offset) * this->Spacing; @@ -89,25 +89,8 @@ struct Worker : public vtkm::exec::FunctorBase // The vtkRTAnalyticSource documentation says the periodic contributions // should be multiplied in, but the implementation adds them. We'll do as // they do, not as they say. - const vtkm::FloatDefault scalar = this->MaximumValue * vtkm::Exp(-gaussSum * this->Temp2) + - periodicContribs[0] + periodicContribs[1] + periodicContribs[2]; - - // Compute output location - // (see ConnectivityStructuredInternals<3>::LogicalToFlatPointIndex) - const vtkm::Id scalarIdx = ijk[0] + this->Dims[0] * (ijk[1] + this->Dims[1] * ijk[2]); - this->Portal.Set(scalarIdx, scalar); - } -}; - -struct runWorker -{ - template - inline bool operator()(Device, const vtkm::Id3 dims, Args... args) const - { - using Algo = vtkm::cont::DeviceAdapterAlgorithm; - Worker worker{ args... }; - Algo::Schedule(worker, dims); - return true; + scalar = + this->MaximumValue * vtkm::Exp(-gaussSum * this->Temp2) + vtkm::ReduceSum(periodicContribs); } }; } // namespace wavelet @@ -143,16 +126,15 @@ vtkm::cont::DataSet Wavelet::Execute() const dataSet.SetCellSet(cellSet); // Scalars, too - vtkm::cont::Field field = this->GeneratePointField("scalars"); + vtkm::cont::Field field = this->GeneratePointField(cellSet, "scalars"); dataSet.AddField(field); return dataSet; } -vtkm::cont::Field Wavelet::GeneratePointField(const std::string& name) const +vtkm::cont::Field Wavelet::GeneratePointField(const vtkm::cont::CellSetStructured<3>& cellset, + const std::string& name) const { - VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); - const vtkm::Id3 dims{ this->MaximumExtent - this->MinimumExtent + vtkm::Id3{ 1 } }; vtkm::Vec3f minPt = vtkm::Vec3f(this->MinimumExtent) * this->Spacing; vtkm::FloatDefault temp2 = 1.f / (2.f * this->StandardDeviation * this->StandardDeviation); @@ -160,13 +142,8 @@ vtkm::cont::Field Wavelet::GeneratePointField(const std::string& name) const computeScaleFactor(this->MinimumExtent[1], this->MaximumExtent[1]), computeScaleFactor(this->MinimumExtent[2], this->MaximumExtent[2]) }; - vtkm::cont::ArrayHandle output; - vtkm::cont::TryExecuteOnDevice(this->Invoke.GetDevice(), - wavelet::runWorker{}, - dims, - output, - this->Center, + wavelet::WaveletField worklet{ this->Center, this->Spacing, this->Frequency, this->Magnitude, @@ -175,7 +152,8 @@ vtkm::cont::Field Wavelet::GeneratePointField(const std::string& name) const this->MinimumExtent, dims, this->MaximumValue, - temp2); + temp2 }; + this->Invoke(worklet, cellset, output); return vtkm::cont::make_FieldPoint(name, output); } diff --git a/vtkm/source/Wavelet.h b/vtkm/source/Wavelet.h index bfc6fff41..dfcac1931 100644 --- a/vtkm/source/Wavelet.h +++ b/vtkm/source/Wavelet.h @@ -94,7 +94,8 @@ public: vtkm::cont::DataSet Execute() const; private: - vtkm::cont::Field GeneratePointField(const std::string& name) const; + vtkm::cont::Field GeneratePointField(const vtkm::cont::CellSetStructured<3>& cellset, + const std::string& name) const; vtkm::Vec3f Center; vtkm::Vec3f Spacing; From 4ff021b08685ee43b26f191535bd3c31a4dec3e1 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 22 Aug 2019 13:41:27 -0400 Subject: [PATCH 012/108] Improve VTK-m compilation times by compiling more keys types We have split the compilation of the different `vtkm::worklet:Keys` types over multiple implementation units to improve parallel build performance. --- vtkm/worklet/CMakeLists.txt | 4 +- vtkm/worklet/Keys.h | 106 ++------------ vtkm/worklet/Keys.hxx | 133 ++++++++++++++++++ .../worklet/{Keys.cxx => KeysSignedTypes.cxx} | 3 +- vtkm/worklet/KeysUnsignedTypes.cxx | 32 +++++ 5 files changed, 181 insertions(+), 97 deletions(-) create mode 100644 vtkm/worklet/Keys.hxx rename vtkm/worklet/{Keys.cxx => KeysSignedTypes.cxx} (96%) create mode 100644 vtkm/worklet/KeysUnsignedTypes.cxx diff --git a/vtkm/worklet/CMakeLists.txt b/vtkm/worklet/CMakeLists.txt index 2f6307180..5cee1a3bd 100644 --- a/vtkm/worklet/CMakeLists.txt +++ b/vtkm/worklet/CMakeLists.txt @@ -98,6 +98,7 @@ set(headers set(header_impls ScalarsToColors.hxx + Keys.hxx ) @@ -109,7 +110,8 @@ set(sources_no_device # This is a list of sources that has code that runs on devices and might need to # be compiled with a device-specific compiler (like CUDA). set(sources_device - Keys.cxx + KeysUnsignedTypes.cxx + KeysSignedTypes.cxx MaskSelect.cxx ScatterCounting.cxx ) diff --git a/vtkm/worklet/Keys.h b/vtkm/worklet/Keys.h index ef73dbcc0..16c0e64d9 100644 --- a/vtkm/worklet/Keys.h +++ b/vtkm/worklet/Keys.h @@ -96,27 +96,10 @@ public: /// efficient for stable sorted arrays, but requires an extra copy of the /// keys for unstable sorting. template - VTKM_CONT void BuildArrays(const KeyArrayType& keys, - KeysSortType sort, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) - { - VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Keys::BuildArrays"); - - switch (sort) - { - case KeysSortType::Unstable: - { - KeyArrayHandleType mutableKeys; - vtkm::cont::Algorithm::Copy(device, keys, mutableKeys); - - this->BuildArraysInternal(mutableKeys, device); - } - break; - case KeysSortType::Stable: - this->BuildArraysInternalStable(keys, device); - break; - } - } + VTKM_CONT void BuildArrays( + const KeyArrayType& keys, + KeysSortType sort, + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()); /// Build the internal arrays and also sort the input keys. This is more /// efficient for unstable sorting, but requires an extra copy for stable @@ -125,28 +108,7 @@ public: VTKM_CONT void BuildArraysInPlace( KeyArrayType& keys, KeysSortType sort, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()) - { - VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Keys::BuildArraysInPlace"); - - switch (sort) - { - case KeysSortType::Unstable: - this->BuildArraysInternal(keys, device); - break; - case KeysSortType::Stable: - { - this->BuildArraysInternalStable(keys, device); - KeyArrayHandleType tmp; - // Copy into a temporary array so that the permutation array copy - // won't alias input/output memory: - vtkm::cont::Algorithm::Copy(device, keys, tmp); - vtkm::cont::Algorithm::Copy( - device, vtkm::cont::make_ArrayHandlePermutation(this->SortedValuesMap, tmp), keys); - } - break; - } - } + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()); VTKM_CONT vtkm::Id GetInputRange() const { return this->UniqueKeys.GetNumberOfValues(); } @@ -205,61 +167,11 @@ private: vtkm::cont::ArrayHandle Counts; template - VTKM_CONT void BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device) - { - VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Keys::BuildArraysInternal"); - - const vtkm::Id numKeys = keys.GetNumberOfValues(); - - vtkm::cont::Algorithm::Copy( - device, vtkm::cont::ArrayHandleIndex(numKeys), this->SortedValuesMap); - - // TODO: Do we need the ability to specify a comparison functor for sort? - vtkm::cont::Algorithm::SortByKey(device, keys, this->SortedValuesMap); - - // Find the unique keys and the number of values per key. - vtkm::cont::Algorithm::ReduceByKey( - device, - keys, - vtkm::cont::ArrayHandleConstant(1, numKeys), - this->UniqueKeys, - this->Counts, - vtkm::Sum()); - - // Get the offsets from the counts with a scan. - vtkm::Id offsetsTotal = vtkm::cont::Algorithm::ScanExclusive( - device, vtkm::cont::make_ArrayHandleCast(this->Counts, vtkm::Id()), this->Offsets); - VTKM_ASSERT(offsetsTotal == numKeys); // Sanity check - (void)offsetsTotal; // Shut up, compiler - } + VTKM_CONT void BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device); template VTKM_CONT void BuildArraysInternalStable(const KeyArrayType& keys, - vtkm::cont::DeviceAdapterId device) - { - VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Keys::BuildArraysInternalStable"); - - const vtkm::Id numKeys = keys.GetNumberOfValues(); - - // Produce a stable sorted map of the keys: - this->SortedValuesMap = StableSortIndices::Sort(device, keys); - auto sortedKeys = vtkm::cont::make_ArrayHandlePermutation(this->SortedValuesMap, keys); - - // Find the unique keys and the number of values per key. - vtkm::cont::Algorithm::ReduceByKey( - device, - sortedKeys, - vtkm::cont::ArrayHandleConstant(1, numKeys), - this->UniqueKeys, - this->Counts, - vtkm::Sum()); - - // Get the offsets from the counts with a scan. - vtkm::Id offsetsTotal = vtkm::cont::Algorithm::ScanExclusive( - vtkm::cont::make_ArrayHandleCast(this->Counts, vtkm::Id()), this->Offsets); - VTKM_ASSERT(offsetsTotal == numKeys); // Sanity check - (void)offsetsTotal; // Shut up, compiler - } + vtkm::cont::DeviceAdapterId device); }; template @@ -433,9 +345,13 @@ struct Transport; +VTK_M_KEYS_EXPORT(Pair_UInt8_Id2); #ifdef VTKM_USE_64BIT_IDS VTK_M_KEYS_EXPORT(vtkm::IdComponent); #endif diff --git a/vtkm/worklet/Keys.hxx b/vtkm/worklet/Keys.hxx new file mode 100644 index 000000000..e11181849 --- /dev/null +++ b/vtkm/worklet/Keys.hxx @@ -0,0 +1,133 @@ +//============================================================================ +// 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_worklet_Keys_hxx +#define vtk_m_worklet_Keys_hxx + +#include + +namespace vtkm +{ +namespace worklet +{ +/// Build the internal arrays without modifying the input. This is more +/// efficient for stable sorted arrays, but requires an extra copy of the +/// keys for unstable sorting. +template +template +VTKM_CONT void Keys::BuildArrays(const KeyArrayType& keys, + KeysSortType sort, + vtkm::cont::DeviceAdapterId device) +{ + VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Keys::BuildArrays"); + + switch (sort) + { + case KeysSortType::Unstable: + { + KeyArrayHandleType mutableKeys; + vtkm::cont::Algorithm::Copy(device, keys, mutableKeys); + + this->BuildArraysInternal(mutableKeys, device); + } + break; + case KeysSortType::Stable: + this->BuildArraysInternalStable(keys, device); + break; + } +} + +/// Build the internal arrays and also sort the input keys. This is more +/// efficient for unstable sorting, but requires an extra copy for stable +/// sorting. +template +template +VTKM_CONT void Keys::BuildArraysInPlace(KeyArrayType& keys, + KeysSortType sort, + vtkm::cont::DeviceAdapterId device) +{ + VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Keys::BuildArraysInPlace"); + + switch (sort) + { + case KeysSortType::Unstable: + this->BuildArraysInternal(keys, device); + break; + case KeysSortType::Stable: + { + this->BuildArraysInternalStable(keys, device); + KeyArrayHandleType tmp; + // Copy into a temporary array so that the permutation array copy + // won't alias input/output memory: + vtkm::cont::Algorithm::Copy(device, keys, tmp); + vtkm::cont::Algorithm::Copy( + device, vtkm::cont::make_ArrayHandlePermutation(this->SortedValuesMap, tmp), keys); + } + break; + } +} + +template +template +VTKM_CONT void Keys::BuildArraysInternal(KeyArrayType& keys, vtkm::cont::DeviceAdapterId device) +{ + VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Keys::BuildArraysInternal"); + + const vtkm::Id numKeys = keys.GetNumberOfValues(); + + vtkm::cont::Algorithm::Copy(device, vtkm::cont::ArrayHandleIndex(numKeys), this->SortedValuesMap); + + // TODO: Do we need the ability to specify a comparison functor for sort? + vtkm::cont::Algorithm::SortByKey(device, keys, this->SortedValuesMap); + + // Find the unique keys and the number of values per key. + vtkm::cont::Algorithm::ReduceByKey(device, + keys, + vtkm::cont::ArrayHandleConstant(1, numKeys), + this->UniqueKeys, + this->Counts, + vtkm::Sum()); + + // Get the offsets from the counts with a scan. + vtkm::Id offsetsTotal = vtkm::cont::Algorithm::ScanExclusive( + device, vtkm::cont::make_ArrayHandleCast(this->Counts, vtkm::Id()), this->Offsets); + VTKM_ASSERT(offsetsTotal == numKeys); // Sanity check + (void)offsetsTotal; // Shut up, compiler +} + +template +template +VTKM_CONT void Keys::BuildArraysInternalStable(const KeyArrayType& keys, + vtkm::cont::DeviceAdapterId device) +{ + VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Keys::BuildArraysInternalStable"); + + const vtkm::Id numKeys = keys.GetNumberOfValues(); + + // Produce a stable sorted map of the keys: + this->SortedValuesMap = StableSortIndices::Sort(device, keys); + auto sortedKeys = vtkm::cont::make_ArrayHandlePermutation(this->SortedValuesMap, keys); + + // Find the unique keys and the number of values per key. + vtkm::cont::Algorithm::ReduceByKey(device, + sortedKeys, + vtkm::cont::ArrayHandleConstant(1, numKeys), + this->UniqueKeys, + this->Counts, + vtkm::Sum()); + + // Get the offsets from the counts with a scan. + vtkm::Id offsetsTotal = vtkm::cont::Algorithm::ScanExclusive( + vtkm::cont::make_ArrayHandleCast(this->Counts, vtkm::Id()), this->Offsets); + VTKM_ASSERT(offsetsTotal == numKeys); // Sanity check + (void)offsetsTotal; // Shut up, compiler +} +} +} +#endif diff --git a/vtkm/worklet/Keys.cxx b/vtkm/worklet/KeysSignedTypes.cxx similarity index 96% rename from vtkm/worklet/Keys.cxx rename to vtkm/worklet/KeysSignedTypes.cxx index 8e7c19274..7ef3a239d 100644 --- a/vtkm/worklet/Keys.cxx +++ b/vtkm/worklet/KeysSignedTypes.cxx @@ -10,6 +10,7 @@ #define vtk_m_worklet_Keys_cxx #include +#include #define VTK_M_KEYS_EXPORT(T) \ template class VTKM_WORKLET_EXPORT vtkm::worklet::Keys; \ @@ -22,8 +23,8 @@ vtkm::worklet::KeysSortType sort, \ vtkm::cont::DeviceAdapterId device) -VTK_M_KEYS_EXPORT(vtkm::HashType); VTK_M_KEYS_EXPORT(vtkm::Id); +VTK_M_KEYS_EXPORT(vtkm::Id2); VTK_M_KEYS_EXPORT(vtkm::Id3); #ifdef VTKM_USE_64BIT_IDS VTK_M_KEYS_EXPORT(vtkm::IdComponent); diff --git a/vtkm/worklet/KeysUnsignedTypes.cxx b/vtkm/worklet/KeysUnsignedTypes.cxx new file mode 100644 index 000000000..7f4a18e80 --- /dev/null +++ b/vtkm/worklet/KeysUnsignedTypes.cxx @@ -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. +//============================================================================ + +#define vtk_m_worklet_Keys_cxx +#include +#include + +#define VTK_M_KEYS_EXPORT(T) \ + template class VTKM_WORKLET_EXPORT vtkm::worklet::Keys; \ + template VTKM_WORKLET_EXPORT VTKM_CONT void vtkm::worklet::Keys::BuildArrays( \ + const vtkm::cont::ArrayHandle& keys, \ + vtkm::worklet::KeysSortType sort, \ + vtkm::cont::DeviceAdapterId device); \ + template VTKM_WORKLET_EXPORT VTKM_CONT void vtkm::worklet::Keys::BuildArrays( \ + const vtkm::cont::ArrayHandleVirtual& keys, \ + vtkm::worklet::KeysSortType sort, \ + vtkm::cont::DeviceAdapterId device) + +VTK_M_KEYS_EXPORT(vtkm::HashType); +VTK_M_KEYS_EXPORT(vtkm::UInt8); +using Pair_UInt8_Id2 = vtkm::Pair; +VTK_M_KEYS_EXPORT(Pair_UInt8_Id2); + + +#undef VTK_M_KEYS_EXPORT From 3ef234ef13e25fbf8b4b0a67e3167c4ac451a540 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 16 Sep 2019 12:36:01 -0400 Subject: [PATCH 013/108] Move Oscillator to the sources directory --- examples/oscillator/CMakeLists.txt | 2 +- examples/oscillator/Oscillator.cxx | 23 ++--- vtkm/filter/CMakeLists.txt | 2 - vtkm/filter/OscillatorSource.hxx | 81 ---------------- vtkm/source/CMakeLists.txt | 2 + vtkm/source/Oscillator.cxx | 94 +++++++++++++++++++ .../Oscillator.h} | 40 ++++---- vtkm/source/Tangle.h | 1 + 8 files changed, 126 insertions(+), 119 deletions(-) delete mode 100644 vtkm/filter/OscillatorSource.hxx create mode 100644 vtkm/source/Oscillator.cxx rename vtkm/{filter/OscillatorSource.h => source/Oscillator.h} (56%) diff --git a/examples/oscillator/CMakeLists.txt b/examples/oscillator/CMakeLists.txt index 750eb1829..9224b7f10 100644 --- a/examples/oscillator/CMakeLists.txt +++ b/examples/oscillator/CMakeLists.txt @@ -14,7 +14,7 @@ project(Oscillator CXX) find_package(VTKm REQUIRED QUIET) add_executable(Oscillator Oscillator.cxx) -target_link_libraries(Oscillator PRIVATE vtkm_filter) +target_link_libraries(Oscillator PRIVATE vtkm_source) vtkm_add_target_information(Oscillator DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS DEVICE_SOURCES Oscillator.cxx) diff --git a/examples/oscillator/Oscillator.cxx b/examples/oscillator/Oscillator.cxx index 7445e79cf..a4fafcc6f 100644 --- a/examples/oscillator/Oscillator.cxx +++ b/examples/oscillator/Oscillator.cxx @@ -22,7 +22,7 @@ #include -#include +#include #if !defined(_WIN32) || defined(__CYGWIN__) #include /* unlink */ @@ -58,7 +58,7 @@ static inline std::string& trim(std::string& s) // ---------------------------------------------------------------------------- -void read_oscillators(std::string filePath, vtkm::filter::OscillatorSource& filter) +void read_oscillators(std::string filePath, vtkm::source::Oscillator& source) { std::ifstream in(filePath); if (!in) @@ -87,15 +87,15 @@ void read_oscillators(std::string filePath, vtkm::filter::OscillatorSource& filt if (stype == "damped") { - filter.AddDamped(x, y, z, r, omega0, zeta); + source.AddDamped(x, y, z, r, omega0, zeta); } else if (stype == "decaying") { - filter.AddDecaying(x, y, z, r, omega0, zeta); + source.AddDecaying(x, y, z, r, omega0, zeta); } else if (stype == "periodic") { - filter.AddPeriodic(x, y, z, r, omega0, zeta); + source.AddPeriodic(x, y, z, r, omega0, zeta); } } } @@ -303,22 +303,19 @@ int main(int argc, char** argv) std::cout << " - end: " << endTime << std::endl; std::cout << "=======================================\n" << std::endl; - vtkm::cont::DataSetBuilderUniform builder; - vtkm::cont::DataSet dataset = builder.Create(vtkm::Id3(sizeX, sizeY, sizeZ)); - - vtkm::filter::OscillatorSource filter; - read_oscillators(oscillatorConfigFile, filter); + vtkm::source::Oscillator source(vtkm::Id3{ sizeX, sizeY, sizeZ }); + read_oscillators(oscillatorConfigFile, source); std::cout << "=========== start computation ============" << std::endl; int count = 0; while (currentTime < endTime) { - filter.SetTime(currentTime); - vtkm::cont::DataSet rdata = filter.Execute(dataset); + source.SetTime(currentTime); + vtkm::cont::DataSet rdata = source.Execute(); if (generateOutput) { vtkm::cont::ArrayHandle tmp; - rdata.GetField("oscillation", vtkm::cont::Field::Association::POINTS).GetData().CopyTo(tmp); + rdata.GetField("scalars", vtkm::cont::Field::Association::POINTS).GetData().CopyTo(tmp); double* values = tmp.GetStorage().GetArray(); writeData(outputDirectory, count++, sizeX, sizeY, sizeZ, values); } diff --git a/vtkm/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt index 815a10754..d0cec6d3e 100644 --- a/vtkm/filter/CMakeLists.txt +++ b/vtkm/filter/CMakeLists.txt @@ -49,7 +49,6 @@ set(headers MeshQuality.h NDEntropy.h NDHistogram.h - OscillatorSource.h Pathline.h PointAverage.h PointElevation.h @@ -115,7 +114,6 @@ set(header_template_sources MeshQuality.hxx NDEntropy.hxx NDHistogram.hxx - OscillatorSource.hxx Pathline.hxx PointAverage.hxx PointElevation.hxx diff --git a/vtkm/filter/OscillatorSource.hxx b/vtkm/filter/OscillatorSource.hxx deleted file mode 100644 index da0ebeb37..000000000 --- a/vtkm/filter/OscillatorSource.hxx +++ /dev/null @@ -1,81 +0,0 @@ -//============================================================================ -// 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 - -namespace vtkm -{ -namespace filter -{ - -//----------------------------------------------------------------------------- -inline VTKM_CONT OscillatorSource::OscillatorSource() - : Worklet() -{ - this->SetUseCoordinateSystemAsField(true); - this->SetOutputFieldName("oscillation"); -} - -//----------------------------------------------------------------------------- -inline VTKM_CONT void OscillatorSource::SetTime(vtkm::Float64 time) -{ - this->Worklet.SetTime(time); -} - -//----------------------------------------------------------------------------- -inline VTKM_CONT void OscillatorSource::AddPeriodic(vtkm::Float64 x, - vtkm::Float64 y, - vtkm::Float64 z, - vtkm::Float64 radius, - vtkm::Float64 omega, - vtkm::Float64 zeta) -{ - this->Worklet.AddPeriodic(x, y, z, radius, omega, zeta); -} - -//----------------------------------------------------------------------------- -inline VTKM_CONT void OscillatorSource::AddDamped(vtkm::Float64 x, - vtkm::Float64 y, - vtkm::Float64 z, - vtkm::Float64 radius, - vtkm::Float64 omega, - vtkm::Float64 zeta) -{ - this->Worklet.AddDamped(x, y, z, radius, omega, zeta); -} - -//----------------------------------------------------------------------------- -inline VTKM_CONT void OscillatorSource::AddDecaying(vtkm::Float64 x, - vtkm::Float64 y, - vtkm::Float64 z, - vtkm::Float64 radius, - vtkm::Float64 omega, - vtkm::Float64 zeta) -{ - this->Worklet.AddDecaying(x, y, z, radius, omega, zeta); -} - - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT vtkm::cont::DataSet OscillatorSource::DoExecute( - const vtkm::cont::DataSet& inDataSet, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMetadata, - const vtkm::filter::PolicyBase&) -{ - vtkm::cont::ArrayHandle outArray; - //todo, we need to use the policy to determine the valid conversions - //that the dispatcher should do - this->Invoke(this->Worklet, field, outArray); - - return CreateResult(inDataSet, outArray, this->GetOutputFieldName(), fieldMetadata); -} -} -} // namespace vtkm::filter diff --git a/vtkm/source/CMakeLists.txt b/vtkm/source/CMakeLists.txt index c9ab20243..959a76786 100644 --- a/vtkm/source/CMakeLists.txt +++ b/vtkm/source/CMakeLists.txt @@ -9,12 +9,14 @@ ##============================================================================ set(headers + Oscillator.h Source.h Tangle.h Wavelet.h ) set(device_sources + Oscillator.cxx Source.cxx Tangle.cxx Wavelet.cxx diff --git a/vtkm/source/Oscillator.cxx b/vtkm/source/Oscillator.cxx new file mode 100644 index 000000000..e8a6796d2 --- /dev/null +++ b/vtkm/source/Oscillator.cxx @@ -0,0 +1,94 @@ +//============================================================================ +// 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 + +namespace vtkm +{ +namespace source +{ + +//----------------------------------------------------------------------------- +Oscillator::Oscillator(vtkm::Id3 dims) + : Dims(dims) + , Worklet() +{ +} + +//----------------------------------------------------------------------------- +void Oscillator::SetTime(vtkm::Float64 time) +{ + this->Worklet.SetTime(time); +} + +//----------------------------------------------------------------------------- +void Oscillator::AddPeriodic(vtkm::Float64 x, + vtkm::Float64 y, + vtkm::Float64 z, + vtkm::Float64 radius, + vtkm::Float64 omega, + vtkm::Float64 zeta) +{ + this->Worklet.AddPeriodic(x, y, z, radius, omega, zeta); +} + +//----------------------------------------------------------------------------- +void Oscillator::AddDamped(vtkm::Float64 x, + vtkm::Float64 y, + vtkm::Float64 z, + vtkm::Float64 radius, + vtkm::Float64 omega, + vtkm::Float64 zeta) +{ + this->Worklet.AddDamped(x, y, z, radius, omega, zeta); +} + +//----------------------------------------------------------------------------- +void Oscillator::AddDecaying(vtkm::Float64 x, + vtkm::Float64 y, + vtkm::Float64 z, + vtkm::Float64 radius, + vtkm::Float64 omega, + vtkm::Float64 zeta) +{ + this->Worklet.AddDecaying(x, y, z, radius, omega, zeta); +} + + +//----------------------------------------------------------------------------- +vtkm::cont::DataSet Oscillator::Execute() const +{ + VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); + + vtkm::cont::DataSet dataSet; + + vtkm::cont::CellSetStructured<3> cellSet; + cellSet.SetPointDimensions(this->Dims); + dataSet.SetCellSet(cellSet); + + const vtkm::Vec3f origin(0.0f, 0.0f, 0.0f); + const vtkm::Vec3f spacing(1.0f / static_cast(this->Dims[0]), + 1.0f / static_cast(this->Dims[1]), + 1.0f / static_cast(this->Dims[2])); + + const vtkm::Id3 pdims{ this->Dims + vtkm::Id3{ 1, 1, 1 } }; + vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(pdims, origin, spacing); + dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates)); + + + vtkm::cont::ArrayHandle outArray; + //todo, we need to use the policy to determine the valid conversions + //that the dispatcher should do + this->Invoke(this->Worklet, coordinates, outArray); + dataSet.AddField(vtkm::cont::make_FieldPoint("scalars", outArray)); + + return dataSet; +} +} +} // namespace vtkm::filter diff --git a/vtkm/filter/OscillatorSource.h b/vtkm/source/Oscillator.h similarity index 56% rename from vtkm/filter/OscillatorSource.h rename to vtkm/source/Oscillator.h index ebe13d23a..9b4c6cb9f 100644 --- a/vtkm/filter/OscillatorSource.h +++ b/vtkm/source/Oscillator.h @@ -7,30 +7,31 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_filter_OscillatorSource_h -#define vtk_m_filter_OscillatorSource_h +#ifndef vtk_m_source_OscillatorSource_h +#define vtk_m_source_OscillatorSource_h -#include +#include #include namespace vtkm { -namespace filter +namespace source { -/**\brief An analytical, time-varying array-source filter. - * - * This filter will create a new array (named "oscillation" by default) - * that evaluates to a sum of time-varying Gaussian exponentials - * specified in its configuration. - */ -class OscillatorSource : public vtkm::filter::FilterField +/**\brief An analytical, time-varying uniform dataset with a point based array + * + * The Execute method creates a complete structured dataset that have a + * point field names 'scalars' + * + * This array is based on the coordinates and evaluates to a sum of time-varying + * Gaussian exponentials specified in its configuration. + */ +class VTKM_SOURCE_EXPORT Oscillator final : public vtkm::source::Source { public: - using SupportedTypes = vtkm::TypeListTagFieldVec3; - + ///Construct a Oscillator with Cell Dimensions VTKM_CONT - OscillatorSource(); + Oscillator(vtkm::Id3 dims); VTKM_CONT void SetTime(vtkm::Float64 time); @@ -59,18 +60,13 @@ public: vtkm::Float64 omega, vtkm::Float64 zeta); - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::DataSet Execute() const; private: + vtkm::Id3 Dims; vtkm::worklet::OscillatorSource Worklet; }; } } -#include - -#endif // vtk_m_filter_OscillatorSource_h +#endif // vtk_m_source_Oscillator_h diff --git a/vtkm/source/Tangle.h b/vtkm/source/Tangle.h index 637ae75a0..304695535 100644 --- a/vtkm/source/Tangle.h +++ b/vtkm/source/Tangle.h @@ -31,6 +31,7 @@ namespace source class VTKM_SOURCE_EXPORT Tangle final : public vtkm::source::Source { public: + ///Construct a Tangle with Cell Dimensions VTKM_CONT Tangle(vtkm::Id3 dims) : Dims(dims) From ed15f684eaed203d8addff03d716a3a17e526bb6 Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Mon, 16 Sep 2019 17:19:18 -0700 Subject: [PATCH 014/108] overhaul workings of mesh quality filter. Unit test a little rocky right now, but heading in the right direction --- vtkm/exec/cellmetrics/CellJacobianMetric.h | 278 ++++++++++++++++++ vtkm/filter/MeshQuality.h | 41 +-- vtkm/filter/MeshQuality.hxx | 178 +---------- .../testing/UnitTestMeshQualityFilter.cxx | 71 ++--- vtkm/worklet/MeshQuality.h | 33 ++- 5 files changed, 350 insertions(+), 251 deletions(-) create mode 100644 vtkm/exec/cellmetrics/CellJacobianMetric.h diff --git a/vtkm/exec/cellmetrics/CellJacobianMetric.h b/vtkm/exec/cellmetrics/CellJacobianMetric.h new file mode 100644 index 000000000..1e9f2e1c8 --- /dev/null +++ b/vtkm/exec/cellmetrics/CellJacobianMetric.h @@ -0,0 +1,278 @@ +//============================================================================ +// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2018 UT-Battelle, LLC. +// Copyright 2018 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_exec_cellmetrics_Jacobian_h +#define vtk_m_exec_cellmetrics_Jacobian_h + +/* + * Mesh quality metric functions that computes the jacobian of mesh cells. + * The jacobian of a cell is defined as the determinant of the Jociabian matrix + * + * These metric computations are adapted from the VTK implementation of the Verdict library, + * which provides a set of mesh/cell metrics for evaluating the geometric qualities of regions + * of mesh spaces. + * + * See: The Verdict Library Reference Manual (for per-cell-type metric formulae) + * See: vtk/ThirdParty/verdict/vtkverdict (for VTK code implementation of this metric) + */ + +#include "vtkm/CellShape.h" +#include "vtkm/CellTraits.h" +#include "vtkm/VecTraits.h" +#include "vtkm/VectorAnalysis.h" +#include "vtkm/exec/FunctorBase.h" + +#define UNUSED(expr) (void)(expr); + +namespace vtkm +{ +namespace exec +{ +namespace cellmetrics +{ + +using FloatType = vtkm::FloatDefault; + +template +VTKM_EXEC inline OutType CellJacobianMetricOfQuad(const VecType& edgeCalculations, + const VecType& axes) +{ + const vtkm::Id numCalculations = edgeCalculations.GetNumberOfComponents(); + + //Compare partitions of quad to find min + using axesType = typename VecType::ComponentType; + axesType centerCalculation = vtkm::Cross(axes[0], axes[1]); + vtkm::Normalize(centerCalculation); + + OutType currCalculation, minCalculation = vtkm::Infinity(); + + for (vtkm::IdComponent i = 0; i < numCalculations; i++) + { + currCalculation = vtkm::Dot(edgeCalculations[i], centerCalculation); + if (currCalculation < minCalculation) + minCalculation = currCalculation; + } + if (minCalculation > 0) + return vtkm::Min(minCalculation, vtkm::Infinity()); //normal case + + return vtkm::Max(minCalculation, OutType(-1) * vtkm::Infinity()); +} + +template +VTKM_EXEC inline OutType CellJacobianMetricOfHex(const VecType& matrices) +{ + const vtkm::IdComponent numMatrices = matrices.GetNumberOfComponents(); + + //Compare determinants to find min + OutType currDeterminant, minDeterminant; + //principle axes matrix computed outside of for loop to avoid un-necessary if statement + minDeterminant = + (OutType)vtkm::Dot(matrices[numMatrices - 1][0], + vtkm::Cross(matrices[numMatrices - 1][1], matrices[numMatrices - 1][2])); + minDeterminant /= 64.0; + for (vtkm::IdComponent i = 0; i < numMatrices - 1; i++) + { + currDeterminant = + (OutType)vtkm::Dot(matrices[i][0], vtkm::Cross(matrices[i][1], matrices[i][2])); + if (currDeterminant < minDeterminant) + minDeterminant = currDeterminant; + } + + if (minDeterminant > 0) + return vtkm::Min(minDeterminant, vtkm::Infinity()); //normal case + + return vtkm::Max(minDeterminant, vtkm::NegativeInfinity()); +} + + +// ========================= Unsupported cells ================================== + +// By default, cells have zero shape unless the shape type template is specialized below. +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, + const PointCoordVecType& pts, + CellShapeType shape, + const vtkm::exec::FunctorBase&) +{ + UNUSED(numPts); + UNUSED(pts); + UNUSED(shape); + return OutType(0.0); +} + +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, + const PointCoordVecType& pts, + vtkm::CellShapeTagPolygon, + const vtkm::exec::FunctorBase& worklet) +{ + switch (numPts) + { + case 4: + return CellJacobianMetric(numPts, pts, vtkm::CellShapeTagQuad(), worklet); + default: + break; + } + return OutType(-1.0); +} + +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent&, + const PointCoordVecType&, + vtkm::CellShapeTagLine, + const vtkm::exec::FunctorBase& worklet) +{ + UNUSED(worklet); + return OutType(-1.0); +} + +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent&, + const PointCoordVecType&, + vtkm::CellShapeTagTriangle, + const vtkm::exec::FunctorBase& worklet) +{ + UNUSED(worklet); + return OutType(-1.0); +} + +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent&, + const PointCoordVecType&, + vtkm::CellShapeTagWedge, + const vtkm::exec::FunctorBase& worklet) +{ + UNUSED(worklet); + return OutType(-1.0); +} + +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent&, + const PointCoordVecType&, + vtkm::CellShapeTagPyramid, + const vtkm::exec::FunctorBase& worklet) +{ + UNUSED(worklet); + return OutType(-1.0); +} +// ========================= 2D cells ================================== +// Compute the jacobian of a quadrilateral. +// Formula: min{Jacobian at each vertex} +// Equals 1 for a unit square +// Acceptable range: [0,FLOAT_MAX] +// Normal range: [0,FLOAT_MAX] +// Full range: [FLOAT_MIN,FLOAT_MAX] +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, + const PointCoordVecType& pts, + vtkm::CellShapeTagQuad, + const vtkm::exec::FunctorBase& worklet) +{ + if (numPts != 4) + { + worklet.RaiseError("Jacobian metric(quad) requires 4 points."); + return OutType(0.0); + } + + + //The 4 edges of a quadrilateral + using Edge = typename PointCoordVecType::ComponentType; + const Edge QuadEdges[4] = { pts[1] - pts[0], pts[2] - pts[1], pts[3] - pts[2], pts[0] - pts[3] }; + const Edge QuadAxes[2] = { QuadEdges[0] - (pts[2] - pts[3]), QuadEdges[1] - (pts[3] - pts[0]) }; + const Edge QuadEdgesToUse[4] = { vtkm::Cross(QuadEdges[3], QuadEdges[0]), + vtkm::Cross(QuadEdges[0], QuadEdges[1]), + vtkm::Cross(QuadEdges[1], QuadEdges[2]), + vtkm::Cross(QuadEdges[2], QuadEdges[3]) }; + return vtkm::exec::cellmetrics::CellJacobianMetricOfQuad( + vtkm::make_VecC(QuadEdgesToUse, 4), vtkm::make_VecC(QuadAxes, 2)); +} + +// ============================= 3D Volume cells ================================== +// Compute the jacobian of a hexahedron. +// Formula: min{ {Alpha_i}, Alpha_8*/64} +// -Alpha_i -> jacobian determinant at respective vertex +// -Alpha_8 -> jacobian at center +// Equals 1 for a unit cube +// Acceptable Range: [0, FLOAT_MAX] +// Normal Range: [0, FLOAT_MAX] +// Full range: [FLOAT_MIN ,FLOAT_MAX] +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, + const PointCoordVecType& pts, + vtkm::CellShapeTagHexahedron, + const vtkm::exec::FunctorBase& worklet) +{ + if (numPts != 8) + { + worklet.RaiseError("Jacobian metric(hexahedron) requires 8 points."); + return OutType(0.0); + } + + + //The 12 edges of a hexahedron + using Edge = typename PointCoordVecType::ComponentType; + Edge HexEdges[12] = { pts[1] - pts[0], pts[2] - pts[1], pts[3] - pts[2], pts[3] - pts[0], + pts[4] - pts[0], pts[5] - pts[1], pts[6] - pts[2], pts[7] - pts[3], + pts[5] - pts[4], pts[6] - pts[5], pts[7] - pts[6], pts[7] - pts[4] }; + Edge principleXAxis = HexEdges[0] + (pts[2] - pts[3]) + HexEdges[8] + (pts[6] - pts[7]); + Edge principleYAxis = HexEdges[3] + HexEdges[1] + HexEdges[11] + HexEdges[9]; + Edge principleZAxis = HexEdges[5] + HexEdges[6] + HexEdges[7] + HexEdges[8]; + + const Edge hexMatrices[9][3] = { { HexEdges[0], HexEdges[3], HexEdges[4] }, + { HexEdges[1], -1 * HexEdges[0], HexEdges[5] }, + { HexEdges[2], -1 * HexEdges[1], HexEdges[6] }, + { -1 * HexEdges[3], -1 * HexEdges[2], HexEdges[7] }, + { HexEdges[11], HexEdges[8], -1 * HexEdges[4] }, + { -1 * HexEdges[8], HexEdges[9], -1 * HexEdges[5] }, + { -1 * HexEdges[9], HexEdges[10], -1 * HexEdges[6] }, + { -1 * HexEdges[10], -1 * HexEdges[11], -1 * HexEdges[7] }, + { principleXAxis, principleYAxis, principleZAxis } }; + return vtkm::exec::cellmetrics::CellJacobianMetricOfHex( + vtkm::make_VecC(hexMatrices, 12)); +} + +// Compute the jacobian of a tetrahedron. +// Formula: (L2 * L0) * L3 +// Equals Sqrt(2) / 2 for unit equilateral tetrahedron +// Acceptable Range: [0, FLOAT_MAX] +// Normal Range: [0, FLOAT_MAX] +// Full range: [FLOAT_MIN,FLOAT_MAX] +template +VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, + const PointCoordVecType& pts, + vtkm::CellShapeTagTetra, + const vtkm::exec::FunctorBase& worklet) +{ + if (numPts != 4) + { + worklet.RaiseError("Jacobian metric requires 4 points"); + return OutType(0.0); + } + + //the 3 edges we need + using Edge = typename PointCoordVecType::ComponentType; + const Edge EdgesNeeded[3] = { pts[1] - pts[0], pts[0] - pts[2], pts[3] - pts[0] }; + return (OutType)vtkm::Dot(vtkm::Cross(EdgesNeeded[1], EdgesNeeded[0]), EdgesNeeded[2]); +} + +} // namespace cellmetrics +} // namespace exec +} // namespace vtkm + +#endif // vtk_m_exec_cellmetrics_CellEdgeRatioMetric_h diff --git a/vtkm/filter/MeshQuality.h b/vtkm/filter/MeshQuality.h index 382db5b39..5793730d7 100644 --- a/vtkm/filter/MeshQuality.h +++ b/vtkm/filter/MeshQuality.h @@ -33,26 +33,35 @@ namespace filter //Names of the available cell metrics, for use in //the output dataset fields -//TODO: static const? -static const std::string MetricNames[] = { "empty", - "diagonalRatio", - "edgeRatio", - //"skew", - "oddy", - "relativeSizeSquared", - "volume" }; +static const std::string MetricNames[] = { + "area", "aspectGamma", "aspectRatio", "condition", "diagonalRatio", "jacobian", + "minAngle", "maxAngle", "oddy", "relativeSize", "scaledJacobian", "shape", + "shear", "skew", "stretch", "taper", "volume", "warpage" +}; //Different cell metrics available to use -//TODO: static const? enum class CellMetric { - EMPTY, //0 + AREA, + ASPECT_GAMMA, + ASPECT_RATIO, + CONDITION, DIAGONAL_RATIO, - EDGE_RATIO, + JACOBIAN, + MIN_ANGLE, + MAX_ANGLE, ODDY, RELATIVE_SIZE, + SCALED_JACOBIAN, + SHAPE, + SHEAR, + SKEW, + STRETCH, + TAPER, VOLUME, - NUMBER_OF_CELL_METRICS //(num metrics = NUMBER_OF_CELL_METRICS - 2) + WARPAGE, + NUMBER_OF_CELL_METRICS, + EMPTY }; /** \brief Computes the quality of an unstructured cell-based mesh. The quality is defined in terms of the @@ -68,9 +77,7 @@ class MeshQuality : public vtkm::filter::FilterCell public: using SupportedTypes = vtkm::TypeListTagFieldVec3; - using ShapeMetricsVecType = std::vector>; - - VTKM_CONT MeshQuality(const ShapeMetricsVecType& metrics); + VTKM_CONT MeshQuality(CellMetric); template VTKM_CONT vtkm::cont::DataSet DoExecute( @@ -81,9 +88,7 @@ public: private: //A user-assigned cell metric per shape/cell type - //Empty metric if not provided by user - //Length of vector is the number of different VTK-m cell types - std::vector CellTypeMetrics; + CellMetric myMetric; }; } // namespace filter diff --git a/vtkm/filter/MeshQuality.hxx b/vtkm/filter/MeshQuality.hxx index 75d520050..0b3292302 100644 --- a/vtkm/filter/MeshQuality.hxx +++ b/vtkm/filter/MeshQuality.hxx @@ -56,14 +56,11 @@ void MeshQualityDebug(const vtkm::cont::ArrayHandle& vtkmNotUsed(outputArr } // namespace debug -inline VTKM_CONT MeshQuality::MeshQuality( - const std::vector>& metrics) +inline VTKM_CONT MeshQuality::MeshQuality(CellMetric metric) : vtkm::filter::FilterCell() { this->SetUseCoordinateSystemAsField(true); - this->CellTypeMetrics.assign(vtkm::NUMBER_OF_CELL_SHAPES, CellMetric::EMPTY); - for (auto p : metrics) - this->CellTypeMetrics[p.first] = p.second; + myMetric = metric; } template @@ -75,183 +72,18 @@ inline VTKM_CONT vtkm::cont::DataSet MeshQuality::DoExecute( { VTKM_ASSERT(fieldMeta.IsPointField()); - using Algorithm = vtkm::cont::Algorithm; - using ShapeHandle = vtkm::cont::ArrayHandle; - using IdHandle = vtkm::cont::ArrayHandle; - using QualityWorklet = vtkm::worklet::MeshQuality; - using FieldStatsWorklet = vtkm::worklet::FieldStatistics; - - //TODO: Should other cellset types be supported? vtkm::cont::CellSetExplicit<> cellSet; input.GetCellSet().CopyTo(cellSet); - ShapeHandle cellShapes = - cellSet.GetShapesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint()); - - //Obtain the frequency counts of each cell type in the input dataset - IdHandle uniqueCellCounts; - ShapeHandle uniqueCellShapes, sortedShapes; - Algorithm::Copy(cellShapes, sortedShapes); - Algorithm::Sort(sortedShapes); - Algorithm::ReduceByKey( - sortedShapes, - vtkm::cont::make_ArrayHandleConstant(vtkm::Id(1), cellShapes.GetNumberOfValues()), - uniqueCellShapes, - uniqueCellCounts, - vtkm::Add()); - - const vtkm::Id numUniqueShapes = uniqueCellShapes.GetNumberOfValues(); - auto uniqueCellShapesPortal = uniqueCellShapes.GetPortalConstControl(); - auto numCellsPerShapePortal = uniqueCellCounts.GetPortalConstControl(); - std::vector tempCounts(vtkm::NUMBER_OF_CELL_SHAPES); - for (vtkm::Id i = 0; i < numUniqueShapes; i++) - { - tempCounts[uniqueCellShapesPortal.Get(i)] = numCellsPerShapePortal.Get(i); - } - IdHandle cellShapeCounts = vtkm::cont::make_ArrayHandle(tempCounts); - //Invoke the MeshQuality worklet vtkm::cont::ArrayHandle outArray; - vtkm::cont::ArrayHandle cellMetrics = vtkm::cont::make_ArrayHandle(CellTypeMetrics); - this->Invoke(QualityWorklet{}, - vtkm::filter::ApplyPolicyCellSet(cellSet, policy), - cellShapeCounts, - cellMetrics, - points, - outArray); + vtkm::worklet::MeshQuality qualityWorklet; + qualityWorklet.SetMetric(myMetric); + this->Invoke(qualityWorklet, vtkm::filter::ApplyPolicyCellSet(cellSet, policy), points, outArray); - //Build the output dataset: a separate field for each cell type that has a specified metric vtkm::cont::DataSet result; result.CopyStructure(input); //clone of the input dataset - auto cellShapePortal = cellShapes.GetPortalConstControl(); - auto metricValuesPortal = outArray.GetPortalConstControl(); - - const vtkm::Id numCells = outArray.GetNumberOfValues(); - T currMetric = 0; - vtkm::UInt8 currShape = 0; - - //Output metric values stored in separate containers - //based on shape type. Unsupported shape types in VTK-m - //are represented with an empty "placeholder" container. - std::vector> metricValsPerShape = { - { /*placeholder*/ }, { /*vertices*/ }, { /*placeholder*/ }, { /*lines*/ }, - { /*placeholder*/ }, { /*triangles*/ }, { /*placeholder*/ }, { /*polygons*/ }, - { /*placeholder*/ }, { /*quads*/ }, { /*tetrahedrons*/ }, { /*placeholder*/ }, - { /*hexahedrons*/ }, { /*wedges*/ }, { /*pyramids*/ } - }; - - for (vtkm::Id metricArrayIndex = 0; metricArrayIndex < numCells; metricArrayIndex++) - { - currShape = cellShapePortal.Get(metricArrayIndex); - currMetric = metricValuesPortal.Get(metricArrayIndex); - metricValsPerShape[currShape].emplace_back(currMetric); - } - - //Compute the mesh quality for each shape type. This consists - //of computing the summary statistics of the metric values for - //each cell of the given shape type. - std::string fieldName = "", metricName = ""; - vtkm::UInt8 cellShape = 0; - vtkm::Id cellCount = 0; - bool skipShape = false; - for (vtkm::Id shapeIndex = 0; shapeIndex < numUniqueShapes; shapeIndex++) - { - cellShape = uniqueCellShapesPortal.Get(shapeIndex); - cellCount = numCellsPerShapePortal.Get(shapeIndex); - metricName = MetricNames[static_cast(CellTypeMetrics[cellShape])]; - - //Skip over shapes with an empty/unspecified metric; - //don't include a field for them - if (CellTypeMetrics[cellShape] == CellMetric::EMPTY) - continue; - - switch (cellShape) - { - case vtkm::CELL_SHAPE_EMPTY: - skipShape = true; - break; - case vtkm::CELL_SHAPE_VERTEX: - fieldName = "vertices"; - break; - case vtkm::CELL_SHAPE_LINE: - fieldName = "lines"; - break; - case vtkm::CELL_SHAPE_TRIANGLE: - fieldName = "triangles"; - break; - case vtkm::CELL_SHAPE_POLYGON: - fieldName = "polygons"; - break; - case vtkm::CELL_SHAPE_QUAD: - fieldName = "quads"; - break; - case vtkm::CELL_SHAPE_TETRA: - fieldName = "tetrahedrons"; - break; - case vtkm::CELL_SHAPE_HEXAHEDRON: - fieldName = "hexahedrons"; - break; - case vtkm::CELL_SHAPE_WEDGE: - fieldName = "wedges"; - break; - case vtkm::CELL_SHAPE_PYRAMID: - fieldName = "pyramids"; - break; - default: - skipShape = true; - break; - } - - //Skip over shapes of empty cell type; don't include a field for them - if (skipShape) - continue; - - fieldName += "-" + metricName; - auto shapeMetricVals = metricValsPerShape[cellShape]; - auto shapeMetricValsHandle = vtkm::cont::make_ArrayHandle(std::move(shapeMetricVals)); - - //Invoke the field stats worklet on the array of metric values for this shape type - typename FieldStatsWorklet::StatInfo statinfo; - FieldStatsWorklet().Run(shapeMetricValsHandle, statinfo); - - //Retrieve summary stats from the output stats struct. - //These stats define the mesh quality with respect to this shape type. - vtkm::cont::ArrayHandle shapeMeshQuality; - shapeMeshQuality.Allocate(5); - { - auto portal = shapeMeshQuality.GetPortalControl(); - portal.Set(0, T(cellCount)); - portal.Set(1, statinfo.mean); - portal.Set(2, statinfo.variance); - portal.Set(3, statinfo.minimum); - portal.Set(4, statinfo.maximum); - } - - //Append the summary stats into the output dataset as a new field - result.AddField(vtkm::cont::make_FieldCell(fieldName, shapeMeshQuality)); - -#ifdef DEBUG_PRINT - std::cout << "-----------------------------------------------------\n" - << "Mesh quality of " << fieldName << ":\n" - << "Number of cells: " << cellCount << "\n" - << "Mean: " << statinfo.mean << "\n" - << "Variance: " << statinfo.variance << "\n" - << "Minimum: " << statinfo.minimum << "\n" - << "Maximum: " << statinfo.maximum << "\n" - << "-----------------------------------------------------\n"; -#endif - } - -#ifdef DEBUG_PRINT - auto metricValsPortal = outArray.GetPortalConstControl(); - std::cout << "-----------------------------------------------------\n" - << "Metric values - all cells:\n"; - for (vtkm::Id v = 0; v < outArray.GetNumberOfValues(); v++) - std::cout << metricValsPortal.Get(v) << "\n"; - std::cout << "-----------------------------------------------------\n"; -#endif - //Append the metric values of all cells into the output //dataset as a new field const std::string s = "allCells-metricValues"; diff --git a/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx b/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx index 7c18cef79..6fe9bf206 100644 --- a/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx +++ b/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx @@ -17,6 +17,7 @@ // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ +#include #include #include #include @@ -189,17 +190,21 @@ inline vtkm::cont::DataSet Make3DExplicitDataSet() template std::vector TestMeshQualityFilter(const vtkm::cont::DataSet& input, - const std::vector& expectedVals, + const std::vector& expectedVals, T filter) { + fprintf(stderr, "In TMQF\n"); std::vector errors; vtkm::cont::DataSet output; try { + fprintf(stderr, "Try execute\n"); output = filter.Execute(input); + fprintf(stderr, "Complete execute\n"); } catch (vtkm::cont::ErrorExecution&) { + fprintf(stderr, "Catch error\n"); errors.push_back("Error occured while executing filter. Exiting..."); return errors; } @@ -232,7 +237,7 @@ void CheckForErrors(const std::vector& messages) int TestMeshQuality() { - using FloatVec = std::vector; + using FloatVec = std::vector; using PairVec = std::vector>; using StringVec = std::vector; using CharVec = std::vector; @@ -254,75 +259,51 @@ int TestMeshQuality() std::cout << "Testing MeshQuality filter: Volume metric" << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - //Assign a cell metric to compute for each different - //shape type that may exist in the input dataset. If no metric - //is specified for a shape type, then it is assumed to be EMPTY - //and no metric is computed. - testedShapes = { vtkm::CELL_SHAPE_TETRA, vtkm::CELL_SHAPE_HEXAHEDRON, vtkm::CELL_SHAPE_WEDGE, - vtkm::CELL_SHAPE_PYRAMID, vtkm::CELL_SHAPE_POLYGON, vtkm::CELL_SHAPE_LINE, - vtkm::CELL_SHAPE_QUAD, vtkm::CELL_SHAPE_TRIANGLE }; - shapeMetricPairs.clear(); - for (auto s : testedShapes) - shapeMetricPairs.push_back(vtkm::make_Pair(s, vtkm::filter::CellMetric::VOLUME)); - //The ground truth metric value for each cell in the input dataset. //These values are generated from VisIt using the equivalent pseudocolor //mesh quality metric. expectedValues = { 1, 1, 0.0100042, 0.0983333, 0.0732667, 0.0845833, -0.5, -0.5, 0, 0, 1, 1, 1.5, 0.7071068, 2, 1, 0.5, 1 }; - filter.reset(new QualityFilter(shapeMetricPairs)); + filter.reset(new QualityFilter(vtkm::filter::CellMetric::VOLUME)); std::vector errors = TestMeshQualityFilter(input, expectedValues, *filter); std::cout << "Volume metric test: "; CheckForErrors(errors); /*************************************************** - * Test 2: Edge Ratio metric - ***************************************************/ - - std::cout << "\nTesting MeshQuality filter: Edge Ratio metric" - << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - - testedShapes = { vtkm::CELL_SHAPE_TETRA, vtkm::CELL_SHAPE_HEXAHEDRON, vtkm::CELL_SHAPE_WEDGE, - vtkm::CELL_SHAPE_PYRAMID, vtkm::CELL_SHAPE_POLYGON, vtkm::CELL_SHAPE_LINE, - vtkm::CELL_SHAPE_QUAD, vtkm::CELL_SHAPE_TRIANGLE }; - - shapeMetricPairs.clear(); - for (auto s : testedShapes) - shapeMetricPairs.push_back(vtkm::make_Pair(s, vtkm::filter::CellMetric::EDGE_RATIO)); - - expectedValues = { 1, 1, 2.55938, 1.80027, 2.59323, 1.73099, 1.41421, 1.41421, 0, - 0, 1, 1, 2.12132, 2.44949, 2, 1, 1.41421, 1.41421 }; - - filter.reset(new QualityFilter(shapeMetricPairs)); - errors = TestMeshQualityFilter(input, expectedValues, *filter); - std::cout << "Edge ratio metric test: "; - CheckForErrors(errors); - - /*************************************************** - * Test 3: Diagonal Ratio metric + * Test 2: Diagonal Ratio metric ***************************************************/ std::cout << "Testing MeshQuality filter: Diagonal Ratio metric" << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - testedShapes = { vtkm::CELL_SHAPE_HEXAHEDRON, vtkm::CELL_SHAPE_POLYGON, vtkm::CELL_SHAPE_QUAD }; - - shapeMetricPairs.clear(); - for (auto s : testedShapes) - shapeMetricPairs.push_back(vtkm::make_Pair(s, vtkm::filter::CellMetric::DIAGONAL_RATIO)); expectedValues = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2.23607 }; - filter.reset(new QualityFilter(shapeMetricPairs)); + filter.reset(new QualityFilter(vtkm::filter::CellMetric::DIAGONAL_RATIO)); errors = TestMeshQualityFilter(input, expectedValues, *filter); std::cout << "Diagonal ratio metric test: "; CheckForErrors(errors); + /*************************************************** + * Test 3: Jacobian metric + ***************************************************/ + + std::cout << "Testing MeshQuality filter: Jacobian metric" + << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; + + + expectedValues = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2.23607 }; + + filter.reset(new QualityFilter(vtkm::filter::CellMetric::JACOBIAN)); + errors = TestMeshQualityFilter(input, expectedValues, *filter); + std::cout << "Jacobian metric test: "; + CheckForErrors(errors); + #if 0 /*************************************************** - * Test 4: Oddy metric + * Test 5: Oddy metric ***************************************************/ std::cout << "Testing MeshQuality filter: Oddy metric" diff --git a/vtkm/worklet/MeshQuality.h b/vtkm/worklet/MeshQuality.h index 99a072433..7b0c12039 100644 --- a/vtkm/worklet/MeshQuality.h +++ b/vtkm/worklet/MeshQuality.h @@ -24,6 +24,7 @@ #include "vtkm/exec/CellMeasure.h" #include "vtkm/exec/cellmetrics/CellDiagonalRatioMetric.h" #include "vtkm/exec/cellmetrics/CellEdgeRatioMetric.h" +#include "vtkm/exec/cellmetrics/CellJacobianMetric.h" #include "vtkm/worklet/WorkletMapTopology.h" namespace vtkm @@ -42,26 +43,22 @@ class MeshQuality : public vtkm::worklet::WorkletVisitCellsWithPoints { public: using ControlSignature = void(CellSetIn cellset, - WholeArrayIn counts, - WholeArrayIn metrics, FieldInPoint pointCoords, FieldOutCell metricOut); - using ExecutionSignature = void(CellShape, PointCount, _2, _3, _4, _5); + using ExecutionSignature = void(CellShape, PointCount, _2, _3); using InputDomain = _1; - template + void SetMetric(MetricTagType m) { metric = m; } + + template VTKM_EXEC void operator()(CellShapeType shape, const vtkm::IdComponent& numPoints, - const CountsArrayType& counts, - const MetricsArrayType& metrics, + //const CountsArrayType& counts, + //const MetricsArrayType& metrics, + //MetricTagType metric, const PointCoordVecType& pts, OutType& metricValue) const { - printf("shape.Id: %u\n", shape.Id); vtkm::UInt8 thisId = shape.Id; if (shape.Id == vtkm::CELL_SHAPE_POLYGON) { @@ -73,8 +70,7 @@ public: switch (thisId) { vtkmGenericCellShapeMacro( - metricValue = this->ComputeMetric( - numPoints, pts, counts.Get(shape.Id), CellShapeTag(), metrics.Get(CellShapeTag().Id))); + metricValue = this->ComputeMetric(numPoints, pts, CellShapeTag(), metric)); default: this->RaiseError("Asked for metric of unknown cell type."); metricValue = OutType(0.0); @@ -82,17 +78,18 @@ public: } protected: + // data member + MetricTagType metric; + template VTKM_EXEC OutType ComputeMetric(const vtkm::IdComponent& numPts, const PointCoordVecType& pts, - const vtkm::Id& numShapes, CellShapeType tag, CellMetricType metric) const { - UNUSED(numShapes); constexpr vtkm::IdComponent dims = vtkm::CellTraits::TOPOLOGICAL_DIMENSIONS; //Only compute the metric for 2D and 3D shapes; return 0 otherwise @@ -105,10 +102,16 @@ protected: metricValue = vtkm::exec::cellmetrics::CellDiagonalRatioMetric(numPts, pts, tag, *this); break; + /* DEPRECATING case MetricTagType::EDGE_RATIO: metricValue = vtkm::exec::cellmetrics::CellEdgeRatioMetric(numPts, pts, tag, *this); break; + */ + case MetricTagType::JACOBIAN: + metricValue = + vtkm::exec::cellmetrics::CellJacobianMetric(numPts, pts, tag, *this); + break; case MetricTagType::VOLUME: metricValue = vtkm::exec::CellMeasure(numPts, pts, tag, *this); break; From 560aa1f673ae78c07070ac3ebdccc5cad75c8c1e Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Mon, 16 Sep 2019 20:48:55 -0700 Subject: [PATCH 015/108] add support for outputname --- vtkm/filter/MeshQuality.h | 4 +- vtkm/filter/MeshQuality.hxx | 8 +++- .../testing/UnitTestMeshQualityFilter.cxx | 42 +++++++++++++------ vtkm/worklet/MeshQuality.h | 12 ++---- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/vtkm/filter/MeshQuality.h b/vtkm/filter/MeshQuality.h index 5793730d7..d6197b84c 100644 --- a/vtkm/filter/MeshQuality.h +++ b/vtkm/filter/MeshQuality.h @@ -40,6 +40,7 @@ static const std::string MetricNames[] = { }; //Different cell metrics available to use +//This must follow the same order as the MetricNames above enum class CellMetric { AREA, @@ -78,6 +79,7 @@ public: using SupportedTypes = vtkm::TypeListTagFieldVec3; VTKM_CONT MeshQuality(CellMetric); + void SetOutputName(const std::string& s) { outputName = s; }; template VTKM_CONT vtkm::cont::DataSet DoExecute( @@ -87,8 +89,8 @@ public: const vtkm::filter::PolicyBase& policy); private: - //A user-assigned cell metric per shape/cell type CellMetric myMetric; + std::string outputName; }; } // namespace filter diff --git a/vtkm/filter/MeshQuality.hxx b/vtkm/filter/MeshQuality.hxx index 0b3292302..5f4bd9a30 100644 --- a/vtkm/filter/MeshQuality.hxx +++ b/vtkm/filter/MeshQuality.hxx @@ -61,6 +61,11 @@ inline VTKM_CONT MeshQuality::MeshQuality(CellMetric metric) { this->SetUseCoordinateSystemAsField(true); myMetric = metric; + if (myMetric < CellMetric::AREA || myMetric >= CellMetric::NUMBER_OF_CELL_METRICS) + { + VTKM_ASSERT(true); + } + outputName = MetricNames[(int)myMetric]; } template @@ -86,8 +91,7 @@ inline VTKM_CONT vtkm::cont::DataSet MeshQuality::DoExecute( //Append the metric values of all cells into the output //dataset as a new field - const std::string s = "allCells-metricValues"; - result.AddField(vtkm::cont::make_FieldCell(s, outArray)); + result.AddField(vtkm::cont::make_FieldCell(outputName, outArray)); return result; } diff --git a/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx b/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx index 6fe9bf206..7b2a886c6 100644 --- a/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx +++ b/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx @@ -191,29 +191,25 @@ inline vtkm::cont::DataSet Make3DExplicitDataSet() template std::vector TestMeshQualityFilter(const vtkm::cont::DataSet& input, const std::vector& expectedVals, + const std::string& outputname, T filter) { - fprintf(stderr, "In TMQF\n"); std::vector errors; vtkm::cont::DataSet output; try { - fprintf(stderr, "Try execute\n"); output = filter.Execute(input); - fprintf(stderr, "Complete execute\n"); } catch (vtkm::cont::ErrorExecution&) { - fprintf(stderr, "Catch error\n"); errors.push_back("Error occured while executing filter. Exiting..."); return errors; } //Test the computed metric values (for all cells) and expected metric //values for equality. - const vtkm::Id numFields = output.GetNumberOfFields(); vtkm::cont::testing::TestEqualResult result = vtkm::cont::testing::test_equal_ArrayHandles( - vtkm::cont::make_ArrayHandle(expectedVals), output.GetField(numFields - 1).GetData()); + vtkm::cont::make_ArrayHandle(expectedVals), output.GetField(outputname).GetData()); if (!result) result.PushMessage(std::string("Data doesn't match")); @@ -262,12 +258,28 @@ int TestMeshQuality() //The ground truth metric value for each cell in the input dataset. //These values are generated from VisIt using the equivalent pseudocolor //mesh quality metric. - expectedValues = { 1, 1, 0.0100042, 0.0983333, 0.0732667, 0.0845833, -0.5, -0.5, 0, - 0, 1, 1, 1.5, 0.7071068, 2, 1, 0.5, 1 }; + expectedValues = { 1, + 1, + (vtkm::FloatDefault)0.0100042, + (vtkm::FloatDefault)0.0983333, + (vtkm::FloatDefault)0.0732667, + (vtkm::FloatDefault)0.0845833, + -0.5, + -0.5, + 0, + 0, + 1, + 1, + 1.5, + (vtkm::FloatDefault)0.7071068, + 2, + 1, + 0.5, + 1 }; filter.reset(new QualityFilter(vtkm::filter::CellMetric::VOLUME)); std::vector errors = - TestMeshQualityFilter(input, expectedValues, *filter); + TestMeshQualityFilter(input, expectedValues, "volume", *filter); std::cout << "Volume metric test: "; CheckForErrors(errors); @@ -279,10 +291,12 @@ int TestMeshQuality() << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - expectedValues = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2.23607 }; + expectedValues = { + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, (vtkm::FloatDefault)2.23607 + }; filter.reset(new QualityFilter(vtkm::filter::CellMetric::DIAGONAL_RATIO)); - errors = TestMeshQualityFilter(input, expectedValues, *filter); + errors = TestMeshQualityFilter(input, expectedValues, "diagonalRatio", *filter); std::cout << "Diagonal ratio metric test: "; CheckForErrors(errors); @@ -294,10 +308,12 @@ int TestMeshQuality() << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - expectedValues = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2.23607 }; + expectedValues = { + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, (vtkm::FloatDefault)2.23607 + }; filter.reset(new QualityFilter(vtkm::filter::CellMetric::JACOBIAN)); - errors = TestMeshQualityFilter(input, expectedValues, *filter); + errors = TestMeshQualityFilter(input, expectedValues, "jacobian", *filter); std::cout << "Jacobian metric test: "; CheckForErrors(errors); diff --git a/vtkm/worklet/MeshQuality.h b/vtkm/worklet/MeshQuality.h index 7b0c12039..afac05352 100644 --- a/vtkm/worklet/MeshQuality.h +++ b/vtkm/worklet/MeshQuality.h @@ -69,8 +69,8 @@ public: } switch (thisId) { - vtkmGenericCellShapeMacro( - metricValue = this->ComputeMetric(numPoints, pts, CellShapeTag(), metric)); + vtkmGenericCellShapeMacro(metricValue = + this->ComputeMetric(numPoints, pts, CellShapeTag())); default: this->RaiseError("Asked for metric of unknown cell type."); metricValue = OutType(0.0); @@ -81,14 +81,10 @@ protected: // data member MetricTagType metric; - template + template VTKM_EXEC OutType ComputeMetric(const vtkm::IdComponent& numPts, const PointCoordVecType& pts, - CellShapeType tag, - CellMetricType metric) const + CellShapeType tag) const { constexpr vtkm::IdComponent dims = vtkm::CellTraits::TOPOLOGICAL_DIMENSIONS; From d1d61b9ebc2bbb5c276709476ca34e8c1b499a3e Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 17 Sep 2019 08:04:59 -0400 Subject: [PATCH 016/108] vtkm::filter::Filter passes filter policies by value It now follows the same pattern that all filter implementations use --- vtkm/filter/Filter.h | 9 ++++----- vtkm/filter/Filter.hxx | 8 ++++---- vtkm/filter/FilterDataSet.h | 7 +++---- vtkm/filter/FilterDataSet.hxx | 4 ++-- vtkm/filter/FilterDataSetWithField.h | 21 +++++++++------------ vtkm/filter/FilterDataSetWithField.hxx | 8 ++++---- vtkm/filter/FilterField.h | 19 ++++++++----------- vtkm/filter/FilterField.hxx | 6 +++--- 8 files changed, 37 insertions(+), 45 deletions(-) diff --git a/vtkm/filter/Filter.h b/vtkm/filter/Filter.h index a7f021097..53d34c3c7 100644 --- a/vtkm/filter/Filter.h +++ b/vtkm/filter/Filter.h @@ -243,7 +243,7 @@ public: template VTKM_CONT vtkm::cont::DataSet Execute(const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase policy); //@} //@{ @@ -253,9 +253,8 @@ public: VTKM_CONT vtkm::cont::PartitionedDataSet Execute(const vtkm::cont::PartitionedDataSet& input); template - VTKM_CONT vtkm::cont::PartitionedDataSet Execute( - const vtkm::cont::PartitionedDataSet& input, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::PartitionedDataSet Execute(const vtkm::cont::PartitionedDataSet& input, + vtkm::filter::PolicyBase policy); //@} /// Map fields from input dataset to output. @@ -264,7 +263,7 @@ public: template VTKM_CONT void MapFieldsToPass(const vtkm::cont::DataSet& input, vtkm::cont::DataSet& output, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase policy); /// Specify the vtkm::cont::Invoker to be used to execute worklets by /// this filter instance. Overriding the default allows callers to control diff --git a/vtkm/filter/Filter.hxx b/vtkm/filter/Filter.hxx index 3dc0ae7ff..e39a56137 100644 --- a/vtkm/filter/Filter.hxx +++ b/vtkm/filter/Filter.hxx @@ -147,7 +147,7 @@ template void CallMapFieldOntoOutput(Derived* self, const vtkm::cont::DataSet& input, vtkm::cont::DataSet& output, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { using call_supported_t = typename SupportsMapFieldOntoOutput::type; CallMapFieldOntoOutputInternal(call_supported_t(), self, input, output, policy); @@ -266,7 +266,7 @@ template template inline VTKM_CONT vtkm::cont::DataSet Filter::Execute( const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { VTKM_LOG_SCOPE( vtkm::cont::LogLevel::Perf, "Filter: '%s'", vtkm::cont::TypeToString().c_str()); @@ -286,7 +286,7 @@ template template inline VTKM_CONT vtkm::cont::PartitionedDataSet Filter::Execute( const vtkm::cont::PartitionedDataSet& input, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Filter (PartitionedDataSet): '%s'", @@ -311,7 +311,7 @@ template inline VTKM_CONT void Filter::MapFieldsToPass( const vtkm::cont::DataSet& input, vtkm::cont::DataSet& output, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { Derived* self = static_cast(this); for (vtkm::IdComponent cc = 0; cc < input.GetNumberOfFields(); ++cc) diff --git a/vtkm/filter/FilterDataSet.h b/vtkm/filter/FilterDataSet.h index 17acbbfb1..318c38e5b 100644 --- a/vtkm/filter/FilterDataSet.h +++ b/vtkm/filter/FilterDataSet.h @@ -51,12 +51,11 @@ public: template VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase policy); template - VTKM_CONT vtkm::cont::DataSet PrepareForExecution( - const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, + vtkm::filter::PolicyBase policy); private: vtkm::Id CoordinateSystemIndex; diff --git a/vtkm/filter/FilterDataSet.hxx b/vtkm/filter/FilterDataSet.hxx index 726300e55..732240c13 100644 --- a/vtkm/filter/FilterDataSet.hxx +++ b/vtkm/filter/FilterDataSet.hxx @@ -38,7 +38,7 @@ template template inline VTKM_CONT vtkm::cont::DataSet FilterDataSet::PrepareForExecution( const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { return (static_cast(this))->DoExecute(input, policy); } @@ -49,7 +49,7 @@ template inline VTKM_CONT bool FilterDataSet::MapFieldOntoOutput( vtkm::cont::DataSet& result, const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { bool valid = false; diff --git a/vtkm/filter/FilterDataSetWithField.h b/vtkm/filter/FilterDataSetWithField.h index 2d56bcecc..2408b80aa 100644 --- a/vtkm/filter/FilterDataSetWithField.h +++ b/vtkm/filter/FilterDataSetWithField.h @@ -77,26 +77,23 @@ public: template VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase policy); template - VTKM_CONT vtkm::cont::DataSet PrepareForExecution( - const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, + vtkm::filter::PolicyBase policy); private: template - VTKM_CONT vtkm::cont::DataSet PrepareForExecution( - const vtkm::cont::DataSet& input, - const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); //How do we specify float/double coordinate types? template - VTKM_CONT vtkm::cont::DataSet PrepareForExecution( - const vtkm::cont::DataSet& input, - const vtkm::cont::CoordinateSystem& field, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::cont::CoordinateSystem& field, + vtkm::filter::PolicyBase policy); std::string OutputFieldName; vtkm::Id CoordinateSystemIndex; diff --git a/vtkm/filter/FilterDataSetWithField.hxx b/vtkm/filter/FilterDataSetWithField.hxx index 5ec5cc7b1..720fde887 100644 --- a/vtkm/filter/FilterDataSetWithField.hxx +++ b/vtkm/filter/FilterDataSetWithField.hxx @@ -49,7 +49,7 @@ template template inline VTKM_CONT vtkm::cont::DataSet FilterDataSetWithField::PrepareForExecution( const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { if (this->UseCoordinateSystemAsField) { @@ -70,7 +70,7 @@ template inline VTKM_CONT vtkm::cont::DataSet FilterDataSetWithField::PrepareForExecution( const vtkm::cont::DataSet& input, const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { vtkm::filter::FieldMetadata metaData(field); vtkm::cont::DataSet result; @@ -92,7 +92,7 @@ template inline VTKM_CONT vtkm::cont::DataSet FilterDataSetWithField::PrepareForExecution( const vtkm::cont::DataSet& input, const vtkm::cont::CoordinateSystem& field, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { //We have a special signature just for CoordinateSystem, so that we can ask //the policy for the storage types and value types just for coordinate systems @@ -122,7 +122,7 @@ template inline VTKM_CONT bool FilterDataSetWithField::MapFieldOntoOutput( vtkm::cont::DataSet& result, const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { bool valid = false; diff --git a/vtkm/filter/FilterField.h b/vtkm/filter/FilterField.h index e007e6fad..f056148a0 100644 --- a/vtkm/filter/FilterField.h +++ b/vtkm/filter/FilterField.h @@ -83,21 +83,18 @@ public: //@{ /// These are provided to satisfy the Filter API requirements. template - VTKM_CONT vtkm::cont::DataSet PrepareForExecution( - const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, + vtkm::filter::PolicyBase policy); template - VTKM_CONT vtkm::cont::DataSet PrepareForExecution( - const vtkm::cont::DataSet& input, - const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::cont::Field& field, + vtkm::filter::PolicyBase policy); template - VTKM_CONT vtkm::cont::DataSet PrepareForExecution( - const vtkm::cont::DataSet& input, - const vtkm::cont::CoordinateSystem& field, - const vtkm::filter::PolicyBase& policy); + VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::cont::CoordinateSystem& field, + vtkm::filter::PolicyBase policy); //@} protected: diff --git a/vtkm/filter/FilterField.hxx b/vtkm/filter/FilterField.hxx index 77add9570..7b546c4a3 100644 --- a/vtkm/filter/FilterField.hxx +++ b/vtkm/filter/FilterField.hxx @@ -48,7 +48,7 @@ template template inline VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { if (this->UseCoordinateSystemAsField) { @@ -70,7 +70,7 @@ template inline VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( const vtkm::cont::DataSet& input, const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { vtkm::filter::FieldMetadata metaData(field); vtkm::cont::DataSet result; @@ -92,7 +92,7 @@ template inline VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( const vtkm::cont::DataSet& input, const vtkm::cont::CoordinateSystem& field, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { //We have a special signature just for CoordinateSystem, so that we can ask //the policy for the storage types and value types just for coordinate systems From ccedb5aac10394bdfbc84845c3379356d59b068c Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Tue, 17 Sep 2019 13:41:53 -0700 Subject: [PATCH 017/108] Jacobian working, unit test working --- vtkm/exec/cellmetrics/CellJacobianMetric.h | 223 ++--- vtkm/exec/cellmetrics/TypeOfCellHexahedral.h | 765 ++++++++++++++++++ .../cellmetrics/TypeOfCellQuadrilateral.h | 468 +++++++++++ vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h | 295 +++++++ vtkm/exec/cellmetrics/TypeOfCellTriangle.h | 192 +++++ .../testing/UnitTestMeshQualityFilter.cxx | 387 +++------ 6 files changed, 1900 insertions(+), 430 deletions(-) create mode 100644 vtkm/exec/cellmetrics/TypeOfCellHexahedral.h create mode 100644 vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h create mode 100644 vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h create mode 100644 vtkm/exec/cellmetrics/TypeOfCellTriangle.h diff --git a/vtkm/exec/cellmetrics/CellJacobianMetric.h b/vtkm/exec/cellmetrics/CellJacobianMetric.h index 1e9f2e1c8..51f54beb1 100644 --- a/vtkm/exec/cellmetrics/CellJacobianMetric.h +++ b/vtkm/exec/cellmetrics/CellJacobianMetric.h @@ -1,3 +1,4 @@ + //============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. @@ -21,17 +22,20 @@ #define vtk_m_exec_cellmetrics_Jacobian_h /* - * Mesh quality metric functions that computes the jacobian of mesh cells. - * The jacobian of a cell is defined as the determinant of the Jociabian matrix + * Mesh quality metric functions that computes the Jacobian of mesh cells. * * These metric computations are adapted from the VTK implementation of the Verdict library, - * which provides a set of mesh/cell metrics for evaluating the geometric qualities of regions - * of mesh spaces. + * which provides a set of mesh/cell metrics for evaluating the geometric qualities of regions + * of mesh spaces. * * See: The Verdict Library Reference Manual (for per-cell-type metric formulae) * See: vtk/ThirdParty/verdict/vtkverdict (for VTK code implementation of this metric) */ +#include "TypeOfCellHexahedral.h" +#include "TypeOfCellQuadrilateral.h" +#include "TypeOfCellTetrahedral.h" +#include "TypeOfCellTriangle.h" #include "vtkm/CellShape.h" #include "vtkm/CellTraits.h" #include "vtkm/VecTraits.h" @@ -47,63 +51,9 @@ namespace exec namespace cellmetrics { -using FloatType = vtkm::FloatDefault; - -template -VTKM_EXEC inline OutType CellJacobianMetricOfQuad(const VecType& edgeCalculations, - const VecType& axes) -{ - const vtkm::Id numCalculations = edgeCalculations.GetNumberOfComponents(); - - //Compare partitions of quad to find min - using axesType = typename VecType::ComponentType; - axesType centerCalculation = vtkm::Cross(axes[0], axes[1]); - vtkm::Normalize(centerCalculation); - - OutType currCalculation, minCalculation = vtkm::Infinity(); - - for (vtkm::IdComponent i = 0; i < numCalculations; i++) - { - currCalculation = vtkm::Dot(edgeCalculations[i], centerCalculation); - if (currCalculation < minCalculation) - minCalculation = currCalculation; - } - if (minCalculation > 0) - return vtkm::Min(minCalculation, vtkm::Infinity()); //normal case - - return vtkm::Max(minCalculation, OutType(-1) * vtkm::Infinity()); -} - -template -VTKM_EXEC inline OutType CellJacobianMetricOfHex(const VecType& matrices) -{ - const vtkm::IdComponent numMatrices = matrices.GetNumberOfComponents(); - - //Compare determinants to find min - OutType currDeterminant, minDeterminant; - //principle axes matrix computed outside of for loop to avoid un-necessary if statement - minDeterminant = - (OutType)vtkm::Dot(matrices[numMatrices - 1][0], - vtkm::Cross(matrices[numMatrices - 1][1], matrices[numMatrices - 1][2])); - minDeterminant /= 64.0; - for (vtkm::IdComponent i = 0; i < numMatrices - 1; i++) - { - currDeterminant = - (OutType)vtkm::Dot(matrices[i][0], vtkm::Cross(matrices[i][1], matrices[i][2])); - if (currDeterminant < minDeterminant) - minDeterminant = currDeterminant; - } - - if (minDeterminant > 0) - return vtkm::Min(minDeterminant, vtkm::Infinity()); //normal case - - return vtkm::Max(minDeterminant, vtkm::NegativeInfinity()); -} - - // ========================= Unsupported cells ================================== -// By default, cells have zero shape unless the shape type template is specialized below. +// By default, cells return the metric 0.0 unless the shape type template is specialized below. template VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, const PointCoordVecType& pts, @@ -116,63 +66,9 @@ VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, return OutType(0.0); } -template -VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, - const PointCoordVecType& pts, - vtkm::CellShapeTagPolygon, - const vtkm::exec::FunctorBase& worklet) -{ - switch (numPts) - { - case 4: - return CellJacobianMetric(numPts, pts, vtkm::CellShapeTagQuad(), worklet); - default: - break; - } - return OutType(-1.0); -} - -template -VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent&, - const PointCoordVecType&, - vtkm::CellShapeTagLine, - const vtkm::exec::FunctorBase& worklet) -{ - UNUSED(worklet); - return OutType(-1.0); -} - -template -VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent&, - const PointCoordVecType&, - vtkm::CellShapeTagTriangle, - const vtkm::exec::FunctorBase& worklet) -{ - UNUSED(worklet); - return OutType(-1.0); -} - -template -VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent&, - const PointCoordVecType&, - vtkm::CellShapeTagWedge, - const vtkm::exec::FunctorBase& worklet) -{ - UNUSED(worklet); - return OutType(-1.0); -} - -template -VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent&, - const PointCoordVecType&, - vtkm::CellShapeTagPyramid, - const vtkm::exec::FunctorBase& worklet) -{ - UNUSED(worklet); - return OutType(-1.0); -} // ========================= 2D cells ================================== -// Compute the jacobian of a quadrilateral. + +// Compute the Jacobian of a quadrilateral. // Formula: min{Jacobian at each vertex} // Equals 1 for a unit square // Acceptable range: [0,FLOAT_MAX] @@ -190,24 +86,25 @@ VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, return OutType(0.0); } + using Scalar = OutType; + using CollectionOfPoints = PointCoordVecType; + using Vector = typename PointCoordVecType::ComponentType; - //The 4 edges of a quadrilateral - using Edge = typename PointCoordVecType::ComponentType; - const Edge QuadEdges[4] = { pts[1] - pts[0], pts[2] - pts[1], pts[3] - pts[2], pts[0] - pts[3] }; - const Edge QuadAxes[2] = { QuadEdges[0] - (pts[2] - pts[3]), QuadEdges[1] - (pts[3] - pts[0]) }; - const Edge QuadEdgesToUse[4] = { vtkm::Cross(QuadEdges[3], QuadEdges[0]), - vtkm::Cross(QuadEdges[0], QuadEdges[1]), - vtkm::Cross(QuadEdges[1], QuadEdges[2]), - vtkm::Cross(QuadEdges[2], QuadEdges[3]) }; - return vtkm::exec::cellmetrics::CellJacobianMetricOfQuad( - vtkm::make_VecC(QuadEdgesToUse, 4), vtkm::make_VecC(QuadAxes, 2)); + const Scalar alpha0 = GetQuadAlpha0(pts); + const Scalar alpha1 = GetQuadAlpha1(pts); + const Scalar alpha2 = GetQuadAlpha2(pts); + const Scalar alpha3 = GetQuadAlpha3(pts); + + const Scalar q = vtkm::Min(alpha0, vtkm::Min(alpha1, vtkm::Min(alpha2, alpha3))); + + return q; } // ============================= 3D Volume cells ================================== -// Compute the jacobian of a hexahedron. -// Formula: min{ {Alpha_i}, Alpha_8*/64} -// -Alpha_i -> jacobian determinant at respective vertex -// -Alpha_8 -> jacobian at center +// Compute the Jacobian of a hexahedron. +// Formula: min{ {Alpha_i for i in 1..7}, Alpha_8/64} +// -Alpha_i -> Jacobian determinant at respective vertex +// -Alpha_8 -> Jacobian at center // Equals 1 for a unit cube // Acceptable Range: [0, FLOAT_MAX] // Normal Range: [0, FLOAT_MAX] @@ -224,31 +121,37 @@ VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, return OutType(0.0); } + using Scalar = OutType; + using CollectionOfPoints = PointCoordVecType; + using Vector = typename PointCoordVecType::ComponentType; - //The 12 edges of a hexahedron - using Edge = typename PointCoordVecType::ComponentType; - Edge HexEdges[12] = { pts[1] - pts[0], pts[2] - pts[1], pts[3] - pts[2], pts[3] - pts[0], - pts[4] - pts[0], pts[5] - pts[1], pts[6] - pts[2], pts[7] - pts[3], - pts[5] - pts[4], pts[6] - pts[5], pts[7] - pts[6], pts[7] - pts[4] }; - Edge principleXAxis = HexEdges[0] + (pts[2] - pts[3]) + HexEdges[8] + (pts[6] - pts[7]); - Edge principleYAxis = HexEdges[3] + HexEdges[1] + HexEdges[11] + HexEdges[9]; - Edge principleZAxis = HexEdges[5] + HexEdges[6] + HexEdges[7] + HexEdges[8]; + const Scalar alpha0 = GetHexAlphai(pts, vtkm::Id(0)); + const Scalar alpha1 = GetHexAlphai(pts, vtkm::Id(1)); + const Scalar alpha2 = GetHexAlphai(pts, vtkm::Id(2)); + const Scalar alpha3 = GetHexAlphai(pts, vtkm::Id(3)); + const Scalar alpha4 = GetHexAlphai(pts, vtkm::Id(4)); + const Scalar alpha5 = GetHexAlphai(pts, vtkm::Id(5)); + const Scalar alpha6 = GetHexAlphai(pts, vtkm::Id(6)); + const Scalar alpha7 = GetHexAlphai(pts, vtkm::Id(7)); + const Scalar alpha8 = GetHexAlphai(pts, vtkm::Id(8)); + const Scalar alpha8Div64 = alpha8 / Scalar(64.0); - const Edge hexMatrices[9][3] = { { HexEdges[0], HexEdges[3], HexEdges[4] }, - { HexEdges[1], -1 * HexEdges[0], HexEdges[5] }, - { HexEdges[2], -1 * HexEdges[1], HexEdges[6] }, - { -1 * HexEdges[3], -1 * HexEdges[2], HexEdges[7] }, - { HexEdges[11], HexEdges[8], -1 * HexEdges[4] }, - { -1 * HexEdges[8], HexEdges[9], -1 * HexEdges[5] }, - { -1 * HexEdges[9], HexEdges[10], -1 * HexEdges[6] }, - { -1 * HexEdges[10], -1 * HexEdges[11], -1 * HexEdges[7] }, - { principleXAxis, principleYAxis, principleZAxis } }; - return vtkm::exec::cellmetrics::CellJacobianMetricOfHex( - vtkm::make_VecC(hexMatrices, 12)); + const Scalar q = vtkm::Min( + alpha0, + vtkm::Min( + alpha1, + vtkm::Min( + alpha2, + vtkm::Min( + alpha3, + vtkm::Min(alpha4, + vtkm::Min(alpha5, vtkm::Min(alpha6, vtkm::Min(alpha7, alpha8Div64)))))))); + + return q; } -// Compute the jacobian of a tetrahedron. -// Formula: (L2 * L0) * L3 +// Compute the Jacobian of a tetrahedron. +// Formula: (L2 x L0) * L3 // Equals Sqrt(2) / 2 for unit equilateral tetrahedron // Acceptable Range: [0, FLOAT_MAX] // Normal Range: [0, FLOAT_MAX] @@ -261,18 +164,24 @@ VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts, { if (numPts != 4) { - worklet.RaiseError("Jacobian metric requires 4 points"); + worklet.RaiseError("Jacobian metric (tetra) requires 4 points"); return OutType(0.0); } - //the 3 edges we need - using Edge = typename PointCoordVecType::ComponentType; - const Edge EdgesNeeded[3] = { pts[1] - pts[0], pts[0] - pts[2], pts[3] - pts[0] }; - return (OutType)vtkm::Dot(vtkm::Cross(EdgesNeeded[1], EdgesNeeded[0]), EdgesNeeded[2]); -} + using Scalar = OutType; + using CollectionOfPoints = PointCoordVecType; + using Vector = typename PointCoordVecType::ComponentType; + const Vector L0 = GetTetraL0(pts); + const Vector L2 = GetTetraL2(pts); + const Vector L3 = GetTetraL3(pts); + + const Scalar q = vtkm::Dot(vtkm::Cross(L2, L0), L3); + + return q; +} } // namespace cellmetrics } // namespace exec } // namespace vtkm -#endif // vtk_m_exec_cellmetrics_CellEdgeRatioMetric_h +#endif // vtk_m_exec_cellmetrics_CellJacobianMetric_h diff --git a/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h b/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h new file mode 100644 index 000000000..428c4874b --- /dev/null +++ b/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h @@ -0,0 +1,765 @@ +#ifndef vtk_m_exec_cellmetrics_TypeOfCellHexahedral +#define vtk_m_exec_cellmetrics_TypeOfCellHexahedral +/** + * The Verdict manual defines a set of commonly + * used components of a hexahedra (hex). For example, + * area, edge lengths, and so forth. + * + * These definitions can be found starting on + * page 77 of the Verdict manual. + * + * This file contains a set of functions which + * implement return the values of those commonly + * used components for subsequent use in metrics. + */ + +/** + * Returns the L0 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL0(const CollectionOfPoints& pts) +{ + const Vector L0(pts[1] - pts[0]); + return L0; +} + +/** + * Returns the L1 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL1(const CollectionOfPoints& pts) +{ + const Vector L1(pts[2] - pts[1]); + return L1; +} + +/** + * Returns the L2 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL2(const CollectionOfPoints& pts) +{ + const Vector L2(pts[3] - pts[2]); + return L2; +} + +/** + * Returns the L3 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL3(const CollectionOfPoints& pts) +{ + const Vector L3(pts[3] - pts[0]); + return L3; +} + +/** + * Returns the L4 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL4(const CollectionOfPoints& pts) +{ + const Vector L4(pts[4] - pts[0]); + return L4; +} + +/** + * Returns the L5 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL5(const CollectionOfPoints& pts) +{ + const Vector L5(pts[5] - pts[1]); + return L5; +} + +/** + * Returns the L6 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL6(const CollectionOfPoints& pts) +{ + const Vector L6(pts[6] - pts[2]); + return L6; +} + +/** + * Returns the L7 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL7(const CollectionOfPoints& pts) +{ + const Vector L7(pts[7] - pts[3]); + return L7; +} + +/** + * Returns the L8 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL8(const CollectionOfPoints& pts) +{ + const Vector L8(pts[5] - pts[4]); + return L8; +} + +/** + * Returns the L9 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL9(const CollectionOfPoints& pts) +{ + const Vector L9(pts[6] - pts[5]); + return L9; +} + +/** + * Returns the L10 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL10(const CollectionOfPoints& pts) +{ + const Vector L10(pts[7] - pts[6]); + return L10; +} +/** + * Returns the L11 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexL11(const CollectionOfPoints& pts) +{ + const Vector L11(pts[7] - pts[4]); + return L11; +} +/** + * Returns the L0 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL0Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l0 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL0(pts))); + return l0; +} +/** + * Returns the L1 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL1Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l1 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL1(pts))); + return l1; +} +/** + * Returns the L2 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL2Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l2 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL2(pts))); + return l2; +} +/** + * Returns the L3 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL3Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l3 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL3(pts))); + return l3; +} +/** + * Returns the L4 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL4Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l4 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL4(pts))); + return l4; +} +/** + * Returns the L5 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL5Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l5 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL5(pts))); + return l5; +} +/** + * Returns the L6 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL6Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l6 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL6(pts))); + return l6; +} +/** + * Returns the L7 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL7Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l7 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL7(pts))); + return l7; +} +/** + * Returns the L8 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL8Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l8 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL8(pts))); + return l8; +} +/** + * Returns the L9 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL9Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l9 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL9(pts))); + return l9; +} +/** + * Returns the L10 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL10Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l10 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL10(pts))); + return l10; +} +/** + * Returns the L11 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexL11Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l11 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexL11(pts))); + return l11; +} +/** + * Returns the Max of the magnitude of each vector which makes up the sides of the Hex. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexLMax(const CollectionOfPoints& pts) +{ + const Scalar l0 = GetHexL0Magnitude(pts); + const Scalar l1 = GetHexL1Magnitude(pts); + const Scalar l2 = GetHexL2Magnitude(pts); + const Scalar l3 = GetHexL3Magnitude(pts); + const Scalar l4 = GetHexL4Magnitude(pts); + const Scalar l5 = GetHexL5Magnitude(pts); + const Scalar l6 = GetHexL6Magnitude(pts); + const Scalar l7 = GetHexL7Magnitude(pts); + const Scalar l8 = GetHexL8Magnitude(pts); + const Scalar l9 = GetHexL9Magnitude(pts); + const Scalar l10 = GetHexL10Magnitude(pts); + const Scalar l11 = GetHexL11Magnitude(pts); + + const Scalar lmax = vtkm::Max( + l0, + vtkm::Max( + l1, + vtkm::Max( + l2, + vtkm::Max( + l3, + vtkm::Max( + l4, + vtkm::Max( + l5, + vtkm::Max(l6, vtkm::Max(l7, vtkm::Max(l8, vtkm::Max(l9, vtkm::Max(l10, l11))))))))))); + + return lmax; +} + +/** + * Returns the Min of the magnitude of each vector which makes up the sides of the Hex. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexLMin(const CollectionOfPoints& pts) +{ + const Scalar l0 = GetHexL0Magnitude(pts); + const Scalar l1 = GetHexL1Magnitude(pts); + const Scalar l2 = GetHexL2Magnitude(pts); + const Scalar l3 = GetHexL3Magnitude(pts); + const Scalar l4 = GetHexL4Magnitude(pts); + const Scalar l5 = GetHexL5Magnitude(pts); + const Scalar l6 = GetHexL6Magnitude(pts); + const Scalar l7 = GetHexL7Magnitude(pts); + const Scalar l8 = GetHexL8Magnitude(pts); + const Scalar l9 = GetHexL9Magnitude(pts); + const Scalar l10 = GetHexL10Magnitude(pts); + const Scalar l11 = GetHexL11Magnitude(pts); + + const Scalar lmin = vtkm::Min( + l0, + vtkm::Min( + l1, + vtkm::Min( + l2, + vtkm::Min( + l3, + vtkm::Min( + l4, + vtkm::Min( + l5, + vtkm::Min(l6, vtkm::Min(l7, vtkm::Min(l8, vtkm::Min(l9, vtkm::Min(l10, l11))))))))))); + + return lmin; +} + +/** + * Returns the D0 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexD0(const CollectionOfPoints& pts) +{ + const Vector D0((pts[6] - pts[0])); + return D0; +} + +/** + * Returns the D1 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexD1(const CollectionOfPoints& pts) +{ + const Vector D1(pts[7] - pts[1]); + return D1; +} + +/** + * Returns the D2 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexD2(const CollectionOfPoints& pts) +{ + const Vector D2(pts[4] - pts[2]); + return D2; +} + +/** + * Returns the D3 vector, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the hexahedra. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexD3(const CollectionOfPoints& pts) +{ + const Vector D3(pts[5] - pts[3]); + return D3; +} + +/** + * Returns the D0 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexD0Magnitude(const CollectionOfPoints& pts) +{ + const Scalar d0 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexD0(pts))); + return d0; +} + +/** + * Returns the D1 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexD1Magnitude(const CollectionOfPoints& pts) +{ + const Scalar d1 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexD1(pts))); + return d1; +} + +/** + * Returns the D2 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexD2Magnitude(const CollectionOfPoints& pts) +{ + const Scalar d2 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexD2(pts))); + return d2; +} + +/** + * Returns the D3 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexD3Magnitude(const CollectionOfPoints& pts) +{ + const Scalar d3 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetHexD3(pts))); + return d3; +} + +/** + * Returns the Min of the magnitude of each vector which makes up the sides of the Hex. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexDMin(const CollectionOfPoints& pts) +{ + const Scalar d0 = GetHexD0Magnitude(pts); + const Scalar d1 = GetHexD1Magnitude(pts); + const Scalar d2 = GetHexD2Magnitude(pts); + const Scalar d3 = GetHexD3Magnitude(pts); + + const Scalar dmin = vtkm::Min(d0, vtkm::Min(d1, vtkm::Min(d2, d3))); + + return dmin; +} + +/** + * Returns the Min of the magnitude of each vector which makes up the sides of the Hex. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetHexDMax(const CollectionOfPoints& pts) +{ + const Scalar d0 = GetHexD0Magnitude(pts); + const Scalar d1 = GetHexD1Magnitude(pts); + const Scalar d2 = GetHexD2Magnitude(pts); + const Scalar d3 = GetHexD3Magnitude(pts); + + const Scalar dmax = vtkm::Max(d0, vtkm::Max(d1, vtkm::Max(d2, d3))); + + return dmax; +} + +/** + * Returns the X1 vector defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexX1(const CollectionOfPoints& pts) +{ + const Vector X1((pts[1] - pts[0]) + (pts[2] - pts[3]) + (pts[5] - pts[4]) + (pts[6] - pts[7])); + return X1; +} + +/** + * Returns the X2 vector defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexX2(const CollectionOfPoints& pts) +{ + const Vector X2((pts[3] - pts[0]) + (pts[2] - pts[1]) + (pts[7] - pts[4]) + (pts[6] - pts[5])); + return X2; +} + +/** + * Returns the X3 vector defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetHexX3(const CollectionOfPoints& pts) +{ + const Vector X3((pts[4] - pts[0]) + (pts[5] - pts[1]) + (pts[6] - pts[2]) + (pts[7] - pts[3])); + return X3; +} + +/** + * Returns the A_i matrix defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \param [in] index The index of A to load. + * \return Returns the vector. + */ +template +VTKM_EXEC vtkm::Vec GetHexAi(const CollectionOfPoints& pts, const vtkm::Id& index) +{ + const Scalar neg1(-1.0); + if (index == 0) + { + const Vector v0 = GetHexL0(pts); + const Vector v1 = GetHexL3(pts); + const Vector v2 = GetHexL4(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } + else if (index == 1) + { + const Vector v0 = GetHexL1(pts); + const Vector v1 = neg1 * GetHexL0(pts); + const Vector v2 = GetHexL5(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } + else if (index == 2) + { + const Vector v0 = GetHexL2(pts); + const Vector v1 = neg1 * GetHexL1(pts); + const Vector v2 = GetHexL6(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } + else if (index == 3) + { + const Vector v0 = neg1 * GetHexL3(pts); + const Vector v1 = neg1 * GetHexL2(pts); + const Vector v2 = GetHexL7(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } + else if (index == 4) + { + const Vector v0 = GetHexL11(pts); + const Vector v1 = GetHexL8(pts); + const Vector v2 = neg1 * GetHexL4(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } + else if (index == 5) + { + const Vector v0 = neg1 * GetHexL8(pts); + const Vector v1 = GetHexL9(pts); + const Vector v2 = neg1 * GetHexL5(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } + else if (index == 6) + { + const Vector v0 = neg1 * GetHexL9(pts); + const Vector v1 = GetHexL10(pts); + const Vector v2 = neg1 * GetHexL6(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } + else if (index == 7) + { + const Vector v0 = neg1 * GetHexL10(pts); + const Vector v1 = neg1 * GetHexL11(pts); + const Vector v2 = neg1 * GetHexL7(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } + else + { + const Vector v0 = GetHexX1(pts); + const Vector v1 = GetHexX2(pts); + const Vector v2 = GetHexX3(pts); + const vtkm::Vec A = { v0, v1, v2 }; + return A; + } +} + +/** + * Returns ||A_i||^2 as defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \param [in] index The index of A to load. + * \return Returns the vector. + */ +template +VTKM_EXEC Scalar GetHexAiNormSquared(const CollectionOfPoints& pts, const vtkm::Id& index) +{ + const vtkm::Vec Ai = GetHexAi(pts, index); + const Scalar magSquared0 = vtkm::MagnitudeSquared(Ai[0]); + const Scalar magSquared1 = vtkm::MagnitudeSquared(Ai[1]); + const Scalar magSquared2 = vtkm::MagnitudeSquared(Ai[2]); + + const Scalar AiNormSquared = magSquared0 + magSquared1 + magSquared2; + + return AiNormSquared; +} + +/** + * Returns ||adj(A_i)||^2 as defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \param [in] index The index of A to load. + * \return Returns the vector. + */ +template +VTKM_EXEC Scalar GetHexAiAdjNormSquared(const CollectionOfPoints& pts, const vtkm::Id& index) +{ + const vtkm::Vec Ai = GetHexAi(pts, index); + const Scalar magSquared0 = vtkm::MagnitudeSquared(vtkm::Cross(Ai[0], Ai[1])); + const Scalar magSquared1 = vtkm::MagnitudeSquared(vtkm::Cross(Ai[1], Ai[2])); + const Scalar magSquared2 = vtkm::MagnitudeSquared(vtkm::Cross(Ai[2], Ai[0])); + + const Scalar AiAdjNormSquared = magSquared0 + magSquared1 + magSquared2; + + return AiAdjNormSquared; +} + +/** + * Returns alpha_i, the determinant of A_i, as defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \param [in] index The index of A to load. + * \return Returns the vector. + */ +template +VTKM_EXEC Scalar GetHexAlphai(const CollectionOfPoints& pts, const vtkm::Id& index) +{ + const vtkm::Vec Ai = GetHexAi(pts, index); + const Scalar alpha_i = vtkm::Dot(Ai[0], vtkm::Cross(Ai[1], Ai[2])); + + return alpha_i; +} + +/** + * Returns hat{A}_i, the "normalized" version of A_i, as defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \param [in] index The index of A to load. + * \return Returns the vector. + */ +template +VTKM_EXEC vtkm::Vec GetHexAiHat(const CollectionOfPoints& pts, const vtkm::Id& index) +{ + const vtkm::Vec Ai = GetHexAi(pts, index); + const Vector v0hat = Ai[0] / vtkm::Sqrt(vtkm::MagnitudeSquared(Ai[0])); + const Vector v1hat = Ai[1] / vtkm::Sqrt(vtkm::MagnitudeSquared(Ai[1])); + const Vector v2hat = Ai[2] / vtkm::Sqrt(vtkm::MagnitudeSquared(Ai[2])); + + const vtkm::Vec Ahat = { v0hat, v1hat, v2hat }; + return Ahat; + + return Ahat; +} +/** + * Returns hat{alpha}_i, the determinant of hat{A}_i, as defined in the verdict manual. + * + * \param [in] pts The eight points which define the Hex. + * \param [in] index The index of A to load. + * \return Returns the vector. + */ +template +VTKM_EXEC Scalar GetHexAlphaiHat(const CollectionOfPoints& pts, const vtkm::Id& index) +{ + const vtkm::Vec Ai = GetHexAiHat(pts, index); + const Scalar hatAlpha_i = vtkm::Dot(Ai[0], vtkm::Cross(Ai[1], Ai[2])); + + return hatAlpha_i; +} +#endif diff --git a/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h b/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h new file mode 100644 index 000000000..1091615ab --- /dev/null +++ b/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h @@ -0,0 +1,468 @@ +#ifndef vtk_m_exec_cellmetrics_TypeOfCellQuadrilateral +#define vtk_m_exec_cellmetrics_TypeOfCellQuadrilateral +/** + * The Verdict manual defines a set of commonly + * used components of a quadrilateral (quad). For example, + * area, side lengths, and so forth. + * + * These definitions can be found starting on + * page 32 of the Verdict manual. + * + * This file contains a set of functions which + * implement return the values of those commonly + * used components for subsequent use in metrics. + */ + +/** + * Returns the L0 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadL0(const CollectionOfPoints& pts) +{ + const Vector L0(pts[1] - pts[0]); + return L0; +} + +/** + * Returns the L1 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadL1(const CollectionOfPoints& pts) +{ + const Vector L1(pts[2] - pts[1]); + return L1; +} + +/** + * Returns the L2 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadL2(const CollectionOfPoints& pts) +{ + const Vector L2(pts[3] - pts[2]); + return L2; +} + +/** + * Returns the L3 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadL3(const CollectionOfPoints& pts) +{ + const Vector L3(pts[0] - pts[3]); + return L3; +} + +/** + * Returns the L0 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadL0Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l0 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetQuadL0(pts))); + return l0; +} + +/** + * Returns the L1 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadL1Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l1 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetQuadL1(pts))); + return l1; +} + +/** + * Returns the L2 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadL2Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l2 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetQuadL2(pts))); + return l2; +} + +/** + * Returns the L3 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadL3Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l3 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetQuadL3(pts))); + return l3; +} + +/** + * Returns the Max of the magnitude of each vector which makes up the sides of the Quad. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadLMax(const CollectionOfPoints& pts) +{ + const Scalar l0 = GetQuadL0Magnitude(pts); + const Scalar l1 = GetQuadL1Magnitude(pts); + const Scalar l2 = GetQuadL2Magnitude(pts); + const Scalar l3 = GetQuadL3Magnitude(pts); + const Scalar lmax = vtkm::Max(l0, vtkm::Max(l1, vtkm::Max(l2, l3))); + return lmax; +} + +/** + * Returns the Min of the magnitude of each vector which makes up the sides of the Quad. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadLMin(const CollectionOfPoints& pts) +{ + const Scalar l0 = GetQuadL0Magnitude(pts); + const Scalar l1 = GetQuadL1Magnitude(pts); + const Scalar l2 = GetQuadL2Magnitude(pts); + const Scalar l3 = GetQuadL3Magnitude(pts); + const Scalar lmin = vtkm::Min(l0, vtkm::Min(l1, vtkm::Min(l2, l3))); + return lmin; +} + +/** + * Returns the D0 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadD0(const CollectionOfPoints& pts) +{ + const Vector D0(pts[2] - pts[0]); + return D0; +} + +/** + * Returns the D1 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadD1(const CollectionOfPoints& pts) +{ + const Vector D1(pts[3] - pts[1]); + return D1; +} + +/** + * Returns the D0 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadD0Magnitude(const CollectionOfPoints& pts) +{ + const Scalar d0 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetQuadD0(pts))); + return d0; +} + +/** + * Returns the D0 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadD1Magnitude(const CollectionOfPoints& pts) +{ + const Scalar d1 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetQuadD1(pts))); + return d1; +} + +/** + * Returns the Max of the magnitude of each vector which makes up the diagonals of the Quad. + * + * \param [in] pts The four points which define the Quad. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetQuadDMax(const CollectionOfPoints& pts) +{ + const Scalar d0 = GetQuadD0Magnitude(pts); + const Scalar d1 = GetQuadD1Magnitude(pts); + + const Scalar dmax = vtkm::Max(d0, d1); + return dmax; +} + +/** + * Returns the X0 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadX0(const CollectionOfPoints& pts) +{ + const Vector X0((pts[1] - pts[0]) + (pts[2] - pts[3])); + return X0; +} + +/** + * Returns the X1 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadX1(const CollectionOfPoints& pts) +{ + const Vector X1((pts[2] - pts[1]) + (pts[3] - pts[0])); + return X1; +} + +/** + * Returns the N0 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadN0(const CollectionOfPoints& pts) +{ + const Vector A = GetQuadL3(pts); + const Vector B = GetQuadL0(pts); + const Vector N0 = vtkm::Cross(A, B); + return N0; +} + +/** + * Returns the N1 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadN1(const CollectionOfPoints& pts) +{ + const Vector A = GetQuadL0(pts); + const Vector B = GetQuadL1(pts); + const Vector N1 = vtkm::Cross(A, B); + return N1; +} + +/** + * Returns the N2 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadN2(const CollectionOfPoints& pts) +{ + const Vector A = GetQuadL1(pts); + const Vector B = GetQuadL2(pts); + const Vector N2 = vtkm::Cross(A, B); + return N2; +} + +/** + * Returns the N3 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadN3(const CollectionOfPoints& pts) +{ + const Vector A = GetQuadL2(pts); + const Vector B = GetQuadL3(pts); + const Vector N3 = vtkm::Cross(A, B); + return N3; +} + +/** + * Returns the normal center vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadNc(const CollectionOfPoints& pts) +{ + const Vector A = GetQuadX0(pts); + const Vector B = GetQuadX1(pts); + const Vector Nc = vtkm::Cross(A, B); + return Nc; +} + +/** + * Returns the normalized N0 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadN0Normalized(const CollectionOfPoints& pts) +{ + return vtkm::Normal(GetQuadN0(pts)); +} + +/** + * Returns the normalized N1 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadN1Normalized(const CollectionOfPoints& pts) +{ + return vtkm::Normal(GetQuadN1(pts)); +} + +/** + * Returns the normalized N2 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadN2Normalized(const CollectionOfPoints& pts) +{ + return vtkm::Normal(GetQuadN2(pts)); +} + +/** + * Returns the normalized N3 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadN3Normalized(const CollectionOfPoints& pts) +{ + return vtkm::Normal(GetQuadN3(pts)); +} + +/** + * Returns the normalized Nc vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetQuadNcNormalized(const CollectionOfPoints& pts) +{ + return vtkm::Normal(GetQuadNc(pts)); +} + +/** + * Returns the alpha0 scalar, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the scalar. + */ +template +VTKM_EXEC Scalar GetQuadAlpha0(const CollectionOfPoints& pts) +{ + const Vector normalizedCenterNormal = + GetQuadNcNormalized(pts); + const Vector N0 = GetQuadN0(pts); + return vtkm::Dot(normalizedCenterNormal, N0); +} + +/** + * Returns the alpha1 scalar, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the scalar. + */ +template +VTKM_EXEC Scalar GetQuadAlpha1(const CollectionOfPoints& pts) +{ + const Vector normalizedCenterNormal = + GetQuadNcNormalized(pts); + const Vector N1 = GetQuadN1(pts); + return vtkm::Dot(normalizedCenterNormal, N1); +} + +/** + * Returns the alpha2 scalar, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the scalar. + */ +template +VTKM_EXEC Scalar GetQuadAlpha2(const CollectionOfPoints& pts) +{ + const Vector normalizedCenterNormal = + GetQuadNcNormalized(pts); + const Vector N2 = GetQuadN2(pts); + return vtkm::Dot(normalizedCenterNormal, N2); +} + + +/** + * Returns the alpha3 scalar, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the scalar. + */ +template +VTKM_EXEC Scalar GetQuadAlpha3(const CollectionOfPoints& pts) +{ + const Vector normalizedCenterNormal = + GetQuadNcNormalized(pts); + const Vector N3 = GetQuadN3(pts); + return vtkm::Dot(normalizedCenterNormal, N3); +} + + +/** + * Returns the area of the quad, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the area. + */ +template +VTKM_EXEC Scalar GetQuadArea(const CollectionOfPoints& pts) +{ + const Scalar quarter(0.25); + const Scalar a0 = GetQuadAlpha0(pts); + const Scalar a1 = GetQuadAlpha1(pts); + const Scalar a2 = GetQuadAlpha2(pts); + const Scalar a3 = GetQuadAlpha3(pts); + return quarter * (a0 + a1 + a2 + a3); +} + +#endif diff --git a/vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h b/vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h new file mode 100644 index 000000000..81baf3aea --- /dev/null +++ b/vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h @@ -0,0 +1,295 @@ +#ifndef vtk_m_exec_cellmetrics_TypeOfCellTetrahedral +#define vtk_m_exec_cellmetrics_TypeOfCellTetrahedral +/** + * Returns the L0 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTetraL0(const CollectionOfPoints& pts) +{ + const Vector L0(pts[1] - pts[0]); + return L0; +} + +/** + * Returns the L1 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTetraL1(const CollectionOfPoints& pts) +{ + const Vector L1(pts[2] - pts[1]); + return L1; +} + +/** + * Returns the L2 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTetraL2(const CollectionOfPoints& pts) +{ + const Vector L2(pts[0] - pts[2]); + return L2; +} + +/** + * Returns the L3 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTetraL3(const CollectionOfPoints& pts) +{ + const Vector L3(pts[3] - pts[0]); + return L3; +} + +/** + * Returns the L4 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTetraL4(const CollectionOfPoints& pts) +{ + const Vector L4(pts[3] - pts[1]); + return L4; +} + +/** + * Returns the L5 vector, as defined by the verdict manual. + * + * \param [in] pts The four points which define the quadrilateral. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTetraL5(const CollectionOfPoints& pts) +{ + const Vector L5(pts[3] - pts[2]); + return L5; +} + +/** + * Returns the L0 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTetraL0Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l0 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTetraL0(pts))); + return l0; +} + +/** + * Returns the L1 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTetraL1Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l1 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTetraL1(pts))); + return l1; +} + +/** + * Returns the L2 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTetraL2Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l2 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTetraL2(pts))); + return l2; +} + +/** + * Returns the L3 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTetraL3Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l3 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTetraL3(pts))); + return l3; +} + +/** + * Returns the L4 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTetraL4Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l4 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTetraL4(pts))); + return l4; +} + +/** + * Returns the L5 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTetraL5Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l5 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTetraL5(pts))); + return l5; +} + +/** + * Returns the Max of the magnitude of each vector which makes up the edges of the Tetra. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the max. + */ +template +VTKM_EXEC Scalar GetTetraLMax(const CollectionOfPoints& pts) +{ + const Scalar l0 = GetTetraL0Magnitude(pts); + const Scalar l1 = GetTetraL1Magnitude(pts); + const Scalar l2 = GetTetraL2Magnitude(pts); + const Scalar l3 = GetTetraL3Magnitude(pts); + const Scalar l4 = GetTetraL4Magnitude(pts); + const Scalar l5 = GetTetraL5Magnitude(pts); + const Scalar lmax = vtkm::Max(l0, vtkm::Max(l1, vtkm::Max(l2, vtkm::Max(l3, vtkm::Max(l4, l5))))); + return lmax; +} + +/** + * Returns the Min of the magnitude of each vector which makes up the sides of the Tetra. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the min. + */ +template +VTKM_EXEC Scalar GetTetraLMin(const CollectionOfPoints& pts) +{ + const Scalar l0 = GetTetraL0Magnitude(pts); + const Scalar l1 = GetTetraL1Magnitude(pts); + const Scalar l2 = GetTetraL2Magnitude(pts); + const Scalar l3 = GetTetraL3Magnitude(pts); + const Scalar l4 = GetTetraL4Magnitude(pts); + const Scalar l5 = GetTetraL5Magnitude(pts); + const Scalar lmin = vtkm::Min(l0, vtkm::Min(l1, vtkm::Min(l2, vtkm::Min(l3, vtkm::Min(l4, l5))))); + return lmin; +} + +/** + * Returns the surface area of the Tetra. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the area. + */ +template +VTKM_EXEC Scalar GetTetraArea(const CollectionOfPoints& pts) +{ + const Vector L0 = GetTetraL0(pts); + const Vector L1 = GetTetraL1(pts); + const Vector L2 = GetTetraL2(pts); + const Vector L3 = GetTetraL3(pts); + const Vector L4 = GetTetraL4(pts); + + const Scalar a = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L2, L0))); + const Scalar b = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L3, L0))); + const Scalar c = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L4, L1))); + const Scalar d = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L3, L2))); + const Scalar half(0.5); + + const Scalar area = half * (a + b + c + d); + return area; +} + +/** + * Returns the volume of the Tetra. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the volume. + */ +template +VTKM_EXEC Scalar GetTetraVolume(const CollectionOfPoints& pts) +{ + const Vector L0 = GetTetraL0(pts); + const Vector L2 = GetTetraL2(pts); + const Vector L3 = GetTetraL3(pts); + const Scalar six(6.0); + + return vtkm::Dot(vtkm::Cross(L2, L0), L3) / six; +} + +/** + * Returns the inradius of the Tetra. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the inradius. + */ +template +VTKM_EXEC Scalar GetTetraInradius(const CollectionOfPoints& pts) +{ + const Scalar three(3.0); + const Scalar volume = GetTetraVolume(pts); + const Scalar area = GetTetraArea(pts); + + return (three * volume) / area; +} + + +/** + * Returns the circumradius of the Tetra. + * + * \param [in] pts The four points which define the Tetra. + * \return Returns the circumradius. + */ +template +VTKM_EXEC Scalar GetTetraCircumradius(const CollectionOfPoints& pts) +{ + const Vector L0 = GetTetraL0(pts); + const Vector L1 = GetTetraL1(pts); + const Vector L2 = GetTetraL2(pts); + const Vector L3 = GetTetraL3(pts); + const Vector L4 = GetTetraL4(pts); + + const Scalar l0l0 = vtkm::MagnitudeSquared(L0); + const Scalar l2l2 = vtkm::MagnitudeSquared(L2); + const Scalar l3l3 = vtkm::MagnitudeSquared(L3); + + const Vector A = l3l3 * vtkm::Cross(L2, L0); + const Vector B = l2l2 * vtkm::Cross(L3, L0); + const Vector C = l0l0 * vtkm::Cross(L3, L2); + + const Vector D(A + B + C); + const Scalar d = vtkm::Sqrt(vtkm::MagnitudeSquared(D)); + + const Scalar twelve(12.0); + const Scalar volume = GetTetraVolume(pts); + + const Scalar circumradius = d / (twelve * volume); + return circumradius; +} + +#endif diff --git a/vtkm/exec/cellmetrics/TypeOfCellTriangle.h b/vtkm/exec/cellmetrics/TypeOfCellTriangle.h new file mode 100644 index 000000000..3a7bd329e --- /dev/null +++ b/vtkm/exec/cellmetrics/TypeOfCellTriangle.h @@ -0,0 +1,192 @@ +#ifndef vtk_m_exec_cellmetrics_TypeOfCellTriangle +#define vtk_m_exec_cellmetrics_TypeOfCellTriangle +/** + * The Verdict manual defines a set of commonly + * used components of a triangle. For example, + * area, side lengths, and so forth. + * + * These definitions can be found starting on + * page 17 of the Verdict manual. + * + * This file contains a set of functions which + * implement return the values of those commonly + * used components for subsequent use in metrics. + */ + + +/** + * Returns the L0 vector, as defined by the verdict manual. + * + * \param [in] pts The three points which define the triangle. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTriangleL0(const CollectionOfPoints& pts) +{ + const Vector L0(pts[2] - pts[1]); + return L0; +} + +/** + * Returns the L1 vector, as defined by the verdict manual. + * + * \param [in] pts The three points which define the triangle. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTriangleL1(const CollectionOfPoints& pts) +{ + const Vector L1(pts[0] - pts[2]); + return L1; +} + +/** + * Returns the L2 vector, as defined by the verdict manual. + * + * \param [in] pts The three points which define the triangle. + * \return Returns the vector. + */ +template +VTKM_EXEC Vector GetTriangleL2(const CollectionOfPoints& pts) +{ + const Vector L2(pts[1] - pts[0]); + return L2; +} + +/** + * Returns the L0 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The three points which define the triangle. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTriangleL0Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l0 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTriangleL0(pts))); + return l0; +} + +/** + * Returns the L1 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The three points which define the triangle. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTriangleL1Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l1 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTriangleL1(pts))); + return l1; +} + +/** + * Returns the L2 vector's magnitude, as defined by the verdict manual. + * + * \param [in] pts The three points which define the triangle. + * \return Returns the magnitude of the vector. + */ +template +VTKM_EXEC Scalar GetTriangleL2Magnitude(const CollectionOfPoints& pts) +{ + const Scalar l2 = + vtkm::Sqrt(vtkm::MagnitudeSquared(GetTriangleL2(pts))); + return l2; +} + +/** + * Returns the Max of the magnitude of each vector which makes up the sides of the triangle. + * + * That is to say, the length of the longest side. + * + * \param [in] pts The three points which define the verticies of the triangle. + * + * \return Returns the max of the triangle side lengths. + */ +template +VTKM_EXEC Scalar GetTriangleLMax(const CollectionOfPoints& pts) +{ + const Scalar l0 = GetTriangleL0Magnitude(pts); + const Scalar l1 = GetTriangleL1Magnitude(pts); + const Scalar l2 = GetTriangleL2Magnitude(pts); + const Scalar lmax = vtkm::Max(l0, vtkm::Max(l1, l2)); + return lmax; +} + +/** + * Returns the Min of the magnitude of each vector which makes up the sides of the triangle. + * + * That is to say, the length of the shortest side. + * + * \param [in] pts The three points which define the verticies of the triangle. + * + * \return Returns the max of the triangle side lengths. + */ +template +VTKM_EXEC Scalar GetTriangleLMin(const CollectionOfPoints& pts) +{ + const Scalar l0 = GetTriangleL0Magnitude(pts); + const Scalar l1 = GetTriangleL1Magnitude(pts); + const Scalar l2 = GetTriangleL2Magnitude(pts); + const Scalar lmin = vtkm::Min(l0, vtkm::Min(l1, l2)); + return lmin; +} + +/** + * Returns the area of the triangle. + * + * \param [in] pts The three points which define the verticies of the triangle. + * + * \return Returns the are of the triangle.. + */ +template +VTKM_EXEC Scalar GetTriangleArea(const CollectionOfPoints& pts) +{ + const Vector L0 = GetTriangleL0(pts); + const Vector L1 = GetTriangleL1(pts); + const Scalar half(0.5); + const Scalar crossProductMagnitude = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L0, L1))); + const Scalar area = half * crossProductMagnitude; + return area; +} + +/** + * Returns the radius of a circle inscribed within the given triangle. This is commonly denoted as 'r'. + * + * \param [in] pts The three points which define the verticies of the triangle. + * + * \return Returns the inradius. + */ +template +VTKM_EXEC Scalar GetTriangleInradius(const CollectionOfPoints& pts) +{ + const Scalar two(2.0); + const Scalar area = GetTriangleArea(pts); + const Scalar l0 = GetTriangleL0Magnitude(pts); + const Scalar l1 = GetTriangleL1Magnitude(pts); + const Scalar l2 = GetTriangleL2Magnitude(pts); + const Scalar inradius = (two * area) / (l0 + l1 + l2); + return inradius; +} + +/** + * Returns the radius of a circle circumscribed around the given triangle. This is commonly denoted as 'R'. + * + * \param [in] pts The three points which define the verticies of the triangle. + * + * \return Returns the circumradius. + */ +template +VTKM_EXEC Scalar GetTriangleCircumradius(const CollectionOfPoints& pts) +{ + const Scalar four(4.0); + const Scalar area = GetTriangleArea(pts); + const Scalar l0 = GetTriangleL0Magnitude(pts); + const Scalar l1 = GetTriangleL1Magnitude(pts); + const Scalar l2 = GetTriangleL2Magnitude(pts); + const Scalar circumradius = (l0 * l1 * l2) / (four * area); + return circumradius; +} + +#endif diff --git a/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx b/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx index 7b2a886c6..c85851309 100644 --- a/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx +++ b/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx @@ -31,8 +31,8 @@ #include //Adapted from vtkm/cont/testing/MakeTestDataSet.h -//Modified the content of the Make3DExplicitDataSetZoo() function -inline vtkm::cont::DataSet Make3DExplicitDataSet() +//Modified the content of the MakeExplicitDataSetZoo() function +inline vtkm::cont::DataSet MakeExplicitDataSet() { vtkm::cont::DataSet dataSet; vtkm::cont::DataSetBuilderExplicit dsb; @@ -40,14 +40,11 @@ inline vtkm::cont::DataSet Make3DExplicitDataSet() using CoordType = vtkm::Vec3f_64; std::vector coords = { - { 0.00, 0.00, 0.00 }, { 1.00, 0.00, 0.00 }, { 2.00, 0.00, 0.00 }, { 0.00, 0.00, 1.00 }, - { 1.00, 0.00, 1.00 }, { 2.00, 0.00, 1.00 }, { 0.00, 1.00, 0.00 }, { 1.00, 1.00, 0.00 }, - { 2.00, 1.00, 0.00 }, { 0.00, 1.00, 1.00 }, { 1.00, 1.00, 1.00 }, { 2.00, 1.00, 1.00 }, - { 0.00, 2.00, 0.00 }, { 1.00, 2.00, 0.00 }, { 2.00, 2.00, 0.00 }, { 0.00, 2.00, 1.00 }, - { 1.00, 2.00, 1.00 }, { 2.00, 2.00, 1.00 }, { 1.00, 3.00, 1.00 }, { 2.75, 0.00, 1.00 }, - { 3.00, 0.00, 0.75 }, { 3.00, 0.25, 1.00 }, { 3.00, 1.00, 1.00 }, { 3.00, 1.00, 0.00 }, - { 2.57, 2.00, 1.00 }, { 3.00, 1.75, 1.00 }, { 3.00, 1.75, 0.75 }, { 3.00, 0.00, 0.00 }, - { 2.57, 0.42, 0.57 }, { 2.59, 1.43, 0.71 } + { 0, 0, 0 }, { 3, 0, 0 }, { 2, 2, 0 }, { 4, 0, 0 }, { 7, 0, 0 }, { 7, 2, 0 }, + { 6, 2, 0 }, { 8, 0, 0 }, { 11, 0, 0 }, { 9, 2, 0 }, { 9, 1, 1 }, { 9, 3, 0 }, + { 11, 3, 0 }, { 11, 5, 0 }, { 9, 5, 0 }, { 10, 4, 1 }, { 12, 0, 0 }, { 12, 3, 0 }, + { 12, 2, 1 }, { 15, 0, 0 }, { 15, 3, 0 }, { 15, 1, 1 }, { 16, 0, 0 }, { 18, 0, 0 }, + { 18, 2, 0 }, { 16, 2, 0 }, { 17, 1, 1 }, { 19, 1, 1 }, { 19, 3, 1 }, { 17, 3, 1 } }; std::vector shapes; @@ -56,145 +53,64 @@ inline vtkm::cont::DataSet Make3DExplicitDataSet() //Construct the shapes/cells of the dataset //This is a zoo of points, lines, polygons, and polyhedra - shapes.push_back(vtkm::CELL_SHAPE_HEXAHEDRON); - numindices.push_back(8); + shapes.push_back(vtkm::CELL_SHAPE_TRIANGLE); + numindices.push_back(3); conn.push_back(0); + conn.push_back(1); + conn.push_back(2); + + shapes.push_back(vtkm::CELL_SHAPE_QUAD); + numindices.push_back(4); conn.push_back(3); conn.push_back(4); - conn.push_back(1); + conn.push_back(5); conn.push_back(6); + + shapes.push_back(vtkm::CELL_SHAPE_TETRA); + numindices.push_back(4); + conn.push_back(7); + conn.push_back(8); conn.push_back(9); conn.push_back(10); - conn.push_back(7); + + shapes.push_back(vtkm::CELL_SHAPE_PYRAMID); + numindices.push_back(5); + conn.push_back(11); + conn.push_back(12); + conn.push_back(13); + conn.push_back(14); + conn.push_back(15); + + shapes.push_back(vtkm::CELL_SHAPE_WEDGE); + numindices.push_back(6); + conn.push_back(16); + conn.push_back(17); + conn.push_back(18); + conn.push_back(19); + conn.push_back(20); + conn.push_back(21); shapes.push_back(vtkm::CELL_SHAPE_HEXAHEDRON); numindices.push_back(8); - conn.push_back(1); - conn.push_back(4); - conn.push_back(5); - conn.push_back(2); - conn.push_back(7); - conn.push_back(10); - conn.push_back(11); - conn.push_back(8); - - shapes.push_back(vtkm::CELL_SHAPE_TETRA); - numindices.push_back(4); - conn.push_back(24); - conn.push_back(26); - conn.push_back(25); - conn.push_back(29); - - shapes.push_back(vtkm::CELL_SHAPE_TETRA); - numindices.push_back(4); - conn.push_back(8); - conn.push_back(17); - conn.push_back(11); - conn.push_back(29); - - shapes.push_back(vtkm::CELL_SHAPE_PYRAMID); - numindices.push_back(5); - conn.push_back(24); - conn.push_back(17); - conn.push_back(8); - conn.push_back(23); - conn.push_back(29); - - shapes.push_back(vtkm::CELL_SHAPE_PYRAMID); - numindices.push_back(5); - conn.push_back(25); conn.push_back(22); - conn.push_back(11); - conn.push_back(17); + conn.push_back(23); + conn.push_back(24); + conn.push_back(25); + conn.push_back(26); + conn.push_back(27); + conn.push_back(28); conn.push_back(29); - shapes.push_back(vtkm::CELL_SHAPE_WEDGE); - numindices.push_back(6); - conn.push_back(8); - conn.push_back(14); - conn.push_back(17); - conn.push_back(7); - conn.push_back(13); - conn.push_back(16); - - shapes.push_back(vtkm::CELL_SHAPE_WEDGE); - numindices.push_back(6); - conn.push_back(11); - conn.push_back(8); - conn.push_back(17); - conn.push_back(10); - conn.push_back(7); - conn.push_back(16); - - shapes.push_back(vtkm::CELL_SHAPE_VERTEX); - numindices.push_back(1); - conn.push_back(0); - - shapes.push_back(vtkm::CELL_SHAPE_VERTEX); - numindices.push_back(1); - conn.push_back(29); - - shapes.push_back(vtkm::CELL_SHAPE_LINE); - numindices.push_back(2); - conn.push_back(0); - conn.push_back(1); - - shapes.push_back(vtkm::CELL_SHAPE_LINE); - numindices.push_back(2); - conn.push_back(15); - conn.push_back(16); - - shapes.push_back(vtkm::CELL_SHAPE_TRIANGLE); - numindices.push_back(3); - conn.push_back(2); - conn.push_back(4); - conn.push_back(15); - - shapes.push_back(vtkm::CELL_SHAPE_TRIANGLE); - numindices.push_back(3); - conn.push_back(5); - conn.push_back(6); - conn.push_back(7); - - shapes.push_back(vtkm::CELL_SHAPE_QUAD); - numindices.push_back(4); - conn.push_back(0); - conn.push_back(3); - conn.push_back(5); - conn.push_back(2); - - shapes.push_back(vtkm::CELL_SHAPE_QUAD); - numindices.push_back(4); - conn.push_back(5); - conn.push_back(4); - conn.push_back(10); - conn.push_back(11); - - shapes.push_back(vtkm::CELL_SHAPE_POLYGON); - numindices.push_back(3); - conn.push_back(4); - conn.push_back(7); - conn.push_back(1); - - shapes.push_back(vtkm::CELL_SHAPE_POLYGON); - numindices.push_back(4); - conn.push_back(1); - conn.push_back(6); - conn.push_back(7); - conn.push_back(2); - dataSet = dsb.Create(coords, shapes, numindices, conn, "coordinates"); return dataSet; } -template -std::vector TestMeshQualityFilter(const vtkm::cont::DataSet& input, - const std::vector& expectedVals, - const std::string& outputname, - T filter) +bool TestMeshQualityFilter(const vtkm::cont::DataSet& input, + const std::vector& expectedVals, + const std::string& outputname, + vtkm::filter::MeshQuality& filter) { - std::vector errors; vtkm::cont::DataSet output; try { @@ -202,168 +118,93 @@ std::vector TestMeshQualityFilter(const vtkm::cont::DataSet& input, } catch (vtkm::cont::ErrorExecution&) { - errors.push_back("Error occured while executing filter. Exiting..."); - return errors; + return true; } //Test the computed metric values (for all cells) and expected metric //values for equality. - vtkm::cont::testing::TestEqualResult result = vtkm::cont::testing::test_equal_ArrayHandles( - vtkm::cont::make_ArrayHandle(expectedVals), output.GetField(outputname).GetData()); - if (!result) - result.PushMessage(std::string("Data doesn't match")); - - return result.GetMessages(); -} - -//Either an error occurred during execution of the -//filter, or mismatches exist between the expected output -//and the computed filter output. -void CheckForErrors(const std::vector& messages) -{ - if (!messages.empty()) + vtkm::cont::ArrayHandle values; + output.GetField(outputname).GetData().CopyTo(values); + auto portal1 = values.GetPortalConstControl(); + if (portal1.GetNumberOfValues() != (vtkm::Id)expectedVals.size()) { - std::cout << "FAIL\n"; - for (std::string m : messages) - std::cout << m << "\n"; + printf("Number of expected values for %s does not match.\n", outputname.c_str()); + return true; } - else - std::cout << "SUCCESS\n"; + + std::vector cellTypes = { "triangle", "quadrilateral", "tetrahedron", + "pyramid", "wedge", "hexahedron" }; + bool anyFailures = false; + for (unsigned long i = 0; i < expectedVals.size(); i++) + { + vtkm::Id id = (vtkm::Id)i; + if (portal1.Get(id) != expectedVals[i]) + { + printf("Metric \"%s\" for cell type \"%s\" does not match. Expected %f and got %f\n", + outputname.c_str(), + cellTypes[i].c_str(), + expectedVals[i], + portal1.Get(id)); + anyFailures = true; + } + } + return anyFailures; } int TestMeshQuality() { using FloatVec = std::vector; - using PairVec = std::vector>; - using StringVec = std::vector; - using CharVec = std::vector; - using QualityFilter = vtkm::filter::MeshQuality; //Test variables - vtkm::cont::DataSet input = Make3DExplicitDataSet(); - std::unique_ptr filter; - std::string metricSuffix; - StringVec fieldNames; - CharVec testedShapes; - PairVec shapeMetricPairs; - FloatVec expectedValues; + vtkm::cont::DataSet input = MakeExplicitDataSet(); - /*************************************************** - * Test 1: Volume metric - ***************************************************/ + int numFailures = 0; + bool testFailed = false; - std::cout << "Testing MeshQuality filter: Volume metric" - << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; + std::vector expectedValues; + std::vector metrics; + std::vector metricName; - //The ground truth metric value for each cell in the input dataset. - //These values are generated from VisIt using the equivalent pseudocolor - //mesh quality metric. - expectedValues = { 1, - 1, - (vtkm::FloatDefault)0.0100042, - (vtkm::FloatDefault)0.0983333, - (vtkm::FloatDefault)0.0732667, - (vtkm::FloatDefault)0.0845833, - -0.5, - -0.5, - 0, - 0, - 1, - 1, - 1.5, - (vtkm::FloatDefault)0.7071068, - 2, - 1, - 0.5, - 1 }; + /* + FloatVec volumeExpectedValues = { 0, 0, 1, (float) 1.333333333, 4, 4 }; + expectedValues.push_back(volumeExpectedValues); + metrics.push_back(vtkm::filter::CellMetric::VOLUME); + metricName.push_back("volume"); + */ - filter.reset(new QualityFilter(vtkm::filter::CellMetric::VOLUME)); - std::vector errors = - TestMeshQualityFilter(input, expectedValues, "volume", *filter); - std::cout << "Volume metric test: "; - CheckForErrors(errors); + FloatVec jacobianExpectedValues = { 0, 2, 6, 0, 0, 4 }; + expectedValues.push_back(jacobianExpectedValues); + metrics.push_back(vtkm::filter::CellMetric::JACOBIAN); + metricName.push_back("jacobian"); - /*************************************************** - * Test 2: Diagonal Ratio metric - ***************************************************/ + /* + FloatVec diagonalRatioExpectedValues = { -1, -1, -1, -1, -1, (float) 0.39 }; + expectedValues.push_back(diagonalRatioExpectedValues); + metrics.push_back(vtkm::filter::CellMetric::DIAGONAL_RATIO); + metricName.push_back("diagonalRatio"); + */ - std::cout << "Testing MeshQuality filter: Diagonal Ratio metric" - << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - - - expectedValues = { - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, (vtkm::FloatDefault)2.23607 - }; - - filter.reset(new QualityFilter(vtkm::filter::CellMetric::DIAGONAL_RATIO)); - errors = TestMeshQualityFilter(input, expectedValues, "diagonalRatio", *filter); - std::cout << "Diagonal ratio metric test: "; - CheckForErrors(errors); - - /*************************************************** - * Test 3: Jacobian metric - ***************************************************/ - - std::cout << "Testing MeshQuality filter: Jacobian metric" - << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - - - expectedValues = { - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, (vtkm::FloatDefault)2.23607 - }; - - filter.reset(new QualityFilter(vtkm::filter::CellMetric::JACOBIAN)); - errors = TestMeshQualityFilter(input, expectedValues, "jacobian", *filter); - std::cout << "Jacobian metric test: "; - CheckForErrors(errors); - -#if 0 - /*************************************************** - * Test 5: Oddy metric - ***************************************************/ - - std::cout << "Testing MeshQuality filter: Oddy metric" - << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - - testedShapes = {vtkm::CELL_SHAPE_HEXAHEDRON, vtkm::CELL_SHAPE_POLYGON, - vtkm::CELL_SHAPE_QUAD}; - - shapeMetricPairs.clear(); - for (auto s : testedShapes) - shapeMetricPairs.push_back(vtkm::make_Pair(s, vtkm::filter::CellMetric::ODDY)); - expectedValues = {0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1.125, 0, - 0, 2.5}; /*(all cells, volume value)*/ - - filter.reset(new QualityFilter(shapeMetricPairs)); - errors = TestMeshQualityFilter(input, expectedValues, *filter); - std::cout << "Oddy metric test: "; - CheckForErrors(errors); - - /*************************************************** - * Test 4: Relative Size Squared metric - ***************************************************/ - - std::cout << "Testing MeshQuality filter: Relative Size Squared metric" - << "\n++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - - testedShapes = {vtkm::CELL_SHAPE_HEXAHEDRON, vtkm::CELL_SHAPE_POLYGON, - vtkm::CELL_SHAPE_QUAD, vtkm::CELL_SHAPE_TRIANGLE, - vtkm::CELL_SHAPE_TETRA}; - - shapeMetricPairs.clear(); - for (auto s : testedShapes) - shapeMetricPairs.push_back(vtkm::make_Pair(s, vtkm::filter::CellMetric::RELATIVE_SIZE)); - expectedValues = {1, 1, 0.0341086, 0.303456, 0, 0, 0, - 0, 0, 0, 0, 0, 0.361898, 0.614047, 1, 1, - 0.307024, 1}; - - filter.reset(new QualityFilter(shapeMetricPairs)); - errors = TestMeshQualityFilter(input, expectedValues, *filter); - std::cout << "Relative Size Square metric test: "; - CheckForErrors(errors); -#endif + unsigned long numTests = metrics.size(); + for (unsigned long i = 0; i < numTests; i++) + { + printf("Testing metric %s\n", metricName[i].c_str()); + vtkm::filter::MeshQuality filter(metrics[i]); + testFailed = TestMeshQualityFilter(input, expectedValues[i], metricName[i], filter); + if (testFailed) + { + numFailures++; + printf("\ttest \"%s\" failed\n", metricName[i].c_str()); + } + else + printf("\t... passed\n"); + } + if (numFailures > 0) + { + printf("Number of failed metrics is %d\n", numFailures); + bool see_previous_messages = false; // this variable name plays well with macro + VTKM_TEST_ASSERT(see_previous_messages, "Failure occurred during test"); + } return 0; } From f4edb6a8ed24c6a0010c7c5fafa10595a3c6e76d Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Tue, 17 Sep 2019 14:46:51 -0700 Subject: [PATCH 018/108] remove trailing whitespace --- vtkm/exec/cellmetrics/TypeOfCellHexahedral.h | 16 ++++++------ .../cellmetrics/TypeOfCellQuadrilateral.h | 4 +-- vtkm/exec/cellmetrics/TypeOfCellTriangle.h | 26 +++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h b/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h index 428c4874b..f30126b69 100644 --- a/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h +++ b/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h @@ -3,9 +3,9 @@ /** * The Verdict manual defines a set of commonly * used components of a hexahedra (hex). For example, - * area, edge lengths, and so forth. + * area, edge lengths, and so forth. * - * These definitions can be found starting on + * These definitions can be found starting on * page 77 of the Verdict manual. * * This file contains a set of functions which @@ -590,7 +590,7 @@ VTKM_EXEC Vector GetHexX3(const CollectionOfPoints& pts) * Returns the A_i matrix defined in the verdict manual. * * \param [in] pts The eight points which define the Hex. - * \param [in] index The index of A to load. + * \param [in] index The index of A to load. * \return Returns the vector. */ template @@ -675,7 +675,7 @@ VTKM_EXEC vtkm::Vec GetHexAi(const CollectionOfPoints& pts, const vtk * Returns ||A_i||^2 as defined in the verdict manual. * * \param [in] pts The eight points which define the Hex. - * \param [in] index The index of A to load. + * \param [in] index The index of A to load. * \return Returns the vector. */ template @@ -695,7 +695,7 @@ VTKM_EXEC Scalar GetHexAiNormSquared(const CollectionOfPoints& pts, const vtkm:: * Returns ||adj(A_i)||^2 as defined in the verdict manual. * * \param [in] pts The eight points which define the Hex. - * \param [in] index The index of A to load. + * \param [in] index The index of A to load. * \return Returns the vector. */ template @@ -715,7 +715,7 @@ VTKM_EXEC Scalar GetHexAiAdjNormSquared(const CollectionOfPoints& pts, const vtk * Returns alpha_i, the determinant of A_i, as defined in the verdict manual. * * \param [in] pts The eight points which define the Hex. - * \param [in] index The index of A to load. + * \param [in] index The index of A to load. * \return Returns the vector. */ template @@ -731,7 +731,7 @@ VTKM_EXEC Scalar GetHexAlphai(const CollectionOfPoints& pts, const vtkm::Id& ind * Returns hat{A}_i, the "normalized" version of A_i, as defined in the verdict manual. * * \param [in] pts The eight points which define the Hex. - * \param [in] index The index of A to load. + * \param [in] index The index of A to load. * \return Returns the vector. */ template @@ -751,7 +751,7 @@ VTKM_EXEC vtkm::Vec GetHexAiHat(const CollectionOfPoints& pts, const * Returns hat{alpha}_i, the determinant of hat{A}_i, as defined in the verdict manual. * * \param [in] pts The eight points which define the Hex. - * \param [in] index The index of A to load. + * \param [in] index The index of A to load. * \return Returns the vector. */ template diff --git a/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h b/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h index 1091615ab..5f69a21ed 100644 --- a/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h +++ b/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h @@ -3,9 +3,9 @@ /** * The Verdict manual defines a set of commonly * used components of a quadrilateral (quad). For example, - * area, side lengths, and so forth. + * area, side lengths, and so forth. * - * These definitions can be found starting on + * These definitions can be found starting on * page 32 of the Verdict manual. * * This file contains a set of functions which diff --git a/vtkm/exec/cellmetrics/TypeOfCellTriangle.h b/vtkm/exec/cellmetrics/TypeOfCellTriangle.h index 3a7bd329e..c09227218 100644 --- a/vtkm/exec/cellmetrics/TypeOfCellTriangle.h +++ b/vtkm/exec/cellmetrics/TypeOfCellTriangle.h @@ -5,7 +5,7 @@ * used components of a triangle. For example, * area, side lengths, and so forth. * - * These definitions can be found starting on + * These definitions can be found starting on * page 17 of the Verdict manual. * * This file contains a set of functions which @@ -97,11 +97,11 @@ VTKM_EXEC Scalar GetTriangleL2Magnitude(const CollectionOfPoints& pts) /** * Returns the Max of the magnitude of each vector which makes up the sides of the triangle. - * + * * That is to say, the length of the longest side. - * + * * \param [in] pts The three points which define the verticies of the triangle. - * + * * \return Returns the max of the triangle side lengths. */ template @@ -116,11 +116,11 @@ VTKM_EXEC Scalar GetTriangleLMax(const CollectionOfPoints& pts) /** * Returns the Min of the magnitude of each vector which makes up the sides of the triangle. - * + * * That is to say, the length of the shortest side. - * + * * \param [in] pts The three points which define the verticies of the triangle. - * + * * \return Returns the max of the triangle side lengths. */ template @@ -135,9 +135,9 @@ VTKM_EXEC Scalar GetTriangleLMin(const CollectionOfPoints& pts) /** * Returns the area of the triangle. - * + * * \param [in] pts The three points which define the verticies of the triangle. - * + * * \return Returns the are of the triangle.. */ template @@ -153,9 +153,9 @@ VTKM_EXEC Scalar GetTriangleArea(const CollectionOfPoints& pts) /** * Returns the radius of a circle inscribed within the given triangle. This is commonly denoted as 'r'. - * + * * \param [in] pts The three points which define the verticies of the triangle. - * + * * \return Returns the inradius. */ template @@ -172,9 +172,9 @@ VTKM_EXEC Scalar GetTriangleInradius(const CollectionOfPoints& pts) /** * Returns the radius of a circle circumscribed around the given triangle. This is commonly denoted as 'R'. - * + * * \param [in] pts The three points which define the verticies of the triangle. - * + * * \return Returns the circumradius. */ template From e040ea05e11143e33c491f30522b1c716911d351 Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Tue, 17 Sep 2019 20:53:42 -0700 Subject: [PATCH 019/108] formatting suggestions from KMorel --- vtkm/filter/MeshQuality.h | 6 +- vtkm/filter/MeshQuality.h.hrc | 113 ++++++++++++++++++++++++++++++++++ vtkm/filter/MeshQuality.hxx | 11 ++-- 3 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 vtkm/filter/MeshQuality.h.hrc diff --git a/vtkm/filter/MeshQuality.h b/vtkm/filter/MeshQuality.h index d6197b84c..d1afb87c3 100644 --- a/vtkm/filter/MeshQuality.h +++ b/vtkm/filter/MeshQuality.h @@ -79,7 +79,7 @@ public: using SupportedTypes = vtkm::TypeListTagFieldVec3; VTKM_CONT MeshQuality(CellMetric); - void SetOutputName(const std::string& s) { outputName = s; }; + void SetOutputName(const std::string& s) { this->OutputName = s; }; template VTKM_CONT vtkm::cont::DataSet DoExecute( @@ -89,8 +89,8 @@ public: const vtkm::filter::PolicyBase& policy); private: - CellMetric myMetric; - std::string outputName; + CellMetric MyMetric; + std::string OutputName; }; } // namespace filter diff --git a/vtkm/filter/MeshQuality.h.hrc b/vtkm/filter/MeshQuality.h.hrc new file mode 100644 index 000000000..94032927b --- /dev/null +++ b/vtkm/filter/MeshQuality.h.hrc @@ -0,0 +1,113 @@ +//============================================================================ +// 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_MeshQuality_h +#define vtk_m_filter_MeshQuality_h + +#include +#include +#include +#include + +namespace vtkm +{ +namespace filter +{ + +//Names of the available cell metrics, for use in +//the output dataset fields +static const std::string MetricNames[] = { "area", + "aspectGamma", + "aspectRatio", + "condition", + "diagonalRatio", + "jacobian", + "minAngle", + "maxAngle", + "oddy", + "relativeSize", + "scaledJacobian", + "shape", + "shear", + "skew", + "stretch", + "taper", + "volume", + "warpage" +}; + +//Different cell metrics available to use +enum class CellMetric +{ + AREA, + ASPECT_GAMMA, + ASPECT_RATIO, + CONDITION, + DIAGONAL_RATIO, + JACOBIAN, + MIN_ANGLE, + MAX_ANGLE, + ODDY, + RELATIVE_SIZE, + SCALED_JACOBIAN, + SHAPE, + SHEAR, + SKEW, + STRETCH, + TAPER, + VOLUME, + WARPAGE, + NUMBER_OF_CELL_METRICS, + EMPTY +}; + +/** \brief Computes the quality of an unstructured cell-based mesh. The quality is defined in terms of the + * summary statistics (frequency, mean, variance, min, max) of metrics computed over the mesh + * cells. One of several different metrics can be specified for a given cell type, and the mesh + * can consist of one or more different cell types. The resulting mesh quality is stored as one + * or more new fields in the output dataset of this filter, with a separate field for each cell type. + * Each field contains the metric summary statistics for the cell type. + * Summary statists with all 0 values imply that the specified metric does not support the cell type. + */ +class MeshQuality : public vtkm::filter::FilterCell +{ +public: + using SupportedTypes = vtkm::TypeListTagFieldVec3; + + VTKM_CONT MeshQuality(CellMetric); + + template + VTKM_CONT vtkm::cont::DataSet DoExecute( + const vtkm::cont::DataSet& input, + const vtkm::cont::ArrayHandle, StorageType>& points, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy); + +private: + //A user-assigned cell metric per shape/cell type + CellMetric myMetric; +}; + +} // namespace filter +} // namespace vtkm + +#include + +#endif // vtk_m_filter_MeshQuality_h diff --git a/vtkm/filter/MeshQuality.hxx b/vtkm/filter/MeshQuality.hxx index 5f4bd9a30..07fc4a41b 100644 --- a/vtkm/filter/MeshQuality.hxx +++ b/vtkm/filter/MeshQuality.hxx @@ -60,12 +60,12 @@ inline VTKM_CONT MeshQuality::MeshQuality(CellMetric metric) : vtkm::filter::FilterCell() { this->SetUseCoordinateSystemAsField(true); - myMetric = metric; - if (myMetric < CellMetric::AREA || myMetric >= CellMetric::NUMBER_OF_CELL_METRICS) + this->MyMetric = metric; + if (this->MyMetric < CellMetric::AREA || this->MyMetric >= CellMetric::NUMBER_OF_CELL_METRICS) { VTKM_ASSERT(true); } - outputName = MetricNames[(int)myMetric]; + this->OutputName = MetricNames[(int)this->MyMetric]; } template @@ -77,13 +77,14 @@ inline VTKM_CONT vtkm::cont::DataSet MeshQuality::DoExecute( { VTKM_ASSERT(fieldMeta.IsPointField()); + //TODO: Should other cellset types be supported? vtkm::cont::CellSetExplicit<> cellSet; input.GetCellSet().CopyTo(cellSet); //Invoke the MeshQuality worklet vtkm::cont::ArrayHandle outArray; vtkm::worklet::MeshQuality qualityWorklet; - qualityWorklet.SetMetric(myMetric); + qualityWorklet.SetMetric(this->MyMetric); this->Invoke(qualityWorklet, vtkm::filter::ApplyPolicyCellSet(cellSet, policy), points, outArray); vtkm::cont::DataSet result; @@ -91,7 +92,7 @@ inline VTKM_CONT vtkm::cont::DataSet MeshQuality::DoExecute( //Append the metric values of all cells into the output //dataset as a new field - result.AddField(vtkm::cont::make_FieldCell(outputName, outArray)); + result.AddField(vtkm::cont::make_FieldCell(this->OutputName, outArray)); return result; } From 91f7e763bcdd96e1fbc1c62be91434e69c335bf5 Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Tue, 17 Sep 2019 21:15:41 -0700 Subject: [PATCH 020/108] fix copyright, warnings, cmake for Jacobian-cellmetric branch --- vtkm/exec/cellmetrics/CMakeLists.txt | 5 ++++ vtkm/exec/cellmetrics/TypeOfCellHexahedral.h | 21 +++++++++++++++-- .../cellmetrics/TypeOfCellQuadrilateral.h | 19 +++++++++++++++ vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h | 23 +++++++++++++++++-- vtkm/exec/cellmetrics/TypeOfCellTriangle.h | 19 +++++++++++++++ .../testing/UnitTestMeshQualityFilter.cxx | 2 +- 6 files changed, 84 insertions(+), 5 deletions(-) diff --git a/vtkm/exec/cellmetrics/CMakeLists.txt b/vtkm/exec/cellmetrics/CMakeLists.txt index c878006c2..4d2584d0e 100644 --- a/vtkm/exec/cellmetrics/CMakeLists.txt +++ b/vtkm/exec/cellmetrics/CMakeLists.txt @@ -21,6 +21,11 @@ set(headers CellDiagonalRatioMetric.h CellEdgeRatioMetric.h + CellJacobianMetric.h + TypeOfCellHexahedron.h + TypeOfCellQuadrilateral.h + TypeOfCellTetrahedral.h + TypeOfCellTriangle.h ) diff --git a/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h b/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h index f30126b69..282747f34 100644 --- a/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h +++ b/vtkm/exec/cellmetrics/TypeOfCellHexahedral.h @@ -1,3 +1,22 @@ +//============================================================================ +// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2018 UT-Battelle, LLC. +// Copyright 2018 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_exec_cellmetrics_TypeOfCellHexahedral #define vtk_m_exec_cellmetrics_TypeOfCellHexahedral /** @@ -744,8 +763,6 @@ VTKM_EXEC vtkm::Vec GetHexAiHat(const CollectionOfPoints& pts, const const vtkm::Vec Ahat = { v0hat, v1hat, v2hat }; return Ahat; - - return Ahat; } /** * Returns hat{alpha}_i, the determinant of hat{A}_i, as defined in the verdict manual. diff --git a/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h b/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h index 5f69a21ed..c402366cf 100644 --- a/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h +++ b/vtkm/exec/cellmetrics/TypeOfCellQuadrilateral.h @@ -1,3 +1,22 @@ +//============================================================================ +// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2018 UT-Battelle, LLC. +// Copyright 2018 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_exec_cellmetrics_TypeOfCellQuadrilateral #define vtk_m_exec_cellmetrics_TypeOfCellQuadrilateral /** diff --git a/vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h b/vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h index 81baf3aea..b51786de5 100644 --- a/vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h +++ b/vtkm/exec/cellmetrics/TypeOfCellTetrahedral.h @@ -1,3 +1,22 @@ +//============================================================================ +// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2018 UT-Battelle, LLC. +// Copyright 2018 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_exec_cellmetrics_TypeOfCellTetrahedral #define vtk_m_exec_cellmetrics_TypeOfCellTetrahedral /** @@ -219,9 +238,9 @@ VTKM_EXEC Scalar GetTetraArea(const CollectionOfPoints& pts) const Scalar b = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L3, L0))); const Scalar c = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L4, L1))); const Scalar d = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L3, L2))); - const Scalar half(0.5); + const Scalar hhalf(0.5); - const Scalar area = half * (a + b + c + d); + const Scalar area = hhalf * (a + b + c + d); return area; } diff --git a/vtkm/exec/cellmetrics/TypeOfCellTriangle.h b/vtkm/exec/cellmetrics/TypeOfCellTriangle.h index c09227218..154c4d3d9 100644 --- a/vtkm/exec/cellmetrics/TypeOfCellTriangle.h +++ b/vtkm/exec/cellmetrics/TypeOfCellTriangle.h @@ -1,3 +1,22 @@ +//============================================================================ +// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2018 UT-Battelle, LLC. +// Copyright 2018 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_exec_cellmetrics_TypeOfCellTriangle #define vtk_m_exec_cellmetrics_TypeOfCellTriangle /** diff --git a/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx b/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx index c85851309..c0e09c51e 100644 --- a/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx +++ b/vtkm/filter/testing/UnitTestMeshQualityFilter.cxx @@ -184,7 +184,7 @@ int TestMeshQuality() metricName.push_back("diagonalRatio"); */ - unsigned long numTests = metrics.size(); + unsigned long numTests = (unsigned long)metrics.size(); for (unsigned long i = 0; i < numTests; i++) { printf("Testing metric %s\n", metricName[i].c_str()); From 954e258745a7509c206b1b0c69f7ed559c213a43 Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Tue, 17 Sep 2019 21:31:50 -0700 Subject: [PATCH 021/108] fix problem with filename --- vtkm/exec/cellmetrics/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtkm/exec/cellmetrics/CMakeLists.txt b/vtkm/exec/cellmetrics/CMakeLists.txt index 4d2584d0e..8167541a0 100644 --- a/vtkm/exec/cellmetrics/CMakeLists.txt +++ b/vtkm/exec/cellmetrics/CMakeLists.txt @@ -22,7 +22,7 @@ set(headers CellDiagonalRatioMetric.h CellEdgeRatioMetric.h CellJacobianMetric.h - TypeOfCellHexahedron.h + TypeOfCellHexahedral.h TypeOfCellQuadrilateral.h TypeOfCellTetrahedral.h TypeOfCellTriangle.h From d59917473dd42091b6b1ecba61803d36cc3ce324 Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Tue, 17 Sep 2019 23:12:23 -0700 Subject: [PATCH 022/108] rename half variable to avoid shadowing CUDA global --- vtkm/exec/cellmetrics/TypeOfCellTriangle.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vtkm/exec/cellmetrics/TypeOfCellTriangle.h b/vtkm/exec/cellmetrics/TypeOfCellTriangle.h index 154c4d3d9..071ca95dd 100644 --- a/vtkm/exec/cellmetrics/TypeOfCellTriangle.h +++ b/vtkm/exec/cellmetrics/TypeOfCellTriangle.h @@ -164,9 +164,9 @@ VTKM_EXEC Scalar GetTriangleArea(const CollectionOfPoints& pts) { const Vector L0 = GetTriangleL0(pts); const Vector L1 = GetTriangleL1(pts); - const Scalar half(0.5); + const Scalar hhalf(0.5); const Scalar crossProductMagnitude = vtkm::Sqrt(vtkm::MagnitudeSquared(vtkm::Cross(L0, L1))); - const Scalar area = half * crossProductMagnitude; + const Scalar area = hhalf * crossProductMagnitude; return area; } From e6a2089d8e5d715cb53dbac9994249094e867703 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 18 Sep 2019 07:59:32 -0400 Subject: [PATCH 023/108] Require CMake 3.12+ for using OpenMP backend --- CMake/FindOpenMP.cmake | 539 --------------------------------- CMake/VTKmDeviceAdapters.cmake | 2 +- CMakeLists.txt | 1 - README.md | 2 +- 4 files changed, 2 insertions(+), 542 deletions(-) delete mode 100644 CMake/FindOpenMP.cmake diff --git a/CMake/FindOpenMP.cmake b/CMake/FindOpenMP.cmake deleted file mode 100644 index 11608ccde..000000000 --- a/CMake/FindOpenMP.cmake +++ /dev/null @@ -1,539 +0,0 @@ -##============================================================================ -## 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. -##============================================================================ - -#.rst: -# FindOpenMP -# ---------- -# -# Finds OpenMP support -# -# This module can be used to detect OpenMP support in a compiler. If -# the compiler supports OpenMP, the flags required to compile with -# OpenMP support are returned in variables for the different languages. -# The variables may be empty if the compiler does not need a special -# flag to support OpenMP. -# -# Variables -# ^^^^^^^^^ -# -# The module exposes the components ``C``, ``CXX``, and ``Fortran``. -# Each of these controls the various languages to search OpenMP support for. -# -# Depending on the enabled components the following variables will be set: -# -# ``OpenMP_FOUND`` -# Variable indicating that OpenMP flags for all requested languages have been found. -# If no components are specified, this is true if OpenMP settings for all enabled languages -# were detected. -# ``OpenMP_VERSION`` -# Minimal version of the OpenMP standard detected among the requested languages, -# or all enabled languages if no components were specified. -# -# This module will set the following variables per language in your -# project, where ```` is one of C, CXX, or Fortran: -# -# ``OpenMP__FOUND`` -# Variable indicating if OpenMP support for ```` was detected. -# ``OpenMP__FLAGS`` -# OpenMP compiler flags for ````, separated by spaces. -# -# For linking with OpenMP code written in ````, the following -# variables are provided: -# -# ``OpenMP__LIB_NAMES`` -# :ref:`;-list ` of libraries for OpenMP programs for ````. -# ``OpenMP__LIBRARY`` -# Location of the individual libraries needed for OpenMP support in ````. -# ``OpenMP__LIBRARIES`` -# A list of libraries needed to link with OpenMP code written in ````. -# -# Additionally, the module provides :prop_tgt:`IMPORTED` targets: -# -# ``OpenMP::OpenMP_`` -# Target for using OpenMP from ````. -# -# Specifically for Fortran, the module sets the following variables: -# -# ``OpenMP_Fortran_HAVE_OMPLIB_HEADER`` -# Boolean indicating if OpenMP is accessible through ``omp_lib.h``. -# ``OpenMP_Fortran_HAVE_OMPLIB_MODULE`` -# Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module. -# -# The module will also try to provide the OpenMP version variables: -# -# ``OpenMP__SPEC_DATE`` -# Date of the OpenMP specification implemented by the ```` compiler. -# ``OpenMP__VERSION_MAJOR`` -# Major version of OpenMP implemented by the ```` compiler. -# ``OpenMP__VERSION_MINOR`` -# Minor version of OpenMP implemented by the ```` compiler. -# ``OpenMP__VERSION`` -# OpenMP version implemented by the ```` compiler. -# -# The specification date is formatted as given in the OpenMP standard: -# ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of -# the OpenMP specification implemented by the ```` compiler. - -cmake_policy(PUSH) -cmake_policy(SET CMP0012 NEW) # if() recognizes numbers and booleans -cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced -cmake_policy(SET CMP0057 NEW) # if IN_LIST - -function(_OPENMP_FLAG_CANDIDATES LANG) - if(NOT OpenMP_${LANG}_FLAG) - unset(OpenMP_FLAG_CANDIDATES) - - set(OMP_FLAG_GNU "-fopenmp") - set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp") - set(OMP_FLAG_AppleClang "-Xclang -fopenmp") - set(OMP_FLAG_HP "+Oopenmp") - if(WIN32) - set(OMP_FLAG_Intel "-Qopenmp") - elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND - "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528") - set(OMP_FLAG_Intel "-openmp") - else() - set(OMP_FLAG_Intel "-qopenmp") - endif() - set(OMP_FLAG_MIPSpro "-mp") - set(OMP_FLAG_MSVC "-openmp") - set(OMP_FLAG_PathScale "-openmp") - set(OMP_FLAG_NAG "-openmp") - set(OMP_FLAG_Absoft "-openmp") - set(OMP_FLAG_PGI "-mp") - set(OMP_FLAG_Flang "-fopenmp") - set(OMP_FLAG_SunPro "-xopenmp") - set(OMP_FLAG_XL "-qsmp=omp") - # Cray compiler activate OpenMP with -h omp, which is enabled by default. - set(OMP_FLAG_Cray " " "-h omp") - - # If we know the correct flags, use those - if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}) - set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") - # Fall back to reasonable default tries otherwise - else() - set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ") - endif() - set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE) - else() - set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE) - endif() -endfunction() - -# sample openmp source code to test -set(OpenMP_C_CXX_TEST_SOURCE -" -#include -int main() { -#ifdef _OPENMP - int n = omp_get_max_threads(); - return 0; -#else - breaks_on_purpose -#endif -} -") - -# in Fortran, an implementation may provide an omp_lib.h header -# or omp_lib module, or both (OpenMP standard, section 3.1) -# Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2) -# Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code -# while not actually enabling OpenMP, building code sequentially -set(OpenMP_Fortran_TEST_SOURCE - " - program test - @OpenMP_Fortran_INCLUDE_LINE@ - !$ integer :: n - n = omp_get_num_threads() - end program test - " -) - -function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH) - set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP) - if("${LANG}" STREQUAL "C") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c") - file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}") - elseif("${LANG}" STREQUAL "CXX") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp") - file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}") - elseif("${LANG}" STREQUAL "Fortran") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90") - file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}") - configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY) - endif() - set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE) -endfunction() - -include(CMakeParseImplicitLinkInfo) - -function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) - _OPENMP_FLAG_CANDIDATES("${LANG}") - _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC) - - unset(OpenMP_VERBOSE_COMPILE_OPTIONS) - separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}") - foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS) - if(NOT _VERBOSE_OPTION MATCHES "^-Wl,") - list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION}) - endif() - endforeach() - - foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES) - set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}") - if(OpenMP_VERBOSE_COMPILE_OPTIONS) - string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}") - endif() - string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}") - try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" - LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT - ) - - if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) - set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE) - - if(CMAKE_${LANG}_VERBOSE_FLAG) - unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES) - unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS) - unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS) - unset(OpenMP_${LANG}_LOG_VAR) - - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") - - cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}" - OpenMP_${LANG}_IMPLICIT_LIBRARIES - OpenMP_${LANG}_IMPLICIT_LINK_DIRS - OpenMP_${LANG}_IMPLICIT_FWK_DIRS - OpenMP_${LANG}_LOG_VAR - "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}" - ) - - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n") - - unset(_OPENMP_LIB_NAMES) - foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES) - get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY) - get_filename_component(_OPENMP_IMPLICIT_LIB_NAME "${_OPENMP_IMPLICIT_LIB}" NAME) - get_filename_component(_OPENMP_IMPLICIT_LIB_PLAIN "${_OPENMP_IMPLICIT_LIB}" NAME_WE) - string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}") - string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}") - if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES - OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" - OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) ) - if(_OPENMP_IMPLICIT_LIB_DIR) - set(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_OPENMP_IMPLICIT_LIB}" CACHE FILEPATH - "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP") - else() - find_library(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY - NAMES "${_OPENMP_IMPLICIT_LIB_NAME}" - DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP" - HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS} - CMAKE_FIND_ROOT_PATH_BOTH - NO_DEFAULT_PATH - ) - endif() - mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY) - list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN}) - endif() - endforeach() - set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE) - else() - # We do not know how to extract implicit OpenMP libraries for this compiler. - # Assume that it handles them automatically, e.g. the Intel Compiler on - # Windows should put the dependency in its object files. - set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE) - endif() - break() - elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang" - AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0") - - # Check for separate OpenMP library on AppleClang 7+ - find_library(OpenMP_libomp_LIBRARY - NAMES omp gomp iomp5 - HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES} - ) - mark_as_advanced(OpenMP_libomp_LIBRARY) - - if(OpenMP_libomp_LIBRARY) - try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" - LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT - ) - if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) - set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE) - set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE) - break() - endif() - endif() - endif() - set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE) - set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE) - endforeach() - - unset(OpenMP_VERBOSE_COMPILE_OPTIONS) -endfunction() - -set(OpenMP_C_CXX_CHECK_VERSION_SOURCE -" -#include -#include -const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', - 'P', '-', 'd', 'a', 't', 'e', '[', - ('0' + ((_OPENMP/100000)%10)), - ('0' + ((_OPENMP/10000)%10)), - ('0' + ((_OPENMP/1000)%10)), - ('0' + ((_OPENMP/100)%10)), - ('0' + ((_OPENMP/10)%10)), - ('0' + ((_OPENMP/1)%10)), - ']', '\\0' }; -int main() -{ - puts(ompver_str); - return 0; -} -") - -set(OpenMP_Fortran_CHECK_VERSION_SOURCE -" - program omp_ver - @OpenMP_Fortran_INCLUDE_LINE@ - integer, parameter :: zero = ichar('0') - integer, parameter :: ompv = openmp_version - character, dimension(24), parameter :: ompver_str =& - (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',& - 'd', 'a', 't', 'e', '[',& - char(zero + mod(ompv/100000, 10)),& - char(zero + mod(ompv/10000, 10)),& - char(zero + mod(ompv/1000, 10)),& - char(zero + mod(ompv/100, 10)),& - char(zero + mod(ompv/10, 10)),& - char(zero + mod(ompv/1, 10)), ']' /) - print *, ompver_str - end program omp_ver -") - -function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE) - _OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC) - - set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin") - string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}") - try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}" - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" - COPY_FILE ${BIN_FILE}) - - if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}}) - file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date") - set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*") - if("${specstr}" MATCHES "${regex_spec_date}") - set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE) - endif() - endif() -endfunction() - -macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG) - set(OpenMP_SPEC_DATE_MAP - # Preview versions - "201611=5.0" # OpenMP 5.0 preview 1 - # Combined versions, 2.5 onwards - "201511=4.5" - "201307=4.0" - "201107=3.1" - "200805=3.0" - "200505=2.5" - # C/C++ version 2.0 - "200203=2.0" - # Fortran version 2.0 - "200011=2.0" - # Fortran version 1.1 - "199911=1.1" - # C/C++ version 1.0 (there's no 1.1 for C/C++) - "199810=1.0" - # Fortran version 1.0 - "199710=1.0" - ) - - if(OpenMP_${LANG}_SPEC_DATE) - string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}") - else() - set(_version_match "") - endif() - if(NOT _version_match STREQUAL "") - set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1}) - set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2}) - set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}") - else() - unset(OpenMP_${LANG}_VERSION_MAJOR) - unset(OpenMP_${LANG}_VERSION_MINOR) - unset(OpenMP_${LANG}_VERSION) - endif() - unset(_version_match) - unset(OpenMP_SPEC_DATE_MAP) -endmacro() - -foreach(LANG IN ITEMS C CXX) - if(CMAKE_${LANG}_COMPILER_LOADED) - if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND" - OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND") - _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK) - endif() - - set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}" - CACHE STRING "${LANG} compiler flags for OpenMP parallelization") - set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}" - CACHE STRING "${LANG} compiler libraries for OpenMP parallelization") - mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES) - endif() -endforeach() - -if(CMAKE_Fortran_COMPILER_LOADED) - if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND" - OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND" - OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE) - set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none") - _OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK) - if(OpenMP_Fortran_FLAGS_WORK) - set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "") - endif() - - set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}" - CACHE STRING "Fortran compiler flags for OpenMP parallelization") - set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}" - CACHE STRING "Fortran compiler libraries for OpenMP parallelization") - mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES) - endif() - - if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND" - OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND" - OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER) - set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'") - _OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK) - if(OpenMP_Fortran_FLAGS_WORK) - set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "") - endif() - - set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}" - CACHE STRING "Fortran compiler flags for OpenMP parallelization") - - set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}" - CACHE STRING "Fortran compiler libraries for OpenMP parallelization") - endif() - - if(OpenMP_Fortran_HAVE_OMPLIB_MODULE) - set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none") - else() - set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'") - endif() -endif() - -if(NOT OpenMP_FIND_COMPONENTS) - set(OpenMP_FINDLIST C CXX Fortran) -else() - set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS}) -endif() - -unset(_OpenMP_MIN_VERSION) - -include(FindPackageHandleStandardArgs) - -foreach(LANG IN LISTS OpenMP_FINDLIST) - if(CMAKE_${LANG}_COMPILER_LOADED) - if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS) - _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL) - set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE - INTERNAL "${LANG} compiler's OpenMP specification date") - _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}") - endif() - - set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY}) - set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED}) - set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION}) - set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT}) - - set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS) - if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND") - set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES) - else() - foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES) - list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY) - endforeach() - endif() - - find_package_handle_standard_args(OpenMP_${LANG} - REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS} - VERSION_VAR OpenMP_${LANG}_VERSION - ) - - if(OpenMP_${LANG}_FOUND) - if(DEFINED OpenMP_${LANG}_VERSION) - if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION) - set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION) - endif() - endif() - set(OpenMP_${LANG}_LIBRARIES "") - foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES) - list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}") - endforeach() - - if(NOT TARGET OpenMP::OpenMP_${LANG}) - add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED) - endif() - if(OpenMP_${LANG}_FLAGS) - separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}") - set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY - INTERFACE_COMPILE_OPTIONS "$<$:${_OpenMP_${LANG}_OPTIONS}>") - unset(_OpenMP_${LANG}_OPTIONS) - endif() - if(OpenMP_${LANG}_LIBRARIES) - set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY - INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}") - endif() - endif() - endif() -endforeach() - -unset(_OpenMP_REQ_VARS) -foreach(LANG IN ITEMS C CXX Fortran) - if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS) - list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND") - endif() -endforeach() - -find_package_handle_standard_args(OpenMP - REQUIRED_VARS ${_OpenMP_REQ_VARS} - VERSION_VAR ${_OpenMP_MIN_VERSION} - HANDLE_COMPONENTS) - -set(OPENMP_FOUND ${OpenMP_FOUND}) - -if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND) - if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE) - set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "") - endif() - if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER) - set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "") - endif() -endif() - -if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED )) - message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled") -endif() - -unset(OpenMP_C_CXX_TEST_SOURCE) -unset(OpenMP_Fortran_TEST_SOURCE) -unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE) -unset(OpenMP_Fortran_CHECK_VERSION_SOURCE) -unset(OpenMP_Fortran_INCLUDE_LINE) - -cmake_policy(POP) diff --git a/CMake/VTKmDeviceAdapters.cmake b/CMake/VTKmDeviceAdapters.cmake index 09f74f47a..ff0b25818 100644 --- a/CMake/VTKmDeviceAdapters.cmake +++ b/CMake/VTKmDeviceAdapters.cmake @@ -86,7 +86,7 @@ endif() if(VTKm_ENABLE_OPENMP AND NOT TARGET vtkm::openmp) - cmake_minimum_required(VERSION 3.9...3.15 FATAL_ERROR) + cmake_minimum_required(VERSION 3.12...3.15 FATAL_ERROR) find_package(OpenMP 4.0 REQUIRED COMPONENTS CXX QUIET) add_library(vtkm::openmp INTERFACE IMPORTED GLOBAL) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ea4f87c9..7695384d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -250,7 +250,6 @@ if(NOT VTKm_INSTALL_ONLY_LIBRARIES) ${VTKm_SOURCE_DIR}/CMake/FindTBB.cmake ${VTKm_SOURCE_DIR}/CMake/FindMPI.cmake ${VTKm_SOURCE_DIR}/CMake/FindOpenGL.cmake - ${VTKm_SOURCE_DIR}/CMake/FindOpenMP.cmake DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR} ) diff --git a/README.md b/README.md index 06fa004cf..06e133be2 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,8 @@ VTK-m Requires: + Intel 17.0.4+ + [CMake](http://www.cmake.org/download/) + CMake 3.8+ - + CMake 3.9+ (for OpenMP support) + CMake 3.11+ (for Visual Studio generator) + + CMake 3.12+ (for OpenMP support) + CMake 3.13+ (for CUDA support) Optional dependencies are: From f9d02b3742b74e3169b541fb25f5a08ee871e084 Mon Sep 17 00:00:00 2001 From: Hank Childs Date: Wed, 18 Sep 2019 08:32:21 -0700 Subject: [PATCH 024/108] remove file that should not have been checked in --- vtkm/filter/MeshQuality.h.hrc | 113 ---------------------------------- 1 file changed, 113 deletions(-) delete mode 100644 vtkm/filter/MeshQuality.h.hrc diff --git a/vtkm/filter/MeshQuality.h.hrc b/vtkm/filter/MeshQuality.h.hrc deleted file mode 100644 index 94032927b..000000000 --- a/vtkm/filter/MeshQuality.h.hrc +++ /dev/null @@ -1,113 +0,0 @@ -//============================================================================ -// 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_MeshQuality_h -#define vtk_m_filter_MeshQuality_h - -#include -#include -#include -#include - -namespace vtkm -{ -namespace filter -{ - -//Names of the available cell metrics, for use in -//the output dataset fields -static const std::string MetricNames[] = { "area", - "aspectGamma", - "aspectRatio", - "condition", - "diagonalRatio", - "jacobian", - "minAngle", - "maxAngle", - "oddy", - "relativeSize", - "scaledJacobian", - "shape", - "shear", - "skew", - "stretch", - "taper", - "volume", - "warpage" -}; - -//Different cell metrics available to use -enum class CellMetric -{ - AREA, - ASPECT_GAMMA, - ASPECT_RATIO, - CONDITION, - DIAGONAL_RATIO, - JACOBIAN, - MIN_ANGLE, - MAX_ANGLE, - ODDY, - RELATIVE_SIZE, - SCALED_JACOBIAN, - SHAPE, - SHEAR, - SKEW, - STRETCH, - TAPER, - VOLUME, - WARPAGE, - NUMBER_OF_CELL_METRICS, - EMPTY -}; - -/** \brief Computes the quality of an unstructured cell-based mesh. The quality is defined in terms of the - * summary statistics (frequency, mean, variance, min, max) of metrics computed over the mesh - * cells. One of several different metrics can be specified for a given cell type, and the mesh - * can consist of one or more different cell types. The resulting mesh quality is stored as one - * or more new fields in the output dataset of this filter, with a separate field for each cell type. - * Each field contains the metric summary statistics for the cell type. - * Summary statists with all 0 values imply that the specified metric does not support the cell type. - */ -class MeshQuality : public vtkm::filter::FilterCell -{ -public: - using SupportedTypes = vtkm::TypeListTagFieldVec3; - - VTKM_CONT MeshQuality(CellMetric); - - template - VTKM_CONT vtkm::cont::DataSet DoExecute( - const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle, StorageType>& points, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); - -private: - //A user-assigned cell metric per shape/cell type - CellMetric myMetric; -}; - -} // namespace filter -} // namespace vtkm - -#include - -#endif // vtk_m_filter_MeshQuality_h From 8520d70e0dc9cdfc7aa20ce8950f5adabccdf653 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 9 Sep 2019 09:39:23 -0400 Subject: [PATCH 025/108] Compile most frequently used VTK-m filters into a library VTK-m now provides the following filters with the default policy as part of the vtkm_filter library: - CellAverage - CleanGrid - ClipWithField - ClipWithImplicitFunction - Contour - ExternalFaces - ExtractStructured - PointAverage - Threshold - VectorMagnitude By building these as a library we hope to provide faster compile times for consumers of VTK-m when using common configurations. --- benchmarking/BenchmarkFilters.cxx | 19 ++- docs/changelog/provide-prebuilt-filters.md | 73 ++++++++++ examples/demo/CMakeLists.txt | 2 +- vtkm/cont/testing/UnitTestCellSetExtrude.cxx | 3 +- vtkm/filter/CMakeLists.txt | 28 ++-- vtkm/filter/CellAverage.cxx | 22 +++ vtkm/filter/CellAverage.h | 16 ++- vtkm/filter/CellAverage.hxx | 10 +- vtkm/filter/CleanGrid.cxx | 122 ++++++++++++++++ vtkm/filter/CleanGrid.h | 50 +++++-- vtkm/filter/CleanGrid.hxx | 130 +----------------- vtkm/filter/ClipWithField.cxx | 22 +++ vtkm/filter/ClipWithField.h | 39 ++++-- vtkm/filter/ClipWithField.hxx | 38 ----- vtkm/filter/ClipWithImplicitFunction.cxx | 22 +++ vtkm/filter/ClipWithImplicitFunction.h | 41 ++++-- vtkm/filter/ClipWithImplicitFunction.hxx | 37 +---- vtkm/filter/Contour.cxx | 75 ++++++++++ vtkm/filter/Contour.h | 54 ++++++-- vtkm/filter/Contour.hxx | 84 +---------- vtkm/filter/ExternalFaces.cxx | 71 ++++++++++ vtkm/filter/ExternalFaces.h | 42 +++++- vtkm/filter/ExternalFaces.hxx | 90 +----------- vtkm/filter/ExtractPoints.hxx | 20 +-- vtkm/filter/ExtractStructured.cxx | 34 +++++ vtkm/filter/ExtractStructured.h | 33 ++++- vtkm/filter/ExtractStructured.hxx | 40 ------ vtkm/filter/Filter.h | 13 ++ vtkm/filter/Filter.hxx | 4 +- vtkm/filter/FilterField.hxx | 6 +- vtkm/filter/GhostCellRemove.hxx | 2 +- vtkm/filter/Mask.h | 1 - vtkm/filter/MaskPoints.hxx | 20 +-- vtkm/filter/PointAverage.cxx | 22 +++ vtkm/filter/PointAverage.h | 16 ++- vtkm/filter/PointAverage.hxx | 9 +- vtkm/filter/Threshold.cxx | 21 +++ vtkm/filter/Threshold.h | 37 +++-- vtkm/filter/Threshold.hxx | 33 ----- vtkm/filter/ThresholdPoints.hxx | 17 +-- vtkm/filter/VectorMagnitude.cxx | 31 +++++ vtkm/filter/VectorMagnitude.h | 11 +- vtkm/filter/VectorMagnitude.hxx | 8 -- vtkm/filter/testing/UnitTestContourFilter.cxx | 1 + .../testing/UnitTestSplitSharpEdgesFilter.cxx | 4 +- vtkm/worklet/testing/CMakeLists.txt | 2 +- .../worklet/testing/UnitTestOrientNormals.cxx | 2 +- 47 files changed, 840 insertions(+), 637 deletions(-) create mode 100644 docs/changelog/provide-prebuilt-filters.md create mode 100644 vtkm/filter/CellAverage.cxx create mode 100644 vtkm/filter/CleanGrid.cxx create mode 100644 vtkm/filter/ClipWithField.cxx create mode 100644 vtkm/filter/ClipWithImplicitFunction.cxx create mode 100644 vtkm/filter/Contour.cxx create mode 100644 vtkm/filter/ExternalFaces.cxx create mode 100644 vtkm/filter/ExtractStructured.cxx create mode 100644 vtkm/filter/PointAverage.cxx create mode 100644 vtkm/filter/Threshold.cxx create mode 100644 vtkm/filter/VectorMagnitude.cxx diff --git a/benchmarking/BenchmarkFilters.cxx b/benchmarking/BenchmarkFilters.cxx index d0d37f8ee..dcf332bc8 100644 --- a/benchmarking/BenchmarkFilters.cxx +++ b/benchmarking/BenchmarkFilters.cxx @@ -142,7 +142,6 @@ using UnstructuredCellList = using AllCellList = vtkm::ListTagJoin; -using CoordinateList = vtkm::ListTagBase; class BenchmarkFilterPolicy : public vtkm::filter::PolicyBase { @@ -152,8 +151,6 @@ public: using StructuredCellSetList = StructuredCellList; using UnstructuredCellSetList = UnstructuredCellList; using AllCellSetList = AllCellList; - - using CoordinateTypeList = CoordinateList; }; // Class implementing all filter benchmarks: @@ -307,7 +304,7 @@ class BenchmarkFilters { Timer timer{ DeviceAdapter() }; timer.Start(); - auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy()); + auto result = this->Filter.Execute(InputDataSet); (void)result; return timer.GetElapsedTime(); } @@ -374,7 +371,7 @@ class BenchmarkFilters { Timer timer{ DeviceAdapter() }; timer.Start(); - auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy()); + auto result = this->Filter.Execute(InputDataSet); (void)result; return timer.GetElapsedTime(); } @@ -400,7 +397,7 @@ class BenchmarkFilters { Timer timer{ DeviceAdapter() }; timer.Start(); - auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy()); + auto result = this->Filter.Execute(InputDataSet); (void)result; return timer.GetElapsedTime(); } @@ -501,7 +498,7 @@ class BenchmarkFilters { Timer timer{ DeviceAdapter() }; timer.Start(); - auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy()); + auto result = this->Filter.Execute(InputDataSet); (void)result; return timer.GetElapsedTime(); } @@ -547,7 +544,7 @@ class BenchmarkFilters { Timer timer{ DeviceAdapter() }; timer.Start(); - auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy()); + auto result = this->Filter.Execute(InputDataSet); (void)result; return timer.GetElapsedTime(); } @@ -954,7 +951,7 @@ void CreateFields(bool needPointScalars, bool needCellScalars, bool needPointVec vtkm::filter::PointAverage avg; avg.SetActiveField(CellScalarsName, vtkm::cont::Field::Association::CELL_SET); avg.SetOutputFieldName("GeneratedPointScalars"); - auto outds = avg.Execute(InputDataSet, BenchmarkFilterPolicy()); + auto outds = avg.Execute(InputDataSet); InputDataSet.AddField( outds.GetField("GeneratedPointScalars", vtkm::cont::Field::Association::POINTS)); PointScalarsName = "GeneratedPointScalars"; @@ -977,7 +974,7 @@ void CreateFields(bool needPointScalars, bool needCellScalars, bool needPointVec vtkm::filter::VectorMagnitude mag; mag.SetActiveField(PointVectorsName, vtkm::cont::Field::Association::POINTS); mag.SetOutputFieldName("GeneratedPointScalars"); - auto outds = mag.Execute(InputDataSet, BenchmarkFilterPolicy()); + auto outds = mag.Execute(InputDataSet); InputDataSet.AddField( outds.GetField("GeneratedPointScalars", vtkm::cont::Field::Association::POINTS)); PointScalarsName = "GeneratedPointScalars"; @@ -999,7 +996,7 @@ void CreateFields(bool needPointScalars, bool needCellScalars, bool needPointVec vtkm::filter::CellAverage avg; avg.SetActiveField(PointScalarsName, vtkm::cont::Field::Association::POINTS); avg.SetOutputFieldName("GeneratedCellScalars"); - auto outds = avg.Execute(InputDataSet, BenchmarkFilterPolicy()); + auto outds = avg.Execute(InputDataSet); InputDataSet.AddField( outds.GetField("GeneratedCellScalars", vtkm::cont::Field::Association::CELL_SET)); CellScalarsName = "GeneratedCellScalars"; diff --git a/docs/changelog/provide-prebuilt-filters.md b/docs/changelog/provide-prebuilt-filters.md new file mode 100644 index 000000000..648b40ae5 --- /dev/null +++ b/docs/changelog/provide-prebuilt-filters.md @@ -0,0 +1,73 @@ +# Provide pre-built filters in the vtkm_filter library. + +VTK-m now provides the following pre built versions of +the following filters as part of the vtkm_filter library, +when executed with the default types. + - CellAverage + - CleanGrid + - ClipWithField + - ClipWithImplicitFunction + - Contour + - ExternalFaces + - ExtractStuctured + - PointAverage + - Threshold + - VectorMagnitude + +The decision on providing a subset of filters as a library +was based on balancing the resulting library size and cross domain +applicibaility of the filter. So the initial set of algorithms +have been selected by looking at what is commonly used by +current VTK-m consuming applications. + +By default types we mean that no explicit user policy has been +passed to the `Execute` method on these filters. For example +the following will use the pre-build `Threshold` and `CleanGrid` +filters: + +```cpp + vtkm::cont::DataSet input = ...; + + //convert input to an unstructured grid + vtkm::filter::CleanGrid clean; + auto cleaned = clean.Execute(input); + + vtkm::filter::Threshold threshold; + threshold.SetLowerThreshold(60.1); + threshold.SetUpperThreshold(60.1); + threshold.SetActiveField("pointvar"); + threshold.SetFieldsToPass("cellvar"); + auto output = threshold.Execute(cleaned); + ... +``` + +While the following, even though it is a subset of the default +policy will need to be compiled by the consuming library by +including the relevant `.hxx` files + +```cpp + #include + #include + + ... + struct CustomPolicy : vtkm::filter::PolicyBase + { + // Defaults are the same as PolicyDefault expect for the field types + using FieldTypeList = vtkm::ListTagBase; + }; + ... + + vtkm::cont::DataSet input = ...; + + //convert input to an unstructured grid + vtkm::filter::CleanGrid clean; + auto cleaned = clean.Execute(input, CustomPolicy{}); + + vtkm::filter::Threshold threshold; + threshold.SetLowerThreshold(60.1); + threshold.SetUpperThreshold(60.1); + threshold.SetActiveField("pointvar"); + threshold.SetFieldsToPass("cellvar"); + auto output = threshold.Execute(cleaned, CustomPolicy{}); + ... +``` diff --git a/examples/demo/CMakeLists.txt b/examples/demo/CMakeLists.txt index fcbb25ba1..6e2da170b 100644 --- a/examples/demo/CMakeLists.txt +++ b/examples/demo/CMakeLists.txt @@ -15,7 +15,7 @@ find_package(VTKm REQUIRED QUIET) if(TARGET vtkm_rendering) add_executable(Demo Demo.cxx) - target_link_libraries(Demo PRIVATE vtkm_rendering) + target_link_libraries(Demo PRIVATE vtkm_filter vtkm_rendering) vtkm_add_target_information(Demo DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS DEVICE_SOURCES Demo.cxx) diff --git a/vtkm/cont/testing/UnitTestCellSetExtrude.cxx b/vtkm/cont/testing/UnitTestCellSetExtrude.cxx index f53ae36e3..ea8e4c496 100644 --- a/vtkm/cont/testing/UnitTestCellSetExtrude.cxx +++ b/vtkm/cont/testing/UnitTestCellSetExtrude.cxx @@ -13,8 +13,9 @@ #include #include #include -#include + #include +#include #include namespace diff --git a/vtkm/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt index 815a10754..c1b6f6c5c 100644 --- a/vtkm/filter/CMakeLists.txt +++ b/vtkm/filter/CMakeLists.txt @@ -141,16 +141,26 @@ set(header_template_sources ZFPCompressor3D.hxx ZFPDecompressor3D.hxx ) +set(sources_device + CellAverage.cxx + CleanGrid.cxx + ClipWithField.cxx + ClipWithImplicitFunction.cxx + Contour.cxx + ExternalFaces.cxx + ExtractStructured.cxx + PointAverage.cxx + Threshold.cxx + VectorMagnitude.cxx +) -vtkm_declare_headers(${headers}) -vtkm_declare_headers(${header_template_sources}) - -# Create an interface library for vtkm_filter. At some point, this will be replaced with a real -# library that contains pre-built filters. That would be created with the vtkm_library CMake -# function (defined in VTKmWrappers.cmake). -add_library(vtkm_filter INTERFACE) -target_link_libraries(vtkm_filter INTERFACE vtkm_worklet) -install(TARGETS vtkm_filter EXPORT ${VTKm_EXPORT_NAME}) +vtkm_library( + NAME vtkm_filter + TEMPLATE_SOURCES ${header_template_sources} + HEADERS ${headers} + DEVICE_SOURCES ${sources_device} + ) +target_link_libraries(vtkm_filter PUBLIC vtkm_worklet) add_subdirectory(internal) diff --git a/vtkm/filter/CellAverage.cxx b/vtkm/filter/CellAverage.cxx new file mode 100644 index 000000000..8ccb4cc07 --- /dev/null +++ b/vtkm/filter/CellAverage.cxx @@ -0,0 +1,22 @@ +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_CellAverage_cxx + +#include +#include + +namespace vtkm +{ +namespace filter +{ +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(CellAverage); +} +} diff --git a/vtkm/filter/CellAverage.h b/vtkm/filter/CellAverage.h index 4780d005d..1b6725c29 100644 --- a/vtkm/filter/CellAverage.h +++ b/vtkm/filter/CellAverage.h @@ -11,6 +11,9 @@ #ifndef vtk_m_filter_CellAverage_h #define vtk_m_filter_CellAverage_h +#include + +#include #include #include @@ -25,24 +28,23 @@ namespace filter /// The method of transformation is based on averaging the data /// values of all points used by particular cell. /// -class CellAverage : public vtkm::filter::FilterCell +class VTKM_ALWAYS_EXPORT CellAverage : public vtkm::filter::FilterCell { public: - VTKM_CONT - CellAverage(); - template VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, const vtkm::cont::ArrayHandle& field, const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase policy); private: vtkm::worklet::CellAverage Worklet; }; + +#ifndef vtkm_filter_CellAverage_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(CellAverage); +#endif } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_CellAverage_h diff --git a/vtkm/filter/CellAverage.hxx b/vtkm/filter/CellAverage.hxx index a3d0c4c7a..b02c8c6b1 100644 --- a/vtkm/filter/CellAverage.hxx +++ b/vtkm/filter/CellAverage.hxx @@ -15,21 +15,13 @@ namespace vtkm { namespace filter { - -//----------------------------------------------------------------------------- -inline VTKM_CONT CellAverage::CellAverage() - : vtkm::filter::FilterCell() - , Worklet() -{ -} - //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet CellAverage::DoExecute( const vtkm::cont::DataSet& input, const vtkm::cont::ArrayHandle& inField, const vtkm::filter::FieldMetadata& fieldMetadata, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { if (!fieldMetadata.IsPointField()) { diff --git a/vtkm/filter/CleanGrid.cxx b/vtkm/filter/CleanGrid.cxx new file mode 100644 index 000000000..19448cfa8 --- /dev/null +++ b/vtkm/filter/CleanGrid.cxx @@ -0,0 +1,122 @@ + +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_CleanGrid_cxx +#include +#include + +namespace vtkm +{ +namespace filter +{ + +//----------------------------------------------------------------------------- +CleanGrid::CleanGrid() + : CompactPointFields(true) + , MergePoints(true) + , Tolerance(1.0e-6) + , ToleranceIsAbsolute(false) + , RemoveDegenerateCells(true) + , FastMerge(true) +{ +} + +//----------------------------------------------------------------------------- +vtkm::cont::DataSet CleanGrid::GenerateOutput(const vtkm::cont::DataSet& inData, + vtkm::cont::CellSetExplicit<>& outputCellSet) +{ + using VecId = std::size_t; + const VecId activeCoordIndex = static_cast(this->GetActiveCoordinateSystemIndex()); + const VecId numCoordSystems = static_cast(inData.GetNumberOfCoordinateSystems()); + + std::vector outputCoordinateSystems(numCoordSystems); + + // Start with a shallow copy of the coordinate systems + for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex) + { + outputCoordinateSystems[coordSystemIndex] = + inData.GetCoordinateSystem(static_cast(coordSystemIndex)); + } + + // Optionally adjust the cell set indices to remove all unused points + if (this->GetCompactPointFields()) + { + this->PointCompactor.FindPointsStart(); + this->PointCompactor.FindPoints(outputCellSet); + this->PointCompactor.FindPointsEnd(); + + outputCellSet = this->PointCompactor.MapCellSet(outputCellSet); + + for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex) + { + outputCoordinateSystems[coordSystemIndex] = + vtkm::cont::CoordinateSystem(outputCoordinateSystems[coordSystemIndex].GetName(), + this->PointCompactor.MapPointFieldDeep( + outputCoordinateSystems[coordSystemIndex].GetData())); + } + } + + // Optionally find and merge coincident points + if (this->GetMergePoints()) + { + vtkm::cont::CoordinateSystem activeCoordSystem = outputCoordinateSystems[activeCoordIndex]; + vtkm::Bounds bounds = activeCoordSystem.GetBounds(); + + vtkm::Float64 delta = this->GetTolerance(); + if (!this->GetToleranceIsAbsolute()) + { + delta *= + vtkm::Magnitude(vtkm::make_Vec(bounds.X.Length(), bounds.Y.Length(), bounds.Z.Length())); + } + + auto coordArray = activeCoordSystem.GetData(); + this->PointMerger.Run(delta, this->GetFastMerge(), bounds, coordArray); + activeCoordSystem = vtkm::cont::CoordinateSystem(activeCoordSystem.GetName(), coordArray); + + for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex) + { + if (coordSystemIndex == activeCoordIndex) + { + outputCoordinateSystems[coordSystemIndex] = activeCoordSystem; + } + else + { + outputCoordinateSystems[coordSystemIndex] = vtkm::cont::CoordinateSystem( + outputCoordinateSystems[coordSystemIndex].GetName(), + this->PointMerger.MapPointField(outputCoordinateSystems[coordSystemIndex].GetData())); + } + } + + outputCellSet = this->PointMerger.MapCellSet(outputCellSet); + } + + // Optionally remove degenerate cells + if (this->GetRemoveDegenerateCells()) + { + outputCellSet = this->CellCompactor.Run(outputCellSet); + } + + // Construct resulting data set with new cell sets + vtkm::cont::DataSet outData; + outData.SetCellSet(outputCellSet); + + // Pass the coordinate systems + for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex) + { + outData.AddCoordinateSystem(outputCoordinateSystems[coordSystemIndex]); + } + + return outData; +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(CleanGrid); +} +} diff --git a/vtkm/filter/CleanGrid.h b/vtkm/filter/CleanGrid.h index f02ab61f8..52922b467 100644 --- a/vtkm/filter/CleanGrid.h +++ b/vtkm/filter/CleanGrid.h @@ -10,6 +10,8 @@ #ifndef vtk_m_filter_CleanGrid_h #define vtk_m_filter_CleanGrid_h +#include + #include #include @@ -35,10 +37,10 @@ namespace filter /// \todo Add a feature to merge points that are coincident or within a /// tolerance. /// -class CleanGrid : public vtkm::filter::FilterDataSet +class VTKM_ALWAYS_EXPORT CleanGrid : public vtkm::filter::FilterDataSet { public: - VTKM_CONT + VTKM_FILTER_EXPORT CleanGrid(); /// When the CompactPointFields flag is true, the filter will identify any @@ -85,15 +87,41 @@ public: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData, vtkm::filter::PolicyBase policy); + template VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase); + vtkm::filter::PolicyBase) + { + if (fieldMeta.IsPointField() && (this->GetCompactPointFields() || this->GetMergePoints())) + { + vtkm::cont::ArrayHandle compactedArray; + if (this->GetCompactPointFields()) + { + compactedArray = this->PointCompactor.MapPointFieldDeep(input); + if (this->GetMergePoints()) + { + compactedArray = this->PointMerger.MapPointField(compactedArray); + } + } + else if (this->GetMergePoints()) + { + compactedArray = this->PointMerger.MapPointField(input); + } + result.AddField(fieldMeta.AsField(compactedArray)); + } + else if (fieldMeta.IsCellField() && this->GetRemoveDegenerateCells()) + { + result.AddField(fieldMeta.AsField(this->CellCompactor.ProcessCellField(input))); + } + else + { + result.AddField(fieldMeta.AsField(input)); + } - template - VTKM_CONT vtkm::cont::ArrayHandle MapPointField( - const vtkm::cont::ArrayHandle& inArray) const; + return true; + } private: bool CompactPointFields; @@ -103,13 +131,19 @@ private: bool RemoveDegenerateCells; bool FastMerge; + VTKM_FILTER_EXPORT vtkm::cont::DataSet GenerateOutput( + const vtkm::cont::DataSet& inData, + vtkm::cont::CellSetExplicit<>& outputCellSet); + vtkm::worklet::RemoveUnusedPoints PointCompactor; vtkm::worklet::RemoveDegenerateCells CellCompactor; vtkm::worklet::PointMerge PointMerger; }; + +#ifndef vtkm_filter_CleanGrid_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(CleanGrid); +#endif } } // namespace vtkm::filter -#include - #endif //vtk_m_filter_CleanGrid_h diff --git a/vtkm/filter/CleanGrid.hxx b/vtkm/filter/CleanGrid.hxx index ebc5ef5f1..1912d0282 100644 --- a/vtkm/filter/CleanGrid.hxx +++ b/vtkm/filter/CleanGrid.hxx @@ -20,24 +20,11 @@ namespace vtkm namespace filter { -inline VTKM_CONT CleanGrid::CleanGrid() - : CompactPointFields(true) - , MergePoints(true) - , Tolerance(1.0e-6) - , ToleranceIsAbsolute(false) - , RemoveDegenerateCells(true) - , FastMerge(true) -{ -} - template inline VTKM_CONT vtkm::cont::DataSet CleanGrid::DoExecute(const vtkm::cont::DataSet& inData, vtkm::filter::PolicyBase policy) { using CellSetType = vtkm::cont::CellSetExplicit<>; - using VecId = std::size_t; - - VecId activeCoordIndex = static_cast(this->GetActiveCoordinateSystemIndex()); CellSetType outputCellSet; // Do a deep copy of the cells to new CellSetExplicit structures @@ -78,122 +65,7 @@ inline VTKM_CONT vtkm::cont::DataSet CleanGrid::DoExecute(const vtkm::cont::Data deducedCellSet.ReleaseResourcesExecution(); } - - VecId numCoordSystems = static_cast(inData.GetNumberOfCoordinateSystems()); - std::vector outputCoordinateSystems(numCoordSystems); - - // Start with a shallow copy of the coordinate systems - for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex) - { - outputCoordinateSystems[coordSystemIndex] = - inData.GetCoordinateSystem(static_cast(coordSystemIndex)); - } - - // Optionally adjust the cell set indices to remove all unused points - if (this->GetCompactPointFields()) - { - this->PointCompactor.FindPointsStart(); - this->PointCompactor.FindPoints(outputCellSet); - this->PointCompactor.FindPointsEnd(); - - outputCellSet = this->PointCompactor.MapCellSet(outputCellSet); - - for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex) - { - outputCoordinateSystems[coordSystemIndex] = - vtkm::cont::CoordinateSystem(outputCoordinateSystems[coordSystemIndex].GetName(), - this->PointCompactor.MapPointFieldDeep( - outputCoordinateSystems[coordSystemIndex].GetData())); - } - } - - // Optionally find and merge coincident points - if (this->GetMergePoints()) - { - vtkm::cont::CoordinateSystem activeCoordSystem = outputCoordinateSystems[activeCoordIndex]; - vtkm::Bounds bounds = activeCoordSystem.GetBounds(); - - vtkm::Float64 delta = this->GetTolerance(); - if (!this->GetToleranceIsAbsolute()) - { - delta *= - vtkm::Magnitude(vtkm::make_Vec(bounds.X.Length(), bounds.Y.Length(), bounds.Z.Length())); - } - - auto coordArray = activeCoordSystem.GetData(); - this->PointMerger.Run(delta, this->GetFastMerge(), bounds, coordArray); - activeCoordSystem = vtkm::cont::CoordinateSystem(activeCoordSystem.GetName(), coordArray); - - for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex) - { - if (coordSystemIndex == activeCoordIndex) - { - outputCoordinateSystems[coordSystemIndex] = activeCoordSystem; - } - else - { - outputCoordinateSystems[coordSystemIndex] = vtkm::cont::CoordinateSystem( - outputCoordinateSystems[coordSystemIndex].GetName(), - this->PointMerger.MapPointField(outputCoordinateSystems[coordSystemIndex].GetData())); - } - } - - outputCellSet = this->PointMerger.MapCellSet(outputCellSet); - } - - // Optionally remove degenerate cells - if (this->GetRemoveDegenerateCells()) - { - outputCellSet = this->CellCompactor.Run(outputCellSet); - } - - // Construct resulting data set with new cell sets - vtkm::cont::DataSet outData; - outData.SetCellSet(outputCellSet); - - // Pass the coordinate systems - for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex) - { - outData.AddCoordinateSystem(outputCoordinateSystems[coordSystemIndex]); - } - - return outData; -} - -template -inline VTKM_CONT bool CleanGrid::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) -{ - if (fieldMeta.IsPointField() && (this->GetCompactPointFields() || this->GetMergePoints())) - { - vtkm::cont::ArrayHandle compactedArray; - if (this->GetCompactPointFields()) - { - compactedArray = this->PointCompactor.MapPointFieldDeep(input); - if (this->GetMergePoints()) - { - compactedArray = this->PointMerger.MapPointField(compactedArray); - } - } - else if (this->GetMergePoints()) - { - compactedArray = this->PointMerger.MapPointField(input); - } - result.AddField(fieldMeta.AsField(compactedArray)); - } - else if (fieldMeta.IsCellField() && this->GetRemoveDegenerateCells()) - { - result.AddField(fieldMeta.AsField(this->CellCompactor.ProcessCellField(input))); - } - else - { - result.AddField(fieldMeta.AsField(input)); - } - - return true; + return this->GenerateOutput(inData, outputCellSet); } } } diff --git a/vtkm/filter/ClipWithField.cxx b/vtkm/filter/ClipWithField.cxx new file mode 100644 index 000000000..8782beb2f --- /dev/null +++ b/vtkm/filter/ClipWithField.cxx @@ -0,0 +1,22 @@ +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_Clip_cxx + +#include +#include + +namespace vtkm +{ +namespace filter +{ +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ClipWithField); +} +} diff --git a/vtkm/filter/ClipWithField.h b/vtkm/filter/ClipWithField.h index a57880651..7c73fa6fe 100644 --- a/vtkm/filter/ClipWithField.h +++ b/vtkm/filter/ClipWithField.h @@ -11,6 +11,8 @@ #ifndef vtk_m_filter_ClipWithField_h #define vtk_m_filter_ClipWithField_h +#include + #include #include @@ -24,14 +26,11 @@ namespace filter /// value are considered outside, and will be discarded. All points that are greater /// are kept. /// The resulting geometry will not be water tight. -class ClipWithField : public vtkm::filter::FilterDataSetWithField +class VTKM_ALWAYS_EXPORT ClipWithField : public vtkm::filter::FilterDataSetWithField { public: using SupportedTypes = vtkm::TypeListTagScalarAll; - VTKM_CONT - ClipWithField(); - VTKM_CONT void SetClipValue(vtkm::Float64 value) { this->ClipValue = value; } @@ -53,16 +52,38 @@ public: VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + vtkm::filter::PolicyBase) + { + vtkm::cont::ArrayHandle output; + + if (fieldMeta.IsPointField()) + { + output = this->Worklet.ProcessPointField(input); + } + else if (fieldMeta.IsCellField()) + { + output = this->Worklet.ProcessCellField(input); + } + else + { + return false; + } + + //use the same meta data as the input so we get the same field name, etc. + result.AddField(fieldMeta.AsField(output)); + return true; + } private: - vtkm::Float64 ClipValue; + vtkm::Float64 ClipValue = 0; vtkm::worklet::Clip Worklet; - bool Invert; + bool Invert = false; }; + +#ifndef vtkm_filter_Clip_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(ClipWithField); +#endif } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_ClipWithField_h diff --git a/vtkm/filter/ClipWithField.hxx b/vtkm/filter/ClipWithField.hxx index 861a22efa..6f67a4411 100644 --- a/vtkm/filter/ClipWithField.hxx +++ b/vtkm/filter/ClipWithField.hxx @@ -18,16 +18,6 @@ namespace vtkm { namespace filter { - -//----------------------------------------------------------------------------- -inline VTKM_CONT ClipWithField::ClipWithField() - : vtkm::filter::FilterDataSetWithField() - , ClipValue(0) - , Worklet() - , Invert(false) -{ -} - //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet ClipWithField::DoExecute( @@ -60,33 +50,5 @@ inline VTKM_CONT vtkm::cont::DataSet ClipWithField::DoExecute( output.AddCoordinateSystem(outputCoords); return output; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ClipWithField::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) -{ - vtkm::cont::ArrayHandle output; - - if (fieldMeta.IsPointField()) - { - output = this->Worklet.ProcessPointField(input); - } - else if (fieldMeta.IsCellField()) - { - output = this->Worklet.ProcessCellField(input); - } - else - { - return false; - } - - //use the same meta data as the input so we get the same field name, etc. - result.AddField(fieldMeta.AsField(output)); - return true; -} } } // end namespace vtkm::filter diff --git a/vtkm/filter/ClipWithImplicitFunction.cxx b/vtkm/filter/ClipWithImplicitFunction.cxx new file mode 100644 index 000000000..8d8ad3e3e --- /dev/null +++ b/vtkm/filter/ClipWithImplicitFunction.cxx @@ -0,0 +1,22 @@ + +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_ClipWithImplicitFunction_cxx +#include +#include + +namespace vtkm +{ +namespace filter +{ +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ClipWithImplicitFunction); +} +} diff --git a/vtkm/filter/ClipWithImplicitFunction.h b/vtkm/filter/ClipWithImplicitFunction.h index 9d9114c04..359ccca7e 100644 --- a/vtkm/filter/ClipWithImplicitFunction.h +++ b/vtkm/filter/ClipWithImplicitFunction.h @@ -7,10 +7,11 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_ClipWithImplicitFunction_h #define vtk_m_filter_ClipWithImplicitFunction_h +#include + #include #include #include @@ -25,11 +26,10 @@ namespace filter /// Clip a dataset using a given implicit function value, such as vtkm::Sphere /// or vtkm::Frustum. /// The resulting geometry will not be water tight. -class ClipWithImplicitFunction : public vtkm::filter::FilterDataSet +class VTKM_ALWAYS_EXPORT ClipWithImplicitFunction + : public vtkm::filter::FilterDataSet { public: - ClipWithImplicitFunction(); - void SetImplicitFunction(const vtkm::cont::ImplicitFunctionHandle& func) { this->Function = func; @@ -41,7 +41,7 @@ public: template vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter. //This call is only valid after Execute has been called. @@ -49,16 +49,39 @@ public: bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase) + { + vtkm::cont::ArrayHandle output; + + if (fieldMeta.IsPointField()) + { + output = this->Worklet.ProcessPointField(input); + } + else if (fieldMeta.IsCellField()) + { + output = this->Worklet.ProcessCellField(input); + } + else + { + return false; + } + + //use the same meta data as the input so we get the same field name, etc. + result.AddField(fieldMeta.AsField(output)); + + return true; + } private: vtkm::cont::ImplicitFunctionHandle Function; vtkm::worklet::Clip Worklet; - bool Invert; + bool Invert = false; }; + +#ifndef vtkm_filter_ClipWithImplicitFunction_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(ClipWithImplicitFunction); +#endif } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_ClipWithImplicitFunction_h diff --git a/vtkm/filter/ClipWithImplicitFunction.hxx b/vtkm/filter/ClipWithImplicitFunction.hxx index 639b90ad6..a26e01bd8 100644 --- a/vtkm/filter/ClipWithImplicitFunction.hxx +++ b/vtkm/filter/ClipWithImplicitFunction.hxx @@ -17,16 +17,10 @@ namespace vtkm namespace filter { //----------------------------------------------------------------------------- - -ClipWithImplicitFunction::ClipWithImplicitFunction() - : Invert(false) -{ -} - template inline vtkm::cont::DataSet ClipWithImplicitFunction::DoExecute( const vtkm::cont::DataSet& input, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { //get the cells and coordinates of the dataset const vtkm::cont::DynamicCellSet& cells = input.GetCellSet(); @@ -48,34 +42,5 @@ inline vtkm::cont::DataSet ClipWithImplicitFunction::DoExecute( return output; } - -//----------------------------------------------------------------------------- -template -inline bool ClipWithImplicitFunction::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase&) -{ - vtkm::cont::ArrayHandle output; - - if (fieldMeta.IsPointField()) - { - output = this->Worklet.ProcessPointField(input); - } - else if (fieldMeta.IsCellField()) - { - output = this->Worklet.ProcessCellField(input); - } - else - { - return false; - } - - //use the same meta data as the input so we get the same field name, etc. - result.AddField(fieldMeta.AsField(output)); - - return true; -} } } // end namespace vtkm::filter diff --git a/vtkm/filter/Contour.cxx b/vtkm/filter/Contour.cxx new file mode 100644 index 000000000..d82fbf9a8 --- /dev/null +++ b/vtkm/filter/Contour.cxx @@ -0,0 +1,75 @@ +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_Contour_cxx +#include +#include + +namespace vtkm +{ +namespace filter +{ + +//----------------------------------------------------------------------------- +VTKM_FILTER_EXPORT Contour::Contour() + : vtkm::filter::FilterDataSetWithField() + , IsoValues() + , GenerateNormals(false) + , AddInterpolationEdgeIds(false) + , ComputeFastNormalsForStructured(false) + , ComputeFastNormalsForUnstructured(true) + , NormalArrayName("normals") + , InterpolationEdgeIdsArrayName("edgeIds") + , Worklet() +{ + // todo: keep an instance of marching cubes worklet as a member variable +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_EXPORT void Contour::SetNumberOfIsoValues(vtkm::Id num) +{ + if (num >= 0) + { + this->IsoValues.resize(static_cast(num)); + } +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_EXPORT vtkm::Id Contour::GetNumberOfIsoValues() const +{ + return static_cast(this->IsoValues.size()); +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_EXPORT void Contour::SetIsoValue(vtkm::Id index, vtkm::Float64 v) +{ + std::size_t i = static_cast(index); + if (i >= this->IsoValues.size()) + { + this->IsoValues.resize(i + 1); + } + this->IsoValues[i] = v; +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_EXPORT void Contour::SetIsoValues(const std::vector& values) +{ + this->IsoValues = values; +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_EXPORT vtkm::Float64 Contour::GetIsoValue(vtkm::Id index) const +{ + return this->IsoValues[static_cast(index)]; +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(Contour); +} +} diff --git a/vtkm/filter/Contour.h b/vtkm/filter/Contour.h index 75c144925..0ff3f2bd3 100644 --- a/vtkm/filter/Contour.h +++ b/vtkm/filter/Contour.h @@ -11,6 +11,8 @@ #ifndef vtk_m_filter_Contour_h #define vtk_m_filter_Contour_h +#include + #include #include @@ -25,30 +27,30 @@ namespace filter /// Multiple contour values must be specified to generate the isosurfaces. /// @warning /// This filter is currently only supports 3D volumes. -class Contour : public vtkm::filter::FilterDataSetWithField +class VTKM_ALWAYS_EXPORT Contour : public vtkm::filter::FilterDataSetWithField { public: using SupportedTypes = vtkm::ListTagBase; - VTKM_CONT + VTKM_FILTER_EXPORT Contour(); - VTKM_CONT + VTKM_FILTER_EXPORT void SetNumberOfIsoValues(vtkm::Id num); - VTKM_CONT + VTKM_FILTER_EXPORT vtkm::Id GetNumberOfIsoValues() const; - VTKM_CONT + VTKM_FILTER_EXPORT void SetIsoValue(vtkm::Float64 v) { this->SetIsoValue(0, v); } - VTKM_CONT + VTKM_FILTER_EXPORT void SetIsoValue(vtkm::Id index, vtkm::Float64); - VTKM_CONT + VTKM_FILTER_EXPORT void SetIsoValues(const std::vector& values); - VTKM_CONT + VTKM_FILTER_EXPORT vtkm::Float64 GetIsoValue(vtkm::Id index) const; /// Set/Get whether the points generated should be unique for every triangle @@ -104,10 +106,10 @@ public: const std::string& GetNormalArrayName() const { return this->NormalArrayName; } template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, + const vtkm::cont::ArrayHandle& field, + const vtkm::filter::FieldMetadata& fieldMeta, + vtkm::filter::PolicyBase policy); //Map a new field onto the resulting dataset after running the filter //this call is only valid @@ -115,7 +117,27 @@ public: VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase) + { + vtkm::cont::ArrayHandle fieldArray; + + if (fieldMeta.IsPointField()) + { + fieldArray = this->Worklet.ProcessPointField(input); + } + else if (fieldMeta.IsCellField()) + { + fieldArray = this->Worklet.ProcessCellField(input); + } + else + { + return false; + } + + //use the same meta data as the input so we get the same field name, etc. + result.AddField(fieldMeta.AsField(fieldArray)); + return true; + } private: std::vector IsoValues; @@ -127,9 +149,11 @@ private: std::string InterpolationEdgeIdsArrayName; vtkm::worklet::Contour Worklet; }; + +#ifndef vtkm_filter_Contour_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(Contour); +#endif } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_Contour_h diff --git a/vtkm/filter/Contour.hxx b/vtkm/filter/Contour.hxx index 177719fb6..19b082390 100644 --- a/vtkm/filter/Contour.hxx +++ b/vtkm/filter/Contour.hxx @@ -25,7 +25,7 @@ namespace { template -bool IsCellSetStructured(const vtkm::cont::DynamicCellSetBase& cellset) +inline bool IsCellSetStructured(const vtkm::cont::DynamicCellSetBase& cellset) { if (cellset.template IsType>() || cellset.template IsType>() || @@ -37,66 +37,13 @@ bool IsCellSetStructured(const vtkm::cont::DynamicCellSetBase& cell } } // anonymous namespace -//----------------------------------------------------------------------------- -inline VTKM_CONT Contour::Contour() - : vtkm::filter::FilterDataSetWithField() - , IsoValues() - , GenerateNormals(false) - , AddInterpolationEdgeIds(false) - , ComputeFastNormalsForStructured(false) - , ComputeFastNormalsForUnstructured(true) - , NormalArrayName("normals") - , InterpolationEdgeIdsArrayName("edgeIds") - , Worklet() -{ - // todo: keep an instance of marching cubes worklet as a member variable -} - -//----------------------------------------------------------------------------- -inline void Contour::SetNumberOfIsoValues(vtkm::Id num) -{ - if (num >= 0) - { - this->IsoValues.resize(static_cast(num)); - } -} - -//----------------------------------------------------------------------------- -inline vtkm::Id Contour::GetNumberOfIsoValues() const -{ - return static_cast(this->IsoValues.size()); -} - -//----------------------------------------------------------------------------- -inline void Contour::SetIsoValue(vtkm::Id index, vtkm::Float64 v) -{ - std::size_t i = static_cast(index); - if (i >= this->IsoValues.size()) - { - this->IsoValues.resize(i + 1); - } - this->IsoValues[i] = v; -} - -//----------------------------------------------------------------------------- -inline void Contour::SetIsoValues(const std::vector& values) -{ - this->IsoValues = values; -} - -//----------------------------------------------------------------------------- -inline vtkm::Float64 Contour::GetIsoValue(vtkm::Id index) const -{ - return this->IsoValues[static_cast(index)]; -} - //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet& input, const vtkm::cont::ArrayHandle& field, const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { if (fieldMeta.IsPointField() == false) { @@ -203,32 +150,5 @@ inline VTKM_CONT vtkm::cont::DataSet Contour::DoExecute( return output; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool Contour::DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase&) -{ - vtkm::cont::ArrayHandle fieldArray; - - if (fieldMeta.IsPointField()) - { - fieldArray = this->Worklet.ProcessPointField(input); - } - else if (fieldMeta.IsCellField()) - { - fieldArray = this->Worklet.ProcessCellField(input); - } - else - { - return false; - } - - //use the same meta data as the input so we get the same field name, etc. - result.AddField(fieldMeta.AsField(fieldArray)); - return true; -} } } // namespace vtkm::filter diff --git a/vtkm/filter/ExternalFaces.cxx b/vtkm/filter/ExternalFaces.cxx new file mode 100644 index 000000000..23f2d4b45 --- /dev/null +++ b/vtkm/filter/ExternalFaces.cxx @@ -0,0 +1,71 @@ + +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_ExternalFaces_cxx +#include +#include + +namespace vtkm +{ +namespace filter +{ + +//----------------------------------------------------------------------------- +ExternalFaces::ExternalFaces() + : vtkm::filter::FilterDataSet() + , CompactPoints(false) + , Worklet() +{ + this->SetPassPolyData(true); +} + +//----------------------------------------------------------------------------- +vtkm::cont::DataSet ExternalFaces::GenerateOutput(const vtkm::cont::DataSet& input, + vtkm::cont::CellSetExplicit<>& outCellSet) +{ + //This section of ExternalFaces is independent of any input so we can build it + //into the vtkm_filter library + + //3. Check the fields of the dataset to see what kinds of fields are present so + // we can free the cell mapping array if it won't be needed. + const vtkm::Id numFields = input.GetNumberOfFields(); + bool hasCellFields = false; + for (vtkm::Id fieldIdx = 0; fieldIdx < numFields && !hasCellFields; ++fieldIdx) + { + auto f = input.GetField(fieldIdx); + hasCellFields = f.IsFieldCell(); + } + + if (!hasCellFields) + { + this->Worklet.ReleaseCellMapArrays(); + } + + //4. create the output dataset + vtkm::cont::DataSet output; + output.SetCellSet(outCellSet); + output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); + + if (this->CompactPoints) + { + this->Compactor.SetCompactPointFields(true); + this->Compactor.SetMergePoints(false); + return this->Compactor.Execute(output, PolicyDefault{}); + } + else + { + return output; + } +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ExternalFaces); +} +} diff --git a/vtkm/filter/ExternalFaces.h b/vtkm/filter/ExternalFaces.h index 50a9b0925..9d0e0eb7f 100644 --- a/vtkm/filter/ExternalFaces.h +++ b/vtkm/filter/ExternalFaces.h @@ -11,6 +11,8 @@ #ifndef vtk_m_filter_ExternalFaces_h #define vtk_m_filter_ExternalFaces_h +#include + #include #include #include @@ -28,10 +30,10 @@ namespace filter /// @warning /// This filter is currently only supports propagation of point properties /// -class ExternalFaces : public vtkm::filter::FilterDataSet +class VTKM_ALWAYS_EXPORT ExternalFaces : public vtkm::filter::FilterDataSet { public: - VTKM_CONT + VTKM_FILTER_EXPORT ExternalFaces(); // When CompactPoints is set, instead of copying the points and point fields @@ -63,17 +65,45 @@ public: VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + vtkm::filter::PolicyBase policy) + { + if (fieldMeta.IsPointField()) + { + if (this->CompactPoints) + { + return this->Compactor.DoMapField(result, input, fieldMeta, policy); + } + else + { + result.AddField(fieldMeta.AsField(input)); + return true; + } + } + else if (fieldMeta.IsCellField()) + { + vtkm::cont::ArrayHandle fieldArray; + fieldArray = this->Worklet.ProcessCellField(input); + result.AddField(fieldMeta.AsField(fieldArray)); + return true; + } -public: + return false; + } + +private: bool CompactPoints; bool PassPolyData; + + VTKM_FILTER_EXPORT vtkm::cont::DataSet GenerateOutput(const vtkm::cont::DataSet& input, + vtkm::cont::CellSetExplicit<>& outCellSet); + vtkm::filter::CleanGrid Compactor; vtkm::worklet::ExternalFaces Worklet; }; +#ifndef vtkm_filter_ExternalFaces_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(ExternalFaces); +#endif } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_ExternalFaces_h diff --git a/vtkm/filter/ExternalFaces.hxx b/vtkm/filter/ExternalFaces.hxx index c694e6501..2f2d4147f 100644 --- a/vtkm/filter/ExternalFaces.hxx +++ b/vtkm/filter/ExternalFaces.hxx @@ -13,33 +13,6 @@ namespace vtkm namespace filter { -//----------------------------------------------------------------------------- -inline VTKM_CONT ExternalFaces::ExternalFaces() - : vtkm::filter::FilterDataSet() - , CompactPoints(false) - , Worklet() -{ - this->SetPassPolyData(true); -} - -namespace -{ - -template -struct CellSetExplicitPolicy : public BasePolicy -{ - using AllCellSetList = vtkm::cont::CellSetListTagExplicitDefault; -}; - -template -inline vtkm::filter::PolicyBase> GetCellSetExplicitPolicy( - const vtkm::filter::PolicyBase&) -{ - return vtkm::filter::PolicyBase>(); -} - -} // anonymous namespace - //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet ExternalFaces::DoExecute( @@ -64,68 +37,7 @@ inline VTKM_CONT vtkm::cont::DataSet ExternalFaces::DoExecute( this->Worklet.Run(vtkm::filter::ApplyPolicyCellSetUnstructured(cells, policy), outCellSet); } - //3. Check the fields of the dataset to see what kinds of fields are present so - // we can free the cell mapping array if it won't be needed. - const vtkm::Id numFields = input.GetNumberOfFields(); - bool hasCellFields = false; - for (vtkm::Id fieldIdx = 0; fieldIdx < numFields && !hasCellFields; ++fieldIdx) - { - auto f = input.GetField(fieldIdx); - hasCellFields = f.IsFieldCell(); - } - - if (!hasCellFields) - { - this->Worklet.ReleaseCellMapArrays(); - } - - //4. create the output dataset - vtkm::cont::DataSet output; - output.SetCellSet(outCellSet); - output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); - - if (this->CompactPoints) - { - this->Compactor.SetCompactPointFields(true); - this->Compactor.SetMergePoints(false); - return this->Compactor.DoExecute(output, GetCellSetExplicitPolicy(policy)); - } - else - { - return output; - } -} - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ExternalFaces::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy) -{ - if (fieldMeta.IsPointField()) - { - if (this->CompactPoints) - { - return this->Compactor.DoMapField(result, input, fieldMeta, policy); - } - else - { - result.AddField(fieldMeta.AsField(input)); - return true; - } - } - else if (fieldMeta.IsCellField()) - { - vtkm::cont::ArrayHandle fieldArray; - fieldArray = this->Worklet.ProcessCellField(input); - result.AddField(fieldMeta.AsField(fieldArray)); - return true; - } - - - return false; + return this->GenerateOutput(input, outCellSet); } } } diff --git a/vtkm/filter/ExtractPoints.hxx b/vtkm/filter/ExtractPoints.hxx index ab2d18cbd..ac873a5af 100644 --- a/vtkm/filter/ExtractPoints.hxx +++ b/vtkm/filter/ExtractPoints.hxx @@ -11,24 +11,6 @@ #include #include -namespace -{ - -// Needed to CompactPoints -template -struct CellSetSingleTypePolicy : public BasePolicy -{ - using AllCellSetList = vtkm::cont::CellSetListTagUnstructured; -}; - -template -inline vtkm::filter::PolicyBase> GetCellSetSingleTypePolicy( - const vtkm::filter::PolicyBase&) -{ - return vtkm::filter::PolicyBase>(); -} -} - namespace vtkm { namespace filter @@ -71,7 +53,7 @@ inline vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& i { this->Compactor.SetCompactPointFields(true); this->Compactor.SetMergePoints(false); - return this->Compactor.DoExecute(output, GetCellSetSingleTypePolicy(policy)); + return this->Compactor.Execute(output, PolicyDefault{}); } else { diff --git a/vtkm/filter/ExtractStructured.cxx b/vtkm/filter/ExtractStructured.cxx new file mode 100644 index 000000000..e522e6338 --- /dev/null +++ b/vtkm/filter/ExtractStructured.cxx @@ -0,0 +1,34 @@ +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_ExtractStructured_cxx +#include +#include + +namespace vtkm +{ +namespace filter +{ + +//----------------------------------------------------------------------------- +ExtractStructured::ExtractStructured() + : vtkm::filter::FilterDataSet() + , VOI(vtkm::RangeId3(0, -1, 0, -1, 0, -1)) + , SampleRate(vtkm::Id3(1, 1, 1)) + , IncludeBoundary(false) + , IncludeOffset(false) + , Worklet() +{ +} + + +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(ExtractStructured); +} +} diff --git a/vtkm/filter/ExtractStructured.h b/vtkm/filter/ExtractStructured.h index 78a81d30a..4ab0beca1 100644 --- a/vtkm/filter/ExtractStructured.h +++ b/vtkm/filter/ExtractStructured.h @@ -11,6 +11,8 @@ #ifndef vtk_m_filter_ExtractStructured_h #define vtk_m_filter_ExtractStructured_h +#include + #include #include @@ -34,10 +36,10 @@ namespace filter /// for image processing, subsampling large volumes to reduce data size, or /// extracting regions of a volume with interesting data. /// -class ExtractStructured : public vtkm::filter::FilterDataSet +class VTKM_ALWAYS_EXPORT ExtractStructured : public vtkm::filter::FilterDataSet { public: - VTKM_CONT + VTKM_FILTER_EXPORT ExtractStructured(); // Set the bounding box for the volume of interest @@ -90,7 +92,27 @@ public: VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + vtkm::filter::PolicyBase) + { + if (fieldMeta.IsPointField()) + { + vtkm::cont::ArrayHandle output = this->Worklet.ProcessPointField(input); + + result.AddField(fieldMeta.AsField(output)); + return true; + } + + // cell data must be scattered to the cells created per input cell + if (fieldMeta.IsCellField()) + { + vtkm::cont::ArrayHandle output = this->Worklet.ProcessCellField(input); + + result.AddField(fieldMeta.AsField(output)); + return true; + } + + return false; + } private: vtkm::RangeId3 VOI; @@ -99,9 +121,12 @@ private: bool IncludeOffset; vtkm::worklet::ExtractStructured Worklet; }; + +#ifndef vtkm_filter_ExtractStructured_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(ExtractStructured); +#endif } } // namespace vtkm::filter -#include #endif // vtk_m_filter_ExtractStructured_h diff --git a/vtkm/filter/ExtractStructured.hxx b/vtkm/filter/ExtractStructured.hxx index caf006594..cef8c513d 100644 --- a/vtkm/filter/ExtractStructured.hxx +++ b/vtkm/filter/ExtractStructured.hxx @@ -12,18 +12,6 @@ namespace vtkm { namespace filter { - -//----------------------------------------------------------------------------- -inline VTKM_CONT ExtractStructured::ExtractStructured() - : vtkm::filter::FilterDataSet() - , VOI(vtkm::RangeId3(0, -1, 0, -1, 0, -1)) - , SampleRate(vtkm::Id3(1, 1, 1)) - , IncludeBoundary(false) - , IncludeOffset(false) - , Worklet() -{ -} - //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet ExtractStructured::DoExecute( @@ -47,33 +35,5 @@ inline VTKM_CONT vtkm::cont::DataSet ExtractStructured::DoExecute( output.AddCoordinateSystem(outputCoordinates); return output; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool ExtractStructured::DoMapField( - vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) -{ - if (fieldMeta.IsPointField()) - { - vtkm::cont::ArrayHandle output = this->Worklet.ProcessPointField(input); - - result.AddField(fieldMeta.AsField(output)); - return true; - } - - // cell data must be scattered to the cells created per input cell - if (fieldMeta.IsCellField()) - { - vtkm::cont::ArrayHandle output = this->Worklet.ProcessCellField(input); - - result.AddField(fieldMeta.AsField(output)); - return true; - } - - return false; -} } } diff --git a/vtkm/filter/Filter.h b/vtkm/filter/Filter.h index 53d34c3c7..639defd6d 100644 --- a/vtkm/filter/Filter.h +++ b/vtkm/filter/Filter.h @@ -279,5 +279,18 @@ private: } } // namespace vtkm::filter +#define VTKM_FILTER_EXPORT_EXECUTE_METHOD_WITH_POLICY(Name, Policy) \ + extern template VTKM_FILTER_TEMPLATE_EXPORT vtkm::cont::PartitionedDataSet \ + vtkm::filter::Filter::Execute(vtkm::cont::PartitionedDataSet const&, \ + vtkm::filter::PolicyBase) +#define VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD_WITH_POLICY(Name, Policy) \ + template VTKM_FILTER_EXPORT vtkm::cont::PartitionedDataSet Filter::Execute( \ + vtkm::cont::PartitionedDataSet const&, vtkm::filter::PolicyBase) + +#define VTKM_FILTER_EXPORT_EXECUTE_METHOD(Name) \ + VTKM_FILTER_EXPORT_EXECUTE_METHOD_WITH_POLICY(Name, vtkm::filter::PolicyDefault) +#define VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(Name) \ + VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD_WITH_POLICY(Name, vtkm::filter::PolicyDefault) + #include #endif diff --git a/vtkm/filter/Filter.hxx b/vtkm/filter/Filter.hxx index e39a56137..49256157e 100644 --- a/vtkm/filter/Filter.hxx +++ b/vtkm/filter/Filter.hxx @@ -264,7 +264,7 @@ inline VTKM_CONT vtkm::cont::PartitionedDataSet Filter::Execute( //---------------------------------------------------------------------------- template template -inline VTKM_CONT vtkm::cont::DataSet Filter::Execute( +VTKM_CONT vtkm::cont::DataSet Filter::Execute( const vtkm::cont::DataSet& input, vtkm::filter::PolicyBase policy) { @@ -284,7 +284,7 @@ inline VTKM_CONT vtkm::cont::DataSet Filter::Execute( //---------------------------------------------------------------------------- template template -inline VTKM_CONT vtkm::cont::PartitionedDataSet Filter::Execute( +VTKM_CONT vtkm::cont::PartitionedDataSet Filter::Execute( const vtkm::cont::PartitionedDataSet& input, vtkm::filter::PolicyBase policy) { diff --git a/vtkm/filter/FilterField.hxx b/vtkm/filter/FilterField.hxx index 7b546c4a3..233aaa528 100644 --- a/vtkm/filter/FilterField.hxx +++ b/vtkm/filter/FilterField.hxx @@ -46,7 +46,7 @@ inline VTKM_CONT FilterField::~FilterField() //----------------------------------------------------------------------------- template template -inline VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( +VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( const vtkm::cont::DataSet& input, vtkm::filter::PolicyBase policy) { @@ -67,7 +67,7 @@ inline VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( //----------------------------------------------------------------------------- template template -inline VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( +VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( const vtkm::cont::DataSet& input, const vtkm::cont::Field& field, vtkm::filter::PolicyBase policy) @@ -89,7 +89,7 @@ inline VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( //----------------------------------------------------------------------------- template template -inline VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( +VTKM_CONT vtkm::cont::DataSet FilterField::PrepareForExecution( const vtkm::cont::DataSet& input, const vtkm::cont::CoordinateSystem& field, vtkm::filter::PolicyBase policy) diff --git a/vtkm/filter/GhostCellRemove.hxx b/vtkm/filter/GhostCellRemove.hxx index 9bdf144ca..aa47e088b 100644 --- a/vtkm/filter/GhostCellRemove.hxx +++ b/vtkm/filter/GhostCellRemove.hxx @@ -328,7 +328,7 @@ inline VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute( extract.SetFieldsToPass(this->GetActiveFieldName(), vtkm::filter::FieldSelection::MODE_EXCLUDE); - auto output = extract.Execute(input, vtkm::filter::GhostCellRemovePolicy()); + auto output = extract.Execute(input); return output; } } diff --git a/vtkm/filter/Mask.h b/vtkm/filter/Mask.h index 1b319e947..d3530edb8 100644 --- a/vtkm/filter/Mask.h +++ b/vtkm/filter/Mask.h @@ -11,7 +11,6 @@ #ifndef vtk_m_filter_Mask_h #define vtk_m_filter_Mask_h -#include #include #include diff --git a/vtkm/filter/MaskPoints.hxx b/vtkm/filter/MaskPoints.hxx index e355c5a3b..a47ef612d 100644 --- a/vtkm/filter/MaskPoints.hxx +++ b/vtkm/filter/MaskPoints.hxx @@ -8,24 +8,6 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -namespace -{ - -// Needed to CompactPoints -template -struct CellSetSingleTypePolicy : public BasePolicy -{ - using AllCellSetList = vtkm::cont::CellSetListTagUnstructured; -}; - -template -inline vtkm::filter::PolicyBase> GetCellSetSingleTypePolicy( - const vtkm::filter::PolicyBase&) -{ - return vtkm::filter::PolicyBase>(); -} -} - namespace vtkm { namespace filter @@ -64,7 +46,7 @@ inline VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute( { this->Compactor.SetCompactPointFields(true); this->Compactor.SetMergePoints(false); - return this->Compactor.DoExecute(output, GetCellSetSingleTypePolicy(policy)); + return this->Compactor.Execute(output, PolicyDefault{}); } else { diff --git a/vtkm/filter/PointAverage.cxx b/vtkm/filter/PointAverage.cxx new file mode 100644 index 000000000..32aab5f8b --- /dev/null +++ b/vtkm/filter/PointAverage.cxx @@ -0,0 +1,22 @@ +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_PointAverage_cxx + +#include +#include + +namespace vtkm +{ +namespace filter +{ +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(PointAverage); +} +} diff --git a/vtkm/filter/PointAverage.h b/vtkm/filter/PointAverage.h index 5148b5fd2..1ca33773a 100644 --- a/vtkm/filter/PointAverage.h +++ b/vtkm/filter/PointAverage.h @@ -11,6 +11,9 @@ #ifndef vtk_m_filter_PointAverage_h #define vtk_m_filter_PointAverage_h +#include + +#include #include #include @@ -24,24 +27,23 @@ namespace filter /// specified per cell) into point data (i.e., data specified at cell /// points). The method of transformation is based on averaging the data /// values of all cells using a particular point. -class PointAverage : public vtkm::filter::FilterCell +class VTKM_ALWAYS_EXPORT PointAverage : public vtkm::filter::FilterCell { public: - VTKM_CONT - PointAverage(); - template VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, const vtkm::cont::ArrayHandle& field, const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); + vtkm::filter::PolicyBase policy); private: vtkm::worklet::PointAverage Worklet; }; + +#ifndef vtkm_filter_PointAverage_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(PointAverage); +#endif } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_PointAverage_h diff --git a/vtkm/filter/PointAverage.hxx b/vtkm/filter/PointAverage.hxx index a4431aa7d..f61801293 100644 --- a/vtkm/filter/PointAverage.hxx +++ b/vtkm/filter/PointAverage.hxx @@ -16,20 +16,13 @@ namespace vtkm namespace filter { -//----------------------------------------------------------------------------- -inline VTKM_CONT PointAverage::PointAverage() - : vtkm::filter::FilterCell() - , Worklet() -{ -} - //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet PointAverage::DoExecute( const vtkm::cont::DataSet& input, const vtkm::cont::ArrayHandle& inField, const vtkm::filter::FieldMetadata& fieldMetadata, - const vtkm::filter::PolicyBase& policy) + vtkm::filter::PolicyBase policy) { if (!fieldMetadata.IsCellField()) { diff --git a/vtkm/filter/Threshold.cxx b/vtkm/filter/Threshold.cxx new file mode 100644 index 000000000..ece40846a --- /dev/null +++ b/vtkm/filter/Threshold.cxx @@ -0,0 +1,21 @@ +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_Threshold_cxx +#include +#include + +namespace vtkm +{ +namespace filter +{ +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(Threshold); +} +} diff --git a/vtkm/filter/Threshold.h b/vtkm/filter/Threshold.h index 73e46edfd..0b0d3573b 100644 --- a/vtkm/filter/Threshold.h +++ b/vtkm/filter/Threshold.h @@ -11,6 +11,8 @@ #ifndef vtk_m_filter_Threshold_h #define vtk_m_filter_Threshold_h +#include + #include #include @@ -28,14 +30,11 @@ namespace filter /// filter is an permutation of the input dataset. /// /// You can threshold either on point or cell fields -class Threshold : public vtkm::filter::FilterDataSetWithField +class VTKM_ALWAYS_EXPORT Threshold : public vtkm::filter::FilterDataSetWithField { public: using SupportedTypes = vtkm::TypeListTagScalarAll; - VTKM_CONT - Threshold(); - VTKM_CONT void SetLowerThreshold(vtkm::Float64 value) { this->LowerValue = value; } VTKM_CONT @@ -58,16 +57,36 @@ public: VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); + vtkm::filter::PolicyBase) + { + if (fieldMeta.IsPointField()) + { + //we copy the input handle to the result dataset, reusing the metadata + result.AddField(fieldMeta.AsField(input)); + return true; + } + else if (fieldMeta.IsCellField()) + { + vtkm::cont::ArrayHandle out = this->Worklet.ProcessCellField(input); + result.AddField(fieldMeta.AsField(out)); + return true; + } + else + { + return false; + } + } private: - double LowerValue; - double UpperValue; + double LowerValue = 0; + double UpperValue = 0; vtkm::worklet::Threshold Worklet; }; + +#ifndef vtkm_filter_Threshold_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(Threshold); +#endif } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_Threshold_h diff --git a/vtkm/filter/Threshold.hxx b/vtkm/filter/Threshold.hxx index 00b19d40e..e0ce26209 100644 --- a/vtkm/filter/Threshold.hxx +++ b/vtkm/filter/Threshold.hxx @@ -44,14 +44,6 @@ namespace vtkm namespace filter { -//----------------------------------------------------------------------------- -inline VTKM_CONT Threshold::Threshold() - : vtkm::filter::FilterDataSetWithField() - , LowerValue(0) - , UpperValue(0) -{ -} - //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet Threshold::DoExecute( @@ -72,30 +64,5 @@ inline VTKM_CONT vtkm::cont::DataSet Threshold::DoExecute( output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); return output; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool Threshold::DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase) -{ - if (fieldMeta.IsPointField()) - { - //we copy the input handle to the result dataset, reusing the metadata - result.AddField(fieldMeta.AsField(input)); - return true; - } - else if (fieldMeta.IsCellField()) - { - vtkm::cont::ArrayHandle out = this->Worklet.ProcessCellField(input); - result.AddField(fieldMeta.AsField(out)); - return true; - } - else - { - return false; - } -} } } diff --git a/vtkm/filter/ThresholdPoints.hxx b/vtkm/filter/ThresholdPoints.hxx index 8a76b02ec..e7670420f 100644 --- a/vtkm/filter/ThresholdPoints.hxx +++ b/vtkm/filter/ThresholdPoints.hxx @@ -12,21 +12,6 @@ namespace { - -// Needed to CompactPoints -template -struct CellSetSingleTypePolicy : public BasePolicy -{ - using AllCellSetList = vtkm::cont::CellSetListTagUnstructured; -}; - -template -inline vtkm::filter::PolicyBase> GetCellSetSingleTypePolicy( - const vtkm::filter::PolicyBase&) -{ - return vtkm::filter::PolicyBase>(); -} - // Predicate for values less than minimum class ValuesBelow { @@ -191,7 +176,7 @@ inline VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute( { this->Compactor.SetCompactPointFields(true); this->Compactor.SetMergePoints(true); - return this->Compactor.DoExecute(output, GetCellSetSingleTypePolicy(policy)); + return this->Compactor.Execute(output, PolicyDefault{}); } else { diff --git a/vtkm/filter/VectorMagnitude.cxx b/vtkm/filter/VectorMagnitude.cxx new file mode 100644 index 000000000..2f3c083a5 --- /dev/null +++ b/vtkm/filter/VectorMagnitude.cxx @@ -0,0 +1,31 @@ +//============================================================================ +// 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. +//============================================================================ +#define vtkm_filter_VectorMagnitude_cxx + +#include +#include + +namespace vtkm +{ +namespace filter +{ + +//----------------------------------------------------------------------------- +VectorMagnitude::VectorMagnitude() + : vtkm::filter::FilterField() + , Worklet() +{ + this->SetOutputFieldName("magnitude"); +} + +//----------------------------------------------------------------------------- +VTKM_FILTER_INSTANTIATE_EXECUTE_METHOD(VectorMagnitude); +} +} diff --git a/vtkm/filter/VectorMagnitude.h b/vtkm/filter/VectorMagnitude.h index 72d17fc7d..41dc3480b 100644 --- a/vtkm/filter/VectorMagnitude.h +++ b/vtkm/filter/VectorMagnitude.h @@ -11,6 +11,8 @@ #ifndef vtk_m_filter_VectorMagnitude_h #define vtk_m_filter_VectorMagnitude_h +#include + #include #include @@ -19,13 +21,13 @@ namespace vtkm namespace filter { -class VectorMagnitude : public vtkm::filter::FilterField +class VTKM_ALWAYS_EXPORT VectorMagnitude : public vtkm::filter::FilterField { public: //currently the VectorMagnitude filter only works on vector data. using SupportedTypes = vtkm::TypeListTagVecCommon; - VTKM_CONT + VTKM_FILTER_EXPORT VectorMagnitude(); template @@ -37,9 +39,10 @@ public: private: vtkm::worklet::Magnitude Worklet; }; +#ifndef vtkm_filter_VectorMagnitude_cxx +VTKM_FILTER_EXPORT_EXECUTE_METHOD(VectorMagnitude); +#endif } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_VectorMagnitude_h diff --git a/vtkm/filter/VectorMagnitude.hxx b/vtkm/filter/VectorMagnitude.hxx index 43708e86a..996a1b0c1 100644 --- a/vtkm/filter/VectorMagnitude.hxx +++ b/vtkm/filter/VectorMagnitude.hxx @@ -15,14 +15,6 @@ namespace vtkm namespace filter { -//----------------------------------------------------------------------------- -inline VTKM_CONT VectorMagnitude::VectorMagnitude() - : vtkm::filter::FilterField() - , Worklet() -{ - this->SetOutputFieldName("magnitude"); -} - //----------------------------------------------------------------------------- template inline VTKM_CONT vtkm::cont::DataSet VectorMagnitude::DoExecute( diff --git a/vtkm/filter/testing/UnitTestContourFilter.cxx b/vtkm/filter/testing/UnitTestContourFilter.cxx index 5548a3f28..62ec66160 100644 --- a/vtkm/filter/testing/UnitTestContourFilter.cxx +++ b/vtkm/filter/testing/UnitTestContourFilter.cxx @@ -18,6 +18,7 @@ #include #include +#include #include namespace vtkm_ut_mc_filter diff --git a/vtkm/filter/testing/UnitTestSplitSharpEdgesFilter.cxx b/vtkm/filter/testing/UnitTestSplitSharpEdgesFilter.cxx index 1d842c2c6..8e17e2fb2 100644 --- a/vtkm/filter/testing/UnitTestSplitSharpEdgesFilter.cxx +++ b/vtkm/filter/testing/UnitTestSplitSharpEdgesFilter.cxx @@ -244,12 +244,12 @@ void TestWithStructuredData() contour.SetGenerateNormals(true); contour.SetComputeFastNormalsForStructured(true); contour.SetNormalArrayName("normals"); - dataSet = contour.Execute(dataSet, SplitSharpTestPolicy{}); + dataSet = contour.Execute(dataSet); // Compute cell normals: vtkm::filter::CellAverage cellNormals; cellNormals.SetActiveField("normals", vtkm::cont::Field::Association::POINTS); - dataSet = cellNormals.Execute(dataSet, SplitSharpTestPolicy{}); + dataSet = cellNormals.Execute(dataSet); // Split sharp edges: std::cout << dataSet.GetNumberOfCells() << std::endl; diff --git a/vtkm/worklet/testing/CMakeLists.txt b/vtkm/worklet/testing/CMakeLists.txt index 1e6342d9e..3154df84c 100644 --- a/vtkm/worklet/testing/CMakeLists.txt +++ b/vtkm/worklet/testing/CMakeLists.txt @@ -89,7 +89,7 @@ set(unit_tests vtkm_unit_tests( SOURCES ${unit_tests} - LIBRARIES vtkm_worklet vtkm_source + LIBRARIES vtkm_source vtkm_worklet vtkm_filter ALL_BACKENDS ) if (TARGET vtkm::cuda) diff --git a/vtkm/worklet/testing/UnitTestOrientNormals.cxx b/vtkm/worklet/testing/UnitTestOrientNormals.cxx index 0ab38a96c..1e54f5da3 100644 --- a/vtkm/worklet/testing/UnitTestOrientNormals.cxx +++ b/vtkm/worklet/testing/UnitTestOrientNormals.cxx @@ -73,7 +73,7 @@ vtkm::cont::DataSet CreateDataSet(bool pointNormals, bool cellNormals) contour.SetIsoValue(192); contour.SetMergeDuplicatePoints(true); contour.SetGenerateNormals(false); - dataSet = contour.Execute(dataSet, TestPolicy{}); + dataSet = contour.Execute(dataSet); vtkm::filter::SurfaceNormals normals; normals.SetGeneratePointNormals(pointNormals); From a46a83cc2a6ab8da411f5c933548c68caf0937e1 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 18 Sep 2019 14:16:42 -0400 Subject: [PATCH 026/108] GCC 4.8 now correctly compiles ArrayHandleDecorator --- vtkm/cont/ArrayHandleDecorator.h | 73 +++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/vtkm/cont/ArrayHandleDecorator.h b/vtkm/cont/ArrayHandleDecorator.h index e923acfab..14a53ae61 100644 --- a/vtkm/cont/ArrayHandleDecorator.h +++ b/vtkm/cont/ArrayHandleDecorator.h @@ -20,6 +20,8 @@ #include #include +#include + #include #include @@ -67,9 +69,9 @@ public: VTKM_CONT ArrayPortalDecorator(FunctorType func, InverseFunctorType iFunc, vtkm::Id numValues) - : Functor{ func } - , InverseFunctor{ iFunc } - , NumberOfValues{ numValues } + : Functor(func) + , InverseFunctor(iFunc) + , NumberOfValues(numValues) { } @@ -349,8 +351,12 @@ struct DecoratorStorageTraits using ArrayTupleType = vtkmstd::tuple; - // size_t integral constants that index ArrayTs: +// size_t integral constants that index ArrayTs: +#if defined(VTKM_MSVC) && (_MSC_VER == 1900) using IndexList = brigand::make_sequence, sizeof...(ArrayTs)>; +#else + using IndexList = tao::seq::make_index_sequence; +#endif // Portal lists: // NOTE we have to pass the parameter pack here instead of using ArrayList @@ -429,6 +435,7 @@ struct DecoratorStorageTraits return { impl.CreateFunctor(portals...), impl.CreateInverseFunctor(portals...), numVals }; } +#if defined(VTKM_MSVC) && (_MSC_VER == 1900) // Portal construction methods. These actually create portals. template