VTK-m  2.0
Stepper.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 
13 #ifndef vtk_m_filter_flow_worklet_Stepper_h
14 #define vtk_m_filter_flow_worklet_Stepper_h
15 
19 
20 #include <limits>
21 
22 namespace vtkm
23 {
24 namespace worklet
25 {
26 namespace flow
27 {
28 
29 template <typename ExecIntegratorType, typename ExecEvaluatorType>
31 {
32 private:
33  ExecIntegratorType Integrator;
34  ExecEvaluatorType Evaluator;
37 
38 public:
40  StepperImpl(const ExecIntegratorType& integrator,
41  const ExecEvaluatorType& evaluator,
42  const vtkm::FloatDefault deltaT,
43  const vtkm::FloatDefault tolerance)
44  : Integrator(integrator)
45  , Evaluator(evaluator)
46  , DeltaT(deltaT)
47  , Tolerance(tolerance)
48  {
49  }
50 
51  template <typename Particle>
53  vtkm::FloatDefault& time,
54  vtkm::Vec3f& outpos) const
55  {
56  vtkm::Vec3f velocity(0, 0, 0);
57  auto status = this->Integrator.CheckStep(particle, this->DeltaT, velocity);
58  if (status.CheckOk())
59  {
60  outpos = particle.GetPosition() + this->DeltaT * velocity;
61  time += this->DeltaT;
62  }
63  else
64  outpos = particle.GetPosition();
65 
66  return status;
67  }
68 
69  template <typename Particle>
71  vtkm::FloatDefault& time,
72  vtkm::Vec3f& outpos) const
73  {
74  //Stepping by this->DeltaT goes beyond the bounds of the dataset.
75  //We need to take an Euler step that goes outside of the dataset.
76  //Use a binary search to find the largest step INSIDE the dataset.
77  //Binary search uses a shrinking bracket of inside / outside, so when
78  //we terminate, the outside value is the stepsize that will nudge
79  //the particle outside the dataset.
80 
81  //The binary search will be between {0, this->DeltaT}
82  vtkm::FloatDefault stepRange[2] = { 0, this->DeltaT };
83 
84  vtkm::Vec3f currPos(particle.GetEvaluationPosition(this->DeltaT));
85  vtkm::Vec3f currVelocity(0, 0, 0);
86  vtkm::VecVariable<vtkm::Vec3f, 2> currValue, tmp;
87  auto evalStatus = this->Evaluator.Evaluate(currPos, particle.GetTime(), currValue);
88  if (evalStatus.CheckFail())
89  return IntegratorStatus(evalStatus, false);
90 
91  const vtkm::FloatDefault eps = vtkm::Epsilon<vtkm::FloatDefault>() * 10;
92  vtkm::FloatDefault div = 1;
93  while ((stepRange[1] - stepRange[0]) > eps)
94  {
95  //Try a step midway between stepRange[0] and stepRange[1]
96  div *= 2;
97  vtkm::FloatDefault currStep = stepRange[0] + (this->DeltaT / div);
98 
99  //See if we can step by currStep
100  IntegratorStatus status = this->Integrator.CheckStep(particle, currStep, currVelocity);
101 
102  if (status.CheckOk()) //Integration step succedded.
103  {
104  //See if this point is in/out.
105  auto newPos = particle.GetPosition() + currStep * currVelocity;
106  evalStatus = this->Evaluator.Evaluate(newPos, particle.GetTime() + currStep, tmp);
107  if (evalStatus.CheckOk())
108  {
109  //Point still in. Update currPos and set range to {currStep, stepRange[1]}
110  currPos = newPos;
111  stepRange[0] = currStep;
112  }
113  else
114  {
115  //The step succedded, but the next point is outside.
116  //Step too long. Set range to: {stepRange[0], currStep} and continue.
117  stepRange[1] = currStep;
118  }
119  }
120  else
121  {
122  //Step too long. Set range to: {stepRange[0], stepCurr} and continue.
123  stepRange[1] = currStep;
124  }
125  }
126 
127  evalStatus = this->Evaluator.Evaluate(currPos, particle.GetTime() + stepRange[0], currValue);
128  // The eval at Time + stepRange[0] better be *inside*
129  VTKM_ASSERT(evalStatus.CheckOk() && !evalStatus.CheckSpatialBounds());
130  if (evalStatus.CheckFail() || evalStatus.CheckSpatialBounds())
131  return IntegratorStatus(evalStatus, false);
132 
133  // Update the position and time.
134  auto velocity = particle.Velocity(currValue, stepRange[1]);
135  outpos = currPos + stepRange[1] * velocity;
136  time += stepRange[1];
137 
138  // Get the evaluation status for the point that is moved by the euler step.
139  evalStatus = this->Evaluator.Evaluate(outpos, time, currValue);
140 
141  IntegratorStatus status(
142  evalStatus, vtkm::MagnitudeSquared(velocity) <= vtkm::Epsilon<vtkm::FloatDefault>());
143  status.SetOk(); //status is ok.
144 
145  return status;
146  }
147 };
148 
149 
150 template <typename IntegratorType, typename EvaluatorType>
152 {
153 private:
154  IntegratorType Integrator;
155  EvaluatorType Evaluator;
158  std::numeric_limits<vtkm::FloatDefault>::epsilon() * static_cast<vtkm::FloatDefault>(100.0f);
159 
160 public:
161  VTKM_CONT
162  Stepper() = default;
163 
164  VTKM_CONT
165  Stepper(const EvaluatorType& evaluator, const vtkm::FloatDefault deltaT)
166  : Integrator(IntegratorType(evaluator))
167  , Evaluator(evaluator)
168  , DeltaT(deltaT)
169  {
170  }
171 
172  VTKM_CONT
173  void SetTolerance(vtkm::FloatDefault tolerance) { this->Tolerance = tolerance; }
174 
175 public:
179  vtkm::cont::Token& token) const
180  -> StepperImpl<decltype(this->Integrator.PrepareForExecution(device, token)),
181  decltype(this->Evaluator.PrepareForExecution(device, token))>
182  {
183  auto integrator = this->Integrator.PrepareForExecution(device, token);
184  auto evaluator = this->Evaluator.PrepareForExecution(device, token);
185  using ExecIntegratorType = decltype(integrator);
186  using ExecEvaluatorType = decltype(evaluator);
188  integrator, evaluator, this->DeltaT, this->Tolerance);
189  }
190 };
191 
192 }
193 }
194 } //vtkm::worklet::flow
195 
196 #endif // vtk_m_filter_flow_worklet_Stepper_h
vtkm::worklet::flow::StepperImpl
Definition: Stepper.h:30
vtkm::MagnitudeSquared
VTKM_EXEC_CONT detail::FloatingPointReturnType< T >::Type MagnitudeSquared(const T &x)
Returns the square of the magnitude of a vector.
Definition: VectorAnalysis.h:64
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::flow::StepperImpl::StepperImpl
VTKM_EXEC_CONT StepperImpl(const ExecIntegratorType &integrator, const ExecEvaluatorType &evaluator, const vtkm::FloatDefault deltaT, const vtkm::FloatDefault tolerance)
Definition: Stepper.h:40
vtkm::worklet::flow::StepperImpl::Integrator
ExecIntegratorType Integrator
Definition: Stepper.h:33
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::Particle
Definition: Particle.h:90
vtkm::Particle::GetEvaluationPosition
VTKM_EXEC_CONT vtkm::Vec3f GetEvaluationPosition(const vtkm::FloatDefault &deltaT) const
Definition: Particle.h:155
vtkm::worklet::flow::IntegratorStatus::SetOk
VTKM_EXEC_CONT void SetOk()
Definition: IntegratorStatus.h:60
vtkm::worklet::flow::Stepper::DeltaT
vtkm::FloatDefault DeltaT
Definition: Stepper.h:156
vtkm::worklet::flow::StepperImpl::SmallStep
VTKM_EXEC IntegratorStatus SmallStep(Particle &particle, vtkm::FloatDefault &time, vtkm::Vec3f &outpos) const
Definition: Stepper.h:70
vtkm::worklet::flow::StepperImpl::Evaluator
ExecEvaluatorType Evaluator
Definition: Stepper.h:34
vtkm::worklet::flow::Stepper::PrepareForExecution
VTKM_CONT auto PrepareForExecution(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const -> StepperImpl< decltype(this->Integrator.PrepareForExecution(device, token)), decltype(this->Evaluator.PrepareForExecution(device, token))>
Return the StepperImpl object Prepares the execution object of Stepper.
Definition: Stepper.h:178
vtkm::worklet::flow::StepperImpl::Tolerance
vtkm::FloatDefault Tolerance
Definition: Stepper.h:36
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::worklet::flow::Stepper::SetTolerance
VTKM_CONT void SetTolerance(vtkm::FloatDefault tolerance)
Definition: Stepper.h:173
Particles.h
vtkm::VecVariable
A short variable-length array with maximum length.
Definition: VecVariable.h:30
vtkm::worklet::flow::IntegratorStatus
Definition: IntegratorStatus.h:33
vtkm::Particle::GetTime
VTKM_EXEC_CONT vtkm::FloatDefault GetTime() const
Definition: Particle.h:141
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::Particle::Velocity
VTKM_EXEC_CONT vtkm::Vec3f Velocity(const vtkm::VecVariable< vtkm::Vec3f, 2 > &vectors, const vtkm::FloatDefault &vtkmNotUsed(length))
Definition: Particle.h:145
GridEvaluators.h
vtkm::cont::ExecutionObjectBase
Base ExecutionObjectBase for execution objects to inherit from so that you can use an arbitrary objec...
Definition: ExecutionObjectBase.h:31
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::Vec< vtkm::FloatDefault, 3 >
vtkm::FloatDefault
vtkm::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:198
vtkm::Particle::GetPosition
const VTKM_EXEC_CONT vtkm::Vec3f & GetPosition() const
Definition: Particle.h:128
vtkm::worklet::flow::StepperImpl::DeltaT
vtkm::FloatDefault DeltaT
Definition: Stepper.h:35
vtkm::worklet::flow::Stepper
Definition: Stepper.h:151
vtkm::worklet::flow::Stepper::Tolerance
vtkm::FloatDefault Tolerance
Definition: Stepper.h:157
vtkm::worklet::flow::Stepper::Integrator
IntegratorType Integrator
Definition: Stepper.h:154
IntegratorStatus.h
vtkm::worklet::flow::Stepper::Stepper
VTKM_CONT Stepper(const EvaluatorType &evaluator, const vtkm::FloatDefault deltaT)
Definition: Stepper.h:165
vtkm::worklet::flow::Stepper::Evaluator
EvaluatorType Evaluator
Definition: Stepper.h:155
vtkm::worklet::flow::Stepper::Stepper
VTKM_CONT Stepper()=default
vtkm::worklet::flow::StepperImpl::Step
VTKM_EXEC IntegratorStatus Step(Particle &particle, vtkm::FloatDefault &time, vtkm::Vec3f &outpos) const
Definition: Stepper.h:52