1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 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_GMSH_IO_H
21 #define LIBMESH_GMSH_IO_H
22 
23 // Local includes
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/mesh_input.h"
26 #include "libmesh/mesh_output.h"
27 
28 // C++ includes
29 #include <cstddef>
30 
31 namespace libMesh
32 {
33 
34 // Forward declarations
35 class MeshBase;
36 
37 
38 
39 /**
40  * \brief Reading and writing meshes in the Gmsh format.
41  *
42  * For a full description of the Gmsh format and to obtain the
43  * GMSH software see
44  * <a href="http://http://www.geuz.org/gmsh/">the Gmsh home page</a>
45  *
46  * \author John W. Peterson
47  * \date 2004, 2014
48  * \author Martin Luthi
49  * \date 2005
50  */
51 class GmshIO : public MeshInput<MeshBase>,
52                public MeshOutput<MeshBase>
53 {
54 public:
55 
56   /**
57    * Constructor.  Takes a non-const Mesh reference which it
58    * will fill up with elements via the read() command.
59    */
60   explicit
61   GmshIO (MeshBase & mesh);
62 
63   /**
64    * Constructor.  Takes a reference to a constant mesh object.
65    * This constructor will only allow us to write the mesh.
66    */
67   explicit
68   GmshIO (const MeshBase & mesh);
69 
70   /**
71    * Reads in a mesh in the Gmsh *.msh format from the ASCII file
72    * given by name.
73    *
74    * \note The user is responsible for calling Mesh::prepare_for_use()
75    * after reading the mesh and before using it.
76    *
77    * The physical group names defined in the Gmsh-file are stored, depending
78    * on the element dimension, as either subdomain name or as side name. The
79    * IDs of the former can be retrieved by using the MeshBase::get_id_by_name
80    * method; the IDs of the latter can be retrieved by using the
81    * MeshBase::get_boundary_info and the BoundaryInfo::get_id_by_name methods.
82    */
83   virtual void read (const std::string & name) override;
84 
85   /**
86    * This method implements writing a mesh to a specified file
87    * in the Gmsh *.msh format.
88    */
89   virtual void write (const std::string & name) override;
90 
91   /**
92    * Bring in base class functionality for name resolution and to
93    * avoid warnings about hidden overloaded virtual functions.
94    */
95   using MeshOutput<MeshBase>::write_nodal_data;
96 
97   /**
98    * This method implements writing a mesh with nodal data to a
99    * specified file where the nodal data and variable names are provided.
100    */
101   virtual void write_nodal_data (const std::string &,
102                                  const std::vector<Number> &,
103                                  const std::vector<std::string> &) override;
104 
105   /**
106    * Flag indicating whether or not to write a binary file.  While binary
107    * files may end up being smaller than equivalent ASCII files, they will
108    * almost certainly take longer to write.  The reason for this is that
109    * the ostream::write() function which is used to write "binary" data to
110    * streams, only takes a pointer to char as its first argument.  This means
111    * if you want to write anything other than a buffer of chars, you first
112    * have to use a strange memcpy hack to get the data into the desired format.
113    * See the templated to_binary_stream() function below.
114    */
115   bool & binary ();
116 
117   /**
118    * Access to the flag which controls whether boundary elements are
119    * written to the Mesh file.
120    */
121   bool & write_lower_dimensional_elements ();
122 
123 private:
124   /**
125    * Implementation of the read() function.  This function
126    * is called by the public interface function and implements
127    * reading the file.
128    */
129   void read_mesh (std::istream & in);
130 
131   /**
132    * This method implements writing a mesh to a
133    * specified file.  This will write an ASCII *.msh file.
134    */
135   void write_mesh (std::ostream & out);
136 
137   /**
138    * This method implements writing a mesh with nodal data to a specified file
139    * where the nodal data and variable names are optionally provided.  This
140    * will write an ASCII or binary *.pos file, depending on the binary flag.
141    */
142   void write_post (const std::string &,
143                    const std::vector<Number> * = nullptr,
144                    const std::vector<std::string> * = nullptr);
145 
146   /**
147    * Flag to write binary data.
148    */
149   bool _binary;
150 
151   /**
152    * If true, lower-dimensional elements based on the boundary
153    * conditions get written to the output file.
154    */
155   bool _write_lower_dimensional_elements;
156 
157   /**
158    * Defines mapping from libMesh element types to Gmsh element types or vice-versa.
159    */
160   struct ElementDefinition
161   {
ElementDefinitionElementDefinition162     ElementDefinition(ElemType type_in,
163                       unsigned gmsh_type_in,
164                       unsigned dim_in,
165                       unsigned nnodes_in) :
166       type(type_in),
167       gmsh_type(gmsh_type_in),
168       dim(dim_in),
169       nnodes(nnodes_in)
170     {}
171 
172     ElemType type;
173     unsigned int gmsh_type;
174     unsigned int dim;
175     unsigned int nnodes;
176     std::vector<unsigned int> nodes;
177   };
178 
179   /**
180    * struct which holds a map from Gmsh to libMesh element numberings
181    * and vice-versa.
182    */
183   struct ElementMaps
184   {
185     // Helper function to add a (key, value) pair to both maps
add_defElementMaps186     void add_def(const ElementDefinition & eledef)
187     {
188       out.emplace(eledef.type, eledef);
189       in.emplace(eledef.gmsh_type, eledef);
190     }
191 
192     std::map<ElemType, ElementDefinition> out;
193     std::map<unsigned int, ElementDefinition> in;
194   };
195 
196   /**
197    * A static ElementMaps object that is built statically and used by
198    * all instances of this class.
199    */
200   static ElementMaps _element_maps;
201 
202   /**
203    * A static function used to construct the _element_maps struct,
204    * statically.
205    */
206   static ElementMaps build_element_maps();
207 };
208 
209 
210 } // namespace libMesh
211 
212 #endif // LIBMESH_GMSH_IO_H
213