src/expde/indices/index.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 //     index.h 
00020 //
00021 // ------------------------------------------------------------
00022 
00023 #ifndef INDEX_H_
00024 #define INDEX_H_
00025        
00027 //  Index_set, ExpdeIndex
00029 
00030 class Index_set;
00031 class ExpdeIndex;
00032 
00033 #include "grid/SSten.h"
00034 
00035 // sorting types
00036 enum sorting_types { z_plane_sort };
00037 
00038 // a) hash table data structure
00040 
00041 class Point_hashtable_indices {
00042   friend class Index_set;
00043  private:
00044   int nx, ny, nz, gedir;   // inter code
00045 
00046   int wert;
00047 
00048   Point_hashtable_indices* next;
00049  public:
00050   Point_hashtable_indices(int Nx, int Ny, int Nz, int Gedir, 
00051                           int value) 
00052     : nx(Nx), ny(Ny), nz(Nz), gedir(Gedir), wert(value) {
00053     next = NULL;
00054   };
00055   int Value() { return wert; }
00056   ~Point_hashtable_indices() {
00057     delete next;
00058   };
00059 };
00060 
00061 inline int hashtable_indices_function(int x, int y, int z, int d, int length) {
00062   return (d + 11*x + 101*y + 10007*z) % length;
00063 }
00064 
00065 
00066 
00067 
00068 // b) ...
00070 
00071 
00072 #define minimal_length_P_interior  27
00073 #define minimal_length_P_nearb     27
00074 #define minimal_length_P_cellpoi   30
00075 #define minimal_length_P_Bo2p      20
00076 
00077 
00078 class assignable_vector {
00079  private:
00080   double *var;
00081   int num;
00082  public:
00083   assignable_vector(double* v, int nu) : var(v), num(nu) {};
00084   void operator=(double w) { var[num]=w; };
00085 };
00086 
00087 class Index_set_Expr {
00088  public:
00089   Index_set* set;
00090   ExpdeIndex* i;
00091   Index_set_Expr(Index_set* Kp, ExpdeIndex* ii) : set(Kp), i(ii) {};
00092 };
00093 
00094 class Index_set {
00095 friend class Variable;
00096  public:
00097   Index_set(Subgrid subgrid, Grid* gr);
00098   Index_set(Grid* gr);
00099 
00100   void Sort_by(sorting_types sort_typ);
00101 
00102   int Size() { return size; }
00103   ExpdeIndex first();
00104   ExpdeIndex last();
00105   Grid* Give_grid() { return grid; }
00106 
00107   void operator=(Index_set_Expr index_set_expr);
00108 
00109   typ_of_general_points type(int n);
00110 
00111   P_interior *pointer_P_interior(int n);
00112   P_nearb    *pointer_P_nearb(int n);
00113   P_cellpoi  *pointer_P_cellpoi(int n);
00114   P_Bo2p     *pointer_P_Bo2p(int n);
00115 
00116   // give number i of element a_i in this set
00117   int  Give_value(Index3D I, int Gedir);
00118   int  Sorted_number(int i) { return sorted_number[i]; }
00119   int  Sorted_number_back(int i) { return sorted_number_back[i]; }
00120  private:
00121   // give pointer to doubles in grid
00122   double *varM(int l);
00123 
00124   // grid
00125   Grid* grid;
00126 
00127   // vector data structure
00128   int size;
00129   // numbering:
00130   // 1. P_interior
00131   // 2. P_nearb
00132   // 3. P_cellpoi
00133   // 4. P_Bo2p
00134 
00135   // for sort_planes
00136   int *sorted_number;
00137   int *sorted_number_back;
00138   int integer_m(int ii, double coordz_min,
00139                 int num_points_z,
00140                 int zwei_po_lev);
00141 
00142 
00143   // starting points of elements
00144   P_interior **start_P_interior;
00145   P_nearb    **start_P_nearb;
00146   P_cellpoi  **start_P_cellpoi;
00147   P_Bo2p     **start_P_Bo2p;
00148 
00149   // length
00150   int length_P_interior;
00151   int length_P_nearb;
00152   int length_P_cellpoi;
00153   int length_P_Bo2p;
00154 
00155   // used
00156   int used_P_interior;
00157   int used_P_nearb;
00158   int used_P_cellpoi;
00159   int used_P_Bo2p;
00160 
00161   // set new array's
00162   void Start_setting_arrays();
00163 
00164   void Add_regular_condi(Index3D I, Index_set* set);
00165   void Add_cellpoi_condi(Index3D I, Index_set* set);
00166   void Add_Bo2p_condi(Index3D I, dir_3D d, Index_set* set);
00167 
00168   // fuer hashtable
00169   // Punkt hinzufuegen usw.
00170   void Add_point(Index3D I, int Gedir, int value);
00171   bool Exists_index(Index3D I, int Gedir);
00172 
00173   // hashtable data structure
00174   bool hashtable_initialized;
00175   bool nicht_implementiert;
00176   void initialize_hashtable();
00177 
00178   Point_hashtable_indices* point;              // fuer Iterationen
00179   int hashtable_indices_leng;                  // Laenge des hashtable
00180   int hashtable_indices_occ;                   // Besetzungszahl des hashtable
00181   Point_hashtable_indices** hashtable_indices_start;   // Zeiger auf Tabelle
00182 
00183   // gehe zu hashtable
00184   Point_hashtable_indices* hashtable_indices_point(int Nx, int Ny, int Nz,
00185                                                    int Gedir) const;
00186 
00187   // Abkuerzung fuer  gedir:
00188   // Bo2p:            gedir = 0,...,5  dir_3D
00189   // interior, nearb: gedir = 6
00190   // cell_poi:        gedir = 7
00191 
00192 
00193 };
00194 
00195 
00196 class ExpdeIndex {
00197  private:
00198   int counter;
00199   int i;
00200   Index_set *set;
00201   void Test_correct();
00202  public:
00203   ExpdeIndex();
00204   ExpdeIndex(int ii, Index_set* s);
00205 
00206   int i_integer() { 
00207     if(developer_version) Test_correct();
00208     return i; 
00209   };
00210   int integer() { 
00211     if(developer_version) Test_correct();
00212     //return i; 
00213     return counter; 
00214   };
00215   int integer(Index_set& M);
00216   Index_set* index_set() {
00217     if(developer_version) Test_correct();
00218     return set;
00219   }
00220   void operator++();
00221   void operator--();
00222   Index_set_Expr neighbours_in(Index_set& K);
00223   bool operator<=(const ExpdeIndex& IR);
00224   bool operator>=(const ExpdeIndex& IR);
00225   Grid* Give_grid() { return set->Give_grid(); }
00226 };
00227 
00228 
00229 
00231 // some inline functions
00233 
00234 inline Point_hashtable_indices* 
00235 Index_set::hashtable_indices_point(int Nx, int Ny, int Nz,
00236                                    int Gedir) const {
00237   Point_hashtable_indices* point;
00238   point = hashtable_indices_start[hashtable_indices_function(Nx,Ny,Nz,Gedir,
00239                                  hashtable_indices_leng)];
00240   while(point!=NULL) {
00241     if(point->nx==Nx && point->ny==Ny && point->nz==Nz &&
00242        point->gedir==Gedir) return point;
00243     point = point->next;
00244   }
00245   return NULL;
00246 }
00247 
00248 
00249 
00250 inline ExpdeIndex Index_set::first() {
00251   return ExpdeIndex(0,this);
00252 };
00253 
00254 inline ExpdeIndex Index_set::last() {
00255   return ExpdeIndex(size-1,this);
00256 };
00257 
00258 
00259   // give pointer to doubles in grid
00260 inline double *Index_set::varM(int n) {
00261   if(n < used_P_interior) 
00262     return start_P_interior[n]->varM(grid,grid->Max_level());
00263   if(n < used_P_nearb+used_P_interior)
00264     return start_P_nearb[n-used_P_interior]->varM(grid,grid->Max_level());
00265   if(n < used_P_cellpoi+used_P_nearb+used_P_interior) 
00266     return start_P_cellpoi[n-used_P_nearb-used_P_interior]->varM(grid);
00267   if(developer_version) {
00268     if(n>=size) 
00269       cout << " error in Index_set::varM(int n); " 
00270            << endl;
00271   }
00272   return start_P_Bo2p[n-used_P_nearb-used_P_interior
00273                      -used_P_cellpoi]->varM(grid);
00274 }
00275 
00276  // starting points of elements
00277 inline P_interior *Index_set::pointer_P_interior(int n) {
00278   if(developer_version) {
00279     if(n<0 || n>=used_P_interior) 
00280       cout << " error in Index_set::pointer_P_interior " << endl;
00281   }
00282   return start_P_interior[n];
00283 }
00284 
00285 inline P_nearb *Index_set::pointer_P_nearb(int n) {
00286   if(developer_version) {
00287     if(n<used_P_interior || n>=used_P_nearb+used_P_interior) 
00288       cout << " error in Index_set::pointer_P_nearb " << endl;
00289   }
00290   return start_P_nearb[n-used_P_interior];
00291 }
00292 
00293 inline P_cellpoi *Index_set::pointer_P_cellpoi(int n) {
00294   if(developer_version) {
00295     if(n<used_P_interior+used_P_nearb || 
00296        n>=used_P_nearb+used_P_interior+used_P_cellpoi) 
00297       cout << " error in Index_set::pointer_P_cellpoi " << endl;
00298   }
00299   return start_P_cellpoi[n-used_P_interior-used_P_nearb];
00300 }
00301 
00302 inline P_Bo2p *Index_set::pointer_P_Bo2p(int n) {
00303   if(developer_version) {
00304     if(n<used_P_interior+used_P_nearb+used_P_cellpoi || 
00305        n>=size) 
00306       cout << " error in Index_set::pointer_P_Bo2p " 
00307            << n 
00308            << " u: " << used_P_interior+used_P_nearb+used_P_cellpoi
00309            << " o: " << size << endl;
00310   }
00311   return start_P_Bo2p[n-used_P_interior-used_P_nearb-used_P_cellpoi];
00312 }
00313 
00314 
00315 
00316 inline typ_of_general_points Index_set::type(int n) {
00317   if(n < used_P_interior)
00318     return type_P_interior;
00319   if(n < used_P_nearb+used_P_interior)
00320     return type_P_nearb;
00321   if(n < used_P_cellpoi+ used_P_nearb+used_P_interior)
00322     return type_P_cellpoi;
00323   if(developer_version) {
00324     if(n>=size) 
00325       cout << " error in Index_set::type(int n); " 
00326            << endl;
00327   }
00328   return type_P_Bo2p;
00329 }
00330 
00331 inline Index_set_Expr ExpdeIndex::neighbours_in(Index_set& K) {
00332   return Index_set_Expr(&K,this);
00333 }
00334 
00335 
00336 inline void ExpdeIndex::operator++() { 
00337   if(developer_version) Test_correct();
00338 
00339   ++counter; 
00340   i = set->Sorted_number(counter);
00341 };
00342 
00343 inline void ExpdeIndex::operator--() { 
00344   if(developer_version) Test_correct();
00345 
00346   --counter; 
00347   i = set->Sorted_number(counter);
00348 };
00349 
00350 inline bool ExpdeIndex::operator<=(const ExpdeIndex& IR) {
00351   // cout << " Vergl: " << i << ", and " << IR.i << endl;
00352   return counter <= IR.counter;
00353 }
00354 inline bool ExpdeIndex::operator>=(const ExpdeIndex& IR) {
00355   // cout << " Vergl: " << i << ", and " << IR.i << endl;
00356   return counter >= IR.counter;
00357 }
00358 
00359 
00360 
00361 
00362 template<class A>
00363 double DExpr<A>::operator[] (ExpdeIndex& i) {
00364  
00365   P_interior *iter_i;
00366   P_nearb    *iter_n;
00367   P_Bo2p     *iter_b;
00368   P_cellpoi  *iter_cf;
00369 
00370   typ_of_general_points typ;
00371 
00372   int lev;
00373   Grid *grid;
00374   double h_mesh;
00375   int size_stencil;
00376 
00377   // Zwischenspeicher
00378   Nearb_Ablage* nearb_ablage;
00379 
00380   grid = i.Give_grid();
00381   lev  = grid->Max_level();
00382   h_mesh = grid->H_mesh() / Zweipotenz(lev);
00383 
00384   typ = i.index_set()->type(i.i_integer());
00385   if(typ==type_P_interior) {
00386     iter_i = i.index_set()->pointer_P_interior(i.i_integer());
00387     
00388     if(developer_version) {
00389       if(iter_i==NULL) cout << " Error: iter_i " << endl;
00390     }
00391     size_stencil=a_.Sice_stencil();
00392     if(size_stencil<=15)
00393       return a_.Give_interior(iter_i,grid,h_mesh,lev,
00394                               iter_i->varN(grid,lev),
00395                               iter_i->varW(grid,lev),
00396                               iter_i->varM(grid,lev),
00397                               iter_i->varE(grid,lev),
00398                               iter_i->varS(grid,lev),
00399                               iter_i->varT(grid,lev),
00400                               iter_i->varD(grid,lev),
00401                               iter_i->varND(grid,lev),
00402                               iter_i->varWN(grid,lev),
00403                               iter_i->varWT(grid,lev),
00404                               iter_i->varED(grid,lev),
00405                               iter_i->varST(grid,lev),
00406                               iter_i->varES(grid,lev),
00407                               NULL, NULL,
00408                               iter_i->varEST(grid,lev),
00409                               iter_i->varWND(grid,lev),
00410                               NULL, NULL, NULL, NULL,
00411                               NULL, NULL, NULL, NULL);
00412     if(size_stencil==17)
00413       return a_.Give_interior(iter_i,grid,h_mesh,lev,
00414                               iter_i->varN(grid,lev),
00415                               iter_i->varW(grid,lev),
00416                               iter_i->varM(grid,lev),
00417                               iter_i->varE(grid,lev),
00418                               iter_i->varS(grid,lev),
00419                               iter_i->varT(grid,lev),
00420                               iter_i->varD(grid,lev),
00421                               iter_i->varND(grid,lev),
00422                               iter_i->varWN(grid,lev),
00423                               iter_i->varWT(grid,lev),
00424                               iter_i->varED(grid,lev),
00425                               iter_i->varST(grid,lev),
00426                               iter_i->varES(grid,lev),
00427                               iter_i->varWD(grid,lev),
00428                               iter_i->varET(grid,lev),
00429                               iter_i->varEST(grid,lev),
00430                               iter_i->varWND(grid,lev),
00431                               NULL, NULL, NULL, NULL,
00432                               NULL, NULL, NULL, NULL);
00433     if(size_stencil==25)
00434       return a_.Give_interior(iter_i,grid,h_mesh,lev,
00435                               iter_i->varN(grid,lev),
00436                               iter_i->varW(grid,lev),
00437                               iter_i->varM(grid,lev),
00438                               iter_i->varE(grid,lev),
00439                               iter_i->varS(grid,lev),
00440                               iter_i->varT(grid,lev),
00441                               iter_i->varD(grid,lev),
00442                               iter_i->varND(grid,lev),
00443                               iter_i->varWN(grid,lev),
00444                               iter_i->varWT(grid,lev),
00445                               iter_i->varED(grid,lev),
00446                               iter_i->varST(grid,lev),
00447                               iter_i->varES(grid,lev),
00448                               iter_i->varWD(grid,lev),
00449                               iter_i->varET(grid,lev),
00450                               iter_i->varEST(grid,lev),
00451                               iter_i->varWND(grid,lev),
00452                               iter_i->cell_varWSD(grid,lev),
00453                               iter_i->cell_varWST(grid,lev),
00454                               iter_i->cell_varWND(grid,lev),
00455                               iter_i->cell_varWNT(grid,lev),
00456                               iter_i->cell_varESD(grid,lev),
00457                               iter_i->cell_varEST(grid,lev),
00458                               iter_i->cell_varEND(grid,lev),
00459                               iter_i->cell_varENT(grid,lev));
00460   }
00461   
00462   if(typ==type_P_cellpoi) {
00463     iter_cf = i.index_set()->pointer_P_cellpoi(i.i_integer());
00464     
00465     if(developer_version) {
00466       if(iter_cf==NULL) cout << " Error: iter_cf " << endl;
00467     }
00468     return
00469       a_.Give_cellpoi(iter_cf,grid,grid->Give_Bo_cell(iter_cf->Ind()));
00470   }
00471 
00472   if(typ==type_P_nearb) {
00473     iter_n = i.index_set()->pointer_P_nearb(i.i_integer());
00474 
00475     if(developer_version) {
00476       if(iter_n==NULL) cout << " Error: iter_n " << endl;
00477     }
00478     nearb_ablage = grid->Give_Nearb_Ablage();
00479     size_stencil=a_.Sice_stencil();
00480     if(size_stencil>=17) {
00481       nearb_ablage->Initialize_17(grid,iter_n,lev);
00482     }
00483     else {
00484       nearb_ablage->Initialize(grid,iter_n,lev);
00485     }
00486     return
00487       a_.Give_nearb(iter_n,grid,h_mesh,lev,nearb_ablage);
00488   }
00489 
00490   if(typ==type_P_Bo2p) {
00491     iter_b = i.index_set()->pointer_P_Bo2p(i.i_integer());
00492 
00493     if(developer_version) {
00494       if(iter_b==NULL) cout << " Error: iter_b " << endl;
00495     }
00496     return
00497       a_.Give_Bo2p(iter_b,grid,lev);
00498   }
00499   cout << " Error in DExpr<A>::operator[] " << endl;
00500 
00501 
00502   cout << " Hello, we are returning zero!!" << endl;
00503   return 0.0;
00504 };
00505 
00506 
00507 #endif
00508          

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