39 return Record(
"vtk",
"Parameters of vtk output format.")
43 "Variant of output stream file format.")
46 "Parallel or serial version of file format.")
52 return Selection(
"VTK variant (ascii or binary)")
54 "ASCII variant of VTK file format")
56 "Uncompressed appended binary XML VTK format without usage of base64 encoding of appended data.")
57 #ifdef FLOW123D_HAVE_ZLIB
59 "Appended binary XML VTK format without usage of base64 encoding of appended data. Compressed with ZLib.")
60 #endif // FLOW123D_HAVE_ZLIB
75 this->enable_refinement_ =
true;
83 this->write_time_frame();
92 const std::shared_ptr<TimeUnitConversion>& time_unit_conv)
97 variant_type_ = format_rec.val<
VTKVariant>(
"variant");
98 this->parallel_ = format_rec.val<
bool>(
"parallel");
99 this->fix_main_file_extension(
".pvd");
101 if(this->rank_ == 0) {
103 this->_base_filename.open_stream( this->_base_file );
104 this->set_stream_precision(this->_base_file);
105 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
107 LogOut() <<
"Writing flow output file: " << this->_base_filename <<
" ... ";
110 this->make_subdirectory();
117 if (this->parallel_) {
119 ss << basename <<
"/" << basename <<
"-"
120 << std::setw(6) << std::setfill(
'0') << i_step <<
"." << rank <<
".vtu";
123 ss << basename <<
"/" << basename <<
"-"
124 << std::setw(6) << std::setfill(
'0') << i_step <<
".vtu";
132 <<
"<DataSet timestep=\"" << step
133 <<
"\" group=\"\" part=\"" << rank
134 <<
"\" file=\"" << file
144 if ( (this->rank_ != 0) && (!parallel_) ) {
156 if (this->rank_ == 0) {
157 ASSERT(this->_base_file.is_open())(this->_base_filename).error();
164 double corrected_time = (isfinite(this->registered_time_)?this->registered_time_:0);
165 corrected_time /= this->time_unit_converter->get_coef();
167 for (
int i_rank=0; i_rank<n_proc_; ++i_rank) {
168 string file = this->form_vtu_filename_(main_output_basename_, current_step, i_rank);
172 string file = this->form_vtu_filename_(main_output_basename_, current_step, -1);
180 std::string frame_file_name = this->form_vtu_filename_(main_output_basename_, current_step, this->rank_);
184 this->set_stream_precision(_data_file);
185 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
187 LogOut() << __func__ <<
": Writing output (frame: " << this->current_step
188 <<
", rank: " << this->rank_
189 <<
") file: " << frame_file_name <<
" ... ";
191 this->write_vtk_vtu();
210 ASSERT_EQ(this->_base_filename.extension(),
".pvd").error();
211 main_output_dir_ = this->_base_filename.parent_path();
212 main_output_basename_ = this->_base_filename.stem();
214 if(this->rank_ == 0) {
215 vector<string> sub_path = { main_output_dir_, main_output_basename_,
"__tmp__" };
226 ofstream &file = this->_data_file;
228 file <<
"<?xml version=\"1.0\"?>" << endl;
231 file <<
"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\"";
232 if ( this->variant_type_ != VTKVariant::VARIANT_ASCII ) {
233 file <<
" header_type=\"UInt64\"";
235 if ( this->variant_type_ == VTKVariant::VARIANT_BINARY_ZLIB ) {
236 file <<
" compressor=\"vtkZLibDataCompressor\"";
239 file <<
"<UnstructuredGrid>" << endl;
246 auto &offsets = *( this->offsets_->get_data().get() );
247 unsigned int n_elements = offsets.size()-1;
253 for(
unsigned int i=0; i < n_elements; i++)
255 n_nodes = offsets[i+1]-offsets[i];
258 data[i] = (
unsigned int)VTK_LINE;
261 data[i] = (
unsigned int)VTK_TRIANGLE;
264 data[i] = (
unsigned int)VTK_TETRA;
278 "Int8",
"UInt8",
"Int16",
"UInt16",
"Int32",
"UInt32",
"Float32",
"Float64" };
280 ofstream &file = this->_data_file;
282 file <<
"<DataArray type=\"" << types[output_data->vtk_type()] <<
"\" ";
284 if( ! output_data->field_input_name().empty())
285 file <<
"Name=\"" << output_data->field_input_name() <<
"\" ";
287 if (output_data->n_comp() > 1)
290 <<
"NumberOfComponents=\"" << output_data->n_comp() <<
"\" ";
292 file <<
"format=\"" << formats[this->variant_type_] <<
"\"";
294 if ( this->variant_type_ == VTKVariant::VARIANT_ASCII ) {
298 output_data->print_ascii_all(file, start);
299 file <<
"\n</DataArray>" << endl;
302 double range_min, range_max;
303 output_data->get_min_max_range(range_min, range_max);
304 file <<
" offset=\"" << appended_data_.tellp() <<
"\" ";
305 file <<
"RangeMin=\"" << range_min <<
"\" RangeMax=\"" << range_max <<
"\"/>" << endl;
306 if ( this->variant_type_ == VTKVariant::VARIANT_BINARY_UNCOMPRESSED ) {
307 output_data->print_binary_all( appended_data_,
true, start );
309 stringstream uncompressed_data, compressed_data;
310 output_data->print_binary_all( uncompressed_data,
false, start );
311 this->compress_data(uncompressed_data, compressed_data);
312 appended_data_ << compressed_data.str();
321 static const size_t BUF_SIZE = 32 * 1024;
323 string uncompressed_string = uncompressed_stream.str();
324 zlib_ulong uncompressed_size = uncompressed_string.size();
325 stringstream compressed_data;
327 zlib_ulong count_of_blocks = (uncompressed_size + BUF_SIZE - 1) / BUF_SIZE;
328 zlib_ulong last_block_size = (uncompressed_size % BUF_SIZE);
329 compressed_stream.write(
reinterpret_cast<const char*
>(&count_of_blocks),
sizeof(
unsigned long long int));
330 compressed_stream.write(
reinterpret_cast<const char*
>(&BUF_SIZE),
sizeof(
unsigned long long int));
331 compressed_stream.write(
reinterpret_cast<const char*
>(&last_block_size),
sizeof(
unsigned long long int));
333 for (
zlib_ulong i=0; i<count_of_blocks; ++i) {
335 std::string data_block = uncompressed_string.substr(i*BUF_SIZE, BUF_SIZE);
336 zlib_ulong data_block_size = data_block.size();
339 uint8_t temp_buffer[BUF_SIZE];
345 strm.next_in =
reinterpret_cast<uint8_t *
>(&data_block[0]);
346 strm.avail_in = data_block_size;
347 strm.next_out = temp_buffer;
348 strm.avail_out = BUF_SIZE;
351 deflateInit(&strm, Z_BEST_COMPRESSION);
352 while (strm.avail_in != 0) {
353 int res = deflate(&strm, Z_NO_FLUSH);
355 if (strm.avail_out == 0) {
356 buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUF_SIZE);
357 strm.next_out = temp_buffer;
358 strm.avail_out = BUF_SIZE;
361 int deflate_res = Z_OK;
362 while (deflate_res == Z_OK) {
363 if (strm.avail_out == 0) {
364 buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUF_SIZE);
365 strm.next_out = temp_buffer;
366 strm.avail_out = BUF_SIZE;
368 deflate_res = deflate(&strm, Z_FINISH);
370 ASSERT_EQ(deflate_res, Z_STREAM_END).error();
371 buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUF_SIZE - strm.avail_out);
375 std::string str(buffer.begin(), buffer.end());
377 compressed_stream.write(
reinterpret_cast<const char*
>(&compressed_data_size),
sizeof(
unsigned long long int));
378 compressed_data << str;
381 compressed_stream << compressed_data.str();
388 if( ! data->is_dummy())
389 write_vtk_data(data);
398 if (output_data_vec.empty())
return;
400 file <<
"Scalars=\"";
403 && ! data->is_dummy())
404 file << data->field_input_name() <<
",";
407 file <<
"Vectors=\"";
410 && ! data->is_dummy())
411 file << data->field_input_name() <<
",";
414 file <<
"Tensors=\"";
417 && ! data->is_dummy())
418 file << data->field_input_name() <<
",";
425 ofstream &file = this->_data_file;
429 node_corner_data.insert(node_corner_data.end(),
430 output_data_vec_[CORNER_DATA].begin(), output_data_vec_[CORNER_DATA].end());
432 if( ! node_corner_data.empty() ) {
434 file <<
"<PointData ";
435 write_vtk_data_names(file, node_corner_data);
439 this->write_vtk_field_data(output_data_vec_[NODE_DATA]);
442 this->write_vtk_field_data(output_data_vec_[CORNER_DATA]);
445 file <<
"</PointData>" << endl;
452 ofstream &file = this->_data_file;
454 auto &data_map = this->output_data_vec_[ELEM_DATA];
455 if (data_map.empty())
return;
458 file <<
"<CellData ";
459 write_vtk_data_names(file, data_map);
463 this->write_vtk_field_data(data_map);
466 file <<
"</CellData>" << endl;
472 ofstream &file = this->_data_file;
474 auto &data_map = this->output_data_vec_[NATIVE_DATA];
475 if (data_map.empty())
return;
478 file <<
"<Flow123dData ";
479 write_vtk_data_names(file, data_map);
484 file <<
"<DataArray type=\"Float64\" ";
485 file <<
"Name=\"" << output_data->field_input_name() <<
"\" ";
486 file <<
"format=\"" << formats[this->variant_type_] <<
"\" ";
487 file <<
"dof_handler_hash=\"" << output_data->dof_handler_hash() <<
"\" ";
488 file <<
"n_dofs_per_element=\"" << output_data->n_dofs_per_element() <<
"\"";
491 if ( this->variant_type_ == VTKVariant::VARIANT_ASCII ) {
495 output_data->print_ascii_all(file);
496 file <<
"\n</DataArray>" << endl;
499 double range_min, range_max;
500 output_data->get_min_max_range(range_min, range_max);
501 file <<
" offset=\"" << appended_data_.tellp() <<
"\" ";
502 file <<
"RangeMin=\"" << range_min <<
"\" RangeMax=\"" << range_max <<
"\"/>" << endl;
503 if ( this->variant_type_ == VTKVariant::VARIANT_BINARY_UNCOMPRESSED ) {
504 output_data->print_binary_all( appended_data_ );
506 stringstream uncompressed_data, compressed_data;
507 output_data->print_binary_all( uncompressed_data,
false );
508 this->compress_data(uncompressed_data, compressed_data);
509 appended_data_ << compressed_data.str();
515 file <<
"</Flow123dData>" << endl;
521 ofstream &file = this->_data_file;
523 file <<
"</UnstructuredGrid>" << endl;
524 if ( this->variant_type_ != VTKVariant::VARIANT_ASCII ) {
526 file <<
"<AppendedData encoding=\"raw\">" << endl;
528 file <<
"_" << appended_data_.str() << endl;
529 file <<
"</AppendedData>" << endl;
531 file <<
"</VTKFile>" << endl;
537 ofstream &file = this->_data_file;
540 this->write_vtk_vtu_head();
543 file <<
"<Piece NumberOfPoints=\"" << this->nodes_->n_values()
544 <<
"\" NumberOfCells=\"" << this->offsets_->n_values()-1 <<
"\">" << endl;
547 file <<
"<Points>" << endl;
548 write_vtk_data(this->nodes_);
549 file <<
"</Points>" << endl;
552 file <<
"<Cells>" << endl;
553 write_vtk_data(this->connectivity_);
554 write_vtk_data(this->offsets_, 1);
555 auto types = fill_element_types_data();
556 write_vtk_data( types );
557 file <<
"</Cells>" << endl;
560 this->write_vtk_node_data();
563 this->write_vtk_element_data();
566 this->write_vtk_native_data();
569 file <<
"</Piece>" << endl;
572 this->write_vtk_vtu_tail();
580 if(this->rank_ != 0) {
584 LogOut() << __func__ <<
": Writing output file (head) " << this->_base_filename <<
" ... ";
586 this->_base_file <<
"<?xml version=\"1.0\"?>" << endl;
587 this->_base_file <<
"<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
588 this->_base_file <<
"<Collection>" << endl;
599 if(this->rank_ != 0) {
603 LogOut() << __func__ <<
": Writing output file (tail) " << this->_base_filename <<
" ... ";
605 this->_base_file <<
"</Collection>" << endl;
606 this->_base_file <<
"</VTKFile>" << endl;