src/Particle/ParticleAttribElem.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_ELEM_H
00012 #define PARTICLE_ATTRIB_ELEM_H
00013 
00014 /*
00015  * ParticleAttribElem - Templated class for indexed particle attrib elements.
00016  *
00017  * This templated class is used to access individual elements of a particle
00018  * attribute in an expression, such as the Nth component of a Vektor or
00019  * the (i,j) element of a Tenzor.  It employs the () operator to access the
00020  * desired quantity, and may participate in particle expressions.
00021  *
00022  * Use of this capability requires the following:
00023  *   1) the data type for the attribute must have the operator() defined,
00024  *      with the proper number of indices (for example, Vektor has an
00025  *      operator(unsigned), and Tenzor has an operator(unsigned, unsigned)
00026  *      to access the (i,j)th element).
00027  *   2) the data type must have a typedef Return defined within it specifying
00028  *      the type of the individual elements; for Vektor<T, Dim>, you need a
00029  *      'typedef T Return' statement in the Vektor code.
00030  */
00031 
00032 // include files
00033 #include "SubParticle/SubParticleAttrib.h"
00034 #include "PETE/IpplExpressions.h"
00035 #include "Utility/Vec.h"
00036 #include "AppTypes/AppTypeTraits.h"
00037 #include <stddef.h>
00038 
00039 // forward declarations
00040 template <class T, unsigned Dim> class ParticleAttribElemIterator;
00041 template <class T>               class ParticleAttrib;
00042 
00043 
00044 // a simple templated function to extract the Nth element of an object
00045 // which has several elements accessed using the () operator.  We define
00046 // versions for 1, 2, and 3D
00047 template<class T>
00048 inline typename AppTypeTraits<T>::Element_t&
00049 get_PETE_Element(T& elem, const vec<unsigned,1U>& indx) {
00050   return elem(indx[0]);
00051 }
00052 template<class T>
00053 inline typename AppTypeTraits<T>::Element_t&
00054 get_PETE_Element(T& elem, const vec<unsigned,2U>& indx) {
00055   return elem(indx[0], indx[1]);
00056 }
00057 template<class T>
00058 inline typename AppTypeTraits<T>::Element_t&
00059 get_PETE_Element(T& elem, const vec<unsigned,3U>& indx) {
00060   return elem(indx[0], indx[1], indx[2]);
00061 }
00062 
00063 
00064 
00065 // ParticleAttribElem - templated on type of data and number of indices
00066 template<class T, unsigned Dim>
00067 class ParticleAttribElem : public PETE_Expr< ParticleAttribElem<T,Dim> > {
00068 
00069   friend class ParticleAttribElemIterator<T,Dim>;
00070 
00071 public:
00072   // type of data contained in the attribute elements
00073   typedef typename AppTypeTraits<T>::Element_t Element_t;
00074   typedef ParticleAttribElemIterator<T,Dim> iterator;
00075 
00076   //
00077   // PETE interface.
00078   //
00079   enum { IsExpr = 0 };
00080   typedef iterator PETE_Expr_t;
00081   PETE_Expr_t MakeExpression() const { return begin(); }
00082 
00083 public:
00084   // constructor: arguments = begin and end iterators (expected to be
00085   // pointers), and indices
00086   ParticleAttribElem(ParticleAttrib<T> &pa, const vec<unsigned,Dim>& i)
00087     : Attrib(pa), indx(i) { }
00088 
00089   // copy constructor
00090   ParticleAttribElem(const ParticleAttribElem<T,Dim>& pae)
00091     : Attrib((ParticleAttrib<T> &)(pae.Attrib)), indx(pae.indx) { }
00092 
00093   // return begin and end iterators for this container
00094   iterator begin() const {
00095     return iterator((ParticleAttribElem<T,Dim>&) *this, 0);
00096   }
00097   iterator end()   const {
00098     return iterator((ParticleAttribElem<T,Dim>&) *this, size());
00099   }
00100 
00101   // return the size of this container
00102   size_t size() const {
00103     return Attrib.size();
00104   }
00105 
00106   //
00107   // methods to make this object have an interface similar to ParticleAttrib
00108   //
00109 
00110   // get the Nth element
00111   Element_t &operator[](size_t);
00112 
00113   // Create storage for M particle attributes.  The storage is uninitialized.
00114   // New items are appended to the end of the array.
00115   void create(size_t);
00116 
00117   // Delete the attribute storage for M particle attributes, starting at
00118   // the position I.
00119   void destroy(size_t M, size_t I, bool optDestroy=true);
00120 
00121   // This version takes a list of particle destroy events
00122   // Boolean flag indicates whether to use optimized destroy method
00123   void destroy(const vector< pair<size_t,size_t> >& dlist,
00124                bool optDestroy=true);
00125 
00126   //
00127   // bracket operator to refer to an attrib and an SIndex object
00128   //
00129 
00130   template<unsigned SDim>
00131   SubParticleAttrib<ParticleAttribElem<T,Dim>, Element_t, SDim>
00132   operator[](const SIndex<SDim> &s) const {
00133     return SubParticleAttrib<ParticleAttribElem<T,Dim>, Element_t, SDim>(
00134         (ParticleAttribElem<T,Dim> &)(*this), s);
00135   }
00136 
00137   //
00138   // Assignment operators
00139   //
00140 
00141 #ifdef __MWERKS__
00142   // assign a general expression
00143   template<class T1>
00144   const ParticleAttribElem<T,Dim>& operator=(PETE_Expr<T1>& rhs) {
00145     assign(*this,rhs);
00146     return *this;
00147   }
00148 #else
00149   // assign a general expression
00150   template<class T1>
00151   const ParticleAttribElem<T,Dim>& operator=(const PETE_Expr<T1>& rhs) {
00152     assign(*this,rhs);
00153     return *this;
00154   }
00155 #endif // __MWERKS__
00156 
00157 #ifdef __MWERKS__ // 1/8/99 Needed?
00158   // assignment of a ParticleAttribElem
00159   const ParticleAttribElem<T,Dim>&
00160   operator=(ParticleAttribElem<T,Dim>& rhs) {
00161     if (size() > rhs.size()) {
00162       ERRORMSG("Attempting to copy particle attributes with unequal sizes.");
00163       ERRORMSG("\n" << size() << " != " << rhs.size() << endl);
00164     }
00165     assign(*this,rhs);
00166     return *this;
00167   }
00168 #else
00169   // assignment of a ParticleAttribElem
00170   const ParticleAttribElem<T,Dim>&
00171   operator=(const ParticleAttribElem<T,Dim>& rhs) {
00172     if (size() > rhs.size()) {
00173       ERRORMSG("Attempting to copy particle attributes with unequal sizes.");
00174       ERRORMSG("\n" << size() << " != " << rhs.size() << endl);
00175     }
00176     assign(*this,rhs);
00177     return *this;
00178   }
00179 #endif // __MWERKS__
00180 
00181   // assignment of a scalar
00182   const ParticleAttribElem<T,Dim>& operator=(Element_t rhs) {
00183     assign(*this,PETE_Scalar<Element_t>(rhs),OpAssign());
00184     return *this;
00185   }
00186 
00187 private:
00188   // the attribute we're finding the Nth element of
00189   ParticleAttrib<T> &Attrib;
00190 
00191   // the desired index
00192   vec<unsigned,Dim> indx;
00193 };
00194 
00195 
00196 // an iterator for the elements in this particle attribute
00197 template <class T, unsigned Dim>
00198 class ParticleAttribElemIterator
00199   : public PETE_Expr< ParticleAttribElemIterator<T,Dim> > {
00200 
00201 public:
00202   ParticleAttribElemIterator() : PAE(0), aptr(0) { }
00203   ParticleAttribElemIterator(ParticleAttribElem<T,Dim>& pae, int p)
00204     : PAE(&pae), aptr(p) { }
00205   ParticleAttribElemIterator(const ParticleAttribElemIterator<T,Dim>& i)
00206     : PAE(i.PAE), aptr(i.aptr) { }
00207 
00208   // PETE interface
00209   typedef ParticleAttribElemIterator<T,Dim> PETE_Expr_t;
00210   typedef typename AppTypeTraits<T>::Element_t PETE_Return_t;
00211   PETE_Expr_t MakeExpression() const { return *this; }
00212   PETE_Return_t& operator*() { return (*PAE)[aptr]; }
00213 
00214   ParticleAttribElemIterator<T,Dim>& operator++() {
00215     ++aptr;
00216     return *this;
00217   }
00218   ParticleAttribElemIterator<T,Dim>& rewind() {
00219     aptr = 0;
00220     return *this;
00221   }
00222 
00223   bool operator!=(const ParticleAttribElemIterator<T,Dim>& a) const {
00224     return (PAE != a.PAE || aptr != a.aptr);
00225   }
00226   bool operator==(const ParticleAttribElemIterator<T,Dim>& a) const {
00227     return (PAE == a.PAE && aptr == a.aptr);
00228   }
00229 
00230   const ParticleAttribElem<T,Dim>& getParticleAttribElem() const {
00231     return *PAE;
00232   }
00233 
00234 private:
00235   ParticleAttribElem<T,Dim> *PAE;
00236   int aptr;
00237 };
00238 
00239 // definitions of routines used to make ParticleAttribElem have an interface
00240 // similar to ParticleAttrib
00241 #include "Particle/ParticleAttrib.h"
00242 
00243 template<class T, unsigned Dim>
00244 inline
00245 typename ParticleAttribElem<T,Dim>::Element_t &
00246 ParticleAttribElem<T,Dim>::operator[](size_t n) {
00247   return get_PETE_Element(Attrib[n], indx);
00248 }
00249 
00250 template<class T, unsigned Dim>
00251 inline void
00252 ParticleAttribElem<T,Dim>::create(size_t M) {
00253   Attrib.create(M);
00254 }
00255 
00256 template<class T, unsigned Dim>
00257 inline void
00258 ParticleAttribElem<T,Dim>::destroy(size_t M, size_t I,
00259                                    bool optDestroy) {
00260   Attrib.destroy(M, I, optDestroy);
00261 }
00262 
00263 template<class T, unsigned Dim>
00264 inline void
00265 ParticleAttribElem<T,Dim>::destroy(const vector< pair<size_t,size_t> > &d,
00266                                    bool optDestroy) {
00267   Attrib.destroy(d, optDestroy);
00268 }
00269 
00270 
00271 #endif // PARTICLE_ATTRIB_ELEM_H
00272 
00273 /***************************************************************************
00274  * $RCSfile: ParticleAttribElem.h,v $   $Author: adelmann $
00275  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:28 $
00276  * IPPL_VERSION_ID: $Id: ParticleAttribElem.h,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $ 
00277  ***************************************************************************/

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