LCOV - code coverage report
Current view: top level - src/mesquite/QualityMetric/Shape - ConditionNumberQualityMetric.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 121 129 93.8 %
Date: 2020-07-18 00:09:26 Functions: 6 6 100.0 %
Branches: 206 495 41.6 %

           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   ConditionNumberQualityMetric.cpp
      29                 :            :   \brief
      30                 :            : 
      31                 :            :   \author Michael Brewer
      32                 :            :   \date   2002-06-9
      33                 :            : */
      34                 :            : #include <vector>
      35                 :            : #include "ConditionNumberQualityMetric.hpp"
      36                 :            : #include <math.h>
      37                 :            : #include "Vector3D.hpp"
      38                 :            : #include "ConditionNumberFunctions.hpp"
      39                 :            : 
      40                 :            : using namespace MBMesquite;
      41                 :            : 
      42         [ +  - ]:          9 : ConditionNumberQualityMetric::ConditionNumberQualityMetric() : AveragingQM( QualityMetric::LINEAR ) {}
      43                 :            : 
      44                 :         20 : std::string ConditionNumberQualityMetric::get_name() const
      45                 :            : {
      46         [ +  - ]:         20 :     return "Condition Number";
      47                 :            : }
      48                 :            : 
      49                 :        361 : int ConditionNumberQualityMetric::get_negate_flag() const
      50                 :            : {
      51                 :        361 :     return 1;
      52                 :            : }
      53                 :            : 
      54                 :    1999700 : bool ConditionNumberQualityMetric::evaluate( PatchData& pd, size_t handle, double& fval, MsqError& err )
      55                 :            : {
      56         [ +  - ]:    1999700 :     const MsqMeshEntity* const element = &pd.element_by_index( handle );
      57                 :            :     bool return_flag;
      58                 :            :     double met_vals[MSQ_MAX_NUM_VERT_PER_ENT];
      59                 :    1999700 :     fval              = MSQ_MAX_CAP;
      60         [ +  - ]:    1999700 :     const size_t* v_i = element->get_vertex_index_array();
      61                 :            :     // only 3 temp_vec will be sent to cond-num calculator, but the
      62                 :            :     // additional vector3Ds may be needed during the calculations
      63 [ +  - ][ +  + ]:   13997900 :     Vector3D temp_vec[6];
      64         [ +  - ]:    1999700 :     const MsqVertex* vertices = pd.get_vertex_array( err );
      65         [ +  - ]:    1999700 :     EntityTopology type       = element->get_element_type();
      66   [ -  +  +  +  :    1999700 :     switch( type )
                +  +  - ]
      67                 :            :     {
      68                 :            :         case TRIANGLE:
      69 [ #  # ][ #  # ]:          0 :             temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
      70 [ #  # ][ #  # ]:          0 :             temp_vec[2] = vertices[v_i[2]] - vertices[v_i[0]];
      71                 :            :             // make relative to equilateral
      72 [ #  # ][ #  # ]:          0 :             temp_vec[1] = ( ( 2 * temp_vec[2] ) - temp_vec[0] ) * MSQ_SQRT_THREE_INV;
         [ #  # ][ #  # ]
      73         [ #  # ]:          0 :             return_flag = condition_number_2d( temp_vec, handle, pd, fval, err );
      74 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
      75                 :          0 :             return return_flag;
      76                 :            :         case QUADRILATERAL:
      77 [ +  - ][ +  - ]:        544 :             temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
      78 [ +  - ][ +  - ]:        544 :             temp_vec[1] = vertices[v_i[3]] - vertices[v_i[0]];
      79         [ +  - ]:        544 :             return_flag = condition_number_2d( temp_vec, handle, pd, met_vals[0], err );
      80 [ +  - ][ -  + ]:        544 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
      81         [ +  + ]:        544 :             if( !return_flag ) return return_flag;
      82 [ +  - ][ +  - ]:        540 :             temp_vec[0] = vertices[v_i[2]] - vertices[v_i[1]];
      83 [ +  - ][ +  - ]:        540 :             temp_vec[1] = vertices[v_i[0]] - vertices[v_i[1]];
      84         [ +  - ]:        540 :             return_flag = condition_number_2d( temp_vec, handle, pd, met_vals[1], err );
      85 [ +  - ][ -  + ]:        540 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
      86         [ -  + ]:        540 :             if( !return_flag ) return return_flag;
      87 [ +  - ][ +  - ]:        540 :             temp_vec[0] = vertices[v_i[3]] - vertices[v_i[2]];
      88 [ +  - ][ +  - ]:        540 :             temp_vec[1] = vertices[v_i[1]] - vertices[v_i[2]];
      89         [ +  - ]:        540 :             return_flag = condition_number_2d( temp_vec, handle, pd, met_vals[2], err );
      90 [ +  - ][ -  + ]:        540 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
      91         [ +  + ]:        540 :             if( !return_flag ) return return_flag;
      92 [ +  - ][ +  - ]:        537 :             temp_vec[0] = vertices[v_i[0]] - vertices[v_i[3]];
      93 [ +  - ][ +  - ]:        537 :             temp_vec[1] = vertices[v_i[2]] - vertices[v_i[3]];
      94         [ +  - ]:        537 :             return_flag = condition_number_2d( temp_vec, handle, pd, met_vals[3], err );
      95 [ +  - ][ -  + ]:        537 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
      96         [ +  - ]:        537 :             fval = average_metrics( met_vals, 4, err );
      97                 :        537 :             return return_flag;
      98                 :            :         case TETRAHEDRON:
      99 [ +  - ][ +  - ]:    1991876 :             temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
     100 [ +  - ][ +  - ]:    1991876 :             temp_vec[3] = vertices[v_i[2]] - vertices[v_i[0]];
     101 [ +  - ][ +  - ]:    1991876 :             temp_vec[4] = vertices[v_i[3]] - vertices[v_i[0]];
     102                 :            :             // transform to equilateral tet
     103 [ +  - ][ +  - ]:    1991876 :             temp_vec[1] = ( ( 2 * temp_vec[3] ) - temp_vec[0] ) / MSQ_SQRT_THREE;
         [ +  - ][ +  - ]
     104 [ +  - ][ +  - ]:    1991876 :             temp_vec[2] = ( ( 3 * temp_vec[4] ) - temp_vec[0] - temp_vec[3] ) / ( MSQ_SQRT_THREE * MSQ_SQRT_TWO );
         [ +  - ][ +  - ]
                 [ +  - ]
     105         [ +  - ]:    1991876 :             return_flag = condition_number_3d( temp_vec, pd, fval, err );
     106 [ +  - ][ -  + ]:    1991876 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     107                 :    1991876 :             return return_flag;
     108                 :            : 
     109                 :            :         case HEXAHEDRON:
     110                 :            :             // transform to v_i[0]
     111 [ +  - ][ +  - ]:         32 :             temp_vec[0] = vertices[v_i[1]] - vertices[v_i[0]];
     112 [ +  - ][ +  - ]:         32 :             temp_vec[1] = vertices[v_i[3]] - vertices[v_i[0]];
     113 [ +  - ][ +  - ]:         32 :             temp_vec[2] = vertices[v_i[4]] - vertices[v_i[0]];
     114         [ +  - ]:         32 :             return_flag = condition_number_3d( temp_vec, pd, met_vals[0], err );
     115 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     116         [ -  + ]:         32 :             if( !return_flag ) return return_flag;
     117 [ +  - ][ +  - ]:         32 :             temp_vec[0] = vertices[v_i[2]] - vertices[v_i[1]];
     118 [ +  - ][ +  - ]:         32 :             temp_vec[1] = vertices[v_i[0]] - vertices[v_i[1]];
     119 [ +  - ][ +  - ]:         32 :             temp_vec[2] = vertices[v_i[5]] - vertices[v_i[1]];
     120         [ +  - ]:         32 :             return_flag = condition_number_3d( temp_vec, pd, met_vals[1], err );
     121 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     122         [ -  + ]:         32 :             if( !return_flag ) return return_flag;
     123 [ +  - ][ +  - ]:         32 :             temp_vec[0] = vertices[v_i[3]] - vertices[v_i[2]];
     124 [ +  - ][ +  - ]:         32 :             temp_vec[1] = vertices[v_i[1]] - vertices[v_i[2]];
     125 [ +  - ][ +  - ]:         32 :             temp_vec[2] = vertices[v_i[6]] - vertices[v_i[2]];
     126         [ +  - ]:         32 :             return_flag = condition_number_3d( temp_vec, pd, met_vals[2], err );
     127 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     128         [ -  + ]:         32 :             if( !return_flag ) return return_flag;
     129 [ +  - ][ +  - ]:         32 :             temp_vec[0] = vertices[v_i[0]] - vertices[v_i[3]];
     130 [ +  - ][ +  - ]:         32 :             temp_vec[1] = vertices[v_i[2]] - vertices[v_i[3]];
     131 [ +  - ][ +  - ]:         32 :             temp_vec[2] = vertices[v_i[7]] - vertices[v_i[3]];
     132         [ +  - ]:         32 :             return_flag = condition_number_3d( temp_vec, pd, met_vals[3], err );
     133 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     134         [ -  + ]:         32 :             if( !return_flag ) return return_flag;
     135 [ +  - ][ +  - ]:         32 :             temp_vec[0] = vertices[v_i[7]] - vertices[v_i[4]];
     136 [ +  - ][ +  - ]:         32 :             temp_vec[1] = vertices[v_i[5]] - vertices[v_i[4]];
     137 [ +  - ][ +  - ]:         32 :             temp_vec[2] = vertices[v_i[0]] - vertices[v_i[4]];
     138         [ +  - ]:         32 :             return_flag = condition_number_3d( temp_vec, pd, met_vals[4], err );
     139 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     140         [ -  + ]:         32 :             if( !return_flag ) return return_flag;
     141 [ +  - ][ +  - ]:         32 :             temp_vec[0] = vertices[v_i[4]] - vertices[v_i[5]];
     142 [ +  - ][ +  - ]:         32 :             temp_vec[1] = vertices[v_i[6]] - vertices[v_i[5]];
     143 [ +  - ][ +  - ]:         32 :             temp_vec[2] = vertices[v_i[1]] - vertices[v_i[5]];
     144         [ +  - ]:         32 :             return_flag = condition_number_3d( temp_vec, pd, met_vals[5], err );
     145 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     146         [ -  + ]:         32 :             if( !return_flag ) return return_flag;
     147 [ +  - ][ +  - ]:         32 :             temp_vec[0] = vertices[v_i[5]] - vertices[v_i[6]];
     148 [ +  - ][ +  - ]:         32 :             temp_vec[1] = vertices[v_i[7]] - vertices[v_i[6]];
     149 [ +  - ][ +  - ]:         32 :             temp_vec[2] = vertices[v_i[2]] - vertices[v_i[6]];
     150         [ +  - ]:         32 :             return_flag = condition_number_3d( temp_vec, pd, met_vals[6], err );
     151 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     152         [ -  + ]:         32 :             if( !return_flag ) return return_flag;
     153 [ +  - ][ +  - ]:         32 :             temp_vec[0] = vertices[v_i[6]] - vertices[v_i[7]];
     154 [ +  - ][ +  - ]:         32 :             temp_vec[1] = vertices[v_i[4]] - vertices[v_i[7]];
     155 [ +  - ][ +  - ]:         32 :             temp_vec[2] = vertices[v_i[3]] - vertices[v_i[7]];
     156         [ +  - ]:         32 :             return_flag = condition_number_3d( temp_vec, pd, met_vals[7], err );
     157 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     158         [ +  - ]:         32 :             fval = average_metrics( met_vals, 8, err );
     159 [ +  - ][ -  + ]:         32 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     160                 :         32 :             return return_flag;
     161                 :            : 
     162                 :            :         case PYRAMID: {
     163                 :            :             unsigned num_adj;
     164                 :            :             const unsigned* adj_idx;
     165                 :       2880 :             return_flag = true;
     166         [ +  + ]:      14400 :             for( size_t j = 0; j < 4; ++j )  // skip fifth vertex (apex)
     167                 :            :             {
     168         [ +  - ]:      11520 :                 adj_idx = TopologyInfo::adjacent_vertices( type, j, num_adj );
     169         [ -  + ]:      11520 :                 assert( num_adj == 3 );
     170                 :            : 
     171 [ +  - ][ +  - ]:      11520 :                 temp_vec[0] = vertices[v_i[adj_idx[0]]] - vertices[v_i[j]];
     172 [ +  - ][ +  - ]:      11520 :                 temp_vec[1] = vertices[v_i[adj_idx[1]]] - vertices[v_i[j]];
     173                 :            :                 // calculate last vect map to right tetrahedron
     174 [ +  - ][ +  - ]:      11520 :                 temp_vec[3] = vertices[v_i[adj_idx[2]]] - vertices[v_i[adj_idx[0]]];
     175 [ +  - ][ +  - ]:      11520 :                 temp_vec[4] = vertices[v_i[adj_idx[2]]] - vertices[v_i[adj_idx[1]]];
     176 [ +  - ][ +  - ]:      11520 :                 temp_vec[2] = 0.5 * ( temp_vec[3] + temp_vec[4] );
                 [ +  - ]
     177                 :            : 
     178 [ +  - ][ +  - ]:      11520 :                 return_flag = return_flag && condition_number_3d( temp_vec, pd, met_vals[j], err );
                 [ +  - ]
     179                 :            :             }
     180         [ +  - ]:       2880 :             fval = average_metrics( met_vals, 4, err );
     181 [ +  - ][ -  + ]:       2880 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     182                 :       2880 :             return return_flag;
     183                 :            :         }
     184                 :            : 
     185                 :            :         case PRISM: {
     186                 :            :             unsigned num_adj;
     187                 :            :             const unsigned* adj_idx;
     188                 :       4368 :             return_flag = true;
     189         [ +  + ]:      30576 :             for( size_t j = 0; j < 6; ++j )
     190                 :            :             {
     191         [ +  - ]:      26208 :                 adj_idx = TopologyInfo::adjacent_vertices( type, j, num_adj );
     192         [ -  + ]:      26208 :                 assert( num_adj == 3 );
     193                 :            : 
     194 [ +  - ][ +  - ]:      26208 :                 temp_vec[0] = vertices[v_i[adj_idx[0]]] - vertices[v_i[j]];
     195 [ +  - ][ +  - ]:      26208 :                 temp_vec[1] = vertices[v_i[adj_idx[1]]] - vertices[v_i[j]];
     196 [ +  - ][ +  - ]:      26208 :                 temp_vec[2] = vertices[v_i[adj_idx[2]]] - vertices[v_i[j]];
     197                 :            :                 // map to right tetrahedron
     198         [ +  - ]:      26208 :                 temp_vec[1] += vertices[v_i[adj_idx[1]]];
     199         [ +  - ]:      26208 :                 temp_vec[1] -= vertices[v_i[adj_idx[0]]];
     200         [ +  - ]:      26208 :                 temp_vec[1] *= MSQ_SQRT_THREE_INV;
     201                 :            : 
     202 [ +  - ][ +  - ]:      26208 :                 return_flag = return_flag && condition_number_3d( temp_vec, pd, met_vals[j], err );
                 [ +  - ]
     203                 :            :             }
     204         [ +  - ]:       4368 :             fval = average_metrics( met_vals, 6, err );
     205 [ +  - ][ -  + ]:       4368 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     206                 :       4368 :             return return_flag;
     207                 :            :         }
     208                 :            : 
     209                 :            :         default:
     210                 :            :             MSQ_SETERR( err )
     211 [ #  # ][ #  # ]:          0 :             ( MsqError::UNSUPPORTED_ELEMENT, "Unsupported cell type (%d) for Condition Number quality metric.", type );
     212                 :            : 
     213                 :          0 :             fval = MSQ_MAX_CAP;
     214                 :    1999700 :             return false;
     215                 :            :     }  // end switch over element type
     216                 :            :     return false;
     217 [ +  - ][ +  - ]:         36 : }

Generated by: LCOV version 1.11