diff --git a/src/language/modules/WriterModule.cpp b/src/language/modules/WriterModule.cpp index fcb3beb6186b8b6918f1f51efccabb54a657c896..a1eebb3ed74df078eabaebeaa440c7bcb2446cdb 100644 --- a/src/language/modules/WriterModule.cpp +++ b/src/language/modules/WriterModule.cpp @@ -20,6 +20,14 @@ WriterModule::WriterModule() this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IWriter>>); + this + ->_addBuiltinFunction("vtk_writer", + std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&)>>( + + [](const std::string& filename) { return std::make_shared<VTKWriter>(filename); } + + )); + this->_addBuiltinFunction("vtk_writer", std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&, const double&)>>( @@ -30,6 +38,14 @@ WriterModule::WriterModule() )); + this + ->_addBuiltinFunction("gnuplot_writer", + std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&)>>( + + [](const std::string& filename) { return std::make_shared<GnuplotWriter>(filename); } + + )); + this->_addBuiltinFunction("gnuplot_writer", std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&, const double&)>>( @@ -40,6 +56,14 @@ WriterModule::WriterModule() )); + this + ->_addBuiltinFunction("gnuplot_1d_writer", + std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&)>>( + + [](const std::string& filename) { return std::make_shared<GnuplotWriter1D>(filename); } + + )); + this->_addBuiltinFunction("gnuplot_1d_writer", std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IWriter>(const std::string&, const double&)>>( @@ -72,6 +96,18 @@ WriterModule::WriterModule() )); + this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder< + void(std::shared_ptr<const IWriter>, + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>&)>>( + + [](std::shared_ptr<const IWriter> writer, + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& + named_discrete_function_list) -> void { + writer->write(named_discrete_function_list); + } + + )); + this->_addBuiltinFunction("write", std::make_shared<BuiltinFunctionEmbedder< void(std::shared_ptr<const IWriter>, diff --git a/src/output/GnuplotWriter.cpp b/src/output/GnuplotWriter.cpp index 4f98d0f2372323aed61af96c824ed262fcd3ace2..ae0ba69aff214a7d0f4a9957113bdac52939315d 100644 --- a/src/output/GnuplotWriter.cpp +++ b/src/output/GnuplotWriter.cpp @@ -239,9 +239,9 @@ GnuplotWriter::_writeNodeData(const NodeArray<DataType>& node_array, NodeId node template <typename MeshType> void -GnuplotWriter::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, - const OutputNamedItemDataSet& output_named_item_data_set, - double time) const +GnuplotWriter::_write(const std::shared_ptr<const MeshType>& mesh, + const OutputNamedItemDataSet& output_named_item_data_set, + std::optional<double> time) const { if (parallel::rank() == 0) { std::ofstream fout{_getFilename()}; @@ -249,8 +249,9 @@ GnuplotWriter::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, fout.setf(std::ios_base::scientific); fout << this->_getDateAndVersionComment(); - fout << "# time = " << time << "\n\n"; - + if (time.has_value()) { + fout << "# time = " << *time << "\n\n"; + } this->_writePreamble<MeshType::Dimension>(output_named_item_data_set, fout); } @@ -267,17 +268,41 @@ GnuplotWriter::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, } void -GnuplotWriter::writeMesh(const std::shared_ptr<const IMesh>& p_mesh) const +GnuplotWriter::_writeAtTime( + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, + double time) const +{ + std::shared_ptr mesh = this->_getMesh(named_discrete_function_list); + + OutputNamedItemDataSet output_named_item_data_set = this->_getOutputNamedItemDataSet(named_discrete_function_list); + + switch (mesh->dimension()) { + case 1: { + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, time); + break; + } + case 2: { + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, time); + break; + } + default: { + throw NormalError("gnuplot format is not available in dimension " + stringify(mesh->dimension())); + } + } +} + +void +GnuplotWriter::_writeMesh(const std::shared_ptr<const IMesh>& p_mesh) const { OutputNamedItemDataSet output_named_item_data_set{}; switch (p_mesh->dimension()) { case 1: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(p_mesh), output_named_item_data_set, 0); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(p_mesh), output_named_item_data_set, {}); break; } case 2: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(p_mesh), output_named_item_data_set, 0); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(p_mesh), output_named_item_data_set, {}); break; } default: { @@ -287,9 +312,8 @@ GnuplotWriter::writeMesh(const std::shared_ptr<const IMesh>& p_mesh) const } void -GnuplotWriter::_writeAtTime( - const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, - double time) const +GnuplotWriter::_write( + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const { std::shared_ptr mesh = this->_getMesh(named_discrete_function_list); @@ -297,11 +321,11 @@ GnuplotWriter::_writeAtTime( switch (mesh->dimension()) { case 1: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, time); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, {}); break; } case 2: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, time); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, {}); break; } default: { diff --git a/src/output/GnuplotWriter.hpp b/src/output/GnuplotWriter.hpp index 312e4886c9d3cb3b19ea2e96bba3d18e611a5eeb..112b460625c9df4a436d55863daa989986611243 100644 --- a/src/output/GnuplotWriter.hpp +++ b/src/output/GnuplotWriter.hpp @@ -9,9 +9,10 @@ class IMesh; +#include <optional> #include <string> -class GnuplotWriter : public WriterBase +class GnuplotWriter final : public WriterBase { private: std::string _getDateAndVersionComment() const; @@ -45,15 +46,20 @@ class GnuplotWriter : public WriterBase std::ostream& fout) const; template <typename MeshType> - void _writeAtTime(const std::shared_ptr<const MeshType>& mesh, - const OutputNamedItemDataSet& output_named_item_data_set, - double time) const; + void _write(const std::shared_ptr<const MeshType>& mesh, + const OutputNamedItemDataSet& output_named_item_data_set, + std::optional<double> time) const; void _writeAtTime(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, double time) const final; + void _write( + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const final; + + void _writeMesh(const std::shared_ptr<const IMesh>& mesh) const final; + public: - void writeMesh(const std::shared_ptr<const IMesh>& mesh) const final; + GnuplotWriter(const std::string& base_filename) : WriterBase(base_filename) {} GnuplotWriter(const std::string& base_filename, const double time_period) : WriterBase(base_filename, time_period) {} diff --git a/src/output/GnuplotWriter1D.cpp b/src/output/GnuplotWriter1D.cpp index 7fbd6612ada3a1aaed3b95fc1050ac43ffc632ac..73e5a4e64a0e85eda1a5571503d28c8b221f2cdc 100644 --- a/src/output/GnuplotWriter1D.cpp +++ b/src/output/GnuplotWriter1D.cpp @@ -260,9 +260,9 @@ GnuplotWriter1D::_writeItemDatas(const std::shared_ptr<const MeshType>& mesh, template <typename MeshType> void -GnuplotWriter1D::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, - const OutputNamedItemDataSet& output_named_item_data_set, - double time) const +GnuplotWriter1D::_write(const std::shared_ptr<const MeshType>& mesh, + const OutputNamedItemDataSet& output_named_item_data_set, + std::optional<double> time) const { bool has_cell_data = false; for (const auto& [name, item_data_variant] : output_named_item_data_set) { @@ -286,7 +286,9 @@ GnuplotWriter1D::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, fout.setf(std::ios_base::scientific); fout << _getDateAndVersionComment(); - fout << "# time = " << time << "\n\n"; + if (time.has_value()) { + fout << "# time = " << *time << "\n\n"; + } _writePreamble(output_named_item_data_set, fout); } @@ -299,7 +301,7 @@ GnuplotWriter1D::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, } void -GnuplotWriter1D::writeMesh(const std::shared_ptr<const IMesh>&) const +GnuplotWriter1D::_writeMesh(const std::shared_ptr<const IMesh>&) const { std::ostringstream errorMsg; errorMsg << "gnuplot_1d_writer does not write meshes\n" @@ -319,7 +321,7 @@ GnuplotWriter1D::_writeAtTime( switch (mesh->dimension()) { case 1: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, time); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, time); break; } case 2: { @@ -334,3 +336,26 @@ GnuplotWriter1D::_writeAtTime( } } } + +void +GnuplotWriter1D::_write( + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const +{ + std::shared_ptr mesh = this->_getMesh(named_discrete_function_list); + + OutputNamedItemDataSet output_named_item_data_set = this->_getOutputNamedItemDataSet(named_discrete_function_list); + + switch (mesh->dimension()) { + case 1: { + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, {}); + break; + } + case 2: { + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, {}); + break; + } + default: { + throw NormalError("gnuplot format is not available in dimension " + stringify(mesh->dimension())); + } + } +} diff --git a/src/output/GnuplotWriter1D.hpp b/src/output/GnuplotWriter1D.hpp index f1e7b23c876aca9aadb93c47154289468e027a85..fad94c13687e3a8ff5c1989401bb39f9bf92f505 100644 --- a/src/output/GnuplotWriter1D.hpp +++ b/src/output/GnuplotWriter1D.hpp @@ -9,9 +9,10 @@ class IMesh; +#include <optional> #include <string> -class GnuplotWriter1D : public WriterBase +class GnuplotWriter1D final : public WriterBase { private: std::string _getDateAndVersionComment() const; @@ -38,15 +39,20 @@ class GnuplotWriter1D : public WriterBase void _writePreamble(const OutputNamedItemDataSet& output_named_item_value_set, std::ostream& fout) const; template <typename MeshType> - void _writeAtTime(const std::shared_ptr<const MeshType>& mesh, - const OutputNamedItemDataSet& output_named_item_value_set, - double time) const; + void _write(const std::shared_ptr<const MeshType>& mesh, + const OutputNamedItemDataSet& output_named_item_value_set, + std::optional<double> time) const; void _writeAtTime(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, double time) const final; + void _write( + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const final; + + void _writeMesh(const std::shared_ptr<const IMesh>& mesh) const final; + public: - void writeMesh(const std::shared_ptr<const IMesh>& mesh) const final; + GnuplotWriter1D(const std::string& base_filename) : WriterBase(base_filename) {} GnuplotWriter1D(const std::string& base_filename, const double time_period) : WriterBase(base_filename, time_period) {} diff --git a/src/output/IWriter.hpp b/src/output/IWriter.hpp index 02317ad98b055567133f9b969476fedbd2a5c0e1..dab629604c0b51f2be9233436af42fe7dee7134b 100644 --- a/src/output/IWriter.hpp +++ b/src/output/IWriter.hpp @@ -13,6 +13,9 @@ class IWriter public: virtual void writeMesh(const std::shared_ptr<const IMesh>& mesh) const = 0; + virtual void write( + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const = 0; + virtual void writeIfNeeded( const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, double time) const = 0; diff --git a/src/output/VTKWriter.cpp b/src/output/VTKWriter.cpp index 55a2e90d90faeea769a2565df655422f41a983d4..8295c351ff66cd106f4a9fdd06e05fd2efb3315c 100644 --- a/src/output/VTKWriter.cpp +++ b/src/output/VTKWriter.cpp @@ -355,14 +355,10 @@ VTKWriter::_write_node_data(std::ofstream& os, template <typename MeshType> void -VTKWriter::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, - const OutputNamedItemDataSet& given_output_named_item_data_set, - double time) const +VTKWriter::_write(const std::shared_ptr<const MeshType>& mesh, + const OutputNamedItemDataSet& given_output_named_item_data_set, + std::optional<double> time) const { - if (not m_period_manager.has_value()) { - throw NormalError("Writer has no period defined"); - } - OutputNamedItemDataSet output_named_item_data_set{given_output_named_item_data_set}; // Adding basic mesh information output_named_item_data_set.add(NamedItemData{"cell_number", mesh->connectivity().cellNumber()}); @@ -622,14 +618,18 @@ VTKWriter::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, fout << "<VTKFile type=\"Collection\" version=\"0.1\">\n"; fout << "<Collection>\n"; - for (size_t i_time = 0; i_time < m_period_manager->nbSavedTimes(); ++i_time) { - std::ostringstream sout; - sout << m_base_filename; - sout << '.' << std::setfill('0') << std::setw(4) << i_time << ".pvtu"; + if (time.has_value()) { + for (size_t i_time = 0; i_time < m_period_manager->nbSavedTimes(); ++i_time) { + std::ostringstream sout; + 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=\"" << sout.str() << "\"/>\n"; + } + fout << "<DataSet timestep=\"" << *time << "\" file=\"" << _getFilenamePVTU() << "\"/>\n"; + } else { + fout << "<DataSet file=\"" << _getFilenamePVTU() << "\"/>\n"; } - fout << "<DataSet timestep=\"" << time << "\" file=\"" << _getFilenamePVTU() << "\"/>\n"; fout << "</Collection>\n"; fout << "</VTKFile>\n"; @@ -637,21 +637,21 @@ VTKWriter::_writeAtTime(const std::shared_ptr<const MeshType>& mesh, } void -VTKWriter::writeMesh(const std::shared_ptr<const IMesh>& mesh) const +VTKWriter::_writeMesh(const std::shared_ptr<const IMesh>& mesh) const { OutputNamedItemDataSet output_named_item_data_set; switch (mesh->dimension()) { case 1: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, 0); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, {}); break; } case 2: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, 0); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, {}); break; } case 3: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<3>>>(mesh), output_named_item_data_set, 0); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<3>>>(mesh), output_named_item_data_set, {}); break; } default: { @@ -670,15 +670,41 @@ VTKWriter::_writeAtTime(const std::vector<std::shared_ptr<const NamedDiscreteFun switch (mesh->dimension()) { case 1: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, time); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, time); + break; + } + case 2: { + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, time); + break; + } + case 3: { + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<3>>>(mesh), output_named_item_data_set, time); + break; + } + default: { + throw UnexpectedError("invalid mesh dimension"); + } + } +} + +void +VTKWriter::_write(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const +{ + std::shared_ptr mesh = this->_getMesh(named_discrete_function_list); + + OutputNamedItemDataSet output_named_item_data_set = this->_getOutputNamedItemDataSet(named_discrete_function_list); + + switch (mesh->dimension()) { + case 1: { + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(mesh), output_named_item_data_set, {}); break; } case 2: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, time); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(mesh), output_named_item_data_set, {}); break; } case 3: { - this->_writeAtTime(std::dynamic_pointer_cast<const Mesh<Connectivity<3>>>(mesh), output_named_item_data_set, time); + this->_write(std::dynamic_pointer_cast<const Mesh<Connectivity<3>>>(mesh), output_named_item_data_set, {}); break; } default: { diff --git a/src/output/VTKWriter.hpp b/src/output/VTKWriter.hpp index eb0f70d9253204124123395a531b28c940c28345..c0adbd6c4e86cff510924018f80b5fb27229001a 100644 --- a/src/output/VTKWriter.hpp +++ b/src/output/VTKWriter.hpp @@ -9,9 +9,10 @@ class IMesh; +#include <optional> #include <string> -class VTKWriter : public WriterBase +class VTKWriter final : public WriterBase { private: class SerializedDataList; @@ -95,16 +96,19 @@ class VTKWriter : public WriterBase SerializedDataList& serialized_data_list) const; template <typename MeshType> - void _writeAtTime(const std::shared_ptr<const MeshType>& mesh, - const OutputNamedItemDataSet& output_named_item_data_set, - double time) const; + void _write(const std::shared_ptr<const MeshType>& mesh, + const OutputNamedItemDataSet& output_named_item_data_set, + std::optional<double> time) const; void _writeAtTime(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, double time) const final; - public: - void writeMesh(const std::shared_ptr<const IMesh>& mesh) const final; + void _write( + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const final; + + void _writeMesh(const std::shared_ptr<const IMesh>& mesh) const final; + public: VTKWriter(const std::string& base_filename) : WriterBase(base_filename) {} VTKWriter(const std::string& base_filename, const double time_period) : WriterBase(base_filename, time_period) {} diff --git a/src/output/WriterBase.cpp b/src/output/WriterBase.cpp index 7ae28e9e800f1a1cea705ab2a1789ad284558e9d..2fe733d540e89c7f7e1bdea6e801e221e6a96eb8 100644 --- a/src/output/WriterBase.cpp +++ b/src/output/WriterBase.cpp @@ -214,7 +214,7 @@ WriterBase::writeIfNeeded(const std::vector<std::shared_ptr<const NamedDiscreteF m_period_manager->setSaveTime(time); } } else { - throw NormalError("Writer has no period defined"); + throw NormalError("this writer does not allow time value"); } } @@ -229,6 +229,26 @@ WriterBase::writeForced(const std::vector<std::shared_ptr<const NamedDiscreteFun this->_writeAtTime(named_discrete_function_list, time); m_period_manager->setSaveTime(time); } else { - throw NormalError("Writer has no period defined"); + throw NormalError("this writer does not allow time value"); + } +} + +void +WriterBase::write(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const +{ + if (m_period_manager.has_value()) { + throw NormalError("this writer requires time value"); + } else { + this->_write(named_discrete_function_list); + } +} + +void +WriterBase::writeMesh(const std::shared_ptr<const IMesh>& mesh) const +{ + if (m_period_manager.has_value()) { + throw NormalError("write_mesh requires a writer without time period"); + } else { + this->_writeMesh(mesh); } } diff --git a/src/output/WriterBase.hpp b/src/output/WriterBase.hpp index 6d96ee410d32632ffaf0b5ead86ac4bdbccc88af..2f29120b596f481bdd437cb42e7fd2fc665cf911 100644 --- a/src/output/WriterBase.hpp +++ b/src/output/WriterBase.hpp @@ -105,13 +105,22 @@ class WriterBase : public IWriter const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, double time) const = 0; + virtual void _write( + const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const = 0; + + virtual void _writeMesh(const std::shared_ptr<const IMesh>& mesh) const = 0; + public: + void write(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const final; + void writeIfNeeded(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, double time) const final; void writeForced(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list, double time) const final; + void writeMesh(const std::shared_ptr<const IMesh>& mesh) const final; + WriterBase() = delete; WriterBase(const std::string& base_filename, const double& time_period);