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

src/expde/extemp/opera.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 OPERA_H_
00018 #define OPERA_H_
00019   
00020 #include "grid/SSten.h"
00021         
00022 // ------------------------------------------------------------
00023 // operator.h
00024 //
00025 // ------------------------------------------------------------
00026 
00027 // Remark: this file uses the formulas in source/formulas/diffopc.h
00028 
00030 //   Constant coefficient Differential operators
00032 
00033  
00034 // a.: Operator
00036 
00037 
00038 
00039 
00040 /* DExprDiff_15S_Op for Differential operators */
00041 template<class V, class DiffOp>
00042 class DVarDiff_15S_Op {
00043   V v_;
00044   double *Stencil;      // stencil independent of meshsize
00045 
00046  public:
00047   // Constructor for concrete operators
00048   DVarDiff_15S_Op(const V& v)
00049     : v_(v) {
00050     DiffOp opp;
00051     if(opp.typ_u()==Poisson_type ||
00052        opp.typ_v()==Poisson_type) 
00053       Stencil = v.Give_grid()->Give_Loc_stencil_Poisson();
00054     else {
00055       Stencil = v.Give_grid()->Give_Loc_stencil(opp.typ_u(),opp.typ_v());
00056     }
00057   }
00058   DVarDiff_15S_Op(const DExpr<V>& v)
00059     : v_(v) {
00060     DiffOp opp;
00061     if(opp.typ_u()==Poisson_type ||
00062        opp.typ_v()==Poisson_type) 
00063       Stencil = v.Give_grid()->Give_Loc_stencil_Poisson();
00064     else {
00065       Stencil = v.Give_grid()->Give_Loc_stencil(opp.typ_u(),opp.typ_v());
00066     }
00067   }
00068   double Give_interior(const P_interior* it_i, const Grid* grid, double h_mesh,
00069                        int lev, double_stencils_in) const {
00070     return Give_interior_here(it_i,grid,h_mesh,lev, double_stencils_out);
00071   }
00072   double Give_interior_coarse(const P_interior* it_i, const Grid* grid,
00073                               double h_mesh,
00074                               int lev, double_stencils_in) const {
00075     return Give_interior_here(it_i,grid,h_mesh,lev, double_stencils_out);
00076   }
00077   double Give_interior_here(const P_interior* it_i, const Grid* gr,
00078                             double h_mesh,
00079                             int l, double_stencils_in) const {
00080    return DiffOp::stencil(LuN[v_.Number_variable()],
00081                           LuW[v_.Number_variable()],
00082                           LuM[v_.Number_variable()],
00083                           LuE[v_.Number_variable()],
00084                           LuS[v_.Number_variable()],
00085                           LuT[v_.Number_variable()],
00086                           LuD[v_.Number_variable()],
00087                           LuND[v_.Number_variable()],
00088                           LuWN[v_.Number_variable()],
00089                           LuWT[v_.Number_variable()],
00090                           LuED[v_.Number_variable()],
00091                           LuST[v_.Number_variable()],
00092                           LuES[v_.Number_variable()],
00093                           LuEST[v_.Number_variable()],
00094                           LuWND[v_.Number_variable()],
00095                           h_mesh);
00096   };
00097   double Give_nearb(const P_nearb* it_n, const Grid* gr, double h_mesh, int l,
00098                     const Nearb_Ablage* nearb_ablage) const {
00099     static int i;
00100     static BoCeData* bocedata;
00101     static Celltype cetyp;
00102     static double sum;
00103     static int num_v;
00104     dir_sons dir_v;
00105 
00106     sum = 0.0;
00107 
00108     for(i=0;i<8;++i) {    // Durchlaufen aller Nachbarzellen
00109       dir_v = opposite3D((dir_sons)i);
00110       // Hole Info ueber i-Randzelle
00111       cetyp = nearb_ablage->Give_Celltyp((dir_sons)i);
00112 
00113       if(cetyp==fine_bo_cell) {
00114         bocedata = nearb_ablage->Give_BoData((dir_sons)i);
00115         // Berechnung der Nummer der Testfunktion auf i-Randzelle
00116         for(num_v=0;(!(bocedata->corner(num_v)==dir_v)) ||
00117               bocedata->edge_point(num_v);) { ++num_v; }
00118         // Auswertung
00119         sum = sum + DiffOp::F_bo_cell(bocedata,num_v,v_.Number_variable());
00120       }
00121       else if(cetyp==int_cell) {
00122         sum = sum +
00123           DiffOp::F_reg_cell(nearb_ablage->Give_u_Recell((dir_sons)i),
00124                              v_.Number_variable(),
00125                              dir_v,h_mesh,Stencil);
00126         //      if(now) cout << " sum r " << sum << endl;
00127       }
00128     }
00129     return sum;
00130   };
00131   double Give_cellpoi(const P_cellpoi* it_cf, const Grid* gr,
00132                       const BoCeData* bocedata) const {
00133     // Auswertung 
00134     return DiffOp::F_bo_cell(bocedata,bocedata->Give_number_points(),
00135                              v_.Number_variable());
00136   };
00137   double Give_Bo2p(const P_Bo2p* it_b, const Grid* gr,int l)  const {
00138     static int i;
00139     static BoCeData* bocedata;
00140     static double sum;
00141     static int num_v;
00142     dir_sons dir_v;
00143     bool stop;
00144 
00145 
00146     // return 0.0;
00147 
00148    sum = 0.0;
00149     for(i=0;i<8;++i) {    // Durchlaufen aller Nachbarzellen
00150       dir_v = opposite3D((dir_sons)i);
00151       // Info ueber i-Randzelle
00152       bocedata = it_b->Give_BoData((dir_sons)i); 
00153       if(bocedata!=NULL) {
00154 
00155         // Berechnung der Nummer der Testfunktion auf i-Randzelle
00156         stop = false;
00157         for(num_v=0;!stop && bocedata->Give_number_points() > num_v;) {
00158           stop = bocedata->corner(num_v)   == dir_v      &&
00159                  bocedata->edge_dir(num_v) == it_b->d()  &&
00160                  bocedata->edge_point(num_v);
00161           if(!stop) ++num_v;
00162         }
00163 
00164         if(bocedata->Give_number_points() > num_v) {
00165           // Auswertung
00166             sum = sum + 
00167               DiffOp::F_bo_cell(bocedata,num_v,v_.Number_variable());
00168         }
00169       }
00170     }
00171 
00172     return sum;
00173   };
00174   // Size of necessary stencil
00175   int Sice_stencil() const { return 15; }
00176 
00177   // activity of points
00178   int Level() const { return (v_).Level(); }
00179   Dominace_label Dominant_lev() const { return not_dominant; }
00180   Dominace_label Dominant_poi() const { return not_dominant; }
00181   bool run_interior() const { return (v_).run_interior(); }
00182   bool run_nearb()    const { return (v_).run_nearb(); }
00183   int run_boundary() const { return (v_).run_boundary(); }
00184 
00185   // number of operations
00186   int ops_interior() const { return DiffOp::ops_interior(); }
00187 
00188   // For operator ==
00189   void Active_Sim_Level( int lev) const {  };
00190   void Active_Sim_interior(bool run) const {  };
00191   void Active_Sim_nearb(bool run) const {  };
00192   void Active_Sim_boundary( int run) const {  };
00193   void Active_Sim_update(Evaluation_Parallelization_object* evpar,
00194                          int level, type_of_update typ) const {  };
00195 
00196   // Put pointer to grid and activity of boundary points of test space  
00197   void Put_grid_rbo(const Grid* gr, int r_bo) const {}; 
00198 
00199 
00200   // For abstract differential operators:
00201   // --------------------------------------
00202   // Is the expression an abstract differential operator?
00203   Differential_op_typ Abstract_differential_operator() const
00204     { return abstract_with_var; }
00205   int Give_number_var_of_abstract_op() const { 
00206     return v_.Number_variable_start();
00207   }
00208   bool Give_array_variable_inserted() const {
00209     return v_.Give_array_variable_inserted();
00210   }
00211   int Give_length_of_array_variable_inserted() const {
00212     return v_.Give_length_of_array_variable_inserted();
00213   }
00214   // For restriction of stencils
00215   // --------------------------------------
00216   double Give_interior_sten_element(Index3D I, double meshsize,
00217                                     int stelle,
00218                                     const Grid* grid, int level) const {
00219     return Stencil[stelle] * DiffOp::Factor_reg_cell(meshsize);
00220   }
00221   double Give_boundary_sten_element(const Grid* grid, BoCeData* b_cell,
00222                                     double* u_ablage, int num_v) const {
00223     return DiffOp::Local_matrix_bo_cell(b_cell,u_ablage,num_v);
00224   }
00225 
00226   // for Parallelization
00227   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar)
00228     const {
00229     evpar->Variable_contained_in_expression(v_.Number_variable());
00230   }
00231   bool GS_type(int var_number_left, int dim) const {
00232     if(var_number_left<=v_.Number_variable() &&
00233        var_number_left+dim>=v_.Number_variable())
00234       return true;
00235     return false; 
00236   };
00237 
00238   // at the and of an iteration of an expression
00239   void clean() const { };
00240 };
00241 
00242 
00243 /* Unary operators */
00244 // Laplace
00245 
00246 class DExprVAR_ARR;
00247 
00248 #define Macro_operator_definition(insertA) \
00249 DExpr<DVarDiff_15S_Op<insertA, laplace_FE_const> > \
00250 Laplace_FE(const insertA& a); \
00251 /* DxDx */ \
00252 DExpr<DVarDiff_15S_Op<insertA, dxdx_FE_const> > \
00253 DxDx_FE(insertA a); \
00254 /* Dydy */ \
00255 DExpr<DVarDiff_15S_Op<insertA, dydy_FE_const> > \
00256 DyDy_FE(insertA a); \
00257 /* Dzdz */ \
00258 DExpr<DVarDiff_15S_Op<insertA, dzdz_FE_const> > \
00259 DzDz_FE(insertA a); \
00260 /* Helm */ \
00261 DExpr<DVarDiff_15S_Op<insertA, helm_FE_const> > \
00262 Helm_FE(insertA a); \
00263 /* ///////////////////////// \
00264 // Nichsymmetrische Terme \
00266 /* Dxdy */ \
00267 DExpr<DVarDiff_15S_Op<insertA, dxdy_FE_const> > \
00268 DxDy_FE(insertA a); \
00269 /* Dydx */ \
00270 DExpr<DVarDiff_15S_Op<insertA, dydx_FE_const> > \
00271 DyDx_FE(insertA a); \
00272 /* Dxdz */ \
00273 DExpr<DVarDiff_15S_Op<insertA, dxdz_FE_const> > \
00274 DxDz_FE(insertA a); \
00275 /* Dzdx */ \
00276 DExpr<DVarDiff_15S_Op<insertA, dzdx_FE_const> > \
00277 DzDx_FE(insertA a); \
00278 /* Dydz */ \
00279 DExpr<DVarDiff_15S_Op<insertA, dydz_FE_const> > \
00280 DyDz_FE(insertA a); \
00281 /* Dzdy */ \
00282 DExpr<DVarDiff_15S_Op<insertA, dzdy_FE_const> > \
00283 DzDy_FE(insertA a); \
00284 DExpr<DVarDiff_15S_Op<insertA, dxhelm_FE_const> > \
00285 DX_FE(insertA a); \
00286 DExpr<DVarDiff_15S_Op<insertA, helmdx_FE_const> > \
00287 DX_FE_t(insertA a); \
00288 DExpr<DVarDiff_15S_Op<insertA, dyhelm_FE_const> > \
00289 DY_FE(insertA a); \
00290 DExpr<DVarDiff_15S_Op<insertA, helmdy_FE_const> > \
00291 DY_FE_t(insertA a); \
00292 DExpr<DVarDiff_15S_Op<insertA, dzhelm_FE_const> > \
00293 DZ_FE(insertA a); \
00294 DExpr<DVarDiff_15S_Op<insertA, helmdz_FE_const> > \
00295 DZ_FE_t(insertA a); \
00296 /* ///////////////////////// \
00297 // Rand-operatoren \
00299 DExpr<DVarDiff_15S_Op<insertA, L2boundary_const> > \
00300 Int_boundary(insertA a);
00301 
00302 Macro_operator_definition(Variable)
00303 // other usage of Macro_operator_definition in array.h
00304  
00305 
00306 // b.: Diagonal operator
00308 
00309 
00310 // We need this, since expression is const!
00311 class Storage_for_one_Stencil {
00312   public :
00313     double *Stencil;
00314 };
00315 
00316 
00317 /* DExprDiff_15S_Op for Differential operators */
00318 template<class DiffOp>
00319 class DiagonalDiff_Op {
00320  private:
00321   Grid* grid;
00322   Storage_for_one_Stencil* OS; 
00323  public:
00324   DiagonalDiff_Op()  {
00325     OS = new Storage_for_one_Stencil;
00326   }
00327   double Give_interior(const P_interior* it_i, const Grid* gr, double h_mesh,
00328                        int l, double_stencils_in) const {
00329     return DiffOp::diag_stencil(h_mesh);
00330   };
00331   double Give_interior_coarse(const P_interior* it_i, const Grid* gr,
00332                               double h_mesh,
00333                               int l, double_stencils_in) const {
00334     return DiffOp::diag_stencil(h_mesh);
00335   };
00336   double Give_nearb(const P_nearb* it_n, const Grid* gr, double h_mesh, int l,
00337                     const Nearb_Ablage* nearb_ablage) const {
00338     static int i;
00339     static BoCeData* bocedata;
00340     static double sum;
00341     static Celltype cetyp;
00342     static int num_v;
00343     dir_sons dir_v;
00344 
00345     sum = 0.0;
00346     for(i=0;i<8;++i) {    // Durchlaufen aller Nachbarzellen
00347       dir_v = opposite3D((dir_sons)i);
00348       cetyp = nearb_ablage->Give_Celltyp((dir_sons)i);
00349       if(cetyp==fine_bo_cell) {
00350         // Hole Info ueber i-Randzelle
00351         bocedata = nearb_ablage->Give_BoData((dir_sons)i); 
00352         // Berechnung der Nummer der Testfunktion auf i-Randzelle
00353         for(num_v=0;(!(bocedata->corner(num_v)==dir_v)) ||
00354               bocedata->edge_point(num_v);) { ++num_v; }
00355         // Auswertung
00356         sum = sum + DiffOp::diag_F_bo_cell(bocedata,num_v);     
00357       }
00358       else if(cetyp==int_cell) {
00359         sum = sum +
00360           DiffOp::diag_F_reg_cell(dir_v,h_mesh,OS->Stencil);
00361       }
00362     }
00363     return sum;
00364   };
00365   double Give_cellpoi(const P_cellpoi* it_cf, const Grid* gr,
00366                       const BoCeData* bocedata) const {
00367     // Auswertung 
00368     return DiffOp::diag_F_bo_cell(bocedata,bocedata->Give_number_points());
00369   };
00370   double Give_Bo2p(const P_Bo2p* it_b, const Grid* gr,int l)  const {
00371     static int i;
00372     static BoCeData* bocedata;
00373     static double sum;
00374     static int num_v;
00375     dir_sons dir_v;
00376     bool stop;
00377 
00378     sum = 0.0;
00379     for(i=0;i<8;++i) {    // Durchlaufen aller Nachbarzellen
00380       dir_v = opposite3D((dir_sons)i);
00381       // Info ueber i-Randzelle
00382       //  wegg bo:    bocedata = bo2p_ablage->Give_BoData((dir_sons)i); 
00383       bocedata = it_b->Give_BoData((dir_sons)i); 
00384       if(bocedata!=NULL) {
00385         // Berechnung der Nummer der Testfunktion auf i-Randzelle
00386         stop = false;
00387         for(num_v=0;!stop && bocedata->Give_number_points() > num_v;) {
00388           stop = bocedata->corner(num_v)   == dir_v      &&
00389                  bocedata->edge_dir(num_v) == it_b->d()  &&
00390                  bocedata->edge_point(num_v);
00391           if(!stop) ++num_v;
00392         }
00393 
00394         if(bocedata->Give_number_points() > num_v) {
00395           // Auswertung
00396           sum = sum + 
00397             DiffOp::diag_F_bo_cell(bocedata,num_v);
00398         }
00399       }
00400     }
00401     return sum;
00402   };
00403   // Size of necessary stencil
00404   int Sice_stencil() const { return 15; }
00405 
00406   // activity of points
00407   int Level() const { return 0; }
00408   Dominace_label Dominant_lev() const { return anti_dominant; }
00409   Dominace_label Dominant_poi() const { return anti_dominant; }
00410   bool run_interior() const { return true; }
00411   bool run_nearb()    const { return true; }
00412   int run_boundary() const { return true; }
00413 
00414   // number of operations
00415   int ops_interior() const { return DiffOp::ops_diag_interior(); }
00416 
00417   // For operator ==
00418   void Active_Sim_Level( int lev) const {  };
00419   void Active_Sim_interior(bool run) const {  };
00420   void Active_Sim_nearb(bool run) const {  };
00421   void Active_Sim_boundary( int run) const {  };
00422   void Active_Sim_update(Evaluation_Parallelization_object* evpar,
00423                          int level, type_of_update typ) const {  };
00424 
00425   // Put pointer to grid and activity of boundary points of test space  
00426   void Put_grid_rbo(Grid* gr, int r_bo) const { 
00427     DiffOp opp;
00428     if(opp.typ_u()==Poisson_type ||
00429        opp.typ_v()==Poisson_type) 
00430       OS->Stencil = gr->Give_Loc_stencil_Poisson();
00431     else {
00432       OS->Stencil = gr->Give_Loc_stencil(opp.typ_u(),opp.typ_v());
00433     }
00434   };
00435   // Is the expression an abstract differential operator?
00436   Differential_op_typ Abstract_differential_operator() const
00437     { return abstract_diag; }
00438   int Give_number_var_of_abstract_op() const { return -1; }
00439   // for Parallelization
00440   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar)
00441     const {};
00442   bool GS_type(int var_number_left, int dim) const {
00443     return false; 
00444   }; 
00445   // at the and of an iteration of an expression
00446   void clean() const { delete(OS); };
00447 };
00448 
00449 
00450 /* Unary operators */
00451 
00452 // Laplace
00453 DExpr<DiagonalDiff_Op<laplace_FE_const> >
00454 Diag_Laplace_FE();
00455 
00456 // DxDx
00457 DExpr<DiagonalDiff_Op<dxdx_FE_const> >
00458 Diag_DxDx_FE();
00459 
00460 // DyDy
00461 DExpr<DiagonalDiff_Op<dydy_FE_const> >
00462 Diag_DyDy_FE();
00463 
00464 // DzDz
00465 DExpr<DiagonalDiff_Op<dzdz_FE_const> >
00466 Diag_DzDz_FE();
00467 
00468 // Helm
00469 DExpr<DiagonalDiff_Op<helm_FE_const> >
00470 Diag_Helm_FE();
00471 
00473 // Nichsymmetrische Terme
00475 
00476 // DxDy
00477 DExpr<DiagonalDiff_Op<dxdy_FE_const> >
00478 Diag_DxDy_FE();
00479 
00480 // DyDx
00481 DExpr<DiagonalDiff_Op<dydx_FE_const> >
00482 Diag_DyDx_FE();
00483 
00484 // DxDz
00485 DExpr<DiagonalDiff_Op<dxdz_FE_const> >
00486 Diag_DxDz_FE();
00487 
00488 // DzDx
00489 DExpr<DiagonalDiff_Op<dzdx_FE_const> >
00490 Diag_DzDx_FE();
00491 
00492 // DyDz
00493 DExpr<DiagonalDiff_Op<dydz_FE_const> >
00494 Diag_DyDz_FE();
00495 
00496 // DzDy
00497 DExpr<DiagonalDiff_Op<dzdy_FE_const> >
00498 Diag_DzDy_FE();
00499 
00500 // DX
00501 DExpr<DiagonalDiff_Op<dxhelm_FE_const> >
00502 Diag_DX_FE();
00503 
00504 // DX transpose
00505 DExpr<DiagonalDiff_Op<helmdx_FE_const> >
00506 Diag_DX_FE_t();
00507 
00508 // DY
00509 DExpr<DiagonalDiff_Op<dyhelm_FE_const> >
00510 Diag_DY_FE();
00511 
00512 // DY transpose
00513 DExpr<DiagonalDiff_Op<helmdy_FE_const> >
00514 Diag_DY_FE_t();
00515 
00516 // DZ
00517 DExpr<DiagonalDiff_Op<dzhelm_FE_const> >
00518 Diag_DZ_FE();
00519 
00520 // DZ transpose
00521 DExpr<DiagonalDiff_Op<helmdz_FE_const> >
00522 Diag_DZ_FE_t();
00523 
00524 
00526 // Rand-operatoren
00528 
00529 DExpr<DiagonalDiff_Op<L2boundary_const> >
00530 Diag_Int_boundary();
00531 
00532 #endif
00533         

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