Skip to content

Commit

Permalink
IO/VTK: add support for writing time series
Browse files Browse the repository at this point in the history
  • Loading branch information
andrea-iob committed Dec 13, 2023
1 parent 1348102 commit 4bfdf0d
Show file tree
Hide file tree
Showing 4 changed files with 226 additions and 3 deletions.
164 changes: 164 additions & 0 deletions src/IO/VTK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
\*---------------------------------------------------------------------------*/

#include <cassert>
#include <sstream>
#include <string>
#include <unordered_set>

#include "VTK.hpp"
Expand Down Expand Up @@ -692,6 +694,25 @@ void VTK::checkAllFields(){

}

/*!
* Writes entire VTK file (headers and data).
* @param[in] writeMode if writeMode == VTKWriteMode::DEFAULT the default write setting will be used according to setCounter();
* if writeMode == VTKWriteMode::NO_SERIES no time stamp will be added and the counter will not be increased;
* if writeMode == VTKWriteMode::NO_INCREMENT the output file will have the same time stamp like the previous one ;
* @param[in] time is the time associated with the file
*/
void VTK::write( VTKWriteMode writeMode, double time ){

// Write VTK file
write(writeMode);

// Write time series file
if( writeMode == VTKWriteMode::DEFAULT || writeMode == VTKWriteMode::NO_INCREMENT ){
writeTimeSeries(time);
}

}

/*!
* Writes entire VTK file (headers and data).
* @param[in] writeMode if writeMode == VTKWriteMode::DEFAULT the default write setting will be used according to setCounter();
Expand Down Expand Up @@ -741,6 +762,23 @@ void VTK::write( const std::string &name, VTKWriteMode writeMode ){
setName(name) ;
write(writeMode) ;
setName(oldName) ;
}

/*!
* Writes entire VTK file (headers and data).
* @param[in] name filename to be set for this output only
* @param[in] writeMode if writeMode == VTKWriteMode::DEFAULT the default write setting will be used according to setCounter();
* if writeMode == VTKWriteMode::NO_SERIES no time stamp will be added and the counter will not be increased;
* if writeMode == VTKWriteMode::NO_INCREMENT the output file will have the same time stamp like the previous one ;
* @param[in] time is the time associated with the file
*/
void VTK::write( const std::string &name, VTKWriteMode writeMode, double time ){

std::string oldName = getName() ;

setName(name) ;
write(writeMode, time) ;
setName(oldName) ;

}

Expand All @@ -762,6 +800,132 @@ void VTK::writeCollection( const std::string &outputName ) const {
writeCollection(outputName, outputName) ;
}

/*!
* Writes time series file.
*
* If the file doesn't exists or if this is the first data set of the series
* (i.e., the counter is equal to zero), the time series will be written from
* scratch and will contain only the current data set. Otherwise, the existing
* time series will be inspected and the current data set will be either added
* at the end of the series or will it will replace the entry with the same
* file name it such an entry exists.
*
* \param time is the time associated with the data set
*/
void VTK::writeTimeSeries( double time ) const {
writeTimeSeries(getName(), getName(), time) ;
}

/*!
* Writes time series file.
*
* If the file doesn't exists or if this is the first data set of the series
* (i.e., the counter is equal to zero), the time series will be written from
* scratch and will contain only the current data set. Otherwise, the existing
* time series will be inspected and the current data set will be either added
* at the end of the series or will it will replace the entry with the same
* file name it such an entry exists.
*
* \param outputName filename to be set for this output only
* \param time is the time associated with the data set
*/
void VTK::writeTimeSeries( const std::string &outputName, double time ) const {
writeTimeSeries(outputName, outputName, time) ;
}

/*!
* Writes time series file.
*
* If the file doesn't exists or if this is the first data set of the series
* (i.e., the counter is equal to zero), the time series will be written from
* scratch and will contain only the current data set. Otherwise, the existing
* time series will be inspected and the current data set will be either added
* at the end of the series or will it will replace the entry with the same
* file name it such an entry exists.
*
* \param outputName filename to be set for this output only
* \param seriesName series filename to be set for this output only
* \param time is the time associated with the data set
*/
void VTK::writeTimeSeries( const std::string &outputName, const std::string &seriesName, double time ) const {

// Only one process should write the time series
if (m_rank != 0) {
return;
}

// Initialize series file handle
FileHandler seriesFileHandler = m_fh ;
seriesFileHandler.setSeries(false) ;
seriesFileHandler.setParallel(false) ;
seriesFileHandler.setName(seriesName) ;
seriesFileHandler.setAppendix("pvd") ;

// Initialize series
if (!seriesFileHandler.exists() || getCounter() == 0) {
std::fstream emptySeriesFileStream;
emptySeriesFileStream.open( seriesFileHandler.getPath(), std::ios::out | std::ios::trunc ) ;
if (!emptySeriesFileStream.is_open()) {
throw std::runtime_error("Cannot create file \"" + seriesFileHandler.getName() + "\"" + " inside the directory \"" + seriesFileHandler.getDirectory() + "\"");
}

emptySeriesFileStream << "<?xml version=\"1.0\"?>" << std::endl;
emptySeriesFileStream << "<VTKFile type=\"Collection\" version=\"0.1\">" << std::endl;
emptySeriesFileStream << " <Collection>" << std::endl;
emptySeriesFileStream << " </Collection>" << std::endl;
emptySeriesFileStream << "</VTKFile>" << std::endl;
emptySeriesFileStream.close();
}

// Create updated series
FileHandler dataSetFileHandler;
if (m_procs <= 1) {
dataSetFileHandler = m_fh ;
dataSetFileHandler.setSeries(false) ;
dataSetFileHandler.setParallel(false) ;
dataSetFileHandler.setName(outputName);
} else {
dataSetFileHandler = createCollectionHandler(outputName) ;
}
dataSetFileHandler.setDirectory(".");

std::string line;
std::stringstream series;

std::fstream seriesFileStream;
seriesFileStream.open( seriesFileHandler.getPath( ), std::ios::in ) ;
if (!seriesFileStream.is_open()) {
throw std::runtime_error("Cannot read file \"" + seriesFileHandler.getName() + "\"" + " inside the directory \"" + seriesFileHandler.getDirectory() + "\"");
}

while (std::getline(seriesFileStream, line)) {
bool duplicateEntry = (line.find("file=\"" + dataSetFileHandler.getPath() + "\"") != std::string::npos);
bool collectionEnd = (line.find("</Collection>") != std::string::npos);

if (collectionEnd || duplicateEntry) {
series << " <DataSet";
series << " timestep=\"" << time << "\"";
series << " file=\"" << dataSetFileHandler.getPath() << "\"";
series << "/>" << std::endl;
}

if (!duplicateEntry) {
series << line << std::endl;
}
}
seriesFileStream.close();

// Write updated series
std::ofstream updatedSeriesFileStream;
updatedSeriesFileStream.open( seriesFileHandler.getPath( )) ;
if (!updatedSeriesFileStream.is_open()) {
throw std::runtime_error("Cannot create file \"" + seriesFileHandler.getName() + "\"" + " inside the directory \"" + seriesFileHandler.getDirectory() + "\"");
}

updatedSeriesFileStream << series.rdbuf();
updatedSeriesFileStream.close();
}

/*!
* Creates a handler for the collection.
*
Expand Down
6 changes: 6 additions & 0 deletions src/IO/VTK.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,13 +374,19 @@ class VTK{
virtual void readMetaInformation() = 0 ;
void readData() ;

void write( VTKWriteMode writeMode, double time ) ;
void write( VTKWriteMode writeMode=VTKWriteMode::DEFAULT ) ;
void write( const std::string &, VTKWriteMode writeMode, double time ) ;
void write( const std::string &, VTKWriteMode writeMode=VTKWriteMode::NO_INCREMENT ) ;

void writeCollection( ) const ;
void writeCollection( const std::string &outputName ) const ;
virtual void writeCollection( const std::string &outputName, const std::string &collectionName ) const = 0;

void writeTimeSeries( double time ) const;
void writeTimeSeries( const std::string &outputName, double time ) const ;
void writeTimeSeries( const std::string &outputName, const std::string &seriesName, double time ) const ;

protected:
//For Writing
virtual void writeMetaInformation() const = 0 ;
Expand Down
54 changes: 51 additions & 3 deletions src/patchkernel/patch_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1173,11 +1173,54 @@ void PatchKernel::write(const std::string &filename, VTKWriteMode mode)
}

/*!
Writes the patch a filename with the same name of the patch.
Writes the patch to filename specified in input.
\param filename the filename where the patch will be written to
\param mode is the VTK file mode that will be used for writing the patch
\param time is the current time
*/
void PatchKernel::write(const std::string &filename, VTKWriteMode mode, double time)
{
std::string oldFilename = m_vtk.getName();

m_vtk.setName(filename);
write(mode, time);
m_vtk.setName(oldFilename);
}

/*!
Writes the patch to filename specified in input.
\param mode is the VTK file mode that will be used for writing the patch
*/
void PatchKernel::write(VTKWriteMode mode)
{
_writePrepare();

m_vtk.write(mode);

_writeFinalize();
}

/*!
Writes the patch a filename with the same name of the patch.
\param mode is the VTK file mode that will be used for writing the patch
\param time is the current time
*/
void PatchKernel::write(VTKWriteMode mode, double time)
{
_writePrepare();

m_vtk.write(mode, time);

_writeFinalize();
}

/*!
Internal function to be called before writing the patch.
*/
void PatchKernel::_writePrepare()
{
// Get VTK cell count
long vtkCellCount = 0;
Expand Down Expand Up @@ -1246,9 +1289,14 @@ void PatchKernel::write(VTKWriteMode mode)
}

m_vtk.setDimensions(vtkCellCount, vtkVertexCount, vtkConnectSize, vtkFaceStreamSize);
}

// Write the mesh
m_vtk.write(mode);
/*!
Internal function to be called after writing the patch.
*/
void PatchKernel::_writeFinalize()
{
// Nothing to do
}

/*!
Expand Down
5 changes: 5 additions & 0 deletions src/patchkernel/patch_kernel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,9 @@ friend class PatchManager;
void setVTKWriteTarget(WriteTarget targetCells);
const CellConstRange getVTKCellWriteRange() const;
void write(VTKWriteMode mode = VTKWriteMode::DEFAULT);
void write(VTKWriteMode mode, double time);
void write(const std::string &name, VTKWriteMode mode = VTKWriteMode::DEFAULT);
void write(const std::string &name, VTKWriteMode mode, double time);

void flushData(std::fstream &stream, const std::string &name, VTKFormat format) override;

Expand Down Expand Up @@ -903,6 +905,9 @@ friend class PatchManager;
virtual void _findCellEdgeNeighs(long id, int edge, const std::vector<long> *blackList, std::vector<long> *neighs) const;
virtual void _findCellVertexNeighs(long id, int vertex, const std::vector<long> *blackList, std::vector<long> *neighs) const;

virtual void _writePrepare();
virtual void _writeFinalize();

void setExpert(bool expert);

void extractEnvelope(PatchKernel &envelope) const;
Expand Down

0 comments on commit 4bfdf0d

Please sign in to comment.