$extrastylesheet
face_tri6.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 // C++ includes
00019 
00020 // Local includes
00021 #include "libmesh/side.h"
00022 #include "libmesh/edge_edge3.h"
00023 #include "libmesh/face_tri6.h"
00024 
00025 namespace libMesh
00026 {
00027 
00028 
00029 
00030 
00031 // ------------------------------------------------------------
00032 // Tri6 class static member initializations
00033 const unsigned int Tri6::side_nodes_map[3][3] =
00034   {
00035     {0, 1, 3}, // Side 0
00036     {1, 2, 4}, // Side 1
00037     {2, 0, 5}  // Side 2
00038   };
00039 
00040 
00041 #ifdef LIBMESH_ENABLE_AMR
00042 
00043 const float Tri6::_embedding_matrix[4][6][6] =
00044   {
00045     // embedding matrix for child 0
00046     {
00047       //  0      1      2    3    4    5
00048       { 1.0,   0.0,   0.0, 0.0, 0.0, 0.0}, // 0
00049       { 0.0,   0.0,   0.0, 1.0, 0.0, 0.0}, // 1
00050       { 0.0,   0.0,   0.0, 0.0, 0.0, 1.0}, // 2
00051       {.375, -.125,   0.0, .75, 0.0, 0.0}, // 3
00052       { 0.0, -.125, -.125, 0.5, .25, 0.5}, // 4
00053       {.375,   0.0, -.125, 0.0, 0.0, .75}  // 5
00054     },
00055 
00056     // embedding matrix for child 1
00057     {
00058       //  0      1      2    3    4    5
00059       {  0.0,  0.0,   0.0, 1.0, 0.0, 0.0}, // 0
00060       {  0.0,  1.0,   0.0, 0.0, 0.0, 0.0}, // 1
00061       {  0.0,  0.0,   0.0, 0.0, 1.0, 0.0}, // 2
00062       {-.125, .375,   0.0, .75, 0.0, 0.0}, // 3
00063       {  0.0, .375, -.125, 0.0, .75, 0.0}, // 4
00064       {-.125,  0.0, -.125, 0.5, 0.5, .25}  // 5
00065     },
00066 
00067     // embedding matrix for child 2
00068     {
00069       //  0       1     2    3    4    5
00070       {  0.0,   0.0,  0.0, 0.0, 0.0, 1.0}, // 0
00071       {  0.0,   0.0,  0.0, 0.0, 1.0, 0.0}, // 1
00072       {  0.0,   0.0,  1.0, 0.0, 0.0, 0.0}, // 2
00073       {-.125, -.125,  0.0, .25, 0.5, 0.5}, // 3
00074       {  0.0, -.125, .375, 0.0, .75, 0.0}, // 4
00075       {-.125,   0.0, .375, 0.0, 0.0, .75}  // 5
00076     },
00077 
00078     // embedding matrix for child 3
00079     {
00080       //  0       1      2    3    4    5
00081       {  0.0,   0.0,   0.0, 1.0, 0.0, 0.0}, // 0
00082       {  0.0,   0.0,   0.0, 0.0, 1.0, 0.0}, // 1
00083       {  0.0,   0.0,   0.0, 0.0, 0.0, 1.0}, // 2
00084       {-.125,   0.0, -.125, 0.5, 0.5, .25}, // 3
00085       {-.125, -.125,   0.0, .25, 0.5, 0.5}, // 4
00086       {  0.0, -.125, -.125, 0.5, .25, 0.5}  // 5
00087     }
00088   };
00089 
00090 #endif
00091 
00092 
00093 
00094 // ------------------------------------------------------------
00095 // Tri6 class member functions
00096 
00097 bool Tri6::is_vertex(const unsigned int i) const
00098 {
00099   if (i < 3)
00100     return true;
00101   return false;
00102 }
00103 
00104 bool Tri6::is_edge(const unsigned int i) const
00105 {
00106   if (i < 3)
00107     return false;
00108   return true;
00109 }
00110 
00111 bool Tri6::is_face(const unsigned int) const
00112 {
00113   return false;
00114 }
00115 
00116 bool Tri6::is_node_on_side(const unsigned int n,
00117                            const unsigned int s) const
00118 {
00119   libmesh_assert_less (s, n_sides());
00120   for (unsigned int i = 0; i != 3; ++i)
00121     if (side_nodes_map[s][i] == n)
00122       return true;
00123   return false;
00124 }
00125 
00126 
00127 
00128 bool Tri6::has_affine_map() const
00129 {
00130   // Make sure edges are straight
00131   if (!this->point(3).relative_fuzzy_equals
00132       ((this->point(0) + this->point(1))/2.))
00133     return false;
00134   if (!this->point(4).relative_fuzzy_equals
00135       ((this->point(1) + this->point(2))/2.))
00136     return false;
00137   if (!this->point(5).relative_fuzzy_equals
00138       ((this->point(2) + this->point(0))/2.))
00139     return false;
00140 
00141   return true;
00142 }
00143 
00144 
00145 
00146 dof_id_type Tri6::key (const unsigned int s) const
00147 {
00148   libmesh_assert_less (s, this->n_sides());
00149 
00150   switch (s)
00151     {
00152     case 0:
00153 
00154       return
00155         this->compute_key (this->node(3));
00156 
00157     case 1:
00158 
00159       return
00160         this->compute_key (this->node(4));
00161 
00162     case 2:
00163 
00164       return
00165         this->compute_key (this->node(5));
00166 
00167     default:
00168       libmesh_error_msg("Invalid side s = " << s);
00169     }
00170 
00171   libmesh_error_msg("We'll never get here!");
00172   return 0;
00173 }
00174 
00175 
00176 
00177 UniquePtr<Elem> Tri6::build_side (const unsigned int i,
00178                                   bool proxy) const
00179 {
00180   libmesh_assert_less (i, this->n_sides());
00181 
00182   if (proxy)
00183     return UniquePtr<Elem>(new Side<Edge3,Tri6>(this,i));
00184 
00185   else
00186     {
00187       Elem* edge = new Edge3;
00188       edge->subdomain_id() = this->subdomain_id();
00189 
00190       switch (i)
00191         {
00192         case 0:
00193           {
00194             edge->set_node(0) = this->get_node(0);
00195             edge->set_node(1) = this->get_node(1);
00196             edge->set_node(2) = this->get_node(3);
00197             break;
00198           }
00199         case 1:
00200           {
00201             edge->set_node(0) = this->get_node(1);
00202             edge->set_node(1) = this->get_node(2);
00203             edge->set_node(2) = this->get_node(4);
00204             break;
00205           }
00206         case 2:
00207           {
00208             edge->set_node(0) = this->get_node(2);
00209             edge->set_node(1) = this->get_node(0);
00210             edge->set_node(2) = this->get_node(5);
00211             break;
00212           }
00213         default:
00214           libmesh_error_msg("Invalid side i = " << i);
00215         }
00216 
00217       return UniquePtr<Elem>(edge);
00218     }
00219 
00220   libmesh_error_msg("We'll never get here!");
00221   return UniquePtr<Elem>();
00222 }
00223 
00224 
00225 void Tri6::connectivity(const unsigned int sf,
00226                         const IOPackage iop,
00227                         std::vector<dof_id_type>& conn) const
00228 {
00229   libmesh_assert_less (sf, this->n_sub_elem());
00230   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
00231 
00232   switch (iop)
00233     {
00234     case TECPLOT:
00235       {
00236         conn.resize(4);
00237         switch(sf)
00238           {
00239           case 0:
00240             // linear sub-triangle 0
00241             conn[0] = this->node(0)+1;
00242             conn[1] = this->node(3)+1;
00243             conn[2] = this->node(5)+1;
00244             conn[3] = this->node(5)+1;
00245 
00246             return;
00247 
00248           case 1:
00249             // linear sub-triangle 1
00250             conn[0] = this->node(3)+1;
00251             conn[1] = this->node(1)+1;
00252             conn[2] = this->node(4)+1;
00253             conn[3] = this->node(4)+1;
00254 
00255             return;
00256 
00257           case 2:
00258             // linear sub-triangle 2
00259             conn[0] = this->node(5)+1;
00260             conn[1] = this->node(4)+1;
00261             conn[2] = this->node(2)+1;
00262             conn[3] = this->node(2)+1;
00263 
00264             return;
00265 
00266           case 3:
00267             // linear sub-triangle 3
00268             conn[0] = this->node(3)+1;
00269             conn[1] = this->node(4)+1;
00270             conn[2] = this->node(5)+1;
00271             conn[3] = this->node(5)+1;
00272 
00273             return;
00274 
00275           default:
00276             libmesh_error_msg("Invalid sf = " << sf);
00277           }
00278       }
00279 
00280     case VTK:
00281       {
00282         // VTK_QUADRATIC_TRIANGLE has same numbering as libmesh TRI6
00283         conn.resize(6);
00284         conn[0] = this->node(0);
00285         conn[1] = this->node(1);
00286         conn[2] = this->node(2);
00287         conn[3] = this->node(3);
00288         conn[4] = this->node(4);
00289         conn[5] = this->node(5);
00290         return;
00291 
00292         // Used to write out linear sub-triangles for VTK...
00293         /*
00294           conn.resize(3);
00295           switch(sf)
00296           {
00297           case 0:
00298           // linear sub-triangle 0
00299           conn[0] = this->node(0);
00300           conn[1] = this->node(3);
00301           conn[2] = this->node(5);
00302 
00303           return;
00304 
00305           case 1:
00306           // linear sub-triangle 1
00307           conn[0] = this->node(3);
00308           conn[1] = this->node(1);
00309           conn[2] = this->node(4);
00310 
00311           return;
00312 
00313           case 2:
00314           // linear sub-triangle 2
00315           conn[0] = this->node(5);
00316           conn[1] = this->node(4);
00317           conn[2] = this->node(2);
00318 
00319           return;
00320 
00321           case 3:
00322           // linear sub-triangle 3
00323           conn[0] = this->node(3);
00324           conn[1] = this->node(4);
00325           conn[2] = this->node(5);
00326 
00327           return;
00328 
00329           default:
00330           libmesh_error_msg("Invalid sf = " << sf);
00331           }
00332         */
00333       }
00334 
00335     default:
00336       libmesh_error_msg("Unsupported IO package " << iop);
00337     }
00338 }
00339 
00340 
00341 
00342 
00343 
00344 unsigned short int Tri6::second_order_adjacent_vertex (const unsigned int n,
00345                                                        const unsigned int v) const
00346 {
00347   libmesh_assert_greater_equal (n, this->n_vertices());
00348   libmesh_assert_less (n, this->n_nodes());
00349   libmesh_assert_less (v, 2);
00350   return _second_order_adjacent_vertices[n-this->n_vertices()][v];
00351 }
00352 
00353 
00354 
00355 const unsigned short int Tri6::_second_order_adjacent_vertices[3][2] =
00356   {
00357     {0, 1}, // vertices adjacent to node 3
00358     {1, 2}, // vertices adjacent to node 4
00359     {0, 2}  // vertices adjacent to node 5
00360   };
00361 
00362 
00363 
00364 std::pair<unsigned short int, unsigned short int>
00365 Tri6::second_order_child_vertex (const unsigned int n) const
00366 {
00367   libmesh_assert_greater_equal (n, this->n_vertices());
00368   libmesh_assert_less (n, this->n_nodes());
00369   return std::pair<unsigned short int, unsigned short int>
00370     (_second_order_vertex_child_number[n],
00371      _second_order_vertex_child_index[n]);
00372 }
00373 
00374 
00375 
00376 const unsigned short int Tri6::_second_order_vertex_child_number[6] =
00377   {
00378     99,99,99, // Vertices
00379     0,1,0     // Edges
00380   };
00381 
00382 
00383 
00384 const unsigned short int Tri6::_second_order_vertex_child_index[6] =
00385   {
00386     99,99,99, // Vertices
00387     1,2,2     // Edges
00388   };
00389 
00390 } // namespace libMesh