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