Change return type to a struct that contains the arrays from the worklet.

This commit is contained in:
Dave Pugmire 2017-07-20 07:36:57 -04:00
parent d2bc02e69e
commit 8bdf42f31c
4 changed files with 64 additions and 46 deletions

@ -163,7 +163,7 @@ void RunTest(const std::string& fname,
if (advectType == 0)
{
vtkm::worklet::ParticleAdvection particleAdvection;
particleAdvection.Run(rk4, seedArray, fieldArray, numSteps, -1, DeviceAdapter());
particleAdvection.Run(rk4, seedArray, fieldArray, numSteps, DeviceAdapter());
}
else
{

@ -30,6 +30,30 @@ namespace vtkm
namespace worklet
{
template <typename FieldType>
struct ParticleAdvectionResult
{
ParticleAdvectionResult()
: positions()
, status()
, stepsTaken()
{
}
ParticleAdvectionResult(const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>& pos,
const vtkm::cont::ArrayHandle<vtkm::Id>& stat,
const vtkm::cont::ArrayHandle<vtkm::Id>& steps)
: positions(pos)
, status(stat)
, stepsTaken(steps)
{
}
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> positions;
vtkm::cont::ArrayHandle<vtkm::Id> status;
vtkm::cont::ArrayHandle<vtkm::Id> stepsTaken;
};
class ParticleAdvection
{
public:
@ -40,19 +64,24 @@ public:
typename PointStorage,
typename FieldStorage,
typename DeviceAdapter>
vtkm::cont::DataSet Run(const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, FieldStorage> fieldArray,
const vtkm::Id& nSteps,
const vtkm::Id& particlesPerRound,
const DeviceAdapter&)
ParticleAdvectionResult<FieldType> Run(
const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, FieldStorage> fieldArray,
const vtkm::Id& nSteps,
const DeviceAdapter&)
{
vtkm::worklet::particleadvection::ParticleAdvectionWorklet<IntegratorType,
FieldType,
DeviceAdapter>
worklet;
return worklet.Run(it, pts, fieldArray, nSteps, particlesPerRound);
vtkm::cont::ArrayHandle<vtkm::Id, FieldStorage> stepsTaken, status;
worklet.Run(it, pts, fieldArray, nSteps, status, stepsTaken);
//Create output.
ParticleAdvectionResult<FieldType> res(pts, status, stepsTaken);
return res;
}
};

@ -96,66 +96,56 @@ public:
ParticleAdvectionWorklet() {}
template <typename PointStorage, typename FieldStorage>
vtkm::cont::DataSet Run(
const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, FieldStorage> fieldArray,
const vtkm::Id& nSteps,
const vtkm::Id& particlesPerRound = -1)
void Run(const IntegratorType& it,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, PointStorage>& pts,
const vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>, FieldStorage> fieldArray,
const vtkm::Id& nSteps,
vtkm::cont::ArrayHandle<vtkm::Id, FieldStorage>& statusArray,
vtkm::cont::ArrayHandle<vtkm::Id, FieldStorage>& stepsTaken)
{
integrator = it;
seedArray = pts;
maxSteps = nSteps;
ParticlesPerRound = particlesPerRound;
field = fieldArray.PrepareForInput(DeviceAdapterTag());
return run();
run(statusArray, stepsTaken);
}
~ParticleAdvectionWorklet() {}
private:
vtkm::cont::DataSet run()
template <typename FieldStorage>
void run(vtkm::cont::ArrayHandle<vtkm::Id, FieldStorage>& statusArray,
vtkm::cont::ArrayHandle<vtkm::Id, FieldStorage>& stepsTaken)
{
typedef typename vtkm::worklet::DispatcherMapField<ParticleAdvectWorkletType>
ParticleWorkletDispatchType;
typedef vtkm::worklet::particleadvection::Particles<FieldType, DeviceAdapterTag> ParticleType;
typedef typename vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag> DeviceAlgorithm;
vtkm::Id totNumSeeds = static_cast<vtkm::Id>(seedArray.GetNumberOfValues());
vtkm::Id numSeeds = totNumSeeds;
if (ParticlesPerRound == -1 || ParticlesPerRound > totNumSeeds)
numSeeds = totNumSeeds;
else
numSeeds = ParticlesPerRound;
vtkm::Id numSeeds = static_cast<vtkm::Id>(seedArray.GetNumberOfValues());
std::vector<vtkm::Id> steps(static_cast<size_t>(numSeeds), 0),
status(static_cast<size_t>(numSeeds), ParticleStatus::OK);
vtkm::cont::ArrayHandle<vtkm::Id> stepArray = vtkm::cont::make_ArrayHandle(&steps[0], numSeeds);
vtkm::cont::ArrayHandle<vtkm::Id> statusArray =
vtkm::cont::make_ArrayHandle(&status[0], numSeeds);
//Allocate status and steps arrays.
vtkm::cont::ArrayHandleConstant<vtkm::Id> ok(ParticleStatus::OK, numSeeds);
statusArray.Allocate(numSeeds);
DeviceAlgorithm::Copy(ok, statusArray);
vtkm::cont::ArrayHandleConstant<vtkm::Id> zero(0, numSeeds);
stepsTaken.Allocate(numSeeds);
DeviceAlgorithm::Copy(zero, stepsTaken);
//Create and invoke the particle advection.
vtkm::cont::ArrayHandleIndex idxArray(numSeeds);
ParticleType particles(seedArray, stepArray, statusArray, maxSteps);
ParticleType particles(seedArray, stepsTaken, statusArray, maxSteps);
ParticleAdvectWorkletType particleWorklet(integrator, field);
ParticleWorkletDispatchType particleWorkletDispatch(particleWorklet);
particleWorkletDispatch.Invoke(idxArray, particles);
vtkm::cont::DataSet output;
vtkm::cont::ArrayHandle<vtkm::Id> stepField, statusField;
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>::Copy(stepArray, stepField);
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>::Copy(statusArray, statusField);
output.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", seedArray));
output.AddField(vtkm::cont::Field("steps", vtkm::cont::Field::ASSOC_POINTS, stepField));
output.AddField(vtkm::cont::Field("status", vtkm::cont::Field::ASSOC_POINTS, statusField));
return output;
}
IntegratorType integrator;
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> seedArray;
vtkm::cont::DataSet ds;
vtkm::Id maxSteps;
vtkm::Id ParticlesPerRound;
FieldPortalConstType field;
};

@ -145,11 +145,10 @@ void TestParticleAdvection()
fieldArray = vtkm::cont::make_ArrayHandle(field);
vtkm::worklet::ParticleAdvection particleAdvection;
vtkm::cont::DataSet outData;
outData = particleAdvection.Run(rk4, seeds, fieldArray, 100, -1, DeviceAdapter());
outData.PrintSummary(std::cout);
VTKM_TEST_ASSERT(seeds.GetNumberOfValues() ==
outData.GetCoordinateSystem().GetData().GetNumberOfValues(),
vtkm::worklet::ParticleAdvectionResult<FieldType> res;
res = particleAdvection.Run(rk4, seeds, fieldArray, 1000, DeviceAdapter());
VTKM_TEST_ASSERT(res.positions.GetNumberOfValues() == seeds.GetNumberOfValues(),
"Number of output particles does not match input.");
}