12#ifndef ARCCORE_ALINA_SOLVERUTILS_H
13#define ARCCORE_ALINA_SOLVERUTILS_H
26#include "arccore/alina/ValueTypeInterface.h"
33namespace Arcane::Alina
39enum class ePreconditionerSideType
48inline std::ostream& operator<<(std::ostream& os, ePreconditionerSideType p)
51 case ePreconditionerSideType::left:
53 case ePreconditionerSideType::right:
63inline std::istream& operator>>(std::istream& in, ePreconditionerSideType& p)
69 p = ePreconditionerSideType::left;
70 else if (val ==
"right")
71 p = ePreconditionerSideType::right;
73 throw std::invalid_argument(
"Invalid preconditioning side. "
74 "Valid choices are: left, right.");
83template <
class Precond,
class Matrix,
class VecF,
class VecX,
class VecT>
void
84preconditioner_spmv(ePreconditionerSideType pside,
const Precond& P,
const Matrix& A,
85 const VecF& F, VecX& X, VecT& T)
87 typedef typename backend::value_type<Matrix>::type value;
88 typedef typename math::scalar_of<value>::type scalar;
90 static const scalar one = math::identity<scalar>();
91 static const scalar zero = math::zero<scalar>();
93 if (pside == ePreconditionerSideType::left) {
94 backend::spmv(one, A, F, zero, T);
99 backend::spmv(one, A, T, zero, X);
111namespace Arcane::Alina::detail
123 template <
class Vec1,
class Vec2>
125 operator()(
const Vec1& x,
const Vec2& y)
const
127 return backend::inner_product(x, y);
138void generate_plane_rotation(T dx, T dy, T& cs, T& sn)
140 if (math::is_zero(dy)) {
144 else if (std::abs(dy) > std::abs(dx)) {
146 sn = math::inverse(sqrt(math::identity<T>() + tmp * tmp));
151 cs = math::inverse(sqrt(math::identity<T>() + tmp * tmp));
157void apply_plane_rotation(T& dx, T& dy, T cs, T sn)
159 T tmp = math::adjoint(cs) * dx + math::adjoint(sn) * dy;
160 dy = -sn * dx + cs * dy;
Default inner product getter for iterative solvers.
Default implementation for inner product.