src/Particle/ParticleAttrib.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef PARTICLE_ATTRIB_H
00012 #define PARTICLE_ATTRIB_H
00013 
00014 /*
00015  * ParticleAttrib - Templated class for all particle attribute classes.
00016  *
00017  * This templated class is used to represent a single particle attribute.
00018  * An attribute is one data element within a particle object, and is
00019  * stored as an array.  This class stores the type information for the
00020  * attribute, and provides methods to create and destroy new items, and
00021  * to perform operations involving this attribute with others.  It also
00022  * provides iterators to allow the user to operate on single particles
00023  * instead of the entire array.
00024  *
00025  * ParticleAttrib is the primary element involved in expressions for
00026  * particles (just as Field is the primary element there).  This file
00027  * defines the necessary templated classes and functions to make
00028  * ParticleAttrib a capable expression-template participant.
00029  *
00030  * For some types such as Vektor, Tenzor, etc. which have multipple items,
00031  * we want to involve just the Nth item from each data element in an 
00032  * expression.  The () operator here returns an object of type
00033  * ParticleAttribElem, which will use the () operator on each individual
00034  * element to access an item over which one can iterate and get just the
00035  * Nth item from each data element.  For example, if we have an attribute
00036  * like this:
00037  *             ParticleAttrib< Vektor<float, 4> > Data
00038  * we can involve just the 2nd item of each Vektor in an expression by
00039  * referring to this as
00040  *             Data(1)
00041  * which returns an object of type ParticleAttribElem that knows to return
00042  * just the 2nd item from each Vektor.  ParticleAttribElem is also expression-
00043  * template-aware; in fact, it is intended primarily for use in expressions
00044  * and not in many other situations.  The ParticleAttribElem will use the
00045  * () operator to get the Nth item out of each data element, so this requires
00046  * the user to define operator () for the particle attribute type being
00047  * used (for Vektor, Tenzor, etc., this has already been done).  This same
00048  * thing has been done for operator () involving either one or two indices,
00049  * which is needed to get the i,j element of a Tenzor, for example.
00050  *
00051  * To perform gather/scatter type operations involving sparse indices, in
00052  * which the sparse indices represent a list of points in a dense field
00053  * onto which we want to gather/scatter values, you can use the [] operator
00054  * to get a SubParticleAttrib object that knows about the particle
00055  * elements and associated sparse index points.  This allows us to have
00056  * the syntax
00057  *    P[S] = expr(A[S])
00058  * where P is a ParticleAttrib, A is some other object such as a Field that
00059  * can be indexed by an SIndex, and S is an SIndex object.  In this case,
00060  * the length of the ParticleAttrib would be changed to match the number
00061  * of local points in the SIndex, and the expression would be evaluated at
00062  * all the points in the SIndex and stored into P.  It also allows the
00063  * syntax
00064  *    A[S] = expr(B[S], P[S])
00065  * where A, B are things like Field, S in an SIndex, and P is a ParticleAttrib.
00066  * Here, the LHS is assigned, at all the points in the SIndex, to the values
00067  * of the expression, which can include a ParticleAttrib only if it is
00068  * indexed by an SIndex.  This is because SubParticleAttrib contains the
00069  * ability to provide an iterator with the right interface for the expression
00070  * evaluation.
00071  */
00072 
00073 // include files
00074 #include "Particle/ParticleAttribBase.h"
00075 #include "Particle/ParticleAttribElem.h"
00076 #include "SubParticle/SubParticleAttrib.h"
00077 #include "DataSource/DataSource.h"
00078 #include "DataSource/MakeDataSource.h"
00079 #include "PETE/IpplExpressions.h"
00080 #include "Index/NDIndex.h"
00081 #include "Utility/DiscType.h"
00082 #include "Utility/Inform.h"
00083 #include "Utility/IpplStats.h"
00084 
00085 #ifdef IPPL_STDSTL
00086 #include <vector>
00087 using std::vector;
00088 #include <utility>
00089 using std::pair;
00090 #else
00091 #include <vector.h>
00092 #include <pair.h>
00093 #endif // IPPL_STDSTL
00094 
00095 
00096 // forward declarations
00097 template<class T, unsigned Dim> class Vektor;
00098 template<class T, unsigned Dim, class M, class C> class Field;
00099 template <class T> class ParticleAttribIterator;
00100 
00101 
00102 // ParticleAttrib class definition
00103 template <class T>
00104 class ParticleAttrib : public ParticleAttribBase, public DataSource,
00105                        public PETE_Expr< ParticleAttrib<T> >
00106 {
00107 
00108   friend class ParticleAttribIterator<T>;
00109 
00110 public:
00111   // useful typedefs for type of data contained here
00112   typedef T Return_t;
00113   typedef vector<T> ParticleList_t;
00114   typedef ParticleAttribIterator<T> iterator;
00115   typedef ParticleAttribBase::SortListIndex_t  SortListIndex_t;
00116   typedef ParticleAttribBase::SortList_t       SortList_t;
00117 
00118 public:
00119   // default constructor
00120   ParticleAttrib() : ParticleAttribBase(sizeof(T), DiscType<T>::str()) {
00121     INCIPPLSTAT(incParticleAttribs);
00122   }
00123 
00124   // copy constructor
00125   ParticleAttrib(const ParticleAttrib<T>& pa)
00126     : ParticleAttribBase(pa), ParticleList(pa.ParticleList) {
00127     INCIPPLSTAT(incParticleAttribs);
00128   }
00129 
00130   // destructor: delete the storage of the attribute array
00131   ~ParticleAttrib() { }
00132 
00133   //
00134   // bracket operators to access the Nth particle data
00135   //
00136 
00137   typename ParticleList_t::reference
00138   operator[](size_t n) {
00139     return ParticleList[n];
00140   }
00141 
00142   typename ParticleList_t::const_reference
00143   operator[](size_t n) const {
00144     return ParticleList[n];
00145   }
00146 
00147   //
00148   // bracket operator to refer to an attrib and an SIndex object
00149   //
00150 
00151   template<unsigned Dim>
00152   SubParticleAttrib<ParticleAttrib<T>, T, Dim>
00153   operator[](const SIndex<Dim> &s) const {
00154     ParticleAttrib<T> &a = const_cast<ParticleAttrib<T> &>(*this);
00155     return SubParticleAttrib<ParticleAttrib<T>, T, Dim>(a, s);
00156   }
00157 
00158   //
00159   // PETE interface.
00160   //
00161   enum { IsExpr = 0 };
00162   typedef iterator PETE_Expr_t;
00163   PETE_Expr_t MakeExpression() const { return begin(); }
00164 
00165   // Get begin and end point iterators
00166   iterator begin() const { return iterator((ParticleList_t&) ParticleList); }
00167   iterator end()   const {
00168     return iterator((ParticleList_t&) ParticleList).at_end();
00169   }
00170 
00171   size_t size(void) const { return ParticleList.size(); }
00172 
00173   //
00174   // methods to allow the user to access components of multipple-item attribs
00175   //
00176 
00177   // Create a ParticleAttribElem to allow the user to access just the Nth
00178   // element of the attribute stored here.
00179   ParticleAttribElem<T,1U> operator()(unsigned);
00180 
00181   // Same as above, but specifying two indices
00182   ParticleAttribElem<T,2U> operator()(unsigned, unsigned);
00183 
00184   // Same as above, but specifying three indices
00185   ParticleAttribElem<T,3U> operator()(unsigned, unsigned, unsigned);
00186 
00187   //
00188   // Particle <-> Field interaction methods
00189   //
00190 
00191   // scatter the data from this attribute onto the given Field, using
00192   // the given Position attribute
00193   template <unsigned Dim, class M, class C, class PT, class IntOp>
00194   void
00195   scatter(Field<T,Dim,M,C>& f,
00196           const ParticleAttrib< Vektor<PT,Dim> >& pp,
00197           const IntOp& intop) const {
00198     TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(pp) + ", " 
00199                     + CT(intop) + ")");
00200     TAU_PROFILE("ParticleAttrib::scatter()", taustr, TAU_PARTICLE);
00201 
00202     // make sure field is uncompressed and guard cells are zeroed
00203     f.Uncompress();
00204     T zero = 0;
00205     f.setGuardCells(zero);
00206 
00207     const M& mesh = f.get_mesh();
00208     // iterate through ParticleAttrib data and call scatter operation
00209     typename ParticleList_t::const_iterator curr, last = ParticleList.end();
00210     typename ParticleAttrib< Vektor<PT,Dim> >::iterator ppiter=pp.begin();
00211     for (curr = ParticleList.begin(); curr != last; ++curr, ++ppiter)
00212       IntOp::scatter(*curr,f,*ppiter,mesh);
00213 
00214     // accumulate values in guard cells (and compress result)
00215     f.accumGuardCells();
00216 
00217     INCIPPLSTAT(incParticleScatters);
00218     return;
00219   }
00220 
00221   // scatter the data from this attribute onto the given Field, using
00222   // the given Position attribute, and store the mesh information
00223   template <unsigned Dim, class M, class C, class PT,
00224             class IntOp, class CacheData>
00225   void
00226   scatter(Field<T,Dim,M,C>& f,
00227           const ParticleAttrib< Vektor<PT,Dim> >& pp,
00228           const IntOp& intop,
00229           ParticleAttrib<CacheData>& cache) const {
00230 
00231     TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(pp) + ", " 
00232                     + CT(intop) + ", " + CT(cache) + ")");
00233     TAU_PROFILE("ParticleAttrib::scatter()", taustr, TAU_PARTICLE);
00234 
00235     // make sure field is uncompressed and guard cells are zeroed
00236     f.Uncompress();
00237     T zero = 0;
00238     f.setGuardCells(zero);
00239 
00240     const M& mesh = f.get_mesh();
00241     // iterate through ParticleAttrib data and call scatter operation
00242     typename ParticleList_t::const_iterator curr, last = ParticleList.end();
00243     typename ParticleAttrib< Vektor<PT,Dim> >::iterator ppiter=pp.begin();
00244     typename ParticleAttrib<CacheData>::iterator citer=cache.begin();
00245     for (curr = ParticleList.begin(); curr != last; ++curr, ++ppiter, ++citer)
00246       IntOp::scatter(*curr,f,*ppiter,mesh,*citer);
00247 
00248     // accumulate values in guard cells (and compress result)
00249     f.accumGuardCells();
00250 
00251     INCIPPLSTAT(incParticleScatters);
00252     return;
00253   }
00254 
00255   // scatter the data from this attribute onto the given Field, using
00256   // the precomputed mesh information
00257   template <unsigned Dim, class M, class C, class IntOp, class CacheData>
00258   void
00259   scatter(Field<T,Dim,M,C>& f, const IntOp& intop,
00260           const ParticleAttrib<CacheData>& cache) const {
00261 
00262     TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(intop) + ", " 
00263                     + CT(cache)  + " )" );
00264     TAU_PROFILE("ParticleAttrib::scatter()", taustr, TAU_PARTICLE);
00265 
00266     // make sure field is uncompressed and guard cells are zeroed
00267     f.Uncompress();
00268     T zero = 0;
00269     f.setGuardCells(zero);
00270 
00271     // iterate through ParticleAttrib data and call scatter operation
00272     typename ParticleList_t::const_iterator curr, last = ParticleList.end();
00273     typename ParticleAttrib<CacheData>::iterator citer=cache.begin();
00274     for (curr = ParticleList.begin(); curr != last; ++curr, ++citer)
00275       IntOp::scatter(*curr,f,*citer);
00276 
00277     // accumulate values in guard cells (and compress result)
00278     f.accumGuardCells();
00279 
00280     INCIPPLSTAT(incParticleScatters);
00281     return;
00282   }
00283 
00284   // gather the data from the given Field into this attribute, using
00285   // the given Position attribute
00286   template <unsigned Dim, class M, class C, class PT, class IntOp>
00287   void
00288   gather(const Field<T,Dim,M,C>& f,
00289          const ParticleAttrib< Vektor<PT,Dim> >& pp,
00290          const IntOp& intop) {
00291     TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(pp) + ", " 
00292                     + CT(intop)  + " )" );
00293     TAU_PROFILE("ParticleAttrib::gather()", taustr, TAU_PARTICLE);
00294 
00295     // make sure field is uncompressed
00296     f.Uncompress();
00297     // fill guard cells if they are dirty
00298     if (f.isDirty())
00299       f.fillGuardCells(true);
00300 
00301     const M& mesh = f.get_mesh();
00302     // iterate through ParticleAttrib data and call gather operation
00303     typename ParticleList_t::iterator curr, last = ParticleList.end();
00304     typename ParticleAttrib< Vektor<PT,Dim> >::iterator ppiter=pp.begin();
00305     for (curr = ParticleList.begin(); curr != last; ++curr, ++ppiter)
00306       IntOp::gather(*curr,f,*ppiter,mesh);
00307 
00308     // try to compress the Field again
00309     f.Compress();
00310 
00311     INCIPPLSTAT(incParticleGathers);
00312     return;
00313   }
00314 
00315   // gather the data from the given Field into this attribute, using
00316   // the given Position attribute, and store the mesh information
00317   template <unsigned Dim, class M, class C, class PT,
00318            class IntOp, class CacheData>
00319   void
00320   gather(const Field<T,Dim,M,C>& f,
00321          const ParticleAttrib< Vektor<PT,Dim> >& pp,
00322          const IntOp& intop,
00323          ParticleAttrib<CacheData>& cache) {
00324 
00325     TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(pp) + ", " 
00326                     + CT(intop) + ", " + CT(cache) + ")");
00327     TAU_PROFILE("ParticleAttrib::gather()", taustr, TAU_PARTICLE);
00328 
00329     // make sure field is uncompressed
00330     f.Uncompress();
00331     // fill guard cells if they are dirty
00332     if (f.isDirty())
00333       f.fillGuardCells(true);
00334 
00335     const M& mesh = f.get_mesh();
00336     // iterate through ParticleAttrib data and call gather operation
00337     typename ParticleList_t::iterator curr, last = ParticleList.end();
00338     typename ParticleAttrib< Vektor<PT,Dim> >::iterator ppiter=pp.begin();
00339     typename ParticleAttrib<CacheData>::iterator citer=cache.begin();
00340     for (curr=ParticleList.begin(); curr != last; ++curr,++ppiter,++citer)
00341       IntOp::gather(*curr,f,*ppiter,mesh,*citer);
00342 
00343     // try to compress the Field again
00344     f.Compress();
00345 
00346     INCIPPLSTAT(incParticleGathers);
00347     return;
00348   }
00349 
00350   // gather the data from the given Field into this attribute, using
00351   // the precomputed mesh information
00352   template <unsigned Dim, class M, class C, class IntOp, class CacheData>
00353   void
00354   gather(const Field<T,Dim,M,C>& f, const IntOp& intop,
00355          const ParticleAttrib<CacheData>& cache) {
00356 
00357     TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(intop) + ", " 
00358                     + CT(cache)  + " )" );
00359     TAU_PROFILE("ParticleAttrib::gather()", taustr, TAU_PARTICLE);
00360 
00361     // make sure field is uncompressed
00362     f.Uncompress();
00363     // fill guard cells if they are dirty
00364     if (f.isDirty())
00365       f.fillGuardCells(true);
00366 
00367     // iterate through ParticleAttrib data and call gather operation
00368     typename ParticleList_t::iterator curr, last = ParticleList.end();
00369     typename ParticleAttrib<CacheData>::iterator citer=cache.begin();
00370     for (curr = ParticleList.begin(); curr != last; ++curr, ++citer)
00371       IntOp::gather(*curr,f,*citer);
00372 
00373     // try to compress the Field again
00374     f.Compress();
00375 
00376     INCIPPLSTAT(incParticleGathers);
00377     return;
00378   }
00379 
00380   //
00381   // Assignment operators
00382   //
00383 
00384   // assign a general expression
00385   template<class T1>
00386   const ParticleAttrib<T>& operator=(const PETE_Expr<T1>& rhs) {
00387     assign(*this,rhs);
00388     return *this;
00389   }
00390 
00391   // assignment of a ParticleAttrib
00392   const ParticleAttrib<T>& operator=(const ParticleAttrib<T>& rhs) {
00393     if (size() != rhs.size()) {
00394       ERRORMSG("Attempting to copy particle attributes with unequal sizes.");
00395       ERRORMSG("\n" << size() << " != " << rhs.size() << endl);
00396     }
00397     assign(*this,rhs);
00398     return *this;
00399   }
00400 
00401   // assignment of a scalar
00402   const ParticleAttrib<T>& operator=(T rhs) {
00403     assign(*this,rhs);
00404     return *this;
00405   }
00406 
00407   //
00408   // methods used to manipulate the normal attrib data
00409   //
00410 
00411   // Create storage for M particle attributes.  The storage is uninitialized.
00412   // New items are appended to the end of the array.
00413   virtual void create(size_t);
00414 
00415   // Delete the attribute storage for M particle attributes, starting at
00416   // the position I.
00417   // This really erases the data, which will change local indices
00418   // of the data.  It actually just copies the data from the end of the
00419   // storage into the selected block
00420   // Boolean flag indicates whether to use optimized destroy method
00421   virtual void destroy(size_t M, size_t I, bool optDestroy=true);
00422 
00423   // This version takes a list of particle destroy events
00424   // Boolean flag indicates whether to use optimized destroy method
00425   virtual void destroy(const vector< pair<size_t,size_t> >& dlist,
00426                        bool optDestroy=true);
00427 
00428   // puts M particle's data starting from index I into a Message.
00429   // Return the number of particles put into the message.
00430   virtual size_t putMessage(Message&, size_t, size_t);
00431 
00432   // Another version of putMessage, which takes list of indices
00433   // Return the number of particles put into the message.
00434   virtual size_t putMessage(Message&, const vector<size_t>&);
00435 
00436   // Get data out of a Message containing N particle's attribute data,
00437   // and store it here.  Data is appended to the end of the list.  Return
00438   // the number of particles retrieved.
00439   virtual size_t getMessage(Message&, size_t);
00440 
00441   //
00442   // methods used to manipulate the ghost particle data
00443   //
00444 
00445   // Delete the ghost attrib storage for M particles, starting at pos I.
00446   // Items from the end of the list are moved up to fill in the space.
00447   // Return the number of items actually destroyed.
00448   virtual size_t ghostDestroy(size_t, size_t) {
00449     return 0;
00450   }
00451 
00452   // puts M particle's data starting from index I into a Message.
00453   // Return the number of particles put into the message.  This is for
00454   // when particles are being swapped to build ghost particle interaction
00455   // lists.
00456   virtual size_t ghostPutMessage(Message&, size_t, size_t) {
00457     return 0;
00458   }
00459   // puts data for a list of particles into a Message, for interaction lists.
00460   // Return the number of particles put into the message.
00461   virtual size_t ghostPutMessage(Message&, const vector<size_t>&) {
00462     return 0;
00463   }
00464 
00465   // Get ghost particle data from a message.
00466   virtual size_t ghostGetMessage(Message&, size_t) {
00467     return 0;
00468   }
00469 
00470   //
00471   // virtual methods used to sort data
00472   //
00473 
00474   // Calculate a "sort list", which is an array of data of the same
00475   // length as this attribute, with each element indicating the
00476   // (local) index wherethe ith particle shoulkd go.  For example, 
00477   // if there are four particles, and the sort-list is {3,1,0,2}, that
00478   // means the particle currently with index=0 should be moved to the third
00479   // position, the one with index=1 should stay where it is, etc.
00480   // The optional second argument indicates if the sort should be ascending
00481   // (true, the default) or descending (false).
00482   virtual void calcSortList(SortList_t &slist, bool ascending = true);
00483 
00484   // Process a sort-list, as described for "calcSortList", to reorder
00485   // the elements in this attribute.  All indices in the sort list are
00486   // considered "local", so they should be in the range 0 ... localnum-1.
00487   // The sort-list does not have to have been calcualted by calcSortList,
00488   // it could be calculated by some other means, but it does have to
00489   // be in the same format.  Note that the routine may need to modify
00490   // the sort-list temporarily, but it will return it in the same state.
00491   virtual void sort(SortList_t &slist);
00492 
00493   //
00494   // other functions
00495   //
00496 
00497   // Print out information for debugging purposes.
00498   virtual void printDebug(Inform&);
00499 
00500 protected:
00501   // a virtual function which is called by this base class to get a
00502   // specific instance of DataSourceObject based on the type of data
00503   // and the connection method (the argument to the call).
00504   virtual DataSourceObject *createDataSourceObject(const char *nm,
00505                                                    DataConnect *dc, int tm) {
00506     return make_DataSourceObject(nm, dc, tm, *this);
00507   }
00508 
00509   // storage for particle data
00510   ParticleList_t ParticleList;
00511 };
00512 
00513 
00514 //
00515 // iterator for data in a ParticleAttrib
00516 //
00517 
00518 template <class T>
00519 class ParticleAttribIterator : public PETE_Expr< ParticleAttribIterator<T> >
00520 {
00521   public:
00522     typedef typename ParticleAttrib<T>::ParticleList_t ParticleList_t;
00523 
00524     ParticleAttribIterator() : myList(0), curr(0) { }
00525 #ifdef __MWERKS__
00526   ParticleAttribIterator(ParticleList_t& pa)
00527     : myList(&pa), curr(&(*pa.begin())) { }
00528 #else
00529   // Is this bad C++ or mwerks bug? Certain STL implems this might be wrong:
00530   //  ParticleAttribIterator(ParticleList_t& pa)
00531   //    : myList(&pa), curr(pa.begin()) { }
00532   ParticleAttribIterator(ParticleList_t& pa)
00533     : myList(&pa), curr(&(*pa.begin())) { }
00534 #endif // __MWERKS
00535     ParticleAttribIterator(const ParticleAttribIterator<T>& i)
00536       : myList(i.myList), curr(i.curr) { }
00537 
00538     // PETE interface.
00539     typedef ParticleAttribIterator<T> PETE_Expr_t;
00540     typedef T PETE_Return_t;
00541     PETE_Expr_t MakeExpression() const { return *this; }
00542     PETE_Return_t& operator*(void) const { return *curr; }
00543 
00544     ParticleAttribIterator<T>& operator++(void) {
00545       ++curr;
00546       return *this;
00547     }
00548     ParticleAttribIterator<T>& at_end(void) {
00549 #ifdef __MWERKS__
00550       curr = &*myList->end();
00551 #else
00552   // Is this bad C++ or mwerks bug? Certain STL implems this might be wrong:
00553       //      curr = myList->end();
00554       curr = &*myList->end();
00555 #endif // __MWERKS__
00556       return *this;
00557     }
00558     bool operator==(const ParticleAttribIterator<T>& a) const {
00559       return  (curr == a.curr);
00560     }
00561     bool operator!=(const ParticleAttribIterator<T>& a) const {
00562       return !(curr == a.curr);
00563     }
00564     const ParticleList_t& getParticleList() const { return *myList; }
00565     T* getP() const { return curr; }
00566 
00567   private:
00568     ParticleList_t* myList;        // ParticleList I iterate over
00569     T* curr;                       // iterator current position
00570 };
00571 
00572 
00573 // Global template functions for gather/scatter operations
00574 
00575 // scatter the data from the given attribute onto the given Field, using
00576 // the given Position attribute
00577 template <class FT, unsigned Dim, class M, class C, class PT, class IntOp>
00578 inline
00579 void scatter(const ParticleAttrib<FT>& attrib, Field<FT,Dim,M,C>& f,
00580              const ParticleAttrib< Vektor<PT,Dim> >& pp, const IntOp& intop) {
00581   attrib.scatter(f, pp, intop);
00582 }
00583 
00584 // scatter the data from the given attribute onto the given Field, using
00585 // the given Position attribute, and save the mesh information for reuse
00586 template <class FT, unsigned Dim, class M, class C, class PT,
00587           class IntOp, class CacheData>
00588 inline
00589 void scatter(const ParticleAttrib<FT>& attrib, Field<FT,Dim,M,C>& f,
00590              const ParticleAttrib< Vektor<PT,Dim> >& pp, const IntOp& intop,
00591              ParticleAttrib<CacheData>& cache) {
00592   attrib.scatter(f, pp, intop, cache);
00593 }
00594 
00595 // scatter the data from the given attribute onto the given Field, using
00596 // the precomputed mesh information
00597 template <class FT, unsigned Dim, class M, class C,
00598           class IntOp, class CacheData>
00599 inline
00600 void scatter(const ParticleAttrib<FT>& attrib, Field<FT,Dim,M,C>& f,
00601              const IntOp& intop, const ParticleAttrib<CacheData>& cache) {
00602   attrib.scatter(f, intop, cache);
00603 }
00604 
00605 // gather the data from the given Field into the given attribute, using
00606 // the given Position attribute
00607 template <class FT, unsigned Dim, class M, class C, class PT, class IntOp>
00608 inline
00609 void gather(ParticleAttrib<FT>& attrib, const Field<FT,Dim,M,C>& f,
00610             const ParticleAttrib< Vektor<PT,Dim> >& pp, const IntOp& intop) {
00611   attrib.gather(f, pp, intop);
00612 }
00613 
00614 // gather the data from the given Field into the given attribute, using
00615 // the given Position attribute, and save the mesh information for reuse
00616 template <class FT, unsigned Dim, class M, class C, class PT,
00617           class IntOp, class CacheData>
00618 inline
00619 void gather(ParticleAttrib<FT>& attrib, const Field<FT,Dim,M,C>& f,
00620             const ParticleAttrib< Vektor<PT,Dim> >& pp, const IntOp& intop,
00621             ParticleAttrib<CacheData>& cache) {
00622   attrib.gather(f, pp, intop, cache);
00623 }
00624 
00625 // gather the data from the given Field into the given attribute, using
00626 // the precomputed mesh information
00627 template <class FT, unsigned Dim, class M, class C,
00628           class CacheData, class IntOp>
00629 inline
00630 void gather(ParticleAttrib<FT>& attrib, const Field<FT,Dim,M,C>& f,
00631             const IntOp& intop, const ParticleAttrib<CacheData>& cache) {
00632   attrib.gather(f, intop, cache);
00633 }
00634 
00635 // This scatter function computes the particle number density by 
00636 // scattering the scalar value val for each particle into the Field.
00637 template <class FT, unsigned Dim, class M, class C, class PT, class IntOp>
00638 void scatter(Field<FT,Dim,M,C>& f, const ParticleAttrib< Vektor<PT,Dim> >& pp,
00639              const IntOp& intop, FT val);
00640 
00641 // version which also caches mesh info
00642 template <class FT, unsigned Dim, class M, class C, class PT,
00643           class IntOp, class CacheData>
00644 void scatter(Field<FT,Dim,M,C>& f, const ParticleAttrib< Vektor<PT,Dim> >& pp,
00645              const IntOp& intop, ParticleAttrib<CacheData>& cache,
00646              FT val);
00647 
00648 // version which uses cached mesh info
00649 template <class FT, unsigned Dim, class M, class C,
00650           class IntOp, class CacheData>
00651 void scatter(Field<FT,Dim,M,C>& f, const IntOp& intop,
00652              const ParticleAttrib<CacheData>& cache, FT val);
00653 
00654 // mwerks: addeded this to work around default-arg bug:
00655 // This scatter function computes the particle number density by 
00656 // scattering the scalar value val for each particle into the Field.
00657 template <class FT, unsigned Dim, class M, class C, class PT, class IntOp>
00658 void scatter(Field<FT,Dim,M,C>& f, const ParticleAttrib< Vektor<PT,Dim> >& pp,
00659              const IntOp& intop){
00660   scatter(f, pp, intop, FT(1));
00661 }
00662 
00663 // mwerks: addeded this to work around default-arg bug:
00664 // version which also caches mesh info
00665 template <class FT, unsigned Dim, class M, class C, class PT,
00666           class IntOp, class CacheData>
00667 void scatter(Field<FT,Dim,M,C>& f, const ParticleAttrib< Vektor<PT,Dim> >& pp,
00668              const IntOp& intop, ParticleAttrib<CacheData>& cache) {
00669   scatter(f, pp, intop, cache, FT(1));
00670 }
00671 
00672 // mwerks: addeded this to work around default-arg bug:
00673 // version which uses cached mesh info
00674 template <class FT, unsigned Dim, class M, class C,
00675           class IntOp, class CacheData>
00676 void scatter(Field<FT,Dim,M,C>& f, const IntOp& intop,
00677              const ParticleAttrib<CacheData>& cache) {
00678   scatter(f, intop, cache, FT(1));
00679 }
00680 
00681 #include "Particle/ParticleAttrib.cpp"
00682 
00683 #endif // PARTICLE_ATTRIB_H
00684 
00685 /***************************************************************************
00686  * $RCSfile: ParticleAttrib.h,v $   $Author: adelmann $
00687  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:28 $
00688  * IPPL_VERSION_ID: $Id: ParticleAttrib.h,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $ 
00689  ***************************************************************************/

Generated on Mon Jan 16 13:23:52 2006 for IPPL by  doxygen 1.4.6