00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef SUB_FIELD_ITER_H
00012 #define SUB_FIELD_ITER_H
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #include "Index/NDIndex.h"
00096 #include "Index/SIndex.h"
00097 #include "Field/BareField.h"
00098 #include "Field/LField.h"
00099 #include "Utility/PAssert.h"
00100 #include "PETE/IpplExpressions.h"
00101
00102
00104
00105 enum { NoSubsetType, NDIndexSubsetType, SIndexSubsetType, SOffsetSubsetType };
00106
00107
00109
00110
00111
00112
00113 template<class T, unsigned int Dim, class S, unsigned int ExprDim>
00114 class SubFieldIterBase {
00115
00116 public:
00117
00118
00119 enum { ExprDim_u = ExprDim };
00120
00121
00122 SubFieldIterBase(const BareField<T,Dim>& df,
00123 const typename BareField<T,Dim>::iterator_if& ldf,
00124 const S& s,
00125 unsigned int B)
00126 : MyBareField(&(const_cast<BareField<T,Dim> &>(df))),
00127 MyDomain(&(const_cast<S&>(s))),
00128 CurrentLField(ldf),
00129 MyBrackets(B) {
00130 LFPtr = (*CurrentLField).second.get();
00131 }
00132
00133
00134 SubFieldIterBase() { }
00135
00136
00137 ~SubFieldIterBase() { }
00138
00139
00140
00141 BareField<T,Dim> &getBareField() { return *MyBareField; }
00142 const BareField<T,Dim> &getBareField() const { return *MyBareField; }
00143
00144
00145 typename BareField<T,Dim>::iterator_if getLFieldIter() const {
00146 return CurrentLField;
00147 }
00148
00149
00150 S &getDomain() { return *MyDomain; }
00151 const S &getDomain() const { return *MyDomain; }
00152
00153
00154 bool checkBrackets() const { return MyBrackets == Dim; }
00155 unsigned int getBrackets() const { return MyBrackets; }
00156
00157
00158 typename BareField<T,Dim>::iterator_if nextLField() {
00159 ++CurrentLField;
00160 LFPtr = (*CurrentLField).second.get();
00161 return CurrentLField;
00162 }
00163
00164
00165 LField<T,Dim>* getLField() { return LFPtr; }
00166 const LField<T,Dim>* getLField() const { return LFPtr; }
00167
00168
00169 void setLField(LField<T,Dim>* p) { LFPtr = p; }
00170
00171
00172 void setLFieldData(LField<T,Dim>* p, NDIndex<Dim>&) { LFPtr = p; }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 void FillGCIfNecessary() const {
00200 bool isdirty = this->getBareField().isDirty();
00201 if (isdirty)
00202 ( const_cast<BareField<T,Dim> &>(this->getBareField()) ).fillGuardCells();
00203 }
00204
00205
00206 private:
00207
00208 BareField<T,Dim>* MyBareField;
00209
00210
00211 S* MyDomain;
00212
00213
00214
00215
00216 LField<T,Dim>* LFPtr;
00217
00218
00219 typename BareField<T,Dim>::iterator_if CurrentLField;
00220
00221
00222 unsigned int MyBrackets;
00223 };
00224
00225
00227
00228
00229
00230 template<class T, unsigned int Dim, class S>
00231 class SubFieldIter { };
00232
00233
00235
00236
00237
00238
00239 template<class T, unsigned int Dim>
00240 class SubFieldIter<T, Dim, NDIndex<Dim> >
00241 : public SubFieldIterBase<T, Dim, NDIndex<Dim>, Dim>,
00242 public PETE_Expr<SubFieldIter<T, Dim, NDIndex<Dim> > >
00243 {
00244
00245 public:
00246
00247 typedef NDIndex<Dim> Subset_t;
00248 typedef SubFieldIter<T, Dim, Subset_t> SFI;
00249
00250
00251 SubFieldIter(const BareField<T,Dim>& df,
00252 const typename BareField<T,Dim>::iterator_if& ldf,
00253 const NDIndex<Dim>& s, unsigned int B)
00254 : SubFieldIterBase<T,Dim,Subset_t,Dim>(df, ldf, s, B) { }
00255
00256
00257 SubFieldIter() { }
00258
00259
00260 ~SubFieldIter() { }
00261
00262
00263
00264
00265
00266
00267 void setLFieldData(LField<T,Dim>* p, NDIndex<Dim>& n) {
00268 SubFieldIterBase<T,Dim,Subset_t,Dim>::setLFieldData(p, n);
00269 P = this->getLField()->begin(n);
00270 }
00271
00272
00273
00274 static int getSubsetType() { return NDIndexSubsetType; }
00275 static bool matchType(int t) { return (t == NDIndexSubsetType); }
00276
00277
00278
00279
00280 void initialize() { }
00281
00282
00283
00284
00285 bool findIntersection(const NDIndex<Dim>& loc, NDIndex<Dim>& inter) {
00286 inter = this->getDomain().intersect(loc);
00287 return ( ! inter.empty() );
00288 }
00289
00290
00291 static void makeNDIndex(const Subset_t& s, NDIndex<Dim>& i) { i = s; }
00292
00293
00294
00295
00296 bool plugBase(const NDIndex<Dim>& i) {
00297
00298 PInsist(this->checkBrackets(),"Field not fully indexed!!");
00299
00300
00301
00302 NDIndex<Dim> plugged = this->getDomain().plugBase(i);
00303
00304
00305
00306 typename BareField<T,Dim>::iterator_if lf_i = this->getBareField().begin_if();
00307 typename BareField<T,Dim>::iterator_if lf_e = this->getBareField().end_if();
00308 for ( ; lf_i != lf_e; ++lf_i) {
00309
00310 if ((*lf_i).second->getAllocated().contains(plugged)) {
00311
00312 setLFieldData((*lf_i).second.get(), plugged);
00313 return true;
00314 }
00315 }
00316
00317
00318 return false;
00319 }
00320
00321
00322 void rewind(unsigned d) { P.rewind(d); }
00323
00324
00325 void step(unsigned int d) { P.step(d); }
00326 void step(unsigned int d, int n) { P.step(d, n); }
00327
00328
00329 int size(unsigned d) const { return P.size(d); }
00330
00331
00332 T& operator*() { return *P; }
00333 T& offset() { return *P; }
00334 T& offset(int i) { return P.offset(i); }
00335 T& offset(int i, int j) { return P.offset(i, j); }
00336 T& offset(int i, int j, int k) { return P.offset(i, j, k); }
00337 T& unit_offset(int i) { return P.unit_offset(i); }
00338 T& unit_offset(int i, int j) { return P.unit_offset(i, j); }
00339 T& unit_offset(int i, int j, int k) { return P.unit_offset(i, j, k); }
00340 int Stride(int d) const { return P.Stride(d); }
00341
00342
00343 bool CanCompress() const { return this->getLField()->CanCompress(); }
00344 void Compress(T v) { return this->getLField()->Compress(v); }
00345 bool TryCompress() { return this->getLField()->TryCompress(); }
00346 bool TryCompress(T v) { return this->getLField()->TryCompress(v);}
00347 bool IsCompressed() const {
00348 PAssert(this->getLField()->IsCompressed() == P.IsCompressed());
00349 return this->getLField()->IsCompressed();
00350 }
00351 bool DomainCompressed() const { return true; }
00352
00353
00354
00355
00356
00357 enum { IsExpr = 1 };
00358 typedef SFI PETE_Expr_t;
00359 typedef T PETE_Return_t;
00360 PETE_Expr_t MakeExpression() const { return *this; }
00361
00362 private:
00363
00364 typename LField<T,Dim>::iterator P;
00365 };
00366
00367
00369
00370
00371
00372
00373 template<class T, unsigned int Dim>
00374 class SubFieldIter<T, Dim, SIndex<Dim> >
00375 : public SubFieldIterBase<T, Dim, SIndex<Dim>, 1U>,
00376 public PETE_Expr<SubFieldIter<T, Dim, SIndex<Dim> > >
00377 {
00378 public:
00379
00380 typedef SIndex<Dim> Subset_t;
00381 typedef SubFieldIter<T, Dim, Subset_t> SFI;
00382
00383
00384 SubFieldIter(const BareField<T,Dim>& df,
00385 const typename BareField<T,Dim>::iterator_if& ldf,
00386 const SIndex<Dim>& s, unsigned int B)
00387 : SubFieldIterBase<T,Dim,Subset_t,1U>(df, ldf, s, B) {
00388 ComponentLF = this->getDomain().begin_iv();
00389 computeLSOffset();
00390 }
00391
00392
00393 SubFieldIter() { }
00394
00395
00396 ~SubFieldIter() { }
00397
00398
00399
00400
00401
00402
00403 typename BareField<T,Dim>::iterator_if nextLField() {
00404 typename BareField<T,Dim>::iterator_if lfi =
00405 SubFieldIterBase<T,Dim,Subset_t,1U>::nextLField();
00406 ++ComponentLF;
00407 computeLSOffset();
00408 return lfi;
00409 }
00410
00411
00412
00413 static int getSubsetType() { return SIndexSubsetType; }
00414 static bool matchType(int t) { return (t == SIndexSubsetType); }
00415
00416
00417
00418
00419 void initialize() { }
00420
00421
00422
00423
00424 bool findIntersection(const NDIndex<Dim>&, NDIndex<Dim>& inter) {
00425
00426
00427 if ((*ComponentLF)->size() > 0) {
00428 inter = this->getLField()->getOwned();
00429 return true;
00430 }
00431 return false;
00432 }
00433
00434
00435 static void makeNDIndex(const Subset_t& s, NDIndex<Dim>& i) {
00436
00437 i = s.getDomain();
00438 }
00439
00440
00441
00442 bool plugBase(const NDIndex<Dim>&) { return true; }
00443
00444
00445 void rewind(unsigned) { }
00446
00447
00448 void step(unsigned int) { }
00449 void step(unsigned int, int) { }
00450
00451
00452 int size(unsigned d) const { return (d == 0 ? (*ComponentLF)->size() : 0); }
00453
00454
00455
00456
00457 T& operator*() { return offset(0); }
00458 T& offset() { return offset(0); }
00459 T& offset(int i) {
00460 SOffset<Dim> loc = (*ComponentLF)->getIndex(i);
00461 loc -= LFOffset;
00462 return this->getLField()->begin().offset(loc.begin());
00463 }
00464 T& unit_offset(int i) { return offset(i); }
00465 int Stride(int) { return 1; }
00466
00467
00468 bool CanCompress() const { return false; }
00469 void Compress(T) { }
00470 bool TryCompress() { return false; }
00471 bool TryCompress(T) { return false; }
00472 bool IsCompressed() const { return this->getLField()->IsCompressed(); }
00473 bool DomainCompressed() const { return (*ComponentLF)->IsCompressed(); }
00474
00475
00476
00477
00478
00479 enum { IsExpr = 1 };
00480 typedef SFI PETE_Expr_t;
00481 typedef T PETE_Return_t;
00482 PETE_Expr_t MakeExpression() const { return *this; }
00483
00484 private:
00485 typename Subset_t::iterator_iv ComponentLF;
00486 SOffset<Dim> LFOffset;
00487
00488
00489
00490
00491 void computeLSOffset() {
00492 if (this->getLFieldIter() != this->getBareField().end_if()) {
00493 NDIndex<Dim> owned = this->getLField()->getOwned();
00494 for (unsigned int d=0; d < Dim; ++d)
00495 LFOffset[d] = (owned[d].first() - this->getDomain().getOffset()[d]);
00496 }
00497 }
00498 };
00499
00500
00502
00503
00504
00505
00506 template<class T, unsigned int Dim>
00507 class SubFieldIter<T, Dim, SOffset<Dim> >
00508 : public SubFieldIterBase<T, Dim, SOffset<Dim>, 1U>,
00509 public PETE_Expr<SubFieldIter<T, Dim, SOffset<Dim> > >
00510 {
00511
00512 public:
00513
00514 typedef SOffset<Dim> Subset_t;
00515 typedef SubFieldIter<T, Dim, Subset_t> SFI;
00516
00517
00518 SubFieldIter(const BareField<T,Dim>& df,
00519 const typename BareField<T,Dim>::iterator_if& ldf,
00520 const SOffset<Dim>& s, unsigned int B)
00521 : SubFieldIterBase<T,Dim,Subset_t,1U>(df, ldf, s, B), SingleValPtr(0) { }
00522
00523
00524 SubFieldIter() { }
00525
00526
00527 ~SubFieldIter() { }
00528
00529
00530
00531
00532
00533
00534 void setLFieldData(LField<T,Dim>* p, NDIndex<Dim>& n) {
00535 SubFieldIterBase<T,Dim,Subset_t,1U>::setLFieldData(p, n);
00536
00537
00538
00539 if (n.contains(Component)) {
00540 SOffset<Dim> s = this->getDomain();
00541 NDIndex<Dim> owned = p->getOwned();
00542 for (unsigned int d=0; d < Dim; ++d)
00543 s[d] -= owned[d].first();
00544 SingleValPtr = &(p->begin().offset(s.begin()));
00545 }
00546 }
00547
00548
00549
00550 static int getSubsetType() { return SOffsetSubsetType; }
00551 static bool matchType(int) { return true; }
00552
00553
00554 void initialize() {
00555
00556 makeNDIndex(this->getDomain(), Component);
00557
00558
00559 this->getBareField().getsingle(Component, SingleValStore);
00560 }
00561
00562
00563
00564
00565 bool findIntersection(const NDIndex<Dim>& loc, NDIndex<Dim>& inter) {
00566 inter = Component.intersect(loc);
00567 return ( ! inter.empty() );
00568 }
00569
00570
00571 static void makeNDIndex(const Subset_t& s, NDIndex<Dim>& i) {
00572 for (unsigned int d=0; d < Dim; ++d)
00573 i[d] = Index(s[d], s[d]);
00574 }
00575
00576
00577
00578 bool plugBase(const NDIndex<Dim>&) { return true; }
00579
00580
00581 void rewind(unsigned) { }
00582
00583
00584 void step(unsigned int) { }
00585 void step(unsigned int, int) { }
00586
00587
00588 int size(unsigned int d) const { return (d == 0 ? 1 : 0); }
00589
00590
00591
00592
00593 T& operator*() { return offset(0); }
00594 T& offset() { return offset(0); }
00595 T& offset(int) {
00596 return (SingleValPtr == 0 ? SingleValStore : *SingleValPtr);
00597 }
00598 T& unit_offset(int) { return offset(0); }
00599 int Stride(int d) { return 0; }
00600
00601
00602 bool CanCompress() const { return false; }
00603 void Compress(T) { }
00604 bool TryCompress() { return false; }
00605 bool TryCompress(T) { return false; }
00606 bool IsCompressed() const { return false; }
00607 bool DomainCompressed() const { return true; }
00608
00609
00610
00611
00612
00613 enum { IsExpr = 1 };
00614 typedef SFI PETE_Expr_t;
00615 typedef T PETE_Return_t;
00616 PETE_Expr_t MakeExpression() const { return *this; }
00617
00618 private:
00619 T* SingleValPtr;
00620 T SingleValStore;
00621 NDIndex<Dim> Component;
00622 };
00623
00624
00625 #endif // SUB_FIELD_ITER_H
00626
00627
00628
00629
00630
00631