CHROMA
eoprec_slrc_linop_w.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Even-odd preconditioned Clover linear operator (fat-relevant, thin-irrelevant terms)
3  *
4  * Here, the relevant terms are smeared and the irrelevant terms are not smeared.
5  * Code provided by Thomas Kaltenbrunner.
6  *
7  */
8 
12 using namespace QDP::Hints;
13 
14 namespace Chroma
15 {
16 
17  //! Creation routine with Anisotropy
18  /*!
19  * \param u_ gauge field (Read)
20  * \param param_ fermion kappa (Read)
21  */
22  void EvenOddPrecSLRCLinOp::create(Handle< FermState<T,P,Q> > fs,
23  const CloverFermActParams& param_)
24  {
25  START_CODE();
26 
27  param = param_;
28 
29  // Need to make sure that fs is a stout ferm state
30  // We want to have Clover with thin links
31  thin_fs = new PeriodicFermState<T,P,Q>(
32  fs.cast< SLICFermState<T, P, Q> >()->getThinLinks());
33 
34  clov.create(thin_fs, param);
35 
36  invclov.create(thin_fs,param,clov); // make a copy
37  invclov.choles(0); // invert the cb=0 part
38 
39  //...and WilsonDslash with stout links
40  D.create(fs, param.anisoParam);
41 
42  END_CODE();
43  }
44 
45  //! Apply the the odd-odd block onto a source std::vector
46  void
47  EvenOddPrecSLRCLinOp::oddOddLinOp(LatticeFermion& chi, const LatticeFermion& psi,
48  enum PlusMinus isign) const
49  {
50  clov.apply(chi, psi, isign, 1);
51  }
52 
53 
54  //! Apply the the even-even block onto a source std::vector
55  void
56  EvenOddPrecSLRCLinOp::evenEvenLinOp(LatticeFermion& chi, const LatticeFermion& psi,
57  enum PlusMinus isign) const
58  {
59  // Nuke for testing
60  clov.apply(chi, psi, isign, 0);
61  }
62 
63  //! Apply the inverse of the even-even block onto a source std::vector
64  void
65  EvenOddPrecSLRCLinOp::evenEvenInvLinOp(LatticeFermion& chi, const LatticeFermion& psi,
66  enum PlusMinus isign) const
67  {
68  invclov.apply(chi, psi, isign, 0);
69  }
70 
71 
72  //! Apply even-odd linop component
73  /*!
74  * The operator acts on the entire even sublattice
75  *
76  * \param chi Pseudofermion field (Write)
77  * \param psi Pseudofermion field (Read)
78  * \param isign Flag ( PLUS | MINUS ) (Read)
79  */
80  void
81  EvenOddPrecSLRCLinOp::evenOddLinOp(LatticeFermion& chi,
82  const LatticeFermion& psi,
83  enum PlusMinus isign) const
84  {
85  START_CODE();
86 
87  Real mhalf = -0.5;
88 
89  D.apply(chi, psi, isign, 0);
90  chi[rb[0]] *= mhalf;
91 
92  END_CODE();
93  }
94 
95  //! Apply odd-even linop component
96  /*!
97  * The operator acts on the entire odd sublattice
98  *
99  * \param chi Pseudofermion field (Write)
100  * \param psi Pseudofermion field (Read)
101  * \param isign Flag ( PLUS | MINUS ) (Read)
102  */
103  void
104  EvenOddPrecSLRCLinOp::oddEvenLinOp(LatticeFermion& chi,
105  const LatticeFermion& psi,
106  enum PlusMinus isign) const
107  {
108  START_CODE();
109 
110  Real mhalf = -0.5;
111 
112  D.apply(chi, psi, isign, 1);
113  chi[rb[1]] *= mhalf;
114 
115  END_CODE();
116  }
117 
118 
119  //! Apply even-odd preconditioned Clover fermion linear operator
120  /*!
121  * \param chi Pseudofermion field (Write)
122  * \param psi Pseudofermion field (Read)
123  * \param isign Flag ( PLUS | MINUS ) (Read)
124  */
125  void EvenOddPrecSLRCLinOp::operator()(LatticeFermion & chi,
126  const LatticeFermion& psi,
127  enum PlusMinus isign) const
128  {
129  START_CODE();
130 
131  LatticeFermion tmp1; moveToFastMemoryHint(tmp1);
132  LatticeFermion tmp2; moveToFastMemoryHint(tmp2);
133  Real mquarter = -0.25;
134 
135  // tmp1_o = D_oe A^(-1)_ee D_eo psi_o
136  D.apply(tmp1, psi, isign, 0);
137  invclov.apply(tmp2, tmp1, isign, 0);
138  D.apply(tmp1, tmp2, isign, 1);
139 
140  // chi_o = A_oo psi_o - tmp1_o
141  clov.apply(chi, psi, isign, 1);
142 
143  chi[rb[1]] += mquarter*tmp1;
144 
145  END_CODE();
146  }
147 
148 
149  //! Apply the even-even block onto a source std::vector
150  void
151  EvenOddPrecSLRCLinOp::derivEvenEvenLinOp(multi1d<LatticeColorMatrix>& ds_u,
152  const LatticeFermion& chi, const LatticeFermion& psi,
153  enum PlusMinus isign) const
154  {
155  START_CODE();
156 
157  clov.deriv(ds_u, chi, psi, isign, 0);
158  getFermBC().zero(ds_u);
159 
160  END_CODE();
161  }
162 
163  //! Apply the even-even block onto a source std::vector
164  void
165  EvenOddPrecSLRCLinOp::derivLogDetEvenEvenLinOp(multi1d<LatticeColorMatrix>& ds_u,
166  enum PlusMinus isign) const
167  {
168  START_CODE();
169 
170  invclov.derivTrLn(ds_u, isign, 0);
171  getFermBC().zero(ds_u);
172 
173  END_CODE();
174  }
175 
176  //! Apply the the even-odd block onto a source std::vector
177  void
178  EvenOddPrecSLRCLinOp::derivEvenOddLinOp(multi1d<LatticeColorMatrix>& ds_u,
179  const LatticeFermion& chi, const LatticeFermion& psi,
180  enum PlusMinus isign) const
181  {
182  START_CODE();
183 
184  //temp variable for the fat force
185  multi1d<LatticeColorMatrix> ds_tmp(Nd);
186  // Dslash will resize this.
187  ds_u.resize(Nd);
188 
189 
190  D.deriv(ds_tmp, chi, psi, isign, 0);
191  for(int mu=0; mu < Nd; mu++) {
192  ds_tmp[mu] *= Real(-0.5);
193  }
194 
195  //WilsonDslash is thick, so need fatForceToThin here! (includes change of BCs)
196  SLICFermState<T, P, Q>& sfs = dynamic_cast<SLICFermState<T,P,Q>& >(*slrc_fs);
197  sfs.fatForceToThin(ds_tmp,ds_u);
198  getFermBC().zero(ds_u);
199 
200  END_CODE();
201  }
202 
203  //! Apply the the odd-even block onto a source std::vector
204  void
205  EvenOddPrecSLRCLinOp::derivOddEvenLinOp(multi1d<LatticeColorMatrix>& ds_u,
206  const LatticeFermion& chi, const LatticeFermion& psi,
207  enum PlusMinus isign) const
208  {
209  START_CODE();
210 
211  //temp variable for the fat force
212  multi1d<LatticeColorMatrix> ds_tmp(Nd);
213  ds_u.resize(Nd);
214 
215  D.deriv(ds_tmp, chi, psi, isign, 1);
216  for(int mu=0; mu < Nd; mu++) {
217  ds_tmp[mu] *= Real(-0.5);
218  }
219 
220  SLICFermState<T, P, Q>& sfs = dynamic_cast<SLICFermState<T,P,Q>& >(*slrc_fs);
221  sfs.fatForceToThin(ds_tmp,ds_u);
222  getFermBC().zero(ds_u);
223 
224  END_CODE();
225  }
226 
227  // Inherit this
228  //! Apply the the odd-odd block onto a source std::vector
229  void
230  EvenOddPrecSLRCLinOp::derivOddOddLinOp(multi1d<LatticeColorMatrix>& ds_u,
231  const LatticeFermion& chi, const LatticeFermion& psi,
232  enum PlusMinus isign) const
233  {
234  START_CODE();
235 
236  ds_u.resize(Nd);
237  clov.deriv(ds_u, chi, psi, isign, 1);
238  getFermBC().zero(ds_u);
239 
240  END_CODE();
241  }
242 
243 
244  //! Return flops performed by the operator()
245  unsigned long EvenOddPrecSLRCLinOp::nFlops() const
246  {
247  unsigned long cbsite_flops = 2*D.nFlops()+2*clov.nFlops()+4*Nc*Ns;
248  return cbsite_flops*(Layout::sitesOnNode()/2);
249  }
250 
251  //! Get the log det of the even even part
252  // BUt for now, return zero for testing.
253  Double EvenOddPrecSLRCLinOp::logDetEvenEvenLinOp(void) const {
254  return invclov.cholesDet(0);
255  }
256 } // 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
Periodic version of FermState.
SLIC (Stout Link Irrelevant Clover ferm connection state.
const Q & getThinLinks() const
void fatForceToThin(const P &F_fat, P &F_thin) const
int mu
Definition: cool.cc:24
Even-odd preconditioned Clover linear operator (fat-relevant, thin-irrelevant terms)
Nd
Definition: meslate.cc:74
Double tmp2
Definition: mesq.cc:30
multi1d< Hadron2PtContraction_t > operator()(const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
FloatingPoint< double > Double
Definition: gtest.h:7351
chi
Definition: pade_trln_w.cc:24
psi
Definition: pade_trln_w.cc:191
Periodic ferm state and a creator.
Simple ferm state and a creator.
Params for clover ferm acts.