VTK
dox/Filters/FlowPaths/vtkParticleTracerBase.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkParticleTracerBase.h
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00027 #ifndef __vtkParticleTracerBase_h
00028 #define __vtkParticleTracerBase_h
00029 
00030 #include "vtkFiltersFlowPathsModule.h" // For export macro
00031 #include "vtkSmartPointer.h" // For protected ivars.
00032 #include "vtkPolyDataAlgorithm.h"
00033 //BTX
00034 #include <vector> // STL Header
00035 #include <list>   // STL Header
00036 //ETX
00037 
00038 class vtkAbstractInterpolatedVelocityField;
00039 class vtkAbstractParticleWriter;
00040 class vtkCellArray;
00041 class vtkCharArray;
00042 class vtkCompositeDataSet;
00043 class vtkDataArray;
00044 class vtkDataSet;
00045 class vtkDoubleArray;
00046 class vtkFloatArray;
00047 class vtkGenericCell;
00048 class vtkInitialValueProblemSolver;
00049 class vtkIntArray;
00050 class vtkMultiBlockDataSet;
00051 class vtkMultiProcessController;
00052 class vtkPointData;
00053 class vtkPoints;
00054 class vtkPolyData;
00055 class vtkTemporalInterpolatedVelocityField;
00056 
00057 //BTX
00058 namespace vtkParticleTracerBaseNamespace
00059 {
00060   typedef struct { double x[4]; } Position;
00061   typedef struct {
00062     // These are used during iteration
00063     Position      CurrentPosition;
00064     int           CachedDataSetId[2];
00065     vtkIdType     CachedCellId[2];
00066     int           LocationState;
00067     // These are computed scalars we might display
00068     int           SourceID;
00069     int           TimeStepAge;
00070     int           InjectedPointId;
00071     int           InjectedStepId;
00072     int           UniqueParticleId;
00073     // These are useful to track for debugging etc
00074     int           ErrorCode;
00075     float         age;
00076     // these are needed across time steps to compute vorticity
00077     float         rotation;
00078     float         angularVel;
00079     float         time;
00080     float         speed;
00081 
00082     vtkIdType     PointId; //once the partice is added, PointId is valid
00083   } ParticleInformation;
00084 
00085   typedef std::vector<ParticleInformation>  ParticleVector;
00086   typedef ParticleVector::iterator             ParticleIterator;
00087   typedef std::list<ParticleInformation>    ParticleDataList;
00088   typedef ParticleDataList::iterator           ParticleListIterator;
00089 };
00090 //ETX
00091 
00092 class VTKFILTERSFLOWPATHS_EXPORT vtkParticleTracerBase : public vtkPolyDataAlgorithm
00093 {
00094 public:
00095   enum Solvers
00096   {
00097     RUNGE_KUTTA2,
00098     RUNGE_KUTTA4,
00099     RUNGE_KUTTA45,
00100     NONE,
00101     UNKNOWN
00102   };
00103 
00104   vtkTypeMacro(vtkParticleTracerBase,vtkPolyDataAlgorithm)
00105   void PrintSelf(ostream& os, vtkIndent indent);
00106   void PrintParticleHistories();
00107 
00109 
00111   vtkGetMacro(ComputeVorticity, bool);
00112   void SetComputeVorticity(bool);
00114 
00116 
00118   vtkGetMacro(TerminalSpeed, double);
00119   void SetTerminalSpeed(double);
00121 
00123 
00125   void SetRotationScale(double);
00126   vtkGetMacro(RotationScale, double);
00128 
00129 
00131 
00133   vtkSetMacro(IgnorePipelineTime, int);
00134   vtkGetMacro(IgnorePipelineTime, int);
00135   vtkBooleanMacro(IgnorePipelineTime, int);
00137 
00139 
00146   void SetForceReinjectionEveryNSteps(int);
00147   vtkGetMacro(ForceReinjectionEveryNSteps,int);
00149 
00151 
00155   void SetTerminationTime(double t);
00156   vtkGetMacro(TerminationTime,double);
00158 
00159   void SetIntegrator(vtkInitialValueProblemSolver *);
00160   vtkGetObjectMacro ( Integrator, vtkInitialValueProblemSolver );
00161 
00162   void SetIntegratorType(int type);
00163   int GetIntegratorType();
00164 
00166 
00170   void SetStartTime(double t);
00171   vtkGetMacro(StartTime,double);
00173 
00174 
00176 
00182   vtkGetMacro(StaticSeeds,int);
00184 
00186 
00192   vtkGetMacro(StaticMesh,int);
00194 
00196 
00200   virtual void SetParticleWriter(vtkAbstractParticleWriter *pw);
00201   vtkGetObjectMacro(ParticleWriter, vtkAbstractParticleWriter);
00203 
00205 
00207   vtkSetStringMacro(ParticleFileName);
00208   vtkGetStringMacro(ParticleFileName);
00210 
00212 
00214   vtkSetMacro(EnableParticleWriting,int);
00215   vtkGetMacro(EnableParticleWriting,int);
00216   vtkBooleanMacro(EnableParticleWriting,int);
00218 
00220 
00222   vtkSetMacro(DisableResetCache,int);
00223   vtkGetMacro(DisableResetCache,int);
00224   vtkBooleanMacro(DisableResetCache,int);
00226 
00228 
00229   void AddSourceConnection(vtkAlgorithmOutput* input);
00230   void RemoveAllSources();
00232 
00233  protected:
00234   vtkSmartPointer<vtkPolyData> Output; //managed by child classes
00235   vtkSmartPointer<vtkPointData> ProtoPD;
00236   vtkIdType UniqueIdCounter;// global Id counter used to give particles a stamp
00237   vtkParticleTracerBaseNamespace::ParticleDataList  ParticleHistories;
00238   vtkSmartPointer<vtkPointData>     ParticlePointData; //the current particle point data consistent
00239                                                        //with particle history
00240   int           ReinjectionCounter;
00241 
00242   //Everything related to time
00243   int IgnorePipelineTime; //whether to use the pipeline time for termination
00244   int DisableResetCache; //whether to enable ResetCache() method
00245 
00246 
00247   vtkParticleTracerBase();
00248   virtual ~vtkParticleTracerBase();
00249 
00250   //
00251   // Make sure the pipeline knows what type we expect as input
00252   //
00253   virtual int FillInputPortInformation(int port, vtkInformation* info);
00254 
00255   //
00256   // The usual suspects
00257   //
00258   virtual int ProcessRequest(vtkInformation* request,
00259                              vtkInformationVector** inputVector,
00260                              vtkInformationVector* outputVector);
00261 
00262   //
00263   // Store any information we need in the output and fetch what we can
00264   // from the input
00265   //
00266   virtual int RequestInformation(vtkInformation* request,
00267                                  vtkInformationVector** inputVector,
00268                                  vtkInformationVector* outputVector);
00269 
00270   //
00271   // Compute input time steps given the output step
00272   //
00273   virtual int RequestUpdateExtent(vtkInformation* request,
00274                                   vtkInformationVector** inputVector,
00275                                   vtkInformationVector* outputVector);
00276 
00277   //
00278   // what the pipeline calls for each time step
00279   //
00280   virtual int RequestData(vtkInformation* request,
00281                           vtkInformationVector** inputVector,
00282                           vtkInformationVector* outputVector);
00283 
00284   //
00285   // these routines are internally called to actually generate the output
00286   //
00287   virtual int ProcessInput(vtkInformationVector** inputVector);
00288 
00289   // This is the main part of the algorithm:
00290   //  * move all the particles one step
00291   //  * Reinject particles (by adding them to this->ParticleHistories)
00292   //    either at the beginning or at the end of each step (modulo this->ForceReinjectionEveryNSteps)
00293   //  * Output a polydata representing the moved particles
00294   // Note that if the starting and the ending time coincide, the polydata is still valid.
00295   virtual vtkPolyData* Execute(vtkInformationVector** inputVector);
00296 
00297   // the RequestData will call these methods in turn
00298   virtual void Initialize(){} //the first iteration
00299   virtual int OutputParticles(vtkPolyData* poly)=0; //every iteration
00300   virtual void Finalize(){} //the last iteration
00301 
00302   //
00303   // Initialization of input (vector-field) geometry
00304   //
00305   int InitializeInterpolator();
00306   int UpdateDataCache(vtkDataObject *td);
00307 
00308 
00310 
00312   void TestParticles(
00313     vtkParticleTracerBaseNamespace::ParticleVector &candidates,
00314     vtkParticleTracerBaseNamespace::ParticleVector &passed,
00315     int &count);
00317 
00318   void TestParticles(
00319     vtkParticleTracerBaseNamespace::ParticleVector &candidates, std::vector<int> &passed);
00320 
00322 
00326   virtual void AssignSeedsToProcessors(double time,
00327     vtkDataSet *source, int sourceID, int ptId,
00328     vtkParticleTracerBaseNamespace::ParticleVector &LocalSeedPoints,
00329     int &LocalAssignedCount);
00331 
00333 
00335   virtual void AssignUniqueIds(
00336     vtkParticleTracerBaseNamespace::ParticleVector &LocalSeedPoints);
00338 
00340 
00342   void UpdateParticleList(
00343     vtkParticleTracerBaseNamespace::ParticleVector &candidates);
00345 
00348   virtual void UpdateParticleListFromOtherProcesses(){};
00349 
00351 
00352   void IntegrateParticle(
00353     vtkParticleTracerBaseNamespace::ParticleListIterator &it,
00354     double currenttime, double terminationtime,
00355     vtkInitialValueProblemSolver* integrator);
00357 
00358   // if the particle is added to send list, then returns value is 1,
00359   // if it is kept on this process after a retry return value is 0
00360   virtual bool SendParticleToAnotherProcess(
00361     vtkParticleTracerBaseNamespace::ParticleInformation &,
00362     vtkParticleTracerBaseNamespace::ParticleInformation &, vtkPointData*)
00363   {
00364     return true;
00365   }
00366 
00368 
00372   bool ComputeDomainExitLocation(
00373     double pos[4], double p2[4], double intersection[4],
00374     vtkGenericCell *cell);
00376 
00377   //
00378   // Scalar arrays that are generated as each particle is updated
00379   //
00380   void CreateProtoPD(vtkDataObject* input);
00381 
00382   vtkFloatArray*    GetParticleAge(vtkPointData*);
00383   vtkIntArray*      GetParticleIds(vtkPointData*);
00384   vtkCharArray*     GetParticleSourceIds(vtkPointData*);
00385   vtkIntArray*      GetInjectedPointIds(vtkPointData*);
00386   vtkIntArray*      GetInjectedStepIds(vtkPointData*);
00387   vtkIntArray*      GetErrorCodeArr(vtkPointData*);
00388   vtkFloatArray*    GetParticleVorticity(vtkPointData*);
00389   vtkFloatArray*    GetParticleRotation(vtkPointData*);
00390   vtkFloatArray*    GetParticleAngularVel(vtkPointData*);
00391 
00392 
00393   // utility function we use to test if a point is inside any of our local datasets
00394   bool InsideBounds(double point[]);
00395 
00396 
00397 
00398   void CalculateVorticity( vtkGenericCell* cell, double pcoords[3],
00399                            vtkDoubleArray* cellVectors, double vorticity[3] );
00400 
00401   //------------------------------------------------------
00402 
00403 
00404   double GetCacheDataTime(int i);
00405   double GetCacheDataTime();
00406 
00407   virtual void ResetCache();
00408   void AddParticle(vtkParticleTracerBaseNamespace::ParticleInformation &info, double* velocity);
00409 
00411 
00414   virtual bool IsPointDataValid(vtkDataObject* input);
00415   bool IsPointDataValid(vtkCompositeDataSet* input, std::vector<std::string>& arrayNames);
00416   void GetPointDataArrayNames(vtkDataSet* input, std::vector<std::string>& names);
00418 
00419 private:
00421   void SetInterpolatorPrototype(vtkAbstractInterpolatedVelocityField*) {};
00422 
00424 
00429   bool RetryWithPush(
00430     vtkParticleTracerBaseNamespace::ParticleInformation &info, double* point1,double delT, int subSteps);
00432 
00433   //Parameters of tracing
00434   vtkInitialValueProblemSolver* Integrator;
00435   double IntegrationStep;
00436   double MaximumError;
00437   bool ComputeVorticity;
00438   double RotationScale;
00439   double TerminalSpeed;
00440 
00441   // Important for Caching of Cells/Ids/Weights etc
00442   int           AllFixedGeometry;
00443   int           StaticMesh;
00444   int           StaticSeeds;
00445 
00446   std::vector<double>  InputTimeValues;
00447   double StartTime;
00448   double TerminationTime;
00449   double CurrentTime;
00450 
00451   int  StartTimeStep; //InputTimeValues[StartTimeStep] <= StartTime <= InputTimeValues[StartTimeStep+1]
00452   int  CurrentTimeStep;
00453   int  TerminationTimeStep; //computed from start time
00454   bool FirstIteration;
00455 
00456   //Innjection parameters
00457   int           ForceReinjectionEveryNSteps;
00458   vtkTimeStamp  ParticleInjectionTime;
00459   bool          HasCache;
00460 
00461   // Particle writing to disk
00462   vtkAbstractParticleWriter *ParticleWriter;
00463   char                      *ParticleFileName;
00464   int                        EnableParticleWriting;
00465 
00466 
00467   // The main lists which are held during operation- between time step updates
00468   vtkParticleTracerBaseNamespace::ParticleVector    LocalSeeds;
00469 
00470 
00471   // The velocity interpolator
00472   vtkSmartPointer<vtkTemporalInterpolatedVelocityField>  Interpolator;
00473   vtkAbstractInterpolatedVelocityField * InterpolatorPrototype;
00474 
00475   // Data for time step CurrentTimeStep-1 and CurrentTimeStep
00476   vtkSmartPointer<vtkMultiBlockDataSet> CachedData[2];
00477 
00478   // Cache bounds info for each dataset we will use repeatedly
00479   typedef struct {
00480     double b[6];
00481   } bounds;
00482   std::vector<bounds> CachedBounds[2];
00483 
00484   // temporary variables used by Exeucte(), for convenience only
00485 
00486   vtkSmartPointer<vtkPoints> OutputCoordinates;
00487   vtkSmartPointer<vtkFloatArray>    ParticleAge;
00488   vtkSmartPointer<vtkIntArray>      ParticleIds;
00489   vtkSmartPointer<vtkCharArray>     ParticleSourceIds;
00490   vtkSmartPointer<vtkIntArray>      InjectedPointIds;
00491   vtkSmartPointer<vtkIntArray>      InjectedStepIds;
00492   vtkSmartPointer<vtkIntArray>      ErrorCode;
00493   vtkSmartPointer<vtkFloatArray>    ParticleVorticity;
00494   vtkSmartPointer<vtkFloatArray>    ParticleRotation;
00495   vtkSmartPointer<vtkFloatArray>    ParticleAngularVel;
00496   vtkSmartPointer<vtkDoubleArray>   CellVectors;
00497   vtkSmartPointer<vtkPointData>     OutputPointData;
00498   vtkSmartPointer<vtkDataSet>       DataReferenceT[2];
00499   vtkSmartPointer<vtkCellArray>     ParticleCells;
00500 
00501   vtkParticleTracerBase(const vtkParticleTracerBase&);  // Not implemented.
00502   void operator=(const vtkParticleTracerBase&);  // Not implemented.
00503   vtkTimeStamp ExecuteTime;
00504 
00505   unsigned int NumberOfParticles();
00506 
00507   friend class ParticlePathFilterInternal;
00508   friend class StreaklineFilterInternal;
00509 
00510   static const double Epsilon;
00511 
00512 };
00513 
00514 #endif