OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
SubFieldIter.h
Go to the documentation of this file.
1//
2// Class SubFieldIter
3// Iterator for a subset of a BareField
4//
5// Copyright (c) 2003 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
6// All rights reserved
7//
8// This file is part of OPAL.
9//
10// OPAL is free software: you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// You should have received a copy of the GNU General Public License
16// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17//
18#ifndef SUB_FIELD_ITER_H
19#define SUB_FIELD_ITER_H
20
21/***************************************************************************
22 SubFieldIter is a class is required for each type of object which is used to
23 store a subset for a BareField. For example, NDIndex specifies a rect-
24 angular block, SIndex specifies a (sparse) list of individual elements,
25 and SOffset specifies a single point (which is assumed to be the same
26 on all nodes). SubFieldIter acts as the iterator for the SubBareField
27 class which uses that particular type of subset object to select a view of
28 the field.
29
30 To add a new subset object and define a new SubFieldIter class:
31 * Add a new item to the enumeration at the top of this file.
32 * Define a new SubFieldIter class, templated on the type of object (e.g.,
33 NDIndex<Dim>), following the pattern for the examples below. The
34 required elements in SubFieldIter are
35 (which can be set up by copying an existing class and modifying it):
36
37 - derive from SubFieldIterBase
38
39 - two construction options, one with needed iterator args, the other
40 a default constructor (this is needed by PETE). You can also
41 define a copy constructor, or else make sure that element-wise
42 copying will suffice for your iterator class.
43
44 - override the versions of all the functions in the base class which
45 need to be overridden, to supply the special functionality for that
46 subset. For example, some classes need special initialization when
47 they are used in an expression - if so, make a specific version of
48 'initialize' in your subset specialization class.
49
50 - add specialization in SubFieldTraits to indicate how this subset
51 object can be constructed from other subset objects, and what kind
52 of combinations of subset objects will work.
53
54 - static bool matchType(int t) { return (t == Type_u); } ... return
55 whether the type of subset object matches the given type. Some
56 objects, like SOffset, match all subset types (since SOffset used
57 as a subset object appears to the rest of the expression like a
58 single value, e.g., as a scalar.
59
60 - static void makeNDIndex(Subset_t& s, NDIndex<Dim>& i) ... convert
61 the given subset object data to an NDIndex
62
63 - bool findIntersection() { } ... find the intersection between a
64 the current component and a given NDIndex, and return the intersection
65 as an NDIndex. Also return a boolean flag indicating if this
66 intersection did indeed contain some points (true). This is then used
67 in a BrickExpression to take data from the RHS and store it into the
68 LHS. findIntersection is only called for an iterator which occurs
69 on the LHS; if something is on the RHS, then plugBase will be called
70 instead, with an argument of the domain as calculated by
71 findIntersection.
72
73 - void nextLField() { } ... for subsets which must keep track of their
74 current vnode (e.g., SIndex), this increments a vnode iterator.
75
76 - NDIndex<Dim> plugBase(const NDIndex<Dim>& i) const ... this is the
77 function which takes the NDIndex component on the LHS, and plugs it
78 in to the RHS. This results in each SubBareField on the RHS setting
79 internal iterators to point to the proper section of data
80 based on any offsets it may have and on the subset from the LHS.
81 For some subset objects, this will not depend on the given subdomain.
82
83 - setLFieldData(LField<T,Dim>*, NDIndex<Dim>&) ... for iterators
84 which occur on the LHS of an expression, the LField referred to by
85 its internal LField iterator may need to be changed to a new one
86 which is a copy of the existing LField (to handle the case where a
87 Field occurs on the LHS and the RHS). This function, which has a
88 default definition, changes the iterator to use a different LField
89 and to iterate over the region specified in the second argument.
90 It is only called for iterators on the LHS.
91
92 - bool CanTryCompress() ... Some subset objects cannot easily be
93 used on the LHS with compressed LFields. If the new one can not
94 (for example, if it is not possible to determine if all the points
95 referred to by the subset have the same value), this should return
96 false, and all the other compression routines can just be no-ops.
97
98 ***************************************************************************/
99
100
101// include files
102#include "Index/NDIndex.h"
103#include "Index/SIndex.h"
104#include "Field/BareField.h"
105#include "Field/LField.h"
107#include "Utility/PAssert.h"
108#include "PETE/IpplExpressions.h"
109
110
112// type codes for different subset objects
114
115
117// A base class for all specialized versions of the SubFieldIter class.
118// This provides common functionality and storage, and default versions of
119// functions which may be overridden in the specialized classes.
120
121template<class T, unsigned int Dim, class S, unsigned int ExprDim>
123
124public:
125 // How many indices we must loop over when doing an expression involving
126 // this object
127 enum { ExprDim_u = ExprDim };
128
129 // Construct with a SubField and the domain to use
131 const typename BareField<T,Dim>::iterator_if& ldf,
132 const S& s,
133 unsigned int B)
134 : MyBareField(&(const_cast<BareField<T,Dim> &>(df))),
135 MyDomain(&(const_cast<S&>(s))),
136 CurrentLField(ldf),
137 MyBrackets(B) {
138 if (CurrentLField != getBareField().end_if()) {
139 LFPtr = (*CurrentLField).second.get();
140 } else {
141 LFPtr = nullptr;
142 }
143 }
144
145 // Default constructor
147
148 // destructor: nothing to do
150
151 // Return the BareField, for which this iterator represents a particular
152 // subset or view of
154 const BareField<T,Dim> &getBareField() const { return *MyBareField; }
155
156 // Return a copy of the current iterator pointing to the active LField
158 return CurrentLField;
159 }
160
161 // Return the subset object
162 S &getDomain() { return *MyDomain; }
163 const S &getDomain() const { return *MyDomain; }
164
165 // Check if our brackets are properly balanced
166 bool checkBrackets() const { return MyBrackets == Dim; }
167 unsigned int getBrackets() const { return MyBrackets; }
168
169 // Go to the next LField.
171 if (CurrentLField != getBareField().end_if()) {
173 } else {
174 throw IpplException("SubFieldIterBase::nextLField()", "Reached the container end, no next LField!");
175 }
176 if (CurrentLField != getBareField().end_if()) {
177 LFPtr = (*CurrentLField).second.get();
178 } else {
179 LFPtr = nullptr;
180 }
181 return CurrentLField;
182 }
183
184 // Return the LField pointed to by LFPtr
186 const LField<T,Dim>* getLField() const { return LFPtr; }
187
188 // Use a new LField
189 void setLField(LField<T,Dim>* p) { LFPtr = p; }
190
191 // Use a new LField, where we use data on the given NDIndex region
193
194 /* tjw 3/3/99: try to mimic changes made in
195 IndexedBareFieldIterator::FillGCIfNecessary:
196
197 // Fill the guard cells for our field, if necessary. We punt on
198 // trying to check for a stencil op, just fill GC's if the Field has
199 // it's dirty flag set.
200 // If we were trying to check for a stencil op, the arguments are
201 // the domain we are doing the expression on, and the NDIndex domain
202 // which is the bounding box for this subset object.
203 void FillGCIfNecessary(const NDIndex<Dim> &, const NDIndex<Dim> &) {
204 bool isdirty = getBareField().isDirty();
205 // bool isstencil = isStencil(i, j);
206 // if (isdirty && isstencil) {
207 if (isdirty)
208 getBareField().fillGuardCells();
209 }
210 tjw 3/3/99 */
211
212 //tjw 3/3/99:
213 // Fill the guard cells for our field, if necessary. We punt on
214 // trying to check for a stencil op, just fill GC's if the Field has
215 // it's dirty flag set.
216 // If we were trying to check for a stencil op, the arguments are
217 // the domain we are doing the expression on, and the NDIndex domain
218 // which is the bounding box for this subset object.
219 void FillGCIfNecessary() const {
220 bool isdirty = this->getBareField().isDirty();
221 if (isdirty)
222 ( const_cast<BareField<T,Dim> &>(this->getBareField()) ).fillGuardCells();
223 }
224 //tjw 3/3/99.
225
226private:
227 // ptr to the subfield we are iterating over
229
230 // pointer to the subset object
232
233 // a pointer to the LField we're working with, which generally starts out
234 // as the LField pointed to by CurrentLField, but can change if, say, we're
235 // using a copy of the LField on the LHS of an expression
237
238 // iterator pointing to the current LField we're looping over
240
241 // how many brackets have been applied so far
242 unsigned int MyBrackets;
243};
244
245
247// The general subset-object-templated class definition for the SubField
248// iterator.
249
250template<class T, unsigned int Dim, class S>
251class SubFieldIter { };
252
253
255// A specialized versions of the SubFieldIter class for an NDIndex
256// subset object. This overrides certain functions from the base class,
257// and provides definitions of needed functions not available in the base.
258
259template<class T, unsigned int Dim>
261 : public SubFieldIterBase<T, Dim, NDIndex<Dim>, Dim>,
262 public PETE_Expr<SubFieldIter<T, Dim, NDIndex<Dim> > >
263{
264
265public:
266 // public typedefs
269
270 // Construct with a SubField and the domain to use
272 const typename BareField<T,Dim>::iterator_if& ldf,
273 const NDIndex<Dim>& s, unsigned int B)
274 : SubFieldIterBase<T,Dim,Subset_t,Dim>(df, ldf, s, B) { }
275
276 // Default constructor
278
279 // destructor: nothing to do
281
282 //
283 // Methods overriding base class behavior
284 //
285
286 // Use a new LField, where we use data on the given NDIndex region
289 P = this->getLField()->begin(n);
290 }
291
292 // Return a special code indicating what the subset type is, and match the
293 // types together.
294 static int getSubsetType() { return NDIndexSubsetType; }
295 static bool matchType(int t) { return (t == NDIndexSubsetType); }
296
297 // If necessary, this routine will distribute any data it needs to
298 // among the processors. For example, single-value subset objects must
299 // broadcast the single value to all the nodes.
300 void initialize() { }
301
302 // Calculate the intersection with the current component and the given
303 // subdomain. Return true if an intersection exists, and the intersection
304 // domain in the second argument.
305 bool findIntersection(const NDIndex<Dim>& loc, NDIndex<Dim>& inter) {
306 inter = this->getDomain().intersect(loc);
307 return ( ! inter.empty() );
308 }
309
310 // convert this subset object into an NDIndex object
311 static void makeNDIndex(const Subset_t& s, NDIndex<Dim>& i) { i = s; }
312
313 // The LHS tells this guy about a given local domain. Not all
314 // subsetting operations will care about this. The LField iterator P
315 // will be set in this call to iterate through the values it needs to.
316 bool plugBase(const NDIndex<Dim>& i) {
317 // make sure we have a fully indexed object
318 PInsist(this->checkBrackets(),"Field not fully indexed!!");
319
320 // Find the modified domain after we plug in the information from what
321 // domain is being iterated over on the LHS
322 NDIndex<Dim> plugged = this->getDomain().plugBase(i);
323
324 // Try to find a single local array that has all of the rhs.
325 // Loop over all the local arrays.
326 typename BareField<T,Dim>::iterator_if lf_i = this->getBareField().begin_if();
327 typename BareField<T,Dim>::iterator_if lf_e = this->getBareField().end_if();
328 for ( ; lf_i != lf_e; ++lf_i) {
329 // is the search domain completely within the LField we're examining?
330 if ((*lf_i).second->getAllocated().contains(plugged)) {
331 // Found it. Make this one current and go.
332 setLFieldData((*lf_i).second.get(), plugged);
333 return true;
334 }
335 }
336
337 // Didn't find it.
338 return false;
339 }
340
341 // Finished this dimension, rewind.
342 void rewind(unsigned d) { P.rewind(d); }
343
344 // Step one or n in a given dimension.
345 void step(unsigned int d) { P.step(d); }
346 void step(unsigned int d, int n) { P.step(d, n); }
347
348 // How big in this dimension.
349 int size(unsigned d) const { return P.size(d); }
350
351 // return the value currently pointed at, or offset in 1,2, or 3 dims
352 T& operator*() { return *P; }
353 T& offset() { return *P; }
354 T& offset(int i) { return P.offset(i); }
355 T& offset(int i, int j) { return P.offset(i, j); }
356 T& offset(int i, int j, int k) { return P.offset(i, j, k); }
357 T& unit_offset(int i) { return P.unit_offset(i); }
358 T& unit_offset(int i, int j) { return P.unit_offset(i, j); }
359 T& unit_offset(int i, int j, int k) { return P.unit_offset(i, j, k); }
360 int Stride(int d) const { return P.Stride(d); }
361
362 // Compression interface
363 bool CanCompress() const { return this->getLField()->CanCompress(); }
364 void Compress(T v) { return this->getLField()->Compress(v); }
365 bool TryCompress() { return this->getLField()->TryCompress(); }
366 bool TryCompress(T v) { return this->getLField()->TryCompress(v);}
367 bool IsCompressed() const {
368 PAssert_EQ(this->getLField()->IsCompressed(), P.IsCompressed());
369 return this->getLField()->IsCompressed();
370 }
371 bool DomainCompressed() const { return true; }
372
373 //
374 // PETE Interface
375 //
376
377 enum { IsExpr = 1 };
380 PETE_Expr_t MakeExpression() const { return *this; }
381
382private:
383 // where in this LField are we
385};
386
387
389// A specialized versions of the SubFieldIter class for an SIndex
390// subset object. This overrides certain functions from the base class,
391// and provides definitions of needed functions not available in the base.
392
393template<class T, unsigned int Dim>
395 : public SubFieldIterBase<T, Dim, SIndex<Dim>, 1U>,
396 public PETE_Expr<SubFieldIter<T, Dim, SIndex<Dim> > >
397{
398public:
399 // public typedefs
402
403 // Construct with a SubField and the domain to use
405 const typename BareField<T,Dim>::iterator_if& ldf,
406 const SIndex<Dim>& s, unsigned int B)
407 : SubFieldIterBase<T,Dim,Subset_t,1U>(df, ldf, s, B) {
408 ComponentLF = this->getDomain().begin_iv();
409 computeLSOffset();
410 }
411
412 // Default constructor
414
415 // destructor: nothing to do
417
418 //
419 // Methods overriding base class behavior
420 //
421
422 // Go to the next LField.
424 typename BareField<T,Dim>::iterator_if lfi =
426 ++ComponentLF;
427 computeLSOffset();
428 return lfi;
429 }
430
431 // Return a special code indicating what the subset type is, and match the
432 // types together.
433 static int getSubsetType() { return SIndexSubsetType; }
434 static bool matchType(int t) { return (t == SIndexSubsetType); }
435
436 // If necessary, this routine will distribute any data it needs to
437 // among the processors. For example, single-value subset objects must
438 // broadcast the single value to all the nodes.
439 void initialize() { }
440
441 // Calculate the intersection with the current LField domain and the
442 // given subdomain. Return true if an intersection exists, and the
443 // intersection domain in the second argument.
445 // If there are any points in the LField, we return the owned domain
446 // for the LField.
447 if ((*ComponentLF)->size() > 0) {
448 inter = this->getLField()->getOwned();
449 return true;
450 }
451 return false;
452 }
453
454 // convert this subset object into an NDIndex object
455 static void makeNDIndex(const Subset_t& s, NDIndex<Dim>& i) {
456 //i = s.getFieldLayout().getDomain();
457 i = s.getDomain();
458 }
459
460 // The LHS tells this guy about a given local domain. Not all
461 // subsetting operations will care about this.
462 bool plugBase(const NDIndex<Dim>&) { return true; }
463
464 // Finished this dimension, rewind.
465 void rewind(unsigned) { }
466
467 // Step one or n in a given dimension.
468 void step(unsigned int) { }
469 void step(unsigned int, int) { }
470
471 // How big in this dimension
472 int size(unsigned d) const { return (d == 0 ? (*ComponentLF)->size() : 0); }
473
474 // return the value currently pointed at, or the Nth value. We only provide
475 // options for 1D, since SIndex looks like a 1D array of values to the
476 // BrickExpression object.
477 T& operator*() { return offset(0); }
478 T& offset() { return offset(0); }
479 T& offset(int i) {
480 SOffset<Dim> loc = (*ComponentLF)->getIndex(i);
481 loc -= LFOffset;
482 return this->getLField()->begin().offset(loc.begin());
483 }
484 T& unit_offset(int i) { return offset(i); }
485 int Stride(int) { return 1; }
486
487 // Compression interface
488 bool CanCompress() const { return false; }
489 void Compress(T) { }
490 bool TryCompress() { return false; }
491 bool TryCompress(T) { return false; }
492 bool IsCompressed() const { return this->getLField()->IsCompressed(); }
493 bool DomainCompressed() const { return (*ComponentLF)->IsCompressed(); }
494
495 //
496 // PETE Interface
497 //
498
499 enum { IsExpr = 1 };
502 PETE_Expr_t MakeExpression() const { return *this; }
503
504private:
507
508 // calculate the offset for the current LField. This is the position of
509 // the lower-left corner of owned domain, minus the offset we are adding to
510 // our sparse indices.
512 if (this->getLFieldIter() != this->getBareField().end_if()) {
513 NDIndex<Dim> owned = this->getLField()->getOwned();
514 for (unsigned int d=0; d < Dim; ++d)
515 LFOffset[d] = (owned[d].first() - this->getDomain().getOffset()[d]);
516 }
517 }
518};
519
520
522// A specialized versions of the SubFieldIter class for an SOffset, which
523// is used to act as a single-value
524// subset object. This overrides certain functions from the base class,
525// and provides definitions of needed functions not available in the base.
526template<class T, unsigned int Dim>
528 : public SubFieldIterBase<T, Dim, SOffset<Dim>, 1U>,
529 public PETE_Expr<SubFieldIter<T, Dim, SOffset<Dim> > >
530{
531
532public:
533 // public typedefs
536
537 // Construct with a SubField and the domain to use
539 const typename BareField<T,Dim>::iterator_if& ldf,
540 const SOffset<Dim>& s, unsigned int B)
541 : SubFieldIterBase<T,Dim,Subset_t,1U>(df, ldf, s, B), SingleValPtr(0) { }
542
543 // Default constructor
545
546 // destructor: nothing to do
548
549 //
550 // Methods overriding base class behavior
551 //
552
553 // Use a new LField, where we use data on the given NDIndex region
556 // the following if test COULD be removed if we assume this function is
557 // called after 'findIntersection' is called and while we're still working
558 // on the same LField.
559 if (n.contains(Component)) {
560 SOffset<Dim> s = this->getDomain();
561 NDIndex<Dim> owned = p->getOwned();
562 for (unsigned int d=0; d < Dim; ++d)
563 s[d] -= owned[d].first();
564 SingleValPtr = &(p->begin().offset(s.begin()));
565 }
566 }
567
568 // Return a special code indicating what the subset type is, and match the
569 // types together.
570 static int getSubsetType() { return SOffsetSubsetType; }
571 static bool matchType(int) { return true; }
572
573 // initialization routines
574 void initialize() {
575 // make an NDIndex with the point in it
576 makeNDIndex(this->getDomain(), Component);
577
578 // distribute the value to all the nodes
579 this->getBareField().getsingle(Component, SingleValStore);
580 }
581
582 // Calculate the intersection with the current component and the given
583 // subdomain. Return true if an intersection exists, and the intersection
584 // domain in the second argument.
585 bool findIntersection(const NDIndex<Dim>& loc, NDIndex<Dim>& inter) {
586 inter = Component.intersect(loc);
587 return ( ! inter.empty() );
588 }
589
590 // convert this subset object into an NDIndex object
591 static void makeNDIndex(const Subset_t& s, NDIndex<Dim>& i) {
592 for (unsigned int d=0; d < Dim; ++d)
593 i[d] = Index(s[d], s[d]);
594 }
595
596 // The LHS tells this guy about a given local domain. Not all
597 // subsetting operations will care about this.
598 bool plugBase(const NDIndex<Dim>&) { return true; }
599
600 // Finished this dimension, rewind.
601 void rewind(unsigned) { }
602
603 // Step one or n in a given dimension.
604 void step(unsigned int) { }
605 void step(unsigned int, int) { }
606
607 // How big in this dimension.
608 int size(unsigned int d) const { return (d == 0 ? 1 : 0); }
609
610 // return the value currently pointed at, or the Nth value. We only provide
611 // options for 1D, since SOffset looks like a 1D array of values to the
612 // BrickExpression object.
613 T& operator*() { return offset(0); }
614 T& offset() { return offset(0); }
615 T& offset(int) {
616 return (SingleValPtr == 0 ? SingleValStore : *SingleValPtr);
617 }
618 T& unit_offset(int) { return offset(0); }
619 int Stride(int /*d*/) { return 0; }
620 // Compression interface
621 bool CanCompress() const { return false; }
622 void Compress(T) { }
623 bool TryCompress() { return false; }
624 bool TryCompress(T) { return false; }
625 bool IsCompressed() const { return false; }
626 bool DomainCompressed() const { return true; }
627
628 //
629 // PETE Interface
630 //
631
632 enum { IsExpr = 1 };
635 PETE_Expr_t MakeExpression() const { return *this; }
636
637private:
641};
642
643#endif // SUB_FIELD_ITER_H
const unsigned Dim
@ SIndexSubsetType
Definition: SubFieldIter.h:113
@ NoSubsetType
Definition: SubFieldIter.h:113
@ SOffsetSubsetType
Definition: SubFieldIter.h:113
@ NDIndexSubsetType
Definition: SubFieldIter.h:113
#define PInsist(c, m)
Definition: PAssert.h:120
#define PAssert_EQ(a, b)
Definition: PAssert.h:104
Interface for a single beam element.
Definition: Component.h:50
NDIndex< Dim > plugBase(const NDIndex< D > &i) const
Definition: NDIndex.h:114
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
bool empty() const
ac_id_larray::iterator iterator_if
Definition: BareField.h:92
Definition: LField.h:58
const NDIndex< Dim > & getOwned() const
Definition: LField.h:99
const iterator & begin() const
Definition: LField.h:110
T & offset(int i) const
Definition: Index.h:237
Definition: SIndex.h:64
container_t::iterator iterator_iv
Definition: SIndex.h:70
const NDIndex< Dim > & getDomain() const
Definition: SIndex.h:153
iterator_iv begin_iv()
Definition: SIndex.h:245
iterator begin()
Definition: SOffset.h:132
Definition: PETE.h:77
unsigned int getBrackets() const
Definition: SubFieldIter.h:167
BareField< T, Dim > & getBareField()
Definition: SubFieldIter.h:153
BareField< T, Dim >::iterator_if nextLField()
Definition: SubFieldIter.h:170
const LField< T, Dim > * getLField() const
Definition: SubFieldIter.h:186
void setLFieldData(LField< T, Dim > *p, NDIndex< Dim > &)
Definition: SubFieldIter.h:192
BareField< T, Dim > * MyBareField
Definition: SubFieldIter.h:228
BareField< T, Dim >::iterator_if CurrentLField
Definition: SubFieldIter.h:239
LField< T, Dim > * LFPtr
Definition: SubFieldIter.h:236
BareField< T, Dim >::iterator_if getLFieldIter() const
Definition: SubFieldIter.h:157
void FillGCIfNecessary() const
Definition: SubFieldIter.h:219
LField< T, Dim > * getLField()
Definition: SubFieldIter.h:185
const S & getDomain() const
Definition: SubFieldIter.h:163
unsigned int MyBrackets
Definition: SubFieldIter.h:242
SubFieldIterBase(const BareField< T, Dim > &df, const typename BareField< T, Dim >::iterator_if &ldf, const S &s, unsigned int B)
Definition: SubFieldIter.h:130
void setLField(LField< T, Dim > *p)
Definition: SubFieldIter.h:189
const BareField< T, Dim > & getBareField() const
Definition: SubFieldIter.h:154
bool checkBrackets() const
Definition: SubFieldIter.h:166
bool findIntersection(const NDIndex< Dim > &loc, NDIndex< Dim > &inter)
Definition: SubFieldIter.h:305
T & unit_offset(int i, int j, int k)
Definition: SubFieldIter.h:359
static void makeNDIndex(const Subset_t &s, NDIndex< Dim > &i)
Definition: SubFieldIter.h:311
bool plugBase(const NDIndex< Dim > &i)
Definition: SubFieldIter.h:316
void step(unsigned int d, int n)
Definition: SubFieldIter.h:346
void setLFieldData(LField< T, Dim > *p, NDIndex< Dim > &n)
Definition: SubFieldIter.h:287
SubFieldIter< T, Dim, Subset_t > SFI
Definition: SubFieldIter.h:268
T & offset(int i, int j, int k)
Definition: SubFieldIter.h:356
SubFieldIter(const BareField< T, Dim > &df, const typename BareField< T, Dim >::iterator_if &ldf, const NDIndex< Dim > &s, unsigned int B)
Definition: SubFieldIter.h:271
LField< T, Dim >::iterator P
Definition: SubFieldIter.h:384
SubFieldIter(const BareField< T, Dim > &df, const typename BareField< T, Dim >::iterator_if &ldf, const SIndex< Dim > &s, unsigned int B)
Definition: SubFieldIter.h:404
BareField< T, Dim >::iterator_if nextLField()
Definition: SubFieldIter.h:423
bool plugBase(const NDIndex< Dim > &)
Definition: SubFieldIter.h:462
bool findIntersection(const NDIndex< Dim > &, NDIndex< Dim > &inter)
Definition: SubFieldIter.h:444
SubFieldIter< T, Dim, Subset_t > SFI
Definition: SubFieldIter.h:401
static void makeNDIndex(const Subset_t &s, NDIndex< Dim > &i)
Definition: SubFieldIter.h:455
static void makeNDIndex(const Subset_t &s, NDIndex< Dim > &i)
Definition: SubFieldIter.h:591
void setLFieldData(LField< T, Dim > *p, NDIndex< Dim > &n)
Definition: SubFieldIter.h:554
bool plugBase(const NDIndex< Dim > &)
Definition: SubFieldIter.h:598
SubFieldIter(const BareField< T, Dim > &df, const typename BareField< T, Dim >::iterator_if &ldf, const SOffset< Dim > &s, unsigned int B)
Definition: SubFieldIter.h:538
bool findIntersection(const NDIndex< Dim > &loc, NDIndex< Dim > &inter)
Definition: SubFieldIter.h:585
int size(unsigned int d) const
Definition: SubFieldIter.h:608
SubFieldIter< T, Dim, Subset_t > SFI
Definition: SubFieldIter.h:535