OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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"
14
15#include <iostream>
17
18// forward declarations
19class Index;
20template<unsigned Dim> class NDIndex;
21template<class T, unsigned Dim> class LField;
22template<class T, unsigned Dim> class BareField;
23template<class T, unsigned Dim, unsigned Brackets> class IndexedBareField;
24template<class T, unsigned Dim, unsigned Brackets>
25std::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//
33template<unsigned D> class DimTag {};
34
35//----------------------------------------------------------------------
36
37template<class T, unsigned Dim>
39{
40public:
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); }
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.
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
179protected:
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
193template < class T, unsigned Dim, unsigned Brackets >
194class 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
200public:
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
301protected:
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
323template < class T, unsigned Dim, unsigned Brackets >
324inline
325std::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:45
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
Layout_t & getLayout() const
Definition: BareField.h:131
virtual void fillGuardCells(bool reallyFill=true) const
Definition: BareField.hpp:297
Definition: LField.h:58
IndexedBareField< T, Dim, Brackets > & operator=(const IndexedBareField< T, Dim, Brackets > &x)
IndexedBareField< T, Dim, Brackets > & operator=(const IndexedBareField< X, Dim1, Brackets1 > &x)
IndexedBareField(BareField< T, Dim > &a, const NDIndex< Brackets-1 > &idx, const Index &i)
constexpr IndexedBareField(const IndexedBareField< T, Dim, Brackets > &)=default
IndexedBareField< T, Dim, Brackets+1 > operator[](const Index &idx)
iterator begin() const
IndexedBareField< T, Dim, Brackets+1 > operator[](const NDIndex< Dim > &ndidx)
PETE_TUTree< OpParens< int >, iterator > operator()(int arg)
IndexedBareField< T, Dim, Brackets > & operator=(const PETE_Expr< B > &x)
IndexedBareField< T, Dim, Brackets > & operator=(const Index &x)
BareField< T, Dim > & A
IndexedBareField(BareField< T, Dim > &a, int i)
const NDIndex< Dim > & getDomain() const
iterator end() const
iterator MakeExpression() const
IndexedBareFieldIterator< T, Dim > iterator
PETE_TUTree< OpParens< std::pair< int, int > >, iterator > operator()(int a1, int a2)
IndexedBareField< T, Dim, Brackets+1 > operator[](int i)
void write(std::ostream &)
const BareField< T, Dim > & getBareField() const
IndexedBareField(BareField< T, Dim > &a, const NDIndex< Dim > &ndidx)
BareField< T, Dim > & getBareField()
IndexedBareField(BareField< T, Dim > &a, const Index &idx)
NDIndex< Brackets > Indexes
void GetCurrentLocation(FieldLoc< Dim > &loc) const
BareField< T, Dim > * MyBareField
BareField< T, Dim > & GetBareField()
IndexedBareFieldIterator< T, Dim > & operator++()
const NDIndex< Dim > & getDomain() const
void FillGCIfNecessary(const BareField< T1, D1 > &lhs) const
bool plugBase(const NDIndex< D2 > &i)
BareField< T, Dim > & getBareField()
void SetCurrentLocation(const FieldLoc< Dim > &loc)
const BareField< T, Dim > & getBareField() const
IndexedBareFieldIterator(BareField< T, Dim > &df, const NDIndex< Dim > &idx)
BrickIterator & operator++()
Definition: BrickIterator.h:73
NDIndex< Dim > getDomain() const
Definition: FieldLoc.h:67
Definition: Index.h:237
Definition: PETE.h:77