VTK  9.2.6
vtkParticleTracerBase.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkParticleTracerBase.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
28 #ifndef vtkParticleTracerBase_h
29 #define vtkParticleTracerBase_h
30 
31 #include "vtkDeprecation.h" // For VTK_DEPRECATED_IN_9_2_0
32 #include "vtkFiltersFlowPathsModule.h" // For export macro
33 #include "vtkPolyDataAlgorithm.h"
34 #include "vtkSmartPointer.h" // For vtkSmartPointer
35 
36 #include <list> // STL Header
37 #include <mutex> // STL Header
38 #include <vector> // STL Header
39 
41 class vtkCellArray;
43 class vtkDataArray;
44 class vtkDataSet;
45 class vtkDoubleArray;
46 class vtkFloatArray;
47 class vtkGenericCell;
49 class vtkIntArray;
52 class vtkPointData;
53 class vtkPoints;
54 class vtkPolyData;
55 class vtkSignedCharArray;
57 
59 {
60 struct Position_t
61 {
62  double x[4];
63 };
64 using Position = struct Position_t;
65 
67 {
68  // These are used during iteration
73  // These are computed scalars we might display
74  int SourceID;
75  int TimeStepAge; // amount of time steps the particle has advanced
77  int InjectedStepId; // time step the particle was injected
80  // These are useful to track for debugging etc
81  int ErrorCode;
82  float age;
83  // these are needed across time steps to compute vorticity
84  float rotation;
85  float angularVel;
86  float time;
87  float speed;
88  // once the particle is added, PointId is valid and is the tuple location
89  // in ProtoPD.
91  // if PointId is negative then in parallel this particle was just
92  // received and we need to get the tuple value from vtkPParticleTracerBase::Tail.
94 };
96 
97 typedef std::vector<ParticleInformation> ParticleVector;
98 typedef ParticleVector::iterator ParticleIterator;
99 typedef std::list<ParticleInformation> ParticleDataList;
100 typedef ParticleDataList::iterator ParticleListIterator;
101 struct ParticleTracerFunctor;
102 };
103 
104 class VTKFILTERSFLOWPATHS_EXPORT vtkParticleTracerBase : public vtkPolyDataAlgorithm
105 {
106 public:
107  friend struct vtkParticleTracerBaseNamespace::ParticleTracerFunctor;
108  enum Solvers
109  {
115  };
116 
118  void PrintSelf(ostream& os, vtkIndent indent) override;
119  void PrintParticleHistories();
120 
122 
127  vtkGetMacro(ComputeVorticity, bool);
128  void SetComputeVorticity(bool);
130 
132 
135  vtkGetMacro(TerminalSpeed, double);
136  void SetTerminalSpeed(double);
138 
140 
144  vtkGetMacro(RotationScale, double);
145  void SetRotationScale(double);
147 
149 
153  vtkSetMacro(IgnorePipelineTime, vtkTypeBool);
154  vtkGetMacro(IgnorePipelineTime, vtkTypeBool);
155  vtkBooleanMacro(IgnorePipelineTime, vtkTypeBool);
157 
159 
168  vtkGetMacro(ForceReinjectionEveryNSteps, vtkTypeBool);
169  void SetForceReinjectionEveryNSteps(vtkTypeBool);
171 
173 
179  void SetTerminationTime(double t);
180  vtkGetMacro(TerminationTime, double);
182 
183  void SetIntegrator(vtkInitialValueProblemSolver*);
184  vtkGetObjectMacro(Integrator, vtkInitialValueProblemSolver);
185 
186  void SetIntegratorType(int type);
187  int GetIntegratorType();
188 
190 
194  vtkGetMacro(StartTime, double);
195  void SetStartTime(double t);
197 
199 
208  vtkSetMacro(StaticSeeds, vtkTypeBool);
209  vtkGetMacro(StaticSeeds, vtkTypeBool);
211 
216  {
217  DIFFERENT = 0,
218  STATIC = 1,
219  LINEAR_TRANSFORMATION = 2,
220  SAME_TOPOLOGY = 3
221  };
222 
224  /*
225  * Set/Get the type of variance of the mesh over time.
226  *
227  * DIFFERENT = 0,
228  * STATIC = 1,
229  * LINEAR_TRANSFORMATION = 2
230  * SAME_TOPOLOGY = 3
231  */
232  virtual void SetMeshOverTime(int meshOverTime);
233  virtual int GetMeshOverTimeMinValue() { return DIFFERENT; }
234  virtual int GetMeshOverTimeMaxValue() { return SAME_TOPOLOGY; }
235  void SetMeshOverTimeToDifferent() { this->SetMeshOverTime(DIFFERENT); }
236  void SetMeshOverTimeToStatic() { this->SetMeshOverTime(STATIC); }
237  void SetMeshOverTimeToLinearTransformation() { this->SetMeshOverTime(LINEAR_TRANSFORMATION); }
238  void SetMeshOverTimeToSameTopology() { this->SetMeshOverTime(SAME_TOPOLOGY); }
239  vtkGetMacro(MeshOverTime, int);
241 
243 
252  VTK_DEPRECATED_IN_9_2_0("Use SetMeshOverTime instead")
253  virtual void SetStaticMesh(vtkTypeBool staticMesh)
254  {
255  this->SetMeshOverTime(staticMesh ? STATIC : DIFFERENT);
256  }
257  VTK_DEPRECATED_IN_9_2_0("Use GetMeshOverTime instead")
258  virtual vtkTypeBool GetStaticMesh() { return this->MeshOverTime == STATIC; }
260 
261  enum
262  {
264  INTERPOLATOR_WITH_CELL_LOCATOR
265  };
266 
278  void SetInterpolatorType(int interpolatorType);
279 
287  void SetInterpolatorTypeToDataSetPointLocator();
288 
295  void SetInterpolatorTypeToCellLocator();
296 
298 
304  virtual void SetParticleWriter(vtkAbstractParticleWriter* pw);
305  vtkGetObjectMacro(ParticleWriter, vtkAbstractParticleWriter);
307 
309 
313  vtkSetFilePathMacro(ParticleFileName);
314  vtkGetFilePathMacro(ParticleFileName);
316 
318 
322  vtkSetMacro(EnableParticleWriting, vtkTypeBool);
323  vtkGetMacro(EnableParticleWriting, vtkTypeBool);
324  vtkBooleanMacro(EnableParticleWriting, vtkTypeBool);
326 
328 
333  vtkSetMacro(DisableResetCache, vtkTypeBool);
334  vtkGetMacro(DisableResetCache, vtkTypeBool);
335  vtkBooleanMacro(DisableResetCache, vtkTypeBool);
337 
339 
342  void AddSourceConnection(vtkAlgorithmOutput* input);
343  void RemoveAllSources();
345 
347 
351  vtkGetMacro(ForceSerialExecution, bool);
352  vtkSetMacro(ForceSerialExecution, bool);
353  vtkBooleanMacro(ForceSerialExecution, bool);
355 protected:
356  vtkSmartPointer<vtkPolyData> Output; // managed by child classes
358 
363  vtkIdType UniqueIdCounter; // global Id counter used to give particles a stamp
365  vtkSmartPointer<vtkPointData> ParticlePointData; // the current particle point data consistent
366  // with particle history
367  // Everything related to time
368  vtkTypeBool IgnorePipelineTime; // whether to use the pipeline time for termination
369  vtkTypeBool DisableResetCache; // whether to enable ResetCache() method
371 
372  // Control execution as serial or threaded
374 
376  ~vtkParticleTracerBase() override;
377 
378  //
379  // Make sure the pipeline knows what type we expect as input
380  //
381  int FillInputPortInformation(int port, vtkInformation* info) override;
382 
383  //
384  // The usual suspects
385  //
387  vtkInformationVector* outputVector) override;
388 
389  //
390  // Store any information we need in the output and fetch what we can
391  // from the input
392  //
393  int RequestInformation(vtkInformation* request, vtkInformationVector** inputVector,
394  vtkInformationVector* outputVector) override;
395 
396  //
397  // Compute input time steps given the output step
398  //
399  int RequestUpdateExtent(vtkInformation* request, vtkInformationVector** inputVector,
400  vtkInformationVector* outputVector) override;
401 
402  //
403  // what the pipeline calls for each time step
404  //
405  int RequestData(vtkInformation* request, vtkInformationVector** inputVector,
406  vtkInformationVector* outputVector) override;
407 
408  //
409  // these routines are internally called to actually generate the output
410  //
411  virtual int ProcessInput(vtkInformationVector** inputVector);
412 
413  // This is the main part of the algorithm:
414  // * move all the particles one step
415  // * Reinject particles (by adding them to this->ParticleHistories)
416  // either at the beginning or at the end of each step (modulo
417  // this->ForceReinjectionEveryNSteps)
418  // * Output a polydata representing the moved particles
419  // Note that if the starting and the ending time coincide, the polydata is still valid.
420  virtual vtkPolyData* Execute(vtkInformationVector** inputVector);
421 
422  // the RequestData will call these methods in turn
423  virtual void Initialize() {} // the first iteration
424  virtual int OutputParticles(vtkPolyData* poly) = 0; // every iteration
425  virtual void Finalize() {} // the last iteration
426 
431  virtual std::vector<vtkDataSet*> GetSeedSources(vtkInformationVector* inputVector, int timeStep);
432 
433  // Initialization of input (vector-field) geometry
434  int InitializeInterpolator();
435  int UpdateDataCache(vtkDataObject* td);
436 
441  void TestParticles(vtkParticleTracerBaseNamespace::ParticleVector& candidates,
443 
444  void TestParticles(
445  vtkParticleTracerBaseNamespace::ParticleVector& candidates, std::vector<int>& passed);
446 
453  virtual void AssignSeedsToProcessors(double time, vtkDataSet* source, int sourceID, int ptId,
454  vtkParticleTracerBaseNamespace::ParticleVector& localSeedPoints, int& localAssignedCount);
455 
460  virtual void AssignUniqueIds(vtkParticleTracerBaseNamespace::ParticleVector& localSeedPoints);
461 
466  void UpdateParticleList(vtkParticleTracerBaseNamespace::ParticleVector& candidates);
467 
473  virtual bool UpdateParticleListFromOtherProcesses() { return false; }
474 
478  void IntegrateParticle(vtkParticleTracerBaseNamespace::ParticleListIterator& it,
479  double currentTime, double targetTime, vtkInitialValueProblemSolver* integrator,
480  vtkTemporalInterpolatedVelocityField* interpolator, vtkDoubleArray* cellVectors,
481  std::atomic<vtkIdType>& particleCount, std::mutex& eraseMutex, bool sequential);
482 
483  // if the particle is added to send list, then returns value is 1,
484  // if it is kept on this process after a retry return value is 0
487  {
488  return true;
489  }
490 
497  bool ComputeDomainExitLocation(
498  double pos[4], double p2[4], double intersection[4], vtkGenericCell* cell);
499 
500  //
501  // Scalar arrays that are generated as each particle is updated
502  //
503  void CreateProtoPD(vtkDataObject* input);
504 
505  vtkFloatArray* GetParticleAge(vtkPointData*);
506  vtkIntArray* GetParticleIds(vtkPointData*);
507  vtkSignedCharArray* GetParticleSourceIds(vtkPointData*);
508  vtkIntArray* GetInjectedPointIds(vtkPointData*);
509  vtkIntArray* GetInjectedStepIds(vtkPointData*);
510  vtkIntArray* GetErrorCodeArr(vtkPointData*);
511  vtkFloatArray* GetParticleVorticity(vtkPointData*);
512  vtkFloatArray* GetParticleRotation(vtkPointData*);
513  vtkFloatArray* GetParticleAngularVel(vtkPointData*);
514 
515  // utility function we use to test if a point is inside any of our local datasets
516  bool InsideBounds(double point[]);
517 
518  void CalculateVorticity(
519  vtkGenericCell* cell, double pcoords[3], vtkDoubleArray* cellVectors, double vorticity[3]);
520 
521  //------------------------------------------------------
522 
523  double GetCacheDataTime(int i);
524  double GetCacheDataTime();
525 
526  virtual void ResetCache();
527  void SetParticle(vtkParticleTracerBaseNamespace::ParticleInformation& info, double* velocity,
528  vtkTemporalInterpolatedVelocityField* interpolator, vtkIdType particleId,
529  vtkDoubleArray* cellVectors);
530 
532 
537  virtual bool IsPointDataValid(vtkDataObject* input);
538  bool IsPointDataValid(vtkCompositeDataSet* input, std::vector<std::string>& arrayNames);
539  void GetPointDataArrayNames(vtkDataSet* input, std::vector<std::string>& names);
541 
542  vtkGetMacro(ReinjectionCounter, int);
543  vtkGetMacro(CurrentTimeValue, double);
544 
545  void ResizeArrays(vtkIdType numTuples);
546 
551  virtual void InitializeExtraPointDataArrays(vtkPointData* vtkNotUsed(outputPD)) {}
552 
555  {
556  }
557 
558  vtkTemporalInterpolatedVelocityField* GetInterpolator();
559 
564  virtual void AddRestartSeeds(vtkInformationVector** /*inputVector*/) {}
565 
566 private:
576  bool RetryWithPush(vtkParticleTracerBaseNamespace::ParticleInformation& info, double* point1,
577  double delT, int subSteps, vtkTemporalInterpolatedVelocityField* interpolator);
578 
579  bool SetTerminationTimeNoModify(double t);
580 
581  // Parameters of tracing
582  vtkInitialValueProblemSolver* Integrator;
583  double IntegrationStep;
584  double MaximumError;
585  bool ComputeVorticity;
586  double RotationScale;
587  double TerminalSpeed;
588 
589  // A counter to keep track of how many times we reinjected
590  int ReinjectionCounter;
591 
592  // Important for Caching of Cells/Ids/Weights etc
593  vtkTypeBool AllFixedGeometry;
594  int MeshOverTime;
595  vtkTypeBool StaticSeeds;
596 
597  std::vector<double> InputTimeValues;
598  double StartTime;
599  double TerminationTime;
600  double CurrentTimeValue;
601 
602  int StartTimeStep; // InputTimeValues[StartTimeStep] <= StartTime <=
603  // InputTimeValues[StartTimeStep+1]
604  int CurrentTimeStep;
605  int TerminationTimeStep; // computed from start time
606  bool FirstIteration;
607 
608  // Innjection parameters
609  vtkTypeBool ForceReinjectionEveryNSteps;
610  vtkTimeStamp ParticleInjectionTime;
611  bool HasCache;
612 
613  // Particle writing to disk
614  vtkAbstractParticleWriter* ParticleWriter;
615  char* ParticleFileName;
616  vtkTypeBool EnableParticleWriting;
617 
618  // The main lists which are held during operation- between time step updates
620 
621  // The velocity interpolator
623 
624  // Data for time step CurrentTimeStep-1 and CurrentTimeStep
626 
627  // Cache bounds info for each dataset we will use repeatedly
628  struct bounds_t
629  {
630  double b[6];
631  };
632  using bounds = struct bounds_t;
633  std::vector<bounds> CachedBounds[2];
634 
635  // variables used by Execute() to produce output
636 
637  vtkSmartPointer<vtkDataSet> DataReferenceT[2];
638 
639  vtkSmartPointer<vtkPoints> OutputCoordinates;
640  vtkSmartPointer<vtkIdTypeArray> ParticleCellsConnectivity;
641  vtkSmartPointer<vtkIdTypeArray> ParticleCellsOffsets;
642  vtkSmartPointer<vtkCellArray> ParticleCells;
643 
644  vtkSmartPointer<vtkFloatArray> ParticleAge;
645  vtkSmartPointer<vtkIntArray> ParticleIds;
646  vtkSmartPointer<vtkSignedCharArray> ParticleSourceIds;
647  vtkSmartPointer<vtkIntArray> InjectedPointIds;
648  vtkSmartPointer<vtkIntArray> InjectedStepIds;
649  vtkSmartPointer<vtkIntArray> ErrorCodeArray;
650  vtkSmartPointer<vtkFloatArray> ParticleVorticity;
651  vtkSmartPointer<vtkFloatArray> ParticleRotation;
652  vtkSmartPointer<vtkFloatArray> ParticleAngularVel;
653  vtkSmartPointer<vtkPointData> OutputPointData;
654 
655  // temp array
657 
659  void operator=(const vtkParticleTracerBase&) = delete;
660  vtkTimeStamp ExecuteTime;
661 
662  unsigned int NumberOfParticles();
663 
666 
667  static const double Epsilon;
668 };
669 
670 #endif
virtual int GetMeshOverTimeMinValue()
A helper class for interpolating between times during particle tracing.
abstract class to write particle data to file
MeshOverTimeTypes
Types of Variance of Mesh over time.
represent and manipulate point attribute data
Definition: vtkPointData.h:41
Store vtkAlgorithm input/output information.
abstract class to specify dataset behavior
Definition: vtkDataSet.h:62
virtual int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
This is called by the superclass.
#define VTK_DEPRECATED_IN_9_2_0(reason)
record modification and/or execution time
Definition: vtkTimeStamp.h:35
dynamic, self-adjusting array of float
Definition: vtkFloatArray.h:41
virtual bool SendParticleToAnotherProcess(vtkParticleTracerBaseNamespace::ParticleInformation &, vtkParticleTracerBaseNamespace::ParticleInformation &, vtkPointData *)
int vtkIdType
Definition: vtkType.h:332
concrete dataset represents vertices, lines, polygons, and triangle strips
Definition: vtkPolyData.h:90
ParticleVector::iterator ParticleIterator
provides thread-safe access to cells
virtual int GetMeshOverTimeMaxValue()
Proxy object to connect input/output ports.
dynamic, self-adjusting array of double
virtual void AddRestartSeeds(vtkInformationVector **)
For restarts of particle paths, we add in the ability to add in particles from a previous computation...
int vtkTypeBool
Definition: vtkABI.h:69
vtkParticleTracerBaseNamespace::ParticleDataList ParticleHistories
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...
virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *)
This is called by the superclass.
dynamic, self-adjusting array of int
Definition: vtkIntArray.h:45
abstract superclass for composite (multi-block or AMR) datasets
Superclass for algorithms that produce only polydata as output.
vtkTypeBool DisableResetCache
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
vtkSmartPointer< vtkPolyData > Output
a simple class to control print indentation
Definition: vtkIndent.h:39
virtual int RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
vtkIdType UniqueIdCounter
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:55
dynamic, self-adjusting array of signed char
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
vtkTypeBool ProcessRequest(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override
see vtkAlgorithm for details
virtual void InitializeExtraPointDataArrays(vtkPointData *vtkNotUsed(outputPD))
Methods to append values to existing point data arrays that may only be desired on specific concrete ...
std::list< ParticleInformation > ParticleDataList
vtkTypeBool IgnorePipelineTime
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
object to represent cell connectivity
Definition: vtkCellArray.h:186
virtual void SetToExtraPointDataArrays(vtkIdType, vtkParticleTracerBaseNamespace::ParticleInformation &)
Composite dataset that organizes datasets into blocks.
int FillInputPortInformation(int port, vtkInformation *info) override
Fill the input port information objects for this algorithm.
std::vector< ParticleInformation > ParticleVector
Store zero or more vtkInformation instances.
vtkSmartPointer< vtkPointData > ParticlePointData
ProtoPD is used just to keep track of the input array names and number of components for copy allocat...
ParticleDataList::iterator ParticleListIterator
general representation of visualization data
Definition: vtkDataObject.h:65
represent and manipulate 3D points
Definition: vtkPoints.h:39
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
virtual bool UpdateParticleListFromOtherProcesses()
this is used during classification of seed points and also between iterations of the main loop as par...
Integrate a set of ordinary differential equations (initial value problem) in time.
A particle tracer for vector fields.
Multiprocessing communication superclass.