From d2987209089f5c38331d2f71e3c09106652d97df Mon Sep 17 00:00:00 2001 From: Oliver Sander <oliver.sander@tu-dresden.de> Date: Sun, 27 Dec 2015 17:45:50 +0100 Subject: [PATCH] Add more matrix operations, with an eye on adouble types This patch adds several more implementations of operator+ etc for FieldMatrices. In particular, you can now combine matrices of adoubles (the 'active' type from the ADOL-C automatic differentiation library) with regular double types. These new operators are needed for the NonplanarCosseratShellEnergy class, which is coming in the next patch. --- dune/gfe/linearalgebra.hh | 126 +++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 9 deletions(-) diff --git a/dune/gfe/linearalgebra.hh b/dune/gfe/linearalgebra.hh index 8e06338f..12ef869d 100644 --- a/dune/gfe/linearalgebra.hh +++ b/dune/gfe/linearalgebra.hh @@ -3,17 +3,17 @@ #include <dune/common/fmatrix.hh> -//! calculates ret = A * B -template< class K, int m, int n, int p > -Dune::FieldMatrix< K, m, p > operator* ( const Dune::FieldMatrix< K, m, n > &A, const Dune::FieldMatrix< K, n, p > &B) +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< K, m, p > :: size_type size_type; - Dune::FieldMatrix< K, m, p > ret; + 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 ] = K( 0 ); + ret[ i ][ j ] = 0.0; for( size_type k = 0; k < n; ++k ) ret[ i ][ j ] += A[ i ][ k ] * B[ k ][ j ]; } @@ -21,20 +21,115 @@ Dune::FieldMatrix< K, m, p > operator* ( const Dune::FieldMatrix< K, m, n > &A, return ret; } -//! calculates ret = A - B +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; +} + +//! 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) +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]; + ret[i][j] = A[i][j] + B[i][j]; return ret; } +//! 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 = A - B +template <int m, int n> +auto operator- ( const Dune::FieldMatrix< adouble, m, n > &A, const Dune::FieldMatrix< adouble, 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; +} + +//! 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> @@ -50,4 +145,17 @@ Dune::FieldMatrix<K,m,n> operator/ ( const Dune::FieldMatrix<K, m, n> &A, const 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; +} + #endif -- GitLab