QUDA  0.9.0
dirac_twisted_mass.cpp
Go to the documentation of this file.
1 #include <dirac_quda.h>
2 #include <blas_quda.h>
3 #include <iostream>
4 #include <multigrid.h>
5 
6 namespace quda {
7 
9  : DiracWilson(param, nDim), mu(param.mu), epsilon(param.epsilon) { }
10 
12  : DiracWilson(dirac), mu(dirac.mu), epsilon(dirac.epsilon) { }
13 
15 
17  {
18  if (&dirac != this) {
20  }
21  return *this;
22  }
23 
24  // Protected method for applying twist
26  const QudaTwistGamma5Type twistType) const
27  {
29  ApplyTwistGamma(out, in, 4, kappa, mu, epsilon, dagger, twistType);
30  flops += 24ll*in.Volume();
31  }
32 
33 
34  // Public method to apply the twist
36  {
38  }
39 
41  QudaParity parity, QudaTwistDslashType twistDslashType,
42  double a, double b, double c, double d) const {
43  twistedMassDslashCuda(&static_cast<cudaColorSpinorField&>(out), *gauge,
44  &static_cast<const cudaColorSpinorField&>(in), parity, dagger,
45  0, twistDslashType, a, b, c, d, commDim, profile);
46  flops += 1392ll*in.Volume();
47  }
48 
51  QudaTwistDslashType twistDslashType,
52  double a, double b, double c, double d) const {
53  twistedMassDslashCuda(&static_cast<cudaColorSpinorField&>(out), *gauge,
54  &static_cast<const cudaColorSpinorField&>(in), parity, dagger,
55  &static_cast<const cudaColorSpinorField&>(x),
56  twistDslashType, a, b, c, d, commDim, profile);
57  flops += 1416ll*in.Volume();
58  }
59 
61  QudaParity parity, QudaTwistDslashType twistDslashType,
62  double a, double b, double c, double d) const {
63  ndegTwistedMassDslashCuda(&static_cast<cudaColorSpinorField&>(out), *gauge,
64  &static_cast<const cudaColorSpinorField&>(in), parity, dagger,
65  0, twistDslashType, a, b, c, d, commDim, profile);
66  flops += (1320ll+120ll)*in.Volume();//per flavor 1320+16*6(rotation per flavor)+24 (scaling per flavor)
67  }
68 
71  QudaTwistDslashType twistDslashType,
72  double a, double b, double c, double d) const {
73  ndegTwistedMassDslashCuda(&static_cast<cudaColorSpinorField&>(out), *gauge,
74  &static_cast<const cudaColorSpinorField&>(in), parity, dagger,
75  &static_cast<const cudaColorSpinorField&>(x),
76  twistDslashType, a, b, c, d, commDim, profile);
77 
78  flops += (1464ll)*in.Volume();
79  }
80 
82  {
84  if (in.TwistFlavor() != out.TwistFlavor())
85  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
86 
87  if (in.TwistFlavor() == QUDA_TWIST_NO || in.TwistFlavor() == QUDA_TWIST_INVALID) {
88  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
89  }
90 
91  // We can eliminate this temporary at the expense of more kernels (like clover)
92  ColorSpinorField *tmp=0; // this hack allows for tmp2 to be full or parity field
93  if (tmp2) {
94  if (tmp2->SiteSubset() == QUDA_FULL_SITE_SUBSET) tmp = &(tmp2->Even());
95  else tmp = tmp2;
96  }
97  bool reset = newTmp(&tmp, in.Even());
98 
99  if(in.TwistFlavor() == QUDA_TWIST_SINGLET) {
100  double a = 2.0 * kappa * mu;//for direct twist (must be daggered separately)
101 
102  TwistedDslashXpay(out.Odd(), in.Even(), in.Odd(), QUDA_ODD_PARITY,
103  QUDA_DEG_DSLASH_TWIST_XPAY, a, -kappa, 0.0, 0.0);
104 
105  TwistedDslashXpay(out.Even(), in.Odd(), in.Even(), QUDA_EVEN_PARITY,
106  QUDA_DEG_DSLASH_TWIST_XPAY, a, -kappa, 0.0, 0.0);
107  } else {
108  double a = -2.0 * kappa * mu; //for twist
109  double b = -2.0 * kappa * epsilon;//for twist
110  NdegTwistedDslashXpay(out.Odd(), in.Even(), in.Odd(), QUDA_ODD_PARITY,
111  QUDA_NONDEG_DSLASH, a, b, 1.0, -kappa);
112 
113  NdegTwistedDslashXpay(out.Even(), in.Odd(), in.Even(), QUDA_EVEN_PARITY,
114  QUDA_NONDEG_DSLASH, a, b, 1.0, -kappa);
115  }
116  deleteTmp(&tmp, reset);
117  }
118 
120  {
122  bool reset = newTmp(&tmp1, in);
123 
124  M(*tmp1, in);
125  Mdag(out, *tmp1);
126 
127  deleteTmp(&tmp1, reset);
128  }
129 
132  const QudaSolutionType solType) const
133  {
134  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
135  errorQuda("Preconditioned solution requires a preconditioned solve_type");
136  }
137 
138  src = &b;
139  sol = &x;
140  }
141 
143  const QudaSolutionType solType) const
144  {
145  // do nothing
146  }
147 
148  void DiracTwistedMass::createCoarseOp(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat, const Transfer &T, double kappa, double mu, double mu_factor) const {
149  double a = 2.0 * kappa * mu;
150  cudaCloverField *c = NULL;
152  }
153 
155 
157 
159  {
160 
161  }
162 
164  {
165  if (&dirac != this) {
167  }
168  return *this;
169  }
170 
171  // Public method to apply the inverse twist
173  {
175  }
176 
177  // apply hopping term, then inverse twist: (A_ee^-1 D_eo) or (A_oo^-1 D_oe),
178  // and likewise for dagger: (D^dagger_eo A_ee^-1) or (D^dagger_oe A_oo^-1)
180  {
183 
184  if (in.TwistFlavor() != out.TwistFlavor())
185  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
186  if (in.TwistFlavor() == QUDA_TWIST_NO || in.TwistFlavor() == QUDA_TWIST_INVALID)
187  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
188 
189  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
190  double a = -2.0 * kappa * mu; //for invert twist (not daggered)
191  double b = 1.0 / (1.0 + a*a); //for invert twist
194  } else {
196  }
197  } else {//TWIST doublet :
198  double a = 2.0 * kappa * mu;
199  double b = 2.0 * kappa * epsilon;
200  double c = 1.0 / (1.0 + a*a - b*b);
201 
204  } else {
205  ColorSpinorField *doubletTmp=0;
206  bool reset = newTmp(&doubletTmp, in);
207 
208  // FIXME why -ve sign in mu needed ?
210 
211  // this is just a vectorized Wilson dslash
212  NdegTwistedDslash(out, *doubletTmp, parity, QUDA_NONDEG_DSLASH, 0.0, 0.0, 1.0, 0.0);
213 
214  deleteTmp(&doubletTmp, reset);
215  }
216  }
217  }
218 
219  // xpay version of the above
221  const ColorSpinorField &x, const double &k) const
222  {
225  if (in.TwistFlavor() != out.TwistFlavor())
226  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
227  if (in.TwistFlavor() == QUDA_TWIST_NO || in.TwistFlavor() == QUDA_TWIST_INVALID)
228  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
229 
230  if(in.TwistFlavor() == QUDA_TWIST_SINGLET) {
231  double a = -2.0 * kappa * mu; //for invert twist
232  double b = k / (1.0 + a*a); //for invert twist
233  if (!dagger) {
235  } else { // tmp1 can alias in, but tmp2 can alias x so must not use this
237  }
238  } else {//TWIST_DOUBLET:
239  double a = 2.0 * kappa * mu;
240  double b = 2.0 * kappa * epsilon;
241  double c = 1.0 / (1.0 + a*a - b*b);
242 
243  if (!dagger) {
244  c *= k;//(-kappa*kappa)
246  } else {
247  ColorSpinorField *doubletTmp=0;
248  bool reset = newTmp(&doubletTmp, in);
250 
251  // this is just a vectorized Wilson dslash
252  NdegTwistedDslashXpay(out, *doubletTmp, x, parity, QUDA_NONDEG_DSLASH, 0.0, 0.0, k, 0.0);
253  deleteTmp(&doubletTmp, reset);
254  }
255  }
256  }
257 
259  {
260  double kappa2 = -kappa*kappa;
261  bool reset = newTmp(&tmp1, in);
262 
263  bool symmetric =(matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
264  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
265  QudaParity parity[2] = {static_cast<QudaParity>((1 + odd_bit) % 2), static_cast<QudaParity>((0 + odd_bit) % 2)};
266 
267  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
268  if (symmetric) {
269  Dslash(*tmp1, in, parity[0]);
270  DslashXpay(out, *tmp1, parity[1], in, kappa2);
271  } else { //asymmetric preconditioning
272  double a = 2.0 * kappa * mu;
273  Dslash(*tmp1, in, parity[0]);
274  TwistedDslashXpay(out, *tmp1, in, parity[1], QUDA_DEG_DSLASH_TWIST_XPAY, a, kappa2, 0.0, 0.0);
275  }
276  } else {
277  if (symmetric) {
278  Dslash(*tmp1, in, parity[0]);
279  DslashXpay(out, *tmp1, parity[1], in, kappa2);
280  } else {// asymmetric preconditioning
281  //Parameter for invert twist (note the implemented operator: c*(1 - i *a * gamma_5 tau_3 + b * tau_1)):
282  //double a = !dagger ? -2.0 * kappa * mu : 2.0 * kappa * mu;
283  double a = -2.0 * kappa * mu;
284  double b = -2.0 * kappa * epsilon;
285  double c = 1.0;
286 
287  Dslash(*tmp1, in, parity[0]);
289  }
290  }
291 
292  deleteTmp(&tmp1, reset);
293  }
294 
296  {
297  // need extra temporary because of symmetric preconditioning dagger
298  bool reset = newTmp(&tmp2, in);
299  M(*tmp2, in);
300  Mdag(out, *tmp2);
301  deleteTmp(&tmp2, reset);
302  }
303 
306  const QudaSolutionType solType) const
307  {
308  // we desire solution to preconditioned system
309  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
310  src = &b;
311  sol = &x;
312  return;
313  }
314 
315  bool reset = newTmp(&tmp1, b.Even());
316 
317  // we desire solution to full system
318  if(b.TwistFlavor() == QUDA_TWIST_SINGLET) {
320  // src = A_ee^-1 (b_e + k D_eo A_oo^-1 b_o)
321  src = &(x.Odd());
322  TwistInv(*src, b.Odd());
324  TwistInv(*src, *tmp1);
325  sol = &(x.Even());
326  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
327  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
328  src = &(x.Even());
329  TwistInv(*src, b.Even());
331  TwistInv(*src, *tmp1);
332  sol = &(x.Odd());
334  // src = b_e + k D_eo A_oo^-1 b_o
335  src = &(x.Odd());
336  TwistInv(*tmp1, b.Odd()); // safe even when *tmp1 = b.odd
338  sol = &(x.Even());
340  // src = b_o + k D_oe A_ee^-1 b_e
341  src = &(x.Even());
342  TwistInv(*tmp1, b.Even()); // safe even when *tmp1 = b.even
344  sol = &(x.Odd());
345  } else {
346  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
347  }
348  } else {//doublet:
349  // we desire solution to preconditioned system
350 
351  // we desire solution to full system
353  // src = A_ee^-1(b_e + k D_eo A_oo^-1 b_o)
354  src = &(x.Odd());
355 
359 
360  sol = &(x.Even());
361 
362  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
363  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
364  src = &(x.Even());
365 
369 
370  sol = &(x.Odd());
372  // src = b_e + k D_eo A_oo^-1 b_o
373  src = &(x.Odd());
374 
377 
378  sol = &(x.Even());
379 
381  // src = b_o + k D_oe A_ee^-1 b_e
382  src = &(x.Even());
383 
386 
387  sol = &(x.Odd());
388  } else {
389  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
390  }
391  }//end of doublet
392  // here we use final solution to store parity solution and parity source
393  // b is now up for grabs if we want
394 
395  deleteTmp(&tmp1, reset);
396  }
397 
399  const QudaSolutionType solType) const
400  {
401  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
402  return;
403  }
404 
405  checkFullSpinor(x, b);
406  bool reset = newTmp(&tmp1, b.Even());
407 
408  // create full solution
409  if(b.TwistFlavor() == QUDA_TWIST_SINGLET) {
411  // x_o = A_oo^-1 (b_o + k D_oe x_e)
413  TwistInv(x.Odd(), *tmp1);
415  // x_e = A_ee^-1 (b_e + k D_eo x_o)
417  TwistInv(x.Even(), *tmp1);
418  } else {
419  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
420  }
421  } else { //twist doublet:
423  // x_o = A_oo^-1 (b_o + k D_oe x_e)
424  NdegTwistedDslashXpay(*tmp1, x.Even(), b.Odd(), QUDA_ODD_PARITY, QUDA_NONDEG_DSLASH, 0.0, 0.0, kappa, 0.0);
427  // x_e = A_ee^-1 (b_e + k D_eo x_o)
428  NdegTwistedDslashXpay(*tmp1, x.Odd(), b.Even(), QUDA_EVEN_PARITY, QUDA_NONDEG_DSLASH, 0.0, 0.0, kappa, 0.0);
430  } else {
431  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
432  }
433  }//end of twist doublet...
434  deleteTmp(&tmp1, reset);
435  }
436 
437  void DiracTwistedMassPC::createCoarseOp(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat, const Transfer &T, double kappa, double mu, double mu_factor) const {
438  double a = -2.0 * kappa * mu;
439  cudaCloverField *c = NULL;
440  CoarseOp(Y, X, Xinv, Yhat, T, *gauge, c, kappa, a, -mu_factor, QUDA_TWISTED_MASSPC_DIRAC, matpcType);
441  }
442 } // namespace quda
virtual void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
unsigned long long flops
Definition: dirac_quda.h:100
double mu
Definition: test_util.cpp:1643
void TwistedDslash(ColorSpinorField &out, const ColorSpinorField &in, QudaParity parity, QudaTwistDslashType twistDslashType, double a, double b, double c, double d) const
const void * src
DiracTwistedMassPC(const DiracTwistedMassPC &dirac)
#define errorQuda(...)
Definition: util_quda.h:90
cudaGaugeField * gauge
Definition: dirac_quda.h:95
double mu_factor[QUDA_MAX_MG_LEVEL]
Definition: test_util.cpp:1659
virtual void checkFullSpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:129
DiracTwistedMassPC & operator=(const DiracTwistedMassPC &dirac)
cudaColorSpinorField * tmp
Definition: covdev_test.cpp:44
void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
const ColorSpinorField & Even() const
void deleteTmp(ColorSpinorField **, const bool &reset) const
Definition: dirac.cpp:64
TimeProfile profile
Definition: dirac_quda.h:112
DiracWilson & operator=(const DiracWilson &dirac)
DiracTwistedMass & operator=(const DiracTwistedMass &dirac)
void createCoarseOp(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat, const Transfer &T, double kappa, double mu, double mu_factor=0.) const
Create the coarse even-odd preconditioned twisted-mass operator.
void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
void Twist(ColorSpinorField &out, const ColorSpinorField &in) const
QudaGaugeParam param
Definition: pack_test.cpp:17
bool newTmp(ColorSpinorField **, const ColorSpinorField &) const
Definition: dirac.cpp:53
#define b
int commDim[QUDA_MAX_DIM]
Definition: dirac_quda.h:110
VOLATILE spinorFloat kappa
void ApplyTwistGamma(ColorSpinorField &out, const ColorSpinorField &in, int d, double kappa, double mu, double epsilon, int dagger, QudaTwistGamma5Type type)
Apply the twisted-mass gamma operator to a color-spinor field.
Definition: dslash_quda.cu:384
void checkSpinorAlias(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:137
cpuColorSpinorField * in
virtual void M(ColorSpinorField &out, const ColorSpinorField &in) const
void TwistedDslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const ColorSpinorField &x, QudaParity parity, QudaTwistDslashType twistDslashType, double a, double b, double c, double d) const
QudaSiteSubset SiteSubset() const
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
virtual void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
virtual void Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
enum QudaSolutionType_s QudaSolutionType
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
QudaDagType dagger
Definition: dirac_quda.h:99
enum QudaParity_s QudaParity
double kappa
Definition: dirac_quda.h:96
QudaMatPCType matpcType
Definition: dirac_quda.h:98
void NdegTwistedDslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const ColorSpinorField &x, QudaParity parity, QudaTwistDslashType twistDslashType, double a, double b, double c, double d) const
void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
enum QudaTwistDslashType_s QudaTwistDslashType
void Mdag(ColorSpinorField &out, const ColorSpinorField &in) const
Definition: dirac.cpp:73
GaugeCovDev * dirac
Definition: covdev_test.cpp:75
cpuColorSpinorField * out
void M(ColorSpinorField &out, const ColorSpinorField &in) const
void ndegTwistedMassDslashCuda(cudaColorSpinorField *out, const cudaGaugeField &gauge, const cudaColorSpinorField *in, const int parity, const int dagger, const cudaColorSpinorField *x, const QudaTwistDslashType type, const double &kappa, const double &mu, const double &epsilon, const double &k, const int *commDim, TimeProfile &profile)
void NdegTwistedDslash(ColorSpinorField &out, const ColorSpinorField &in, QudaParity parity, QudaTwistDslashType twistDslashType, double a, double b, double c, double d) const
void twistedMassDslashCuda(cudaColorSpinorField *out, const cudaGaugeField &gauge, const cudaColorSpinorField *in, const int parity, const int dagger, const cudaColorSpinorField *x, const QudaTwistDslashType type, const double &kappa, const double &mu, const double &epsilon, const double &k, const int *commDim, TimeProfile &profile)
const void * c
void createCoarseOp(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat, const Transfer &T, double kappa, double mu, double mu_factor=0.) const
Create the coarse twisted-mass operator.
void CoarseOp(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat, const Transfer &T, const cudaGaugeField &gauge, const cudaCloverField *clover, double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc)
Coarse operator construction from a fine-grid operator (Wilson / Clover)
Definition: coarse_op.cu:170
enum QudaTwistGamma5Type_s QudaTwistGamma5Type
DiracTwistedMass(const DiracTwistedMass &dirac)
void TwistInv(ColorSpinorField &out, const ColorSpinorField &in) const
virtual void checkParitySpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:89
static __inline__ size_t size_t d
QudaParity parity
Definition: covdev_test.cpp:53
ColorSpinorField * tmp2
Definition: dirac_quda.h:102
#define a
virtual void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
void twistedApply(ColorSpinorField &out, const ColorSpinorField &in, const QudaTwistGamma5Type twistType) const
ColorSpinorField * tmp1
Definition: dirac_quda.h:101