DOLFIN
DOLFIN C++ interface
XDMFFile.h
1 // Copyright (C) 2012-2015 Chris N. Richardson and Garth N. Wells
2 //
3 // This file is part of DOLFIN.
4 //
5 // DOLFIN is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // DOLFIN is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // Modified by Garth N. Wells, 2012
19 
20 #ifndef __DOLFIN_XDMFFILE_H
21 #define __DOLFIN_XDMFFILE_H
22 
23 #include <cstdint>
24 #include <memory>
25 #include <string>
26 #include <utility>
27 #include <vector>
28 
29 #ifdef HAS_HDF5
30 #include <hdf5.h>
31 #else
32 typedef int hid_t;
33 #endif
34 
35 #include <dolfin/common/MPI.h>
36 #include <dolfin/common/Variable.h>
37 #include <dolfin/mesh/CellType.h>
38 
39 namespace boost
40 {
41  namespace filesystem
42  {
43  class path;
44  }
45 }
46 
47 namespace pugi
48 {
49  class xml_node;
50  class xml_document;
51 }
52 
53 namespace dolfin
54 {
55 
56  // Forward declarations
57  class Function;
58 #ifdef HAS_HDF5
59  class HDF5File;
60 #endif
61  class LocalMeshData;
62  class Mesh;
63  template<typename T> class MeshFunction;
64  template<typename T> class MeshValueCollection;
65  class Point;
66 
68 
76 
77  class XDMFFile : public Variable
78  {
79  public:
80 
82  enum class Encoding {HDF5, ASCII};
83 
85 #ifdef HAS_HDF5
86  static const Encoding default_encoding = Encoding::HDF5;
87 #else
88  static const Encoding default_encoding = Encoding::ASCII;
89 #endif
90 
92  XDMFFile(const std::string filename)
93  : XDMFFile(MPI_COMM_WORLD, filename) {}
94 
96  XDMFFile(MPI_Comm comm, const std::string filename);
97 
99  ~XDMFFile();
100 
113  void close();
114 
124  void write(const Mesh& mesh, Encoding encoding=default_encoding);
125 
153  void write_checkpoint(const Function& u,
154  std::string function_name,
155  double time_step = 0.0,
156  Encoding encoding=default_encoding,
157  bool append=false);
158 
167  void write(const Function& u, Encoding encoding=default_encoding);
168 
193  void write(const Function& u, double t,
194  Encoding encoding=default_encoding);
195 
204  void write(const MeshFunction<bool>& meshfunction,
205  Encoding encoding=default_encoding);
206 
215  void write(const MeshFunction<int>& meshfunction,
216  Encoding encoding=default_encoding);
217 
226  void write(const MeshFunction<std::size_t>& meshfunction,
227  Encoding encoding=default_encoding);
228 
237  void write(const MeshFunction<double>& meshfunction,
238  Encoding encoding=default_encoding);
239 
248  void write(const MeshValueCollection<bool>& mvc,
249  Encoding encoding=default_encoding);
250 
259  void write(const MeshValueCollection<int>& mvc,
260  Encoding encoding=default_encoding);
261 
270  void write(const MeshValueCollection<std::size_t>& mvc,
271  Encoding encoding=default_encoding);
272 
281  void write(const MeshValueCollection<double>& mvc,
282  Encoding encoding=default_encoding);
283 
292  void write(const std::vector<Point>& points,
293  Encoding encoding=default_encoding);
294 
305  void write(const std::vector<Point>& points,
306  const std::vector<double>& values,
307  Encoding encoding=default_encoding);
308 
313  void read(Mesh& mesh) const;
314 
335  void read_checkpoint(Function& u, std::string func_name,
336  std::int64_t counter=-1);
337 
343  void read(MeshFunction<bool>& meshfunction, std::string name="");
344 
350  void read(MeshFunction<int>& meshfunction, std::string name="");
351 
357  void read(MeshFunction<std::size_t>& meshfunction, std::string name="");
358 
364  void read(MeshFunction<double>& meshfunction, std::string name="");
365 
371  void read(MeshValueCollection<bool>& mvc, std::string name="");
372 
378  void read(MeshValueCollection<int>& mvc, std::string name="");
379 
385  void read(MeshValueCollection<std::size_t>& mvc, std::string name="");
386 
392  void read(MeshValueCollection<double>& mvc, std::string name="");
393 
394  private:
395 
396  // Generic MVC writer
397  template <typename T>
398  void write_mesh_value_collection(const MeshValueCollection<T>& mvc,
399  Encoding encoding);
400 
401  // Generic MVC reader
402  template <typename T>
403  void read_mesh_value_collection(MeshValueCollection<T>& mvc,
404  std::string name);
405 
406  // Remap meshfunction data, scattering data to appropriate processes
407  template <typename T>
408  static void remap_meshfunction_data(MeshFunction<T>& meshfunction,
409  const std::vector<std::int64_t>& topology_data,
410  const std::vector<T>& value_data);
411 
412  // Build mesh (serial)
413  static void build_mesh(Mesh& mesh, const CellType& cell_type,
414  std::int64_t num_points, std::int64_t num_cells,
415  int tdim, int gdim,
416  const pugi::xml_node& topology_dataset_node,
417  const pugi::xml_node& geometry_dataset_node,
418  const boost::filesystem::path& parent_path);
419 
420  // Build local mesh data structure
421  static void
422  build_local_mesh_data (LocalMeshData& local_mesh_data,
423  const CellType& cell_type,
424  std::int64_t num_points, std::int64_t num_cells,
425  int tdim, int gdim,
426  const pugi::xml_node& topology_dataset_node,
427  const pugi::xml_node& geometry_dataset_node,
428  const boost::filesystem::path& parent_path);
429 
430  static void build_mesh_quadratic(Mesh& mesh, const CellType& cell_type,
431  std::int64_t num_points, std::int64_t num_cells,
432  int tdim, int gdim,
433  const pugi::xml_node& topology_dataset_node,
434  const pugi::xml_node& geometry_dataset_node,
435  const boost::filesystem::path& relative_path);
436 
437 
438 
439  // Add mesh to XDMF xml_node (usually a Domain or Time Grid) and
440  // write data
441  static void add_mesh(MPI_Comm comm, pugi::xml_node& xml_node,
442  hid_t h5_id, const Mesh& mesh,
443  const std::string path_prefix);
444 
445  // Add function to a XML node
446  static void add_function(MPI_Comm comm, pugi::xml_node& xml_node,
447  hid_t h5_id, std::string h5_path,
448  const Function& u, std::string function_name,
449  const Mesh& mesh);
450 
451  // Add set of points to XDMF xml_node and write data
452  static void add_points(MPI_Comm comm, pugi::xml_node& xml_node,
453  hid_t h5_id, const std::vector<Point>& points);
454 
455  // Add topology node to xml_node (includes writing data to XML or HDF5
456  // file)
457  template<typename T>
458  static void add_topology_data(MPI_Comm comm, pugi::xml_node& xml_node,
459  hid_t h5_id, const std::string path_prefix,
460  const Mesh& mesh, int tdim);
461 
462  // Add geometry node and data to xml_node
463  static void add_geometry_data(MPI_Comm comm, pugi::xml_node& xml_node,
464  hid_t h5_id, const std::string path_prefix,
465  const Mesh& mesh);
466 
467  // Add DataItem node to an XML node. If HDF5 is open (h5_id > 0)
468  // the data is written to the HDFF5 file with the path
469  // 'h5_path'. Otherwise, data is witten to the XML node and
470  // 'h5_path' is ignored
471  template<typename T>
472  static void add_data_item(MPI_Comm comm, pugi::xml_node& xml_node,
473  hid_t h5_id, const std::string h5_path, const T& x,
474  const std::vector<std::int64_t> dimensions,
475  const std::string number_type="");
476 
477  // Calculate set of entities of dimension cell_dim which are
478  // duplicated on other processes and should not be output on this
479  // process
480  static std::set<unsigned int> compute_nonlocal_entities(const Mesh& mesh,
481  int cell_dim);
482 
483  // Return topology data on this process as a flat vector
484  template<typename T>
485  static std::vector<T> compute_topology_data(const Mesh& mesh, int cell_dim);
486 
487  // Return quadratic topology for Mesh of degree 2
488  template<typename T>
489  static std::vector<T> compute_quadratic_topology(const Mesh& mesh);
490 
491  // Return data which is local
492  template<typename T>
493  std::vector<T> compute_value_data(const MeshFunction<T>& meshfunction);
494 
495  // Get DOLFIN cell type string from XML topology node
496  static std::pair<std::string, int>
497  get_cell_type(const pugi::xml_node& topology_node);
498 
499  // Get dimensions from an XML DataSet node
500  static std::vector<std::int64_t>
501  get_dataset_shape(const pugi::xml_node& dataset_node);
502 
503  // Get number of cells from an XML Topology node
504  static std::int64_t get_num_cells(const pugi::xml_node& topology_node);
505 
506  // Return data associated with a data set node
507  template <typename T>
508  static std::vector<T> get_dataset(MPI_Comm comm,
509  const pugi::xml_node& dataset_node,
510  const boost::filesystem::path& parent_path,
511  std::pair<std::int64_t, std::int64_t> range={0, 0});
512 
513  // Return (0) HDF5 filename and (1) path in HDF5 file from a
514  // DataItem node
515  static std::array<std::string, 2> get_hdf5_paths(const pugi::xml_node& dataitem_node);
516 
517  static std::string get_hdf5_filename(std::string xdmf_filename);
518 
519  // Generic MeshFunction reader
520  template<typename T>
521  void read_mesh_function(MeshFunction<T>& meshfunction, std::string name="");
522 
523  // Generic MeshFunction writer
524  template<typename T>
525  void write_mesh_function(const MeshFunction<T>& meshfunction,
526  Encoding encoding);
527 
528  // Get data width - normally the same as u.value_size(), but
529  // expand for 2D vector/tensor because XDMF presents everything as
530  // 3D
531  static std::int64_t get_padded_width(const Function& u);
532 
533  // Returns true for DG0 Functions
534  static bool has_cell_centred_data(const Function& u);
535 
536  // Get point data values for linear or quadratic mesh into
537  // flattened 2D array
538  static std::vector<double> get_point_data_values(const Function& u);
539 
540  // Get point data values collocated at P2 geometry points
541  // (vertices and edges) flattened as a 2D array
542  static std::vector<double> get_p2_data_values(const Function& u);
543 
544  // Get cell data values as a flattened 2D array
545  static std::vector<double> get_cell_data_values(const Function& u);
546 
547  // Check whether the requested encoding is supported
548  void check_encoding(Encoding encoding) const;
549 
550  // Check function names equality across processes
551  void check_function_name(std::string function_name);
552 
553  // Generate the XDMF format string based on the Encoding
554  // enumeration
555  static std::string xdmf_format_str(Encoding encoding)
556  { return (encoding == XDMFFile::Encoding::HDF5) ? "HDF" : "XML"; }
557 
558  static std::string vtk_cell_type_str(CellType::Type cell_type, int order);
559 
560  // Return a string of the form "x y"
561  template <typename X, typename Y>
562  static std::string to_string(X x, Y y);
563 
564  // Return a vector of numerical values from a vector of
565  // stringstream
566  template <typename T>
567  static std::vector<T> string_to_vector(const std::vector<std::string>& x_str);
568 
569  // Convert a value_rank to the XDMF string description (Scalar,
570  // Vector, Tensor)
571  static std::string rank_to_string(std::size_t value_rank);
572 
573  // MPI communicator
574  dolfin::MPI::Comm _mpi_comm;
575 
576 #ifdef HAS_HDF5
577  // HDF5 data file
578  std::unique_ptr<HDF5File> _hdf5_file;
579 #endif
580 
581  // Cached filename
582  const std::string _filename;
583 
584  // Counter for time series
585  std::size_t _counter;
586 
587  // The XML document currently representing the XDMF
588  // which needs to be kept open for time series etc.
589  std::unique_ptr<pugi::xml_document> _xml_doc;
590 
591  };
592 
593 #ifndef DOXYGEN_IGNORE
594  // Specialisation for std::vector<bool>, as HDF5 does not support it natively
595  template<> inline
596  void XDMFFile::add_data_item(MPI_Comm comm, pugi::xml_node& xml_node,
597  hid_t h5_id, const std::string h5_path,
598  const std::vector<bool>& x,
599  const std::vector<std::int64_t> shape,
600  const std::string number_type)
601  {
602  // HDF5 cannot accept 'bool' so copy to 'int'
603  std::vector<int> x_int(x.size());
604  for (std::size_t i = 0; i < x.size(); ++i)
605  x_int[i] = (int)x[i];
606  add_data_item(comm, xml_node, h5_id, h5_path, x_int, shape, number_type);
607  }
608 #endif
609 
610 }
611 
612 #endif
std::string to_string(const double *x, std::size_t n)
Return string representation of given array.
Definition: utils.cpp:42
Definition: adapt.h:41
Common base class for DOLFIN variables.
Definition: Variable.h:35
Definition: XDMFFile.h:39
XDMFFile(const std::string filename)
Constructor.
Definition: XDMFFile.h:92
Definition: adapt.h:29
This class stores mesh data on a local processor corresponding to a portion of a (larger) global mesh...
Definition: LocalMeshData.h:58
Type
Enum for different cell types.
Definition: CellType.h:51
Encoding
File encoding type.
Definition: XDMFFile.h:82
Read and write Mesh, Function, MeshFunction and other objects in XDMF.
Definition: XDMFFile.h:77
Definition: CellType.h:46
Definition: Function.h:65
Definition: GenericFile.h:38
Definition: VTKFile.h:27
Definition: Mesh.h:82
Definition: MPI.h:76