28#ifndef EWOMS_VTK_MULTI_WRITER_HH
29#define EWOMS_VTK_MULTI_WRITER_HH
31#include <dune/common/fvector.hh>
32#include <dune/common/version.hh>
33#include <dune/grid/io/file/vtk/vtkwriter.hh>
34#include <dune/istl/bvector.hh>
36#include <opm/material/common/Valgrind.hpp>
63template <
class Gr
idView, Dune::VTK::OutputType vtkFormat>
70 : multiWriter_(multiWriter)
73 void run()
override final
77 if (multiWriter_.commSize_ > 1) {
78 fileName = multiWriter_.curWriter_->pwrite(multiWriter_.curOutFileName_,
79 multiWriter_.outputDir_,
84 fileName = multiWriter_.curWriter_->write(multiWriter_.outputDir_ +
"/" +
85 multiWriter_.curOutFileName_,
92 const std::filesystem::path fullPath{fileName};
93 const std::string localFileName = fullPath.filename();
94 multiWriter_.multiFile_.precision(16);
95 multiWriter_.multiFile_ <<
" <DataSet timestep=\"" << multiWriter_.curTime_ <<
"\" file=\""
96 << localFileName <<
"\"/>\n";
103 enum { dim = GridView::dimension };
105 using VertexMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
106 using ElementMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
119 const GridView& gridView,
120 const std::string& outputDir,
121 const std::string& simName =
"",
122 const std::string& multiFileName =
"")
123 : gridView_(gridView)
124 , elementMapper_(gridView,
Dune::mcmgElementLayout())
125 , vertexMapper_(gridView,
Dune::mcmgVertexLayout())
126 , outputDir_(outputDir.empty() ?
"." : outputDir)
127 , simName_(simName.empty() ?
"sim" : simName)
128 , multiFileName_(multiFileName.empty() ? outputDir_ +
"/" + simName_ +
".pvd" : multiFileName)
129 , commSize_(gridView.comm().size())
130 , commRank_(gridView.comm().rank())
132 , taskletRunner_(asyncWriting ? 1 : 0)
141 if (commRank_ == 0) {
150 {
return curWriterNum_; }
169 gridView_ = gridView;
175 elementMapper_.update(gridView_);
176 vertexMapper_.update(gridView_);
184 if (!multiFile_.is_open()) {
185 startMultiFile_(multiFileName_);
194 curOutFileName_ = fileName_();
196 curWriter_ = std::make_unique<VtkWriter>(gridView_, Dune::VTK::conforming);
208 managedScalarBuffers_.emplace_back(std::make_unique<ScalarBuffer>(numEntities));
209 return managedScalarBuffers_.back().get();
220 managedVectorBuffers_.emplace_back(std::make_unique<VectorBuffer>(numOuter));
221 for (
auto& buffer : *managedVectorBuffers_.back()) {
222 buffer.resize(numInner);
225 return managedVectorBuffers_.back().get();
246 sanitizeScalarBuffer_(buf);
249 curWriter_->addVertexData(std::make_shared<VtkFn>(name,
273 sanitizeScalarBuffer_(buf);
276 curWriter_->addCellData(std::make_shared<VtkFn>(name,
301 sanitizeVectorBuffer_(buf);
304 curWriter_->addVertexData(std::make_shared<VtkFn>(name,
318 for (
unsigned colIdx = 0; colIdx < buf[0].N(); ++colIdx) {
319 std::ostringstream oss;
320 oss << name <<
"[" << colIdx <<
"]";
321 curWriter_->addVertexData(std::make_shared<VtkFn>(oss.str(),
347 sanitizeVectorBuffer_(buf);
350 curWriter_->addCellData(std::make_shared<VtkFn>(name,
364 for (
unsigned colIdx = 0; colIdx < buf[0].N(); ++colIdx) {
365 std::ostringstream oss;
366 oss << name <<
"[" << colIdx <<
"]";
367 curWriter_->addCellData(std::make_shared<VtkFn>(oss.str(),
386 auto tasklet = std::make_shared<WriteDataTasklet>(*
this);
402 template <
class Restarter>
405 res.serializeSectionBegin(
"VTKMultiWriter");
406 res.serializeStream() << curWriterNum_ <<
"\n";
408 if (commRank_ == 0) {
409 std::streamsize fileLen = 0;
410 std::streamoff filePos = 0;
411 if (multiFile_.is_open()) {
413 filePos = multiFile_.tellp();
414 multiFile_.seekp(0, std::ios::end);
415 fileLen = multiFile_.tellp();
416 multiFile_.seekp(filePos);
419 res.serializeStream() << fileLen <<
" " << filePos <<
"\n";
422 std::ifstream multiFileIn(multiFileName_.c_str());
423 std::vector<char> tmp(fileLen);
424 multiFileIn.read(tmp.data(),
static_cast<long>(fileLen));
425 res.serializeStream().write(tmp.data(), fileLen);
429 res.serializeSectionEnd();
435 template <
class Restarter>
438 res.deserializeSectionBegin(
"VTKMultiWriter");
439 res.deserializeStream() >> curWriterNum_;
441 if (commRank_ == 0) {
443 std::getline(res.deserializeStream(), dummy);
446 std::streamoff filePos;
447 std::streamsize fileLen;
448 res.deserializeStream() >> fileLen >> filePos;
449 std::getline(res.deserializeStream(), dummy);
450 if (multiFile_.is_open()) {
455 multiFile_.open(multiFileName_);
457 std::vector<char> tmp(fileLen);
458 res.deserializeStream().read(tmp.data(), fileLen);
459 multiFile_.write(tmp.data(), fileLen);
462 multiFile_.seekp(filePos);
466 std::getline(res.deserializeStream(), tmp);
468 res.deserializeSectionEnd();
472 std::string fileName_()
const
475 std::ostringstream oss;
476 oss << simName_ <<
"-"
477 << std::setw(5) << std::setfill(
'0') << curWriterNum_;
481 static std::string fileSuffix_()
482 {
return (GridView::dimension == 1) ?
"vtp" :
"vtu"; }
484 void startMultiFile_(
const std::string& multiFileName)
487 if (commRank_ == 0) {
489 multiFile_.open(multiFileName);
490 multiFile_ <<
"<?xml version=\"1.0\"?>\n"
491 "<VTKFile type=\"Collection\"\n"
493 " byte_order=\"LittleEndian\"\n"
494 " compressor=\"vtkZLibDataCompressor\">\n"
499 void finishMultiFile_()
502 if (commRank_ == 0) {
504 std::ofstream::pos_type pos = multiFile_.tellp();
505 multiFile_ <<
" </Collection>\n"
507 multiFile_.seekp(pos);
525 void releaseBuffers_()
529 managedScalarBuffers_.clear();
530 managedVectorBuffers_.clear();
534 ElementMapper elementMapper_;
535 VertexMapper vertexMapper_;
537 const std::string outputDir_;
538 const std::string simName_;
539 std::ofstream multiFile_;
540 const std::string multiFileName_;
545 std::unique_ptr<VtkWriter> curWriter_;
547 std::string curOutFileName_;
550 std::vector<std::unique_ptr<ScalarBuffer>> managedScalarBuffers_;
551 std::vector<std::unique_ptr<VectorBuffer>> managedVectorBuffers_;
553 TaskletRunner taskletRunner_;
The base class for all output writers.
Definition: baseoutputwriter.hh:46
Dune::DynamicVector< double > Vector
Definition: baseoutputwriter.hh:50
std::vector< Tensor > TensorBuffer
Definition: baseoutputwriter.hh:52
Dune::DynamicMatrix< double > Tensor
Definition: baseoutputwriter.hh:49
std::vector< Vector > VectorBuffer
Definition: baseoutputwriter.hh:53
std::vector< Scalar > ScalarBuffer
Definition: baseoutputwriter.hh:51
double Scalar
Definition: baseoutputwriter.hh:48
The base class for tasklets.
Definition: tasklets.hpp:45
void barrier()
Make sure that all tasklets have been completed after this method has been called.
void dispatch(std::shared_ptr< TaskletInterface > tasklet)
Add a new tasklet.
Simplifies writing multi-file VTK datasets.
Definition: vtkmultiwriter.hh:65
VectorBuffer * allocateManagedVectorBuffer(std::size_t numOuter, std::size_t numInner)
Allocate a managed buffer for a vector field.
Definition: vtkmultiwriter.hh:218
void attachTensorElementData(TensorBuffer &buf, std::string_view name) override
Add a finished element-centered tensor field to the output.
Definition: vtkmultiwriter.hh:360
void deserialize(Restarter &res)
Read the multi-writer's state from a restart file.
Definition: vtkmultiwriter.hh:436
void endWrite(bool onlyDiscard) override
Finalizes the current writer.
Definition: vtkmultiwriter.hh:383
void attachScalarVertexData(ScalarBuffer &buf, std::string_view name) override
Add a finished vertex centered vector field to the output.
Definition: vtkmultiwriter.hh:244
BaseOutputWriter::ScalarBuffer ScalarBuffer
Definition: vtkmultiwriter.hh:112
int curWriterNum() const
Returns the number of the current VTK file.
Definition: vtkmultiwriter.hh:149
void gridChanged()
Definition: vtkmultiwriter.hh:173
void beginWrite(double t) override
Called whenever a new time step must be written.
Definition: vtkmultiwriter.hh:182
void attachVectorVertexData(VectorBuffer &buf, std::string_view name) override
Add a finished vertex centered vector field to the output.
Definition: vtkmultiwriter.hh:299
ScalarBuffer * allocateManagedScalarBuffer(std::size_t numEntities)
Allocate a managed buffer for a scalar field.
Definition: vtkmultiwriter.hh:206
void attachVectorElementData(VectorBuffer &buf, std::string_view name) override
Add a element centered quantity to the output.
Definition: vtkmultiwriter.hh:345
BaseOutputWriter::VectorBuffer VectorBuffer
Definition: vtkmultiwriter.hh:114
Dune::VTKWriter< GridView > VtkWriter
Definition: vtkmultiwriter.hh:116
void attachScalarElementData(ScalarBuffer &buf, std::string_view name) override
Add a element centered quantity to the output.
Definition: vtkmultiwriter.hh:271
VtkMultiWriter(bool asyncWriting, const GridView &gridView, const std::string &outputDir, const std::string &simName="", const std::string &multiFileName="")
Definition: vtkmultiwriter.hh:118
void attachTensorVertexData(TensorBuffer &buf, std::string_view name) override
Add a finished vertex-centered tensor field to the output.
Definition: vtkmultiwriter.hh:314
~VtkMultiWriter() override
Definition: vtkmultiwriter.hh:135
void gridViewChanged(const GridView &gridView)
Updates the internal data structures after mesh refinement.
Definition: vtkmultiwriter.hh:167
void serialize(Restarter &res)
Write the multi-writer's state to a restart file.
Definition: vtkmultiwriter.hh:403
Provides a vector-valued function using Dune::FieldVectors as elements.
Definition: vtkscalarfunction.hh:50
Provides a tensor-valued function using Dune::FieldMatrix objects as elements.
Definition: vtktensorfunction.hh:49
Provides a vector-valued function using Dune::FieldVectors as elements.
Definition: vtkvectorfunction.hh:48
Definition: fvbaseprimaryvariables.hh:161
Definition: blackoilbioeffectsmodules.hh:45
Provides a mechanism to dispatch work to separate threads.