MOAB: Mesh Oriented datABase  (version 5.2.1)
QualityMetric.hpp
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     (2006) kraftche@cae.wisc.edu
00027 
00028   ***************************************************************** */
00029 
00030 /*! \file QualityMetric.hpp
00031     \brief
00032 Header file for the MBMesquite::QualityMetric class
00033 
00034   \author Thomas Leurent
00035   \author Michael Brewer
00036   \date   2002-05-01
00037  */
00038 
00039 #ifndef QualityMetric_hpp
00040 #define QualityMetric_hpp
00041 
00042 #include <cmath>
00043 #include <vector>
00044 #include <algorithm>
00045 
00046 #include "Mesquite.hpp"
00047 #include "Vector3D.hpp"
00048 #include "Matrix3D.hpp"
00049 
00050 #ifdef _WIN32
00051 typedef unsigned uint32_t;
00052 #elif defined( MOAB_HAVE_STDINT_H )
00053 #include <stdint.h>
00054 #elif defined( MOAB_HAVE_INTTYPES_H )
00055 #include <inttypes.h>
00056 #endif
00057 
00058 namespace MBMesquite
00059 {
00060 
00061 /*! \class QualityMetric
00062   \brief Base class for concrete quality metrics.
00063 */
00064 class PatchData;
00065 class MsqMeshEntity;
00066 class Mesh;
00067 class MeshDomain;
00068 class MeshDomainAssoc;
00069 class Settings;
00070 
00071 class QualityMetric
00072 {
00073   protected:
00074     QualityMetric() : keepFiniteDiffEps( false ), haveFiniteDiffEps( false ) {}
00075 
00076   public:
00077     enum MetricType
00078     {
00079         VERTEX_BASED, /**< Iterate over vertices to evaluate metric. */
00080         ELEMENT_BASED /**< Iterate over elements to evaluate metric. */
00081     };
00082 
00083     MESQUITE_EXPORT virtual ~QualityMetric() {}
00084 
00085     MESQUITE_EXPORT virtual MetricType get_metric_type() const = 0;
00086 
00087     MESQUITE_EXPORT virtual std::string get_name() const = 0;
00088 
00089     //! 1 if metric should be minimized, -1 if metric should be maximized.
00090     MESQUITE_EXPORT virtual int get_negate_flag() const = 0;
00091 
00092     /**\brief Get locations at which metric can be evaluated
00093      *
00094      * Different metrics are evaluated for different things within
00095      * a patch.  For example, an element-based metric will be evaluated
00096      * once for each element in patch, a vertex-based metric once for
00097      * each veretx, and a target/sample-point based metric will be
00098      * evaluated once for each samle point in each element.  This method
00099      * returns a list of handles, one for each location in the patch
00100      * at which the metric can be evaluated.  The handle values are used
00101      * as input to the evaluate methods.
00102      *\param pd       The patch
00103      *\param handles  Output list of handles
00104      *\param free_vertices_only If true, only pass back evaluation points
00105      *         that depend on at least one free vertex.
00106      */
00107     MESQUITE_EXPORT virtual void get_evaluations( PatchData& pd, std::vector< size_t >& handles,
00108                                                   bool free_vertices_only, MsqError& err ) = 0;
00109 
00110     /**\brief Get locations at which metric can be evaluated for
00111      *        use in BCD intialization and QualityAssessor.
00112      *
00113      * For element-based, sample-based, and vertex-based metrics,
00114      * this function is the same as get_evaluations.  For edge-based
00115      * metrics it returns only a subset of the results for get_evaluations
00116      * such that each edge in the mesh is visited only once even though
00117      * it would normally be visited twice when iterating over patches
00118      * of the mesh.  This assumes that no vertex occurs in more than one
00119      * patch without its MSQ_PATCH_FIXED flag set.  This assumption is true for
00120      * both element-on-vertex and global patches.
00121      *\param pd       The patch
00122      *\param handles  Output list of handles
00123      *\param free_vertices_only If true, only pass back evaluation points
00124      *         that depend on at least one free vertex.
00125      */
00126     MESQUITE_EXPORT virtual void get_single_pass( PatchData& pd, std::vector< size_t >& handles,
00127                                                   bool free_vertices_only, MsqError& err );
00128 
00129     /**\brief Get metric value at a logical location in the patch.
00130      *
00131      * Evaluate the metric at one location in the PatchData.
00132      *\param pd     The patch.
00133      *\param handle The location in the patch (as passed back from get_evaluations).
00134      *\param value  The output metric value.
00135      */
00136     MESQUITE_EXPORT virtual bool evaluate( PatchData& pd, size_t handle, double& value, MsqError& err ) = 0;
00137 
00138     /**\brief Get metric value at a logical location in the patch.
00139      *
00140      * Evaluate the metric at one location in the PatchData.
00141      *\param pd      The patch.
00142      *\param handle  The location in the patch (as passed back from get_evaluations).
00143      *\param value   The output metric value.
00144      *\param indices The free vertices that the evaluation is a function
00145      *               of, specified as vertex indices in the PatchData.
00146      */
00147     MESQUITE_EXPORT virtual bool evaluate_with_indices( PatchData& pd, size_t handle, double& value,
00148                                                         std::vector< size_t >& indices, MsqError& err ) = 0;
00149 
00150     /**\brief Get metric value and gradient at a logical location in the patch.
00151      *
00152      * Evaluate the metric at one location in the PatchData.
00153      *\param pd      The patch.
00154      *\param handle  The location in the patch (as passed back from get_evaluations).
00155      *\param value   The output metric value.
00156      *\param indices The free vertices that the evaluation is a function
00157      *               of, specified as vertex indices in the PatchData.
00158      *\param gradient The gradient of the metric as a function of the
00159      *               coordinates of the free vertices passed back in
00160      *               the indices list.
00161      */
00162     MESQUITE_EXPORT virtual bool evaluate_with_gradient( PatchData& pd, size_t handle, double& value,
00163                                                          std::vector< size_t >& indices,
00164                                                          std::vector< Vector3D >& gradient, MsqError& err );
00165 
00166     /**\brief Get metric value and gradient at a logical location in the patch.
00167      *
00168      * Evaluate the metric at one location in the PatchData.
00169      *\param pd      The patch.
00170      *\param handle  The location in the patch (as passed back from get_evaluations).
00171      *\param value   The output metric value.
00172      *\param indices The free vertices that the evaluation is a function
00173      *               of, specified as vertex indices in the PatchData.
00174      *\param gradient The gradient of the metric as a function of the
00175      *               coordinates of the free vertices passed back in
00176      *               the indices list.
00177      *\param Hessian_diagonal The 3x3 blocks along the diagonal of
00178      *               the Hessian matrix.
00179      */
00180     MESQUITE_EXPORT virtual bool evaluate_with_Hessian_diagonal( PatchData& pd, size_t handle, double& value,
00181                                                                  std::vector< size_t >& indices,
00182                                                                  std::vector< Vector3D >& gradient,
00183                                                                  std::vector< SymMatrix3D >& Hessian_diagonal,
00184                                                                  MsqError& err );
00185 
00186     /**\brief Get metric value and deravitives at a logical location in the patch.
00187      *
00188      * Evaluate the metric at one location in the PatchData.
00189      *\param pd      The patch.
00190      *\param handle  The location in the patch (as passed back from get_evaluations).
00191      *\param value   The output metric value.
00192      *\param indices The free vertices that the evaluation is a function
00193      *               of, specified as vertex indices in the PatchData.
00194      *\param gradient The gradient of the metric as a function of the
00195      *               coordinates of the free vertices passed back in
00196      *               the indices list.
00197      *\param Hessian The Hessian of the metric as a function of the
00198      *               coordinates. The Hessian is passed back as the
00199      *               upper-triangular portion of the matrix in row-major
00200      *               order, where each Matrix3D is the portion of the
00201      *               Hessian with respect to the vertices at the
00202      *               corresponding positions in the indices list.
00203      */
00204     MESQUITE_EXPORT virtual bool evaluate_with_Hessian( PatchData& pd, size_t handle, double& value,
00205                                                         std::vector< size_t >& indices,
00206                                                         std::vector< Vector3D >& gradient,
00207                                                         std::vector< Matrix3D >& Hessian, MsqError& err );
00208 
00209     //! Escobar Barrier Function for Shape and Other Metrics
00210     // det = signed determinant of Jacobian Matrix at a Vertex
00211     // delta = scaling parameter
00212     static inline double vertex_barrier_function( double det, double delta )
00213     {
00214         return 0.5 * ( det + sqrt( det * det + 4 * delta * delta ) );
00215     }
00216     // protected:
00217 
00218     /** \brief Remove from vector any gradient terms corresponding
00219      *         to a fixed vertex.
00220      *
00221      * Remove terms from vector that correspond to fixed vertices.
00222      *\param type            Element type
00223      *\param fixed_vertices  Bit flags, one per vertex, 1 if
00224      *                       vertex is fixed.
00225      *\param gradients       Array of gradients
00226      */
00227     MESQUITE_EXPORT
00228     static void remove_fixed_gradients( EntityTopology type, uint32_t fixed_vertices,
00229                                         std::vector< Vector3D >& gradients );
00230 
00231     /** \brief Remove from vectors any gradient terms and hessian
00232      *         diagonal blcoks corresponding to a fixed vertex.
00233      *
00234      * Remove terms from vector that correspond to fixed vertices.
00235      *\param type            Element type
00236      *\param fixed_vertices  Bit flags, one per vertex, 1 if
00237      *                       vertex is fixed.
00238      *\param gradients       Array of gradients
00239      *\param hess_diagonal_blocks   Array of diagonal blocks of Hessian matrix.
00240      */
00241     MESQUITE_EXPORT
00242     static void remove_fixed_diagonals( EntityTopology type, uint32_t fixed_vertices,
00243                                         std::vector< Vector3D >& gradients,
00244                                         std::vector< SymMatrix3D >& hess_diagonal_blocks );
00245 
00246     /** \brief Remove from vector any Hessian blocks corresponding
00247      *         to a fixed vertex.
00248      *
00249      * Remove blocks from vector that correspond to fixed vertices.
00250      *\param type            Element type
00251      *\param fixed_vertices  Bit flags, one per vertex, 1 if
00252      *                       vertex is fixed.
00253      *\param hessians        Array of Hessian blocks (upper trianguler, row-major)
00254      */
00255     MESQUITE_EXPORT
00256     static void remove_fixed_hessians( EntityTopology type, uint32_t fixed_vertices,
00257                                        std::vector< Matrix3D >& hessians );
00258 
00259     /** \brief Convert fixed vertex format from list to bit flags
00260      *
00261      * Given list of pointers to fixed vertices as passed to
00262      * evaluation functions, convert to bit flag format used
00263      * for many utility functions in this class.  Bits correspond
00264      * to vertices in the canonical vertex order, beginning with
00265      * the least-significant bit.  The bit is cleared for free
00266      * vertices and set (1) for fixed vertices.
00267      */
00268     MESQUITE_EXPORT
00269     static uint32_t fixed_vertex_bitmap( PatchData& pd, const MsqMeshEntity* elem,
00270                                          std::vector< size_t >& free_indices );
00271 
00272     //! takes an array of coefficients and an array of metrics (both of length num_value)
00273     //! and averages the contents using averaging method 'method'.
00274     MESQUITE_EXPORT
00275     double weighted_average_metrics( const double coef[], const double metric_values[], const int& num_values,
00276                                      MsqError& err );
00277 
00278     /*!AveragingMethod allows you to set how the quality metric values
00279       attained at each sample point will be averaged together to produce
00280       a single metric value for an element.
00281     */
00282     enum AveragingMethod
00283     {
00284         LINEAR,       //!< the linear average
00285         RMS,          //!< the root-mean-squared average
00286         HMS,          //!< the harmonic-mean-squared average
00287         SUM,          //!< the sum of the values
00288         SUM_SQUARED,  //!< the sum of the squares of the values
00289         HARMONIC,     //!< the harmonic average
00290         LAST_WITH_HESSIAN = HARMONIC,
00291         MINIMUM,    //!< the minimum value
00292         MAXIMUM,    //!< the maximum value
00293         GEOMETRIC,  //!< the geometric average
00294         LAST_WITH_GRADIENT = GEOMETRIC,
00295         STANDARD_DEVIATION,    //!< the standard deviation squared of the values
00296         MAX_OVER_MIN,          //!< the maximum value minus the minum value
00297         MAX_MINUS_MIN,         //!< the maximum value divided by the minimum value
00298         SUM_OF_RATIOS_SQUARED  //!< (1/(N^2))*(SUM (SUM (v_i/v_j)^2))
00299     };
00300 
00301     //!\brief Called at start of instruction queue processing
00302     //!
00303     //! Do any preliminary global initialization, consistency checking,
00304     //! etc.  Default implementation does nothing.
00305     MESQUITE_EXPORT virtual void initialize_queue( MeshDomainAssoc* mesh_and_domain, const Settings* settings,
00306                                                    MsqError& err );
00307 
00308   private:
00309     int feasible;
00310 
00311     std::vector< Matrix3D > tmpHess;
00312     bool keepFiniteDiffEps;  //!< True if gradient finite difference
00313                              //!< calculation should set \c finiteDiffEps
00314     bool haveFiniteDiffEps;  //!< True if finite difference Hessian code
00315                              //!< has calculated \c finiteDiffEps
00316     double finiteDiffEps;    //!< Location for finite difference Hessian code
00317                              //!< to store this value so that it doesn't need
00318                              //!< to be recalculated if the gradient calculation
00319                              //!< is also finite difference
00320 };
00321 
00322 }  // namespace MBMesquite
00323 
00324 #endif  // QualityMetric_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines