VTK-m  2.0
DataSetIntegratorSteadyState.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_filter_flow_internal_DataSetIntegratorSteadyState_h
12 #define vtk_m_filter_flow_internal_DataSetIntegratorSteadyState_h
13 
14 #include <vtkm/cont/ArrayCopy.h>
16 
17 namespace vtkm
18 {
19 namespace filter
20 {
21 namespace flow
22 {
23 namespace internal
24 {
25 
26 class DataSetIntegratorSteadyState
27  : public vtkm::filter::flow::internal::DataSetIntegrator<DataSetIntegratorSteadyState>
28 {
29 public:
30  DataSetIntegratorSteadyState(const vtkm::cont::DataSet& ds,
31  vtkm::Id id,
32  const FieldNameType& fieldName,
36  : vtkm::filter::flow::internal::DataSetIntegrator<DataSetIntegratorSteadyState>(id,
37  fieldName,
38  solverType,
39  vecFieldType,
40  resultType)
41  , DataSet(ds)
42  {
43  }
44 
45  VTKM_CONT inline void DoAdvect(DSIHelperInfo<vtkm::Particle>& b,
46  vtkm::FloatDefault stepSize,
47  vtkm::Id maxSteps);
48 
49  VTKM_CONT inline void DoAdvect(DSIHelperInfo<vtkm::ChargedParticle>& b,
50  vtkm::FloatDefault stepSize,
51  vtkm::Id maxSteps);
52 
53 protected:
54  template <typename ArrayType>
55  VTKM_CONT void GetVelocityField(
57  {
58  if (this->FieldName.IsType<VelocityFieldNameType>())
59  {
60  const auto& fieldNm = this->FieldName.Get<VelocityFieldNameType>();
61  auto assoc = this->DataSet.GetField(fieldNm).GetAssociation();
62  ArrayType arr;
63  vtkm::cont::ArrayCopyShallowIfPossible(this->DataSet.GetField(fieldNm).GetData(), arr);
64 
65  velocityField = vtkm::worklet::flow::VelocityField<ArrayType>(arr, assoc);
66  }
67  else
68  throw vtkm::cont::ErrorFilterExecution("Velocity field vector type not available");
69  }
70 
71  template <typename ArrayType>
72  VTKM_CONT void GetElectroMagneticField(
74  {
75  if (this->FieldName.IsType<ElectroMagneticFieldNameType>())
76  {
77  const auto& fieldNm = this->FieldName.Get<ElectroMagneticFieldNameType>();
78  const auto& electric = fieldNm.first;
79  const auto& magnetic = fieldNm.second;
80  auto eAssoc = this->DataSet.GetField(electric).GetAssociation();
81  auto bAssoc = this->DataSet.GetField(magnetic).GetAssociation();
82 
83  if (eAssoc != bAssoc)
84  {
85  throw vtkm::cont::ErrorFilterExecution("E and B field need to have same association");
86  }
87  ArrayType eField, bField;
88  vtkm::cont::ArrayCopyShallowIfPossible(this->DataSet.GetField(electric).GetData(), eField);
89  vtkm::cont::ArrayCopyShallowIfPossible(this->DataSet.GetField(magnetic).GetData(), bField);
90  ebField = vtkm::worklet::flow::ElectroMagneticField<ArrayType>(eField, bField, eAssoc);
91  }
92  else
93  throw vtkm::cont::ErrorFilterExecution("Electromagnetic field vector type not available");
94  }
95 
96 private:
97  vtkm::cont::DataSet DataSet;
98 };
99 
100 
101 namespace internal
102 {
103 using ArrayType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
104 
105 using VelocityFieldType = vtkm::worklet::flow::VelocityField<ArrayType>;
107 
110 
111 //template <typename GridEvalType, typename ParticleType>
112 //class AdvectHelper;
113 
114 template <typename FieldType, typename ParticleType>
115 class AdvectHelper //<FieldType, ParticleType>
116 {
117 public:
118  using SteadyStateGridEvalType = vtkm::worklet::flow::GridEvaluator<FieldType>;
119 
120  static void Advect(const FieldType& vecField,
121  const vtkm::cont::DataSet& ds,
123  vtkm::FloatDefault stepSize,
124  vtkm::Id maxSteps,
125  const IntegrationSolverType& solverType,
127  {
128  if (solverType == IntegrationSolverType::RK4_TYPE)
129  {
133  vecField, ds, seedArray, stepSize, maxSteps, result);
134  }
135  else if (solverType == IntegrationSolverType::EULER_TYPE)
136  {
140  vecField, ds, seedArray, stepSize, maxSteps, result);
141  }
142  else
143  throw vtkm::cont::ErrorFilterExecution("Unsupported Integrator type");
144  }
145 
146  static void Advect(const FieldType& vecField,
147  const vtkm::cont::DataSet& ds,
149  vtkm::FloatDefault stepSize,
150  vtkm::Id maxSteps,
151  const IntegrationSolverType& solverType,
153  {
154  if (solverType == IntegrationSolverType::RK4_TYPE)
155  {
159  vecField, ds, seedArray, stepSize, maxSteps, result);
160  }
161  else if (solverType == IntegrationSolverType::EULER_TYPE)
162  {
166  vecField, ds, seedArray, stepSize, maxSteps, result);
167  }
168  else
169  throw vtkm::cont::ErrorFilterExecution("Unsupported Integrator type");
170  }
171 
172  template <typename WorkletType,
173  template <typename>
174  class ResultType,
175  template <typename>
176  class SolverType>
177  static void DoAdvect(const FieldType& vecField,
178  const vtkm::cont::DataSet& ds,
180  vtkm::FloatDefault stepSize,
181  vtkm::Id maxSteps,
182  ResultType<ParticleType>& result)
183  {
184  using StepperType =
186 
187  WorkletType worklet;
188  SteadyStateGridEvalType eval(ds, vecField);
189  StepperType stepper(eval, stepSize);
190  result = worklet.Run(stepper, seedArray, maxSteps);
191  }
192 };
193 }
194 
195 VTKM_CONT inline void DataSetIntegratorSteadyState::DoAdvect(DSIHelperInfo<vtkm::Particle>& b,
196  vtkm::FloatDefault stepSize,
197  vtkm::Id maxSteps)
198 {
199  using ArrayType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
200 
201  auto copyFlag = (this->CopySeedArray ? vtkm::CopyFlag::On : vtkm::CopyFlag::Off);
202  auto seedArray = vtkm::cont::make_ArrayHandle(b.V, copyFlag);
203 
204  if (this->VecFieldType == VectorFieldType::VELOCITY_FIELD_TYPE)
205  {
207  FieldType vecField;
208  this->GetVelocityField(vecField);
209 
210  using AHType = internal::AdvectHelper<internal::VelocityFieldType, vtkm::Particle>;
211 
212  if (this->IsParticleAdvectionResult())
213  {
215  AHType::Advect(
216  vecField, this->DataSet, seedArray, stepSize, maxSteps, this->SolverType, result);
217  this->UpdateResult(result, b);
218  }
219  else if (this->IsStreamlineResult())
220  {
222  AHType::Advect(
223  vecField, this->DataSet, seedArray, stepSize, maxSteps, this->SolverType, result);
224  this->UpdateResult(result, b);
225  }
226  else
227  throw vtkm::cont::ErrorFilterExecution("Unsupported result type");
228  }
229  else
230  throw vtkm::cont::ErrorFilterExecution("Unsupported vector field type");
231 }
232 
233 VTKM_CONT inline void DataSetIntegratorSteadyState::DoAdvect(
234  DSIHelperInfo<vtkm::ChargedParticle>& b,
235  vtkm::FloatDefault stepSize,
236  vtkm::Id maxSteps)
237 {
238  using ArrayType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
239 
240  auto copyFlag = (this->CopySeedArray ? vtkm::CopyFlag::On : vtkm::CopyFlag::Off);
241  auto seedArray = vtkm::cont::make_ArrayHandle(b.V, copyFlag);
242 
243  if (this->VecFieldType == VectorFieldType::ELECTRO_MAGNETIC_FIELD_TYPE)
244  {
246  FieldType ebField;
247  this->GetElectroMagneticField(ebField);
248 
249  using AHType = internal::AdvectHelper<internal::EBFieldType, vtkm::ChargedParticle>;
250 
251  if (this->IsParticleAdvectionResult())
252  {
254  AHType::Advect(
255  ebField, this->DataSet, seedArray, stepSize, maxSteps, this->SolverType, result);
256  this->UpdateResult(result, b);
257  }
258  else if (this->IsStreamlineResult())
259  {
261  AHType::Advect(
262  ebField, this->DataSet, seedArray, stepSize, maxSteps, this->SolverType, result);
263  this->UpdateResult(result, b);
264  }
265  else
266  throw vtkm::cont::ErrorFilterExecution("Unsupported result type");
267  }
268  else
269  throw vtkm::cont::ErrorFilterExecution("Unsupported vector field type");
270 }
271 
272 }
273 }
274 }
275 } //vtkm::filter::flow::internal
276 
277 #endif //vtk_m_filter_flow_internal_DataSetIntegratorSteadyState_h
vtkm::cont::make_ArrayHandle
VTKM_CONT vtkm::cont::ArrayHandleBasic< T > make_ArrayHandle(const T *array, vtkm::Id numberOfValues, vtkm::CopyFlag copy)
A convenience function for creating an ArrayHandle from a standard C array.
Definition: ArrayHandleBasic.h:217
vtkm::filter::flow::IntegrationSolverType::RK4_TYPE
@ RK4_TYPE
vtkm::cont::ArrayHandle< vtkm::Vec3f >
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::flow::RK4Integrator
Definition: RK4Integrator.h:94
vtkm::filter::flow::IntegrationSolverType::EULER_TYPE
@ EULER_TYPE
vtkm::worklet::flow::GridEvaluator
Definition: GridEvaluators.h:161
vtkm::worklet::flow::Streamline
Definition: worklet/ParticleAdvection.h:149
vtkm::filter::flow::VectorFieldType::VELOCITY_FIELD_TYPE
@ VELOCITY_FIELD_TYPE
vtkm::cont::ArrayCopyShallowIfPossible
VTKM_CONT void ArrayCopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle source, vtkm::cont::ArrayHandle< T, S > &destination)
Copies from an unknown to a known array type.
Definition: ArrayCopy.h:182
vtkm::cont::ErrorFilterExecution
This class is primarily intended to filters to throw in the control environment to indicate an execut...
Definition: ErrorFilterExecution.h:27
vtkm::worklet::flow::ParticleAdvectionResult
Definition: worklet/ParticleAdvection.h:52
vtkm::cont::DataSet
Definition: DataSet.h:34
vtkm::worklet::flow::ParticleAdvection
Definition: worklet/ParticleAdvection.h:67
DataSetIntegrator.h
vtkm::worklet::flow::ElectroMagneticField
Definition: filter/flow/worklet/Field.h:172
vtkm::worklet::flow::StreamlineResult
Definition: worklet/ParticleAdvection.h:126
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
ArrayCopy.h
vtkm::worklet::flow::EulerIntegrator
Definition: EulerIntegrator.h:59
vtkm::filter::flow::FlowResultType
FlowResultType
Definition: FlowTypes.h:31
vtkm::filter::flow::IntegrationSolverType
IntegrationSolverType
Definition: FlowTypes.h:19
vtkm::filter::flow::VectorFieldType
VectorFieldType
Definition: FlowTypes.h:25
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::CopyFlag::On
@ On
vtkm::filter::flow::VectorFieldType::ELECTRO_MAGNETIC_FIELD_TYPE
@ ELECTRO_MAGNETIC_FIELD_TYPE
vtkm::CopyFlag::Off
@ Off
vtkm::FloatDefault
vtkm::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:198
vtkm::worklet::flow::VelocityField
Definition: filter/flow/worklet/Field.h:134
vtkm::worklet::flow::Stepper
Definition: Stepper.h:151