LCOV - code coverage report
Current view: top level - src/mesquite/QualityImprover/OptSolvers - NonSmoothDescent.hpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 38 38 100.0 %
Date: 2020-07-18 00:09:26 Functions: 15 15 100.0 %
Branches: 11 18 61.1 %

           Branch data     Line data    Source code
       1                 :            : /* *****************************************************************
       2                 :            :     MESQUITE -- The Mesh Quality Improvement Toolkit
       3                 :            : 
       4                 :            :     Copyright 2004 Sandia Corporation and Argonne National
       5                 :            :     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
       6                 :            :     with Sandia Corporation, the U.S. Government retains certain
       7                 :            :     rights in this software.
       8                 :            : 
       9                 :            :     This library is free software; you can redistribute it and/or
      10                 :            :     modify it under the terms of the GNU Lesser General Public
      11                 :            :     License as published by the Free Software Foundation; either
      12                 :            :     version 2.1 of the License, or (at your option) any later version.
      13                 :            : 
      14                 :            :     This library is distributed in the hope that it will be useful,
      15                 :            :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :            :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17                 :            :     Lesser General Public License for more details.
      18                 :            : 
      19                 :            :     You should have received a copy of the GNU Lesser General Public License
      20                 :            :     (lgpl.txt) along with this library; if not, write to the Free Software
      21                 :            :     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      22                 :            : 
      23                 :            :     [email protected], [email protected], [email protected],
      24                 :            :     [email protected], [email protected], [email protected]
      25                 :            : 
      26                 :            :   ***************************************************************** */
      27                 :            : /*!
      28                 :            :   \file   NonSmoothDescent.hpp
      29                 :            :   \brief
      30                 :            : 
      31                 :            :   The NonSmoothDescent Class implements the steepest descent algorythm in
      32                 :            :   order to move a free vertex to an optimal position given an
      33                 :            :   ObjectiveFunction object and a QaulityMetric object.
      34                 :            : 
      35                 :            :   \author Thomas Leurent
      36                 :            :   \date   2002-06-13
      37                 :            : */
      38                 :            : 
      39                 :            : #ifndef Mesquite_NonSmoothDescent_hpp
      40                 :            : #define Mesquite_NonSmoothDescent_hpp
      41                 :            : 
      42                 :            : #include "Mesquite.hpp"
      43                 :            : #include "VertexMover.hpp"
      44                 :            : #include "ObjectiveFunction.hpp"
      45                 :            : #include "MsqFreeVertexIndexIterator.hpp"
      46                 :            : #include "MsqDebug.hpp"
      47                 :            : #include "QualityMetric.hpp"
      48                 :            : #include "VertexPatches.hpp"
      49                 :            : #include <vector>
      50                 :            : #include "Vector3D.hpp"
      51                 :            : 
      52                 :            : namespace MBMesquite
      53                 :            : {
      54                 :            : 
      55                 :            : class NonSmoothDescent : public VertexMover
      56                 :            : {
      57                 :            :   public:
      58                 :            :     MESQUITE_EXPORT
      59                 :            :     NonSmoothDescent( QualityMetric* qm );
      60                 :            : 
      61         [ -  + ]:          2 :     MESQUITE_EXPORT virtual ~NonSmoothDescent() {}
      62                 :            : 
      63                 :            :     MESQUITE_EXPORT virtual std::string get_name() const;
      64                 :            : 
      65                 :            :     MESQUITE_EXPORT virtual PatchSet* get_patch_set();
      66                 :            : 
      67                 :            :   protected:
      68                 :      70218 :     struct ActiveSet
      69                 :            :     {
      70                 :            :         int num_equal;
      71                 :            :         double true_active_value;
      72                 :            :         std::vector< int > active_ind;
      73                 :            : 
      74                 :     100495 :         void set( int index )
      75                 :            :         {
      76                 :     100495 :             active_ind.clear();
      77                 :     100495 :             active_ind.push_back( index );
      78                 :     100495 :             num_equal = 0;
      79                 :     100495 :         }
      80                 :      23171 :         void add( int index, bool equal )
      81                 :            :         {
      82                 :      23171 :             active_ind.push_back( index );
      83                 :      23171 :             num_equal += equal;
      84                 :      23171 :         }
      85                 :            :     };
      86                 :            : 
      87                 :            :     class SymmetricMatrix
      88                 :            :     {
      89                 :            :         double* storage;
      90                 :            :         size_t size;
      91                 :     221646 :         size_t index( size_t r, size_t c ) const
      92                 :            :         {
      93         [ +  + ]:     221646 :             return ( r <= c ) ? size * r - r * ( r + 1 ) / 2 + c : size * c - c * ( c + 1 ) / 2 + r;
      94                 :            :         }
      95                 :            : 
      96                 :            :       public:
      97                 :      13464 :         SymmetricMatrix() : storage( 0 ), size( 0 ) {}
      98                 :            : 
      99                 :      13464 :         ~SymmetricMatrix()
     100                 :            :         {
     101                 :      13464 :             free( storage );
     102                 :      13464 :         }
     103                 :            : 
     104                 :      11789 :         void resize( size_t new_size )
     105                 :            :         {
     106                 :      11789 :             size    = new_size;
     107                 :      11789 :             storage = (double*)realloc( storage, sizeof( double ) * size * ( size + 1 ) / 2 );
     108                 :      11789 :         }
     109                 :            : 
     110                 :       1322 :         void fill( double value )
     111                 :            :         {
     112                 :       1322 :             std::fill( storage, storage + ( size * ( size + 1 ) / 2 ), value );
     113                 :       1322 :         }
     114                 :            : 
     115                 :     194727 :         double& operator()( size_t r, size_t c )
     116                 :            :         {
     117                 :     194727 :             return storage[index( r, c )];
     118                 :            :         }
     119                 :            : 
     120                 :      26919 :         double operator()( size_t r, size_t c ) const
     121                 :            :         {
     122                 :      26919 :             return storage[index( r, c )];
     123                 :            :         }
     124                 :            : 
     125                 :            :         double condition3x3() const;
     126                 :            :     };
     127                 :            : 
     128                 :            :     MESQUITE_EXPORT virtual void initialize( PatchData& pd, MsqError& err );
     129                 :            : 
     130                 :            :     MESQUITE_EXPORT virtual void optimize_vertex_positions( PatchData& pd, MsqError& err );
     131                 :            : 
     132                 :            :     MESQUITE_EXPORT virtual void initialize_mesh_iteration( PatchData& pd, MsqError& err );
     133                 :            : 
     134                 :            :     MESQUITE_EXPORT virtual void terminate_mesh_iteration( PatchData& pd, MsqError& err );
     135                 :            : 
     136                 :            :     MESQUITE_EXPORT virtual void cleanup();
     137                 :            : 
     138                 :            :   private:
     139                 :            :     enum OptStatus
     140                 :            :     {
     141                 :            :         MSQ_NO_STATUS     = 0,
     142                 :            :         MSQ_STEP_ACCEPTED = 100,
     143                 :            :         MSQ_IMP_TOO_SMALL,
     144                 :            :         MSQ_FLAT_NO_IMP,
     145                 :            :         MSQ_STEP_TOO_SMALL,
     146                 :            :         MSQ_EQUILIBRIUM,
     147                 :            :         MSQ_ZERO_SEARCH,
     148                 :            :         MSQ_MAX_ITER_EXCEEDED
     149                 :            :     };
     150                 :            : 
     151                 :            :     enum Status
     152                 :            :     {
     153                 :            :         MSQ_NO_EQUIL = 101,
     154                 :            :         MSQ_CHECK_TOP_DOWN,
     155                 :            :         MSQ_CHECK_BOTTOM_UP,
     156                 :            :         MSQ_TWO_PT_PLANE,
     157                 :            :         MSQ_THREE_PT_PLANE,
     158                 :            :         MSQ_CHECK_Y_COORD_DIRECTION,
     159                 :            :         MSQ_CHECK_X_COORD_DIRECTION,
     160                 :            :         MSQ_CHECK_Z_COORD_DIRECTION,
     161                 :            :         MSQ_EQUIL,
     162                 :            :         MSQ_HULL_TEST_ERROR
     163                 :            :     };
     164                 :            : 
     165                 :            :     enum Direction
     166                 :            :     {
     167                 :            :         MSQ_XDIR = 0,
     168                 :            :         MSQ_YDIR = 1,
     169                 :            :         MSQ_ZDIR = 2
     170                 :            :     };
     171                 :            : 
     172                 :            :     /* local copy of patch data */
     173                 :            :     //    PatchData patch_data;
     174                 :            :     size_t freeVertexIndex;
     175                 :            : 
     176                 :            :     /* smoothing parameters */
     177                 :            :     double minStepSize;
     178                 :            : 
     179                 :            :     /* optimization data */
     180                 :            :     VertexPatches patchSet;
     181                 :            :     QualityMetric* currentQM;
     182                 :            :     double originalValue;
     183                 :            :     std::vector< double > mFunction, testFunction, originalFunction;
     184                 :            :     std::vector< double > mGS;
     185                 :            :     SymmetricMatrix mG;
     186                 :            :     Matrix3D mPDG;
     187                 :            :     std::vector< double > prevActiveValues;
     188                 :            :     std::vector< Vector3D > mGradient, tmpGrad;
     189                 :            :     std::vector< size_t > tmpIdx, qmHandles;
     190                 :            :     OptStatus optStatus;
     191                 :            :     size_t mSteepest;
     192                 :            :     double mAlpha;
     193                 :            :     double maxAlpha;
     194                 :            :     int pdgInd[3];
     195                 :            :     ActiveSet mActive, testActive, originalActive;
     196                 :            : 
     197                 :            :     /* functions */
     198                 :            :     void init_opt( PatchData& pd, MsqError& err );
     199                 :            :     void init_max_step_length( PatchData& pd, MsqError& err );
     200                 :            : 
     201                 :            :     /* optimize */
     202                 :            :     void minmax_opt( PatchData& pd, MsqError& err );
     203                 :            :     void step_acceptance( PatchData& pd, int iter_count, const Vector3D& search_dir, MsqError& err );
     204                 :            :     void get_min_estimate( double* final_est, MsqError& err );
     205                 :            :     void get_gradient_projections( const Vector3D& mSearch, MsqError& err );
     206                 :            :     void compute_alpha( MsqError& err );
     207                 :            : 
     208                 :            :     /* function/gradient/active set computations */
     209                 :            :     bool compute_function( PatchData* pd, std::vector< double >& function, MsqError& err );
     210                 :            :     bool compute_gradient( PatchData* pd, std::vector< Vector3D >& grad_out, MsqError& err );
     211                 :            :     void find_active_set( const std::vector< double >& function, ActiveSet& active_set );
     212                 :            :     void print_active_set( const ActiveSet& active_set, const std::vector< double >& func );
     213                 :            : 
     214                 :            :     /* checking validity/improvement */
     215                 :            :     bool improvement_check( MsqError& err );
     216                 :            :     bool validity_check( PatchData& pd, MsqError& err );
     217                 :            : 
     218                 :            :     /* checking equilibrium routines */
     219                 :            :     bool check_equilibrium( OptStatus& opt_status, MsqError& err );
     220                 :            :     bool convex_hull_test( const std::vector< Vector3D >& vec, MsqError& err );
     221                 :            :     bool check_vector_dots( const std::vector< Vector3D >& vec, const Vector3D& normal, MsqError& err );
     222                 :            :     void find_plane_normal( const Vector3D& pt1, const Vector3D& pt2, const Vector3D& pt3, Vector3D& cross,
     223                 :            :                             MsqError& /*err*/ );
     224                 :            :     void find_plane_points( Direction dir1, Direction dir2, const std::vector< Vector3D >& vec, Vector3D& pt1,
     225                 :            :                             Vector3D& pt2, Vector3D& pt3, Status& status, MsqError& );
     226                 :            : 
     227                 :            :     /* from the matrix file */
     228                 :            :     void form_grammian( const std::vector< Vector3D >& vec, MsqError& err );
     229                 :            :     void form_PD_grammian( MsqError& err );
     230                 :            :     void singular_test( int n, const Matrix3D& A, bool& singular, MsqError& err );
     231                 :            :     bool solve2x2( double a11, double a12, double a21, double a22, double b1, double b2, double x[2], MsqError& err );
     232                 :            :     void form_reduced_matrix( SymmetricMatrix& P );
     233                 :            : 
     234                 :            :     /* search direction */
     235                 :            :     void search_direction( PatchData& pd, Vector3D& search_dir_out, MsqError& err );
     236                 :            :     void search_edges_faces( const Vector3D* dir, Vector3D& search, MsqError& err );
     237                 :            :     void get_active_directions( const std::vector< Vector3D >& gradient, std::vector< Vector3D >& dir, MsqError& err );
     238                 :            :     NonSmoothDescent( const NonSmoothDescent& pd );             // disable copying
     239                 :            :     NonSmoothDescent& operator=( const NonSmoothDescent& pd );  // disable assignment
     240                 :            : };
     241                 :            : 
     242                 :       5694 : inline void NonSmoothDescent::find_plane_normal( const Vector3D& pt1, const Vector3D& pt2, const Vector3D& pt3,
     243                 :            :                                                  Vector3D& cross, MsqError& /*err*/ )
     244                 :            : {
     245         [ +  - ]:       5694 :     Vector3D vecA = pt2 - pt1;
     246         [ +  - ]:       5694 :     Vector3D vecB = pt3 - pt1;
     247 [ +  - ][ +  - ]:       5694 :     cross         = vecA * vecB;
     248 [ +  - ][ +  - ]:       5694 :     cross /= cross.length();
     249                 :       5694 : }
     250                 :            : 
     251                 :      40309 : inline bool NonSmoothDescent::improvement_check( MsqError& /*err*/ )
     252                 :            : {
     253                 :            :     /* check to see that the mesh didn't get worse */
     254         [ +  + ]:      40309 :     if( originalValue < mActive.true_active_value )
     255                 :            :     {
     256                 :            :         MSQ_PRINT( 2 )
     257                 :            :         ( "The local mesh got worse; initial value %f; final value %f\n", originalValue, mActive.true_active_value );
     258                 :       5954 :         return false;
     259                 :            :     }
     260                 :            : 
     261                 :      34355 :     return true;
     262                 :            : }
     263                 :            : 
     264                 :            : }  // namespace MBMesquite
     265                 :            : 
     266                 :            : #endif  // Mesquite_NonSmoothDescent_hpp

Generated by: LCOV version 1.11