$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/face_quad.h" 00022 #include "libmesh/edge_edge2.h" 00023 00024 namespace libMesh 00025 { 00026 00027 00028 // ------------------------------------------------------------ 00029 // Quad class member functions 00030 dof_id_type Quad::key (const unsigned int s) const 00031 { 00032 libmesh_assert_less (s, this->n_sides()); 00033 00034 switch (s) 00035 { 00036 case 0: 00037 return 00038 this->compute_key (this->node(0), 00039 this->node(1)); 00040 00041 case 1: 00042 return 00043 this->compute_key (this->node(1), 00044 this->node(2)); 00045 00046 case 2: 00047 return 00048 this->compute_key (this->node(2), 00049 this->node(3)); 00050 00051 case 3: 00052 return 00053 this->compute_key (this->node(3), 00054 this->node(0)); 00055 00056 default: 00057 libmesh_error_msg("Invalid side s = " << s); 00058 } 00059 00060 libmesh_error_msg("We'll never get here!"); 00061 return 0; 00062 } 00063 00064 00065 00066 UniquePtr<Elem> Quad::side (const unsigned int i) const 00067 { 00068 libmesh_assert_less (i, this->n_sides()); 00069 00070 Elem* edge = new Edge2; 00071 00072 switch (i) 00073 { 00074 case 0: 00075 { 00076 edge->set_node(0) = this->get_node(0); 00077 edge->set_node(1) = this->get_node(1); 00078 break; 00079 } 00080 case 1: 00081 { 00082 edge->set_node(0) = this->get_node(1); 00083 edge->set_node(1) = this->get_node(2); 00084 break; 00085 } 00086 case 2: 00087 { 00088 edge->set_node(0) = this->get_node(2); 00089 edge->set_node(1) = this->get_node(3); 00090 break; 00091 } 00092 case 3: 00093 { 00094 edge->set_node(0) = this->get_node(3); 00095 edge->set_node(1) = this->get_node(0); 00096 break; 00097 } 00098 default: 00099 libmesh_error_msg("Invalid side i = " << i); 00100 } 00101 00102 return UniquePtr<Elem>(edge); 00103 } 00104 00105 00106 00107 bool Quad::is_child_on_side(const unsigned int c, 00108 const unsigned int s) const 00109 { 00110 libmesh_assert_less (c, this->n_children()); 00111 libmesh_assert_less (s, this->n_sides()); 00112 00113 // A quad's children and nodes don't share the same ordering: 00114 // child 2 and 3 are swapped; 00115 unsigned int n = (c < 2) ? c : 5-c; 00116 return (n == s || n == (s+1)%4); 00117 } 00118 00119 00120 00121 unsigned int Quad::opposite_side(const unsigned int side_in) const 00122 { 00123 libmesh_assert_less (side_in, 4); 00124 00125 return (side_in + 2) % 4; 00126 } 00127 00128 00129 00130 unsigned int Quad::opposite_node(const unsigned int node_in, 00131 const unsigned int side_in) const 00132 { 00133 libmesh_assert_less (node_in, 8); 00134 libmesh_assert_less (node_in, this->n_nodes()); 00135 libmesh_assert_less (side_in, this->n_sides()); 00136 libmesh_assert(this->is_node_on_side(node_in, side_in)); 00137 00138 static const unsigned char side02_nodes_map[] = 00139 {3, 2, 1, 0, 6, 255, 4, 255}; 00140 static const unsigned char side13_nodes_map[] = 00141 {1, 0, 3, 2, 255, 7, 255, 5}; 00142 00143 switch (side_in) 00144 { 00145 case 0: 00146 case 2: 00147 return side02_nodes_map[node_in]; 00148 case 1: 00149 case 3: 00150 return side13_nodes_map[node_in]; 00151 default: 00152 libmesh_error_msg("Unsupported side_in = " << side_in); 00153 } 00154 00155 libmesh_error_msg("We'll never get here!"); 00156 return 255; 00157 } 00158 00159 00160 Real Quad::quality (const ElemQuality q) const 00161 { 00162 switch (q) 00163 { 00164 00169 case DISTORTION: 00170 case DIAGONAL: 00171 case STRETCH: 00172 { 00173 // Diagonal between node 0 and node 2 00174 const Real d02 = this->length(0,2); 00175 00176 // Diagonal between node 1 and node 3 00177 const Real d13 = this->length(1,3); 00178 00179 // Find the biggest and smallest diagonals 00180 if ( (d02 > 0.) && (d13 >0.) ) 00181 if (d02 < d13) return d02 / d13; 00182 else return d13 / d02; 00183 else 00184 return 0.; 00185 break; 00186 } 00187 00188 default: 00189 return Elem::quality(q); 00190 } 00191 00197 return Elem::quality(q); 00198 } 00199 00200 00201 00202 00203 00204 00205 std::pair<Real, Real> Quad::qual_bounds (const ElemQuality q) const 00206 { 00207 std::pair<Real, Real> bounds; 00208 00209 switch (q) 00210 { 00211 00212 case ASPECT_RATIO: 00213 bounds.first = 1.; 00214 bounds.second = 4.; 00215 break; 00216 00217 case SKEW: 00218 bounds.first = 0.; 00219 bounds.second = 0.5; 00220 break; 00221 00222 case TAPER: 00223 bounds.first = 0.; 00224 bounds.second = 0.7; 00225 break; 00226 00227 case WARP: 00228 bounds.first = 0.9; 00229 bounds.second = 1.; 00230 break; 00231 00232 case STRETCH: 00233 bounds.first = 0.25; 00234 bounds.second = 1.; 00235 break; 00236 00237 case MIN_ANGLE: 00238 bounds.first = 45.; 00239 bounds.second = 90.; 00240 break; 00241 00242 case MAX_ANGLE: 00243 bounds.first = 90.; 00244 bounds.second = 135.; 00245 break; 00246 00247 case CONDITION: 00248 bounds.first = 1.; 00249 bounds.second = 4.; 00250 break; 00251 00252 case JACOBIAN: 00253 bounds.first = 0.5; 00254 bounds.second = 1.; 00255 break; 00256 00257 case SHEAR: 00258 case SHAPE: 00259 case SIZE: 00260 bounds.first = 0.3; 00261 bounds.second = 1.; 00262 break; 00263 00264 case DISTORTION: 00265 bounds.first = 0.6; 00266 bounds.second = 1.; 00267 break; 00268 00269 default: 00270 libMesh::out << "Warning: Invalid quality measure chosen." << std::endl; 00271 bounds.first = -1; 00272 bounds.second = -1; 00273 } 00274 00275 return bounds; 00276 } 00277 00278 00279 00280 00281 const unsigned short int Quad::_second_order_adjacent_vertices[4][2] = 00282 { 00283 {0, 1}, // vertices adjacent to node 4 00284 {1, 2}, // vertices adjacent to node 5 00285 {2, 3}, // vertices adjacent to node 6 00286 {0, 3} // vertices adjacent to node 7 00287 }; 00288 00289 00290 00291 const unsigned short int Quad::_second_order_vertex_child_number[9] = 00292 { 00293 99,99,99,99, // Vertices 00294 0,1,2,0, // Edges 00295 0 // Interior 00296 }; 00297 00298 00299 00300 const unsigned short int Quad::_second_order_vertex_child_index[9] = 00301 { 00302 99,99,99,99, // Vertices 00303 1,2,3,3, // Edges 00304 2 // Interior 00305 }; 00306 00307 } // namespace libMesh