$extrastylesheet
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