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