LCOV - code coverage report
Current view: top level - include/mesh - xdr_io.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 18 20 90.0 %
Date: 2025-08-19 19:27:09 Functions: 13 14 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : #ifndef LIBMESH_XDR_IO_H
      21             : #define LIBMESH_XDR_IO_H
      22             : 
      23             : 
      24             : // Local includes
      25             : #include "libmesh/libmesh.h"
      26             : #include "libmesh/mesh_input.h"
      27             : #include "libmesh/mesh_output.h"
      28             : #include "libmesh/parallel_object.h"
      29             : 
      30             : // C++ includes
      31             : #include <string>
      32             : #include <vector>
      33             : 
      34             : namespace libMesh
      35             : {
      36             : 
      37             : // Forward declarations
      38             : class Xdr;
      39             : class Elem;
      40             : 
      41             : /**
      42             :  * MeshIO class used for writing XDR (eXternal Data Representation)
      43             :  * and XDA mesh files.  XDR/XDA is libmesh's internal data format, and
      44             :  * allows the full refinement tree structure of the mesh to be written
      45             :  * to file.
      46             :  *
      47             :  * \author Benjamin Kirk
      48             :  * \author John Peterson
      49             :  * \date 2004
      50             :  */
      51         312 : class XdrIO : public MeshInput<MeshBase>,
      52             :               public MeshOutput<MeshBase>,
      53             :               public ParallelObject
      54             : {
      55             : public:
      56             :   // The size used for encoding all id types in this file
      57             :   typedef largest_id_type xdr_id_type;
      58             : 
      59             :   // The size type used to read pre-1.3.0 header sizes (meta data information)
      60             :   typedef uint32_t old_header_id_type;
      61             : 
      62             :   // Likewise, but for 1.3.0 and newer header files
      63             :   typedef uint64_t new_header_id_type;
      64             : 
      65             :   /**
      66             :    * Constructor.  Takes a writable reference to a mesh object.
      67             :    * This is the constructor required to read a mesh.
      68             :    * The optional parameter \p binary can be used to switch
      69             :    * between ASCII (\p false, the default) or binary (\p true)
      70             :    * files.
      71             :    */
      72             :   explicit
      73             :   XdrIO (MeshBase &, const bool=false);
      74             : 
      75             :   /**
      76             :    * Constructor.  Takes a reference to a constant mesh object.
      77             :    * This constructor will only allow us to write the mesh.
      78             :    * The optional parameter \p binary can be used to switch
      79             :    * between ASCII (\p false, the default) or binary (\p true)
      80             :    * files.
      81             :    */
      82             :   explicit
      83             :   XdrIO (const MeshBase &, const bool=false);
      84             : 
      85             :   /**
      86             :    * Destructor.
      87             :    */
      88             :   virtual ~XdrIO ();
      89             : 
      90             :   /**
      91             :    * This method implements reading a mesh from a specified file.
      92             :    */
      93             :   virtual void read (const std::string &) override;
      94             : 
      95             :   /**
      96             :    * This method implements writing a mesh to a specified file.
      97             :    */
      98             :   virtual void write (const std::string &) override;
      99             : 
     100             :   /**
     101             :    * Get/Set the flag indicating if we should read/write binary.
     102             :    */
     103             :   bool   binary() const { return _binary; }
     104         270 :   bool & binary()       { return _binary; }
     105             : 
     106             :   /**
     107             :    * Get/Set the flag indicating if we should read/write legacy.
     108             :    */
     109             :   bool   legacy() const { return _legacy; }
     110         384 :   bool & legacy()       { return _legacy; }
     111             : 
     112             :   /**
     113             :    * Report whether we should write parallel files.
     114             :    */
     115             :   bool write_parallel() const;
     116             : 
     117             :   /**
     118             :    * Insist that we should/shouldn't write parallel files.
     119             :    */
     120             :   void set_write_parallel      (bool do_parallel = true);
     121             : 
     122             :   /**
     123             :    * Insist that we should write parallel files if and only if the
     124             :    * mesh is an already distributed DistributedMesh.
     125             :    */
     126             :   void set_auto_parallel ();
     127             : 
     128             :   /**
     129             :    * Get/Set the version string.  Valid version strings:
     130             :    *
     131             :    * \verbatim
     132             :    * "libMesh-0.7.0+"
     133             :    * "libMesh-0.7.0+ parallel"
     134             :    * \endverbatim
     135             :    *
     136             :    * If "libMesh" is not detected in the version string the
     137             :    * \p LegacyXdrIO class will be used to read older
     138             :    * (pre version 0.7.0) mesh files.
     139             :    */
     140       62122 :   const std::string & version () const { return _version; }
     141        4586 :   std::string &       version ()       { return _version; }
     142             : 
     143             :   /**
     144             :    * Get/Set the boundary condition file name.
     145             :    */
     146             :   const std::string & boundary_condition_file_name() const { return _bc_file_name; }
     147       15204 :   std::string &       boundary_condition_file_name()       { return _bc_file_name; }
     148             : 
     149             :   /**
     150             :    * Get/Set the partitioning file name.
     151             :    */
     152        1425 :   const std::string & partition_map_file_name() const { return _partition_map_file; }
     153        7891 :   std::string &       partition_map_file_name()       { return _partition_map_file; }
     154             : 
     155             :   /**
     156             :    * Get/Set the subdomain file name.
     157             :    */
     158        1425 :   const std::string & subdomain_map_file_name() const { return _subdomain_map_file; }
     159        9358 :   std::string &       subdomain_map_file_name()       { return _subdomain_map_file; }
     160             : 
     161             :   /**
     162             :    * Get/Set the polynomial degree file name.
     163             :    */
     164        1425 :   const std::string & polynomial_level_file_name() const { return _p_level_file; }
     165        7891 :   std::string &       polynomial_level_file_name()       { return _p_level_file; }
     166             : 
     167             :   /**
     168             :    * \returns \p true if the current file has an XDR/XDA version that
     169             :    * matches or exceeds 0.9.2.
     170             :    *
     171             :    * As of this version we encode integer field widths, nodesets,
     172             :    * subdomain names, boundary names, and element unique_id values (if
     173             :    * they exist) into our files.
     174             :    */
     175             :   bool version_at_least_0_9_2() const;
     176             : 
     177             :   /**
     178             :    * \returns \p true if the current file has an XDR/XDA version that
     179             :    * matches or exceeds 0.9.6.
     180             :    *
     181             :    * In this version we add node unique_id values to our files, if
     182             :    * they exist.
     183             :    */
     184             :   bool version_at_least_0_9_6() const;
     185             : 
     186             :   /**
     187             :    * \returns \p true if the current file has an XDR/XDA version that
     188             :    * matches or exceeds 1.1.0.
     189             :    *
     190             :    * In this version we add edge and shellface boundary conditions to
     191             :    * our files.
     192             :    */
     193             :   bool version_at_least_1_1_0() const;
     194             : 
     195             :   /**
     196             :    * \returns \p true if the current file has an XDR/XDA version that
     197             :    * matches or exceeds 1.3.0.
     198             :    *
     199             :    * In this version we fix handling of uint64_t binary values on
     200             :    * Linux, which were previously miswritten as 32 bit via xdr_long.
     201             :    */
     202             :   bool version_at_least_1_3_0() const;
     203             : 
     204             :   /**
     205             :    * \returns \p true if the current file has an XDR/XDA version that
     206             :    * matches or exceeds 1.8.0.
     207             :    *
     208             :    * In this version we added support for writing the Mesh's "extra"
     209             :    * integer fields to the file.
     210             :    */
     211             :   bool version_at_least_1_8_0() const;
     212             : 
     213             : private:
     214             : 
     215             : 
     216             :   //---------------------------------------------------------------------------
     217             :   // Write Implementation
     218             :   /**
     219             :    * Write subdomain name information - NEW in 0.9.2 format
     220             :    */
     221             :   void write_serialized_subdomain_names(Xdr & io) const;
     222             : 
     223             :   /**
     224             :    * Write the connectivity for a parallel, distributed mesh
     225             :    */
     226             :   void write_serialized_connectivity (Xdr & io, const dof_id_type n_elem,
     227             :                                       const new_header_id_type n_elem_integers) const;
     228             : 
     229             :   /**
     230             :    * Write the nodal locations for a parallel, distributed mesh
     231             :    */
     232             :   void write_serialized_nodes (Xdr & io, const dof_id_type n_nodes,
     233             :                                const new_header_id_type n_node_integers) const;
     234             : 
     235             :   /**
     236             :    * Helper function used in write_serialized_side_bcs, write_serialized_edge_bcs, and
     237             :    * write_serialized_shellface_bcs.
     238             :    */
     239             :   void write_serialized_bcs_helper (Xdr & io, const new_header_id_type n_side_bcs, const std::string bc_type) const;
     240             : 
     241             :   /**
     242             :    * Write the side boundary conditions for a parallel, distributed mesh
     243             :    */
     244             :   void write_serialized_side_bcs (Xdr & io, const new_header_id_type n_side_bcs) const;
     245             : 
     246             :   /**
     247             :    * Write the edge boundary conditions for a parallel, distributed mesh.
     248             :    * NEW in 1.1.0 format.
     249             :    */
     250             :   void write_serialized_edge_bcs (Xdr & io, const new_header_id_type n_edge_bcs) const;
     251             : 
     252             :   /**
     253             :    * Write the "shell face" boundary conditions for a parallel, distributed mesh.
     254             :    * NEW in 1.1.0 format.
     255             :    */
     256             :   void write_serialized_shellface_bcs (Xdr & io, const new_header_id_type n_shellface_bcs) const;
     257             : 
     258             :   /**
     259             :    * Write the boundary conditions for a parallel, distributed mesh
     260             :    */
     261             :   void write_serialized_nodesets (Xdr & io, const new_header_id_type n_nodesets) const;
     262             : 
     263             :   /**
     264             :    * Write boundary names information (sideset and nodeset) - NEW in 0.9.2 format
     265             :    */
     266             :   void write_serialized_bc_names (Xdr & io, const BoundaryInfo & info, bool is_sideset) const;
     267             : 
     268             : 
     269             :   //---------------------------------------------------------------------------
     270             :   // Read Implementation
     271             :   //
     272             :   // In the function templates below, the "T type_size" argument is only
     273             :   // used for template argument deduction purposes. The value of this
     274             :   // parameter can be arbitrary because it will not be used within the
     275             :   // function.
     276             : 
     277             :   /**
     278             :    * Read header information - templated to handle old (4-byte) or new
     279             :    * (8-byte) header id types.
     280             :    */
     281             :   template <typename T>
     282             :   void read_header(Xdr & io, std::vector<T> & meta_data);
     283             : 
     284             :   /**
     285             :    * Read subdomain name information - NEW in 0.9.2 format
     286             :    */
     287             :   void read_serialized_subdomain_names(Xdr & io);
     288             : 
     289             :   /**
     290             :    * Read the connectivity for a parallel, distributed mesh.
     291             :    */
     292             :   template <typename T>
     293             :   void read_serialized_connectivity (Xdr & io,
     294             :                                      const dof_id_type n_elem,
     295             :                                      const std::vector<new_header_id_type> & meta_data,
     296             :                                      T type_size);
     297             : 
     298             :   /**
     299             :    * Read the nodal locations for a parallel, distributed mesh
     300             :    */
     301             :   void read_serialized_nodes (Xdr & io, const dof_id_type n_nodes,
     302             :                               const std::vector<new_header_id_type> & meta_data);
     303             : 
     304             :   /**
     305             :    * Helper function used in read_serialized_side_bcs, read_serialized_edge_bcs, and
     306             :    * read_serialized_shellface_bcs.
     307             :    */
     308             :   template <typename T>
     309             :   void read_serialized_bcs_helper (Xdr & io, T type_size, const std::string bc_type);
     310             : 
     311             :   /**
     312             :    * Read the side boundary conditions for a parallel, distributed mesh
     313             :    * \returns The number of bcs read
     314             :    */
     315             :   template <typename T>
     316             :   void read_serialized_side_bcs (Xdr & io, T type_size);
     317             : 
     318             :   /**
     319             :    * Read the edge boundary conditions for a parallel, distributed mesh.
     320             :    * NEW in 1.1.0 format.
     321             :    * \returns The number of bcs read
     322             :    */
     323             :   template <typename T>
     324             :   void read_serialized_edge_bcs (Xdr & io, T type_size);
     325             : 
     326             :   /**
     327             :    * Read the "shell face" boundary conditions for a parallel, distributed mesh.
     328             :    * NEW in 1.1.0 format.
     329             :    * \returns The number of bcs read
     330             :    */
     331             :   template <typename T>
     332             :   void read_serialized_shellface_bcs (Xdr & io, T type_size);
     333             : 
     334             :   /**
     335             :    * Read the nodeset conditions for a parallel, distributed mesh
     336             :    * \returns The number of nodesets read
     337             :    */
     338             :   template <typename T>
     339             :   void read_serialized_nodesets (Xdr & io, T type_size);
     340             : 
     341             :   /**
     342             :    * Read boundary names information (sideset and nodeset) - NEW in 0.9.2 format
     343             :    */
     344             :   void read_serialized_bc_names(Xdr & io, BoundaryInfo & info, bool is_sideset);
     345             : 
     346             :   //-------------------------------------------------------------------------
     347             :   /**
     348             :    * Pack an element into a transfer buffer for parallel communication.
     349             :    */
     350             :   void pack_element (std::vector<xdr_id_type> & conn,
     351             :                      const Elem * elem,
     352             :                      const dof_id_type parent_id,
     353             :                      const dof_id_type parent_pid,
     354             :                      const new_header_id_type n_elem_integers) const;
     355             : 
     356             :   bool _binary;
     357             :   bool _legacy;
     358             :   bool _write_serial;
     359             :   bool _write_parallel;
     360             :   bool _write_unique_id;
     361             :   unsigned int _field_width;
     362             :   std::string _version;
     363             :   std::string _bc_file_name;
     364             :   std::string _partition_map_file;
     365             :   std::string _subdomain_map_file;
     366             :   std::string _p_level_file;
     367             : 
     368             :   /**
     369             :    * Define the block size to use for chunked IO.
     370             :    */
     371             :   static const std::size_t io_blksize;
     372             : };
     373             : 
     374             : 
     375             : // ------------------------------------------------------------
     376             : // XdrIO inline members
     377             : 
     378             : inline
     379        1383 : bool XdrIO::write_parallel() const
     380             : {
     381             :   // We can't insist on both serial and parallel
     382          42 :   libmesh_assert (!this->_write_serial || !this->_write_parallel);
     383             : 
     384             :   // If we insisted on serial, do that
     385        1425 :   if (this->_write_serial)
     386           0 :     return false;
     387             : 
     388             :   // If we insisted on parallel, do that
     389        1425 :   if (this->_write_parallel)
     390           0 :     return true;
     391             : 
     392             :   // If we're doing things automatically, check the mesh
     393          84 :   const MeshBase & mesh = MeshOutput<MeshBase>::mesh();
     394        1425 :   return !mesh.is_serial();
     395             : }
     396             : 
     397             : 
     398             : 
     399             : inline
     400             : void XdrIO::set_write_parallel (bool do_parallel)
     401             : {
     402             :   this->_write_parallel = do_parallel;
     403             : 
     404             :   this->_write_serial = !do_parallel;
     405             : }
     406             : 
     407             : 
     408             : 
     409             : inline
     410             : void XdrIO::set_auto_parallel ()
     411             : {
     412             :   this->_write_serial   = false;
     413             :   this->_write_parallel = false;
     414             : }
     415             : 
     416             : 
     417             : } // namespace libMesh
     418             : 
     419             : 
     420             : 
     421             : #endif // LIBMESH_XDR_IO_H

Generated by: LCOV version 1.14