VTK-m  2.0
worklet/ComputeMoments.h
Go to the documentation of this file.
1 //============================================================================
2 //
3 // Copyright (c) Kitware, Inc.
4 // All rights reserved.
5 // See LICENSE.txt for details.
6 //
7 // This software is distributed WITHOUT ANY WARRANTY; without even
8 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9 // PURPOSE. See the above copyright notice for more information.
10 //
11 //=======================================================================
12 #ifndef vtk_m_worklet_moments_ComputeMoments_h
13 #define vtk_m_worklet_moments_ComputeMoments_h
14 
15 #include <vtkm/Math.h>
17 
18 #include <vtkm/cont/Field.h>
21 
23 
24 #include <cassert>
25 #include <string>
26 
27 namespace vtkm
28 {
29 namespace worklet
30 {
31 namespace moments
32 {
33 
35 {
36 public:
37  ComputeMoments2D(const vtkm::Vec3f& _spacing, vtkm::Float64 _radius, int _p, int _q)
38  : RadiusDiscrete(vtkm::IdComponent(_radius / (_spacing[0] - 1e-10)),
39  vtkm::IdComponent(_radius / (_spacing[1] - 1e-10)),
40  vtkm::IdComponent(_radius / (_spacing[2] - 1e-10)))
41  , SpacingProduct(_spacing[0] * _spacing[1])
42  , p(_p)
43  , q(_q)
44  {
45  assert(_spacing[0] > 1e-10);
46  assert(_spacing[1] > 1e-10);
47  assert(_spacing[2] > 1e-10);
48 
49  assert(_p >= 0);
50  assert(_q >= 0);
51  }
52 
54 
55  using ExecutionSignature = void(_2, Boundary, _3);
56 
57  template <typename NeighIn, typename T>
58  VTKM_EXEC void operator()(const NeighIn& image,
59  const vtkm::exec::BoundaryState& boundary,
60  T& moment) const
61  {
62  // TODO: type safety and numerical precision
64 
65  // Clamp the radius to the dataset bounds (discard out-of-bounds points).
66  const auto minRadius = boundary.ClampNeighborIndex(-this->RadiusDiscrete);
67  const auto maxRadius = boundary.ClampNeighborIndex(this->RadiusDiscrete);
68 
69  vtkm::Vec2f_64 radius;
70  for (vtkm::IdComponent j = minRadius[1]; j <= maxRadius[1]; ++j)
71  {
72  if (j > -this->RadiusDiscrete[1] && boundary.IJK[1] + j == 0)
73  { // Don't double count samples that exist on other nodes:
74  continue;
75  }
76  radius[1] = j * 1. / this->RadiusDiscrete[1];
77 
78  for (vtkm::IdComponent i = minRadius[0]; i <= maxRadius[0]; ++i)
79  {
80  if (i > -this->RadiusDiscrete[0] && boundary.IJK[0] + i == 0)
81  { // Don't double count samples that exist on other nodes:
82  continue;
83  }
84  radius[0] = i * 1. / this->RadiusDiscrete[0];
85 
86  if (vtkm::Dot(radius, radius) <= 1)
87  {
88  sum +=
89  static_cast<T>(vtkm::Pow(radius[0], p) * vtkm::Pow(radius[1], q) * image.Get(i, j, 0));
90  }
91  }
92  }
93 
94  moment = T(sum * this->SpacingProduct);
95  }
96 
97 private:
100  const int p;
101  const int q;
102 };
103 
105 {
106 public:
107  ComputeMoments3D(const vtkm::Vec3f& _spacing, vtkm::Float64 _radius, int _p, int _q, int _r)
108  : RadiusDiscrete(vtkm::IdComponent(_radius / (_spacing[0] - 1e-10)),
109  vtkm::IdComponent(_radius / (_spacing[1] - 1e-10)),
110  vtkm::IdComponent(_radius / (_spacing[2] - 1e-10)))
111  , SpacingProduct(vtkm::ReduceProduct(_spacing))
112  , p(_p)
113  , q(_q)
114  , r(_r)
115  {
116  assert(_spacing[0] > 1e-10);
117  assert(_spacing[1] > 1e-10);
118  assert(_spacing[2] > 1e-10);
119 
120  assert(_p >= 0);
121  assert(_q >= 0);
122  assert(_r >= 0);
123  }
124 
126 
127  using ExecutionSignature = void(_2, Boundary, _3);
128 
129  template <typename NeighIn, typename T>
130  VTKM_EXEC void operator()(const NeighIn& image,
131  const vtkm::exec::BoundaryState& boundary,
132  T& moment) const
133  {
134  // TODO: type safety and numerical precision
136 
137  // Clamp the radius to the dataset bounds (discard out-of-bounds points).
138  const auto minRadius = boundary.ClampNeighborIndex(-this->RadiusDiscrete);
139  const auto maxRadius = boundary.ClampNeighborIndex(this->RadiusDiscrete);
140 
141  vtkm::Vec3f_64 radius;
142  for (vtkm::IdComponent k = minRadius[2]; k <= maxRadius[2]; ++k)
143  {
144  if (k > -this->RadiusDiscrete[2] && boundary.IJK[2] + k == 0)
145  { // Don't double count samples that exist on other nodes:
146  continue;
147  }
148  radius[2] = k * 1. / this->RadiusDiscrete[2];
149 
150  for (vtkm::IdComponent j = minRadius[1]; j <= maxRadius[1]; ++j)
151  {
152  if (j > -this->RadiusDiscrete[1] && boundary.IJK[1] + j == 0)
153  { // Don't double count samples that exist on other nodes:
154  continue;
155  }
156  radius[1] = j * 1. / this->RadiusDiscrete[1];
157 
158  for (vtkm::IdComponent i = minRadius[0]; i <= maxRadius[0]; ++i)
159  {
160  if (i > -this->RadiusDiscrete[0] && boundary.IJK[0] + i == 0)
161  { // Don't double count samples that exist on other nodes:
162  continue;
163  }
164  radius[0] = i * 1. / this->RadiusDiscrete[0];
165 
166  if (vtkm::Dot(radius, radius) <= 1)
167  {
168  sum += static_cast<T>(vtkm::Pow(radius[0], p) * vtkm::Pow(radius[1], q) *
169  vtkm::Pow(radius[2], r) * image.Get(i, j, k));
170  }
171  }
172  }
173  }
174 
175  moment = T(sum * this->SpacingProduct);
176  }
177 
178 private:
181  const int p;
182  const int q;
183  const int r;
184 };
185 
187 {
188 public:
189  ComputeMoments(double _radius, const vtkm::Vec3f& _spacing)
190  : Radius(_radius)
191  , Spacing(_spacing)
192  {
193  }
194 
196  {
197  public:
198  template <typename T, typename S>
200  const vtkm::cont::ArrayHandle<T, S>& pixels,
201  vtkm::Vec3f spacing,
202  vtkm::Float64 radius,
203  int maxOrder,
204  vtkm::cont::DataSet& output) const
205  {
206  using WorkletType = vtkm::worklet::moments::ComputeMoments2D;
208 
209  for (int order = 0; order <= maxOrder; ++order)
210  {
211  for (int p = 0; p <= order; ++p)
212  {
213  const int q = order - p;
214 
216 
217  DispatcherType dispatcher(WorkletType{ spacing, radius, p, q });
218  dispatcher.Invoke(input, pixels, moments);
219 
220  std::string fieldName = std::string("index") + std::string(p, '0') + std::string(q, '1');
221 
222  vtkm::cont::Field momentsField(
223  fieldName, vtkm::cont::Field::Association::Points, moments);
224  output.AddField(momentsField);
225  }
226  }
227  }
228 
229  template <typename T, typename S>
231  const vtkm::cont::ArrayHandle<T, S>& pixels,
232  vtkm::Vec3f spacing,
233  vtkm::Float64 radius,
234  int maxOrder,
235  vtkm::cont::DataSet& output) const
236  {
237  using WorkletType = vtkm::worklet::moments::ComputeMoments3D;
239 
240  for (int order = 0; order <= maxOrder; ++order)
241  {
242  for (int r = 0; r <= order; ++r)
243  {
244  const int qMax = order - r;
245  for (int q = 0; q <= qMax; ++q)
246  {
247  const int p = order - r - q;
248 
250 
251  DispatcherType dispatcher(WorkletType{ spacing, radius, p, q, r });
252  dispatcher.Invoke(input, pixels, moments);
253 
254  std::string fieldName = std::string("index") + std::string(p, '0') +
255  std::string(q, '1') + std::string(r, '2');
256 
257  vtkm::cont::Field momentsField(
258  fieldName, vtkm::cont::Field::Association::Points, moments);
259  output.AddField(momentsField);
260  }
261  }
262  }
263  }
264  };
265 
266  template <typename T, typename S>
267  void Run(const vtkm::cont::UnknownCellSet& input,
268  const vtkm::cont::ArrayHandle<T, S>& pixels,
269  int maxOrder,
270  vtkm::cont::DataSet& output) const
271  {
273  .CastAndCall(ResolveUnknownCellSet(), pixels, this->Spacing, this->Radius, maxOrder, output);
274  }
275 
276 private:
279 };
280 }
281 }
282 }
283 
284 #endif // vtk_m_worklet_moments_ComputeMoments_h
vtkm::worklet::moments::ComputeMoments3D::ExecutionSignature
void(_2, Boundary, _3) ExecutionSignature
Definition: worklet/ComputeMoments.h:127
vtkm::exec::BoundaryState
Provides a neighborhood's placement with respect to the mesh's boundary.
Definition: BoundaryState.h:31
vtkm::worklet::moments::ComputeMoments3D::p
const int p
Definition: worklet/ComputeMoments.h:181
vtkm::cont::ArrayHandle< T, S >
vtkm::worklet::moments::ComputeMoments2D::SpacingProduct
const vtkm::Float64 SpacingProduct
Definition: worklet/ComputeMoments.h:99
vtkm::worklet::moments::ComputeMoments::Spacing
const vtkm::Vec3f Spacing
Definition: worklet/ComputeMoments.h:278
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::cont::CellSetStructured
Definition: CastAndCall.h:32
vtkm::worklet::WorkletNeighborhood::CellSetIn
A control signature tag for input connectivity.
Definition: WorkletNeighborhood.h:110
vtkm::worklet::moments::ComputeMoments2D
Definition: worklet/ComputeMoments.h:34
vtkm::worklet::WorkletNeighborhood::FieldOut
A control signature tag for output point fields.
Definition: WorkletNeighborhood.h:89
WorkletPointNeighborhood.h
vtkm::cont::UnknownCellSet::ResetCellSetList
VTKM_CONT vtkm::cont::UncertainCellSet< CellSetList > ResetCellSetList(CellSetList) const
Assigns potential cell set types.
vtkm::worklet::moments::ComputeMoments2D::q
const int q
Definition: worklet/ComputeMoments.h:101
vtkm::cont::DataSet
Definition: DataSet.h:34
vtkm::worklet::moments::ComputeMoments3D::q
const int q
Definition: worklet/ComputeMoments.h:182
vtkm::worklet::moments::ComputeMoments3D::r
const int r
Definition: worklet/ComputeMoments.h:183
vtkm::exec::BoundaryState::IJK
vtkm::Id3 IJK
Definition: BoundaryState.h:260
vtkm::worklet::moments::ComputeMoments3D::ComputeMoments3D
ComputeMoments3D(const vtkm::Vec3f &_spacing, vtkm::Float64 _radius, int _p, int _q, int _r)
Definition: worklet/ComputeMoments.h:107
vtkm::cont::UnknownCellSet
A CellSet of an unknown type.
Definition: UnknownCellSet.h:48
UncertainCellSet.h
vtkm::worklet::moments::ComputeMoments2D::ExecutionSignature
void(_2, Boundary, _3) ExecutionSignature
Definition: worklet/ComputeMoments.h:55
vtkm::exec::BoundaryState::ClampNeighborIndex
VTKM_EXEC vtkm::IdComponent3 ClampNeighborIndex(const vtkm::IdComponent3 &neighbor) const
Definition: BoundaryState.h:204
vtkm::worklet::moments::ComputeMoments::Run
void Run(const vtkm::cont::UnknownCellSet &input, const vtkm::cont::ArrayHandle< T, S > &pixels, int maxOrder, vtkm::cont::DataSet &output) const
Definition: worklet/ComputeMoments.h:267
vtkm::worklet::moments::ComputeMoments
Definition: worklet/ComputeMoments.h:186
BoundaryState.h
UncertainArrayHandle.h
Math.h
vtkm::worklet::moments::ComputeMoments::ResolveUnknownCellSet::operator()
void operator()(const vtkm::cont::CellSetStructured< 3 > &input, const vtkm::cont::ArrayHandle< T, S > &pixels, vtkm::Vec3f spacing, vtkm::Float64 radius, int maxOrder, vtkm::cont::DataSet &output) const
Definition: worklet/ComputeMoments.h:230
vtkm::cont::Field
A Field encapsulates an array on some piece of the mesh, such as the points, a cell set,...
Definition: cont/Field.h:31
vtkm::worklet::moments::ComputeMoments2D::RadiusDiscrete
vtkm::Vec3i_32 RadiusDiscrete
Definition: worklet/ComputeMoments.h:98
vtkm::cont::Field::Association::Points
@ Points
vtkm::worklet::moments::ComputeMoments2D::ControlSignature
void(CellSetIn, FieldInNeighborhood, FieldOut) ControlSignature
Definition: worklet/ComputeMoments.h:53
vtkm::worklet::moments::ComputeMoments3D
Definition: worklet/ComputeMoments.h:104
vtkm::ReduceProduct
VTKM_EXEC_CONT T ReduceProduct(const vtkm::Vec< T, Size > &a)
Definition: Types.h:1567
vtkm::worklet::WorkletNeighborhood::Boundary
The ExecutionSignature tag to query if the current iteration is inside the boundary.
Definition: WorkletNeighborhood.h:54
vtkm::cont::DataSet::AddField
VTKM_CONT void AddField(const Field &field)
Adds a field to the DataSet.
vtkm::Vec< vtkm::FloatDefault, 3 >
vtkm::worklet::moments::ComputeMoments3D::SpacingProduct
const vtkm::Float64 SpacingProduct
Definition: worklet/ComputeMoments.h:180
Field.h
vtkm::worklet::DispatcherPointNeighborhood
Dispatcher for worklets that inherit from WorkletPointNeighborhood.
Definition: DispatcherPointNeighborhood.h:26
vtkm::worklet::moments::ComputeMoments2D::p
const int p
Definition: worklet/ComputeMoments.h:100
vtkm::List
Definition: List.h:34
vtkm::Float64
double Float64
Definition: Types.h:155
vtkm::worklet::moments::ComputeMoments3D::operator()
VTKM_EXEC void operator()(const NeighIn &image, const vtkm::exec::BoundaryState &boundary, T &moment) const
Definition: worklet/ComputeMoments.h:130
vtkm::worklet::moments::ComputeMoments::ResolveUnknownCellSet::operator()
void operator()(const vtkm::cont::CellSetStructured< 2 > &input, const vtkm::cont::ArrayHandle< T, S > &pixels, vtkm::Vec3f spacing, vtkm::Float64 radius, int maxOrder, vtkm::cont::DataSet &output) const
Definition: worklet/ComputeMoments.h:199
vtkm::worklet::moments::ComputeMoments2D::ComputeMoments2D
ComputeMoments2D(const vtkm::Vec3f &_spacing, vtkm::Float64 _radius, int _p, int _q)
Definition: worklet/ComputeMoments.h:37
vtkm::worklet::WorkletNeighborhood::FieldInNeighborhood
A control signature tag for neighborhood input values.
Definition: WorkletNeighborhood.h:129
vtkm::worklet::WorkletPointNeighborhood
Definition: WorkletPointNeighborhood.h:27
vtkm::worklet::moments::ComputeMoments3D::ControlSignature
void(CellSetIn, FieldInNeighborhood, FieldOut) ControlSignature
Definition: worklet/ComputeMoments.h:125
vtkm::worklet::moments::ComputeMoments::ComputeMoments
ComputeMoments(double _radius, const vtkm::Vec3f &_spacing)
Definition: worklet/ComputeMoments.h:189
vtkm::worklet::moments::ComputeMoments::Radius
const vtkm::Float64 Radius
Definition: worklet/ComputeMoments.h:277
vtkm::worklet::moments::ComputeMoments2D::operator()
VTKM_EXEC void operator()(const NeighIn &image, const vtkm::exec::BoundaryState &boundary, T &moment) const
Definition: worklet/ComputeMoments.h:58
vtkm::TypeTraits::ZeroInitialization
static VTKM_EXEC_CONT T ZeroInitialization()
Definition: TypeTraits.h:75
vtkm::worklet::moments::ComputeMoments::ResolveUnknownCellSet
Definition: worklet/ComputeMoments.h:195
vtkm::worklet::moments::ComputeMoments3D::RadiusDiscrete
vtkm::Vec3i_32 RadiusDiscrete
Definition: worklet/ComputeMoments.h:179