SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/LinearSolver - BuildMatrix.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 33.3 % 3 1
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            0 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : #pragma once
       5              : 
       6              : #include <algorithm>
       7              : #include <blaze/math/Column.h>
       8              : #include <blaze/math/Matrix.h>
       9              : #include <blaze/math/typetraits/IsDenseMatrix.h>
      10              : #include <blaze/math/typetraits/IsSparseMatrix.h>
      11              : #include <cstddef>
      12              : #include <tuple>
      13              : 
      14              : #include "Utilities/EqualWithinRoundoff.hpp"
      15              : #include "Utilities/Gsl.hpp"
      16              : #include "Utilities/TypeTraits/CreateIsCallable.hpp"
      17              : 
      18            0 : namespace LinearSolver::Serial {
      19              : 
      20              : namespace detail {
      21              : CREATE_IS_CALLABLE(reset)
      22              : CREATE_IS_CALLABLE_V(reset)
      23              : }  // namespace detail
      24              : 
      25              : /*!
      26              :  * \brief Construct an explicit matrix representation by "sniffing out" the
      27              :  * linear operator, i.e. feeding it unit vectors.
      28              :  *
      29              :  * \param matrix Output buffer for the operator matrix. Must be sized correctly
      30              :  * on entry. Can be any dense or sparse Blaze matrix.
      31              :  * \param operand_buffer Memory buffer that can hold operand data for the
      32              :  * `linear_operator`. Must be sized correctly on entry, and must be filled with
      33              :  * zeros.
      34              :  * \param result_buffer Memory buffer that can hold the result of the
      35              :  * `linear_operator` applied to the operand. Must be sized correctly on entry.
      36              :  * \param linear_operator The linear operator of which the matrix representation
      37              :  * should be constructed. See `::LinearSolver::Serial::LinearSolver::solve` for
      38              :  * requirements on the linear operator.
      39              :  * \param operator_args These arguments are passed along to the
      40              :  * `linear_operator` when it is applied to an operand.
      41              :  */
      42              : template <typename LinearOperator, typename OperandType, typename ResultType,
      43              :           typename MatrixType, typename... OperatorArgs>
      44            1 : void build_matrix(const gsl::not_null<MatrixType*> matrix,
      45              :                   const gsl::not_null<OperandType*> operand_buffer,
      46              :                   const gsl::not_null<ResultType*> result_buffer,
      47              :                   const LinearOperator& linear_operator,
      48              :                   const std::tuple<OperatorArgs...>& operator_args = {}) {
      49              :   static_assert(
      50              :       blaze::IsSparseMatrix_v<MatrixType> or blaze::IsDenseMatrix_v<MatrixType>,
      51              :       "Unexpected matrix type");
      52              :   if constexpr (blaze::IsSparseMatrix_v<MatrixType>) {
      53              :     matrix->reset();
      54              :   }
      55              :   size_t i = 0;
      56              :   // Re-using the iterators for all operator invocations
      57              :   auto result_iterator_begin = result_buffer->begin();
      58              :   auto result_iterator_end = result_buffer->end();
      59              :   for (auto& unit_vector_data : *operand_buffer) {
      60              :     // Set a 1 at the unit vector location i
      61              :     unit_vector_data = 1.;
      62              :     // Invoke the operator on the unit vector
      63              :     std::apply(
      64              :         linear_operator,
      65              :         std::tuple_cat(std::forward_as_tuple(result_buffer, *operand_buffer),
      66              :                        operator_args));
      67              :     // Set the unit vector back to zero
      68              :     unit_vector_data = 0.;
      69              :     // Reset the iterator by calling its `reset` member function or by
      70              :     // re-creating it
      71              :     if constexpr (detail::is_reset_callable_v<
      72              :                       decltype(result_iterator_begin)>) {
      73              :       result_iterator_begin.reset();
      74              :     } else {
      75              :       result_iterator_begin = result_buffer->begin();
      76              :       result_iterator_end = result_buffer->end();
      77              :     }
      78              :     // Store the result in column i of the matrix
      79              :     auto col = column(*matrix, i);
      80              :     if constexpr (blaze::IsSparseMatrix_v<MatrixType>) {
      81              :       size_t k = 0;
      82              :       while (result_iterator_begin != result_iterator_end) {
      83              :         if (not equal_within_roundoff(*result_iterator_begin, 0.)) {
      84              :           col[k] = *result_iterator_begin;
      85              :         }
      86              :         ++result_iterator_begin;
      87              :         ++k;
      88              :       }
      89              :     } else {
      90              :       std::copy(result_iterator_begin, result_iterator_end, col.begin());
      91              :     }
      92              :     ++i;
      93              :   }
      94              :   ASSERT(i == matrix->columns(), "Incomplete matrix. Expected "
      95              :                                      << matrix->columns()
      96              :                                      << " columns, but only filled " << i
      97              :                                      << " columns.");
      98              : }
      99              : 
     100              : }  // namespace LinearSolver::Serial
        

Generated by: LCOV version 2.0-1