diff --git a/vtkm/exec/BoundaryState.h b/vtkm/exec/BoundaryState.h new file mode 100644 index 000000000..aa7a1a950 --- /dev/null +++ b/vtkm/exec/BoundaryState.h @@ -0,0 +1,188 @@ +//============================================================================ +// 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_BoundaryState_h +#define vtk_m_exec_BoundaryState_h + +#include + +namespace vtkm +{ +namespace exec +{ + +/// \brief Provides a neighborhood's placement with respect to the mesh's boundary. +/// +/// \c BoundaryState provides functionality for \c WorkletPointNeighborhood algorithms and Fetch's +/// to determine if they are operating on a point near the boundary. It allows you to query about +/// overlaps of the neighborhood and the mesh boundary. It also helps convert local neighborhood +/// ids to the corresponding location in the mesh. +/// +/// This class is typically constructed using the \c Boundary tag in an \c ExecutionSignature. +/// There is little reason to construct this in user code. +/// +struct BoundaryState +{ + VTKM_EXEC + BoundaryState(const vtkm::Id3& ijk, const vtkm::Id3& pdims) + : IJK(ijk) + , PointDimensions(pdims) + { + } + + //@{ + /// Returns true if a neighborhood of the given radius is contained within the bounds of the cell + /// set in the X, Y, or Z direction. Returns false if the neighborhood extends ouside of the + /// boundary of the data in the X, Y, or Z direction. + /// + /// The radius defines the size of the neighborhood in terms of how far away it extends from the + /// center. So if there is a radius of 1, the neighborhood extends 1 unit away from the center in + /// each direction and is 3x3x3. If there is a radius of 2, the neighborhood extends 2 units for + /// a size of 5x5x5. + /// + VTKM_EXEC bool InXBoundary(vtkm::IdComponent radius) const + { + return (((this->IJK[0] - radius) >= 0) && ((this->IJK[0] + radius) < this->PointDimensions[0])); + } + VTKM_EXEC bool InYBoundary(vtkm::IdComponent radius) const + { + return (((this->IJK[1] - radius) >= 0) && ((this->IJK[1] + radius) < this->PointDimensions[1])); + } + VTKM_EXEC bool InZBoundary(vtkm::IdComponent radius) const + { + return (((this->IJK[2] - radius) >= 0) && ((this->IJK[2] + radius) < this->PointDimensions[2])); + } + //@} + + /// Returns true if a neighborhood of the given radius is contained within the bounds + /// of the cell set. Returns false if the neighborhood extends ouside of the boundary of the + /// data. + /// + /// The radius defines the size of the neighborhood in terms of how far away it extends from the + /// center. So if there is a radius of 1, the neighborhood extends 1 unit away from the center in + /// each direction and is 3x3x3. If there is a radius of 2, the neighborhood extends 2 units for + /// a size of 5x5x5. + /// + VTKM_EXEC bool InBoundary(vtkm::IdComponent radius) const + { + return this->InXBoundary(radius) && this->InYBoundary(radius) && this->InZBoundary(radius); + } + + /// Returns the minimum neighborhood indices that are within the bounds of the data. + /// + VTKM_EXEC vtkm::Vec MinNeighborIndices(vtkm::IdComponent radius) const + { + vtkm::Vec minIndices; + + for (vtkm::IdComponent component = 0; component < 3; ++component) + { + if (this->IJK[component] >= radius) + { + minIndices[component] = -radius; + } + else + { + minIndices[component] = static_cast(-this->IJK[component]); + } + } + + return minIndices; + } + + /// Returns the minimum neighborhood indices that are within the bounds of the data. + /// + VTKM_EXEC vtkm::Vec MaxNeighborIndices(vtkm::IdComponent radius) const + { + vtkm::Vec maxIndices; + + for (vtkm::IdComponent component = 0; component < 3; ++component) + { + if ((this->PointDimensions[component] - this->IJK[component] - 1) >= radius) + { + maxIndices[component] = radius; + } + else + { + maxIndices[component] = static_cast(this->PointDimensions[component] - + this->IJK[component] - 1); + } + } + + return maxIndices; + } + + //todo: This needs to work with BoundaryConstantValue + //todo: This needs to work with BoundaryPeroidic + + //@{ + /// Takes a local neighborhood index (in the ranges of -neighborhood size to neighborhood size) + /// and returns the ijk of the equivalent point in the full data set. If the given value is out + /// of range, the value is clamped to the nearest boundary. For example, if given a neighbor + /// index that is past the minimum x range of the data, the index at the minimum x boundary is + /// returned. + /// + VTKM_EXEC vtkm::Id3 NeighborIndexToFullIndexClamp( + const vtkm::Vec& neighbor) const + { + vtkm::Id3 fullIndex = this->IJK + neighbor; + + return vtkm::Max(vtkm::Id3(0), vtkm::Min(this->PointDimensions - vtkm::Id3(1), fullIndex)); + } + + VTKM_EXEC vtkm::Id3 NeighborIndexToFullIndexClamp(vtkm::IdComponent neighborI, + vtkm::IdComponent neighborJ, + vtkm::IdComponent neighborK) const + { + return this->NeighborIndexToFullIndexClamp(vtkm::make_Vec(neighborI, neighborJ, neighborK)); + } + //@} + + //todo: This needs to work with BoundaryConstantValue + //todo: This needs to work with BoundaryPeroidic + + //@{ + /// Takes a local neighborhood index (in the ranges of -neighborhood size to neighborhood size) + /// and returns the flat index of the equivalent point in the full data set. If the given value + /// is out of range, the value is clamped to the nearest boundary. For example, if given a + /// neighbor index that is past the minimum x range of the data, the index at the minimum x + /// boundary is returned. + /// + VTKM_EXEC vtkm::Id NeighborIndexToFlatIndexClamp( + const vtkm::Vec& neighbor) const + { + vtkm::Id3 full = this->NeighborIndexToFullIndexClamp(neighbor); + + return (full[2] * this->PointDimensions[1] + full[1]) * this->PointDimensions[0] + full[0]; + } + + VTKM_EXEC vtkm::Id NeighborIndexToFlatIndexClamp(vtkm::IdComponent neighborI, + vtkm::IdComponent neighborJ, + vtkm::IdComponent neighborK) const + { + return this->NeighborIndexToFlatIndexClamp(vtkm::make_Vec(neighborI, neighborJ, neighborK)); + } + //@} + + vtkm::Id3 IJK; + vtkm::Id3 PointDimensions; +}; +} +} // namespace vtkm::exec + +#endif //vtk_m_exec_BoundaryState_h diff --git a/vtkm/exec/CMakeLists.txt b/vtkm/exec/CMakeLists.txt index bc701d6a7..85a1a1c40 100644 --- a/vtkm/exec/CMakeLists.txt +++ b/vtkm/exec/CMakeLists.txt @@ -20,6 +20,7 @@ set(headers BoundingIntervalHierarchyExec.h + BoundaryState.h AtomicArrayExecutionObject.h CellDerivative.h CellEdge.h @@ -33,6 +34,7 @@ set(headers ConnectivityPermuted.h ConnectivityStructured.h ExecutionWholeArray.h + FieldNeighborhood.h FunctorBase.h Jacobian.h ParametricCoordinates.h diff --git a/vtkm/exec/FieldNeighborhood.h b/vtkm/exec/FieldNeighborhood.h new file mode 100644 index 000000000..5ba09b5ac --- /dev/null +++ b/vtkm/exec/FieldNeighborhood.h @@ -0,0 +1,107 @@ +//============================================================================ +// 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_FieldNeighborhood_h +#define vtk_m_exec_FieldNeighborhood_h + +#include +#include + +namespace vtkm +{ +namespace exec +{ + +/// \brief Retrieves field values from a neighborhood. +/// +/// \c FieldNeighborhood manages the retrieval of field values within the neighborhood of a +/// \c WorkletPointNeighborhood worklet. The \c Get methods take ijk indices relative to the +/// neighborhood (with 0, 0, 0 being the element visted) and return the field value at that part of +/// the neighborhood. If the requested neighborhood is outside the boundary, a different value will +/// be returned determined by the boundary behavior. A \c BoundaryState object can be used to +/// determine if the neighborhood extends beyond the boundary of the mesh. +/// +/// This class is typically constructued using the \c FieldInNeighborhood tag in an +/// \c ExecutionSignature. There is little reason to construct this in user code. +/// +/// \c FieldNeighborhood is templated on the array portal from which field values are retrieved. +/// +template +struct FieldNeighborhood +{ + VTKM_EXEC + FieldNeighborhood(const FieldPortalType& portal, const vtkm::exec::BoundaryState& boundary) + : Boundary(&boundary) + , Portal(portal) + { + } + + using ValueType = typename FieldPortalType::ValueType; + + VTKM_EXEC + ValueType Get(vtkm::IdComponent i, vtkm::IdComponent j, vtkm::IdComponent k) const + { + return Portal.Get(this->Boundary->NeighborIndexToFlatIndexClamp(i, j, k)); + } + + VTKM_EXEC + ValueType Get(const vtkm::Id3& ijk) const + { + return Portal.Get(this->Boundary->NeighborIndexToFlatIndexClamp(ijk)); + } + + vtkm::exec::BoundaryState const* const Boundary; + FieldPortalType Portal; +}; + +/// \brief Specialization of Neighborhood for ArrayPortalUniformPointCoordinates +/// We can use fast paths inside ArrayPortalUniformPointCoordinates to allow +/// for very fast computation of the coordinates reachable by the neighborhood +template <> +struct FieldNeighborhood +{ + VTKM_EXEC + FieldNeighborhood(const vtkm::internal::ArrayPortalUniformPointCoordinates& portal, + const vtkm::exec::BoundaryState& boundary) + : Boundary(&boundary) + , Portal(portal) + { + } + + using ValueType = vtkm::internal::ArrayPortalUniformPointCoordinates::ValueType; + + VTKM_EXEC + ValueType Get(vtkm::IdComponent i, vtkm::IdComponent j, vtkm::IdComponent k) const + { + return Portal.Get(this->Boundary->NeighborIndexToFullIndexClamp(i, j, k)); + } + + VTKM_EXEC + ValueType Get(const vtkm::Vec& ijk) const + { + return Portal.Get(this->Boundary->NeighborIndexToFullIndexClamp(ijk)); + } + + vtkm::exec::BoundaryState const* const Boundary; + vtkm::internal::ArrayPortalUniformPointCoordinates Portal; +}; +} +} // namespace vtkm::exec + +#endif //vtk_m_exec_FieldNeighborhood_h diff --git a/vtkm/exec/arg/OnBoundary.h b/vtkm/exec/arg/Boundary.h similarity index 86% rename from vtkm/exec/arg/OnBoundary.h rename to vtkm/exec/arg/Boundary.h index c25c08097..4200976ed 100644 --- a/vtkm/exec/arg/OnBoundary.h +++ b/vtkm/exec/arg/Boundary.h @@ -33,31 +33,31 @@ namespace arg /// \brief Aspect tag to use for getting if a point is a boundary point. /// -/// The \c AspectTagOnBoundary aspect tag causes the \c Fetch class to obtain +/// The \c AspectTagBoundary aspect tag causes the \c Fetch class to obtain /// if the point is on a boundary. /// -struct AspectTagOnBoundary +struct AspectTagBoundary { }; /// \brief The \c ExecutionSignature tag to get if executing on a boundary element /// -struct OnBoundary : vtkm::exec::arg::ExecutionSignatureTagBase +struct Boundary : vtkm::exec::arg::ExecutionSignatureTagBase { static constexpr vtkm::IdComponent INDEX = 1; - using AspectTag = vtkm::exec::arg::AspectTagOnBoundary; + using AspectTag = vtkm::exec::arg::AspectTagBoundary; }; template struct Fetch { using ThreadIndicesType = vtkm::exec::arg::ThreadIndicesPointNeighborhood; - using ValueType = vtkm::exec::arg::BoundaryState; + using ValueType = vtkm::exec::BoundaryState; VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC diff --git a/vtkm/exec/arg/CMakeLists.txt b/vtkm/exec/arg/CMakeLists.txt index 058f41487..a56690734 100644 --- a/vtkm/exec/arg/CMakeLists.txt +++ b/vtkm/exec/arg/CMakeLists.txt @@ -21,6 +21,7 @@ set(headers AspectTagDefault.h BasicArg.h + Boundary.h CellShape.h ExecutionSignatureTagBase.h Fetch.h @@ -36,7 +37,6 @@ set(headers FromCount.h FromIndices.h InputIndex.h - OnBoundary.h OutputIndex.h ThreadIndices.h ThreadIndicesBasic.h diff --git a/vtkm/exec/arg/FetchTagArrayNeighborhoodIn.h b/vtkm/exec/arg/FetchTagArrayNeighborhoodIn.h index 6e749cc8f..078a7645e 100644 --- a/vtkm/exec/arg/FetchTagArrayNeighborhoodIn.h +++ b/vtkm/exec/arg/FetchTagArrayNeighborhoodIn.h @@ -20,10 +20,10 @@ #ifndef vtk_m_exec_arg_FetchTagArrayNeighborhoodIn_h #define vtk_m_exec_arg_FetchTagArrayNeighborhoodIn_h +#include #include #include #include -#include namespace vtkm { @@ -41,66 +41,6 @@ struct FetchTagArrayNeighborhoodIn { }; -template -struct Neighborhood -{ - VTKM_EXEC - Neighborhood(const ExecObjectType& portal, const vtkm::exec::arg::BoundaryState& boundary) - : Boundary(&boundary) - , Portal(portal) - { - } - - using ValueType = typename ExecObjectType::ValueType; - - VTKM_EXEC - ValueType Get(vtkm::IdComponent i, vtkm::IdComponent j, vtkm::IdComponent k) const - { - return Portal.Get(this->Boundary->NeighborIndexToFlatIndexClamp(i, j, k)); - } - - VTKM_EXEC - ValueType Get(const vtkm::Id3& ijk) const - { - return Portal.Get(this->Boundary->NeighborIndexToFlatIndexClamp(ijk)); - } - - vtkm::exec::arg::BoundaryState const* const Boundary; - ExecObjectType Portal; -}; - -/// \brief Specialization of Neighborhood for ArrayPortalUniformPointCoordinates -/// We can use fast paths inside ArrayPortalUniformPointCoordinates to allow -/// for very fast computation of the coordinates reachable by the neighborhood -template <> -struct Neighborhood -{ - VTKM_EXEC - Neighborhood(const vtkm::internal::ArrayPortalUniformPointCoordinates& portal, - const vtkm::exec::arg::BoundaryState& boundary) - : Boundary(&boundary) - , Portal(portal) - { - } - - using ValueType = vtkm::internal::ArrayPortalUniformPointCoordinates::ValueType; - - VTKM_EXEC - ValueType Get(vtkm::IdComponent i, vtkm::IdComponent j, vtkm::IdComponent k) const - { - return Portal.Get(this->Boundary->NeighborIndexToFullIndexClamp(i, j, k)); - } - - VTKM_EXEC - ValueType Get(const vtkm::Vec& ijk) const - { - return Portal.Get(this->Boundary->NeighborIndexToFullIndexClamp(ijk)); - } - - vtkm::exec::arg::BoundaryState const* const Boundary; - vtkm::internal::ArrayPortalUniformPointCoordinates Portal; -}; - template struct Fetch { using ThreadIndicesType = vtkm::exec::arg::ThreadIndicesPointNeighborhood; - using ValueType = Neighborhood; + using ValueType = vtkm::exec::FieldNeighborhood; VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC diff --git a/vtkm/exec/arg/ThreadIndicesPointNeighborhood.h b/vtkm/exec/arg/ThreadIndicesPointNeighborhood.h index 7be9a1c08..a09ea1057 100644 --- a/vtkm/exec/arg/ThreadIndicesPointNeighborhood.h +++ b/vtkm/exec/arg/ThreadIndicesPointNeighborhood.h @@ -20,6 +20,7 @@ #ifndef vtk_m_exec_arg_ThreadIndicesPointNeighborhood_h #define vtk_m_exec_arg_ThreadIndicesPointNeighborhood_h +#include #include #include #include //for Deflate and Inflate @@ -33,157 +34,6 @@ namespace exec namespace arg { -/// \brief Provides information if the current point is a boundary point -/// Provides functionality for WorkletPointNeighborhood algorithms -/// and Fetch's to determine if they are operating on a boundary point - -//Todo we need to have this class handle different BoundaryTypes -struct BoundaryState -{ - VTKM_EXEC - BoundaryState(const vtkm::Id3& ijk, const vtkm::Id3& pdims) - : IJK(ijk) - , PointDimensions(pdims) - { - } - - //@{ - /// Returns true if a neighborhood of the given radius is contained within the bounds of the cell - /// set in the X, Y, or Z direction. Returns false if the neighborhood extends ouside of the - /// boundary of the data in the X, Y, or Z direction. - /// - /// The radius defines the size of the neighborhood in terms of how far away it extends from the - /// center. So if there is a radius of 1, the neighborhood extends 1 unit away from the center in - /// each direction and is 3x3x3. If there is a radius of 2, the neighborhood extends 2 units for - /// a size of 5x5x5. - /// - VTKM_EXEC bool InXBoundary(vtkm::IdComponent radius) const - { - return (((this->IJK[0] - radius) >= 0) && ((this->IJK[0] + radius) < this->PointDimensions[0])); - } - VTKM_EXEC bool InYBoundary(vtkm::IdComponent radius) const - { - return (((this->IJK[1] - radius) >= 0) && ((this->IJK[1] + radius) < this->PointDimensions[1])); - } - VTKM_EXEC bool InZBoundary(vtkm::IdComponent radius) const - { - return (((this->IJK[2] - radius) >= 0) && ((this->IJK[2] + radius) < this->PointDimensions[2])); - } - //@} - - /// Returns true if a neighborhood of the given radius is contained within the bounds - /// of the cell set. Returns false if the neighborhood extends ouside of the boundary of the - /// data. - /// - /// The radius defines the size of the neighborhood in terms of how far away it extends from the - /// center. So if there is a radius of 1, the neighborhood extends 1 unit away from the center in - /// each direction and is 3x3x3. If there is a radius of 2, the neighborhood extends 2 units for - /// a size of 5x5x5. - /// - VTKM_EXEC bool InBoundary(vtkm::IdComponent radius) const - { - return this->InXBoundary(radius) && this->InYBoundary(radius) && this->InZBoundary(radius); - } - - /// Returns the minimum neighborhood indices that are within the bounds of the data. - /// - VTKM_EXEC vtkm::Vec MinNeighborIndices(vtkm::IdComponent radius) const - { - vtkm::Vec minIndices; - - for (vtkm::IdComponent component = 0; component < 3; ++component) - { - if (this->IJK[component] >= radius) - { - minIndices[component] = -radius; - } - else - { - minIndices[component] = static_cast(-this->IJK[component]); - } - } - - return minIndices; - } - - /// Returns the minimum neighborhood indices that are within the bounds of the data. - /// - VTKM_EXEC vtkm::Vec MaxNeighborIndices(vtkm::IdComponent radius) const - { - vtkm::Vec maxIndices; - - for (vtkm::IdComponent component = 0; component < 3; ++component) - { - if ((this->PointDimensions[component] - this->IJK[component] - 1) >= radius) - { - maxIndices[component] = radius; - } - else - { - maxIndices[component] = static_cast(this->PointDimensions[component] - - this->IJK[component] - 1); - } - } - - return maxIndices; - } - - //todo: This needs to work with BoundaryConstantValue - //todo: This needs to work with BoundaryPeroidic - - //@{ - /// Takes a local neighborhood index (in the ranges of -neighborhood size to neighborhood size) - /// and returns the ijk of the equivalent point in the full data set. If the given value is out - /// of range, the value is clamped to the nearest boundary. For example, if given a neighbor - /// index that is past the minimum x range of the data, the index at the minimum x boundary is - /// returned. - /// - VTKM_EXEC vtkm::Id3 NeighborIndexToFullIndexClamp( - const vtkm::Vec& neighbor) const - { - vtkm::Id3 fullIndex = this->IJK + neighbor; - - return vtkm::Max(vtkm::Id3(0), vtkm::Min(this->PointDimensions - vtkm::Id3(1), fullIndex)); - } - - VTKM_EXEC vtkm::Id3 NeighborIndexToFullIndexClamp(vtkm::IdComponent neighborI, - vtkm::IdComponent neighborJ, - vtkm::IdComponent neighborK) const - { - return this->NeighborIndexToFullIndexClamp(vtkm::make_Vec(neighborI, neighborJ, neighborK)); - } - //@} - - //todo: This needs to work with BoundaryConstantValue - //todo: This needs to work with BoundaryPeroidic - - //@{ - /// Takes a local neighborhood index (in the ranges of -neighborhood size to neighborhood size) - /// and returns the flat index of the equivalent point in the full data set. If the given value - /// is out of range, the value is clamped to the nearest boundary. For example, if given a - /// neighbor index that is past the minimum x range of the data, the index at the minimum x - /// boundary is returned. - /// - VTKM_EXEC vtkm::Id NeighborIndexToFlatIndexClamp( - const vtkm::Vec& neighbor) const - { - vtkm::Id3 full = this->NeighborIndexToFullIndexClamp(neighbor); - - return (full[2] * this->PointDimensions[1] + full[1]) * this->PointDimensions[0] + full[0]; - } - - VTKM_EXEC vtkm::Id NeighborIndexToFlatIndexClamp(vtkm::IdComponent neighborI, - vtkm::IdComponent neighborJ, - vtkm::IdComponent neighborK) const - { - return this->NeighborIndexToFlatIndexClamp(vtkm::make_Vec(neighborI, neighborJ, neighborK)); - } - //@} - - vtkm::Id3 IJK; - vtkm::Id3 PointDimensions; -}; - namespace detail { /// Given a \c Vec of (semi) arbitrary size, inflate it to a vtkm::Id3 by padding with zeros. @@ -276,7 +126,7 @@ public: } VTKM_EXEC - const BoundaryState& GetBoundaryState() const { return this->State; } + const vtkm::exec::BoundaryState& GetBoundaryState() const { return this->State; } VTKM_EXEC vtkm::Id GetInputIndex() const { return this->InputIndex; } @@ -297,7 +147,7 @@ public: vtkm::Id GetGlobalIndex() const { return (this->GlobalThreadIndexOffset + this->OutputIndex); } private: - BoundaryState State; + vtkm::exec::BoundaryState State; vtkm::Id InputIndex; vtkm::Id OutputIndex; vtkm::IdComponent VisitIndex; diff --git a/vtkm/worklet/MarchingCubes.h b/vtkm/worklet/MarchingCubes.h index 4aa8d2f30..7d3057b43 100644 --- a/vtkm/worklet/MarchingCubes.h +++ b/vtkm/worklet/MarchingCubes.h @@ -604,8 +604,8 @@ public: const auto& boundary = tpn.GetBoundaryState(); auto pointPortal = pointCoordinates.GetPortal(); auto fieldPortal = inputField.GetPortal(); - vtkm::exec::arg::Neighborhood points(pointPortal, boundary); - vtkm::exec::arg::Neighborhood field(fieldPortal, boundary); + vtkm::exec::FieldNeighborhood points(pointPortal, boundary); + vtkm::exec::FieldNeighborhood field(fieldPortal, boundary); vtkm::worklet::gradient::StructuredPointGradient gradient; gradient(boundary, points, field, normal); @@ -688,8 +688,8 @@ public: const auto& boundary = tpn.GetBoundaryState(); auto pointPortal = pointCoordinates.GetPortal(); auto fieldPortal = inputField.GetPortal(); - vtkm::exec::arg::Neighborhood points(pointPortal, boundary); - vtkm::exec::arg::Neighborhood field(fieldPortal, boundary); + vtkm::exec::FieldNeighborhood points(pointPortal, boundary); + vtkm::exec::FieldNeighborhood field(fieldPortal, boundary); vtkm::worklet::gradient::StructuredPointGradient gradient; NormalType grad1; diff --git a/vtkm/worklet/WorkletPointNeighborhood.h b/vtkm/worklet/WorkletPointNeighborhood.h index 45be4bf24..bcb222403 100644 --- a/vtkm/worklet/WorkletPointNeighborhood.h +++ b/vtkm/worklet/WorkletPointNeighborhood.h @@ -39,12 +39,12 @@ #include #include +#include #include #include #include #include #include -#include #include #include @@ -87,16 +87,16 @@ public: template using Dispatcher = vtkm::worklet::DispatcherPointNeighborhood; - /// \brief The \c ExecutionSignature tag to get if you the current iteration is on a boundary. + /// \brief The \c ExecutionSignature tag to query if the current iteration is inside the boundary. /// - /// A \c WorkletPointNeighborhood operates by iterating over all points using - /// a defined neighborhood. This \c ExecutionSignature tag provides different - /// types when you are on or off a boundary, allowing for separate code paths - /// just for handling boundaries. + /// A \c WorkletPointNeighborhood operates by iterating over all points using a defined + /// neighborhood. This \c ExecutionSignature tag provides a \c BoundaryState object that allows + /// you to query whether the neighborhood of the current iteration is completely inside the + /// bounds of the mesh or if it extends beyond the mesh. This is important as when you are on a + /// boundary the neighboordhood will contain empty values for a certain subset of values, and in + /// this case the values returned will depend on the boundary behavior. /// - /// This is important as when you are on a boundary the neighboordhood will - /// contain empty values for a certain subset of values - struct OnBoundary : vtkm::exec::arg::OnBoundary + struct Boundary : vtkm::exec::arg::Boundary { }; diff --git a/vtkm/worklet/gradient/StructuredPointGradient.h b/vtkm/worklet/gradient/StructuredPointGradient.h index ebd44c7ca..026ba30c3 100644 --- a/vtkm/worklet/gradient/StructuredPointGradient.h +++ b/vtkm/worklet/gradient/StructuredPointGradient.h @@ -46,12 +46,12 @@ struct StructuredPointGradient : public vtkm::worklet::WorkletPointNeighborhood FieldInNeighborhood>, GradientOutputs outputFields); - using ExecutionSignature = void(OnBoundary, _2, _3, _4); + using ExecutionSignature = void(Boundary, _2, _3, _4); using InputDomain = _1; template - VTKM_EXEC void operator()(const vtkm::exec::arg::BoundaryState& boundary, + VTKM_EXEC void operator()(const vtkm::exec::BoundaryState& boundary, const PointsIn& inputPoints, const FieldIn& inputField, GradientOutType& outputGradient) const @@ -77,8 +77,8 @@ struct StructuredPointGradient : public vtkm::worklet::WorkletPointNeighborhood } template - VTKM_EXEC void operator()(const vtkm::exec::arg::BoundaryState& boundary, - const vtkm::exec::arg::Neighborhood< + VTKM_EXEC void operator()(const vtkm::exec::BoundaryState& boundary, + const vtkm::exec::FieldNeighborhood< vtkm::internal::ArrayPortalUniformPointCoordinates>& inputPoints, const FieldIn& inputField, GradientOutType& outputGradient) const @@ -87,7 +87,7 @@ struct StructuredPointGradient : public vtkm::worklet::WorkletPointNeighborhood //performance by not doing the Jacobian, but instead do an image gradient //using central differences using PointsIn = - vtkm::exec::arg::Neighborhood; + vtkm::exec::FieldNeighborhood; using CoordType = typename PointsIn::ValueType; using OT = typename GradientOutType::ComponentType; @@ -112,7 +112,7 @@ struct StructuredPointGradient : public vtkm::worklet::WorkletPointNeighborhood //will be float,3 even when T is a 3 component field template VTKM_EXEC void Jacobian(const PointsIn& inputPoints, - const vtkm::exec::arg::BoundaryState& boundary, + const vtkm::exec::BoundaryState& boundary, vtkm::Vec& m_xi, vtkm::Vec& m_eta, vtkm::Vec& m_zeta) const diff --git a/vtkm/worklet/testing/UnitTestWorkletMapPointNeighborhood.cxx b/vtkm/worklet/testing/UnitTestWorkletMapPointNeighborhood.cxx index 8a1dda68a..24a2369bf 100644 --- a/vtkm/worklet/testing/UnitTestWorkletMapPointNeighborhood.cxx +++ b/vtkm/worklet/testing/UnitTestWorkletMapPointNeighborhood.cxx @@ -43,13 +43,13 @@ struct MaxNeighborValue : public vtkm::worklet::WorkletPointNeighborhood CellSetIn, FieldOut maxV); - using ExecutionSignature = void(OnBoundary, _1, _3); + using ExecutionSignature = void(Boundary, _1, _3); //verify input domain can be something other than first parameter using InputDomain = _2; template - VTKM_EXEC void operator()(const vtkm::exec::arg::BoundaryState& boundary, - const vtkm::exec::arg::Neighborhood& inputField, + VTKM_EXEC void operator()(const vtkm::exec::BoundaryState& boundary, + const vtkm::exec::FieldNeighborhood& inputField, FieldOut& output) const { using ValueType = typename FieldIn::ValueType;