00001
00024 #ifndef _TRI_LINEAR_COORD_CONN_H_
00025 #define _TRI_LINEAR_COORD_CONN_H_
00026
00027 #include "CoordConn.h"
00028
00032 struct TriLinearTraits {
00033 enum {
00034 SPD = 2,
00035 NODES_PER_ELEM = 3,
00036 TOPO = 2,
00037 NUM_EDGES = 3,
00038 NFIELDS = SPD,
00039 };
00040 };
00041
00042 class TriLinearCoordConn
00043 : public AbstractCoordConn <TriLinearTraits::SPD, TriLinearTraits::NODES_PER_ELEM, TriLinearTraits::TOPO> {
00044
00045 protected:
00053 virtual Element* makeElem (const size_t elemIndex) const {
00054 std::vector<GlobalNodalIndex> conn;
00055
00056 genElemConnectivity (elemIndex, conn);
00057
00058 Triangle<TriLinearTraits::SPD>* triGeom = new Triangle<TriLinearTraits::SPD> (coordinates, conn);
00059 return new P12D<TriLinearTraits::NFIELDS>::Bulk (*triGeom);
00060 }
00061
00062 public:
00063
00068 virtual void subdivide () {
00069
00070 std::vector<edgestruct> faces;
00071
00072 unsigned int iElements = getNumElements();
00073 unsigned int iNodes = getNumNodes();
00074
00075 for (unsigned int e = 0; e < iElements; e++) {
00076
00077 GlobalNodalIndex node0;
00078 GlobalNodalIndex node1;
00079
00080
00081 node0 = connectivity[e * 3 + 0];
00082 node1 = connectivity[e * 3 + 1];
00083 faces.push_back (edgestruct (e, 0, node0, node1));
00084
00085 node0 = connectivity[e * 3 + 1];
00086 node1 = connectivity[e * 3 + 2];
00087 faces.push_back (edgestruct (e, 1, node0, node1));
00088
00089 node0 = connectivity[e * 3 + 2];
00090 node1 = connectivity[e * 3 + 0];
00091 faces.push_back (edgestruct (e, 2, node0, node1));
00092 }
00093
00094 std::sort (faces.begin (), faces.end ());
00095
00096 std::vector<size_t> NodeInfo (faces.size () * 2, 0);
00097 size_t middlenodenum = iNodes;
00098
00099
00100 for (std::vector<edgestruct>::iterator it = faces.begin (); it != faces.end (); it++) {
00101
00102
00103
00104
00105
00106 double xm = (coordinates[2 * it->node0] + coordinates[2 * it->node1]) / 2.;
00107 double ym = (coordinates[2 * it->node0 + 1] + coordinates[2 * it->node1 + 1]) / 2.;
00108 coordinates.push_back (xm);
00109 coordinates.push_back (ym);
00110
00111 NodeInfo[it->elemId * 6 + it->edgeId * 2 + 0] = it->edgeId;
00112
00113
00114 NodeInfo[it->elemId * 6 + it->edgeId * 2 + 1] = middlenodenum;
00115
00116 if (it + 1 != faces.end ()) {
00117 if (it->node0 == (it + 1)->node0 && it->node1 == (it + 1)->node1) {
00118 it++;
00119 NodeInfo[it->elemId * 6 + it->edgeId * 2 + 0] = it->edgeId;
00120
00121
00122 NodeInfo[it->elemId * 6 + it->edgeId * 2 + 1] = middlenodenum;
00123 }
00124 }
00125
00126 ++middlenodenum;
00127 }
00128
00129
00130 std::vector<GlobalNodalIndex> copyconn (connectivity);
00131 connectivity.resize (iElements * 3 * 4);
00132
00133 for (unsigned int e = 0; e < iElements; e++) {
00134
00135 connectivity[e * 4 * 3 + 0 * 3 + 0] = copyconn[e * 3];
00136 connectivity[e * 4 * 3 + 0 * 3 + 1] = NodeInfo[e * 6 + 0 * 2 + 1];
00137 connectivity[e * 4 * 3 + 0 * 3 + 2] = NodeInfo[e * 6 + 2 * 2 + 1];
00138
00139
00140 connectivity[e * 4 * 3 + 1 * 3 + 0] = copyconn[e * 3 + 1];
00141 connectivity[e * 4 * 3 + 1 * 3 + 1] = NodeInfo[e * 6 + 1 * 2 + 1];
00142 connectivity[e * 4 * 3 + 1 * 3 + 2] = NodeInfo[e * 6 + 0 * 2 + 1];
00143
00144
00145 connectivity[e * 4 * 3 + 2 * 3 + 0] = copyconn[e * 3 + 2];
00146 connectivity[e * 4 * 3 + 2 * 3 + 1] = NodeInfo[e * 6 + 2 * 2 + 1];
00147 connectivity[e * 4 * 3 + 2 * 3 + 2] = NodeInfo[e * 6 + 1 * 2 + 1];
00148
00149
00150 connectivity[e * 4 * 3 + 3 * 3 + 0] = NodeInfo[e * 6 + 0 * 2 + 1];
00151 connectivity[e * 4 * 3 + 3 * 3 + 1] = NodeInfo[e * 6 + 1 * 2 + 1];
00152 connectivity[e * 4 * 3 + 3 * 3 + 2] = NodeInfo[e * 6 + 2 * 2 + 1];
00153 }
00154
00155
00156
00157 }
00158
00159 };
00160
00161 #endif // _TRI_LINEAR_COORD_CONN_H_