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

src/expde/formulas/res_sten.cc

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_sten.cc
00019 //
00020 // ------------------------------------------------------------
00021 
00022 // Include level 0:
00023 #ifdef COMP_GNUOLD
00024  #include <iostream.h>
00025  #include <fstream.h>
00026  #include <math.h>
00027 #else
00028  #include <iostream>
00029  #include <fstream>
00030  #include <cmath>
00031 #endif 
00032 
00033 
00034 // Include level 1:
00035 #include "../paramete.h"
00036 #include "../abbrevi.h"
00037 #include "../math_lib/math_lib.h"
00038 
00039 // Include level special
00040 #include "../formulas/loc_sten.h"
00041 
00042 
00044 // This file contains the restriction formula for
00045 // local 64- Stiffness matrices
00046 // 1. formula for interior points
00047 // 2. formula for boundary points
00049 
00050 
00051 // 1. formula for interior points
00053 
00054 
00055 inline int number_coarse(dir_sons i) {
00056   return trans_cellP_27(i,i);
00057 }
00058 
00059 void Set_coarse_function(int* U, dir_sons v) {
00060   int k, trans, d;
00061   dir_sons next;
00062 
00063 
00064   // part 0: set zero
00065   //--------
00066   for(k=0;k<27;++k) U[k]=0;
00067 
00068   // part 1: corners of coarse cell
00069   //--------
00070   for(k=0;k<8;++k) { // iteration over cells
00071     if(k==v) U[number_coarse((dir_sons)k)]=2;
00072     else     U[number_coarse((dir_sons)k)]=0;
00073   }
00074 
00075   // part 2: middle of coarse cell
00076   //--------
00077   U[trans27(MOrt,MOrt,MOrt)] = (U[number_coarse(ESTd)] +
00078                                 U[number_coarse(WNDd)]) / 2;
00079 
00080   // part 3: faces of coarse cell
00081   //--------
00082   // TD-surface
00083   // edge between ES-WN
00084   U[trans27(MOrt,MOrt,LOrt)] = (U[number_coarse(ESDd)] +
00085                                 U[number_coarse(WNDd)]) / 2;
00086   U[trans27(MOrt,MOrt,ROrt)] = (U[number_coarse(ESTd)] +
00087                                 U[number_coarse(WNTd)]) / 2;
00088   // NS-surface
00089   // edge between WT-ED
00090   U[trans27(MOrt,LOrt,MOrt)] = (U[number_coarse(WSTd)] +
00091                                 U[number_coarse(ESDd)]) / 2;
00092   U[trans27(MOrt,ROrt,MOrt)] = (U[number_coarse(WNTd)] +
00093                                 U[number_coarse(ENDd)]) / 2;
00094   // EW-surface
00095   // edge between ST-ND
00096   U[trans27(LOrt,MOrt,MOrt)] = (U[number_coarse(WSTd)] +
00097                                 U[number_coarse(WNDd)]) / 2;
00098   U[trans27(ROrt,MOrt,MOrt)] = (U[number_coarse(ESTd)] +
00099                                 U[number_coarse(ENDd)]) / 2;
00100 
00101   // part 4: edges of coarse cell
00102   //--------
00103   for(k=0;k<8;++k) { // iteration over cells
00104     for(d=0;d<3;++d) {  // iteration over directions
00105       next = Next_corner((dir_sons)k,(dir_3D)(2*d));
00106       trans = trans_cellP_27((dir_sons)k,next);
00107       U[trans] = U[trans] + U[number_coarse((dir_sons)k)] / 2;
00108     }
00109   }
00110 }
00111 
00112 
00113 void Restrict_local_stiffness_matrix(double*  Stencil_coarse,
00114                                      double** Stencils_fine,
00115                                      int* coarse_grid_functions) {
00116 
00117   int i,j,k,l,m;
00118   int* v_function;
00119   int* u_function;
00120   int u_f, v_f;
00121 
00122   // 1.Part: Set zero
00123   for(i=0;i<8;++i) for(j=0;j<8;++j) Stencil_coarse[j+8*i] = 0.0;
00124   
00125   // 2.Part: Iterate
00126   for(i=0;i<8;++i) { // iteration for U
00127     u_function = &(coarse_grid_functions[i*27]);
00128     for(j=0;j<8;++j) { // iteration for V
00129       v_function = &(coarse_grid_functions[j*27]);
00130       for(k=0;k<8;++k) { // iteration over cells
00131         for(l=0;l<8;++l) { // iteration over corners of cell for U
00132           u_f = u_function[trans_cellP_27((dir_sons)k,(dir_sons)l)];
00133           if(u_f != 0) for(m=0;m<8;++m) { // iteration over corners of cell for V
00134             v_f = v_function[trans_cellP_27((dir_sons)k,(dir_sons)m)];
00135             if(v_f!=0)
00136               Stencil_coarse[j+8*i] = Stencil_coarse[j+8*i] +
00137                 (double)u_f * (double)v_f * 0.25 *
00138                 Stencils_fine[k][m+8*l];
00139           }
00140         }
00141       }
00142     }
00143   }
00144 
00145 }
00146 
00147 
00148 
00149 
00150 // 2. formula for boundary points
00152 
00153 
00154 // cid: corner in domain
00155 void Set_coarse_function(double U[27], dir_sons v, bool* cid) {
00156   int i,j,k;
00157   dir_sons corner;
00158   int anz;
00159   double sum;
00160 
00161   // part 0: set zero
00162   //--------
00163   for(k=0;k<27;++k) U[k]=0.0;
00164 
00165   // part 1: corners of coarse cell
00166   //--------
00167   for(k=0;k<8;++k) { // iteration over cells
00168     if(k==v) U[number_coarse((dir_sons)k)]=1.0;
00169     else     U[number_coarse((dir_sons)k)]=0.0;
00170   }
00171 
00172   // part 2: middle of coarse cell
00173   //--------
00174   anz = 0;
00175   for(i=0;i<2;++i) for(j=0;j<2;++j) for(k=0;k<2;++k) {
00176     corner = dir_sons_from_three_LR((dir1D)i,(dir1D)j,(dir1D)k);
00177     if(cid[corner]) {
00178       ++anz;
00179       U[trans27(MOrt,MOrt,MOrt)] +=
00180         U[number_coarse(corner)];
00181     }
00182   }
00183   if(anz!=0) U[trans27(MOrt,MOrt,MOrt)] = U[trans27(MOrt,MOrt,MOrt)] / anz;
00184   else       U[trans27(MOrt,MOrt,MOrt)] = 0.0;
00185 
00186   // part 3: faces of coarse cell
00187   //--------
00188   // part 3.1: interpolation for a interior face
00189   //----------
00190   // TD-surface
00191   // edge between ES-WN
00192   U[trans27(MOrt,MOrt,LOrt)] = 0.5*(U[number_coarse(ESDd)] +
00193                                     U[number_coarse(WNDd)]);
00194   U[trans27(MOrt,MOrt,ROrt)] = 0.5*(U[number_coarse(ESTd)] +
00195                                     U[number_coarse(WNTd)]);
00196   // NS-surface
00197   // edge between WT-ED
00198   U[trans27(MOrt,LOrt,MOrt)] = 0.5*(U[number_coarse(WSTd)] +
00199                                     U[number_coarse(ESDd)]);
00200   U[trans27(MOrt,ROrt,MOrt)] = 0.5*(U[number_coarse(WNTd)] +
00201                                     U[number_coarse(ENDd)]);
00202   // EW-surface
00203   // edge between ST-ND
00204   U[trans27(LOrt,MOrt,MOrt)] = 0.5*(U[number_coarse(WSTd)] +
00205                                     U[number_coarse(WNDd)]);
00206   U[trans27(ROrt,MOrt,MOrt)] = 0.5*(U[number_coarse(ESTd)] +
00207                                     U[number_coarse(ENDd)]);
00208   // part 3.2: interpolation at a face near the boundary
00209   // TD-surface
00210   for(k=0;k<2;++k) {
00211     anz=0;
00212     sum=0.0;
00213     for(i=0;i<2;++i) for(j=0;j<2;++j) {
00214       corner = dir_sons_from_three_LR((dir1D)i,(dir1D)j,(dir1D)k);
00215       if(cid[corner]) {
00216         ++anz;
00217         sum += U[number_coarse(corner)];
00218       }
00219     }
00220     if(anz!=0) {
00221       if(anz!=4) // overwrite 3.1
00222         U[trans27(MOrt,MOrt,(Ort1D)(2*k))] = sum / anz;
00223     }
00224     else U[trans27(MOrt,MOrt,(Ort1D)(2*k))] = 0.0;
00225   }
00226   // NS-surface
00227   for(j=0;j<2;++j) {
00228     anz=0;
00229     sum=0.0;
00230     for(i=0;i<2;++i) for(k=0;k<2;++k) {
00231       corner = dir_sons_from_three_LR((dir1D)i,(dir1D)j,(dir1D)k);
00232       if(cid[corner]) {
00233         ++anz;
00234         sum += U[number_coarse(corner)];
00235       }
00236     }
00237     if(anz!=0) {
00238       if(anz!=4)  // overwrite 3.1
00239         U[trans27(MOrt,(Ort1D)(2*j),MOrt)] = sum / anz;
00240     }
00241     else U[trans27(MOrt,(Ort1D)(2*j),MOrt)] = 0.0;
00242   }
00243   // EW-surface
00244   for(i=0;i<2;++i) {
00245     anz=0;
00246     sum=0.0;
00247     for(j=0;j<2;++j) for(k=0;k<2;++k) {
00248       corner = dir_sons_from_three_LR((dir1D)i,(dir1D)j,(dir1D)k);
00249       if(cid[corner]) {
00250         ++anz;
00251         sum += U[number_coarse(corner)];
00252       }
00253     }
00254     if(anz!=0) {
00255       if(anz!=4)  // overwrite 3.1
00256         U[trans27((Ort1D)(2*i),MOrt,MOrt)] = sum / anz;
00257     }
00258     else U[trans27((Ort1D)(2*i),MOrt,MOrt)] = 0.0;
00259   }
00260 
00261   // part 4: edges of coarse cell
00262   //--------
00263   // EW-edges
00264   for(j=0;j<2;++j) for(k=0;k<2;++k) {
00265     anz=0;
00266     for(i=0;i<2;++i) {
00267       corner = dir_sons_from_three_LR((dir1D)i,(dir1D)j,(dir1D)k);
00268       if(cid[corner]) {
00269         ++anz;
00270         U[trans27(MOrt,(Ort1D)(2*j),(Ort1D)(2*k))] +=
00271           U[number_coarse(corner)];
00272       }
00273     }
00274     if(anz!=0) 
00275       U[trans27(MOrt,(Ort1D)(2*j),(Ort1D)(2*k))] = 
00276         U[trans27(MOrt,(Ort1D)(2*j),(Ort1D)(2*k))] / anz;
00277     else U[trans27(MOrt,(Ort1D)(2*j),(Ort1D)(2*k))] = 0.0;
00278   }
00279 
00280   // NS-edges
00281   for(i=0;i<2;++i) for(k=0;k<2;++k) {
00282     anz=0;
00283     for(j=0;j<2;++j) {
00284       corner = dir_sons_from_three_LR((dir1D)i,(dir1D)j,(dir1D)k);
00285       if(cid[corner]) {
00286         ++anz;
00287         U[trans27((Ort1D)(2*i),MOrt,(Ort1D)(2*k))] +=
00288           U[number_coarse(corner)];
00289       }
00290     }
00291     if(anz!=0) {
00292       U[trans27((Ort1D)(2*i),MOrt,(Ort1D)(2*k))] = 
00293         U[trans27((Ort1D)(2*i),MOrt,(Ort1D)(2*k))] / anz;
00294     }
00295     else U[trans27((Ort1D)(2*i),MOrt,(Ort1D)(2*k))] = 0.0;
00296   }
00297 
00298   // TD-edges
00299   for(i=0;i<2;++i) for(j=0;j<2;++j) {
00300     anz=0;
00301     for(k=0;k<2;++k) {
00302       corner = dir_sons_from_three_LR((dir1D)i,(dir1D)j,(dir1D)k);
00303       if(cid[corner]) {
00304         ++anz;
00305         U[trans27((Ort1D)(2*i),(Ort1D)(2*j),MOrt)] +=
00306           U[number_coarse(corner)];
00307       }
00308     }
00309     if(anz!=0)
00310       U[trans27((Ort1D)(2*i),(Ort1D)(2*j),MOrt)] = 
00311         U[trans27((Ort1D)(2*i),(Ort1D)(2*j),MOrt)] / anz;
00312     else U[trans27((Ort1D)(2*i),(Ort1D)(2*j),MOrt)] = 0.0;
00313   }
00314 }
00315 
00316 void Restrict_local_stiffness_matrix(double*  Stencil_coarse,
00317                                      double** Stencils_fine,
00318                                      bool* cid) {
00319 
00320   double Ucoarse[27];
00321   double Vcoarse[27];
00322   int i,j,k,l,m;
00323   int trans_l, trans_m;
00324   
00325   // 1.Part: Set zero
00326   for(i=0;i<8;++i) for(j=0;j<8;++j) Stencil_coarse[j+8*i] = 0.0;
00327   
00328   // 2.Part: Iterate
00329   for(i=0;i<8;++i) { // iteration for U
00330     Set_coarse_function(Ucoarse,(dir_sons)i,cid);
00331     for(j=0;j<8;++j) { // iteration for V
00332       Set_coarse_function(Vcoarse,(dir_sons)j,cid);
00333       for(k=0;k<8;++k) { // iteration over cells
00334         for(l=0;l<8;++l) { // iteration over corners of cell for U
00335           trans_l = trans_cellP_27((dir_sons)k,(dir_sons)l);
00336           for(m=0;m<8;++m) { // iteration over corners of cell for V
00337             trans_m = trans_cellP_27((dir_sons)k,(dir_sons)m);
00338             Stencil_coarse[j+8*i] = Stencil_coarse[j+8*i] +
00339               Ucoarse[trans_l] * Vcoarse[trans_m] * 
00340               Stencils_fine[k][m+8*l];
00341           }
00342         }
00343       }
00344     }
00345   }
00346 
00347 }
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 

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