cell_pyramid5.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 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 AutoPtr<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 { 00122 AutoPtr<Elem> face(new Side<Tri3,Pyramid5>(this,i)); 00123 return face; 00124 } 00125 00126 case 4: 00127 { 00128 AutoPtr<Elem> face(new Side<Quad4,Pyramid5>(this,i)); 00129 return face; 00130 } 00131 00132 default: 00133 { 00134 libmesh_error(); 00135 } 00136 } 00137 } 00138 00139 else 00140 { 00141 switch (i) 00142 { 00143 case 0: // triangular face 1 00144 { 00145 AutoPtr<Elem> face(new Tri3); 00146 00147 face->set_node(0) = this->get_node(0); 00148 face->set_node(1) = this->get_node(1); 00149 face->set_node(2) = this->get_node(4); 00150 00151 return face; 00152 } 00153 case 1: // triangular face 2 00154 { 00155 AutoPtr<Elem> face(new Tri3); 00156 00157 face->set_node(0) = this->get_node(1); 00158 face->set_node(1) = this->get_node(2); 00159 face->set_node(2) = this->get_node(4); 00160 00161 return face; 00162 } 00163 case 2: // triangular face 3 00164 { 00165 AutoPtr<Elem> face(new Tri3); 00166 00167 face->set_node(0) = this->get_node(2); 00168 face->set_node(1) = this->get_node(3); 00169 face->set_node(2) = this->get_node(4); 00170 00171 return face; 00172 } 00173 case 3: // triangular face 4 00174 { 00175 AutoPtr<Elem> face(new Tri3); 00176 00177 face->set_node(0) = this->get_node(3); 00178 face->set_node(1) = this->get_node(0); 00179 face->set_node(2) = this->get_node(4); 00180 00181 return face; 00182 } 00183 case 4: // the quad face at z=0 00184 { 00185 AutoPtr<Elem> face(new Quad4); 00186 00187 face->set_node(0) = this->get_node(0); 00188 face->set_node(1) = this->get_node(3); 00189 face->set_node(2) = this->get_node(2); 00190 face->set_node(3) = this->get_node(1); 00191 00192 return face; 00193 } 00194 default: 00195 { 00196 libmesh_error(); 00197 } 00198 } 00199 } 00200 00201 00202 // We'll never get here. 00203 libmesh_error(); 00204 AutoPtr<Elem> ap(NULL); return ap; 00205 } 00206 00207 00208 00209 AutoPtr<Elem> Pyramid5::build_edge (const unsigned int i) const 00210 { 00211 libmesh_assert_less (i, this->n_edges()); 00212 00213 return AutoPtr<Elem>(new SideEdge<Edge2,Pyramid5>(this,i)); 00214 } 00215 00216 00217 00218 void Pyramid5::connectivity(const unsigned int libmesh_dbg_var(sc), 00219 const IOPackage iop, 00220 std::vector<dof_id_type>& conn) const 00221 { 00222 libmesh_assert(_nodes); 00223 libmesh_assert_less (sc, this->n_sub_elem()); 00224 libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE); 00225 00226 switch (iop) 00227 { 00228 case TECPLOT: 00229 { 00230 conn.resize(8); 00231 conn[0] = this->node(0)+1; 00232 conn[1] = this->node(1)+1; 00233 conn[2] = this->node(2)+1; 00234 conn[3] = this->node(3)+1; 00235 conn[4] = this->node(4)+1; 00236 conn[5] = this->node(4)+1; 00237 conn[6] = this->node(4)+1; 00238 conn[7] = this->node(4)+1; 00239 return; 00240 } 00241 00242 case VTK: 00243 { 00244 conn.resize(5); 00245 conn[0] = this->node(3); 00246 conn[1] = this->node(2); 00247 conn[2] = this->node(1); 00248 conn[3] = this->node(0); 00249 conn[4] = this->node(4); 00250 return; 00251 } 00252 00253 default: 00254 libmesh_error(); 00255 } 00256 00257 libmesh_error(); 00258 } 00259 00260 00261 Real Pyramid5::volume () const 00262 { 00263 // The pyramid with a bilinear base has volume given by the 00264 // formula in: "Calculation of the Volume of a General Hexahedron 00265 // for Flow Predictions", AIAA Journal v.23, no.6, 1984, p.954- 00266 Node* node0 = this->get_node(0); 00267 Node* node1 = this->get_node(1); 00268 Node* node2 = this->get_node(2); 00269 Node* node3 = this->get_node(3); 00270 Node* node4 = this->get_node(4); 00271 00272 // Construct Various edge and diagonal vectors 00273 Point v40 ( *node0 - *node4 ); 00274 Point v13 ( *node3 - *node1 ); 00275 Point v02 ( *node2 - *node0 ); 00276 Point v03 ( *node3 - *node0 ); 00277 Point v01 ( *node1 - *node0 ); 00278 00279 // Finally, ready to return the volume! 00280 return (1./6.)*(v40*(v13.cross(v02))) + (1./12.)*(v02*(v01.cross(v03))); 00281 } 00282 00283 } // namespace libMesh
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:45 UTC
Hosted By: