Commit a2602183 authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

Make integrators have a virtual superclass

This will make it easier to support integrators as an ExecObject.

One side effect is that the integrators and partical advection
are not templated by the type of the field.
Regardless of the type of the field, there is probably little reason to
compute particle advection with less than 64 bit floats to account for
accumulated errors. This will make it easier to use these classes.
parent 56121b10
......@@ -79,7 +79,7 @@ void RunTest(const std::string& fname,
using RGEvalType = vtkm::worklet::particleadvection::UniformGridEvaluate<FieldPortalConstType,
FieldType,
DeviceAdapter>;
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType, FieldType>;
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType>;
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> fieldArray;
ds.GetField(0).GetData().CopyTo(fieldArray);
......
......@@ -77,7 +77,7 @@ void RunTest(vtkm::Id numSteps, vtkm::Float32 stepSize, vtkm::Id advectType)
vtkm::worklet::particleadvection::TemporalGridEvaluator<FieldPortalConstType,
FieldType,
DeviceAdapter>;
using Integrator = vtkm::worklet::particleadvection::EulerIntegrator<GridEvaluator, FieldType>;
using Integrator = vtkm::worklet::particleadvection::EulerIntegrator<GridEvaluator>;
GridEvaluator eval(ds1.GetCoordinateSystem(),
ds1.GetCellSet(0),
......
......@@ -23,6 +23,7 @@
#include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/worklet/ParticleAdvection.h>
#include <vtkm/worklet/particleadvection/Integrators.h>
namespace vtkm
{
......@@ -39,7 +40,7 @@ public:
Streamline();
VTKM_CONT
void SetStepSize(vtkm::Float64 s) { this->StepSize = s; }
void SetStepSize(vtkm::worklet::particleadvection::ScalarType s) { this->StepSize = s; }
VTKM_CONT
void SetNumberOfSteps(vtkm::Id n) { this->NumberOfSteps = n; }
......@@ -66,7 +67,7 @@ public:
private:
vtkm::worklet::Streamline Worklet;
vtkm::Float64 StepSize;
vtkm::worklet::particleadvection::ScalarType StepSize;
vtkm::Id NumberOfSteps;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> Seeds;
};
......
......@@ -91,14 +91,14 @@ inline VTKM_CONT vtkm::cont::DataSet Streamline::DoExecute(
typename FieldHandle::template ExecutionTypes<DeviceAdapter>::PortalConst;
using RGEvalType = vtkm::worklet::particleadvection::
UniformGridEvaluate<FieldPortalConstType, T, DeviceAdapter, StorageType>;
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType, T>;
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType>;
//RGEvalType eval(input.GetCoordinateSystem(), input.GetCellSet(0), field);
RGEvalType eval(coords, cells, field);
RK4RGType rk4(eval, static_cast<T>(this->StepSize));
vtkm::worklet::Streamline streamline;
vtkm::worklet::StreamlineResult<T> res;
vtkm::worklet::StreamlineResult res;
vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>> seedArray;
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Copy(this->Seeds, seedArray);
......
......@@ -31,9 +31,10 @@ namespace vtkm
namespace worklet
{
template <typename FieldType>
struct ParticleAdvectionResult
{
using ScalarType = vtkm::worklet::particleadvection::ScalarType;
ParticleAdvectionResult()
: positions()
, status()
......@@ -42,7 +43,7 @@ struct ParticleAdvectionResult
{
}
ParticleAdvectionResult(const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>& pos,
ParticleAdvectionResult(const vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& pos,
const vtkm::cont::ArrayHandle<vtkm::Id>& stat,
const vtkm::cont::ArrayHandle<vtkm::Id>& steps)
: positions(pos)
......@@ -51,10 +52,10 @@ struct ParticleAdvectionResult
{
}
ParticleAdvectionResult(const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>& pos,
ParticleAdvectionResult(const vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& pos,
const vtkm::cont::ArrayHandle<vtkm::Id>& stat,
const vtkm::cont::ArrayHandle<vtkm::Id>& steps,
const vtkm::cont::ArrayHandle<FieldType>& timeArray)
const vtkm::cont::ArrayHandle<ScalarType>& timeArray)
: positions(pos)
, status(stat)
, stepsTaken(steps)
......@@ -62,40 +63,39 @@ struct ParticleAdvectionResult
{
}
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> positions;
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> positions;
vtkm::cont::ArrayHandle<vtkm::Id> status;
vtkm::cont::ArrayHandle<vtkm::Id> stepsTaken;
vtkm::cont::ArrayHandle<FieldType> times;
vtkm::cont::ArrayHandle<ScalarType> times;
};
class ParticleAdvection
{
public:
using ScalarType = vtkm::worklet::particleadvection::ScalarType;
ParticleAdvection() {}
template <typename IntegratorType,
typename FieldType,
typename PointStorage,
typename DeviceAdapter>
ParticleAdvectionResult<FieldType> Run(
const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
const vtkm::Id& nSteps,
DeviceAdapter tag)
ParticleAdvectionResult Run(const IntegratorType& it,
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
const vtkm::Id& nSteps,
DeviceAdapter tag)
{
vtkm::Id numSeeds = static_cast<vtkm::Id>(pts.GetNumberOfValues());
vtkm::cont::ArrayHandle<vtkm::Id> stepsTaken;
vtkm::cont::ArrayHandle<FieldType> timeArray;
vtkm::cont::ArrayHandle<ScalarType> timeArray;
//Allocate status and steps arrays.
vtkm::cont::ArrayHandleConstant<vtkm::Id> init(0, numSeeds);
stepsTaken.Allocate(numSeeds);
vtkm::cont::ArrayCopy(init, stepsTaken, tag);
//Allocate memory to store the time for temporal integration.
vtkm::cont::ArrayHandleConstant<FieldType> time(0, numSeeds);
timeArray.Allocate(numSeeds);
vtkm::cont::ArrayHandleConstant<ScalarType> time(0, numSeeds);
vtkm::cont::ArrayCopy(time, timeArray, tag);
return Run(it, pts, stepsTaken, timeArray, nSteps, tag);
......@@ -105,37 +105,32 @@ public:
typename FieldType,
typename PointStorage,
typename DeviceAdapter>
ParticleAdvectionResult<FieldType> Run(
const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
const vtkm::Id& nSteps,
DeviceAdapter tag)
ParticleAdvectionResult Run(const IntegratorType& it,
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
const vtkm::Id& nSteps,
DeviceAdapter tag)
{
vtkm::Id numSeeds = static_cast<vtkm::Id>(pts.GetNumberOfValues());
vtkm::cont::ArrayHandle<FieldType> timeArray;
vtkm::cont::ArrayHandle<ScalarType> timeArray;
//Allocate memory to store the time for temporal integration.
vtkm::cont::ArrayHandleConstant<FieldType> time(0, numSeeds);
vtkm::cont::ArrayHandleConstant<ScalarType> time(0, numSeeds);
timeArray.Allocate(numSeeds);
vtkm::cont::ArrayCopy(time, timeArray, tag);
return Run(it, pts, inputSteps, timeArray, nSteps, tag);
}
template <typename IntegratorType,
typename FieldType,
typename PointStorage,
typename DeviceAdapter>
ParticleAdvectionResult<FieldType> Run(
const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
vtkm::cont::ArrayHandle<FieldType>& inputTime,
const vtkm::Id& nSteps,
DeviceAdapter tag)
template <typename IntegratorType, typename DeviceAdapter>
ParticleAdvectionResult Run(const IntegratorType& it,
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& pts,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
vtkm::cont::ArrayHandle<ScalarType>& inputTime,
const vtkm::Id& nSteps,
DeviceAdapter tag)
{
vtkm::worklet::particleadvection::ParticleAdvectionWorklet<IntegratorType, FieldType> worklet;
vtkm::worklet::particleadvection::ParticleAdvectionWorklet<IntegratorType> worklet;
vtkm::Id numSeeds = static_cast<vtkm::Id>(pts.GetNumberOfValues());
......@@ -147,14 +142,31 @@ public:
worklet.Run(it, pts, nSteps, status, inputSteps, inputTime, tag);
//Create output.
ParticleAdvectionResult<FieldType> res(pts, status, inputSteps, inputTime);
return res;
return ParticleAdvectionResult(pts, status, inputSteps, inputTime);
}
template <typename IntegratorType,
typename FieldType,
typename PointStorage,
typename DeviceAdapter>
ParticleAdvectionResult Run(const IntegratorType& it,
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
vtkm::cont::ArrayHandle<ScalarType>& inputTime,
const vtkm::Id& nSteps,
DeviceAdapter tag)
{
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> ptsCopy;
vtkm::cont::ArrayCopy(pts, ptsCopy, tag);
return Run(it, ptsCopy, inputSteps, inputTime, nSteps, tag);
}
};
template <typename FieldType>
struct StreamlineResult
{
using ScalarType = vtkm::worklet::particleadvection::ScalarType;
using VectorType = vtkm::Vec<ScalarType, 3>;
StreamlineResult()
: positions()
, polyLines()
......@@ -164,7 +176,7 @@ struct StreamlineResult
{
}
StreamlineResult(const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>& pos,
StreamlineResult(const vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& pos,
const vtkm::cont::CellSetExplicit<>& lines,
const vtkm::cont::ArrayHandle<vtkm::Id>& stat,
const vtkm::cont::ArrayHandle<vtkm::Id>& steps)
......@@ -175,11 +187,11 @@ struct StreamlineResult
{
}
StreamlineResult(const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>& pos,
StreamlineResult(const vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& pos,
const vtkm::cont::CellSetExplicit<>& lines,
const vtkm::cont::ArrayHandle<vtkm::Id>& stat,
const vtkm::cont::ArrayHandle<vtkm::Id>& steps,
const vtkm::cont::ArrayHandle<FieldType>& timeArray)
const vtkm::cont::ArrayHandle<ScalarType>& timeArray)
: positions(pos)
, polyLines(lines)
......@@ -189,27 +201,28 @@ struct StreamlineResult
{
}
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> positions;
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> positions;
vtkm::cont::CellSetExplicit<> polyLines;
vtkm::cont::ArrayHandle<vtkm::Id> status;
vtkm::cont::ArrayHandle<vtkm::Id> stepsTaken;
vtkm::cont::ArrayHandle<FieldType> times;
vtkm::cont::ArrayHandle<ScalarType> times;
};
class Streamline
{
public:
using ScalarType = vtkm::worklet::particleadvection::ScalarType;
Streamline() {}
template <typename IntegratorType,
typename FieldType,
typename PointStorage,
typename DeviceAdapter>
StreamlineResult<FieldType> Run(
const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& seedArray,
const vtkm::Id& nSteps,
DeviceAdapter tag)
StreamlineResult Run(const IntegratorType& it,
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& seedArray,
const vtkm::Id& nSteps,
DeviceAdapter tag)
{
using DeviceAlgorithm = typename vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
......@@ -227,8 +240,8 @@ public:
DeviceAlgorithm::Copy(zero, steps);
//Allocate memory to store the time for temporal integration.
vtkm::cont::ArrayHandle<FieldType> timeArray;
vtkm::cont::ArrayHandleConstant<FieldType> time(0, numSeeds);
vtkm::cont::ArrayHandle<ScalarType> timeArray;
vtkm::cont::ArrayHandleConstant<ScalarType> time(0, numSeeds);
timeArray.Allocate(numSeeds);
DeviceAlgorithm::Copy(time, timeArray);
......@@ -239,12 +252,11 @@ public:
typename FieldType,
typename PointStorage,
typename DeviceAdapter>
StreamlineResult<FieldType> Run(
const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& seedArray,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
const vtkm::Id& nSteps,
DeviceAdapter tag)
StreamlineResult Run(const IntegratorType& it,
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& seedArray,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
const vtkm::Id& nSteps,
DeviceAdapter tag)
{
using DeviceAlgorithm = typename vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
......@@ -257,30 +269,26 @@ public:
DeviceAlgorithm::Copy(statusOK, status);
//Allocate memory to store the time for temporal integration.
vtkm::cont::ArrayHandle<FieldType> timeArray;
vtkm::cont::ArrayHandleConstant<FieldType> time(0, numSeeds);
vtkm::cont::ArrayHandle<ScalarType> timeArray;
vtkm::cont::ArrayHandleConstant<ScalarType> time(0, numSeeds);
timeArray.Allocate(numSeeds);
DeviceAlgorithm::Copy(time, timeArray);
return Run(it, seedArray, inputSteps, timeArray, nSteps, tag);
}
template <typename IntegratorType,
typename FieldType,
typename PointStorage,
typename DeviceAdapter>
StreamlineResult<FieldType> Run(
const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& seedArray,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
vtkm::cont::ArrayHandle<FieldType>& inputTime,
const vtkm::Id& nSteps,
DeviceAdapter tag)
template <typename IntegratorType, typename DeviceAdapter>
StreamlineResult Run(const IntegratorType& it,
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& seedArray,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
vtkm::cont::ArrayHandle<ScalarType>& inputTime,
const vtkm::Id& nSteps,
DeviceAdapter tag)
{
using DeviceAlgorithm = typename vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
vtkm::worklet::particleadvection::StreamlineWorklet<IntegratorType, FieldType> worklet;
vtkm::worklet::particleadvection::StreamlineWorklet<IntegratorType> worklet;
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage> positions;
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> positions;
vtkm::cont::CellSetExplicit<> polyLines;
//Allocate and initialize status array.
......@@ -292,8 +300,23 @@ public:
worklet.Run(it, seedArray, nSteps, positions, polyLines, status, inputSteps, inputTime, tag);
StreamlineResult<FieldType> res(positions, polyLines, status, inputSteps, inputTime);
return res;
return StreamlineResult(positions, polyLines, status, inputSteps, inputTime);
}
template <typename IntegratorType,
typename FieldType,
typename PointStorage,
typename DeviceAdapter>
StreamlineResult Run(const IntegratorType& it,
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& seedArray,
vtkm::cont::ArrayHandle<vtkm::Id>& inputSteps,
vtkm::cont::ArrayHandle<ScalarType>& inputTime,
const vtkm::Id& nSteps,
DeviceAdapter tag)
{
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> seedCopy;
vtkm::cont::ArrayCopy(seedArray, seedCopy, tag);
return Run(it, seedCopy, inputSteps, inputTime, nSteps, tag);
}
};
}
......
......@@ -29,6 +29,8 @@
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/worklet/particleadvection/Integrators.h>
namespace vtkm
{
namespace worklet
......@@ -37,19 +39,20 @@ namespace particleadvection
{
// Constant vector
template <typename FieldType>
class ConstantField
{
public:
using ScalarType = vtkm::worklet::particleadvection::ScalarType;
VTKM_CONT
ConstantField(const vtkm::Bounds& bb, const vtkm::Vec<FieldType, 3>& v)
ConstantField(const vtkm::Bounds& bb, const vtkm::Vec<ScalarType, 3>& v)
: bounds{ bb }
, vector{ v }
{
}
VTKM_EXEC_CONT
bool IsWithinSpatialBoundary(const vtkm::Vec<FieldType, 3>& position) const
bool IsWithinSpatialBoundary(const vtkm::Vec<ScalarType, 3>& position) const
{
if (!bounds.Contains(position))
return false;
......@@ -57,35 +60,35 @@ public:
}
VTKM_EXEC_CONT
bool IsWithinTemporalBoundary(const FieldType vtkmNotUsed(time)) const { return true; }
bool IsWithinTemporalBoundary(const ScalarType vtkmNotUsed(time)) const { return true; }
VTKM_EXEC_CONT
void GetSpatialBoundary(vtkm::Vec<FieldType, 3>& dir, vtkm::Vec<FieldType, 3>& boundary) const
void GetSpatialBoundary(vtkm::Vec<ScalarType, 3>& dir, vtkm::Vec<ScalarType, 3>& boundary) const
{
// Based on the direction of the velocity we need to be able to tell where
// the particle will exit the domain from to actually push it out of domain.
boundary[0] = static_cast<FieldType>(dir[0] > 0 ? bounds.X.Max : bounds.X.Min);
boundary[1] = static_cast<FieldType>(dir[1] > 0 ? bounds.Y.Max : bounds.Y.Min);
boundary[2] = static_cast<FieldType>(dir[2] > 0 ? bounds.Z.Max : bounds.Z.Min);
boundary[0] = static_cast<ScalarType>(dir[0] > 0 ? bounds.X.Max : bounds.X.Min);
boundary[1] = static_cast<ScalarType>(dir[1] > 0 ? bounds.Y.Max : bounds.Y.Min);
boundary[2] = static_cast<ScalarType>(dir[2] > 0 ? bounds.Z.Max : bounds.Z.Min);
}
VTKM_EXEC_CONT
void GetTemporalBoundary(FieldType& boundary) const
void GetTemporalBoundary(ScalarType& boundary) const
{
// Return the time of the newest time slice
boundary = 0;
}
VTKM_EXEC
bool Evaluate(const vtkm::Vec<FieldType, 3>& pos,
FieldType vtkmNotUsed(time),
vtkm::Vec<FieldType, 3>& out) const
bool Evaluate(const vtkm::Vec<ScalarType, 3>& pos,
ScalarType vtkmNotUsed(time),
vtkm::Vec<ScalarType, 3>& out) const
{
return Evaluate(pos, out);
}
VTKM_EXEC
bool Evaluate(const vtkm::Vec<FieldType, 3>& pos, vtkm::Vec<FieldType, 3>& out) const
bool Evaluate(const vtkm::Vec<ScalarType, 3>& pos, vtkm::Vec<ScalarType, 3>& out) const
{
if (!bounds.Contains(pos))
return false;
......@@ -98,14 +101,15 @@ public:
private:
vtkm::Bounds bounds;
vtkm::Vec<FieldType, 3> vector;
vtkm::Vec<ScalarType, 3> vector;
};
// Circular Orbit
template <typename FieldType>
class AnalyticalOrbitEvaluate
{
public:
using ScalarType = vtkm::worklet::particleadvection::ScalarType;
VTKM_CONT
AnalyticalOrbitEvaluate(const vtkm::Bounds& bb)
: bounds{ bb }
......@@ -113,7 +117,7 @@ public:
}
VTKM_EXEC_CONT
bool IsWithinSpatialBoundary(const vtkm::Vec<FieldType, 3>& position) const
bool IsWithinSpatialBoundary(const vtkm::Vec<ScalarType, 3>& position) const
{
if (!bounds.Contains(position))
return false;
......@@ -121,41 +125,41 @@ public:
}
VTKM_EXEC_CONT
bool IsWithinTemporalBoundary(const FieldType vtkmNotUsed(time)) const { return true; }
bool IsWithinTemporalBoundary(const ScalarType vtkmNotUsed(time)) const { return true; }
VTKM_EXEC_CONT
void GetSpatialBoundary(vtkm::Vec<FieldType, 3>& dir, vtkm::Vec<FieldType, 3>& boundary) const
void GetSpatialBoundary(vtkm::Vec<ScalarType, 3>& dir, vtkm::Vec<ScalarType, 3>& boundary) const
{
// Based on the direction of the velocity we need to be able to tell where
// the particle will exit the domain from to actually push it out of domain.
boundary[0] = static_cast<FieldType>(dir[0] > 0 ? bounds.X.Max : bounds.X.Min);
boundary[1] = static_cast<FieldType>(dir[1] > 0 ? bounds.Y.Max : bounds.Y.Min);
boundary[2] = static_cast<FieldType>(dir[2] > 0 ? bounds.Z.Max : bounds.Z.Min);
boundary[0] = static_cast<ScalarType>(dir[0] > 0 ? bounds.X.Max : bounds.X.Min);
boundary[1] = static_cast<ScalarType>(dir[1] > 0 ? bounds.Y.Max : bounds.Y.Min);
boundary[2] = static_cast<ScalarType>(dir[2] > 0 ? bounds.Z.Max : bounds.Z.Min);
}
VTKM_EXEC_CONT
void GetTemporalBoundary(FieldType& boundary) const
void GetTemporalBoundary(ScalarType& boundary) const
{
// Return the time of the newest time slice
boundary = 0;
}
VTKM_EXEC
bool Evaluate(const vtkm::Vec<FieldType, 3>& pos,
FieldType vtkmNotUsed(time),
vtkm::Vec<FieldType, 3>& out) const
bool Evaluate(const vtkm::Vec<ScalarType, 3>& pos,
ScalarType vtkmNotUsed(time),
vtkm::Vec<ScalarType, 3>& out) const
{
return Evaluate(pos, out);
}
VTKM_EXEC bool Evaluate(const vtkm::Vec<FieldType, 3>& pos, vtkm::Vec<FieldType, 3>& out) const
VTKM_EXEC bool Evaluate(const vtkm::Vec<ScalarType, 3>& pos, vtkm::Vec<ScalarType, 3>& out) const
{
if (!bounds.Contains(pos))
return false;
//statically return a value which is orthogonal to the input pos in the xy plane.
FieldType oneDivLen = 1.0f / Magnitude(pos);
ScalarType oneDivLen = 1.0f / Magnitude(pos);
out[0] = -1.0f * pos[1] * oneDivLen;
out[1] = pos[0] * oneDivLen;
out[2] = pos[2] * oneDivLen;
......@@ -173,6 +177,7 @@ template <typename PortalType,
typename StorageTag = VTKM_DEFAULT_STORAGE_TAG>
class UniformGridEvaluate
{
using ScalarType = vtkm::worklet::particleadvection::ScalarType;
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, StorageTag>;
public:
......@@ -210,11 +215,11 @@ public:
//
// In our case output_min is 0
scale[0] =
static_cast<FieldType>(dims[0] - 1) / static_cast<FieldType>(bounds.X.Max - bounds.X.Min);
static_cast<ScalarType>(dims[0] - 1) / static_cast<ScalarType>(bounds.X.Max - bounds.X.Min);
scale[1] =
static_cast<FieldType>(dims[1] - 1) / static_cast<FieldType>(bounds.Y.Max - bounds.Y.Min);
static_cast<ScalarType>(dims[1] - 1) / static_cast<ScalarType>(bounds.Y.Max - bounds.Y.Min);
scale[2] =
static_cast<FieldType>(dims[2] - 1) / static_cast<FieldType>(bounds.Z.Max - bounds.Z.Min);
static_cast<ScalarType>(dims[2] - 1) / static_cast<ScalarType>(bounds.Z.Max - bounds.Z.Min);
planeSize = dims[0] * dims[1];
rowSize = dims[0];
......@@ -244,18 +249,18 @@ public:
//
// In our case output_min is 0
scale[0] =
static_cast<FieldType>(dims[0] - 1) / static_cast<FieldType>(bounds.X.Max - bounds.X.Min);
static_cast<ScalarType>(dims[0] - 1) / static_cast<ScalarType>(bounds.X.Max - bounds.X.Min);
scale[1] =
static_cast<FieldType>(dims[1] - 1) / static_cast<FieldType>(bounds.Y.Max - bounds.Y.Min);
static_cast<ScalarType>(dims[1] - 1) / static_cast<ScalarType>(bounds.Y.Max - bounds.Y.Min);
scale[2] =
static_cast<FieldType>(dims[2] - 1) / static_cast<FieldType>(bounds.Z.Max - bounds.Z.Min);
static_cast<ScalarType>(dims[2] - 1) / static_cast<ScalarType>(bounds.Z.Max - bounds.Z.Min);
planeSize = dims[0] * dims[1];
rowSize = dims[0];
}
VTKM_EXEC_CONT