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