LCOV - code coverage report
Current view: top level - src/mesquite/Mesh - MeshUtil.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 46 120 38.3 %
Date: 2020-07-18 00:09:26 Functions: 6 7 85.7 %
Branches: 71 508 14.0 %

           Branch data     Line data    Source code
       1                 :            : /* *****************************************************************
       2                 :            :     MESQUITE -- The Mesh Quality Improvement Toolkit
       3                 :            : 
       4                 :            :     Copyright 2010 Sandia National Laboratories.  Developed at the
       5                 :            :     University of Wisconsin--Madison under SNL contract number
       6                 :            :     624796.  The U.S. Government and the University of Wisconsin
       7                 :            :     retain certain rights to 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                 :            :     (2010) [email protected]
      24                 :            : 
      25                 :            :   ***************************************************************** */
      26                 :            : 
      27                 :            : /** \file MeshUtil.cpp
      28                 :            :  *  \brief Implement MeshUtil class
      29                 :            :  *  \author Jason Kraftcheck
      30                 :            :  */
      31                 :            : 
      32                 :            : #include "Mesquite.hpp"
      33                 :            : #include "MeshUtil.hpp"
      34                 :            : #include "MeshInterface.hpp"
      35                 :            : #include "EdgeIterator.hpp"
      36                 :            : #include "SimpleStats.hpp"
      37                 :            : #include "MsqError.hpp"
      38                 :            : #include "TMPQualityMetric.hpp"
      39                 :            : #include "MappingFunction.hpp"
      40                 :            : #include "TargetCalculator.hpp"
      41                 :            : 
      42                 :            : #include <vector>
      43                 :            : #include <algorithm>
      44                 :            : #include <limits>
      45                 :            : #include <sstream>
      46                 :            : 
      47                 :            : namespace MBMesquite
      48                 :            : {
      49                 :            : 
      50                 :         33 : MeshUtil::~MeshUtil()
      51                 :            : {
      52         [ +  - ]:         33 :     delete globalPatch;
      53                 :         33 : }
      54                 :            : 
      55                 :         53 : PatchData* MeshUtil::get_global_patch( MsqError& err )
      56                 :            : {
      57         [ +  + ]:         53 :     if( !globalPatch )
      58                 :            :     {
      59         [ +  - ]:         33 :         globalPatch = new PatchData;
      60                 :         33 :         globalPatch->set_mesh( myMesh );
      61         [ +  + ]:         33 :         if( mySettings ) globalPatch->attach_settings( mySettings );
      62                 :         33 :         globalPatch->fill_global_patch( err );
      63 [ -  + ][ #  # ]:         33 :         if( MSQ_CHKERR( err ) )
                 [ -  + ]
      64                 :            :         {
      65         [ #  # ]:          0 :             delete globalPatch;
      66                 :          0 :             globalPatch = 0;
      67                 :            :         }
      68                 :            :     }
      69                 :         53 :     return globalPatch;
      70                 :            : }
      71                 :            : 
      72                 :         30 : void MeshUtil::edge_length_distribution( SimpleStats& results, MsqError& err )
      73                 :            : {
      74 [ +  - ][ +  - ]:         60 :     PatchData* pd = get_global_patch( err );MSQ_ERRRTN( err );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
      75 [ +  - ][ +  - ]:         30 :     EdgeIterator iter( pd, err );MSQ_ERRRTN( err );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
      76 [ +  - ][ +  + ]:      58399 :     while( !iter.is_at_end() )
      77                 :            :     {
      78 [ +  - ][ +  - ]:      58369 :         Vector3D diff = iter.start() - iter.end();
                 [ +  - ]
      79 [ +  - ][ +  - ]:      58369 :         results.add_squared( diff % diff );
      80 [ +  - ][ +  - ]:      58369 :         iter.step( err );MSQ_ERRRTN( err );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
      81                 :            :     }
      82                 :            : 
      83 [ +  - ][ -  + ]:         30 :     if( results.empty() )
      84                 :            :     {  // no mesh
      85 [ #  # ][ #  # ]:         30 :         MSQ_SETERR( err )( "Mesh contains no elements", MsqError::INVALID_MESH );
                 [ +  - ]
      86                 :         30 :     }
      87                 :            : }
      88                 :            : 
      89                 :         23 : void MeshUtil::lambda_distribution( SimpleStats& results, MsqError& err )
      90                 :            : {
      91 [ +  - ][ +  - ]:         46 :     PatchData& pd = *get_global_patch( err );MSQ_ERRRTN( err );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
      92                 :            : 
      93         [ +  - ]:         23 :     std::vector< size_t > handles;
      94         [ +  - ]:         23 :     TMPQualityMetric::get_patch_evaluations( pd, handles, false, err );
      95                 :            : 
      96                 :         23 :     const size_t N = 64;
      97                 :            :     size_t count;
      98                 :            :     size_t indices[N];
      99 [ +  - ][ +  + ]:       1495 :     MsqVector< 2 > derivs2D[N];
     100 [ +  - ][ +  + ]:       1495 :     MsqVector< 3 > derivs3D[N];
     101                 :            : 
     102         [ +  + ]:      73799 :     for( size_t i = 0; i < handles.size(); ++i )
     103                 :            :     {
     104                 :            :         double lambda;
     105 [ +  - ][ +  - ]:      73776 :         const Sample s      = ElemSampleQM::sample( handles[i] );
     106 [ +  - ][ +  - ]:      73776 :         const size_t e      = ElemSampleQM::elem( handles[i] );
     107 [ +  - ][ +  - ]:      73776 :         EntityTopology type = pd.element_by_index( e ).get_element_type();
     108         [ +  - ]:      73776 :         const NodeSet bits  = pd.non_slave_node_set( e );
     109                 :            : 
     110 [ +  - ][ -  + ]:      73776 :         if( TopologyInfo::dimension( type ) == 3 )
     111                 :            :         {
     112         [ #  # ]:          0 :             const MappingFunction3D* mf = pd.get_mapping_function_3D( type );
     113         [ #  # ]:          0 :             if( !mf )
     114                 :            :             {
     115                 :            :                 MSQ_SETERR( err )
     116 [ #  # ][ #  # ]:          0 :                 ( "No mapping function for element type", MsqError::UNSUPPORTED_ELEMENT );
     117                 :          0 :                 return;
     118                 :            :             }
     119                 :            : 
     120         [ #  # ]:          0 :             MsqMatrix< 3, 3 > W;
     121 [ #  # ][ #  # ]:          0 :             mf->jacobian( pd, e, bits, s, indices, derivs3D, count, W, err );MSQ_ERRRTN( err );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     122         [ #  # ]:          0 :             assert( N >= count );
     123         [ #  # ]:          0 :             lambda = TargetCalculator::size( W );
     124                 :            :         }
     125                 :            :         else
     126                 :            :         {
     127 [ +  - ][ -  + ]:      73776 :             assert( TopologyInfo::dimension( type ) == 2 );
     128         [ +  - ]:      73776 :             const MappingFunction2D* mf = pd.get_mapping_function_2D( type );
     129         [ -  + ]:      73776 :             if( !mf )
     130                 :            :             {
     131                 :            :                 MSQ_SETERR( err )
     132 [ #  # ][ #  # ]:          0 :                 ( "No mapping function for element type", MsqError::UNSUPPORTED_ELEMENT );
     133                 :          0 :                 return;
     134                 :            :             }
     135                 :            : 
     136         [ +  - ]:      73776 :             MsqMatrix< 3, 2 > W;
     137 [ +  - ][ +  - ]:      73776 :             mf->jacobian( pd, e, bits, s, indices, derivs2D, count, W, err );MSQ_ERRRTN( err );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
     138         [ -  + ]:      73776 :             assert( N >= count );
     139         [ +  - ]:      73776 :             lambda = TargetCalculator::size( W );
     140                 :            :         }
     141                 :            : 
     142         [ +  - ]:      73776 :         results.add_value( lambda );
     143                 :            :     }
     144                 :            : 
     145 [ +  - ][ -  + ]:         23 :     if( results.empty() )
     146                 :            :     {  // no mesh
     147 [ #  # ][ #  # ]:         23 :         MSQ_SETERR( err )( "Mesh contains no elements", MsqError::INVALID_MESH );
                 [ +  - ]
     148                 :         23 :     }
     149                 :            : }
     150                 :            : 
     151                 :          0 : bool MeshUtil::meshes_are_different( Mesh& mesh1, Mesh& mesh2, MsqError& err, double tol, bool do_print )
     152                 :            : {
     153                 :            :     // MsqError& err = (do_print ? MsqPrintError(cout) : MsqError());
     154                 :            : 
     155                 :            :     // mesh 1
     156         [ #  # ]:          0 :     std::vector< Mesh::ElementHandle > elements1;
     157         [ #  # ]:          0 :     std::vector< Mesh::VertexHandle > vertices1;
     158         [ #  # ]:          0 :     std::vector< Mesh::VertexHandle > connectivity1;
     159         [ #  # ]:          0 :     std::vector< size_t > offsets1;
     160                 :            : 
     161         [ #  # ]:          0 :     mesh1.get_all_elements( elements1, err );
     162 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     163         [ #  # ]:          0 :     mesh1.get_all_vertices( vertices1, err );
     164 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     165 [ #  # ][ #  # ]:          0 :     mesh1.elements_get_attached_vertices( arrptr( elements1 ), elements1.size(), connectivity1, offsets1, err );
     166 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     167         [ #  # ]:          0 :     std::vector< EntityTopology > types1( elements1.size() );
     168 [ #  # ][ #  # ]:          0 :     mesh1.elements_get_topologies( arrptr( elements1 ), arrptr( types1 ), elements1.size(), err );
                 [ #  # ]
     169 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     170                 :            : 
     171                 :            :     // mesh 2
     172         [ #  # ]:          0 :     std::vector< Mesh::ElementHandle > elements2;
     173         [ #  # ]:          0 :     std::vector< Mesh::VertexHandle > vertices2;
     174         [ #  # ]:          0 :     std::vector< Mesh::VertexHandle > connectivity2;
     175         [ #  # ]:          0 :     std::vector< size_t > offsets2;
     176                 :            : 
     177         [ #  # ]:          0 :     mesh2.get_all_elements( elements2, err );
     178 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     179         [ #  # ]:          0 :     mesh2.get_all_vertices( vertices2, err );
     180 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     181 [ #  # ][ #  # ]:          0 :     mesh2.elements_get_attached_vertices( arrptr( elements2 ), elements2.size(), connectivity2, offsets2, err );
     182 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     183         [ #  # ]:          0 :     std::vector< EntityTopology > types2( elements2.size() );
     184 [ #  # ][ #  # ]:          0 :     mesh2.elements_get_topologies( arrptr( elements2 ), arrptr( types2 ), elements2.size(), err );
                 [ #  # ]
     185 [ #  # ][ #  # ]:          0 :     MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     186                 :            : 
     187                 :            : #define MDRET( msg )                                                                                  \
     188                 :            :     do                                                                                                \
     189                 :            :     {                                                                                                 \
     190                 :            :         if( do_print ) std::cout << "MeshUtil::mesh_diff meshes are different: " << msg << std::endl; \
     191                 :            :         return true;                                                                                  \
     192                 :            :     } while( 0 )
     193 [ #  # ][ #  # ]:          0 :     if( elements1.size() != elements2.size() ) MDRET( "elements sizes differ" );
         [ #  # ][ #  # ]
                 [ #  # ]
     194 [ #  # ][ #  # ]:          0 :     if( vertices1.size() != vertices2.size() ) MDRET( "vertices sizes differ" );
         [ #  # ][ #  # ]
                 [ #  # ]
     195 [ #  # ][ #  # ]:          0 :     if( offsets1.size() != offsets2.size() ) MDRET( "offsets sizes differ" );
         [ #  # ][ #  # ]
                 [ #  # ]
     196 [ #  # ][ #  # ]:          0 :     if( connectivity1.size() != connectivity2.size() ) MDRET( "connectivity sizes differ" );
         [ #  # ][ #  # ]
                 [ #  # ]
     197                 :            : 
     198         [ #  # ]:          0 :     for( unsigned i = 0; i < offsets1.size(); i++ )
     199                 :            :     {
     200 [ #  # ][ #  # ]:          0 :         if( offsets1[i] != offsets2[i] ) MDRET( "offets differ" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     201                 :            :     }
     202                 :            : 
     203         [ #  # ]:          0 :     for( unsigned i = 0; i < vertices1.size(); i++ )
     204                 :            :     {
     205 [ #  # ][ #  # ]:          0 :         MsqVertex vert1, vert2;
     206 [ #  # ][ #  # ]:          0 :         mesh1.vertices_get_coordinates( &vertices1[i], &vert1, 1, err );
     207 [ #  # ][ #  # ]:          0 :         MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     208 [ #  # ][ #  # ]:          0 :         mesh2.vertices_get_coordinates( &vertices2[i], &vert2, 1, err );
     209 [ #  # ][ #  # ]:          0 :         MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     210         [ #  # ]:          0 :         double dist = Vector3D::distance_between( vert1, vert2 );
     211         [ #  # ]:          0 :         double v1   = vert1.length();
     212         [ #  # ]:          0 :         double v2   = vert2.length();
     213         [ #  # ]:          0 :         if( dist > 0.5 * ( v1 + v2 ) * tol )
     214                 :            :         {
     215         [ #  # ]:          0 :             std::ostringstream ost;
     216 [ #  # ][ #  # ]:          0 :             ost << "vertices coordinates differ more than tolerance [" << tol << "], vert1= " << vert1
         [ #  # ][ #  # ]
     217 [ #  # ][ #  # ]:          0 :                 << " vert2= " << vert2;
     218 [ #  # ][ #  # ]:          0 :             MDRET( ost.str() );
         [ #  # ][ #  # ]
                 [ #  # ]
     219                 :            :         }
     220                 :            :     }
     221                 :            : 
     222         [ #  # ]:          0 :     for( unsigned i = 0; i < connectivity1.size(); i++ )
     223                 :            :     {
     224 [ #  # ][ #  # ]:          0 :         MsqVertex vert1, vert2;
     225 [ #  # ][ #  # ]:          0 :         mesh1.vertices_get_coordinates( &connectivity1[i], &vert1, 1, err );
     226 [ #  # ][ #  # ]:          0 :         MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     227 [ #  # ][ #  # ]:          0 :         mesh2.vertices_get_coordinates( &connectivity2[i], &vert2, 1, err );
     228 [ #  # ][ #  # ]:          0 :         MSQ_ERRZERO( err );
         [ #  # ][ #  # ]
                 [ #  # ]
     229         [ #  # ]:          0 :         double dist = Vector3D::distance_between( vert1, vert2 );
     230         [ #  # ]:          0 :         double v1   = vert1.length();
     231         [ #  # ]:          0 :         double v2   = vert2.length();
     232         [ #  # ]:          0 :         if( dist > 0.5 * ( v1 + v2 ) * tol )
     233                 :            :         {
     234         [ #  # ]:          0 :             std::ostringstream ost;
     235 [ #  # ][ #  # ]:          0 :             ost << "connectivity coordinates differ more than tolerance [" << tol << "], vert1= " << vert1
         [ #  # ][ #  # ]
     236 [ #  # ][ #  # ]:          0 :                 << " vert2= " << vert2;
     237 [ #  # ][ #  # ]:          0 :             MDRET( ost.str() );
         [ #  # ][ #  # ]
                 [ #  # ]
     238                 :            :         }
     239                 :            :     }
     240                 :            : 
     241                 :          0 :     return false;
     242                 :            : }
     243                 :            : 
     244 [ +  - ][ +  - ]:        120 : }  // namespace MBMesquite

Generated by: LCOV version 1.11