//============================================================================ // 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_cont_Field_h #define vtk_m_cont_Field_h #include #include #include #include #include #include #include namespace vtkm { namespace cont { namespace internal { class ComputeRange { public: ComputeRange(ArrayHandle& range) : Range(&range) { } template void operator()(const ArrayHandleType& input) const { *this->Range = vtkm::cont::ArrayRangeCompute(input); } private: vtkm::cont::ArrayHandle* Range; }; } // 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 AssociationEnum { ASSOC_ANY, ASSOC_WHOLE_MESH, ASSOC_POINTS, ASSOC_CELL_SET, ASSOC_LOGICAL_DIM }; /// constructors for points / whole mesh VTKM_CONT Field(std::string name, AssociationEnum association, const vtkm::cont::DynamicArrayHandle& data) : Name(name) , Association(association) , AssocCellSetName() , AssocLogicalDim(-1) , Data(data) , Range() , ModifiedFlag(true) { VTKM_ASSERT(this->Association == ASSOC_WHOLE_MESH || this->Association == ASSOC_POINTS); } template VTKM_CONT Field(std::string name, AssociationEnum association, const ArrayHandle& data) : Name(name) , Association(association) , AssocCellSetName() , AssocLogicalDim(-1) , Data(data) , Range() , ModifiedFlag(true) { VTKM_ASSERT((this->Association == ASSOC_WHOLE_MESH) || (this->Association == ASSOC_POINTS)); } /// constructors for cell set associations VTKM_CONT Field(std::string name, AssociationEnum association, const std::string& cellSetName, const vtkm::cont::DynamicArrayHandle& data) : Name(name) , Association(association) , AssocCellSetName(cellSetName) , AssocLogicalDim(-1) , Data(data) , Range() , ModifiedFlag(true) { VTKM_ASSERT(this->Association == ASSOC_CELL_SET); } template VTKM_CONT Field(std::string name, AssociationEnum association, const std::string& cellSetName, const vtkm::cont::ArrayHandle& data) : Name(name) , Association(association) , AssocCellSetName(cellSetName) , AssocLogicalDim(-1) , Data(data) , Range() , ModifiedFlag(true) { VTKM_ASSERT(this->Association == ASSOC_CELL_SET); } /// constructors for logical dimension associations VTKM_CONT Field(std::string name, AssociationEnum association, vtkm::IdComponent logicalDim, const vtkm::cont::DynamicArrayHandle& data) : Name(name) , Association(association) , AssocCellSetName() , AssocLogicalDim(logicalDim) , Data(data) , Range() , ModifiedFlag(true) { VTKM_ASSERT(this->Association == ASSOC_LOGICAL_DIM); } template VTKM_CONT Field(std::string name, AssociationEnum association, vtkm::IdComponent logicalDim, const vtkm::cont::ArrayHandle& data) : Name(name) , Association(association) , AssocLogicalDim(logicalDim) , Data(data) , Range() , ModifiedFlag(true) { VTKM_ASSERT(this->Association == ASSOC_LOGICAL_DIM); } VTKM_CONT Field() : Name() , Association(ASSOC_ANY) , AssocCellSetName() , AssocLogicalDim() , Data() , Range() , ModifiedFlag(true) { //Generate an empty field } VTKM_CONT virtual ~Field(); VTKM_CONT Field& operator=(const vtkm::cont::Field& src) = default; VTKM_CONT const std::string& GetName() const { return this->Name; } VTKM_CONT AssociationEnum GetAssociation() const { return this->Association; } VTKM_CONT std::string GetAssocCellSet() const { return this->AssocCellSetName; } VTKM_CONT vtkm::IdComponent GetAssocLogicalDim() const { return this->AssocLogicalDim; } template VTKM_CONT const vtkm::cont::ArrayHandle& GetRange(TypeList, StorageList) const { VTKM_IS_LIST_TAG(TypeList); VTKM_IS_LIST_TAG(StorageList); return this->GetRangeImpl(TypeList(), StorageList()); } VTKM_CONT const vtkm::cont::ArrayHandle& GetRange(VTKM_DEFAULT_TYPE_LIST_TAG, VTKM_DEFAULT_STORAGE_LIST_TAG) const; template VTKM_CONT void GetRange(vtkm::Range* range, TypeList, StorageList) const { VTKM_IS_LIST_TAG(TypeList); VTKM_IS_LIST_TAG(StorageList); this->GetRange(TypeList(), StorageList()); vtkm::Id length = this->Range.GetNumberOfValues(); for (vtkm::Id i = 0; i < length; ++i) { range[i] = this->Range.GetPortalConstControl().Get(i); } } template VTKM_CONT const vtkm::cont::ArrayHandle& GetRange(TypeList) const { VTKM_IS_LIST_TAG(TypeList); return this->GetRange(TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG()); } template VTKM_CONT void GetRange(vtkm::Range* range, TypeList) const { VTKM_IS_LIST_TAG(TypeList); this->GetRange(range, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG()); } VTKM_CONT const vtkm::cont::ArrayHandle& GetRange() const; VTKM_CONT void GetRange(vtkm::Range* range) const; const vtkm::cont::DynamicArrayHandle& GetData() const; vtkm::cont::DynamicArrayHandle& GetData(); template VTKM_CONT void SetData(const vtkm::cont::ArrayHandle& newdata) { this->Data = newdata; this->ModifiedFlag = true; } VTKM_CONT void SetData(const vtkm::cont::DynamicArrayHandle& newdata) { this->Data = newdata; this->ModifiedFlag = true; } template VTKM_CONT void CopyData(const T* ptr, vtkm::Id nvals) { this->Data = vtkm::cont::make_ArrayHandle(ptr, nvals, true); this->ModifiedFlag = true; } VTKM_CONT virtual void PrintSummary(std::ostream& out) const; private: std::string Name; ///< name of field AssociationEnum Association; std::string AssocCellSetName; ///< only populate if assoc is cells vtkm::IdComponent AssocLogicalDim; ///< only populate if assoc is logical dim vtkm::cont::DynamicArrayHandle Data; mutable vtkm::cont::ArrayHandle Range; mutable bool ModifiedFlag; template VTKM_CONT const vtkm::cont::ArrayHandle& GetRangeImpl(TypeList, StorageList) const { VTKM_IS_LIST_TAG(TypeList); VTKM_IS_LIST_TAG(StorageList); if (this->ModifiedFlag) { internal::ComputeRange computeRange(this->Range); this->Data.ResetTypeAndStorageLists(TypeList(), StorageList()).CastAndCall(computeRange); this->ModifiedFlag = false; } return this->Range; } }; template void CastAndCall(const vtkm::cont::Field& field, Functor&& f, Args&&... args) { field.GetData().CastAndCall(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::AssociationEnum association, const T* data, vtkm::Id size, vtkm::CopyFlag copy = vtkm::CopyFlag::Off) { return vtkm::cont::Field(name, association, vtkm::cont::make_ArrayHandle(data, size, copy)); } template vtkm::cont::Field make_Field(std::string name, Field::AssociationEnum association, const std::vector& data, vtkm::CopyFlag copy = vtkm::CopyFlag::Off) { return vtkm::cont::Field(name, association, vtkm::cont::make_ArrayHandle(data, copy)); } template vtkm::cont::Field make_Field(std::string name, Field::AssociationEnum association, const std::string& cellSetName, const T* data, vtkm::Id size, vtkm::CopyFlag copy = vtkm::CopyFlag::Off) { return vtkm::cont::Field( name, association, cellSetName, vtkm::cont::make_ArrayHandle(data, size, copy)); } template vtkm::cont::Field make_Field(std::string name, Field::AssociationEnum association, const std::string& cellSetName, const std::vector& data, vtkm::CopyFlag copy = vtkm::CopyFlag::Off) { return vtkm::cont::Field( name, association, cellSetName, vtkm::cont::make_ArrayHandle(data, copy)); } template vtkm::cont::Field make_Field(std::string name, Field::AssociationEnum association, vtkm::IdComponent logicalDim, const T* data, vtkm::Id size, vtkm::CopyFlag copy = vtkm::CopyFlag::Off) { return vtkm::cont::Field( name, association, logicalDim, vtkm::cont::make_ArrayHandle(data, size, copy)); } template vtkm::cont::Field make_Field(std::string name, Field::AssociationEnum association, vtkm::IdComponent logicalDim, const std::vector& data, vtkm::CopyFlag copy = vtkm::CopyFlag::Off) { return vtkm::cont::Field(name, association, logicalDim, vtkm::cont::make_ArrayHandle(data, copy)); } //@} namespace internal { template <> struct DynamicTransformTraits { using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall; }; } // namespace internal } // namespace cont } // namespace vtkm #endif //vtk_m_cont_Field_h