src/expde/grid/hash.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 //  hash.h
00020 //
00021 // ------------------------------------------------------------
00022 
00023 
00024 //  Fuer Hashtable 0: Zellen und Kanten
00025 // -------------------------------------
00026 class Point_hashtable0 {
00027   friend class Grid_base;
00028   friend class Grid;
00029  private:
00030   Index3D ind;      // Mittelpunkt der Kante oder der Zelle
00031   int typ;          // typ der Kante bzw. Zelle
00032   bool isCell_m;      // I.Cell_index() 
00033   int  depth_m;
00034   bool send_m;
00035 
00036   // Speicher fuer Zellen
00037   double *var;
00038 
00039   Point_hashtable0* next;
00040  public:
00041   //  I Index des  Mittelpunktes der Zelle oder Kante
00042   Point_hashtable0(Index3D I) : ind(I) { 
00043     isCell_m = I.Cell_index(); 
00044     depth_m  = I.Tiefe();
00045     typ=noeinfo;
00046     next = NULL;
00047     var = NULL;
00048   };
00049   Point_hashtable0(Point_hashtable0* point_old);
00050   Index3D Give_Index() { return ind; }
00051   double *Give_var() { return var; }
00052   Celltype Give_cell_typ();
00053   Point_hashtable0* Next() { return next; }
00054   bool isCell() { return isCell_m; }
00055   bool doSend() {  return send_m; }
00056   void will_be_sent(bool s) { send_m = s; }
00057   int Give_Tiefe() { return depth_m; }
00058   ~Point_hashtable0() {
00059     delete next;
00060   };
00061 };
00062 
00063 inline int hashtable0_function(int x, int y, int z, int length) {
00064   //  return (x + 179*y + 2137*z) % length;
00065   return (x + 101*y + 10007*z) % length;
00066 }
00067 
00068 //  Fuer Iteration durch Hashtable 0: Grid
00069 // -----------------------------------------
00070 // folgendes define verwendet : point0:
00071 #define iterate_hash0  for(i_iter=0;i_iter<hashtable0_leng;++i_iter) for(point0=hashtable0_start[i_iter];point0!=NULL;point0=point0->next) 
00072 
00073 #define Iterate_hash0  for(i_iter=0;i_iter<hashtable0_leng;++i_iter) for(point0=hashtable0_start[i_iter];point0!=NULL;point0=point0->Next()) 
00074 
00075 
00076 //  Fuer Hashtable 1: Grid
00077 // ------------------------
00078 class Point_hashtable1 {
00079  friend class Grid_base;
00080  friend class Grid;
00081  private:
00082   Index3D ind;
00083   Pointtype typ;               // type of the point: interior,  exterior, 
00084                                //   not responsible points are parallel_p
00085   Pointtype global_typ;        // type of the point: interior,  exterior, ...
00086                                //   multigrid is always correct
00087                                // needed in rers_op.h
00088 
00089   int nummer;                  // Nummer des Punktes (fuer AVS)
00090   bool label4;                 // Label zum Allocieren von Hashtable4 MG  
00091   int  depth_m;
00092 
00093 
00094   // different level informations
00095   int level;                   // falls randnaher Punkt: 
00096                                //       level der lokalen Maschenweite
00097                                // falls uniformer Punkt:
00098                                //       level des groebsten 27-Sternes
00099 
00100   int my_finest_parallel_level; // fuer Parallelisierung
00101                                
00102   int finest_level;            // feinster moeglicher level fuer multigrid
00103                                // Punkte und 
00104                                // andere Punkte; wird auch in Print AVS verw.
00105   //  bool responsible_mg;         // responsibility for a multigrid point
00106 
00107   // groebster level bezueglich Label fuer multigrid Punkte
00108   int *label_level;
00109   types_of_label_send send_label;  // used in: labbo.cc
00110 
00111   Point_hashtable1* next;
00112  public:
00113   // I Index des Punktes
00114   Point_hashtable1(Index3D I);
00115   Point_hashtable1(Index3D I,Pointtype);
00116   Point_hashtable1(Point_hashtable1* point_old);
00117   Index3D Give_Index() { return ind; }
00118   Pointtype Give_typ() { return typ; }
00119   int  Give_label(int num);               // label heisst hier ob Dirichlet
00120   void Put_label_level(int num, int lev); // Rand fuer Level
00121                                           // groesser gleich lev
00122   int Give_Tiefe() { return depth_m; }
00123   ~Point_hashtable1() {
00124     delete next;
00125     if(label_level!=NULL) {
00126       delete label_level;
00127     }
00128   };
00129 };
00130 
00131 inline int hashtable1_function(int x, int y, int z, int length) {
00132   //  return (x + 179*y + 2137*z) % length;
00133   return (x + 101*y + 10007*z) % length;
00134 }
00135 
00136 
00137 //  Fuer Iteration durch Hashtable 1: Grid
00138 // -----------------------------------------
00139 // folgendes define verwendet : point1:
00140 #define iterate_hash1  for(i_iter=0;i_iter<hashtable1_leng;++i_iter) for(point1=hashtable1_start[i_iter];point1!=NULL;point1=point1->next) 
00141 
00142 
00143 
00144 //  Fuer Hashtable 2: Randzellen, Boundary Cell
00145 //  Beachte obiges: #define Point_hashtable2 BoCell 
00146 // -------------------------------------------------
00147 class BoCell : public BoCeData {
00148  friend class Grid_base;
00149  friend class Grid;
00150  private:
00151   Index3D ind;
00152 
00153   // Speicher fuer Freiheitsgrad in Zelle; existiert nicht immer
00154   double *var;
00155 
00156   Point_hashtable2* next;
00157  public:
00158   BoCell(Index3D I, Grid_base* gitter);
00159   Index3D Give_Index() { return ind; }
00160   double *Give_var() { return var; }
00161   Point_hashtable2* Next() { return next; }
00162   ~BoCell() {
00163     delete next;
00164   };
00165 };
00166 
00167 inline int hashtable2_function(int x, int y, int z, int length) {
00168   //  return (x + 179*y + 2137*z) % length;
00169   return (x + 101*y + 10007*z) % length;
00170 }
00171 
00172 
00173 //  Fuer Iteration durch Hashtable 2: Randzellen
00174 // -----------------------------------------------
00175 // folgendes define verwendet : bocell:
00176 #define iterate_hash2  for(i_iter=0;i_iter<hashtable2_leng;++i_iter) for(bocell=hashtable2_start[i_iter];bocell!=NULL;bocell=bocell->next) 
00177 
00178 #define Iterate_hash2  for(i_iter=0;i_iter<hashtable2_leng;++i_iter) for(bocell=hashtable2_start[i_iter];bocell!=NULL;bocell=bocell->Next()) 
00179 
00180 
00181 
00182 
00183 //  Fuer Hashtable 3: Randpunkte 
00184 // --------------------------------
00185 class Bo2Point {
00186  friend class Grid_base;
00187  friend class Grid;
00188  private:
00189   Index3D ind;
00190   dir_3D  direction;
00191   int level;
00192   double h;                // Abstand zum Rand gerastert
00193   double h_origional;      // Exacter Abstand zum Rand
00194   double *var;
00195   int nummer;              // for avs
00196 
00197   // Label fuer Randpunkte
00198   TypLabel label;
00199 
00200   Point_hashtable3* next;
00201  public:
00202   inline Bo2Point(Index3D I, dir_3D d, int l, Grid_base* gitter,
00203                   int number_var);
00204   void Set_number_avs(int numavs) { nummer = numavs; };
00205   // Koordinate des Punktes gerastert
00206   inline D3vector transform_coord(D3vector A, double H);
00207   // Koordinate des Orginalpunktes verschoben
00208   inline D3vector transform_coord_org_shift(D3vector A, double h, 
00209                                             double H, double shift);
00210   int Nummer() { return nummer; }
00211 
00212   void Put_label(bool lab, int num);    // label heisst hier
00213   bool Give_label(int num);             // Punkt im Gebiet oder nicht
00214   IndexBo Give_boindex() const { return IndexBo(ind,direction); }
00215   ~Bo2Point() {
00216     delete next;
00217   };
00218 };
00219 
00220 inline int hashtable3_function(int x, int y, int z, dir_3D  d, int length) {
00221   //  return (d + 10*x + 1079*y + 20137*z) % length;
00222   return (d + 11*x + 101*y + 10007*z) % length;
00223 }
00224 
00225 
00226 //  Fuer Iteration durch Hashtable 3: Randpunkte 2.Teil
00227 // ----------------------------------------------------
00228 // folgendes define verwendet : bo2point:
00229 #define iterate_hash3  for(i_iter=0;i_iter<hashtable3_leng;++i_iter) for(bo2point=hashtable3_start[i_iter];bo2point!=NULL;bo2point=bo2point->next) 
00230 
00231 
00232 
00233 //  Fuer Hashtable 4: Datenspeicher
00234 // ----------------------------------
00235 class Data {
00236  friend class Grid_base;
00237  private:
00238   Index3D ind;
00239   int level;
00240   double *var;
00241 
00242   Point_hashtable4* next;
00243  public:
00244   double *Get_var() { return var; };
00245   Data(Index3D I, int l, int number_var);
00246   ~Data() {
00247     delete next;
00248   };
00249 };
00250 
00251 // hier Achtung, dass keine negative Zahl entsteht:
00252 // Parameter_MG_Variable is Parameter aus parameter.h
00253 inline int hashtable4_function(int x, int y, int z, int ebene, int length) {
00254   // return ((100 + Parameter_MG_Variable) + 11*x + 1079*y + 20137*z) % length;
00255   return ((100 + Parameter_MG_Variable) + 11*x + 101*y + 10007*z) % length;
00256 }
00257 
00258 
00259 //  Fuer Iteration durch Hashtable 4: Datenspeicher
00260 // -------------------------------------------------
00261 // folgendes define verwendet : varpoint:
00262 #define iterate_hash4  for(i_iter=0;i_iter<hashtable4_leng;++i_iter) for(varpoint=hashtable4_start[i_iter];varpoint!=NULL;varpoint=varpoint->next) 
00263 
00264 
00266 // Implementierung einiger Memberfunktionen
00268 
00269 // allgemein
00270 inline double *newdouble(int number) {
00271   static int i;
00272   static double* sp;
00273   sp = new double[number];
00274   for(i=0;i<number;++i) sp[i]=0.0;
00275   return sp;
00276 }
00277 
00278 // hash 0
00279 
00280 inline Point_hashtable0* Grid_base::hashtable0_point(Index3D I) const {
00281   Point_hashtable0* point;
00282   point = hashtable0_start
00283     [hashtable0_function(I.ind_x.index,I.ind_y.index,I.ind_z.index,
00284                          hashtable0_leng)];
00285   while(point!=NULL) {
00286     if(point->ind==I) return point;
00287     point = point->next;
00288   }
00289   return NULL;
00290 }
00291 
00292 inline Point_hashtable0::Point_hashtable0(Point_hashtable0* point_old) {
00293   ind = point_old->ind;
00294   typ = point_old->typ;
00295   var = point_old->var;
00296 
00297   isCell_m = point_old->isCell_m;
00298   depth_m  = point_old->depth_m;
00299 
00300   next=NULL;
00301 }
00302 
00303 inline Celltype Point_hashtable0::Give_cell_typ() {
00304   if(developer_version) {
00305     if(!ind.Cell_index()) {
00306       cout << "\n Error 1 in Point_hashtable0::Give_cell_typ!" << endl;
00307       cout << " Point: "; ind.coordinate().Print(); cout << endl;
00308     }
00309   }
00310   return (Celltype)typ;
00311 }
00312 
00313 // hash 1
00314 
00315 inline Point_hashtable1::Point_hashtable1(Index3D I) {
00316   ind = I;
00317   typ = exterior;
00318   next=NULL;
00319   //  responsible_mg = false;
00320 
00321   depth_m  = I.Tiefe();
00322 
00323   label_level=NULL;
00324 
00325   finest_level=0;
00326   my_finest_parallel_level=0;
00327   label4 = false;
00328 }
00329 
00330 inline Point_hashtable1::Point_hashtable1(Index3D I, Pointtype type) {
00331   ind = I;
00332   typ = type;
00333   next=NULL;
00334   //  responsible_mg = false;
00335 
00336   depth_m  = I.Tiefe();
00337 
00338   label_level=NULL;
00339 
00340   finest_level=0;
00341   my_finest_parallel_level=0;
00342   label4 = false;
00343 }
00344 
00345 inline void Point_hashtable1::Put_label_level(int num, int lev) {
00346   label_level[num-1] = lev; 
00347 }
00348 
00349 inline int Point_hashtable1::Give_label(int num) {
00350   return label_level[num-1]; 
00351 }
00352 
00353 
00354 inline Point_hashtable1::Point_hashtable1(Point_hashtable1* point_old) {
00355   ind = point_old->ind;
00356   typ = point_old->typ;
00357 
00358   label_level=NULL;
00359 
00360   nummer = point_old->nummer;
00361   label4 = point_old->label4;
00362   finest_level=0;
00363   my_finest_parallel_level=0;
00364   next=NULL;
00365 
00366   depth_m  = point_old->depth_m;
00367 }
00368 
00369 
00370 inline Point_hashtable1* Grid_base::hashtable1_point(Index3D I) const {
00371   Point_hashtable1* point;
00372   point = hashtable1_start
00373     [hashtable1_function(I.ind_x.index,I.ind_y.index,I.ind_z.index,
00374                          hashtable1_leng)];
00375   while(point!=NULL) {
00376     if(point->ind==I) return point;
00377     point = point->next;
00378   }
00379   return NULL;
00380 }
00381 
00382 // hash 2
00383 
00384 inline Point_hashtable2::Point_hashtable2(Index3D I, Grid_base* gitter) {
00385   ind = I;  
00386   var = NULL;
00387   next=NULL;
00388 }
00389 
00390 inline Point_hashtable2* Grid_base::hashtable2_point(Index3D I) const {
00391   static Point_hashtable2* point;
00392   point = hashtable2_start
00393     [hashtable2_function(I.ind_x.index,I.ind_y.index,I.ind_z.index,
00394                          hashtable2_leng)];
00395   while(point!=NULL) {
00396     if(point->ind==I) return point;
00397     point = point->next;
00398   }
00399   return NULL;
00400 }
00401 
00402 
00403 // hash 3
00404 
00405 inline Point_hashtable3::Point_hashtable3(Index3D I,  dir_3D d, int l,
00406                                    Grid_base* gitter, int number_var) {
00407   double h_min, h_max;
00408   ind = I;
00409   direction = d;
00410   level = l;
00411   label=0;
00412 
00413   // Minimaler Abstand am Rand 
00414   //^^^^^parallel^^^^^^^^^ deswegen braucht man hier -1
00415   // h_min = gitter->H_mesh() / Zweipotenz(l*2-1) * factor_boundary_dis; //old
00416 
00417   h_min =  gitter->h_min_for_boundary_points;  //new
00418 
00419   //  h_min = gitter->finest_mesh_size() / 4.0; // (for testing)
00420   //  h_min = 0.0;  // Test
00421   // Maximaler Abstand am Rand
00422   //  h_max = gitter->H_mesh() / Zweipotenz(l) - h_min;//old
00423   h_max = gitter->finest_mesh_size() - h_min; //new
00424   h = gitter->distanceD(I.coordinate(),d);
00425   // Test 
00426   //  h = gitter->finest_mesh_size() * 0.25;
00427 
00428   h_origional = h;
00429 
00430 
00431   if(h<h_min)      h = h_min;
00432   else if(h>h_max) h = h_max;
00433 
00434   //  h_max = gitter->H_mesh() / Zweipotenz(l); //old
00435   h_max = gitter->finest_mesh_size();       //new
00436   h_min = 0.0;
00437   if(h_origional<h_min)      h_origional = h_min;
00438   else if(h_origional>h_max) h_origional = h_max;
00439   if(developer_version==true) {
00440     if(h>h_max*1.2) 
00441       cout << "\n Fehler bei Randabstand! (zu gross)! " << endl;  
00442     if(h<0.0)
00443       cout << "\n Fehler bei Randabstand! (negativ)! " << endl;  
00444   }  
00445 
00446   next=NULL;
00447   if(number_var>0)    var   = newdouble(number_var);
00448   else var   = NULL;
00449 }
00450 
00451 
00452 
00453 inline D3vector Point_hashtable3::transform_coord(D3vector A,
00454                                                   double H) {
00455   A.x = A.x + ind.coordinate_x() * H;
00456   A.y = A.y + ind.coordinate_y() * H;
00457   A.z = A.z + ind.coordinate_z() * H;
00458 
00459   if(direction==Wdir)
00460     return D3vector(A.x-h,A.y,A.z);
00461   if(direction==Edir)
00462     return D3vector(A.x+h,A.y,A.z);
00463   if(direction==Ndir)
00464     return D3vector(A.x,A.y+h,A.z);
00465   if(direction==Sdir)
00466     return D3vector(A.x,A.y-h,A.z);
00467   if(direction==Tdir)
00468     return D3vector(A.x,A.y,A.z+h);
00469   //  if(direction==Ddir)
00470   return D3vector(A.x,A.y,A.z-h);
00471 };
00472 
00473 
00474 // Orginal Randpunkt wird leucht verschoben
00475 inline D3vector Point_hashtable3::transform_coord_org_shift(D3vector A,
00476                                                             double h_s,
00477                                                             double H, 
00478                                                             double shift) {
00479   double h_shift;
00480   // Rand_punkt wird hier leicht verschoben
00481   h_shift = h_origional + h_s * shift;
00482 
00483   A.x = A.x + ind.coordinate_x() * H;
00484   A.y = A.y + ind.coordinate_y() * H;
00485   A.z = A.z + ind.coordinate_z() * H;
00486 
00487   if(direction==Wdir)
00488     return D3vector(A.x-h_shift,A.y,A.z);
00489   if(direction==Edir)
00490     return D3vector(A.x+h_shift,A.y,A.z);
00491   if(direction==Ndir)
00492     return D3vector(A.x,A.y+h_shift,A.z);
00493   if(direction==Sdir)
00494     return D3vector(A.x,A.y-h_shift,A.z);
00495   if(direction==Tdir)
00496     return D3vector(A.x,A.y,A.z+h_shift);
00497   //  if(direction==Ddir)
00498   return D3vector(A.x,A.y,A.z-h_shift);
00499 };
00500 
00501 
00502 
00503 inline void Point_hashtable3::Put_label(bool lab, int num) {
00504   int i, z;
00505   if(developer_version) {
00506     if(num>Max_label_number || num<=0) {
00507       cout << " Label number wrong in Point_hashtable3::Put_label! " << endl;
00508       cout << " num is: " << num << endl;
00509       num=0;
00510     } 
00511   }
00512   z=0;
00513   for(i=0;i<num-1;++i) {
00514     z = (z<<1) + 1; 
00515   }
00516 
00517   label = ((((label>>num)<<1)+lab)<<(num-1)) + (label&z);
00518 };
00519 
00520 inline bool Point_hashtable3::Give_label(int num) {
00521   if(developer_version) {
00522     if(num>Max_label_number || num<=0) {
00523       cout << " Label number wrong in Point_hashtable3::Give_label! " << endl;
00524       num=0;
00525     } 
00526   }
00527   return (bool)((label>>(num-1))&1);
00528 };
00529 
00530 
00531 inline Point_hashtable3* Grid_base::hashtable3_point(IndexBo IBo) const {
00532   static Point_hashtable3* point;
00533   point = hashtable3_start
00534     [hashtable3_function(IBo.I.ind_x.index,IBo.I.ind_y.index,IBo.
00535                          I.ind_z.index, IBo.d, hashtable3_leng)];
00536   while(point!=NULL) {
00537     if(point->ind==IBo.I && point->direction==IBo.d) return point;
00538     point = point->next;
00539   }
00540   return NULL;
00541 }
00542 
00543 inline Point_hashtable3* Grid_base::hashtable3_point(Index3D Ind, dir_3D dir)
00544      const {
00545   static Point_hashtable3* point;
00546   point = hashtable3_start
00547     [hashtable3_function(Ind.ind_x.index,Ind.ind_y.index,
00548                          Ind.ind_z.index, dir, hashtable3_leng)];
00549   while(point!=NULL) {
00550     if(point->ind==Ind && point->direction==dir) return point;
00551     point = point->next;
00552   }
00553   return NULL;
00554 }
00555 
00556 
00557 inline double* Grid_base::Give_variable(Index3D I, int ebene) const {
00558   static Point_hashtable4* point;
00559   point = hashtable4_start
00560     [hashtable4_function(I.ind_x.index,I.ind_y.index,I.ind_z.index, ebene,
00561                          hashtable4_leng)];
00562   if(developer_version) {
00563     if(point==NULL) {
00564       cout << "\n Error 1 in Give_variable (H4) "
00565            << my_rank 
00566            << " x: " << I.I_x().get()
00567            << " y: " << I.I_y().get()
00568            << " z: " << I.I_z().get()
00569            << endl;
00570       I.Print();
00571       I.coordinate().Print(); cout << " ebene: " << ebene << endl;
00572       return NULL;
00573     }
00574   }
00575   while(true) {
00576     if(point->ind==I && point->level==Parameter_MG_Variable) return point->var;
00577     point = point->next;
00578     if(developer_version) {
00579       if(point==NULL) {
00580         cout << "\n Error 2 in Give_variable (H4) " 
00581              << my_rank 
00582              << " x: " << I.I_x().get()
00583              << " y: " << I.I_y().get()
00584              << " z: " << I.I_z().get()
00585              << endl;
00586         I.coordinate().Print(); cout << " ebene: " << ebene << endl;
00587         return NULL;
00588       }
00589     }
00590   }
00591 }
00592 
00593 inline double* Grid_base::Give_variable_slow(const Index3D I, int ebene) const {
00594   static Point_hashtable4* point;
00595   point = hashtable4_start
00596     [hashtable4_function(I.ind_x.index,I.ind_y.index,I.ind_z.index, ebene, 
00597                          hashtable4_leng)];
00598   while(point!=NULL) {
00599     if(point->ind==I && point->level==Parameter_MG_Variable) return point->var;
00600     point = point->next;
00601   }
00602   return NULL;
00603 }
00604 
00605 
00606 // Elementares fuer hashtable4
00607 // ----------------------------
00608 
00609 inline Point_hashtable4::Point_hashtable4(Index3D I, int ebene, 
00610                                           int number_var) {
00611   ind = I;
00612   // Parameter_MG_Variable is Parameter aus parameter.h
00613   level = Parameter_MG_Variable;
00614   var = newdouble(number_var);
00615   next=NULL;
00616 }
00617 
00618 
00619 inline Point_hashtable4 *Grid_base::hashtable4_point(Index3D I, int ebene) {
00620   static Point_hashtable4* point;
00621   point = hashtable4_start
00622     [hashtable4_function(I.ind_x.index,I.ind_y.index,
00623                          I.ind_z.index, ebene, hashtable4_leng)];
00624   while(point!=NULL) {
00625     // Parameter_MG_Variable is Parameter aus parameter.h
00626     if(point->ind==I && point->level==Parameter_MG_Variable) return point;
00627     point = point->next;
00628   }
00629   return NULL;
00630 }
00631 
00632 inline Point_hashtable4* Grid_base::hashtable4_point(Index3D I) {
00633   static Point_hashtable4* point;
00634   point = hashtable4_start
00635     [hashtable4_function(I.ind_x.index,I.ind_y.index,
00636                          I.ind_z.index, 0, hashtable4_leng)];
00637   while(point!=NULL) {
00638     if(point->ind==I && point->level==0) return point;
00639     point = point->next;
00640   }
00641   return NULL;
00642 }
00643 
00644 
00645 
00646 

Generated on Mon Jan 16 13:23:41 2006 for IPPL by  doxygen 1.4.6