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);