11 #ifndef vtk_m_filter_flow_internal_DataSetIntegrator_h
12 #define vtk_m_filter_flow_internal_DataSetIntegrator_h
36 template <
typename ParticleType>
40 DSIHelperInfo(
const std::vector<ParticleType>& v,
41 const vtkm::filter::flow::internal::BoundsMap& boundsMap,
42 const std::unordered_map<
vtkm::Id, std::vector<vtkm::Id>>& particleBlockIDsMap)
43 : BoundsMap(boundsMap)
44 , ParticleBlockIDsMap(particleBlockIDsMap)
49 const vtkm::filter::flow::internal::BoundsMap BoundsMap;
50 const std::unordered_map<vtkm::Id, std::vector<vtkm::Id>> ParticleBlockIDsMap;
52 std::vector<ParticleType> A, I, V;
53 std::unordered_map<vtkm::Id, std::vector<vtkm::Id>> IdMapA, IdMapI;
54 std::vector<vtkm::Id> TermIdx, TermID;
57 using DSIHelperInfoType =
58 vtkm::cont::Variant<DSIHelperInfo<vtkm::Particle>, DSIHelperInfo<vtkm::ChargedParticle>>;
60 template <
typename Derived>
61 class DataSetIntegrator
64 using VelocityFieldNameType = std::string;
65 using ElectroMagneticFieldNameType = std::pair<std::string, std::string>;
68 using FieldNameType = vtkm::cont::Variant<VelocityFieldNameType, ElectroMagneticFieldNameType>;
71 vtkm::cont::Variant<vtkm::worklet::flow::ParticleAdvectionResult<vtkm::Particle>,
78 const FieldNameType& fieldName,
82 : FieldName(fieldName)
84 , SolverType(solverType)
85 , VecFieldType(vecFieldType)
86 , AdvectionResType(resultType)
87 , Rank(this->Comm.rank())
93 VTKM_CONT void SetCopySeedFlag(
bool val) { this->CopySeedArray = val; }
96 void Advect(DSIHelperInfoType& b,
100 Derived* inst =
static_cast<Derived*
>(
this);
103 b.CastAndCall([&](
auto& concrete) { inst->DoAdvect(concrete, stepSize, maxSteps); });
106 template <
typename ParticleType>
111 template <
typename ParticleType,
template <
typename>
class ResultType>
112 VTKM_CONT void UpdateResult(
const ResultType<ParticleType>& result,
113 DSIHelperInfo<ParticleType>& dsiInfo);
115 VTKM_CONT bool IsParticleAdvectionResult()
const
120 VTKM_CONT bool IsStreamlineResult()
const
125 template <
typename ParticleType>
127 DSIHelperInfo<ParticleType>& dsiInfo)
const;
130 vtkm::cont::Variant<VelocityFieldNameType, ElectroMagneticFieldNameType> FieldName;
140 bool CopySeedArray =
false;
141 std::vector<RType> Results;
144 template <
typename Derived>
145 template <
typename ParticleType>
146 VTKM_CONT inline void DataSetIntegrator<Derived>::ClassifyParticles(
148 DSIHelperInfo<ParticleType>& dsiInfo)
const
152 dsiInfo.TermID.clear();
153 dsiInfo.TermIdx.clear();
154 dsiInfo.IdMapI.clear();
155 dsiInfo.IdMapA.clear();
158 vtkm::Id n = portal.GetNumberOfValues();
162 auto p = portal.Get(i);
164 if (p.GetStatus().CheckTerminate())
166 dsiInfo.TermIdx.emplace_back(i);
167 dsiInfo.TermID.emplace_back(p.GetID());
171 const auto& it = dsiInfo.ParticleBlockIDsMap.find(p.GetID());
172 VTKM_ASSERT(it != dsiInfo.ParticleBlockIDsMap.end());
173 auto currBIDs = it->second;
176 std::vector<vtkm::Id> newIDs;
177 if (p.GetStatus().CheckSpatialBounds() && !p.GetStatus().CheckTookAnySteps())
178 newIDs.assign(std::next(currBIDs.begin(), 1), currBIDs.end());
180 newIDs = dsiInfo.BoundsMap.FindBlocks(p.GetPosition(), currBIDs);
187 p.GetStatus().SetTerminate();
188 dsiInfo.TermIdx.emplace_back(i);
189 dsiInfo.TermID.emplace_back(p.GetID());
195 if (newIDs.size() > 1)
197 for (
auto idit = newIDs.begin(); idit != newIDs.end(); idit++)
200 if (dsiInfo.BoundsMap.FindRank(bid) == this->Rank)
203 newIDs.insert(newIDs.begin(), bid);
209 int dstRank = dsiInfo.BoundsMap.FindRank(newIDs[0]);
210 if (dstRank == this->Rank)
212 dsiInfo.A.emplace_back(p);
213 dsiInfo.IdMapA[p.GetID()] = newIDs;
217 dsiInfo.I.emplace_back(p);
218 dsiInfo.IdMapI[p.GetID()] = newIDs;
227 (dsiInfo.A.size() + dsiInfo.I.size() + dsiInfo.TermIdx.size()));
228 VTKM_ASSERT(dsiInfo.TermIdx.size() == dsiInfo.TermID.size());
231 template <
typename Derived>
232 template <
typename ParticleType,
template <
typename>
class ResultType>
233 VTKM_CONT inline void DataSetIntegrator<Derived>::UpdateResult(
234 const ResultType<ParticleType>& result,
235 DSIHelperInfo<ParticleType>& dsiInfo)
237 this->ClassifyParticles(result.Particles, dsiInfo);
239 if (this->IsParticleAdvectionResult())
241 if (dsiInfo.TermIdx.empty())
251 ResType termRes(termParticles);
252 this->Results.emplace_back(termRes);
254 else if (this->IsStreamlineResult())
255 this->Results.emplace_back(result);
258 template <
typename Derived>
259 template <
typename ParticleType>
262 std::size_t nResults = this->Results.size();
266 if (this->IsParticleAdvectionResult())
270 std::vector<vtkm::cont::ArrayHandle<ParticleType>> allParticles;
271 allParticles.reserve(nResults);
272 for (
const auto& vres : this->Results)
273 allParticles.emplace_back(vres.template Get<ResType>().Particles);
293 else if (this->IsStreamlineResult())
300 const auto& res = this->Results[0].template Get<ResType>();
306 std::vector<vtkm::Id> posOffsets(nResults, 0);
307 vtkm::Id totalNumCells = 0, totalNumPts = 0;
308 for (std::size_t i = 0; i < nResults; i++)
310 const auto& res = this->Results[i].template Get<ResType>();
314 posOffsets[i] = totalNumPts;
316 totalNumPts += res.Positions.GetNumberOfValues();
317 totalNumCells += res.PolyLines.GetNumberOfCells();
323 for (std::size_t i = 0; i < nResults; i++)
325 const auto& res = this->Results[i].template Get<ResType>();
328 res.Positions, 0, res.Positions.GetNumberOfValues(), appendPts, posOffsets[i]);
333 std::vector<vtkm::Id> numPtsPerCell(
static_cast<std::size_t
>(totalNumCells));
335 for (std::size_t i = 0; i < nResults; i++)
337 const auto& res = this->Results[i].template Get<ResType>();
338 vtkm::Id nCells = res.PolyLines.GetNumberOfCells();
339 for (
vtkm::Id j = 0; j < nCells; j++)
340 numPtsPerCell[off++] =
static_cast<vtkm::Id>(res.PolyLines.GetNumberOfPointsInCell(j));
353 auto polyLineShape = vtkm::cont::make_ArrayHandleConstant<vtkm::UInt8>(
359 polyLines.
Fill(totalNumPts, cellTypes, connectivity, offsets);
376 #endif //vtk_m_filter_flow_internal_DataSetIntegrator_h