QUDA  1.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
dirac_twisted_clover.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 #define NEW_DSLASH
7 
8 namespace quda {
9 
11  DiracWilson(param, nDim),
12  mu(param.mu),
13  epsilon(param.epsilon),
14  clover(*(param.clover))
15  {
16  }
17 
19  DiracWilson(dirac),
20  mu(dirac.mu),
21  epsilon(dirac.epsilon),
22  clover(dirac.clover)
23  {
24  }
25 
27 
29  {
30  if (&dirac != this)
31  {
33  clover = dirac.clover;
34  }
35 
36  return *this;
37  }
38 
40  {
41  Dirac::checkParitySpinor(out, in);
42 
43  if (out.Volume() != clover.VolumeCB())
44  errorQuda("Parity spinor volume %d doesn't match clover checkboard volume %d", out.Volume(), clover.VolumeCB());
45  }
46 
47  // Protected method for applying twist
49  {
50  checkParitySpinor(out, in);
51  ApplyTwistClover(out, in, clover, kappa, mu, 0.0, parity, dagger, twistType);
52 
53  if (twistType == QUDA_TWIST_GAMMA5_INVERSE) flops += 1056ll*in.Volume();
54  else flops += 552ll*in.Volume();
55  }
56 
57 
58  // Public method to apply the twist
60  {
62  }
63 
65  {
66  // this would really just be a Wilson dslash (not actually instantiated at present)
67  errorQuda("Not implemented");
68  }
69 
71  const ColorSpinorField &x, const double &k) const
72  {
73 
74  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
75  // k * D * in + (1 + i*2*mu*kappa*gamma_5) *x
76  ApplyTwistedClover(out, in, *gauge, clover, k, 2 * mu * kappa, x, parity, dagger, commDim, profile);
77  flops += (1320ll + 552ll) * in.Volume();
78 
79  } else {
80  errorQuda("Non-degenerate operator is not implemented");
81  }
82  }
83 
85  {
86  checkFullSpinor(out, in);
87  if (in.TwistFlavor() != out.TwistFlavor())
88  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
89 
91  errorQuda("Twist flavor not set %d", in.TwistFlavor());
92  }
93 
95  out, in, *gauge, clover, -kappa, 2.0 * kappa * mu, in, QUDA_INVALID_PARITY, dagger, commDim, profile);
96  flops += (1320ll + 552ll) * in.Volume();
97  }
98 
100  {
101  checkFullSpinor(out, in);
102  bool reset = newTmp(&tmp1, in);
103 
104  M(*tmp1, in);
105  Mdag(out, *tmp1);
106 
107  deleteTmp(&tmp1, reset);
108  }
109 
111  ColorSpinorField &b, const QudaSolutionType solType) const
112  {
113  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
114  errorQuda("Preconditioned solution requires a preconditioned solve_type");
115  }
116 
117  src = &b;
118  sol = &x;
119  }
120 
122  const QudaSolutionType solType) const
123  {
124  // do nothing
125  }
126 
128  double kappa, double mass, double mu, double mu_factor) const {
129  double a = 2.0 * kappa * mu * T.Vectors().TwistFlavor();
130  CoarseOp(Y, X, T, *gauge, &clover, kappa, a, mu_factor, QUDA_TWISTED_CLOVER_DIRAC, QUDA_MATPC_INVALID);
131  }
132 
134  DiracTwistedClover(dirac),
135  reverse(false)
136  {
137  }
138 
140  DiracTwistedClover(param, nDim),
141  reverse(false)
142  {
143  }
144 
146  {
147 
148  }
149 
151  {
152  if (&dirac != this) {
154  }
155  return *this;
156  }
157 
158  // Public method to apply the inverse twist
160  {
162  }
163 
164  // apply hopping term, then inverse twist: (A_ee^-1 D_eo) or (A_oo^-1 D_oe),
165  // and likewise for dagger: (D^dagger_eo D_ee^-1) or (D^dagger_oe A_oo^-1)
167  {
168  checkParitySpinor(in, out);
169  checkSpinorAlias(in, out);
170 
171  if (in.TwistFlavor() != out.TwistFlavor())
172  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
174  errorQuda("Twist flavor not set %d", in.TwistFlavor());
175 
176  bool symmetric = (matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
177  if (dagger && symmetric && !reverse) {
178  bool reset = newTmp(&tmp2, in);
179  TwistCloverInv(*tmp2, in, 1 - parity);
180  DiracWilson::Dslash(out, *tmp2, parity);
181  deleteTmp(&tmp2, reset);
182  } else {
183  ApplyTwistedCloverPreconditioned(out, in, *gauge, clover, 1.0, -2.0 * kappa * mu, false, in, parity, dagger,
184  commDim, profile);
185  flops += (1320ll + 552ll) * in.Volume();
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", in.TwistFlavor());
199 
200  bool symmetric = (matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
201  if (dagger && symmetric && !reverse) {
202  bool reset = newTmp(&tmp2, in);
203  TwistCloverInv(*tmp2, in, 1 - parity);
204  DiracWilson::DslashXpay(out, *tmp2, parity, x, k);
205  deleteTmp(&tmp2, reset);
206  } else {
208  out, in, *gauge, clover, k, -2.0 * kappa * mu, true, x, parity, dagger, commDim, profile);
209  flops += (1320ll + 552ll) * in.Volume();
210  }
211  }
212 
214  {
215  double kappa2 = -kappa*kappa;
216  bool reset = newTmp(&tmp1, in);
217 
218  bool symmetric =(matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
219  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
220  QudaParity parity[2] = {static_cast<QudaParity>((1 + odd_bit) % 2), static_cast<QudaParity>((0 + odd_bit) % 2)};
221 
222  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
223  if (!symmetric) { // asymmetric preconditioning
224  Dslash(*tmp1, in, parity[0]);
225  DiracTwistedClover::DslashXpay(out, *tmp1, parity[1], in, kappa2);
226  } else if (!dagger) { // symmetric preconditioning
227  Dslash(*tmp1, in, parity[0]);
228  DslashXpay(out, *tmp1, parity[1], in, kappa2);
229  } else { // symmetric preconditioning, dagger
230  TwistCloverInv(out, in, parity[1]);
231  reverse = true;
232  Dslash(*tmp1, out, parity[0]);
233  reverse = false;
234  DiracWilson::DslashXpay(out, *tmp1, parity[1], in, kappa2);
235  }
236  } else { //Twist doublet
237  errorQuda("Non-degenerate operator is not implemented");
238  }
239 
240  deleteTmp(&tmp1, reset);
241  }
242 
244  {
245  // need extra temporary because of symmetric preconditioning dagger
246  bool reset = newTmp(&tmp2, in);
247  M(*tmp2, in);
248  Mdag(out, *tmp2);
249  deleteTmp(&tmp2, reset);
250  }
251 
253  ColorSpinorField &b, const QudaSolutionType solType) const
254  {
255  // we desire solution to preconditioned system
256  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
257  src = &b;
258  sol = &x;
259  return;
260  }
261 
262  bool reset = newTmp(&tmp1, b.Even());
263 
264  bool symmetric = (matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
265  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
266 
267  src = odd_bit ? &(x.Even()) : &(x.Odd());
268  sol = odd_bit ? &(x.Odd()) : &(x.Even());
269 
270  TwistCloverInv(symmetric ? *src : *tmp1, odd_bit ? b.Even() : b.Odd(), odd_bit ? QUDA_EVEN_PARITY : QUDA_ODD_PARITY);
271 
272  // we desire solution to full system
273  if (b.TwistFlavor() == QUDA_TWIST_SINGLET) {
274 
276  // src = A_ee^-1 (b_e + k D_eo A_oo^-1 b_o)
278  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
279  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
280  DiracWilson::DslashXpay(*tmp1, *src, QUDA_ODD_PARITY, b.Odd(), kappa);
282  // src = b_e + k D_eo A_oo^-1 b_o
285  // src = b_o + k D_oe A_ee^-1 b_e
286  DiracWilson::DslashXpay(*src, *tmp1, QUDA_ODD_PARITY, b.Odd(), kappa);
287  } else {
288  errorQuda("MatPCType %d not valid for DiracTwistedCloverPC", matpcType);
289  }
290 
291  } else { // doublet:
292  errorQuda("Non-degenerate operator is not implemented");
293  } // end of doublet
294 
295  if (symmetric) TwistCloverInv(*src, *tmp1, odd_bit ? QUDA_ODD_PARITY : QUDA_EVEN_PARITY);
296 
297  // here we use final solution to store parity solution and parity source
298  // b is now up for grabs if we want
299 
300  deleteTmp(&tmp1, reset);
301  }
302 
304  const QudaSolutionType solType) const
305  {
306  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) { return; }
307 
308  checkFullSpinor(x, b);
309  bool reset = newTmp(&tmp1, b.Even());
310  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
311 
312  // create full solution
313  if (b.TwistFlavor() == QUDA_TWIST_SINGLET) {
315  // x_o = A_oo^-1 (b_o + k D_oe x_e)
318  // x_e = A_ee^-1 (b_e + k D_eo x_o)
320  } else {
321  errorQuda("MatPCType %d not valid for DiracTwistedCloverPC", matpcType);
322  }
323  } else { // twist doublet:
324  errorQuda("Non-degenerate operator is not implemented");
325  } // end of twist doublet...
326 
327  TwistCloverInv(odd_bit ? x.Even() : x.Odd(), *tmp1, odd_bit ? QUDA_EVEN_PARITY : QUDA_ODD_PARITY);
328  deleteTmp(&tmp1, reset);
329  }
330 
332  double kappa, double mass, double mu, double mu_factor) const {
333  double a = -2.0 * kappa * mu * T.Vectors().TwistFlavor();
334  CoarseOp(Y, X, T, *gauge, &clover, kappa, a, -mu_factor, QUDA_TWISTED_CLOVERPC_DIRAC, matpcType);
335  }
336 } // namespace quda
virtual void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
void M(ColorSpinorField &out, const ColorSpinorField &in) const
unsigned long long flops
Definition: dirac_quda.h:121
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
double mu
Definition: test_util.cpp:1648
#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
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-clover operator. Unlike the Wilson operator...
void ApplyTwistedClover(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, const CloverField &C, double a, double b, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
Driver for applying the twisted-clover stencil.
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
DiracWilson & operator=(const DiracWilson &dirac)
DiracTwistedCloverPC(const DiracTwistedCloverPC &dirac)
void checkParitySpinor(const ColorSpinorField &, const ColorSpinorField &) const
QudaGaugeParam param
Definition: pack_test.cpp:17
bool newTmp(ColorSpinorField **, const ColorSpinorField &) const
Definition: dirac.cpp:70
void TwistCloverInv(ColorSpinorField &out, const ColorSpinorField &in, const int parity) const
int commDim[QUDA_MAX_DIM]
Definition: dirac_quda.h:130
void createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu, double mu_factor=0.) const
Create the coarse twisted-clover operator.
cudaCloverField & clover
Definition: dirac_quda.h:606
DiracTwistedCloverPC & operator=(const DiracTwistedCloverPC &dirac)
void checkSpinorAlias(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:154
cpuColorSpinorField * in
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
DiracTwistedClover & operator=(const DiracTwistedClover &dirac)
double mass
Definition: dirac_quda.h:117
enum QudaSolutionType_s QudaSolutionType
virtual void M(ColorSpinorField &out, const ColorSpinorField &in) const
DiracTwistedClover(const DiracTwistedClover &dirac)
QudaDagType dagger
Definition: dirac_quda.h:120
int X[4]
Definition: covdev_test.cpp:70
enum QudaParity_s QudaParity
void TwistClover(ColorSpinorField &out, const ColorSpinorField &in, const int parity) const
double kappa
Definition: dirac_quda.h:116
QudaMatPCType matpcType
Definition: dirac_quda.h:119
void Mdag(ColorSpinorField &out, const ColorSpinorField &in) const
Definition: dirac.cpp:90
void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
GaugeCovDev * dirac
Definition: covdev_test.cpp:73
cpuColorSpinorField * out
void ApplyTwistedCloverPreconditioned(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, const CloverField &C, double a, double b, bool xpay, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
Driver for applying the preconditioned twisted-clover stencil.
void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
virtual void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
int VolumeCB() const
virtual void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
QudaTwistFlavorType TwistFlavor() const
double mu_factor[QUDA_MAX_MG_LEVEL]
Definition: test_util.cpp:1674
virtual void Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
enum QudaTwistGamma5Type_s QudaTwistGamma5Type
virtual void Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
virtual void checkParitySpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:106
void twistedCloverApply(ColorSpinorField &out, const ColorSpinorField &in, const QudaTwistGamma5Type twistType, const int parity) const
QudaParity parity
Definition: covdev_test.cpp:54
virtual void Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
ColorSpinorField * tmp2
Definition: dirac_quda.h:123
const ColorSpinorField & Vectors(QudaFieldLocation location=QUDA_INVALID_FIELD_LOCATION) const
Definition: transfer.h:205
void ApplyTwistClover(ColorSpinorField &out, const ColorSpinorField &in, const CloverField &clover, double kappa, double mu, double epsilon, int parity, int dagger, QudaTwistGamma5Type twist)
Apply twisted clover-matrix field to a color-spinor field.
Definition: dslash_quda.cu:769
void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
ColorSpinorField * tmp1
Definition: dirac_quda.h:122