40 return Record(
"vtk",
"Parameters of vtk output format.")
44 "Variant of output stream file format.")
47 "Parallel or serial version of file format.")
53 return Selection(
"VTK variant (ascii or binary)")
55 "ASCII variant of VTK file format")
57 "Uncompressed appended binary XML VTK format without usage of base64 encoding of appended data.")
58 #ifdef FLOW123D_HAVE_ZLIB
60 "Appended binary XML VTK format without usage of base64 encoding of appended data. Compressed with ZLib.")
61 #endif // FLOW123D_HAVE_ZLIB
76 this->enable_refinement_ =
true;
93 variant_type_ = format_rec.val<
VTKVariant>(
"variant");
94 this->parallel_ = format_rec.val<
bool>(
"parallel");
95 this->fix_main_file_extension(
".pvd");
97 if(this->rank_ == 0) {
99 this->_base_filename.open_stream( this->_base_file );
100 this->set_stream_precision(this->_base_file);
101 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
103 LogOut() <<
"Writing flow output file: " << this->_base_filename <<
" ... ";
106 this->make_subdirectory();
113 if (this->parallel_) {
115 ss << main_output_basename_ <<
"/" << main_output_basename_ <<
"-"
116 << std::setw(6) << std::setfill(
'0') << current_step <<
"." << rank <<
".vtu";
119 ss << main_output_basename_ <<
"/" << main_output_basename_ <<
"-"
120 << std::setw(6) << std::setfill(
'0') << current_step <<
".vtu";
128 <<
"<DataSet timestep=\"" << step
129 <<
"\" group=\"\" part=\"" << rank
130 <<
"\" file=\"" << file
140 if ( (this->rank_ != 0) && (!parallel_) ) {
152 if (this->rank_ == 0) {
153 ASSERT(this->_base_file.is_open())(this->_base_filename).error();
160 double corrected_time = (isfinite(this->time)?this->time:0);
163 for (
int i_rank=0; i_rank<n_proc_; ++i_rank) {
164 string file = this->form_vtu_filename_(main_output_basename_, current_step, i_rank);
168 string file = this->form_vtu_filename_(main_output_basename_, current_step, -1);
176 std::string frame_file_name = this->form_vtu_filename_(main_output_basename_, current_step, this->rank_);
180 this->set_stream_precision(_data_file);
181 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, input_record_)
183 LogOut() << __func__ <<
": Writing output (frame: " << this->current_step
184 <<
", rank: " << this->rank_
185 <<
") file: " << frame_file_name <<
" ... ";
187 this->write_vtk_vtu();
206 ASSERT_EQ(this->_base_filename.extension(),
".pvd").error();
207 main_output_dir_ = this->_base_filename.parent_path();
208 main_output_basename_ = this->_base_filename.stem();
210 if(this->rank_ == 0) {
211 vector<string> sub_path = { main_output_dir_, main_output_basename_,
"__tmp__" };
222 ofstream &file = this->_data_file;
224 file <<
"<?xml version=\"1.0\"?>" << endl;
227 file <<
"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\"";
228 if ( this->variant_type_ != VTKVariant::VARIANT_ASCII ) {
229 file <<
" header_type=\"UInt64\"";
231 if ( this->variant_type_ == VTKVariant::VARIANT_BINARY_ZLIB ) {
232 file <<
" compressor=\"vtkZLibDataCompressor\"";
235 file <<
"<UnstructuredGrid>" << endl;
242 auto &offsets = *( this->offsets_->get_component_data(0).get() );
243 unsigned int n_elements = offsets.size();
249 n_nodes = offsets[0];
252 data[0] = (
unsigned int)VTK_LINE;
255 data[0] = (
unsigned int)VTK_TRIANGLE;
258 data[0] = (
unsigned int)VTK_TETRA;
262 for(
unsigned int i=1; i < n_elements; i++)
264 n_nodes = offsets[i]-offsets[i-1];
267 data[i] = (
unsigned int)VTK_LINE;
270 data[i] = (
unsigned int)VTK_TRIANGLE;
273 data[i] = (
unsigned int)VTK_TETRA;
287 "Int8",
"UInt8",
"Int16",
"UInt16",
"Int32",
"UInt32",
"Float32",
"Float64" };
289 ofstream &file = this->_data_file;
291 file <<
"<DataArray type=\"" << types[output_data->vtk_type()] <<
"\" ";
293 if( ! output_data->field_input_name().empty())
294 file <<
"Name=\"" << output_data->field_input_name() <<
"\" ";
296 if (output_data->n_comp() > 1)
299 <<
"NumberOfComponents=\"" << output_data->n_comp() <<
"\" ";
301 file <<
"format=\"" << formats[this->variant_type_] <<
"\"";
303 if ( this->variant_type_ == VTKVariant::VARIANT_ASCII ) {
307 output_data->print_ascii_all(file);
308 file <<
"\n</DataArray>" << endl;
311 double range_min, range_max;
312 output_data->get_min_max_range(range_min, range_max);
313 file <<
" offset=\"" << appended_data_.tellp() <<
"\" ";
314 file <<
"RangeMin=\"" << range_min <<
"\" RangeMax=\"" << range_max <<
"\"/>" << endl;
315 if ( this->variant_type_ == VTKVariant::VARIANT_BINARY_UNCOMPRESSED ) {
316 output_data->print_binary_all( appended_data_ );
318 stringstream uncompressed_data, compressed_data;
319 output_data->print_binary_all( uncompressed_data,
false );
320 this->compress_data(uncompressed_data, compressed_data);
321 appended_data_ << compressed_data.str();
330 static const size_t BUF_SIZE = 32 * 1024;
332 string uncompressed_string = uncompressed_stream.str();
333 uLong uncompressed_size = uncompressed_string.size();
334 stringstream compressed_data;
336 uLong count_of_blocks = (uncompressed_size + BUF_SIZE - 1) / BUF_SIZE;
337 uLong last_block_size = (uncompressed_size % BUF_SIZE);
338 compressed_stream.write(
reinterpret_cast<const char*
>(&count_of_blocks),
sizeof(
unsigned long long int));
339 compressed_stream.write(
reinterpret_cast<const char*
>(&BUF_SIZE),
sizeof(
unsigned long long int));
340 compressed_stream.write(
reinterpret_cast<const char*
>(&last_block_size),
sizeof(
unsigned long long int));
342 for (uLong i=0; i<count_of_blocks; ++i) {
344 std::string data_block = uncompressed_string.substr(i*BUF_SIZE, BUF_SIZE);
345 uLong data_block_size = data_block.size();
348 uint8_t temp_buffer[BUF_SIZE];
354 strm.next_in =
reinterpret_cast<uint8_t *
>(&data_block[0]);
355 strm.avail_in = data_block_size;
356 strm.next_out = temp_buffer;
357 strm.avail_out = BUF_SIZE;
360 deflateInit(&strm, Z_BEST_COMPRESSION);
361 while (strm.avail_in != 0) {
362 int res = deflate(&strm, Z_NO_FLUSH);
364 if (strm.avail_out == 0) {
365 buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUF_SIZE);
366 strm.next_out = temp_buffer;
367 strm.avail_out = BUF_SIZE;
370 int deflate_res = Z_OK;
371 while (deflate_res == Z_OK) {
372 if (strm.avail_out == 0) {
373 buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUF_SIZE);
374 strm.next_out = temp_buffer;
375 strm.avail_out = BUF_SIZE;
377 deflate_res = deflate(&strm, Z_FINISH);
379 ASSERT_EQ(deflate_res, Z_STREAM_END).error();
380 buffer.insert(buffer.end(), temp_buffer, temp_buffer + BUF_SIZE - strm.avail_out);
384 std::string str(buffer.begin(), buffer.end());
385 uLong compressed_data_size = str.size();
386 compressed_stream.write(
reinterpret_cast<const char*
>(&compressed_data_size),
sizeof(
unsigned long long int));
387 compressed_data << str;
390 compressed_stream << compressed_data.str();
397 if( ! data->is_dummy())
398 write_vtk_data(data);
407 if (output_data_vec.empty())
return;
409 file <<
"Scalars=\"";
412 && ! data->is_dummy())
413 file << data->field_input_name() <<
",";
416 file <<
"Vectors=\"";
419 && ! data->is_dummy())
420 file << data->field_input_name() <<
",";
423 file <<
"Tensors=\"";
426 && ! data->is_dummy())
427 file << data->field_input_name() <<
",";
434 ofstream &file = this->_data_file;
438 node_corner_data.insert(node_corner_data.end(),
439 output_data_vec_[CORNER_DATA].begin(), output_data_vec_[CORNER_DATA].end());
441 if( ! node_corner_data.empty() ) {
443 file <<
"<PointData ";
444 write_vtk_data_names(file, node_corner_data);
448 this->write_vtk_field_data(output_data_vec_[NODE_DATA]);
451 this->write_vtk_field_data(output_data_vec_[CORNER_DATA]);
454 file <<
"</PointData>" << endl;
461 ofstream &file = this->_data_file;
463 auto &data_map = this->output_data_vec_[ELEM_DATA];
464 if (data_map.empty())
return;
467 file <<
"<CellData ";
468 write_vtk_data_names(file, data_map);
472 this->write_vtk_field_data(data_map);
475 file <<
"</CellData>" << endl;
481 ofstream &file = this->_data_file;
483 auto &data_map = this->output_data_vec_[NATIVE_DATA];
484 if (data_map.empty())
return;
487 file <<
"<Flow123dData ";
488 write_vtk_data_names(file, data_map);
493 file <<
"<DataArray type=\"Float64\" ";
494 file <<
"Name=\"" << output_data->field_input_name() <<
"\" ";
495 file <<
"format=\"" << formats[this->variant_type_] <<
"\" ";
496 file <<
"dof_handler_hash=\"" << output_data->dof_handler_hash() <<
"\" ";
497 file <<
"n_dofs_per_element=\"" << output_data->n_comp() <<
"\"";
499 if ( this->variant_type_ == VTKVariant::VARIANT_ASCII ) {
502 file << std::fixed << std::setprecision(10);
503 output_data->print_ascii_all(file);
504 file <<
"\n</DataArray>" << endl;
507 double range_min, range_max;
508 output_data->get_min_max_range(range_min, range_max);
509 file <<
" offset=\"" << appended_data_.tellp() <<
"\" ";
510 file <<
"RangeMin=\"" << range_min <<
"\" RangeMax=\"" << range_max <<
"\"/>" << endl;
511 if ( this->variant_type_ == VTKVariant::VARIANT_BINARY_UNCOMPRESSED ) {
512 output_data->print_binary_all( appended_data_ );
514 stringstream uncompressed_data, compressed_data;
515 output_data->print_binary_all( uncompressed_data,
false );
516 this->compress_data(uncompressed_data, compressed_data);
517 appended_data_ << compressed_data.str();
523 file <<
"</Flow123dData>" << endl;
529 ofstream &file = this->_data_file;
531 file <<
"</UnstructuredGrid>" << endl;
532 if ( this->variant_type_ != VTKVariant::VARIANT_ASCII ) {
534 file <<
"<AppendedData encoding=\"raw\">" << endl;
536 file <<
"_" << appended_data_.str() << endl;
537 file <<
"</AppendedData>" << endl;
539 file <<
"</VTKFile>" << endl;
545 ofstream &file = this->_data_file;
548 this->write_vtk_vtu_head();
551 file <<
"<Piece NumberOfPoints=\"" << this->nodes_->n_values()
552 <<
"\" NumberOfCells=\"" << this->offsets_->n_values() <<
"\">" << endl;
555 file <<
"<Points>" << endl;
556 write_vtk_data(this->nodes_);
557 file <<
"</Points>" << endl;
560 file <<
"<Cells>" << endl;
561 write_vtk_data(this->connectivity_);
562 write_vtk_data(this->offsets_);
563 auto types = fill_element_types_data();
564 write_vtk_data( types );
565 file <<
"</Cells>" << endl;
568 this->write_vtk_node_data();
571 this->write_vtk_element_data();
574 this->write_vtk_native_data();
577 file <<
"</Piece>" << endl;
580 this->write_vtk_vtu_tail();
588 if(this->rank_ != 0) {
592 LogOut() << __func__ <<
": Writing output file (head) " << this->_base_filename <<
" ... ";
594 this->_base_file <<
"<?xml version=\"1.0\"?>" << endl;
595 this->_base_file <<
"<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
596 this->_base_file <<
"<Collection>" << endl;
607 if(this->rank_ != 0) {
611 LogOut() << __func__ <<
": Writing output file (tail) " << this->_base_filename <<
" ... ";
613 this->_base_file <<
"</Collection>" << endl;
614 this->_base_file <<
"</VTKFile>" << endl;