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

src/expde/extemp/varcon.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 #ifndef VARCON_H_
00018 #define VARCON_H_
00019            
00020 // ------------------------------------------------------------
00021 //
00022 //     varcon.h 
00023 //
00024 // ------------------------------------------------------------
00025 
00027 //
00028 // coefficient with constant variable on cells
00029 //
00031 
00032 
00034 // 1. first wrapper class
00036 /* wrapper class wich contains  ...contains the expression types 
00037                - ConExprVAR
00038                - ConExprLIT 
00039                - ConExprBinOp 
00040                - ...           */
00041 
00042 
00043 template<class A>
00044 class CoExpr {
00045  private:
00046   A a_;
00047 
00048  public:
00049   CoExpr(const A& x)
00050     : a_(x)
00051     {}
00052   // for evaluate on cell
00053   double Give_interior_cell(const P_interior_cell* it_icell ,
00054                             const Grid* gr, int l) const {
00055     return a_.Give_interior_cell(it_icell,gr ,l);
00056   };
00057   double Give_bo_tet(const P_boundary_tet* it_bcell, 
00058                       const Grid* gr) const {
00059     return a_.Give_bo_tet(it_bcell,gr);
00060   };
00061 
00062   // activity of points
00063   int Level() const { return a_.Level(); }
00064   Dominace_label Dominant_lev() const { return a_.Dominant_lev(); }
00065 
00066   // number of operations
00067   int ops_interior() const { return a_.ops_interior(); }
00068 
00069   // for Parallelization
00070   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00071     const {
00072     a_.Add_variables_for_parallel(evpar);
00073   };
00074 };
00075 
00076 
00078 // 2. variable
00080 
00081 /* class Cell_Variable */
00082 class Cell_Variable {
00083  private:
00084   //  public:
00085   // Aktive Punkte:
00086   int  level;        // level:
00087 
00088   // Iterator
00089   P_interior_cell  *iter_ice;
00090   P_boundary_tet  *iter_bce;
00091 
00092   // Zwischenspeicher
00093 
00094   // Gitter
00095   Grid *grid;
00096 
00097   // Nummer der Variablen
00098   int number_cell_variable;
00099 
00100  public:
00101   Cell_Variable(Grid* gridp);
00102 
00103   int my_rank() { return grid->Give_my_rank(); };
00104 
00106   // Zur Speicherverwaltung:
00107   inline void Test_init() { grid->Test_init(); }
00108 
00109   int Number_cell_variable() const { return number_cell_variable; }
00110 
00111   // activity of level
00112   inline int  Level() const { return level; }
00113   inline void Level_up();
00114   inline void Level_down();
00115   inline void Active_Level(int Level);
00116 
00117   // activity of points
00118   inline int Max_Level() const { return grid->Max_level(); }
00119 
00120   inline Grid* Give_grid() const {
00121     if(developer_version) {
00122       if(grid==NULL) cout << "\n Variable is not initialized! Error!" << endl;
00123     }
00124     return grid;
00125   }
00126 
00127   // for assign
00128   template<class A>
00129     //  void operator=(const CellExpr<A>& a_);
00130   void operator=(const Cell_Variable &v);
00131   void operator=(double (*Formula)(double x,double y,double z));
00132   void operator=(double x);
00133   void operator=(Input_data_object& input_object);
00134   template<class A>
00135   void operator=(const CoExpr<A>& a_);
00136   template<class A>
00137   void operator=(const DExpr<A>& a_);
00138 
00139   // for Parallelization
00140   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00141     const {  };
00142 };
00143 
00144 /* DExprVAR for Variable */
00145 
00146 class CoExprVAR {
00147  private:
00148   // Aktive Punkte:
00149   int  level;        // level:
00150 
00151   // Nummer der Variablen
00152   int number_cell_variable;
00153  public:
00154   CoExprVAR(const Cell_Variable& vec) {
00155     level      = vec.Level();
00156     number_cell_variable =  vec.Number_cell_variable();
00157   }
00158   // for evaluate on cell
00159   double Give_interior_cell(const P_interior_cell* it_icell ,
00160                             const Grid* gr, int l) const {
00161     return it_icell->varM(gr)[number_cell_variable];
00162   };
00163   double Give_bo_tet(const P_boundary_tet* it_bcell, 
00164                       const Grid* gr) const {
00165     return it_bcell->varM(gr)[number_cell_variable];
00166   };
00167 
00168   // activity of points
00169   int Level() const { return level; }
00170   Dominace_label Dominant_lev() const { return not_dominant; }
00171 
00172   // number of operations
00173   int ops_interior() const { return 0; }
00174 
00175   // for Parallelization
00176   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00177     const {  };
00178 };
00179 
00180 
00181 
00183 // 3.:  double
00185 
00186 
00187 /* DExprLIT for double */
00188 class CoExprLIT {
00189  private:
00190   double value_;
00191  public:
00192   CoExprLIT(double value)
00193     { value_ = value; }
00194   // for evaluate on cell
00195   double Give_interior_cell(const P_interior_cell* it_icell ,
00196                             const Grid* gr, int l) const {
00197     return value_;
00198   };
00199   double Give_bo_tet(const P_boundary_tet* it_bcell, 
00200                       const Grid* gr) const {
00201     return value_;
00202   };
00203 
00204   // activity of points
00205   int Level() const { return 0; }
00206   Dominace_label Dominant_lev() const { return anti_dominant; }
00207 
00208   // number of operations
00209   int ops_interior() const { return 0; }
00210 
00211   // for Parallelization
00212   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00213     const {  };
00214 };
00215 
00216 
00217 
00219 // 4.:  Binary operators
00221 
00222 /* DExprBinOp for Representing a Binary operators */
00223 template<class A, class B, class Op>
00224 class CoExprBinOp {
00225   A a_;
00226   B b_;
00227  public:
00228   CoExprBinOp(const A& a, const B& b)
00229     : a_(a), b_(b)
00230     {}
00231   // for evaluate on cell
00232   double Give_interior_cell(const P_interior_cell* it_icell ,
00233                             const Grid* gr, int l) const {
00234     return Op::apply(a_.Give_interior_cell(it_icell,gr ,l),
00235                      b_.Give_interior_cell(it_icell,gr ,l));
00236   };
00237   double Give_bo_tet(const P_boundary_tet* it_bcell, 
00238                       const Grid* gr) const {
00239     return Op::apply(a_.Give_bo_tet(it_bcell,gr),
00240                      b_.Give_bo_tet(it_bcell,gr));
00241   };
00242 
00243   // activity of points
00244   int Level() const { 
00245     if(b_.Dominant_lev()==yes_dominant || a_.Dominant_lev() == anti_dominant)
00246       return b_.Level();
00247     else
00248       if(a_.Dominant_lev()==yes_dominant || b_.Dominant_lev() == anti_dominant)
00249         return a_.Level();
00250     else return MAX(a_.Level(),b_.Level()); 
00251   }
00252   Dominace_label Dominant_lev() const {
00253     return (Dominace_label)(MAX(a_.Dominant_lev(),b_.Dominant_lev()));
00254   }
00255 
00256   // number of operations
00257   int ops_interior() const { return a_.ops_interior()+b_.ops_interior() + 1; }
00258 
00259   // for Parallelization
00260   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00261     const {
00262     a_.Add_variables_for_parallel(evpar);
00263     b_.Add_variables_for_parallel(evpar);
00264   };
00265 };
00266 
00268 // 5.: transfer function
00270 
00271 class CoExprTrans {
00272  private:
00273   // Aktive Punkte:
00274   int  level;        // level:
00275 
00276   // Nummer der Variablen
00277   int number_variable;
00278  public:
00279   CoExprTrans(const Variable& vec) {
00280     level      = vec.Level();
00281     number_variable =  vec.Number_variable();
00282   }
00283   // for evaluate on cell
00284   double Give_interior_cell(const P_interior_cell* it_icell ,
00285                             const Grid* gr, int l) const {
00286     return (it_icell->varENT(gr,l)[number_variable] +
00287             it_icell->varEND(gr,l)[number_variable] +
00288             it_icell->varEST(gr,l)[number_variable] +
00289             it_icell->varESD(gr,l)[number_variable] +
00290             it_icell->varWNT(gr,l)[number_variable] +
00291             it_icell->varWND(gr,l)[number_variable] +
00292             it_icell->varWST(gr,l)[number_variable] +
00293             it_icell->varWSD(gr,l)[number_variable])   * 0.125;
00294   };
00295   double Give_bo_tet(const P_boundary_tet* it_bcell, 
00296                       const Grid* gr) const {
00297     return (it_bcell->var0(gr)[number_variable] +
00298             it_bcell->var1(gr)[number_variable] +
00299             it_bcell->var2(gr)[number_variable] +
00300             it_bcell->var3(gr)[number_variable])       * 0.25;
00301   };
00302 
00303   // activity of points
00304   int Level() const { return level; }
00305   Dominace_label Dominant_lev() const { return not_dominant; }
00306 
00307   // number of operations
00308   int ops_interior() const { return 0; }
00309 
00310   // for Parallelization
00311   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00312     const {
00313     evpar->Variable_contained_in_expression(number_variable);
00314   };
00315 };
00316 
00317 CoExpr<CoExprTrans> Cell_Interpolation(const Variable& vec);
00318 
00320 // 6.: Some functions
00322 
00323 void Print_UCD(Cell_Variable& a,ofstream *Datei);
00324 void Print_UCD_moved(Cell_Variable& v,
00325                      Variable& a, Variable& b, Variable& c, ofstream *Datei);
00326 void Print_UCD_parallel(Cell_Variable& a,ofstream *Datei);
00327 
00328 double Maximum(Cell_Variable& a);
00329 double Minimum(Cell_Variable& a);
00330 double L_infty(Cell_Variable& a);
00331 
00332 // ------------------------------------------------------------
00333 //  implementierung of the inline member functions of cell variable
00334 // ------------------------------------------------------------
00335 
00336 inline Cell_Variable::Cell_Variable(Grid* gridp) {
00337   grid = gridp;
00338   number_cell_variable = grid->Give_number_cell_variable();
00339   // all points of finest level become active
00340   level = gridp->Max_level();
00341   if(gridp->Is_storage_initialized()==true) {
00342     cout << " \n Definition of cell_variable not possible! ";
00343   }
00344 }
00345 
00346 inline void Cell_Variable::Level_up()   { 
00347   level++; 
00348 }
00349 inline void Cell_Variable::Level_down() { 
00350   level--; 
00351 }
00352 inline void Cell_Variable::Active_Level(int Level) { 
00353   level = Level; 
00354 }
00355 
00356 // for assign; usual
00357 template<class A>
00358 void Cell_Variable::operator=(const CoExpr<A>& a_) {
00359   int lev;
00360   if(grid->I_am_active()) {
00361     Test_init();  // Grid storage initialization
00362   }
00363 
00364   // 1.Step: level
00365   if(a_.Dominant_lev()==anti_dominant) lev = level;
00366   else                                 lev = a_.Level();
00367   if(lev < 0)          { cout << "\n Level too coarse! "   << endl; }
00368   else if (lev > Max_Level())  { cout << "\n Level too fine! " << endl; }
00369   
00370   Active_Level(lev);
00371 
00372   if(grid->I_am_active()) {    
00373     // 2.Step: Evaluation_Parallelization
00374     Evaluation_Parallelization_object* ev_par_obj;
00375 
00376     if(parallel_version) {
00377       ev_par_obj = grid->Give_eval_par();
00378       ev_par_obj->StartA_varcon_evaluation(lev);
00379       a_.Add_variables_for_parallel(ev_par_obj);  // this adds the variables
00380       // for communication
00381       ev_par_obj->StartB_varcon_evaluation();     // makes parallelization
00382     }
00383     // 3.Step: interior_cells
00384     for(iter_ice=grid->Start_P_interior_cell(level);
00385         iter_ice!=NULL;iter_ice=iter_ice->Next()) {
00386       iter_ice->varM(grid)[number_cell_variable] = 
00387         a_.Give_interior_cell(iter_ice,grid, level);
00388     }
00389     // 4.Step: boundary cells
00390     for(iter_bce=grid->Start_P_boundary_tet(level);
00391         iter_bce!=NULL;iter_bce=iter_bce->Next()) {
00392       iter_bce->varM(grid)[number_cell_variable] =
00393         a_.Give_bo_tet(iter_bce,grid);
00394     }
00395   }
00396 }
00397 
00398 // for assign; usual
00399 template<class A>
00400 void Cell_Variable::operator=(const DExpr<A>& a_) {
00401   int lev;
00402   Test_init();  // Grid storage initialization
00403 
00404   // level
00405   if(a_.Dominant_lev()==anti_dominant) lev = level;
00406   else                                 lev = a_.Level();
00407   if(lev < 0)          { cout << "\n Level too coarse! "   << endl; }
00408   else if (lev > Max_Level())  { cout << "\n Level too fine! " << endl; }
00409 
00410   Active_Level(lev);
00411 
00412   // interior_cells
00413   for(iter_ice=grid->Start_P_interior_cell(level);
00414       iter_ice!=NULL;iter_ice=iter_ice->Next()) {
00415     iter_ice->varM(grid)[number_cell_variable] = 
00416       a_.Give_interior_cell(iter_ice,grid, level);
00417   }
00418   // boundary cells
00419   for(iter_bce=grid->Start_P_boundary_tet(level);
00420       iter_bce!=NULL;iter_bce=iter_bce->Next()) {
00421     iter_bce->varM(grid)[number_cell_variable] =
00422       a_.Give_bo_tet(iter_bce,grid);
00423   }
00424 }
00425 
00426 
00427 // ------------------------------------------------------------
00428 //  Addition, Multi, ...
00429 // ------------------------------------------------------------
00430 
00431 
00432 /* Applicative Template classes */
00433 class CoApAdd {
00434  public:
00435   CoApAdd() { }
00436   static inline double apply(double a, double b)
00437     { return a+b; }
00438 };
00439 
00440 
00441 class CoApDivide {
00442  public:
00443   CoApDivide() { }
00444   static inline double apply(double a, double b)
00445     { return a/b; }
00446 };
00447 
00448 
00449 class CoApMul {
00450  public:
00451   CoApMul() { }
00452   static inline double apply(double a, double b)
00453     { return a*b; }
00454 };
00455 
00456 class CoApSub {
00457  public:
00458   CoApSub() { }
00459   static inline double apply(double a, double b)
00460     { return a-b; }
00461 };
00462 
00463 
00464 #define Macro_expressions_for_cells(insertA,insertB) \
00465 template<class A, class B> \
00466 CoExpr<CoExprBinOp<CoExpr<A>, CoExpr<B>, insertA> > \
00467 insertB(const CoExpr<A>& a,const  CoExpr<B>& b) \
00468 { \
00469   typedef CoExprBinOp<CoExpr<A>, CoExpr<B>, insertA> ExprT; \
00470   return CoExpr<ExprT>(ExprT(a,b)); \
00471 } \
00472 CoExpr<CoExprBinOp<CoExprLIT, CoExprVAR, insertA> > \
00473 insertB(double x, Cell_Variable& a); \
00474 template<class A> \
00475 CoExpr<CoExprBinOp<CoExprLIT, CoExpr<A>, insertA> > \
00476 insertB(double x,const  CoExpr<A>& a) \
00477 { \
00478   typedef CoExprBinOp<CoExprLIT, CoExpr<A>, insertA> ExprT; \
00479   return CoExpr<ExprT>(ExprT(CoExprLIT(x),a)); \
00480 } \
00481 template<class A> \
00482 CoExpr<CoExprBinOp<CoExpr<A>, CoExprLIT, insertA> > \
00483 insertB(const   CoExpr<A>& a, double x) \
00484 { \
00485   typedef CoExprBinOp<CoExpr<A>, CoExprLIT, insertA> ExprT; \
00486   return CoExpr<ExprT>(ExprT(a,CoExprLIT(x))); \
00487 } \
00488 template<class A> \
00489 CoExpr<CoExprBinOp<CoExprVAR, CoExpr<A>, insertA> > \
00490 insertB(  Cell_Variable& v,const  CoExpr<A>& a) \
00491 { \
00492   typedef CoExprBinOp<CoExprVAR, CoExpr<A>, insertA> ExprT; \
00493   return CoExpr<ExprT>(ExprT(CoExprVAR(v),a)); \
00494 } \
00495 template<class A> \
00496 CoExpr<CoExprBinOp<CoExpr<A>, CoExprVAR, insertA> > \
00497 insertB(const  CoExpr<A>& a, Cell_Variable& v) \
00498 { \
00499   typedef CoExprBinOp<CoExpr<A>, CoExprVAR, insertA> ExprT; \
00500   return CoExpr<ExprT>(ExprT(a,CoExprVAR(v))); \
00501 } \
00502 CoExpr<CoExprBinOp<CoExprVAR, CoExprLIT, insertA> > \
00503 insertB(Cell_Variable& a,double x); \
00504 CoExpr<CoExprBinOp<CoExprVAR, CoExprVAR, insertA> > \
00505 insertB(Cell_Variable& b, Cell_Variable& a); \
00506 template<class A, class B> \
00507 CoExpr<CoExprBinOp<DExpr<A>, CoExpr<B>, insertA> > \
00508 insertB(const DExpr<A>& a,const  CoExpr<B>& b) \
00509 { \
00510   typedef CoExprBinOp<DExpr<A>, CoExpr<B>, insertA> ExprT; \
00511   return CoExpr<ExprT>(ExprT(a,b)); \
00512 } \
00513 template<class A, class B> \
00514 CoExpr<CoExprBinOp<CoExpr<A>, DExpr<B>, insertA> > \
00515 insertB(const CoExpr<A>& a,const  DExpr<B>& b) \
00516 { \
00517   typedef CoExprBinOp<CoExpr<A>, DExpr<B>, insertA> ExprT; \
00518   return CoExpr<ExprT>(ExprT(a,b)); \
00519 } \
00520 template<class A> \
00521 CoExpr<CoExprBinOp<CoExprVAR, DExpr<A>, insertA> > \
00522 insertB(  Cell_Variable& v,const  DExpr<A>& a) \
00523 { \
00524   typedef CoExprBinOp<CoExprVAR, DExpr<A>, insertA> ExprT; \
00525   return CoExpr<ExprT>(ExprT(CoExprVAR(v),a)); \
00526 } \
00527 template<class A> \
00528 CoExpr<CoExprBinOp<DExpr<A>, CoExprVAR, insertA> > \
00529 insertB(const  DExpr<A>& a, Cell_Variable& v) \
00530 { \
00531   typedef CoExprBinOp<DExpr<A>, CoExprVAR, insertA> ExprT; \
00532   return CoExpr<ExprT>(ExprT(a,CoExprVAR(v))); \
00533 }
00534 
00535 
00536 
00537 Macro_expressions_for_cells(CoApMul,operator*)
00538 Macro_expressions_for_cells(CoApAdd,operator+)
00539 Macro_expressions_for_cells(CoApDivide,operator/)
00540 Macro_expressions_for_cells(CoApSub,operator-)
00541 
00542 #endif
00543               

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