CHROMA
unprec_w12_linop_w.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Unpreconditioned W12 action
3  */
4 
5 #include "qdp_config.h"
6 #if QDP_NS == 4
7 #if QDP_ND == 4
8 #if QDP_NC == 3
9 
10 
11 #include "chromabase.h"
13 
14 namespace Chroma
15 {
16  //! Creation routine with Anisotropy
17  /*!
18  * \param u_ gauge field (Read)
19  * \param param_ parameters (Read)
20  */
21  void UnprecW12LinOp::create(Handle< FermState<T,P,Q> > fs,
22  const CloverFermActParams& param_)
23  {
24  u = fs->getLinks();
25  param = param_;
26 
27  A.create(fs, param); // Unaltered fields for clover
28 
29  if (Nd != 4)
30  {
31  QDPIO::cerr << "UnprecW12 only supports Nd=4" << std::endl;
32  QDP_abort(1);
33  }
34 
35  Real ff;
36 
38  {
41  }
42  else
43  {
44  aniso_fact = 1.0;
45  j_decay = Nd;
46  }
47 
48  fact1 = 1 + (Nd-1)*aniso_fact + param.Mass;
49  fact2 = -2 /(3*param.u0);
50  fact4 = 1 / (12*param.u0*param.u0);
51  fact3 = 2 * fact4;
52 
53  if (j_decay != Nd-1)
54  {
55  QDPIO::cerr << "W12: implementation restriction: j_decay must be Nd-1" << std::endl;
56  QDP_abort(1);
57  }
58 
59  // Anisotropy not yet folded into gauge fields
60  }
61 
62 
63  //! GAMW
64  /*!
65  * Description:
66  *
67  * This routine applies the operator W' to Psi, putting the result in Chi.
68  *
69  * chi(x,mu) := + (1 - isign gamma ) U (x) psi(x+mu)
70  * mu mu
71  * +
72  * + (1 + isign gamma ) U (x-mu) psi(x-mu)
73  * mu mu
74  */
75  void UnprecW12LinOp::gamW(multi1d<LatticeFermion>& chi,
76  const LatticeFermion& psi,
77  int j_decay,
78  enum PlusMinus isign) const
79  {
80  START_CODE();
81 
82  chi.resize(Nd);
83 
84  /* F
85  * a2 (x) := U (x) (1 - isign gamma ) psi(x)
86  * mu mu mu
87  */
88  /* B +
89  * a2 (x) := U (x-mu) (1 + isign gamma ) psi(x-mu)
90  * mu mu mu
91  */
92  // Recontruct the bottom two spinor components from the top two
93  /* F B
94  * chi(x) := sum_mu a2 (x) + a2 (x)
95  * mu mu
96  */
97  switch (isign)
98  {
99  case PLUS:
100  chi[0] = spinReconstructDir0Minus(u[0] * shift(spinProjectDir0Minus(psi), FORWARD, 0))
101  + spinReconstructDir0Plus(shift(adj(u[0]) * spinProjectDir0Plus(psi), BACKWARD, 0));
102  chi[1] = spinReconstructDir1Minus(u[1] * shift(spinProjectDir1Minus(psi), FORWARD, 1))
103  + spinReconstructDir1Plus(shift(adj(u[1]) * spinProjectDir1Plus(psi), BACKWARD, 1));
104  chi[2] = spinReconstructDir2Minus(u[2] * shift(spinProjectDir2Minus(psi), FORWARD, 2))
105  + spinReconstructDir2Plus(shift(adj(u[2]) * spinProjectDir2Plus(psi), BACKWARD, 2));
106  chi[3] = spinReconstructDir3Minus(u[3] * shift(spinProjectDir3Minus(psi), FORWARD, 3))
107  + spinReconstructDir3Plus(shift(adj(u[3]) * spinProjectDir3Plus(psi), BACKWARD, 3));
108  break;
109 
110  case MINUS:
111  chi[0] = spinReconstructDir0Plus(u[0] * shift(spinProjectDir0Plus(psi), FORWARD, 0))
112  + spinReconstructDir0Minus(shift(adj(u[0]) * spinProjectDir0Minus(psi), BACKWARD, 0));
113  chi[1] = spinReconstructDir1Plus(u[1] * shift(spinProjectDir1Plus(psi), FORWARD, 1))
114  + spinReconstructDir1Minus(shift(adj(u[1]) * spinProjectDir1Minus(psi), BACKWARD, 1));
115  chi[2] = spinReconstructDir2Plus(u[2] * shift(spinProjectDir2Plus(psi), FORWARD, 2))
116  + spinReconstructDir2Minus(shift(adj(u[2]) * spinProjectDir2Minus(psi), BACKWARD, 2));
117  chi[3] = spinReconstructDir3Plus(u[3] * shift(spinProjectDir3Plus(psi), FORWARD, 3))
118  + spinReconstructDir3Minus(shift(adj(u[3]) * spinProjectDir3Minus(psi), BACKWARD, 3));
119  break;
120  }
121 
122  END_CODE();
123  }
124 
125 
126  //! GAMWMU
127  /*! This routine applies the operator W' to Psi, putting the result in Chi.
128  *
129  * chi(x,mu) := + (1 - isign gamma ) U (x) psi (x+mu)
130  * mu mu mu
131  * +
132  * + (1 + isign gamma ) U (x-mu) psi (x-mu)
133  * mu mu mu
134  */
135  void UnprecW12LinOp::gamWmu(multi1d<LatticeFermion>& chi,
136  const multi1d<LatticeFermion>& psi,
137  int j_decay,
138  enum PlusMinus isign) const
139  {
140  START_CODE();
141 
142  chi.resize(Nd);
143 
144  /* F
145  * a2 (x) := U (x) (1 - isign gamma ) psi(x)
146  * mu mu mu
147  */
148  /* B +
149  * a2 (x) := U (x-mu) (1 + isign gamma ) psi(x-mu)
150  * mu mu mu
151  */
152  // Recontruct the bottom two spinor components from the top two
153  /* F B
154  * chi(x) := sum_mu a2 (x) + a2 (x)
155  * mu mu
156  */
157  switch (isign)
158  {
159  case PLUS:
160  chi[0] = spinReconstructDir0Minus(u[0] * shift(spinProjectDir0Minus(psi[0]), FORWARD, 0))
161  + spinReconstructDir0Plus(shift(adj(u[0]) * spinProjectDir0Plus(psi[0]), BACKWARD, 0));
162  chi[1] = spinReconstructDir1Minus(u[1] * shift(spinProjectDir1Minus(psi[1]), FORWARD, 1))
163  + spinReconstructDir1Plus(shift(adj(u[1]) * spinProjectDir1Plus(psi[1]), BACKWARD, 1));
164  chi[2] = spinReconstructDir2Minus(u[2] * shift(spinProjectDir2Minus(psi[2]), FORWARD, 2))
165  + spinReconstructDir2Plus(shift(adj(u[2]) * spinProjectDir2Plus(psi[2]), BACKWARD, 2));
166  chi[3] = spinReconstructDir3Minus(u[3] * shift(spinProjectDir3Minus(psi[3]), FORWARD, 3))
167  + spinReconstructDir3Plus(shift(adj(u[3]) * spinProjectDir3Plus(psi[3]), BACKWARD, 3));
168  break;
169 
170  case MINUS:
171  chi[0] = spinReconstructDir0Plus(u[0] * shift(spinProjectDir0Plus(psi[0]), FORWARD, 0))
172  + spinReconstructDir0Minus(shift(adj(u[0]) * spinProjectDir0Minus(psi[0]), BACKWARD, 0));
173  chi[1] = spinReconstructDir1Plus(u[1] * shift(spinProjectDir1Plus(psi[1]), FORWARD, 1))
174  + spinReconstructDir1Minus(shift(adj(u[1]) * spinProjectDir1Minus(psi[1]), BACKWARD, 1));
175  chi[2] = spinReconstructDir2Plus(u[2] * shift(spinProjectDir2Plus(psi[2]), FORWARD, 2))
176  + spinReconstructDir2Minus(shift(adj(u[2]) * spinProjectDir2Minus(psi[2]), BACKWARD, 2));
177  chi[3] = spinReconstructDir3Plus(u[3] * shift(spinProjectDir3Plus(psi[3]), FORWARD, 3))
178  + spinReconstructDir3Minus(shift(adj(u[3]) * spinProjectDir3Minus(psi[3]), BACKWARD, 3));
179  break;
180  }
181 
182  END_CODE();
183  }
184 
185 
186  // Override inherited one with a few more funkies
187  /*!
188  * Chi = (m0 - (2/3*((1/2)*(1/4))*sigma.F + W' + (1/6)*W^2_mu) * Psi
189  *
190  * For sake of generality, efficiency, and future tinkering, this routine
191  * actually does
192  *
193  * Chi = (clov + Kappa_ds*W' + Kappa_w2*W^2_mu) * Psi
194  *
195  * where
196  *
197  * clov = 1 + const*sigma.F
198  *
199  * and const is some constant depending on kappa described in conslinop
200  */
201  void UnprecW12LinOp::operator()(LatticeFermion & chi,
202  const LatticeFermion& psi,
203  enum PlusMinus isign) const
204  {
205  START_CODE();
206 
207  multi1d<LatticeFermion> tmp1(Nd);
208  multi1d<LatticeFermion> tmp2(Nd);
209 
210  // Apply clover term
211  A(chi, psi, isign);
212 
213  // Add the diagonal term from W^2
214  chi += fact1 * psi;
215 
216  /* Tmp1_mu = D'_mu * Psi */
217  /* Chi -= sum_mu Kappa_ds * Tmp1_mu */
218  gamW(tmp1, psi, Nd, isign);
219  for(int mu = 0; mu < Nd; ++mu)
220  {
221  if (mu != j_decay)
222  chi -= Real(aniso_fact * fact2) * tmp1[mu];
223  else
224  chi -= fact2 * tmp1[mu];
225  }
226 
227  /* Tmp2_mu = D'_mu * Tmp1_mu */
228  /* Chi += sum_mu Kappa_w2 * Tmp1_mu */
229  gamWmu(tmp2, tmp1, j_decay, isign);
230  for(int mu = 0; mu < Nd; ++mu)
231  if (mu != j_decay)
232  chi += fact4 * tmp2[mu];
233 
234  END_CODE();
235  }
236 
237 
238  //! Return flops performed by the operator()
239  unsigned long UnprecW12LinOp::nFlops() const
240  {
241  unsigned long site_flops = 0;
242  return site_flops*(Layout::sitesOnNode());
243  }
244 
245 
246  //! Derivative of unpreconditioned W12 dM/dU
247  /*!
248  * \param chi left std::vector on cb (Read)
249  * \param psi right std::vector on 1-cb (Read)
250  * \param isign D'^dag or D' ( MINUS | PLUS ) resp. (Read)
251  * \param cb Checkerboard of chi std::vector (Read)
252  *
253  * \return Computes \f$\chi^\dag * \dot(D} * \psi\f$
254  */
255  void
256  UnprecW12LinOp::deriv(multi1d<LatticeColorMatrix>& ds_u,
257  const LatticeFermion& chi, const LatticeFermion& psi,
258  enum PlusMinus isign) const
259  {
260  QDP_error_exit("W12 deriv not correct yet");
261 
262 
263  START_CODE();
264 
265  // This does both parities
266  A.deriv(ds_u, chi, psi, isign);
267 
268  // Factor in front of the dslash
269  for(int mu = 0; mu < Nd; ++mu)
270  ds_u[mu] *= fact2;
271 
272  // NOTE: missing derivative of 2 link piece
273 
274  END_CODE();
275  }
276 
277 } // End Namespace Chroma
278 
279 
280 #endif
281 #endif
282 #endif
Primary include file for CHROMA library code.
void deriv(multi1d< U > &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Take deriv of D.
void create(Handle< FermState< T, multi1d< U >, multi1d< U > > > fs, const CloverFermActParams &param_)
Creation routine.
unsigned long nFlops() const
Return flops performed by the operator()
multi1d< LatticeColorMatrix > u
CloverFermActParams param
void gamW(multi1d< LatticeFermion > &chi, const LatticeFermion &psi, int j_decay, enum PlusMinus isign) const
GAMWM.
void deriv(multi1d< LatticeColorMatrix > &ds_u, const LatticeFermion &chi, const LatticeFermion &psi, enum PlusMinus isign) const
Derivative of unpreconditioned W12 dM/dU.
void create(Handle< FermState< T, P, Q > > fs, const CloverFermActParams &param_)
Creation routine.
void operator()(LatticeFermion &chi, const LatticeFermion &psi, enum PlusMinus isign) const
Apply the operator onto a source std::vector.
void gamWmu(multi1d< LatticeFermion > &chi, const multi1d< LatticeFermion > &psi, int j_decay, enum PlusMinus isign) const
GAMWMUM.
int mu
Definition: cool.cc:24
int j_decay
Definition: meslate.cc:22
Nd
Definition: meslate.cc:74
Double tmp2
Definition: mesq.cc:30
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)
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
multi1d< LatticeFermion > chi(Ncb)
LatticeFermion psi
Definition: mespbg5p_w.cc:35
START_CODE()
#define FORWARD
Definition: primitives.h:82
#define BACKWARD
Definition: primitives.h:83
Unpreconditioned W12 action.