cell_inf_hex8.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 // C++ includes 00024 00025 // Local includes cont'd 00026 #include "libmesh/cell_inf_hex8.h" 00027 #include "libmesh/edge_edge2.h" 00028 #include "libmesh/edge_inf_edge2.h" 00029 #include "libmesh/face_quad4.h" 00030 #include "libmesh/face_inf_quad4.h" 00031 #include "libmesh/fe_interface.h" 00032 #include "libmesh/fe_type.h" 00033 #include "libmesh/side.h" 00034 00035 namespace libMesh 00036 { 00037 00038 00039 // ------------------------------------------------------------ 00040 // InfHex8 class member functions 00041 const unsigned int InfHex8::side_nodes_map[5][4] = 00042 { 00043 { 0, 1, 2, 3}, // Side 0 00044 { 0, 1, 4, 5}, // Side 1 00045 { 1, 2, 5, 6}, // Side 2 00046 { 2, 3, 6, 7}, // Side 3 00047 { 3, 0, 7, 4} // Side 4 00048 }; 00049 00050 const unsigned int InfHex8::edge_nodes_map[8][2] = 00051 { 00052 { 0, 1}, // Side 0 00053 { 1, 2}, // Side 1 00054 { 2, 3}, // Side 2 00055 { 0, 3}, // Side 3 00056 { 0, 4}, // Side 4 00057 { 1, 5}, // Side 5 00058 { 2, 6}, // Side 6 00059 { 3, 7} // Side 7 00060 }; 00061 00062 00063 // ------------------------------------------------------------ 00064 // InfHex8 class member functions 00065 00066 bool InfHex8::is_vertex(const unsigned int i) const 00067 { 00068 if (i < 4) 00069 return true; 00070 return false; 00071 } 00072 00073 bool InfHex8::is_edge(const unsigned int i) const 00074 { 00075 if (i < 4) 00076 return false; 00077 return true; 00078 } 00079 00080 bool InfHex8::is_face(const unsigned int) const 00081 { 00082 return false; 00083 } 00084 00085 bool InfHex8::is_node_on_side(const unsigned int n, 00086 const unsigned int s) const 00087 { 00088 libmesh_assert_less (s, n_sides()); 00089 for (unsigned int i = 0; i != 4; ++i) 00090 if (side_nodes_map[s][i] == n) 00091 return true; 00092 return false; 00093 } 00094 00095 bool InfHex8::is_node_on_edge(const unsigned int n, 00096 const unsigned int e) const 00097 { 00098 libmesh_assert_less (e, n_edges()); 00099 for (unsigned int i = 0; i != 2; ++i) 00100 if (edge_nodes_map[e][i] == n) 00101 return true; 00102 return false; 00103 } 00104 00105 AutoPtr<Elem> InfHex8::build_side (const unsigned int i, 00106 bool proxy) const 00107 { 00108 libmesh_assert_less (i, this->n_sides()); 00109 00110 if (proxy) 00111 { 00112 switch (i) 00113 { 00114 // base 00115 case 0: 00116 { 00117 AutoPtr<Elem> ap(new Side<Quad4,InfHex8>(this,i)); 00118 return ap; 00119 } 00120 // ifem sides 00121 case 1: 00122 case 2: 00123 case 3: 00124 case 4: 00125 { 00126 AutoPtr<Elem> ap(new Side<InfQuad4,InfHex8>(this,i)); 00127 return ap; 00128 } 00129 default: 00130 libmesh_error(); 00131 } 00132 } 00133 00134 else 00135 { 00136 // FIXME: Find out how to return non-proxy side 00137 libmesh_error(); 00138 } 00139 00140 00141 // We'll never get here. 00142 libmesh_error(); 00143 AutoPtr<Elem> ap(NULL); return ap; 00144 } 00145 00146 00147 AutoPtr<Elem> InfHex8::build_edge (const unsigned int i) const 00148 { 00149 libmesh_assert_less (i, this->n_edges()); 00150 00151 if (i < 4) // base edges 00152 return AutoPtr<Elem>(new SideEdge<Edge2,InfHex8>(this,i)); 00153 // infinite edges 00154 return AutoPtr<Elem>(new SideEdge<InfEdge2,InfHex8>(this,i)); 00155 } 00156 00157 bool InfHex8::contains_point (const Point& p, Real tol) const 00158 { 00159 /* 00160 * For infinite elements with linear base interpolation: 00161 * 00162 * make use of the fact that infinite elements do not 00163 * live inside the envelope. Use a fast scheme to 00164 * check whether point \p p is inside or outside 00165 * our relevant part of the envelope. Note that 00166 * this is not exclusive: only when the distance is less, 00167 * we are safe. Otherwise, we cannot say anything. The 00168 * envelope may be non-spherical, the physical point may lie 00169 * inside the envelope, outside the envelope, or even inside 00170 * this infinite element. Therefore if this fails, 00171 * fall back to the FEInterface::inverse_map() 00172 */ 00173 const Point origin (this->origin()); 00174 00175 /* 00176 * determine the minimal distance of the base from the origin 00177 * Use size_sq() instead of size(), it is faster 00178 */ 00179 const Real min_distance_sq = std::min((Point(this->point(0)-origin)).size_sq(), 00180 std::min((Point(this->point(1)-origin)).size_sq(), 00181 std::min((Point(this->point(2)-origin)).size_sq(), 00182 (Point(this->point(3)-origin)).size_sq()))); 00183 00184 /* 00185 * work with 1% allowable deviation. We can still fall 00186 * back to the InfFE::inverse_map() 00187 */ 00188 const Real conservative_p_dist_sq = 1.01 * (Point(p-origin).size_sq()); 00189 00190 00191 00192 if (conservative_p_dist_sq < min_distance_sq) 00193 { 00194 /* 00195 * the physical point is definitely not contained in the element 00196 */ 00197 return false; 00198 } 00199 else 00200 { 00201 /* 00202 * Declare a basic FEType. Will use default in the base, 00203 * and something else (not important) in radial direction. 00204 */ 00205 FEType fe_type(default_order()); 00206 00207 const Point mapped_point = FEInterface::inverse_map(dim(), 00208 fe_type, 00209 this, 00210 p, 00211 tol, 00212 false); 00213 00214 return FEInterface::on_reference_element(mapped_point, this->type(), tol); 00215 } 00216 } 00217 00218 00219 void InfHex8::connectivity(const unsigned int libmesh_dbg_var(sc), 00220 const IOPackage iop, 00221 std::vector<dof_id_type>& conn) const 00222 { 00223 libmesh_assert(_nodes); 00224 libmesh_assert_less (sc, this->n_sub_elem()); 00225 libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE); 00226 00227 switch (iop) 00228 { 00229 case TECPLOT: 00230 { 00231 conn.resize(8); 00232 conn[0] = this->node(0)+1; 00233 conn[1] = this->node(1)+1; 00234 conn[2] = this->node(2)+1; 00235 conn[3] = this->node(3)+1; 00236 conn[4] = this->node(4)+1; 00237 conn[5] = this->node(5)+1; 00238 conn[6] = this->node(6)+1; 00239 conn[7] = this->node(7)+1; 00240 return; 00241 } 00242 00243 00244 default: 00245 libmesh_error(); 00246 } 00247 00248 libmesh_error(); 00249 } 00250 00251 00252 00253 #ifdef LIBMESH_ENABLE_AMR 00254 00255 const float InfHex8::_embedding_matrix[4][8][8] = 00256 { 00257 // embedding matrix for child 0 00258 { 00259 // 0 1 2 3 4 5 6 7 th parent N.(ode) 00260 { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N. 00261 { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1 00262 { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 2 00263 { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3 00264 { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 4 00265 { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 5 00266 { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 6 00267 { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5} // 7 00268 }, 00269 00270 // embedding matrix for child 1 00271 { 00272 // 0 1 2 3 4 5 6 7 th parent N.(ode) 00273 { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N. 00274 { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1 00275 { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2 00276 { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 3 00277 { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 4 00278 { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 5 00279 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 6 00280 { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25} // 7 00281 }, 00282 00283 // embedding matrix for child 2 00284 { 00285 // 0 1 2 3 4 5 6 7 th parent N.(ode) 00286 { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 0th child N. 00287 { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 1 00288 { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 2 00289 { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 3 00290 { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5}, // 4 00291 { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 5 00292 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}, // 6 00293 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0} // 7 00294 }, 00295 00296 // embedding matrix for child 3 00297 { 00298 // 0 1 2 3 4 5 6 7 th parent N.(ode) 00299 { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 0th child N. 00300 { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1 00301 { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2 00302 { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3 00303 { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 4 00304 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 5 00305 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 6 00306 { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5} // 7 00307 } 00308 }; 00309 00310 00311 00312 #endif 00313 00314 } // namespace libMesh 00315 00316 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:45 UTC
Hosted By: