elem/Tetra4.cpp

00001 #include "DAPTA.hpp"
00002 
00003 namespace DAPTA { // Define namespace DAPTA
00004 
00005 /*
00006 Tetra4<V>::Tetra4(VertexHandle i, VertexHandle j, VertexHandle k, VertexHandle l)
00007 Create a Tetra element from 4 Vertex definitions.
00008 */
00009 template <typename V>
00010 Tetra4<V>::Tetra4(VertexHandle i, VertexHandle j, VertexHandle k, VertexHandle l) {
00011    assert(i != NULL);
00012    assert(j != NULL);
00013    assert(k != NULL);
00014    assert(l != NULL);
00015 
00016    for(int x=0; x<4; x++)
00017       vertices.at(x) = NULL;
00018 
00019    vertices.at(0) = i;
00020    vertices.at(1) = j;
00021    vertices.at(2) = k;
00022    vertices.at(3) = l;
00023       
00024    for(int x=0; x<num_adjacents; x++) {
00025       adjacents.at(x) = NULL;
00026       coh_adjacents.at(x) = NULL;
00027    }
00028    
00029    globalID = 0;
00030 }
00031 
00032 /*
00033 Tetra4<V>::Tetra4(boost::array<VertexHandle, num_vertices> nodes)
00034 Create a Tetra element from a vector of Vertex definitions.
00035 */
00036 template <typename V>
00037 Tetra4<V>::Tetra4(boost::array<VertexHandle, num_vertices> nodes) {
00038    for(int i=0; i<num_vertices; i++) {
00039       assert(nodes.at(i) != NULL);
00040       vertices.at(i) = nodes.at(i);
00041    }
00042    
00043    for(int x=0; x<num_adjacents; x++) {
00044       adjacents.at(x) = NULL;
00045       coh_adjacents.at(x) = NULL;
00046    }
00047    
00048    globalID = 0;
00049 }
00050 
00051 /*
00052 int Tetra4<V>::FindVertex(VertexHandle v)
00053 Returns the index in the vertices vector where v is located.
00054 */
00055 template <typename V>
00056 int Tetra4<V>::FindVertex(VertexHandle v) {
00057    assert(v != NULL);
00058    
00059    int j=0;
00060    while(j<vertices.size() && vertices.at(j)!=v)
00061       j++;
00062    return j;
00063 }
00064 
00065 /*
00066 bool Tetra4<V>::IsBoundaryEdge(VertexHandle v1, VertexHandle v2)
00067 */
00068 template <typename V>
00069 bool Tetra4<V>::IsBoundaryEdge(VertexHandle v1, VertexHandle v2) {
00070    return this->IsBoundaryEdge(FindVertex(v1), FindVertex(v2));
00071 }
00072 
00073 /*
00074 bool Tetra4<V>::IsBoundaryEdge(int v1, int v2)
00075 */
00076 template <typename V>
00077 bool Tetra4<V>::IsBoundaryEdge(int v1, int v2) {
00078    return true;
00079 /* assert(v1 < vertices.size());
00080    assert(v2 < vertices.size());
00081    
00082    ElementHandle cur_tet = this;
00083    
00084    boost::array<VertexHandle,2> vvs;
00085    vvs[0] = vertices.at(v1);
00086    vvs[1] = vertices.at(v2);
00087    
00088    EdgeElementType edge(vvs);
00089    
00090    do {
00091       v1 = cur_tet->FindVertex(vvs[0]);
00092       v2 = cur_tet->FindVertex(vvs[1]);
00093       int test1=-1, test2=-1;
00094       for(int i=0; i<4; i++) {
00095          if((i != v1) && (i != v2)) {
00096             (test1 == -1) ? test1 = i : test2 = i;
00097          }
00098       }
00099       if((cur_tet->adjacents.at(test1) == NULL) || (cur_tet->coh_adjacents.at(test1) != NULL) || 
00100          (cur_tet->adjacents.at(test2) == NULL) || (cur_tet->coh_adjacents.at(test2) != NULL) )
00101          // If we've found a boundary face then return true
00102          // Boundary is if there's a cohesive element there, or if there isn't any element there
00103          return true;
00104       cur_tet = cur_tet->NextOnEdge(cur_tet->GetEdgeIndex(edge));
00105       std::cout << this << ":" << cur_tet << std::endl;
00106    } while(cur_tet != this);
00107    
00108    // We didn't find a boundary face, so this isn't a boundary edge
00109    return false;
00110 */
00111    
00112 /* assert(v1 < vertices.size());
00113    assert(v2 < vertices.size());
00114 
00115    // Start iterating round with this tetra
00116    ElementHandle cur_tet = this;
00117 
00118    // Choose a direction to go round in
00119    int next_face=0;
00120    while((next_face == v1) || (next_face == v2))
00121       next_face++;
00122 
00123    do {
00124       //std::cout << "1: " << v1 << ", 2: " << v2 << ", f: " << next_face << std::endl;
00125       //std::cout << cur_tet->adjacents.at(next_face) << ", " << cur_tet->coh_adjacents.at(next_face) << std::endl;
00126       if((cur_tet->adjacents.at(next_face) == NULL) || (cur_tet->coh_adjacents.at(next_face) != NULL))
00127          // If we've found a boundary face then return true
00128          // Boundary is if there's a cohesive element there, or if there isn't any element there
00129          return true;
00130       cur_tet = cur_tet->NextTetOnEdge(v1, v2, next_face);
00131    } while(cur_tet != this);
00132    
00133    // We didn't find a boundary face, so this isn't a boundary edge
00134    return false; */
00135 }
00136 
00137 /*
00138 typename Tetra4<V>::ElementHandle Tetra4<V>::NextTetOnEdge(int &v1, int &v2, int &f)
00139 Update v1, v2 and f indexes and return pointer to the next tetra along when iterating
00140 around an edge defined by v1 and v2 going in the direction of f.
00141 */
00142 template <typename V>
00143 typename Tetra4<V>::ElementHandle Tetra4<V>::NextTetOnEdge(int &v1, int &v2, int &f) {
00144    ElementHandle new_tetra = adjacents.at(f);
00145 
00146    assert(new_tetra != NULL);
00147 
00148    int new_f=this->FaceToVertex(v1, v2, f);
00149    //std::cout << "v1: " << v1 << ", v2: " << v2 << ", f: " << f << std::endl;
00150    //std::cout << "new_f: " << new_f << std::endl;
00151 
00152    VertexHandle v1_vertex, v2_vertex, new_f_vertex;
00153    v1_vertex = this->vertices.at(v1);
00154    v2_vertex = this->vertices.at(v2);
00155    new_f_vertex = this->vertices.at(new_f);
00156 
00157    v1 = new_tetra->FindVertex(v1_vertex);
00158    v2 = new_tetra->FindVertex(v2_vertex);
00159    f = new_tetra->FindVertex(new_f_vertex);
00160    
00161    //std::cout << "v1: " << v1 << ", v2: " << v2 << ", f: " << f << std::endl;
00162    //std::cout << "old: " << this << ", new: " << new_tetra << std::endl;
00163    
00164    assert(v1 < new_tetra->vertices.size());
00165    assert(v2 < new_tetra->vertices.size());
00166    assert(f < new_tetra->vertices.size());
00167 
00168    return new_tetra;
00169 }
00170 
00171 /*
00172 int Tetra4<V>::FaceToVertex(VertexHandle v1, VertexHandle v2, VertexHandle v3)
00173 Return the index of the vertex defining the face defined by v1, v2 and v3
00174 */
00175 template <typename V>
00176 int Tetra4<V>::FaceToVertex(VertexHandle v1, VertexHandle v2, VertexHandle v3) { 
00177    return this->FaceToVertex(FindVertex(v1), FindVertex(v2), FindVertex(v3));
00178 }
00179 
00180 /*
00181 int Tetra4<V>::FaceToVertex(int v1, int v2, int v3)
00182 Return the index of the vertex defining the face defined by v1, v2 and v3
00183 */
00184 template <typename V>
00185 int Tetra4<V>::FaceToVertex(int v1, int v2, int v3) {
00186    for(int i=0; i<vertices.size(); i++)
00187       if((i != v1) && (i != v2) && (i != v3))
00188          return i;
00189 }
00190 
00191 /*
00192 int Tetra4<V>::FaceToVertex(boost::array<VertexHandle, 3> vs)
00193 Return the index of the vertex defining the face defined by v1, v2 and v3
00194 */
00195 template <typename V>
00196 int Tetra4<V>::FaceToVertex(boost::array<VertexHandle, 3> vs) {
00197    return this->FaceToVertex(vs.at(0), vs.at(1), vs.at(2));
00198 }
00199 
00200 /*
00201 Tetra4<V>::FaceElementType Tetra4<V>::GetFace(int ind)
00202 Return the edge data structure for the edge defined by index, ind
00203 */
00204 template <typename V>
00205 typename Tetra4<V>::FaceElementType Tetra4<V>::GetFace(int ind) {
00206    int f[4][3] = { {1,2,3}, {0,3,2}, {0,1,3}, {0,2,1} };
00207    
00208    boost::array<VertexHandle, FaceElementType::num_vertices> vs;
00209    
00210    for(int i=0; i<3; i++) {
00211       vs.at(i) = vertices.at(f[ind][i]);
00212    }
00213    return FaceElementType(vs);
00214 }
00215 
00216 /*
00217 int Tetra4<V>::GetFaceIndex(Tetra4<V>::FaceElementType face)
00218 Return the index for the face as defined
00219 */
00220 template <typename V>
00221 int Tetra4<V>::GetFaceIndex(Tetra4<V>::FaceElementType face) {
00222    return this->FaceToVertex(face.vertices);
00223    
00224    for(int i=0; i<num_adjacents; i++) {
00225       if(face == this->GetFace(i)) {
00226          return i;
00227       }
00228    }
00229    return num_adjacents;
00230 }
00231 
00232 /*
00233 Tetra4<V>::EdgeElementType Tetra4<V>::GetEdge(int ind)
00234 Return the edge data structure for the edge defined by index, ind
00235 */
00236 template <typename V>
00237 typename Tetra4<V>::EdgeElementType Tetra4<V>::GetEdge(int ind) {
00238    int e[6][2] = { {0,1}, {0,2}, {0,3}, {1,2}, {1,3}, {2,3} };
00239    boost::array<VertexHandle, EdgeElementType::num_vertices> vs;
00240    vs.at(0) = vertices.at(e[ind][0]);
00241    vs.at(1) = vertices.at(e[ind][1]);
00242    return   EdgeElementType(vs);
00243 }
00244 
00245 /*
00246 int Tetra4<V>::GetEdgeIndex(Tetra4<V>::EdgeElementType edge)
00247 Return the index for the edge as defined
00248 */
00249 template <typename V>
00250 int Tetra4<V>::GetEdgeIndex(Tetra4<V>::EdgeElementType edge) {
00251    for(int i=0; i<num_edges; i++) {
00252       if(edge == this->GetEdge(i)) {
00253          return i;
00254       }
00255    }
00256    return num_edges;
00257 }
00258 
00259 /*
00260 std::vector<EdgeElementType> Tetra4<V>::GetEdges(int f)
00261 Return the edges in an array which correspond to the given face, f
00262 */
00263 template <typename V>
00264 std::vector<typename Tetra4<V>::EdgeElementType> Tetra4<V>::GetEdges(int f) {
00265    int e[4][3][2] = { { {2,3}, {3,1}, {1,2} }, 
00266                        { {3,2}, {2,0}, {0,3} }, 
00267                        { {1,3}, {3,0}, {0,1} }, 
00268                        { {0,2}, {2,1}, {1,0} } };
00269    
00270    std::vector<EdgeElementType> edges;
00271 
00272    boost::array<VertexHandle,EdgeElementType::num_vertices> vertices_1, vertices_2, vertices_3;
00273    
00274    vertices_1.at(0) = this->vertices.at(e[f][0][0]);
00275    vertices_1.at(1) = this->vertices.at(e[f][0][1]);
00276    vertices_2.at(0) = this->vertices.at(e[f][1][0]);
00277    vertices_2.at(1) = this->vertices.at(e[f][1][1]);
00278    vertices_3.at(0) = this->vertices.at(e[f][2][0]);
00279    vertices_3.at(1) = this->vertices.at(e[f][2][1]);
00280    
00281    edges.push_back(EdgeElementType(vertices_1));
00282    edges.push_back(EdgeElementType(vertices_2));
00283    edges.push_back(EdgeElementType(vertices_3));
00284    
00285    return edges;
00286 }
00287 
00288 /*
00289 std::vector<EdgeElementType> Tetra4<V>::GetAllEdges()
00290 */
00291 template <typename V>
00292 std::vector<typename Tetra4<V>::EdgeElementType> Tetra4<V>::GetAllEdges() {
00293    int e[4][3][2] = { { {2,3}, {3,1}, {1,2} }, 
00294                        { {3,2}, {2,0}, {0,3} }, 
00295                        { {1,3}, {3,0}, {0,1} }, 
00296                        { {0,2}, {2,1}, {1,0} } };
00297    
00298    std::vector<EdgeElementType> edges;
00299    
00300    boost::array<VertexHandle,EdgeElementType::num_vertices> vertices_1, vertices_2, vertices_3, vertices_4, vertices_5, vertices_6;
00301    
00302    vertices_1.at(0) = this->vertices.at(e[0][0][0]);
00303    vertices_1.at(1) = this->vertices.at(e[0][0][1]);
00304    vertices_2.at(0) = this->vertices.at(e[0][1][0]);
00305    vertices_2.at(1) = this->vertices.at(e[0][1][1]);
00306    vertices_3.at(0) = this->vertices.at(e[0][2][0]);
00307    vertices_3.at(1) = this->vertices.at(e[0][2][1]);
00308    vertices_4.at(0) = this->vertices.at(e[1][1][0]);
00309    vertices_4.at(1) = this->vertices.at(e[1][1][1]);
00310    vertices_5.at(0) = this->vertices.at(e[1][2][0]);
00311    vertices_5.at(1) = this->vertices.at(e[1][2][1]);
00312    vertices_6.at(0) = this->vertices.at(e[2][2][0]);
00313    vertices_6.at(1) = this->vertices.at(e[2][2][1]);
00314    
00315    edges.push_back(EdgeElementType(vertices_1));
00316    edges.push_back(EdgeElementType(vertices_2));
00317    edges.push_back(EdgeElementType(vertices_3));
00318    edges.push_back(EdgeElementType(vertices_4));
00319    edges.push_back(EdgeElementType(vertices_5));
00320    edges.push_back(EdgeElementType(vertices_6));
00321    
00322    return edges;
00323 }
00324 
00325 /*
00326 Tetra4<V>::ElementHandle Tetra4<V>::NextOnEdge(int ind)
00327 Return the next element on the edge defined by index, ind
00328 */
00329 template <typename V>
00330 typename Tetra4<V>::ElementHandle Tetra4<V>::NextOnEdge(int ind) {
00331    int e1[6] = { 2, 3, 1, 0, 2, 0 };
00332    int e2[6] = { 3, 1, 2, 3, 0, 1 };
00333    return adjacents.at(e1[ind]);
00334 }
00335 
00336 /*
00337 Tetra4<V>::ElementHandle Tetra4<V>::PrevOnEdge(int ind)
00338 Return the previous element on the edge defined by index, ind
00339 */
00340 template <typename V>
00341 typename Tetra4<V>::ElementHandle Tetra4<V>::PrevOnEdge(int ind) {
00342    int e1[6] = { 2, 3, 1, 0, 2, 0 };
00343    int e2[6] = { 3, 1, 2, 3, 0, 1 };
00344    return adjacents.at(e2[ind]);
00345 }
00346 
00347 /*
00348 Tetra4<V>::ElementHandle Tetra4<V>::NextOnEdge(EdgeElementType edge)
00349 Return the next element on the edge
00350 */
00351 template <typename V>
00352 typename Tetra4<V>::ElementHandle Tetra4<V>::NextOnEdge(EdgeElementType edge) {
00353    int e1[6] = { 2, 3, 1, 0, 2, 0 };
00354    int e2[6] = { 3, 1, 2, 3, 0, 1 };
00355    
00356    for(int i=0; i<num_edges; i++) {
00357       if(edge == this->GetEdge(i)) {
00358          return adjacents.at(e1[i]);
00359       }
00360       else if(edge == !this->GetEdge(i)) {
00361          return adjacents.at(e2[i]);
00362       }
00363    }
00364    
00365    return NULL;
00366 }
00367 
00368 /*
00369 Tetra4<V>::ElementHandle Tetra4<V>::PrevOnEdge(EdgeElementType edge)
00370 Return the previous element on the edge
00371 */
00372 template <typename V>
00373 typename Tetra4<V>::ElementHandle Tetra4<V>::PrevOnEdge(EdgeElementType edge) {
00374    int e1[6] = { 2, 3, 1, 0, 2, 0 };
00375    int e2[6] = { 3, 1, 2, 3, 0, 1 };
00376    
00377    for(int i=0; i<num_edges; i++) {
00378       if(edge == this->GetEdge(i)) {
00379          return adjacents.at(e2[i]);
00380       }
00381       else if(edge == !this->GetEdge(i)) {
00382          return adjacents.at(e1[i]);
00383       }
00384    }
00385    
00386    return NULL;}
00387 
00388 /*
00389 Tetra4<V>::CohElementHandle Tetra4<V>::NextCohOnEdge(int ind)
00390 Return the previous element on the edge defined by index, ind
00391 */
00392 template <typename V>
00393 typename Tetra4<V>::CohElementHandle Tetra4<V>::NextCohOnEdge(int ind) {
00394    int e[6] = { 2, 3, 1, 0, 2, 0 };
00395    return coh_adjacents.at(e[ind]);
00396 }
00397 
00398 /*
00399 Tetra4<V>::CohElementHandle Tetra4<V>::PrevCohOnEdge(int ind)
00400 Return the previous element on the edge defined by index, ind
00401 */
00402 template <typename V>
00403 typename Tetra4<V>::CohElementHandle Tetra4<V>::PrevCohOnEdge(int ind) {
00404    int e[6] = { 3, 1, 2, 3, 0, 1 };
00405    return coh_adjacents.at(e[ind]);
00406 }
00407 
00408 /*
00409 typename Tetra4<V>::VertexHandle Tetra4<V>::GetCentre()
00410 Return a the centre of the element (vertex will have it's global ID set to that of the element)
00411 */
00412 template <typename V>
00413 typename Tetra4<V>::VertexHandle Tetra4<V>::GetCentre() {
00414    typename V::CoordType new_x=0.0, new_y=0.0, new_z=0.0;
00415    for(int i=0; i<4; i++) {
00416       new_x += vertices.at(i)->coords.at(0);
00417       new_y += vertices.at(i)->coords.at(1);
00418       new_z += vertices.at(i)->coords.at(2);
00419    }
00420    new_x /= 4; new_y /= 4; new_z /= 4;
00421    
00422    return new V(new_x, new_y, new_z);
00423 }
00424 
00425 } // namespace DAPTA

Generated on Tue May 29 17:13:48 2007 for DAPTA by  doxygen 1.5.1