Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

src/expde/basic/basic.h

Go to the documentation of this file.
00001 //    expde: expression templates for partial differential equations.
00002 //    Copyright (C) 2001  Christoph Pflaum
00003 //    This program is free software; you can redistribute it and/or modify
00004 //    it under the terms of the GNU General Public License as published by
00005 //    the Free Software Foundation; either version 2 of the License, or
00006 //    (at your option) any later version.
00007 //
00008 //    This program is distributed in the hope that it will be useful,
00009 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //    GNU General Public License for more details.
00012 //
00013 //                 SEE  Notice1.doc made by 
00014 //                 LAWRENCE LIVERMORE NATIONAL LABORATORY
00015 //
00016 
00017 // ------------------------------------------------------------
00018 //
00019 // basic.h
00020 //
00021 // ------------------------------------------------------------
00022 
00023 
00024 #ifndef BASIC_H_
00025 #define BASIC_H_
00026              
00027 class Index3D;
00028 class Grid_base;
00029 class Grid;
00030 class IndexEdge;
00031 class IndexSurface;
00032 class Parallel_Info;
00033 
00034 
00035 // 1D index
00036 class Index1D {
00037  friend class Index3D;
00038  friend class Grid_base;
00039  friend class Parallel_Info;
00040  private:
00041   long_int index;
00042  public:
00043   Index1D(long_int ind) {
00044     /*
00045     if(developer_version) {
00046       if(ind==0) {
00047         cout << " error in Index1D::Index1D(long_int ind) " << endl;
00048       }
00049     }
00050     */
00051     index = ind; 
00052   };
00053 
00054 #ifdef PERIODIC
00055   Index1D()                   { index = 1; };
00056 #else
00057   Index1D()                   { index = 0; };
00058 #endif
00059   inline long_int get() const { return index; };
00060 
00061   inline double coordinate() const;
00062   inline int    Tiefe() const;
00063   inline double h_loc() const;
00064   inline Index1D son(dir1D d) const;
00065   inline Index1D father();
00066   inline Index1D neighbour(dir1D d) const;
00067   inline Index1D neighbour_non_periodic(dir1D d) const;
00068   inline bool    Is_non_periodic() const;
00069 
00070   inline Index1D next(dir1D d, int l) const;
00071 
00072   inline long_int cart_index(int l) const;       // cartesian index of level l
00073                                             // is 0,1,...,2^l
00074 
00075   inline void Print() const { cout << index; }
00076 
00077   inline Index1D next(Ort1D ort, int l) const;
00078 
00079   inline int  operator!=(Index1D I) const;
00080   inline int  operator==(Index1D I) const;
00081   inline bool operator<=(Index1D I) const;  // point finer or equal as this
00082   inline bool operator< (Index1D I) const;  // I_this subset [I-h,I+h[
00083   inline bool operator<<(Index1D I) const;  // I_this subset [I-h,I+h]
00084 
00085   inline Index1D cut_level(int l) const;
00086 };
00087 
00088 // 3D index
00089 class Index3D {
00090  friend class Grid_base;
00091  friend class Grid;
00092  friend class Parallel_Info;
00093  private:
00094   Index1D ind_x;
00095   Index1D ind_y;
00096   Index1D ind_z;
00097  public:
00098   Index3D()  { ind_x = Index1D(); ind_y = Index1D(); ind_z = Index1D(); };
00099   // Index3D(2,2,2) : middle  point: (0.5,0.5,0.5)
00100   // Index3D(3,3,3) : outside point: (1.5,1.5,1.5)
00101   Index3D(long_int intx, long_int inty, long_int intz);
00102   Index3D(Index1D indx,Index1D indy,Index1D indz);
00103   int     Tiefe() const;
00104   Index3D son(dir_sons) const;
00105   Index3D father();
00106   Index3D son_EW(dir1D);
00107   Index3D son_NS(dir1D);
00108   Index3D son_TD(dir1D);
00109   Index3D next(Ort1D ortx, Ort1D orty, Ort1D ortz, int l) const;
00110   Index3D next_NS(dir1D d, int l) const;
00111   Index3D next_EW(dir1D d, int l) const;
00112   Index3D next_TD(dir1D d, int l) const;
00113 
00114   Index3D next(dir_sons d, int l) const;
00115   Index3D next(dir_3D d, int l) const;
00116   Index3D next(Edges_cell ed, int l) const;
00117 
00118   Index3D next_N(int l) const;
00119   Index3D next_S(int l) const;
00120   Index3D next_W(int l) const;
00121   Index3D next_E(int l) const;
00122   Index3D next_T(int l) const;
00123   Index3D next_D(int l) const;
00124 
00125   Index3D next_EN(int l) const;
00126   Index3D next_WN(int l) const;
00127   Index3D next_ES(int l) const;
00128   Index3D next_WS(int l) const;
00129 
00130   Index3D next_ET(int l) const;
00131   Index3D next_WT(int l) const;
00132   Index3D next_ED(int l) const;
00133   Index3D next_WD(int l) const;
00134 
00135   Index3D next_NT(int l) const;
00136   Index3D next_ST(int l) const;
00137   Index3D next_ND(int l) const;
00138   Index3D next_SD(int l) const;
00139 
00140   Index3D next_ENT(int l) const;
00141   Index3D next_WNT(int l) const;
00142   Index3D next_EST(int l) const;
00143   Index3D next_WST(int l) const;
00144   Index3D next_END(int l) const;
00145   Index3D next_WND(int l) const;
00146   Index3D next_ESD(int l) const;
00147   Index3D next_WSD(int l) const;
00148 
00149   void Print() const;
00150 
00151   Index3D corner_of_edge_index(dir1D d);
00152 
00153   Index3D neighbour(dir_sons) const;
00154   Index3D neighbour_non_periodic(dir_sons) const;
00155   bool    Is_non_periodic() const;
00156 
00157   inline Index3D neighbour_EW(dir1D);
00158   inline Index3D neighbour_NS(dir1D);
00159   inline Index3D neighbour_TD(dir1D);
00160   D3vector coordinate() const;
00161   double coordinate_x() const;
00162   double coordinate_y() const;
00163   double coordinate_z() const;
00164 
00165   bool Cell_index();  // is index a  cell index?
00166   bool Edge_index();  // is index an edge index?
00167 
00168   dir_3D direction(Index3D I);
00169 
00170   inline Index1D I_x() const { return ind_x; }
00171   inline Index1D I_y() const { return ind_y; }
00172   inline Index1D I_z() const { return ind_z; }
00173 
00174   inline Index1D I_q(main_dir_3D i) const { 
00175     if(i==WE_dir) return ind_x.index;
00176     if(i==SN_dir) return ind_y.index;
00177     return ind_z.index;
00178   }
00179 
00180   // functions which give back the edge or face of a cell
00181   // with center point of type Index3D
00182   IndexEdge edge(Edges_cell ec);
00183   Index3D I_edge(Edges_cell ec);
00184   IndexSurface surface(dir_3D d);
00185 
00186   dir_sons color(int level);
00187 
00188   bool Index_for_cell();
00189   int  operator!=(Index3D I) const;
00190   int  operator==(Index3D I) const;
00191   bool operator<=(Index3D I) const;  // point finer or equal as this
00192   bool operator< (Index3D I) const;  // I_this subset [I-h,I+h[ x ...
00193   bool operator<<(Index3D I) const;  // I_this subset [I-h,I+h] x ...
00194 };
00195 
00196 class IndexBo {
00197  public:
00198   IndexBo(Index3D Ind, dir_3D dir) : I(Ind), d(dir) {};
00199   IndexBo() : d(Wdir) {};
00200   Index3D I;
00201   dir_3D d;
00202 };
00203 
00204 class IndexEdge {
00205  friend class Index3D;
00206  public:
00207   IndexEdge();
00208   inline IndexEdge(Index3D in, dir_3D di);
00209 
00210   Index3D corner(dir1D di);
00211   dir_3D  opposite_direction(dir1D di);
00212   dir_3D           direction(dir1D di);
00213   Index3D I() { return ind; };
00214   bool operator>>(Index3D I) const;        // I subset Edge
00215   bool operator<=(Index3D I) const;  // point finer or equal edge
00216                                      // middle point
00217  private:
00218   Index3D ind;
00219   dir_3D d;
00220 };
00221 
00222 class IndexSurface {
00223  public:
00224   IndexSurface(Index3D I, dir_3D d) : ind(I), dir(d) {};
00225   IndexSurface() : dir(Wdir) {};
00226   Index3D corner(dir2D_sons cor);    // corner of face
00227   Index3D edge(dir_2D edg);          // edges of face
00228   dir_3D  direction(dir_2D d);       // 3D direction of 2D-face-direction
00229   Index3D I();                       // index of center point
00230   bool operator>>(Index3D I) const;  // I subset Surface
00231   bool operator<=(Index3D I) const;  // point finer or equal surface 
00232                                      // middle point
00233  private:
00234   Index3D ind;
00235   dir_3D dir;
00236 };
00237 
00238 // function for backtransfomation
00239 // level ist Tiefe der Nachbarn der zu suchenden Zelle mit Index I
00240 // in der x enthalten ist. Rueckgabe Index der Zelle.
00241 inline Index1D back_coordinate(double x, int level); 
00242 inline Index3D back_coordinate(D3vector v, int level); 
00243 
00244 
00246 // inline implementation of some member functions
00248 
00249 // coding of 1D index:
00250 // 0 ist point 0
00251 // ... + (2*c-1)*0.25 + (2*b-1)*0.5 + (2*a-1)*1.0   =  abc... = p
00252 // where a=1 or p=0
00253 
00254 //  Index1D:
00255 //-----------
00256 
00257 inline long_int Index1D::cart_index(int l) const {
00258   long_int sum, ind;
00259   int level;
00260   sum  = 0;
00261   if(developer_version) {
00262     if(l<Tiefe()) cout << " Error in Index1D::cart_index!! " << endl;
00263   }  
00264   level= l-Tiefe();
00265   for(ind = index;ind>0;ind = ind >> 1) {
00266     sum = sum + Zweipotenz(level)*(2*(ind&1)-1);
00267     level=level+1;
00268   };
00269   return sum;
00270 }
00271 
00272 
00273 
00274 inline Index1D Index1D::cut_level(int l) const   {
00275   long_int ind, v;
00276   v=1;
00277   v = v << l;
00278   for(ind = index;ind>v;ind = ind >> 1) {};
00279   return Index1D(ind);
00280 }
00281 
00282 
00283 inline Index1D Index1D::neighbour(dir1D d) const   {
00284   long_int ind;
00285 
00286 #ifdef PERIODIC
00287   for(ind = index;(ind&1)==d;ind = ind >> 1) {};
00288   if(developer_version) {
00289     if(ind==3) cout << " error 2 in Index1D::neighbour " << endl;
00290   }
00291   ind = ind >> 1;
00292   if(ind==0) return Index1D(1); 
00293   return Index1D(ind);
00294 #else 
00295   if(d==Ld && index==0) return 3; // this means outside of [0,1]
00296   for(ind = index;(ind&1)==d;ind = ind >> 1) {};
00297   return Index1D(ind >> 1);
00298 #endif
00299 }
00300 
00301 
00302 inline Index1D Index1D::neighbour_non_periodic(dir1D d) const   {
00303   long_int ind;
00304   if(d==Ld && index==0) return 3; // this means outside of [0,1]
00305   for(ind = index;(ind&1)==d;ind = ind >> 1) {};
00306   return Index1D(ind >> 1);
00307 }
00308 
00309 inline bool Index1D::Is_non_periodic() const {
00310 // geaendert 22.5.03: index==0 statt index!=0
00311   return (index==0);
00312 }
00313 
00314 inline int Index1D::Tiefe() const {
00315   int T;
00316   long_int ind;
00317 
00318   ind = index;
00319   for(T=-1;ind!=0;++T) ind = ind >> 1;
00320   return T;
00321 }
00322 
00323 inline Index1D Index1D::next(dir1D d, int l) const {
00324 #ifdef PERIODIC
00325     int i;
00326     long_int ind;
00327   if(developer_version) {
00328     if(index==0) cout << " error 1 in Index1D::next(dir1D d, int l) " << endl;
00329   }
00330   l = l - Tiefe();
00331   if(l==0) return neighbour(d);
00332   ind = (index << 1) + d ; 
00333   if(ind==3) ind=2;
00334   for(i=1;i<l;++i) ind = (ind << 1) + ((~d)&1) ; 
00335   return Index1D(ind);
00336 #else
00337   int i;
00338   long_int ind;
00339   l = l - Tiefe();
00340   if(d==Ld && index==0) return 3; // this means outside of [0,1]
00341   if(l==0) return neighbour(d);
00342   ind = (index << 1) + d ; 
00343   for(i=1;i<l;++i) ind = (ind << 1) + ((~d)&1) ; 
00344   return Index1D(ind);
00345 #endif
00346 }
00347 
00348 inline Index1D Index1D::next(Ort1D ort, int l) const {
00349 #ifdef PERIODIC
00350   int i, dir_of_ort;
00351   long_int ind;
00352 
00353   if(developer_version) {
00354     if(index==0) cout << " error 1 in Index1D::next(dir1D d, int l) " << endl;
00355   }
00356   if(ort==MOrt) return Index1D(index);
00357   dir_of_ort = ort/2;
00358 
00359   l = l - Tiefe();
00360   if(l==0) return neighbour((dir1D)dir_of_ort);
00361   ind = (index << 1) + dir_of_ort ; 
00362   if(ind==3) ind=2;
00363   for(i=1;i<l;++i) ind = (ind << 1) + ((~dir_of_ort)&1) ; 
00364   return Index1D(ind);
00365 #else
00366   int i, dir_of_ort;
00367   long_int ind;
00368 
00369   if(ort==1) return Index1D(index);
00370   dir_of_ort = ort/2;
00371 
00372   if(ort==LOrt && index==0) return 3; // this means outside of [0,1]
00373   l = l - Tiefe();
00374   if(l==0) return neighbour((dir1D)dir_of_ort);
00375   ind = (index << 1) + dir_of_ort ; 
00376   for(i=1;i<l;++i) ind = (ind << 1) + ((~dir_of_ort)&1) ; 
00377   return Index1D(ind);
00378 #endif
00379 }
00380 
00381 inline Index1D Index1D::son(dir1D d) const {
00382 #ifdef PERIODIC
00383   if(index==1) return Index1D(2); 
00384 #endif
00385   return Index1D( (index << 1) + d ); 
00386 };
00387 
00388 inline Index1D Index1D::father() {
00389   return Index1D(index >> 1);
00390 };
00391 
00392 inline double Index1D::h_loc() const {
00393   static long_int ind;
00394   static double h;
00395   ind = index;
00396   h = 2.0;
00397   for(h = 2.0;ind!=0;h = h * 0.5) {
00398     ind = ind >> 1;
00399   }
00400   return h;
00401 }
00402 
00403 inline double Index1D::coordinate() const {
00404   int i;
00405   long_int ind;
00406 
00407   static double h, x;
00408   ind = index;
00409   h = h_loc();
00410   x = 0.0;
00411   for(i=Tiefe();i>=0;--i) {
00412     x = x + h * (2*(ind&1)-1);
00413     h = h * 2.0;
00414     ind = ind >> 1;
00415   }
00416   return x;
00417 }
00418 
00419 inline int Index1D::operator!=(Index1D I) const {
00420   return index!=I.index;
00421 }
00422 inline int Index1D::operator==(Index1D I) const {
00423   return index==I.index;
00424 }
00425 
00426 
00427 // I_this subset [I-h,I+h[
00428 inline bool Index1D::operator<(Index1D I) const {
00429   long_int ind;
00430 #ifdef PERIODIC
00431   if(I.index==1) return true;
00432 #endif
00433 
00434   if(index==I.neighbour(Ld).index) return true;
00435   ind = index;
00436   while(I.index<ind) ind = ind>>1;
00437   return I.index==ind;
00438 }
00439 
00440 // I_this subset [I-h,I+h]
00441 inline bool Index1D::operator<<(Index1D I) const {
00442   long_int ind;
00443 
00444 #ifdef PERIODIC
00445   if(I.index==1) return true;
00446 #else
00447   if(I.index==0 || I.index==1) return true;
00448 #endif
00449 
00450   if(index==I.neighbour(Ld).index) return true;
00451   if(index==I.neighbour(Rd).index) return true;
00452   ind = index;
00453   while(I.index<ind) ind = ind>>1;
00454   return I.index==ind;
00455 }
00456 
00457 // point finer or equal as this
00458 inline bool Index1D::operator<=(Index1D I) const {
00459   long_int ind;
00460   ind = I.index;
00461   while(index<ind) ind = ind>>1;
00462   return index==ind;
00463 }
00464 
00465 //  Index3D:
00466 //----------
00467 inline void Index3D::Print() const {
00468   ind_x.Print();
00469   cout << ", ";
00470   ind_y.Print();
00471   cout << ", ";
00472   ind_z.Print();
00473 }
00474 
00475 inline Index3D Index3D::corner_of_edge_index(dir1D d) {
00476   if(ind_x.Tiefe() > ind_y.Tiefe() &&
00477      ind_x.Tiefe() > ind_z.Tiefe()) return neighbour_EW(d);
00478   if(ind_y.Tiefe() > ind_x.Tiefe() &&
00479      ind_y.Tiefe() > ind_z.Tiefe()) return neighbour_NS(d);
00480   // if(ind_z.Tiefe() > ind_x.Tiefe() &&
00481   // ind_z.Tiefe() > ind_y.Tiefe()) 
00482   return neighbour_TD(d);
00483 };
00484 
00485 inline Index3D::Index3D(long_int intx,long_int inty,long_int intz) {
00486   ind_x = Index1D(intx); 
00487   ind_y = Index1D(inty); 
00488   ind_z = Index1D(intz); 
00489 };
00490 
00491 inline Index3D::Index3D(Index1D indx,Index1D indy,Index1D indz) {
00492   ind_x=indx; ind_y=indy; ind_z=indz; 
00493 };
00494 
00495 
00496 inline Index3D Index3D::son(dir_sons d) const {
00497   return Index3D(ind_x.son((dir1D)(d&1)),
00498                  ind_y.son((dir1D)((d >> 1)&1)),
00499                  ind_z.son((dir1D)((d >> 2)&1)));
00500 };
00501 
00502 inline Index3D Index3D::father() {
00503   return Index3D(ind_x.father(),
00504                  ind_y.father(),
00505                  ind_z.father());
00506 };
00507 
00508 inline Index3D Index3D::son_EW(dir1D d) {
00509   return Index3D(ind_x.son(d),ind_y,ind_z); 
00510 };
00511 
00512 inline Index3D Index3D::son_NS(dir1D d) {
00513   return Index3D(ind_x,ind_y.son(d),ind_z); 
00514 };
00515 
00516 inline Index3D Index3D::son_TD(dir1D d) {
00517   return Index3D(ind_x,ind_y,ind_z.son(d)); 
00518 };
00519 
00520 inline Index3D Index3D::next(Ort1D ortx, Ort1D orty, Ort1D ortz, int l) const {
00521   return Index3D(ind_x.next(ortx,l),ind_y.next(orty,l),ind_z.next(ortz,l));
00522 }
00523 
00524 inline Index3D Index3D::next(dir_sons d, int l) const {
00525   return Index3D(ind_x.next((dir1D)(d&1),l),
00526                  ind_y.next((dir1D)((d >> 1)&1),l),
00527                  ind_z.next((dir1D)((d >> 2)&1),l));
00528 }
00529 inline Index3D Index3D::next(dir_3D d, int l) const {
00530   if(d>Ndir) {
00531     return next_TD(OneDpart(d),l);
00532   }
00533   if(d<Sdir) {
00534     return next_EW(OneDpart(d),l);
00535   }
00536   return next_NS(OneDpart(d),l);
00537 }
00538 
00539 inline Index3D Index3D::next(Edges_cell ed, int t) const {
00540   if(ed==SDed) return next_SD(t);
00541   if(ed==NDed) return next_ND(t);
00542   if(ed==STed) return next_ST(t);
00543   if(ed==NTed) return next_NT(t);
00544 
00545   if(ed==EDed) return next_ED(t);
00546   if(ed==WDed) return next_WD(t);
00547   if(ed==ETed) return next_ET(t);
00548   if(ed==WTed) return next_WT(t);
00549 
00550   if(ed==NEed) return next_EN(t);
00551   if(ed==NWed) return next_WN(t);
00552   if(ed==SEed) return next_ES(t);
00553   // if(ed==SWed) 
00554   return next_WS(t);
00555 }
00556 
00557 inline Index3D Index3D::next_EW(dir1D d, int l) const  {
00558   return Index3D(ind_x.next(d,l),ind_y,ind_z);
00559 }
00560 inline Index3D Index3D::next_NS(dir1D d, int l) const {
00561   return Index3D(ind_x,ind_y.next(d,l),ind_z);
00562 }
00563 inline Index3D Index3D::next_TD(dir1D d, int l) const  {
00564   return Index3D(ind_x,ind_y,ind_z.next(d,l));
00565 }
00566 
00567 inline Index3D Index3D::next_N(int l) const {  return next_NS(Rd,l); };
00568 inline Index3D Index3D::next_S(int l) const {  return next_NS(Ld,l); };
00569 inline Index3D Index3D::next_E(int l) const {  return next_EW(Rd,l); };
00570 inline Index3D Index3D::next_W(int l) const {  return next_EW(Ld,l); };
00571 inline Index3D Index3D::next_T(int l) const {  return next_TD(Rd,l); };
00572 inline Index3D Index3D::next_D(int l) const {  return next_TD(Ld,l); };
00573 
00574 inline Index3D Index3D::next_EN(int l) const { 
00575   return next_EW(Rd,l).next_NS(Rd,l); };
00576 inline Index3D Index3D::next_WN(int l) const {
00577   return next_EW(Ld,l).next_NS(Rd,l); };
00578 inline Index3D Index3D::next_ES(int l) const {
00579   return next_EW(Rd,l).next_NS(Ld,l); };
00580 inline Index3D Index3D::next_WS(int l) const {
00581   return next_EW(Ld,l).next_NS(Ld,l); };
00582 
00583 inline Index3D Index3D::next_ET(int l) const {
00584   return next_EW(Rd,l).next_TD(Rd,l); };
00585 inline Index3D Index3D::next_WT(int l) const {
00586   return next_EW(Ld,l).next_TD(Rd,l); };
00587 inline Index3D Index3D::next_ED(int l) const {
00588   return next_EW(Rd,l).next_TD(Ld,l); };
00589 inline Index3D Index3D::next_WD(int l) const {
00590   return next_EW(Ld,l).next_TD(Ld,l); };
00591 
00592 inline Index3D Index3D::next_NT(int l) const {
00593   return next_NS(Rd,l).next_TD(Rd,l); };
00594 inline Index3D Index3D::next_ST(int l) const {
00595   return next_NS(Ld,l).next_TD(Rd,l); };
00596 inline Index3D Index3D::next_ND(int l) const {
00597   return next_NS(Rd,l).next_TD(Ld,l); };
00598 inline Index3D Index3D::next_SD(int l) const {
00599   return next_NS(Ld,l).next_TD(Ld,l); };
00600 
00601 inline Index3D Index3D::next_ENT(int l) const {
00602   return next_EW(Rd,l).next_NS(Rd,l).next_TD(Rd,l); };
00603 inline Index3D Index3D::next_WNT(int l) const {
00604   return next_EW(Ld,l).next_NS(Rd,l).next_TD(Rd,l); };
00605 inline Index3D Index3D::next_EST(int l) const {
00606   return next_EW(Rd,l).next_NS(Ld,l).next_TD(Rd,l); };
00607 inline Index3D Index3D::next_WST(int l) const {
00608   return next_EW(Ld,l).next_NS(Ld,l).next_TD(Rd,l); };
00609 inline Index3D Index3D::next_END(int l) const {
00610   return next_EW(Rd,l).next_NS(Rd,l).next_TD(Ld,l); };
00611 inline Index3D Index3D::next_WND(int l) const {
00612   return next_EW(Ld,l).next_NS(Rd,l).next_TD(Ld,l); };
00613 inline Index3D Index3D::next_ESD(int l) const {
00614   return next_EW(Rd,l).next_NS(Ld,l).next_TD(Ld,l); };
00615 inline Index3D Index3D::next_WSD(int l) const {
00616   return next_EW(Ld,l).next_NS(Ld,l).next_TD(Ld,l); };
00617 
00618 inline dir_3D Index3D::direction(Index3D I) {
00619   if(ind_x != I.ind_x) {
00620     if(ind_x.coordinate() < I.ind_x.coordinate()) return Edir;
00621     else return Wdir;
00622   }
00623   if(ind_y != I.ind_y) {
00624     if(ind_y.coordinate() < I.ind_y.coordinate()) return Ndir;
00625     else return Sdir;
00626   }
00627   // if(ind_z != I.ind_z) {
00628   if(ind_z.coordinate() < I.ind_z.coordinate()) return Tdir;
00629   else return Ddir;
00630   // }
00631 }
00632 
00633 inline Index3D Index3D::neighbour(dir_sons d) const {
00634   return Index3D(ind_x.neighbour((dir1D)(d&1)),
00635                  ind_y.neighbour((dir1D)((d >> 1)&1)),
00636                  ind_z.neighbour((dir1D)((d >> 2)&1)));
00637 };
00638 
00639 inline bool Index3D::Is_non_periodic() const {
00640  // geaendert 22.5.03: || statt &&
00641    return (ind_x.Is_non_periodic() ||
00642           ind_y.Is_non_periodic() ||
00643           ind_z.Is_non_periodic());
00644 }
00645 
00646 inline Index3D Index3D::neighbour_non_periodic(dir_sons d) const {
00647   return Index3D(ind_x.neighbour_non_periodic((dir1D)(d&1)),
00648                  ind_y.neighbour_non_periodic((dir1D)((d >> 1)&1)),
00649                  ind_z.neighbour_non_periodic((dir1D)((d >> 2)&1)));
00650 };
00651 
00652 inline Index3D Index3D::neighbour_EW(dir1D d) {
00653   return Index3D(ind_x.neighbour(d),ind_y,ind_z); 
00654 };
00655 
00656 inline Index3D Index3D::neighbour_NS(dir1D d) {
00657   return Index3D(ind_x,ind_y.neighbour(d),ind_z); 
00658 };
00659 
00660 inline Index3D Index3D::neighbour_TD(dir1D d) {
00661   return Index3D(ind_x,ind_y,ind_z.neighbour(d)); 
00662 };
00663 
00664 inline int Index3D::Tiefe() const {
00665   return MAX(ind_x.Tiefe(),ind_y.Tiefe(),ind_z.Tiefe());
00666 };
00667 
00668 inline D3vector Index3D::coordinate() const {
00669   return D3vector(ind_x.coordinate(),ind_y.coordinate(),ind_z.coordinate());
00670 };
00671 
00672 inline double Index3D::coordinate_x() const {
00673   return ind_x.coordinate();
00674 };
00675 
00676 inline double Index3D::coordinate_y() const {
00677   return ind_y.coordinate();
00678 };
00679 
00680 inline double Index3D::coordinate_z() const {
00681   return ind_z.coordinate();
00682 };
00683 
00684 inline bool Index3D::Cell_index() {
00685   return (ind_x.Tiefe()==ind_y.Tiefe()) && (ind_y.Tiefe()==ind_z.Tiefe());
00686 }
00687 
00688 inline dir_sons Index3D::color(int level) {
00689   return (dir_sons)(((int)(ind_x.Tiefe()==level))
00690                     + ((int)(ind_y.Tiefe()==level)) * 2
00691                     + ((int)(ind_z.Tiefe()==level)) * 4);
00692 }
00693 
00694 inline bool Index3D::Edge_index() {
00695   if((ind_x.Tiefe()>ind_y.Tiefe()) && (ind_x.Tiefe()>ind_z.Tiefe()))
00696     return true;
00697   if((ind_y.Tiefe()>ind_x.Tiefe()) && (ind_y.Tiefe()>ind_z.Tiefe()))
00698     return true;
00699   if((ind_z.Tiefe()>ind_x.Tiefe()) && (ind_z.Tiefe()>ind_y.Tiefe()))
00700     return true;
00701   return false;
00702 }
00703 
00704 inline int Index3D::operator!=(Index3D I) const {
00705   return ind_x!=I.ind_x || ind_y!=I.ind_y || ind_z!=I.ind_z;
00706 }
00707 inline int Index3D::operator==(Index3D I) const {
00708   return ind_x==I.ind_x && ind_y==I.ind_y && ind_z==I.ind_z;
00709 }
00710 inline bool Index3D::operator<(Index3D I) const {
00711   return ind_x<I.ind_x && ind_y<I.ind_y && ind_z<I.ind_z;
00712 }
00713 inline bool Index3D::operator<=(Index3D I) const {
00714   return ind_x<=I.ind_x && ind_y<=I.ind_y && ind_z<=I.ind_z;
00715 }
00716 inline bool Index3D::operator<<(Index3D I) const {
00717   return ind_x<<I.ind_x && ind_y<<I.ind_y && ind_z<<I.ind_z;
00718 }
00719 
00720 inline bool Index3D::Index_for_cell() {
00721   return (ind_x.Tiefe() == ind_y.Tiefe() &&
00722           ind_y.Tiefe() == ind_z.Tiefe());
00723 }
00724 
00725 // concept: ec has 4 bits. first two bits are direction of the edge
00726 //          and the other two bits the location of the orthogonal
00727 inline IndexEdge Index3D::edge(Edges_cell ec) {
00728   enum dir_3D dir;
00729   dir = (dir_3D) ((ec >> 2) << 1);
00730   if(dir<Sdir)
00731     return IndexEdge(Index3D(ind_x,
00732                              ind_y.neighbour((dir1D)(ec&1)),
00733                              ind_z.neighbour((dir1D)((ec>>1)&1))),Wdir);
00734   if(dir>Ndir)
00735     return IndexEdge(Index3D(ind_x.neighbour((dir1D)(ec&1)),
00736                              ind_y.neighbour((dir1D)((ec>>1)&1)),
00737                              ind_z),Ddir);
00738 
00739   return IndexEdge(Index3D(ind_x.neighbour((dir1D)(ec&1)),
00740                            ind_y,
00741                            ind_z.neighbour((dir1D)((ec>>1)&1))),Sdir);
00742 };
00743 
00744 inline Index3D Index3D::I_edge(Edges_cell ec) {
00745   dir_3D dir;
00746   dir = (dir_3D) ((ec >> 2) << 1);
00747   if(dir<Sdir)
00748     return Index3D(ind_x,
00749                    ind_y.neighbour((dir1D)(ec&1)),
00750                    ind_z.neighbour((dir1D)((ec>>1)&1)));
00751   if(dir>Ndir)
00752     return Index3D(ind_x.neighbour((dir1D)(ec&1)),
00753                    ind_y.neighbour((dir1D)((ec>>1)&1)),
00754                    ind_z);
00755 
00756   return Index3D(ind_x.neighbour((dir1D)(ec&1)),
00757                  ind_y,
00758                  ind_z.neighbour((dir1D)((ec>>1)&1)));
00759 };
00760 
00761 inline IndexSurface Index3D::surface(dir_3D d) {
00762   if(d<Sdir) 
00763     return IndexSurface(Index3D(ind_x.neighbour((dir1D)(d&1)),ind_y,ind_z),d);
00764   if(d>Ndir) 
00765     return IndexSurface(Index3D(ind_x,ind_y,ind_z.neighbour((dir1D)(d&1))),d);
00766   return IndexSurface(Index3D(ind_x,ind_y.neighbour((dir1D)(d&1)),ind_z),d);
00767 };
00768 
00769 
00770 
00771 
00772 //  IndexEdge:
00773 //------------
00774 inline IndexEdge::IndexEdge() : d(Wdir) {};
00775 inline IndexEdge::IndexEdge(Index3D in, dir_3D di) : ind(in), d(di) {};
00776 
00777 inline Index3D IndexEdge::corner(dir1D di) {
00778   if(d>Ndir) return ind.neighbour_TD(di);
00779   if(d<Sdir) return ind.neighbour_EW(di);
00780   return ind.neighbour_NS(di);
00781 }
00782 
00783 inline dir_3D IndexEdge::direction(dir1D di) {
00784   return (dir_3D)(d + di);
00785 }
00786 
00787 inline dir_3D IndexEdge::opposite_direction(dir1D di) {
00788   return (dir_3D)(d + ((~di)&1));
00789 }
00790 
00791 inline bool IndexEdge::operator>>(Index3D I) const {
00792   if(d>Ndir)
00793     return I.I_z()<<ind.I_z() && ind.I_y()==I.I_y() && ind.I_x()==I.I_x();
00794   if(d<Sdir)
00795     return ind.I_z()==I.I_z() && ind.I_y()==I.I_y() && I.I_x()<<ind.I_x();
00796   return   ind.I_z()==I.I_z() && I.I_y()<<ind.I_y() && ind.I_x()==I.I_x();
00797 }
00798 
00799 inline bool IndexEdge::operator<=(Index3D I) const {
00800   if(d>Ndir)
00801     return ind.I_z()<=I.I_z() && ind.I_y()==I.I_y() && ind.I_x()==I.I_x();
00802   if(d<Sdir)
00803     return ind.I_z()==I.I_z() && ind.I_y()==I.I_y() && ind.I_x()<=I.I_x();
00804   return   ind.I_z()==I.I_z() && ind.I_y()<=I.I_y() && ind.I_x()==I.I_x();
00805 }
00806 
00807 
00808 //  IndexSurface:
00809 //---------------
00810 
00811 inline bool IndexSurface::operator>>(Index3D I) const {
00812   return (I<<ind) && 
00813     (ind.I_q(Main_direction(dir))==I.I_q(Main_direction(dir)));
00814 }
00815 
00816 inline bool IndexSurface::operator<=(Index3D I) const {
00817   return (ind<=I) && 
00818     (ind.I_q(Main_direction(dir))==I.I_q(Main_direction(dir)));
00819 }
00820 
00821 
00822 inline Index3D IndexSurface::corner(dir2D_sons cor) {
00823   if(dir < Sdir)
00824     return ind.neighbour_NS((dir1D)(cor&1)).neighbour_TD((dir1D)(cor>>1));
00825   if(dir > Ndir)
00826     return ind.neighbour_EW((dir1D)(cor&1)).neighbour_NS((dir1D)(cor>>1));
00827   return ind.neighbour_EW((dir1D)(cor&1)).neighbour_TD((dir1D)(cor>>1));
00828 
00829 };
00830 
00831 inline Index3D IndexSurface::edge(dir_2D edg) {
00832   if(dir < Sdir) {
00833     if(edg < Sdir2D)
00834       return ind.neighbour_NS((dir1D)(edg&1));
00835     else
00836       return ind.neighbour_TD((dir1D)(edg&1));
00837   }
00838   if(dir > Ndir) {
00839     if(edg < Sdir2D)
00840       return ind.neighbour_EW((dir1D)(edg&1));
00841     else
00842       return ind.neighbour_NS((dir1D)(edg&1));
00843   }
00844   if(edg < Sdir2D)
00845     return ind.neighbour_EW((dir1D)(edg&1));
00846   else
00847     return ind.neighbour_TD((dir1D)(edg&1));
00848 };
00849 
00850 inline dir_3D IndexSurface::direction(dir_2D d) {
00851   if(dir < Sdir) return (dir_3D)(d+2);
00852   if(dir > Ndir) return (dir_3D)d;
00853   if(d < Sdir2D) return (dir_3D)d;
00854   else           return (dir_3D)(d+2);
00855 }
00856 
00857 inline Index3D IndexSurface::I() {
00858   return ind;
00859 }
00860 
00861 
00862 
00864 // back transformation function
00866 /*
00867 inline double Index1D::coordinate() const {
00868   int i;
00869   long_int ind;
00870 
00871   static double h, x;
00872   ind = index;
00873   h = h_loc();
00874   x = 0.0;
00875   for(i=Tiefe();i>=0;--i) {
00876     x = x + h * (2*(ind&1)-1);
00877     h = h * 2.0;
00878     ind = ind >> 1;
00879   }
00880   return x;
00881 }
00882 */
00883 
00884 
00885 
00886 // Kann man noch linear optimieren
00887 // so ist es quadratisch
00888 inline Index1D back_coordinate(double x, int level) {
00889   Index1D I(2);
00890   double xx;
00891 
00892   for(int t=1;t<=level;++t) {
00893     xx = I.coordinate();
00894     if(x<xx) 
00895       I = I.son(Ld);
00896     else
00897       I = I.son(Rd);
00898   }
00899   return I;
00900 };
00901 
00902 
00903 inline Index3D back_coordinate(D3vector v, int level) {
00904   return Index3D(back_coordinate(v.x,level),
00905                  back_coordinate(v.y,level),
00906                  back_coordinate(v.z,level));
00907 } 
00908 
00909 
00910 
00911 
00912 
00913 
00914 
00915 
00916 
00917 #endif
00918        

Generated on Fri Nov 2 01:25:55 2007 for IPPL by doxygen 1.3.5