MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2004 Sandia Corporation and Argonne National 00005 Laboratory. Under the terms of Contract DE-AC04-94AL85000 00006 with Sandia Corporation, the U.S. Government retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov, 00024 pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov 00025 00026 ***************************************************************** */ 00027 /*! 00028 \file AspectRatioGammaQualityMetric.cpp 00029 00030 \brief Evaluates the Aspect Ratio Gamma metric for two- and 00031 three-diminsional simplicial elements. 00032 \author Michael Brewer 00033 \date 2002-05-09 00034 */ 00035 00036 #include "AspectRatioGammaQualityMetric.hpp" 00037 #include <cmath> 00038 #include "Vector3D.hpp" 00039 #include "MsqMeshEntity.hpp" 00040 #include "PatchData.hpp" 00041 00042 #include <vector> 00043 using std::vector; 00044 00045 using namespace MBMesquite; 00046 00047 const double fourDivRootThree = 4.0 / sqrt( 3.0 ); 00048 const double twelveDivRootTwo = 12.0 / sqrt( 2.0 ); 00049 00050 std::string AspectRatioGammaQualityMetric::get_name() const 00051 { 00052 return "AspectRatioGamma"; 00053 } 00054 00055 int AspectRatioGammaQualityMetric::get_negate_flag() const 00056 { 00057 return 1; 00058 } 00059 00060 // note that we can define this metric for other element types? 00061 //! Evaluate aspect ratio gamma on ``element'' 00062 bool AspectRatioGammaQualityMetric::evaluate( PatchData& pd, size_t elem_index, double& fval, MsqError& err ) 00063 { 00064 MsqMeshEntity& element = pd.element_by_index( elem_index ); 00065 EntityTopology entity = element.get_element_type(); 00066 double vol; 00067 Vector3D cross, normal( 0, 0, 0 ); 00068 fval = MSQ_MAX_CAP; 00069 00070 // get element's nodes 00071 vert.clear(); 00072 pd.get_element_vertex_coordinates( elem_index, vert, err ); 00073 MSQ_ERRZERO( err ); 00074 00075 switch( entity ) 00076 { 00077 case TRIANGLE: 00078 // area 00079 cross = ( vert[1] - vert[0] ) * ( vert[2] - vert[0] ); 00080 vol = cross.length() / 2.0; 00081 if( vol < MSQ_MIN ) return false; 00082 00083 if( pd.domain_set() ) 00084 { // need domain to check for inverted elements 00085 pd.get_domain_normal_at_corner( elem_index, 0, normal, err ); 00086 MSQ_ERRZERO( err ); 00087 if( ( cross % normal ) < -MSQ_MIN ) return false; 00088 } 00089 00090 // sum squares of edge lengths 00091 fval = ( ( vert[1] - vert[0] ).length_squared() + ( vert[2] - vert[0] ).length_squared() + 00092 ( vert[1] - vert[2] ).length_squared() ); 00093 // average 00094 fval /= 3.0; 00095 00096 // normalize to equil. and div by area 00097 fval /= vol * fourDivRootThree; 00098 00099 break; 00100 00101 case TETRAHEDRON: 00102 vol = ( vert[1] - vert[0] ) % ( ( vert[2] - vert[0] ) * ( vert[3] - vert[0] ) ) / 6.0; 00103 if( vol < MSQ_MIN ) // zero for degenerate and negative for inverted 00104 return false; 00105 00106 // sum squares of edge lengths 00107 fval = ( vert[1] - vert[0] ).length_squared() + ( vert[2] - vert[0] ).length_squared() + 00108 ( vert[3] - vert[0] ).length_squared() + ( vert[2] - vert[1] ).length_squared() + 00109 ( vert[3] - vert[1] ).length_squared() + ( vert[3] - vert[2] ).length_squared(); 00110 // average 00111 fval /= 6.0; 00112 00113 fval *= sqrt( fval ); 00114 // normalize to equil. and div by volume 00115 fval /= vol * twelveDivRootTwo; 00116 00117 break; 00118 default: 00119 MSQ_SETERR( err ) 00120 ( MsqError::UNSUPPORTED_ELEMENT, "Entity type %d is not valid for Aspect Ratio Gamma\n", (int)entity ); 00121 return false; 00122 }; 00123 00124 return true; 00125 }