mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 10:35:42 +00:00
Fixes for streamlines.
This commit is contained in:
parent
bdab4a56d2
commit
8054dfdafb
@ -72,8 +72,8 @@ inline VTKM_CONT vtkm::cont::DataSet Streamline::DoExecute(
|
||||
res = this->Worklet.Run(rk4, seedArray, this->NumberOfSteps);
|
||||
|
||||
vtkm::cont::DataSet outData;
|
||||
vtkm::cont::CoordinateSystem outputCoords("coordinates", res.positions);
|
||||
outData.SetCellSet(res.polyLines);
|
||||
vtkm::cont::CoordinateSystem outputCoords("coordinates", res.Positions);
|
||||
outData.SetCellSet(res.PolyLines);
|
||||
outData.AddCoordinateSystem(outputCoords);
|
||||
|
||||
return outData;
|
||||
|
@ -80,44 +80,24 @@ public:
|
||||
struct StreamlineResult
|
||||
{
|
||||
StreamlineResult()
|
||||
: positions()
|
||||
, polyLines()
|
||||
, status()
|
||||
, stepsTaken()
|
||||
, times()
|
||||
: Particles()
|
||||
, Positions()
|
||||
, PolyLines()
|
||||
{
|
||||
}
|
||||
|
||||
StreamlineResult(const vtkm::cont::ArrayHandle<vtkm::Vec3f>& pos,
|
||||
const vtkm::cont::CellSetExplicit<>& lines,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& stat,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& steps)
|
||||
: positions(pos)
|
||||
, polyLines(lines)
|
||||
, status(stat)
|
||||
, stepsTaken(steps)
|
||||
StreamlineResult(const vtkm::cont::ArrayHandle<vtkm::Particle>& part,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec3f>& pos,
|
||||
const vtkm::cont::CellSetExplicit<>& lines)
|
||||
: Particles(part)
|
||||
, Positions(pos)
|
||||
, PolyLines(lines)
|
||||
{
|
||||
}
|
||||
|
||||
StreamlineResult(const vtkm::cont::ArrayHandle<vtkm::Vec3f>& pos,
|
||||
const vtkm::cont::CellSetExplicit<>& lines,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& stat,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& steps,
|
||||
const vtkm::cont::ArrayHandle<vtkm::FloatDefault>& timeArray)
|
||||
|
||||
: positions(pos)
|
||||
, polyLines(lines)
|
||||
, status(stat)
|
||||
, stepsTaken(steps)
|
||||
, times(timeArray)
|
||||
{
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> positions;
|
||||
vtkm::cont::CellSetExplicit<> polyLines;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> status;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> stepsTaken;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> times;
|
||||
vtkm::cont::ArrayHandle<vtkm::Particle> Particles;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> Positions;
|
||||
vtkm::cont::CellSetExplicit<> PolyLines;
|
||||
};
|
||||
|
||||
class Streamline
|
||||
@ -137,8 +117,7 @@ public:
|
||||
|
||||
worklet.Run(it, particles, MaxSteps, positions, polyLines);
|
||||
|
||||
std::cout << "FIX ME " << __FILE__ << " " << __LINE__ << std::endl;
|
||||
return StreamlineResult();
|
||||
return StreamlineResult(particles, positions, polyLines);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -63,8 +63,8 @@ public:
|
||||
integralCurve.PreStepUpdate(idx);
|
||||
do
|
||||
{
|
||||
vtkm::Particle p = integralCurve.GetParticle(idx);
|
||||
std::cout << idx << ": " << inpos << " #" << p.NumSteps << " " << p.Status << std::endl;
|
||||
//vtkm::Particle p = integralCurve.GetParticle(idx);
|
||||
//std::cout<<idx<<": "<<inpos<<" #"<<p.NumSteps<<" "<<p.Status<<std::endl;
|
||||
vtkm::Vec3f outpos;
|
||||
auto status = integrator->Step(inpos, time, outpos);
|
||||
if (status.CheckOk())
|
||||
@ -96,9 +96,8 @@ public:
|
||||
//Mark if any steps taken
|
||||
integralCurve.UpdateTookSteps(idx, tookAnySteps);
|
||||
|
||||
particle = integralCurve.GetParticle(idx);
|
||||
std::cout << idx << ": " << inpos << " #" << particle.NumSteps << " " << particle.Status
|
||||
<< std::endl;
|
||||
//particle = integralCurve.GetParticle(idx);
|
||||
//std::cout<<idx<<": "<<inpos<<" #"<<particle.NumSteps<<" "<<particle.Status<<std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
@ -143,16 +142,34 @@ public:
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class Subtract : public vtkm::worklet::WorkletMapField
|
||||
class GetSteps : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
Subtract() {}
|
||||
using ControlSignature = void(FieldOut, FieldIn, FieldIn);
|
||||
using ExecutionSignature = void(_1, _2, _3);
|
||||
VTKM_EXEC void operator()(vtkm::Id& res, const vtkm::Id& x, const vtkm::Id& y) const
|
||||
GetSteps() {}
|
||||
using ControlSignature = void(FieldIn, FieldOut);
|
||||
using ExecutionSignature = void(_1, _2);
|
||||
VTKM_EXEC void operator()(const vtkm::Particle& p, vtkm::Id& numSteps) const
|
||||
{
|
||||
res = x - y;
|
||||
numSteps = p.NumSteps;
|
||||
}
|
||||
};
|
||||
|
||||
class ComputeNumPoints : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
ComputeNumPoints() {}
|
||||
using ControlSignature = void(FieldIn, FieldIn, FieldOut);
|
||||
using ExecutionSignature = void(_1, _2, _3);
|
||||
|
||||
// Offset is number of points in streamline.
|
||||
// 1 (inital point) + number of steps taken (p.NumSteps - initalNumSteps)
|
||||
VTKM_EXEC void operator()(const vtkm::Particle& p,
|
||||
const vtkm::Id& initialNumSteps,
|
||||
vtkm::Id& diff) const
|
||||
{
|
||||
diff = 1 + p.NumSteps - initialNumSteps;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
@ -174,12 +191,20 @@ public:
|
||||
vtkm::worklet::particleadvection::ParticleAdvectWorklet>;
|
||||
using StreamlineType = vtkm::worklet::particleadvection::StateRecordingParticles;
|
||||
|
||||
//NEED TO DEFINE THESE
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> stepsTaken, initialStepsTaken, offsets;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> initialStepsTaken;
|
||||
|
||||
vtkm::Id numSeeds = static_cast<vtkm::Id>(particles.GetNumberOfValues());
|
||||
vtkm::cont::ArrayHandleIndex idxArray(numSeeds);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<detail::GetSteps> getStepDispatcher{ (detail::GetSteps{}) };
|
||||
getStepDispatcher.Invoke(particles, initialStepsTaken);
|
||||
|
||||
#ifdef VTKM_CUDA
|
||||
// This worklet needs some extra space on CUDA.
|
||||
vtkm::cont::cuda::ScopedCudaStackSize stack(16 * 1024);
|
||||
(void)stack;
|
||||
#endif // VTKM_CUDA
|
||||
|
||||
//Run streamline worklet
|
||||
StreamlineType streamlines(particles, MaxSteps);
|
||||
ParticleWorkletDispatchType particleWorkletDispatch;
|
||||
@ -188,16 +213,15 @@ public:
|
||||
|
||||
//Get the positions
|
||||
streamlines.GetCompactedHistory(positions);
|
||||
vtkm::cont::printSummary_ArrayHandle(positions, std::cout);
|
||||
|
||||
//Create the cells
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> stepsTakenNow;
|
||||
stepsTakenNow.Allocate(numSeeds);
|
||||
vtkm::worklet::DispatcherMapField<detail::Subtract> subtractDispatcher{ (detail::Subtract{}) };
|
||||
subtractDispatcher.Invoke(stepsTakenNow, stepsTaken, initialStepsTaken);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> numPoints;
|
||||
vtkm::worklet::DispatcherMapField<detail::ComputeNumPoints> computeNumPointsDispatcher{ (
|
||||
detail::ComputeNumPoints{}) };
|
||||
computeNumPointsDispatcher.Invoke(particles, initialStepsTaken, numPoints);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellIndex;
|
||||
vtkm::Id connectivityLen = vtkm::cont::Algorithm::ScanExclusive(stepsTakenNow, cellIndex);
|
||||
vtkm::Id connectivityLen = vtkm::cont::Algorithm::ScanExclusive(numPoints, cellIndex);
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> connCount(0, 1, connectivityLen);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
|
||||
vtkm::cont::ArrayCopy(connCount, connectivity);
|
||||
@ -207,34 +231,9 @@ public:
|
||||
vtkm::cont::make_ArrayHandleConstant<vtkm::UInt8>(vtkm::CELL_SHAPE_POLY_LINE, numSeeds);
|
||||
vtkm::cont::ArrayCopy(polyLineShape, cellTypes);
|
||||
|
||||
auto numIndices = vtkm::cont::make_ArrayHandleCast(stepsTakenNow, vtkm::IdComponent());
|
||||
//auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
|
||||
auto numIndices = vtkm::cont::make_ArrayHandleCast(numPoints, vtkm::IdComponent());
|
||||
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
|
||||
polyLines.Fill(positions.GetNumberOfValues(), cellTypes, connectivity, offsets);
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
using ParticleAdvectWorkletType = vtkm::worklet::particleadvection::StreamlineWorkletAOS;
|
||||
using ParticleWorkletDispatchType =
|
||||
typename vtkm::worklet::DispatcherMapField<ParticleAdvectWorkletType>;
|
||||
|
||||
|
||||
vtkm::Id numSeeds = static_cast<vtkm::Id>(particles.GetNumberOfValues());
|
||||
//Create and invoke the particle advection.
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id> maxSteps(MaxSteps, numSeeds);
|
||||
vtkm::cont::ArrayHandleIndex idxArray(numSeeds);
|
||||
|
||||
#ifdef VTKM_CUDA
|
||||
// This worklet needs some extra space on CUDA.
|
||||
vtkm::cont::cuda::ScopedCudaStackSize stack(16 * 1024);
|
||||
(void)stack;
|
||||
#endif // VTKM_CUDA
|
||||
|
||||
//Invoke particle advection worklet
|
||||
ParticleWorkletDispatchType particleWorkletDispatch;
|
||||
particleWorkletDispatch.Invoke(idxArray, it, particles, maxSteps);
|
||||
*/
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -139,6 +139,7 @@ public:
|
||||
: ParticleExecutionObject<Device>()
|
||||
, History()
|
||||
, Length(0)
|
||||
, StepCount()
|
||||
, ValidPoint()
|
||||
{
|
||||
}
|
||||
@ -147,6 +148,7 @@ public:
|
||||
StateRecordingParticleExecutionObject(vtkm::cont::ArrayHandle<vtkm::Particle> pArray,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> historyArray,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> validPointArray,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> stepCountArray,
|
||||
vtkm::Id maxSteps)
|
||||
: ParticleExecutionObject<Device>(pArray, maxSteps)
|
||||
, Length(maxSteps + 1)
|
||||
@ -154,6 +156,7 @@ public:
|
||||
vtkm::Id numPos = pArray.GetNumberOfValues();
|
||||
History = historyArray.PrepareForOutput(numPos * Length, Device());
|
||||
ValidPoint = validPointArray.PrepareForInPlace(Device());
|
||||
StepCount = stepCountArray.PrepareForInPlace(Device());
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
@ -163,9 +166,10 @@ public:
|
||||
if (p.NumSteps == 0)
|
||||
{
|
||||
vtkm::Id loc = idx * Length;
|
||||
std::cout << "PreStepUpdate " << idx << ": loc= " << loc << " " << p.Pos << std::endl;
|
||||
//std::cout<<"PreStepUpdate "<<idx<<": loc= "<<loc<<" "<<p.Pos<<std::endl;
|
||||
this->History.Set(loc, p.Pos);
|
||||
this->ValidPoint.Set(loc, 1);
|
||||
this->StepCount.Set(idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,12 +178,16 @@ public:
|
||||
{
|
||||
this->ParticleExecutionObject<Device>::StepUpdate(idx, time, pt);
|
||||
|
||||
vtkm::Particle p = this->ParticleExecutionObject<Device>::GetParticle(idx);
|
||||
//vtkm::Particle p = this->ParticleExecutionObject<Device>::GetParticle(idx);
|
||||
|
||||
vtkm::Id loc = idx * Length + p.NumSteps;
|
||||
std::cout << "StepUpdate " << idx << ": loc= " << loc << " " << pt << std::endl;
|
||||
//local step count.
|
||||
vtkm::Id stepCount = this->StepCount.Get(idx);
|
||||
|
||||
vtkm::Id loc = idx * Length + stepCount;
|
||||
//std::cout<<"StepUpdate "<<idx<<": loc= "<<loc<<" "<<pt<<std::endl;
|
||||
this->History.Set(loc, pt);
|
||||
this->ValidPoint.Set(loc, 1);
|
||||
this->StepCount.Set(idx, stepCount + 1);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -190,6 +198,7 @@ protected:
|
||||
|
||||
HistoryPortal History;
|
||||
vtkm::Id Length;
|
||||
IdPortal StepCount;
|
||||
IdPortal ValidPoint;
|
||||
};
|
||||
|
||||
@ -201,7 +210,11 @@ public:
|
||||
PrepareForExecution(Device) const
|
||||
{
|
||||
return vtkm::worklet::particleadvection::StateRecordingParticleExecutionObject<Device>(
|
||||
ParticleArray, HistoryArray, ValidPointArray, MaxSteps);
|
||||
this->ParticleArray,
|
||||
this->HistoryArray,
|
||||
this->ValidPointArray,
|
||||
this->StepCountArray,
|
||||
this->MaxSteps);
|
||||
}
|
||||
VTKM_CONT
|
||||
StateRecordingParticles(vtkm::cont::ArrayHandle<vtkm::Particle>& pArray, const vtkm::Id& maxSteps)
|
||||
@ -209,9 +222,14 @@ public:
|
||||
, ParticleArray(pArray)
|
||||
{
|
||||
vtkm::Id numParticles = static_cast<vtkm::Id>(pArray.GetNumberOfValues());
|
||||
std::cout << "ctor size: " << this->MaxSteps + 1 << " " << numParticles << std::endl;
|
||||
|
||||
//Create ValidPointArray initialized to zero.
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id> tmp(0, (this->MaxSteps + 1) * numParticles);
|
||||
vtkm::cont::ArrayCopy(tmp, this->ValidPointArray);
|
||||
|
||||
//Create StepCountArray initialized to zero.
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id> tmp2(0, numParticles);
|
||||
vtkm::cont::ArrayCopy(tmp2, this->StepCountArray);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -236,6 +254,7 @@ protected:
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> HistoryArray;
|
||||
vtkm::Id MaxSteps;
|
||||
vtkm::cont::ArrayHandle<vtkm::Particle> ParticleArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> StepCountArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> ValidPointArray;
|
||||
|
||||
struct IsOne
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifndef vtk_m_worklet_particleadvection_TemporalGridEvaluators_h
|
||||
#define vtk_m_worklet_particleadvection_TemporalGridEvaluators_h
|
||||
|
||||
#include <vtkm/worklet/particleadvection/GridEvaluatorStatus.h>
|
||||
#include <vtkm/worklet/particleadvection/GridEvaluators.h>
|
||||
|
||||
namespace vtkm
|
||||
@ -68,10 +69,12 @@ public:
|
||||
}
|
||||
|
||||
template <typename Point>
|
||||
VTKM_EXEC EvaluatorStatus Evaluate(const Point& pos, vtkm::FloatDefault time, Point& out) const
|
||||
VTKM_EXEC GridEvaluatorStatus Evaluate(const Point& pos,
|
||||
vtkm::FloatDefault time,
|
||||
Point& out) const
|
||||
{
|
||||
// Validate time is in bounds for the current two slices.
|
||||
EvaluatorStatus status;
|
||||
GridEvaluatorStatus status;
|
||||
|
||||
if (!(time >= TimeOne && time <= TimeTwo))
|
||||
{
|
||||
@ -91,6 +94,8 @@ public:
|
||||
// LERP between the two values of calculated fields to obtain the new value
|
||||
vtkm::FloatDefault proportion = (time - this->TimeOne) / this->TimeDiff;
|
||||
out = vtkm::Lerp(one, two, proportion);
|
||||
|
||||
status.SetOk();
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ set(unit_tests
|
||||
UnitTestStreamLineUniformGrid.cxx
|
||||
UnitTestStreamSurface.cxx
|
||||
UnitTestSurfaceNormals.cxx
|
||||
# UnitTestTemporalAdvection.cxx
|
||||
UnitTestTemporalAdvection.cxx
|
||||
UnitTestTetrahedralize.cxx
|
||||
UnitTestThreshold.cxx
|
||||
UnitTestThresholdPoints.cxx
|
||||
|
@ -534,23 +534,33 @@ void ValidateParticleAdvectionResult(const vtkm::worklet::ParticleAdvectionResul
|
||||
VTKM_TEST_ASSERT(res.Particles.GetNumberOfValues() == nSeeds,
|
||||
"Number of output particles does not match input.");
|
||||
for (vtkm::Id i = 0; i < nSeeds; i++)
|
||||
{
|
||||
VTKM_TEST_ASSERT(res.Particles.GetPortalConstControl().Get(i).NumSteps <= maxSteps,
|
||||
"Too many steps taken in particle advection");
|
||||
VTKM_TEST_ASSERT(res.Particles.GetPortalConstControl().Get(i).Status.CheckOk(),
|
||||
"Bad status in particle advection");
|
||||
}
|
||||
}
|
||||
|
||||
void ValidateStreamlineResult(const vtkm::worklet::StreamlineResult& res,
|
||||
vtkm::Id nSeeds,
|
||||
vtkm::Id maxSteps)
|
||||
{
|
||||
VTKM_TEST_ASSERT(res.polyLines.GetNumberOfCells() == nSeeds,
|
||||
VTKM_TEST_ASSERT(res.PolyLines.GetNumberOfCells() == nSeeds,
|
||||
"Number of output streamlines does not match input.");
|
||||
|
||||
for (vtkm::Id i = 0; i < nSeeds; i++)
|
||||
VTKM_TEST_ASSERT(res.stepsTaken.GetPortalConstControl().Get(i) <= maxSteps,
|
||||
{
|
||||
VTKM_TEST_ASSERT(res.Particles.GetPortalConstControl().Get(i).NumSteps <= maxSteps,
|
||||
"Too many steps taken in streamline");
|
||||
VTKM_TEST_ASSERT(res.Particles.GetPortalConstControl().Get(i).Status.CheckOk(),
|
||||
"Bad status in streamline");
|
||||
}
|
||||
VTKM_TEST_ASSERT(res.Particles.GetNumberOfValues() == nSeeds,
|
||||
"Number of output particles does not match input.");
|
||||
}
|
||||
|
||||
void TestParticleWorklets()
|
||||
void TestParticleWorkletsWithDataSetTypes()
|
||||
{
|
||||
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
|
||||
using GridEvalType = vtkm::worklet::particleadvection::GridEvaluator<FieldHandle>;
|
||||
@ -641,9 +651,7 @@ void TestParticleWorklets()
|
||||
auto seeds = vtkm::cont::make_ArrayHandle(pts2, vtkm::CopyFlag::On);
|
||||
res = s.Run(rk4, seeds, maxSteps);
|
||||
}
|
||||
|
||||
std::cout << "FIX ME.. Add some testing " << __FILE__ << " " << __LINE__ << std::endl;
|
||||
//ValidateStreamlineResult(res, nSeeds, maxSteps);
|
||||
ValidateStreamlineResult(res, nSeeds, maxSteps);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -688,7 +696,7 @@ void TestParticleStatus()
|
||||
VTKM_TEST_ASSERT(tookStep1 == false, "Particle took a step when it should not have.");
|
||||
}
|
||||
|
||||
void TestStreamline()
|
||||
void TestWorkletsBasic()
|
||||
{
|
||||
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
|
||||
using GridEvalType = vtkm::worklet::particleadvection::GridEvaluator<FieldHandle>;
|
||||
@ -699,14 +707,10 @@ void TestStreamline()
|
||||
vtkm::Id nElements = dims[0] * dims[1] * dims[2] * 3;
|
||||
|
||||
std::vector<vtkm::Vec3f> field;
|
||||
vtkm::Vec3f vecDir(1, 0, 0);
|
||||
for (vtkm::Id i = 0; i < nElements; i++)
|
||||
{
|
||||
vtkm::FloatDefault x = vecData[i];
|
||||
vtkm::FloatDefault y = vecData[++i];
|
||||
vtkm::FloatDefault z = vecData[++i];
|
||||
vtkm::Vec3f vec(x, y, z);
|
||||
field.push_back(vtkm::Normal(vec));
|
||||
}
|
||||
field.push_back(vtkm::Normal(vecDir));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> fieldArray;
|
||||
fieldArray = vtkm::cont::make_ArrayHandle(field);
|
||||
|
||||
@ -716,24 +720,112 @@ void TestStreamline()
|
||||
GridEvalType eval(ds.GetCoordinateSystem(), ds.GetCellSet(), fieldArray);
|
||||
RK4Type rk4(eval, stepSize);
|
||||
|
||||
std::vector<vtkm::Particle> pts;
|
||||
pts.push_back(vtkm::Particle(vtkm::Vec3f(.5, .5, .5), 0));
|
||||
auto seedsArray = vtkm::cont::make_ArrayHandle(pts, vtkm::CopyFlag::On);
|
||||
vtkm::Id maxSteps = 100;
|
||||
vtkm::Id maxSteps = 83;
|
||||
std::vector<std::string> workletTypes = { "particleAdvection", "streamline" };
|
||||
vtkm::FloatDefault endT = stepSize * maxSteps;
|
||||
|
||||
vtkm::worklet::Streamline s;
|
||||
vtkm::worklet::StreamlineResult res;
|
||||
for (auto w : workletTypes)
|
||||
{
|
||||
std::vector<vtkm::Particle> particles;
|
||||
std::vector<vtkm::Vec3f> pts, samplePts, endPts;
|
||||
vtkm::FloatDefault X = static_cast<vtkm::FloatDefault>(.1);
|
||||
vtkm::FloatDefault Y = static_cast<vtkm::FloatDefault>(.1);
|
||||
vtkm::FloatDefault Z = static_cast<vtkm::FloatDefault>(.1);
|
||||
|
||||
res = s.Run(rk4, seedsArray, maxSteps);
|
||||
std::cout << "FIX ME.. Add some testing " << __FILE__ << " " << __LINE__ << std::endl;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
pts.push_back(vtkm::Vec3f(X, Y, Z));
|
||||
Y += static_cast<vtkm::FloatDefault>(.1);
|
||||
}
|
||||
|
||||
vtkm::Id id = 0;
|
||||
for (std::size_t i = 0; i < pts.size(); i++, id++)
|
||||
{
|
||||
vtkm::Vec3f p = pts[i];
|
||||
particles.push_back(vtkm::Particle(p, id));
|
||||
samplePts.push_back(p);
|
||||
for (vtkm::Id j = 0; j < maxSteps; j++)
|
||||
{
|
||||
p = p + vecDir * stepSize;
|
||||
samplePts.push_back(p);
|
||||
}
|
||||
endPts.push_back(p);
|
||||
}
|
||||
|
||||
auto seedsArray = vtkm::cont::make_ArrayHandle(particles, vtkm::CopyFlag::On);
|
||||
|
||||
if (w == "particleAdvection")
|
||||
{
|
||||
vtkm::worklet::ParticleAdvection pa;
|
||||
vtkm::worklet::ParticleAdvectionResult res;
|
||||
|
||||
res = pa.Run(rk4, seedsArray, maxSteps);
|
||||
|
||||
vtkm::Id numRequiredPoints = static_cast<vtkm::Id>(endPts.size());
|
||||
VTKM_TEST_ASSERT(res.Particles.GetNumberOfValues() == numRequiredPoints,
|
||||
"Wrong number of points in particle advection result.");
|
||||
auto portal = res.Particles.GetPortalConstControl();
|
||||
for (vtkm::Id i = 0; i < res.Particles.GetNumberOfValues(); i++)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(i).Pos == endPts[i], "Particle advection point is wrong");
|
||||
VTKM_TEST_ASSERT(portal.Get(i).NumSteps == maxSteps,
|
||||
"Particle advection NumSteps is wrong");
|
||||
VTKM_TEST_ASSERT(vtkm::Abs(portal.Get(i).Time - endT) < stepSize / 100,
|
||||
"Particle advection Time is wrong");
|
||||
VTKM_TEST_ASSERT(portal.Get(i).Status.CheckOk(), "Particle advection Status is wrong");
|
||||
VTKM_TEST_ASSERT(portal.Get(i).Status.CheckTerminate(),
|
||||
"Particle advection particle did not terminate");
|
||||
}
|
||||
}
|
||||
else if (w == "streamline")
|
||||
{
|
||||
vtkm::worklet::Streamline s;
|
||||
vtkm::worklet::StreamlineResult res;
|
||||
|
||||
res = s.Run(rk4, seedsArray, maxSteps);
|
||||
|
||||
vtkm::Id numRequiredPoints = static_cast<vtkm::Id>(samplePts.size());
|
||||
VTKM_TEST_ASSERT(res.Positions.GetNumberOfValues() == numRequiredPoints,
|
||||
"Wrong number of points in streamline result.");
|
||||
|
||||
//Make sure all the points match.
|
||||
auto parPortal = res.Particles.GetPortalConstControl();
|
||||
for (vtkm::Id i = 0; i < res.Particles.GetNumberOfValues(); i++)
|
||||
{
|
||||
VTKM_TEST_ASSERT(parPortal.Get(i).Pos == endPts[i], "Streamline end point is wrong");
|
||||
VTKM_TEST_ASSERT(parPortal.Get(i).NumSteps == maxSteps, "Streamline NumSteps is wrong");
|
||||
VTKM_TEST_ASSERT(vtkm::Abs(parPortal.Get(i).Time - endT) < stepSize / 100,
|
||||
"Streamline Time is wrong");
|
||||
VTKM_TEST_ASSERT(parPortal.Get(i).Status.CheckOk(), "Streamline Status is wrong");
|
||||
VTKM_TEST_ASSERT(parPortal.Get(i).Status.CheckTerminate(),
|
||||
"Streamline particle did not terminate");
|
||||
}
|
||||
|
||||
auto posPortal = res.Positions.GetPortalConstControl();
|
||||
for (vtkm::Id i = 0; i < res.Positions.GetNumberOfValues(); i++)
|
||||
VTKM_TEST_ASSERT(posPortal.Get(i) == samplePts[i], "Streamline points do not match");
|
||||
|
||||
vtkm::Id numCells = res.PolyLines.GetNumberOfCells();
|
||||
VTKM_TEST_ASSERT(numCells == static_cast<vtkm::Id>(pts.size()),
|
||||
"Wrong number of polylines in streamline");
|
||||
for (vtkm::Id i = 0; i < numCells; i++)
|
||||
{
|
||||
VTKM_TEST_ASSERT(res.PolyLines.GetCellShape(i) == vtkm::CELL_SHAPE_POLY_LINE,
|
||||
"Wrong cell type in streamline.");
|
||||
VTKM_TEST_ASSERT(res.PolyLines.GetNumberOfPointsInCell(i) ==
|
||||
static_cast<vtkm::Id>(maxSteps + 1),
|
||||
"Wrong number of points in streamline cell");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TestParticleAdvection()
|
||||
{
|
||||
TestStreamline();
|
||||
TestEvaluators();
|
||||
TestParticleWorklets();
|
||||
TestParticleStatus();
|
||||
TestWorkletsBasic();
|
||||
TestParticleWorkletsWithDataSetTypes();
|
||||
}
|
||||
|
||||
int UnitTestParticleAdvection(int argc, char* argv[])
|
||||
|
@ -39,7 +39,6 @@ vtkm::cont::DataSet CreateUniformDataSet(const vtkm::Bounds& bounds, const vtkm:
|
||||
return ds;
|
||||
}
|
||||
|
||||
template <typename ScalarType>
|
||||
class TestEvaluatorWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
@ -51,29 +50,30 @@ public:
|
||||
using ExecutionSignature = void(_1, _2, _3, _4);
|
||||
|
||||
template <typename EvaluatorType>
|
||||
VTKM_EXEC void operator()(vtkm::Vec<ScalarType, 3>& pointIn,
|
||||
VTKM_EXEC void operator()(vtkm::Particle& pointIn,
|
||||
const EvaluatorType& evaluator,
|
||||
vtkm::worklet::particleadvection::EvaluatorStatus& status,
|
||||
vtkm::Vec<ScalarType, 3>& pointOut) const
|
||||
vtkm::worklet::particleadvection::GridEvaluatorStatus& status,
|
||||
vtkm::Vec3f& pointOut) const
|
||||
{
|
||||
status = evaluator.Evaluate(pointIn, 0.5f, pointOut);
|
||||
status = evaluator.Evaluate(pointIn.Pos, 0.5f, pointOut);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename EvalType, typename ScalarType>
|
||||
template <typename EvalType>
|
||||
void ValidateEvaluator(const EvalType& eval,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& pointIns,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& validity,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Particle>& pointIns,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec3f>& validity,
|
||||
const std::string& msg)
|
||||
{
|
||||
using EvalTester = TestEvaluatorWorklet<ScalarType>;
|
||||
using EvalTester = TestEvaluatorWorklet;
|
||||
using EvalTesterDispatcher = vtkm::worklet::DispatcherMapField<EvalTester>;
|
||||
using Status = vtkm::worklet::particleadvection::EvaluatorStatus;
|
||||
using Status = vtkm::worklet::particleadvection::GridEvaluatorStatus;
|
||||
|
||||
EvalTester evalTester;
|
||||
EvalTesterDispatcher evalTesterDispatcher(evalTester);
|
||||
vtkm::Id numPoints = pointIns.GetNumberOfValues();
|
||||
vtkm::cont::ArrayHandle<Status> evalStatus;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>> evalResults;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> evalResults;
|
||||
evalTesterDispatcher.Invoke(pointIns, eval, evalStatus, evalResults);
|
||||
auto statusPortal = evalStatus.GetPortalConstControl();
|
||||
auto resultsPortal = evalResults.GetPortalConstControl();
|
||||
@ -81,8 +81,8 @@ void ValidateEvaluator(const EvalType& eval,
|
||||
for (vtkm::Id index = 0; index < numPoints; index++)
|
||||
{
|
||||
Status status = statusPortal.Get(index);
|
||||
vtkm::Vec<ScalarType, 3> result = resultsPortal.Get(index);
|
||||
vtkm::Vec<ScalarType, 3> expected = validityPortal.Get(index);
|
||||
vtkm::Vec3f result = resultsPortal.Get(index);
|
||||
vtkm::Vec3f expected = validityPortal.Get(index);
|
||||
VTKM_TEST_ASSERT(status.CheckOk(), "Error in evaluator for " + msg);
|
||||
VTKM_TEST_ASSERT(result == expected, "Error in evaluator result for " + msg);
|
||||
}
|
||||
@ -100,45 +100,45 @@ void CreateConstantVectorField(vtkm::Id num,
|
||||
vtkm::cont::ArrayCopy(vecConst, vecField);
|
||||
}
|
||||
|
||||
template <typename ScalarType>
|
||||
vtkm::Vec<ScalarType, 3> RandomPoint(const vtkm::Bounds& bounds)
|
||||
vtkm::Vec3f RandomPt(const vtkm::Bounds& bounds)
|
||||
{
|
||||
ScalarType rx = static_cast<ScalarType>(rand()) / static_cast<ScalarType>(RAND_MAX);
|
||||
ScalarType ry = static_cast<ScalarType>(rand()) / static_cast<ScalarType>(RAND_MAX);
|
||||
ScalarType rz = static_cast<ScalarType>(rand()) / static_cast<ScalarType>(RAND_MAX);
|
||||
vtkm::FloatDefault rx =
|
||||
static_cast<vtkm::FloatDefault>(rand()) / static_cast<vtkm::FloatDefault>(RAND_MAX);
|
||||
vtkm::FloatDefault ry =
|
||||
static_cast<vtkm::FloatDefault>(rand()) / static_cast<vtkm::FloatDefault>(RAND_MAX);
|
||||
vtkm::FloatDefault rz =
|
||||
static_cast<vtkm::FloatDefault>(rand()) / static_cast<vtkm::FloatDefault>(RAND_MAX);
|
||||
|
||||
vtkm::Vec<ScalarType, 3> p;
|
||||
p[0] = static_cast<ScalarType>(bounds.X.Min + rx * bounds.X.Length());
|
||||
p[1] = static_cast<ScalarType>(bounds.Y.Min + ry * bounds.Y.Length());
|
||||
p[2] = static_cast<ScalarType>(bounds.Z.Min + rz * bounds.Z.Length());
|
||||
vtkm::Vec3f p;
|
||||
p[0] = static_cast<vtkm::FloatDefault>(bounds.X.Min + rx * bounds.X.Length());
|
||||
p[1] = static_cast<vtkm::FloatDefault>(bounds.Y.Min + ry * bounds.Y.Length());
|
||||
p[2] = static_cast<vtkm::FloatDefault>(bounds.Z.Min + rz * bounds.Z.Length());
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename ScalarType>
|
||||
void GeneratePoints(const vtkm::Id numOfEntries,
|
||||
const vtkm::Bounds& bounds,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& pointIns)
|
||||
vtkm::cont::ArrayHandle<vtkm::Particle>& pointIns)
|
||||
{
|
||||
pointIns.Allocate(numOfEntries);
|
||||
auto writePortal = pointIns.GetPortalControl();
|
||||
for (vtkm::Id index = 0; index < numOfEntries; index++)
|
||||
{
|
||||
vtkm::Vec<ScalarType, 3> value = RandomPoint<ScalarType>(bounds);
|
||||
writePortal.Set(index, value);
|
||||
vtkm::Particle particle(RandomPt(bounds), index);
|
||||
writePortal.Set(index, particle);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ScalarType>
|
||||
void GenerateValidity(const vtkm::Id numOfEntries,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<ScalarType, 3>>& validity,
|
||||
const vtkm::Vec<ScalarType, 3>& vecOne,
|
||||
const vtkm::Vec<ScalarType, 3>& vecTwo)
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f>& validity,
|
||||
const vtkm::Vec3f& vecOne,
|
||||
const vtkm::Vec3f& vecTwo)
|
||||
{
|
||||
validity.Allocate(numOfEntries);
|
||||
auto writePortal = validity.GetPortalControl();
|
||||
for (vtkm::Id index = 0; index < numOfEntries; index++)
|
||||
{
|
||||
vtkm::Vec<ScalarType, 3> value = 0.5f * vecOne + (1.0f - 0.5f) * vecTwo;
|
||||
vtkm::Vec3f value = 0.5f * vecOne + (1.0f - 0.5f) * vecTwo;
|
||||
writePortal.Set(index, value);
|
||||
}
|
||||
}
|
||||
@ -170,7 +170,8 @@ void TestTemporalEvaluators()
|
||||
|
||||
// Test data : populate with meaningful values
|
||||
vtkm::Id numValues = 10;
|
||||
vtkm::cont::ArrayHandle<PointType> pointIns, validity;
|
||||
vtkm::cont::ArrayHandle<vtkm::Particle> pointIns;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> validity;
|
||||
GeneratePoints(numValues, bounds, pointIns);
|
||||
GenerateValidity(numValues, validity, X, Z);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user