$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 #include <iostream> 00020 #include <sstream> 00021 00022 // Local includes 00023 #include "libmesh/libmesh_common.h" 00024 #include "libmesh/elem_quality.h" 00025 00026 namespace libMesh 00027 { 00028 00029 // ------------------------------------------------------------ 00030 // Quality function definitions 00031 00039 std::string Quality::name (const ElemQuality q) 00040 { 00041 std::string its_name; 00042 00043 switch (q) 00044 { 00045 00046 case ASPECT_RATIO: 00047 its_name = "Aspect Ratio"; 00048 break; 00049 00050 case SKEW: 00051 its_name = "Skew"; 00052 break; 00053 00054 case SHEAR: 00055 its_name = "Shear"; 00056 break; 00057 00058 case SHAPE: 00059 its_name = "Shape"; 00060 break; 00061 00062 case MAX_ANGLE: 00063 its_name = "Maximum Angle"; 00064 break; 00065 00066 case MIN_ANGLE: 00067 its_name = "Minimum Angle"; 00068 break; 00069 00070 case CONDITION: 00071 its_name = "Condition Number"; 00072 break; 00073 00074 case DISTORTION: 00075 its_name = "Distortion"; 00076 break; 00077 00078 case TAPER: 00079 its_name = "Taper"; 00080 break; 00081 00082 case WARP: 00083 its_name = "Warp"; 00084 break; 00085 00086 case STRETCH: 00087 its_name = "Stretch"; 00088 break; 00089 00090 case DIAGONAL: 00091 its_name = "Diagonal"; 00092 break; 00093 00094 case ASPECT_RATIO_BETA: 00095 its_name = "AR Beta"; 00096 break; 00097 00098 case ASPECT_RATIO_GAMMA: 00099 its_name = "AR Gamma"; 00100 break; 00101 00102 case SIZE: 00103 its_name = "Size"; 00104 break; 00105 00106 case JACOBIAN: 00107 its_name = "Jacobian"; 00108 break; 00109 00110 default: 00111 its_name = "Unknown"; 00112 break; 00113 } 00114 00115 return its_name; 00116 } 00117 00118 00119 00120 00121 00127 std::string Quality::describe (const ElemQuality q) 00128 { 00129 00130 std::ostringstream desc; 00131 00132 switch (q) 00133 { 00134 00135 case ASPECT_RATIO: 00136 desc << "Max edge length ratio\n" 00137 << "at element center.\n" 00138 << '\n' 00139 << "Suggested ranges:\n" 00140 << "Hexes: (1 -> 4)\n" 00141 << "Quads: (1 -> 4)"; 00142 break; 00143 00144 case SKEW: 00145 desc << "Maximum |cos A|, where A\n" 00146 << "is the angle between edges\n" 00147 << "at element center.\n" 00148 << '\n' 00149 << "Suggested ranges:\n" 00150 << "Hexes: (0 -> 0.5)\n" 00151 << "Quads: (0 -> 0.5)"; 00152 break; 00153 00154 case SHEAR: 00155 desc << "LIBMESH_DIM / K(Js)\n" 00156 << '\n' 00157 << "LIBMESH_DIM = element dimension.\n" 00158 << "K(Js) = Condition number of \n" 00159 << " Jacobian skew matrix.\n" 00160 << '\n' 00161 << "Suggested ranges:\n" 00162 << "Hexes(LIBMESH_DIM=3): (0.3 -> 1)\n" 00163 << "Quads(LIBMESH_DIM=2): (0.3 -> 1)"; 00164 break; 00165 00166 case SHAPE: 00167 desc << "LIBMESH_DIM / K(Jw)\n" 00168 << '\n' 00169 << "LIBMESH_DIM = element dimension.\n" 00170 << "K(Jw) = Condition number of \n" 00171 << " weighted Jacobian\n" 00172 << " matrix.\n" 00173 << '\n' 00174 << "Suggested ranges:\n" 00175 << "Hexes(LIBMESH_DIM=3): (0.3 -> 1)\n" 00176 << "Tets(LIBMESH_DIM=3): (0.2 -> 1)\n" 00177 << "Quads(LIBMESH_DIM=2): (0.3 -> 1)."; 00178 break; 00179 00180 case MAX_ANGLE: 00181 desc << "Largest included angle.\n" 00182 << '\n' 00183 << "Suggested ranges:\n" 00184 << "Quads: (90 -> 135)\n" 00185 << "Triangles: (60 -> 90)"; 00186 break; 00187 00188 case MIN_ANGLE: 00189 desc << "Smallest included angle.\n" 00190 << '\n' 00191 << "Suggested ranges:\n" 00192 << "Quads: (45 -> 90)\n" 00193 << "Triangles: (30 -> 60)"; 00194 break; 00195 00196 case CONDITION: 00197 desc << "Condition number of the\n" 00198 << "Jacobian matrix.\n" 00199 << '\n' 00200 << "Suggested ranges:\n" 00201 << "Quads: (1 -> 4)\n" 00202 << "Hexes: (1 -> 8)\n" 00203 << "Tris: (1 -> 1.3)\n" 00204 << "Tets: (1 -> 3)"; 00205 break; 00206 00207 case DISTORTION: 00208 desc << "min |J| * A / <A>\n" 00209 << '\n' 00210 << "|J| = norm of Jacobian matrix\n" 00211 << " A = actual area\n" 00212 << "<A> = reference area\n" 00213 << '\n' 00214 << "Suggested ranges:\n" 00215 << "Quads: (0.6 -> 1), <A>=4\n" 00216 << "Hexes: (0.6 -> 1), <A>=8\n" 00217 << "Tris: (0.6 -> 1), <A>=1/2\n" 00218 << "Tets: (0.6 -> 1), <A>=1/6"; 00219 break; 00220 00221 case TAPER: 00222 desc << "Maximum ratio of lengths\n" 00223 << "derived from opposited edges.\n" 00224 << '\n' 00225 << "Suggested ranges:\n" 00226 << "Quads: (0.7 -> 1)\n" 00227 << "Hexes: (0.4 -> 1)"; 00228 break; 00229 00230 case WARP: 00231 desc << "cos D\n" 00232 << '\n' 00233 << "D = minimum dihedral angle\n" 00234 << " formed by diagonals.\n" 00235 << '\n' 00236 << "Suggested ranges:\n" 00237 << "Quads: (0.9 -> 1)"; 00238 break; 00239 00240 case STRETCH: 00241 desc << "Sqrt(3) * L_min / L_max\n" 00242 << '\n' 00243 << "L_min = minimum edge length.\n" 00244 << "L_max = maximum edge length.\n" 00245 << '\n' 00246 << "Suggested ranges:\n" 00247 << "Quads: (0.25 -> 1)\n" 00248 << "Hexes: (0.25 -> 1)"; 00249 break; 00250 00251 case DIAGONAL: 00252 desc << "D_min / D_max\n" 00253 << '\n' 00254 << "D_min = minimum diagonal.\n" 00255 << "D_max = maximum diagonal.\n" 00256 << '\n' 00257 << "Suggested ranges:\n" 00258 << "Hexes: (0.65 -> 1)"; 00259 break; 00260 00261 case ASPECT_RATIO_BETA: 00262 desc << "CR / (3 * IR)\n" 00263 << '\n' 00264 << "CR = circumsphere radius\n" 00265 << "IR = inscribed sphere radius\n" 00266 << '\n' 00267 << "Suggested ranges:\n" 00268 << "Tets: (1 -> 3)"; 00269 break; 00270 00271 case ASPECT_RATIO_GAMMA: 00272 desc << "S^(3/2) / 8.479670 * V\n" 00273 << '\n' 00274 << "S = sum(si*si/6)\n" 00275 << "si = edge length\n" 00276 << "V = volume\n" 00277 << '\n' 00278 << "Suggested ranges:\n" 00279 << "Tets: (1 -> 3)"; 00280 break; 00281 00282 case SIZE: 00283 desc << "min (|J|, |1/J|)\n" 00284 << '\n' 00285 << "|J| = norm of Jacobian matrix.\n" 00286 << '\n' 00287 << "Suggested ranges:\n" 00288 << "Quads: (0.3 -> 1)\n" 00289 << "Hexes: (0.5 -> 1)\n" 00290 << "Tris: (0.25 -> 1)\n" 00291 << "Tets: (0.2 -> 1)"; 00292 break; 00293 00294 case JACOBIAN: 00295 desc << "Minimum Jacobian divided by\n" 00296 << "the lengths of the LIBMESH_DIM\n" 00297 << "largest edge vectors.\n" 00298 << '\n' 00299 << "LIBMESH_DIM = element dimension.\n" 00300 << '\n' 00301 << "Suggested ranges:\n" 00302 << "Quads: (0.5 -> 1)\n" 00303 << "Hexes: (0.5 -> 1)\n" 00304 << "Tris: (0.5 -> 1.155)\n" 00305 << "Tets: (0.5 -> 1.414)"; 00306 break; 00307 00308 default: 00309 desc << "Unknown"; 00310 break; 00311 } 00312 00313 return desc.str(); 00314 } 00315 00316 00321 std::vector<ElemQuality> Quality::valid(const ElemType t) 00322 { 00323 std::vector<ElemQuality> v; 00324 00325 switch (t) 00326 { 00327 case EDGE2: 00328 case EDGE3: 00329 case EDGE4: 00330 { 00331 // None yet 00332 break; 00333 } 00334 00335 case TRI3: 00336 case TRI6: 00337 { 00338 v.resize(7); 00339 v[0] = MAX_ANGLE; 00340 v[1] = MIN_ANGLE; 00341 v[2] = CONDITION; 00342 v[3] = JACOBIAN; 00343 v[4] = SIZE; 00344 v[5] = SHAPE; 00345 v[6] = DISTORTION; 00346 break; 00347 } 00348 00349 case QUAD4: 00350 case QUAD8: 00351 case QUAD9: 00352 { 00353 v.resize(13); 00354 v[0] = ASPECT_RATIO; 00355 v[1] = SKEW; 00356 v[2] = TAPER; 00357 v[3] = WARP; 00358 v[4] = STRETCH; 00359 v[5] = MIN_ANGLE; 00360 v[6] = MAX_ANGLE; 00361 v[7] = CONDITION; 00362 v[8] = JACOBIAN; 00363 v[9] = SHEAR; 00364 v[10] = SHAPE; 00365 v[11] = SIZE; 00366 v[12] = DISTORTION; 00367 break; 00368 } 00369 00370 case TET4: 00371 case TET10: 00372 { 00373 v.resize(7); 00374 v[0] = ASPECT_RATIO_BETA; 00375 v[1] = ASPECT_RATIO_GAMMA; 00376 v[2] = CONDITION; 00377 v[3] = JACOBIAN; 00378 v[4] = SHAPE; 00379 v[5] = SIZE; 00380 v[6] = DISTORTION; 00381 break; 00382 } 00383 00384 case HEX8: 00385 case HEX20: 00386 case HEX27: 00387 { 00388 v.resize(11); 00389 v[0] = ASPECT_RATIO; 00390 v[1] = SKEW; 00391 v[2] = SHEAR; 00392 v[3] = SHAPE; 00393 v[4] = CONDITION; 00394 v[5] = JACOBIAN; 00395 v[6] = DISTORTION; 00396 v[7] = TAPER; 00397 v[8] = STRETCH; 00398 v[9] = DIAGONAL; 00399 v[10] = SIZE; 00400 break; 00401 } 00402 00403 case PRISM6: 00404 case PRISM18: 00405 { 00406 // None yet 00407 break; 00408 } 00409 00410 case PYRAMID5: 00411 case PYRAMID13: 00412 case PYRAMID14: 00413 { 00414 // None yet 00415 break; 00416 } 00417 00418 00419 00420 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 00421 00422 case INFEDGE2: 00423 { 00424 // None yet 00425 break; 00426 } 00427 00428 case INFQUAD4: 00429 case INFQUAD6: 00430 { 00431 // None yet 00432 break; 00433 } 00434 00435 case INFHEX8: 00436 case INFHEX16: 00437 case INFHEX18: 00438 { 00439 // None yet 00440 break; 00441 } 00442 00443 case INFPRISM6: 00444 case INFPRISM12: 00445 { 00446 // None yet 00447 break; 00448 } 00449 00450 #endif 00451 00452 00453 default: 00454 libmesh_error_msg("Undefined element type!"); 00455 } 00456 00457 return v; 00458 } 00459 00460 } // namespace libMesh