29#ifndef GRID_MIXED_PRECISION_FLEXIBLE_GENERALISED_MINIMAL_RESIDUAL_H
30#define GRID_MIXED_PRECISION_FLEXIBLE_GENERALISED_MINIMAL_RESIDUAL_H
34template<class FieldD, class FieldF, typename std::enable_if<getPrecision<FieldD>::value == 2,
int>::type = 0,
typename std::enable_if< getPrecision<FieldF>::value == 1,
int>::type = 0>
60 std::vector<ComplexD>
y;
62 std::vector<ComplexD>
c;
63 std::vector<ComplexD>
s;
74 bool err_on_no_conv =
true)
90 psi.Checkerboard() = src.Checkerboard();
94 assert(std::isnan(guess) == 0);
100 FieldD r(src.Grid());
102 std::cout << std::setprecision(4) << std::scientific;
132 RealD true_residual = resnorm / srcnorm;
135 <<
" computed residual " <<
sqrt(cp / ssq)
136 <<
" true residual " << true_residual
139 std::cout <<
GridLogMessage <<
"MPFGMRES Time elapsed: Total " << SolverTimer.
Elapsed() << std::endl;
150 std::cout <<
GridLogMessage <<
"MPFGMRES did NOT converge" << std::endl;
160 FieldD w(src.Grid());
161 FieldD r(src.Grid());
164 std::vector<FieldD> v(
RestartLength + 1, src.Grid());
for (
auto &elem : v) elem =
Zero();
165 std::vector<FieldD> z(
RestartLength + 1, src.Grid());
for (
auto &elem : z) elem =
Zero();
176 v[0] = (1. /
gamma[0]) * r;
187 cp = norm(
gamma[i+1]);
190 <<
" residual " << cp <<
" target " << rsq << std::endl;
223 LinOp.
Op(z[iter], w);
227 for (
int i = 0; i <= iter; ++i) {
233 v[iter + 1] =
ComplexD(1. /
H(iter, iter + 1)) * w;
240 for (
int i = 0; i < iter ; ++i) {
243 H(iter, i + 1) = tmp;
247 auto nu =
sqrt(std::norm(
H(iter, iter)) + std::norm(
H(iter, iter + 1)));
248 c[iter] =
H(iter, iter) / nu;
249 s[iter] =
H(iter, iter + 1) / nu;
253 H(iter, iter + 1) = 0.;
263 for (
int i = iter; i >= 0; i--) {
265 for (
int k = i + 1; k <= iter; k++)
270 for (
int i = 0; i <= iter; i++)
271 psi = psi + z[i] *
y[i];
accelerator_inline Grid_simd< S, V > sqrt(const Grid_simd< S, V > &r)
void axpy(Lattice< vobj > &ret, sobj a, const Lattice< vobj > &x, const Lattice< vobj > &y)
Lattice< vobj > conjugate(const Lattice< vobj > &lhs)
ComplexD innerProduct(const Lattice< vobj > &left, const Lattice< vobj > &right)
RealD norm2(const Lattice< vobj > &arg)
void precisionChange(Lattice< VobjOut > &out, const Lattice< VobjIn > &in, const precisionChangeWorkspace &workspace)
GridLogger GridLogIterative(1, "Iterative", GridLogColours, "BLUE")
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
std::complex< RealD > ComplexD
GridTime Elapsed(void) const
void operator()(LinearOperatorBase< FieldD > &LinOp, const FieldD &src, FieldD &psi)
GridStopWatch MatrixTimer
void computeSolution(std::vector< FieldD > const &z, FieldD &psi, int iter)
GridStopWatch ChangePrecTimer
Integer MaxNumberOfRestarts
std::vector< ComplexD > c
void arnoldiStep(LinearOperatorBase< FieldD > &LinOp, std::vector< FieldD > &v, std::vector< FieldD > &z, FieldD &w, int iter)
std::vector< ComplexD > y
GridStopWatch CompSolutionTimer
std::vector< ComplexD > gamma
RealD outerLoopBody(LinearOperatorBase< FieldD > &LinOp, const FieldD &src, FieldD &psi, RealD rsq)
LinearFunction< FieldF > & Preconditioner
GridStopWatch LinalgTimer
MixedPrecisionFlexibleGeneralisedMinimalResidual(RealD tol, Integer maxit, GridBase *sp_grid, LinearFunction< FieldF > &Prec, Integer restart_length, bool err_on_no_conv=true)
GridBase * SinglePrecGrid
std::vector< ComplexD > s
virtual void Op(const Field &in, Field &out)=0