Quinoa all test code coverage report
Current view: top level - IO - GmshMeshReader.cpp (source / functions) Hit Total Coverage
Commit: Quinoa_v0.3-957-gb4f0efae0 Lines: 88 94 93.6 %
Date: 2021-11-09 15:14:18 Functions: 4 5 80.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 98 381 25.7 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/IO/GmshMeshReader.cpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.
       7                 :            :              All rights reserved. See the LICENSE file for details.
       8                 :            :   \brief     Gmsh mesh reader class definition
       9                 :            :   \details   Gmsh mesh reader class definition. Currently, this class supports
      10                 :            :     line, triangle, tetrahedron, and point Gmsh element types.
      11                 :            : */
      12                 :            : // *****************************************************************************
      13                 :            : 
      14                 :            : #include <limits>
      15                 :            : #include <array>
      16                 :            : #include <cmath>
      17                 :            : #include <cstddef>
      18                 :            : #include <istream>
      19                 :            : #include <string>
      20                 :            : #include <utility>
      21                 :            : #include <vector>
      22                 :            : 
      23                 :            : #include "UnsMesh.hpp"
      24                 :            : #include "GmshMeshReader.hpp"
      25                 :            : #include "GmshMeshIO.hpp"
      26                 :            : #include "Reorder.hpp"
      27                 :            : #include "PrintUtil.hpp"
      28                 :            : 
      29                 :            : using tk::GmshMeshReader;
      30                 :            : 
      31                 :            : void
      32                 :          7 : GmshMeshReader::readMesh( UnsMesh& mesh )
      33                 :            : // *****************************************************************************
      34                 :            : //  Public interface for read a Gmsh mesh from file
      35                 :            : //! \param[in] mesh Unstructured mesh object
      36                 :            : // *****************************************************************************
      37                 :            : {
      38                 :            :   // Read in mandatory "$MeshFormat" section
      39                 :          7 :   readMeshFormat();
      40                 :            : 
      41                 :            :   // Keep reading in sections until end of file. These sections can be in
      42                 :            :   // arbitrary order, hence a while loop.
      43         [ +  + ]:         28 :   while ( !m_inFile.eof() ) {
      44                 :            :     std::string s;
      45         [ +  - ]:         21 :     getline( m_inFile, s );
      46         [ +  + ]:         21 :     if ( s == "$Nodes" )
      47         [ +  - ]:          7 :       readNodes( mesh );
      48         [ +  + ]:         14 :     else if ( s == "$Elements" )
      49         [ +  - ]:          7 :       readElements( mesh );
      50         [ -  + ]:          7 :     else if ( s == "$PhysicalNames" )
      51                 :          0 :       readPhysicalNames();
      52                 :            :   }
      53                 :          7 : }
      54                 :            : 
      55                 :            : void
      56         [ +  - ]:          7 : GmshMeshReader::readMeshFormat()
      57                 :            : // *****************************************************************************
      58                 :            : //  Read mandatory "$MeshFormat--$EndMeshFormat" section
      59                 :            : // *****************************************************************************
      60                 :            : {
      61                 :            :   using tk::operator<<;
      62                 :            :   std::string s;
      63                 :            : 
      64                 :            :   // Read in beginning of header: $MeshFormat
      65         [ +  - ]:          7 :   getline( m_inFile, s );
      66 [ -  + ][ -  - ]:          7 :   ErrChk( s == "$MeshFormat",
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      67                 :            :           std::string("Unsupported mesh format '") + s + "' in file " +
      68                 :            :           m_filename );
      69                 :            : 
      70                 :            :   // Read in "version-number file-type data-size"
      71                 :            :   int type;
      72 [ +  - ][ +  - ]:          7 :   m_inFile >> m_version >> type >> m_datasize;
                 [ +  - ]
      73         [ +  + ]:          7 :   if (type == 0 )
      74                 :          4 :     m_type = GmshFileType::ASCII;
      75         [ +  - ]:          3 :   else if (type == 1 )
      76                 :          3 :     m_type = GmshFileType::BINARY;
      77                 :            : 
      78 [ -  + ][ -  - ]:          7 :   ErrChk( ( fabs(m_version-2.2) < std::numeric_limits<tk::real>::epsilon() ||
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
      79                 :            :             fabs(m_version-2.0) < std::numeric_limits<tk::real>::epsilon() ),
      80                 :            :             std::string("Unsupported mesh version '") << m_version <<
      81                 :            :             "' in file " << m_filename );
      82                 :            : 
      83 [ -  + ][ -  - ]:          7 :   ErrChk( ( m_type == GmshFileType::ASCII || m_type == GmshFileType::BINARY ),
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
      84                 :            :             std::string("Unsupported mesh type '") << m_type << "' in file " <<
      85                 :            :             m_filename );
      86                 :            : 
      87 [ -  + ][ -  - ]:          7 :   ErrChk( m_datasize == sizeof(tk::real),
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      88                 :            :           std::string("Unsupported mesh datasize '") << m_datasize <<
      89                 :            :           "' in file " << m_filename );
      90                 :            : 
      91         [ +  - ]:          7 :   getline( m_inFile, s );  // finish reading the line
      92                 :            : 
      93                 :            :   // if file is binary, binary-read in binary "one"
      94         [ +  + ]:          7 :   if ( isBinary() ) {
      95                 :            :     int one;
      96         [ +  - ]:          3 :     m_inFile.read( reinterpret_cast<char*>(&one), sizeof(int) );
      97                 :            :     #ifdef __bg__
      98                 :            :     one = tk::swap_endian< int >( one );
      99                 :            :     #endif
     100 [ -  + ][ -  - ]:          3 :     ErrChk( one == 1, "Endianness does not match in file " + m_filename );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     101         [ +  - ]:          3 :     getline( m_inFile, s );  // finish reading the line
     102                 :            :   }
     103                 :            : 
     104                 :            :   // Read in end of header: $EndMeshFormat
     105         [ +  - ]:          7 :   getline( m_inFile, s );
     106 [ -  + ][ -  - ]:          7 :   ErrChk( s == "$EndMeshFormat",
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     107                 :            :           "'$EndMeshFormat' keyword is missing in file " + m_filename );
     108                 :          7 : }
     109                 :            : 
     110                 :            : void
     111                 :          7 : GmshMeshReader::readNodes( UnsMesh& mesh )
     112                 :            : // *****************************************************************************
     113                 :            : //  Read "$Nodes--$EndNodes" section
     114                 :            : //! \param[in] mesh Unstructured mesh object
     115                 :            : // *****************************************************************************
     116                 :            : {
     117                 :            :   // Read in number of nodes in this node set
     118                 :            :   std::size_t nnode;
     119                 :          7 :   m_inFile >> nnode;
     120 [ -  + ][ -  - ]:          7 :   ErrChk( nnode > 0,
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     121                 :            :           "Number of nodes must be greater than zero in file " + m_filename  );
     122                 :            :   std::string s;
     123 [ +  + ][ +  - ]:          7 :   if (isBinary()) getline( m_inFile, s );  // finish reading the line
     124                 :            : 
     125                 :            :   // Read in node ids and coordinates: node-number x-coord y-coord z-coord
     126         [ +  + ]:        105 :   for ( std::size_t i=0; i<nnode; ++i ) {
     127                 :            :     int id;
     128                 :            :     std::array< tk::real, 3 > coord;
     129                 :            : 
     130         [ +  + ]:         98 :     if (isASCII()) {
     131         [ +  - ]:         56 :       m_inFile >> id >> coord[0] >> coord[1] >> coord[2];
     132                 :            :     } else {
     133         [ +  - ]:         42 :       m_inFile.read( reinterpret_cast<char*>(&id), sizeof(int) );
     134                 :            :       #ifdef __bg__
     135                 :            :       id = tk::swap_endian< int >( id );
     136                 :            :       #endif
     137         [ +  - ]:         42 :       m_inFile.read( reinterpret_cast<char*>(coord.data()), 3*sizeof(double) );
     138                 :            :       #ifdef __bg__
     139                 :            :       coord[0] = tk::swap_endian< double >( coord[0] );
     140                 :            :       coord[1] = tk::swap_endian< double >( coord[1] );
     141                 :            :       coord[2] = tk::swap_endian< double >( coord[2] );
     142                 :            :       #endif
     143                 :            :     }
     144                 :            : 
     145         [ +  - ]:         98 :     mesh.x().push_back( coord[0] );
     146         [ +  - ]:         98 :     mesh.y().push_back( coord[1] );
     147         [ +  - ]:         98 :     mesh.z().push_back( coord[2] );
     148                 :            :   }
     149         [ +  - ]:          7 :   getline( m_inFile, s );  // finish reading the last line
     150                 :            : 
     151                 :            :   // Read in end of header: $EndNodes
     152         [ +  - ]:          7 :   getline( m_inFile, s );
     153 [ -  + ][ -  - ]:          7 :   ErrChk( s == "$EndNodes",
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     154                 :            :           "'$EndNodes' keyword is missing in file" + m_filename );
     155                 :          7 : }
     156                 :            : 
     157                 :            : void
     158         [ +  - ]:          7 : GmshMeshReader::readElements( UnsMesh& mesh )
     159                 :            : // *****************************************************************************
     160                 :            : //  Read "$Elements--$EndElements" section
     161                 :            : //! \param[in] mesh Unstructured mesh object
     162                 :            : // *****************************************************************************
     163                 :            : {
     164                 :            :   using tk::operator<<;
     165                 :            : 
     166                 :            :   std::string s;
     167                 :            : 
     168                 :            :   // Read in number of elements in this element set
     169                 :            :   int nel;
     170         [ +  - ]:          7 :   m_inFile >> nel;
     171 [ -  + ][ -  - ]:          7 :   ErrChk( nel > 0, "Number of elements must be greater than zero in file " +
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     172                 :            :           m_filename );
     173         [ +  - ]:          7 :   getline( m_inFile, s );  // finish reading the last line
     174                 :            : 
     175                 :            :   // Read in element ids, tags, and element connectivity (node list)
     176                 :          7 :   int n=1;
     177         [ +  + ]:        180 :   for (int i=0; i<nel; i+=n) {
     178                 :            :     int id, elmtype, ntags;
     179                 :            : 
     180         [ +  + ]:        173 :     if (isASCII()) {
     181                 :            :       // elm-number elm-type number-of-tags < tag > ... node-number-list
     182 [ +  - ][ +  - ]:        168 :       m_inFile >> id >> elmtype >> ntags;
                 [ +  - ]
     183                 :            :     } else {
     184                 :            :       // elm-type num-of-elm-follow number-of-tags
     185         [ +  - ]:          5 :       m_inFile.read( reinterpret_cast<char*>(&elmtype), sizeof(int) );
     186         [ +  - ]:          5 :       m_inFile.read( reinterpret_cast<char*>(&n), sizeof(int) );
     187         [ +  - ]:          5 :       m_inFile.read( reinterpret_cast<char*>(&ntags), sizeof(int) );
     188                 :            :       #ifdef __bg__
     189                 :            :       elmtype = tk::swap_endian< int >( elmtype );
     190                 :            :       n = tk::swap_endian< int >( n );
     191                 :            :       ntags = tk::swap_endian< int >( ntags );
     192                 :            :       #endif
     193                 :            :     }
     194                 :            : 
     195                 :            :     // Find element type, throw exception if not supported
     196                 :            :     const auto it = m_elemNodes.find( elmtype );
     197 [ +  - ][ -  - ]:        173 :     ErrChk( it != m_elemNodes.end(),
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     198                 :            :             std::string("Unsupported element type ") << elmtype <<
     199                 :            :             " in mesh file: " << m_filename );
     200                 :            : 
     201         [ +  + ]:        461 :     for (int e=0; e<n; ++e) {
     202                 :            :       // Read element id if binary
     203         [ +  + ]:        288 :       if (isBinary()) {
     204         [ +  - ]:        120 :         m_inFile.read( reinterpret_cast<char*>(&id), sizeof(int) );
     205                 :            :         #ifdef __bg__
     206                 :            :         id = tk::swap_endian< int >( id );
     207                 :            :         #endif
     208                 :            :       }
     209                 :            : 
     210                 :            :       // Read and ignore element tags
     211 [ +  - ][ -  - ]:        288 :       std::vector< int > tags( static_cast<std::size_t>(ntags), 0 );
     212         [ +  + ]:        288 :       if (isASCII()) {
     213         [ +  + ]:        480 :         for (std::size_t j=0; j<static_cast<std::size_t>(ntags); j++)
     214         [ +  - ]:        312 :           m_inFile >> tags[j];
     215                 :            :       } else {
     216                 :            :         m_inFile.read(
     217                 :        120 :           reinterpret_cast<char*>(tags.data()),
     218                 :            :           static_cast<std::streamsize>(
     219         [ +  - ]:        120 :             static_cast<std::size_t>(ntags) * sizeof(int) ) );
     220                 :            :         #ifdef __bg__
     221                 :            :         for (auto& t : tags) t = tk::swap_endian< int >( t );
     222                 :            :         #endif
     223                 :            :       }
     224                 :            : 
     225                 :            :       // Read and add element node list (i.e. connectivity)
     226                 :        288 :       std::size_t nnode = static_cast< std::size_t >( it->second );
     227 [ +  - ][ -  - ]:        288 :       std::vector< std::size_t > nodes( nnode, 0 );
     228         [ +  + ]:        288 :       if (isASCII()) {
     229         [ +  + ]:        768 :         for (std::size_t j=0; j<nnode; j++)
     230         [ +  - ]:        600 :           m_inFile >> nodes[j];
     231                 :            :       } else {
     232 [ +  - ][ -  - ]:        120 :         std::vector< int > nds( nnode, 0 );
     233                 :            :         m_inFile.read(
     234                 :        120 :           reinterpret_cast< char* >( nds.data() ),
     235         [ +  - ]:        120 :           static_cast< std::streamsize >( nnode * sizeof(int) ) );
     236                 :            :         #ifdef __bg__
     237                 :            :         for (auto& j : nds) j = tk::swap_endian< int >( j );
     238                 :            :         #endif
     239         [ +  + ]:        552 :         for (std::size_t j=0; j<nnode; j++)
     240                 :        432 :           nodes[j] = static_cast< std::size_t >( nds[j] );
     241                 :            :       }
     242                 :            :       // Put in element connectivity for different types of elements
     243 [ -  + ][ +  - ]:        288 :       switch ( elmtype ) {
                    [ - ]
     244                 :          0 :         case GmshElemType::LIN:
     245 [ -  - ][ -  - ]:          0 :           for (const auto& j : nodes) mesh.lininpoel().push_back( j );
     246                 :            :           break;
     247                 :        120 :         case GmshElemType::TRI:
     248 [ +  + ][ +  - ]:        480 :           for (const auto& j : nodes) mesh.triinpoel().push_back( j );
     249                 :            :           break;
     250                 :        168 :         case GmshElemType::TET:
     251 [ +  + ][ +  - ]:        840 :           for (const auto& j : nodes) mesh.tetinpoel().push_back( j );
     252                 :            :           break;
     253                 :            :         case GmshElemType::PNT:
     254                 :            :           break;     // ignore 1-node 'point element' type
     255 [ -  - ][ -  - ]:          0 :         default: Throw( std::string("Unsupported element type ") << elmtype <<
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
                 [ -  - ]
     256                 :            :                         " in mesh file: " << m_filename );
     257                 :            :       }
     258                 :            :     }
     259                 :            :   }
     260         [ +  - ]:          7 :   getline( m_inFile, s );  // finish reading the last line
     261                 :            : 
     262                 :            :   // Shift node IDs to start from zero (gmsh likes one-based node ids)
     263         [ +  - ]:          7 :   shiftToZero( mesh.lininpoel() );
     264         [ +  - ]:          7 :   shiftToZero( mesh.triinpoel() );
     265         [ +  - ]:          7 :   shiftToZero( mesh.tetinpoel() );
     266                 :            : 
     267                 :            :   // Read in end of header: $EndNodes
     268         [ +  - ]:          7 :   getline( m_inFile, s );
     269 [ -  + ][ -  - ]:          7 :   ErrChk( s == "$EndElements",
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     270                 :            :           "'$EndElements' keyword is missing in file" + m_filename );
     271                 :          7 : }
     272                 :            : 
     273                 :            : void
     274                 :          0 : GmshMeshReader::readPhysicalNames()
     275                 :            : // *****************************************************************************
     276                 :            : //  Read "$PhysicalNames--$EndPhysicalNames" section
     277                 :            : // *****************************************************************************
     278                 :            : {
     279 [ -  - ][ -  - ]:          0 :   Throw( "Mesh section '$PhysicalNames -- $EndPhysicalNames' not implemented" );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
     280                 :            : }

Generated by: LCOV version 1.14