Peano 4
Loading...
Searching...
No Matches
PVDTimeSeriesWriter.cpp
Go to the documentation of this file.
1#include <fstream>
2
4#include "tarch/mpi/Rank.h"
6#include "tarch/Assertions.h"
7
8namespace {
9 tarch::logging::Log _log( "tarch::plotter::PVDTimeSeriesWriter" );
10
11 //const std::string Tail = "</Collection>\n</VTKFile>\n\n";
12
13 double TimeStampPrecision = 1e-5;
14}
15
17 if ( dataFile.find( ".pvd" )==std::string::npos ) {
18 dataFile += ".pvd";
19 }
20
21 std::tuple< double, int, std::vector<std::string> > fileData = parseFile( dataFile );
22 double result = std::get<0>(fileData);
23 logDebug( "getLatestTimeStepInIndexFile(string)", "latest timestamp is " << result );
24 return result;
25}
26
27void tarch::plotter::PVDTimeSeriesWriter::createEmptyIndexFile( const std::string& snapshotFileName ) {
28 const std::string filename = snapshotFileName + ".pvd";
29
30 std::vector<std::string> lines;
31
32 lines.push_back( "<?xml version=\"1.0\"?>" );
33 lines.push_back( "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" );
34 lines.push_back( "<Collection>" );
35
36 addFileTail(lines);
37
38 writeFile( filename, lines );
39}
40
41void tarch::plotter::PVDTimeSeriesWriter::addFileTail( std::vector<std::string>& lines ) {
42 lines.push_back( "</Collection>" );
43 lines.push_back( "</VTKFile>" );
44}
45
46void tarch::plotter::PVDTimeSeriesWriter::removeFileTail( std::vector<std::string>& lines ) {
47 if (not lines.empty()) {
48 if (lines.back().find("</VTKFile>")!=std::string::npos) {
49 lines.pop_back();
50 }
51 if (lines.back().find("</Collection>")!=std::string::npos) {
52 lines.pop_back();
53 }
54 }
55}
56
57std::tuple< double, int, std::vector<std::string> > tarch::plotter::PVDTimeSeriesWriter::parseFile( const std::string& filename, bool createBackup ) {
58 std::ifstream in( filename );
59
60 std::vector< std::string > fileLines;
61 double timestamp = 0;
62 int part = -1;
63
64 std::string line;
65 while (std::getline(in, line)) {
66 fileLines.push_back(line);
67 if ( line.find("<DataSet")!=std::string::npos ) {
68 std::size_t startTimeStep = line.find( "timestep=\"" ) + std::string("timestep=\"").size();
69 std::size_t endTimeStep = line.find( "\"", startTimeStep+1 );
70 std::string tokenTimeStep = line.substr(startTimeStep, endTimeStep-startTimeStep );
71
72 std::size_t startPart = line.find( "part=\"" ) + std::string("part=\"").size();
73 std::size_t endPart = line.find( "\"", startPart+1 );
74 std::string tokenPart = line.substr(startPart, endPart-startPart );
75
76 double currentTimeStep = std::atof( tokenTimeStep.c_str() );
77 int currentPart = std::atoi( tokenPart.c_str() );
78
79 if (tarch::la::smaller(timestamp,currentTimeStep,TimeStampPrecision)) {
80 timestamp = currentTimeStep;
81 part = currentPart;
82 } else if (tarch::la::equals(timestamp,currentTimeStep,TimeStampPrecision)) {
83 part = std::max(part, currentPart);
84 }
85 }
86 }
87
88 if (createBackup) {
89 std::ofstream out( filename + ".bak");
90 for (auto& p: fileLines) {
91 out << p << std::endl;
92 }
93 }
94
95 return std::tuple< double, int, std::vector<std::string> >(timestamp, part, fileLines);
96}
97
98void tarch::plotter::PVDTimeSeriesWriter::writeFile( const std::string& filename, const std::vector<std::string>& lines ) {
99 std::ofstream out;
100 out.open( filename.c_str() );
101 if ( (!out.fail()) and out.is_open() ) {
102 for (auto& p: lines) {
103 out << p << std::endl;
104 }
105 } else {
106 logError( "createEmptyNewFile(std::string)", "failed to open " << filename );
107 }
108}
109
110std::string tarch::plotter::PVDTimeSeriesWriter::createFileEntry( const std::string& snapshotFileName, double timestamp, int partCounter ) {
111 std::string newEntry = "<DataSet timestep=\"" + std::to_string(timestamp) + "\" group=\"\" part=\"" + std::to_string(partCounter) + "\" file=\"" + snapshotFileName + "\" />";
112 logDebug( "createFileEntry(...)", "added " << newEntry );
113 return newEntry;
114}
115
116void tarch::plotter::PVDTimeSeriesWriter::appendNewData(const std::string& snapshotFileName, const std::string& dataFile, double timeStamp) {
117 const std::string filename = snapshotFileName + ".pvd";
118
119 auto file = parseFile( filename );
120
121 double latestTimeStep = std::get<0>(file);
122 int part = std::get<1>(file);
123 std::vector< std::string > lines = std::get<2>(file);
124
125 removeFileTail(lines);
126
127 if ( tarch::la::equals(latestTimeStep,timeStamp,TimeStampPrecision) ) {
128 lines.push_back( createFileEntry(dataFile, timeStamp, part+1) );
129 }
130 else {
131 lines.push_back( createFileEntry(dataFile, timeStamp, 0) );
132 }
133
134 logDebug( "appendNewDataSet(...)", "no of lines=" << lines.size() );
135
136 addFileTail(lines);
137 writeFile( filename, lines );
138}
#define logError(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:464
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
Log Device.
Definition Log.h:516
static void writeFile(const std::string &filename, const std::vector< std::string > &lines)
static void appendNewData(const std::string &snapshotFileName, const std::string &dataFile, double timeStamp)
static void addFileTail(std::vector< std::string > &lines)
static std::string createFileEntry(const std::string &snapshotFileName, double timestamp, int partCounter)
static void removeFileTail(std::vector< std::string > &lines)
static std::tuple< double, int, std::vector< std::string > > parseFile(const std::string &filename, bool createBackup=true)
static void createEmptyIndexFile(const std::string &dataFile)
static double getLatestTimeStepInIndexFile(std::string dataFile)
static bool smaller(double lhs, double rhs, double tolerance=NUMERICAL_ZERO_DIFFERENCE) InlineMethod
Smaller operator for floating point values.
bool equals(const Matrix< Rows, Cols, Scalar > &lhs, const Matrix< Rows, Cols, Scalar > &rhs, const Scalar &tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares to matrices on equality by means of a numerical accuracy.
tarch::logging::Log _log("examples::unittests")