32 const multi1d<Complex>& zeta,
33 const multi1d<Real>& rho,
41 int numroot =
x.size();
42 if( zeta.size() != numroot ) {
43 QDPIO::cerr <<
"zeta size:"<< zeta.size()
44 <<
" is different from x.size:"<<numroot << std::endl;
49 if( rho.size() != numroot) {
50 QDPIO::cerr <<
"rho size:"<< rho.size()
51 <<
" is different from x.size:"<<numroot << std::endl;
55 if(
epsilon.size() != numroot) {
56 QDPIO::cerr <<
"epsilon size:"<<
epsilon.size()
57 <<
" is different from x.size:"<<numroot << std::endl;
63 Real epsilon_sigma =
epsilon[0];
64 for(
int shift = 0; shift < numroot; shift++) {
65 if ( toBool(
epsilon[shift] < epsilon_sigma ) ) {
78 for(
int shift = 0; shift < numroot; shift++) {
86 Real delta = sqrt(norm2(
r));
88 multi1d<Complex> phihat(numroot);
89 multi1d<Complex> tauhat(numroot);
93 for(
int shift = 0; shift < numroot; shift++) {
95 phihat[shift] = Real(1)/delta;
98 tauhat[shift] = delta/rho[shift];
102 LatticeFermion v_old =
zero;
106 multi1d<LatticeFermion> w_old(numroot);
107 multi1d<LatticeFermion>
p(numroot);
113 for(
int shift = 0; shift < numroot; shift++) {
121 Complex gamma = Real(1);
122 Real sigma = Real(1);
125 multi1d<Complex>
phi(numroot);
126 multi1d<Real>
s(numroot);
127 multi1d<Complex> lambda(numroot);
128 multi1d<Complex>
r0(numroot);
129 multi1d<Complex> r1_old(numroot);
130 multi1d<Complex>
c(numroot);
134 for(
int shift = 0; shift < numroot; shift++) {
135 phi[shift] = Real(0);
137 lambda[shift] = Real(0);
139 r1_old[shift] = Real(1);
149 LatticeFermion vtilde;
151 Real ftmp = Real(1)/delta;
158 multi1d<bool> convP(numroot);
160 bool allConvP =
false;
163 for(
int iter = 1; iter <= MaxSUMR && !allConvP; iter++) {
175 while( convP[unc] ==
true && unc < numroot) { unc++; }
178 if( unc < numroot ) {
179 Real mod_me = sqrt(real(conj(zeta[unc])*zeta[unc]));
182 for(
int shift=unc+1; shift < numroot; shift++) {
185 if( convP[shift] ==
false ) {
186 Real mod_trial = sqrt(real(conj(zeta[shift])*zeta[shift]));
188 if ( toBool(mod_trial < mod_me) ) {
199 QDPIO::cerr <<
"All systems appear to be converged. I shouldnt be here" << std::endl;
206 Real inner_tol = epsilon_sigma / sqrt(real(conj(tauhat[unc])*tauhat[unc]));
220 sigma = sqrt( Real(1) - real( conj(gamma)*gamma ) );
224 alpha = -gamma*delta;
226 multi1d<Complex> r1hat(numroot);
231 Real abs_sigma_sq = sigma*sigma;
233 multi1d<Complex> r1(numroot);
236 for(
int shift = 0; shift < numroot; shift++) {
239 if( !convP[shift] ) {
242 r0[shift] =
alpha *
phi[shift] +
s[shift]*zeta[shift]/rho[shift];
245 r1hat =
alpha * phihat[shift]+conj(
c[shift])*zeta[shift]/rho[shift];
253 abs_rhat_sq = real(conj(r1hat[shift])*r1hat[shift]);
254 tmp_length = sqrt(abs_rhat_sq + abs_sigma_sq);
256 c[shift] = conj(r1hat[shift])/tmp_length;
257 s[shift] = - sigma / tmp_length;
260 r1[shift] = -
c[shift]*r1hat[shift] + cmplx(
s[shift]*sigma,0);
263 Complex tau = -
c[shift]*tauhat[shift];
266 tauhat[shift] =
s[shift] * tauhat[shift];
269 Complex
eta = tau / r1[shift];
272 Complex
kappa =
r0[shift]/r1_old[shift];
275 r1_old[shift]=r1[shift];
281 LatticeFermion w_minus_v;
282 w_minus_v = w_old[shift] - v_old;
284 LatticeFermion w =
alpha*
p[shift] -
kappa*w_minus_v;
285 p[shift] =
p[shift] - lambda[shift]*w_minus_v;
292 x[shift] =
x[shift] -
eta*w_minus_v;
306 if( toBool( sqrt(real(conj(sigma)*sigma)) > epsilon_sigma ) ) {
314 for(
int shift=0; shift < numroot; shift++) {
317 if( !convP[shift] ) {
320 phi[shift] = -
c[shift]*phihat[shift]
321 +
s[shift]*conj(gamma)/delta;
324 lambda[shift] =
phi[shift]/r1[shift];
327 phihat[shift] =
s[shift]* phihat[shift]
328 + conj(
c[shift]) * conj(gamma)/delta;
337 v =
u + gamma*vtilde;
338 Real
ftmp2 = Real(1)/sigma;
342 Complex gconj = conj(gamma);
343 Complex csigma=cmplx(sigma,0);
344 vtilde = csigma*vtilde + gconj*v;
348 Real ftmp3 = Real(1)/sqrt(norm2(vtilde));
360 for(
int shift=0; shift < numroot; shift++) {
363 if( ! convP[shift] ) {
366 Real taumod = sqrt(real(conj(tauhat[shift])*tauhat[shift]));
368 QDPIO::cout <<
"Iter " << iter <<
": Shift: " << shift
369 <<
" | tauhat |=" << taumod << std::endl;
372 if ( toBool(taumod <
epsilon[shift] ) ) convP[shift] =
true;
375 allConvP &= convP[shift];
392 if(
n_count == MaxSUMR && ! allConvP ) {
393 QDPIO::cout <<
"Solver Nonconvergence Warning " << std::endl;
402 const LatticeFermion&
b,
403 multi1d<LatticeFermion>&
x,
404 const multi1d<Complex>& zeta,
405 const multi1d<Real>& rho,
Primary include file for CHROMA library code.
Conjugate-Gradient algorithm for a generic Linear Operator.
int epsilon(int i, int j, int k)
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPSubType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
static const LatticeInteger & alpha(const int dim)
Asqtad Staggered-Dirac operator.
static multi1d< LatticeColorMatrix > u
void MInvRelSUMR_a(const LinearOperator< T > &U, const T &b, multi1d< T > &x, const multi1d< Complex > &zeta, const multi1d< Real > &rho, const multi1d< Real > &epsilon, int MaxSUMR, int &n_count)
LinOpSysSolverMGProtoClover::T T
void MInvRelSUMR(const LinearOperator< LatticeFermion > &U, const LatticeFermion &b, multi1d< LatticeFermion > &x, const multi1d< Complex > &zeta, const multi1d< Real > &rho, const multi1d< Real > &epsilon, int MaxSUMR, int &n_count)
multi1d< LatticeFermion > s(Ncb)
multi1d< LatticeColorMatrix > U