LoAdSG
index.h
1/**********************************************************************************
2* Author: Christoph Pflaum, Riccarda Scherner-Griesshammer
3 * Department Informatik Lehrstuhl 10 - Systemsimulation
4 * Friedrich-Alexander Universität Erlangen-Nürnberg
5 *
6*********************************************/
7#ifndef INDEXSPARSE_H
8#define INDEXSPARSE_H
9
10#include "../myAssert.h"
11#include "../myMath/myMath.h"
12
13#include <iostream>
14#include <vector>
15
16class Depth;
17
18using namespace std;
19
20
21
22enum Direction {
23 Left, Right
24};
25enum Richtung {
26 Mitte, Links, Rechts, LinksLinks, RechtsRechts
27};
28
29
30
31enum elementaryIntervalPoints {
32 startUnitInterval, endUnitInterval, centerUnitInterval
33};
34
85public:
86 inline static double coordinate_test(indexInteger index);
87 inline static double coordinate(indexInteger index);
88
89protected:
90 inline static int depth(indexInteger index);
91
92 inline static indexInteger father(const indexInteger index);
93
94 inline static indexInteger leftSon(const indexInteger index);
95
96 inline static indexInteger rightSon(const indexInteger index);
97
98 inline static indexInteger nextLeft(indexInteger index);
99 inline static indexInteger nextRight(indexInteger index);
100
101 inline static indexInteger nextLeft(indexInteger index, int level);
102 inline static indexInteger nextRight(indexInteger index, int level);
103
104
105
106private:
107 inline static int internDepth(indexInteger index);
108};
109
159public:
160
161
162 explicit inline IndexOneD(elementaryIntervalPoints x);
163
164 inline IndexOneD(indexInteger ind) : index(ind) {};
165
166 inline int depth();
167
168 inline IndexOneD father();
169
170 inline IndexOneD leftSon();
171
172 inline IndexOneD rightSon();
174
180 inline IndexOneD nextLeft();
182
183 inline IndexOneD nextRight();
185
190 inline IndexOneD nextLeft(int level);
191 inline IndexOneD nextRight(int level);
192 bool operator==(const IndexOneD I) const { return index==I.index; }
193 bool operator!=(const IndexOneD I) const { return index!=I.index; }
194
195 inline double coordinate();
196
197 indexInteger getInteger() const { return index; }
198
199
200private:
201 indexInteger index;
202
203};
204
208template<int Di>
209class MaxShift {
210public:
211 enum {
212 value = 3 * MaxShift<Di - 1>::value
213 };
214};
215
216template<>
217class MaxShift<1> {
218public:
219 enum {
220 value = 3
221 };
222};
223
227template<int Di>
228class IntCases {
229public:
230 enum {
231 value = 2 * IntCases<Di - 1>::value
232 };
233};
234
235template<>
236class IntCases<1> {
237public:
238 enum {
239 value = 2
240 };
241};
242
243
262public:
263 MultiDimTwoCompass() { shiftNumber = 0; }
264
265 inline Richtung getRichtung(unsigned int d) const;
266
267 void operator++() { ++shiftNumber; }
268
269 unsigned int getMaxShift() { return maxShift; }
270
271 unsigned int getShiftNumber() { return shiftNumber; };
272
273 bool goon() { return shiftNumber < maxShift; }
274
275
276
277private:
278 unsigned int shiftNumber;
279 static unsigned int maxShift;
280};
281
282
283
/*
301
302class MultiDimCompass {
303public:
304 MultiDimCompass() { shiftNumber = 0; }
305
306 inline Richtung getRichtung(unsigned int d) const;
307
308 void operator++() { ++shiftNumber; }
309
310 unsigned int getMaxShift() { return maxShift; }
311
312 unsigned int getShiftNumber() { return shiftNumber; };
313
314 bool goon() { return shiftNumber < maxShift; }
315
316 bool operator==(MultiDimTwoCompass& mc){
317 for(int d=0; d<DimensionSparseGrid; d++){
318 if(getRichtung(d)==mc.getRichtung(d))
319 return true;
320 }
321 return false;
322
323 }
324
325 void PrintRichtung(int d){
326 if(getRichtung(d)==Mitte)
327 cout << "Mitte ";
328 if(getRichtung(d)==Links)
329 cout << "Links ";
330 if(getRichtung(d)==Rechts)
331 cout << "Rechts ";
332 }
333
334private:
335 unsigned int shiftNumber;
336 static unsigned int maxShift;
337};
338*/
357public:
359 shiftNumber = 0;
360 for (size_t i = 0; i < DimensionSparseGrid; i++)
361 {
362 richtungen[i]=0;
363 }
364 /* Richtungen = new unsigned int [DimensionSparseGrid*maxShift];
365
366 for(int shiftN=0;shiftN<maxShift;shiftN++){
367
368 for(size_t d=0; d<DimensionSparseGrid; d++){
369 Richtungen[shiftN*DimensionSparseGrid+d]=richtungen[d];
370
371 }
372
373
374 for (size_t i = 0; i < DimensionSparseGrid; i++)
375 {
376
377 richtungen[i]=richtungen[i]+1;
378 if(richtungen[i]==3){
379 richtungen[i] = 0;
380
381 goto goon_inner;
382 }
383 goto goon_outer;
384 goon_inner:;
385 }
386
387 goon_outer:;
388 }
389*/
390 }
391
392
393
394 inline Richtung getRichtung (unsigned int d) const;
395
396 void operator++() {
397 ++shiftNumber;
398 for (size_t i = 0; i < DimensionSparseGrid; i++)
399 {
400 richtungen[i]=richtungen[i]+1;
401 if(richtungen[i]==3){
402 richtungen[i] = 0;
403 continue;
404 }
405 break;
406 }
407
408 }
409
410 static unsigned int getMaxShift() { return maxShift; }
411
412 unsigned int getShiftNumber() { return shiftNumber; };
413
414 bool hasNext() { return shiftNumber < maxShift; }
415
416 bool goon() { return shiftNumber < maxShift; }
417
418private:
419 unsigned int richtungen[DimensionSparseGrid];
420 unsigned int shiftNumber;
421 static unsigned int maxShift;
422
423};
424
425
426
427
437public:
438 MultiDimFiveCompass() { shiftNumber = 0;
439 for (size_t i = 0; i < DimensionSparseGrid; i++)
440 {
441 directions[i]=0;
442 }
443 }
444
445 inline Richtung getRichtung(unsigned int d){
446 return (Richtung) directions[d];
447 };
448
449/*
450 inline Richtung getRichtung(unsigned int d){
451 unsigned int num = shiftNumber;
452 for (int s = 0; s < d; ++s) num = num / 5;
453 return (Richtung) (num % 5);
454 };
455*/
456
457 void operator++() { ++shiftNumber;
458
459 for (size_t i = 0; i < DimensionSparseGrid; i++)
460 {
461 directions[i]=directions[i]+1;
462 if(directions[i]==5){
463 directions[i] = 0;
464 continue;
465 }
466 break;
467 }
468 }
469
470 unsigned int getMaxShift() { return maxShift; }
471 bool hasNext() { return shiftNumber < maxShift; }
472
473 bool goon() { return shiftNumber < maxShift; }
474
475 void goToStart(){ shiftNumber = 0;}
476
477 int getShiftNumber(){return shiftNumber;}
478
479private:
480 unsigned int shiftNumber;
481 static unsigned int maxShift;
482 unsigned int directions[DimensionSparseGrid];
483
484
485};
486
487
488
489class IndexDimension : private Static_IndexOneD {
490public:
491 inline IndexDimension();
492 inline indexInteger getIndex(int d) const;
493
494 inline int getDepth(int d) const;
495
496
497 inline double coordinate(int d) const;
498
499 inline IndexDimension nextLeft(int d);
500 inline IndexDimension nextLeft(int d) const;
501
502 inline IndexDimension nextRight(int d) const;
503 inline IndexDimension nextRight(int d);
504
505 inline IndexDimension nextLeft(int d, int level) const;
506 inline IndexDimension nextRight(int d, int level) const;
507 inline IndexDimension father(int d);
508
516 IndexDimension
517 nextTwoStep(MultiDimCompass *mc, Depth T) const;
518
519 IndexDimension
520 nextFive(MultiDimFiveCompass *mc, Depth T) const;
521
522 IndexDimension
523 nextFive(MultiDimFiveCompass *mc, Depth T,
524 double *stencilvalue) const;
525
526 IndexDimension
527 nextFiveP(MultiDimFiveCompass *mc, Depth& T,
528 double *stencilvalue) const;
529
530 IndexDimension
531 nextFive(MultiDimFiveCompass *mc, Depth T,
532 double *stencilvalue,
533 bool *last) const;
534
535 inline IndexDimension
536 nextFive(MultiDimFiveCompass *mc, int *T,
537 double *stencilvalue) const;
538
539
540 IndexDimension
541 nextFive_Neumann(MultiDimFiveCompass *mc, Depth &T, double *stencilvalue) const;
542
543 IndexDimension
544 nextFive_Neumann(MultiDimFiveCompass *mc, Depth &T, double *stencilvalue, bool *last) const;
545
546 inline IndexDimension
547 nextFive_Neumann(MultiDimFiveCompass *mc, int *Tiefen, double *stencilvalue) const;
548
549
550 IndexDimension
551 nextThree_Stencil(MultiDimCompass *mc, Depth T, double *stencilvalue) const;
552
553 inline IndexDimension
554 nextThree(MultiDimCompass *mc, int *Tiefen) const;
555
556 inline IndexDimension
557 nextThree2(MultiDimCompass *mc, int *Tiefen) const;
558
559 IndexDimension
560 nextThree_boundary(MultiDimCompass *mc, Depth &T) const;
561
562 inline IndexDimension
563 nextThree_boundary(MultiDimCompass *mc, int *Tiefen) const;
564
565
566 inline bool wasLeftChild(int d);
567
568 inline bool wasRightChild(int d);
569
570 inline bool isLeftGrandChildOf(IndexDimension Index);
571
572 inline IndexDimension leftSon(int d) const;
573
574 inline IndexDimension rightSon(int d) const;
575
576 inline void replace(int d, indexInteger newIndex);
577 inline void replace(int d, IndexOneD indRep);
578 inline bool operator==(const IndexDimension I) const;
579
580 inline bool operator!=(const IndexDimension I) const;
581
582 inline void operator=(const IndexOneD indRep);
583
584 inline void Print() const;
585
586 inline void PrintCoord() const;
587
588 inline bool isNotAtBoundary() const;
589
590 inline bool isNotAtBoundary(int d) const;
591
592 inline bool isOutOfBoundary(
593 int d) const;
594
595 inline bool isAtRightBoundary(int d) const;
596
597 inline bool isAtLeftBoundary(int d) const;
598
599 inline bool isAtBoundary() const;
600
601 inline bool isLinksRandNah(int d) const;
602
603 inline bool isRechtsRandNah(int d) const;
604
605 static IndexDimension Maximum(IndexDimension &A, IndexDimension &B);
606
607 static IndexDimension Minimum(IndexDimension &A, IndexDimension &B);
608
609 static IndexDimension Maximum(IndexDimension &max, IndexDimension &B, int *changes);
610
611 static IndexDimension Minimum(IndexDimension &min, IndexDimension &B, int *changes);
612
613 inline Richtung isRandnah(int d);
614
615 inline bool isRandnah(Richtung* richtung);
616
617private:
618 inline IndexDimension(const indexInteger index_org[DimensionSparseGrid]);
619
620 indexInteger index[DimensionSparseGrid];
621};
622
623
624
625
627
628inline Richtung MultiDimTwoCompass::getRichtung(unsigned int d) const{
629 unsigned int num = shiftNumber;
630 for (int s = 0; s < d; ++s) num = num / 2;
631 return (Richtung) ((num % 2)+1);
632}
633
634inline Richtung MultiDimCompass::getRichtung(unsigned int d) const{
635 return (Richtung) richtungen[d];
636 //return (Richtung) Richtungen[shiftNumber*DimensionSparseGrid+d];
637/* unsigned int num = shiftNumber;
638 for (int s = 0; s < d; ++s) num = num / 3;
639 return (Richtung) (num % 3)*/;
640}
641
642/*inline Richtung MultiDimFiveCompass::getRichtung(unsigned int d) {
643 unsigned int num = shiftNumber;
644 for (int s = 0; s < d; ++s) num = num / 5;
645 return (Richtung) (num % 5);
646}*/
647
648IndexOneD::IndexOneD(elementaryIntervalPoints x) {
649
650 if (x == startUnitInterval) index = 0;
651 else if (x == endUnitInterval) index = 1;
652 else index = 2;
653}
654
655//---------
656
657indexInteger Static_IndexOneD::father(const indexInteger index) {
658 return index>>1;
659}
660
661IndexOneD IndexOneD::father() {
662 return IndexOneD(Static_IndexOneD::father(index));
663}
664
665//---------
666
667indexInteger Static_IndexOneD::leftSon(const indexInteger index) {
668 return index<<1;
669}
670
671IndexOneD IndexOneD::leftSon() {
672 return IndexOneD(Static_IndexOneD::leftSon(index));
673}
674
675//---------
676
677indexInteger Static_IndexOneD::rightSon(const indexInteger index) {
678 return ((index<<1)+1);
679}
680
681IndexOneD IndexOneD::rightSon() {
682 return IndexOneD(Static_IndexOneD::rightSon(index));
683}
684
685//---------
686
687double Static_IndexOneD::coordinate_test(indexInteger index) {
688 double co = 0.0;
689 indexInteger newindex=index;
690 while(index>0) {
691 co = co * 0.5;
692 if((index&1)==1) co = co + 1.0;
693 else co = co - 1.0;
694 index = index>>1;
695//cout << " co: " << co << endl;
696 }
697/* double newco = coordinate_test(newindex);
698 if(abs(newco-co)>0){
699 cout<< "error new coordinate" << endl;
700 cout << newindex << " " << co << " " << newco << " " << abs(newco-co) << endl;
701 exit(0);
702 }*/
703 return co;
704}
705
706inline int subtractFirstBit(int num) {
707 // Find the position of the most significant bit
708 int msb_pos = 31 - __builtin_clz(num); // Assuming a 32-bit integer, use appropriate value for other sizes
709
710 // Create a mask with all bits set except for the most significant bit
711 int mask = ~(1 << msb_pos);
712
713 // Perform bitwise AND operation to subtract the first bit
714 return num & mask;
715}
716
717
718double Static_IndexOneD::coordinate(indexInteger index) {
719 if(index==0)return 0;
720 int d = depth(index);
721 //cout << d << endl;
722
723 double h = 1.0/double(POW2(d));
724 //cout << h << endl;
725 indexInteger n= subtractFirstBit(index);
726 //cout << n << endl;
727 return double(2*n+1)*h;
728
729
730}
731
732
733double IndexOneD::coordinate() {
734 return Static_IndexOneD::coordinate(index);
735}
736
737//---------
738
739//---------
740
741#if __cplusplus >= 202002L
742indexInteger Static_IndexOneD::nextLeft(indexInteger index) {
743 if(index==(1<<(sizeof(index)*8-1)))
744 return 0;
745 return index >> (std::countr_zero(index)+1);
746}
747#else
748
749indexInteger Static_IndexOneD::nextLeft(indexInteger index) {
750 static_assert(sizeof(indexInteger) == 4,
751 "__builtin_ctz only works for ints or compile with cpp20 support");
752 unsigned firstRight = __builtin_ctz(index);
753 return index >> (firstRight + 1 );
754
755}
756#endif
758 return IndexOneD(Static_IndexOneD::nextLeft(index));
759}
760
761//--------
762
763//--------
764
765
766// static indexInteger nextRight_original(indexInteger index) {
767// if((index&1)==0) return (index>>1);
768// index = index>>1;
769// while((index&1)==1) {
770// index = index >> 1;
771// }
772// return (index>>1);
773// }
774
775#if __cplusplus >= 202002L
776indexInteger Static_IndexOneD::nextRight(indexInteger index) {
777 if(index==~(1<<(sizeof(index)*8-1))) return 0;
778 return index >> (std::countr_one(index)+1);
779}
780#else
781
782indexInteger Static_IndexOneD::nextRight(indexInteger index) {
783
784 static_assert(sizeof(indexInteger) == 4,
785 "__builtin_ctz only works for ints or compile with cpp20 support");
786 unsigned inverted = ~index;
787 unsigned firstRight = __builtin_ctz(inverted);
788 return index >> (firstRight + 1 );
789}
790#endif
791
795
796//---------
797#if __cplusplus >= 202002L
798inline int Static_IndexOneD::depth(indexInteger index) {
799 return std::bit_width(index>>1);
800}
801#else
802
803// static int Static_IndexOneD::depth_orignal(indexInteger index) {
804// int de = 0;
805// while(index!=1) {
806// de = de + 1;
807// index = index >> 1;
808// }
809// return de;
810// }
811
812inline int Static_IndexOneD::depth(indexInteger index) {
813 static_assert(sizeof(indexInteger) == 4,
814 "__builtin_clz only works for ints or compile with cpp20 support");
815 if(index==0) return 0;
816 return __builtin_clz(index) ^ 31;
817}
818#endif
819
820inline int IndexOneD::depth() {
821 return Static_IndexOneD::depth(index);
822}
823//---------
824
825inline int Static_IndexOneD::internDepth(indexInteger index) {
826 if(index==0) return -1;
827 return (sizeof(index)<<3) - __builtin_clz(index) - 1;
828/* int de = 0;
829 while(index!=1) {
830 de = de + 1;
831 index = index >> 1;
832 }
833 return de;*/
834}
835
836
837//------
838
839indexInteger Static_IndexOneD::nextLeft(indexInteger index, int level) {
840 int myDepth = depth(index);
841
842 level = level - myDepth;
843 myAssert(level>=0);
844
845 if(level==0) return nextLeft(index);
846 index = index << 1;
847 for(int i=1;i<level;++i) {
848 index = (index << 1) + 1;
849 }
850 return index;
851}
852
854 return IndexOneD(Static_IndexOneD::nextLeft(index,level));
855}
856
857//------
858
859indexInteger Static_IndexOneD::nextRight(indexInteger index, int level) {
860 int myDepth = internDepth(index);
861
862 level = level - myDepth;
863 myAssert(level>=0);
864
865 if(level==0) return nextRight(index);
866 index = (index << 1) + 1;
867 for(int i=1;i<level;++i) {
868 index = index << 1;
869 }
870 return index;
871}
872
873
875 return IndexOneD(Static_IndexOneD::nextRight(index,level));
876}
877
878//-------------------------------------------------------------------------
879// IndexDimension
880//-------------------------------------------------------------------------
881
882IndexDimension::IndexDimension(const indexInteger index_org[DimensionSparseGrid]) {
883 for (int i = 0; i < DimensionSparseGrid; ++i) {
884 index[i] = index_org[i];
885 }
886};
887
888
889void IndexDimension::Print() const {
890 cout << " Print index for test: " << endl;
891 for(int i=0;i<DimensionSparseGrid;++i) {
892 cout << index[i] << endl;
893 }
894}
895
896void IndexDimension::PrintCoord() const {
897// cout << " Print coordinate: " << endl;
898 cout << "(" << Static_IndexOneD::coordinate(index[0]);
899 for(int i=1;i<DimensionSparseGrid;++i) {
900 cout << ", " << Static_IndexOneD::coordinate(index[i]);
901 }
902 cout << ")";
903}
904
905
906IndexDimension::IndexDimension() {
907 for (int i = 0; i < DimensionSparseGrid; ++i) {
908 index[i] = 2; // center point
909 }
910
911
912};
913
914double IndexDimension::coordinate(int d) const {
915 return Static_IndexOneD::coordinate(index[d]);
916}
917
918IndexDimension IndexDimension::leftSon(int d) const{
919 assertDimension(d);
920
921 IndexDimension back(index);
922 back.replace(d, Static_IndexOneD::leftSon(index[d]));
923
924 return back;
925}
926
927IndexDimension IndexDimension::rightSon(int d) const{
928 assertDimension(d);
929
930 IndexDimension back(index);
931 back.replace(d, Static_IndexOneD::rightSon(index[d]));
932
933 return back;
934}
935
936
937bool IndexDimension::wasLeftChild(int d){
938 if((index[d]&1)==1) return false;
939 return true;
940}
941
942
943bool IndexDimension::wasRightChild(int d){
944 if((index[d]&1)==1) return true;
945 return false;
946}
947
948
949
950
951//---------------------
952
953IndexDimension IndexDimension::nextLeft(int d) const {
954 assertDimension(d);
955
956 IndexDimension back(index);
957 back.replace(d, Static_IndexOneD::nextLeft(index[d]));
958
959 return back;
960}
961
962IndexDimension IndexDimension::nextLeft(int d){
963 assertDimension(d);
964
965 IndexDimension back(index);
966 back.replace(d, Static_IndexOneD::nextLeft(index[d]));
967
968 return back;
969}
970
971
972
973IndexDimension IndexDimension::nextRight(int d) {
974 assertDimension(d);
975
976 IndexDimension back(index);
977 back.replace(d, Static_IndexOneD::nextRight(index[d]));
978
979 return back;
980}
981
982
983IndexDimension IndexDimension::nextRight(int d) const {
984 assertDimension(d);
985
986 IndexDimension back(index);
987 back.replace(d, Static_IndexOneD::nextRight(index[d]));
988
989 return back;
990}
991
992
993
994//---------------------
995
996
997
998IndexDimension IndexDimension::nextLeft(int d, int level) const{
999 assertDimension(d);
1000
1001 IndexDimension back(index);
1002 back.replace(d, Static_IndexOneD::nextLeft(index[d],level));
1003
1004 return back;
1005}
1006
1007
1008
1009IndexDimension IndexDimension::nextRight(int d, int level) const{
1010 assertDimension(d);
1011
1012 IndexDimension back(index);
1013 back.replace(d, Static_IndexOneD::nextRight(index[d],level));
1014
1015 return back;
1016}
1017
1018IndexDimension IndexDimension::father(int d){
1019 assertDimension(d);
1020
1021 IndexDimension back(index);
1022 back.replace(d, Static_IndexOneD::father(index[d]));
1023
1024 return back;
1025}
1026
1027
1028
1029//---------------------
1030
1031
1032
1033
1034
1035inline void IndexDimension::replace(int d, indexInteger newIndex) {
1036 index[d] = newIndex;
1037}
1038
1039
1040void IndexDimension::replace(int d, IndexOneD indRep) {
1041 index[d] = indRep.getInteger();
1042}
1043
1044//------------------
1045
1046bool IndexDimension::isNotAtBoundary() const {
1047 for(int d=0;d<DimensionSparseGrid;++d) {
1048 if(index[d]==0) return false;
1049 if(index[d]==1) return false;
1050 }
1051 return true;
1052}
1053
1054bool IndexDimension::isNotAtBoundary(int d) const {
1055 if(index[d]==0) return false;
1056 if(index[d]==1) return false;
1057 return true;
1058}
1059
1060
1061bool IndexDimension::isOutOfBoundary(int d) const {
1062 int x =index[d];
1063
1064 if (x == 3){return true;}
1065 if (x == 2) {return false;}
1066
1067 int y = x;
1068 int bits;
1069 for (bits = 0; x != 0; ++bits) { x = x >> 1; }
1070 bits = bits - 2;
1071 y = y >> bits;
1072
1073 if (y == 3) { return true; }
1074 if (y == 2) { return false; }
1075
1076 return true;
1077}
1078
1079
1080bool IndexDimension::isAtRightBoundary(int d) const {
1081 if (index[d] == 1) return true;
1082 return false;
1083}
1084
1085bool IndexDimension::isAtLeftBoundary(int d) const {
1086 if (index[d] == 0) return true;
1087 return false;
1088}
1089
1090bool IndexDimension::isAtBoundary() const {
1091 for (int d = 0; d < DimensionSparseGrid; d++)
1092 if (index[d] == 0 || index[d] == 1) return true;
1093 return false;
1094}
1095
1096bool IndexDimension::isLinksRandNah(int d) const {
1097 if (nextLeft(d).isAtLeftBoundary(d)) return true;
1098 return false;
1099}
1100
1101bool IndexDimension::isRechtsRandNah(int d) const {
1102 if (nextRight(d).isAtRightBoundary(d)) return true;
1103 return false;
1104}
1105
1106
1107
1108//-------------------------
1109
1110
1111
1112void IndexDimension::operator=(const IndexOneD indRep) {
1113 indexInteger newIndex = indRep.getInteger();
1114 for (int d = 0; d < DimensionSparseGrid; ++d) {
1115 index[d] = newIndex;
1116 }
1117}
1118
1119indexInteger IndexDimension::getIndex(int d) const {
1120 assertDimension(d);
1121 return index[d];
1122}
1123
1124int IndexDimension::getDepth(int d) const {
1125 assertDimension(d);
1126 return Static_IndexOneD::depth(index[d]);
1127}
1128
1129
1130inline bool IndexDimension::operator==(const IndexDimension I) const {
1131 for(int d=0;d<DimensionSparseGrid;++d) {
1132 if(index[d] != I.index[d]) return false;
1133 }
1134 return true;
1135}
1136
1137inline bool IndexDimension::operator!=(const IndexDimension I) const {
1138 for (int d = 0; d < DimensionSparseGrid; ++d) {
1139 if (index[d] != I.index[d]) return true;
1140 }
1141 return false;
1142}
1143
1144Richtung IndexDimension::isRandnah(int d) {
1145 if (nextLeft(d).isAtLeftBoundary(d))
1146 return Links;
1147 if (nextRight(d).isAtRightBoundary(d)) return Rechts;
1148 return Mitte;
1149}
1150
1151bool IndexDimension::isRandnah(Richtung* richtung) {
1152 bool returnbool = false;
1153 for(int d=0; d<DimensionSparseGrid; d++) {
1154 if (nextLeft(d).isAtLeftBoundary(d)){
1155 richtung[d]=Links;
1156 returnbool=true;
1157 continue;
1158 }
1159
1160 if (nextRight(d).isAtRightBoundary(d)){
1161 richtung[d]=Rechts;
1162 returnbool=true;
1163 continue;
1164 }
1165
1166 richtung[d]=Mitte;
1167
1168 }
1169 return returnbool;
1170}
1171
1172//IndexDimension::IndexDimension(int d, indexInteger newIndex);
1173IndexDimension IndexDimension::nextThree_boundary(MultiDimCompass *mc, int *Tiefen) const {
1174
1175 IndexDimension J = (*this);
1176
1177 while (mc->goon()) {
1178
1179 for (int d = 0; d < DimensionSparseGrid; ++d) {
1180
1181 int t = Tiefen[d];
1182 Richtung r = mc->getRichtung(d);
1183
1184
1185 if (r == Links) {
1186 if (J.isAtLeftBoundary(d)) goto startagain;
1187 J = J.nextLeft(d, t);
1188 }
1189
1190
1191 if (r == Rechts) {
1192 if (J.isAtRightBoundary(d)) goto startagain;
1193 J = J.nextRight(d, t);
1194 }
1195
1196
1197 }
1198
1199 // forloop wurde für alle Dimensionen Erfolgreich ausgeführt -> gehe zu stop und return neuen Index
1200 goto stop;
1201
1202 startagain:
1203 J = (*this);
1204 mc->operator++();
1205 }
1206
1207 stop:
1208 //Teste J darf nur == this sein, falls es über Mitte Mitte Mitte ... "generiert" wurde.
1209 return J;
1210}
1211
1212
1213IndexDimension IndexDimension::nextFive_Neumann(MultiDimFiveCompass *mc, int *Tiefen, double *stencilvalue) const {
1214 double val = 1.0;
1215 IndexDimension J = (*this);
1216
1217 while (mc->goon()) {
1218 for (int d = 0; d < DimensionSparseGrid; ++d) {
1219 int t = Tiefen[d];
1220 Richtung r = mc->getRichtung(d);
1221
1222
1223 if (r == Links) {
1224 if (J.getDepth(d) < 1) goto startagain;
1225
1226 if (J.isAtLeftBoundary(d)) goto startagain;
1227 J = J.nextLeft(d, t);
1228 if (J.isAtLeftBoundary(d) && t > 1) val = -1.2 * val;
1229 else if (J.isAtLeftBoundary(d) && t == 1) val = -1.0 * val;
1230 else val = -0.6 * val;
1231
1232 }
1233
1234 if (r == LinksLinks) {
1235 if (J.getDepth(d) < 2) goto startagain;
1236 if (J.isAtLeftBoundary(d) || J.nextLeft(d, t).isAtLeftBoundary(d)) goto startagain;
1237 J = J.nextLeft(d, t).nextLeft(d, t);
1238 val = 0.1 * val;
1239
1240 }
1241
1242 if (r == Rechts) {
1243 if (J.getDepth(d) < 1) goto startagain;
1244
1245 if (J.isAtRightBoundary(d)) goto startagain;
1246 J = J.nextRight(d, t);
1247 if (J.isAtRightBoundary(d) && t > 1) val = -1.2 * val;
1248 else if (J.isAtRightBoundary(d) && t == 1) val = -1.0 * val;
1249 else val = -0.6 * val;
1250 }
1251 if (r == RechtsRechts) {
1252 if (J.getDepth(d) < 2) goto startagain;
1253
1254 if (J.isAtRightBoundary(d) || J.nextRight(d, t).isAtRightBoundary(d)) goto startagain;
1255 J = J.nextRight(d, t).nextRight(d, t);
1256 val = 0.1 * val;
1257
1258
1259 }
1260
1261 if (r == Mitte) {
1262
1263
1264 if (J.getDepth(d) < 2) val = 1.0 * val;
1265 else {
1266 if (J.nextLeft(d, t).isAtLeftBoundary(d) && !J.nextRight(d, t).isAtRightBoundary(d))
1267 val = 1.1 * val;
1268 if (J.nextRight(d, t).isAtRightBoundary(d) && !J.nextLeft(d, t).isAtLeftBoundary(d))
1269 val = 1.1 * val;
1270 }
1271 }
1272
1273
1274 }
1275
1276 // forloop wurde für alle Dimensionen Erfolgreich ausgeführt -> gehe zu stop und return neuen Index
1277 goto stop;
1278
1279 startagain:
1280 val = 1.0;
1281 J = (*this);
1282 mc->operator++();
1283
1284
1285 }
1286
1287 stop:
1288 //Teste J darf nur == this sein, falls es über Mitte Mitte Mitte ... "generiert" wurde.
1289
1290 if (mc->goon() == false && J == *this) val = 0.0;
1291
1292 *stencilvalue = val;
1293
1294 return J;
1295}
1296
1297inline IndexDimension IndexDimension::nextThree(MultiDimCompass *mc, int *Tiefen) const {
1298
1299 IndexDimension J = (*this);
1300
1301 while (mc->goon()) {
1302
1303 for (size_t d = 0; d < DimensionSparseGrid; ++d) {
1304
1305 int t = Tiefen[d];
1306 Richtung r = mc->getRichtung(d);
1307 //if(J.getDepth(d)==1) r = Mitte;
1308
1309
1310
1311 if (r == Links) {
1312 if (J.getDepth(d) < 1) goto startagain;
1313
1314 //if (J.isAtLeftBoundary(d)) goto startagain;
1315 J = J.nextLeft(d, t);
1316
1317
1318 }
1319
1320
1321 if (r == Rechts) {
1322 if (J.getDepth(d) < 1) goto startagain;
1323
1324 //if (J.isAtRightBoundary(d)) goto startagain;
1325 J = J.nextRight(d, t);
1326
1327 }
1328
1329
1330 }
1331
1332 // forloop wurde für alle Dimensionen Erfolgreich ausgeführt -> gehe zu stop und return neuen Index
1333 goto stop;
1334
1335 startagain:
1336
1337 J = (*this);
1338 mc->operator++();
1339
1340
1341 }
1342
1343 stop:
1344 //Teste J darf nur == this sein, falls es über Mitte Mitte Mitte ... "generiert" wurde.
1345
1346 return J;
1347}
1348
1349
1350inline IndexDimension IndexDimension::nextThree2(MultiDimCompass *mc, int *Tiefen) const {
1351
1352 IndexDimension J = (*this);
1353 for (size_t d = 0; d < DimensionSparseGrid && mc->goon(); ++d) {
1354
1355 int t = Tiefen[d];
1356 Richtung r = mc->getRichtung(d);
1357
1358
1359 if (J.getDepth(d) < 1 && r !=Mitte){
1360 mc->operator++();
1361 d--;
1362 continue;
1363 }
1364
1365
1366 if (r == Links)
1367 J = J.nextLeft(d, t);
1368
1369
1370
1371 if (r == Rechts)
1372 J = J.nextRight(d, t);
1373
1374
1375
1376
1377 }
1378
1379 return J;
1380}
1381
1382inline IndexDimension IndexDimension::nextFive(MultiDimFiveCompass *mc, int *T, double *stencilvalue) const {
1383 double val = 1.0;
1384 IndexDimension J = (*this);
1385
1386 while (mc->goon()) {
1387 for (int d = 0; d < DimensionSparseGrid; ++d) {
1388
1389 int t = T[d];
1390 Richtung r = mc->getRichtung(d);
1391
1392 if (r == Links) {
1393 if (J.nextLeft(d, t).isNotAtBoundary(d)) {
1394 val = -0.6 * val;
1395 J = J.nextLeft(d, t);
1396 } else // break outer for loop
1397 goto startagain;
1398
1399 }
1400
1401 if (r == LinksLinks) {
1402 if (J.nextLeft(d, t).isNotAtBoundary(d)) {
1403 J = J.nextLeft(d, t).nextLeft(d, t);
1404 val = 0.1 * val;
1405 } else goto startagain;
1406 }
1407 if (r == Rechts) {
1408 if (J.nextRight(d, t).isNotAtBoundary(d)) {
1409 val = -0.6 * val;
1410 J = J.nextRight(d, t);
1411 } else goto startagain;
1412 }
1413 if (r == RechtsRechts) {
1414 if (J.nextRight(d, t).isNotAtBoundary(d)) {
1415 J = J.nextRight(d, t).nextRight(d, t);
1416 val = 0.1 * val;
1417 } else goto startagain;
1418 }
1419
1420 if (r == Mitte) {
1421 if (J.getDepth(d) > 1)
1422 if (J.nextRight(d, t).isAtRightBoundary(d) || J.nextLeft(d, t).isAtLeftBoundary(d))
1423 val = 0.9 * val;
1424 }
1425
1426
1427 }
1428
1429 // forloop wurde für alle Dimensionen Erfolgreich ausgeführt -> gehe zu stop und return neuen Index
1430 goto stop;
1431
1432 startagain:
1433 val = 1.0;
1434 J = (*this);
1435 mc->operator++();
1436
1437
1438 }
1439
1440 stop:
1441 //Teste J darf nur == this sein, falls es über Mitte Mitte Mitte ... "generiert" wurde.
1442 if (mc->goon() == false && J == *this) val = 0.0;
1443 *stencilvalue = val;
1444
1445 return J;
1446}
1447
1448
1449#endif // INDEXSPARSE_H
1450
Definition index.h:158
bool operator==(const IndexOneD I) const
‍next right index on level >= depth
Definition index.h:192
IndexOneD nextRight()
next right index on same level
Definition index.h:792
IndexOneD nextLeft()
next left index on same level
Definition index.h:757
Definition index.h:228
Definition index.h:209
Definition index.h:356
Definition index.h:436
Definition index.h:261
Definition index.h:84
static int nextLeft(int index, int level)
‍next right index on same level
Definition index.h:839
static int internDepth(int index)
‍next right index on level >= depth
Definition index.h:825
static int nextRight(int index, int level)
‍next left index on level >= depth
Definition index.h:859
static int nextRight(int index)
‍next left index on same level
Definition index.h:782