VTK-m  2.0
Spline3rdOrder.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_SPLINE_3RD_ORDER_H
11 #define VTKM_KERNEL_SPLINE_3RD_ORDER_H
12 
14 
15 //
16 // Spline 3rd Order kernel.
17 //
18 
19 namespace vtkm
20 {
21 namespace worklet
22 {
23 namespace splatkernels
24 {
25 
26 template <vtkm::IdComponent Dim>
28 
29 template <>
31 {
32  const double value = 10.0 / (7.0 * M_PI);
33 };
34 
35 template <>
37 {
38  const double value = 1.0 / M_PI;
39 };
40 
41 
42 template <int Dimensions>
43 struct Spline3rdOrder : public KernelBase<Spline3rdOrder<Dimensions>>
44 {
45  //---------------------------------------------------------------------
46  // Constructor
47  // Calculate coefficients used repeatedly when evaluating the kernel
48  // value or gradient
50  Spline3rdOrder(double smoothingLength)
51  : KernelBase<Spline3rdOrder<Dimensions>>(smoothingLength)
52  {
53  Hinverse_ = 1.0 / smoothingLength;
55  maxRadius_ = 2.0 * smoothingLength;
57  //
59 
60  scale_W_ = norm_ * PowerExpansion<Dimensions>(Hinverse_);
61  scale_GradW_ = norm_ * PowerExpansion<Dimensions + 1>(Hinverse_);
62  }
63  //---------------------------------------------------------------------
64  // Calculates the kernel value for the given distance
66  double w(double distance) const
67  {
68  // compute Q=(r/h)
69  double Q = distance * Hinverse_;
70  if (Q < 1.0)
71  {
72  return scale_W_ * (1.0 - (3.0 / 2.0) * Q * Q + (3.0 / 4.0) * Q * Q * Q);
73  }
74  else if (Q < 2.0)
75  {
76  double q2 = (2.0 - Q);
77  return scale_W_ * (1.0 / 4.0) * (q2 * q2 * q2);
78  }
79  else
80  {
81  return 0.0;
82  }
83  }
84 
85  //---------------------------------------------------------------------
86  // Calculates the kernel value for the given squared distance
88  double w2(double distance2) const
89  {
90  // compute Q
91  double Q = sqrt(distance2) * Hinverse_;
92  if (Q < 1.0)
93  {
94  return scale_W_ * (1.0 - (3.0 / 2.0) * Q * Q + (3.0 / 4.0) * Q * Q * Q);
95  }
96  else if (Q < 2.0)
97  {
98  double q2 = (2.0 - Q);
99  return scale_W_ * (1.0 / 4.0) * (q2 * q2 * q2);
100  }
101  else
102  {
103  return 0.0;
104  }
105  }
106 
107  //---------------------------------------------------------------------
108  // compute w(h) for a variable h kernel
110  double w(double h, double distance) const
111  {
112  double Hinverse = 1.0 / h;
113  double scale_W = norm_ * PowerExpansion<Dimensions>(Hinverse);
114  double Q = distance * Hinverse;
115  if (Q < 1.0)
116  {
117  return scale_W * (1.0 - (3.0 / 2.0) * Q * Q + (3.0 / 4.0) * Q * Q * Q);
118  }
119  else if (Q < 2.0)
120  {
121  double q2 = (2.0 - Q);
122  return scale_W * (1.0 / 4.0) * (q2 * q2 * q2);
123  }
124  else
125  {
126  return 0.0;
127  }
128  }
129 
130  //---------------------------------------------------------------------
131  // compute w(h) for a variable h kernel using distance squared
133  double w2(double h, double distance2) const
134  {
135  double Hinverse = 1.0 / h;
136  double scale_W = norm_ * PowerExpansion<Dimensions>(Hinverse);
137  double Q = sqrt(distance2) * Hinverse;
138  if (Q < 1.0)
139  {
140  return scale_W * (1.0 - (3.0 / 2.0) * Q * Q + (3.0 / 4.0) * Q * Q * Q);
141  }
142  else if (Q < 2.0)
143  {
144  double q2 = (2.0 - Q);
145  return scale_W * (1.0 / 4.0) * (q2 * q2 * q2);
146  }
147  else
148  {
149  return 0.0;
150  }
151  }
152 
153  //---------------------------------------------------------------------
154  // Calculates the kernel derivation for the given distance of two particles.
155  // The used formula is the derivation of Speith (3.126) for the value
156  // with (3.21) for the direction of the gradient vector.
157  // Be careful: grad W is antisymmetric in r (3.25)!.
159  vector_type gradW(double distance, const vector_type& pos) const
160  {
161  double Q = distance * Hinverse_;
162  if (Q == 0.0)
163  {
164  return vector_type(0.0);
165  }
166  else if (Q < 1.0)
167  {
168  return scale_GradW_ * (-3.0 * Q + (9.0 / 4.0) * Q * Q) * pos;
169  }
170  else if (Q < 2.0)
171  {
172  double q2 = (2.0 - Q);
173  return scale_GradW_ * (-3.0 / 4.0) * q2 * q2 * pos;
174  }
175  else
176  {
177  return vector_type(0.0);
178  }
179  }
180 
181  //---------------------------------------------------------------------
183  vector_type gradW(double h, double distance, const vector_type& pos) const
184  {
185  double Hinverse = 1.0 / h;
186  double scale_GradW = norm_ * PowerExpansion<Dimensions + 1>(Hinverse);
187  double Q = distance * Hinverse;
188  if (Q == 0.0)
189  {
190  return vector_type(0.0);
191  }
192  else if (Q < 1.0)
193  {
194  return scale_GradW * (-3.0 * Q + (9.0 / 4.0) * Q * Q) * pos;
195  }
196  else if (Q < 2.0)
197  {
198  double q2 = (2.0 - Q);
199  return scale_GradW * (-3.0 / 4.0) * q2 * q2 * pos;
200  }
201  else
202  {
203  return vector_type(0.0);
204  }
205  }
206 
207  //---------------------------------------------------------------------
208  // return the maximum distance at which this kernel is non zero
210  double maxDistance() const { return maxRadius_; }
211 
212  //---------------------------------------------------------------------
213  // return the maximum distance at which this variable h kernel is non zero
215  double maxDistance(double h) const { return 2.0 * h; }
216 
217  //---------------------------------------------------------------------
218  // return the maximum distance at which this kernel is non zero
220  double maxSquaredDistance() const { return maxRadius2_; }
221 
222  //---------------------------------------------------------------------
223  // return the maximum distance at which this kernel is non zero
225  double maxSquaredDistance(double h) const { return 4.0 * h * h; }
226 
227  //---------------------------------------------------------------------
228  // return the multiplier between smoothing length and max cutoff distance
230  double getDilationFactor() const { return 2.0; }
231 
232 private:
233  double norm_;
234  double Hinverse_;
235  double Hinverse2_;
236  double maxRadius_;
237  double maxRadius2_;
238  double scale_W_;
239  double scale_GradW_;
240 };
241 }
242 }
243 }
244 
245 #endif
vtkm::worklet::splatkernels::Spline3rdOrder::w2
VTKM_EXEC_CONT double w2(double h, double distance2) const
Definition: Spline3rdOrder.h:133
vtkm::worklet::splatkernels::Spline3rdOrder::maxRadius_
double maxRadius_
Definition: Spline3rdOrder.h:236
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::worklet::splatkernels::default_norm_value
Definition: Spline3rdOrder.h:27
KernelBase.h
vtkm::worklet::splatkernels::Spline3rdOrder::gradW
VTKM_EXEC_CONT vector_type gradW(double h, double distance, const vector_type &pos) const
Definition: Spline3rdOrder.h:183
vtkm::worklet::splatkernels::Spline3rdOrder::Spline3rdOrder
VTKM_EXEC_CONT Spline3rdOrder(double smoothingLength)
Definition: Spline3rdOrder.h:50
vtkm::worklet::splatkernels::Spline3rdOrder::Hinverse_
double Hinverse_
Definition: Spline3rdOrder.h:234
vtkm::worklet::splatkernels::Spline3rdOrder::getDilationFactor
VTKM_EXEC_CONT double getDilationFactor() const
Definition: Spline3rdOrder.h:230
vtkm::worklet::splatkernels::Spline3rdOrder::maxSquaredDistance
VTKM_EXEC_CONT double maxSquaredDistance() const
Definition: Spline3rdOrder.h:220
vtkm::worklet::splatkernels::Spline3rdOrder::Hinverse2_
double Hinverse2_
Definition: Spline3rdOrder.h:235
vtkm::worklet::splatkernels::Spline3rdOrder::scale_GradW_
double scale_GradW_
Definition: Spline3rdOrder.h:239
M_PI
#define M_PI
Definition: KernelBase.h:27
vtkm::worklet::splatkernels::KernelBase
Definition: KernelBase.h:53
vtkm::worklet::splatkernels::Spline3rdOrder::norm_
double norm_
Definition: Spline3rdOrder.h:233
vtkm::worklet::splatkernels::Spline3rdOrder::maxRadius2_
double maxRadius2_
Definition: Spline3rdOrder.h:237
vtkm::worklet::splatkernels::Spline3rdOrder::w2
VTKM_EXEC_CONT double w2(double distance2) const
Definition: Spline3rdOrder.h:88
vtkm::worklet::splatkernels::Spline3rdOrder::gradW
VTKM_EXEC_CONT vector_type gradW(double distance, const vector_type &pos) const
Definition: Spline3rdOrder.h:159
vtkm::worklet::splatkernels::Spline3rdOrder
Definition: Spline3rdOrder.h:43
vtkm::worklet::splatkernels::Spline3rdOrder::w
VTKM_EXEC_CONT double w(double distance) const
Definition: Spline3rdOrder.h:66
vtkm::worklet::splatkernels::Spline3rdOrder::w
VTKM_EXEC_CONT double w(double h, double distance) const
Definition: Spline3rdOrder.h:110
vtkm::Vec< vtkm::Float64, 3 >
vtkm::worklet::splatkernels::Spline3rdOrder::scale_W_
double scale_W_
Definition: Spline3rdOrder.h:238
vtkm::worklet::splatkernels::Spline3rdOrder::maxSquaredDistance
VTKM_EXEC_CONT double maxSquaredDistance(double h) const
Definition: Spline3rdOrder.h:225
vtkm::worklet::splatkernels::vector_type
vtkm::Vec3f_64 vector_type
Definition: KernelBase.h:24
vtkm::worklet::splatkernels::Spline3rdOrder::maxDistance
VTKM_EXEC_CONT double maxDistance() const
Definition: Spline3rdOrder.h:210
vtkm::worklet::splatkernels::Spline3rdOrder::maxDistance
VTKM_EXEC_CONT double maxDistance(double h) const
Definition: Spline3rdOrder.h:215