Skip to content
Snippets Groups Projects
Commit 3337035d authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Merge branch 'feature/output-in-subdirs' into 'develop'

Create missing directories when creating a file

See merge request !173
parents 3434c4f3 f103fb38
Branches
Tags
1 merge request!173Create missing directories when creating a file
#include <language/utils/OFStream.hpp>
#include <utils/Filesystem.hpp>
#include <utils/Messenger.hpp>
OFStream::OFStream(const std::string& filename)
{
if (parallel::rank() == 0) {
createDirectoryIfNeeded(filename);
m_fstream.open(filename);
if (m_fstream.is_open()) {
m_ostream = &m_fstream;
......
......@@ -5,6 +5,7 @@
#include <mesh/Mesh.hpp>
#include <mesh/MeshData.hpp>
#include <mesh/MeshDataManager.hpp>
#include <utils/Filesystem.hpp>
#include <utils/Messenger.hpp>
#include <utils/PugsTraits.hpp>
#include <utils/RevisionInfo.hpp>
......@@ -243,8 +244,16 @@ GnuplotWriter::_write(const MeshType& mesh,
const OutputNamedItemDataSet& output_named_item_data_set,
std::optional<double> time) const
{
createDirectoryIfNeeded(_getFilename());
if (parallel::rank() == 0) {
std::ofstream fout{_getFilename()};
if (not fout) {
std::ostringstream error_msg;
error_msg << "cannot create file \"" << rang::fgB::yellow << _getFilename() << rang::fg::reset << '"';
throw NormalError(error_msg.str());
}
fout.precision(15);
fout.setf(std::ios_base::scientific);
......@@ -286,6 +295,12 @@ GnuplotWriter::_write(const MeshType& mesh,
for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
if (i_rank == parallel::rank()) {
std::ofstream fout(_getFilename(), std::ios_base::app);
if (not fout) {
std::ostringstream error_msg;
error_msg << "cannot open file \"" << rang::fgB::yellow << _getFilename() << rang::fg::reset << '"';
throw NormalError(error_msg.str());
}
fout.precision(15);
fout.setf(std::ios_base::scientific);
......
......@@ -5,6 +5,7 @@
#include <mesh/Mesh.hpp>
#include <mesh/MeshData.hpp>
#include <mesh/MeshDataManager.hpp>
#include <utils/Filesystem.hpp>
#include <utils/Messenger.hpp>
#include <utils/PugsTraits.hpp>
#include <utils/RevisionInfo.hpp>
......@@ -322,6 +323,12 @@ GnuplotWriter1D::_write(const MeshType& mesh,
if (parallel::rank() == 0) {
fout.open(_getFilename());
if (not fout) {
std::ostringstream error_msg;
error_msg << "cannot create file \"" << rang::fgB::yellow << _getFilename() << rang::fg::reset << '"';
throw NormalError(error_msg.str());
}
fout.precision(15);
fout.setf(std::ios_base::scientific);
fout << _getDateAndVersionComment();
......
......@@ -4,6 +4,7 @@
#include <mesh/Mesh.hpp>
#include <mesh/MeshData.hpp>
#include <mesh/MeshDataManager.hpp>
#include <utils/Filesystem.hpp>
#include <utils/Messenger.hpp>
#include <utils/RevisionInfo.hpp>
#include <utils/Stringify.hpp>
......@@ -364,8 +365,16 @@ VTKWriter::_write(const MeshType& mesh,
output_named_item_data_set.add(NamedItemData{"cell_number", mesh.connectivity().cellNumber()});
output_named_item_data_set.add(NamedItemData{"node_number", mesh.connectivity().nodeNumber()});
createDirectoryIfNeeded(m_base_filename);
if (parallel::rank() == 0) { // write PVTK file
std::ofstream fout(_getFilenamePVTU());
if (not fout) {
std::ostringstream error_msg;
error_msg << "cannot create file \"" << rang::fgB::yellow << _getFilenamePVTU() << rang::fg::reset << '"';
throw NormalError(error_msg.str());
}
fout << "<?xml version=\"1.0\"?>\n";
fout << _getDateAndVersionComment();
fout << "<VTKFile type=\"PUnstructuredGrid\">\n";
......@@ -424,7 +433,7 @@ VTKWriter::_write(const MeshType& mesh,
fout << "</PCellData>\n";
for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
fout << "<Piece Source=\"" << _getFilenameVTU(i_rank) << "\"/>\n";
fout << "<Piece Source=" << std::filesystem::path{_getFilenameVTU(i_rank)}.filename() << "/>\n";
}
fout << "</PUnstructuredGrid>\n";
fout << "</VTKFile>\n";
......@@ -435,6 +444,13 @@ VTKWriter::_write(const MeshType& mesh,
// write VTK files
std::ofstream fout(_getFilenameVTU(parallel::rank()));
if (not fout) {
std::ostringstream error_msg;
error_msg << "cannot create file \"" << rang::fgB::yellow << _getFilenameVTU(parallel::rank()) << rang::fg::reset
<< '"';
throw NormalError(error_msg.str());
}
fout << "<?xml version=\"1.0\"?>\n";
fout << _getDateAndVersionComment();
fout << "<VTKFile type=\"UnstructuredGrid\"";
......@@ -632,7 +648,13 @@ VTKWriter::_write(const MeshType& mesh,
}
if (parallel::rank() == 0) { // write PVD file
std::ofstream fout(m_base_filename + ".pvd");
const std::string pvd_filename = m_base_filename + ".pvd";
std::ofstream fout(pvd_filename);
if (not fout) {
std::ostringstream error_msg;
error_msg << "cannot create file \"" << rang::fgB::yellow << pvd_filename << rang::fg::reset << '"';
throw NormalError(error_msg.str());
}
fout << "<?xml version=\"1.0\"?>\n";
fout << _getDateAndVersionComment();
......@@ -645,11 +667,13 @@ VTKWriter::_write(const MeshType& mesh,
sout << m_base_filename;
sout << '.' << std::setfill('0') << std::setw(4) << i_time << ".pvtu";
fout << "<DataSet timestep=\"" << m_period_manager->savedTime(i_time) << "\" file=\"" << sout.str() << "\"/>\n";
fout << "<DataSet timestep=\"" << m_period_manager->savedTime(i_time)
<< "\" file=" << std::filesystem::path{sout.str()}.filename() << "/>\n";
}
fout << "<DataSet timestep=\"" << *time << "\" file=\"" << _getFilenamePVTU() << "\"/>\n";
fout << "<DataSet timestep=\"" << *time << "\" file=" << std::filesystem::path{_getFilenamePVTU()}.filename()
<< "/>\n";
} else {
fout << "<DataSet file=\"" << _getFilenamePVTU() << "\"/>\n";
fout << "<DataSet file=" << std::filesystem::path{_getFilenamePVTU()}.filename() << "/>\n";
}
fout << "</Collection>\n";
......
#ifndef FILESYSTEM_HPP
#define FILESYSTEM_HPP
#include <utils/Exceptions.hpp>
#include <utils/PugsMacros.hpp>
#include <filesystem>
PUGS_INLINE void
createDirectoryIfNeeded(const std::string& filename)
{
std::filesystem::path path = std::filesystem::path{filename}.parent_path();
if (not path.empty()) {
try {
std::filesystem::create_directories(path);
}
catch (std::filesystem::filesystem_error& e) {
throw NormalError(e.what());
}
}
}
#endif // FILESYSTEM_HPP
......@@ -13,7 +13,8 @@ TEST_CASE("OFStream", "[language]")
{
SECTION("ofstream")
{
const std::string basename = std::filesystem::path{PUGS_BINARY_DIR}.append("tests").append("ofstream_");
const std::string basename =
std::filesystem::path{PUGS_BINARY_DIR}.append("tests").append("ofstream_dir").append("ofstream_");
const std::string filename = basename + stringify(parallel::rank());
// Ensures that the file is closed after this line
......@@ -47,13 +48,4 @@ TEST_CASE("OFStream", "[language]")
REQUIRE(not std::filesystem::exists(filename));
}
SECTION("invalid filename")
{
if (parallel::rank() == 0) {
const std::string filename = "badpath/invalidpath/ofstream";
REQUIRE_THROWS_WITH(std::make_shared<OFStream>(filename), "error: cannot create file " + filename);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment