Commit 6536d541 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Timeseries write and pvd writer have similar interface

parent 13ce7b24
......@@ -6,13 +6,14 @@
#include <tuple>
#include <dune/vtk/vtktypes.hh>
// #include <dune/vtk/vtkwriterinterface.hh>
#include <dune/vtk/filewriter.hh>
namespace Dune
{
/// File-Writer for ParaView .pvd files
template <class VtkWriter>
class PvdWriter
: public FileWriter
{
using Self = PvdWriter;
......@@ -29,7 +30,18 @@ namespace Dune
}
/// Write the attached data to the file
void writeTimestep (double time, std::string const& fn) const;
/**
* Create timestep files for the data associated to the current timestep `time`.
*
* \param time The time value of the written data
* \param fn Filename of the file to write to. Is stored in \ref timesteps_.
* \param writeCollection Create a collection .pvd file directly
**/
void writeTimestep (double time, std::string const& fn, bool writeCollection = true) const;
/// Writes collection of timesteps to .pvd file.
// NOTE: requires an aforging call to \ref writeTimestep
virtual void write (std::string const& fn) const override;
/// Attach point data to the writer, \see VtkFunction for possible arguments
template <class Function, class... Args>
......@@ -49,7 +61,7 @@ namespace Dune
protected:
/// Write a series of vtk files in a .pvd ParaView Data file
void writeFile (double time, std::ofstream& out) const;
void writeFile (std::ofstream& out) const;
protected:
VtkWriter vtkWriter_;
......
......@@ -9,7 +9,7 @@ namespace Dune {
template <class W>
void PvdWriter<W>
::writeTimestep (double time, std::string const& fn) const
::writeTimestep (double time, std::string const& fn, bool writeCollection) const
{
auto p = filesystem::path(fn);
auto name = p.stem();
......@@ -31,6 +31,36 @@ void PvdWriter<W>
timesteps_.emplace_back(time, filename + ext);
vtkWriter_.write(filename + ext);
if (rank == 0 && writeCollection) {
std::ofstream out(p.string() + ".pvd", std::ios_base::ate | std::ios::binary);
assert(out.is_open());
out.imbue(std::locale::classic());
out << std::setprecision(datatype_ == Vtk::FLOAT32
? std::numeric_limits<float>::digits10+2
: std::numeric_limits<double>::digits10+2);
writeFile(out);
}
}
template <class W>
void PvdWriter<W>
::write (std::string const& fn) const
{
auto p = filesystem::path(fn);
auto name = p.stem();
p.remove_filename();
p /= name.string();
int rank = 0;
int num_ranks = 1;
#ifdef HAVE_MPI
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_ranks);
#endif
if (rank == 0) {
std::ofstream out(p.string() + ".pvd", std::ios_base::ate | std::ios::binary);
assert(out.is_open());
......@@ -40,14 +70,14 @@ void PvdWriter<W>
? std::numeric_limits<float>::digits10+2
: std::numeric_limits<double>::digits10+2);
writeFile(time, out);
writeFile(out);
}
}
template <class W>
void PvdWriter<W>
::writeFile (double time, std::ofstream& out) const
::writeFile (std::ofstream& out) const
{
out << "<?xml version=\"1.0\"?>\n";
out << "<VTKFile"
......
......@@ -47,16 +47,26 @@ namespace Dune
filesystem::create_directories(tmpDir_);
}
~VtkTimeseriesWriter ()
{
std::remove(tmpDir_.string().c_str());
}
/// Remove all written intermediate files and remove temporary directory
~VtkTimeseriesWriter ();
/// Write the attached data to the file with \ref Vtk::FormatTypes and \ref Vtk::DataTypes
void writeTimestep (double time, std::string const& fn) const;
/// Write the attached data to the file
/**
* Create intermediate files for the data associated to the current timestep `time`.
*
* \param time The time value of the written data
* \param fn Filename of the file to write to. Only the base part
* (without dir and extentsion) is used to write the intermediate
* file into a tmp directory.
* \param writeCollection Create a timeseries file directly
**/
void writeTimestep (double time, std::string const& fn, bool writeCollection = true) const;
/// Writes all timesteps to single timeseries file.
// NOTE: requires an aforging call to \ref writeTimestep
/**
* Create a timeseries file with all timesteps written by \ref writeTimestep.
**/
virtual void write (std::string const& fn) const override;
/// Attach point data to the writer, \see VtkFunction for possible arguments
......
......@@ -22,15 +22,30 @@
namespace Dune {
template <class W>
VtkTimeseriesWriter<W>::~VtkTimeseriesWriter ()
{
if (initialized_) {
int ec = std::remove(filenameMesh_.c_str());
assert(ec == 0);
for (auto const& timestep : timesteps_) {
ec = std::remove(timestep.second.c_str());
assert(ec == 0);
}
}
std::remove(tmpDir_.string().c_str());
}
template <class W>
void VtkTimeseriesWriter<W>
::writeTimestep (double time, std::string const& fn)
::writeTimestep (double time, std::string const& fn, bool writeCollection) const
{
auto name = filesystem::path(fn).stem();
auto tmp = tmpDir_;
tmp /= name.string();
vtkWriter_.update();
vtkWriter_.dataCollector_.update();
std::string filenameBase = tmp.string();
......@@ -55,6 +70,9 @@ void VtkTimeseriesWriter<W>
std::ofstream out(filenameData, std::ios_base::ate | std::ios::binary);
vtkWriter_.writeDataAppended(out, blocks_);
timesteps_.emplace_back(time, filenameData);
if (writeCollection)
write(fn);
}
......@@ -63,7 +81,6 @@ void VtkTimeseriesWriter<W>
::write (std::string const& fn) const
{
assert( initialized_ );
assert( timesteps_.size() < 1000 ); // maximal number of allowed timesteps in timeseries file
auto p = filesystem::path(fn);
auto name = p.stem();
......@@ -109,16 +126,6 @@ void VtkTimeseriesWriter<W>
vtkWriter_.writeTimeseriesParallelFile(parallel_out, p.string() + "_ts", num_ranks, timesteps_);
}
#endif
// remove all temporary data files
int ec = std::remove(filenameMesh_.c_str());
assert(ec == 0);
for (auto const& timestep : timesteps_) {
ec = std::remove(timestep.second.c_str());
assert(ec == 0);
}
timesteps_.clear();
initialized_ = false;
}
} // end namespace Dune
......@@ -147,11 +147,6 @@ namespace Dune
return datatype_;
}
void update ()
{
dataCollector_.update();
}
protected:
mutable DataCollector dataCollector_;
......
......@@ -41,10 +41,12 @@ void write (std::string prefix, GridView const& gridView)
using Writer = VtkUnstructuredGridWriter<GridView>;
PvdWriter<Writer> pvdWriter(gridView, Vtk::ASCII, Vtk::FLOAT32);
std::string filename = prefix + "_" + std::to_string(GridView::dimensionworld) + "d_ascii.vtu";
pvdWriter.addPointData(p1Analytic, "p1");
pvdWriter.addCellData(p1Analytic, "p0");
for (double t = 0.0; t < 10.0; t += 1.0) {
pvdWriter.writeTimestep(t, prefix + "_" + std::to_string(GridView::dimensionworld) + "d_ascii.vtu");
pvdWriter.writeTimestep(t, filename);
}
}
......
......@@ -25,7 +25,8 @@ template <class GridView>
void write (std::string prefix, GridView const& gridView)
{
FieldVector<double,GridView::dimensionworld> c{11.0, 7.0, 3.0};
auto p1Analytic = makeAnalyticGridViewFunction([&c](auto const& x) -> float { return c.dot(x); }, gridView);
double shift = 0.0;
auto p1Analytic = makeAnalyticGridViewFunction([&c,&shift](auto const& x) -> float { return c.dot(x) + shift; }, gridView);
using Writer = VtkUnstructuredGridWriter<GridView>;
VtkTimeseriesWriter<Writer> seriesWriter(gridView, Vtk::BINARY, Vtk::FLOAT32);
......@@ -33,7 +34,8 @@ void write (std::string prefix, GridView const& gridView)
seriesWriter.addCellData(p1Analytic, "q0");
std::string filename = prefix + "_" + std::to_string(GridView::dimensionworld) + "d_binary32.vtu";
for (double t = 0.0; t < 5; t += 0.5) {
seriesWriter.writeTimestep(t, filename);
seriesWriter.writeTimestep(t, filename, false);
shift += 0.25;
}
seriesWriter.write(filename);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment