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

Make particle advection integrators and evaluators ExecObject

By making these helper classes ExecObject, they no longer need to have a
device to be constructed. This is important for future plans to make the
filters not determine a device adapter now that dispatchers no longer
require a device adapter.
parent a2602183
......@@ -87,10 +87,7 @@ inline VTKM_CONT vtkm::cont::DataSet Streamline::DoExecute(
//todo: add check for rectilinear.
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>;
using FieldPortalConstType =
typename FieldHandle::template ExecutionTypes<DeviceAdapter>::PortalConst;
using RGEvalType = vtkm::worklet::particleadvection::
UniformGridEvaluate<FieldPortalConstType, T, DeviceAdapter, StorageType>;
using RGEvalType = vtkm::worklet::particleadvection::UniformGridEvaluate<FieldHandle>;
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType>;
//RGEvalType eval(input.GetCoordinateSystem(), input.GetCellSet(0), field);
......
......@@ -39,35 +39,36 @@ namespace worklet
namespace particleadvection
{
template <typename IntegratorType>
class ParticleAdvectWorklet : public vtkm::worklet::WorkletMapField
{
public:
using ControlSignature = void(FieldIn<IdType> idx, ExecObject ic);
using ExecutionSignature = void(_1, _2);
using ControlSignature = void(FieldIn<IdType> idx,
ExecObject integrator,
ExecObject integralCurve);
using ExecutionSignature = void(_1, _2, _3);
using InputDomain = _1;
template <typename IntegralCurveType>
VTKM_EXEC void operator()(const vtkm::Id& idx, IntegralCurveType& ic) const
template <typename IntegratorType, typename IntegralCurveType>
VTKM_EXEC void operator()(const vtkm::Id& idx,
const IntegratorType* integrator,
IntegralCurveType& integralCurve) const
{
using ScalarType = typename vtkm::worklet::particleadvection::ScalarType;
vtkm::Vec<ScalarType, 3> inpos = ic.GetPos(idx);
vtkm::Vec<ScalarType, 3> inpos = integralCurve.GetPos(idx);
vtkm::Vec<ScalarType, 3> outpos;
ScalarType time = ic.GetTime(idx);
ScalarType time = integralCurve.GetTime(idx);
ParticleStatus status;
while (!ic.Done(idx))
while (!integralCurve.Done(idx))
{
status = integrator.Step(inpos, time, outpos);
status = integrator->Step(inpos, time, outpos);
// If the status is OK, we only need to check if the particle
// has completed the maximum steps required.
if (status == ParticleStatus::STATUS_OK)
{
ic.TakeStep(idx, outpos, status);
integralCurve.TakeStep(idx, outpos, status);
// This is to keep track of the particle's time.
// This is what the Evaluator uses to determine if the particle
// has exited temporal boundary.
ic.SetTime(idx, time);
integralCurve.SetTime(idx, time);
inpos = outpos;
}
// If the particle is at spatial or temporal boundary, take steps to just
......@@ -77,36 +78,29 @@ public:
if (status == ParticleStatus::AT_SPATIAL_BOUNDARY ||
status == ParticleStatus::AT_TEMPORAL_BOUNDARY)
{
vtkm::Id numSteps = ic.GetStep(idx);
status = integrator.PushOutOfBoundary(inpos, numSteps, time, status, outpos);
ic.TakeStep(idx, outpos, status);
ic.SetTime(idx, time);
vtkm::Id numSteps = integralCurve.GetStep(idx);
status = integrator->PushOutOfBoundary(inpos, numSteps, time, status, outpos);
integralCurve.TakeStep(idx, outpos, status);
integralCurve.SetTime(idx, time);
if (status == ParticleStatus::EXITED_SPATIAL_BOUNDARY)
ic.SetExitedSpatialBoundary(idx);
integralCurve.SetExitedSpatialBoundary(idx);
if (status == ParticleStatus::EXITED_TEMPORAL_BOUNDARY)
ic.SetExitedTemporalBoundary(idx);
integralCurve.SetExitedTemporalBoundary(idx);
}
// If the particle has exited spatial boundary, set corresponding status.
else if (status == ParticleStatus::EXITED_SPATIAL_BOUNDARY)
{
ic.TakeStep(idx, outpos, status);
ic.SetExitedSpatialBoundary(idx);
integralCurve.TakeStep(idx, outpos, status);
integralCurve.SetExitedSpatialBoundary(idx);
}
// If the particle has exited temporal boundary, set corresponding status.
else if (status == ParticleStatus::EXITED_TEMPORAL_BOUNDARY)
{
ic.TakeStep(idx, outpos, status);
ic.SetExitedTemporalBoundary(idx);
integralCurve.TakeStep(idx, outpos, status);
integralCurve.SetExitedTemporalBoundary(idx);
}
}
}
ParticleAdvectWorklet(const IntegratorType& it)
: integrator(it)
{
}
IntegratorType integrator;
};
......@@ -114,8 +108,6 @@ template <typename IntegratorType>
class ParticleAdvectionWorklet
{
public:
using ScalarType = typename vtkm::worklet::particleadvection::ScalarType;
VTKM_EXEC_CONT ParticleAdvectionWorklet() {}
~ParticleAdvectionWorklet() {}
......@@ -129,8 +121,7 @@ public:
vtkm::cont::ArrayHandle<ScalarType>& timeArray,
DeviceAdapterTag)
{
using ParticleAdvectWorkletType =
vtkm::worklet::particleadvection::ParticleAdvectWorklet<IntegratorType>;
using ParticleAdvectWorkletType = vtkm::worklet::particleadvection::ParticleAdvectWorklet;
using ParticleWorkletDispatchType =
typename vtkm::worklet::DispatcherMapField<ParticleAdvectWorkletType>;
using ParticleType = vtkm::worklet::particleadvection::Particles;
......@@ -141,10 +132,9 @@ public:
ParticleType particles(seedArray, stepsTaken, statusArray, timeArray, maxSteps);
//Invoke particle advection worklet
ParticleAdvectWorkletType particleWorklet(integrator);
ParticleWorkletDispatchType particleWorkletDispatch(particleWorklet);
ParticleWorkletDispatchType particleWorkletDispatch;
particleWorkletDispatch.SetDevice(DeviceAdapterTag());
particleWorkletDispatch.Invoke(idxArray, particles);
particleWorkletDispatch.Invoke(idxArray, integrator, particles);
}
};
......@@ -162,14 +152,12 @@ public:
res = x - y;
}
};
};
} // namespace detail
template <typename IntegratorType>
class StreamlineWorklet
{
public:
using ScalarType = typename vtkm::worklet::particleadvection::ScalarType;
VTKM_EXEC_CONT StreamlineWorklet() {}
template <typename PointStorage, typename FieldStorage, typename DeviceAdapterTag>
......@@ -211,10 +199,8 @@ private:
{
using DeviceAlgorithm = typename vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>;
using ParticleAdvectWorkletType =
vtkm::worklet::particleadvection::ParticleAdvectWorklet<IntegratorType>;
using ParticleWorkletDispatchType =
typename vtkm::worklet::DispatcherMapField<ParticleAdvectWorkletType>;
using ParticleWorkletDispatchType = typename vtkm::worklet::DispatcherMapField<
vtkm::worklet::particleadvection::ParticleAdvectWorklet>;
using StreamlineType = vtkm::worklet::particleadvection::StateRecordingParticles;
vtkm::cont::ArrayHandle<vtkm::Id> initialStepsTaken;
......@@ -222,8 +208,7 @@ private:
vtkm::Id numSeeds = static_cast<vtkm::Id>(seedArray.GetNumberOfValues());
ParticleAdvectWorkletType particleWorklet(integrator);
ParticleWorkletDispatchType particleWorkletDispatch(particleWorklet);
ParticleWorkletDispatchType particleWorkletDispatch;
particleWorkletDispatch.SetDevice(DeviceAdapterTag());
vtkm::cont::ArrayHandleIndex idxArray(numSeeds);
......@@ -237,7 +222,7 @@ private:
StreamlineType streamlines(
seedArray, history, stepsTaken, status, timeArray, validPoint, maxSteps);
particleWorkletDispatch.Invoke(idxArray, streamlines);
particleWorkletDispatch.Invoke(idxArray, integrator, streamlines);
DeviceAlgorithm::CopyIf(history, validPoint, positions, IsOne());
vtkm::cont::ArrayHandle<vtkm::Id> stepsTakenNow;
......@@ -272,6 +257,6 @@ private:
};
}
}
}
} // namespace vtkm::worklet::particleadvection
#endif // vtk_m_worklet_particleadvection_ParticleAdvectionWorklets_h
......@@ -170,27 +170,25 @@ void CreateConstantVectorField(vtkm::Id num,
DeviceAlgorithm::Copy(vecConst, vecField);
}
template <typename ScalarType, typename Evaluator>
template <typename ScalarType>
class TestEvaluatorWorklet : public vtkm::worklet::WorkletMapField
{
public:
TestEvaluatorWorklet(Evaluator e)
: evaluator(e){};
using ControlSignature = void(FieldIn<> inputPoint, FieldOut<> validity, FieldOut<> outputPoint);
using ExecutionSignature = void(_1, _2, _3);
VTKM_EXEC
void operator()(vtkm::Vec<ScalarType, 3>& pointIn,
bool& validity,
vtkm::Vec<ScalarType, 3>& pointOut) const
using ControlSignature = void(FieldIn<> inputPoint,
ExecObject evaluator,
FieldOut<> validity,
FieldOut<> outputPoint);
using ExecutionSignature = void(_1, _2, _3, _4);
template <typename EvaluatorType>
VTKM_EXEC void operator()(vtkm::Vec<ScalarType, 3>& pointIn,
const EvaluatorType& evaluator,
bool& validity,
vtkm::Vec<ScalarType, 3>& pointOut) const
{
validity = evaluator.Evaluate(pointIn, pointOut);
}
private:
Evaluator evaluator;
};
template <typename EvalType, typename ScalarType>
......@@ -200,9 +198,9 @@ void ValidateEvaluator(const EvalType& eval,
const std::string& msg)
{
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
using EvalTester = TestEvaluatorWorklet<ScalarType, EvalType>;
using EvalTester = TestEvaluatorWorklet<ScalarType>;
using EvalTesterDispatcher = vtkm::worklet::DispatcherMapField<EvalTester>;
EvalTester evalTester(eval);
EvalTester evalTester;
EvalTesterDispatcher evalTesterDispatcher(evalTester);
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> pointsHandle =
vtkm::cont::make_ArrayHandle(pointIns);
......@@ -212,7 +210,7 @@ void ValidateEvaluator(const EvalType& eval,
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> evalResults;
evalStatus.PrepareForOutput(numPoints, DeviceAdapter());
evalResults.PrepareForOutput(numPoints, DeviceAdapter());
evalTesterDispatcher.Invoke(pointsHandle, evalStatus, evalResults);
evalTesterDispatcher.Invoke(pointsHandle, eval, evalStatus, evalResults);
auto statusPortal = evalStatus.GetPortalConstControl();
auto resultsPortal = evalResults.GetPortalConstControl();
for (vtkm::Id index = 0; index < numPoints; index++)
......@@ -227,28 +225,26 @@ void ValidateEvaluator(const EvalType& eval,
evalResults.ReleaseResources();
}
template <typename ScalarType, typename Integrator>
template <typename ScalarType>
class TestIntegratorWorklet : public vtkm::worklet::WorkletMapField
{
public:
TestIntegratorWorklet(Integrator i)
: integrator(i){};
using ControlSignature = void(FieldIn<> inputPoint, FieldOut<> validity, FieldOut<> outputPoint);
using ExecutionSignature = void(_1, _2, _3);
VTKM_EXEC
void operator()(vtkm::Vec<ScalarType, 3>& pointIn,
vtkm::worklet::particleadvection::ParticleStatus& status,
vtkm::Vec<ScalarType, 3>& pointOut) const
using ControlSignature = void(FieldIn<> inputPoint,
ExecObject integrator,
FieldOut<> validity,
FieldOut<> outputPoint);
using ExecutionSignature = void(_1, _2, _3, _4);
template <typename IntegratorType>
VTKM_EXEC void operator()(vtkm::Vec<ScalarType, 3>& pointIn,
const IntegratorType* integrator,
vtkm::worklet::particleadvection::ParticleStatus& status,
vtkm::Vec<ScalarType, 3>& pointOut) const
{
ScalarType time = 0;
status = integrator.Step(pointIn, time, pointOut);
status = integrator->Step(pointIn, time, pointOut);
}
private:
Integrator integrator;
};
......@@ -259,11 +255,10 @@ void ValidateIntegrator(const IntegratorType& integrator,
const std::string& msg)
{
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
using IntegratorTester = TestIntegratorWorklet<ScalarType, IntegratorType>;
using IntegratorTester = TestIntegratorWorklet<ScalarType>;
using IntegratorTesterDispatcher = vtkm::worklet::DispatcherMapField<IntegratorTester>;
using Status = vtkm::worklet::particleadvection::ParticleStatus;
IntegratorTester integratorTester(integrator);
IntegratorTesterDispatcher integratorTesterDispatcher(integratorTester);
IntegratorTesterDispatcher integratorTesterDispatcher;
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> pointsHandle =
vtkm::cont::make_ArrayHandle(pointIns);
vtkm::Id numPoints = pointsHandle.GetNumberOfValues();
......@@ -272,7 +267,7 @@ void ValidateIntegrator(const IntegratorType& integrator,
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> stepResults;
stepStatus.PrepareForOutput(numPoints, DeviceAdapter());
stepResults.PrepareForOutput(numPoints, DeviceAdapter());
integratorTesterDispatcher.Invoke(pointsHandle, stepStatus, stepResults);
integratorTesterDispatcher.Invoke(pointsHandle, integrator, stepStatus, stepResults);
auto statusPortal = stepStatus.GetPortalConstControl();
auto resultsPortal = stepResults.GetPortalConstControl();
for (vtkm::Id index = 0; index < numPoints; index++)
......@@ -292,28 +287,20 @@ void ValidateIntegrator(const IntegratorType& integrator,
void TestEvaluators()
{
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
//Constant field evaluator and RK4 integrator.
using CEvalType = vtkm::worklet::particleadvection::ConstantField;
using RK4CType = vtkm::worklet::particleadvection::RK4Integrator<CEvalType>;
using ScalarType = vtkm::worklet::particleadvection::ScalarType;
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>;
using FieldPortalConstType = FieldHandle::template ExecutionTypes<DeviceAdapter>::PortalConst;
//Uniform grid evaluator and RK4 integrator.
using UniformEvalType =
vtkm::worklet::particleadvection::UniformGridEvaluate<FieldPortalConstType,
ScalarType,
DeviceAdapter>;
using UniformEvalType = vtkm::worklet::particleadvection::UniformGridEvaluate<FieldHandle>;
using RK4UniformType = vtkm::worklet::particleadvection::RK4Integrator<UniformEvalType>;
//Rectilinear grid evaluator and RK4 integrator.
using RectilinearEvalType =
vtkm::worklet::particleadvection::RectilinearGridEvaluate<FieldPortalConstType,
ScalarType,
DeviceAdapter>;
vtkm::worklet::particleadvection::RectilinearGridEvaluate<FieldHandle>;
using RK4RectilinearType = vtkm::worklet::particleadvection::RK4Integrator<RectilinearEvalType>;
std::vector<vtkm::Vec<ScalarType, 3>> vecs;
......@@ -413,7 +400,6 @@ void TestParticleWorklets()
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
using ScalarType = vtkm::Float32;
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>;
using FieldPortalConstType = FieldHandle::template ExecutionTypes<DeviceAdapter>::PortalConst;
ScalarType stepSize = 0.01f;
......@@ -433,9 +419,7 @@ void TestParticleWorklets()
}
vtkm::cont::DataSet ds = dataSetBuilder.Create(dims);
using RGEvalType = vtkm::worklet::particleadvection::UniformGridEvaluate<FieldPortalConstType,
ScalarType,
DeviceAdapter>;
using RGEvalType = vtkm::worklet::particleadvection::UniformGridEvaluate<FieldHandle>;
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType>;
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> fieldArray;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment