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

src/expde/formulas/boundy.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 //
00019 // boundary.cc
00020 //
00021 // ------------------------------------------------------------
00022 
00023 // Include level 0:
00024 #ifdef COMP_GNUOLD
00025  #include <iostream.h>
00026  #include <fstream.h>
00027  #include <math.h>
00028 #else
00029  #include <iostream>
00030  #include <fstream>
00031  #include <cmath>
00032 #endif 
00033 
00034 // Include level 1:
00035 #include "../paramete.h"
00036 #include "../abbrevi.h"
00037 #include "../math_lib/math_lib.h"
00038 
00039 // Include level 4:
00040 #include "../formulas/boundy.h"
00041 #include "subdiv.h"
00042 
00043 
00044 
00045 
00046 // now in math_lib.h
00047 
00048 #define x0 V0.x
00049 #define y0 V0.y
00050 #define z0 V0.z
00051 
00052 #define x1 V1.x
00053 #define y1 V1.y
00054 #define z1 V1.z
00055 
00056 #define x2 V2.x
00057 #define y2 V2.y
00058 #define z2 V2.z
00059 
00060 #define x3 V3.x
00061 #define y3 V3.y
00062 #define z3 V3.z
00063 
00064 
00065 /*
00066 inline double Calc_det(const D3vector& V0, const D3vector& V1,
00067                        const D3vector& V2, const D3vector& V3) {
00068   return (x1*y2*z0 - 
00069           x1*y3*z0 - x0*y2*z1 + x0*y3*z1 - x1*y0*z2 + x0*y1*z2 - x0*y3*z2 + 
00070           x1*y3*z2 + x3*(y1*z0 - y2*z0 - y0*z1 + y2*z1 + y0*z2 - y1*z2) + 
00071           x1*y0*z3 - x0*y1*z3 + x0*y2*z3 - x1*y2*z3 + 
00072           x2*(y3*z0 + y0*z1 - y3*z1 - y0*z3 + y1*(-z0 + z3)));
00073 }
00074 */
00075 
00076 #define Wx (V0.x - V1.x)
00077 #define Wy (V0.y - V1.y)
00078 #define Wz (V0.z - V1.z)
00079 
00080 #define Vx (V0.x - V2.x)
00081 #define Vy (V0.y - V2.y)
00082 #define Vz (V0.z - V2.z)
00083 
00084 #define Vcrossx (Wy * Vz - Wz * Vy)
00085 #define Vcrossy (Wx * Vz - Wz * Vx)
00086 #define Vcrossz (Wy * Vx - Wx * Vy)
00087 
00088 inline double Calc_det_triangle(const D3vector& V0, const D3vector& V1,
00089                                 const D3vector& V2) {
00090   return sqrt(Vcrossx*Vcrossx + Vcrossy*Vcrossy + Vcrossz*Vcrossz);
00091 }
00092 
00093 void BoCeData::Set_h(double *h, Bo_description& desc) {
00094   int num;
00095 
00096   for(num=0;num<number_points;++num) {
00097     if(edge_point(num)==edge_poi_typ) {
00098       h[num] = desc.h(corner(num),edge_dir(num));
00099     }
00100   }
00101 
00102 
00103 }
00104 
00105 void BoCeData::Calc_FE_elements(Bo_description& desc) {
00106   Calculator_FE calculator;
00107   Tetraeder_storage* tet;
00108   double h[24];
00109   double deter;
00110   D3vector V0;
00111   D3vector V1;
00112   D3vector V2;
00113   D3vector V3;
00114   int num;
00115 
00116   // 1. Initialisierung: Informationen ueber Randzelle abspeichern
00117   Initialize(desc);
00118 
00119   // 2. Berechnung der Tetraeder
00120   calculator.Start(&desc,this);
00121   Act_on_subdivision(&desc,&calculator);
00122 
00123   // An letzten inneren Tet: Tets am Rand haengen.
00124   if(Tets!=NULL) {
00125     tet=Tets;
00126     if(tet->Next()!=NULL) {
00127       while(tet->Next()!=NULL) { tet=tet->Next(); }
00128     }
00129     tet->Put_Next(Tets_boundary);
00130   }
00131   else Tets = Tets_boundary;
00132 
00133 
00134   // 3. Berechnung der Determinante und lokaler Matrix der Tetraeder
00135   // Berechnung der Maschenweiten
00136   hhh = new double[number_points];
00137   for(num=0;num<number_points;++num) {
00138     if(edge_point(num)==edge_poi_typ) {
00139       h[num] = desc.h(corner(num),edge_dir(num));
00140       hhh[num] = h[num];
00141     }
00142   }
00143 
00144 
00145   
00146 
00147 
00148   
00149   for(tet=Tets;tet!=NULL;tet=tet->Next()) {
00150     // Berechnung der Koordinaten
00151     V0 = coord(tet->N0(),h);
00152     V1 = coord(tet->N1(),h);
00153     V2 = coord(tet->N2(),h);
00154     V3 = coord(tet->N3(),h);
00155 
00156     // Determinante
00157     deter = Calc_det(V0,V1,V2,V3);
00158     tet->Put_det(deter);
00159     if(developer_version) {
00160       if(deter < 0.0)
00161         cout << "\n Negatives Gewicht in Tet! " << endl;
00162     }
00163     // Speicher fuer lokale Matrix
00164     tet->Xm0 = y3 * (z1 - z2) + y1 * (z2 - z3) + y2 * (z3 - z1);
00165     tet->Xm1 = y3 * (z2 - z0) + y2 * (z0 - z3) + y0 * (z3 - z2);
00166     tet->Xm2 = y3 * (z0 - z1) + y0 * (z1 - z3) + y1 * (z3 - z0);
00167     tet->Xm3 = y2 * (z1 - z0) + y1 * (z0 - z2) + y0 * (z2 - z1);
00168     
00169     tet->Ym0 = x3 * (z2 - z1) + x2 * (z1 - z3) + x1 * (z3 - z2);
00170     tet->Ym1 = x3 * (z0 - z2) + x0 * (z2 - z3) + x2 * (z3 - z0);
00171     tet->Ym2 = x3 * (z1 - z0) + x1 * (z0 - z3) + x0 * (z3 - z1);
00172     tet->Ym3 = x2 * (z0 - z1) + x0 * (z1 - z2) + x1 * (z2 - z0);
00173 
00174     tet->Zm0 = x3 * (y1 - y2) + x1 * (y2 - y3) + x2 * (y3 - y1);
00175     tet->Zm1 = x3 * (y2 - y0) + x2 * (y0 - y3) + x0 * (y3 - y2);
00176     tet->Zm2 = x3 * (y0 - y1) + x0 * (y1 - y3) + x1 * (y3 - y0);
00177     tet->Zm3 = x2 * (y1 - y0) + x1 * (y0 - y2) + x0 * (y2 - y1);
00178 
00179     // Determinante ueber Randflaechen
00180     if(tet->Boundary_tet()) {
00181       tet->Put_det_surface(Calc_det_triangle(V0,V1,V2));
00182     }
00183   }
00184   // 4. Speicher fuer Liste der Zeiger auf Variablen initialisieren 
00185   if(Exists_bocellpoint())
00186     vars   = new double*[number_points+1];
00187   else
00188     vars   = new double*[number_points];
00189 
00190   // 5. Only for looking for a mistake
00191   // Analyse_angles(desc);
00192 }
00193 
00194 void BoCeData::Analyse_angles(Bo_description& desc) {
00195   Tetraeder_storage* tet;
00196   bool mistake;
00197   mistake = false;
00198   for(tet=Tets;tet!=NULL;tet=tet->Next()) {
00199     if(tet->Check_angles(&desc)==false) mistake=true;
00200   }
00201   if(mistake) {
00202     Print();
00203     for(tet=Tets;tet!=NULL;tet=tet->Next()) {
00204       if(tet->Check_angles(&desc)==false) {
00205         cout << "\n Corners of Tet with bad angles: " <<
00206           tet->N0() << ", " << 
00207           tet->N1() << ", " << 
00208           tet->N2() << ", " << 
00209           tet->N3() << ", " << endl;
00210       }
00211     }
00212     cout << "Meshsize: " << Meshsize() << endl;
00213   }
00214 }
00215 
00216 // Funktionen zum Testen:  muss spaeter wohl weg:
00217 void Bo_description::Test_Initialisierung() {
00218   H = 1.0;
00219 
00220  // Beispiel fuer einen Tetraeder bei der Ecke: WSDd
00221   /*
00222  cout << " Beispiel fuer einen Tetraeder bei der Ecke: WSDd \n";
00223  Put_corner_point(WSDd);
00224  Put_edge_point(WSDd,Edir,0.5);
00225  Put_edge_point(WSDd,Ndir,0.5);
00226  Put_edge_point(WSDd,Tdir,0.5);
00227   */
00228   
00229   /*
00230   // Beispiel fuer eine Kante im Gebiet
00231   cout << " Beispiel fuer eine Kante im Gebiet  \n";
00232   Put_corner_point(WSDd);
00233   Put_corner_point(WSTd);
00234 
00235   Put_edge_point(WSDd,Edir,0.5);
00236   Put_edge_point(WSDd,Ndir,0.5);
00237 
00238   Put_edge_point(WSTd,Edir,0.5);
00239   Put_edge_point(WSTd,Ndir,0.5);
00240   
00241   Put_edge(SWed);
00242   */
00243 
00244   // Beispiel fuer einen halben Wuerfel
00245   cout << " Beispiel fuer einen halben Wuerfel  \n";
00246   Put_corner_point(WSDd);
00247   Put_corner_point(WNDd);
00248   Put_corner_point(ESDd);
00249   Put_corner_point(ENDd);
00250 
00251   Put_edge_point(WSDd,Tdir,0.5);
00252   Put_edge_point(WNDd,Tdir,0.5);
00253   Put_edge_point(ESDd,Tdir,0.5);
00254   Put_edge_point(ENDd,Tdir,0.5);
00255   
00256   Put_edge(SDed);
00257   Put_edge(NDed);
00258   Put_edge(EDed);
00259   Put_edge(WDed);
00260 
00261 
00262   // Beispiel fuer zwei nicht zusammenhaengende Tetraeder
00263   /*
00264   cout << " Beispiel fuer zwei nicht zusammenhaengende Tetraeder \n";
00265   Put_corner_point(WSDd);
00266   Put_edge_point(WSDd,Edir,0.5);
00267   Put_edge_point(WSDd,Ndir,0.5);
00268   Put_edge_point(WSDd,Tdir,0.5);
00269 
00270   Put_corner_point(WNDd);
00271   Put_edge_point(WNDd,Edir,0.5);
00272   Put_edge_point(WNDd,Sdir,0.5);
00273   Put_edge_point(WNDd,Tdir,0.5);
00274 */
00275 }
00276 
00277 
00278 void BoCeData::Initialize(Bo_description& desc) {
00279   static int i,k,number;
00280 
00281   bocellpoint=NULL; 
00282 
00283   number=0;
00284   // 1. Anzahl der Eckpunkte und Kantenpunkte zaehlen
00285   for(i=0;i<8;++i)  if(desc.corner_point((dir_sons)i)) ++number;
00286   for(i=0;i<8;++i) for(k=0;k<3;++k) 
00287     if(desc.edge_point((dir_sons)i,(dir_3D)(k<<1))) ++number;
00288   // 2. Speicher bereitstellen
00289   Allocate(number);
00290 
00291   // 3. Informationen setzen
00292   desc.Set_num_cellpoi(number_points);
00293   number=0;
00294   for(i=0;i<8;++i)  if(desc.corner_point((dir_sons)i)) {
00295     Put_corner_point(number,(dir_sons)i);
00296     desc.Set_num_corner((dir_sons)i,number);
00297     ++number;
00298   }
00299   for(i=0;i<8;++i) {
00300     if(desc.edge_point((dir_sons)i,Wdir)) {
00301       Put_edge_point(number,(dir_sons)i,(dir_3D)((~i)&1));
00302       desc.Set_num_edge_poi((dir_sons)i,(dir_3D)((~i)&1),number);
00303       ++number;
00304     }
00305     if(desc.edge_point((dir_sons)i,Sdir)) {
00306       Put_edge_point(number,(dir_sons)i,(dir_3D)(2+(((~i)>>1)&1)));
00307       desc.Set_num_edge_poi((dir_sons)i,(dir_3D)(2+(((~i)>>1)&1)),number);
00308       ++number;
00309     }
00310     if(desc.edge_point((dir_sons)i,Ddir)) {
00311       Put_edge_point(number,(dir_sons)i,(dir_3D)(4+(((~i)>>2)&1)));
00312       desc.Set_num_edge_poi((dir_sons)i,(dir_3D)(4+(((~i)>>2)&1)),number);
00313       ++number;
00314     }
00315   }
00316   // 4. Maschenweite setzen
00317   Put_Meshsize(desc.Meshsize());
00318   // 5. Kanteninfo setzen
00319   Put_edge_info(desc.edge_info());
00320 
00321   // 5. Setz Zeiger auf Bocelldata
00322   desc.Put_bocedata(this);
00323 }
00324 
00325 
00326 
00327 // Funktion, die die Informationen der Randzelle ausdruckt
00328 void BoCeData::Print() {
00329   int i;
00330   cout << "\n 1.Teil: Punkte:";
00331   for(i=0;i<number_points;++i) {
00332     cout << "\n Nummer " << i;
00333     if(edge_point(i)) {
00334       cout << " ist Kantenpunkt bei Ecke: ";
00335       Print(corner(i));
00336       cout << " in Richtung: ";
00337       Print(edge_dir(i));
00338      }
00339     else {
00340       cout << " ist Eckpunkt    bei Ecke: ";
00341       Print(corner(i));
00342       cout << "                  ";
00343     }
00344   }
00345   cout << "\n 2.Teil: Kanten: \n ";
00346   for(i=0;i<12;++i) if(Edge((Edges_cell)i)) {
00347     cout << "Kante im Gebiet: ";
00348     Print((Edges_cell)i);
00349     cout << endl;
00350   }
00351   cout << endl;
00352 
00353   cout << " Determinante of tets: " << endl; 
00354   Tetraeder_storage* tet;
00355   for(tet=Give_tets();tet!=NULL;tet=tet->Next()) {
00356     cout << " Tet: det: "  << tet->Det() << endl;
00357   }
00358   cout << " Connection of tets: " << endl; 
00359   for(tet=Give_tets();tet!=NULL;tet=tet->Next()) {
00360     cout << " new tet num: " << endl;
00361     cout << tet->N0() << ", " << tet->N1() << ", " 
00362          << tet->N2() << ", " << tet->N3() << endl;
00363   }
00364 }
00365 
00366 // Ganz einfache Hilfs-Funktionen  
00367 void BoCeData::Print(dir_3D d) {
00368   if(d==Wdir) cout << "Wdir"; 
00369   if(d==Edir) cout << "Edir"; 
00370   if(d==Sdir) cout << "Sdir"; 
00371   if(d==Ndir) cout << "Ndir"; 
00372   if(d==Ddir) cout << "Ddir"; 
00373   if(d==Tdir) cout << "Tdir"; 
00374 }
00375 
00376 
00377 void BoCeData::Print(dir_sons d) {
00378   if(d==WSDd) cout << "WSDd"; 
00379   if(d==ESDd) cout << "ESDd"; 
00380   if(d==WNDd) cout << "WNDd"; 
00381   if(d==ENDd) cout << "ENDd"; 
00382   if(d==WSTd) cout << "WSTd"; 
00383   if(d==ESTd) cout << "ESTd"; 
00384   if(d==WNTd) cout << "WNTd"; 
00385   if(d==ENTd) cout << "ENTd"; 
00386 }
00387 
00388 
00389 void BoCeData::Print(Edges_cell ed) {
00390   if(ed==SDed) cout << "SDed";
00391   if(ed==NDed) cout << "NDed";
00392   if(ed==STed) cout << "STed";
00393   if(ed==NTed) cout << "NTed";
00394   if(ed==WDed) cout << "WDed";
00395   if(ed==EDed) cout << "EDed";
00396   if(ed==WTed) cout << "WTed";
00397   if(ed==ETed) cout << "ETed";
00398   if(ed==SWed) cout << "SWed";
00399   if(ed==SEed) cout << "SEed";
00400   if(ed==NWed) cout << "NWed";
00401   if(ed==NEed) cout << "NEed";
00402 }
00403 
00404 
00405 

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