From 1ece230ef3e8e914b214bf7ba93c2e336fe5be6d Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Fri, 14 Oct 2011 16:59:10 +0000
Subject: [PATCH] A three-dimensional matrix with two static and one dynamic
 dimension

[[Imported from SVN: r7924]]
---
 dune/gfe/Makefile.am  |  1 +
 dune/gfe/tensorssd.hh | 95 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)
 create mode 100644 dune/gfe/tensorssd.hh

diff --git a/dune/gfe/Makefile.am b/dune/gfe/Makefile.am
index bd9c3f23..51867819 100644
--- a/dune/gfe/Makefile.am
+++ b/dune/gfe/Makefile.am
@@ -31,6 +31,7 @@ srcinclude_HEADERS = averagedistanceassembler.hh \
                      skewmatrix.hh \
                      svd.hh \
                      targetspacertrsolver.hh \
+                     tensorssd.hh \
                      tensor3.hh \
                      unitvector.hh
 
diff --git a/dune/gfe/tensorssd.hh b/dune/gfe/tensorssd.hh
new file mode 100644
index 00000000..17f72448
--- /dev/null
+++ b/dune/gfe/tensorssd.hh
@@ -0,0 +1,95 @@
+#ifndef DUNE_TENSOR_SSD_HH
+#define DUNE_TENSOR_SSD_HH
+
+/** \file
+    \brief A third-rank tensor with two static (SS) and one dynamic (D) dimension
+    */
+
+#include <dune/common/array.hh>
+#include <dune/common/fmatrix.hh>
+    
+/** \brief A third-rank tensor with two static (SS) and one dynamic (D) dimension
+ * 
+ * \tparam T Type of the entries
+ * \tparam N1 Size of the first dimension
+ * \tparam N2 Size of the second dimension
+*/
+template <class T, int N1, int N2>
+class TensorSSD
+{
+public:
+
+    /** \brief Constructor with the third dimension */
+    explicit TensorSSD(size_t N3)
+    : N3_(N3)
+    {
+        for (int i=0; i<N1; i++)
+            for (int j=0; j<N2; j++)
+                data_[i][j].resize(N3_);
+    }
+        
+    size_t dim(int index) const
+    {
+        switch (index) {
+            case 0:
+                return N1;
+            case 1:
+                return N2;
+            case 2:
+                return N3_;
+            default:
+                assert(false);
+        }
+    }
+        
+    /** \brief Assignment from scalar */
+    TensorSSD<T,N1,N2>& operator=(const T& scalar)
+    {
+        for (int i=0; i<N1; i++)
+            for (int j=0; j<N2; j++)
+                for (size_t k=0; k<dim(2); k++)
+                    data_[i][j][k] = scalar;
+                    
+        return *this;
+    }
+
+    friend TensorSSD<T,N1,N2> operator*(const TensorSSD<T,N1,N2>& a, const Dune::Matrix<Dune::FieldMatrix<T,1,1> >& b)
+    {
+        TensorSSD<T,N1,N2> result(b.M());
+            
+        assert(a.dim(2)==b.N());
+        size_t N4 = a.dim(2);  // third dimension of a
+            
+        for (int i=0; i<N1; i++)
+            for (int j=0; j<N2; j++)
+                for (size_t k=0; k<b.M(); k++) {
+                    result.data_[i][j][k] = 0;
+                    for (size_t l=0; l<N4; l++)
+                        result.data_[i][j][k] += a.data_[i][j][l]*b[l][k][0][0];
+                }
+                    
+        return result;
+    }
+
+    friend TensorSSD<T,N1,N2> operator+(const TensorSSD<T,N1,N2>& a, const TensorSSD<T,N1,N2>& b)
+    {
+        assert(a.dim(2)==b.dim(2));
+        size_t N3 = a.dim(2);
+        TensorSSD<T,N1,N2> result(N3);
+            
+        for (int i=0; i<N1; i++)
+            for (int j=0; j<N2; j++)
+                for (size_t k=0; k<N3; k++)
+                    result.data_[i][j][k] = a.data_[i][j][k] + b.data_[i][j][k];
+                    
+        return result;
+    }
+
+    // having the dynamic data type on the inside is kind of a stupid data layout
+    Dune::array<Dune::array<std::vector<T>, N2>, N1> data_;
+    
+    // size of the third dimension
+    size_t N3_;
+};
+
+#endif
\ No newline at end of file
-- 
GitLab