00001
00024 #ifndef _TET_LINEAR_COORD_CONN_H_
00025 #define _TET_LINEAR_COORD_CONN_H_
00026
00030 struct TetLinearTraits {
00031 enum {
00032 SPD = 3,
00033 NODES_PER_ELEM = 4,
00034 TOPO = 6,
00035 NUM_EDGES = 6,
00036 NFIELDS = SPD,
00037 };
00038 };
00039
00040 class TetLinearCoordConn
00041 : public AbstractCoordConn <TetLinearTraits::SPD, TetLinearTraits::NODES_PER_ELEM, TetLinearTraits::TOPO> {
00042 public:
00043 static const int NUM_EDGES = TetLinearTraits::NUM_EDGES;
00044
00045 protected:
00050 virtual Element* makeElem (const size_t elemIndex) const {
00051 std::vector<GlobalNodalIndex> conn;
00052
00053 genElemConnectivity (elemIndex, conn);
00054
00055 Tetrahedron* tetGeom = new Tetrahedron (coordinates, conn);
00056 return new P13D<TetLinearTraits::NFIELDS>::Bulk (*tetGeom);
00057 }
00058
00059 private:
00070 void getEdgeNeighborList (std::vector<std::vector<std::vector<int> > > &neighbors) const {
00071
00072 unsigned int iElements = getNumElements ();
00073
00074 neighbors.clear();
00075 neighbors.resize(iElements);
00076
00077 std::vector<edgestruct> edges;
00078
00079 int V1[] = { 0, 1, 0, 2, 0, 1 };
00080 int V2[] = { 1, 2, 2, 3, 3, 3 };
00081
00082
00083
00084
00085
00086
00087
00088
00089 for (unsigned int e = 0; e < iElements; e++) {
00090 neighbors[e].resize(NUM_EDGES);
00091
00092 int econn[] = { connectivity[e * 4 + 0], connectivity[e * 4 + 1], connectivity[e * 4 + 2], connectivity[e * 4 + 3] };
00093
00094 for (int edgenum = 0; edgenum < NUM_EDGES; edgenum++) {
00095 GlobalNodalIndex node0;
00096 GlobalNodalIndex node1;
00097
00098 node0 = econn[V1[edgenum]];
00099 node1 = econn[V2[edgenum]];
00100 edgestruct myedge(e, edgenum, node0, node1);
00101 edges.push_back(myedge);
00102 }
00103 }
00104
00105 std::sort(edges.begin(), edges.end());
00106
00107
00108
00109 std::vector<edgestruct>::iterator it1 = edges.begin();
00110 while (it1 != edges.end()) {
00111 std::vector<edgestruct> repedges;
00112 repedges.clear();
00113 repedges.push_back(*it1);
00114 std::vector<edgestruct>::iterator it2 = it1 + 1;
00115
00116 while (true && it2 != edges.end()) {
00117
00118 if ((it2->node0 == it1->node0) && (it2->node1 == it1->node1)) {
00119 repedges.push_back(*it2);
00120 it2++;
00121
00122 } else {
00123 break;
00124 }
00125 }
00126
00127 if (repedges.size() > 1) {
00128 for (unsigned int p = 0; p < repedges.size(); p++) {
00129 for (unsigned int q = 0; q < repedges.size(); q++) {
00130 if (p != q) {
00131 neighbors[repedges[p].elemId][repedges[p].edgeId]. push_back(repedges[q].elemId);
00132
00133 neighbors[repedges[p].elemId][repedges[p].edgeId]. push_back(repedges[q].edgeId);
00134 }
00135 }
00136 }
00137 }
00138
00139 it1 = it2;
00140 }
00141
00142 }
00143
00144 public:
00145
00164 virtual void subdivide () {
00165
00166 int sd = getSpatialDim();
00167 int eNodes = getNodesPerElem();
00168
00169 unsigned int iElements = getNumElements();
00170 unsigned int iNodes = getNumNodes();
00171
00172 std::vector<std::vector<std::vector<int> > > neighbors;
00173 getEdgeNeighborList(neighbors);
00174
00175
00176 int midconn[iElements][NUM_EDGES];
00177 int count = iNodes;
00178
00179 for (unsigned int e = 0; e < iElements; e++) {
00180 for (int f = 0; f < NUM_EDGES; f++) {
00181
00182
00183 int nNeighbors = neighbors[e][f].size() / 2;
00184
00185 if (nNeighbors == 0) {
00186
00187
00188
00189 midconn[e][f] = count;
00190 ++count;
00191
00192 } else {
00193
00194 int minElem = e;
00195 for (int p = 0; p < nNeighbors; p++) {
00196 if (minElem > neighbors[e][f][2 * p]) {
00197 minElem = neighbors[e][f][2 * p];
00198 }
00199 }
00200
00201 if (int(e) == minElem) {
00202
00203
00204 midconn[e][f] = count;
00205
00206 for (int p = 0; p < nNeighbors; p++) {
00207 int nelem = neighbors[e][f][2 * p];
00208 int nedge = neighbors[e][f][2 * p + 1];
00209 midconn[nelem][nedge] = count;
00210 }
00211
00212 ++count;
00213 }
00214 }
00215 }
00216 }
00217
00218
00219
00220 std::vector<double> newCoord(count * sd);
00221 std::vector<int> newConn;
00222
00223 for (unsigned int i = 0; i < coordinates.size(); i++) {
00224 newCoord[i] = coordinates[i];
00225 }
00226
00227
00228 int V1[] = { 0, 1, 0, 2, 0, 1 };
00229 int V2[] = { 1, 2, 2, 3, 3, 3 };
00230 for (unsigned int e = 0; e < iElements; e++)
00231 for (int f = 0; f < NUM_EDGES; f++) {
00232
00233
00234
00235
00236
00237 int v1 = connectivity[e * eNodes + V1[f]];
00238 int v2 = connectivity[e * eNodes + V2[f]];
00239 for (int k = 0; k < sd; k++) {
00240 newCoord[midconn[e][f] * sd + k] = 0.5 * (coordinates[v1 * sd + k] + coordinates[v2 * sd + k]);
00241 }
00242 }
00243
00244 for (unsigned int e = 0; e < iElements; e++) {
00245
00246 int t1conn[] = { connectivity[e * eNodes + 0], midconn[e][0], midconn[e][2], midconn[e][4] };
00247 for (int i = 0; i < eNodes; i++) {
00248 newConn.push_back(t1conn[i]);
00249 }
00250
00251
00252 int t2conn[] = { midconn[e][0], connectivity[e * eNodes + 1], midconn[e][1], midconn[e][5] };
00253 for (int i = 0; i < eNodes; i++) {
00254 newConn.push_back(t2conn[i]);
00255 }
00256
00257
00258 int t3conn[] = { midconn[e][2], midconn[e][1], connectivity[e * eNodes + 2], midconn[e][3] };
00259 for (int i = 0; i < eNodes; i++) {
00260 newConn.push_back(t3conn[i]);
00261 }
00262
00263
00264 int t4conn[] = { midconn[e][4], midconn[e][5], midconn[e][3], connectivity[e * eNodes + 3] };
00265
00266 for (int i = 0; i < eNodes; i++) {
00267 newConn.push_back(t4conn[i]);
00268 }
00269
00270
00271 int t5conn[] = { midconn[e][0], midconn[e][3], midconn[e][4], midconn[e][5] };
00272 for (int i = 0; i < eNodes; i++) {
00273 newConn.push_back(t5conn[i]);
00274 }
00275
00276
00277 int t6conn[] = { midconn[e][0], midconn[e][3], midconn[e][5], midconn[e][1] };
00278 for (int i = 0; i < eNodes; i++) {
00279 newConn.push_back(t6conn[i]);
00280 }
00281
00282
00283 int t7conn[] = { midconn[e][0], midconn[e][3], midconn[e][1], midconn[e][2] };
00284 for (int i = 0; i < eNodes; i++) {
00285 newConn.push_back(t7conn[i]);
00286 }
00287
00288
00289 int t8conn[] = { midconn[e][0], midconn[e][3], midconn[e][2], midconn[e][4] };
00290 for (int i = 0; i < eNodes; i++) {
00291 newConn.push_back(t8conn[i]);
00292 }
00293 }
00294 coordinates.clear();
00295 connectivity.clear();
00296 coordinates.assign(newCoord.begin(), newCoord.end());
00297 connectivity.assign(newConn.begin(), newConn.end());
00298
00299
00300
00301 }
00302 };
00303
00304 #endif // _TET_LINEAR_COORD_CONN_H_