OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
IndexedBareField.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 INDEXED_BARE_FIELD_H
12 #define INDEXED_BARE_FIELD_H
13 
14 // Include files
15 #include "Field/FieldLoc.h"
16 #include "Utility/PAssert.h"
17 #include "PETE/IpplExpressions.h"
18 
19 #include <iostream>
21 
22 // forward declarations
23 class Index;
24 template<unsigned Dim> class NDIndex;
25 template<class T, unsigned Dim> class LField;
26 template<class T, unsigned Dim> class BareField;
27 template<class T, unsigned Dim, unsigned Brackets> class IndexedBareField;
28 template<class T, unsigned Dim, unsigned Brackets>
29 std::ostream& operator<<(std::ostream&, const IndexedBareField<T,Dim,Brackets>&);
30 
31 
32 //
33 // Because of a limitation in the template mechanism on SGI
34 // we need a tag class to get it to match the Dim parameter
35 // in the IndexedBareField.
36 //
37 template<unsigned D> class DimTag {};
38 
39 //----------------------------------------------------------------------
40 
41 template<class T, unsigned Dim>
43 {
44 public:
45  enum { Dim_u = Dim };
46  typedef T return_type;
47 
48  // Null ctor for arrays of these things.
50  {
51  }
52 
53  // Construct with a BareField and an NDIndex.
54  // Point to the beginning of the BareField & record the index.
56  : BareField<T,Dim>::iterator(df), I(idx)
57  {
58  // make sure we're at the start of the PROPER LField (not necessarily
59  // the first)
60  beginLField();
61  }
62 
63  // Destructor
65  {
66  }
67 
68  // Return the subdomain we are indexing into here
69  const NDIndex<Dim>& getDomain() const
70  {
71  return I;
72  }
73 
74  // Some other accsssor functions:
75  const BareField<T,Dim>& getBareField() const { return *(this->MyBareField); }
76  BareField<T,Dim>& getBareField() { return *(this->MyBareField); }
77 
78  // Fills the guard cells if necessary.
79  template<unsigned D1, class T1>
80  void FillGCIfNecessary(const BareField<T1,D1> &lhs) const
81  {
82  // If the dirty flag is set, we need to decide whether we need
83  // to fill the guard cells. A safe way to do this is to pass
84  // the domain of the lhs and our domain to 'isStencil', which
85  // will check to see if the domains are offset, indicating a
86  // stencil. This doesn't necessarily mean that we *must* fill
87  // (as in the case where the stencil is fully contained in an
88  // LField), but filling is the safe thing to do short of a more
89  // detailed analysis.
90 
91  if (this->GetBareField().isDirty())
92  {
93  if ( isStencil(lhs.getDomain(), getDomain()) ||
94  !(lhs.getLayout() == getBareField().getLayout()) )
95  {
96  BareField<T,Dim> &bf =
97  const_cast<BareField<T,Dim>&>(this->GetBareField());
98  bf.fillGuardCells();
99  }
100  }
101  }
102 
103 
104  // The LHS tells this guy about a given local domain.
105  //MWERKS: Moved this member template function definition into here.
106  //MWERKS template<unsigned int D1>
107  //MWERKS bool plugBase(const NDIndex<D1>& i);
108  template<unsigned int D2>
109  bool
111  {
112 
113 
114 
115  // Inform msg("plugBase", INFORM_ALL_NODES);
116 
117  // Substitute the index expression from the lhs into this one.
118  NDIndex<Dim> plugged ( I.plugBase(i) );
119 
120  // Try to find a single local array that has all of the rhs.
121  // Loop over all the local arrays.
122  typedef typename BareField<T,Dim>::iterator_if BFI;
124  for (BFI lf_i = BareFieldIterator<T,Dim>::MyBareField->begin_if(); lf_i != e ; ++lf_i) {
125  if ( (*lf_i).second->getAllocated().contains( plugged ) ) {
126  // Found it. Make this one current and go.
128  (CompressedBrickIterator<T,Dim>&)(*this) = (*lf_i).second->begin(plugged);
129  return true;
130  }
131  }
132  // Didn't find it.
133  return false;
134  }
135 
136  // From a given FieldLoc, set where we're pointing. Since an
137  // IndexedBareField iterates over only a subset, we must make sure the
138  // requested point is within the subset domain.
140  {
142  if (!this->done()) {
143  FieldLoc<Dim> checkloc;
144  GetCurrentLocation(checkloc);
145  PAssert(I.contains(checkloc.getDomain()));
146  }
147  }
148 
149  // Increment this iterator.
151  {
153  if (*this == (*BareFieldIterator<T,Dim>::CurrentLField).second->end())
155  return *this;
156  }
157 
158  // Set ourselves up to point to the first item in the current LField
159  // that we'll be accessing. Since we're iterating over a subset of
160  // the domain, we might need to skip over some LFields first.
161  void beginLField()
162  {
163  // get a pointer to the current LField, and ourselves cast as a
164  // compressed brick iterator.
166 
167  // advance to the first LField that intersects our subdomain
168  while (!this->done() && ! I.touches((*BareFieldIterator<T,Dim>::CurrentLField).second->getOwned()))
169  this->nextLField();
170 
171  // now that we're at a new LField with some points, set the pointer
172  // to the first item we'll need. Set ourselves equal to a
173  // compressed brick iterator that iterates over the subdomain formed
174  // from the intersection of the total indexed subdomain and the
175  // current LField's owned domain.
176  if (!this->done())
177  *c = (*BareFieldIterator<T,Dim>::CurrentLField).second->begin(
178  I.intersect((*BareFieldIterator<T,Dim>::CurrentLField).second->getOwned()));
179  else
181  }
182 
183 protected:
184  // User supplied offsets.
186 
187  // Increment and go on to the next LField if necessary.
189  {
190  this->nextLField();
191  beginLField();
192  }
193 };
194 
195 //----------------------------------------------------------------------
196 
197 template < class T, unsigned Dim, unsigned Brackets >
198 class IndexedBareField : public PETE_Expr< IndexedBareField<T,Dim,Brackets> >
199 {
200 
201  friend class IndexedBareField<T,Dim,Brackets-1>;
202  friend class BareField<T,Dim>;
203 
204 public:
205 
206  typedef T T_t;
207  enum { Dim_u = Dim };
209 
211  {
212  CTAssert(Brackets<Dim);
214  }
215 
217  {
218  CTAssert(Brackets<Dim);
220  }
221  // Also allow using a single NDIndex instead of N Index objects:
223  {
224  CTAssert(Brackets<Dim);
226  }
227 
228  void operator=(T x)
229  {
230  assign(*this,x);
231  }
232 
235  {
236  CTAssert(Dim==Brackets);
237  assign(*this,x);
238  return *this;
239  }
240 
241  template<class X, unsigned Dim1, unsigned Brackets1>
244  {
245  CTAssert(Dim1==Brackets1);
246  assign(*this,x);
247  return *this;
248  }
249 
251  operator=(const Index& x)
252  {
253  assign(*this,x);
254  return *this;
255  }
256 
257  template<class B>
260  {
261  assign(*this,x);
262  return *this;
263  }
264 
265  const NDIndex<Dim>& getDomain() const { return Indexes; }
267  const BareField<T,Dim>& getBareField() const { return A; }
268 
269  // Pass operator() down to each element of type T.
270  // Could also build versions with 2 or more arguments...
271  // Without member templates we are restricted to passing an integer down.
274  {
275  CTAssert(Dim==Brackets);
276  typedef PETE_TUTree< OpParens<int> , iterator > Elem_t;
277  return Elem_t(arg,begin());
278  }
280  operator()(int a1, int a2)
281  {
282  CTAssert(Dim==Brackets);
284  return Elem_t(std::pair<int,int>(a1,a2),begin());
285  }
286 
287  // Return a single value.
288  // operator T() { T r; getsingle(r); return r; }
289  //T get() { T r ; getsingle(r); return r; }
290  T get();
291 
292  // Return the beginning and end iterators for this class.
293  iterator begin() const { return iterator( A, Indexes ); }
294  iterator end() const { return iterator(); }
295 
296  // Print out the values for this object to the given output stream.
297  void write(std::ostream&);
298 
299  // PETE interface
300  enum { IsExpr = 0 };
302  iterator MakeExpression() const { return begin(); }
303 
304 protected:
307 
308  // Make the constructors private so that only BareField and IndexedBareField
309  // can construct them.
311  : A(a), Indexes(idx) {}
313  : A(a), Indexes(Index(i,i)) {}
315  : A(a), Indexes(idx,i) {}
316 
317  // Also allow using a single NDIndex instead of N Index objects:
319  : A(a), Indexes(ndidx) {}
320 
321  // read a single value from the array.
322  void getsingle(T&);
323 };
324 
325 
326 template < class T, unsigned Dim, unsigned Brackets >
327 inline
328 std::ostream& operator<<(std::ostream& out, const IndexedBareField<T,Dim,Brackets>& i) {
329 
330 
332  const_cast<IndexedBareField<T,Dim,Brackets>&>(i);
333  nci.write(out);
334  return out;
335 }
336 
338 
340 
341 #endif // INDEXED_BARE_FIELD_H
342 
343 /***************************************************************************
344  * $RCSfile: IndexedBareField.h,v $ $Author: adelmann $
345  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:26 $
346  * IPPL_VERSION_ID: $Id: IndexedBareField.h,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $
347  ***************************************************************************/
iterator MakeExpression() const
Definition: PETE.h:80
Layout_t & getLayout() const
Definition: BareField.h:130
ac_id_larray::iterator iterator_if
Definition: BareField.h:91
void GetCurrentLocation(FieldLoc< Dim > &loc) const
constexpr double e
The value of .
Definition: Physics.h:40
BareField< T, Dim > & getBareField()
const NDIndex< Dim > & getDomain() const
Definition: BareField.h:151
IndexedBareFieldIterator< T, Dim > iterator
Definition: rbendmap.h:8
const NDIndex< Dim > & getDomain() const
BareField< T, Dim > * MyBareField
void FillGCIfNecessary(const BareField< T1, D1 > &lhs) const
iterator end() const
Definition: FFT.h:31
#define CTAssert(c)
Definition: PAssert.h:40
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
virtual void fillGuardCells(bool reallyFill=true) const
Definition: BareField.hpp:298
IndexedBareField< T, Dim, Brackets+1 > operator[](const Index &idx)
IndexedBareField(BareField< T, Dim > &a, const Index &idx)
IndexedBareField< T, Dim, Brackets+1 > operator[](int i)
BareField< T, Dim > & getBareField()
BareField< T, Dim > & A
Definition: Index.h:236
IndexedBareField< T, Dim, Brackets > & operator=(const Index &x)
void write(std::ostream &)
const BareField< T, Dim > & getBareField() const
IndexedBareField< T, Dim, Brackets > & operator=(const IndexedBareField< X, Dim1, Brackets1 > &x)
PETE_TUTree< OpParens< int >, iterator > operator()(int arg)
IndexedBareFieldIterator(BareField< T, Dim > &df, const NDIndex< Dim > &idx)
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
IndexedBareFieldIterator< T, Dim > & operator++()
IndexedBareField(BareField< T, Dim > &a, const NDIndex< Brackets-1 > &idx, const Index &i)
const BareField< T, Dim > & getBareField() const
NDIndex< Brackets > Indexes
IndexedBareField< T, Dim, Brackets+1 > operator[](const NDIndex< Dim > &ndidx)
bool isStencil(const NDIndex< D1 > &i1, const NDIndex< D2 > &i2)
IndexedBareField< T, Dim, Brackets > & operator=(const PETE_Expr< B > &x)
Definition: FFT.h:30
arg(a))
IndexedBareField< T, Dim, Brackets > & operator=(const IndexedBareField< T, Dim, Brackets > &x)
NDIndex< Dim > getDomain() const
Definition: FieldLoc.h:67
bool plugBase(const NDIndex< D2 > &i)
const NDIndex< Dim > & getDomain() const
void SetCurrentLocation(const FieldLoc< Dim > &loc)
#define PAssert(c)
Definition: PAssert.h:117
std::string::iterator iterator
Definition: MSLang.h:16
const unsigned Dim
IndexedBareField(BareField< T, Dim > &a, const NDIndex< Dim > &ndidx)
IndexedBareField(BareField< T, Dim > &a, int i)
iterator begin() const
BrickIterator & operator++()
Definition: BrickIterator.h:78
PETE_TUTree< OpParens< std::pair< int, int > >, iterator > operator()(int a1, int a2)
BareField< T, Dim > & GetBareField()