cell_inf_hex.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 // Local includes 00019 #include "libmesh/libmesh_config.h" 00020 00021 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 00022 00023 00024 // C++ includes 00025 #include <algorithm> // for std::min, std::max 00026 00027 // Local includes cont'd 00028 #include "libmesh/cell_inf_hex.h" 00029 #include "libmesh/cell_inf_hex8.h" 00030 #include "libmesh/face_quad4.h" 00031 #include "libmesh/face_inf_quad4.h" 00032 00033 namespace libMesh 00034 { 00035 00036 00037 00038 00039 // ------------------------------------------------------------ 00040 // InfHex class member functions 00041 dof_id_type InfHex::key (const unsigned int s) const 00042 { 00043 libmesh_assert_less (s, this->n_sides()); 00044 00045 switch (s) 00046 { 00047 case 0: // the face at z = -1 00048 00049 return 00050 this->compute_key (this->node(0), 00051 this->node(1), 00052 this->node(2), 00053 this->node(3)); 00054 00055 case 1: // the face at y = -1 00056 00057 return 00058 this->compute_key (this->node(0), 00059 this->node(1), 00060 this->node(5), 00061 this->node(4)); 00062 00063 case 2: // the face at x = 1 00064 00065 return 00066 this->compute_key (this->node(1), 00067 this->node(2), 00068 this->node(6), 00069 this->node(5)); 00070 00071 case 3: // the face at y = 1 00072 00073 return 00074 this->compute_key (this->node(2), 00075 this->node(3), 00076 this->node(7), 00077 this->node(6)); 00078 00079 00080 case 4: // the face at x = -1 00081 00082 return 00083 this->compute_key (this->node(3), 00084 this->node(0), 00085 this->node(4), 00086 this->node(7)); 00087 } 00088 00089 // We'll never get here. 00090 libmesh_error(); 00091 return 0; 00092 } 00093 00094 00095 00096 AutoPtr<Elem> InfHex::side (const unsigned int i) const 00097 { 00098 libmesh_assert_less (i, this->n_sides()); 00099 00100 /* 00101 *Think of a unit cube: (-1,1) x (-1,1)x (-1,1), 00102 * with (in general) the normals pointing outwards 00103 */ 00104 switch (i) 00105 { 00106 case 0: // the face at z = -1 00107 // the base, where the infinite element couples to conventional 00108 // elements 00109 { 00110 Elem* face = new Quad4; 00111 AutoPtr<Elem> ap_face(face); 00112 00113 /* 00114 * Oops, here we are, claiming the normal of the face 00115 * elements point outwards -- and this is the exception: 00116 * For the side built from the base face, 00117 * the normal is pointing _into_ the element! 00118 * Why is that? - In agreement with build_side(), 00119 * which in turn _has_ to build the face in this 00120 * way as to enable the cool way \p InfFE re-uses \p FE. 00121 */ 00122 face->set_node(0) = this->get_node(0); 00123 face->set_node(1) = this->get_node(1); 00124 face->set_node(2) = this->get_node(2); 00125 face->set_node(3) = this->get_node(3); 00126 00127 return ap_face; 00128 } 00129 00130 case 1: // the face at y = -1 00131 // this face connects to another infinite element 00132 { 00133 Elem* face = new InfQuad4; 00134 AutoPtr<Elem> ap_face(face); 00135 00136 face->set_node(0) = this->get_node(0); 00137 face->set_node(1) = this->get_node(1); 00138 face->set_node(2) = this->get_node(4); 00139 face->set_node(3) = this->get_node(5); 00140 00141 return ap_face; 00142 } 00143 00144 case 2: // the face at x = 1 00145 // this face connects to another infinite element 00146 { 00147 Elem* face = new InfQuad4; 00148 AutoPtr<Elem> ap_face(face); 00149 //AutoPtr<Elem> face(new InfQuad4); 00150 00151 face->set_node(0) = this->get_node(1); 00152 face->set_node(1) = this->get_node(2); 00153 face->set_node(2) = this->get_node(5); 00154 face->set_node(3) = this->get_node(6); 00155 00156 return ap_face; 00157 } 00158 00159 case 3: // the face at y = 1 00160 // this face connects to another infinite element 00161 { 00162 Elem* face = new InfQuad4; 00163 AutoPtr<Elem> ap_face(face); 00164 //AutoPtr<Elem> face(new InfQuad4); 00165 00166 face->set_node(0) = this->get_node(2); 00167 face->set_node(1) = this->get_node(3); 00168 face->set_node(2) = this->get_node(6); 00169 face->set_node(3) = this->get_node(7); 00170 00171 return ap_face; 00172 } 00173 00174 case 4: // the face at x = -1 00175 // this face connects to another infinite element 00176 { 00177 Elem* face = new InfQuad4; 00178 AutoPtr<Elem> ap_face(face); 00179 //AutoPtr<Elem> face(new InfQuad4); 00180 00181 face->set_node(0) = this->get_node(3); 00182 face->set_node(1) = this->get_node(0); 00183 face->set_node(2) = this->get_node(7); 00184 face->set_node(3) = this->get_node(4); 00185 00186 return ap_face; 00187 } 00188 00189 default: 00190 { 00191 libmesh_error(); 00192 AutoPtr<Elem> ap(NULL); return ap; 00193 } 00194 } 00195 00196 // We'll never get here. 00197 libmesh_error(); 00198 AutoPtr<Elem> ap(NULL); return ap; 00199 } 00200 00201 00202 00203 bool InfHex::is_child_on_side(const unsigned int c, 00204 const unsigned int s) const 00205 { 00206 libmesh_assert_less (c, this->n_children()); 00207 libmesh_assert_less (s, this->n_sides()); 00208 00209 return (s == 0 || c+1 == s || c == s%4); 00210 } 00211 00212 00213 00214 bool InfHex::is_edge_on_side (const unsigned int e, 00215 const unsigned int s) const 00216 { 00217 libmesh_assert_less (e, this->n_edges()); 00218 libmesh_assert_less (s, this->n_sides()); 00219 00220 return (is_node_on_side(InfHex8::edge_nodes_map[e][0],s) && 00221 is_node_on_side(InfHex8::edge_nodes_map[e][1],s)); 00222 } 00223 00224 00225 00226 00227 Real InfHex::quality (const ElemQuality q) const 00228 { 00229 switch (q) 00230 { 00231 00241 case DIAGONAL: 00242 { 00243 // Diagonal between node 0 and node 2 00244 const Real d02 = this->length(0,2); 00245 00246 // Diagonal between node 1 and node 3 00247 const Real d13 = this->length(1,3); 00248 00249 // Find the biggest and smallest diagonals 00250 const Real min = std::min(d02, d13); 00251 const Real max = std::max(d02, d13); 00252 00253 libmesh_assert_not_equal_to (max, 0.0); 00254 00255 return min / max; 00256 00257 break; 00258 } 00259 00267 case TAPER: 00268 { 00269 00273 const Real d01 = this->length(0,1); 00274 const Real d12 = this->length(1,2); 00275 const Real d23 = this->length(2,3); 00276 const Real d03 = this->length(0,3); 00277 00278 std::vector<Real> edge_ratios(2); 00279 00280 // Bottom 00281 edge_ratios[8] = std::min(d01, d23) / std::max(d01, d23); 00282 edge_ratios[9] = std::min(d03, d12) / std::max(d03, d12); 00283 00284 return *(std::min_element(edge_ratios.begin(), edge_ratios.end())) ; 00285 00286 break; 00287 } 00288 00289 00297 case STRETCH: 00298 { 00302 const Real sqrt3 = 1.73205080756888; 00303 00307 const Real d02 = this->length(0,2); 00308 const Real d13 = this->length(1,3); 00309 const Real max_diag = std::max(d02, d13); 00310 00311 libmesh_assert_not_equal_to ( max_diag, 0.0 ); 00312 00316 std::vector<Real> edges(4); 00317 edges[0] = this->length(0,1); 00318 edges[1] = this->length(1,2); 00319 edges[2] = this->length(2,3); 00320 edges[3] = this->length(0,3); 00321 00322 const Real min_edge = *(std::min_element(edges.begin(), edges.end())); 00323 return sqrt3 * min_edge / max_diag ; 00324 break; 00325 } 00326 00327 00332 default: 00333 { 00334 return Elem::quality(q); 00335 } 00336 } 00337 00338 00339 // Will never get here... 00340 libmesh_error(); 00341 return 0.; 00342 } 00343 00344 00345 00346 std::pair<Real, Real> InfHex::qual_bounds (const ElemQuality) const 00347 { 00348 libmesh_not_implemented(); 00349 00350 std::pair<Real, Real> bounds; 00351 00352 /* 00353 switch (q) 00354 { 00355 00356 case ASPECT_RATIO: 00357 bounds.first = 1.; 00358 bounds.second = 4.; 00359 break; 00360 00361 case SKEW: 00362 bounds.first = 0.; 00363 bounds.second = 0.5; 00364 break; 00365 00366 case SHEAR: 00367 case SHAPE: 00368 bounds.first = 0.3; 00369 bounds.second = 1.; 00370 break; 00371 00372 case CONDITION: 00373 bounds.first = 1.; 00374 bounds.second = 8.; 00375 break; 00376 00377 case JACOBIAN: 00378 bounds.first = 0.5; 00379 bounds.second = 1.; 00380 break; 00381 00382 case DISTORTION: 00383 bounds.first = 0.6; 00384 bounds.second = 1.; 00385 break; 00386 00387 case TAPER: 00388 bounds.first = 0.; 00389 bounds.second = 0.4; 00390 break; 00391 00392 case STRETCH: 00393 bounds.first = 0.25; 00394 bounds.second = 1.; 00395 break; 00396 00397 case DIAGONAL: 00398 bounds.first = 0.65; 00399 bounds.second = 1.; 00400 break; 00401 00402 case SIZE: 00403 bounds.first = 0.5; 00404 bounds.second = 1.; 00405 break; 00406 00407 default: 00408 libMesh::out << "Warning: Invalid quality measure chosen." << std::endl; 00409 bounds.first = -1; 00410 bounds.second = -1; 00411 } 00412 */ 00413 00414 return bounds; 00415 } 00416 00417 00418 00419 00420 00421 const unsigned short int InfHex::_second_order_adjacent_vertices[8][2] = 00422 { 00423 { 0, 1}, // vertices adjacent to node 8 00424 { 1, 2}, // vertices adjacent to node 9 00425 { 2, 3}, // vertices adjacent to node 10 00426 { 0, 3}, // vertices adjacent to node 11 00427 00428 { 4, 5}, // vertices adjacent to node 12 00429 { 5, 6}, // vertices adjacent to node 13 00430 { 6, 7}, // vertices adjacent to node 14 00431 { 4, 7} // vertices adjacent to node 15 00432 }; 00433 00434 00435 00436 const unsigned short int InfHex::_second_order_vertex_child_number[18] = 00437 { 00438 99,99,99,99,99,99,99,99, // Vertices 00439 0,1,2,0, // Edges 00440 0,1,2,0,0, // Faces 00441 0 // Interior 00442 }; 00443 00444 00445 00446 const unsigned short int InfHex::_second_order_vertex_child_index[18] = 00447 { 00448 99,99,99,99,99,99,99,99, // Vertices 00449 1,2,3,3, // Edges 00450 5,6,7,7,2, // Faces 00451 6 // Interior 00452 }; 00453 00454 } // namespace libMesh 00455 00456 00457 00458 00459 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:45 UTC
Hosted By: