//============================================================================ // 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_cont_Field_h #define vtk_m_cont_Field_h #include #include #include #include #include #include namespace vtkm { namespace cont { namespace internal { // This implements deprecated functionality. struct ComputeRange { template void operator()(const ArrayHandleType& input, vtkm::cont::ArrayHandle& range) const { range = vtkm::cont::ArrayRangeCompute(input); } }; } // namespace internal /// A \c Field encapsulates an array on some piece of the mesh, such as /// the points, a cell set, a point logical dimension, or the whole mesh. /// class VTKM_CONT_EXPORT Field { public: enum struct Association { ANY, WHOLE_MESH, POINTS, CELL_SET }; VTKM_CONT Field() = default; VTKM_CONT Field(std::string name, Association association, const vtkm::cont::UnknownArrayHandle& data); template VTKM_CONT Field(std::string name, Association association, const vtkm::cont::ArrayHandle& data) : Field(name, association, vtkm::cont::UnknownArrayHandle{ data }) { } Field(const vtkm::cont::Field& src); Field(vtkm::cont::Field&& src) noexcept; VTKM_CONT virtual ~Field(); VTKM_CONT Field& operator=(const vtkm::cont::Field& src); VTKM_CONT Field& operator=(vtkm::cont::Field&& src) noexcept; VTKM_CONT const std::string& GetName() const { return this->Name; } VTKM_CONT Association GetAssociation() const { return this->FieldAssociation; } const vtkm::cont::VariantArrayHandle& GetData() const; vtkm::cont::VariantArrayHandle& GetData(); VTKM_CONT bool IsFieldCell() const { return this->FieldAssociation == Association::CELL_SET; } VTKM_CONT bool IsFieldPoint() const { return this->FieldAssociation == Association::POINTS; } VTKM_CONT bool IsFieldGlobal() const { return this->FieldAssociation == Association::WHOLE_MESH; } VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Data.GetNumberOfValues(); } template VTKM_DEPRECATED(1.6, "TypeList no longer supported in Field::GetRange.") VTKM_CONT void GetRange(vtkm::Range* range, TypeList) const { this->GetRangeImpl(TypeList()); const vtkm::Id length = this->Range.GetNumberOfValues(); auto portal = this->Range.ReadPortal(); for (vtkm::Id i = 0; i < length; ++i) { range[i] = portal.Get(i); } } template VTKM_DEPRECATED(1.6, "TypeList no longer supported in Field::GetRange.") VTKM_CONT const vtkm::cont::ArrayHandle& GetRange(TypeList) const { VTKM_STATIC_ASSERT_MSG((!std::is_same::value), "Cannot get the field range with vtkm::ListUniversal."); return this->GetRangeImpl(TypeList()); } VTKM_CONT const vtkm::cont::ArrayHandle& GetRange() const; VTKM_CONT void GetRange(vtkm::Range* range) const; template VTKM_CONT void SetData(const vtkm::cont::ArrayHandle& newdata) { this->Data = newdata; this->ModifiedFlag = true; } template VTKM_CONT void SetData(const vtkm::cont::VariantArrayHandleBase& newdata) { this->Data = vtkm::cont::VariantArrayHandle(newdata); this->ModifiedFlag = true; } VTKM_CONT virtual void PrintSummary(std::ostream& out) const; VTKM_CONT virtual void ReleaseResourcesExecution() { this->Data.ReleaseResourcesExecution(); this->Range.ReleaseResourcesExecution(); } private: std::string Name; ///< name of field Association FieldAssociation = Association::ANY; vtkm::cont::VariantArrayHandle Data; mutable vtkm::cont::ArrayHandle Range; mutable bool ModifiedFlag = true; // This implements deprecated functionality template VTKM_CONT const vtkm::cont::ArrayHandle& GetRangeImpl(TypeList) const { VTKM_IS_LIST(TypeList); VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "Field::GetRange"); if (this->ModifiedFlag) { vtkm::cont::CastAndCall( this->Data.ResetTypes(TypeList()), internal::ComputeRange{}, this->Range); this->ModifiedFlag = false; } return this->Range; } }; template void CastAndCall(const vtkm::cont::Field& field, Functor&& f, Args&&... args) { vtkm::cont::CastAndCall(field.GetData(), std::forward(f), std::forward(args)...); } //@{ /// Convenience functions to build fields from C style arrays and std::vector template vtkm::cont::Field make_Field(std::string name, Field::Association association, const T* data, vtkm::Id size, vtkm::CopyFlag copy) { return vtkm::cont::Field(name, association, vtkm::cont::make_ArrayHandle(data, size, copy)); } template VTKM_DEPRECATED(1.6, "Specify a vtkm::CopyFlag or use a move version of make_Field.") vtkm::cont::Field make_Field(std::string name, Field::Association association, const T* data, vtkm::Id size) { return make_Field(name, association, data, size, vtkm::CopyFlag::Off); } template vtkm::cont::Field make_Field(std::string name, Field::Association association, const std::vector& data, vtkm::CopyFlag copy) { return vtkm::cont::Field(name, association, vtkm::cont::make_ArrayHandle(data, copy)); } template VTKM_DEPRECATED(1.6, "Specify a vtkm::CopyFlag or use a move version of make_Field.") vtkm::cont::Field make_Field(std::string name, Field::Association association, const std::vector& data) { return make_Field(name, association, data, vtkm::CopyFlag::Off); } template vtkm::cont::Field make_FieldMove(std::string name, Field::Association association, std::vector&& data) { return vtkm::cont::Field(name, association, vtkm::cont::make_ArrayHandleMove(data)); } template vtkm::cont::Field make_Field(std::string name, Field::Association association, std::vector&& data, vtkm::CopyFlag vtkmNotUsed(copy)) { return make_FieldMove(name, association, std::move(data)); } template vtkm::cont::Field make_Field(std::string name, Field::Association association, std::initializer_list&& data) { return make_FieldMove(name, association, vtkm::cont::make_ArrayHandle(std::move(data))); } //@} /// Convenience function to build point fields from vtkm::cont::ArrayHandle template vtkm::cont::Field make_FieldPoint(std::string name, const vtkm::cont::ArrayHandle& data) { return vtkm::cont::Field(name, vtkm::cont::Field::Association::POINTS, data); } /// Convenience function to build point fields from vtkm::cont::VariantArrayHandle inline vtkm::cont::Field make_FieldPoint(std::string name, const vtkm::cont::VariantArrayHandle& data) { return vtkm::cont::Field(name, vtkm::cont::Field::Association::POINTS, data); } /// Convenience function to build cell fields from vtkm::cont::ArrayHandle template vtkm::cont::Field make_FieldCell(std::string name, const vtkm::cont::ArrayHandle& data) { return vtkm::cont::Field(name, vtkm::cont::Field::Association::CELL_SET, data); } /// Convenience function to build cell fields from vtkm::cont::VariantArrayHandle inline vtkm::cont::Field make_FieldCell(std::string name, const vtkm::cont::VariantArrayHandle& data) { return vtkm::cont::Field(name, vtkm::cont::Field::Association::CELL_SET, data); } } // namespace cont } // namespace vtkm namespace vtkm { namespace cont { namespace internal { template <> struct DynamicTransformTraits { using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall; }; } // namespace internal } // namespace cont } // namespace vtkm //============================================================================= // Specializations of serialization related classes /// @cond SERIALIZATION namespace vtkm { namespace cont { template struct SerializableField { SerializableField() = default; explicit SerializableField(const vtkm::cont::Field& field) : Field(field) { } vtkm::cont::Field Field; }; // Cannot directly serialize fields with a vtkm::ListUniversal type list since there has to // be a finite number of types to serialize. Do the best possible by serializing all basic // VTK-m types. template <> struct SerializableField : SerializableField { using SerializableField::SerializableField; }; } // namespace cont } // namespace vtkm namespace mangled_diy_namespace { template struct Serialization> { private: using Type = vtkm::cont::SerializableField; public: static VTKM_CONT void save(BinaryBuffer& bb, const Type& serializable) { const auto& field = serializable.Field; vtkmdiy::save(bb, field.GetName()); vtkmdiy::save(bb, static_cast(field.GetAssociation())); vtkmdiy::save(bb, field.GetData().ResetTypes(TypeList{})); } static VTKM_CONT void load(BinaryBuffer& bb, Type& serializable) { auto& field = serializable.Field; std::string name; vtkmdiy::load(bb, name); int assocVal = 0; vtkmdiy::load(bb, assocVal); auto assoc = static_cast(assocVal); vtkm::cont::VariantArrayHandleBase data; vtkmdiy::load(bb, data); field = vtkm::cont::Field(name, assoc, vtkm::cont::VariantArrayHandle(data)); } }; template <> struct Serialization> : Serialization> { }; } // diy /// @endcond SERIALIZATION #endif //vtk_m_cont_Field_h