LCOV - code coverage report
Current view: top level - src/mesquite/QualityMetric/Shape - IdealWeightInverseMeanRatio.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 216 364 59.3 %
Date: 2020-07-18 00:09:26 Functions: 10 11 90.9 %
Branches: 296 1042 28.4 %

           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   IdealWeightInverseMeanRatio.cpp
      29                 :            :   \brief
      30                 :            : 
      31                 :            :   \author Michael Brewer
      32                 :            :   \author Todd Munson
      33                 :            :   \author Thomas Leurent
      34                 :            : 
      35                 :            :   \date   2002-06-9
      36                 :            : */
      37                 :            : #include "IdealWeightInverseMeanRatio.hpp"
      38                 :            : #include "MeanRatioFunctions.hpp"
      39                 :            : #include "MsqTimer.hpp"
      40                 :            : #include "MsqDebug.hpp"
      41                 :            : #include "MsqError.hpp"
      42                 :            : #include "PatchData.hpp"
      43                 :            : 
      44                 :            : #include <vector>
      45                 :            : using std::vector;
      46                 :            : #include <math.h>
      47                 :            : 
      48                 :            : namespace MBMesquite
      49                 :            : {
      50                 :            : 
      51                 :          9 : IdealWeightInverseMeanRatio::IdealWeightInverseMeanRatio( MsqError& err, double pow_dbl )
      52 [ +  - ][ +  - ]:       1053 :     : AveragingQM( QualityMetric::LINEAR )
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
           [ +  -  #  #  
             #  #  #  # ]
      53                 :            : {
      54 [ +  - ][ +  - ]:          9 :     set_metric_power( pow_dbl, err );MSQ_ERRRTN( err );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
                 [ #  # ]
      55                 :            : }
      56                 :            : 
      57 [ +  - ][ +  - ]:       1062 : IdealWeightInverseMeanRatio::IdealWeightInverseMeanRatio() : AveragingQM( QualityMetric::LINEAR )
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
           [ +  -  #  #  
             #  #  #  # ]
      58                 :            : {
      59         [ +  - ]:          9 :     MsqError err;
      60         [ +  - ]:          9 :     set_metric_power( 1.0, err );
      61 [ +  - ][ -  + ]:          9 :     assert( !err );
      62         [ #  # ]:          9 : }
      63                 :            : 
      64                 :         28 : std::string IdealWeightInverseMeanRatio::get_name() const
      65                 :            : {
      66         [ +  - ]:         28 :     return "Inverse Mean Ratio";
      67                 :            : }
      68                 :            : 
      69                 :     152739 : int IdealWeightInverseMeanRatio::get_negate_flag() const
      70                 :            : {
      71         [ -  + ]:     152739 :     return b2Con.value() < 0 ? -1 : 1;
      72                 :            : }
      73                 :            : 
      74                 :            : //! Sets the power value in the metric computation.
      75                 :         18 : void IdealWeightInverseMeanRatio::set_metric_power( double pow_dbl, MsqError& err )
      76                 :            : {
      77         [ -  + ]:         18 :     if( fabs( pow_dbl ) <= MSQ_MIN )
      78                 :            :     {
      79         [ #  # ]:          0 :         MSQ_SETERR( err )( MsqError::INVALID_ARG );
      80                 :         18 :         return;
      81                 :            :     }
      82                 :         18 :     a2Con = pow( .5, pow_dbl );
      83                 :         18 :     b2Con = pow_dbl;
      84                 :         18 :     c2Con = -pow_dbl;
      85                 :         18 :     a3Con = pow( 1.0 / 3.0, pow_dbl );
      86                 :         18 :     b3Con = pow_dbl;
      87                 :         18 :     c3Con = -2.0 * pow_dbl / 3.0;
      88                 :            : }
      89                 :            : 
      90                 :      84464 : bool IdealWeightInverseMeanRatio::evaluate( PatchData& pd, size_t handle, double& m, MsqError& err )
      91                 :            : {
      92         [ +  - ]:      84464 :     const MsqMeshEntity* e = &pd.element_by_index( handle );
      93         [ +  - ]:      84464 :     EntityTopology topo    = e->get_element_type();
      94                 :            : 
      95         [ +  - ]:      84464 :     const MsqVertex* vertices = pd.get_vertex_array( err );
      96 [ +  - ][ -  + ]:      84464 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
      97         [ +  - ]:      84464 :     const size_t* v_i = e->get_vertex_index_array();
      98                 :            : 
      99         [ +  - ]:      84464 :     Vector3D n;  // Surface normal for 2D objects
     100                 :            : 
     101                 :            :     // Prism and Hex element descriptions
     102                 :            :     static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 },
     103                 :            :                                         { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } };
     104                 :            :     static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 },
     105                 :            :                                         { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } };
     106                 :            : 
     107         [ +  - ]:      84464 :     const Vector3D d_con( 1.0, 1.0, 1.0 );
     108                 :            : 
     109                 :            :     int i;
     110                 :            : 
     111                 :      84464 :     m                 = 0.0;
     112                 :      84464 :     bool metric_valid = false;
     113   [ +  +  +  +  :      84464 :     switch( topo )
                -  +  - ]
     114                 :            :     {
     115                 :            :         case TRIANGLE:
     116         [ +  - ]:        367 :             pd.get_domain_normal_at_element( e, n, err );
     117 [ +  - ][ -  + ]:        367 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     118 [ +  - ][ +  - ]:        367 :             n            = n / n.length();  // Need unit normal
                 [ +  - ]
     119         [ +  - ]:        367 :             mCoords[0]   = vertices[v_i[0]];
     120         [ +  - ]:        367 :             mCoords[1]   = vertices[v_i[1]];
     121         [ +  - ]:        367 :             mCoords[2]   = vertices[v_i[2]];
     122         [ +  - ]:        367 :             metric_valid = m_fcn_2e( m, mCoords, n, a2Con, b2Con, c2Con );
     123         [ +  + ]:        367 :             if( !metric_valid ) return false;
     124                 :        364 :             break;
     125                 :            : 
     126                 :            :         case QUADRILATERAL:
     127         [ +  - ]:      17784 :             pd.get_domain_normal_at_element( e, n, err );
     128 [ +  - ][ -  + ]:      17784 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     129 [ +  - ][ +  - ]:      17784 :             n = n / n.length();  // Need unit normal
                 [ +  - ]
     130         [ +  + ]:      88808 :             for( i = 0; i < 4; ++i )
     131                 :            :             {
     132         [ +  - ]:      71052 :                 mCoords[0]   = vertices[v_i[locs_hex[i][0]]];
     133         [ +  - ]:      71052 :                 mCoords[1]   = vertices[v_i[locs_hex[i][1]]];
     134         [ +  - ]:      71052 :                 mCoords[2]   = vertices[v_i[locs_hex[i][2]]];
     135         [ +  - ]:      71052 :                 metric_valid = m_fcn_2i( mMetrics[i], mCoords, n, a2Con, b2Con, c2Con, d_con );
     136         [ +  + ]:      71052 :                 if( !metric_valid ) return false;
     137                 :            :             }
     138         [ +  - ]:      17756 :             m = average_metrics( mMetrics, 4, err );
     139                 :      17756 :             break;
     140                 :            : 
     141                 :            :         case TETRAHEDRON:
     142         [ +  - ]:      57270 :             mCoords[0]   = vertices[v_i[0]];
     143         [ +  - ]:      57270 :             mCoords[1]   = vertices[v_i[1]];
     144         [ +  - ]:      57270 :             mCoords[2]   = vertices[v_i[2]];
     145         [ +  - ]:      57270 :             mCoords[3]   = vertices[v_i[3]];
     146         [ +  - ]:      57270 :             metric_valid = m_fcn_3e( m, mCoords, a3Con, b3Con, c3Con );
     147         [ -  + ]:      57270 :             if( !metric_valid ) return false;
     148                 :      57270 :             break;
     149                 :            : 
     150                 :            :         case PYRAMID:
     151         [ +  + ]:       5690 :             for( i = 0; i < 4; ++i )
     152                 :            :             {
     153         [ +  - ]:       4553 :                 mCoords[0]   = vertices[v_i[i]];
     154         [ +  - ]:       4553 :                 mCoords[1]   = vertices[v_i[( i + 1 ) % 4]];
     155         [ +  - ]:       4553 :                 mCoords[2]   = vertices[v_i[( i + 3 ) % 4]];
     156         [ +  - ]:       4553 :                 mCoords[3]   = vertices[v_i[4]];
     157         [ +  - ]:       4553 :                 metric_valid = m_fcn_3p( mMetrics[i], mCoords, a3Con, b3Con, c3Con );
     158         [ +  + ]:       4553 :                 if( !metric_valid ) return false;
     159                 :            :             }
     160         [ +  - ]:       1137 :             m = average_metrics( mMetrics, 4, err );
     161 [ +  - ][ -  + ]:       1137 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     162                 :       1137 :             break;
     163                 :            : 
     164                 :            :         case PRISM:
     165         [ #  # ]:          0 :             for( i = 0; i < 6; ++i )
     166                 :            :             {
     167         [ #  # ]:          0 :                 mCoords[0]   = vertices[v_i[locs_pri[i][0]]];
     168         [ #  # ]:          0 :                 mCoords[1]   = vertices[v_i[locs_pri[i][1]]];
     169         [ #  # ]:          0 :                 mCoords[2]   = vertices[v_i[locs_pri[i][2]]];
     170         [ #  # ]:          0 :                 mCoords[3]   = vertices[v_i[locs_pri[i][3]]];
     171         [ #  # ]:          0 :                 metric_valid = m_fcn_3w( mMetrics[i], mCoords, a3Con, b3Con, c3Con );
     172         [ #  # ]:          0 :                 if( !metric_valid ) return false;
     173                 :            :             }
     174         [ #  # ]:          0 :             m = average_metrics( mMetrics, 6, err );
     175 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     176                 :          0 :             break;
     177                 :            : 
     178                 :            :         case HEXAHEDRON:
     179         [ +  + ]:      71121 :             for( i = 0; i < 8; ++i )
     180                 :            :             {
     181         [ +  - ]:      63219 :                 mCoords[0]   = vertices[v_i[locs_hex[i][0]]];
     182         [ +  - ]:      63219 :                 mCoords[1]   = vertices[v_i[locs_hex[i][1]]];
     183         [ +  - ]:      63219 :                 mCoords[2]   = vertices[v_i[locs_hex[i][2]]];
     184         [ +  - ]:      63219 :                 mCoords[3]   = vertices[v_i[locs_hex[i][3]]];
     185         [ +  - ]:      63219 :                 metric_valid = m_fcn_3i( mMetrics[i], mCoords, a3Con, b3Con, c3Con, d_con );
     186         [ +  + ]:      63219 :                 if( !metric_valid ) return false;
     187                 :            :             }
     188         [ +  - ]:       7902 :             m = average_metrics( mMetrics, 8, err );
     189 [ +  - ][ -  + ]:       7902 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     190                 :       7902 :             break;
     191                 :            : 
     192                 :            :         default:
     193                 :            :             MSQ_SETERR( err )
     194                 :            :             ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightInverseMeanRatio",
     195 [ #  # ][ #  # ]:          0 :               (int)topo );
     196                 :          0 :             return false;
     197                 :            :     }  // end switch over element type
     198                 :      84464 :     return true;
     199                 :            : }
     200                 :            : 
     201                 :     152617 : bool IdealWeightInverseMeanRatio::evaluate_with_gradient( PatchData& pd, size_t handle, double& m,
     202                 :            :                                                           std::vector< size_t >& indices, std::vector< Vector3D >& g,
     203                 :            :                                                           MsqError& err )
     204                 :            : {
     205         [ +  - ]:     152617 :     const MsqMeshEntity* e = &pd.element_by_index( handle );
     206         [ +  - ]:     152617 :     EntityTopology topo    = e->get_element_type();
     207                 :            : 
     208 [ +  - ][ -  + ]:     152617 :     if( !analytical_average_gradient() && topo != TRIANGLE && topo != TETRAHEDRON )
         [ #  # ][ #  # ]
                 [ -  + ]
     209                 :            :     {
     210                 :            :         static bool print = true;
     211         [ #  # ]:          0 :         if( print )
     212                 :            :         {
     213                 :            :             MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. "
     214                 :            :                             << "Using (possibly much slower) numerical approximation of gradient"
     215                 :            :                             << " of quality metric. " << std::endl;
     216                 :          0 :             print = false;
     217                 :            :         }
     218         [ #  # ]:          0 :         return QualityMetric::evaluate_with_gradient( pd, handle, m, indices, g, err );
     219                 :            :     }
     220                 :            : 
     221         [ +  - ]:     152617 :     const MsqVertex* vertices = pd.get_vertex_array( err );
     222 [ +  - ][ -  + ]:     152617 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     223         [ +  - ]:     152617 :     const size_t* v_i = e->get_vertex_index_array();
     224                 :            : 
     225         [ +  - ]:     152617 :     Vector3D n;  // Surface normal for 2D objects
     226                 :            : 
     227                 :            :     // Prism and Hex element descriptions
     228                 :            :     static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 },
     229                 :            :                                         { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } };
     230                 :            :     static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 },
     231                 :            :                                         { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } };
     232                 :            : 
     233         [ +  - ]:     152617 :     const Vector3D d_con( 1.0, 1.0, 1.0 );
     234                 :            : 
     235                 :            :     int i;
     236                 :            : 
     237                 :     152617 :     bool metric_valid = false;
     238         [ +  - ]:     152617 :     const uint32_t fm = fixed_vertex_bitmap( pd, e, indices );
     239                 :            : 
     240                 :     152617 :     m = 0.0;
     241                 :            : 
     242   [ +  +  +  +  :     152617 :     switch( topo )
                +  +  - ]
     243                 :            :     {
     244                 :            :         case TRIANGLE:
     245         [ +  - ]:        101 :             pd.get_domain_normal_at_element( e, n, err );
     246 [ +  - ][ -  + ]:        101 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     247 [ +  - ][ +  - ]:        101 :             n /= n.length();  // Need unit normal
     248         [ +  - ]:        101 :             mCoords[0] = vertices[v_i[0]];
     249         [ +  - ]:        101 :             mCoords[1] = vertices[v_i[1]];
     250         [ +  - ]:        101 :             mCoords[2] = vertices[v_i[2]];
     251         [ +  - ]:        101 :             g.resize( 3 );
     252 [ +  - ][ +  - ]:        101 :             if( !g_fcn_2e( m, arrptr( g ), mCoords, n, a2Con, b2Con, c2Con ) ) return false;
                 [ -  + ]
     253                 :        101 :             break;
     254                 :            : 
     255                 :            :         case QUADRILATERAL:
     256         [ +  - ]:        532 :             pd.get_domain_normal_at_element( e, n, err );
     257 [ +  - ][ -  + ]:        532 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     258 [ +  - ][ +  - ]:        532 :             n /= n.length();  // Need unit normal
     259         [ +  + ]:       2660 :             for( i = 0; i < 4; ++i )
     260                 :            :             {
     261         [ +  - ]:       2128 :                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
     262         [ +  - ]:       2128 :                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
     263         [ +  - ]:       2128 :                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
     264 [ +  - ][ -  + ]:       2128 :                 if( !g_fcn_2i( mMetrics[i], mGradients + 3 * i, mCoords, n, a2Con, b2Con, c2Con, d_con ) ) return false;
     265                 :            :             }
     266                 :            : 
     267         [ +  - ]:        532 :             g.resize( 4 );
     268 [ +  - ][ +  - ]:        532 :             m = average_corner_gradients( QUADRILATERAL, fm, 4, mMetrics, mGradients, arrptr( g ), err );
     269 [ +  - ][ -  + ]:        532 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     270                 :        532 :             break;
     271                 :            : 
     272                 :            :         case TETRAHEDRON:
     273         [ +  - ]:     136059 :             mCoords[0] = vertices[v_i[0]];
     274         [ +  - ]:     136059 :             mCoords[1] = vertices[v_i[1]];
     275         [ +  - ]:     136059 :             mCoords[2] = vertices[v_i[2]];
     276         [ +  - ]:     136059 :             mCoords[3] = vertices[v_i[3]];
     277         [ +  - ]:     136059 :             g.resize( 4 );
     278 [ +  - ][ +  - ]:     136059 :             metric_valid = g_fcn_3e( m, arrptr( g ), mCoords, a3Con, b3Con, c3Con );
     279         [ -  + ]:     136059 :             if( !metric_valid ) return false;
     280                 :     136059 :             break;
     281                 :            : 
     282                 :            :         case PYRAMID:
     283         [ +  + ]:      11382 :             for( i = 0; i < 4; ++i )
     284                 :            :             {
     285         [ +  - ]:       9106 :                 mCoords[0]   = vertices[v_i[i]];
     286         [ +  - ]:       9106 :                 mCoords[1]   = vertices[v_i[( i + 1 ) % 4]];
     287         [ +  - ]:       9106 :                 mCoords[2]   = vertices[v_i[( i + 3 ) % 4]];
     288         [ +  - ]:       9106 :                 mCoords[3]   = vertices[v_i[4]];
     289         [ +  - ]:       9106 :                 metric_valid = g_fcn_3p( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con );
     290         [ +  + ]:       9106 :                 if( !metric_valid ) return false;
     291                 :            :             }
     292                 :            : 
     293         [ +  - ]:       2276 :             g.resize( 5 );
     294 [ +  - ][ +  - ]:       2276 :             m = average_corner_gradients( PYRAMID, fm, 4, mMetrics, mGradients, arrptr( g ), err );
     295 [ +  - ][ -  + ]:       2276 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     296                 :       2276 :             break;
     297                 :            : 
     298                 :            :         case PRISM:
     299         [ +  + ]:        462 :             for( i = 0; i < 6; ++i )
     300                 :            :             {
     301         [ +  - ]:        396 :                 mCoords[0] = vertices[v_i[locs_pri[i][0]]];
     302         [ +  - ]:        396 :                 mCoords[1] = vertices[v_i[locs_pri[i][1]]];
     303         [ +  - ]:        396 :                 mCoords[2] = vertices[v_i[locs_pri[i][2]]];
     304         [ +  - ]:        396 :                 mCoords[3] = vertices[v_i[locs_pri[i][3]]];
     305 [ +  - ][ -  + ]:        396 :                 if( !g_fcn_3w( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con ) ) return false;
     306                 :            :             }
     307                 :            : 
     308         [ +  - ]:         66 :             g.resize( 6 );
     309 [ +  - ][ +  - ]:         66 :             m = average_corner_gradients( PRISM, fm, 6, mMetrics, mGradients, arrptr( g ), err );
     310 [ +  - ][ -  + ]:         66 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     311                 :         66 :             break;
     312                 :            : 
     313                 :            :         case HEXAHEDRON:
     314         [ +  + ]:     122229 :             for( i = 0; i < 8; ++i )
     315                 :            :             {
     316         [ +  - ]:     108648 :                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
     317         [ +  - ]:     108648 :                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
     318         [ +  - ]:     108648 :                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
     319         [ +  - ]:     108648 :                 mCoords[3] = vertices[v_i[locs_hex[i][3]]];
     320 [ +  - ][ -  + ]:     108648 :                 if( !g_fcn_3i( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con, d_con ) ) return false;
     321                 :            :             }
     322                 :            : 
     323         [ +  - ]:      13581 :             g.resize( 8 );
     324 [ +  - ][ +  - ]:      13581 :             m = average_corner_gradients( HEXAHEDRON, fm, 8, mMetrics, mGradients, arrptr( g ), err );
     325 [ +  - ][ -  + ]:      13581 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     326                 :      13581 :             break;
     327                 :            : 
     328                 :            :         default:
     329                 :            :             MSQ_SETERR( err )
     330                 :            :             ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightInverseMeanRatio",
     331 [ #  # ][ #  # ]:          0 :               (int)topo );
     332                 :          0 :             return false;
     333                 :            :     }  // end switch over element type
     334                 :            : 
     335         [ +  - ]:     152615 :     remove_fixed_gradients( topo, fm, g );
     336                 :     152617 :     return true;
     337                 :            : }
     338                 :            : 
     339                 :          0 : bool IdealWeightInverseMeanRatio::evaluate_with_Hessian_diagonal( PatchData& pd, size_t handle, double& m,
     340                 :            :                                                                   std::vector< size_t >& indices,
     341                 :            :                                                                   std::vector< Vector3D >& g,
     342                 :            :                                                                   std::vector< SymMatrix3D >& h, MsqError& err )
     343                 :            : {
     344         [ #  # ]:          0 :     const MsqMeshEntity* e = &pd.element_by_index( handle );
     345         [ #  # ]:          0 :     EntityTopology topo    = e->get_element_type();
     346                 :            : 
     347 [ #  # ][ #  # ]:          0 :     if( !analytical_average_hessian() && topo != TRIANGLE && topo != TETRAHEDRON )
         [ #  # ][ #  # ]
                 [ #  # ]
     348                 :            :     {
     349                 :            :         static bool print = true;
     350         [ #  # ]:          0 :         if( print )
     351                 :            :         {
     352                 :            :             MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. "
     353                 :            :                             << "Using (possibly much slower) numerical approximation of gradient"
     354                 :            :                             << " of quality metric. " << std::endl;
     355                 :          0 :             print = false;
     356                 :            :         }
     357         [ #  # ]:          0 :         return QualityMetric::evaluate_with_Hessian_diagonal( pd, handle, m, indices, g, h, err );
     358                 :            :     }
     359                 :            : 
     360         [ #  # ]:          0 :     const MsqVertex* vertices = pd.get_vertex_array( err );
     361 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     362         [ #  # ]:          0 :     const size_t* v_i = e->get_vertex_index_array();
     363                 :            : 
     364         [ #  # ]:          0 :     Vector3D n;  // Surface normal for 2D objects
     365                 :            : 
     366                 :            :     // Prism and Hex element descriptions
     367                 :            :     static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 },
     368                 :            :                                         { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } };
     369                 :            :     static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 },
     370                 :            :                                         { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } };
     371                 :            : 
     372         [ #  # ]:          0 :     const Vector3D d_con( 1.0, 1.0, 1.0 );
     373                 :            : 
     374                 :            :     int i;
     375                 :            : 
     376                 :          0 :     bool metric_valid = false;
     377         [ #  # ]:          0 :     const uint32_t fm = fixed_vertex_bitmap( pd, e, indices );
     378                 :            : 
     379                 :          0 :     m = 0.0;
     380                 :            : 
     381   [ #  #  #  #  :          0 :     switch( topo )
                #  #  # ]
     382                 :            :     {
     383                 :            :         case TRIANGLE:
     384         [ #  # ]:          0 :             pd.get_domain_normal_at_element( e, n, err );
     385 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     386 [ #  # ][ #  # ]:          0 :             n /= n.length();  // Need unit normal
     387         [ #  # ]:          0 :             mCoords[0] = vertices[v_i[0]];
     388         [ #  # ]:          0 :             mCoords[1] = vertices[v_i[1]];
     389         [ #  # ]:          0 :             mCoords[2] = vertices[v_i[2]];
     390         [ #  # ]:          0 :             g.resize( 3 );
     391         [ #  # ]:          0 :             h.resize( 3 );
     392 [ #  # ][ #  # ]:          0 :             if( !h_fcn_2e( m, arrptr( g ), mHessians, mCoords, n, a2Con, b2Con, c2Con ) ) return false;
                 [ #  # ]
     393 [ #  # ][ #  # ]:          0 :             h[0] = mHessians[0].upper();
     394 [ #  # ][ #  # ]:          0 :             h[1] = mHessians[3].upper();
     395 [ #  # ][ #  # ]:          0 :             h[2] = mHessians[5].upper();
     396                 :          0 :             break;
     397                 :            : 
     398                 :            :         case QUADRILATERAL:
     399         [ #  # ]:          0 :             pd.get_domain_normal_at_element( e, n, err );
     400 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     401 [ #  # ][ #  # ]:          0 :             n /= n.length();  // Need unit normal
     402         [ #  # ]:          0 :             for( i = 0; i < 4; ++i )
     403                 :            :             {
     404         [ #  # ]:          0 :                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
     405         [ #  # ]:          0 :                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
     406         [ #  # ]:          0 :                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
     407         [ #  # ]:          0 :                 if( !h_fcn_2i( mMetrics[i], mGradients + 3 * i, mHessians + 6 * i, mCoords, n, a2Con, b2Con, c2Con,
     408         [ #  # ]:          0 :                                d_con ) )
     409                 :          0 :                     return false;
     410                 :            :             }
     411                 :            : 
     412         [ #  # ]:          0 :             g.resize( 4 );
     413         [ #  # ]:          0 :             h.resize( 4 );
     414                 :            :             m = average_corner_hessian_diagonals( QUADRILATERAL, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ),
     415 [ #  # ][ #  # ]:          0 :                                                   arrptr( h ), err );
                 [ #  # ]
     416 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     417                 :          0 :             break;
     418                 :            : 
     419                 :            :         case TETRAHEDRON:
     420         [ #  # ]:          0 :             mCoords[0] = vertices[v_i[0]];
     421         [ #  # ]:          0 :             mCoords[1] = vertices[v_i[1]];
     422         [ #  # ]:          0 :             mCoords[2] = vertices[v_i[2]];
     423         [ #  # ]:          0 :             mCoords[3] = vertices[v_i[3]];
     424         [ #  # ]:          0 :             g.resize( 4 );
     425         [ #  # ]:          0 :             h.resize( 4 );
     426 [ #  # ][ #  # ]:          0 :             metric_valid = h_fcn_3e( m, arrptr( g ), mHessians, mCoords, a3Con, b3Con, c3Con );
     427         [ #  # ]:          0 :             if( !metric_valid ) return false;
     428 [ #  # ][ #  # ]:          0 :             h[0] = mHessians[0].upper();
     429 [ #  # ][ #  # ]:          0 :             h[1] = mHessians[4].upper();
     430 [ #  # ][ #  # ]:          0 :             h[2] = mHessians[7].upper();
     431 [ #  # ][ #  # ]:          0 :             h[3] = mHessians[9].upper();
     432                 :          0 :             break;
     433                 :            : 
     434                 :            :         case PYRAMID:
     435         [ #  # ]:          0 :             for( i = 0; i < 4; ++i )
     436                 :            :             {
     437         [ #  # ]:          0 :                 mCoords[0] = vertices[v_i[i]];
     438         [ #  # ]:          0 :                 mCoords[1] = vertices[v_i[( i + 1 ) % 4]];
     439         [ #  # ]:          0 :                 mCoords[2] = vertices[v_i[( i + 3 ) % 4]];
     440         [ #  # ]:          0 :                 mCoords[3] = vertices[v_i[4]];
     441                 :            :                 metric_valid =
     442         [ #  # ]:          0 :                     h_fcn_3p( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con );
     443                 :            : 
     444         [ #  # ]:          0 :                 if( !metric_valid ) return false;
     445                 :            :             }
     446                 :            : 
     447         [ #  # ]:          0 :             g.resize( 5 );
     448         [ #  # ]:          0 :             h.resize( 5 );
     449                 :            :             m = average_corner_hessian_diagonals( PYRAMID, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ),
     450 [ #  # ][ #  # ]:          0 :                                                   arrptr( h ), err );
                 [ #  # ]
     451 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     452                 :          0 :             break;
     453                 :            : 
     454                 :            :         case PRISM:
     455         [ #  # ]:          0 :             for( i = 0; i < 6; ++i )
     456                 :            :             {
     457         [ #  # ]:          0 :                 mCoords[0] = vertices[v_i[locs_pri[i][0]]];
     458         [ #  # ]:          0 :                 mCoords[1] = vertices[v_i[locs_pri[i][1]]];
     459         [ #  # ]:          0 :                 mCoords[2] = vertices[v_i[locs_pri[i][2]]];
     460         [ #  # ]:          0 :                 mCoords[3] = vertices[v_i[locs_pri[i][3]]];
     461 [ #  # ][ #  # ]:          0 :                 if( !h_fcn_3w( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con ) )
     462                 :          0 :                     return false;
     463                 :            :             }
     464                 :            : 
     465         [ #  # ]:          0 :             g.resize( 6 );
     466         [ #  # ]:          0 :             h.resize( 6 );
     467                 :            :             m = average_corner_hessian_diagonals( PRISM, fm, 6, mMetrics, mGradients, mHessians, arrptr( g ),
     468 [ #  # ][ #  # ]:          0 :                                                   arrptr( h ), err );
                 [ #  # ]
     469 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     470                 :          0 :             break;
     471                 :            : 
     472                 :            :         case HEXAHEDRON:
     473         [ #  # ]:          0 :             for( i = 0; i < 8; ++i )
     474                 :            :             {
     475         [ #  # ]:          0 :                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
     476         [ #  # ]:          0 :                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
     477         [ #  # ]:          0 :                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
     478         [ #  # ]:          0 :                 mCoords[3] = vertices[v_i[locs_hex[i][3]]];
     479         [ #  # ]:          0 :                 if( !h_fcn_3i( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con,
     480         [ #  # ]:          0 :                                d_con ) )
     481                 :          0 :                     return false;
     482                 :            :             }
     483                 :            : 
     484         [ #  # ]:          0 :             g.resize( 8 );
     485         [ #  # ]:          0 :             h.resize( 8 );
     486                 :            :             m = average_corner_hessian_diagonals( HEXAHEDRON, fm, 8, mMetrics, mGradients, mHessians, arrptr( g ),
     487 [ #  # ][ #  # ]:          0 :                                                   arrptr( h ), err );
                 [ #  # ]
     488 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     489                 :          0 :             break;
     490                 :            : 
     491                 :            :         default:
     492                 :            :             MSQ_SETERR( err )
     493                 :            :             ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightInverseMeanRatio",
     494 [ #  # ][ #  # ]:          0 :               (int)topo );
     495                 :          0 :             return false;
     496                 :            :     }  // end switch over element type
     497                 :            : 
     498         [ #  # ]:          0 :     remove_fixed_diagonals( topo, fm, g, h );
     499                 :          0 :     return true;
     500                 :            : }
     501                 :            : 
     502                 :     139646 : bool IdealWeightInverseMeanRatio::evaluate_with_Hessian( PatchData& pd, size_t handle, double& m,
     503                 :            :                                                          std::vector< size_t >& indices, std::vector< Vector3D >& g,
     504                 :            :                                                          std::vector< Matrix3D >& h, MsqError& err )
     505                 :            : {
     506         [ +  - ]:     139646 :     const MsqMeshEntity* e = &pd.element_by_index( handle );
     507         [ +  - ]:     139646 :     EntityTopology topo    = e->get_element_type();
     508                 :            : 
     509 [ +  - ][ -  + ]:     139646 :     if( !analytical_average_hessian() && topo != TRIANGLE && topo != TETRAHEDRON )
         [ #  # ][ #  # ]
                 [ -  + ]
     510                 :            :     {
     511                 :            :         static bool print = true;
     512         [ #  # ]:          0 :         if( print )
     513                 :            :         {
     514                 :            :             MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. "
     515                 :            :                             << "Using (possibly much slower) numerical approximation of gradient"
     516                 :            :                             << " of quality metric. " << std::endl;
     517                 :          0 :             print = false;
     518                 :            :         }
     519         [ #  # ]:          0 :         return QualityMetric::evaluate_with_Hessian( pd, handle, m, indices, g, h, err );
     520                 :            :     }
     521                 :            : 
     522         [ +  - ]:     139646 :     const MsqVertex* vertices = pd.get_vertex_array( err );
     523 [ +  - ][ -  + ]:     139646 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     524         [ +  - ]:     139646 :     const size_t* v_i = e->get_vertex_index_array();
     525                 :            : 
     526         [ +  - ]:     139646 :     Vector3D n;  // Surface normal for 2D objects
     527                 :            : 
     528                 :            :     // Prism and Hex element descriptions
     529                 :            :     static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 },
     530                 :            :                                         { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } };
     531                 :            :     static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 },
     532                 :            :                                         { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } };
     533                 :            : 
     534         [ +  - ]:     139646 :     const Vector3D d_con( 1.0, 1.0, 1.0 );
     535                 :            : 
     536                 :            :     int i;
     537                 :            : 
     538                 :     139646 :     bool metric_valid = false;
     539         [ +  - ]:     139646 :     const uint32_t fm = fixed_vertex_bitmap( pd, e, indices );
     540                 :            : 
     541                 :     139646 :     m = 0.0;
     542                 :            : 
     543   [ -  -  +  +  :     139646 :     switch( topo )
                +  +  - ]
     544                 :            :     {
     545                 :            :         case TRIANGLE:
     546         [ #  # ]:          0 :             pd.get_domain_normal_at_element( e, n, err );
     547 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     548 [ #  # ][ #  # ]:          0 :             n /= n.length();  // Need unit normal
     549         [ #  # ]:          0 :             mCoords[0] = vertices[v_i[0]];
     550         [ #  # ]:          0 :             mCoords[1] = vertices[v_i[1]];
     551         [ #  # ]:          0 :             mCoords[2] = vertices[v_i[2]];
     552         [ #  # ]:          0 :             g.resize( 3 );
     553         [ #  # ]:          0 :             h.resize( 6 );
     554 [ #  # ][ #  # ]:          0 :             if( !h_fcn_2e( m, arrptr( g ), arrptr( h ), mCoords, n, a2Con, b2Con, c2Con ) ) return false;
         [ #  # ][ #  # ]
     555                 :          0 :             break;
     556                 :            : 
     557                 :            :         case QUADRILATERAL:
     558         [ #  # ]:          0 :             pd.get_domain_normal_at_element( e, n, err );
     559 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     560 [ #  # ][ #  # ]:          0 :             n /= n.length();  // Need unit normal
     561         [ #  # ]:          0 :             for( i = 0; i < 4; ++i )
     562                 :            :             {
     563         [ #  # ]:          0 :                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
     564         [ #  # ]:          0 :                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
     565         [ #  # ]:          0 :                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
     566         [ #  # ]:          0 :                 if( !h_fcn_2i( mMetrics[i], mGradients + 3 * i, mHessians + 6 * i, mCoords, n, a2Con, b2Con, c2Con,
     567         [ #  # ]:          0 :                                d_con ) )
     568                 :          0 :                     return false;
     569                 :            :             }
     570                 :            : 
     571         [ #  # ]:          0 :             g.resize( 4 );
     572         [ #  # ]:          0 :             h.resize( 10 );
     573                 :            :             m = average_corner_hessians( QUADRILATERAL, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ),
     574 [ #  # ][ #  # ]:          0 :                                          arrptr( h ), err );
                 [ #  # ]
     575 [ #  # ][ #  # ]:          0 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     576                 :          0 :             break;
     577                 :            : 
     578                 :            :         case TETRAHEDRON:
     579         [ +  - ]:     125015 :             mCoords[0] = vertices[v_i[0]];
     580         [ +  - ]:     125015 :             mCoords[1] = vertices[v_i[1]];
     581         [ +  - ]:     125015 :             mCoords[2] = vertices[v_i[2]];
     582         [ +  - ]:     125015 :             mCoords[3] = vertices[v_i[3]];
     583         [ +  - ]:     125015 :             g.resize( 4 );
     584         [ +  - ]:     125015 :             h.resize( 10 );
     585 [ +  - ][ +  - ]:     125015 :             metric_valid = h_fcn_3e( m, arrptr( g ), arrptr( h ), mCoords, a3Con, b3Con, c3Con );
                 [ +  - ]
     586         [ -  + ]:     125015 :             if( !metric_valid ) return false;
     587                 :     125015 :             break;
     588                 :            : 
     589                 :            :         case PYRAMID:
     590         [ +  + ]:      11050 :             for( i = 0; i < 4; ++i )
     591                 :            :             {
     592         [ +  - ]:       8840 :                 mCoords[0] = vertices[v_i[i]];
     593         [ +  - ]:       8840 :                 mCoords[1] = vertices[v_i[( i + 1 ) % 4]];
     594         [ +  - ]:       8840 :                 mCoords[2] = vertices[v_i[( i + 3 ) % 4]];
     595         [ +  - ]:       8840 :                 mCoords[3] = vertices[v_i[4]];
     596                 :            :                 metric_valid =
     597         [ +  - ]:       8840 :                     h_fcn_3p( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con );
     598                 :            : 
     599         [ -  + ]:       8840 :                 if( !metric_valid ) return false;
     600                 :            :             }
     601                 :            : 
     602         [ +  - ]:       2210 :             g.resize( 5 );
     603         [ +  - ]:       2210 :             h.resize( 15 );
     604                 :            :             m = average_corner_hessians( PYRAMID, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ),
     605 [ +  - ][ +  - ]:       2210 :                                          err );
                 [ +  - ]
     606 [ +  - ][ -  + ]:       2210 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     607                 :       2210 :             break;
     608                 :            : 
     609                 :            :         case PRISM:
     610         [ +  + ]:        462 :             for( i = 0; i < 6; ++i )
     611                 :            :             {
     612         [ +  - ]:        396 :                 mCoords[0] = vertices[v_i[locs_pri[i][0]]];
     613         [ +  - ]:        396 :                 mCoords[1] = vertices[v_i[locs_pri[i][1]]];
     614         [ +  - ]:        396 :                 mCoords[2] = vertices[v_i[locs_pri[i][2]]];
     615         [ +  - ]:        396 :                 mCoords[3] = vertices[v_i[locs_pri[i][3]]];
     616 [ +  - ][ -  + ]:        396 :                 if( !h_fcn_3w( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con ) )
     617                 :          0 :                     return false;
     618                 :            :             }
     619                 :            : 
     620         [ +  - ]:         66 :             g.resize( 6 );
     621         [ +  - ]:         66 :             h.resize( 21 );
     622 [ +  - ][ +  - ]:         66 :             m = average_corner_hessians( PRISM, fm, 6, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err );
                 [ +  - ]
     623 [ +  - ][ -  + ]:         66 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     624                 :         66 :             break;
     625                 :            : 
     626                 :            :         case HEXAHEDRON:
     627         [ +  + ]:     111195 :             for( i = 0; i < 8; ++i )
     628                 :            :             {
     629         [ +  - ]:      98840 :                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
     630         [ +  - ]:      98840 :                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
     631         [ +  - ]:      98840 :                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
     632         [ +  - ]:      98840 :                 mCoords[3] = vertices[v_i[locs_hex[i][3]]];
     633         [ -  + ]:      98840 :                 if( !h_fcn_3i( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con,
     634         [ +  - ]:      98840 :                                d_con ) )
     635                 :          0 :                     return false;
     636                 :            :             }
     637                 :            : 
     638         [ +  - ]:      12355 :             g.resize( 8 );
     639         [ +  - ]:      12355 :             h.resize( 36 );
     640                 :            :             m = average_corner_hessians( HEXAHEDRON, fm, 8, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ),
     641 [ +  - ][ +  - ]:      12355 :                                          err );
                 [ +  - ]
     642 [ +  - ][ -  + ]:      12355 :             MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ -  + ]
     643                 :      12355 :             break;
     644                 :            : 
     645                 :            :         default:
     646                 :            :             MSQ_SETERR( err )
     647                 :            :             ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightInverseMeanRatio",
     648 [ #  # ][ #  # ]:          0 :               (int)topo );
     649                 :          0 :             return false;
     650                 :            :     }  // end switch over element type
     651                 :            : 
     652         [ +  - ]:     139646 :     remove_fixed_gradients( topo, fm, g );
     653         [ +  - ]:     139646 :     remove_fixed_hessians( topo, fm, h );
     654                 :     139646 :     return true;
     655                 :            : }
     656                 :            : 
     657 [ +  - ][ +  - ]:         56 : }  // namespace MBMesquite

Generated by: LCOV version 1.11