Added a version that directly uses ArrayHandle<vtkm::Particle>
This commit is contained in:
parent
0c70950596
commit
28a73494b1
@ -82,7 +82,7 @@ int main(int argc, char** argv)
|
|||||||
//create seeds randomly placed withing the bounding box of the data.
|
//create seeds randomly placed withing the bounding box of the data.
|
||||||
vtkm::Bounds bounds = ds.GetCoordinateSystem().GetBounds();
|
vtkm::Bounds bounds = ds.GetCoordinateSystem().GetBounds();
|
||||||
std::vector<vtkm::Vec3f> seeds;
|
std::vector<vtkm::Vec3f> seeds;
|
||||||
std::vector<vtkm::Particle> particles;
|
std::vector<vtkm::Particle> particles, particles2;
|
||||||
|
|
||||||
for (int i = 0; i < numSeeds; i++)
|
for (int i = 0; i < numSeeds; i++)
|
||||||
{
|
{
|
||||||
@ -101,10 +101,12 @@ int main(int argc, char** argv)
|
|||||||
pa.Pos = p;
|
pa.Pos = p;
|
||||||
pa.NumSteps = 0;
|
pa.NumSteps = 0;
|
||||||
particles.push_back(pa);
|
particles.push_back(pa);
|
||||||
|
particles2.push_back(pa);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto seedArrayPts = vtkm::cont::make_ArrayHandle(seeds);
|
auto seedArrayPts = vtkm::cont::make_ArrayHandle(seeds);
|
||||||
auto seedArrayPar = vtkm::cont::make_ArrayHandle(particles);
|
auto seedArrayPar = vtkm::cont::make_ArrayHandle(particles);
|
||||||
|
auto seedArrayPar2 = vtkm::cont::make_ArrayHandle(particles2);
|
||||||
|
|
||||||
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
|
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
|
||||||
using GridEvalType = vtkm::worklet::particleadvection::GridEvaluator<FieldHandle>;
|
using GridEvalType = vtkm::worklet::particleadvection::GridEvaluator<FieldHandle>;
|
||||||
@ -131,12 +133,21 @@ int main(int argc, char** argv)
|
|||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
auto s = std::chrono::system_clock::now();
|
auto s = std::chrono::system_clock::now();
|
||||||
auto res1 = paPART.Run(rk4, seedArrayPar, numSteps);
|
auto res1 = paPART.Run(rk4, seedArrayPar, numSteps, 0);
|
||||||
auto e = std::chrono::system_clock::now();
|
auto e = std::chrono::system_clock::now();
|
||||||
dT = e - s;
|
dT = e - s;
|
||||||
std::cout << "AOS_Time= " << dT.count() << std::endl;
|
std::cout << "AOS_Time= " << dT.count() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (1)
|
||||||
|
{
|
||||||
|
auto s = std::chrono::system_clock::now();
|
||||||
|
auto res1 = paPART.Run(rk4, seedArrayPar2, numSteps, 1);
|
||||||
|
auto e = std::chrono::system_clock::now();
|
||||||
|
dT = e - s;
|
||||||
|
std::cout << "AOS2_Time= " << dT.count() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
//compute streamlines
|
//compute streamlines
|
||||||
vtkm::filter::Streamline streamline;
|
vtkm::filter::Streamline streamline;
|
||||||
|
@ -29,12 +29,37 @@ enum ParticleStatus : vtkm::Id
|
|||||||
class Particle
|
class Particle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Particle() {}
|
VTKM_EXEC_CONT
|
||||||
Particle(const vtkm::Vec3f& p, vtkm::Id id, vtkm::Id numSteps)
|
Particle()
|
||||||
|
: Pos()
|
||||||
|
, ID(-1)
|
||||||
|
, NumSteps(0)
|
||||||
|
, Status(vtkm::ParticleStatus::UNDEFINED)
|
||||||
|
, Time(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
Particle(const vtkm::Particle& p)
|
||||||
|
: Pos(p.Pos)
|
||||||
|
, ID(p.ID)
|
||||||
|
, NumSteps(p.NumSteps)
|
||||||
|
, Status(p.Status)
|
||||||
|
, Time(p.Time)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
Particle(const vtkm::Vec3f& p,
|
||||||
|
vtkm::Id id,
|
||||||
|
vtkm::Id numSteps,
|
||||||
|
vtkm::Id status = vtkm::ParticleStatus::UNDEFINED,
|
||||||
|
vtkm::FloatDefault time = 0)
|
||||||
: Pos(p)
|
: Pos(p)
|
||||||
, ID(id)
|
, ID(id)
|
||||||
, NumSteps(numSteps)
|
, NumSteps(numSteps)
|
||||||
, Status(vtkm::ParticleStatus::UNDEFINED)
|
, Status(status)
|
||||||
|
, Time(time)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,27 +139,17 @@ public:
|
|||||||
template <typename IntegratorType, typename ParticleStorage>
|
template <typename IntegratorType, typename ParticleStorage>
|
||||||
ParticleAdvectionResult Run(const IntegratorType& it,
|
ParticleAdvectionResult Run(const IntegratorType& it,
|
||||||
vtkm::cont::ArrayHandle<vtkm::Particle, ParticleStorage>& particles,
|
vtkm::cont::ArrayHandle<vtkm::Particle, ParticleStorage>& particles,
|
||||||
const vtkm::Id& MaxSteps)
|
const vtkm::Id& MaxSteps,
|
||||||
|
int which)
|
||||||
{
|
{
|
||||||
vtkm::worklet::particleadvection::ParticleAdvectionWorklet<IntegratorType> worklet;
|
vtkm::worklet::particleadvection::ParticleAdvectionWorklet<IntegratorType> worklet;
|
||||||
|
|
||||||
worklet.Run(it, particles, MaxSteps);
|
if (which == 0)
|
||||||
|
worklet.Run(it, particles, MaxSteps);
|
||||||
|
else
|
||||||
|
worklet.Run2(it, particles, MaxSteps);
|
||||||
|
|
||||||
return ParticleAdvectionResult();
|
return ParticleAdvectionResult();
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
vtkm::Id numSeeds = static_cast<vtkm::Id>(particles.GetNumberOfValues());
|
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> status;
|
|
||||||
//Allocate status arrays.
|
|
||||||
vtkm::cont::ArrayHandleConstant<vtkm::Id> statusOK(static_cast<vtkm::Id>(1), numSeeds);
|
|
||||||
status.Allocate(numSeeds);
|
|
||||||
vtkm::cont::ArrayCopy(statusOK, status);
|
|
||||||
|
|
||||||
worklet.Run(it, pts, nSteps, status, inputSteps, inputTime);
|
|
||||||
//Create output.
|
|
||||||
return ParticleAdvectionResult(pts, status, inputSteps, inputTime);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,6 +101,92 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ParticleAdvectWorkletAOS2 : public vtkm::worklet::WorkletMapField
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using ControlSignature = void(ExecObject integrator, FieldInOut particles, FieldIn maxSteps);
|
||||||
|
using ExecutionSignature = void(_1, _2, _3);
|
||||||
|
using InputDomain = _3;
|
||||||
|
|
||||||
|
template <typename IntegratorType, typename ParticleType>
|
||||||
|
VTKM_EXEC void operator()(const IntegratorType* integrator,
|
||||||
|
ParticleType& particle,
|
||||||
|
const vtkm::Id& maxSteps) const
|
||||||
|
|
||||||
|
{
|
||||||
|
vtkm::Vec3f inpos = particle.Pos, outpos;
|
||||||
|
vtkm::FloatDefault time = particle.Time;
|
||||||
|
IntegratorStatus status;
|
||||||
|
bool tookAnySteps = false;
|
||||||
|
while ((particle.Status & ParticleStatus::SUCCESS) != 0)
|
||||||
|
{
|
||||||
|
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 == IntegratorStatus::SUCCESS)
|
||||||
|
{
|
||||||
|
//particle.TakeStep(idx, outpos, time);
|
||||||
|
particle.Pos = outpos;
|
||||||
|
particle.NumSteps++;
|
||||||
|
particle.Time = time;
|
||||||
|
if (particle.NumSteps == maxSteps)
|
||||||
|
{
|
||||||
|
particle.Status &= ~ParticleStatus::SUCCESS;
|
||||||
|
particle.Status |= ParticleStatus::TERMINATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
inpos = outpos;
|
||||||
|
tookAnySteps = true;
|
||||||
|
}
|
||||||
|
// If the particle is at spatial or temporal boundary, take steps to just
|
||||||
|
// push it a little out of the boundary so that it will start advection in
|
||||||
|
// another domain, or in another time slice. Taking small steps enables
|
||||||
|
// reducing the error introduced at spatial or temporal boundaries.
|
||||||
|
else if (status == IntegratorStatus::OUTSIDE_TEMPORAL_BOUNDS)
|
||||||
|
{
|
||||||
|
particle.Status &= ~ParticleStatus::SUCCESS;
|
||||||
|
particle.Status |= ParticleStatus::EXIT_TEMPORAL_BOUNDARY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (status == IntegratorStatus::OUTSIDE_SPATIAL_BOUNDS)
|
||||||
|
{
|
||||||
|
status = integrator->SmallStep(inpos, time, outpos);
|
||||||
|
//particle.TakeStep(idx, outpos, time);
|
||||||
|
particle.Pos = outpos;
|
||||||
|
particle.NumSteps++;
|
||||||
|
particle.Time = time;
|
||||||
|
|
||||||
|
if (status == IntegratorStatus::OUTSIDE_TEMPORAL_BOUNDS)
|
||||||
|
{
|
||||||
|
particle.Status &= ~ParticleStatus::SUCCESS;
|
||||||
|
particle.Status |= ParticleStatus::EXIT_TEMPORAL_BOUNDARY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (status == IntegratorStatus::OUTSIDE_SPATIAL_BOUNDS)
|
||||||
|
{
|
||||||
|
particle.Status &= ~ParticleStatus::SUCCESS;
|
||||||
|
particle.Status |= ParticleStatus::EXIT_SPATIAL_BOUNDARY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (status == IntegratorStatus::FAIL)
|
||||||
|
{
|
||||||
|
particle.Status &= ~ParticleStatus::SUCCESS;
|
||||||
|
particle.Status |= ParticleStatus::FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tookAnySteps)
|
||||||
|
particle.Status |= ParticleStatus::TOOK_ANY_STEPS;
|
||||||
|
else
|
||||||
|
particle.Status &= ~ParticleStatus::TOOK_ANY_STEPS;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class ParticleAdvectWorklet : public vtkm::worklet::WorkletMapField
|
class ParticleAdvectWorklet : public vtkm::worklet::WorkletMapField
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -228,9 +314,32 @@ public:
|
|||||||
|
|
||||||
//Invoke particle advection worklet
|
//Invoke particle advection worklet
|
||||||
ParticleWorkletDispatchType particleWorkletDispatch;
|
ParticleWorkletDispatchType particleWorkletDispatch;
|
||||||
//problem
|
|
||||||
particleWorkletDispatch.Invoke(idxArray, integrator, particles);
|
particleWorkletDispatch.Invoke(idxArray, integrator, particles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AOS version
|
||||||
|
void Run2(const IntegratorType& integrator,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Particle>& particles,
|
||||||
|
const vtkm::Id& MaxSteps)
|
||||||
|
{
|
||||||
|
using ParticleAdvectWorkletType = vtkm::worklet::particleadvection::ParticleAdvectWorkletAOS2;
|
||||||
|
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);
|
||||||
|
|
||||||
|
#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(integrator, particles, maxSteps);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
|
@ -658,7 +658,7 @@ void TestParticleStatus()
|
|||||||
VTKM_TEST_ASSERT(tookStep1 == 0, "Particle took a step when it should not have.");
|
VTKM_TEST_ASSERT(tookStep1 == 0, "Particle took a step when it should not have.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
double TestParticleAOS(bool doAOS)
|
double TestParticleAOS(bool doAOS)
|
||||||
{
|
{
|
||||||
vtkm::Bounds bounds(0, 1, 0, 1, 0, 1);
|
vtkm::Bounds bounds(0, 1, 0, 1, 0, 1);
|
||||||
@ -696,37 +696,38 @@ double TestParticleAOS(bool doAOS)
|
|||||||
int n = 10000;
|
int n = 10000;
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
vtkm::Particle p;
|
vtkm::Particle p;
|
||||||
p.ID = i;
|
p.ID = i;
|
||||||
p.Status = vtkm::ParticleStatus::SUCCESS;
|
p.Status = vtkm::ParticleStatus::SUCCESS;
|
||||||
auto pt = RandomPoint(bounds);
|
auto pt = RandomPoint(bounds);
|
||||||
p.Pos = pt;
|
p.Pos = pt;
|
||||||
particles.push_back(p);
|
particles.push_back(p);
|
||||||
pts.push_back(pt);
|
pts.push_back(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::duration<double> dT;
|
std::chrono::duration<double> dT;
|
||||||
if (doAOS)
|
if (doAOS)
|
||||||
{
|
{
|
||||||
auto seedsArray = vtkm::cont::make_ArrayHandle(particles);
|
auto seedsArray = vtkm::cont::make_ArrayHandle(particles);
|
||||||
//vtkm::cont::printSummary_ArrayHandle(seedsArray, std::cout, true);
|
//vtkm::cont::printSummary_ArrayHandle(seedsArray, std::cout, true);
|
||||||
auto s = std::chrono::system_clock::now();
|
auto s = std::chrono::system_clock::now();
|
||||||
auto res = pa.Run(rk4, seedsArray, maxSteps);
|
auto res = pa.Run(rk4, seedsArray, maxSteps);
|
||||||
auto e = std::chrono::system_clock::now();
|
auto e = std::chrono::system_clock::now();
|
||||||
dT = e - s;
|
dT = e-s;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto seedsArray = vtkm::cont::make_ArrayHandle(pts);
|
auto seedsArray = vtkm::cont::make_ArrayHandle(pts);
|
||||||
//vtkm::cont::printSummary_ArrayHandle(seedsArray, std::cout, true);
|
//vtkm::cont::printSummary_ArrayHandle(seedsArray, std::cout, true);
|
||||||
auto s = std::chrono::system_clock::now();
|
auto s = std::chrono::system_clock::now();
|
||||||
auto res = pa.Run(rk4, seedsArray, maxSteps);
|
auto res = pa.Run(rk4, seedsArray, maxSteps);
|
||||||
auto e = std::chrono::system_clock::now();
|
auto e = std::chrono::system_clock::now();
|
||||||
dT = e - s;
|
dT = e-s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dT.count();
|
return dT.count();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void TestParticleAdvection()
|
void TestParticleAdvection()
|
||||||
{
|
{
|
||||||
@ -734,11 +735,11 @@ void TestParticleAdvection()
|
|||||||
// TestParticleWorklets();
|
// TestParticleWorklets();
|
||||||
// TestParticleStatus();
|
// TestParticleStatus();
|
||||||
|
|
||||||
double aosTime = TestParticleAOS(true);
|
// double aosTime = TestParticleAOS(true);
|
||||||
double soaTime = TestParticleAOS(false);
|
// double soaTime = TestParticleAOS(false);
|
||||||
|
|
||||||
std::cout << "AOS_time= " << aosTime << std::endl;
|
// std::cout<<"AOS_time= "<< aosTime<<std::endl;
|
||||||
std::cout << "SOA_time= " << soaTime << std::endl;
|
// std::cout<<"SOA_time= "<< soaTime<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UnitTestParticleAdvection(int argc, char* argv[])
|
int UnitTestParticleAdvection(int argc, char* argv[])
|
||||||
|
Loading…
Reference in New Issue
Block a user