Flow123d  release_2.2.0-33-g759111d
msh_vtkreader.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file msh_vtkreader.cc
15  * @brief
16  * @author dalibor
17  */
18 
19 
20 #include <iostream>
21 #include <vector>
22 #include "boost/lexical_cast.hpp"
23 
24 #include "msh_vtkreader.hh"
25 #include "system/system.hh"
26 #include "mesh/bih_tree.hh"
27 
28 #include "config.h"
29 #include <zlib.h>
30 
31 
32 /*******************************************************************
33  * Helper methods
34  */
35 template<typename T>
36 T read_binary_value(std::istream &data_stream)
37 {
38  T val;
39  data_stream.read(reinterpret_cast<char *>(&val), sizeof(val));
40  return val;
41 }
42 
43 
44 uint64_t read_header_type(DataType data_header_type, std::istream &data_stream)
45 {
46  if (data_header_type == DataType::uint64)
47  return read_binary_value<uint64_t>(data_stream);
48  else if (data_header_type == DataType::uint32)
49  return (uint64_t)read_binary_value<unsigned int>(data_stream);
50  else {
51  ASSERT(false).error("Unsupported header_type!\n"); //should not happen
52  return 0;
53  }
54 }
55 
56 
57 /*******************************************************************
58  * implementation of VtkMeshReader
59  */
60 const double VtkMeshReader::point_tolerance = 1E-10;
61 
62 
64 : BaseMeshReader(file_name)
65 {
66  data_section_name_ = "DataArray";
67  has_compatible_mesh_ = false;
69 }
70 
71 
72 
74 {
75  delete data_stream_;
76 }
77 
78 
79 
80 void VtkMeshReader::read_base_vtk_attributes(pugi::xml_node vtk_node, unsigned int &n_nodes, unsigned int &n_elements)
81 {
82  try {
83  // header type of appended data
84  header_type_ = this->get_data_type( vtk_node.attribute("header_type").as_string() );
85  } catch(ExcWrongType &e) {
86  e << EI_SectionTypeName("base parameter header_type");
87  }
88  // data format
90  data_format_ = DataFormat::ascii;
91  } else {
93  // Allowable values of header type are only 'UInt64' or 'UInt32'
94  THROW( ExcWrongType() << EI_ErrMessage("Forbidden") << EI_SectionTypeName("base parameter header_type")
95  << EI_VTKFile(tok_.f_name()));
96  }
97  std::string compressor = vtk_node.attribute("compressor").as_string();
98  if (compressor == "vtkZLibDataCompressor")
99  data_format_ = DataFormat::binary_zlib;
100  else
101  data_format_ = DataFormat::binary_uncompressed;
102  }
103  // size of node and element vectors
104  pugi::xml_node piece_node = vtk_node.child("UnstructuredGrid").child("Piece");
105  n_nodes = piece_node.attribute("NumberOfPoints").as_uint();
106  n_elements = piece_node.attribute("NumberOfCells").as_uint();
107 }
108 
109 
110 
112  Tokenizer::Position appended_pos;
113 
114  {
115  // find line by tokenizer
116  tok_.set_position( Tokenizer::Position() );
117  if (! tok_.skip_to("AppendedData"))
118  THROW(ExcMissingTag() << EI_TagType("tag") << EI_TagName("AppendedData") << EI_VTKFile(tok_.f_name()) );
119  else {
120  appended_pos = tok_.get_position();
121  }
122  }
123 
124  // find exact position of appended data (starts with '_')
125  char c;
126  data_stream_->seekg(appended_pos.file_position_);
127  do {
128  data_stream_->get(c);
129  } while (c!='_');
130  appended_pos.file_position_ = data_stream_->tellg();
131  appended_pos.line_counter_++;
132  delete data_stream_; // close stream
133 
134  // reopen stream in binary mode
135  data_stream_ = new std::ifstream( tok_.f_name(), std::ios_base::in | std::ios_base::binary );
136 
137  return appended_pos;
138 }
139 
140 
141 MeshDataHeader VtkMeshReader::create_header(pugi::xml_node node, unsigned int n_entities, Tokenizer::Position pos)
142 {
143  MeshDataHeader header;
144  header.field_name = node.attribute("Name").as_string();
145  header.time = 0.0;
146  try {
147  header.type = this->get_data_type( node.attribute("type").as_string() );
148  } catch(ExcWrongType &e) {
149  e << EI_SectionTypeName("DataArray " + header.field_name);
150  }
151  header.n_components = node.attribute("NumberOfComponents").as_uint(1);
152  header.n_entities = n_entities;
153  std::string format = node.attribute("format").as_string();
154  if (format=="appended") {
155  if (data_format_ == DataFormat::ascii)
156  THROW(ExcInvalidFormat() << EI_FieldName(header.field_name) << EI_ExpectedFormat("ascii") << EI_VTKFile(tok_.f_name()) );
157  std::streampos file_pos = pos.file_position_;
158  file_pos += node.attribute("offset").as_uint();
159  header.position = Tokenizer::Position( file_pos, pos.line_counter_, pos.line_position_ );
160  } else if (format=="ascii") {
161  if (data_format_ != DataFormat::ascii)
162  THROW(ExcInvalidFormat() << EI_FieldName(header.field_name) << EI_ExpectedFormat("appended") << EI_VTKFile(tok_.f_name()) );
163 
164  tok_.set_position( Tokenizer::Position() );
165  bool is_point = (header.field_name=="");
166  std::string found_str = (is_point) ? "<Points>" : "Name=\"" + header.field_name + "\"";
167  if (! tok_.skip_to(found_str))
168  THROW(ExcMissingTag() << EI_TagType("DataArray tag") << EI_TagName(header.field_name) << EI_VTKFile(tok_.f_name()) );
169  else {
170  if (is_point) tok_.skip_to("DataArray");
171  header.position = tok_.get_position();
172  }
173  } else {
174  THROW(ExcUnknownFormat() << EI_FieldName(header.field_name) << EI_VTKFile(tok_.f_name()) );
175  }
176 
177  return header;
178 }
179 
180 
182 {
183  pugi::xml_document doc;
184  doc.load_file( tok_.f_name().c_str() );
185  unsigned int n_nodes, n_elements;
186  this->read_base_vtk_attributes( doc.child("VTKFile"), n_nodes, n_elements );
187 
188  // open ifstream for find position
189  data_stream_ = new std::ifstream( tok_.f_name() );
190 
191  // data of appended tag
192  Tokenizer::Position appended_pos;
194  // no AppendedData tag
195  } else {
196  appended_pos = get_appended_position();
197  }
198 
199  pugi::xml_node node = doc.child("VTKFile").child("UnstructuredGrid").child("Piece");
200 
201  header_table_.clear();
202 
203  // create headers of Points and Cells DataArrays
204  header_table_["Points"] = create_header( node.child("Points").child("DataArray"), n_nodes, appended_pos );
205  header_table_["Points"].field_name = "Points";
206  header_table_["connectivity"]
207  = create_header( node.child("Cells").find_child_by_attribute("DataArray", "Name", "connectivity"), n_elements, appended_pos );
208  header_table_["offsets"]
209  = create_header( node.child("Cells").find_child_by_attribute("DataArray", "Name", "offsets"), n_elements, appended_pos );
210  header_table_["types"]
211  = create_header( node.child("Cells").find_child_by_attribute("DataArray", "Name", "types"), n_elements, appended_pos );
212 
213  node = node.child("CellData");
214  for (pugi::xml_node subnode = node.child("DataArray"); subnode; subnode = subnode.next_sibling("DataArray")) {
215  auto header = create_header( subnode, n_elements, appended_pos );
216  header_table_[header.field_name] = header;
217  }
218 }
219 
220 
221 MeshDataHeader & VtkMeshReader::find_header(double time, std::string field_name)
222 {
223  HeaderTable::iterator table_it = header_table_.find(field_name);
224 
225  if (table_it == header_table_.end()) {
226  // no data found
227  THROW( ExcFieldNameNotFound() << EI_FieldName(field_name) << EI_MeshFile(tok_.f_name()));
228  }
229 
230  return table_it->second;
231 }
232 
233 
234 
235 DataType VtkMeshReader::get_data_type(std::string type_str) {
236  // names of types in DataArray section
237  static const std::map<std::string, DataType> types = {
238  {"Int8", DataType::int8},
239  {"UInt8", DataType::uint8},
240  {"Int16", DataType::int16},
241  {"UInt16", DataType::uint16},
242  {"Int32", DataType::int32},
243  {"UInt32", DataType::uint32},
244  {"Int64", DataType::int64},
245  {"UInt64", DataType::uint64},
246  {"Float32", DataType::float32},
247  {"Float64", DataType::float64},
248  {"", DataType::undefined}
249  };
250 
252  if (it != types.end()) {
253  return it->second;
254  } else {
255  THROW( ExcWrongType() << EI_ErrMessage("Unknown") << EI_VTKFile(tok_.f_name()));
256  return DataType::uint32;
257  }
258 
259 }
260 
261 
262 
264 {
265  static const std::vector<unsigned int> sizes = { 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 0 };
266 
267  return sizes[data_type];
268 }
269 
270 
271 
272 void VtkMeshReader::read_element_data(ElementDataCacheBase &data_cache, MeshDataHeader actual_header, unsigned int n_components,
273  bool boundary_domain) {
274 
275  ASSERT(!boundary_domain).error("Reading VTK data of boundary elements is not supported yet!\n");
276 
277  switch (data_format_) {
278  case DataFormat::ascii: {
279  parse_ascii_data( data_cache, n_components, actual_header.n_entities, actual_header.position, boundary_domain );
280  break;
281  }
282  case DataFormat::binary_uncompressed: {
283  ASSERT_PTR(data_stream_).error();
284  parse_binary_data( data_cache, n_components, actual_header.n_entities, actual_header.position, boundary_domain,
285  actual_header.type );
286  break;
287  }
288  case DataFormat::binary_zlib: {
289  ASSERT_PTR(data_stream_).error();
290  parse_compressed_data( data_cache, n_components, actual_header.n_entities, actual_header.position, boundary_domain,
291  actual_header.type);
292  break;
293  }
294  default: {
295  ASSERT(false).error(); // should not happen
296  break;
297  }
298  }
299 
300  LogOut().fmt("time: {}; {} entities of field {} read.\n",
301  actual_header.time, n_read_, actual_header.field_name);
302 }
303 
304 
305 void VtkMeshReader::parse_ascii_data(ElementDataCacheBase &data_cache, unsigned int n_components, unsigned int n_entities,
306  Tokenizer::Position pos, bool boundary_domain)
307 {
308  n_read_ = 0;
309 
310  tok_.set_position( pos );
311  try {
312  tok_.next_line();
313  for (unsigned int i_row = 0; i_row < n_entities; ++i_row) {
314  data_cache.read_ascii_data(tok_, n_components, get_element_vector(boundary_domain)[i_row]);
315  n_read_++;
316  }
317  } catch (boost::bad_lexical_cast &) {
318  THROW(ExcWrongFormat() << EI_Type("DataArray tag") << EI_TokenizerMsg(tok_.position_msg())
319  << EI_MeshFile(tok_.f_name()) );
320  }
321 }
322 
323 
324 void VtkMeshReader::parse_binary_data(ElementDataCacheBase &data_cache, unsigned int n_components, unsigned int n_entities,
325  Tokenizer::Position pos, bool boundary_domain, DataType value_type)
326 {
327  n_read_ = 0;
328 
329  data_stream_->seekg(pos.file_position_);
330  uint64_t data_size = read_header_type(header_type_, *data_stream_) / type_value_size(value_type);
331 
332  for (unsigned int i_row = 0; i_row < n_entities; ++i_row) {
333  data_cache.read_binary_data(*data_stream_, n_components, get_element_vector(boundary_domain)[i_row]);
334  n_read_++;
335  }
336 }
337 
338 
339 void VtkMeshReader::parse_compressed_data(ElementDataCacheBase &data_cache, unsigned int n_components, unsigned int n_entities,
340  Tokenizer::Position pos, bool boundary_domain, DataType value_type)
341 {
342  data_stream_->seekg(pos.file_position_);
343  uint64_t n_blocks = read_header_type(header_type_, *data_stream_);
344  uint64_t u_size = read_header_type(header_type_, *data_stream_);
345  uint64_t p_size = read_header_type(header_type_, *data_stream_);
346 
347  std::vector<uint64_t> block_sizes;
348  block_sizes.reserve(n_blocks);
349  for (uint64_t i = 0; i < n_blocks; ++i) {
350  block_sizes.push_back( read_header_type(header_type_, *data_stream_) );
351  }
352 
353  stringstream decompressed_data;
354  uint64_t decompressed_data_size = 0;
355  for (uint64_t i = 0; i < n_blocks; ++i) {
356  uint64_t decompressed_block_size = (i==n_blocks-1 && p_size>0) ? p_size : u_size;
357  uint64_t compressed_block_size = block_sizes[i];
358 
359  std::vector<char> data_block(compressed_block_size);
360  data_stream_->read(&data_block[0], compressed_block_size);
361 
362  std::vector<char> buffer(decompressed_block_size);
363 
364  // set zlib object
365  z_stream strm;
366  strm.zalloc = 0;
367  strm.zfree = 0;
368  strm.next_in = (Bytef *)(&data_block[0]);
369  strm.avail_in = compressed_block_size;
370  strm.next_out = (Bytef *)(&buffer[0]);
371  strm.avail_out = decompressed_block_size;
372 
373  // decompression of data
374  inflateInit(&strm);
375  inflate(&strm, Z_NO_FLUSH);
376  inflateEnd(&strm);
377 
378  // store decompressed data to stream
379  decompressed_data << std::string(buffer.begin(), buffer.end());
380  decompressed_data_size += decompressed_block_size;
381  }
382 
383  n_read_ = 0;
384 
385  uint64_t data_size = decompressed_data_size / type_value_size(value_type);
386 
387  for (unsigned int i_row = 0; i_row < n_entities; ++i_row) {
388  data_cache.read_binary_data(decompressed_data, n_components, get_element_vector(boundary_domain)[i_row]);
389  n_read_++;
390  }
391 }
392 
393 
395 {
396  std::vector<unsigned int> node_ids; // allow mapping ids of nodes from VTK mesh to GMSH
397  std::vector<unsigned int> offsets_vec; // value of offset section in VTK file
398 
399  {
400  // read points data section, find corresponding nodes in GMSH trough BIH tree
401  // points in data section and nodes in GMSH must be in ratio 1:1
402  // store orders (mapping between VTK and GMSH file) into node_ids vector
403  std::vector<unsigned int> searched_elements; // for BIH tree
404  unsigned int i_node, i_elm_node;
405  const BIHTree &bih_tree=mesh.get_bih_tree();
406 
407  MeshDataHeader point_header = this->find_header(0.0, "Points");
408  ASSERT_EQ(3, point_header.n_components).error();
409  node_ids.resize(point_header.n_entities);
410  // fill vectors necessary for correct reading of data, we read all data same order as data is stored
411  for (unsigned int i=0; i<point_header.n_entities; ++i) {
412  bulk_elements_id_.push_back(i);
413  }
414 
415  // create temporary data cache
416  ElementDataCache<double> node_cache(point_header, 1, point_header.n_components*point_header.n_entities);
417 
418  // check compatible nodes, to each VTK point must exist only one GMSH node
419  this->read_element_data(node_cache, point_header, point_header.n_components, false);
420  std::vector<double> &node_vec = *(node_cache.get_component_data(0) );
421  ASSERT_EQ(node_vec.size(), point_header.n_components*point_header.n_entities).error();
422  for (unsigned int i=0; i<point_header.n_entities; ++i) {
423  arma::vec3 point = { node_vec[3*i], node_vec[3*i+1], node_vec[3*i+2] };
424  int found_i_node = -1;
425  bih_tree.find_point(point, searched_elements);
426 
427  for (std::vector<unsigned int>::iterator it = searched_elements.begin(); it!=searched_elements.end(); it++) {
428  ElementFullIter ele = mesh.element( *it );
429  FOR_ELEMENT_NODES(ele, i_node)
430  {
431  if ( compare_points(ele->node[i_node]->point(), point) ) {
432  i_elm_node = mesh.node_vector.index(ele->node[i_node]);
433  if (found_i_node == -1) found_i_node = i_elm_node;
434  else if (found_i_node != i_elm_node) {
435  THROW( ExcIncompatibleMesh() << EI_ErrMessage("duplicate nodes found in GMSH file")
436  << EI_VTKFile(tok_.f_name()));
437  }
438  }
439  }
440  }
441  if (found_i_node == -1) {
442  THROW( ExcIncompatibleMesh() << EI_ErrMessage("no node found in GMSH file") << EI_VTKFile(tok_.f_name()));
443  }
444  node_ids[i] = (unsigned int)found_i_node;
445  searched_elements.clear();
446  }
447 
448  }
449 
450  {
451  // read offset data section into offsets_vec vector, it's used for reading connectivity
452  MeshDataHeader offset_header = this->find_header(0.0, "offsets");
453  for (unsigned int i=bulk_elements_id_.size(); i<offset_header.n_entities; ++i) {
454  bulk_elements_id_.push_back(i);
455  }
456 
457  ElementDataCache<unsigned int> offset_cache(offset_header, 1, offset_header.n_components*offset_header.n_entities);
458  this->read_element_data(offset_cache, offset_header, offset_header.n_components, false);
459 
460  offsets_vec = *(offset_cache.get_component_data(0) );
461  }
462 
463  {
464  // read connectivity data section, find corresponding elements in GMSH
465  // cells in data section and elements in GMSH must be in ratio 1:1
466  // store orders (mapping between VTK and GMSH file) into bulk_elements_id_ vector
467  MeshDataHeader con_header = this->find_header(0.0, "connectivity");
468  con_header.n_entities = offsets_vec[offsets_vec.size()-1];
469  for (unsigned int i=bulk_elements_id_.size(); i<con_header.n_entities; ++i) {
470  bulk_elements_id_.push_back(i);
471  }
472 
473  ElementDataCache<unsigned int> con_cache(con_header, 1, con_header.n_components*con_header.n_entities);
474  this->read_element_data(con_cache, con_header, con_header.n_components, false);
475 
476  std::vector<unsigned int> &connectivity_vec = *(con_cache.get_component_data(0) );
477  vector<unsigned int> node_list;
478  vector<unsigned int> candidate_list; // returned by intersect_element_lists
479  vector<unsigned int> result_list; // list of elements with same dimension as vtk element
480  bulk_elements_id_.clear();
481  bulk_elements_id_.resize(offsets_vec.size());
482  // iterate trough connectivity data, to each VTK cell must exist only one GMSH element
483  // fill bulk_elements_id_ vector
484  unsigned int i_con = 0, last_offset=0, dim;
485  for (unsigned int i=0; i<offsets_vec.size(); ++i) { // iterate trough offset - one value for every element
486  dim = offsets_vec[i] - last_offset - 1; // dimension of vtk element
487  for ( ; i_con<offsets_vec[i]; ++i_con ) { // iterate trough all nodes of any element
488  node_list.push_back( node_ids[connectivity_vec[i_con]] );
489  }
490  mesh.intersect_element_lists(node_list, candidate_list);
491  for (auto i_elm : candidate_list) {
492  if ( mesh.element( i_elm )->dim() == dim ) result_list.push_back(i_elm);
493  }
494  if (result_list.size() != 1) {
495  THROW( ExcIncompatibleMesh() << EI_ErrMessage("intersect_element_lists must produce one element")
496  << EI_VTKFile(tok_.f_name()));
497  }
498  bulk_elements_id_[i] = result_list[0];
499  node_list.clear();
500  result_list.clear();
501  last_offset = offsets_vec[i];
502  }
503  }
504 
505  has_compatible_mesh_ = true;
506 }
507 
508 
510  return fabs(p1[0]-p2[0]) < point_tolerance
511  && fabs(p1[1]-p2[1]) < point_tolerance
512  && fabs(p1[2]-p2[2]) < point_tolerance;
513 }
514 
515 
517  // will be implemented later
518 }
519 
520 
522  ASSERT(false).error("Reading of VTK mesh is not supported yet!");
523  // will be implemented later
524 }
525 
526 
528  // will be implemented later
529 }
530 
531 
532 
533 // explicit instantiation of template methods
534 template unsigned int read_binary_value<unsigned int>(std::istream &data_stream);
535 template uint64_t read_binary_value<uint64_t>(std::istream &data_stream);
void make_header_table() override
Reads table of DataArray headers through pugixml interface.
bool compare_points(arma::vec3 &p1, arma::vec3 &p2)
#define FOR_ELEMENT_NODES(i, j)
Definition: elements.h:187
HeaderTable header_table_
Table with data of DataArray headers.
void read_nodes(Mesh *mesh)
static const double point_tolerance
Tolerance during comparison point data with GMSH nodes.
DataFormat data_format_
variants of data format (ascii, appended, compressed appended)
MeshDataHeader & find_header(double time, std::string field_name) override
template unsigned int read_binary_value< unsigned int >(std::istream &data_stream)
VtkMeshReader(const FilePath &file_name)
template uint64_t read_binary_value< uint64_t >(std::istream &data_stream)
unsigned int n_entities
Number of rows.
std::string format(CStringRef format_str, ArgList args)
Definition: format.h:3141
std::string field_name
Name of field.
void read_base_vtk_attributes(pugi::xml_node vtk_node, unsigned int &n_nodes, unsigned int &n_elements)
Set base attributes of VTK and get count of nodes and elements.
Definition: mesh.h:97
DataType get_data_type(std::string type_str)
Get DataType by value of string.
std::string data_section_name_
Store name of field data section specify for type of mesh file.
void parse_compressed_data(ElementDataCacheBase &data_cache, unsigned int n_components, unsigned int n_entities, Tokenizer::Position pos, bool boundary_domain, DataType value_type)
Uncompress and parse binary compressed data to data cache.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
#define LogOut()
Macro defining &#39;log&#39; record of log.
Definition: logger.hh:239
uint64_t read_header_type(DataType data_header_type, std::istream &data_stream)
void read_physical_names(Mesh *mesh) override
std::istream * data_stream_
input stream allow read appended data, used only if this tag exists
vector< int > bulk_elements_id_
void check_compatible_mesh(Mesh &mesh) override
double time
Time of field data (used only for GMSH reader)
Tokenizer::Position position
Position of data in mesh file.
virtual void read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row)=0
Class for O(log N) lookup for intersections with a set of bounding boxes.
Definition: bih_tree.hh:36
unsigned int index(const T *pointer) const
Definition: sys_vector.hh:373
~VtkMeshReader()
Destructor.
DataType header_type_
header type of VTK file (only for appended data)
void find_point(const Space< 3 >::Point &point, std::vector< unsigned int > &result_list) const
Definition: bih_tree.cc:240
DataType type
Type of data (used only for VTK reader)
unsigned int n_components
Number of values on one row.
const BIHTree & get_bih_tree()
Definition: mesh.cc:735
unsigned int n_read_
store count of read entities
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
void read_elements(Mesh *mesh)
void parse_binary_data(ElementDataCacheBase &data_cache, unsigned int n_components, unsigned int n_entities, Tokenizer::Position pos, bool boundary_domain, DataType value_type)
Parse binary data to data cache.
MeshDataHeader create_header(pugi::xml_node node, unsigned int n_entities, Tokenizer::Position pos)
Helper method that create DataArray header of given xml node (used from make_header_table) ...
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:335
T read_binary_value(std::istream &data_stream)
void read_element_data(ElementDataCacheBase &data_cache, MeshDataHeader actual_header, unsigned int n_components, bool boundary_domain) override
ComponentDataPtr get_component_data(unsigned int component_idx)
Return vector of element data for get component.
void intersect_element_lists(vector< unsigned int > const &nodes_list, vector< unsigned int > &intersection_element_list)
Definition: mesh.cc:284
DataType
Types of VTK data (value &#39;undefined&#39; for empty value)
Tokenizer tok_
Tokenizer used for reading ASCII file format.
virtual void read_binary_data(std::istream &data_stream, unsigned int n_components, unsigned int i_row)=0
unsigned int type_value_size(DataType data_type)
Return size of value of data_type.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
Tokenizer::Position get_appended_position()
Get position of AppendedData tag in VTK file.
std::vector< int > const & get_element_vector(bool boundary_domain)
NodeVector node_vector
Vector of nodes of the mesh.
Definition: mesh.h:226
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:327
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:228
void parse_ascii_data(ElementDataCacheBase &data_cache, unsigned int n_components, unsigned int n_entities, Tokenizer::Position pos, bool boundary_domain)
Parse ascii data to data cache.