QUDA  1.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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),
10  mu(param.mu),
11  epsilon(param.epsilon)
12  {
13  }
14 
16  DiracWilson(dirac),
17  mu(dirac.mu),
18  epsilon(dirac.epsilon)
19  {
20  }
21 
23 
25  {
26  if (&dirac != this) {
28  }
29  return *this;
30  }
31 
32  // Protected method for applying twist
34  const QudaTwistGamma5Type twistType) const
35  {
36  checkParitySpinor(out, in);
37  ApplyTwistGamma(out, in, 4, kappa, mu, epsilon, dagger, twistType);
38  flops += 24ll*in.Volume();
39  }
40 
41  // Public method to apply the twist
43  {
45  }
46 
48  {
49 
50  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
51  // this would really just be a Wilson dslash (not actually instantiated at present)
52  ApplyTwistedMass(out, in, *gauge, 0.0, 2 * mu * kappa, in, parity, dagger, commDim, profile);
53  flops += 1392ll * in.Volume();
54  } else {
55  // this would really just be a 2-way vectorized Wilson dslash (not actually instantiated at present)
57  out, in, *gauge, 0.0, 2 * mu * kappa, -2 * kappa * epsilon, in, parity, dagger, commDim, profile);
58  flops += (1440ll) * in.Volume();
59  }
60  }
61 
63  const ColorSpinorField &x, const double &k) const
64  {
65 
66  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
67  // k * D * in + (1 + i*2*mu*kappa*gamma_5) *x
68  ApplyTwistedMass(out, in, *gauge, k, 2 * mu * kappa, x, parity, dagger, commDim, profile);
69  flops += 1416ll * in.Volume();
70  } else {
71  // k * D * in + (1 + i*2*mu*kappa*gamma_5*tau_3 - 2*epsilon*kappa*tau_1) * x
72  ApplyNdegTwistedMass(out, in, *gauge, k, 2 * mu * kappa, -2 * kappa * epsilon, x, parity, dagger, commDim, profile);
73  flops += (1464ll) * in.Volume();
74  }
75  }
76 
77  // apply full operator / (-kappa * D + (1 + i*2*mu*kappa*gamma_5*tau_3 - 2*epsilon*kappa*tau_1)) * in
79  {
80  checkFullSpinor(out, in);
81  if (in.TwistFlavor() != out.TwistFlavor())
82  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
83 
85  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
86  }
87 
88  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
90  flops += 1416ll * in.Volume();
91  } else {
92  ApplyNdegTwistedMass(out, in, *gauge, -kappa, 2 * mu * kappa, -2 * kappa * epsilon, in, QUDA_INVALID_PARITY,
94  flops += (1464ll) * in.Volume();
95  }
96  }
97 
99  {
100  checkFullSpinor(out, in);
101  bool reset = newTmp(&tmp1, in);
102 
103  M(*tmp1, in);
104  Mdag(out, *tmp1);
105 
106  deleteTmp(&tmp1, reset);
107  }
108 
110  ColorSpinorField &b, const QudaSolutionType solType) const
111  {
112  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
113  errorQuda("Preconditioned solution requires a preconditioned solve_type");
114  }
115 
116  src = &b;
117  sol = &x;
118  }
119 
121  const QudaSolutionType solType) const
122  {
123  // do nothing
124  }
125 
127  double kappa, double mass, double mu, double mu_factor) const {
128  double a = 2.0 * kappa * mu;
129  cudaCloverField *c = NULL;
130  CoarseOp(Y, X, T, *gauge, c, kappa, a, mu_factor, QUDA_TWISTED_MASS_DIRAC, QUDA_MATPC_INVALID);
131  }
132 
134 
136 
138  {
139 
140  }
141 
143  {
144  if (&dirac != this) {
146  }
147  return *this;
148  }
149 
150  // Public method to apply the inverse twist
152  {
154  }
155 
156  // apply hopping term, then inverse twist: (A_ee^-1 D_eo) or (A_oo^-1 D_oe),
157  // and likewise for dagger: (D^dagger_eo A_ee^-1) or (D^dagger_oe A_oo^-1)
159  {
160  checkParitySpinor(in, out);
161  checkSpinorAlias(in, out);
162 
163  if (in.TwistFlavor() != out.TwistFlavor())
164  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
166  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
167 
168  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
169  double a = -2.0 * kappa * mu; // for inverse twist
170  double b = 1.0 / (1.0 + a * a);
171 
172  bool asymmetric
174  ApplyTwistedMassPreconditioned(out, in, *gauge, b, a, false, in, parity, dagger, asymmetric, commDim, profile);
175  flops += 1392ll * in.Volume(); // flops numbers are approximate since they will vary depending on the dagger or not
176  } else {//TWIST doublet :
177  double a = 2.0 * kappa * mu;
178  double b = 2.0 * kappa * epsilon;
179  double c = 1.0 / (1.0 + a * a - b * b);
180 
181  bool asymmetric
183  ApplyNdegTwistedMassPreconditioned(out, in, *gauge, c, -2.0 * mu * kappa, 2.0 * kappa * epsilon, false, in,
184  parity, dagger, asymmetric, commDim, profile);
185  flops += (1440ll) * in.Volume(); // flops are approx. since they will vary depending on the dagger or not
186  }
187  }
188 
189  // xpay version of the above
191  const ColorSpinorField &x, const double &k) const
192  {
193  checkParitySpinor(in, out);
194  checkSpinorAlias(in, out);
195  if (in.TwistFlavor() != out.TwistFlavor())
196  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
198  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
199 
200  if(in.TwistFlavor() == QUDA_TWIST_SINGLET) {
201  double a = -2.0 * kappa * mu; // for inverse twist
202  double b = k / (1.0 + a * a);
203  // asymmetric should never be true here since we never need to apply 1 + k * A^{-1} D^\dagger
204  bool asymmetric
206  ApplyTwistedMassPreconditioned(out, in, *gauge, b, a, true, x, parity, dagger, asymmetric, commDim, profile);
207  flops += 1416ll * in.Volume(); // flops numbers are approximate since they will vary depending on the dagger or not
208  } else {//TWIST_DOUBLET:
209  double a = 2.0 * kappa * mu;
210  double b = 2.0 * kappa * epsilon;
211  double c = 1.0 / (1.0 + a * a - b * b);
212 
213  bool asymmetric
215  ApplyNdegTwistedMassPreconditioned(out, in, *gauge, k * c, -2 * mu * kappa, 2 * kappa * epsilon, true, x, parity,
216  dagger, asymmetric, commDim, profile);
217  flops += (1464ll)
218  * in.Volume(); // flops numbers are approximate since they will vary depending on the dagger or not
219  }
220  }
221 
223  {
224  double kappa2 = -kappa*kappa;
225  bool reset = newTmp(&tmp1, in);
226 
227  bool symmetric =(matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
228  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
229  QudaParity parity[2] = {static_cast<QudaParity>((1 + odd_bit) % 2), static_cast<QudaParity>((0 + odd_bit) % 2)};
230 
231  if (symmetric) {
232  Dslash(*tmp1, in, parity[0]);
233  DslashXpay(out, *tmp1, parity[1], in, kappa2);
234  } else { // asymmetric preconditioning
235  Dslash(*tmp1, in, parity[0]);
236  DiracTwistedMass::DslashXpay(out, *tmp1, parity[1], in, kappa2);
237  }
238 
239  deleteTmp(&tmp1, reset);
240  }
241 
243  {
244  // need extra temporary because of symmetric preconditioning dagger
245  bool reset = newTmp(&tmp2, in);
246  M(*tmp2, in);
247  Mdag(out, *tmp2);
248  deleteTmp(&tmp2, reset);
249  }
250 
252  ColorSpinorField &b, const QudaSolutionType solType) const
253  {
254  // we desire solution to preconditioned system
255  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
256  src = &b;
257  sol = &x;
258  return;
259  }
260 
261  bool reset = newTmp(&tmp1, b.Even());
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 
266  src = odd_bit ? &(x.Even()) : &(x.Odd());
267  sol = odd_bit ? &(x.Odd()) : &(x.Even());
268 
269  TwistInv(symmetric ? *src : *tmp1, odd_bit ? b.Even() : b.Odd());
270 
271  // we desire solution to full system
272  if (b.TwistFlavor() == QUDA_TWIST_SINGLET) {
273 
275  // src = A_ee^-1 (b_e + k D_eo A_oo^-1 b_o)
277  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
278  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
279  DiracWilson::DslashXpay(*tmp1, *src, QUDA_ODD_PARITY, b.Odd(), kappa);
281  // src = b_e + k D_eo A_oo^-1 b_o
284  // src = b_o + k D_oe A_ee^-1 b_e
285  DiracWilson::DslashXpay(*src, *tmp1, QUDA_ODD_PARITY, b.Odd(), kappa);
286  } else {
287  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
288  }
289 
290  } else { // doublet:
291 
292  // repurpose the precondiitoned dslash as a vectorized operator: 1+kappa*D
293  double mu_ = mu;
294  mu = 0.0;
295  double epsilon_ = epsilon;
296  epsilon = 0.0;
297 
298  // we desire solution to full system
300  // src = A_ee^-1(b_e + k D_eo A_oo^-1 b_o)
301  DslashXpay(*tmp1, *src, QUDA_EVEN_PARITY, b.Even(), kappa);
302  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
303  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
304  DslashXpay(*tmp1, *src, QUDA_ODD_PARITY, b.Odd(), kappa);
306  // src = b_e + k D_eo A_oo^-1 b_o
307  DslashXpay(*src, *tmp1, QUDA_EVEN_PARITY, b.Even(), kappa);
309  // src = b_o + k D_oe A_ee^-1 b_e
310  DslashXpay(*src, *tmp1, QUDA_ODD_PARITY, b.Odd(), kappa);
311  } else {
312  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
313  }
314 
315  mu = mu_;
316  epsilon = epsilon_;
317 
318  } // end of doublet
319 
320  if (symmetric) TwistInv(*src, *tmp1);
321 
322  // here we use final solution to store parity solution and parity source
323  // b is now up for grabs if we want
324 
325  deleteTmp(&tmp1, reset);
326  }
327 
329  const QudaSolutionType solType) const
330  {
331  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) { return; }
332 
333  checkFullSpinor(x, b);
334  bool reset = newTmp(&tmp1, b.Even());
335  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
336 
337  // create full solution
338  if (b.TwistFlavor() == QUDA_TWIST_SINGLET) {
340  // x_o = A_oo^-1 (b_o + k D_oe x_e)
343  // x_e = A_ee^-1 (b_e + k D_eo x_o)
345  } else {
346  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
347  }
348  } else { // twist doublet:
349  double mu_ = mu;
350  mu = 0.0;
351  double epsilon_ = epsilon;
352  epsilon = 0.0;
353 
355  // x_o = A_oo^-1 (b_o + k D_oe x_e)
358  // x_e = A_ee^-1 (b_e + k D_eo x_o)
360  } else {
361  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
362  }
363 
364  mu = mu_;
365  epsilon = epsilon_;
366  } // end of twist doublet...
367 
368  TwistInv(odd_bit ? x.Even() : x.Odd(), *tmp1);
369  deleteTmp(&tmp1, reset);
370  }
371 
373  double kappa, double mass, double mu, double mu_factor) const {
374  double a = -2.0 * kappa * mu;
375  cudaCloverField *c = NULL;
376  CoarseOp(Y, X, T, *gauge, c, kappa, a, -mu_factor, QUDA_TWISTED_MASSPC_DIRAC, matpcType);
377  }
378 } // namespace quda
virtual void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
unsigned long long flops
Definition: dirac_quda.h:121
double mu
Definition: test_util.cpp:1648
DiracTwistedMassPC(const DiracTwistedMassPC &dirac)
#define errorQuda(...)
Definition: util_quda.h:121
cudaGaugeField * gauge
Definition: dirac_quda.h:115
virtual void checkFullSpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:146
double epsilon
Definition: test_util.cpp:1649
DiracTwistedMassPC & operator=(const DiracTwistedMassPC &dirac)
void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
const ColorSpinorField & Even() const
void deleteTmp(ColorSpinorField **, const bool &reset) const
Definition: dirac.cpp:81
void CoarseOp(GaugeField &Y, GaugeField &X, 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:201
const ColorSpinorField & Odd() const
TimeProfile profile
Definition: dirac_quda.h:132
void createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu, double mu_factor=0.) const
Create the coarse twisted-mass operator.
DiracWilson & operator=(const DiracWilson &dirac)
DiracTwistedMass & operator=(const DiracTwistedMass &dirac)
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:70
void createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu, double mu_factor=0.) const
Create the coarse even-odd preconditioned twisted-mass operator.
int commDim[QUDA_MAX_DIM]
Definition: dirac_quda.h:130
void ApplyNdegTwistedMass(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, double b, double c, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
Driver for applying the non-degenerate twisted-mass stencil.
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:416
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, QudaParity parity, const ColorSpinorField &x, const double &k) const
void checkSpinorAlias(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:154
cpuColorSpinorField * in
virtual void M(ColorSpinorField &out, const ColorSpinorField &in) const
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
double mass
Definition: dirac_quda.h:117
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:120
int X[4]
Definition: covdev_test.cpp:70
enum QudaParity_s QudaParity
double kappa
Definition: dirac_quda.h:116
QudaMatPCType matpcType
Definition: dirac_quda.h:119
void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
void Mdag(ColorSpinorField &out, const ColorSpinorField &in) const
Definition: dirac.cpp:90
GaugeCovDev * dirac
Definition: covdev_test.cpp:73
cpuColorSpinorField * out
void M(ColorSpinorField &out, const ColorSpinorField &in) const
void ApplyTwistedMass(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, double b, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
Driver for applying the twisted-mass stencil.
QudaTwistFlavorType TwistFlavor() const
double mu_factor[QUDA_MAX_MG_LEVEL]
Definition: test_util.cpp:1674
void ApplyTwistedMassPreconditioned(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, double b, bool xpay, const ColorSpinorField &x, int parity, bool dagger, bool asymmetric, const int *comm_override, TimeProfile &profile)
Driver for applying the preconditioned twisted-mass stencil.
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:106
void ApplyNdegTwistedMassPreconditioned(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, double b, double c, bool xpay, const ColorSpinorField &x, int parity, bool dagger, bool asymmetric, const int *comm_override, TimeProfile &profile)
Driver for applying the preconditioned non-degenerate twisted-mass stencil.
QudaParity parity
Definition: covdev_test.cpp:54
virtual void Dslash(ColorSpinorField &out, const ColorSpinorField &in, QudaParity parity) const
ColorSpinorField * tmp2
Definition: dirac_quda.h:123
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:122