From 373ccd737b66013f5eaa2a7764ff7717ba424b68 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 10:26:47 +0100
Subject: [PATCH] Rework the way DiscreteFunctionP0 are constructed

This enforces coherency between data:
- the mesh
- the cell values defined on its connectivity
---
 src/scheme/DiscreteFunctionInterpoler.cpp | 56 ++++++++++++++---------
 1 file changed, 34 insertions(+), 22 deletions(-)

diff --git a/src/scheme/DiscreteFunctionInterpoler.cpp b/src/scheme/DiscreteFunctionInterpoler.cpp
index 55348a408..07e113b98 100644
--- a/src/scheme/DiscreteFunctionInterpoler.cpp
+++ b/src/scheme/DiscreteFunctionInterpoler.cpp
@@ -7,49 +7,61 @@
 #include <mesh/MeshDataManager.hpp>
 #include <utils/Exceptions.hpp>
 
-template <typename DataType>
+template <size_t Dimension, typename DataType>
 class DiscreteFunctionP0 : public IDiscreteFunction
 {
  private:
-  CellValue<DataType> m_cell_value;
+  using MeshType = Mesh<Connectivity<Dimension>>;
+
+  std::shared_ptr<const MeshType> m_mesh;
+  CellValue<DataType> m_cell_values;
 
  public:
-  DiscreteFunctionP0(const CellValue<DataType>& cell_value) : m_cell_value{cell_value} {}
-  DiscreteFunctionP0(CellValue<DataType>&& cell_value) : m_cell_value{std::move(cell_value)} {}
-  ~DiscreteFunctionP0() = default;
-};
+  PUGS_FORCEINLINE
+  DataType&
+  operator[](const CellId& cell_id) const noexcept(NO_ASSERT)
+  {
+    return m_cell_values[cell_id];
+  }
 
-template <size_t Dimension>
-std::shared_ptr<IDiscreteFunction>
-DiscreteFunctionInterpoler::_interpolate() const
-{
-  using MeshType       = Mesh<Connectivity<Dimension>>;
-  const MeshType& mesh = dynamic_cast<const MeshType&>(*m_mesh);
+  DiscreteFunctionP0(const std::shared_ptr<const MeshType>& mesh, const FunctionSymbolId& function_id) : m_mesh(mesh)
+  {
+    using MeshDataType      = MeshData<Dimension>;
+    MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*mesh);
+    m_cell_values =
+      InterpolateItemValue<DataType(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(function_id,
+                                                                                                  mesh_data.xj());
+  }
 
-  using MeshDataType      = MeshData<Dimension>;
-  MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(mesh);
+  DiscreteFunctionP0(const DiscreteFunctionP0&) noexcept = default;
+  DiscreteFunctionP0(DiscreteFunctionP0&&) noexcept      = default;
 
-  return std::make_shared<DiscreteFunctionP0<double>>(
-    InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(m_function_id,
-                                                                                              mesh_data.xj()));
-}
+  ~DiscreteFunctionP0() = default;
+};
 
 std::shared_ptr<IDiscreteFunction>
 DiscreteFunctionInterpoler::interpolate() const
 {
+  std::shared_ptr<IDiscreteFunction> discrete_function;
   switch (m_mesh->dimension()) {
   case 1: {
-    return this->_interpolate<1>();
+    std::shared_ptr mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<1>>>(m_mesh);
+    discrete_function    = std::make_shared<DiscreteFunctionP0<1, double>>(mesh, m_function_id);
+    break;
   }
   case 2: {
-    return this->_interpolate<2>();
+    std::shared_ptr mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<2>>>(m_mesh);
+    discrete_function    = std::make_shared<DiscreteFunctionP0<2, double>>(mesh, m_function_id);
+    break;
   }
   case 3: {
-    return this->_interpolate<3>();
+    std::shared_ptr mesh = std::dynamic_pointer_cast<const Mesh<Connectivity<3>>>(m_mesh);
+    discrete_function    = std::make_shared<DiscreteFunctionP0<3, double>>(mesh, m_function_id);
+    break;
   }
   default: {
     throw UnexpectedError("invalid dimension");
   }
   }
-  return nullptr;
+  return discrete_function;
 }
-- 
GitLab