MOAB: Mesh Oriented datABase  (version 5.4.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     [email protected], [email protected], [email protected],
00024     [email protected], [email protected], [email protected]
00025 
00026     (2006) [email protected]
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,
00108                                                   std::vector< size_t >& handles,
00109                                                   bool free_vertices_only,
00110                                                   MsqError& err ) = 0;
00111 
00112     /**\brief Get locations at which metric can be evaluated for
00113      *        use in BCD intialization and QualityAssessor.
00114      *
00115      * For element-based, sample-based, and vertex-based metrics,
00116      * this function is the same as get_evaluations.  For edge-based
00117      * metrics it returns only a subset of the results for get_evaluations
00118      * such that each edge in the mesh is visited only once even though
00119      * it would normally be visited twice when iterating over patches
00120      * of the mesh.  This assumes that no vertex occurs in more than one
00121      * patch without its MSQ_PATCH_FIXED flag set.  This assumption is true for
00122      * both element-on-vertex and global patches.
00123      *\param pd       The patch
00124      *\param handles  Output list of handles
00125      *\param free_vertices_only If true, only pass back evaluation points
00126      *         that depend on at least one free vertex.
00127      */
00128     MESQUITE_EXPORT virtual void get_single_pass( PatchData& pd,
00129                                                   std::vector< size_t >& handles,
00130                                                   bool free_vertices_only,
00131                                                   MsqError& err );
00132 
00133     /**\brief Get metric value at a logical location in the patch.
00134      *
00135      * Evaluate the metric at one location in the PatchData.
00136      *\param pd     The patch.
00137      *\param handle The location in the patch (as passed back from get_evaluations).
00138      *\param value  The output metric value.
00139      */
00140     MESQUITE_EXPORT virtual bool evaluate( PatchData& pd, size_t handle, double& value, MsqError& err ) = 0;
00141 
00142     /**\brief Get metric value at a logical location in the patch.
00143      *
00144      * Evaluate the metric at one location in the PatchData.
00145      *\param pd      The patch.
00146      *\param handle  The location in the patch (as passed back from get_evaluations).
00147      *\param value   The output metric value.
00148      *\param indices The free vertices that the evaluation is a function
00149      *               of, specified as vertex indices in the PatchData.
00150      */
00151     MESQUITE_EXPORT virtual bool evaluate_with_indices( PatchData& pd,
00152                                                         size_t handle,
00153                                                         double& value,
00154                                                         std::vector< size_t >& indices,
00155                                                         MsqError& err ) = 0;
00156 
00157     /**\brief Get metric value and gradient at a logical location in the patch.
00158      *
00159      * Evaluate the metric at one location in the PatchData.
00160      *\param pd      The patch.
00161      *\param handle  The location in the patch (as passed back from get_evaluations).
00162      *\param value   The output metric value.
00163      *\param indices The free vertices that the evaluation is a function
00164      *               of, specified as vertex indices in the PatchData.
00165      *\param gradient The gradient of the metric as a function of the
00166      *               coordinates of the free vertices passed back in
00167      *               the indices list.
00168      */
00169     MESQUITE_EXPORT virtual bool evaluate_with_gradient( PatchData& pd,
00170                                                          size_t handle,
00171                                                          double& value,
00172                                                          std::vector< size_t >& indices,
00173                                                          std::vector< Vector3D >& gradient,
00174                                                          MsqError& err );
00175 
00176     /**\brief Get metric value and gradient at a logical location in the patch.
00177      *
00178      * Evaluate the metric at one location in the PatchData.
00179      *\param pd      The patch.
00180      *\param handle  The location in the patch (as passed back from get_evaluations).
00181      *\param value   The output metric value.
00182      *\param indices The free vertices that the evaluation is a function
00183      *               of, specified as vertex indices in the PatchData.
00184      *\param gradient The gradient of the metric as a function of the
00185      *               coordinates of the free vertices passed back in
00186      *               the indices list.
00187      *\param Hessian_diagonal The 3x3 blocks along the diagonal of
00188      *               the Hessian matrix.
00189      */
00190     MESQUITE_EXPORT virtual bool evaluate_with_Hessian_diagonal( PatchData& pd,
00191                                                                  size_t handle,
00192                                                                  double& value,
00193                                                                  std::vector< size_t >& indices,
00194                                                                  std::vector< Vector3D >& gradient,
00195                                                                  std::vector< SymMatrix3D >& Hessian_diagonal,
00196                                                                  MsqError& err );
00197 
00198     /**\brief Get metric value and deravitives at a logical location in the patch.
00199      *
00200      * Evaluate the metric at one location in the PatchData.
00201      *\param pd      The patch.
00202      *\param handle  The location in the patch (as passed back from get_evaluations).
00203      *\param value   The output metric value.
00204      *\param indices The free vertices that the evaluation is a function
00205      *               of, specified as vertex indices in the PatchData.
00206      *\param gradient The gradient of the metric as a function of the
00207      *               coordinates of the free vertices passed back in
00208      *               the indices list.
00209      *\param Hessian The Hessian of the metric as a function of the
00210      *               coordinates. The Hessian is passed back as the
00211      *               upper-triangular portion of the matrix in row-major
00212      *               order, where each Matrix3D is the portion of the
00213      *               Hessian with respect to the vertices at the
00214      *               corresponding positions in the indices list.
00215      */
00216     MESQUITE_EXPORT virtual bool evaluate_with_Hessian( PatchData& pd,
00217                                                         size_t handle,
00218                                                         double& value,
00219                                                         std::vector< size_t >& indices,
00220                                                         std::vector< Vector3D >& gradient,
00221                                                         std::vector< Matrix3D >& Hessian,
00222                                                         MsqError& err );
00223 
00224     //! Escobar Barrier Function for Shape and Other Metrics
00225     // det = signed determinant of Jacobian Matrix at a Vertex
00226     // delta = scaling parameter
00227     static inline double vertex_barrier_function( double det, double delta )
00228     {
00229         return 0.5 * ( det + sqrt( det * det + 4 * delta * delta ) );
00230     }
00231     // protected:
00232 
00233     /** \brief Remove from vector any gradient terms corresponding
00234      *         to a fixed vertex.
00235      *
00236      * Remove terms from vector that correspond to fixed vertices.
00237      *\param type            Element type
00238      *\param fixed_vertices  Bit flags, one per vertex, 1 if
00239      *                       vertex is fixed.
00240      *\param gradients       Array of gradients
00241      */
00242     MESQUITE_EXPORT
00243     static void remove_fixed_gradients( EntityTopology type,
00244                                         uint32_t fixed_vertices,
00245                                         std::vector< Vector3D >& gradients );
00246 
00247     /** \brief Remove from vectors any gradient terms and hessian
00248      *         diagonal blcoks corresponding to a fixed vertex.
00249      *
00250      * Remove terms from vector that correspond to fixed vertices.
00251      *\param type            Element type
00252      *\param fixed_vertices  Bit flags, one per vertex, 1 if
00253      *                       vertex is fixed.
00254      *\param gradients       Array of gradients
00255      *\param hess_diagonal_blocks   Array of diagonal blocks of Hessian matrix.
00256      */
00257     MESQUITE_EXPORT
00258     static void remove_fixed_diagonals( EntityTopology type,
00259                                         uint32_t fixed_vertices,
00260                                         std::vector< Vector3D >& gradients,
00261                                         std::vector< SymMatrix3D >& hess_diagonal_blocks );
00262 
00263     /** \brief Remove from vector any Hessian blocks corresponding
00264      *         to a fixed vertex.
00265      *
00266      * Remove blocks from vector that correspond to fixed vertices.
00267      *\param type            Element type
00268      *\param fixed_vertices  Bit flags, one per vertex, 1 if
00269      *                       vertex is fixed.
00270      *\param hessians        Array of Hessian blocks (upper trianguler, row-major)
00271      */
00272     MESQUITE_EXPORT
00273     static void remove_fixed_hessians( EntityTopology type,
00274                                        uint32_t fixed_vertices,
00275                                        std::vector< Matrix3D >& hessians );
00276 
00277     /** \brief Convert fixed vertex format from list to bit flags
00278      *
00279      * Given list of pointers to fixed vertices as passed to
00280      * evaluation functions, convert to bit flag format used
00281      * for many utility functions in this class.  Bits correspond
00282      * to vertices in the canonical vertex order, beginning with
00283      * the least-significant bit.  The bit is cleared for free
00284      * vertices and set (1) for fixed vertices.
00285      */
00286     MESQUITE_EXPORT
00287     static uint32_t fixed_vertex_bitmap( PatchData& pd,
00288                                          const MsqMeshEntity* elem,
00289                                          std::vector< size_t >& free_indices );
00290 
00291     //! takes an array of coefficients and an array of metrics (both of length num_value)
00292     //! and averages the contents using averaging method 'method'.
00293     MESQUITE_EXPORT
00294     double weighted_average_metrics( const double coef[],
00295                                      const double metric_values[],
00296                                      const int& num_values,
00297                                      MsqError& err );
00298 
00299     /*!AveragingMethod allows you to set how the quality metric values
00300       attained at each sample point will be averaged together to produce
00301       a single metric value for an element.
00302     */
00303     enum AveragingMethod
00304     {
00305         LINEAR,       //!< the linear average
00306         RMS,          //!< the root-mean-squared average
00307         HMS,          //!< the harmonic-mean-squared average
00308         SUM,          //!< the sum of the values
00309         SUM_SQUARED,  //!< the sum of the squares of the values
00310         HARMONIC,     //!< the harmonic average
00311         LAST_WITH_HESSIAN = HARMONIC,
00312         MINIMUM,    //!< the minimum value
00313         MAXIMUM,    //!< the maximum value
00314         GEOMETRIC,  //!< the geometric average
00315         LAST_WITH_GRADIENT = GEOMETRIC,
00316         STANDARD_DEVIATION,    //!< the standard deviation squared of the values
00317         MAX_OVER_MIN,          //!< the maximum value minus the minum value
00318         MAX_MINUS_MIN,         //!< the maximum value divided by the minimum value
00319         SUM_OF_RATIOS_SQUARED  //!< (1/(N^2))*(SUM (SUM (v_i/v_j)^2))
00320     };
00321 
00322     //!\brief Called at start of instruction queue processing
00323     //!
00324     //! Do any preliminary global initialization, consistency checking,
00325     //! etc.  Default implementation does nothing.
00326     MESQUITE_EXPORT virtual void initialize_queue( MeshDomainAssoc* mesh_and_domain,
00327                                                    const Settings* settings,
00328                                                    MsqError& err );
00329 
00330   private:
00331     int feasible;
00332 
00333     std::vector< Matrix3D > tmpHess;
00334     bool keepFiniteDiffEps;  //!< True if gradient finite difference
00335                              //!< calculation should set \c finiteDiffEps
00336     bool haveFiniteDiffEps;  //!< True if finite difference Hessian code
00337                              //!< has calculated \c finiteDiffEps
00338     double finiteDiffEps;    //!< Location for finite difference Hessian code
00339                              //!< to store this value so that it doesn't need
00340                              //!< to be recalculated if the gradient calculation
00341                              //!< is also finite difference
00342 };
00343 
00344 }  // namespace MBMesquite
00345 
00346 #endif  // QualityMetric_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines