MOAB: Mesh Oriented datABase  (version 5.2.1)
AspectRatioGammaQualityMetric.cpp
Go to the documentation of this file.
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 <math.h>
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines