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

src/expde/extemp/res_op.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 // res_op.h
00019 //
00020 // ------------------------------------------------------------
00021 
00022 #ifndef RESOP_H_
00023 #define RESOP_H_
00024          
00025 #include "grid/SSten.h"
00026 
00028 //   Operators with stencils near the boundary
00030 
00031 class Res_stencil_boundary;
00032 
00033 
00034 // a) Abstract operator with variable
00035 //-------------------------------------------------
00036 template<class A>
00037 class DResDiff_Bo {
00038   A a_;
00039 
00040   //number of storage for boundary stencils
00041   int num_stencils;
00042 
00043   // information about the variable put in the abstract diff. operator
00044   int number_variable;  // number of the variable
00045   int r_bou;            // boundary conditions of the variable 
00046                         // (activity of the boundary points)
00047   bool* label_on_cell;
00048 
00049   // Gitter
00050   Grid *grid;
00051 
00052   // needed for the calculation of local stiffness matrix
00053   double** Stencils_fine;  // eight stencils for finer cells
00054   double* u_ablage; // Ablage
00055   bool question_calc_stencil;
00056   bool *corner_in_domain;
00057 
00058  public:
00059   // Constructor for concrete operators
00060   DResDiff_Bo(const A& a, int num_s, Grid* gr, bool isRestricted);
00061   void Iterate_Calc_stencil(int r_bo) const;
00062 
00063   double Give_interior(const P_interior* it_i, const Grid* gr, double h_mesh,
00064                        int l, double_stencils_in) const {
00065     return a_.Give_interior(it_i,gr,h_mesh,l, double_stencils_out);
00066   };
00067   double Give_interior_coarse(const P_interior* it_i, const Grid* gr,
00068                               double h_mesh,
00069                               int l, double_stencils_in) const {
00070     return a_.Give_interior_coarse(it_i,gr,h_mesh,l, double_stencils_out);
00071   };
00072   double Give_nearb(const P_nearb* it_n, const Grid* gr, double h_mesh, int l,
00073                     const Nearb_Ablage* nearb_ablage) const {
00074     static int i;
00075     static Celltype cetyp;
00076     static double sum;
00077     dir_sons dir_v;
00078 
00079     // Part 1: interior cells and boundary cells on the finest grid
00080     sum = a_.Give_nearb(it_n,gr,h_mesh,l,nearb_ablage);
00081 
00082     // Part 2: boundary cells on coarser grid
00083     for(i=0;i<8;++i) {    // Durchlaufen aller Nachbarzellen
00084       dir_v = opposite3D((dir_sons)i);
00085       // Hole Info ueber i-Randzelle
00086       cetyp = nearb_ablage->Give_Celltyp((dir_sons)i);
00087       if(cetyp==bo_cell) {
00088         sum = sum +
00089           Evaluate_lsm(nearb_ablage->Give_u_Recell((dir_sons)i),
00090                        number_variable, dir_v,
00091                        gr->Give_bo_stencil(it_n->Ind().next((dir_sons)i,l+1),
00092                                            num_stencils));
00093       }
00094     }    
00095     return sum;
00096   };
00097   double Give_cellpoi(const P_cellpoi* it_cf, const Grid* gr,
00098                       const BoCeData* bocedata) const {
00099     return a_.Give_cellpoi(it_cf,gr,bocedata);
00100   };
00101   double Give_Bo2p(const P_Bo2p* it_b, const Grid* gr,int l)  const {
00102     return a_.Give_Bo2p(it_b,gr,l);
00103   };
00104   // Size of necessary stencil
00105   int Sice_stencil() const { return a_.Sice_stencil(); }
00106 
00107   // activity of points
00108   int Level() const { return (a_).Level(); }
00109   Dominace_label Dominant_lev() const { return not_dominant; }
00110   Dominace_label Dominant_poi() const { return not_dominant; }
00111   bool run_interior() const { return (a_).run_interior(); }
00112   bool run_nearb()    const { return (a_).run_nearb(); }
00113   int run_boundary() const { return (a_).run_boundary(); }
00114 
00115   // number of operations
00116   int ops_interior() const { return a_.ops_interior(); }
00117 
00118   // For operator ==
00119   void Active_Sim_Level( int lev) const {  };
00120   void Active_Sim_interior(bool run) const {  };
00121   void Active_Sim_nearb(bool run) const {  };
00122   void Active_Sim_boundary( int run) const {  };
00123   void Active_Sim_update(Evaluation_Parallelization_object* evpar,
00124                          int level, type_of_update typ) const {  };
00125 
00126   // Put pointer to grid and activity of boundary points of test space  
00127   void Put_grid_rbo(Grid* gr, int r_bo) const;
00128   // For abstract differential operators:
00129   // --------------------------------------
00130   // Is the expression an abstract differential operator?
00131   Differential_op_typ Abstract_differential_operator() const
00132     { return not_abstract; }
00133   // for Parallelization
00134   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar)
00135     const {
00136     a_.Add_variables_for_parallel(evpar);
00137   };
00138   bool GS_type(int var_number_left, int dim) const {
00139     return a_.GS_type(var_number_left,dim); 
00140   };
00141   // at the and of an iteration of an expression
00142   void clean() const { a_.clean(); };
00143 };
00144 
00145 // b) Diagonal abstract operator
00146 //-------------------------------------------------
00147 template<class A>
00148 class DResDiagDiff_Bo {
00149   A a_;
00150 
00151   //number of storage for boundary stencils
00152   int num_stencils;
00153 
00154   // Gitter
00155   Grid *grid;
00156   
00157   // Corresponding object for the stancils
00158   Res_stencil_boundary *ResS;
00159 
00160  public:
00161   // Constructor for concrete operators
00162   DResDiagDiff_Bo(const A& a, int num_s, Grid* gr, Res_stencil_boundary *resS) 
00163     : a_(a), num_stencils(num_s), grid(gr), ResS(resS) { }
00164   double Give_interior(const P_interior* it_i, const Grid* gr, double h_mesh,
00165                        int l, double_stencils_in) const {
00166     return a_.Give_interior(it_i,gr,h_mesh,l, double_stencils_out);
00167   };
00168   double Give_interior_coarse(const P_interior* it_i, const Grid* gr,
00169                               double h_mesh,
00170                               int l, double_stencils_in) const {
00171     return a_.Give_interior_coarse(it_i,gr,h_mesh,l, double_stencils_out);
00172   };
00173   double Give_nearb(const P_nearb* it_n, const Grid* gr, double h_mesh, int l,
00174                     const Nearb_Ablage* nearb_ablage) const {
00175     static int i;
00176     static Celltype cetyp;
00177     static double sum;
00178     dir_sons dir_v;
00179     sum = a_.Give_nearb(it_n,gr,h_mesh,l,nearb_ablage);
00180 
00181     for(i=0;i<8;++i) {    // Durchlaufen aller Nachbarzellen
00182       dir_v = opposite3D((dir_sons)i);
00183       // Hole Info ueber i-Randzelle
00184       cetyp = nearb_ablage->Give_Celltyp((dir_sons)i);
00185       if(cetyp==bo_cell) {
00186         sum = sum + gr->Give_bo_stencil(it_n->Ind().next((dir_sons)i,l+1),
00187                                         num_stencils)[9*dir_v];
00188       }
00189     }
00190 
00191     return sum;
00192   };
00193   double Give_cellpoi(const P_cellpoi* it_cf, const Grid* gr,
00194                       const BoCeData* bocedata) const {
00195     return a_.Give_cellpoi(it_cf,gr,bocedata);
00196   };
00197   double Give_Bo2p(const P_Bo2p* it_b, const Grid* gr,int l)  const {
00198     return a_.Give_Bo2p(it_b,gr,l);
00199   };
00200   // Size of necessary stencil
00201   int Sice_stencil() const { return a_.Sice_stencil(); }
00202 
00203   // activity of points
00204   int Level() const { return 0; }
00205   Dominace_label Dominant_lev() const { return anti_dominant; }
00206   Dominace_label Dominant_poi() const { return anti_dominant; }
00207   bool run_interior() const { return true; } 
00208   bool run_nearb()    const { return true; }
00209   int run_boundary() const { return true; }
00210 
00211   // number of operations
00212   int ops_interior() const { return a_.ops_interior(); }
00213 
00214   // For operator ==
00215   void Active_Sim_Level( int lev) const {  };
00216   void Active_Sim_interior(bool run) const {  };
00217   void Active_Sim_nearb(bool run) const {  };
00218   void Active_Sim_boundary( int run) const {  };
00219   void Active_Sim_update(Evaluation_Parallelization_object* evpar,
00220                          int level, type_of_update typ) const {  };
00221 
00222   // Put pointer to grid and activity of boundary points of test space  
00223   void Put_grid_rbo(Grid* gr, int r_bo) const ;    // ada: implementation further down in order to make gcc 3.4.3 happy
00224 
00225   // For abstract differential operators:
00226   // --------------------------------------
00227   // Is the expression an abstract differential operator?
00228   Differential_op_typ Abstract_differential_operator() const
00229     { return not_abstract; }
00230   // for Parallelization
00231   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00232     const {
00233     a_.Add_variables_for_parallel(evpar);
00234   };
00235   bool GS_type(int var_number_left, int dim) const {
00236     return a_.GS_type(var_number_left,dim); 
00237   };
00238   // at the and of an iteration of an expression
00239   void clean() const { a_.clean(); };
00240 };
00241 
00242 
00243 class Array_Res_stencil_boundary;
00244 class Res_stencil_boundary {
00245   friend class Array_Res_stencil_boundary;
00246  private:
00247   // is stencil already used?
00248   // this has to be changed later!
00249   bool used;
00250 
00251   // Gitter
00252   Grid *grid;
00253 
00254   //number of storage for boundary stencils
00255   int num_stencils;
00256 
00257   Res_stencil_boundary() : grid(NULL) {};
00258   void Initialize(Grid* gr)  {
00259     grid = gr;
00260     used = false;
00261     num_stencils = gr->Give_number_bo_stencil();
00262 
00263     if(gr->Is_storage_initialized()==true) {
00264       cout << " \n Definition of Res_stencil_boundary not possible! ";
00265       cout << " \n Define Res_stencil_boundary before ";
00266       cout << " initialization of the grid! " << endl;
00267     }
00268   }
00269  public:
00270   Res_stencil_boundary(Grid* gr) {
00271     Initialize(gr);
00272   }
00273   
00274   bool Give_used() { return used;  }
00275   void clear()     { used = false; }
00276 
00277   void Calc_stencil(int r_bo);
00278 
00279   template<class A>
00280   DExpr<DResDiff_Bo<DExpr<A> > > 
00281   operator() (const DExpr<A>& a_) {
00282     Differential_op_typ a_abstract;
00283     a_abstract = a_.Abstract_differential_operator();
00284     if(a_abstract==not_abstract) {
00285       cout << " This is not an abstract differential operator! Error!" << endl;
00286     }
00287     if(a_abstract==abstract_diag)
00288       cout<<"\n Please use operator [] instead of operator ()! Error!" << endl;
00289 
00290     typedef DResDiff_Bo<DExpr<A> > ExprT;
00291     if(used==false) { // restrict stencil
00292       used = true;
00293       return DExpr<ExprT>(ExprT(a_,num_stencils,grid,true));
00294     }
00295     else              // restrict stencil not necessary
00296       return DExpr<ExprT>(ExprT(a_,num_stencils,grid,false));
00297   }
00298 
00299 
00300   template<class A>
00301   DExpr<DResDiagDiff_Bo<DExpr<A> > > 
00302   operator[] (const DExpr<A>& a_) {
00303     Differential_op_typ a_abstract;
00304     a_abstract = a_.Abstract_differential_operator();
00305     if(a_abstract==not_abstract) {
00306       cout << " This is not an abstract differential operator! Error!" << endl;
00307     }
00308     if(a_abstract==abstract_with_var)
00309       cout<<"\n Please use operator () instead of operator []! Error!" << endl;
00310     typedef DResDiagDiff_Bo<DExpr<A> > ExprT;
00311     return DExpr<ExprT>(ExprT(a_,num_stencils,grid,this));
00312   }
00313 };
00314 
00315 
00317 // Implementation of some member functions
00319 
00320 template<class A>
00321 void DResDiagDiff_Bo<A>::Put_grid_rbo(Grid* gr, int r_bo) const {
00322   a_.Put_grid_rbo(gr,r_bo);
00323   if(ResS->Give_used()==false) {
00324     cout << "\n An abstract diagonal differential operator without";
00325     cout << "\n a variable cannot be restricted! Error! " << endl;
00326   }
00327 }
00328 
00329 
00330 
00331 template<class A>
00332 DResDiff_Bo<A>::DResDiff_Bo(const A& a, int num_s, Grid* gr, bool isRestricted)
00333   : a_(a), num_stencils(num_s), grid(gr) {
00334 
00335   number_variable = a_.Give_number_var_of_abstract_op();
00336   r_bou           = a_.run_boundary();
00337 
00338   if(isRestricted) {
00339     Stencils_fine = gr->Give_Stencils_fine();
00340     u_ablage = gr->Give_vector_ablage();
00341     label_on_cell = gr->Give_label_on_cell_ablage();
00342     corner_in_domain = gr->Give_eight_bools();
00343 
00344     question_calc_stencil = true;
00345   }
00346   else {
00347     question_calc_stencil = false;
00348   }
00349 }
00350 
00351 template<class A>
00352 void DResDiff_Bo<A>::Put_grid_rbo(Grid* gr, int r_bov) const {
00353   a_.Put_grid_rbo(gr,r_bov);
00354 
00355   if(question_calc_stencil == true) {
00356     DResDiff_Bo<A>::Iterate_Calc_stencil(r_bov);
00357   }
00358 };
00359 
00360 
00361 template<class A>
00362 void DResDiff_Bo<A>::Iterate_Calc_stencil(int r_bov) const {
00363   int i, j, jj, level, lev;
00364   Celltype ce_typ;
00365   Index3D I_son, I_ecke;
00366   BoCell* b_cell;
00367   int num_v, num_u, dir_u;
00368   double* sp;
00369   double* Stencil_coarse;
00370   double mesh_size;
00371   double finest_mesh_size;
00372   double a,b, ss, hh;
00373   double weight_bocellpoint[8];
00374   dir_3D d;
00375   Index3D my_lev_index;
00376   D3vector Co;
00377   bool u_in_space, uu_in_space, v_in_space;
00378   bool cell_point_in_space;
00379   Pointtype type;
00380   int *coarse_grid_functions;
00381 
00382   Index3D I;
00383 
00384   coarse_grid_functions = grid->Give_coarse_grid_functions();
00385 
00386   // for iteration
00387   int i_iter, hashtable0_leng;
00388   Point_hashtable0* point0;
00389   Point_hashtable0** hashtable0_start;  //Zeiger auf Tabelle
00390   hashtable0_leng  = grid->Give_hashtable0_leng();
00391   hashtable0_start = grid->Give_hashtable0_start();
00392 
00393 
00394   // Remark: By recursion cell type of I is: bo_cell
00395 
00396   // I. First step: cells on one level under finest level
00397   finest_mesh_size = grid->Give_finest_mesh_size();
00398   level=grid->Max_level();
00399   Iterate_hash0 {
00400    // a) search for boundary cells    
00401    I = point0->Give_Index();
00402    if(I.Cell_index()) {
00403     lev = I.Tiefe();
00404     if(point0->Give_cell_typ()==bo_cell && lev == level) {
00405       // b) Get the finer stencils
00406       // mesh_size = grid->H_mesh() / Zweipotenz(I.Tiefe()+1);
00407       mesh_size = grid->H_mesh() / Zweipotenz(I.Tiefe());
00408       for(i=0;i<8;++i) {
00409         // iterate 8 finer cells
00410         I_son = I.son((dir_sons)i);
00411         ce_typ = grid->Give_cell_typ(I_son);
00412         if(ce_typ==int_cell) {
00413           // if int_cell
00414           for(j=0;j<64;++j)
00415             Stencils_fine[i][j]
00416               = a_.Give_interior_sten_element(I_son,mesh_size,j,
00417                                               grid,I.Tiefe());
00418         }
00419         else if(ce_typ==fine_bo_cell) {
00420           // if fine_bo_cell
00421           // first: 1): set zero
00422           for(j=0;j<64;++j) Stencils_fine[i][j] = 0.0;
00423 
00424           // second: 2): set bocell
00425           b_cell = grid->Give_Bo_cell(I_son);
00426           
00427           // third: 3): calc weights for bocellpoint
00428           if(b_cell->Exists_bocellpoint()) {
00429             Co = b_cell->Coord_bocellpoint_normal();
00430             weight_bocellpoint[WSDd] = 
00431               (1.0 - Co.x) * (1.0 - Co.y) * (1.0 - Co.z);
00432             weight_bocellpoint[ESDd] =
00433               Co.x  * (1.0 - Co.y) * (1.0 - Co.z);
00434             weight_bocellpoint[WNDd] = 
00435               (1.0 - Co.x) *         Co.y * (1.0 - Co.z);
00436             weight_bocellpoint[ENDd] =
00437               Co.x  *         Co.y * (1.0 - Co.z);
00438             weight_bocellpoint[WSTd] = 
00439               (1.0 - Co.x) * (1.0 - Co.y) *        Co.z; 
00440             weight_bocellpoint[ESTd] =
00441               Co.x  * (1.0 - Co.y) *        Co.z; 
00442             weight_bocellpoint[WNTd] =
00443               (1.0 - Co.x) *         Co.y *        Co.z; 
00444             weight_bocellpoint[ENTd] =
00445               Co.x  *         Co.y *        Co.z;
00446           }
00447 
00448           // forth: 4): calculate local stiffness matrix
00449           for(dir_u=0;dir_u<8;++dir_u) { // iter. on u
00450             if(r_bou==1) {
00451               // case pure Neumann for u
00452               u_in_space = true;
00453             }
00454             else if(r_bou==0) {
00455               // case pure Dirichlet for u
00456               u_in_space = false;
00457             }
00458             else {
00459               // case mixed for u
00460               I_ecke = I_son.neighbour((dir_sons)dir_u);
00461               if(grid->Give_global_type(I_ecke)==multigrid) {
00462                 if(grid->Give_label_bo_D(I_ecke,-r_bou,level))
00463                   u_in_space = false;
00464                 else
00465                   u_in_space = true;
00466               }
00467             }
00468 
00469             for(num_u=0;num_u<b_cell->Give_number_points();++num_u) {
00470               j = b_cell->corner(num_u);
00471               if(b_cell->edge_point(num_u) == corner_poi_typ) {
00472                 // num_u is corner point
00473                 if(j==dir_u) u_ablage[num_u] = 1.0;
00474                 else         u_ablage[num_u] = 0.0;
00475                 if(r_bou<=0) {
00476                   // case pure Dirichlet and mixed for u
00477                   if(j==dir_u) u_in_space = true;
00478                 }
00479               }
00480               else {
00481                 // num_u is edge point          
00482                 if(r_bou==1) {
00483                   // case pure Neumann for u
00484                   uu_in_space = true;
00485                   d = b_cell->edge_dir(num_u);
00486                   
00487                 }
00488                 else if(r_bou<0) {
00489                   // case mixed for u
00490                   d = b_cell->edge_dir(num_u);
00491                   uu_in_space = 
00492                     grid->Give_label_bo(I_son.neighbour((dir_sons)j), // "I"
00493                                         d,                            // "d"
00494                                         -r_bou);
00495                 }
00496                 else {
00497                   // case pure Dirichlet for u
00498                   uu_in_space = false;
00499                 }
00500                 if(uu_in_space) {
00501                   if(j==dir_u) a = 1.0;
00502                   else         a = 0.0;
00503                   if(Next_corner((dir_sons)j,d)==dir_u) b = 1.0;
00504                   else                                  b = 0.0;
00505                   u_ablage[num_u] =
00506                     (a + grid->Give_h(I_son.neighbour((dir_sons)j),d)
00507                      / finest_mesh_size
00508                      * (b-a));
00509                 }
00510                 else {
00511                   u_ablage[num_u] = 0.0;
00512                 }
00513               }
00514             }
00515             if(b_cell->Exists_bocellpoint()) {
00516               if(r_bou==1) {
00517                 // case pure Neumann
00518                 u_in_space = true;
00519               }
00520               else if(r_bou<0) {
00521                 // case mixed for u
00522                 if(b_cell->Is_Dirichlet(-r_bou)==false)
00523                   u_in_space = true;
00524               }
00525               // num_u is bocellpoint
00526               num_u = b_cell->Give_number_points();
00527               u_ablage[num_u] = weight_bocellpoint[dir_u];
00528             }
00529 
00530             if(u_in_space) { // go on only when u is in space
00531               // v: cases of boundary conditions for v!
00532               // corners of boundary cell
00533               for(num_v=0;num_v<b_cell->Give_number_points();++num_v) {
00534                 // iter. on v
00535                 j = b_cell->corner(num_v);
00536                 if(b_cell->edge_point(num_v) == corner_poi_typ) {
00537                   // num_v is corner point
00538                   Stencils_fine[i][j+8*dir_u] 
00539                     += a_.Give_boundary_sten_element(grid,b_cell,
00540                                                     u_ablage,num_v);
00541                 }
00542                 else {
00543                   // num_v is edge point
00544                   if(r_bov==1) {
00545                     // case pure Neumann for v
00546                     d = b_cell->edge_dir(num_v);
00547                     v_in_space = true;
00548                   }
00549                   else if(r_bov<0) {
00550                     // case mixed for v
00551                     d = b_cell->edge_dir(num_v);
00552                     v_in_space = 
00553                       grid->Give_label_bo(I_son.neighbour((dir_sons)j), // "I"
00554                                           d,                            // "d"
00555                                           -r_bov);
00556                   }
00557                   else {
00558                     // case Dirichlet for v
00559                     v_in_space = false;
00560                   }
00561                   if(v_in_space) {
00562                     ss = a_.Give_boundary_sten_element(grid,b_cell,
00563                                                        u_ablage,num_v);
00564                     d = b_cell->edge_dir(num_v);
00565                     j = b_cell->corner(num_v);
00566                     
00567                     hh = grid->Give_h(I_son.neighbour((dir_sons)j),d)
00568                       / finest_mesh_size;
00569                     // corner at num_v 
00570                     Stencils_fine[i][j+8*dir_u] 
00571                       += ss * (1.0 + hh * (0.0-1.0));
00572                     // opposite corner of num_v 
00573                     jj = Next_corner((dir_sons)j,d);
00574                     Stencils_fine[i][jj+8*dir_u]
00575                       += ss * (0.0 + hh * (1.0-0.0));
00576                   }
00577                 }
00578               }
00579 
00580               if(b_cell->Exists_bocellpoint()) {
00581                 // num_v is bocellpoint
00582                 num_v = b_cell->Give_number_points();
00583                 ss = a_.Give_boundary_sten_element(grid,b_cell,
00584                                                    u_ablage,num_v);
00585                 if(r_bov==1) {
00586                   // case pure Neumann
00587                   cell_point_in_space = true;
00588                 }
00589                 else if(r_bov<0) {
00590                   // case mixed for u
00591                   if(b_cell->Is_Dirichlet(-r_bov)==false)
00592                     cell_point_in_space = true;
00593                   else 
00594                     cell_point_in_space = false;
00595                 }
00596                 else
00597                   // case pure Dirichlet
00598                   cell_point_in_space = false;
00599                 if(cell_point_in_space) {
00600                   // case pure Neumann  or mixed for v
00601                   for(j=0;j<8;++j)
00602                     Stencils_fine[i][j+8*dir_u] += ss * weight_bocellpoint[j];
00603                 }
00604                 else {
00605                   // case pure Dirichlet for v
00606                   for(num_v=0;num_v<b_cell->Give_number_points();++num_v) {
00607                     if(b_cell->edge_point(num_v) == corner_poi_typ) {
00608                       j = b_cell->corner(num_v);
00609                       Stencils_fine[i][j+8*dir_u] += ss * weight_bocellpoint[j];
00610                     }
00611                   }
00612                 }
00613               }
00614             }
00615           }
00616         }
00617         else {
00618           for(j=0;j<64;++j) Stencils_fine[i][j] = 0.0;
00619         }
00620       }
00621 
00622 
00623       // c) Coarse the finer stencils
00624       Stencil_coarse = grid->Give_bo_stencil(I,num_stencils);
00625       Restrict_local_stiffness_matrix(Stencil_coarse,
00626                                       Stencils_fine,coarse_grid_functions);
00627 
00628       // Dirichlet for v
00629       if(r_bov==0) {
00630         for(i=0;i<8;++i) 
00631           if(grid->Give_global_type(I.neighbour((dir_sons)i))==multigrid) {
00632             for(j=0;j<8;++j) {
00633               Stencil_coarse[i+8*j] = 0.0;
00634             }
00635           }
00636       }
00637       // Dirichlet for u
00638       if(r_bou==0) {
00639         for(i=0;i<8;++i) 
00640           if(grid->Give_global_type(I.neighbour((dir_sons)i))==multigrid) {
00641             for(j=0;j<8;++j) {
00642               Stencil_coarse[j+8*i] = 0.0;
00643             }
00644           }
00645       }
00646       
00647       // mixed for v
00648       if(r_bov<0) {
00649         for(i=0;i<8;++i) {
00650           type = grid->Give_global_type(I.neighbour((dir_sons)i));
00651           if(type==multigrid) {
00652             if(grid->Give_label_bo_D(I.neighbour((dir_sons)i),-r_bov,level-1)) {
00653               for(j=0;j<8;++j) {
00654                 Stencil_coarse[i+8*j] = 0.0;
00655               }
00656             }
00657           }
00658           if(type==exterior) {
00659             for(j=0;j<8;++j) {
00660               Stencil_coarse[i+8*j] = 0.0;
00661             }
00662           }
00663         }
00664       }
00665       // mixed for u
00666       if(r_bou<0) {
00667         for(i=0;i<8;++i) {
00668           type = grid->Give_global_type(I.neighbour((dir_sons)i));
00669           if(type==multigrid) {
00670             if(grid->Give_label_bo_D(I.neighbour((dir_sons)i),-r_bou,level-1)) {
00671               for(j=0;j<8;++j) {
00672                 Stencil_coarse[j+8*i] = 0.0;
00673               }
00674             }
00675           }
00676           if(type==exterior) {
00677             for(j=0;j<8;++j) {
00678               Stencil_coarse[j+8*i] = 0.0;
00679             }
00680           }
00681         }
00682       }
00683     }
00684    }
00685   }
00686   // d) Parallel:
00687   if(parallel_version)
00688     grid->Update_boundary_stencil(num_stencils,grid->Max_level());
00689 
00690   // II. Second step: all coarser level
00691   for(level=grid->Max_level()-1;level>grid->Min_level();--level) {
00692     my_lev_index = grid->Give_my_level_index(level);
00693     Iterate_hash0 {
00694      // a) search for boundary cells
00695      I = point0->Give_Index();
00696      if(I.Cell_index()) {
00697       lev = I.Tiefe();
00698       if(point0->Give_cell_typ()==bo_cell && lev == level &&
00699          I < my_lev_index) {
00700 
00701         // b) Get the finer stencils
00702         // mesh_size = grid->H_mesh() / Zweipotenz(I.Tiefe()+1);
00703         mesh_size = grid->H_mesh() / Zweipotenz(I.Tiefe());
00704         for(i=0;i<8;++i) {
00705           I_son = I.son((dir_sons)i);
00706           ce_typ = grid->Give_cell_typ(I_son);
00707 
00708           if(ce_typ==int_cell) {
00709             for(j=0;j<64;++j)
00710               Stencils_fine[i][j]
00711                 = a_.Give_interior_sten_element(I_son,mesh_size,j,
00712                                                 grid,I.Tiefe());
00713           }
00714           else if(ce_typ==bo_cell) {
00715             sp = grid->Give_bo_stencil(I_son,num_stencils);
00716             for(j=0;j<64;++j) Stencils_fine[i][j] = sp[j];
00717           }
00718           else {
00719             for(j=0;j<64;++j) Stencils_fine[i][j] = 0.0;
00720           }
00721         }
00722   
00723         // c) Coarse the finer stencils
00724         Stencil_coarse = grid->Give_bo_stencil(I,num_stencils);
00725         Restrict_local_stiffness_matrix(Stencil_coarse,
00726                                         Stencils_fine,coarse_grid_functions);
00727 
00728         // Dirichlet for v
00729         if(r_bov==0) {
00730           for(i=0;i<8;++i) 
00731             if(grid->Give_global_type(I.neighbour((dir_sons)i))==multigrid) {
00732               for(j=0;j<8;++j) {
00733                 Stencil_coarse[i+8*j] = 0.0;
00734               }
00735             }
00736         }
00737         // Dirichlet for u
00738         if(r_bou==0) {
00739           for(i=0;i<8;++i) 
00740             if(grid->Give_global_type(I.neighbour((dir_sons)i))==multigrid) {
00741               for(j=0;j<8;++j) {
00742                 Stencil_coarse[j+8*i] = 0.0;
00743               }
00744             }
00745         }
00746 
00747         // mixed for v
00748         if(r_bov<0) {
00749           for(i=0;i<8;++i) {
00750             type = grid->Give_global_type(I.neighbour((dir_sons)i));
00751             if(type==multigrid) {
00752               if(grid->Give_label_bo_D(I.neighbour((dir_sons)i),-r_bov,level-1)) {
00753                 for(j=0;j<8;++j) {
00754                   Stencil_coarse[i+8*j] = 0.0;
00755                 }
00756               }
00757             }
00758             if(type==exterior) {
00759               for(j=0;j<8;++j) {
00760                 Stencil_coarse[i+8*j] = 0.0;
00761               }
00762             }
00763           }
00764         }
00765         // mixed for u
00766         if(r_bou<0) {
00767           for(i=0;i<8;++i) {
00768             type = grid->Give_global_type(I.neighbour((dir_sons)i));
00769             if(type==multigrid) {
00770               if(grid->Give_label_bo_D(I.neighbour((dir_sons)i),-r_bou,level-1)) {
00771                 for(j=0;j<8;++j) {
00772                   Stencil_coarse[j+8*i] = 0.0;
00773                 }
00774               }
00775             }
00776             if(type==exterior) {
00777               for(j=0;j<8;++j) {
00778                 Stencil_coarse[j+8*i] = 0.0;
00779               }
00780             }
00781           }
00782         }
00783         
00784       }
00785      }
00786     }
00787     // d) Parallel:
00788     if(parallel_version) {
00789       grid->Update_boundary_stencil(num_stencils,level);
00790     }
00791   }
00792 }
00793 
00794 
00795 
00796 
00797 #endif
00798 
00799            

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