vtkLegacyParticleTracerBase.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
16 #ifndef vtkLegacyParticleTracerBase_h
17 #define vtkLegacyParticleTracerBase_h
18 
19 #include "vtkDeprecation.h" // For VTK_DEPRECATED_IN_9_2_0
20 #include "vtkPVVTKExtensionsFiltersGeneralMPIModule.h" // For export macro
21 #include "vtkPolyDataAlgorithm.h"
22 #include "vtkSmartPointer.h" // For vtkSmartPointer
23 
24 #include <list> // STL Header
25 #include <mutex> // STL Header
26 #include <vector> // STL Header
27 
30 class vtkCellArray;
32 class vtkDataArray;
33 class vtkDataSet;
34 class vtkDoubleArray;
35 class vtkFloatArray;
36 class vtkGenericCell;
38 class vtkIntArray;
41 class vtkPointData;
42 class vtkPoints;
43 class vtkPolyData;
44 class vtkSignedCharArray;
47 
49 {
51 struct Position_t
52 {
53  double x[4];
54 };
55 using Position = struct Position_t;
56 
58 {
59  // These are used during iteration
61  int CachedDataSetId[2];
62  vtkIdType CachedCellId[2];
64  // These are computed scalars we might display
65  int SourceID;
66  int TimeStepAge; // amount of time steps the particle has advanced
68  int InjectedStepId; // time step the particle was injected
71  // These are useful to track for debugging etc
72  int ErrorCode;
73  float age;
74  // these are needed across time steps to compute vorticity
75  float rotation;
76  float angularVel;
77  float time;
78  float speed;
79  // once the particle is added, PointId is valid and is the tuple location
80  // in ProtoPD.
82  // if PointId is negative then in parallel this particle was just
83  // received and we need to get the tuple value from vtkPParticleTracerBase::Tail.
85 };
87 
88 typedef std::vector<ParticleInformation> ParticleVector;
89 typedef ParticleVector::iterator ParticleIterator;
90 typedef std::list<ParticleInformation> ParticleDataList;
91 typedef ParticleDataList::iterator ParticleListIterator;
92 struct ParticleTracerFunctor;
94 }
95 
98  : public vtkPolyDataAlgorithm
99 {
100 public:
101  friend struct vtkLegacyParticleTracerBaseNamespace::ParticleTracerFunctor;
102  enum Solvers
103  {
108  UNKNOWN
109  };
110 
112  void PrintSelf(ostream& os, vtkIndent indent) override;
113  void PrintParticleHistories();
114 
116 
121  vtkGetMacro(ComputeVorticity, bool);
122  void SetComputeVorticity(bool);
124 
126 
129  vtkGetMacro(TerminalSpeed, double);
130  void SetTerminalSpeed(double);
132 
134 
138  vtkGetMacro(RotationScale, double);
139  void SetRotationScale(double);
141 
143 
147  vtkSetMacro(IgnorePipelineTime, vtkTypeBool);
148  vtkGetMacro(IgnorePipelineTime, vtkTypeBool);
149  vtkBooleanMacro(IgnorePipelineTime, vtkTypeBool);
151 
153 
162  vtkGetMacro(ForceReinjectionEveryNSteps, int);
163  void SetForceReinjectionEveryNSteps(int);
165 
167 
173  void SetTerminationTime(double t);
174  vtkGetMacro(TerminationTime, double);
176 
177  void SetIntegrator(vtkInitialValueProblemSolver*);
178  vtkGetObjectMacro(Integrator, vtkInitialValueProblemSolver);
179 
180  void SetIntegratorType(int type);
181  int GetIntegratorType();
182 
184 
188  vtkGetMacro(StartTime, double);
189  void SetStartTime(double t);
191 
193 
202  vtkSetMacro(StaticSeeds, vtkTypeBool);
203  vtkGetMacro(StaticSeeds, vtkTypeBool);
205 
210  {
211  DIFFERENT = 0,
212  STATIC = 1,
213  LINEAR_TRANSFORMATION = 2,
214  SAME_TOPOLOGY = 3
215  };
216 
218  /*
219  * Set/Get the type of variance of the mesh over time.
220  *
221  * DIFFERENT = 0,
222  * STATIC = 1,
223  * LINEAR_TRANSFORMATION = 2
224  * SAME_TOPOLOGY = 3
225  */
226  virtual void SetMeshOverTime(int meshOverTime);
227  virtual int GetMeshOverTimeMinValue() { return DIFFERENT; }
228  virtual int GetMeshOverTimeMaxValue() { return SAME_TOPOLOGY; }
229  void SetMeshOverTimeToDifferent() { this->SetMeshOverTime(DIFFERENT); }
230  void SetMeshOverTimeToStatic() { this->SetMeshOverTime(STATIC); }
231  void SetMeshOverTimeToLinearTransformation() { this->SetMeshOverTime(LINEAR_TRANSFORMATION); }
232  void SetMeshOverTimeToSameTopology() { this->SetMeshOverTime(SAME_TOPOLOGY); }
233  vtkGetMacro(MeshOverTime, int);
235 
237 
246  VTK_DEPRECATED_IN_9_2_0("Use SetMeshOverTime instead")
247  virtual void SetStaticMesh(vtkTypeBool staticMesh)
248  {
249  this->SetMeshOverTime(staticMesh ? STATIC : DIFFERENT);
250  }
251  VTK_DEPRECATED_IN_9_2_0("Use GetMeshOverTime instead")
252  virtual vtkTypeBool GetStaticMesh() { return this->MeshOverTime == STATIC; }
254 
255  enum
256  {
258  INTERPOLATOR_WITH_CELL_LOCATOR
259  };
260 
272  void SetInterpolatorType(int interpolatorType);
273 
281  void SetInterpolatorTypeToDataSetPointLocator();
282 
289  void SetInterpolatorTypeToCellLocator();
290 
292 
298  virtual void SetParticleWriter(vtkAbstractParticleWriter* pw);
299  vtkGetObjectMacro(ParticleWriter, vtkAbstractParticleWriter);
301 
303 
307  vtkSetFilePathMacro(ParticleFileName);
308  vtkGetFilePathMacro(ParticleFileName);
310 
312 
316  vtkSetMacro(EnableParticleWriting, vtkTypeBool);
317  vtkGetMacro(EnableParticleWriting, vtkTypeBool);
318  vtkBooleanMacro(EnableParticleWriting, vtkTypeBool);
320 
322 
327  vtkSetMacro(DisableResetCache, vtkTypeBool);
328  vtkGetMacro(DisableResetCache, vtkTypeBool);
329  vtkBooleanMacro(DisableResetCache, vtkTypeBool);
331 
333 
336  void AddSourceConnection(vtkAlgorithmOutput* input);
337  void RemoveAllSources();
339 
341 
345  vtkGetMacro(ForceSerialExecution, bool);
346  vtkSetMacro(ForceSerialExecution, bool);
347  vtkBooleanMacro(ForceSerialExecution, bool);
349 protected:
350  vtkSmartPointer<vtkPolyData> Output; // managed by child classes
352 
357  vtkIdType UniqueIdCounter; // global Id counter used to give particles a stamp
359  vtkSmartPointer<vtkPointData> ParticlePointData; // the current particle point data consistent
360  // with particle history
361  // Everything related to time
362  vtkTypeBool IgnorePipelineTime; // whether to use the pipeline time for termination
363  vtkTypeBool DisableResetCache; // whether to enable ResetCache() method
365 
366  // Control execution as serial or threaded
368 
370  ~vtkLegacyParticleTracerBase() override;
371 
372  //
373  // Make sure the pipeline knows what type we expect as input
374  //
375  int FillInputPortInformation(int port, vtkInformation* info) override;
376 
377  //
378  // The usual suspects
379  //
380  vtkTypeBool ProcessRequest(vtkInformation* request, vtkInformationVector** inputVector,
381  vtkInformationVector* outputVector) override;
382 
383  //
384  // Store any information we need in the output and fetch what we can
385  // from the input
386  //
387  int RequestInformation(vtkInformation* request, vtkInformationVector** inputVector,
388  vtkInformationVector* outputVector) override;
389 
390  //
391  // Compute input time steps given the output step
392  //
393  int RequestUpdateExtent(vtkInformation* request, vtkInformationVector** inputVector,
394  vtkInformationVector* outputVector) override;
395 
396  //
397  // what the pipeline calls for each time step
398  //
399  int RequestData(vtkInformation* request, vtkInformationVector** inputVector,
400  vtkInformationVector* outputVector) override;
401 
402  //
403  // these routines are internally called to actually generate the output
404  //
405  virtual int ProcessInput(vtkInformationVector** inputVector);
406 
407  // This is the main part of the algorithm:
408  // * move all the particles one step
409  // * Reinject particles (by adding them to this->ParticleHistories)
410  // either at the beginning or at the end of each step (modulo
411  // this->ForceReinjectionEveryNSteps)
412  // * Output a polydata representing the moved particles
413  // Note that if the starting and the ending time coincide, the polydata is still valid.
414  virtual vtkPolyData* Execute(vtkInformationVector** inputVector);
415 
416  // the RequestData will call these methods in turn
417  virtual void Initialize() {} // the first iteration
418  virtual int OutputParticles(vtkPolyData* poly) = 0; // every iteration
419  virtual void Finalize() {} // the last iteration
420 
425  virtual std::vector<vtkDataSet*> GetSeedSources(vtkInformationVector* inputVector, int timeStep);
426 
427  // Initialization of input (vector-field) geometry
428  int InitializeInterpolator();
429  int UpdateDataCache(vtkDataObject* td);
430 
435  void TestParticles(vtkLegacyParticleTracerBaseNamespace::ParticleVector& candidates,
437 
438  void TestParticles(
439  vtkLegacyParticleTracerBaseNamespace::ParticleVector& candidates, std::vector<int>& passed);
440 
447  virtual void AssignSeedsToProcessors(double time, vtkDataSet* source, int sourceID, int ptId,
448  vtkLegacyParticleTracerBaseNamespace::ParticleVector& localSeedPoints, int& localAssignedCount);
449 
454  virtual void AssignUniqueIds(
456 
461  void UpdateParticleList(vtkLegacyParticleTracerBaseNamespace::ParticleVector& candidates);
462 
468  virtual bool UpdateParticleListFromOtherProcesses() { return false; }
469 
474  double currentTime, double targetTime, vtkInitialValueProblemSolver* integrator,
475  vtkTemporalInterpolatedVelocityField* interpolator, vtkDoubleArray* cellVectors,
476  std::atomic<vtkIdType>& particleCount, std::mutex& eraseMutex, bool sequential);
477 
478  // if the particle is added to send list, then returns value is 1,
479  // if it is kept on this process after a retry return value is 0
483  {
484  return true;
485  }
486 
493  bool ComputeDomainExitLocation(
494  double pos[4], double p2[4], double intersection[4], vtkGenericCell* cell);
495 
496  //
497  // Scalar arrays that are generated as each particle is updated
498  //
499  void CreateProtoPD(vtkDataObject* input);
500 
501  vtkFloatArray* GetParticleAge(vtkPointData*);
502  vtkIntArray* GetParticleIds(vtkPointData*);
503  vtkSignedCharArray* GetParticleSourceIds(vtkPointData*);
504  vtkIntArray* GetInjectedPointIds(vtkPointData*);
505  vtkIntArray* GetInjectedStepIds(vtkPointData*);
506  vtkIntArray* GetErrorCodeArr(vtkPointData*);
507  vtkFloatArray* GetParticleVorticity(vtkPointData*);
508  vtkFloatArray* GetParticleRotation(vtkPointData*);
509  vtkFloatArray* GetParticleAngularVel(vtkPointData*);
510 
511  // utility function we use to test if a point is inside any of our local datasets
512  bool InsideBounds(double point[]);
513 
514  void CalculateVorticity(
515  vtkGenericCell* cell, double pcoords[3], vtkDoubleArray* cellVectors, double vorticity[3]);
516 
517  //------------------------------------------------------
518 
519  double GetCacheDataTime(int i);
520  double GetCacheDataTime();
521 
522  virtual void ResetCache();
524  double* velocity, vtkTemporalInterpolatedVelocityField* interpolator, vtkIdType particleId,
525  vtkDoubleArray* cellVectors);
526 
528 
533  virtual bool IsPointDataValid(vtkDataObject* input);
534  bool IsPointDataValid(vtkCompositeDataSet* input, std::vector<std::string>& arrayNames);
535  void GetPointDataArrayNames(vtkDataSet* input, std::vector<std::string>& names);
537 
538  vtkGetMacro(ReinjectionCounter, int);
539  vtkGetMacro(CurrentTimeValue, double);
540 
541  void ResizeArrays(vtkIdType numTuples);
542 
547  virtual void InitializeExtraPointDataArrays(vtkPointData* vtkNotUsed(outputPD)) {}
548 
551  {
552  }
553 
554  vtkTemporalInterpolatedVelocityField* GetInterpolator();
555 
560  virtual void AddRestartSeeds(vtkInformationVector** /*inputVector*/) {}
561 
566  virtual void RenameGhostArray(vtkPointData* pd);
567 
568 private:
579  double* point1, double delT, int subSteps, vtkTemporalInterpolatedVelocityField* interpolator);
580 
581  bool SetTerminationTimeNoModify(double t);
582 
583  // Parameters of tracing
584  vtkInitialValueProblemSolver* Integrator;
585  double IntegrationStep;
586  double MaximumError;
587  bool ComputeVorticity;
588  double RotationScale;
589  double TerminalSpeed;
590 
591  // A counter to keep track of how many times we reinjected
592  int ReinjectionCounter;
593 
594  // Important for Caching of Cells/Ids/Weights etc
595  vtkTypeBool AllFixedGeometry;
596  int MeshOverTime;
597  vtkTypeBool StaticSeeds;
598 
599  std::vector<double> InputTimeValues;
600  double StartTime;
601  double TerminationTime;
602  double CurrentTimeValue;
603 
604  int StartTimeStep; // InputTimeValues[StartTimeStep] <= StartTime <=
605  // InputTimeValues[StartTimeStep+1]
606  int CurrentTimeStep;
607  int TerminationTimeStep; // computed from start time
608  bool FirstIteration;
609 
610  // Innjection parameters
611  int ForceReinjectionEveryNSteps;
612  vtkTimeStamp ParticleInjectionTime;
613  bool HasCache;
614 
615  // Particle writing to disk
616  vtkAbstractParticleWriter* ParticleWriter;
617  char* ParticleFileName;
618  vtkTypeBool EnableParticleWriting;
619 
620  // The main lists which are held during operation- between time step updates
622 
623  // The velocity interpolator
625 
626  // Data for time step CurrentTimeStep-1 and CurrentTimeStep
628 
629  // Cache bounds info for each dataset we will use repeatedly
630  struct bounds_t
631  {
632  double b[6];
633  };
634  using bounds = struct bounds_t;
635  std::vector<bounds> CachedBounds[2];
636 
637  // variables used by Execute() to produce output
638 
639  vtkSmartPointer<vtkDataSet> DataReferenceT[2];
640 
641  vtkSmartPointer<vtkPoints> OutputCoordinates;
642  vtkSmartPointer<vtkIdTypeArray> ParticleCellsConnectivity;
643  vtkSmartPointer<vtkIdTypeArray> ParticleCellsOffsets;
644  vtkSmartPointer<vtkCellArray> ParticleCells;
645 
646  vtkSmartPointer<vtkFloatArray> ParticleAge;
647  vtkSmartPointer<vtkIntArray> ParticleIds;
648  vtkSmartPointer<vtkSignedCharArray> ParticleSourceIds;
649  vtkSmartPointer<vtkIntArray> InjectedPointIds;
650  vtkSmartPointer<vtkIntArray> InjectedStepIds;
651  vtkSmartPointer<vtkIntArray> ErrorCodeArray;
652  vtkSmartPointer<vtkFloatArray> ParticleVorticity;
653  vtkSmartPointer<vtkFloatArray> ParticleRotation;
654  vtkSmartPointer<vtkFloatArray> ParticleAngularVel;
655  vtkSmartPointer<vtkPointData> OutputPointData;
656 
657  // temp array
659 
661  void operator=(const vtkLegacyParticleTracerBase&) = delete;
662  vtkTimeStamp ExecuteTime;
663 
664  unsigned int NumberOfParticles();
665 
667 
668  static const double Epsilon;
669 };
670 
672 #endif
A particle tracer for vector fields.
std::list< ParticleInformation > ParticleDataList
virtual void AddRestartSeeds(vtkInformationVector **)
For restarts of particle paths, we add in the ability to add in particles from a previous computation...
vtkTypeBool IgnorePipelineTime
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
#define VTK_ABI_NAMESPACE_END
MeshOverTimeTypes
Types of Variance of Mesh over time.
info
int vtkIdType
vtkLegacyParticleTracerBaseNamespace::ParticleDataList ParticleHistories
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
vtkSmartPointer< vtkPolyData > Output
vtkIdType UniqueIdCounter
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
vtkSmartPointer< vtkPointData > ProtoPD
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
int vtkTypeBool
vtkTypeBool DisableResetCache
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
#define VTK_ABI_NAMESPACE_BEGIN
time
source
A Parallel Particle tracer for unsteady vector fields.
std::vector< ParticleInformation > ParticleVector
virtual bool SendParticleToAnotherProcess(vtkLegacyParticleTracerBaseNamespace::ParticleInformation &, vtkLegacyParticleTracerBaseNamespace::ParticleInformation &, vtkPointData *)
virtual bool UpdateParticleListFromOtherProcesses()
this is used during classification of seed points and also between iterations of the main loop as par...
virtual void SetToExtraPointDataArrays(vtkIdType, vtkLegacyParticleTracerBaseNamespace::ParticleInformation &)
point
virtual void InitializeExtraPointDataArrays(vtkPointData *vtkNotUsed(outputPD))
Methods to append values to existing point data arrays that may only be desired on specific concrete ...
#define VTKPVVTKEXTENSIONSFILTERSGENERALMPI_EXPORT
vtkSmartPointer< vtkPointData > ParticlePointData
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...