$extrastylesheet
cell_pyramid5.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_pyramid5.h"
00024 #include "libmesh/edge_edge2.h"
00025 #include "libmesh/face_tri3.h"
00026 #include "libmesh/face_quad4.h"
00027 
00028 namespace libMesh
00029 {
00030 
00031 
00032 
00033 
00034 // ------------------------------------------------------------
00035 // Pyramid5 class static member initializations
00036 const unsigned int Pyramid5::side_nodes_map[5][4] =
00037   {
00038     {0, 1, 4, 99}, // Side 0
00039     {1, 2, 4, 99}, // Side 1
00040     {2, 3, 4, 99}, // Side 2
00041     {3, 0, 4, 99}, // Side 3
00042     {0, 3, 2,  1}  // Side 4
00043   };
00044 
00045 const unsigned int Pyramid5::edge_nodes_map[8][2] =
00046   {
00047     {0, 1}, // Side 0
00048     {1, 2}, // Side 1
00049     {2, 3}, // Side 2
00050     {0, 3}, // Side 3
00051     {0, 4}, // Side 4
00052     {1, 4}, // Side 5
00053     {2, 4}, // Side 6
00054     {3, 4}  // Side 7
00055   };
00056 
00057 
00058 
00059 // ------------------------------------------------------------
00060 // Pyramid5 class member functions
00061 
00062 bool Pyramid5::is_vertex(const unsigned int) const
00063 {
00064   return true;
00065 }
00066 
00067 bool Pyramid5::is_edge(const unsigned int) const
00068 {
00069   return false;
00070 }
00071 
00072 bool Pyramid5::is_face(const unsigned int) const
00073 {
00074   return false;
00075 }
00076 
00077 bool Pyramid5::is_node_on_side(const unsigned int n,
00078                                const unsigned int s) const
00079 {
00080   libmesh_assert_less (s, n_sides());
00081   for (unsigned int i = 0; i != 4; ++i)
00082     if (side_nodes_map[s][i] == n)
00083       return true;
00084   return false;
00085 }
00086 
00087 bool Pyramid5::is_node_on_edge(const unsigned int n,
00088                                const unsigned int e) const
00089 {
00090   libmesh_assert_less (e, n_edges());
00091   for (unsigned int i = 0; i != 2; ++i)
00092     if (edge_nodes_map[e][i] == n)
00093       return true;
00094   return false;
00095 }
00096 
00097 
00098 
00099 bool Pyramid5::has_affine_map() const
00100 {
00101   //  Point v = this->point(3) - this->point(0);
00102   //  return (v.relative_fuzzy_equals(this->point(2) - this->point(1)));
00103   return false;
00104 }
00105 
00106 
00107 
00108 UniquePtr<Elem> Pyramid5::build_side (const unsigned int i,
00109                                       bool proxy) const
00110 {
00111   libmesh_assert_less (i, this->n_sides());
00112 
00113   if (proxy)
00114     {
00115       switch (i)
00116         {
00117         case 0:
00118         case 1:
00119         case 2:
00120         case 3:
00121           return UniquePtr<Elem>(new Side<Tri3,Pyramid5>(this,i));
00122 
00123         case 4:
00124           return UniquePtr<Elem>(new Side<Quad4,Pyramid5>(this,i));
00125 
00126         default:
00127           libmesh_error_msg("Invalid side i = " << i);
00128         }
00129     }
00130 
00131   else
00132     {
00133       // Create NULL pointer to be initialized, returned later.
00134       Elem* face = NULL;
00135 
00136       switch (i)
00137         {
00138         case 0:  // triangular face 1
00139           {
00140             face = new Tri3;
00141 
00142             face->set_node(0) = this->get_node(0);
00143             face->set_node(1) = this->get_node(1);
00144             face->set_node(2) = this->get_node(4);
00145 
00146             break;
00147           }
00148         case 1:  // triangular face 2
00149           {
00150             face = new Tri3;
00151 
00152             face->set_node(0) = this->get_node(1);
00153             face->set_node(1) = this->get_node(2);
00154             face->set_node(2) = this->get_node(4);
00155 
00156             break;
00157           }
00158         case 2:  // triangular face 3
00159           {
00160             face = new Tri3;
00161 
00162             face->set_node(0) = this->get_node(2);
00163             face->set_node(1) = this->get_node(3);
00164             face->set_node(2) = this->get_node(4);
00165 
00166             break;
00167           }
00168         case 3:  // triangular face 4
00169           {
00170             face = new Tri3;
00171 
00172             face->set_node(0) = this->get_node(3);
00173             face->set_node(1) = this->get_node(0);
00174             face->set_node(2) = this->get_node(4);
00175 
00176             break;
00177           }
00178         case 4:  // the quad face at z=0
00179           {
00180             face = new Quad4;
00181 
00182             face->set_node(0) = this->get_node(0);
00183             face->set_node(1) = this->get_node(3);
00184             face->set_node(2) = this->get_node(2);
00185             face->set_node(3) = this->get_node(1);
00186 
00187             break;
00188           }
00189         default:
00190           libmesh_error_msg("Invalid side i = " << i);
00191         }
00192 
00193       face->subdomain_id() = this->subdomain_id();
00194       return UniquePtr<Elem>(face);
00195     }
00196 
00197   libmesh_error_msg("We'll never get here!");
00198   return UniquePtr<Elem>();
00199 }
00200 
00201 
00202 
00203 UniquePtr<Elem> Pyramid5::build_edge (const unsigned int i) const
00204 {
00205   libmesh_assert_less (i, this->n_edges());
00206 
00207   return UniquePtr<Elem>(new SideEdge<Edge2,Pyramid5>(this,i));
00208 }
00209 
00210 
00211 
00212 void Pyramid5::connectivity(const unsigned int libmesh_dbg_var(sc),
00213                             const IOPackage iop,
00214                             std::vector<dof_id_type>& conn) const
00215 {
00216   libmesh_assert(_nodes);
00217   libmesh_assert_less (sc, this->n_sub_elem());
00218   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
00219 
00220   switch (iop)
00221     {
00222     case TECPLOT:
00223       {
00224         conn.resize(8);
00225         conn[0] = this->node(0)+1;
00226         conn[1] = this->node(1)+1;
00227         conn[2] = this->node(2)+1;
00228         conn[3] = this->node(3)+1;
00229         conn[4] = this->node(4)+1;
00230         conn[5] = this->node(4)+1;
00231         conn[6] = this->node(4)+1;
00232         conn[7] = this->node(4)+1;
00233         return;
00234       }
00235 
00236     case VTK:
00237       {
00238         conn.resize(5);
00239         conn[0] = this->node(3);
00240         conn[1] = this->node(2);
00241         conn[2] = this->node(1);
00242         conn[3] = this->node(0);
00243         conn[4] = this->node(4);
00244         return;
00245       }
00246 
00247     default:
00248       libmesh_error_msg("Unsupported IO package " << iop);
00249     }
00250 }
00251 
00252 
00253 Real Pyramid5::volume () const
00254 {
00255   // The pyramid with a bilinear base has volume given by the
00256   // formula in: "Calculation of the Volume of a General Hexahedron
00257   // for Flow Predictions", AIAA Journal v.23, no.6, 1984, p.954-
00258   Node* node0 = this->get_node(0);
00259   Node* node1 = this->get_node(1);
00260   Node* node2 = this->get_node(2);
00261   Node* node3 = this->get_node(3);
00262   Node* node4 = this->get_node(4);
00263 
00264   // Construct Various edge and diagonal vectors
00265   Point v40 ( *node0 - *node4 );
00266   Point v13 ( *node3 - *node1 );
00267   Point v02 ( *node2 - *node0 );
00268   Point v03 ( *node3 - *node0 );
00269   Point v01 ( *node1 - *node0 );
00270 
00271   // Finally, ready to return the volume!
00272   return (1./6.)*(v40*(v13.cross(v02))) + (1./12.)*(v02*(v01.cross(v03)));
00273 }
00274 
00275 } // namespace libMesh