VTK-m  2.0
Gaussian.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 #ifndef VTKM_KERNEL_GAUSSIAN_H
11 #define VTKM_KERNEL_GAUSSIAN_H
12 
14 
15 //
16 // Gaussian kernel.
17 // Compact support is achieved by truncating the kernel beyond the cutoff radius
18 // This implementation uses a factor of 5 between smoothing length and cutoff
19 //
20 
21 namespace vtkm
22 {
23 namespace worklet
24 {
25 namespace splatkernels
26 {
27 
28 template <int Dimensions>
29 struct Gaussian : public KernelBase<Gaussian<Dimensions>>
30 {
31  //---------------------------------------------------------------------
32  // Constructor
33  // Calculate coefficients used repeatedly when evaluating the kernel
34  // value or gradient
36  Gaussian(double smoothingLength)
37  : KernelBase<Gaussian<Dimensions>>(smoothingLength)
38  {
39  Hinverse_ = 1.0 / smoothingLength;
41  maxRadius_ = 5.0 * smoothingLength;
43  //
44  norm_ = 1.0 / vtkm::Pow(M_PI, static_cast<double>(Dimensions) / 2.0);
45  scale_W_ = norm_ * PowerExpansion<Dimensions>(Hinverse_);
46  scale_GradW_ = -2.0 * PowerExpansion<Dimensions + 1>(Hinverse_) / norm_;
47  }
48 
49  //---------------------------------------------------------------------
50  // return the multiplier between smoothing length and max cutoff distance
52  constexpr double getDilationFactor() const { return 5.0; }
53 
54  //---------------------------------------------------------------------
55  // compute w(h) for the given distance
57  double w(double distance) const
58  {
59  if (distance < maxDistance())
60  {
61  // compute r/h
62  double normedDist = distance * Hinverse_;
63  // compute w(h)
64  return scale_W_ * vtkm::Exp(-normedDist * normedDist);
65  }
66  return 0.0;
67  }
68 
69  //---------------------------------------------------------------------
70  // compute w(h) for the given squared distance
72  double w2(double distance2) const
73  {
74  if (distance2 < maxSquaredDistance())
75  {
76  // compute (r/h)^2
77  double normedDist = distance2 * Hinverse2_;
78  // compute w(h)
79  return scale_W_ * vtkm::Exp(-normedDist);
80  }
81  return 0.0;
82  }
83 
84  //---------------------------------------------------------------------
85  // compute w(h) for a variable h kernel
87  double w(double h, double distance) const
88  {
89  if (distance < maxDistance(h))
90  {
91  double Hinverse = 1.0 / h;
92  double scale_W = norm_ * PowerExpansion<Dimensions>(Hinverse);
93  double Q = distance * Hinverse;
94 
95  return scale_W * vtkm::Exp(-Q * Q);
96  }
97  return 0;
98  }
99 
100  //---------------------------------------------------------------------
101  // compute w(h) for a variable h kernel using distance squared
103  double w2(double h, double distance2) const
104  {
105  if (distance2 < maxSquaredDistance(h))
106  {
107  double Hinverse = 1.0 / h;
108  double scale_W = norm_ * PowerExpansion<Dimensions>(Hinverse);
109  double Q = distance2 * Hinverse * Hinverse;
110 
111  return scale_W * vtkm::Exp(-Q);
112  }
113  return 0;
114  }
115 
116  //---------------------------------------------------------------------
117  // Calculates the kernel derivative for a distance {x,y,z} vector
118  // from the centre
120  vector_type gradW(double distance, const vector_type& pos) const
121  {
122  double Q = distance * Hinverse_;
123  if (Q != 0.0)
124  {
125  return scale_GradW_ * vtkm::Exp(-Q * Q) * pos;
126  }
127  else
128  {
129  return vector_type(0.0);
130  }
131  }
132 
133  //---------------------------------------------------------------------
134  // Calculates the kernel derivative for a distance {x,y,z} vector
135  // from the centre using a variable h
137  vector_type gradW(double h, double distance, const vector_type& pos) const
138  {
139  double Hinverse = 1.0 / h;
140  double scale_GradW = -2.0 * PowerExpansion<Dimensions + 1>(Hinverse) /
141  vtkm::Pow(M_PI, static_cast<double>(Dimensions) / 2.0);
142  double Q = distance * Hinverse;
143 
145  if (distance != 0.0)
146  {
147  return scale_GradW * vtkm::Exp(-Q * Q) * pos;
148  }
149  else
150  {
151  return vector_type(0.0);
152  }
153  }
154 
155  //---------------------------------------------------------------------
156  // return the maximum distance at which this kernel is non zero
158  double maxDistance() const { return maxRadius_; }
159 
160  //---------------------------------------------------------------------
161  // return the maximum distance at which this variable h kernel is non zero
163  double maxDistance(double h) const { return getDilationFactor() * h; }
164 
165  //---------------------------------------------------------------------
166  // return the maximum distance at which this kernel is non zero
168  double maxSquaredDistance() const { return maxRadius2_; }
169 
170  //---------------------------------------------------------------------
171  // return the maximum distance at which this kernel is non zero
173  double maxSquaredDistance(double h) const
174  {
175  return PowerExpansion<2>(getDilationFactor()) * h * h;
176  }
177 
178 private:
179  double norm_;
180  double Hinverse_;
181  double Hinverse2_;
182  double maxRadius_;
183  double maxRadius2_;
184  double scale_W_;
185  double scale_GradW_;
186 };
187 }
188 }
189 }
190 
191 #endif
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::splatkernels::Gaussian::maxSquaredDistance
VTKM_EXEC_CONT double maxSquaredDistance(double h) const
Definition: Gaussian.h:173
vtkm::worklet::splatkernels::Gaussian::Gaussian
VTKM_EXEC_CONT Gaussian(double smoothingLength)
Definition: Gaussian.h:36
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
KernelBase.h
vtkm::worklet::splatkernels::Gaussian::w2
VTKM_EXEC_CONT double w2(double h, double distance2) const
Definition: Gaussian.h:103
vtkm::worklet::splatkernels::Gaussian::scale_GradW_
double scale_GradW_
Definition: Gaussian.h:185
vtkm::worklet::splatkernels::Gaussian::Hinverse_
double Hinverse_
Definition: Gaussian.h:180
vtkm::worklet::splatkernels::Gaussian::norm_
double norm_
Definition: Gaussian.h:179
vtkm::worklet::splatkernels::Gaussian::maxSquaredDistance
VTKM_EXEC_CONT double maxSquaredDistance() const
Definition: Gaussian.h:168
vtkm::worklet::splatkernels::Gaussian::gradW
VTKM_EXEC_CONT vector_type gradW(double h, double distance, const vector_type &pos) const
Definition: Gaussian.h:137
vtkm::worklet::splatkernels::Gaussian::maxRadius_
double maxRadius_
Definition: Gaussian.h:182
M_PI
#define M_PI
Definition: KernelBase.h:27
vtkm::Exp
VTKM_EXEC_CONT vtkm::Float32 Exp(vtkm::Float32 x)
Computes e**x, the base-e exponential of x.
Definition: Math.h:1212
vtkm::worklet::splatkernels::Gaussian::w
VTKM_EXEC_CONT double w(double distance) const
Definition: Gaussian.h:57
vtkm::worklet::splatkernels::KernelBase
Definition: KernelBase.h:53
vtkm::worklet::splatkernels::Gaussian::maxDistance
VTKM_EXEC_CONT double maxDistance(double h) const
Definition: Gaussian.h:163
vtkm::worklet::splatkernels::Gaussian::w
VTKM_EXEC_CONT double w(double h, double distance) const
Definition: Gaussian.h:87
vtkm::worklet::splatkernels::Gaussian::w2
VTKM_EXEC_CONT double w2(double distance2) const
Definition: Gaussian.h:72
vtkm::worklet::splatkernels::Gaussian::Hinverse2_
double Hinverse2_
Definition: Gaussian.h:181
vtkm::worklet::splatkernels::Gaussian::gradW
VTKM_EXEC_CONT vector_type gradW(double distance, const vector_type &pos) const
Definition: Gaussian.h:120
vtkm::worklet::splatkernels::Gaussian::getDilationFactor
constexpr VTKM_EXEC_CONT double getDilationFactor() const
Definition: Gaussian.h:52
vtkm::worklet::splatkernels::Gaussian::maxDistance
VTKM_EXEC_CONT double maxDistance() const
Definition: Gaussian.h:158
vtkm::Vec< vtkm::Float64, 3 >
vtkm::worklet::splatkernels::vector_type
vtkm::Vec3f_64 vector_type
Definition: KernelBase.h:24
vtkm::worklet::splatkernels::Gaussian::maxRadius2_
double maxRadius2_
Definition: Gaussian.h:183
vtkm::worklet::splatkernels::Gaussian
Definition: Gaussian.h:29
vtkm::worklet::splatkernels::Gaussian::scale_W_
double scale_W_
Definition: Gaussian.h:184