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

src/expde/extemp/mg_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 // mg_op.h
00019 //
00020 // ------------------------------------------------------------
00021 
00022 #ifndef MGOP_H_
00023 #define MGOP_H_
00024                    
00026 // 1.:  Restriction operator for Multigrid
00027 // 2.:  Prolongation operator for Multigrid
00029 
00030 
00032 // 1.:  Restriction operator for Multigrid
00034 
00035 
00036 
00037 #define near_bo_restriction_coarse(insert_I) \
00038 var = gr->Give_variable_slow( insert_I ,lpo); \
00039 if(var!=NULL) sum = sum + var[v_.Number_variable()];
00040 
00041 
00042 #define near_bo_restriction_fine(insert_I) \
00043 sum = sum + gr->Give_variable( insert_I ,lpo)[v_.Number_variable()]; 
00044 
00045 
00046 #define near_bo_restriction_fine_bo(insert_I,d,a,b) \
00047 var = gr->Give_variable( insert_I , d ); \
00048 if(var!=NULL) { \
00049   sum = sum + ((double)a + \
00050                gr->Give_h( insert_I , d ) / finest_meshsize \
00051                * (double)(b-a)) * \
00052     var[v_.Number_variable()]; \
00053 }
00054 
00055 
00056 
00057 
00058 
00060 // preparation
00061 
00062 
00063 class DVar_Res_Op {
00064   Variable v_;
00065   double **Stencil;
00066   //
00067   double* weight27;
00068 
00069   Restriction_stencil_container* restriction_stencil;
00070 
00071  public:
00072   DVar_Res_Op(const Variable& v)
00073     : v_(v) {
00074     weight27 =  v.Give_grid()->Give_weight_27();
00075     restriction_stencil = v.Give_grid()->Give_restriction_stencil();
00076   }
00077   double Give_interior_here(const P_interior* it_i, const Grid* grid,
00078                             double h_mesh,
00079                             int lev, double_stencils_in) const {
00080     return 
00081       it_i->var_fine_M(grid,lev)[v_.Number_variable()] +
00082       0.5 * (it_i->var_fine_N(grid,lev)[v_.Number_variable()] +
00083              it_i->var_fine_W(grid,lev)[v_.Number_variable()] +
00084              it_i->var_fine_E(grid,lev)[v_.Number_variable()] +
00085              it_i->var_fine_S(grid,lev)[v_.Number_variable()] +
00086              it_i->var_fine_T(grid,lev)[v_.Number_variable()] +
00087              it_i->var_fine_D(grid,lev)[v_.Number_variable()] +
00088              it_i->var_fine_ND(grid,lev)[v_.Number_variable()] +
00089              it_i->var_fine_WN(grid,lev)[v_.Number_variable()] +
00090              it_i->var_fine_WT(grid,lev)[v_.Number_variable()] +
00091              it_i->var_fine_ED(grid,lev)[v_.Number_variable()] +
00092              it_i->var_fine_ST(grid,lev)[v_.Number_variable()] +
00093              it_i->var_fine_ES(grid,lev)[v_.Number_variable()] +
00094              it_i->var_fine_EST(grid,lev)[v_.Number_variable()] +
00095              it_i->var_fine_WND(grid,lev)[v_.Number_variable()]);
00096   };
00097   double Give_interior(const P_interior* it_i, const Grid* grid, double h_mesh,
00098                        int lev, double_stencils_in) const {
00099     return Give_interior_here(it_i,grid,h_mesh,lev, double_stencils_out);
00100   }
00101   double Give_interior_coarse(const P_interior* it_i, const Grid* grid,
00102                               double h_mesh,
00103                               int lev, double_stencils_in) const {
00104     return Give_interior_here(it_i,grid,h_mesh,lev, double_stencils_out);
00105   }
00106   double Give_nearb(const P_nearb* it_n, const Grid* gr, double h_mesh, int l,
00107                     const Nearb_Ablage* nearb_ablage) const {
00108     double sum;
00109     double* var;
00110     bool from_finest_grid;
00111     Index3D next, Inext;
00112     int lpo; // l+1
00113     double finest_meshsize;
00114     bool cell_point_in_space;
00115 
00116     if(l == gr->Max_level()-1)
00117       from_finest_grid = true;
00118     else 
00119       from_finest_grid = false;
00120 
00121     finest_meshsize = gr->Give_finest_mesh_size();
00122   
00123     if(mg_coefficients) {
00124       Point_mg_coeff_nearb* l_nearb;  // Hilfspeicher 
00125       Point_mg_coeff_bo*    l_bo;     // Hilfspeicher 
00126     
00127       sum = 0.0;
00128       for(l_nearb=it_n->Give_first_mg_coeff_nearb();
00129           l_nearb!=NULL;l_nearb=l_nearb->Next_res()) {
00130         sum = sum + l_nearb->Give_var()[v_.Number_variable()] 
00131           * l_nearb->Give_weight();
00132       }
00133       if(v_.run_boundary() == 1) {
00134         for(l_bo=it_n->Give_first_mg_coeff_bo();
00135             l_bo!=NULL;l_bo=l_bo->Next_res()) {
00136           sum = sum + l_bo->Give_var()[v_.Number_variable()] 
00137             * l_bo->Give_weight();
00138         }
00139       }
00140       else if(v_.run_boundary() < 0) {
00141         for(l_bo=it_n->Give_first_mg_coeff_bo();
00142             l_bo!=NULL;l_bo=l_bo->Next_res()) {
00143           if(gr->Give_label_bo(l_bo->I(),l_bo->d(),-v_.run_boundary())) {
00144             sum = sum + l_bo->Give_var()[v_.Number_variable()] 
00145               * l_bo->Give_weight();
00146           }
00147         }
00148       }
00149     }
00150     else {
00151       Index3D I, next, next_cell;
00152       D3vector Co;
00153       BoCeData* bocedata;
00154       int i,j,k;
00155       double* UU;
00156       
00157       I = it_n->Ind();
00158 
00159       lpo = l+1;
00160 
00161       // the following code was mainly generated by 
00162       //    void Print_bos_for_restriction(...);
00163       // in loc_sten.cc
00164       // by hand : Mittelpunkt
00165       if(from_finest_grid) {
00166         // restrict from finest grid
00167         sum = 0.0;
00168 
00169         next = I.next_W(lpo).next_W(lpo);
00170         //      if(gr->Grid_point_on_finest_level(next)) {
00171           near_bo_restriction_fine_bo(next,Edir,0,1);
00172           //    };
00173 
00174         next = I.next_W(lpo).next_W(lpo).next_T(lpo);
00175         //      if(gr->Grid_point_on_finest_level(next)) {
00176           near_bo_restriction_fine_bo(next,Edir,0,1);
00177           //    };
00178 
00179         next = I.next_W(lpo).next_W(lpo).next_N(lpo).next_D(lpo);
00180         //      if(gr->Grid_point_on_finest_level(next)) {
00181           near_bo_restriction_fine_bo(next,Edir,0,1);
00182           //    };
00183         next = I.next_W(lpo).next_W(lpo).next_N(lpo);
00184         //      if(gr->Grid_point_on_finest_level(next)) {
00185           near_bo_restriction_fine_bo(next,Edir,0,1);
00186           //    };
00187         next = I.next_W(lpo).next_S(lpo);
00188         //      if(gr->Grid_point_on_finest_level(next)) {
00189           near_bo_restriction_fine_bo(next,Edir,0,1);
00190           near_bo_restriction_fine_bo(next,Ndir,0,1);
00191           //    };      
00192         next = I.next_W(lpo).next_S(lpo).next_T(lpo);
00193         //      if(gr->Grid_point_on_finest_level(next)) {
00194           near_bo_restriction_fine_bo(next,Edir,0,1);
00195           near_bo_restriction_fine_bo(next,Ndir,0,1);
00196           //    };
00197         next = I.next_W(lpo).next_D(lpo);  
00198         //      if(gr->Grid_point_on_finest_level(next)) {
00199           near_bo_restriction_fine_bo(next,Edir,0,1);
00200           near_bo_restriction_fine_bo(next,Ndir,0,1);
00201           near_bo_restriction_fine_bo(next,Tdir,0,1);
00202           //    };
00203         next = I.next_W(lpo);
00204         if(gr->Grid_point_on_finest_level(next)) {
00205           near_bo_restriction_fine(next);
00206         }
00207           near_bo_restriction_fine_bo(next,Wdir,1,0);
00208           near_bo_restriction_fine_bo(next,Edir,1,2);
00209           near_bo_restriction_fine_bo(next,Ndir,1,1);
00210           near_bo_restriction_fine_bo(next,Sdir,1,0);
00211           near_bo_restriction_fine_bo(next,Tdir,1,1);
00212           near_bo_restriction_fine_bo(next,Ddir,1,0);
00213           //    };
00214         next = I.next_W(lpo).next_T(lpo);
00215         if(gr->Grid_point_on_finest_level(next)) {
00216           near_bo_restriction_fine(next);
00217         }
00218           near_bo_restriction_fine_bo(next,Wdir,1,0);
00219           near_bo_restriction_fine_bo(next,Edir,1,1);
00220           near_bo_restriction_fine_bo(next,Ndir,1,0);
00221           near_bo_restriction_fine_bo(next,Sdir,1,0);
00222           near_bo_restriction_fine_bo(next,Tdir,1,0);
00223           near_bo_restriction_fine_bo(next,Ddir,1,1);
00224           //    };
00225         next = I.next_W(lpo).next_T(lpo).next_T(lpo);
00226         //      if(gr->Grid_point_on_finest_level(next)) {
00227           near_bo_restriction_fine_bo(next,Ddir,0,1);
00228           //    };
00229         next = I.next_W(lpo).next_N(lpo).next_D(lpo).next_D(lpo);
00230         //      if(gr->Grid_point_on_finest_level(next)) {
00231           near_bo_restriction_fine_bo(next,Tdir,0,1);
00232           //    };
00233         next = I.next_W(lpo).next_N(lpo).next_D(lpo);
00234         if(gr->Grid_point_on_finest_level(next)) {
00235           near_bo_restriction_fine(next);
00236         }
00237           near_bo_restriction_fine_bo(next,Wdir,1,0);
00238           near_bo_restriction_fine_bo(next,Edir,1,1);
00239           near_bo_restriction_fine_bo(next,Ndir,1,0);
00240           near_bo_restriction_fine_bo(next,Sdir,1,0);
00241           near_bo_restriction_fine_bo(next,Tdir,1,1);
00242           near_bo_restriction_fine_bo(next,Ddir,1,0);
00243           //    };
00244         next = I.next_W(lpo).next_N(lpo);
00245         if(gr->Grid_point_on_finest_level(next)) {
00246           near_bo_restriction_fine(next);
00247         }
00248           near_bo_restriction_fine_bo(next,Wdir,1,0);
00249           near_bo_restriction_fine_bo(next,Edir,1,1);
00250           near_bo_restriction_fine_bo(next,Ndir,1,0);
00251           near_bo_restriction_fine_bo(next,Sdir,1,1);
00252           near_bo_restriction_fine_bo(next,Tdir,1,0);
00253           near_bo_restriction_fine_bo(next,Ddir,1,1);
00254           //    };
00255         next = I.next_W(lpo).next_N(lpo).next_T(lpo);
00256         //      if(gr->Grid_point_on_finest_level(next)) {
00257           near_bo_restriction_fine_bo(next,Sdir,0,1);
00258           near_bo_restriction_fine_bo(next,Ddir,0,1);
00259           //    };
00260         next = I.next_W(lpo).next_N(lpo).next_N(lpo).next_D(lpo);
00261         //      if(gr->Grid_point_on_finest_level(next)) {
00262           near_bo_restriction_fine_bo(next,Sdir,0,1);
00263           //    };
00264         next = I.next_W(lpo).next_N(lpo).next_N(lpo);
00265         //      if(gr->Grid_point_on_finest_level(next)) {
00266           near_bo_restriction_fine_bo(next,Sdir,0,1);
00267           //    };
00268         next = I.next_S(lpo).next_S(lpo);
00269         //      if(gr->Grid_point_on_finest_level(next)) {
00270           near_bo_restriction_fine_bo(next,Ndir,0,1);
00271           //    };
00272         next = I.next_S(lpo).next_S(lpo).next_T(lpo);
00273         //      if(gr->Grid_point_on_finest_level(next)) {
00274           near_bo_restriction_fine_bo(next,Ndir,0,1);
00275           //    };
00276         next = I.next_S(lpo).next_D(lpo);
00277         //      if(gr->Grid_point_on_finest_level(next)) {
00278           near_bo_restriction_fine_bo(next,Ndir,0,1);
00279           near_bo_restriction_fine_bo(next,Tdir,0,1);
00280           //    };
00281         next = I.next_S(lpo);
00282         if(gr->Grid_point_on_finest_level(next)) {
00283           near_bo_restriction_fine(next);
00284         }
00285           near_bo_restriction_fine_bo(next,Wdir,1,0);
00286           near_bo_restriction_fine_bo(next,Edir,1,1);
00287           near_bo_restriction_fine_bo(next,Ndir,1,2);
00288           near_bo_restriction_fine_bo(next,Sdir,1,0);
00289           near_bo_restriction_fine_bo(next,Tdir,1,1);
00290           near_bo_restriction_fine_bo(next,Ddir,1,0);
00291           //    };
00292         next = I.next_S(lpo).next_T(lpo);
00293         if(gr->Grid_point_on_finest_level(next)) {
00294           near_bo_restriction_fine(next);
00295         }
00296           near_bo_restriction_fine_bo(next,Wdir,1,0);
00297           near_bo_restriction_fine_bo(next,Edir,1,1);
00298           near_bo_restriction_fine_bo(next,Ndir,1,1);
00299           near_bo_restriction_fine_bo(next,Sdir,1,0);
00300           near_bo_restriction_fine_bo(next,Tdir,1,0);
00301           near_bo_restriction_fine_bo(next,Ddir,1,1);
00302           //    };
00303         next = I.next_S(lpo).next_T(lpo).next_T(lpo);
00304         //      if(gr->Grid_point_on_finest_level(next)) {
00305           near_bo_restriction_fine_bo(next,Ddir,0,1);
00306           //    };
00307         next = I.next_D(lpo).next_D(lpo);
00308         //      if(gr->Grid_point_on_finest_level(next)) {
00309           near_bo_restriction_fine_bo(next,Tdir,0,1);
00310           //    };
00311         next = I.next_D(lpo);
00312         if(gr->Grid_point_on_finest_level(next)) {
00313           near_bo_restriction_fine(next);
00314         }
00315           near_bo_restriction_fine_bo(next,Wdir,1,0);
00316           near_bo_restriction_fine_bo(next,Edir,1,1);
00317           near_bo_restriction_fine_bo(next,Ndir,1,1);
00318           near_bo_restriction_fine_bo(next,Sdir,1,0);
00319           near_bo_restriction_fine_bo(next,Tdir,1,2);
00320           near_bo_restriction_fine_bo(next,Ddir,1,0);
00321           //    };
00322         // Mittelpunkt::
00323         next = I;
00324         if(gr->Grid_point_on_finest_level(next)) {
00325           sum = sum + 2.0 *
00326             gr->Give_variable( next ,lpo)[v_.Number_variable()];
00327           //      near_bo_restriction_fine(next);
00328         }
00329           near_bo_restriction_fine_bo(next,Wdir,2,1);
00330           near_bo_restriction_fine_bo(next,Edir,2,1);
00331           near_bo_restriction_fine_bo(next,Ndir,2,1);
00332           near_bo_restriction_fine_bo(next,Sdir,2,1);
00333           near_bo_restriction_fine_bo(next,Tdir,2,1);
00334           near_bo_restriction_fine_bo(next,Ddir,2,1);
00335           //    };
00336         next = I.next_T(lpo);
00337         if(gr->Grid_point_on_finest_level(next)) {
00338           near_bo_restriction_fine(next);
00339         }
00340           near_bo_restriction_fine_bo(next,Wdir,1,1);
00341           near_bo_restriction_fine_bo(next,Edir,1,0);
00342           near_bo_restriction_fine_bo(next,Ndir,1,0);
00343           near_bo_restriction_fine_bo(next,Sdir,1,1);
00344           near_bo_restriction_fine_bo(next,Tdir,1,0);
00345           near_bo_restriction_fine_bo(next,Ddir,1,2);
00346           //    };
00347         next = I.next_T(lpo).next_T(lpo);
00348         //      if(gr->Grid_point_on_finest_level(next)) {
00349           near_bo_restriction_fine_bo(next,Ddir,0,1);
00350           //    };
00351         next = I.next_N(lpo).next_D(lpo).next_D(lpo);
00352         //      if(gr->Grid_point_on_finest_level(next)) {
00353           near_bo_restriction_fine_bo(next,Tdir,0,1);
00354           //    };
00355         next = I.next_N(lpo).next_D(lpo);
00356         if(gr->Grid_point_on_finest_level(next)) {
00357           near_bo_restriction_fine(next);
00358         }
00359           near_bo_restriction_fine_bo(next,Wdir,1,1);
00360           near_bo_restriction_fine_bo(next,Edir,1,0);
00361           near_bo_restriction_fine_bo(next,Ndir,1,0);
00362           near_bo_restriction_fine_bo(next,Sdir,1,1);
00363           near_bo_restriction_fine_bo(next,Tdir,1,1);
00364           near_bo_restriction_fine_bo(next,Ddir,1,0);
00365           //    };
00366         next = I.next_N(lpo);
00367         if(gr->Grid_point_on_finest_level(next)) {
00368           near_bo_restriction_fine(next);
00369         }
00370           near_bo_restriction_fine_bo(next,Wdir,1,1);
00371           near_bo_restriction_fine_bo(next,Edir,1,0);
00372           near_bo_restriction_fine_bo(next,Ndir,1,0);
00373           near_bo_restriction_fine_bo(next,Sdir,1,2);
00374           near_bo_restriction_fine_bo(next,Tdir,1,0);
00375           near_bo_restriction_fine_bo(next,Ddir,1,1);
00376           //    };
00377         next = I.next_N(lpo).next_T(lpo);
00378         //      if(gr->Grid_point_on_finest_level(next)) {
00379           near_bo_restriction_fine_bo(next,Sdir,0,1);
00380           near_bo_restriction_fine_bo(next,Ddir,0,1);
00381           //    };
00382         next = I.next_N(lpo).next_N(lpo).next_D(lpo);
00383         //      if(gr->Grid_point_on_finest_level(next)) {
00384           near_bo_restriction_fine_bo(next,Sdir,0,1);
00385           //    };
00386         next = I.next_N(lpo).next_N(lpo);
00387         //      if(gr->Grid_point_on_finest_level(next)) {
00388           near_bo_restriction_fine_bo(next,Sdir,0,1);
00389           //    };
00390         next = I.next_E(lpo).next_S(lpo).next_S(lpo);
00391         //      if(gr->Grid_point_on_finest_level(next)) {
00392           near_bo_restriction_fine_bo(next,Ndir,0,1);
00393           //    };
00394         next = I.next_E(lpo).next_S(lpo).next_S(lpo).next_T(lpo);
00395         //      if(gr->Grid_point_on_finest_level(next)) {
00396           near_bo_restriction_fine_bo(next,Ndir,0,1);
00397           //    };
00398         next = I.next_E(lpo).next_S(lpo).next_D(lpo);
00399         //      if(gr->Grid_point_on_finest_level(next)) {
00400           near_bo_restriction_fine_bo(next,Ndir,0,1);
00401           near_bo_restriction_fine_bo(next,Tdir,0,1);
00402           //    };
00403         next = I.next_E(lpo).next_S(lpo);
00404         if(gr->Grid_point_on_finest_level(next)) {
00405           near_bo_restriction_fine(next);
00406         }
00407           near_bo_restriction_fine_bo(next,Wdir,1,1);
00408           near_bo_restriction_fine_bo(next,Edir,1,0);
00409           near_bo_restriction_fine_bo(next,Ndir,1,1);
00410           near_bo_restriction_fine_bo(next,Sdir,1,0);
00411           near_bo_restriction_fine_bo(next,Tdir,1,1);
00412           near_bo_restriction_fine_bo(next,Ddir,1,0);
00413           //    };
00414         next = I.next_E(lpo).next_S(lpo).next_T(lpo);
00415         if(gr->Grid_point_on_finest_level(next)) {
00416           near_bo_restriction_fine(next);
00417         }
00418           near_bo_restriction_fine_bo(next,Wdir,1,1);
00419           near_bo_restriction_fine_bo(next,Edir,1,0);
00420           near_bo_restriction_fine_bo(next,Ndir,1,0);
00421           near_bo_restriction_fine_bo(next,Sdir,1,0);
00422           near_bo_restriction_fine_bo(next,Tdir,1,0);
00423           near_bo_restriction_fine_bo(next,Ddir,1,1);
00424           //    };
00425         next = I.next_E(lpo).next_S(lpo).next_T(lpo).next_T(lpo);
00426         //      if(gr->Grid_point_on_finest_level(next)) {
00427           near_bo_restriction_fine_bo(next,Ddir,0,1);
00428           //    };
00429         next = I.next_E(lpo).next_D(lpo).next_D(lpo);
00430         //      if(gr->Grid_point_on_finest_level(next)) {
00431           near_bo_restriction_fine_bo(next,Tdir,0,1);
00432           //    };
00433         next = I.next_E(lpo).next_D(lpo);
00434         if(gr->Grid_point_on_finest_level(next)) {
00435           near_bo_restriction_fine(next);
00436         }
00437           near_bo_restriction_fine_bo(next,Wdir,1,1);
00438           near_bo_restriction_fine_bo(next,Edir,1,0);
00439           near_bo_restriction_fine_bo(next,Ndir,1,0);
00440           near_bo_restriction_fine_bo(next,Sdir,1,0);
00441           near_bo_restriction_fine_bo(next,Tdir,1,1);
00442           near_bo_restriction_fine_bo(next,Ddir,1,0);
00443           //    };
00444         next = I.next_E(lpo);
00445         if(gr->Grid_point_on_finest_level(next)) {
00446           near_bo_restriction_fine(next);
00447         }
00448           near_bo_restriction_fine_bo(next,Wdir,1,2);
00449           near_bo_restriction_fine_bo(next,Edir,1,0);
00450           near_bo_restriction_fine_bo(next,Ndir,1,0);
00451           near_bo_restriction_fine_bo(next,Sdir,1,1);
00452           near_bo_restriction_fine_bo(next,Tdir,1,0);
00453           near_bo_restriction_fine_bo(next,Ddir,1,1);
00454           //    };
00455         next = I.next_E(lpo).next_T(lpo);
00456         //      if(gr->Grid_point_on_finest_level(next)) {
00457           near_bo_restriction_fine_bo(next,Wdir,0,1);
00458           near_bo_restriction_fine_bo(next,Sdir,0,1);
00459           near_bo_restriction_fine_bo(next,Ddir,0,1);
00460           //    };
00461         next = I.next_E(lpo).next_N(lpo).next_D(lpo);
00462         //      if(gr->Grid_point_on_finest_level(next)) {
00463           near_bo_restriction_fine_bo(next,Wdir,0,1);
00464           near_bo_restriction_fine_bo(next,Sdir,0,1);
00465           //    };
00466         next = I.next_E(lpo).next_N(lpo);
00467         //      if(gr->Grid_point_on_finest_level(next)) {
00468           near_bo_restriction_fine_bo(next,Wdir,0,1);
00469           near_bo_restriction_fine_bo(next,Sdir,0,1);
00470           //    };
00471         next = I.next_E(lpo).next_E(lpo).next_S(lpo);
00472         //      if(gr->Grid_point_on_finest_level(next)) {
00473           near_bo_restriction_fine_bo(next,Wdir,0,1);
00474           //    };
00475         next = I.next_E(lpo).next_E(lpo).next_S(lpo).next_T(lpo);
00476         //      if(gr->Grid_point_on_finest_level(next)) {
00477           near_bo_restriction_fine_bo(next,Wdir,0,1);
00478           //    };
00479         next = I.next_E(lpo).next_E(lpo).next_D(lpo);
00480         //      if(gr->Grid_point_on_finest_level(next)) {
00481           near_bo_restriction_fine_bo(next,Wdir,0,1);
00482           //    };
00483         next = I.next_E(lpo).next_E(lpo);
00484         //      if(gr->Grid_point_on_finest_level(next)) {
00485           near_bo_restriction_fine_bo(next,Wdir,0,1);
00486           //    };
00487 
00488         // bocell point (Randzellfreiheitsgrad)
00489         for(i=0;i<8;++i) {    // go to middle point of neighbour coarse cells
00490           next_cell = I.next((dir_sons)i,lpo); 
00491           for(j=0;j<8;++j) {    // go to middle point of neighbour fine cells
00492             next = next_cell.next((dir_sons)j,l+2); 
00493             bocedata = gr->Give_Bo_cell(next);
00494             if(bocedata!=NULL) {
00495               //if(bocedata->Exists_bocellpoint() && false) {
00496               if(bocedata->Exists_bocellpoint()) {
00497 
00498                 // cout << " fine_bo_cell " << endl;
00499                 
00500                 UU = gr->Give_vector_ablage();
00501 
00502                 if(v_.run_boundary()==1) {
00503                   // Neumann boundary condition
00504                   cell_point_in_space = true;
00505                 }
00506                 else if(v_.run_boundary()==0) {
00507                   // Dirichlet boundary condition
00508                   cell_point_in_space = false;
00509                 }
00510                 else {
00511                   // mixed boundary condition
00512                   if(bocedata->Is_Dirichlet(-v_.run_boundary()))
00513                     cell_point_in_space = false;
00514                   else 
00515                     cell_point_in_space = true;
00516                 }
00517 
00518                 if(cell_point_in_space) { 
00519                   // Neumann boundary condition
00520                   for(k=0;k<8;++k) {
00521                     UU[k] =
00522                       restriction_stencil->Calc_trans_weight((dir_sons)i,
00523                                                              (dir_sons)j,
00524                                                              (dir_sons)k);
00525                   }
00526                 }
00527                 else {
00528                   // Dirichlet boundary condition
00529                   for(k=0;k<8;++k) {
00530                     Inext = next.neighbour((dir_sons)k);
00531                     if(gr->Grid_point_on_finest_level(Inext))
00532                       UU[k] =
00533                         restriction_stencil->Calc_trans_weight((dir_sons)i,
00534                                                                (dir_sons)j,
00535                                                                (dir_sons)k);
00536                     else
00537                       UU[k] = 0.0;
00538                   }
00539                 }
00540 
00541                 Co = bocedata->Coord_bocellpoint_normal();
00542 
00543                 if(developer_version) {
00544                   if(Co.x<0.0 || Co.x>1.0 ||
00545                      Co.y<0.0 || Co.y>1.0 ||
00546                      Co.z<0.0 || Co.z>1.0) {
00547                     cout << " error in DVar_Res_Op::Give_nearb! " << endl;
00548                   }
00549                 }
00550 
00551                 sum +=
00552                   // (UU[0] + UU[1] + UU[2] + UU[3] +
00553                   // UU[4] + UU[5] + UU[6] + UU[7] ) * 0.125 * 
00554                   (UU[WSDd] * (1.0 - Co.x) * (1.0 - Co.y) * (1.0 - Co.z) +
00555                    UU[ESDd] *        Co.x  * (1.0 - Co.y) * (1.0 - Co.z) +
00556                    UU[WNDd] * (1.0 - Co.x) *         Co.y * (1.0 - Co.z) +
00557                    UU[ENDd] *        Co.x  *         Co.y * (1.0 - Co.z) +
00558                    UU[WSTd] * (1.0 - Co.x) * (1.0 - Co.y) *        Co.z  +
00559                    UU[ESTd] *        Co.x  * (1.0 - Co.y) *        Co.z  +
00560                    UU[WNTd] * (1.0 - Co.x) *         Co.y *        Co.z  +
00561                    UU[ENTd] *        Co.x  *         Co.y *        Co.z)  *
00562                   bocedata->vars[bocedata->Give_number_points()]
00563                   [v_.Number_variable()];
00564 
00565 
00566               }
00567             }
00568           }
00569         }
00570        
00571 
00572 
00573         return sum * 0.5;
00574 
00575       }
00576       else {
00577         // restrict from coarser grids
00578         sum = 0.0;
00579 
00580         near_bo_restriction_coarse(I.next_W(lpo));
00581         near_bo_restriction_coarse(I.next_WT(lpo));
00582         near_bo_restriction_coarse(I.next_WND(lpo));
00583         near_bo_restriction_coarse(I.next_WN(lpo));
00584         near_bo_restriction_coarse(I.next_S(lpo));
00585         near_bo_restriction_coarse(I.next_ST(lpo));
00586         near_bo_restriction_coarse(I.next_D(lpo));
00587         near_bo_restriction_coarse(I.next_T(lpo));
00588         near_bo_restriction_coarse(I.next_ND(lpo));
00589         near_bo_restriction_coarse(I.next_N(lpo));
00590         near_bo_restriction_coarse(I.next_ES(lpo));
00591         near_bo_restriction_coarse(I.next_EST(lpo));
00592         near_bo_restriction_coarse(I.next_ED(lpo));
00593         near_bo_restriction_coarse(I.next_E(lpo));
00594         
00595         sum = sum * 0.5;
00596 
00597         near_bo_restriction_coarse(I);
00598 
00599         return sum;
00600       }
00601     }
00602     return sum;
00603   };
00604 
00605 
00606 
00607 
00608   double Give_cellpoi(const P_cellpoi* it_cf, const Grid* gr,
00609                       const BoCeData* bocedata) const {
00610     cout << " Error in DVar_Res_Op::Give_cellpoi! " << endl;
00611     cout << " This function should never be used! " << endl;
00612     return 0.0;
00613   };
00614   double Give_Bo2p(const P_Bo2p* it_b, const Grid* gr,int l)  const {
00615     cout << " Error in DVar_Res_Op::Give_Bo2p! " << endl;
00616     cout << " This function should never be used! " << endl;
00617     return 0.0;
00618   };
00619   // Size of necessary stencil
00620   int Sice_stencil() const { return 15; }
00621 
00622   // activity of points
00623   int Level() const { return (v_).Level()-1; }
00624   Dominace_label Dominant_lev() const { return yes_dominant; }
00625   Dominace_label Dominant_poi() const { return yes_dominant; }
00626   bool run_interior() const { return (v_).run_interior(); }
00627   bool run_nearb()    const { return (v_).run_nearb(); }
00628   int run_boundary() const { return (v_).run_boundary(); }
00629 
00630   // number of operations
00631   int ops_interior() const { return 15; }
00632 
00633   // For operator ==
00634   void Active_Sim_Level( int lev) const {  };
00635   void Active_Sim_interior(bool run) const {  };
00636   void Active_Sim_nearb(bool run) const {  };
00637   void Active_Sim_boundary( int run) const {  };
00638   void Active_Sim_update(Evaluation_Parallelization_object* evpar,
00639                          int level, type_of_update typ) const {  };
00640 
00641   // Put pointer to grid and activity of boundary points of test space  
00642   void Put_grid_rbo(Grid* gr, int r_bo) const { };
00643   // Is the expression an abstract differential operator?
00644   Differential_op_typ Abstract_differential_operator() const
00645     { return not_abstract; }
00646   // for Parallelization
00647   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00648     const {
00649     evpar->Variable_contained_in_expression_other(v_.Number_variable());
00650     evpar->Other_is_fine();
00651   }
00652   bool GS_type(int var_number_left, int dim) const {
00653     return false; 
00654   }; 
00655   // at the and of an iteration of an expression
00656   void clean() const { };
00657 };
00658 
00659 
00660 /* Unary operator */
00661 
00662 DExpr<DVar_Res_Op>
00663 Restriction_FE(Variable a);
00664 
00665 
00667 // 2.:  Prolongation operator for Multigrid
00669 
00670 
00671 
00672 
00673 class DVar_Prol_Op {
00674  public:
00675   DVar_Prol_Op(const Variable& v)
00676     : v_(v) {}
00677   double Give_interior(const P_interior* it_i, const Grid* grid, double h_mesh,
00678                        int lev, double_stencils_in) const {
00679     return Give_interior_here(it_i,grid,h_mesh,lev, double_stencils_out);
00680   }
00681   double Give_interior_coarse(const P_interior* it_i, const Grid* grid,
00682                               double h_mesh,
00683                               int lev, double_stencils_in) const {
00684     return Give_interior_here(it_i,grid,h_mesh,lev, double_stencils_out);
00685   }
00686   double Give_interior_here(const P_interior* it_i, const Grid* grid,
00687                             double h_mesh,
00688                             int l, double_stencils_in) const {
00689 
00690     Index3D I;
00691 
00692     I = it_i->Ind();
00693 
00694     if(I.I_x().Tiefe()==l) {
00695       if(I.I_y().Tiefe()==l) {
00696         if(I.I_z().Tiefe()==l) {
00697           // middle point
00698           // edge between EST-WND
00699           return 0.5 *
00700             (it_i->var_coarse_EST(grid,l)[v_.Number_variable()] +
00701              it_i->var_coarse_WND(grid,l)[v_.Number_variable()]);
00702         }
00703         else {
00704           // TD-surface
00705           // edge between ES-WN
00706           return 0.5 *
00707             (it_i->var_coarse_ES(grid,l)[v_.Number_variable()] +
00708              it_i->var_coarse_WN(grid,l)[v_.Number_variable()]);
00709         }
00710       }
00711       else {
00712         if(I.I_z().Tiefe()==l) {
00713           // NS-surface
00714           // edge between WT-ED
00715           return 0.5 *
00716             (it_i->var_coarse_WT(grid,l)[v_.Number_variable()] +
00717              it_i->var_coarse_ED(grid,l)[v_.Number_variable()]);
00718         }
00719         else {
00720           // EW-edge
00721           return 0.5 *
00722             (it_i->var_coarse_E(grid,l)[v_.Number_variable()] +
00723              it_i->var_coarse_W(grid,l)[v_.Number_variable()]);
00724         }
00725       }
00726     }
00727     else {
00728       if(I.I_y().Tiefe()==l) {
00729         if(I.I_z().Tiefe()==l) {
00730           // EW-surface
00731           // edge between ST-ND
00732           return 0.5 *
00733             (it_i->var_coarse_ST(grid,l)[v_.Number_variable()] +
00734              it_i->var_coarse_ND(grid,l)[v_.Number_variable()]);
00735         }
00736         else {
00737           // NS-edge
00738           return 0.5 *
00739             (it_i->var_coarse_N(grid,l)[v_.Number_variable()] +
00740              it_i->var_coarse_S(grid,l)[v_.Number_variable()]);
00741         }
00742       }
00743       else {
00744         if(I.I_z().Tiefe()==l) {
00745           // TD-edge
00746           return 0.5 *
00747             (it_i->var_coarse_T(grid,l)[v_.Number_variable()] +
00748              it_i->var_coarse_D(grid,l)[v_.Number_variable()]);
00749         }
00750         else {
00751           // idem-point
00752           return it_i->var_coarse_M(grid,l)[v_.Number_variable()];
00753         }
00754       }
00755     }
00756 
00757   };
00758 
00759   double Give_nearb(const P_nearb* it_n, const Grid* grid, double h_mesh,
00760                     int l, const Nearb_Ablage* nearb_ablage) const {
00761 
00762     // return 0.0;
00763     return Give_at_Index(it_n->Ind(),grid,l);
00764   };
00765 
00766   double Give_cellpoi(const P_cellpoi* it_cf, const Grid* gr,
00767                       const BoCeData* bocedata) const {
00768     double* UU;
00769     Index3D Inext;
00770     D3vector Co;
00771     bool cell_point_in_space;
00772 
00773     // return 0.0;
00774 
00775     UU = gr->Give_vector_ablage();
00776 
00777     if(v_.run_boundary()==1) {
00778       // Neumann boundary condition
00779       cell_point_in_space = true;
00780     }
00781     else if(v_.run_boundary()==0) {
00782       // Dirichlet boundary condition
00783       cell_point_in_space = false;
00784     }
00785     else {
00786       // mixed boundary condition
00787       if(bocedata->Is_Dirichlet(-v_.run_boundary()))
00788         cell_point_in_space = false;
00789       else 
00790         cell_point_in_space = true;
00791     }
00792     
00793     if(cell_point_in_space) {
00794       // Neumann boundary condition
00795       for(int i=0;i<8;++i) {
00796         Inext = it_cf->Ind().neighbour((dir_sons)i);
00797         UU[i] = Give_at_Index(Inext,gr,it_cf->Ind().Tiefe()-1);
00798       }
00799     }
00800     else {
00801       // Dirichlet boundary condition
00802       for(int i=0;i<8;++i) {
00803         Inext = it_cf->Ind().neighbour((dir_sons)i);
00804         if(gr->Grid_point_on_finest_level(Inext))
00805           UU[i] = Give_at_Index(Inext,gr,it_cf->Ind().Tiefe()-1);
00806         else 
00807           UU[i] = 0.0;
00808       }
00809     }
00810 
00811     Co = bocedata->Coord_bocellpoint_normal();
00812         
00813     return
00814       // (UU[0] + UU[1] + UU[2] + UU[3] +
00815       // UU[4] + UU[5] + UU[6] + UU[7] ) * 0.125 * 
00816       (UU[WSDd] * (1.0 - Co.x) * (1.0 - Co.y) * (1.0 - Co.z) +
00817        UU[ESDd] *        Co.x  * (1.0 - Co.y) * (1.0 - Co.z) +
00818        UU[WNDd] * (1.0 - Co.x) *         Co.y * (1.0 - Co.z) +
00819        UU[ENDd] *        Co.x  *         Co.y * (1.0 - Co.z) +
00820        UU[WSTd] * (1.0 - Co.x) * (1.0 - Co.y) *        Co.z  +
00821        UU[ESTd] *        Co.x  * (1.0 - Co.y) *        Co.z  +
00822        UU[WNTd] * (1.0 - Co.x) *         Co.y *        Co.z  +
00823        UU[ENTd] *        Co.x  *         Co.y *        Co.z);
00824   };
00825 
00826   double Give_Bo2p(const P_Bo2p* it_b, const Grid* gr,int l)  const {
00827     double a,b;
00828     
00829     a = Give_at_Index(it_b->Ind(),gr,l);
00830     b = Give_at_Index(it_b->Ind().next(it_b->d(),l),gr,l);
00831     
00832     return 
00833       (a + 
00834        gr->Give_h(it_b->Ind(),it_b->d()) / gr->Give_finest_mesh_size()
00835        * (b-a));
00836   };
00837 
00838   // Size of necessary stencil
00839   int Sice_stencil() const { return 15; }
00840 
00841   // activity of points
00842   int Level() const { return (v_).Level()+1; }
00843   Dominace_label Dominant_lev() const { return yes_dominant; }
00844   Dominace_label Dominant_poi() const { return yes_dominant; }
00845   bool run_interior() const { return (v_).run_interior(); }
00846   bool run_nearb()    const { return (v_).run_nearb(); }
00847   int run_boundary() const { return (v_).run_boundary(); }
00848 
00849   // number of operations
00850   int ops_interior() const { return 2; }
00851 
00852   // For operator ==
00853   void Active_Sim_Level( int lev) const {  };
00854   void Active_Sim_interior(bool run) const {  };
00855   void Active_Sim_nearb(bool run) const {  };
00856   void Active_Sim_boundary( int run) const {  };
00857   void Active_Sim_update(Evaluation_Parallelization_object* evpar,
00858                          int level, type_of_update typ) const {  };
00859 
00860   // Put pointer to grid and activity of boundary points of test space  
00861   void Put_grid_rbo(Grid* gr, int r_bo) const { };
00862   // Is the expression an abstract differential operator?
00863   Differential_op_typ Abstract_differential_operator() const
00864     { return not_abstract; }
00865   // for Parallelization
00866   void Add_variables_for_parallel(Evaluation_Parallelization_object *evpar) 
00867     const {
00868     evpar->Variable_contained_in_expression_other(v_.Number_variable());
00869     evpar->Other_is_coarse();
00870   }
00871   bool GS_type(int var_number_left, int dim) const {
00872     return false; 
00873   };
00874 
00875   // at the and of an iteration of an expression
00876   void clean() const { };
00877 
00878  private:
00879   Variable v_;
00880   double **Stencil;
00881 
00882   double Give_at_Index(const Index3D I, const Grid* grid, int l) const;
00883 };
00884 
00885 
00886 /* Unary operator */
00887 
00888 DExpr<DVar_Prol_Op>
00889 Prolongation_FE(Variable a);
00890 
00891 
00892 #endif
00893 
00894            

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