face_quad8.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 // C++ includes 00019 00020 // Local includes 00021 #include "libmesh/side.h" 00022 #include "libmesh/edge_edge3.h" 00023 #include "libmesh/face_quad8.h" 00024 00025 namespace libMesh 00026 { 00027 00028 00029 00030 00031 // ------------------------------------------------------------ 00032 // Quad8 class static member initializations 00033 const unsigned int Quad8::side_nodes_map[4][3] = 00034 { 00035 {0, 1, 4}, // Side 0 00036 {1, 2, 5}, // Side 1 00037 {2, 3, 6}, // Side 2 00038 {3, 0, 7} // Side 3 00039 }; 00040 00041 00042 #ifdef LIBMESH_ENABLE_AMR 00043 00044 const float Quad8::_embedding_matrix[4][8][8] = 00045 { 00046 // embedding matrix for child 0 00047 { 00048 // 0 1 2 3 4 5 6 7 00049 { 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 0 00050 { 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000 }, // 1 00051 { -0.250000, -0.250000, -0.250000, -0.250000, 0.500000, 0.500000, 0.500000, 0.500000 }, // 2 00052 { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000 }, // 3 00053 { 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000, 0.00000 }, // 4 00054 { -0.187500, -0.187500, -0.187500, -0.187500, 0.750000, 0.375000, 0.250000, 0.375000 }, // 5 00055 { -0.187500, -0.187500, -0.187500, -0.187500, 0.375000, 0.250000, 0.375000, 0.750000 }, // 6 00056 { 0.375000, 0.00000, 0.00000, -0.125000, 0.00000, 0.00000, 0.00000, 0.750000 } // 7 00057 }, 00058 00059 // embedding matrix for child 1 00060 { 00061 // 0 1 2 3 4 5 6 7 00062 { 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000 }, // 0 00063 { 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 1 00064 { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000 }, // 2 00065 { -0.250000, -0.250000, -0.250000, -0.250000, 0.500000, 0.500000, 0.500000, 0.500000 }, // 3 00066 { -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000, 0.00000 }, // 4 00067 { 0.00000, 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000 }, // 5 00068 { -0.187500, -0.187500, -0.187500, -0.187500, 0.375000, 0.750000, 0.375000, 0.250000 }, // 6 00069 { -0.187500, -0.187500, -0.187500, -0.187500, 0.750000, 0.375000, 0.250000, 0.375000 } // 7 00070 }, 00071 00072 // embedding matrix for child 2 00073 { 00074 // 0 1 2 3 4 5 6 7 00075 { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000 }, // 0 00076 { -0.250000, -0.250000, -0.250000, -0.250000, 0.500000, 0.500000, 0.500000, 0.500000 }, // 1 00077 { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000 }, // 2 00078 { 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 3 00079 { -0.187500, -0.187500, -0.187500, -0.187500, 0.375000, 0.250000, 0.375000, 0.750000 }, // 4 00080 { -0.187500, -0.187500, -0.187500, -0.187500, 0.250000, 0.375000, 0.750000, 0.375000 }, // 5 00081 { 0.00000, 0.00000, -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000 }, // 6 00082 { -0.125000, 0.00000, 0.00000, 0.375000, 0.00000, 0.00000, 0.00000, 0.750000 } // 7 00083 }, 00084 00085 // embedding matrix for child 3 00086 { 00087 // 0 1 2 3 4 5 6 7 00088 { -0.250000, -0.250000, -0.250000, -0.250000, 0.500000, 0.500000, 0.500000, 0.500000 }, // 0 00089 { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000 }, // 1 00090 { 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 2 00091 { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000 }, // 3 00092 { -0.187500, -0.187500, -0.187500, -0.187500, 0.375000, 0.750000, 0.375000, 0.250000 }, // 4 00093 { 0.00000, -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000 }, // 5 00094 { 0.00000, 0.00000, 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000 }, // 6 00095 { -0.187500, -0.187500, -0.187500, -0.187500, 0.250000, 0.375000, 0.750000, 0.375000 } // 7 00096 } 00097 }; 00098 00099 00100 #endif 00101 00102 00103 // ------------------------------------------------------------ 00104 // Quad8 class member functions 00105 00106 bool Quad8::is_vertex(const unsigned int i) const 00107 { 00108 if (i < 4) 00109 return true; 00110 return false; 00111 } 00112 00113 bool Quad8::is_edge(const unsigned int i) const 00114 { 00115 if (i < 4) 00116 return false; 00117 return true; 00118 } 00119 00120 bool Quad8::is_face(const unsigned int) const 00121 { 00122 return false; 00123 } 00124 00125 bool Quad8::is_node_on_side(const unsigned int n, 00126 const unsigned int s) const 00127 { 00128 libmesh_assert_less (s, n_sides()); 00129 for (unsigned int i = 0; i != 3; ++i) 00130 if (side_nodes_map[s][i] == n) 00131 return true; 00132 return false; 00133 } 00134 00135 00136 00137 bool Quad8::has_affine_map() const 00138 { 00139 // make sure corners form a parallelogram 00140 Point v = this->point(1) - this->point(0); 00141 if (!v.relative_fuzzy_equals(this->point(2) - this->point(3))) 00142 return false; 00143 // make sure sides are straight 00144 v /= 2; 00145 if (!v.relative_fuzzy_equals(this->point(4) - this->point(0)) || 00146 !v.relative_fuzzy_equals(this->point(6) - this->point(3))) 00147 return false; 00148 v = (this->point(3) - this->point(0))/2; 00149 if (!v.relative_fuzzy_equals(this->point(7) - this->point(0)) || 00150 !v.relative_fuzzy_equals(this->point(5) - this->point(1))) 00151 return false; 00152 return true; 00153 } 00154 00155 00156 00157 dof_id_type Quad8::key (const unsigned int s) const 00158 { 00159 libmesh_assert_less (s, this->n_sides()); 00160 00161 switch (s) 00162 { 00163 case 0: 00164 00165 return 00166 this->compute_key (this->node(4)); 00167 00168 case 1: 00169 00170 return 00171 this->compute_key (this->node(5)); 00172 00173 case 2: 00174 00175 return 00176 this->compute_key (this->node(6)); 00177 00178 case 3: 00179 00180 return 00181 this->compute_key (this->node(7)); 00182 } 00183 00184 00185 // We will never get here... Look at the code above. 00186 libmesh_error(); 00187 return 0; 00188 } 00189 00190 00191 00192 AutoPtr<Elem> Quad8::build_side (const unsigned int i, 00193 bool proxy) const 00194 { 00195 libmesh_assert_less (i, this->n_sides()); 00196 00197 if (proxy) 00198 { 00199 AutoPtr<Elem> ap(new Side<Edge3,Quad8>(this,i)); 00200 return ap; 00201 } 00202 00203 else 00204 { 00205 Edge3* edge = new Edge3; 00206 00207 switch (i) 00208 { 00209 case 0: 00210 { 00211 edge->set_node(0) = this->get_node(0); 00212 edge->set_node(1) = this->get_node(1); 00213 edge->set_node(2) = this->get_node(4); 00214 00215 AutoPtr<Elem> ap(edge); return ap; 00216 } 00217 case 1: 00218 { 00219 edge->set_node(0) = this->get_node(1); 00220 edge->set_node(1) = this->get_node(2); 00221 edge->set_node(2) = this->get_node(5); 00222 00223 AutoPtr<Elem> ap(edge); return ap; 00224 } 00225 case 2: 00226 { 00227 edge->set_node(0) = this->get_node(2); 00228 edge->set_node(1) = this->get_node(3); 00229 edge->set_node(2) = this->get_node(6); 00230 00231 AutoPtr<Elem> ap(edge); return ap; 00232 } 00233 case 3: 00234 { 00235 edge->set_node(0) = this->get_node(3); 00236 edge->set_node(1) = this->get_node(0); 00237 edge->set_node(2) = this->get_node(7); 00238 00239 AutoPtr<Elem> ap(edge); return ap; 00240 } 00241 default: 00242 { 00243 libmesh_error(); 00244 } 00245 } 00246 } 00247 00248 // We will never get here... 00249 AutoPtr<Elem> ap(NULL); return ap; 00250 } 00251 00252 00253 00254 00255 00256 00257 void Quad8::connectivity(const unsigned int sf, 00258 const IOPackage iop, 00259 std::vector<dof_id_type>& conn) const 00260 { 00261 libmesh_assert_less (sf, this->n_sub_elem()); 00262 libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE); 00263 00264 switch (iop) 00265 { 00266 // Note: TECPLOT connectivity is output as four triangles with 00267 // a central quadrilateral. Therefore, the first four connectivity 00268 // arrays are degenerate quads (triangles in Tecplot). 00269 case TECPLOT: 00270 { 00271 // Create storage 00272 conn.resize(4); 00273 00274 switch(sf) 00275 { 00276 case 0: 00277 // linear sub-tri 0 00278 conn[0] = this->node(0)+1; 00279 conn[1] = this->node(4)+1; 00280 conn[2] = this->node(7)+1; 00281 conn[3] = this->node(7)+1; 00282 00283 return; 00284 00285 case 1: 00286 // linear sub-tri 1 00287 conn[0] = this->node(4)+1; 00288 conn[1] = this->node(1)+1; 00289 conn[2] = this->node(5)+1; 00290 conn[3] = this->node(5)+1; 00291 00292 return; 00293 00294 case 2: 00295 // linear sub-tri 2 00296 conn[0] = this->node(5)+1; 00297 conn[1] = this->node(2)+1; 00298 conn[2] = this->node(6)+1; 00299 conn[3] = this->node(6)+1; 00300 00301 return; 00302 00303 case 3: 00304 // linear sub-tri 3 00305 conn[0] = this->node(7)+1; 00306 conn[1] = this->node(6)+1; 00307 conn[2] = this->node(3)+1; 00308 conn[3] = this->node(3)+1; 00309 00310 return; 00311 00312 case 4: 00313 // linear sub-quad 00314 conn[0] = this->node(4)+1; 00315 conn[1] = this->node(5)+1; 00316 conn[2] = this->node(6)+1; 00317 conn[3] = this->node(7)+1; 00318 00319 return; 00320 00321 default: 00322 libmesh_error(); 00323 } 00324 } 00325 00326 00327 // Note: VTK connectivity is output as four triangles with 00328 // a central quadrilateral. Therefore most of the connectivity 00329 // arrays have length three. 00330 case VTK: 00331 { 00332 // Create storage 00333 conn.resize(8); 00334 conn[0] = this->node(0); 00335 conn[1] = this->node(1); 00336 conn[2] = this->node(2); 00337 conn[3] = this->node(3); 00338 conn[4] = this->node(4); 00339 conn[5] = this->node(5); 00340 conn[6] = this->node(6); 00341 conn[7] = this->node(7); 00342 return; 00343 /* 00344 conn.resize(3); 00345 00346 switch (sf) 00347 { 00348 case 0: 00349 // linear sub-tri 0 00350 conn[0] = this->node(0); 00351 conn[1] = this->node(4); 00352 conn[2] = this->node(7); 00353 00354 return; 00355 00356 case 1: 00357 // linear sub-tri 1 00358 conn[0] = this->node(4); 00359 conn[1] = this->node(1); 00360 conn[2] = this->node(5); 00361 00362 return; 00363 00364 case 2: 00365 // linear sub-tri 2 00366 conn[0] = this->node(5); 00367 conn[1] = this->node(2); 00368 conn[2] = this->node(6); 00369 00370 return; 00371 00372 case 3: 00373 // linear sub-tri 3 00374 conn[0] = this->node(7); 00375 conn[1] = this->node(6); 00376 conn[2] = this->node(3); 00377 00378 return; 00379 00380 case 4: 00381 conn.resize(4); 00382 00383 // linear sub-quad 00384 conn[0] = this->node(4); 00385 conn[1] = this->node(5); 00386 conn[2] = this->node(6); 00387 conn[3] = this->node(7); 00388 */ 00389 // return; 00390 00391 // default: 00392 // libmesh_error(); 00393 // } 00394 } 00395 00396 default: 00397 libmesh_error(); 00398 } 00399 00400 libmesh_error(); 00401 } 00402 00403 00404 00405 00406 unsigned short int Quad8::second_order_adjacent_vertex (const unsigned int n, 00407 const unsigned int v) const 00408 { 00409 libmesh_assert_greater_equal (n, this->n_vertices()); 00410 libmesh_assert_less (n, this->n_nodes()); 00411 libmesh_assert_less (v, 2); 00412 // use the matrix from \p face_quad.C 00413 return _second_order_adjacent_vertices[n-this->n_vertices()][v]; 00414 } 00415 00416 00417 00418 std::pair<unsigned short int, unsigned short int> 00419 Quad8::second_order_child_vertex (const unsigned int n) const 00420 { 00421 libmesh_assert_greater_equal (n, this->n_vertices()); 00422 libmesh_assert_less (n, this->n_nodes()); 00423 /* 00424 * the _second_order_vertex_child_* vectors are 00425 * stored in face_quad.C, since they are identical 00426 * for Quad8 and Quad9 (for the first 4 higher-order nodes) 00427 */ 00428 return std::pair<unsigned short int, unsigned short int> 00429 (_second_order_vertex_child_number[n], 00430 _second_order_vertex_child_index[n]); 00431 } 00432 00433 } // namespace libMesh 00434
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:46 UTC
Hosted By: