$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 // C++ includes 00019 00020 // Local includes 00021 #include "libmesh/side.h" 00022 #include "libmesh/edge_edge3.h" 00023 #include "libmesh/face_tri6.h" 00024 00025 namespace libMesh 00026 { 00027 00028 00029 00030 00031 // ------------------------------------------------------------ 00032 // Tri6 class static member initializations 00033 const unsigned int Tri6::side_nodes_map[3][3] = 00034 { 00035 {0, 1, 3}, // Side 0 00036 {1, 2, 4}, // Side 1 00037 {2, 0, 5} // Side 2 00038 }; 00039 00040 00041 #ifdef LIBMESH_ENABLE_AMR 00042 00043 const float Tri6::_embedding_matrix[4][6][6] = 00044 { 00045 // embedding matrix for child 0 00046 { 00047 // 0 1 2 3 4 5 00048 { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0 00049 { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 1 00050 { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}, // 2 00051 {.375, -.125, 0.0, .75, 0.0, 0.0}, // 3 00052 { 0.0, -.125, -.125, 0.5, .25, 0.5}, // 4 00053 {.375, 0.0, -.125, 0.0, 0.0, .75} // 5 00054 }, 00055 00056 // embedding matrix for child 1 00057 { 00058 // 0 1 2 3 4 5 00059 { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0 00060 { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 1 00061 { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 2 00062 {-.125, .375, 0.0, .75, 0.0, 0.0}, // 3 00063 { 0.0, .375, -.125, 0.0, .75, 0.0}, // 4 00064 {-.125, 0.0, -.125, 0.5, 0.5, .25} // 5 00065 }, 00066 00067 // embedding matrix for child 2 00068 { 00069 // 0 1 2 3 4 5 00070 { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}, // 0 00071 { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 1 00072 { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 2 00073 {-.125, -.125, 0.0, .25, 0.5, 0.5}, // 3 00074 { 0.0, -.125, .375, 0.0, .75, 0.0}, // 4 00075 {-.125, 0.0, .375, 0.0, 0.0, .75} // 5 00076 }, 00077 00078 // embedding matrix for child 3 00079 { 00080 // 0 1 2 3 4 5 00081 { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0 00082 { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 1 00083 { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}, // 2 00084 {-.125, 0.0, -.125, 0.5, 0.5, .25}, // 3 00085 {-.125, -.125, 0.0, .25, 0.5, 0.5}, // 4 00086 { 0.0, -.125, -.125, 0.5, .25, 0.5} // 5 00087 } 00088 }; 00089 00090 #endif 00091 00092 00093 00094 // ------------------------------------------------------------ 00095 // Tri6 class member functions 00096 00097 bool Tri6::is_vertex(const unsigned int i) const 00098 { 00099 if (i < 3) 00100 return true; 00101 return false; 00102 } 00103 00104 bool Tri6::is_edge(const unsigned int i) const 00105 { 00106 if (i < 3) 00107 return false; 00108 return true; 00109 } 00110 00111 bool Tri6::is_face(const unsigned int) const 00112 { 00113 return false; 00114 } 00115 00116 bool Tri6::is_node_on_side(const unsigned int n, 00117 const unsigned int s) const 00118 { 00119 libmesh_assert_less (s, n_sides()); 00120 for (unsigned int i = 0; i != 3; ++i) 00121 if (side_nodes_map[s][i] == n) 00122 return true; 00123 return false; 00124 } 00125 00126 00127 00128 bool Tri6::has_affine_map() const 00129 { 00130 // Make sure edges are straight 00131 if (!this->point(3).relative_fuzzy_equals 00132 ((this->point(0) + this->point(1))/2.)) 00133 return false; 00134 if (!this->point(4).relative_fuzzy_equals 00135 ((this->point(1) + this->point(2))/2.)) 00136 return false; 00137 if (!this->point(5).relative_fuzzy_equals 00138 ((this->point(2) + this->point(0))/2.)) 00139 return false; 00140 00141 return true; 00142 } 00143 00144 00145 00146 dof_id_type Tri6::key (const unsigned int s) const 00147 { 00148 libmesh_assert_less (s, this->n_sides()); 00149 00150 switch (s) 00151 { 00152 case 0: 00153 00154 return 00155 this->compute_key (this->node(3)); 00156 00157 case 1: 00158 00159 return 00160 this->compute_key (this->node(4)); 00161 00162 case 2: 00163 00164 return 00165 this->compute_key (this->node(5)); 00166 00167 default: 00168 libmesh_error_msg("Invalid side s = " << s); 00169 } 00170 00171 libmesh_error_msg("We'll never get here!"); 00172 return 0; 00173 } 00174 00175 00176 00177 UniquePtr<Elem> Tri6::build_side (const unsigned int i, 00178 bool proxy) const 00179 { 00180 libmesh_assert_less (i, this->n_sides()); 00181 00182 if (proxy) 00183 return UniquePtr<Elem>(new Side<Edge3,Tri6>(this,i)); 00184 00185 else 00186 { 00187 Elem* edge = new Edge3; 00188 edge->subdomain_id() = this->subdomain_id(); 00189 00190 switch (i) 00191 { 00192 case 0: 00193 { 00194 edge->set_node(0) = this->get_node(0); 00195 edge->set_node(1) = this->get_node(1); 00196 edge->set_node(2) = this->get_node(3); 00197 break; 00198 } 00199 case 1: 00200 { 00201 edge->set_node(0) = this->get_node(1); 00202 edge->set_node(1) = this->get_node(2); 00203 edge->set_node(2) = this->get_node(4); 00204 break; 00205 } 00206 case 2: 00207 { 00208 edge->set_node(0) = this->get_node(2); 00209 edge->set_node(1) = this->get_node(0); 00210 edge->set_node(2) = this->get_node(5); 00211 break; 00212 } 00213 default: 00214 libmesh_error_msg("Invalid side i = " << i); 00215 } 00216 00217 return UniquePtr<Elem>(edge); 00218 } 00219 00220 libmesh_error_msg("We'll never get here!"); 00221 return UniquePtr<Elem>(); 00222 } 00223 00224 00225 void Tri6::connectivity(const unsigned int sf, 00226 const IOPackage iop, 00227 std::vector<dof_id_type>& conn) const 00228 { 00229 libmesh_assert_less (sf, this->n_sub_elem()); 00230 libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE); 00231 00232 switch (iop) 00233 { 00234 case TECPLOT: 00235 { 00236 conn.resize(4); 00237 switch(sf) 00238 { 00239 case 0: 00240 // linear sub-triangle 0 00241 conn[0] = this->node(0)+1; 00242 conn[1] = this->node(3)+1; 00243 conn[2] = this->node(5)+1; 00244 conn[3] = this->node(5)+1; 00245 00246 return; 00247 00248 case 1: 00249 // linear sub-triangle 1 00250 conn[0] = this->node(3)+1; 00251 conn[1] = this->node(1)+1; 00252 conn[2] = this->node(4)+1; 00253 conn[3] = this->node(4)+1; 00254 00255 return; 00256 00257 case 2: 00258 // linear sub-triangle 2 00259 conn[0] = this->node(5)+1; 00260 conn[1] = this->node(4)+1; 00261 conn[2] = this->node(2)+1; 00262 conn[3] = this->node(2)+1; 00263 00264 return; 00265 00266 case 3: 00267 // linear sub-triangle 3 00268 conn[0] = this->node(3)+1; 00269 conn[1] = this->node(4)+1; 00270 conn[2] = this->node(5)+1; 00271 conn[3] = this->node(5)+1; 00272 00273 return; 00274 00275 default: 00276 libmesh_error_msg("Invalid sf = " << sf); 00277 } 00278 } 00279 00280 case VTK: 00281 { 00282 // VTK_QUADRATIC_TRIANGLE has same numbering as libmesh TRI6 00283 conn.resize(6); 00284 conn[0] = this->node(0); 00285 conn[1] = this->node(1); 00286 conn[2] = this->node(2); 00287 conn[3] = this->node(3); 00288 conn[4] = this->node(4); 00289 conn[5] = this->node(5); 00290 return; 00291 00292 // Used to write out linear sub-triangles for VTK... 00293 /* 00294 conn.resize(3); 00295 switch(sf) 00296 { 00297 case 0: 00298 // linear sub-triangle 0 00299 conn[0] = this->node(0); 00300 conn[1] = this->node(3); 00301 conn[2] = this->node(5); 00302 00303 return; 00304 00305 case 1: 00306 // linear sub-triangle 1 00307 conn[0] = this->node(3); 00308 conn[1] = this->node(1); 00309 conn[2] = this->node(4); 00310 00311 return; 00312 00313 case 2: 00314 // linear sub-triangle 2 00315 conn[0] = this->node(5); 00316 conn[1] = this->node(4); 00317 conn[2] = this->node(2); 00318 00319 return; 00320 00321 case 3: 00322 // linear sub-triangle 3 00323 conn[0] = this->node(3); 00324 conn[1] = this->node(4); 00325 conn[2] = this->node(5); 00326 00327 return; 00328 00329 default: 00330 libmesh_error_msg("Invalid sf = " << sf); 00331 } 00332 */ 00333 } 00334 00335 default: 00336 libmesh_error_msg("Unsupported IO package " << iop); 00337 } 00338 } 00339 00340 00341 00342 00343 00344 unsigned short int Tri6::second_order_adjacent_vertex (const unsigned int n, 00345 const unsigned int v) const 00346 { 00347 libmesh_assert_greater_equal (n, this->n_vertices()); 00348 libmesh_assert_less (n, this->n_nodes()); 00349 libmesh_assert_less (v, 2); 00350 return _second_order_adjacent_vertices[n-this->n_vertices()][v]; 00351 } 00352 00353 00354 00355 const unsigned short int Tri6::_second_order_adjacent_vertices[3][2] = 00356 { 00357 {0, 1}, // vertices adjacent to node 3 00358 {1, 2}, // vertices adjacent to node 4 00359 {0, 2} // vertices adjacent to node 5 00360 }; 00361 00362 00363 00364 std::pair<unsigned short int, unsigned short int> 00365 Tri6::second_order_child_vertex (const unsigned int n) const 00366 { 00367 libmesh_assert_greater_equal (n, this->n_vertices()); 00368 libmesh_assert_less (n, this->n_nodes()); 00369 return std::pair<unsigned short int, unsigned short int> 00370 (_second_order_vertex_child_number[n], 00371 _second_order_vertex_child_index[n]); 00372 } 00373 00374 00375 00376 const unsigned short int Tri6::_second_order_vertex_child_number[6] = 00377 { 00378 99,99,99, // Vertices 00379 0,1,0 // Edges 00380 }; 00381 00382 00383 00384 const unsigned short int Tri6::_second_order_vertex_child_index[6] = 00385 { 00386 99,99,99, // Vertices 00387 1,2,2 // Edges 00388 }; 00389 00390 } // namespace libMesh