Skip to content
Snippets Groups Projects
linearalgebra.hh 7.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef DUNE_GFE_LINEARALGEBRA_HH
    #define DUNE_GFE_LINEARALGEBRA_HH
    
    
    #include <dune/common/fmatrix.hh>
    
    Sander, Oliver's avatar
    Sander, Oliver committed
    #include <dune/common/version.hh>
    
    ///////////////////////////////////////////////////////////////////////////////////////////
    //  Various vector-space matrix methods
    ///////////////////////////////////////////////////////////////////////////////////////////
    
    
    #if ADOLC_ADOUBLE_H
    
    #if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7)
    
    template< int m, int n, int p >
    auto operator* ( const Dune::FieldMatrix< adouble, m, n > &A, const Dune::FieldMatrix< adouble, n, p > &B)
      -> Dune::FieldMatrix<adouble, m, p>
    
        typedef typename Dune::FieldMatrix< adouble, m, p > :: size_type size_type;
        Dune::FieldMatrix< adouble, m, p > ret;
    
        for( size_type i = 0; i < m; ++i ) {
    
            for( size_type j = 0; j < p; ++j ) {
    
                for( size_type k = 0; k < n; ++k )
                    ret[ i ][ j ] += A[ i ][ k ] * B[ k ][ j ];
            }
        }
        return ret;
    }
    
    
    template< int m, int n, int p >
    auto operator* ( const Dune::FieldMatrix< adouble, m, n > &A, const Dune::FieldMatrix< double, n, p > &B)
      -> Dune::FieldMatrix<adouble, m, p>
    {
        typedef typename Dune::FieldMatrix< adouble, m, p > :: size_type size_type;
        Dune::FieldMatrix< adouble, m, p > ret;
    
        for( size_type i = 0; i < m; ++i ) {
    
            for( size_type j = 0; j < p; ++j ) {
                ret[ i ][ j ] = 0.0;
                for( size_type k = 0; k < n; ++k )
                    ret[ i ][ j ] += A[ i ][ k ] * B[ k ][ j ];
            }
        }
        return ret;
    }
    
    template< int m, int n, int p >
    auto operator* ( const Dune::FieldMatrix< double, m, n > &A, const Dune::FieldMatrix< adouble, n, p > &B)
      -> Dune::FieldMatrix<adouble, m, p>
    {
        typedef typename Dune::FieldMatrix< adouble, m, p > :: size_type size_type;
        Dune::FieldMatrix< adouble, m, p > ret;
    
        for( size_type i = 0; i < m; ++i ) {
    
            for( size_type j = 0; j < p; ++j ) {
                ret[ i ][ j ] = 0.0;
                for( size_type k = 0; k < n; ++k )
                    ret[ i ][ j ] += A[ i ][ k ] * B[ k ][ j ];
            }
        }
        return ret;
    }
    
    #if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7)
    
    //! calculates ret = A + B
    
    template< class K, int m, int n>
    
    Dune::FieldMatrix<K,m,n> operator+ ( const Dune::FieldMatrix<K, m, n> &A, const Dune::FieldMatrix<K,m,n> &B)
    
    {
        typedef typename Dune::FieldMatrix<K,m,n> :: size_type size_type;
        Dune::FieldMatrix<K,m,n> ret;
    
        for( size_type i = 0; i < m; ++i )
            for( size_type j = 0; j < n; ++j )
    
                ret[i][j] = A[i][j] + B[i][j];
    
    //! calculates ret = A - B
    
    template <class T, int m, int n>
    auto operator- ( const Dune::FieldMatrix< T, m, n > &A, const Dune::FieldMatrix< T, m, n > &B)
      -> Dune::FieldMatrix<T, m, n>
    
        Dune::FieldMatrix<T,m,n> result;
    
        typedef typename decltype(result)::size_type size_type;
    
        for( size_type i = 0; i < m; ++i )
            for( size_type j = 0; j < n; ++j )
                result[i][j] = A[i][j] - B[i][j];
    
        return result;
    }
    
    #if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7)
    
    //! calculates ret = A - B
    template <int m, int n>
    
    auto operator- ( const Dune::FieldMatrix< adouble, m, n > &A, const Dune::FieldMatrix< double, m, n > &B)
    
      -> Dune::FieldMatrix<adouble, m, n>
    {
        Dune::FieldMatrix<adouble,m,n> result;
        typedef typename decltype(result)::size_type size_type;
    
        for( size_type i = 0; i < m; ++i )
            for( size_type j = 0; j < n; ++j )
                result[i][j] = A[i][j] - B[i][j];
    
        return result;
    }
    
    
    //! calculates ret = s*A
    template< int m, int n>
    auto operator* ( const double& s, const Dune::FieldMatrix<adouble, m, n> &A)
      -> Dune::FieldMatrix<adouble,m,n>
    {
        typedef typename Dune::FieldMatrix<adouble,m,n> :: size_type size_type;
        Dune::FieldMatrix<adouble,m,n> ret;
    
        for( size_type i = 0; i < m; ++i )
            for( size_type j = 0; j < n; ++j )
                ret[i][j] = s * A[i][j];
    
        return ret;
    }
    
    #if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7)
    
    //! calculates ret = s*A
    template< int m, int n>
    auto operator* ( const double& s, const Dune::FieldMatrix<double, m, n> &A)
      -> Dune::FieldMatrix<double,m,n>
    {
        typedef typename Dune::FieldMatrix<double,m,n> :: size_type size_type;
        Dune::FieldMatrix<double,m,n> ret;
    
        for( size_type i = 0; i < m; ++i )
            for( size_type j = 0; j < n; ++j )
                ret[i][j] = s * A[i][j];
    
        return ret;
    }
    
    //! calculates ret = A/s
    
    template< class K, int m, int n>
    Dune::FieldMatrix<K,m,n> operator/ ( const Dune::FieldMatrix<K, m, n> &A, const K& s)
    {
        typedef typename Dune::FieldMatrix<K,m,n> :: size_type size_type;
        Dune::FieldMatrix<K,m,n> ret;
    
        for( size_type i = 0; i < m; ++i )
            for( size_type j = 0; j < n; ++j )
                ret[i][j] = A[i][j] / s;
    
        return ret;
    }
    
    
    //! calculates ret = A/s
    template< class K, int m>
    Dune::FieldVector<K,m> operator/ ( const Dune::FieldVector<K, m> &A, const K& s)
    {
        typedef typename Dune::FieldVector<K,m> :: size_type size_type;
        Dune::FieldVector<K,m> result;
    
        for( size_type i = 0; i < m; ++i )
            result[i] = A[i] / s;
    
        return result;
    }
    
    
    ///////////////////////////////////////////////////////////////////////////////////////////
    //  Various other matrix methods
    ///////////////////////////////////////////////////////////////////////////////////////////
    
    namespace Dune {
    
      namespace GFE {
    
      /** \brief Return the trace of a matrix */
      template <class T, int n>
      static T trace(const FieldMatrix<T,n,n>& A)
      {
        T trace = 0;
        for (int i=0; i<n; i++)
          trace += A[i][i];
        return trace;
      }
    
      /** \brief Return the square of the trace of a matrix */
      template <class T, int n>
      static T traceSquared(const FieldMatrix<T,n,n>& A)
      {
        T trace = 0;
        for (int i=0; i<n; i++)
          trace += A[i][i];
        return trace*trace;
      }
    
      /** \brief Compute the symmetric part of a matrix A, i.e. \f$ \frac 12 (A + A^T) \f$ */
      template <class T, int n>
      static FieldMatrix<T,n,n> sym(const FieldMatrix<T,n,n>& A)
      {
        FieldMatrix<T,n,n> result;
        for (int i=0; i<n; i++)
          for (int j=0; j<n; j++)
            result[i][j] = 0.5 * (A[i][j] + A[j][i]);
        return result;
      }
    
      /** \brief Compute the antisymmetric part of a matrix A, i.e. \f$ \frac 12 (A - A^T) \f$ */
      template <class T, int n>
      static FieldMatrix<T,n,n> skew(const FieldMatrix<T,n,n>& A)
      {
        FieldMatrix<T,n,n> result;
        for (int i=0; i<n; i++)
          for (int j=0; j<n; j++)
            result[i][j] = 0.5 * (A[i][j] - A[j][i]);
        return result;
      }
    
      /** \brief Compute the deviator of a matrix A */
      template <class T, int n>
      static FieldMatrix<T,n,n> dev(const FieldMatrix<T,n,n>& A)
      {
        FieldMatrix<T,n,n> result = A;
        auto t = trace(A);
        for (int i=0; i<n; i++)
          result[i][i] -= t / n;
        return result;
      }
    
      /** \brief Return the transposed matrix */
      template <class T, int n>
      static FieldMatrix<T,n,n> transpose(const FieldMatrix<T,n,n>& A)
      {
        FieldMatrix<T,n,n> result;
    
        for (int i=0; i<n; i++)
          for (int j=0; j<n; j++)
            result[i][j] = A[j][i];
    
        return result;
      }
    
      /** \brief The Frobenius (i.e., componentwise) product of two matrices */
      template <class T, int n>
      static T frobeniusProduct(const FieldMatrix<T,n,n>& A, const FieldMatrix<T,n,n>& B)
      {
        T result(0.0);
    
        for (int i=0; i<n; i++)
          for (int j=0; j<n; j++)
            result += A[i][j] * B[i][j];
    
        return result;
      }
    
      template <class T, int n>
      static auto dyadicProduct(const FieldVector<T,n>& A, const FieldVector<T,n>& B)
      {
        FieldMatrix<T,n,n> result;
    
        for (int i=0; i<n; i++)
          for (int j=0; j<n; j++)
            result[i][j] = A[i]*B[j];
    
        return result;
      }
    
    #if ADOLC_ADOUBLE_H
      template <int n>
      static auto dyadicProduct(const FieldVector<adouble,n>& A, const FieldVector<double,n>& B)
        -> FieldMatrix<adouble,n,n>
      {
        FieldMatrix<adouble,n,n> result;
    
        for (int i=0; i<n; i++)
          for (int j=0; j<n; j++)
            result[i][j] = A[i]*B[j];
    
        return result;
      }
    #endif
    
      }
    }