00001
00006 #ifndef __UIUC_CHARM_TETMESH_H
00007 #define __UIUC_CHARM_TETMESH_H
00008
00009 #include <stdio.h>
00010 #include "ckvector3d.h"
00011 #include <vector>
00012
00013 #define OSL_TETMESH_DEBUG 0
00014
00018 class TetMesh {
00019 public:
00020 enum {nodePer=4};
00021
00022
00023 class conn_t {
00024 public:
00025 int nodes[TetMesh::nodePer];
00026 conn_t() {nodes[0]=-1;}
00027 conn_t(int a,int b,int c,int d)
00028 {nodes[0]=a; nodes[1]=b; nodes[2]=c; nodes[3]=d;}
00029 };
00030
00032 TetMesh();
00034 TetMesh(int nt,int np);
00035 virtual ~TetMesh();
00036
00039 virtual void allocate(int nt,int np);
00040
00042 inline int getTets(void) const {return tet.size();}
00044 inline int *getTet(int t) {ct(t); return &(tet[t].nodes[0]);}
00045 inline const int *getTet(int t) const {ct(t); return &(tet[t].nodes[0]);}
00046 inline int *getTetConn(void) {return getTet(0);}
00047 inline const int *getTetConn(void) const {return getTet(0);}
00048 double getTetVolume(int t) const;
00049 inline void flipTet(int t) {
00050 int tmp = tet[t].nodes[0];
00051 tet[t].nodes[0] = tet[t].nodes[1];
00052 tet[t].nodes[1] = tmp;
00053 }
00054 inline double getTetOrientation(int t) {
00055 double yz01 = pts[tet[t].nodes[0]][1]*pts[tet[t].nodes[1]][2] - pts[tet[t].nodes[0]][2]*pts[tet[t].nodes[1]][1];
00056 double yz02 = pts[tet[t].nodes[0]][1]*pts[tet[t].nodes[2]][2] - pts[tet[t].nodes[0]][2]*pts[tet[t].nodes[2]][1];
00057 double yz03 = pts[tet[t].nodes[0]][1]*pts[tet[t].nodes[3]][2] - pts[tet[t].nodes[0]][2]*pts[tet[t].nodes[3]][1];
00058 double yz12 = pts[tet[t].nodes[1]][1]*pts[tet[t].nodes[2]][2] - pts[tet[t].nodes[1]][2]*pts[tet[t].nodes[2]][1];
00059 double yz13 = pts[tet[t].nodes[1]][1]*pts[tet[t].nodes[3]][2] - pts[tet[t].nodes[1]][2]*pts[tet[t].nodes[3]][1];
00060 double yz23 = pts[tet[t].nodes[2]][1]*pts[tet[t].nodes[3]][2] - pts[tet[t].nodes[2]][2]*pts[tet[t].nodes[3]][1];
00061 double x0 = pts[tet[t].nodes[0]][0], x1 = pts[tet[t].nodes[1]][0], x2 = pts[tet[t].nodes[2]][0],
00062 x3 = pts[tet[t].nodes[3]][0];
00063
00064 return x1*yz23 - x2*yz13 + x3*yz12 - x0*yz23 + x2*yz03 - x3*yz02 + x0*yz13
00065 - x1*yz03 + x3*yz01 - x0*yz12 + x1*yz02 - x2*yz01;
00066 }
00067
00068
00070 inline int getPoints(void) const {return pts.size();}
00072 inline CkVector3d &getPoint(int p) {cp(p); return pts[p];}
00073 inline const CkVector3d &getPoint(int p) const {cp(p); return pts[p];}
00074 CkVector3d *getPointArray(void);
00075 const CkVector3d *getPointArray(void) const;
00076
00077 void cleanup() {
00078 pts.erase(pts.begin(), pts.end());
00079 std::vector<CkVector3d>(pts).swap(pts);
00080 tet.erase(tet.begin(), tet.end());
00081 std::vector<conn_t>(tet).swap(tet);
00082 }
00083
00086 int addTet(const conn_t &c) {tet.push_back(c); return tet.size()-1;}
00087 int addPoint(const CkVector3d &pt) {pts.push_back(pt); return pts.size()-1;}
00088
00089 void translateMesh(const CkVector3d &pt) {
00090 for (int i=0; i<pts.size(); i++) {
00091 pts[i][0] += pt[0];
00092 pts[i][1] += pt[1];
00093 pts[i][2] += pt[2];
00094 }
00095 }
00096
00097 int nonGhostTet, nonGhostPt;
00098 void write_real_tecplot(char *fname) {
00099 FILE *file = fopen(fname, "w");
00100
00101 nonGhostPt = pts.size();
00102 nonGhostTet = tet.size();
00103 fprintf (file, "TITLE=\"%s\"\n", fname);
00104 fprintf (file, "ZONE N=%d E=%d ET=TETRAHEDRON F=FEPOINT\n",
00105 nonGhostPt, nonGhostTet);
00106
00107 int n;
00108 n=nonGhostPt;
00109 for (int i=0; i<n; ++i) {
00110 fprintf(file,"%lf %lf %lf %lf\n",pts[i][0],pts[i][1],pts[i][2],pts[i][3]);
00111 }
00112
00113 n=nonGhostTet;
00114 for (int i=0; i<n; ++i) {
00115 for (int j=0; j<4; ++j) {
00116 fprintf(file,"%d ", tet[i].nodes[j]+1);
00117 }
00118 fprintf(file,"\n");
00119 }
00120 fclose(file);
00121 }
00122
00123 private:
00124 std::vector<conn_t> tet;
00125 std::vector<CkVector3d> pts;
00126
00127
00129 #if OSL_TETMESH_DEBUG
00130 void ct(int t) const;
00131 void cp(int p) const;
00132 #else
00133 inline void ct(int t) const {}
00134 inline void cp(int p) const {}
00135 #endif
00136 };
00137
00139 void print(const TetMesh &t);
00140
00142 void printSize(const TetMesh &t);
00143
00145 void printTet(const TetMesh &m,int t);
00146
00148 void print(const CkVector3d &p);
00149
00152 void readNoboite(FILE *f,TetMesh &t);
00153 void writeNoboite(FILE *f,TetMesh &t);
00154
00156 void readFEM(int m,TetMesh &t);
00157 void readGhostFEM(int m,TetMesh &t);
00158
00160 void writeFEM(int m,TetMesh &t);
00161
00162 namespace cg3d { class Planar3dDest; }
00163
00167 double averageEdgeLength(const TetMesh &m);
00168
00169 #endif