Commit b3062bde by Praetorius, Simon

### Merge branch 'feature/fixmatvec_operations' into example/stokes

parents cf5746e0 3f2e3f75
 ... ... @@ -7,8 +7,7 @@ #include #include #include #include #include namespace AMDiS { ... ...
 ... ... @@ -82,51 +82,88 @@ namespace Dune /// Convert pseudo-scalar to real scalar type /// @{ template decltype(auto) simplify(T&& t) decltype(auto) as_scalar(T&& t) { return FWD(t); } template T simplify(FieldVector const& t) T as_scalar(FieldVector const& t) { return t[0]; } template T simplify(FieldMatrix const& t) T as_scalar(FieldMatrix const& t) { return t[0][0]; } template T simplify(DiagonalMatrix const& t) T as_scalar(DiagonalMatrix const& t) { return t.diagonal(0); } /// @} /// Convert pseudo-vector to real vector type /// @{ template decltype(auto) as_vector(T&& t) { return FWD(t); } template FieldVector const& as_vector(FieldMatrix const& t) { return t[0]; } template FieldVector& as_vector(FieldMatrix& t) { return t[0]; } /// @} /// Convert pseudo-matrix to real matrix type with proper operator[][] /// @{ template decltype(auto) as_matrix(T&& t) { return FWD(t); } template class MatrixView; template MatrixView> as_matrix(DiagonalMatrix const& mat) { return {mat}; } // returns -a template auto negate(A const& a); // returns a+b template auto plus(A a, B const& b) { return a += b; } auto plus(A const& a, B const& b); // returns a-b template auto minus(A a, B const& b) { return a -= b; } auto minus(A const& a, B const& b); // returns a*b template ::value || IsNumber::value, int> = 0> std::enable_if_t::value && IsNumber::value, int> = 0> auto multiplies(A const& a, B const& b); template ::value != IsNumber::value, int> = 0> auto multiplies(A const& a, B const& b); template ... ... @@ -158,35 +195,35 @@ namespace Dune std::enable_if_t::value, int> = 0> auto operator-(A const& a) { return MatVec::negate(MatVec::simplify(a)); return MatVec::negate(MatVec::as_scalar(a)); } template ::value || MatVec::IsMatVec::value, int> = 0> auto operator+(A const& a, B const& b) { return MatVec::plus(MatVec::simplify(a), MatVec::simplify(b)); return MatVec::plus(MatVec::as_scalar(a), MatVec::as_scalar(b)); } template ::value || MatVec::IsMatVec::value, int> = 0> auto operator-(A const& a, B const& b) { return MatVec::minus(MatVec::simplify(a), MatVec::simplify(b)); return MatVec::minus(MatVec::as_scalar(a), MatVec::as_scalar(b)); } template ::value || MatVec::IsMatVec::value, int> = 0> auto operator*(A const& a, B const& b) { return MatVec::multiplies(MatVec::simplify(a), MatVec::simplify(b)); return MatVec::multiplies(MatVec::as_scalar(a), MatVec::as_scalar(b)); } template ::value || MatVec::IsMatVec::value, int> = 0> auto operator/(A const& a, B const& b) { return MatVec::divides(MatVec::simplify(a), MatVec::simplify(b)); return MatVec::divides(MatVec::as_scalar(a), MatVec::as_scalar(b)); } // ---------------------------------------------------------------------------- ... ... @@ -346,19 +383,28 @@ namespace Dune template FieldMatrix trans(FieldMatrix const& A); template DiagonalMatrix const& trans(DiagonalMatrix const& A) { return A; } // ----------------------------------------------------------------------------- template FieldMatrix multiplies_AtB(FieldMatrix const& A, FieldMatrix const& B); template FieldMatrix,M,N> multiplies_AtB(FieldMatrix const& A, FieldMatrix const& B); template FieldMatrix multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B); template FieldMatrix,M,N> multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B); template FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B, FieldMatrix& C); template FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B, FieldMatrix& C); template FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldMatrix& C); template FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldMatrix& C); template FieldVector& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldVector& C); // ----------------------------------------------------------------------------- ... ...
 ... ... @@ -3,6 +3,8 @@ #include #include #include #include #include #include ... ... @@ -19,8 +21,47 @@ namespace MatVec { return multiplies(a, -1); } // returns a+b template auto plus(A const& a, B const& b) { using T = std::common_type_t::field_type, typename FieldTraits::field_type>; typename MakeMatVec::type c{a}; auto b_ = Dune::Functions::flatVectorView(b); auto c_ = Dune::Functions::flatVectorView(c); assert(int(b_.size()) == int(c_.size())); for(int i = 0; i < int(b_.size()); ++i) c_[i] += b_[i]; return c; } // returns a-b template auto minus(A const& a, B const& b) { using T = std::common_type_t::field_type, typename FieldTraits::field_type>; typename MakeMatVec::type c{a}; auto b_ = Dune::Functions::flatVectorView(b); auto c_ = Dune::Functions::flatVectorView(c); assert(int(b_.size()) == int(c_.size())); for(int i = 0; i < int(b_.size()); ++i) c_[i] -= b_[i]; return c; } template ::value || IsNumber::value, int>> std::enable_if_t::value && IsNumber::value, int>> auto multiplies(A const& a, B const& b) { return a * b; } template ::value != IsNumber::value, int>> auto multiplies(A const& a, B const& b) { using T = std::common_type_t::field_type, typename FieldTraits::field_type>; ... ... @@ -85,6 +126,49 @@ namespace MatVec { return C; } template class MatrixView> { using Matrix = DiagonalMatrix; using size_type = typename Matrix::size_type; struct RowView { T operator[](size_type c) const { assert(0 <= c && c < mat_->M()); return c == r_ ? mat_->diagonal(r_) : T(0); } Matrix const* mat_; size_type r_; }; public: MatrixView(Matrix const& mat) : mat_(mat) {} RowView operator[](size_type r) const { assert(0 <= r && r < mat_.N()); return {&mat_,r}; } size_type N() const { return mat_.N(); } size_type M() const { return mat_.M(); } private: Matrix const& mat_; }; } // end namespace MatVec // ---------------------------------------------------------------------------- ... ... @@ -158,14 +242,14 @@ T sum(FieldMatrix const& x) template auto unary_dot(FieldVector const& x) { auto op = [](auto const& a, auto const& b) { return a + AMDiS::Math::sqr(std::abs(b)); }; auto op = [](auto const& a, auto const& b) { using std::abs; return a + AMDiS::Math::sqr(abs(b)); }; return Impl::accumulate(x, T(0), op); } template auto unary_dot(FieldMatrix const& x) { auto op = [](auto const& a, auto const& b) { return a + AMDiS::Math::sqr(std::abs(b)); }; auto op = [](auto const& a, auto const& b) { using std::abs; return a + AMDiS::Math::sqr(abs(b)); }; return Impl::accumulate(x, T(0), op); } ... ... @@ -229,14 +313,14 @@ auto abs_min(FieldMatrix const& x) template auto one_norm(FieldVector const& x) { auto op = [](auto const& a, auto const& b) { return a + std::abs(b); }; auto op = [](auto const& a, auto const& b) { using std::abs; return a + abs(b); }; return Impl::accumulate(x, T(0), op); } template auto one_norm(FieldMatrix const& x) { auto op = [](auto const& a, auto const& b) { return a + std::abs(b); }; auto op = [](auto const& a, auto const& b) { using std::abs; return a + abs(b); }; return Impl::accumulate(x, T(0), op); } ... ... @@ -261,14 +345,14 @@ auto two_norm(FieldMatrix const& x) template auto p_norm(FieldVector const& x) { auto op = [](auto const& a, auto const& b) { return a + AMDiS::Math::pow

(std::abs(b)); }; auto op = [](auto const& a, auto const& b) { using std::abs; return a + AMDiS::Math::pow

(abs(b)); }; return std::pow( Impl::accumulate(x, T(0), op), 1.0/p ); } template auto p_norm(FieldMatrix const& x) { auto op = [](auto const& a, auto const& b) { return a + AMDiS::Math::pow

(std::abs(b)); }; auto op = [](auto const& a, auto const& b) { using std::abs; return a + AMDiS::Math::pow

(abs(b)); }; return std::pow( Impl::accumulate(x, T(0), op), 1.0/p ); } ... ... @@ -293,10 +377,11 @@ auto infty_norm(FieldMatrix const& x) template T distance(FieldVector const& lhs, FieldVector const& rhs) { using std::sqrt; T result = 0; for (int i = 0; i < N; ++i) result += AMDiS::Math::sqr(lhs[i] - rhs[i]); return std::sqrt(result); return sqrt(result); } // ---------------------------------------------------------------------------- ... ... @@ -397,10 +482,10 @@ FieldMatrix trans(FieldMatrix const& A) } template FieldMatrix multiplies_AtB(FieldMatrix const& A, FieldMatrix const& B) template FieldMatrix,M,N> multiplies_AtB(FieldMatrix const& A, FieldMatrix const& B) { FieldMatrix C; FieldMatrix,M,N> C; for (int m = 0; m < M; ++m) { for (int n = 0; n < N; ++n) { ... ... @@ -412,15 +497,15 @@ FieldMatrix multiplies_AtB(FieldMatrix const& A, FieldMatrix FieldMatrix multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B) template FieldMatrix,M,N> multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B) { FieldMatrix C; FieldMatrix,M,N> C; return multiplies_ABt(A,B,C); } template FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B, FieldMatrix& C) template FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B, FieldMatrix& C) { for (int m = 0; m < M; ++m) { for (int n = 0; n < N; ++n) { ... ... @@ -432,8 +517,8 @@ FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldMatrix& C) template FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldMatrix& C) { for (int m = 0; m < M; ++m) { for (int n = 0; n < N; ++n) { ... ... @@ -443,6 +528,15 @@ FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatri return C; } template FieldVector& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldVector& C) { for (int n = 0; n < N; ++n) { C[n] = A[0][n] * B.diagonal(n); } return C; } template T const& at(FieldMatrix const& vec, std::size_t i) { ... ...