VTK-m  2.0
StructuredPointGradient.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 
11 #ifndef vtk_m_worklet_gradient_StructuredPointGradient_h
12 #define vtk_m_worklet_gradient_StructuredPointGradient_h
13 
16 
17 
18 namespace vtkm
19 {
20 namespace worklet
21 {
22 namespace gradient
23 {
24 
26 {
27 
28  using ControlSignature = void(CellSetIn,
29  FieldInNeighborhood points,
31  GradientOutputs outputFields);
32 
33  using ExecutionSignature = void(Boundary, _2, _3, _4);
34 
35  using InputDomain = _1;
36 
37  template <typename PointsIn, typename FieldIn, typename GradientOutType>
39  const PointsIn& inputPoints,
40  const FieldIn& inputField,
41  GradientOutType& outputGradient) const
42  {
43  using CoordType = typename PointsIn::ValueType;
45  using OT = typename GradientOutType::ComponentType;
46 
47  vtkm::Vec<CT, 3> xi, eta, zeta;
48  vtkm::Vec<bool, 3> onBoundary{ !boundary.IsRadiusInXBoundary(1),
49  !boundary.IsRadiusInYBoundary(1),
50  !boundary.IsRadiusInZBoundary(1) };
51 
52  this->Jacobian(inputPoints, onBoundary, xi, eta, zeta); //store the metrics in xi,eta,zeta
53 
54  auto dxi = inputField.Get(1, 0, 0) - inputField.Get(-1, 0, 0);
55  auto deta = inputField.Get(0, 1, 0) - inputField.Get(0, -1, 0);
56  auto dzeta = inputField.Get(0, 0, 1) - inputField.Get(0, 0, -1);
57 
58  dxi = (onBoundary[0] ? dxi : dxi * 0.5f);
59  deta = (onBoundary[1] ? deta : deta * 0.5f);
60  dzeta = (onBoundary[2] ? dzeta : dzeta * 0.5f);
61 
62  outputGradient[0] = static_cast<OT>(xi[0] * dxi + eta[0] * deta + zeta[0] * dzeta);
63  outputGradient[1] = static_cast<OT>(xi[1] * dxi + eta[1] * deta + zeta[1] * dzeta);
64  outputGradient[2] = static_cast<OT>(xi[2] * dxi + eta[2] * deta + zeta[2] * dzeta);
65  }
66 
67  template <typename FieldIn, typename GradientOutType>
69  const vtkm::exec::BoundaryState& boundary,
71  inputPoints,
72  const FieldIn& inputField,
73  GradientOutType& outputGradient) const
74  {
75  //When the points and cells are both structured we can achieve even better
76  //performance by not doing the Jacobian, but instead do an image gradient
77  //using central differences
78  using PointsIn =
80  using CoordType = typename PointsIn::ValueType;
81  using OT = typename GradientOutType::ComponentType;
82 
83  CoordType r = inputPoints.Portal.GetSpacing();
84 
85 #if (defined(VTKM_CUDA) && defined(VTKM_GCC))
86 #pragma GCC diagnostic push
87 #pragma GCC diagnostic ignored "-Wconversion"
88 #endif
89  if (boundary.IsRadiusInXBoundary(1))
90  {
91  auto dx = inputField.GetUnchecked(1, 0, 0) - inputField.GetUnchecked(-1, 0, 0);
92  outputGradient[0] = static_cast<OT>((dx * 0.5f) / r[0]);
93  }
94  else
95  {
96  auto dx = inputField.Get(1, 0, 0) - inputField.Get(-1, 0, 0);
97  outputGradient[0] = static_cast<OT>(dx / r[0]);
98  }
99 
100  if (boundary.IsRadiusInYBoundary(1))
101  {
102  auto dy = inputField.GetUnchecked(0, 1, 0) - inputField.GetUnchecked(0, -1, 0);
103  outputGradient[1] = static_cast<OT>((dy * 0.5f) / r[1]);
104  }
105  else
106  {
107  auto dy = inputField.Get(0, 1, 0) - inputField.Get(0, -1, 0);
108  outputGradient[1] = static_cast<OT>(dy / (r[1]));
109  }
110 
111  if (boundary.IsRadiusInZBoundary(1))
112  {
113  auto dz = inputField.GetUnchecked(0, 0, 1) - inputField.GetUnchecked(0, 0, -1);
114  outputGradient[2] = static_cast<OT>((dz * 0.5f) / r[2]);
115  }
116  else
117  {
118  auto dz = inputField.Get(0, 0, 1) - inputField.Get(0, 0, -1);
119  outputGradient[2] = static_cast<OT>(dz / (r[2]));
120  }
121 #if (defined(VTKM_CUDA) && defined(VTKM_GCC))
122 #pragma GCC diagnostic pop
123 #endif
124  }
125 
126  //we need to pass the coordinates into this function, and instead
127  //of the input being Vec<coordtype,3> it needs to be Vec<float,3> as the metrics
128  //will be float,3 even when T is a 3 component field
129  template <typename PointsIn, typename CT>
130  VTKM_EXEC void Jacobian(const PointsIn& inputPoints,
131  const vtkm::Vec<bool, 3>& onBoundary,
132  vtkm::Vec<CT, 3>& m_xi,
133  vtkm::Vec<CT, 3>& m_eta,
134  vtkm::Vec<CT, 3>& m_zeta) const
135  {
136  using CoordType = typename PointsIn::ValueType;
137  CoordType xi, eta, zeta;
138 
139 
140  if (onBoundary[0])
141  {
142  xi = (inputPoints.Get(1, 0, 0) - inputPoints.Get(-1, 0, 0));
143  }
144  else
145  {
146  xi = (inputPoints.GetUnchecked(1, 0, 0) - inputPoints.GetUnchecked(-1, 0, 0)) * 0.5f;
147  }
148 
149  if (onBoundary[1])
150  {
151  eta = (inputPoints.Get(0, 1, 0) - inputPoints.Get(0, -1, 0));
152  }
153  else
154  {
155  eta = (inputPoints.GetUnchecked(0, 1, 0) - inputPoints.GetUnchecked(0, -1, 0)) * 0.5f;
156  }
157 
158  if (onBoundary[2])
159  {
160  zeta = (inputPoints.Get(0, 0, 1) - inputPoints.Get(0, 0, -1));
161  }
162  else
163  {
164  zeta = (inputPoints.GetUnchecked(0, 0, 1) - inputPoints.GetUnchecked(0, 0, -1)) * 0.5f;
165  }
166 
167  CT aj = xi[0] * eta[1] * zeta[2] + xi[1] * eta[2] * zeta[0] + xi[2] * eta[0] * zeta[1] -
168  xi[2] * eta[1] * zeta[0] - xi[1] * eta[0] * zeta[2] - xi[0] * eta[2] * zeta[1];
169 
170  aj = (aj != 0.0) ? 1.f / aj : aj;
171 
172  // Xi metrics.
173  m_xi[0] = aj * (eta[1] * zeta[2] - eta[2] * zeta[1]);
174  m_xi[1] = -aj * (eta[0] * zeta[2] - eta[2] * zeta[0]);
175  m_xi[2] = aj * (eta[0] * zeta[1] - eta[1] * zeta[0]);
176 
177  // Eta metrics.
178  m_eta[0] = -aj * (xi[1] * zeta[2] - xi[2] * zeta[1]);
179  m_eta[1] = aj * (xi[0] * zeta[2] - xi[2] * zeta[0]);
180  m_eta[2] = -aj * (xi[0] * zeta[1] - xi[1] * zeta[0]);
181 
182  // Zeta metrics.
183  m_zeta[0] = aj * (xi[1] * eta[2] - xi[2] * eta[1]);
184  m_zeta[1] = -aj * (xi[0] * eta[2] - xi[2] * eta[0]);
185  m_zeta[2] = aj * (xi[0] * eta[1] - xi[1] * eta[0]);
186  }
187 };
188 }
189 }
190 }
191 
192 #endif
vtkm::exec::BoundaryState
Provides a neighborhood's placement with respect to the mesh's boundary.
Definition: BoundaryState.h:31
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::gradient::StructuredPointGradient::InputDomain
_1 InputDomain
Definition: StructuredPointGradient.h:35
vtkm::worklet::WorkletNeighborhood::CellSetIn
A control signature tag for input connectivity.
Definition: WorkletNeighborhood.h:110
WorkletPointNeighborhood.h
vtkm::worklet::gradient::StructuredPointGradient::ExecutionSignature
void(Boundary, _2, _3, _4) ExecutionSignature
Definition: StructuredPointGradient.h:33
vtkm::VecTraits::BaseComponentType
typename vtkm::VecTraits< ComponentType >::BaseComponentType BaseComponentType
Base component type in the vector.
Definition: VecTraits.h:80
vtkm::exec::BoundaryState::IsRadiusInXBoundary
VTKM_EXEC bool IsRadiusInXBoundary(vtkm::IdComponent radius) const
Definition: BoundaryState.h:50
vtkm::worklet::gradient::StructuredPointGradient::operator()
VTKM_EXEC void operator()(const vtkm::exec::BoundaryState &boundary, const PointsIn &inputPoints, const FieldIn &inputField, GradientOutType &outputGradient) const
Definition: StructuredPointGradient.h:38
GradientOutput.h
vtkm::exec::BoundaryState::IsRadiusInYBoundary
VTKM_EXEC bool IsRadiusInYBoundary(vtkm::IdComponent radius) const
Definition: BoundaryState.h:55
vtkm::worklet::WorkletNeighborhood::FieldIn
A control signature tag for input point fields.
Definition: WorkletNeighborhood.h:77
vtkm::exec::BoundaryState::IsRadiusInZBoundary
VTKM_EXEC bool IsRadiusInZBoundary(vtkm::IdComponent radius) const
Definition: BoundaryState.h:60
vtkm::worklet::WorkletNeighborhood::Boundary
The ExecutionSignature tag to query if the current iteration is inside the boundary.
Definition: WorkletNeighborhood.h:54
vtkm::worklet::gradient::StructuredPointGradient::ControlSignature
void(CellSetIn, FieldInNeighborhood points, FieldInNeighborhood, GradientOutputs outputFields) ControlSignature
Definition: StructuredPointGradient.h:31
vtkm::Vec
A short fixed-length array.
Definition: Types.h:767
vtkm::worklet::gradient::StructuredPointGradient::Jacobian
VTKM_EXEC void Jacobian(const PointsIn &inputPoints, const vtkm::Vec< bool, 3 > &onBoundary, vtkm::Vec< CT, 3 > &m_xi, vtkm::Vec< CT, 3 > &m_eta, vtkm::Vec< CT, 3 > &m_zeta) const
Definition: StructuredPointGradient.h:130
vtkm::worklet::gradient::StructuredPointGradient::operator()
VTKM_EXEC void operator()(const vtkm::exec::BoundaryState &boundary, const vtkm::exec::FieldNeighborhood< vtkm::internal::ArrayPortalUniformPointCoordinates > &inputPoints, const FieldIn &inputField, GradientOutType &outputGradient) const
Definition: StructuredPointGradient.h:68
vtkm::worklet::WorkletNeighborhood::FieldInNeighborhood
A control signature tag for neighborhood input values.
Definition: WorkletNeighborhood.h:129
vtkm::worklet::WorkletPointNeighborhood
Definition: WorkletPointNeighborhood.h:27
vtkm::exec::FieldNeighborhood
Retrieves field values from a neighborhood.
Definition: FieldNeighborhood.h:36
vtkm::worklet::gradient::StructuredPointGradient
Definition: StructuredPointGradient.h:25
vtkm::worklet::gradient::GradientOutputs
Definition: GradientOutput.h:305