From fdf0dc1a8e1d1a0b4e9118d23e64c9ba76100ed0 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Fri, 15 Nov 2024 08:58:24 +0100
Subject: [PATCH] Add doubleDot functions for discrete functions P0 id Rdxd

---
 src/scheme/DiscreteFunctionP0.hpp |  38 ++++++++
 tests/test_DiscreteFunctionP0.cpp | 141 ++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+)

diff --git a/src/scheme/DiscreteFunctionP0.hpp b/src/scheme/DiscreteFunctionP0.hpp
index ea0ec56ae..ea53974e8 100644
--- a/src/scheme/DiscreteFunctionP0.hpp
+++ b/src/scheme/DiscreteFunctionP0.hpp
@@ -606,6 +606,44 @@ class DiscreteFunctionP0
     return result;
   }
 
+  PUGS_INLINE friend DiscreteFunctionP0<double>
+  doubleDot(const DiscreteFunctionP0& f, const DiscreteFunctionP0& g)
+  {
+    static_assert(is_tiny_matrix_v<std::decay_t<DataType>>);
+    Assert(f.m_cell_values.isBuilt() and g.m_cell_values.isBuilt());
+    Assert(f.m_mesh_v->id() == g.m_mesh_v->id());
+    DiscreteFunctionP0<double> result{f.m_mesh_v};
+    parallel_for(
+      f.m_mesh_v->numberOfCells(),
+      PUGS_LAMBDA(CellId cell_id) { result[cell_id] = doubleDot(f[cell_id], g[cell_id]); });
+
+    return result;
+  }
+
+  PUGS_INLINE friend DiscreteFunctionP0<double>
+  doubleDot(const DiscreteFunctionP0& f, const DataType& a)
+  {
+    static_assert(is_tiny_matrix_v<std::decay_t<DataType>>);
+    Assert(f.m_cell_values.isBuilt());
+    DiscreteFunctionP0<double> result{f.m_mesh_v};
+    parallel_for(
+      f.m_mesh_v->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { result[cell_id] = doubleDot(f[cell_id], a); });
+
+    return result;
+  }
+
+  PUGS_INLINE friend DiscreteFunctionP0<double>
+  doubleDot(const DataType& a, const DiscreteFunctionP0& f)
+  {
+    static_assert(is_tiny_matrix_v<std::decay_t<DataType>>);
+    Assert(f.m_cell_values.isBuilt());
+    DiscreteFunctionP0<double> result{f.m_mesh_v};
+    parallel_for(
+      f.m_mesh_v->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { result[cell_id] = doubleDot(a, f[cell_id]); });
+
+    return result;
+  }
+
   template <typename LHSDataType>
   PUGS_INLINE friend DiscreteFunctionP0<decltype(tensorProduct(LHSDataType{}, DataType{}))>
   tensorProduct(const LHSDataType& u, const DiscreteFunctionP0& v)
diff --git a/tests/test_DiscreteFunctionP0.cpp b/tests/test_DiscreteFunctionP0.cpp
index 14c96b0db..90ebb76d8 100644
--- a/tests/test_DiscreteFunctionP0.cpp
+++ b/tests/test_DiscreteFunctionP0.cpp
@@ -2729,6 +2729,53 @@ TEST_CASE("DiscreteFunctionP0", "[scheme]")
             CHECK_STD_BINARY_MATH_FUNCTION_WITH_LHS_VALUE(u, vh, dot);
           }
 
+          SECTION("doubleDot(Ah,Bh)")
+          {
+            DiscreteFunctionP0<TinyMatrix<2>> Ah{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{x + 1, 2 * x - 3, 3 - x, 3 * x - 2};
+              });
+
+            DiscreteFunctionP0<TinyMatrix<2>> Bh{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{2.3 * x, 1 - x, 2 * x, 1.5 * x};
+              });
+
+            CHECK_STD_BINARY_MATH_FUNCTION(Ah, Bh, doubleDot);
+          }
+
+          SECTION("doubleDot(Ah,B)")
+          {
+            DiscreteFunctionP0<TinyMatrix<2>> Ah{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{x + 1, 2 * x - 3, 3 - x, 3 * x - 2};
+              });
+
+            const TinyMatrix<2> B{1, 2, 3, 4};
+
+            CHECK_STD_BINARY_MATH_FUNCTION_WITH_RHS_VALUE(Ah, B, doubleDot);
+          }
+
+          SECTION("doubleDot(A,Bh)")
+          {
+            const TinyMatrix<2> A{3, -2, 4, 5};
+
+            DiscreteFunctionP0<TinyMatrix<2>> Bh{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Bh[cell_id]    = TinyMatrix<2>{2.3 * x, 1 - x, 2 * x, -x};
+              });
+
+            CHECK_STD_BINARY_MATH_FUNCTION_WITH_LHS_VALUE(A, Bh, doubleDot);
+          }
+
           SECTION("tensorProduct(uh,hv)")
           {
             DiscreteFunctionP0<TinyVector<2>> uh{mesh};
@@ -3118,6 +3165,53 @@ TEST_CASE("DiscreteFunctionP0", "[scheme]")
             CHECK_STD_BINARY_MATH_FUNCTION_WITH_LHS_VALUE(u, vh, dot);
           }
 
+          SECTION("doubleDot(Ah,Bh)")
+          {
+            DiscreteFunctionP0<TinyMatrix<2>> Ah{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{x + 1, 2 * x - 3, 3 - x, 3 * x - 2};
+              });
+
+            DiscreteFunctionP0<TinyMatrix<2>> Bh{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{2.3 * x, 1 - x, 2 * x, 1.5 * x};
+              });
+
+            CHECK_STD_BINARY_MATH_FUNCTION(Ah, Bh, doubleDot);
+          }
+
+          SECTION("doubleDot(Ah,B)")
+          {
+            DiscreteFunctionP0<TinyMatrix<2>> Ah{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{x + 1, 2 * x - 3, 3 - x, 3 * x - 2};
+              });
+
+            const TinyMatrix<2> B{1, 2, 3, 4};
+
+            CHECK_STD_BINARY_MATH_FUNCTION_WITH_RHS_VALUE(Ah, B, doubleDot);
+          }
+
+          SECTION("doubleDot(A,Bh)")
+          {
+            const TinyMatrix<2> A{3, -2, 4, 5};
+
+            DiscreteFunctionP0<TinyMatrix<2>> Bh{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Bh[cell_id]    = TinyMatrix<2>{2.3 * x, 1 - x, 2 * x, -x};
+              });
+
+            CHECK_STD_BINARY_MATH_FUNCTION_WITH_LHS_VALUE(A, Bh, doubleDot);
+          }
+
           SECTION("scalar sum")
           {
             const CellValue<const double> cell_value = positive_function.cellValues();
@@ -3460,6 +3554,53 @@ TEST_CASE("DiscreteFunctionP0", "[scheme]")
             CHECK_STD_BINARY_MATH_FUNCTION_WITH_LHS_VALUE(u, vh, dot);
           }
 
+          SECTION("doubleDot(Ah,Bh)")
+          {
+            DiscreteFunctionP0<TinyMatrix<2>> Ah{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{x + 1, 2 * x - 3, 3 - x, 3 * x - 2};
+              });
+
+            DiscreteFunctionP0<TinyMatrix<2>> Bh{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{2.3 * x, 1 - x, 2 * x, 1.5 * x};
+              });
+
+            CHECK_STD_BINARY_MATH_FUNCTION(Ah, Bh, doubleDot);
+          }
+
+          SECTION("doubleDot(Ah,B)")
+          {
+            DiscreteFunctionP0<TinyMatrix<2>> Ah{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Ah[cell_id]    = TinyMatrix<2>{x + 1, 2 * x - 3, 3 - x, 3 * x - 2};
+              });
+
+            const TinyMatrix<2> B{1, 2, 3, 4};
+
+            CHECK_STD_BINARY_MATH_FUNCTION_WITH_RHS_VALUE(Ah, B, doubleDot);
+          }
+
+          SECTION("doubleDot(A,Bh)")
+          {
+            const TinyMatrix<2> A{3, -2, 4, 5};
+
+            DiscreteFunctionP0<TinyMatrix<2>> Bh{mesh};
+            parallel_for(
+              mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+                const double x = xj[cell_id][0];
+                Bh[cell_id]    = TinyMatrix<2>{2.3 * x, 1 - x, 2 * x, -x};
+              });
+
+            CHECK_STD_BINARY_MATH_FUNCTION_WITH_LHS_VALUE(A, Bh, doubleDot);
+          }
+
           SECTION("det(Ah)")
           {
             DiscreteFunctionP0<TinyMatrix<2>> Ah{mesh};
-- 
GitLab