22 #include <pugixml.hpp>
23 #include "boost/lexical_cast.hpp"
43 data_stream.read(
reinterpret_cast<char *
>(&val),
sizeof(val));
55 ASSERT(
false).error(
"Unsupported header_type!\n");
103 }
catch(ExcWrongType &e) {
104 e << EI_SectionTypeName(
"base parameter header_type");
113 THROW( ExcWrongType() << EI_ErrMessage(
"Forbidden") << EI_SectionTypeName(
"base parameter header_type")
114 << EI_VTKFile(
tok_.f_name()));
116 std::string compressor = vtk_node.attribute(
"compressor").as_string();
117 if (compressor ==
"vtkZLibDataCompressor")
123 pugi::xml_node piece_node = vtk_node.child(
"UnstructuredGrid").child(
"Piece");
124 n_nodes = piece_node.attribute(
"NumberOfPoints").as_uint();
125 n_elements = piece_node.attribute(
"NumberOfCells").as_uint();
131 Tokenizer::Position appended_pos;
135 tok_.set_position( Tokenizer::Position() );
136 if (!
tok_.skip_to(
"AppendedData"))
137 THROW(ExcMissingTag() << EI_TagType(
"tag") << EI_TagName(
"AppendedData") << EI_VTKFile(
tok_.f_name()) );
139 appended_pos =
tok_.get_position();
150 appended_pos.line_counter_++;
154 data_stream_ =
new std::ifstream(
tok_.f_name(), std::ios_base::in | std::ios_base::binary );
164 header.
field_name = node.attribute(
"Name").as_string();
168 }
catch(ExcWrongType &e) {
169 e << EI_SectionTypeName(
"DataArray " + header.
field_name);
172 if (disc == OutputTime::DiscreteSpace::NATIVE_DATA) {
173 header.
n_components = node.attribute(
"n_dofs_per_element").as_uint();
176 header.
n_components = node.attribute(
"NumberOfComponents").as_uint(1);
179 std::string
format = node.attribute(
"format").as_string();
182 THROW(ExcInvalidFormat() << EI_FieldName(header.
field_name) << EI_ExpectedFormat(
"ascii") << EI_VTKFile(
tok_.f_name()) );
183 std::streampos file_pos = pos.file_position_;
184 file_pos += node.attribute(
"offset").as_uint();
185 header.
position = Tokenizer::Position( file_pos, pos.line_counter_, pos.line_position_ );
186 }
else if (
format==
"ascii") {
188 THROW(ExcInvalidFormat() << EI_FieldName(header.
field_name) << EI_ExpectedFormat(
"appended") << EI_VTKFile(
tok_.f_name()) );
190 tok_.set_position( Tokenizer::Position() );
192 std::string found_str = (is_point) ?
"<Points>" :
"Name=\"" + header.
field_name +
"\"";
193 if (!
tok_.skip_to(found_str))
194 THROW(ExcMissingTag() << EI_TagType(
"DataArray tag") << EI_TagName(header.
field_name) << EI_VTKFile(
tok_.f_name()) );
196 if (is_point)
tok_.skip_to(
"DataArray");
200 THROW(ExcUnknownFormat() << EI_FieldName(header.
field_name) << EI_VTKFile(
tok_.f_name()) );
209 pugi::xml_document doc;
210 doc.load_file(
tok_.f_name().c_str() );
211 unsigned int n_nodes, n_elements;
218 Tokenizer::Position appended_pos;
225 pugi::xml_node node = doc.child(
"VTKFile").child(
"UnstructuredGrid").child(
"Piece");
230 auto points_header =
create_header( node.child(
"Points").child(
"DataArray"), n_nodes, appended_pos,
231 OutputTime::DiscreteSpace::MESH_DEFINITION );
232 points_header.field_name =
"Points";
233 header_table_.insert( std::pair<std::string, MeshDataHeader>(
"Points", points_header) );
234 auto con_header =
create_header( node.child(
"Cells").find_child_by_attribute(
"DataArray",
"Name",
"connectivity"),
235 n_elements, appended_pos, OutputTime::DiscreteSpace::MESH_DEFINITION );
236 header_table_.insert( std::pair<std::string, MeshDataHeader>(
"connectivity", con_header) );
237 auto offsets_header =
create_header( node.child(
"Cells").find_child_by_attribute(
"DataArray",
"Name",
"offsets"),
238 n_elements, appended_pos, OutputTime::DiscreteSpace::MESH_DEFINITION );
239 header_table_.insert( std::pair<std::string, MeshDataHeader>(
"offsets", offsets_header) );
240 auto types_header =
create_header( node.child(
"Cells").find_child_by_attribute(
"DataArray",
"Name",
"types"), n_elements,
241 appended_pos, OutputTime::DiscreteSpace::MESH_DEFINITION );
242 header_table_.insert( std::pair<std::string, MeshDataHeader>(
"types", types_header) );
244 pugi::xml_node point_node = node.child(
"PointData");
245 for (pugi::xml_node subnode = point_node.child(
"DataArray"); subnode; subnode = subnode.next_sibling(
"DataArray")) {
246 auto header =
create_header( subnode, n_nodes, appended_pos, OutputTime::DiscreteSpace::NODE_DATA );
247 header_table_.insert( std::pair<std::string, MeshDataHeader>(header.field_name, header) );
250 pugi::xml_node cell_node = node.child(
"CellData");
251 for (pugi::xml_node subnode = cell_node.child(
"DataArray"); subnode; subnode = subnode.next_sibling(
"DataArray")) {
252 auto header =
create_header( subnode, n_elements, appended_pos, OutputTime::DiscreteSpace::ELEM_DATA );
253 header_table_.insert( std::pair<std::string, MeshDataHeader>(header.field_name, header) );
256 pugi::xml_node native_node = node.child(
"Flow123dData");
257 for (pugi::xml_node subnode = native_node.child(
"DataArray"); subnode; subnode = subnode.next_sibling(
"DataArray")) {
258 auto header =
create_header( subnode, n_elements, appended_pos, OutputTime::DiscreteSpace::NATIVE_DATA );
259 header_table_.insert( std::pair<std::string, MeshDataHeader>(header.field_name, header) );
270 THROW( ExcFieldNameNotFound() << EI_FieldName(header_query.
field_name) << EI_MeshFile(
tok_.f_name()));
271 }
else if (count == 1) {
275 if (header_query.
discretization != table_it->second.discretization) {
276 if (header_query.
discretization != OutputTime::DiscreteSpace::UNDEFINED) {
278 "Invalid value of 'input_discretization' for field '{}', time: {}.\nCorrect discretization type will be used.\n",
284 if (header_query.
discretization == OutputTime::DiscreteSpace::NATIVE_DATA)
286 THROW(ExcInvalidDofHandler() << EI_FieldName(header_query.
field_name) << EI_VTKFile(
tok_.f_name()) );
297 THROW( ExcMissingFieldDiscretization() << EI_FieldName(header_query.
field_name) << EI_Time(header_query.
time) << EI_MeshFile(
tok_.f_name()));
322 if (
it != types.end()) {
325 THROW( ExcWrongType() << EI_ErrMessage(
"Unknown") << EI_VTKFile(
tok_.f_name()));
335 static const std::vector<unsigned int> sizes = { 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 0 };
337 return sizes[data_type];
343 bool boundary_domain) {
345 ASSERT(!boundary_domain).error(
"Reading VTK data of boundary elements is not supported yet!\n");
348 case DataFormat::ascii: {
352 case DataFormat::binary_uncompressed: {
357 case DataFormat::binary_zlib: {
368 LogOut().fmt(
"time: {}; {} entities of field {} read.\n",
374 Tokenizer::Position pos)
378 tok_.set_position( pos );
381 for (
unsigned int i_row = 0; i_row < n_entities; ++i_row) {
385 }
catch (boost::bad_lexical_cast &) {
386 THROW(ExcWrongFormat() << EI_Type(
"DataArray tag") << EI_TokenizerMsg(
tok_.position_msg())
387 << EI_MeshFile(
tok_.f_name()) );
393 Tokenizer::Position pos)
400 for (
unsigned int i_row = 0; i_row < n_entities; ++i_row) {
408 Tokenizer::Position pos)
416 block_sizes.reserve(n_blocks);
417 for (uint64_t i = 0; i < n_blocks; ++i) {
421 stringstream decompressed_data;
422 uint64_t decompressed_data_size = 0;
423 for (uint64_t i = 0; i < n_blocks; ++i) {
424 uint64_t decompressed_block_size = (i==n_blocks-1 && p_size>0) ? p_size : u_size;
425 uint64_t compressed_block_size = block_sizes[i];
428 data_stream_->read(&data_block[0], compressed_block_size);
436 strm.next_in = (Bytef *)(&data_block[0]);
437 strm.avail_in = compressed_block_size;
438 strm.next_out = (Bytef *)(&buffer[0]);
439 strm.avail_out = decompressed_block_size;
443 inflate(&strm, Z_NO_FLUSH);
447 decompressed_data << std::string(buffer.begin(), buffer.end());
448 decompressed_data_size += decompressed_block_size;
453 for (
unsigned int i_row = 0; i_row < n_entities; ++i_row) {
474 unsigned int n_nodes = vect.size()/3;
477 for (
unsigned int i=0, ivec=0; i<n_nodes; ++i) {
478 point(0)=vect[ivec]; ++ivec;
479 point(1)=vect[ivec]; ++ivec;
480 point(2)=vect[ivec]; ++ivec;
491 ASSERT(offset_it !=
element_data_values_->end()).error(
"Missing cache of offsets section. Did you call create_node_element_caches()?\n");
496 ASSERT(conn_it !=
element_data_values_->end()).error(
"Missing cache of offsets section. Did you call create_node_element_caches()?\n");
504 unsigned int i_con = 0, last_offset=0, dim;
506 for (
unsigned int i=0; i<offsets_vec.size(); ++i) {
507 dim = offsets_vec[i] - last_offset - 1;
508 for ( ; i_con<offsets_vec[i]; ++i_con ) {
509 node_list.push_back( connectivity_vec[i_con] );
514 last_offset = offsets_vec[i];
531 HeaderQuery header_params(
"Points", 0.0, OutputTime::DiscreteSpace::MESH_DEFINITION);
532 auto point_header = this->
find_header(header_params);
535 this->get_element_data<double>(point_header.n_entities, point_header.n_components,
false, 0 );
538 HeaderQuery offsets_params(
"offsets", 0.0, OutputTime::DiscreteSpace::MESH_DEFINITION);
539 auto offset_header = this->
find_header(offsets_params);
541 std::vector<unsigned int> &offsets_vec = *( this->get_element_data<unsigned int>(offset_header.n_entities, offset_header.n_components,
false, 0 ) );
544 HeaderQuery con_params(
"connectivity", 0.0, OutputTime::DiscreteSpace::MESH_DEFINITION);
546 con_header.n_entities = offsets_vec[offsets_vec.size()-1];
548 this->get_element_data<unsigned int>(con_header.n_entities, con_header.n_components,
false, 0 );