//============================================================================ // 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_ArrayHandleXGCCoordinates_h #define vtk_m_cont_ArrayHandleXGCCoordinates_h #include #include #include #include namespace vtkm { namespace internal { template struct VTKM_ALWAYS_EXPORT ArrayPortalXGCCoordinates { using ValueType = vtkm::Vec; VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT ArrayPortalXGCCoordinates() : Portal() , NumberOfPointsPerPlane(0) , NumberOfPlanes(0) , NumberOfPlanesOwned(0) , PlaneStartId(0) , UseCylindrical(false){}; VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT ArrayPortalXGCCoordinates(const PortalType& p, vtkm::Id numOfPlanes, vtkm::Id numOfPlanesOwned, vtkm::Id planeStartId, bool cylindrical = false) : Portal(p) , NumberOfPlanes(numOfPlanes) , NumberOfPlanesOwned(numOfPlanesOwned) , PlaneStartId(planeStartId) , UseCylindrical(cylindrical) { this->NumberOfPointsPerPlane = this->Portal.GetNumberOfValues() / 2; } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return (this->NumberOfPointsPerPlane * static_cast(NumberOfPlanesOwned)); } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const { const vtkm::Id realIdx = ((index * 2) % this->Portal.GetNumberOfValues()) / 2; const vtkm::Id whichPlane = (index * 2) / this->Portal.GetNumberOfValues() + this->PlaneStartId; return this->Get(vtkm::Id2(realIdx, whichPlane)); } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT ValueType Get(vtkm::Id2 index) const { using CompType = typename ValueType::ComponentType; const vtkm::Id realIdx = (index[0] * 2); const vtkm::Id whichPlane = index[1]; const auto phi = static_cast(whichPlane * (vtkm::TwoPi() / this->NumberOfPlanes)); auto r = this->Portal.Get(realIdx); auto z = this->Portal.Get(realIdx + 1); if (this->UseCylindrical) { return ValueType(r, phi, z); } else { return ValueType(r * vtkm::Cos(phi), r * vtkm::Sin(phi), z); } } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT vtkm::Vec GetWedge(const exec::IndicesExtrude& index) const { using CompType = typename ValueType::ComponentType; vtkm::Vec result; for (int j = 0; j < 2; ++j) { const auto phi = static_cast(index.Planes[j] * (vtkm::TwoPi() / this->NumberOfPlanes)); for (int i = 0; i < 3; ++i) { const vtkm::Id realIdx = index.PointIds[j][i] * 2; auto r = this->Portal.Get(realIdx); auto z = this->Portal.Get(realIdx + 1); result[3 * j + i] = this->UseCylindrical ? ValueType(r, phi, z) : ValueType(r * vtkm::Cos(phi), r * vtkm::Sin(phi), z); } } return result; } private: PortalType Portal; vtkm::Id NumberOfPointsPerPlane; vtkm::Id NumberOfPlanes; vtkm::Id NumberOfPlanesOwned; vtkm::Id PlaneStartId; bool UseCylindrical; }; } } // namespace vtkm::internal namespace vtkm { namespace cont { struct VTKM_ALWAYS_EXPORT StorageTagXGCCoordinates { }; namespace internal { struct XGCCoordinatesMetaData { vtkm::Id NumberOfPlanes = 0; vtkm::Id NumberOfPlanesOwned = 0; vtkm::Id PlaneStartId = -1; bool UseCylindrical = false; XGCCoordinatesMetaData() = default; XGCCoordinatesMetaData(vtkm::Id numberOfPlanes, vtkm::Id numberOfPlanesOwned, vtkm::Id planeStartId, bool useCylindrical) : NumberOfPlanes(numberOfPlanes) , NumberOfPlanesOwned(numberOfPlanesOwned) , PlaneStartId(planeStartId) , UseCylindrical(useCylindrical) { } }; namespace detail { template class XGCCoordinatesStorageImpl { using SourceStorage = Storage; // only allow input AH to use StorageTagBasic using MetaData = XGCCoordinatesMetaData; static MetaData& GetMetaData(const std::vector& buffers) { return buffers[0].GetMetaData(); } // Used to skip the metadata buffer and return only actual data buffers VTKM_CONT static std::vector SourceBuffers( const std::vector& buffers) { return std::vector(buffers.begin() + 1, buffers.end()); } public: using ReadPortalType = vtkm::internal::ArrayPortalXGCCoordinates; VTKM_CONT static vtkm::Id GetNumberOfValues( const std::vector& buffers) { return GetNumberOfValuesPerPlane(buffers) * GetNumberOfPlanesOwned(buffers); } VTKM_CONT static vtkm::Id GetNumberOfValuesPerPlane( const std::vector& buffers) { return SourceStorage::GetNumberOfValues(SourceBuffers(buffers)) / 2; } VTKM_CONT static vtkm::Id GetNumberOfPlanes( const std::vector& buffers) { return GetMetaData(buffers).NumberOfPlanes; } VTKM_CONT static vtkm::Id GetNumberOfPlanesOwned( const std::vector& buffers) { return GetMetaData(buffers).NumberOfPlanesOwned; } VTKM_CONT static vtkm::Id GetPlaneStartId( const std::vector& buffers) { return GetMetaData(buffers).PlaneStartId; } VTKM_CONT static bool GetUseCylindrical(const std::vector& buffers) { return GetMetaData(buffers).UseCylindrical; } VTKM_CONT static ReadPortalType CreateReadPortal( const std::vector& buffers, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) { return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token), GetNumberOfPlanes(buffers), GetNumberOfPlanesOwned(buffers), GetPlaneStartId(buffers), GetUseCylindrical(buffers)); } VTKM_CONT static std::vector CreateBuffers( const vtkm::cont::ArrayHandle& array, vtkm::Id numberOfPlanes, vtkm::Id numberOfPlanesOwned, vtkm::Id planeStartId, bool useCylindrical) { return vtkm::cont::internal::CreateBuffers( MetaData(numberOfPlanes, numberOfPlanesOwned, planeStartId, useCylindrical), array); } VTKM_CONT static std::vector CreateBuffers() { return CreateBuffers(vtkm::cont::ArrayHandle{}, 0, 0, 0, false); } VTKM_CONT static vtkm::cont::ArrayHandle GetArrayHandle( const std::vector& buffers) { return vtkm::cont::ArrayHandle(SourceBuffers(buffers)); } }; } // namespace detail template <> class Storage : public detail::XGCCoordinatesStorageImpl { public: VTKM_STORAGE_NO_RESIZE; VTKM_STORAGE_NO_WRITE_PORTAL; }; template <> class Storage : public detail::XGCCoordinatesStorageImpl { public: VTKM_STORAGE_NO_RESIZE; VTKM_STORAGE_NO_WRITE_PORTAL; }; } // namespace internal template class VTKM_ALWAYS_EXPORT ArrayHandleXGCCoordinates : public vtkm::cont::ArrayHandle, vtkm::cont::StorageTagXGCCoordinates> { using AHandleType = vtkm::cont::ArrayHandle>; using OriginalType = vtkm::cont::ArrayHandle; public: VTKM_ARRAY_HANDLE_SUBCLASS( ArrayHandleXGCCoordinates, (ArrayHandleXGCCoordinates), (vtkm::cont::ArrayHandle, vtkm::cont::StorageTagXGCCoordinates>)); VTKM_CONT ArrayHandleXGCCoordinates(const OriginalType& array, vtkm::Id numberOfPlanes, vtkm::Id numberOfPlanesOwned, vtkm::Id planeStartId, bool cylindrical) : Superclass(StorageType::CreateBuffers(array, numberOfPlanes, numberOfPlanesOwned, planeStartId, cylindrical)) { } ~ArrayHandleXGCCoordinates() {} VTKM_CONT vtkm::Id GetNumberOfPlanes() const { return StorageType::GetNumberOfPlanes(this->GetBuffers()); } VTKM_CONT vtkm::Id GetNumberOfPlanesOwned() const { return StorageType::GetNumberOfPlanesOwned(this->GetBuffers()); } VTKM_CONT vtkm::Id GetPlaneStartId() const { return StorageType::GetPlaneStartId(this->GetBuffers()); } VTKM_CONT bool GetUseCylindrical() const { return StorageType::GetUseCylindrical(this->GetBuffers()); } VTKM_CONT vtkm::Id GetNumberOfPointsPerPlane() const { return StorageType::GetNumberOfValuesPerPlane(this->GetBuffers()); } VTKM_CONT OriginalType GetArray() const { return StorageType::GetArrayHandle(this->GetBuffers()); } }; template vtkm::cont::ArrayHandleXGCCoordinates make_ArrayHandleXGCCoordinates( const vtkm::cont::ArrayHandle& arrHandle, vtkm::Id numberOfPlanesOwned, bool cylindrical, vtkm::Id numberOfPlanes = -1, vtkm::Id planeStartId = 0) { if (numberOfPlanes == -1) { numberOfPlanes = numberOfPlanesOwned; } return ArrayHandleXGCCoordinates( arrHandle, numberOfPlanes, numberOfPlanesOwned, planeStartId, cylindrical); } template vtkm::cont::ArrayHandleXGCCoordinates make_ArrayHandleXGCCoordinates( const T* array, vtkm::Id length, vtkm::Id numberOfPlanesOwned, bool cylindrical, vtkm::Id numberOfPlanes = -1, vtkm::Id planeStartId = 0, vtkm::CopyFlag copy = vtkm::CopyFlag::Off) { if (numberOfPlanes == -1) { numberOfPlanes = numberOfPlanesOwned; } return ArrayHandleXGCCoordinates(vtkm::cont::make_ArrayHandle(array, length, copy), numberOfPlanes, numberOfPlanesOwned, planeStartId, cylindrical); } // if all planes belong to a single partition, then numberOfPlanes and planeStartId not needed template vtkm::cont::ArrayHandleXGCCoordinates make_ArrayHandleXGCCoordinates( const std::vector& array, vtkm::Id numberOfPlanesOwned, bool cylindrical, vtkm::Id numberOfPlanes = -1, vtkm::Id planeStartId = 0, vtkm::CopyFlag copy = vtkm::CopyFlag::Off) { if (!array.empty()) { if (numberOfPlanes == -1) { numberOfPlanes = numberOfPlanesOwned; } return make_ArrayHandleXGCCoordinates(&array.front(), static_cast(array.size()), numberOfPlanesOwned, cylindrical, numberOfPlanes, planeStartId, copy); } else { // Vector empty. Just return an empty array handle. return ArrayHandleXGCCoordinates(); } } } } // end namespace vtkm::cont //============================================================================= // Specializations of serialization related classes /// @cond SERIALIZATION namespace vtkm { namespace cont { template struct SerializableTypeString> { static VTKM_CONT const std::string& Get() { static std::string name = "AH_XGCCoordinates<" + SerializableTypeString::Get() + ">"; return name; } }; template struct SerializableTypeString< vtkm::cont::ArrayHandle, vtkm::cont::StorageTagXGCCoordinates>> : SerializableTypeString> { }; } } // vtkm::cont namespace mangled_diy_namespace { template struct Serialization> { private: using Type = vtkm::cont::ArrayHandleXGCCoordinates; using BaseType = vtkm::cont::ArrayHandle; public: static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj) { Type ah = obj; vtkmdiy::save(bb, ah.GetNumberOfPlanes()); vtkmdiy::save(bb, ah.GetNumberOfPlanesOwned()); vtkmdiy::save(bb, ah.GetPlaneStartId()); vtkmdiy::save(bb, ah.GetUseCylindrical()); vtkmdiy::save(bb, ah.GetArray()); } static VTKM_CONT void load(BinaryBuffer& bb, BaseType& ah) { vtkm::Id numberOfPlanes; vtkm::Id numberOfPlanesOwned; vtkm::Id planeStartId; bool isCylindrical; vtkm::cont::ArrayHandle array; vtkmdiy::load(bb, numberOfPlanes); vtkmdiy::load(bb, numberOfPlanesOwned); vtkmdiy::load(bb, planeStartId); vtkmdiy::load(bb, isCylindrical); vtkmdiy::load(bb, array); ah = vtkm::cont::make_ArrayHandleXGCCoordinates( array, numberOfPlanes, numberOfPlanesOwned, planeStartId, isCylindrical); } }; template struct Serialization, vtkm::cont::StorageTagXGCCoordinates>> : Serialization> { }; } // diy /// @endcond SERIALIZATION #endif