$extrastylesheet
cell_pyramid14.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 
00019 // C++ includes
00020 
00021 // Local includes
00022 #include "libmesh/side.h"
00023 #include "libmesh/cell_pyramid14.h"
00024 #include "libmesh/edge_edge3.h"
00025 #include "libmesh/face_tri6.h"
00026 #include "libmesh/face_quad9.h"
00027 
00028 namespace libMesh
00029 {
00030 
00031 
00032 
00033 
00034 // ------------------------------------------------------------
00035 // Pyramid14 class static member initializations
00036 const unsigned int Pyramid14::side_nodes_map[5][9] =
00037   {
00038     {0, 1, 4, 5, 10,  9, 99, 99, 99}, // Side 0 (front)
00039     {1, 2, 4, 6, 11, 10, 99, 99, 99}, // Side 1 (right)
00040     {2, 3, 4, 7, 12, 11, 99, 99, 99}, // Side 2 (back)
00041     {3, 0, 4, 8,  9, 12, 99, 99, 99}, // Side 3 (left)
00042     {0, 3, 2, 1,  8,  7,  6,  5, 13}  // Side 4 (base)
00043   };
00044 
00045 const unsigned int Pyramid14::edge_nodes_map[8][3] =
00046   {
00047     {0, 1,  5}, // Edge 0
00048     {1, 2,  6}, // Edge 1
00049     {2, 3,  7}, // Edge 2
00050     {0, 3,  8}, // Edge 3
00051     {0, 4,  9}, // Edge 4
00052     {1, 4, 10}, // Edge 5
00053     {2, 4, 11}, // Edge 6
00054     {3, 4, 12}  // Edge 7
00055   };
00056 
00057 
00058 
00059 // ------------------------------------------------------------
00060 // Pyramid14 class member functions
00061 
00062 bool Pyramid14::is_vertex(const unsigned int i) const
00063 {
00064   if (i < 5)
00065     return true;
00066   return false;
00067 }
00068 
00069 
00070 
00071 bool Pyramid14::is_edge(const unsigned int i) const
00072 {
00073   if (i < 5)
00074     return false;
00075   if (i == 13)
00076     return false;
00077   return true;
00078 }
00079 
00080 
00081 
00082 bool Pyramid14::is_face(const unsigned int i) const
00083 {
00084   if (i == 13)
00085     return true;
00086   return false;
00087 }
00088 
00089 
00090 
00091 bool Pyramid14::is_node_on_side(const unsigned int n,
00092                                 const unsigned int s) const
00093 {
00094   libmesh_assert_less (s, n_sides());
00095   for (unsigned int i = 0; i != 9; ++i)
00096     if (side_nodes_map[s][i] == n)
00097       return true;
00098   return false;
00099 }
00100 
00101 bool Pyramid14::is_node_on_edge(const unsigned int n,
00102                                 const unsigned int e) const
00103 {
00104   libmesh_assert_less (e, n_edges());
00105   for (unsigned int i = 0; i != 3; ++i)
00106     if (edge_nodes_map[e][i] == n)
00107       return true;
00108   return false;
00109 }
00110 
00111 
00112 
00113 bool Pyramid14::has_affine_map() const
00114 {
00115   // TODO: If the base is a parallelogram and all the triangular faces are planar,
00116   // the map should be linear, but I need to test this theory...
00117   return false;
00118 }
00119 
00120 
00121 
00122 UniquePtr<Elem> Pyramid14::build_side (const unsigned int i, bool proxy) const
00123 {
00124   libmesh_assert_less (i, this->n_sides());
00125 
00126   if (proxy)
00127     {
00128       switch (i)
00129         {
00130         case 0:
00131         case 1:
00132         case 2:
00133         case 3:
00134           return UniquePtr<Elem>(new Side<Tri6,Pyramid14>(this,i));
00135 
00136         case 4:
00137           return UniquePtr<Elem>(new Side<Quad9,Pyramid14>(this,i));
00138 
00139         default:
00140           libmesh_error_msg("Invalid side i = " << i);
00141         }
00142     }
00143 
00144   else
00145     {
00146       // Create NULL pointer to be initialized, returned later.
00147       Elem* face = NULL;
00148 
00149       switch (i)
00150         {
00151         case 0:  // triangular face 1
00152           {
00153             face = new Tri6;
00154 
00155             face->set_node(0) = this->get_node(0);
00156             face->set_node(1) = this->get_node(1);
00157             face->set_node(2) = this->get_node(4);
00158             face->set_node(3) = this->get_node(5);
00159             face->set_node(4) = this->get_node(10);
00160             face->set_node(5) = this->get_node(9);
00161 
00162             break;
00163           }
00164         case 1:  // triangular face 2
00165           {
00166             face = new Tri6;
00167 
00168             face->set_node(0) = this->get_node(1);
00169             face->set_node(1) = this->get_node(2);
00170             face->set_node(2) = this->get_node(4);
00171             face->set_node(3) = this->get_node(6);
00172             face->set_node(4) = this->get_node(11);
00173             face->set_node(5) = this->get_node(10);
00174 
00175             break;
00176           }
00177         case 2:  // triangular face 3
00178           {
00179             face = new Tri6;
00180 
00181             face->set_node(0) = this->get_node(2);
00182             face->set_node(1) = this->get_node(3);
00183             face->set_node(2) = this->get_node(4);
00184             face->set_node(3) = this->get_node(7);
00185             face->set_node(4) = this->get_node(12);
00186             face->set_node(5) = this->get_node(11);
00187 
00188             break;
00189           }
00190         case 3:  // triangular face 4
00191           {
00192             face = new Tri6;
00193 
00194             face->set_node(0) = this->get_node(3);
00195             face->set_node(1) = this->get_node(0);
00196             face->set_node(2) = this->get_node(4);
00197             face->set_node(3) = this->get_node(8);
00198             face->set_node(4) = this->get_node(9);
00199             face->set_node(5) = this->get_node(12);
00200 
00201             break;
00202           }
00203         case 4:  // the quad face at z=0
00204           {
00205             face = new Quad9;
00206 
00207             face->set_node(0) = this->get_node(0);
00208             face->set_node(1) = this->get_node(3);
00209             face->set_node(2) = this->get_node(2);
00210             face->set_node(3) = this->get_node(1);
00211             face->set_node(4) = this->get_node(8);
00212             face->set_node(5) = this->get_node(7);
00213             face->set_node(6) = this->get_node(6);
00214             face->set_node(7) = this->get_node(5);
00215             face->set_node(8) = this->get_node(13);
00216 
00217             break;
00218           }
00219         default:
00220           libmesh_error_msg("Invalid side i = " << i);
00221         }
00222 
00223       face->subdomain_id() = this->subdomain_id();
00224       return UniquePtr<Elem>(face);
00225     }
00226 
00227   libmesh_error_msg("We'll never get here!");
00228   return UniquePtr<Elem>();
00229 }
00230 
00231 
00232 
00233 UniquePtr<Elem> Pyramid14::build_edge (const unsigned int i) const
00234 {
00235   libmesh_assert_less (i, this->n_edges());
00236 
00237   return UniquePtr<Elem>(new SideEdge<Edge3,Pyramid14>(this,i));
00238 }
00239 
00240 
00241 
00242 void Pyramid14::connectivity(const unsigned int libmesh_dbg_var(sc),
00243                              const IOPackage iop,
00244                              std::vector<dof_id_type>& /*conn*/) const
00245 {
00246   libmesh_assert(_nodes);
00247   libmesh_assert_less (sc, this->n_sub_elem());
00248   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
00249 
00250   switch (iop)
00251     {
00252     case TECPLOT:
00253       {
00254         // TODO
00255         libmesh_not_implemented();
00256       }
00257 
00258     case VTK:
00259       {
00260         // TODO
00261         libmesh_not_implemented();
00262       }
00263 
00264     default:
00265       libmesh_error_msg("Unsupported IO package " << iop);
00266     }
00267 }
00268 
00269 
00270 
00271 unsigned int Pyramid14::n_second_order_adjacent_vertices (const unsigned int n) const
00272 {
00273   switch (n)
00274     {
00275     case 5:
00276     case 6:
00277     case 7:
00278     case 8:
00279     case 9:
00280     case 10:
00281     case 11:
00282     case 12:
00283       return 2;
00284 
00285     case 13:
00286       return 4;
00287 
00288     default:
00289       libmesh_error_msg("Invalid node n = " << n);
00290     }
00291 
00292   libmesh_error_msg("We'll never get here!");
00293   return libMesh::invalid_uint;
00294 }
00295 
00296 
00297 unsigned short int Pyramid14::second_order_adjacent_vertex (const unsigned int n,
00298                                                             const unsigned int v) const
00299 {
00300   libmesh_assert_greater_equal (n, this->n_vertices());
00301   libmesh_assert_less (n, this->n_nodes());
00302 
00303   switch (n)
00304     {
00305     case 5:
00306     case 6:
00307     case 7:
00308     case 8:
00309     case 9:
00310     case 10:
00311     case 11:
00312     case 12:
00313       {
00314         libmesh_assert_less (v, 2);
00315 
00316         // This is the analog of the static, const arrays
00317         // {Hex,Prism,Tet10}::_second_order_adjacent_vertices
00318         // defined in the respective source files... possibly treat
00319         // this similarly once the Pyramid13 has been added?
00320         unsigned short node_list[8][2] =
00321           {
00322             {0,1},
00323             {1,2},
00324             {2,3},
00325             {0,3},
00326             {0,4},
00327             {1,4},
00328             {2,4},
00329             {3,4}
00330           };
00331 
00332         return node_list[n-5][v];
00333       }
00334 
00335       // mid-face node on bottom
00336     case 13:
00337       {
00338         libmesh_assert_less (v, 4);
00339 
00340         // The vertex nodes surrounding node 13 are 0, 1, 2, and 3.
00341         // Thus, the v'th node is simply = v.
00342         return cast_int<unsigned short>(v);
00343       }
00344 
00345     default:
00346       libmesh_error_msg("Invalid n = " << n);
00347 
00348     }
00349 
00350   libmesh_error_msg("We'll never get here!");
00351   return static_cast<unsigned short int>(-1);
00352 }
00353 
00354 } // namespace libMesh