//============================================================================ // 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_gradient_GradientOutput_h #define vtk_m_worklet_gradient_GradientOutput_h #include #include #include #include #include #include #include #include namespace vtkm { namespace exec { template struct GradientScalarOutputExecutionObject { using ValueType = vtkm::Vec; using BaseTType = typename vtkm::VecTraits::BaseComponentType; struct PortalTypes { using HandleType = vtkm::cont::ArrayHandle; using ExecutionTypes = typename HandleType::template ExecutionTypes; using Portal = typename ExecutionTypes::Portal; }; GradientScalarOutputExecutionObject() = default; GradientScalarOutputExecutionObject(vtkm::cont::ArrayHandle gradient, vtkm::Id size, vtkm::cont::Token& token) { this->GradientPortal = gradient.PrepareForOutput(size, DeviceAdapter(), token); } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC void Set(vtkm::Id index, const vtkm::Vec& value) const { this->GradientPortal.Set(index, value); } typename PortalTypes::Portal GradientPortal; }; template struct GradientScalarOutput : public vtkm::cont::ExecutionObjectBase { using ValueType = vtkm::Vec; using BaseTType = typename vtkm::VecTraits::BaseComponentType; template VTKM_CONT vtkm::exec::GradientScalarOutputExecutionObject PrepareForExecution( Device, vtkm::cont::Token& token) const { return vtkm::exec::GradientScalarOutputExecutionObject( this->Gradient, this->Size, token); } GradientScalarOutput() = default; GradientScalarOutput(bool, bool, bool, bool, vtkm::cont::ArrayHandle& gradient, vtkm::cont::ArrayHandle&, vtkm::cont::ArrayHandle>&, vtkm::cont::ArrayHandle&, vtkm::Id size) : Size(size) , Gradient(gradient) { } vtkm::Id Size; vtkm::cont::ArrayHandle Gradient; }; template struct GradientVecOutputExecutionObject { using ValueType = vtkm::Vec; using BaseTType = typename vtkm::VecTraits::BaseComponentType; template struct PortalTypes { using HandleType = vtkm::cont::ArrayHandle; using ExecutionTypes = typename HandleType::template ExecutionTypes; using Portal = typename ExecutionTypes::Portal; }; GradientVecOutputExecutionObject() = default; GradientVecOutputExecutionObject(bool g, bool d, bool v, bool q, vtkm::cont::ArrayHandle gradient, vtkm::cont::ArrayHandle divergence, vtkm::cont::ArrayHandle> vorticity, vtkm::cont::ArrayHandle qcriterion, vtkm::Id size, vtkm::cont::Token& token) { this->SetGradient = g; this->SetDivergence = d; this->SetVorticity = v; this->SetQCriterion = q; DeviceAdapter device; if (g) { this->GradientPortal = gradient.PrepareForOutput(size, device, token); } if (d) { this->DivergencePortal = divergence.PrepareForOutput(size, device, token); } if (v) { this->VorticityPortal = vorticity.PrepareForOutput(size, device, token); } if (q) { this->QCriterionPortal = qcriterion.PrepareForOutput(size, device, token); } } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC void Set(vtkm::Id index, const vtkm::Vec& value) const { if (this->SetGradient) { this->GradientPortal.Set(index, value); } if (this->SetDivergence) { vtkm::worklet::gradient::Divergence divergence; BaseTType output; divergence(value, output); this->DivergencePortal.Set(index, output); } if (this->SetVorticity) { vtkm::worklet::gradient::Vorticity vorticity; T output; vorticity(value, output); this->VorticityPortal.Set(index, output); } if (this->SetQCriterion) { vtkm::worklet::gradient::QCriterion qc; BaseTType output; qc(value, output); this->QCriterionPortal.Set(index, output); } } bool SetGradient; bool SetDivergence; bool SetVorticity; bool SetQCriterion; typename PortalTypes::Portal GradientPortal; typename PortalTypes::Portal DivergencePortal; typename PortalTypes>::Portal VorticityPortal; typename PortalTypes::Portal QCriterionPortal; }; template struct GradientVecOutput : public vtkm::cont::ExecutionObjectBase { using ValueType = vtkm::Vec; using BaseTType = typename vtkm::VecTraits::BaseComponentType; template VTKM_CONT vtkm::exec::GradientVecOutputExecutionObject PrepareForExecution( Device, vtkm::cont::Token& token) const { return vtkm::exec::GradientVecOutputExecutionObject(this->G, this->D, this->V, this->Q, this->Gradient, this->Divergence, this->Vorticity, this->Qcriterion, this->Size, token); } GradientVecOutput() = default; GradientVecOutput(bool g, bool d, bool v, bool q, vtkm::cont::ArrayHandle& gradient, vtkm::cont::ArrayHandle& divergence, vtkm::cont::ArrayHandle>& vorticity, vtkm::cont::ArrayHandle& qcriterion, vtkm::Id size) { this->G = g; this->D = d; this->V = v; this->Q = q; this->Gradient = gradient; this->Divergence = divergence; this->Vorticity = vorticity; this->Qcriterion = qcriterion; this->Size = size; } bool G; bool D; bool V; bool Q; vtkm::cont::ArrayHandle Gradient; vtkm::cont::ArrayHandle Divergence; vtkm::cont::ArrayHandle> Vorticity; vtkm::cont::ArrayHandle Qcriterion; vtkm::Id Size; }; template struct GradientOutput : public GradientScalarOutput { using GradientScalarOutput::GradientScalarOutput; }; template <> struct GradientOutput : public GradientVecOutput { using GradientVecOutput::GradientVecOutput; }; template <> struct GradientOutput : public GradientVecOutput { using GradientVecOutput::GradientVecOutput; }; } } // namespace vtkm::exec namespace vtkm { namespace cont { namespace arg { /// \brief \c Transport tag for output arrays. /// /// \c TransportTagArrayOut is a tag used with the \c Transport class to /// transport \c ArrayHandle objects for output data. /// struct TransportTagGradientOut { }; template struct Transport { using ExecObjectFactoryType = vtkm::exec::GradientOutput; using ExecObjectType = decltype( std::declval().PrepareForExecution(Device(), std::declval())); template VTKM_CONT ExecObjectType operator()(ContObjectType object, const InputDomainType& vtkmNotUsed(inputDomain), vtkm::Id vtkmNotUsed(inputRange), vtkm::Id outputRange, vtkm::cont::Token& token) const { ExecObjectFactoryType ExecutionObjectFactory = object.PrepareForOutput(outputRange); return ExecutionObjectFactory.PrepareForExecution(Device(), token); } }; } } } // namespace vtkm::cont::arg namespace vtkm { namespace worklet { namespace gradient { struct GradientOutputs : vtkm::cont::arg::ControlSignatureTagBase { using TypeCheckTag = vtkm::cont::arg::TypeCheckTagExecObject; using TransportTag = vtkm::cont::arg::TransportTagGradientOut; using FetchTag = vtkm::exec::arg::FetchTagArrayDirectOut; }; } } } // namespace vtkm::worklet::gradient #endif