MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to 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 (2006) kraftche@cae.wisc.edu 00024 00025 ***************************************************************** */ 00026 00027 /** \file ElementMaxQM.cpp 00028 * \brief 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "ElementMaxQM.hpp" 00034 #include "ElemSampleQM.hpp" 00035 #include "MsqError.hpp" 00036 #include "PatchData.hpp" 00037 #include <limits> 00038 00039 namespace MBMesquite 00040 { 00041 00042 ElementMaxQM::ElementMaxQM( ElemSampleQM* metric ) : mMetric( metric ) {} 00043 00044 ElementMaxQM::~ElementMaxQM() {} 00045 00046 std::string ElementMaxQM::get_name() const 00047 { 00048 std::string result( "ElementMaxQM(" ); 00049 result += mMetric->get_name(); 00050 result += ")"; 00051 return result; 00052 } 00053 00054 int ElementMaxQM::get_negate_flag() const 00055 { 00056 return get_quality_metric()->get_negate_flag(); 00057 } 00058 00059 bool ElementMaxQM::evaluate( PatchData& pd, size_t handle, double& value, MsqError& err ) 00060 { 00061 ElemSampleQM* qm = get_quality_metric(); 00062 mHandles.clear(); 00063 qm->get_element_evaluations( pd, handle, mHandles, err ); 00064 MSQ_ERRFALSE( err ); 00065 00066 bool valid = true; 00067 double tmpval; 00068 bool tmpvalid; 00069 00070 value = -1.e+100; // initialize max computation 00071 for( std::vector< size_t >::iterator h = mHandles.begin(); h != mHandles.end(); ++h ) 00072 { 00073 tmpvalid = qm->evaluate( pd, *h, tmpval, err ); // MSQ_ERRZERO(err); 00074 if( !tmpvalid ) 00075 { 00076 value = +1.e+100; 00077 return false; // if any handle within the element makes tmpvalid false, then valid is 00078 // false, no matter what the other handles say 00079 } 00080 else if( tmpval > value ) 00081 value = tmpval; 00082 } 00083 00084 return valid; 00085 } 00086 /* 00087 bool ElementMaxQM::evaluate_with_gradient( PatchData& pd, 00088 size_t handle, 00089 double& value, 00090 std::vector<size_t>& indices, 00091 std::vector<Vector3D>& gradient, 00092 MsqError& err ) 00093 { 00094 ElemSampleQM* qm = get_quality_metric(); 00095 mHandles.clear(); 00096 qm->get_element_evaluations( pd, handle, mHandles, err ); MSQ_ERRFALSE(err); 00097 00098 bool valid = true; 00099 double tmpval; 00100 bool tmpvalid; 00101 unsigned count = 0; 00102 std::vector<size_t>::iterator h, i, j; 00103 00104 value = -std::numeric_limits<double>::maximum(); 00105 for (h = mHandles.begin(); h != mHandles.end(); ++h) { 00106 mIndices.clear(); 00107 mGrad.clear(); 00108 tmpvalid = qm->evaluate_with_gradient( pd, *h, tmpval, mIndices, mGrad, err ); 00109 MSQ_ERRZERO(err); 00110 if (!tmpvalid) { 00111 valid = false; 00112 } 00113 // new value greater than previous max value 00114 else if (tmpval - value > 1e-6) { 00115 indices = mIndices; 00116 gradient = mGrad; 00117 count = 1; 00118 value = tmpval; 00119 } 00120 // new value equal to previous max value 00121 else if (tmpval - value >= -1e-6) { 00122 ++count; 00123 for (i = mIndices.begin(); i != mIndices.end(); ++i) { 00124 j = std::find( indices.begin(), indices.end(), *i ); 00125 if (j == indices.end()) { 00126 indices.push_back( *i ); 00127 gradient.push_back( mGrad[i - mIndices.begin()] ); 00128 } 00129 else { 00130 gradient[j - indices.begin()] += mGrad[i - mIndices.begin()]; 00131 } 00132 } 00133 } 00134 } 00135 if (count > 1) { 00136 const double inv_count = 1.0 / count; 00137 for (std::vector<Vector3D>::iterator g = gradient.begin(); g != gradient.end(); ++g) 00138 *g *= inv_count; 00139 } 00140 00141 return valid; 00142 } 00143 */ 00144 00145 } // namespace MBMesquite