OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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
54
55#include <iostream>
56
57// forward declarations
58template <class PA, class T, unsigned Dim> class SubParticleAttrib;
59template <class PA, class T, unsigned Dim>
60std::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.
65template <class PA, class T, unsigned Dim>
67 : public PETE_Expr< SubParticleAttribIter<PA,T,Dim> >
68{
69public:
70 // useful typedefs
74
75 // constructor
77 : dom(&s), attrib(&a), lfield(lf), attribOffset(o) { }
78
79 // copy constructor
81 : dom(i.dom),
82 attrib(const_cast<PA *>(i.attrib)),
83 lfield(i.lfield),
85
86 // default constructor
88
89 // destructor
91
93 return (attribOffset != i.attribOffset);
94 }
95
96 PA &getAttrib() { return *attrib; }
97 const Index_t &getDomain() const { return *dom; }
98
99 static int getSubsetType() { return SFI::getSubsetType(); }
100 static bool matchType(int t) { return SFI::matchType(t); }
101
102 void initialize() { }
103
104 int size() const { return attrib->size(); }
105 int size(int) const { return (*lfield)->size(); }
106 T& offset(int i) { return (*attrib)[attribOffset + i]; }
107 T& unit_offset(int i) { return (*attrib)[attribOffset + i]; }
108
109 static void makeNDIndex(const Index_t &s, NDIndex<Dim>& i) {
110 i = s.getDomain();
111 }
112
114 attribOffset += size(0);
115 ++lfield;
116 return lfield;
117 }
118
120 return lfield;
121 }
122
123 bool plugBase(const NDIndex<Dim>&) {
124 return true;
125 }
126
127 //
128 // PETE Interface
129 //
130
131 enum { IsExpr = 1 };
134 PETE_Expr_t MakeExpression() const { return *this; }
135
136private:
137 // the domain, the attrib, and the iterator to the first vnode to use
138 const Index_t *dom;
141
142 // our current starting offset for indexing into the attrib array. This
143 // is changed as we switch among LFields.
145};
146
147
148// The SubParticleAttrib class declaration.
149template <class PA, class T, unsigned Dim>
150class SubParticleAttrib : public PETE_Expr< SubParticleAttrib<PA,T,Dim> > {
151
152public:
153 // useful typedefs
154 typedef PA Attrib_t;
155 typedef T T_t;
157 typedef typename iterator::Index_t Index_t;
158
159 // useful enums
160 enum { Dim_u = Dim };
161
162 // constructor
163 SubParticleAttrib(PA &a, const Index_t &dom)
164 : A(a), MyDomain(dom) { }
165
166 // copy constructor
168 : A(const_cast<PA &>(spa.A)), MyDomain(spa.MyDomain) { }
169
170 // destructor
172
173 //
174 // accessor functions
175 //
176
177 // return the 'domain', that is, the information which subsets the field
178 const Index_t &getDomain() const { return MyDomain; }
179
180 // return a reference to the attribute we are subsetting
181 PA &getAttrib() const { return A; }
182
183 // Return a typecode for the subset object
184 static int getSubsetType() { return iterator::getSubsetType(); }
185
186 // Return an NDIndex representing the bounding box of this object
188
189 // Return the beginning and end iterators for this class.
190 iterator begin() const;
191 iterator end() const;
192
193 // Make sure the LHS ParticleAttrib has the proper length. It should
194 // have the same length as the number of LOCAL sparse index points.
195 // If it does not, we readjust the length. Return the size of the result.
196 int adjustSize();
197
198 //
199 // assignment operators
200 //
201
202 // assignment of another SubParticleAttrib
204
205 // assignment of a scalar
207
208 // assignment of an arbitrary expression
209 //mwerks template<class B>
210 //mwerks SubParticleAttrib<PA,T,Dim>& operator=(const PETE_Expr<B> &);
212 // assignment of an arbitrary expression
213 template<class B>
216
217 // invoke the complex expression assignment, which gathers items from
218 // the expression and puts them in the attribute
219 assign(*this, b);
220 return *this;
221 }
222
223 //
224 // I/O
225 //
226
227 void write(std::ostream &) const;
228
229 //
230 // PETE interface
231 //
232
233 enum { IsExpr = 1 };
235 PETE_Expr_t MakeExpression() const { return begin(); }
236
237private:
238 // the attribute we are subsetting
239 PA &A;
240
241 // the 'domain', that is, the information which subsets the object
243};
244
245// I/O
246
247// write to the given ostream
248template<class PA, class T, unsigned Dim>
249inline
250std::ostream& operator<<(std::ostream &o, const SubParticleAttrib<PA,T,Dim> &n) {
251
252 n.write(o);
253 return o;
254}
255
256
258
259#endif
260
261/***************************************************************************
262 * $RCSfile: SubParticleAttrib.h,v $ $Author: adelmann $
263 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
264 * IPPL_VERSION_ID: $Id: SubParticleAttrib.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
265 ***************************************************************************/
const unsigned Dim
std::ostream & operator<<(std::ostream &, const SubParticleAttrib< PA, T, Dim > &)
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
std::complex< double > a
Definition: SIndex.h:64
const NDIndex< Dim > & getDomain() const
Definition: SIndex.h:153
container_t::const_iterator const_iterator_iv
Definition: SIndex.h:71
Definition: PETE.h:77
SubParticleAttrib(const SubParticleAttrib< PA, T, Dim > &spa)
SubParticleAttrib< PA, T, Dim > & operator=(const SubParticleAttrib< PA, T, Dim > &)
const Index_t & MyDomain
iterator begin() const
const Index_t & getDomain() const
void write(std::ostream &) const
void makeNDIndex(NDIndex< Dim > &i)
SubParticleAttrib< PA, T, Dim > & operator=(const PETE_Expr< B > &b)
PA & getAttrib() const
iterator end() const
SubParticleAttribIter< PA, T, Dim > iterator
static int getSubsetType()
PETE_Expr_t MakeExpression() const
SubParticleAttrib(PA &a, const Index_t &dom)
iterator::Index_t Index_t
static void makeNDIndex(const Index_t &s, NDIndex< Dim > &i)
SubParticleAttribIter< PA, T, Dim > PETE_Expr_t
Index_t::const_iterator_iv const_iterator_iv
const_iterator_iv lfield
SubParticleAttribIter(PA &a, const_iterator_iv lf, int o, const Index_t &s)
const_iterator_iv nextLField()
bool operator!=(const SubParticleAttribIter< PA, T, Dim > &i)
PETE_Expr_t MakeExpression() const
SubParticleAttribIter(const SubParticleAttribIter< PA, T, Dim > &i)
bool plugBase(const NDIndex< Dim > &)
const Index_t & getDomain() const
static bool matchType(int t)
SubFieldIter< T, Dim, Index_t > SFI
const_iterator_iv getLFieldIter() const