diff --git a/src/language/modules/WriterModule.cpp b/src/language/modules/WriterModule.cpp index fbfcbfd62f6aec2213b0c005b6cc0f4f58412ce3..00095779ba4f184e1ef62afcd5cc17d6833f71d9 100644 --- a/src/language/modules/WriterModule.cpp +++ b/src/language/modules/WriterModule.cpp @@ -203,4 +203,14 @@ WriterModule::registerCheckpointResume() const const HighFive::Group& symbol_table_group) -> EmbeddedData { return readINamedDiscreteData(symbol_name, symbol_table_group); })); + + CheckpointResumeRepository::instance() + .addCheckpointResume(ast_node_data_type_from<std::shared_ptr<const IWriter>>, + std::function([](const std::string& symbol_name, const EmbeddedData& embedded_data, + HighFive::File& file, HighFive::Group& checkpoint_group, + HighFive::Group& symbol_table_group) { + writeIWriter(symbol_name, embedded_data, file, checkpoint_group, symbol_table_group); + }), + std::function([](const std::string& symbol_name, const HighFive::Group& symbol_table_group) + -> EmbeddedData { return readIWriter(symbol_name, symbol_table_group); })); } diff --git a/src/output/GnuplotWriter.hpp b/src/output/GnuplotWriter.hpp index 3069b79da716d2640e8446822e23fcab37b98316..7bfc671601b5a442619354d3c989572fa0d7cc2b 100644 --- a/src/output/GnuplotWriter.hpp +++ b/src/output/GnuplotWriter.hpp @@ -61,6 +61,12 @@ class GnuplotWriter final : public WriterBase void _writeMesh(const MeshVariant& mesh_v) const final; public: + Type + type() const final + { + return Type::gnuplot; + } + 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.hpp b/src/output/GnuplotWriter1D.hpp index 66661918252856d8b6a069773c931c705a9b9330..8b49e1935f5526603960e6995613cb3481eabd30 100644 --- a/src/output/GnuplotWriter1D.hpp +++ b/src/output/GnuplotWriter1D.hpp @@ -60,6 +60,12 @@ class GnuplotWriter1D final : public WriterBase void _writeMesh(const MeshVariant& mesh_v) const final; public: + Type + type() const final + { + return Type::gnuplot_1d; + } + 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 3d821fdacaaf12b3ec28560cf6197fde29e9494c..742d0cf349a6d64356cc6021ec0a380247c1d50b 100644 --- a/src/output/IWriter.hpp +++ b/src/output/IWriter.hpp @@ -11,6 +11,15 @@ class MeshVariant; class IWriter { public: + enum class Type + { + gnuplot, + gnuplot_1d, + vtk + }; + + virtual Type type() const = 0; + virtual void writeMesh(const std::shared_ptr<const MeshVariant>& mesh_v) const = 0; virtual void writeMesh(const MeshVariant& mesh_v) const = 0; diff --git a/src/output/VTKWriter.hpp b/src/output/VTKWriter.hpp index 6c40f1005952d1649dcbd989f639907826a312fd..94c1fb8442bdfaa8bd9ee162f04c084c9714c09e 100644 --- a/src/output/VTKWriter.hpp +++ b/src/output/VTKWriter.hpp @@ -109,6 +109,12 @@ class VTKWriter final : public WriterBase void _writeMesh(const MeshVariant& mesh_v) const final; public: + Type + type() const final + { + return Type::vtk; + } + 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 bc7f90be252c42465ec3107f6f362f9658997909..5baa126018248dcddd6c3178e72aba2043162354 100644 --- a/src/output/WriterBase.cpp +++ b/src/output/WriterBase.cpp @@ -304,7 +304,9 @@ WriterBase::WriterBase(const std::string& base_filename, const double& time_peri : m_base_filename{base_filename}, m_period_manager(time_period), m_signature(std::nullopt) {} -WriterBase::WriterBase(const std::string& base_filename) : m_base_filename{base_filename}, m_signature(std::nullopt) {} +WriterBase::WriterBase(const std::string& base_filename) + : m_base_filename{base_filename}, m_period_manager{std::nullopt}, m_signature(std::nullopt) +{} void WriterBase::write(const std::vector<std::shared_ptr<const INamedDiscreteData>>& named_discrete_data_list) const diff --git a/src/output/WriterBase.hpp b/src/output/WriterBase.hpp index c07c20c711e827ae566635ca82c9456bbda853ac..d3821b964e2fde6a6baf36c732460b40e61216d1 100644 --- a/src/output/WriterBase.hpp +++ b/src/output/WriterBase.hpp @@ -4,6 +4,8 @@ #include <output/IWriter.hpp> #include <utils/PugsAssert.hpp> +#include <utils/HighFivePugsUtils.hpp> + #include <limits> #include <optional> #include <string> @@ -11,6 +13,7 @@ class MeshVariant; class OutputNamedItemDataSet; class NamedDiscreteFunction; +class EmbeddedData; class WriterBase : public IWriter { @@ -42,6 +45,12 @@ class WriterBase : public IWriter m_next_time = next_time; } + const std::vector<double>& + getSavedTimes() const + { + return m_saved_times; + } + size_t nbSavedTimes() const { @@ -79,9 +88,22 @@ class WriterBase : public IWriter PeriodManager(PeriodManager&&) = default; PeriodManager(double time_period) : m_time_period{time_period}, m_next_time{std::numeric_limits<double>::lowest()} {} + PeriodManager(double time_period, double next_time, const std::vector<double>& saved_times) + : m_time_period{time_period}, m_next_time{next_time}, m_saved_times{saved_times} + {} }; protected: + // useful for checkpoint + friend void writeIWriter(const std::string& symbol_name, + const EmbeddedData& embedded_data, + HighFive::File& file, + HighFive::Group& checkpoint_group, + HighFive::Group& symbol_table_group); + + // useful for resume + friend EmbeddedData readIWriter(const std::string& symbol_name, const HighFive::Group& symbol_table_group); + const std::string m_base_filename; std::optional<PeriodManager> m_period_manager; diff --git a/src/utils/checkpointing/CheckpointUtils.cpp b/src/utils/checkpointing/CheckpointUtils.cpp index 8649a2f5d1564ecf951dbb8fdabf459a3f055b3a..3db38f27756af45305722043ad29c77f2a00d974 100644 --- a/src/utils/checkpointing/CheckpointUtils.cpp +++ b/src/utils/checkpointing/CheckpointUtils.cpp @@ -23,6 +23,7 @@ #include <output/NamedDiscreteFunction.hpp> #include <output/NamedItemArrayVariant.hpp> #include <output/NamedItemValueVariant.hpp> +#include <output/WriterBase.hpp> #include <scheme/DiscreteFunctionP0.hpp> #include <scheme/DiscreteFunctionP0Vector.hpp> #include <scheme/DiscreteFunctionVariant.hpp> @@ -32,6 +33,7 @@ #include <utils/checkpointing/IBoundaryDescriptorHFType.hpp> #include <utils/checkpointing/IInterfaceDescriptorHFType.hpp> #include <utils/checkpointing/INamedDiscreteDataHF.hpp> +#include <utils/checkpointing/IWriterHFType.hpp> #include <utils/checkpointing/IZoneDescriptorHFType.hpp> #include <utils/checkpointing/ItemTypeHFType.hpp> #include <utils/checkpointing/OStreamTypeHFType.hpp> @@ -608,6 +610,44 @@ writeItemValueVariant(const std::string& symbol_name, writeItemValueVariant(variable_group, item_value_variant_p, file, checkpoint_group); } +void +writeIWriter(const std::string& symbol_name, + const EmbeddedData& embedded_data, + HighFive::File&, + HighFive::Group&, + HighFive::Group& symbol_table_group) +{ + HighFive::Group variable_group = symbol_table_group.createGroup("embedded/" + symbol_name); + + std::shared_ptr<const IWriter> iwriter_p = + dynamic_cast<const DataHandler<const IWriter>&>(embedded_data.get()).data_ptr(); + + variable_group.createAttribute("iwriter_type", iwriter_p->type()); + + switch (iwriter_p->type()) { + case IWriter::Type::gnuplot: + case IWriter::Type::gnuplot_1d: + case IWriter::Type::vtk: { + const WriterBase& writer = dynamic_cast<const WriterBase&>(*iwriter_p); + + variable_group.createAttribute("base_filename", writer.m_base_filename); + if (writer.m_signature.has_value()) { + variable_group.createAttribute("signature", writer.m_signature.value()); + } + if (writer.m_period_manager.has_value()) { + const WriterBase::PeriodManager period_manager = writer.m_period_manager.value(); + HighFive::Group period_manager_group = variable_group.createGroup("period_manager"); + + period_manager_group.createAttribute("time_period", period_manager.timePeriod()); + period_manager_group.createAttribute("next_time", period_manager.nextTime()); + period_manager_group.createAttribute("saved_times", period_manager.getSavedTimes()); + } + + break; + } + } +} + void writeIZoneDescriptor(const std::string& symbol_name, const EmbeddedData& embedded_data, diff --git a/src/utils/checkpointing/CheckpointUtils.hpp b/src/utils/checkpointing/CheckpointUtils.hpp index 89030bd51246b3178d0c73cd7bb705ef2b0abada..0019d85fddbc3a32d1521ae8d95c8f028ce143c6 100644 --- a/src/utils/checkpointing/CheckpointUtils.hpp +++ b/src/utils/checkpointing/CheckpointUtils.hpp @@ -173,6 +173,12 @@ void writeItemValueVariant(const std::string& symbol_name, HighFive::Group& checkpoint_group, HighFive::Group& symbol_table_group); +void writeIWriter(const std::string& symbol_name, + const EmbeddedData& embedded_data, + HighFive::File& file, + HighFive::Group& checkpoint_group, + HighFive::Group& symbol_table_group); + void writeIZoneDescriptor(const std::string& symbol_name, const EmbeddedData& embedded_data, HighFive::File& file, diff --git a/src/utils/checkpointing/IWriterHFType.hpp b/src/utils/checkpointing/IWriterHFType.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cb26891be92365a54c8ffda976554c14158705a7 --- /dev/null +++ b/src/utils/checkpointing/IWriterHFType.hpp @@ -0,0 +1,14 @@ +#ifndef I_WRITER_HF_TYPE_HPP +#define I_WRITER_HF_TYPE_HPP + +#include <output/IWriter.hpp> +#include <utils/checkpointing/CheckpointUtils.hpp> + +HighFive::EnumType<IWriter::Type> PUGS_INLINE +create_enum_i_writer_type() +{ + return {{"gnuplot", IWriter::Type::gnuplot}, {"gnuplot_1d", IWriter::Type::gnuplot_1d}, {"vtk", IWriter::Type::vtk}}; +} +HIGHFIVE_REGISTER_TYPE(IWriter::Type, create_enum_i_writer_type); + +#endif // I_WRITER_HF_TYPE_HPP diff --git a/src/utils/checkpointing/ResumeUtils.cpp b/src/utils/checkpointing/ResumeUtils.cpp index 0b5c21f5bcc7aed622939908e54f7689af13de10..ca2c55eec67d04c3189ebf8b65df7af24c4cfc40 100644 --- a/src/utils/checkpointing/ResumeUtils.cpp +++ b/src/utils/checkpointing/ResumeUtils.cpp @@ -14,9 +14,12 @@ #include <mesh/NumberedBoundaryDescriptor.hpp> #include <mesh/NumberedInterfaceDescriptor.hpp> #include <mesh/NumberedZoneDescriptor.hpp> +#include <output/GnuplotWriter.hpp> +#include <output/GnuplotWriter1D.hpp> #include <output/NamedDiscreteFunction.hpp> #include <output/NamedItemArrayVariant.hpp> #include <output/NamedItemValueVariant.hpp> +#include <output/VTKWriter.hpp> #include <scheme/AxisBoundaryConditionDescriptor.hpp> #include <scheme/DirichletBoundaryConditionDescriptor.hpp> #include <scheme/DiscreteFunctionDescriptorP0.hpp> @@ -37,6 +40,7 @@ #include <utils/checkpointing/IBoundaryDescriptorHFType.hpp> #include <utils/checkpointing/IInterfaceDescriptorHFType.hpp> #include <utils/checkpointing/INamedDiscreteDataHF.hpp> +#include <utils/checkpointing/IWriterHFType.hpp> #include <utils/checkpointing/IZoneDescriptorHFType.hpp> #include <utils/checkpointing/ItemTypeHFType.hpp> #include <utils/checkpointing/OStreamTypeHFType.hpp> @@ -459,6 +463,50 @@ readItemValueVariant(const std::string& symbol_name, const HighFive::Group& symb return {std::make_shared<DataHandler<const ItemValueVariant>>(readItemValueVariant(item_value_variant_group))}; } +EmbeddedData +readIWriter(const std::string& symbol_name, const HighFive::Group& symbol_table_group) +{ + const HighFive::Group iwriter_group = symbol_table_group.getGroup("embedded/" + symbol_name); + + std::shared_ptr<WriterBase> p_writer; + + IWriter::Type type = iwriter_group.getAttribute("iwriter_type").read<IWriter::Type>(); + + std::string base_filename = iwriter_group.getAttribute("base_filename").read<std::string>(); + + switch (type) { + case IWriter::Type::gnuplot: { + p_writer = std::make_shared<GnuplotWriter>(base_filename); + break; + } + case IWriter::Type::gnuplot_1d: { + p_writer = std::make_shared<GnuplotWriter1D>(base_filename); + break; + } + case IWriter::Type::vtk: { + p_writer = std::make_shared<VTKWriter>(base_filename); + break; + } + } + + if (iwriter_group.exist("period_manager")) { + HighFive::Group period_manager_group = iwriter_group.getGroup("period_manager"); + + const double time_period = period_manager_group.getAttribute("time_period").read<double>(); + const double next_time = period_manager_group.getAttribute("next_time").read<double>(); + const std::vector<double> saved_times = + period_manager_group.getAttribute("saved_times").read<std::vector<double>>(); + + p_writer->m_period_manager.emplace(WriterBase::PeriodManager(time_period, next_time, saved_times)); + } + + if (iwriter_group.hasAttribute("signature")) { + p_writer->m_signature = iwriter_group.getAttribute("signature").read<std::string>(); + } + + return {std::make_shared<DataHandler<const IWriter>>(p_writer)}; +} + EmbeddedData readIZoneDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group) { diff --git a/src/utils/checkpointing/ResumeUtils.hpp b/src/utils/checkpointing/ResumeUtils.hpp index dbdc5611d88a5305d3e78ab137d6419896274be2..50e4a67a4d7aba453d8ff8355208c08361494dce 100644 --- a/src/utils/checkpointing/ResumeUtils.hpp +++ b/src/utils/checkpointing/ResumeUtils.hpp @@ -92,6 +92,7 @@ EmbeddedData readIQuadratureDescriptor(const std::string& symbol_name, const Hig EmbeddedData readItemArrayVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group); EmbeddedData readItemType(const std::string& symbol_name, const HighFive::Group& symbol_table_group); EmbeddedData readItemValueVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group); +EmbeddedData readIWriter(const std::string& symbol_name, const HighFive::Group& symbol_table_group); EmbeddedData readIZoneDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group); EmbeddedData readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_group); EmbeddedData readOStream(const std::string& symbol_name, const HighFive::Group& symbol_table_group);