OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
SubParticleAttrib.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  *
7  * Visit http://people.web.psi.ch/adelmann/ for more details
8  *
9  ***************************************************************************/
10 
11 #ifndef SUB_PARTICLE_ATTRIB_H
12 #define SUB_PARTICLE_ATTRIB_H
13 
14 /***************************************************************************
15  SubParticleAttrib - represents a view on a given ParticleAttrib or
16  ParticleAttribElem, given an SIndex. It is used in gathering or
17  scattering data from SIndex-listed points in a Field to a ParticleAttrib.
18 
19  SubParticleAttrib is templated on the general attribute type (either
20  ParticleAttrib or ParticleAttribElem), the type of the data, and the
21  Dim of the data. It will only work with these cases indexed by an
22  SIndex object. In that case, the SIndex represents a 1-D "serialization"
23  of any other N-D object, such as a BareField, so that ParticleAttrib's
24  can be involved directly with BareField's in expressions. The syntax is
25  like this:
26  SIndex<Dim> S = (some expression);
27  BareField<T,Dim> A = (some value);
28  ParticleAttrib<T> PA;
29  PA[S] = A[S];
30  In this case, S refers to a set of points in the field, and the expression
31  loops through all the LOCAL points in the sparse index object S and
32  assigns the value of the expression to PA. PA will be changed in length
33  to have the same number of elements, on each processor, as there are local
34  sparse index points. The RHS can be any expression, as long as all Field
35  and ParticleAttrib's are indexed by a sparse index. This is basically
36  a random 'gather' from the field to the attribute storage. The opposite
37  operation is like this:
38  A[S] = PA[S] + (other expression terms);
39  In that case, PA[S] can act like any other SIndex-indexed object in the
40  expression. It just needs to have the proper number of elements. This
41  is then a 'scatter' of values from the attribute back to the field.
42 
43  SubParticleAttrib does not define any further [] operators, etc. as does
44  SubBareField. It is used when you apply [] with an SIndex object to a
45  ParticleAttrib or ParticleAttribElem. It has the extra interface to
46  supply the necessary iterators to participate in a SIndex PETE expression.
47  The user will not typically make any of these objects themselves.
48 
49  ***************************************************************************/
50 
51 // include files
52 #include "SubField/SubFieldIter.h"
53 #include "PETE/IpplExpressions.h"
54 
55 #include <iostream>
56 
57 // forward declarations
58 template <class PA, class T, unsigned Dim> class SubParticleAttrib;
59 template <class PA, class T, unsigned Dim>
60 std::ostream& operator<<(std::ostream &, const SubParticleAttrib<PA,T,Dim> &);
61 
62 
63 // an iterator for a SubParticleAttrib. This must be defined outside the
64 // class for proper templated function resolution.
65 template <class PA, class T, unsigned Dim>
67  : public PETE_Expr< SubParticleAttribIter<PA,T,Dim> >
68 {
69 public:
70  // useful typedefs
74 
75  // constructor
76  SubParticleAttribIter(PA &a, const_iterator_iv lf, int o, const Index_t &s)
77  : dom(&s), attrib(&a), lfield(lf), attribOffset(o) { }
78 
79  // copy constructor
81  : attrib(const_cast<PA *>(i.attrib)),
83 
84  // default constructor
86 
87  // destructor
89 
91  return (attribOffset != i.attribOffset);
92  }
93 
94  PA &getAttrib() { return *attrib; }
95  const Index_t &getDomain() const { return *dom; }
96 
97  static int getSubsetType() { return SFI::getSubsetType(); }
98  static bool matchType(int t) { return SFI::matchType(t); }
99 
100  void initialize() { }
101 
102  int size() const { return attrib->size(); }
103  int size(int) const { return (*lfield)->size(); }
104  T& offset(int i) { return (*attrib)[attribOffset + i]; }
105  T& unit_offset(int i) { return (*attrib)[attribOffset + i]; }
106 
107  static void makeNDIndex(const Index_t &s, NDIndex<Dim>& i) {
108  i = s.getDomain();
109  }
110 
112  attribOffset += size(0);
113  ++lfield;
114  return lfield;
115  }
116 
118  return lfield;
119  }
120 
121  bool plugBase(const NDIndex<Dim>&) {
122  return true;
123  }
124 
125  //
126  // PETE Interface
127  //
128 
129  enum { IsExpr = 1 };
131  typedef T PETE_Return_t;
132  PETE_Expr_t MakeExpression() const { return *this; }
133 
134 private:
135  // the domain, the attrib, and the iterator to the first vnode to use
136  const Index_t *dom;
137  PA *attrib;
139 
140  // our current starting offset for indexing into the attrib array. This
141  // is changed as we switch among LFields.
143 };
144 
145 
146 // The SubParticleAttrib class declaration.
147 template <class PA, class T, unsigned Dim>
148 class SubParticleAttrib : public PETE_Expr< SubParticleAttrib<PA,T,Dim> > {
149 
150 public:
151  // useful typedefs
152  typedef PA Attrib_t;
153  typedef T T_t;
155  typedef typename iterator::Index_t Index_t;
156 
157  // useful enums
158  enum { Dim_u = Dim };
159 
160  // constructor
161  SubParticleAttrib(PA &a, const Index_t &dom)
162  : A(a), MyDomain(dom) { }
163 
164  // copy constructor
166  : A(const_cast<PA &>(spa.A)), MyDomain(spa.MyDomain) { }
167 
168  // destructor
170 
171  //
172  // accessor functions
173  //
174 
175  // return the 'domain', that is, the information which subsets the field
176  const Index_t &getDomain() const { return MyDomain; }
177 
178  // return a reference to the attribute we are subsetting
179  PA &getAttrib() const { return A; }
180 
181  // Return a typecode for the subset object
182  static int getSubsetType() { return iterator::getSubsetType(); }
183 
184  // Return an NDIndex representing the bounding box of this object
186 
187  // Return the beginning and end iterators for this class.
188  iterator begin() const;
189  iterator end() const;
190 
191  // Make sure the LHS ParticleAttrib has the proper length. It should
192  // have the same length as the number of LOCAL sparse index points.
193  // If it does not, we readjust the length. Return the size of the result.
194  int adjustSize();
195 
196  //
197  // assignment operators
198  //
199 
200  // assignment of another SubParticleAttrib
202 
203  // assignment of a scalar
205 
206  // assignment of an arbitrary expression
207  //mwerks template<class B>
208  //mwerks SubParticleAttrib<PA,T,Dim>& operator=(const PETE_Expr<B> &);
210  // assignment of an arbitrary expression
211  template<class B>
214 
215  // invoke the complex expression assignment, which gathers items from
216  // the expression and puts them in the attribute
217  assign(*this, b);
218  return *this;
219  }
220 
221  //
222  // I/O
223  //
224 
225  void write(std::ostream &) const;
226 
227  //
228  // PETE interface
229  //
230 
231  enum { IsExpr = 1 };
233  PETE_Expr_t MakeExpression() const { return begin(); }
234 
235 private:
236  // the attribute we are subsetting
237  PA &A;
238 
239  // the 'domain', that is, the information which subsets the object
241 };
242 
243 // I/O
244 
245 // write to the given ostream
246 template<class PA, class T, unsigned Dim>
247 inline
248 std::ostream& operator<<(std::ostream &o, const SubParticleAttrib<PA,T,Dim> &n) {
249 
250  n.write(o);
251  return o;
252 }
253 
254 
256 
257 #endif
258 
259 /***************************************************************************
260  * $RCSfile: SubParticleAttrib.h,v $ $Author: adelmann $
261  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
262  * IPPL_VERSION_ID: $Id: SubParticleAttrib.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
263  ***************************************************************************/
Definition: PETE.h:80
Definition: rbendmap.h:8
const_iterator_iv getLFieldIter() const
SubParticleAttrib(PA &a, const Index_t &dom)
PETE_Expr_t MakeExpression() const
Definition: SIndex.h:28
const Index_t & getDomain() const
Index_t::const_iterator_iv const_iterator_iv
PA & getAttrib() const
iterator end() const
SubParticleAttribIter(PA &a, const_iterator_iv lf, int o, const Index_t &s)
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
const Index_t & getDomain() const
container_t::const_iterator const_iterator_iv
Definition: SIndex.h:72
bool plugBase(const NDIndex< Dim > &)
const_iterator_iv lfield
PETE_Expr_t MakeExpression() const
SubFieldIter< T, Dim, Index_t > SFI
SubParticleAttrib(const SubParticleAttrib< PA, T, Dim > &spa)
const Index_t & MyDomain
iterator::Index_t Index_t
const NDIndex< Dim > & getDomain() const
Definition: SIndex.h:154
iterator begin() const
static bool matchType(int t)
SubParticleAttribIter< PA, T, Dim > PETE_Expr_t
static void makeNDIndex(const Index_t &s, NDIndex< Dim > &i)
SubParticleAttribIter(const SubParticleAttribIter< PA, T, Dim > &i)
SubParticleAttribIter< PA, T, Dim > iterator
static int getSubsetType()
void makeNDIndex(NDIndex< Dim > &i)
const unsigned Dim
bool operator!=(const SubParticleAttribIter< PA, T, Dim > &i)
SubParticleAttrib< PA, T, Dim > & operator=(const SubParticleAttrib< PA, T, Dim > &)
SubParticleAttrib< PA, T, Dim > & operator=(const PETE_Expr< B > &b)
const_iterator_iv nextLField()
void write(std::ostream &) const