CHROMA
unprec_ovlap_contfrac5d_linop_array_w.cc
Go to the documentation of this file.
1 /* $Id: unprec_ovlap_contfrac5d_linop_array_w.cc,v 3.0 2006-04-03 04:58:52 edwards Exp $
2 * \file
3 * \brief Unpreconditioned extended-Overlap (5D) (Naryanan&Neuberger) linear operator
4 */
5 
6 #include "chromabase.h"
7 #include "linearop.h"
8 
10 
11 
12 namespace Chroma
13 {
14  //! Apply the operator onto a source std::vector
15  /*!
16  * The operator acts on the entire lattice
17  *
18  * \param psi Pseudofermion field (Read)
19  * \param isign Flag ( PLUS | MINUS ) (Read)
20  */
21  void
23  const multi1d<LatticeFermion>& psi,
24  enum PlusMinus isign) const
25  {
26  START_CODE();
27 
28  if( chi.size() != N5 ) chi.resize(N5);
29  int G5 = Ns*Ns - 1;
30 
31  // This is the upper limit for the index of the 5th dimension, i.e.
32  // it runs from 0 to TwoN. (altogether TwoN + 1 numbers. This
33  // makes sense since N5 is ALWAYS odd. )
34  int TwoN = N5 - 1;
35 
36  // This is our scaling: we evaluate
37  // ( 1 + m_q ) / ( 1 - m_q ) gamma5 + eps
38  //
39  Real mass = ( Real(1) + m_q ) / (Real(1) - m_q);
40 
41  // The sign of the diagonal terms.
42  // We flip Hsign BEFORE using it
43  // This makes the first element always have a PLUS sign
44  int Hsign=-1;
45 
46  /* N5 is ALWAYS ODD hence the explicit setting above */
47  /*
48  if( N5%2 == 0 ) {
49  Hsign = 1;
50  }
51  else {
52  Hsign = -1;
53  }
54  */
55 
56  // Run through all the pseudofermion fields:
57  // chi(0) = beta(0)*H*psi(0) + alpha(0)*psi(1)
58  // chi(n) = alpha(n-1)*psi(n-1)
59  // + (-)^n*beta(n)*H*psi(n) + alpha(n)*psi(n+1)
60  // chi(TwoN) = alpha(TwoN-1)*psi(TwoN-1)
61  // + (-)^TwoN*beta(TwoN)*H*psi(TwoN)
62 
63  LatticeFermion tmp1, tmp2;
64  Real pmscale;
65 
66  for(int n = 0; n < TwoN; ++n) {
67  (*M)(tmp1, psi[n], PLUS); // tmp1 = M psi[n]
68  tmp2 = Gamma(G5)*tmp1; // tmp2 = gamma_5 M psi
69 
70  // Scale factor and sign for the diagonal term proportional to H
71  // The scale factor should be chosen in the fermact call such
72  // that scale_fac * gamma5 * M has eigenvalues between -1 and 1
73  Hsign = -Hsign;
74  pmscale = beta[n]*Hsign*scale_fac;
75  chi[n] = pmscale*tmp2;
76 
77  if( N5 > 1 ) {
78  chi[n] += alpha[n] * psi[n+1];
79  }
80 
81  if( n > 0 ) {
82  chi[n] += alpha[n-1]*psi[n-1];
83  }
84  }
85 
86  // Last Component
87  // chi[N] = mass*gamma5*psi[N] + alpha[N-1]*psi[N-1]
88  tmp1 = Gamma(G5)*psi[TwoN];
89  chi[TwoN] = mass*tmp1;;
90  chi[TwoN] += alpha[TwoN-1]*psi[ TwoN -1 ];
91 
92  // Project out eigenvectors from Source if desired
93  //
94  // (What does this do then? Urs????)
95  LatticeFermion psi_proj;
96  psi_proj = zero;
97 
98 
99  if( NEig > 0 ) {
100  Complex cconsts;
101  for(int i = 0 ; i < NEig; i++) {
102 
103  // Project out eigenvectors in psi_{2N} */
104  cconsts = innerProduct(EigVec[i],psi[TwoN]);
105  psi_proj -= EigVec[i]*cconsts;
106 
107  // The vectors are added into chi_2N
108  chi[TwoN] += cconsts*EigValFunc[i]*EigVec[i];
109 
110  // Project out the eigenvectors from psi_{2N-1} and subtract from chi[N]
111  cconsts = innerProduct(EigVec[i],psi[TwoN-1]);
112  chi[TwoN] -= alpha[TwoN-1]*cconsts*EigVec[i];
113  }
114 
115  // Subtract out projected psi_{N} from chi_{N-1} */
116  chi[TwoN-1] += psi_proj * alpha[TwoN-1];
117  }
118 
119  // Complete the last component
120  // chi(N) = chi(N) + beta_{N}*gamma_5*M*psi_{N}
121  // The other two contributions
122  // chi[N] = mass * gamma[5]*psi[N] + alpha[N-1] * psi[N-1]
123  // have been already calculated above
124 
125  // The contribution beta_{N}*gamma_5*M*psi_{N} is
126  // caluclated only if betaa_{N} != 0 */
127 
128 
129  if( !isLastZeroP ) {
130 
131  // Complete psi_proj
132  psi_proj += psi[TwoN];
133 
134  (*M)(tmp1, psi_proj, PLUS);
135  pmscale = beta[TwoN]*scale_fac;
136  tmp2 = Gamma(G5)*tmp1;
137  chi[TwoN] += pmscale*tmp2;
138 
139  }
140 
141  getFermBC().modifyF(chi);
142 
143  END_CODE();
144  }
145 
146 
147  //! Derivative
148  void
149  UnprecOvlapContFrac5DLinOpArray::deriv(multi1d<LatticeColorMatrix>& ds_u,
150  const multi1d<LatticeFermion>& chi,
151  const multi1d<LatticeFermion>& psi,
152  enum PlusMinus isign) const
153  {
154  START_CODE();
155 
156  ds_u.resize(Nd);
157  ds_u = zero;
158 
159  multi1d<LatticeColorMatrix> ds_tmp(Nd);
160  int G5 = Ns*Ns - 1;
161 
162  // This is the upper limit for the index of the 5th dimension, i.e.
163  // it runs from 0 to TwoN. (altogether TwoN + 1 numbers. This
164  // makes sense since N5 is ALWAYS odd. )
165  int TwoN = N5 - 1;
166 
167  // The sign of the diagonal terms.
168  // We flip Hsign BEFORE using it
169  // This makes the first element always have a PLUS sign
170  int Hsign=-1;
171 
172  /* N5 is ALWAYS ODD hence the explicit setting above */
173  /*
174  if( N5%2 == 0 ) {
175  Hsign = 1;
176  }
177  else {
178  Hsign = -1;
179  }
180  */
181 
182  // Run through all the pseudofermion fields:
183  // chi(0) = beta(0)*H*psi(0) + alpha(0)*psi(1)
184  // chi(n) = alpha(n-1)*psi(n-1)
185  // + (-)^n*beta(n)*H*psi(n) + alpha(n)*psi(n+1)
186  // chi(TwoN) = alpha(TwoN-1)*psi(TwoN-1)
187  // + (-)^TwoN*beta(TwoN)*H*psi(TwoN)
188 
189  LatticeFermion tmp1, tmp2;
190  Real pmscale;
191 
192  switch (isign)
193  {
194  case PLUS:
195  for(int n = 0; n < N5; ++n)
196  {
197  if (n == N5-1 && isLastZeroP) continue;
198 
199  tmp2 = Gamma(G5)*chi[n]; // tmp2 = gamma_5 M chi
200 
201  // Scale factor and sign for the diagonal term proportional to H
202  // The scale factor should be chosen in fermact call such
203  // that scale_fac * gamma5 * M has eigenvalues between -1 and 1
204  Hsign = -Hsign;
205  pmscale = beta[n]*Hsign*scale_fac;
206  tmp1 = pmscale*tmp2;
207 
208  M->deriv(ds_tmp, tmp1, psi[n], PLUS);
209  ds_u += ds_tmp;
210  }
211  break;
212 
213  case MINUS:
214  for(int n = 0; n < N5; ++n)
215  {
216  if (n == N5-1 && isLastZeroP) continue;
217 
218  tmp2 = Gamma(G5)*psi[n]; // tmp2 = M^dag gamma_5 psi
219 
220  // Scale factor and sign for the diagonal term proportional to H
221  // The scale factor should be chosen in conszolotarev5d_w.m such
222  // that scale_fac * gamma5 * M has eigenvalues between -1 and 1
223  Hsign = -Hsign;
224  pmscale = beta[n]*Hsign*scale_fac;
225  tmp1 = pmscale*tmp2;
226 
227  M->deriv(ds_tmp, chi[n], tmp1, MINUS);
228  ds_u += ds_tmp;
229  }
230  break;
231 
232  default:
233  QDP_error_exit("unknown case");
234  }
235 
236  // Last Component
237  if( NEig > 0 )
238  {
239  QDPIO::cerr << "contfrac5d deriv - projection not supported" << std::endl;
240  QDP_abort(1);
241  }
242 
243  getFermBC().zero(ds_u);
244 
245  END_CODE();
246  }
247 
248 } // End Namespace Chroma
249 
250 
Primary include file for CHROMA library code.
void deriv(multi1d< LatticeColorMatrix > &ds_u, const multi1d< LatticeFermion > &chi, const multi1d< LatticeFermion > &psi, enum PlusMinus isign) const
Derivative.
void operator()(multi1d< LatticeFermion > &chi, const multi1d< LatticeFermion > &psi, enum PlusMinus isign) const
Apply the operator onto a source std::vector.
const FermBC< T, P, Q > & getFermBC() const
Return the fermion BC object for this linear operator.
unsigned n
Definition: ldumul_w.cc:36
Linear Operators.
Nd
Definition: meslate.cc:74
Double tmp2
Definition: mesq.cc:30
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPSubType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
QDP_error_exit("too many BiCG iterations", n_count, rsd_sq, cp, c, re_rvr, im_rvr, re_a, im_a, re_b, im_b)
int G5
Definition: pbg5p_w.cc:57
int i
Definition: pbg5p_w.cc:55
Double mass
Definition: pbg5p_w.cc:54
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
multi1d< LatticeFermion > chi(Ncb)
LatticeFermion psi
Definition: mespbg5p_w.cc:35
START_CODE()
Double zero
Definition: invbicg.cc:106
Unpreconditioned extended-Overlap (5D) (Naryanan&Neuberger) linear operator.