namebased_io.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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 // C++ includes
20 #include <iomanip>
21 #include <fstream>
22 #include <vector>
23 
24 #include <sys/types.h> // getpid
25 #include <unistd.h>
26 
27 // Local includes
29 #include "libmesh/mesh_base.h"
31 #include "libmesh/namebased_io.h"
32 #include "libmesh/exodusII_io.h"
33 #include "libmesh/gmv_io.h"
34 #include "libmesh/tecplot_io.h"
35 #include "libmesh/tetgen_io.h"
36 #include "libmesh/ucd_io.h"
37 #include "libmesh/unv_io.h"
38 #include "libmesh/matlab_io.h"
39 #include "libmesh/off_io.h"
40 #include "libmesh/medit_io.h"
41 #include "libmesh/nemesis_io.h"
42 #include "libmesh/gmsh_io.h"
43 #include "libmesh/fro_io.h"
44 #include "libmesh/xdr_io.h"
45 #include "libmesh/vtk_io.h"
46 #include "libmesh/abaqus_io.h"
47 #include "libmesh/checkpoint_io.h"
49 #include "libmesh/enum_xdr_mode.h"
50 
51 
52 namespace libMesh
53 {
54 
55 
56 
57 // ------------------------------------------------------------
58 // NameBasedIO members
59 void NameBasedIO::read (const std::string & name)
60 {
62 
63  // See if the file exists. Perform this check on all processors
64  // so that the code is terminated properly in the case that the
65  // file does not exist.
66 
67  // For Nemesis files, the name we try to read will have suffixes
68  // identifying processor rank
69  if (name.rfind(".nem") + 4 == name.size() ||
70  name.rfind(".n") + 2 == name.size())
71  {
72  std::ostringstream full_name;
73 
74  // Find the length of a string which represents the highest processor ID
75  full_name << (mymesh.n_processors());
76  int field_width = cast_int<int>(full_name.str().size());
77 
78  // reset the string stream
79  full_name.str("");
80 
81  // And build up the full filename
82  full_name << name
83  << '.' << mymesh.n_processors()
84  << '.' << std::setfill('0') << std::setw(field_width) << mymesh.processor_id();
85 
86  std::ifstream in (full_name.str().c_str());
87 
88  if (!in.good())
89  libmesh_error_msg("ERROR: cannot locate specified file:\n\t" << full_name.str());
90  }
91  else if (name.rfind(".cp")) {} // Do error checking in the reader
92  else
93  {
94  std::ifstream in (name.c_str());
95 
96  if (!in.good())
97  libmesh_error_msg("ERROR: cannot locate specified file:\n\t" << name);
98  }
99 
100  // Look for parallel formats first
102  {
103  // no need to handle bz2 files here -- the Xdr class does that.
104  if ((name.rfind(".xda") < name.size()) ||
105  (name.rfind(".xdr") < name.size()))
106  {
107  XdrIO xdr_io(mymesh);
108 
109  // .xda* ==> bzip2/gzip/ASCII flavors
110  if (name.rfind(".xda") < name.size())
111  {
112  xdr_io.binary() = false;
113  xdr_io.read (name);
114  }
115  else // .xdr* ==> true binary XDR file
116  {
117  xdr_io.binary() = true;
118  xdr_io.read (name);
119  }
120 
121  // The xdr_io object gets constructed with legacy() == false.
122  // if legacy() == true then it means that a legacy file was detected and
123  // thus processor 0 performed the read. We therefore need to broadcast the
124  // mesh. Further, for this flavor of mesh solution data ordering is tied
125  // to the node ordering, so we better not reorder the nodes!
126  if (xdr_io.legacy())
127  {
128  mymesh.allow_renumbering(false);
129  MeshCommunication().broadcast(mymesh);
130  }
131 
132  // libHilbert-enabled libMesh builds should construct files
133  // with a canonical node ordering, which libHilbert-enabled
134  // builds will be able to read in again regardless of any
135  // renumbering. So in that case we're free to renumber.
136  // However, if either the writer or the reader of this file
137  // don't have libHilbert, then we'll have to skip
138  // renumbering because we need the numbering to remain
139  // consistent with any solution file we read in next.
140 #ifdef LIBMESH_HAVE_LIBHILBERT
141  // if (!xdr_io.libhilbert_ordering())
142  // skip_renumber_nodes_and_elements = true;
143 #else
144  mymesh.allow_renumbering(false);
145 #endif
146  }
147  else if (name.rfind(".nem") < name.size() ||
148  name.rfind(".n") < name.size())
149  Nemesis_IO(mymesh).read (name);
150  else if (name.rfind(".cp") < name.size())
151  {
152  if (name.rfind(".cpa") < name.size())
153  CheckpointIO(mymesh, false).read(name);
154  else
155  CheckpointIO(mymesh, true).read(name);
156  }
157  }
158 
159  // Serial mesh formats
160  else
161  {
162  // Read the file based on extension. Only processor 0
163  // needs to read the mesh. It will then broadcast it and
164  // the other processors will pick it up
165  if (mymesh.processor_id() == 0)
166  {
167  LOG_SCOPE("read()", "NameBasedIO");
168 
169  std::ostringstream pid_suffix;
170  pid_suffix << '_' << getpid();
171  // Nasty hack for reading/writing zipped files
172  std::string new_name = name;
173  if (name.size() - name.rfind(".bz2") == 4)
174  {
175 #ifdef LIBMESH_HAVE_BZIP
176  new_name.erase(new_name.end() - 4, new_name.end());
177  new_name += pid_suffix.str();
178  std::string system_string = "bunzip2 -f -k -c ";
179  system_string += name + " > " + new_name;
180  LOG_SCOPE("system(bunzip2)", "NameBasedIO");
181  if (std::system(system_string.c_str()))
182  libmesh_file_error(system_string);
183 #else
184  libmesh_error_msg("ERROR: need bzip2/bunzip2 to open .bz2 file " << name);
185 #endif
186  }
187  else if (name.size() - name.rfind(".xz") == 3)
188  {
189 #ifdef LIBMESH_HAVE_XZ
190  new_name.erase(new_name.end() - 3, new_name.end());
191  new_name += pid_suffix.str();
192  std::string system_string = "xz -f -d -k -c ";
193  system_string += name + " > " + new_name;
194  LOG_SCOPE("system(xz -d)", "XdrIO");
195  if (std::system(system_string.c_str()))
196  libmesh_file_error(system_string);
197 #else
198  libmesh_error_msg("ERROR: need xz to open .xz file " << name);
199 #endif
200  }
201 
202  if (new_name.rfind(".mat") < new_name.size())
203  MatlabIO(mymesh).read(new_name);
204 
205  else if (new_name.rfind(".ucd") < new_name.size())
206  UCDIO(mymesh).read (new_name);
207 
208  else if ((new_name.rfind(".off") < new_name.size()) ||
209  (new_name.rfind(".ogl") < new_name.size()) ||
210  (new_name.rfind(".oogl") < new_name.size()))
211  OFFIO(mymesh).read (new_name);
212 
213  else if (new_name.rfind(".unv") < new_name.size())
214  UNVIO(mymesh).read (new_name);
215 
216  else if ((new_name.rfind(".node") < new_name.size()) ||
217  (new_name.rfind(".ele") < new_name.size()))
218  TetGenIO(mymesh).read (new_name);
219 
220  else if (new_name.rfind(".exd") < new_name.size() ||
221  new_name.rfind(".e") < new_name.size())
222  ExodusII_IO(mymesh).read (new_name);
223 
224  else if (new_name.rfind(".msh") < new_name.size())
225  GmshIO(mymesh).read (new_name);
226 
227  else if (new_name.rfind(".gmv") < new_name.size())
228  GMVIO(mymesh).read (new_name);
229 
230  else if (new_name.rfind(".vtu") < new_name.size())
231  VTKIO(mymesh).read(new_name);
232 
233  else if (new_name.rfind(".inp") < new_name.size())
234  AbaqusIO(mymesh).read(new_name);
235 
236  else
237  {
238  libmesh_error_msg(" ERROR: Unrecognized file extension: " \
239  << name \
240  << "\n I understand the following:\n\n" \
241  << " *.e -- Sandia's ExodusII format\n" \
242  << " *.exd -- Sandia's ExodusII format\n" \
243  << " *.gmv -- LANL's General Mesh Viewer format\n" \
244  << " *.mat -- Matlab triangular ASCII file\n" \
245  << " *.n -- Sandia's Nemesis format\n" \
246  << " *.nem -- Sandia's Nemesis format\n" \
247  << " *.off -- OOGL OFF surface format\n" \
248  << " *.ucd -- AVS's ASCII UCD format\n" \
249  << " *.unv -- I-deas Universal format\n" \
250  << " *.vtu -- Paraview VTK format\n" \
251  << " *.inp -- Abaqus .inp format\n" \
252  << " *.xda -- libMesh ASCII format\n" \
253  << " *.xdr -- libMesh binary format\n" \
254  << " *.gz -- any above format gzipped\n" \
255  << " *.bz2 -- any above format bzip2'ed\n" \
256  << " *.xz -- any above format xzipped\n" \
257  << " *.cpa -- libMesh Checkpoint ASCII format\n" \
258  << " *.cpr -- libMesh Checkpoint binary format\n");
259  }
260 
261  // If we temporarily decompressed a file, remove the
262  // uncompressed version
263  if (name.size() - name.rfind(".bz2") == 4)
264  std::remove(new_name.c_str());
265  if (name.size() - name.rfind(".xz") == 3)
266  std::remove(new_name.c_str());
267  }
268 
269  // Send the mesh & bcs (which are now only on processor 0) to the other
270  // processors
271  MeshCommunication().broadcast (mymesh);
272  }
273 }
274 
275 
276 void NameBasedIO::write (const std::string & name)
277 {
278  MeshBase & mymesh = MeshInput<MeshBase>::mesh();
279 
280  // parallel formats are special -- they may choose to write
281  // separate files, let's not try to handle the zipping here.
283  {
284  // no need to handle bz2 files here -- the Xdr class does that.
285  if (name.rfind(".xda") < name.size())
286  XdrIO(mymesh).write(name);
287 
288  else if (name.rfind(".xdr") < name.size())
289  XdrIO(mymesh,true).write(name);
290 
291  else if (name.rfind(".nem") < name.size() ||
292  name.rfind(".n") < name.size())
293  Nemesis_IO(mymesh).write(name);
294  }
295 
296  // serial file formats
297  else
298  {
299  // Nasty hack for reading/writing zipped files
300  std::string new_name = name;
301  pid_t pid_0 = 0;
302  if (mymesh.processor_id() == 0)
303  pid_0 = getpid();
304  mymesh.comm().broadcast(pid_0);
305  std::ostringstream pid_suffix;
306  pid_suffix << '_' << pid_0;
307 
308  if (name.size() - name.rfind(".bz2") == 4)
309  {
310  new_name.erase(new_name.end() - 4, new_name.end());
311  new_name += pid_suffix.str();
312  }
313  else if (name.size() - name.rfind(".xz") == 3)
314  {
315  new_name.erase(new_name.end() - 3, new_name.end());
316  new_name += pid_suffix.str();
317  }
318 
319  // New scope so that io will close before we try to zip the file
320  {
321  // Write the file based on extension
322  if (new_name.rfind(".dat") < new_name.size())
323  TecplotIO(mymesh).write (new_name);
324 
325  else if (new_name.rfind(".plt") < new_name.size())
326  TecplotIO(mymesh,true).write (new_name);
327 
328  else if (new_name.rfind(".ucd") < new_name.size())
329  UCDIO (mymesh).write (new_name);
330 
331  else if (new_name.rfind(".gmv") < new_name.size())
332  if (mymesh.n_partitions() > 1)
333  GMVIO(mymesh).write (new_name);
334  else
335  {
336  GMVIO io(mymesh);
337  io.partitioning() = false;
338  io.write (new_name);
339  }
340 
341  else if (new_name.rfind(".e") < new_name.size())
342  ExodusII_IO(mymesh).write(new_name);
343 
344  else if (new_name.rfind(".unv") < new_name.size())
345  UNVIO(mymesh).write (new_name);
346 
347  else if (new_name.rfind(".mesh") < new_name.size())
348  MEDITIO(mymesh).write (new_name);
349 
350  else if (new_name.rfind(".poly") < new_name.size())
351  TetGenIO(mymesh).write (new_name);
352 
353  else if (new_name.rfind(".msh") < new_name.size())
354  GmshIO(mymesh).write (new_name);
355 
356  else if (new_name.rfind(".fro") < new_name.size())
357  FroIO(mymesh).write (new_name);
358 
359  else if (new_name.rfind(".vtu") < new_name.size())
360  VTKIO(mymesh).write (new_name);
361 
362  else
363  {
365  << " ERROR: Unrecognized file extension: " << name
366  << "\n I understand the following:\n\n"
367  << " *.dat -- Tecplot ASCII file\n"
368  << " *.e -- Sandia's ExodusII format\n"
369  << " *.exd -- Sandia's ExodusII format\n"
370  << " *.fro -- ACDL's surface triangulation file\n"
371  << " *.gmv -- LANL's GMV (General Mesh Viewer) format\n"
372  << " *.mesh -- MEdit mesh format\n"
373  << " *.mgf -- MGF binary mesh format\n"
374  << " *.msh -- GMSH ASCII file\n"
375  << " *.n -- Sandia's Nemesis format\n"
376  << " *.nem -- Sandia's Nemesis format\n"
377  << " *.plt -- Tecplot binary file\n"
378  << " *.poly -- TetGen ASCII file\n"
379  << " *.ucd -- AVS's ASCII UCD format\n"
380  << " *.ugrid -- Kelly's DIVA ASCII format\n"
381  << " *.unv -- I-deas Universal format\n"
382  << " *.vtu -- VTK (paraview-readable) format\n"
383  << " *.xda -- libMesh ASCII format\n"
384  << " *.xdr -- libMesh binary format,\n"
385  << std::endl
386  << "\n Exiting without writing output\n";
387  }
388  }
389 
390  // Nasty hack for reading/writing zipped files
391  if (name.size() - name.rfind(".bz2") == 4)
392  {
393  LOG_SCOPE("system(bzip2)", "NameBasedIO");
394  if (mymesh.processor_id() == 0)
395  {
396  std::string system_string = "bzip2 -f -c ";
397  system_string += new_name + " > " + name;
398  if (std::system(system_string.c_str()))
399  libmesh_file_error(system_string);
400  std::remove(new_name.c_str());
401  }
402  mymesh.comm().barrier();
403  }
404  if (name.size() - name.rfind(".xz") == 3)
405  {
406  LOG_SCOPE("system(xz)", "NameBasedIO");
407  if (mymesh.processor_id() == 0)
408  {
409  std::string system_string = "xz -f -c ";
410  system_string += new_name + " > " + name;
411  if (std::system(system_string.c_str()))
412  libmesh_file_error(system_string);
413  std::remove(new_name.c_str());
414  }
415  mymesh.comm().barrier();
416  }
417  }
418 
419 }
420 
421 
422 void NameBasedIO::write_nodal_data (const std::string & name,
423  const std::vector<Number> & v,
424  const std::vector<std::string> & vn)
425 {
426  MeshBase & mymesh = MeshInput<MeshBase>::mesh();
427 
428  // Write the file based on extension
429  if (name.rfind(".dat") < name.size())
430  TecplotIO(mymesh).write_nodal_data (name, v, vn);
431 
432  else if (name.rfind(".e") < name.size())
433  ExodusII_IO(mymesh).write_nodal_data(name, v, vn);
434 
435  else if (name.rfind(".gmv") < name.size())
436  {
437  if (mymesh.n_subdomains() > 1)
438  GMVIO(mymesh).write_nodal_data (name, v, vn);
439  else
440  {
441  GMVIO io(mymesh);
442  io.partitioning() = false;
443  io.write_nodal_data (name, v, vn);
444  }
445  }
446 
447  else if (name.rfind(".mesh") < name.size())
448  MEDITIO(mymesh).write_nodal_data (name, v, vn);
449 
450  else if (name.rfind(".msh") < name.size())
451  GmshIO(mymesh).write_nodal_data (name, v, vn);
452 
453  else if (name.rfind(".nem") < name.size() ||
454  name.rfind(".n") < name.size())
455  Nemesis_IO(mymesh).write_nodal_data(name, v, vn);
456 
457  else if (name.rfind(".plt") < name.size())
458  TecplotIO(mymesh,true).write_nodal_data (name, v, vn);
459 
460  else if (name.rfind(".pvtu") < name.size())
461  VTKIO(mymesh).write_nodal_data (name, v, vn);
462 
463  else if (name.rfind(".ucd") < name.size())
464  UCDIO (mymesh).write_nodal_data (name, v, vn);
465 
466  else
467  {
469  << " ERROR: Unrecognized file extension: " << name
470  << "\n I understand the following:\n\n"
471  << " *.dat -- Tecplot ASCII file\n"
472  << " *.e -- Sandia's ExodusII format\n"
473  << " *.exd -- Sandia's ExodusII format\n"
474  << " *.gmv -- LANL's GMV (General Mesh Viewer) format\n"
475  << " *.mesh -- MEdit mesh format\n"
476  << " *.msh -- GMSH ASCII file\n"
477  << " *.n -- Sandia's Nemesis format\n"
478  << " *.nem -- Sandia's Nemesis format\n"
479  << " *.plt -- Tecplot binary file\n"
480  << " *.pvtu -- Paraview VTK file\n"
481  << " *.ucd -- AVS's ASCII UCD format\n"
482  << "\n Exiting without writing output\n";
483  }
484 }
485 
486 
487 void NameBasedIO::write_equation_systems (const std::string & filename,
488  const EquationSystems & es,
489  const std::set<std::string> * system_names)
490 {
491  // XDA/XDR require a separate code path, and currently only support
492  // writing complete restarts
493  if (!system_names)
494  {
495  if (filename.rfind(".xda") < filename.size())
496  {
497  es.write(filename,WRITE,
500  return;
501  }
502  else if (filename.rfind(".xdr") < filename.size())
503  {
504  es.write(filename,ENCODE,
507  return;
508  }
509  }
510 
511  // Other formats just use the default "write nodal values" path
513  (filename, es, system_names);
514 }
515 
516 
517 
518 } // namespace libMesh
virtual void read(const std::string &name) override
Definition: abaqus_io.C:205
std::string name(const ElemQuality q)
Definition: elem_quality.C:42
virtual void read(const std::string &mesh_file) override
Definition: gmv_io.C:1881
virtual void read(const std::string &) override
Definition: ucd_io.C:82
virtual void write_equation_systems(const std::string &filename, const EquationSystems &es, const std::set< std::string > *system_names=nullptr) override
Definition: namebased_io.C:487
Manages multiples systems of equations.
virtual void write(const std::string &name) override
Definition: gmsh_io.C:612
virtual void read(const std::string &base_filename) override
Definition: nemesis_io.C:148
virtual void read(const std::string &) override
Definition: tetgen_io.C:33
virtual void read(const std::string &mesh_file) override
Definition: namebased_io.C:59
virtual void write(const std::string &) override
Definition: gmv_io.C:269
void allow_renumbering(bool allow)
Definition: mesh_base.h:782
virtual void write(const std::string &) override
Definition: medit_io.C:37
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
Definition: mesh_output.C:31
bool legacy() const
Definition: xdr_io.h:109
Handles reading and writing of Exodus binary files.
Definition: exodusII_io.h:52
virtual void read(const std::string &input_name) override
virtual void read(const std::string &name) override
Definition: matlab_io.C:33
virtual void write(const std::string &) override
const Parallel::Communicator & comm() const
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Definition: gmsh_io.C:629
bool & partitioning()
Definition: gmv_io.h:115
Base class for Mesh.
Definition: mesh_base.h:77
virtual void read(const std::string &) override
Definition: vtk_io.C:149
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Definition: gmv_io.C:279
void write(const std::string &name, const XdrMODE, const unsigned int write_flags=(WRITE_DATA), bool partition_agnostic=true) const
virtual void write(const std::string &) override
Definition: unv_io.C:260
processor_id_type n_processors() const
Reads OOF OOGL triangulated surface files.
Definition: off_io.h:39
virtual void write(const std::string &) override
Definition: xdr_io.C:168
virtual void write(const std::string &mesh_file) override
Definition: namebased_io.C:276
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Definition: vtk_io.C:245
OStreamProxy err(std::cerr)
virtual void write(const std::string &) override
Definition: tecplot_io.C:175
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Definition: namebased_io.C:422
virtual void read(const std::string &name) override
Definition: exodusII_io.C:140
virtual void write(const std::string &) override
Definition: fro_io.C:41
virtual void write_nodal_data(const std::string &fname, const std::vector< Number > &soln, const std::vector< std::string > &names) override
Definition: nemesis_io.C:1456
unsigned int n_partitions() const
Definition: mesh_base.h:875
subdomain_id_type n_subdomains() const
Definition: mesh_base.C:304
virtual void read(const std::string &name) override
Definition: off_io.C:35
virtual void write(const std::string &fname) override
Definition: exodusII_io.C:879
void broadcast(MeshBase &) const
virtual void write(const std::string &) override
Definition: tetgen_io.C:259
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Definition: medit_io.C:46
virtual void write(const std::string &base_filename) override
Definition: nemesis_io.C:1190
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Definition: tecplot_io.C:188
bool binary() const
Definition: xdr_io.h:103
virtual void read(const std::string &name) override
Definition: gmsh_io.C:144
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
Definition: exodusII_io.C:700
processor_id_type processor_id() const
virtual void write_nodal_data(const std::string &fname, const std::vector< Number > &soln, const std::vector< std::string > &names) override
Definition: ucd_io.C:324
virtual void write(const std::string &) override
Definition: ucd_io.C:103
virtual void read(const std::string &) override
Definition: unv_io.C:96
void broadcast(T &data, const unsigned int root_id=0) const
virtual void read(const std::string &) override
Definition: xdr_io.C:1250
bool is_parallel_file_format(const std::string &filename)
Definition: namebased_io.h:124