22 #include "boost/lexical_cast.hpp" 39 data_stream.read(reinterpret_cast<char *>(&val),
sizeof(val));
51 ASSERT(
false).error(
"Unsupported header_type!\n");
85 }
catch(ExcWrongType &e) {
86 e << EI_SectionTypeName(
"base parameter header_type");
94 THROW( ExcWrongType() << EI_ErrMessage(
"Forbidden") << EI_SectionTypeName(
"base parameter header_type")
95 << EI_VTKFile(
tok_.f_name()));
97 std::string compressor = vtk_node.attribute(
"compressor").as_string();
98 if (compressor ==
"vtkZLibDataCompressor")
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();
112 Tokenizer::Position appended_pos;
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()) );
120 appended_pos =
tok_.get_position();
131 appended_pos.line_counter_++;
135 data_stream_ =
new std::ifstream(
tok_.f_name(), std::ios_base::in | std::ios_base::binary );
144 header.
field_name = node.attribute(
"Name").as_string();
148 }
catch(ExcWrongType &e) {
149 e << EI_SectionTypeName(
"DataArray " + header.
field_name);
151 header.
n_components = node.attribute(
"NumberOfComponents").as_uint(1);
153 std::string
format = node.attribute(
"format").as_string();
154 if (format==
"appended") {
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") {
162 THROW(ExcInvalidFormat() << EI_FieldName(header.
field_name) << EI_ExpectedFormat(
"appended") << EI_VTKFile(
tok_.f_name()) );
164 tok_.set_position( Tokenizer::Position() );
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()) );
170 if (is_point)
tok_.skip_to(
"DataArray");
174 THROW(ExcUnknownFormat() << EI_FieldName(header.
field_name) << EI_VTKFile(
tok_.f_name()) );
183 pugi::xml_document doc;
184 doc.load_file(
tok_.f_name().c_str() );
185 unsigned int n_nodes, n_elements;
192 Tokenizer::Position appended_pos;
199 pugi::xml_node node = doc.child(
"VTKFile").child(
"UnstructuredGrid").child(
"Piece");
207 =
create_header( node.child(
"Cells").find_child_by_attribute(
"DataArray",
"Name",
"connectivity"), n_elements, appended_pos );
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 );
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;
223 HeaderTable::iterator table_it =
header_table_.find(field_name);
227 THROW( ExcFieldNameNotFound() << EI_FieldName(field_name) << EI_MeshFile(
tok_.f_name()));
230 return table_it->second;
252 if (it != types.end()) {
255 THROW( ExcWrongType() << EI_ErrMessage(
"Unknown") << EI_VTKFile(
tok_.f_name()));
265 static const std::vector<unsigned int> sizes = { 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 0 };
267 return sizes[data_type];
273 bool boundary_domain) {
275 ASSERT(!boundary_domain).error(
"Reading VTK data of boundary elements is not supported yet!\n");
278 case DataFormat::ascii: {
282 case DataFormat::binary_uncompressed: {
285 actual_header.
type );
288 case DataFormat::binary_zlib: {
300 LogOut().fmt(
"time: {}; {} entities of field {} read.\n",
306 Tokenizer::Position pos,
bool boundary_domain)
310 tok_.set_position( pos );
313 for (
unsigned int i_row = 0; i_row < n_entities; ++i_row) {
317 }
catch (boost::bad_lexical_cast &) {
318 THROW(ExcWrongFormat() << EI_Type(
"DataArray tag") << EI_TokenizerMsg(
tok_.position_msg())
319 << EI_MeshFile(
tok_.f_name()) );
325 Tokenizer::Position pos,
bool boundary_domain,
DataType value_type)
332 for (
unsigned int i_row = 0; i_row < n_entities; ++i_row) {
340 Tokenizer::Position pos,
bool boundary_domain,
DataType value_type)
348 block_sizes.reserve(n_blocks);
349 for (uint64_t i = 0; i < n_blocks; ++i) {
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];
360 data_stream_->read(&data_block[0], compressed_block_size);
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;
375 inflate(&strm, Z_NO_FLUSH);
379 decompressed_data << std::string(buffer.begin(), buffer.end());
380 decompressed_data_size += decompressed_block_size;
385 uint64_t data_size = decompressed_data_size /
type_value_size(value_type);
387 for (
unsigned int i_row = 0; i_row < n_entities; ++i_row) {
404 unsigned int i_node, i_elm_node;
411 for (
unsigned int i=0; i<point_header.
n_entities; ++i) {
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);
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()));
441 if (found_i_node == -1) {
442 THROW( ExcIncompatibleMesh() << EI_ErrMessage(
"no node found in GMSH file") << EI_VTKFile(
tok_.f_name()));
444 node_ids[i] = (
unsigned int)found_i_node;
445 searched_elements.clear();
468 con_header.
n_entities = offsets_vec[offsets_vec.size()-1];
484 unsigned int i_con = 0, last_offset=0, dim;
485 for (
unsigned int i=0; i<offsets_vec.size(); ++i) {
486 dim = offsets_vec[i] - last_offset - 1;
487 for ( ; i_con<offsets_vec[i]; ++i_con ) {
488 node_list.push_back( node_ids[connectivity_vec[i_con]] );
491 for (
auto i_elm : candidate_list) {
492 if ( mesh.
element( i_elm )->dim() == dim ) result_list.push_back(i_elm);
494 if (result_list.size() != 1) {
495 THROW( ExcIncompatibleMesh() << EI_ErrMessage(
"intersect_element_lists must produce one element")
496 << EI_VTKFile(
tok_.f_name()));
501 last_offset = offsets_vec[i];
522 ASSERT(
false).error(
"Reading of VTK mesh is not supported yet!");
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)
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)
std::string format(CStringRef format_str, ArgList args)
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.
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...
#define LogOut()
Macro defining 'log' record of log.
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
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.
unsigned int index(const T *pointer) const
~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
const BIHTree & get_bih_tree()
unsigned int n_read_
store count of read entities
Dedicated class for storing path to input and output files.
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)
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)
bool has_compatible_mesh_
DataType
Types of VTK data (value 'undefined' 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.
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.
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
ElementVector element
Vector of elements of the mesh.
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.