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

src/expde/formulas/diffop.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 // diffop.h
00019 //
00020 // ------------------------------------------------------------
00021 
00022 // -----------------------------------------------------------
00023 //    FFFF    OO     RR     M     M   EEEE  L     N     N
00024 //    F      O  O    R R    M M M M   E     L     N N   N
00025 //    FFF    O  O    RR     M  M  M   EEEE  L     N  N  N
00026 //    F      O  O    R R    M     M   E     L     N   N N
00027 //    F       OO     R  R   M     M   EEEE  LLLL  N     N
00028 // -----------------------------------------------------------
00029 
00031 // 1.:  lokale Randzellen-Matrizen
00032 // 2.:  Boundary operators
00034 
00035 
00036 #ifndef DIFFOP_H_
00037 #define DIFFOP_H_
00038                  
00039 
00040 #define XM0 tet->Xm0
00041 #define YM0 tet->Ym0
00042 #define ZM0 tet->Zm0
00043 
00044 #define XM1 tet->Xm1
00045 #define YM1 tet->Ym1
00046 #define ZM1 tet->Zm1
00047 
00048 #define XM2 tet->Xm2
00049 #define YM2 tet->Ym2
00050 #define ZM2 tet->Zm2
00051 
00052 #define XM3 tet->Xm3
00053 #define YM3 tet->Ym3
00054 #define ZM3 tet->Zm3
00055 
00056 
00057 #define UU0  bocedata->vars[tet->N0()][num_variable]
00058 #define UU1  bocedata->vars[tet->N1()][num_variable]
00059 #define UU2  bocedata->vars[tet->N2()][num_variable]
00060 #define UU3  bocedata->vars[tet->N3()][num_variable]
00061 
00062 #define UAA0 U_array[tet->N0()]
00063 #define UAA1 U_array[tet->N1()]
00064 #define UAA2 U_array[tet->N2()]
00065 #define UAA3 U_array[tet->N3()]
00066 
00067 #define Coefficient_triangle  (bocedata->vars[tet->N0()][num_coefficient]+bocedata->vars[tet->N1()][num_coefficient]+bocedata->vars[tet->N2()][num_coefficient]+bocedata->vars[tet->N3()][num_coefficient])/4.0
00068 
00070      // 1.: lokale Randzellen-Matrizen
00072 
00073 // definiert in boundary.h
00074 
00075 
00076 
00077 
00079 
00080 
00082    // 2.:  interpolation operators
00084 
00085 
00086 /*
00087 // interpolation operator for Zellfreiheitsgrad
00088 inline double BoCeData::Interpolation_interior_corners(double *UU) const {
00089 
00091 
00092   cout << " weg! " << endl;
00093 
00094 
00095   return 1.0;
00096 };
00097 
00098 // weight for Zellfreiheitsgrad
00099 inline double BoCeData::Weight_bocellpoint() const {
00100   int anz, i;
00101 
00102   // arithmetic middle
00103   anz = 0;
00104   for(i=0;i<number_points;++i) {
00105     if(edge_point(i)==corner_poi_typ) {
00106       ++anz;
00107     }
00108   }
00109   if(developer_version) {
00110     if(anz==0) cout << "Error in BoCeData::Interpolation_interior_corners! "
00111                     << endl;
00112   }
00113   return 1.0 / anz;
00114 };
00115 
00116 
00117 
00118 //  alless weggggggggggggggggggg::
00119 inline void BoCeData::Nodal_vector_Dirichlet(double *UN, dir_sons i) const {
00120   int k, anz;
00121   // Calculate UN
00122   // a) corner and edge points
00123   anz = 0;
00124   for(k=0;k<number_points;++k) { 
00125     if(edge_point(k) == corner_poi_typ) ++anz;
00126     if(edge_point(k) == corner_poi_typ && corner(k) == i) {
00127       UN[k]=1.0;
00128     }
00129     else UN[k]=0.0;
00130   }
00131   // b) Zellfreiheitsgrad
00132   // arithmetic middle
00133   UN[number_points] = 1.0/ anz;
00134   if(developer_version) {
00135     if(anz==0) cout << "Error in BoCeData::Nodal_vector_Dirichlet! "
00136                     << endl;
00137   }
00138 }
00139 
00140 inline void BoCeData::Nodal_vector_Neumann(double *UN, dir_sons i) const {
00141   int k, anz;
00142   // Calculate UN
00143   // a) corner and edge points
00144   anz=0;
00145   for(k=0;k<number_points;++k) {
00146     if(edge_point(k) == corner_poi_typ) ++anz;
00147     if((corner(k) == i) &&
00148        (edge_point(k) == corner_poi_typ || edge_point(k) == edge_poi_typ)) {
00149       UN[k]=1.0;
00150     }
00151     else UN[k]=0.0;
00152   }
00153 
00154   // b) Zellfreiheitsgrad
00155   // arithmetic middle
00156   UN[number_points] = 1.0/ anz;
00157   if(developer_version) {
00158     if(anz==0) cout << "Error in BoCeData::Nodal_vector_Neumann! "
00159                     << endl;
00160   }
00161 }
00162 
00163 inline void BoCeData::Nodal_vector_Mixed(double *UN, dir_sons i,
00164                                          bool* label_on_cell) const {
00165   int k, anz;
00166   // Calculate UN
00167   // a) corner and edge points
00168   anz=0;
00169   for(k=0;k<number_points;++k) {
00170     if(edge_point(k) == corner_poi_typ) ++anz;
00171     if((corner(k) == i) &&
00172        (edge_point(k) == corner_poi_typ ||
00173         (edge_point(k) == edge_poi_typ  && label_on_cell[k] ))) {
00174       UN[k]=1.0;
00175     }
00176     else UN[k]=0.0;
00177   }
00178 
00179   // b) Zellfreiheitsgrad
00180   // arithmetic middle
00181   UN[number_points] = 1.0/ anz;
00182 }
00183 */
00184 
00186 // 2. boundary operators
00188 
00189 // L2 Integration
00190 class L2boundary_const {
00191  public:
00192   diff_type typ_u() { return  Helm_type; }; 
00193   diff_type typ_v() { return  Helm_type; };
00194 
00195   L2boundary_const() { }
00196   static inline int    ops_interior() { return 0; }
00197   static inline int    ops_diag_interior() { return 0; }
00198   static inline double stencil(double uN,
00199                                double uW, double uM, double uO,
00200                                double uS, double uT, double uD,
00201                                double uND, double uWN, double uWT,
00202                                double uED, double uST, double uES,
00203                                double uEST, double uWND,
00204                                double h_mesh) {
00205     return 0.0;
00206   }
00207   static inline double diag_stencil(double h_mesh) {
00208     return 0.0;
00209   }
00210   static inline double F_reg_cell(double*const * u_Recell, int num_var,
00211                                   dir_sons dir_v,
00212                                   double h_mesh, double* sten) {
00213     return 0.0;
00214   }
00215   static inline double Factor_reg_cell(double h_mesh) {
00216     return 0.0;
00217   }
00218   static inline double diag_F_reg_cell(dir_sons dir_v,
00219                                        double h_mesh, double* sten) {
00220     return 0.0;
00221   }
00222 
00223   // Operator applied to variable with number
00224   static inline double F_bo_cell(const BoCeData* bocedata,
00225                                  int num_v, int num_variable) {
00226     static double sum;
00227     Tetraeder_storage* tet;
00228     
00229     if(bocedata->edge_point(num_v)!=edge_poi_typ) return 0.0;
00230     else {
00231       sum=0.0;
00232       for(tet=bocedata->Give_boundary_tets();tet!=NULL;tet=tet->Next()) {
00233         if(tet->N0()==num_v) {
00234           sum = sum + tet->Give_det_surface() *
00235             (2.0 * UU0 + UU1 + UU2) / 24.0;
00236         }
00237         else if(tet->N1()==num_v) {
00238           sum = sum + tet->Give_det_surface() *
00239             (2.0 * UU1 + UU0 + UU2) / 24.0;
00240         }
00241         else if(tet->N2()==num_v) {
00242           sum = sum + tet->Give_det_surface() *
00243             (2.0 * UU2 + UU0 + UU1) / 24.0;
00244         }
00245       }  
00246       return sum;
00247     }
00248   }
00249   static inline double Local_matrix_bo_cell(const BoCeData* bocedata,
00250                                           double*  U_array, int num_v) {
00251     static double sum;
00252     Tetraeder_storage* tet;
00253     
00254     if(bocedata->edge_point(num_v)!=edge_poi_typ) return 0.0;
00255     else {
00256       sum=0.0;
00257       for(tet=bocedata->Give_boundary_tets();tet!=NULL;tet=tet->Next()) {
00258         if(tet->N0()==num_v) {
00259           sum = sum + tet->Give_det_surface() *
00260             (2.0 * UAA0 + UAA1 + UAA2) / 24.0;
00261         }
00262         else if(tet->N1()==num_v) {
00263           sum = sum + tet->Give_det_surface() *
00264             (2.0 * UAA1 + UAA0 + UAA2) / 24.0;
00265         }
00266         else if(tet->N2()==num_v) {
00267           sum = sum + tet->Give_det_surface() *
00268             (2.0 * UAA2 + UAA0 + UAA1) / 24.0;
00269         }
00270       }  
00271       return sum;
00272     }
00273   }
00274   static inline double diag_F_bo_cell(const BoCeData* bocedata,
00275                                       int num_v) {
00276     static double sum;
00277     Tetraeder_storage* tet;
00278     
00279     if(bocedata->edge_point(num_v)!=edge_poi_typ) return 0.0;
00280     else {
00281       sum=0.0;
00282       for(tet=bocedata->Give_boundary_tets();tet!=NULL;tet=tet->Next()) {
00283         if(tet->N0()==num_v) {
00284           sum = sum + tet->Give_det_surface() / 12.0;
00285         }
00286         else if(tet->N1()==num_v) {
00287           sum = sum + tet->Give_det_surface() / 12.0;
00288         }
00289         else if(tet->N2()==num_v) {
00290           sum = sum + tet->Give_det_surface() / 12.0;
00291         }
00292       }  
00293       return sum;
00294     }
00295   }
00296 };
00297 
00298 
00299 // L2 Integration variable
00300 class L2boundary_variable {
00301  public:
00302   diff_type typ_u() { return  Helm_type; }; 
00303   diff_type typ_v() { return  Helm_type; };
00304 
00305   L2boundary_variable() { }
00306   static inline int    ops_interior() { return 0; }
00307   static inline int    ops_diag_interior() { return 0; }
00308   static inline double stencil(double uN,
00309                                double uW, double uM, double uE,
00310                                double uS, double uT, double uD,
00311                                double uND, double uWN, double uWT,
00312                                double uED, double uST, double uES,
00313                                double uEST, double uWND,
00314                                double aN,
00315                                double aW, double aM, double aE,
00316                                double aS, double aT, double aD,
00317                                double aST, double aET, double aES,
00318                                double aND, double aWD, double aWN,
00319                                double aEST, double aWND,
00320                                double h_mesh) {
00321     return 0.0;
00322   }
00323   static inline double diag_stencil(double h_mesh,
00324                                     double aN,
00325                                     double aW, double aM, double aE,
00326                                     double aS, double aT, double aD,
00327                                     double aST, double aET, double aES,
00328                                     double aND, double aWD, double aWN,
00329                                     double aEST, double aWND) {
00330     return 0.0;
00331   }
00332   static inline double F_reg_cell(double*const * u_Recell, int num_var,
00333                                   dir_sons dir_v,
00334                                   double h_mesh, double* sten) {
00335     return 0.0;
00336   }
00337   static inline double Factor_reg_cell(double h_mesh) {
00338     return 0.0;
00339   }
00340   static inline double diag_F_reg_cell(dir_sons dir_v,
00341                                        double h_mesh, double* sten) {
00342     return 0.0;
00343   }
00344 
00345   // Operator applied to variable with number
00346   static inline double F_bo_cell(const BoCeData* bocedata,
00347                                  int num_v, int num_variable,
00348                                  int num_coefficient) {
00349     static double sum;
00350     Tetraeder_storage* tet;
00351     
00352     if(bocedata->edge_point(num_v)!=edge_poi_typ) return 0.0;
00353     else {
00354       sum=0.0;
00355       for(tet=bocedata->Give_boundary_tets();tet!=NULL;tet=tet->Next()) {
00356         if(tet->N0()==num_v) {
00357           sum = sum + tet->Give_det_surface() *
00358             (2.0 * UU0 + UU1 + UU2) / 24.0 * Coefficient_triangle;
00359         }
00360         else if(tet->N1()==num_v) {
00361           sum = sum + tet->Give_det_surface() *
00362             (2.0 * UU1 + UU0 + UU2) / 24.0 * Coefficient_triangle;
00363         }
00364         else if(tet->N2()==num_v) {
00365           sum = sum + tet->Give_det_surface() *
00366             (2.0 * UU2 + UU0 + UU1) / 24.0 * Coefficient_triangle;
00367         }
00368       }  
00369       return sum;
00370     }
00371   }
00372   static inline double Local_matrix_bo_cell(const BoCeData* bocedata,
00373                                             double*  U_array, int num_v,
00374                                             int num_coefficient) {
00375     static double sum;
00376     Tetraeder_storage* tet;
00377     
00378     if(bocedata->edge_point(num_v)!=edge_poi_typ) return 0.0;
00379     else {
00380       sum=0.0;
00381       for(tet=bocedata->Give_boundary_tets();tet!=NULL;tet=tet->Next()) {
00382         if(tet->N0()==num_v) {
00383           sum = sum + tet->Give_det_surface() *
00384             (2.0 * UAA0 + UAA1 + UAA2) / 24.0 * Coefficient_triangle;
00385         }
00386         else if(tet->N1()==num_v) {
00387           sum = sum + tet->Give_det_surface() *
00388             (2.0 * UAA1 + UAA0 + UAA2) / 24.0 * Coefficient_triangle;
00389         }
00390         else if(tet->N2()==num_v) {
00391           sum = sum + tet->Give_det_surface() *
00392             (2.0 * UAA2 + UAA0 + UAA1) / 24.0 * Coefficient_triangle;
00393         }
00394       }  
00395       return sum;
00396     }
00397   }
00398   static inline double diag_F_bo_cell(const BoCeData* bocedata,
00399                                       int num_v, int num_coefficient) {
00400     static double sum;
00401     Tetraeder_storage* tet;
00402     
00403     if(bocedata->edge_point(num_v)!=edge_poi_typ) return 0.0;
00404     else {
00405       sum=0.0;
00406       for(tet=bocedata->Give_boundary_tets();tet!=NULL;tet=tet->Next()) {
00407         if(tet->N0()==num_v) {
00408           sum = sum + tet->Give_det_surface() / 12.0 * Coefficient_triangle;
00409         }
00410         else if(tet->N1()==num_v) {
00411           sum = sum + tet->Give_det_surface() / 12.0 * Coefficient_triangle;
00412         }
00413         else if(tet->N2()==num_v) {
00414           sum = sum + tet->Give_det_surface() / 12.0 * Coefficient_triangle;
00415         }
00416       }  
00417       return sum;
00418     }
00419   }
00420 };
00421 
00422 #endif
00423         

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