From ceb8691a87f2150bdba0c7b54b8d6e4391d8d878 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Thu, 4 Feb 2021 17:17:42 +0100
Subject: [PATCH] Begin discrete function output from script files

Actually one needs to pass the discrete function and its name to the
writer method. With this commit one just checks that the given
functions are all defined on a same mesh.
---
 src/language/modules/VTKModule.cpp         | 63 +++++++++++++++++++++-
 src/scheme/DiscreteFunctionInterpoler.cpp  |  6 +++
 src/scheme/DiscreteFunctionType.hpp        |  9 ++++
 src/scheme/IDiscreteFunction.hpp           |  8 +++
 src/scheme/IDiscreteFunctionDescriptor.hpp | 11 ++--
 5 files changed, 88 insertions(+), 9 deletions(-)
 create mode 100644 src/scheme/DiscreteFunctionType.hpp

diff --git a/src/language/modules/VTKModule.cpp b/src/language/modules/VTKModule.cpp
index ce84141ee..3144460fb 100644
--- a/src/language/modules/VTKModule.cpp
+++ b/src/language/modules/VTKModule.cpp
@@ -6,10 +6,11 @@
 #include <mesh/GmshReader.hpp>
 #include <mesh/Mesh.hpp>
 #include <output/VTKWriter.hpp>
+#include <scheme/IDiscreteFunction.hpp>
 
 VTKModule::VTKModule()
 {
-  this->_addBuiltinFunction("writeVTK",
+  this->_addBuiltinFunction("writeMeshVTK",
                             std::make_shared<
                               BuiltinFunctionEmbedder<void(std::shared_ptr<const IMesh>, const std::string&)>>(
 
@@ -57,5 +58,65 @@ VTKModule::VTKModule()
                                 time++;
                               }
 
+                              ));
+
+  this->_addBuiltinFunction("writeVTK",
+                            std::make_shared<BuiltinFunctionEmbedder<
+                              void(const std::vector<std::shared_ptr<const IDiscreteFunction>>&, const std::string&)>>(
+
+                              [](const std::vector<std::shared_ptr<const IDiscreteFunction>>& discrete_function_list,
+                                 const std::string& filename) -> void {
+                                Assert(discrete_function_list.size() > 0);
+
+                                VTKWriter writer(filename, 0.1);
+
+                                static double time = 0;
+
+                                std::shared_ptr p_mesh = discrete_function_list[0]->mesh();
+                                for (size_t i = 1; i < discrete_function_list.size(); ++i) {
+                                  if (p_mesh != discrete_function_list[i]->mesh()) {
+                                    throw NormalError("discrete functions must be defined on the same mesh!");
+                                  }
+                                }
+
+                                switch (p_mesh->dimension()) {
+                                case 1: {
+                                  using MeshType = Mesh<Connectivity<1>>;
+                                  const std::shared_ptr<const MeshType> mesh =
+                                    std::dynamic_pointer_cast<const MeshType>(p_mesh);
+
+                                  writer.write(mesh,
+                                               OutputNamedItemValueSet{
+                                                 NamedItemValue{"cell_number", mesh->connectivity().cellNumber()}},
+                                               time, true);
+                                  break;
+                                }
+                                case 2: {
+                                  using MeshType = Mesh<Connectivity<2>>;
+                                  const std::shared_ptr<const MeshType> mesh =
+                                    std::dynamic_pointer_cast<const MeshType>(p_mesh);
+
+                                  writer.write(mesh,
+                                               OutputNamedItemValueSet{
+                                                 NamedItemValue{"cell_number", mesh->connectivity().cellNumber()}},
+                                               time, true);
+                                  break;
+                                }
+                                case 3: {
+                                  using MeshType = Mesh<Connectivity<3>>;
+                                  const std::shared_ptr<const MeshType> mesh =
+                                    std::dynamic_pointer_cast<const MeshType>(p_mesh);
+
+                                  writer.write(mesh,
+                                               OutputNamedItemValueSet{
+                                                 NamedItemValue{"cell_number", mesh->connectivity().cellNumber()}},
+                                               time, true);
+                                  break;
+                                }
+                                }
+
+                                time++;
+                              }
+
                               ));
 }
diff --git a/src/scheme/DiscreteFunctionInterpoler.cpp b/src/scheme/DiscreteFunctionInterpoler.cpp
index 07e113b98..60b481cde 100644
--- a/src/scheme/DiscreteFunctionInterpoler.cpp
+++ b/src/scheme/DiscreteFunctionInterpoler.cpp
@@ -17,6 +17,12 @@ class DiscreteFunctionP0 : public IDiscreteFunction
   CellValue<DataType> m_cell_values;
 
  public:
+  std::shared_ptr<const IMesh>
+  mesh() const
+  {
+    return m_mesh;
+  }
+
   PUGS_FORCEINLINE
   DataType&
   operator[](const CellId& cell_id) const noexcept(NO_ASSERT)
diff --git a/src/scheme/DiscreteFunctionType.hpp b/src/scheme/DiscreteFunctionType.hpp
new file mode 100644
index 000000000..debf86349
--- /dev/null
+++ b/src/scheme/DiscreteFunctionType.hpp
@@ -0,0 +1,9 @@
+#ifndef DISCRETE_FUNCTION_TYPE_HPP
+#define DISCRETE_FUNCTION_TYPE_HPP
+
+enum class DiscreteFunctionType
+{
+  P0
+};
+
+#endif   // DISCRETE_FUNCTION_TYPE_HPP
diff --git a/src/scheme/IDiscreteFunction.hpp b/src/scheme/IDiscreteFunction.hpp
index 3eea07af9..eafea0e96 100644
--- a/src/scheme/IDiscreteFunction.hpp
+++ b/src/scheme/IDiscreteFunction.hpp
@@ -1,9 +1,17 @@
 #ifndef I_DISCRETE_FUNCTION_HPP
 #define I_DISCRETE_FUNCTION_HPP
 
+#include <scheme/DiscreteFunctionType.hpp>
+
+#include <memory>
+
+class IMesh;
+
 class IDiscreteFunction
 {
  public:
+  virtual std::shared_ptr<const IMesh> mesh() const = 0;
+
   IDiscreteFunction() = default;
 
   IDiscreteFunction(const IDiscreteFunction&) = default;
diff --git a/src/scheme/IDiscreteFunctionDescriptor.hpp b/src/scheme/IDiscreteFunctionDescriptor.hpp
index c2b795d6d..fcd9fdd1a 100644
--- a/src/scheme/IDiscreteFunctionDescriptor.hpp
+++ b/src/scheme/IDiscreteFunctionDescriptor.hpp
@@ -1,15 +1,10 @@
 #ifndef I_DISCRETE_FUNCTION_DESCRIPTOR_HPP
 #define I_DISCRETE_FUNCTION_DESCRIPTOR_HPP
 
-enum class DiscreteFunctionDescriptorType
-{
-  P0
-};
-
 class IDiscreteFunctionDescriptor
 {
  public:
-  virtual DiscreteFunctionDescriptorType type() const = 0;
+  virtual DiscreteFunctionType type() const = 0;
 
   IDiscreteFunctionDescriptor() noexcept = default;
 
@@ -23,10 +18,10 @@ class IDiscreteFunctionDescriptor
 class DiscreteFunctionDescriptorP0 : public IDiscreteFunctionDescriptor
 {
  public:
-  DiscreteFunctionDescriptorType
+  DiscreteFunctionType
   type() const final
   {
-    return DiscreteFunctionDescriptorType::P0;
+    return DiscreteFunctionType::P0;
   }
 
   DiscreteFunctionDescriptorP0() noexcept = default;
-- 
GitLab