From f0dbbad47974cd5ef03e45082b2c268d821e3b70 Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Tue, 19 May 2015 14:26:55 +0000
Subject: [PATCH] matrix*vector in expressions allowed

---
 AMDiS/CMakeLists.txt     |  4 ++
 AMDiS/src/DOFIndexed.h   | 42 +++++++++++++++++
 AMDiS/src/DOFVector.h    | 39 +---------------
 AMDiS/src/DOFVector.hh   |  6 +--
 AMDiS/src/FixVec.h       |  3 --
 AMDiS/src/MatrixVector.h | 98 ++++++++++++++++++++++++----------------
 AMDiS/src/Traits.h       | 13 +++++-
 7 files changed, 119 insertions(+), 86 deletions(-)

diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt
index cb9fbf91..30c4e218 100644
--- a/AMDiS/CMakeLists.txt
+++ b/AMDiS/CMakeLists.txt
@@ -651,6 +651,10 @@ FILE(GLOB HEADERS "${SOURCE_DIR}/*.hh")
 INSTALL(FILES ${HEADERS} 
 	DESTINATION include/amdis/)
 
+FILE(GLOB HEADERS "${SOURCE_DIR}/*.hpp")
+INSTALL(FILES ${HEADERS} 
+	DESTINATION include/amdis/)
+
 FILE(GLOB HEADERS "${SOURCE_DIR}/parallel/*.h")
 INSTALL(FILES ${HEADERS} 
 	DESTINATION include/amdis/parallel/)
diff --git a/AMDiS/src/DOFIndexed.h b/AMDiS/src/DOFIndexed.h
index 0aa66352..f54ba30d 100644
--- a/AMDiS/src/DOFIndexed.h
+++ b/AMDiS/src/DOFIndexed.h
@@ -33,6 +33,15 @@
 
 namespace AMDiS {
 
+  /// Specifies which operation should be done after coarsening
+  typedef enum{
+    NO_OPERATION = 0,   
+    COARSE_RESTRICT = 1,
+    COARSE_INTERPOL = 2, 
+    REFINE_INTERPOL = 4
+  } RefineCoarsenOperation;
+
+
   /** \ingroup DOFAdministration
    * \brief
    * Interface for objects that stores information indexed by DOF indices
@@ -42,6 +51,10 @@ namespace AMDiS {
   class DOFIndexedBase
   {
   public:
+    DOFIndexedBase()
+      : coarsenOperation(COARSE_INTERPOL),
+	refineOperation(REFINE_INTERPOL) {}
+  
     virtual ~DOFIndexedBase() {}
 
     /// Returns the actual size. Must be overriden by sub classes
@@ -74,9 +87,38 @@ namespace AMDiS {
     /// The default behavior is to do nothing.
     virtual void coarseRestrict(RCNeighbourList&, int) {}
 
+    /// Sets \ref coarsenOperation to op
+    inline void setCoarsenOperation(RefineCoarsenOperation op) 
+    { 
+      coarsenOperation = op; 
+    }
+
+    /// Returns \ref coarsenOperation
+    inline RefineCoarsenOperation getCoarsenOperation() 
+    { 
+      return coarsenOperation; 
+    }
+
+    /// Sets \ref refineOperation to op
+    inline void setRefineOperation(RefineCoarsenOperation op) 
+    { 
+      refineOperation = op; 
+    }
+
+    /// Returns \ref refineOperation
+    inline RefineCoarsenOperation getRefineOperation() 
+    { 
+      return refineOperation; 
+    }
+
     /// Returns the finite element space of this DOFIndexed object. Must be
     /// overriden in sub classes. 
     virtual const FiniteElemSpace* getFeSpace() const = 0;
+ 
+  protected:
+    /// Specifies what operation should be performed after coarsening
+    RefineCoarsenOperation coarsenOperation;
+    RefineCoarsenOperation refineOperation;
   };
 
   /** \ingroup DOFAdministration
diff --git a/AMDiS/src/DOFVector.h b/AMDiS/src/DOFVector.h
index 49e6125d..baa17dbb 100644
--- a/AMDiS/src/DOFVector.h
+++ b/AMDiS/src/DOFVector.h
@@ -276,14 +276,6 @@ namespace AMDiS {
   };
 
 
-  /// Specifies which operation should be done after coarsening
-  typedef enum{
-    NO_OPERATION = 0,   
-    COARSE_RESTRICT = 1,
-    COARSE_INTERPOL = 2, 
-    REFINE_INTERPOL = 4
-  } RefineCoarsenOperation;
- 
 
   /** \ingroup DOFAdministration 
    * \brief
@@ -345,8 +337,7 @@ namespace AMDiS {
   public:
     /// Empty constructor. No initialization!
     DOFVector() 
-      : DOFVectorBase<T>(), 
-	coarsenOperation(NO_OPERATION)
+      : DOFVectorBase<T>()
     {}
 
     /// Constructs a DOFVector with name n belonging to FiniteElemSpace f
@@ -395,30 +386,6 @@ namespace AMDiS {
     /// \ref DOFIndexedBase::compress()
     virtual void compressDOFIndexed(int first, int last,
 				    std::vector<DegreeOfFreedom> &newDof);
-
-    /// Sets \ref coarsenOperation to op
-    inline void setCoarsenOperation(RefineCoarsenOperation op) 
-    { 
-      coarsenOperation = op; 
-    }
-
-    /// Returns \ref coarsenOperation
-    inline RefineCoarsenOperation getCoarsenOperation() 
-    { 
-      return coarsenOperation; 
-    }
-
-    /// Sets \ref refineOperation to op
-    inline void setRefineOperation(RefineCoarsenOperation op) 
-    { 
-      refineOperation = op; 
-    }
-
-    /// Returns \ref refineOperation
-    inline RefineCoarsenOperation getRefineOperation() 
-    { 
-      return refineOperation; 
-    }
     
     /// Restriction after coarsening. Implemented for DOFVector<double>
     inline void coarseRestrict(RCNeighbourList&, int) {}
@@ -672,10 +639,6 @@ namespace AMDiS {
 
     /// Data container
     std::vector<T> vec; 
- 
-    /// Specifies what operation should be performed after coarsening
-    RefineCoarsenOperation coarsenOperation;
-    RefineCoarsenOperation refineOperation;
   }; 
 
 
diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh
index f01c6ee9..2f841a2f 100644
--- a/AMDiS/src/DOFVector.hh
+++ b/AMDiS/src/DOFVector.hh
@@ -112,9 +112,7 @@ namespace AMDiS {
  
   template<typename T>
   DOFVector<T>::DOFVector(const FiniteElemSpace* f, std::string n, bool addToSynch)
-    : DOFVectorBase<T>(f, n),
-      coarsenOperation(COARSE_INTERPOL),
-      refineOperation(REFINE_INTERPOL)
+    : DOFVectorBase<T>(f, n)
   {
     vec.resize(0);
     init(f, n, addToSynch);
@@ -1041,8 +1039,6 @@ namespace AMDiS {
     this->nBasFcts = rhs.nBasFcts;
     vec = rhs.vec;
     this->elementVector.change_dim(this->nBasFcts);
-    coarsenOperation = rhs.coarsenOperation;
-    refineOperation = rhs.refineOperation;
     this->operators = rhs.operators;
     this->operatorFactor = rhs.operatorFactor;
     
diff --git a/AMDiS/src/FixVec.h b/AMDiS/src/FixVec.h
index 21a8e369..8a06436d 100644
--- a/AMDiS/src/FixVec.h
+++ b/AMDiS/src/FixVec.h
@@ -108,9 +108,6 @@ namespace AMDiS {
       else
 	return Global::getGeo(d, dim);
     }
-
-  public:
-    friend class GLWindow;
   };
 
 
diff --git a/AMDiS/src/MatrixVector.h b/AMDiS/src/MatrixVector.h
index 83de2579..3098d9f5 100644
--- a/AMDiS/src/MatrixVector.h
+++ b/AMDiS/src/MatrixVector.h
@@ -59,26 +59,26 @@ namespace AMDiS {
     
     /// Copy constructor for other of different value_type
     // TODO: notwendig?
-    template <typename S>
-    Vector(Vector<S> const& rhs)
-      : Serializable(),
-	size(rhs.getSize()),
-	valArray(new T[rhs.getSize()])
-    {
-      setValues(rhs.getValArray());
-    }
+//     template <typename S>
+//     Vector(Vector<S> const& rhs)
+//       : Serializable(),
+// 	size(rhs.getSize()),
+// 	valArray(size ? new T[size] : NULL)
+//     {
+//       setValues(rhs.valArray);
+//     }
     
-#if HAS_RVALUE_REFERENCES
-    /// move constructor
-    Vector(self&& other)
-      : Vector()
-    {
-      swap(*this, other);
-    }
-#endif
+// #if HAS_RVALUE_REFERENCES
+//     /// move constructor
+//     Vector(self&& other)
+//       : Vector()
+//     {
+//       swap(*this, other);
+//     }
+// #endif
 
     /// Destructor.
-    ~Vector() 
+    virtual ~Vector() 
     {
       if (valArray != NULL) {
 	delete [] valArray; 
@@ -92,13 +92,13 @@ namespace AMDiS {
     }
 
     /// Change the size of the vector to newSize.
-    inline void resize(int newSize) 
+    inline void resize(int s) 
     {
-      if (size != newSize && newSize > 0) {
+      if (size != s && s > 0) {
 	if (valArray != NULL) 
 	  delete [] valArray;
-	valArray = new T[newSize];
-	size = newSize;
+	valArray = new T[s];
+	size = s;
       }
     }
 
@@ -107,15 +107,21 @@ namespace AMDiS {
     typename disable_if< boost::is_same<S, T>, self >::type &
     operator=(Vector<S> const& other) 
     {
-      resize(other.getSize());
+      assert( size == other.getSize() );
+//       resize(other.getSize());
       setValues(other.getValArray());
       return *this;
     }
     
     /// copy assignment operator
-    self& operator=(self other) 
+//     self& operator=(self other) 
+//     {
+//       swap(*this, other);
+
+    self& operator=(self const& other)
     {
-      swap(*this, other);
+      assert( size == other.getSize() );
+      setValues(other.getValArray());
       return *this;
     }
 
@@ -149,14 +155,22 @@ namespace AMDiS {
     typename enable_if< boost::is_convertible<S, T> >::type
     set(S value) 
     {
-      std::fill(begin(), end(), value);
+      for (T *thisIt = this->begin(); thisIt != this->end(); ++thisIt)
+	*thisIt = value;
+//       std::fill(begin(), end(), value);
     }
 
     /// Sets all entries.
     template <typename S>
-    void setValues(const S* values) 
+    inline void setValues(const S* values) 
     {
-      std::copy(values, values + size, valArray);
+      T *thisIt;
+      const S *valuesIt;
+      for (thisIt = this->begin(), valuesIt = values; 
+	   thisIt != this->end(); 
+	   ++thisIt, ++valuesIt) 
+	*thisIt = *valuesIt;
+//       std::copy(values, values + size, valArray);
     }
 
     /// Comparison operator.
@@ -275,14 +289,14 @@ namespace AMDiS {
 	cols(other.getNumCols())
     { }
     
-#if HAS_RVALUE_REFERENCES
-    /// move constructor
-    Matrix(self&& other)
-      : Matrix()
-    {
-      swap(*this, other);
-    }
-#endif
+// #if HAS_RVALUE_REFERENCES
+//     /// move constructor
+//     Matrix(self&& other)
+//       : Matrix()
+//     {
+//       swap(*this, other);
+//     }
+// #endif
 
     /// Changes the size of the matrix to newRows x newCols.
     inline void resize(int newRows, int newCols) 
@@ -294,9 +308,16 @@ namespace AMDiS {
       }
     }
     
-    self& operator=(self other) 
+//     self& operator=(self other) 
+//     {
+//       swap(*this, other);
+//       return *this;
+//     }
+    
+    self& operator=(self const& other)
     {
-      swap(*this, other);
+      assert( this->size == other.getSize() && rows == other.getNumRows() && cols == other.getNumCols() );
+      this->setValues(other.getValArray());
       return *this;
     }
 
@@ -304,7 +325,8 @@ namespace AMDiS {
     template <typename S>
     inline self& operator=(const Matrix<S>& other) 
     {
-      resize(other.getNumRows(), other.getNumCols());
+      assert( rows == other.getNumRows() && cols == other.getNumCols() );
+//       resize(other.getNumRows(), other.getNumCols());
       this->setValues(other.getValArray());
       return *this;
     }
diff --git a/AMDiS/src/Traits.h b/AMDiS/src/Traits.h
index dc58d9e2..554ce76c 100644
--- a/AMDiS/src/Traits.h
+++ b/AMDiS/src/Traits.h
@@ -55,7 +55,7 @@ namespace AMDiS
       typedef typename boost::mpl::if_c< (sizeof(T1) > sizeof(T2)), T1, T2 >::type type;
     };
     
-#ifdef HAS_CPP11_DECLTYPE
+#if HAS_DECLTYPE
     
     /// determines the type of the product T1*T2
     template<typename T1, typename T2>
@@ -158,6 +158,15 @@ namespace AMDiS
     };
     
     
+    /// Matrix*Vector => Vector
+    template<template<class> class MatrixType, typename T1, template<class> class VectorType, typename T2>
+    struct mult_type_dispatch<MatrixType<T1>, VectorType<T2>, tag::matrix, tag::vector>
+    {
+      typedef typename mult_type<T1, T2>::type value_type;
+      typedef VectorType<value_type> type;
+    };
+    
+    
     // addition types
     // _________________________________________________________________________
     template<typename T1, typename T2, typename Category1, typename Category2>
@@ -215,7 +224,7 @@ namespace AMDiS
       typedef Container<value_type> type;
     };
     
-#endif // endif(HAS_CPP11_DECLTYPE)
+#endif // endif(HAS_DECLTYPE)
       
       
   } // end namespace traits
-- 
GitLab