exodusII_io_helper.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 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 #ifndef LIBMESH_EXODUSII_IO_HELPER_H
19 #define LIBMESH_EXODUSII_IO_HELPER_H
20 
21 #include "libmesh/libmesh_config.h"
22 
23 #ifdef LIBMESH_HAVE_EXODUS_API
24 
25 // Local includes
26 #include "libmesh/mesh_base.h"
28 #include "libmesh/point.h"
29 
30 // C++ includes
31 #include <iostream>
32 #include <string>
33 #include <vector>
34 #include <map>
35 
36 // Macro to simplify checking Exodus error codes
37 #define EX_CHECK_ERR(code, msg) \
38  do { \
39  if ((code) < 0) { \
40  libMesh::err << (msg) << std::endl; \
41  libmesh_error(); \
42  } } while(0)
43 
44 
45 namespace libMesh
46 {
47 
48 
49 namespace exII {
50  extern "C" {
51 #include "exodusII.h" // defines MAX_LINE_LENGTH, MAX_STR_LENGTH used later
52  }
53 }
54 
62 {
63 public:
64 
72  ExodusII_IO_Helper(const ParallelObject &parent,
73  bool v=false,
74  bool run_only_on_proc0=true);
78  virtual ~ExodusII_IO_Helper();
79 
84  const char* get_elem_type() const;
85 
91  void open(const char* filename, bool read_only);
92 
96  void read_header();
97 
103  void print_header();
104 
109  void read_nodes();
110 
115  void read_node_num_map();
116 
120  void print_nodes(std::ostream &out = libMesh::out);
121 
126  void read_block_info();
127 
131  int get_block_id(int index);
132 
137  std::string get_block_name(int index);
138 
142  int get_side_set_id(int index);
143 
148  std::string get_side_set_name(int index);
149 
153  int get_node_set_id(int index);
154 
159  std::string get_node_set_name(int index);
160 
165  void read_elem_in_block(int block);
166 
171  void read_elem_num_map();
172 
177  void read_sideset_info();
178 
183  void read_nodeset_info();
184 
189  void read_sideset(int id, int offset);
190 
195  void read_nodeset(int id);
196 
200  void close();
201 
205  int inquire(int req_info, std::string error_msg="");
206 
210  void read_time_steps();
211 
216  void read_num_time_steps();
217 
222  void read_nodal_var_values(std::string nodal_var_name, int time_step);
223 
228  void read_elemental_var_values(std::string elemental_var_name, int time_step);
229 
233  virtual void create(std::string filename);
234 
238  virtual void initialize(std::string title, const MeshBase & mesh);
239 
243  void initialize_discontinuous(std::string title, const MeshBase & mesh);
244 
248  virtual void write_nodal_coordinates(const MeshBase & mesh);
249 
254 
259  virtual void write_elements(const MeshBase & mesh);
260 
265  void write_elements_discontinuous(const MeshBase & mesh);
266 
270  virtual void write_sidesets(const MeshBase & mesh);
271 
275  virtual void write_nodesets(const MeshBase & mesh);
276 
280  void initialize_element_variables(std::vector<std::string> names);
281 
285  void initialize_nodal_variables(std::vector<std::string> names);
286 
290  void initialize_global_variables(std::vector<std::string> names);
291 
295  void write_timestep(int timestep, Real time);
296 
300  void write_element_values(const MeshBase & mesh, const std::vector<Number> & values, int timestep);
301 
305  void write_nodal_values(int var_id, const std::vector<Number> & values, int timestep);
306 
310  void write_information_records(const std::vector<std::string> & records);
311 
315  void write_global_values(const std::vector<Number> & values, int timestep);
316 
326 
332 
338  class Conversion;
339 
346  class ElementMaps;
347 
353  class NamesData;
354 
359  void message(const std::string msg);
360 
366  void message(const std::string msg, int i);
367 
368  // File identification flag
369  int ex_id;
370 
371  // General error flag
372  int ex_err;
373 
374  // Number of dimensions in the mesh
375  int num_dim;
376 
377  // Number of global variables
379 
380  // Total number of nodes in the mesh
382 
383  // Total number of elements in the mesh
384  int num_elem;
385 
386  // Total number of element blocks
388 
389  // Total number of node sets
391 
392  // Total number of element sets
394 
395  // Number of elements in this block
397 
398  // Number of nodes in each element
400 
401  // Number of attributes for a given block
402  int num_attr;
403 
404  // Total number of elements in all side sets
406 
407  // Vector of the block identification numbers
408  std::vector<int> block_ids;
409 
410  // Vector of nodes in an element
411  std::vector<int> connect;
412 
413  // Vector of the sideset IDs
414  std::vector<int> ss_ids;
415 
416  // Vector of the nodeset IDs
417  std::vector<int> nodeset_ids;
418 
419  // Number of sides (edges/faces) in current set
420  std::vector<int> num_sides_per_set;
421 
422  // Number of nodes in current set
423  std::vector<int> num_nodes_per_set;
424 
425  // Number of distribution factors per set
426  std::vector<int> num_df_per_set;
427 
428  // Number of distribution factors per set
429  std::vector<int> num_node_df_per_set;
430 
431  // List of element numbers in all sidesets
432  std::vector<int> elem_list;
433 
434  // Side (face/edge) number actually on the boundary
435  std::vector<int> side_list;
436 
437  // Node number actually on the boundary
438  std::vector<int> node_list;
439 
440  // Side (face/edge) id number
441  std::vector<int> id_list;
442 
443  // Optional mapping from internal [0,num_nodes) to arbitrary indices
444  std::vector<int> node_num_map;
445 
446  // Optional mapping from internal [0,num_elem) to arbitrary indices
447  std::vector<int> elem_num_map;
448 
449  // x locations of node points
450  std::vector<Real> x;
451 
452  // y locations of node points
453  std::vector<Real> y;
454 
455  // z locations of node points
456  std::vector<Real> z;
457 
458  // Problem title (Use vector<char> to emulate a char*)
459  std::vector<char> title;
460 
461  // Type of element in a given block
462  std::vector<char> elem_type;
463 
464  // Maps libMesh element numbers to Exodus element numbers
465  // gets filled in when write_elements gets called
466  std::map<int, int> libmesh_elem_num_to_exodus;
467  std::vector<int> exodus_elem_num_to_libmesh;
468 
469  // Map of all node numbers connected to local node numbers to their exodus numbering.
470  // The exodus numbers are stored in here starting with 1
471  std::map<int, int> libmesh_node_num_to_exodus;
472  std::vector<int> exodus_node_num_to_libmesh;
473 
474  // The number of timesteps in the file, as returned by ex_inquire
476 
477  // The timesteps stored in the solution file, filled by read_time_steps()
478  std::vector<Real> time_steps;
479 
480  // The number of nodal variables in the Exodus file
482 
483  // The names of the nodal variables stored in the Exodus file
484  std::vector<std::string> nodal_var_names;
485 
486  // Holds the nodal variable values for a given variable, one value per node
487  std::vector<Real> nodal_var_values;
488 
489  // The number of elemental variables in the Exodus file
491 
492  // The names of the elemental variables stored in the Exodus file
493  std::vector<std::string> elem_var_names;
494 
495  // Holds the elemental variable values for a given variable, one value per element
496  std::vector<Real> elem_var_values;
497 
498  // The names of the global variables stored in the Exodus file
499  std::vector<std::string> global_var_names;
500 
501  // Maps of Ids to named entities
502  std::map<int, std::string> id_to_block_names;
503  std::map<int, std::string> id_to_ss_names;
504  std::map<int, std::string> id_to_ns_names;
505 
506  // On/Off message flag
507  bool verbose;
508 
509  // This flag gets set after the Exodus file has been successfully opened for writing.
510  // Both the create() and open() (if called with EX_WRITE) functions may set this flag.
512 
513  // This flag gets set after the open() function has been successfully called.
514  // We call open() to open an ExodusII file for reading.
516 
517  // When either create() or open() is called, the Helper stores the
518  // name of the opened file as current_filename. This way, the
519  // ExodusII_IO object can check to see if, on subsequent writes, the
520  // user is asking to write to a *different* filename from the one
521  // that is currently open, and signal an error. The current
522  // ExodusII_IO implementation is designed to work with a single file
523  // only, so if you want to write to multiple Exodus files, use a
524  // different ExodusII_IO object for each one.
525  std::string current_filename;
526 
527 protected:
528  // If true, whenever there is an I/O operation, only perform if if we are on processor 0.
530 
531  // True once the elem vars are initialized
533 
534  // True once the global vars are initialized
536 
537  // True once the nodal vars are initialized
539 
540  // If true, use the Mesh's dimension (as determined by the dimension
541  // of the elements comprising the mesh) instead of the mesh's
542  // spatial dimension, when writing. By default this is false.
544 
545  // On output, shift every point by _coordinate_offset
547 
548 private:
558  void read_var_names(ExodusVarType type);
559 
565  void write_var_names(ExodusVarType type, std::vector<std::string>& names);
566 
571  void check_existing_vars(ExodusVarType type, std::vector<std::string>& names, std::vector<std::string>& names_from_file);
572 
576  void read_var_names_impl(const char* var_type, int& count, std::vector<std::string>& result);
577 
581  void write_var_names_impl(const char* var_type, int& count, std::vector<std::string>& names);
582 };
583 
584 
585 
586 
587 
588 
589 
590 
592 {
593 public:
594 
599  Conversion(const int* nm, // node_map
600  size_t nm_size,
601  const int* inm, // inverse_node_map
602  size_t inm_size,
603  const int* sm, // side_map
604  size_t sm_size,
605  const int* ism, // inverse_side_map
606  size_t ism_size,
607  const ElemType ct, // "canonical" aka libmesh element type
608  std::string ex_type) // string representing the Exodus element type
609  : node_map(nm),
610  node_map_size(nm_size),
611  inverse_node_map(inm),
612  inverse_node_map_size(inm_size),
613  side_map(sm),
614  side_map_size(sm_size),
615  inverse_side_map(ism),
616  inverse_side_map_size(ism_size),
617  canonical_type(ct),
618  exodus_type(ex_type)
619  {}
620 
626  int get_node_map(int i) const
627  {
628  libmesh_assert_less (static_cast<size_t>(i), node_map_size);
629  return node_map[i];
630  }
631 
638  int get_inverse_node_map(int i) const
639  {
640  libmesh_assert_less (static_cast<size_t>(i), inverse_node_map_size);
641  return inverse_node_map[i];
642  }
643 
649  int get_side_map(int i) const
650  {
651  libmesh_assert_less (static_cast<size_t>(i), side_map_size);
652  return side_map[i];
653  }
654 
660  int get_inverse_side_map(int i) const
661  {
662  libmesh_assert_less (static_cast<size_t>(i), inverse_side_map_size);
663  return inverse_side_map[i];
664  }
665 
672 
676  std::string exodus_elem_type() const { return exodus_type; }
677 
678 
679 private:
683  const int* node_map;
684 
689 
695  const int* inverse_node_map;
696 
701 
705  const int* side_map;
706 
711 
715  const int* inverse_side_map;
716 
721 
727 
731  const std::string exodus_type;
732 };
733 
734 
735 
736 
737 
738 
740 {
741 public:
742 
747 
756  static const int edge2_node_map[2];
757 
761  static const int edge3_node_map[3];
762 
766  // FIXME: This notion may or may not be defined in ExodusII
767 
772  static const int edge_edge_map[2];
773 
778  static const int edge_inverse_edge_map[2];
779 
789  static const int quad4_node_map[4];
790 
795  static const int quad8_node_map[8];
796 
801  static const int quad9_node_map[9];
802 
806  static const int tri3_node_map[3];
807 
812  static const int tri6_node_map[6];
813 
822  static const int tri_edge_map[3];
823 
828  static const int quad_edge_map[4];
829 
834  static const int tri_inverse_edge_map[3];
835 
840  static const int quad_inverse_edge_map[4];
841 
851  static const int hex8_node_map[8];
852 
857  static const int hex20_node_map[20];
858 
863  static const int hex27_node_map[27];
864 
869  static const int hex27_inverse_node_map[27];
870 
875  static const int tet4_node_map[4];
876 
881  static const int tet10_node_map[10];
882 
886  static const int prism6_node_map[6];
887 
892  static const int prism15_node_map[15];
893 
897  static const int prism18_node_map[18];
898 
903  static const int pyramid5_node_map[5];
904 
909  static const int pyramid14_node_map[14];
910 
911 
920  static const int hex_face_map[6];
921 
926  static const int hex27_face_map[6];
927 
932  static const int tet_face_map[4];
933 
938  static const int prism_face_map[5];
939 
944  static const int pyramid_face_map[5];
945 
950  static const int hex_inverse_face_map[6];
951 
956  static const int hex27_inverse_face_map[6];
957 
962  static const int tet_inverse_face_map[4];
963 
968  static const int prism_inverse_face_map[5];
969 
974  static const int pyramid_inverse_face_map[5];
975 
980 
985 };
986 
987 
988 
995 {
996 public:
1002  explicit
1003  NamesData(size_t n_strings, size_t string_length);
1004 
1008  void push_back_entry(const std::string & name);
1009 
1013  char** get_char_star_star();
1014 
1018  char* get_char_star(int i);
1019 
1020 private:
1021  // C++ data structures for managing string memory
1022  std::vector<std::vector<char> > data_table;
1023  std::vector<char*> data_table_pointers;
1024 
1025  size_t counter;
1026  size_t table_size;
1027 };
1028 
1029 
1030 } // namespace libMesh
1031 
1032 #endif // LIBMESH_HAVE_EXODUS_API
1033 
1034 #endif // LIBMESH_EXODUSII_IO_HELPER_H

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:04 UTC

Hosted By:
SourceForge.net Logo