MOAB: Mesh Oriented datABase  (version 5.4.1)
PowerQualityMetric.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     [email protected], [email protected], [email protected],
00024     [email protected], [email protected], [email protected]
00025 
00026   ***************************************************************** */
00027 /*!
00028   \file   PowerQualityMetric.cpp
00029   \brief
00030 
00031   \author Michael Brewer
00032   \date   April 1, 2003
00033 */
00034 
00035 #include "PowerQualityMetric.hpp"
00036 #include "MsqError.hpp"
00037 
00038 using namespace MBMesquite;
00039 
00040 PowerQualityMetric::PowerQualityMetric( QualityMetric* qm, double pow_factor ) : mMetric( *qm ), mPower( pow_factor ) {}
00041 
00042 PowerQualityMetric::~PowerQualityMetric() {}
00043 
00044 std::string PowerQualityMetric::get_name() const
00045 {
00046     return std::string( "pow(" ) + mMetric.get_name() + ")";
00047 }
00048 
00049 int PowerQualityMetric::get_negate_flag() const
00050 {
00051     return mPower.value() < 0 ? mMetric.get_negate_flag() : -mMetric.get_negate_flag();
00052 }
00053 
00054 void PowerQualityMetric::get_evaluations( PatchData& pd, std::vector< size_t >& handles, bool free_only, MsqError& err )
00055 {
00056     mMetric.get_evaluations( pd, handles, free_only, err );MSQ_CHKERR( err );
00057 }
00058 
00059 bool PowerQualityMetric::evaluate( PatchData& pd, size_t handle, double& value, MsqError& err )
00060 {
00061     bool rval = mMetric.evaluate( pd, handle, value, err );
00062     value     = mPower.raise( value );
00063     return !MSQ_CHKERR( err ) && rval;
00064 }
00065 
00066 bool PowerQualityMetric::evaluate_with_indices( PatchData& pd,
00067                                                 size_t handle,
00068                                                 double& value,
00069                                                 std::vector< size_t >& indices,
00070                                                 MsqError& err )
00071 {
00072     bool rval = mMetric.evaluate_with_indices( pd, handle, value, indices, err );
00073     value     = mPower.raise( value );
00074     return !MSQ_CHKERR( err ) && rval;
00075 }
00076 
00077 bool PowerQualityMetric::evaluate_with_gradient( PatchData& pd,
00078                                                  size_t handle,
00079                                                  double& value,
00080                                                  std::vector< size_t >& indices,
00081                                                  std::vector< Vector3D >& gradient,
00082                                                  MsqError& err )
00083 {
00084     bool rval      = mMetric.evaluate_with_gradient( pd, handle, value, indices, gradient, err );
00085     const double v = mPower.raise( value );
00086     const double g = fabs( value ) > DBL_EPSILON ? mPower.value() * v / value : 0;
00087     value          = v;
00088     for( std::vector< Vector3D >::iterator i = gradient.begin(); i != gradient.end(); ++i )
00089         *i *= g;
00090     return !MSQ_CHKERR( err ) && rval;
00091 }
00092 
00093 bool PowerQualityMetric::evaluate_with_Hessian( PatchData& pd,
00094                                                 size_t handle,
00095                                                 double& value,
00096                                                 std::vector< size_t >& indices,
00097                                                 std::vector< Vector3D >& gradient,
00098                                                 std::vector< Matrix3D >& Hessian,
00099                                                 MsqError& err )
00100 {
00101     indices.clear();
00102     bool rval      = mMetric.evaluate_with_Hessian( pd, handle, value, indices, gradient, Hessian, err );
00103     const double v = mPower.raise( value );
00104     const double g = fabs( value ) > DBL_EPSILON ? mPower.value() * v / value : 0.0;
00105     const double h = fabs( value ) > DBL_EPSILON ? g * ( mPower.value() - 1 ) / value : 0.0;
00106     value          = v;
00107     Matrix3D op;
00108     unsigned idx = 0;
00109     unsigned n   = indices.size();
00110     for( unsigned r = 0; r < n; ++r )
00111     {
00112         for( unsigned c = r; c < n; ++c )
00113         {
00114             Hessian[idx] *= g;
00115             op.outer_product( gradient[r], gradient[c] );
00116             op *= h;
00117             Hessian[idx] += op;
00118             ++idx;
00119         }
00120         gradient[r] *= g;
00121     }
00122     return !MSQ_CHKERR( err ) && rval;
00123 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines