Commit b3062bde by Praetorius, Simon

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

parents cf5746e0 3f2e3f75
 ... @@ -7,8 +7,7 @@ ... @@ -7,8 +7,7 @@ #include #include #include #include #include #include #include namespace AMDiS { namespace AMDiS { ... ...
 ... @@ -82,51 +82,88 @@ namespace Dune ... @@ -82,51 +82,88 @@ namespace Dune /// Convert pseudo-scalar to real scalar type /// Convert pseudo-scalar to real scalar type /// @{ /// @{ template template decltype(auto) simplify(T&& t) decltype(auto) as_scalar(T&& t) { { return FWD(t); return FWD(t); } } template template T simplify(FieldVector const& t) T as_scalar(FieldVector const& t) { { return t[0]; return t[0]; } } template template T simplify(FieldMatrix const& t) T as_scalar(FieldMatrix const& t) { { return t[0][0]; return t[0][0]; } } template template T simplify(DiagonalMatrix const& t) T as_scalar(DiagonalMatrix const& t) { { return t.diagonal(0); 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 // returns -a template template auto negate(A const& a); auto negate(A const& a); // returns a+b // returns a+b template template auto plus(A a, B const& b) auto plus(A const& a, B const& b); { return a += b; } // returns a-b // returns a-b template template auto minus(A a, B const& b) auto minus(A const& a, B const& b); { return a -= b; } // returns a*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); auto multiplies(A const& a, B const& b); template template ... @@ -158,35 +195,35 @@ namespace Dune ... @@ -158,35 +195,35 @@ namespace Dune std::enable_if_t::value, int> = 0> std::enable_if_t::value, int> = 0> auto operator-(A const& a) 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> std::enable_if_t::value || MatVec::IsMatVec::value, int> = 0> auto operator+(A const& a, B const& b) 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> std::enable_if_t::value || MatVec::IsMatVec::value, int> = 0> auto operator-(A const& a, B const& b) 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> std::enable_if_t::value || MatVec::IsMatVec::value, int> = 0> auto operator*(A const& a, B const& b) 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> std::enable_if_t::value || MatVec::IsMatVec::value, int> = 0> auto operator/(A const& a, B const& b) 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 ... @@ -346,19 +383,28 @@ namespace Dune template template FieldMatrix trans(FieldMatrix const& A); FieldMatrix trans(FieldMatrix const& A); template DiagonalMatrix const& trans(DiagonalMatrix const& A) { return A; } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- template template FieldMatrix multiplies_AtB(FieldMatrix const& A, FieldMatrix const& B); FieldMatrix,M,N> multiplies_AtB(FieldMatrix const& A, FieldMatrix const& B); template template FieldMatrix multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B); FieldMatrix,M,N> multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B); template template FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B, FieldMatrix& C); FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B, FieldMatrix& C); template template FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldMatrix& C); 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 @@ ... @@ -3,6 +3,8 @@ #include #include #include #include #include #include #include #include #include #include #include ... @@ -19,8 +21,47 @@ namespace MatVec { ... @@ -19,8 +21,47 @@ namespace MatVec { return multiplies(a, -1); 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) auto multiplies(A const& a, B const& b) { { using T = std::common_type_t::field_type, typename FieldTraits::field_type>; using T = std::common_type_t::field_type, typename FieldTraits::field_type>; ... @@ -85,6 +126,49 @@ namespace MatVec { ... @@ -85,6 +126,49 @@ namespace MatVec { return C; 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 } // end namespace MatVec // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- ... @@ -158,14 +242,14 @@ T sum(FieldMatrix const& x) ... @@ -158,14 +242,14 @@ T sum(FieldMatrix const& x) template template auto unary_dot(FieldVector const& x) 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); return Impl::accumulate(x, T(0), op); } } template template auto unary_dot(FieldMatrix const& x) 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); return Impl::accumulate(x, T(0), op); } } ... @@ -229,14 +313,14 @@ auto abs_min(FieldMatrix const& x) ... @@ -229,14 +313,14 @@ auto abs_min(FieldMatrix const& x) template template auto one_norm(FieldVector const& x) 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); return Impl::accumulate(x, T(0), op); } } template template auto one_norm(FieldMatrix const& x) 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); return Impl::accumulate(x, T(0), op); } } ... @@ -261,14 +345,14 @@ auto two_norm(FieldMatrix const& x) ... @@ -261,14 +345,14 @@ auto two_norm(FieldMatrix const& x) template template auto p_norm(FieldVector const& x) 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 ); return std::pow( Impl::accumulate(x, T(0), op), 1.0/p ); } } template template auto p_norm(FieldMatrix const& x) 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 ); return std::pow( Impl::accumulate(x, T(0), op), 1.0/p ); } } ... @@ -293,10 +377,11 @@ auto infty_norm(FieldMatrix const& x) ... @@ -293,10 +377,11 @@ auto infty_norm(FieldMatrix const& x) template template T distance(FieldVector const& lhs, FieldVector const& rhs) T distance(FieldVector const& lhs, FieldVector const& rhs) { { using std::sqrt; T result = 0; T result = 0; for (int i = 0; i < N; ++i) for (int i = 0; i < N; ++i) result += AMDiS::Math::sqr(lhs[i] - rhs[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) ... @@ -397,10 +482,10 @@ FieldMatrix trans(FieldMatrix const& A) } } template template FieldMatrix multiplies_AtB(FieldMatrix const& A, FieldMatrix const& B) 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 m = 0; m < M; ++m) { for (int n = 0; n < N; ++n) { for (int n = 0; n < N; ++n) { ... @@ -412,15 +497,15 @@ FieldMatrix multiplies_AtB(FieldMatrix const& A, FieldMatrix multiplies_AtB(FieldMatrix const& A, FieldMatrix template FieldMatrix multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B) FieldMatrix,M,N> multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B) { { FieldMatrix C; FieldMatrix,M,N> C; return multiplies_ABt(A,B,C); return multiplies_ABt(A,B,C); } } template template FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B, FieldMatrix& C) FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix const& B, FieldMatrix& C) { { for (int m = 0; m < M; ++m) { for (int m = 0; m < M; ++m) { for (int n = 0; n < N; ++n) { for (int n = 0; n < N; ++n) { ... @@ -432,8 +517,8 @@ FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix& multiplies_ABt(FieldMatrix const& A, FieldMatrix template FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldMatrix& C) FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatrix const& B, FieldMatrix& C) { { for (int m = 0; m < M; ++m) { for (int m = 0; m < M; ++m) { for (int n = 0; n < N; ++n) { for (int n = 0; n < N; ++n) { ... @@ -443,6 +528,15 @@ FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatri ... @@ -443,6 +528,15 @@ FieldMatrix& multiplies_ABt(FieldMatrix const& A, DiagonalMatri return C; 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 template T const& at(FieldMatrix const& vec, std::size_t i) T const& at(FieldMatrix const& vec, std::size_t i) { { ... ...

 ... @@ -3,6 +3,7 @@ ... @@ -3,6 +3,7 @@ #include #include #include #include #include #include #include namespace AMDiS { namespace AMDiS { ... @@ -197,7 +198,7 @@ GradientLocalFunction::operator()(Domain const& x) const ... @@ -197,7 +198,7 @@ GradientLocalFunction::operator()(Domain const& x) const { { // TODO: may DOFVectorView::Range to FieldVector type if necessary // TODO: may DOFVectorView::Range to FieldVector type if necessary using LocalDerivativeTraits using LocalDerivativeTraits = Dune::Functions::DefaultDerivativeTraits(Domain)>; = Dune::Functions::DefaultDerivativeTraits; using GradientBlock = typename LocalDerivativeTraits::Range; using GradientBlock = typename LocalDerivativeTraits::Range;