SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/LinearSolver - InnerProduct.hpp Hit Total Coverage
Commit: ebec864322c50bab8dca0a90baf8d01875114261 Lines: 5 7 71.4 %
Date: 2020-11-25 20:28:50
Legend: Lines: hit not hit

          Line data    Source code
       1           1 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : ///\file
       5             : /// Defines an inner product for the linear solver
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <array>
      10             : 
      11             : #include "DataStructures/Variables.hpp"
      12             : #include "Utilities/Blas.hpp"
      13             : #include "Utilities/Blaze.hpp"
      14             : #include "Utilities/ForceInline.hpp"
      15             : 
      16             : namespace LinearSolver {
      17             : 
      18             : /// \ingroup LinearSolverGroup
      19             : /// Implementations of LinearSolver::inner_product.
      20           1 : namespace InnerProductImpls {
      21             : 
      22             : /// The inner product between any types that have a `dot` product
      23             : template <typename Lhs, typename Rhs>
      24           1 : struct InnerProductImpl {
      25           0 :   static double apply(const Lhs& lhs, const Rhs& rhs) noexcept {
      26             :     return dot(lhs, rhs);
      27             :   }
      28             : };
      29             : 
      30             : /// The inner product between `Variables`
      31             : template <typename LhsTagsList, typename RhsTagsList>
      32           1 : struct InnerProductImpl<Variables<LhsTagsList>, Variables<RhsTagsList>> {
      33           0 :   static double apply(const Variables<LhsTagsList>& lhs,
      34             :                       const Variables<RhsTagsList>& rhs) noexcept {
      35             :     const auto size = lhs.size();
      36             :     ASSERT(size == rhs.size(),
      37             :            "The Variables must be of the same size to take an inner product");
      38             :     return ddot_(size, lhs.data(), 1, rhs.data(), 1);
      39             :   }
      40             : };
      41             : 
      42             : }  // namespace InnerProductImpls
      43             : 
      44             : /*!
      45             :  * \ingroup LinearSolverGroup
      46             :  * \brief The local part of the Euclidean inner product on the vector space
      47             :  * w.r.t. which the addition and scalar multiplication of both `Lhs` and `Rhs`
      48             :  * is defined.
      49             :  *
      50             :  * \details The linear solver works under the following assumptions:
      51             :  * - The data represented by \p lhs and \p rhs can each be interpreted as the
      52             :  * local chunk of a vector of the same vector space \f$V\f$. _Local_ means there
      53             :  * are vectors \f$q, p\in V\f$ such that \p lhs and \p rhs represent the
      54             :  * components of these vectors w.r.t. a subset \f$B_i\f$ of a basis
      55             :  * \f$B\subset V\f$.
      56             :  * - The `*` and `+` operators of `Lhs` and `Rhs` implement the scalar
      57             :  * multiplication and addition in the vector space _locally_, i.e. restricted to
      58             :  * \f$B_i\f$ in the above sense.
      59             :  * - The inner product is the local part \f$\langle p,q\rangle|_{B_i}\f$ of the
      60             :  * standard Euclidean dot product in the vector space so that globally it is
      61             :  * \f$\langle p,q\rangle=\sum_{i}\langle p,q\rangle|_{B_i}\f$ for
      62             :  * \f$B=\mathop{\dot{\bigcup}}_i B_i\f$.
      63             :  *
      64             :  * In practice this means that the full vectors \f$p\f$ and \f$q\f$ can be
      65             :  * distributed on many elements, where each only holds local chunks \p lhs and
      66             :  * \p rhs of the components. Scalar multiplication and addition can be performed
      67             :  * locally as expected, but computing the full inner product requires a global
      68             :  * reduction over all elements that sums their local `inner_product`s.
      69             :  */
      70             : template <typename Lhs, typename Rhs>
      71           1 : SPECTRE_ALWAYS_INLINE double inner_product(const Lhs& lhs,
      72             :                                            const Rhs& rhs) noexcept {
      73             :   return InnerProductImpls::InnerProductImpl<Lhs, Rhs>::apply(lhs, rhs);
      74             : }
      75             : 
      76             : }  // namespace LinearSolver

Generated by: LCOV version 1.14