src/SubParticle/SubParticleAttrib.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 SUB_PARTICLE_ATTRIB_H
00012 #define SUB_PARTICLE_ATTRIB_H
00013 
00014 /***************************************************************************
00015   SubParticleAttrib - represents a view on a given ParticleAttrib or
00016   ParticleAttribElem, given an SIndex.  It is used in gathering or
00017   scattering data from SIndex-listed points in a Field to a ParticleAttrib.
00018 
00019   SubParticleAttrib is templated on the general attribute type (either
00020   ParticleAttrib or ParticleAttribElem), the type of the data, and the
00021   Dim of the data.  It will only work with these cases indexed by an
00022   SIndex object.  In that case, the SIndex represents a 1-D "serialization"
00023   of any other N-D object, such as a BareField, so that ParticleAttrib's
00024   can be involved directly with BareField's in expressions.  The syntax is
00025   like this:
00026                 SIndex<Dim> S = (some expression);
00027                 BareField<T,Dim> A = (some value);
00028                 ParticleAttrib<T> PA;
00029                 PA[S] = A[S];
00030   In this case, S refers to a set of points in the field, and the expression
00031   loops through all the LOCAL points in the sparse index object S and
00032   assigns the value of the expression to PA.  PA will be changed in length
00033   to have the same number of elements, on each processor, as there are local
00034   sparse index points.  The RHS can be any expression, as long as all Field
00035   and ParticleAttrib's are indexed by a sparse index.  This is basically
00036   a random 'gather' from the field to the attribute storage.  The opposite
00037   operation is like this:
00038                 A[S] = PA[S] + (other expression terms);
00039   In that case, PA[S] can act like any other SIndex-indexed object in the
00040   expression.  It just needs to have the proper number of elements.  This
00041   is then a 'scatter' of values from the attribute back to the field.
00042 
00043   SubParticleAttrib does not define any further [] operators, etc. as does
00044   SubBareField.  It is used when you apply [] with an SIndex object to a
00045   ParticleAttrib or ParticleAttribElem.  It has the extra interface to
00046   supply the necessary iterators to participate in a SIndex PETE expression.
00047   The user will not typically make any of these objects themselves.
00048 
00049  ***************************************************************************/
00050 
00051 // include files
00052 #include "SubField/SubFieldIter.h"
00053 #include "PETE/IpplExpressions.h"
00054 
00055 #ifdef IPPL_USE_STANDARD_HEADERS
00056 #include <iostream>
00057 using namespace std;
00058 #else
00059 #include <iostream.h>
00060 #endif
00061 
00062 // forward declarations
00063 template <class PA, class T, unsigned Dim> class SubParticleAttrib;
00064 template <class PA, class T, unsigned Dim>
00065 ostream& operator<<(ostream &, const SubParticleAttrib<PA,T,Dim> &);
00066 
00067 
00068 // an iterator for a SubParticleAttrib.  This must be defined outside the
00069 // class for proper templated function resolution.
00070 template <class PA, class T, unsigned Dim>
00071 class SubParticleAttribIter
00072   : public PETE_Expr< SubParticleAttribIter<PA,T,Dim> >
00073 {
00074 public:
00075   // useful typedefs
00076   typedef SIndex<Dim>                         Index_t;
00077   typedef SubFieldIter<T, Dim, Index_t>       SFI;
00078   typedef typename Index_t::const_iterator_iv const_iterator_iv;
00079 
00080   // constructor
00081   SubParticleAttribIter(PA &a, const_iterator_iv lf, int o, const Index_t &s)
00082     : dom(&s), attrib(&a), lfield(lf), attribOffset(o) { }
00083 
00084   // copy constructor
00085   SubParticleAttribIter(const SubParticleAttribIter<PA,T,Dim> &i)
00086     : attrib(const_cast<PA *>(i.attrib)),
00087       dom(i.dom), lfield(i.lfield), attribOffset(i.attribOffset) { }
00088 
00089   // default constructor
00090   SubParticleAttribIter() : dom(0), attrib(0), attribOffset(0) { }
00091 
00092   // destructor
00093   ~SubParticleAttribIter() { }
00094 
00095   bool operator!=(const SubParticleAttribIter<PA,T,Dim> &i) {
00096     return (attribOffset != i.attribOffset);
00097   }
00098 
00099   PA             &getAttrib()       { return *attrib; }
00100   const Index_t  &getDomain() const { return *dom; }
00101 
00102   static int  getSubsetType()       { return SFI::getSubsetType(); }
00103   static bool matchType(int t)      { return SFI::matchType(t); }
00104 
00105   void initialize()                 { }
00106 
00107   int size() const                  { return attrib->size(); }
00108   int size(int) const               { return (*lfield)->size(); }
00109   T& offset(int i)                  { return (*attrib)[attribOffset + i]; }
00110   T& unit_offset(int i)             { return (*attrib)[attribOffset + i]; }
00111 
00112   static void makeNDIndex(const Index_t &s, NDIndex<Dim>& i) {
00113     i = s.getDomain();
00114   }
00115 
00116   const_iterator_iv nextLField() {
00117     attribOffset += size(0);
00118     ++lfield;
00119     return lfield;
00120   }
00121 
00122   const_iterator_iv getLFieldIter() const {
00123     return lfield;
00124   }
00125 
00126   bool plugBase(const NDIndex<Dim>&) {
00127     return true;
00128   }
00129 
00130   //
00131   // PETE Interface
00132   //
00133 
00134   enum                                    { IsExpr = 1 };
00135   typedef SubParticleAttribIter<PA,T,Dim> PETE_Expr_t;
00136   typedef T                               PETE_Return_t;
00137   PETE_Expr_t MakeExpression() const { return *this; }
00138 
00139 private:
00140   // the domain, the attrib, and the iterator to the first vnode to use
00141   const Index_t     *dom;
00142   PA                *attrib;
00143   const_iterator_iv  lfield;
00144 
00145   // our current starting offset for indexing into the attrib array.  This
00146   // is changed as we switch among LFields.
00147   int attribOffset;
00148 };
00149 
00150 
00151 // The SubParticleAttrib class declaration.
00152 template <class PA, class T, unsigned Dim>
00153 class SubParticleAttrib : public PETE_Expr< SubParticleAttrib<PA,T,Dim> > {
00154 
00155 public:
00156   // useful typedefs
00157   typedef PA                              Attrib_t;
00158   typedef T                               T_t;
00159   typedef SubParticleAttribIter<PA,T,Dim> iterator;
00160   typedef typename iterator::Index_t      Index_t;
00161 
00162   // useful enums
00163   enum { Dim_u = Dim };
00164 
00165   // constructor
00166   SubParticleAttrib(PA &a, const Index_t &dom)
00167     : A(a), MyDomain(dom) { }
00168 
00169   // copy constructor
00170   SubParticleAttrib(const SubParticleAttrib<PA,T,Dim> &spa)
00171     : A(const_cast<PA &>(spa.A)), MyDomain(spa.MyDomain) { }
00172 
00173   // destructor
00174   ~SubParticleAttrib() { }
00175 
00176   //
00177   // accessor functions
00178   //
00179 
00180   // return the 'domain', that is, the information which subsets the field
00181   const Index_t &getDomain() const { return MyDomain; }
00182 
00183   // return a reference to the attribute we are subsetting
00184   PA &getAttrib() const { return A; }
00185 
00186   // Return a typecode for the subset object
00187   static int getSubsetType() { return iterator::getSubsetType(); }
00188 
00189   // Return an NDIndex representing the bounding box of this object
00190   void makeNDIndex(NDIndex<Dim>& i) { iterator::makeNDIndex(MyDomain, i); }
00191 
00192   // Return the beginning and end iterators for this class.
00193   iterator begin() const;
00194   iterator end() const;
00195 
00196   // Make sure the LHS ParticleAttrib has the proper length.  It should
00197   // have the same length as the number of LOCAL sparse index points.
00198   // If it does not, we readjust the length.  Return the size of the result.
00199   int adjustSize();
00200 
00201   //
00202   // assignment operators
00203   //
00204 
00205   // assignment of another SubParticleAttrib
00206   SubParticleAttrib<PA,T,Dim>& operator=(const SubParticleAttrib<PA,T,Dim> &);
00207 
00208   // assignment of a scalar
00209   SubParticleAttrib<PA,T,Dim>& operator=(T);
00210 
00211   // assignment of an arbitrary expression
00212   //mwerks  template<class B>
00213   //mwerks  SubParticleAttrib<PA,T,Dim>& operator=(const PETE_Expr<B> &);
00215   // assignment of an arbitrary expression
00216   template<class B>
00217   SubParticleAttrib<PA,T,Dim>&
00218   operator=(const PETE_Expr<B> &b) {
00219     TAU_TYPE_STRING(taustr, CT(*this) + " (" + CT(b) + " )" );
00220     TAU_PROFILE("SubParticleAttrib::operator=()", taustr,
00221                 TAU_SUBFIELD | TAU_ASSIGN);
00222 
00223     // invoke the complex expression assignment, which gathers items from
00224     // the expression and puts them in the attribute
00225     assign(*this, b);
00226     return *this;
00227   }
00228 
00229   //
00230   // I/O
00231   //
00232 
00233   void write(ostream &) const;
00234 
00235   //
00236   // PETE interface
00237   //
00238 
00239   enum { IsExpr = 1 };
00240   typedef iterator PETE_Expr_t;
00241   PETE_Expr_t MakeExpression() const { return begin(); }
00242 
00243 private:
00244   // the attribute we are subsetting
00245   PA &A;
00246 
00247   // the 'domain', that is, the information which subsets the object
00248   const Index_t &MyDomain;
00249 };
00250 
00251 // I/O
00252 
00253 // write to the given ostream
00254 template<class PA, class T, unsigned Dim>
00255 inline
00256 ostream& operator<<(ostream &o, const SubParticleAttrib<PA,T,Dim> &n) {
00257   TAU_TYPE_STRING(taustr, "ostream (ostream, " + CT(s) + " )" );
00258   TAU_PROFILE("SubParticleAttrib::operator<<()", taustr,
00259               TAU_SUBFIELD | TAU_IO );
00260   n.write(o);
00261   return o;
00262 }
00263 
00264 
00265 #include "SubParticle/SubParticleAttrib.cpp"
00266 
00267 #endif
00268 
00269 /***************************************************************************
00270  * $RCSfile: SubParticleAttrib.h,v $   $Author: adelmann $
00271  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00272  * IPPL_VERSION_ID: $Id: SubParticleAttrib.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00273  ***************************************************************************/

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