Quinoa all test code coverage report
Current view: top level - IO - GmshMeshWriter.cpp (source / functions) Hit Total Coverage
Commit: -128-NOTFOUND Lines: 66 66 100.0 %
Date: 2024-11-22 09:12:55 Functions: 5 5 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 53 112 47.3 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/IO/GmshMeshWriter.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 writer class definition
       9                 :            :   \details   Gmsh mesh writer class definition. Currently, this class supports
      10                 :            :     line, triangle, tetrahedron, and point Gmsh element types.
      11                 :            : */
      12                 :            : // *****************************************************************************
      13                 :            : 
      14                 :            : #include <iterator>
      15                 :            : #include <iomanip>
      16                 :            : #include <algorithm>
      17                 :            : #include <cstddef>
      18                 :            : #include <ostream>
      19                 :            : #include <string>
      20                 :            : #include <utility>
      21                 :            : 
      22                 :            : #include "Exception.hpp"
      23                 :            : #include "UnsMesh.hpp"
      24                 :            : #include "PrintUtil.hpp"
      25                 :            : #include "GmshMeshWriter.hpp"
      26                 :            : #include "GmshMeshIO.hpp"
      27                 :            : 
      28                 :            : using tk::GmshMeshWriter;
      29                 :            : 
      30                 :          6 : GmshMeshWriter::GmshMeshWriter( const std::string& filename,
      31                 :            :                                 GmshFileType type,
      32                 :            :                                 tk::real version,
      33                 :          6 :                                 int datasize ) :
      34                 :          6 :   Writer( filename ), m_type( type )
      35                 :            : // *****************************************************************************
      36                 :            : //  Constructor: write mandatory "$MeshFormat" section
      37                 :            : //! \param[in] filename File to open as a Gmsh file
      38                 :            : //! \param[in] type Gmsh file type: ASCII or binary
      39                 :            : //! \param[in] version Gmsh file version
      40                 :            : //! \param[in] datasize Size of double precision number on machine
      41                 :            : // *****************************************************************************
      42                 :            : {
      43                 :            :   using tk::operator<<;
      44                 :            : 
      45                 :            :   // Write beginning of header: $MeshFormat
      46         [ +  - ]:          6 :   m_outFile << "$MeshFormat\n";
      47 [ -  + ][ -  - ]:          6 :   ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      48                 :            : 
      49                 :            :   // Write "version-number file-type data-size"
      50 [ +  - ][ +  - ]:          6 :   m_outFile << version << " " << type << " " << datasize << "\n";
      51 [ -  + ][ -  - ]:          6 :   ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      52                 :            : 
      53         [ +  + ]:          6 :   if (isBinary()) {
      54                 :          5 :     int one = 1;
      55         [ +  - ]:          5 :     m_outFile.write( reinterpret_cast<char*>(&one), sizeof(int) );
      56                 :            :     m_outFile << std::endl;
      57                 :            :   }
      58                 :            : 
      59                 :            :   // Write end of header: $EndMeshFormat
      60                 :            :   m_outFile << "$EndMeshFormat" << std::endl;
      61 [ -  + ][ -  - ]:          6 :   ErrChk( !m_outFile.bad(), "Failed to write to file: " + m_filename );
         [ -  - ][ -  - ]
         [ -  - ][ -  - ]
      62                 :          6 : }
      63                 :            : 
      64                 :            : void
      65                 :          6 : GmshMeshWriter::writeMesh( const UnsMesh& mesh )
      66                 :            : // *****************************************************************************
      67                 :            : //  Write Gmsh mesh file
      68                 :            : //! \param[in] mesh Unstructured mesh object
      69                 :            : // *****************************************************************************
      70                 :            : {
      71                 :            :   // Write sections
      72                 :          6 :   writeNodes( mesh );
      73                 :          6 :   writeElements( mesh );
      74                 :          6 : }
      75                 :            : 
      76                 :            : void
      77                 :          6 : GmshMeshWriter::writeNodes( const UnsMesh& mesh )
      78                 :            : // *****************************************************************************
      79                 :            : //  Write "$Nodes--$EndNodes" section
      80                 :            : //! \param[in] mesh Unstructured mesh object
      81                 :            : // *****************************************************************************
      82                 :            : {
      83                 :          6 :   m_outFile << "$Nodes" << std::endl;
      84                 :            : 
      85                 :            :   // Write out number of nodes
      86                 :            :   m_outFile << mesh.nnode() << std::endl;
      87                 :            : 
      88                 :            :   // Write node ids and coordinates: node-number x-coord y-coord z-coord
      89         [ +  + ]:          6 :   if (isASCII()) {
      90         [ +  + ]:         15 :     for (std::size_t i=0; i<mesh.nnode(); ++i) {
      91                 :         14 :       m_outFile << i+1 << " " << std::setprecision(16)
      92                 :         14 :                 << mesh.x()[i] << " "
      93                 :         14 :                 << mesh.y()[i] << " "
      94                 :         14 :                 << mesh.z()[i] << std::endl;
      95                 :            :     }
      96                 :            :   } else {
      97         [ +  + ]:      19262 :     for (std::size_t i=0; i<mesh.nnode(); ++i) {
      98                 :            :       // gmsh likes one-based node ids
      99                 :      19257 :       int I = static_cast< int >( i+1 );
     100                 :            :       m_outFile.write(
     101                 :      19257 :         reinterpret_cast<const char*>(&I), sizeof(int) );
     102                 :            :       m_outFile.write(
     103                 :      19257 :         reinterpret_cast<const char*>(&mesh.x()[i]), sizeof(double) );
     104                 :            :       m_outFile.write(
     105                 :      19257 :         reinterpret_cast<const char*>(&mesh.y()[i]), sizeof(double) );
     106                 :            :       m_outFile.write(
     107                 :      19257 :         reinterpret_cast<const char*>(&mesh.z()[i]), sizeof(double) );
     108                 :            :     }
     109                 :            :     m_outFile << std::endl;
     110                 :            :   }
     111                 :            : 
     112                 :            :   m_outFile << "$EndNodes" << std::endl;
     113                 :          6 : }
     114                 :            : 
     115                 :            : void
     116                 :          6 : GmshMeshWriter::writeElements( const UnsMesh& mesh )
     117                 :            : // *****************************************************************************
     118                 :            : //  Write "$Elements--$EndElements" section
     119                 :            : //! \param[in] mesh Unstructured mesh object
     120                 :            : // *****************************************************************************
     121                 :            : {
     122                 :          6 :   m_outFile << "$Elements" << std::endl;
     123                 :            : 
     124                 :            :   // Write out number of elements
     125                 :          6 :   m_outFile << mesh.lininpoel().size()/2 +
     126                 :          6 :                mesh.triinpoel().size()/3 +
     127                 :          6 :                mesh.tetinpoel().size()/4
     128                 :            :             << std::endl;
     129                 :            : 
     130                 :            :   // Write out line element ids and connectivity (node list)
     131                 :          6 :   writeElemBlock( 2, GmshElemType::LIN, mesh.lininpoel() );
     132                 :            : 
     133                 :            :   // Write out triangle element ids and connectivity (node list)
     134                 :          6 :   writeElemBlock( 3, GmshElemType::TRI, mesh.triinpoel() );
     135                 :            : 
     136                 :            :   // Write out terahedron element ids and connectivity (node list)
     137                 :          6 :   writeElemBlock( 4, GmshElemType::TET, mesh.tetinpoel() );
     138                 :            : 
     139         [ +  + ]:          6 :   if (isBinary()) m_outFile << std::endl;
     140                 :            :   m_outFile << "$EndElements" << std::endl;
     141                 :          6 : }
     142                 :            : 
     143                 :            : void
     144         [ +  + ]:         18 : GmshMeshWriter::writeElemBlock( std::size_t nnpe,
     145                 :            :                                 GmshElemType type,
     146                 :            :                                 const std::vector< std::size_t >& inpoel )
     147                 :            : // *****************************************************************************
     148                 :            : //  Write element block: element ids and connectivity (node list)
     149                 :            : //! \param[in] nnpe Number of nodes per element
     150                 :            : //! \param[in] type Element type
     151                 :            : //! \param[in] inpoel Element connectivity (must be zero-based)
     152                 :            : // *****************************************************************************
     153                 :            : {
     154                 :            :   // Return if connectivity is empty, there is no such element block in mesh
     155         [ +  + ]:         18 :   if (inpoel.empty()) return;
     156                 :            : 
     157                 :            :   // Make sure element connectivity starts with zero
     158                 :            :   Assert( *std::minmax_element( begin(inpoel), end(inpoel) ).first == 0,
     159                 :            :           "node ids should start from zero" );
     160                 :            : 
     161                 :            :   // Get number of elements in mesh
     162         [ +  - ]:         10 :   auto n = inpoel.size()/nnpe;
     163                 :            : 
     164                 :            :   // Ignore element tags
     165                 :         10 :   std::vector< std::vector< int > > tg;
     166         [ +  - ]:         10 :   tg.resize( n );
     167 [ +  + ][ +  - ]:     109390 :   for (auto& t : tg) t.push_back( 0 );
     168                 :            : 
     169         [ +  + ]:         10 :   if (isASCII()) {
     170                 :            : 
     171         [ +  + ]:         25 :     for (std::size_t i=0; i<n; i++) {
     172                 :            :       // elm-number elm-type number-of-tags < tag > ... node-number-list
     173 [ +  - ][ +  - ]:         72 :       m_outFile << i+1 << " " << type << " " << tg[i].size() << " ";
         [ +  - ][ +  - ]
     174         [ +  - ]:         24 :       copy( tg[i].begin(), tg[i].end()-1,
     175                 :            :             std::ostream_iterator< int >( m_outFile, " " ) );
     176 [ +  - ][ +  - ]:         24 :       m_outFile << tg[i].back() << " ";
     177                 :            : 
     178                 :            :       // gmsh likes one-based node ids
     179 [ +  + ][ +  - ]:        120 :       for (std::size_t k=0; k<nnpe; k++) m_outFile << inpoel[i*nnpe+k]+1 << " ";
                 [ +  - ]
     180                 :            :       m_outFile << std::endl;
     181                 :            :     }
     182                 :            : 
     183                 :            :   } else {
     184                 :            : 
     185         [ +  - ]:          9 :     int ntags = static_cast< int >( tg[0].size() );
     186                 :          9 :     int nel = static_cast< int >( n );
     187                 :            :     // elm-type num-of-elm-follow number-of-tags
     188         [ +  - ]:          9 :     m_outFile.write( reinterpret_cast<char*>(&type), sizeof(int) );
     189         [ +  - ]:          9 :     m_outFile.write( reinterpret_cast<char*>(&nel), sizeof(int) );
     190         [ +  - ]:          9 :     m_outFile.write( reinterpret_cast<char*>(&ntags), sizeof(int) );
     191         [ +  + ]:     109365 :     for (std::size_t i=0; i<n; i++) {
     192                 :     109356 :       int I = static_cast< int >( i );
     193                 :            :       // gmsh likes one-based node ids
     194                 :            :       std::vector< int > Inpoel;
     195         [ +  + ]:     536652 :       for (std::size_t k=0; k<nnpe; ++k)
     196 [ +  - ][ -  - ]:     427296 :          Inpoel.push_back( static_cast< int >( inpoel[i*nnpe+k]+1 ) );
     197                 :            :       // element id
     198         [ +  - ]:     109356 :       m_outFile.write( reinterpret_cast<const char*>(&I), sizeof(int) );
     199                 :            :       // element tags
     200                 :            :       m_outFile.write( reinterpret_cast<const char*>(tg[i].data()),
     201         [ +  - ]:     109356 :                        static_cast<std::streamsize>(tg[i].size()*sizeof(int)) );
     202                 :            :       // element node list (i.e. connectivity)
     203                 :     109356 :       m_outFile.write( reinterpret_cast<const char*>(Inpoel.data()),
     204         [ +  - ]:     109356 :                        static_cast<std::streamsize>(nnpe*sizeof(int)) );
     205                 :            :     }
     206                 :            : 
     207                 :            :   }
     208                 :            : }

Generated by: LCOV version 1.14