29#ifndef GRID_FLEXIBLE_COMMUNICATION_AVOIDING_GENERALISED_MINIMAL_RESIDUAL_H
30#define GRID_FLEXIBLE_COMMUNICATION_AVOIDING_GENERALISED_MINIMAL_RESIDUAL_H
58 std::vector<ComplexD>
y;
60 std::vector<ComplexD>
c;
61 std::vector<ComplexD>
s;
69 bool err_on_no_conv =
true)
84 std::cout <<
GridLogWarning <<
"This algorithm currently doesn't differ from regular FGMRES" << std::endl;
86 psi.Checkerboard() = src.Checkerboard();
90 assert(std::isnan(guess) == 0);
98 std::cout << std::setprecision(4) << std::scientific;
99 std::cout <<
GridLogIterative <<
"FlexibleCommunicationAvoidingGeneralisedMinimalResidual: guess " << guess << std::endl;
100 std::cout <<
GridLogIterative <<
"FlexibleCommunicationAvoidingGeneralisedMinimalResidual: src " << ssq << std::endl;
127 RealD true_residual = resnorm / srcnorm;
130 <<
" computed residual " <<
sqrt(cp / ssq)
131 <<
" true residual " << true_residual
134 std::cout <<
GridLogMessage <<
"FCAGMRES Time elapsed: Total " << SolverTimer.
Elapsed() << std::endl;
144 std::cout <<
GridLogMessage <<
"FlexibleCommunicationAvoidingGeneralisedMinimalResidual did NOT converge" << std::endl;
158 std::vector<Field> v(
RestartLength + 1, src.Grid());
for (
auto &elem : v) elem =
Zero();
159 std::vector<Field> z(
RestartLength + 1, src.Grid());
for (
auto &elem : z) elem =
Zero();
170 v[0] = (1. /
gamma[0]) * r;
181 cp = norm(
gamma[i+1]);
184 <<
" residual " << cp <<
" target " << rsq << std::endl;
205 LinOp.
Op(z[iter], w);
209 for (
int i = 0; i <= iter; ++i) {
215 v[iter + 1] =
ComplexD(1. /
H(iter, iter + 1)) * w;
222 for (
int i = 0; i < iter ; ++i) {
225 H(iter, i + 1) = tmp;
229 auto nu =
sqrt(std::norm(
H(iter, iter)) + std::norm(
H(iter, iter + 1)));
230 c[iter] =
H(iter, iter) / nu;
231 s[iter] =
H(iter, iter + 1) / nu;
235 H(iter, iter + 1) = 0.;
245 for (
int i = iter; i >= 0; i--) {
247 for (
int k = i + 1; k <= iter; k++)
252 for (
int i = 0; i <= iter; i++)
253 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)
GridLogger GridLogIterative(1, "Iterative", GridLogColours, "BLUE")
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
GridLogger GridLogWarning(1, "Warning", GridLogColours, "YELLOW")
std::complex< RealD > ComplexD
GridTime Elapsed(void) const
LinearFunction< Field > & Preconditioner
GridStopWatch CompSolutionTimer
GridStopWatch MatrixTimer
void computeSolution(std::vector< Field > const &z, Field &psi, int iter)
GridStopWatch LinalgTimer
std::vector< ComplexD > c
std::vector< ComplexD > s
std::vector< ComplexD > y
void operator()(LinearOperatorBase< Field > &LinOp, const Field &src, Field &psi)
FlexibleCommunicationAvoidingGeneralisedMinimalResidual(RealD tol, Integer maxit, LinearFunction< Field > &Prec, Integer restart_length, bool err_on_no_conv=true)
RealD outerLoopBody(LinearOperatorBase< Field > &LinOp, const Field &src, Field &psi, RealD rsq)
Integer MaxNumberOfRestarts
std::vector< ComplexD > gamma
void arnoldiStep(LinearOperatorBase< Field > &LinOp, std::vector< Field > &v, std::vector< Field > &z, Field &w, int iter)
virtual void Op(const Field &in, Field &out)=0