CHROMA
eoprec_wilson_linop_w.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Even-odd preconditioned Wilson linear operator
3  */
4 
6 
7 using namespace QDP::Hints;
8 namespace Chroma
9 {
10  //! Creation routine
11  /*!
12  * \param fs gauge state (Read)
13  * \param Mass_ fermion kappa (Read)
14  */
15  void EvenOddPrecWilsonLinOp::create(Handle< FermState<T,P,Q> > fs,
16  const Real& Mass_)
17  {
18  multi1d<Real> cf(Nd);
19  cf = 1.0;
20  create(fs, Mass_, cf);
21  }
22 
23 
24  //! Creation routine with Anisotropy
25  /*!
26  * \param fs gauge state (Read)
27  * \param Mass_ fermion kappa (Read)
28  * \param aniso anisotropy struct (Read)
29  */
30  void EvenOddPrecWilsonLinOp::create(Handle< FermState<T,P,Q> > fs,
31  const Real& Mass_,
32  const AnisoParam_t& anisoParam)
33  {
34  START_CODE();
35 
36  create(fs, Mass_, makeFermCoeffs(anisoParam));
37 
38  END_CODE();
39  }
40 
41 
42  //! Creation routine with general coefficients
43  /*!
44  * \param fs gauge state (Read)
45  * \param Mass_ fermion kappa (Read)
46  * \param coeffs_ fermion coeffs (Read)
47  */
48  void EvenOddPrecWilsonLinOp::create(Handle< FermState<T,P,Q> > fs,
49  const Real& Mass_,
50  const multi1d<Real>& coeffs_)
51  {
52  START_CODE();
53 
54  Mass = Mass_;
55  coeffs = coeffs_;
56 
57  if (coeffs.size() != Nd)
58  {
59  QDPIO::cerr << "EvenOddPrecWilsonLinOp::create : coeffs not size Nd" << std::endl;
60  QDP_abort(1);
61  }
62 
63  D.create(fs,coeffs);
64 
65  // Fold in the diagonal parts of the laplacian. Here, we insist that
66  // the laplacian has the same scaling as the first deriv. term.
67  fact = Mass;
68  for(int mu=0; mu < Nd; ++mu)
69  fact += coeffs[mu];
70 
71  invfact = 1/fact;
72 
73  END_CODE();
74  }
75 
76 
77  //! Apply even-odd linop component
78  /*!
79  * The operator acts on the entire even sublattice
80  *
81  * \param chi Pseudofermion field (Write)
82  * \param psi Pseudofermion field (Read)
83  * \param isign Flag ( PLUS | MINUS ) (Read)
84  */
85  void
86  EvenOddPrecWilsonLinOp::evenOddLinOp(LatticeFermion& chi,
87  const LatticeFermion& psi,
88  enum PlusMinus isign) const
89  {
90  START_CODE();
91 
92  Real mhalf = -0.5;
93 
94  D.apply(chi, psi, isign, 0);
95  chi[rb[0]] *= mhalf;
96 
97  END_CODE();
98  }
99 
100  //! Apply odd-even linop component
101  /*!
102  * The operator acts on the entire odd sublattice
103  *
104  * \param chi Pseudofermion field (Write)
105  * \param psi Pseudofermion field (Read)
106  * \param isign Flag ( PLUS | MINUS ) (Read)
107  */
108  void
109  EvenOddPrecWilsonLinOp::oddEvenLinOp(LatticeFermion& chi,
110  const LatticeFermion& psi,
111  enum PlusMinus isign) const
112  {
113  START_CODE();
114 
115  Real mhalf = -0.5;
116 
117  D.apply(chi, psi, isign, 1);
118  chi[rb[1]] *= mhalf;
119 
120  END_CODE();
121  }
122 
123 
124 
125  //! Override inherited one with a few more funkies
126  void EvenOddPrecWilsonLinOp::operator()(LatticeFermion & chi,
127  const LatticeFermion& psi,
128  enum PlusMinus isign) const
129  {
130  START_CODE();
131 
132  LatticeFermion tmp1, tmp2, tmp3; // if an array is used here,
133 
134  moveToFastMemoryHint(tmp1);
135  moveToFastMemoryHint(tmp2);
136  moveToFastMemoryHint(tmp3);
137 
138 
139  Real mquarterinvfact = -0.25*invfact;
140 
141  // tmp1[0] = D_eo psi[1]
142  D.apply(tmp1, psi, isign, 0);
143 
144  // tmp2[1] = D_oe tmp1[0]
145  D.apply(tmp2, tmp1, isign, 1);
146 
147  // Now we have tmp2[1] = D_oe D_eo psi[1]
148 
149  // now scale tmp2[1] with (-1/4)/fact = (-1/4)*(1/(Nd + m))
150  // with a vscale -- using tmp2 on both sides should be OK, but
151  // just to be safe use tmp3
152  tmp3[rb[1]] = mquarterinvfact*tmp2;
153 
154  // now tmp3[1] should be = (-1/4)*(1/(Nd + m) D_oe D_eo psi[1]
155 
156  // Now get chi[1] = fact*psi[1] + tmp3[1]
157  // with a vaxpy3
158  // chi[1] = (Nd + m) - (1/4)*(1/(Nd + m)) D_oe D_eo psi[1]
159  //
160  // in this order, this last job could be replaced with a
161  // vaxpy3_norm if we wanted the || M psi ||^2 over the subset.
162  chi[rb[1]] = fact*psi + tmp3;
163 
164  getFermBC().modifyF(chi, rb[1]);
165 
166  END_CODE();
167  }
168 
169 
170  //! Derivative of even-odd linop component
171  void
172  EvenOddPrecWilsonLinOp::derivEvenOddLinOp(multi1d<LatticeColorMatrix>& ds_u,
173  const LatticeFermion& chi,
174  const LatticeFermion& psi,
175  enum PlusMinus isign) const
176  {
177  START_CODE();
178 
179  ds_u.resize(Nd);
180 
181  D.deriv(ds_u, chi, psi, isign, 0);
182  for(int mu=0; mu < Nd; mu++) {
183  ds_u[mu] *= Real(-0.5);
184  }
185 
186  END_CODE();
187  }
188 
189 
190  //! Derivative of odd-even linop component
191  void
192  EvenOddPrecWilsonLinOp::derivOddEvenLinOp(multi1d<LatticeColorMatrix>& ds_u,
193  const LatticeFermion& chi,
194  const LatticeFermion& psi,
195  enum PlusMinus isign) const
196  {
197  START_CODE();
198 
199  ds_u.resize(Nd);
200 
201  D.deriv(ds_u, chi, psi, isign, 1);
202  for(int mu=0; mu < Nd; mu++) {
203  ds_u[mu] *= Real(-0.5);
204  }
205  END_CODE();
206  }
207 
208 #if 0
209  //! Derivative of even-odd linop component
210  void
211  EvenOddPrecWilsonLinOp::derivEvenOddLinOpMP(multi1d<LatticeColorMatrix>& ds_u,
212  const LatticeFermion& chi,
213  const LatticeFermion& psi,
214  enum PlusMinus isign) const
215  {
216  START_CODE();
217 
218  ds_u.resize(Nd);
219 
220  D.deriv(ds_u, chi, psi, isign, 0);
221  for(int mu=0; mu < Nd; mu++) {
222  ds_u[mu] *= Real(-0.5);
223  }
224 
225  END_CODE();
226  }
227 
228 
229  //! Derivative of odd-even linop component
230  void
231  EvenOddPrecWilsonLinOp::derivOddEvenLinOpMP(multi1d<LatticeColorMatrix>& ds_u,
232  const LatticeFermion& chi,
233  const LatticeFermion& psi,
234  enum PlusMinus isign) const
235  {
236  START_CODE();
237 
238  ds_u.resize(Nd);
239 
240  D.deriv(ds_u, chi, psi, isign, 1);
241  for(int mu=0; mu < Nd; mu++) {
242  ds_u[mu] *= Real(-0.5);
243  }
244  END_CODE();
245  }
246 #endif
247 
248  //! Return flops performed by the operator()
249  unsigned long EvenOddPrecWilsonLinOp::nFlops() const
250  {
251  unsigned long cbsite_flops = 2*D.nFlops()+6*Nc*Ns;
252  return cbsite_flops*(Layout::sitesOnNode()/2);
253  }
254 
255 } // End Namespace Chroma
#define END_CODE()
Definition: chromabase.h:65
#define START_CODE()
Definition: chromabase.h:64
Support class for fermion actions and linear operators.
Definition: state.h:94
Class for counted reference semantics.
Definition: handle.h:33
int mu
Definition: cool.cc:24
Even-odd preconditioned Wilson fermion linear operator.
Real Mass
Nd
Definition: meslate.cc:74
Double tmp2
Definition: mesq.cc:30
Double tmp3
Definition: mesq.cc:31
multi1d< Hadron2PtContraction_t > operator()(const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
multi1d< Real > makeFermCoeffs(const AnisoParam_t &aniso)
Make fermion coefficients.
Definition: aniso_io.cc:63
chi
Definition: pade_trln_w.cc:24
psi
Definition: pade_trln_w.cc:191
Parameters for anisotropy.
Definition: aniso_io.h:24