CHROMA
eoprec_constdet_linop.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! @file
3  * @brief Preconditioned 4D Linop with Gauge Independent Even-Even part
4  */
5 
6 #ifndef __eoprec_constdet_linop_h__
7 #define __eoprec_constdet_linop_h__
8 
9 #include "eoprec_linop.h"
10 
11 using namespace QDP::Hints;
12 
13 namespace Chroma
14 {
15 
16  //----------------------------------------------------------------
17  //! Even-odd preconditioned linear operator
18  /*! @ingroup linop
19  *
20  * Support for even-odd preconditioned linear operators
21  * Given a matrix M written in block form:
22  *
23  * [ A D ]
24  * [ E,E E,O ]
25  * [ ]
26  * [ D A ]
27  * [ O,E O,O ]
28  *
29  * The preconditioning consists of using the triangular matrices
30  *
31  * [ 1 0 ]
32  * [ E,E E,O ]
33  * L = [ ]
34  * [ D A^(-1) 1 ]
35  * [ O,E E,E O,O ]
36  *
37  * and
38  *
39  * [ 1 A^{-1} D ]
40  * [ E,E EE E,O ]
41  * U = [ ]
42  * [ 0 1 ]
43  * [ O,E O,O ]
44  *
45  * The preconditioned matrix is formed from
46  *
47  * M' = L^-1 * M * U^-1
48  *
49  * where
50  *
51  * [ 1 0 ]
52  * [ E,E E,O ]
53  * L^(-1) = [ ]
54  * [ - D A^(-1) 1 ]
55  * [ O,E E,E O,O ]
56  *
57  * and
58  *
59  * [ 1 - A^(-1) D ]
60  * [ E,E E,E E,O ]
61  * U^(-1) = [ ]
62  * [ 0 1 ]
63  * [ O,E O,O ]
64  *
65  * Resulting in a new M
66  *
67  * [ A 0 ]
68  * [ E,E E,O ]
69  * [ ]
70  * [ 0 A - D A^(-1) D ]
71  * [ O,E O,O O,E E,E E,O ]
72  *
73  *
74  * This class is used to implement the resulting linear operator
75  *
76  * ~
77  * M = A(o,o) - D(o,e) . A^-1(e,e) . D(e,o)
78  *
79  * where A^{-1}_{ee} is independent of the gauge fields. This
80  * means that the det A_{ee} is an irrelevant constant and that
81  * the force term due to the A_{ee} part is zero.
82  *
83  * This structure suits most of the linear operators we use, and
84  * It simplifies the force term.
85  * By construction, the linear operator is ONLY defined on the odd subset
86  *
87  */
88 
89  template<typename T, typename P, typename Q>
91  {
92  public:
93  //! Virtual destructor to help with cleanup;
95 
96  //! Return the fermion BC object for this linear operator
97  virtual const FermBC<T,P,Q>& getFermBC() const = 0;
98 
99  //! Apply the derivative of the operator onto a source std::vector
100  /*! User should make sure deriv routines do a resize */
101  virtual void deriv(P& ds_u, const T& chi, const T& psi,
102  enum PlusMinus isign) const
103  {
104  // Need deriv of (A_oo - D_oe*Ainv_ee*D_eo*psi_e)
105  enum PlusMinus msign = (isign == PLUS) ? MINUS : PLUS;
106 
107  //
108  // Make sure the deriv routines do a resize !!!
109  //
110  T tmp1, tmp2; // if an array is used here, the space is not reserved
111  moveToFastMemoryHint(tmp1);
112  moveToFastMemoryHint(tmp2);
113 
114  P ds_1; // deriv routines should resize
115 
116  //
117  // NOTE: even with even-odd decomposition, the ds_u will still have contributions
118  // on all cb. So, no adding of ds_1 onto ds_u under a subset
119  //
120 
121  // ds_u -= chi^dag * D'_oe * Ainv_ee * D_eo * psi_o
122  this->evenOddLinOp(tmp1, psi, isign);
123  this->evenEvenInvLinOp(tmp2, tmp1, isign);
124  this->derivOddEvenLinOp(ds_u, chi, tmp2, isign);
125 
126 
127  // ds_u -= chi^dag * D_oe * Ainv_ee * D'_eo * psi_o
128  this->evenOddLinOp(tmp1, chi, msign);
129  this->evenEvenInvLinOp(tmp2, tmp1, msign);
130  this->derivEvenOddLinOp(ds_1, tmp2, psi, isign);
131  ds_u += ds_1;
132 
133  // This is yucky and ws should have a *= function
134  // so that I wouldn't have to expose the fact that I expect
135  // ds_u to be an Nd dimensional array
136  for(int mu=0; mu < Nd; mu++) {
137  ds_u[mu] *= Real(-1);
138  }
139 
140  getFermBC().zero(ds_u);
141  }
142 
143  //! Apply the even-even block onto a source std::vector
144  virtual void derivEvenEvenLinOp(P& ds_u, const T& chi, const T& psi,
145  enum PlusMinus isign) const
146  {
147  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
148  QDP_abort(1);
149  }
150 
151  //! Apply the the even-odd block onto a source std::vector
152  virtual void derivEvenOddLinOp(P& ds_u, const T& chi, const T& psi,
153  enum PlusMinus isign) const
154  {
155  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
156  QDP_abort(1);
157  }
158 
159  //! Apply the the odd-even block onto a source std::vector
160  virtual void derivOddEvenLinOp(P& ds_u, const T& chi, const T& psi,
161  enum PlusMinus isign) const
162  {
163  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
164  QDP_abort(1);
165  }
166 
167  //! Apply the the odd-odd block onto a source std::vector
168  virtual void derivOddOddLinOp(P& ds_u, const T& chi, const T& psi,
169  enum PlusMinus isign) const
170  {
171  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
172  QDP_abort(1);
173  }
174 
175  // Multipole derivatives
176  virtual void derivEvenEvenLinOpMP(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
177  enum PlusMinus isign) const
178  {
179  // implement in terms existing derivatives:
180  // Trivially zero since determinant is constant
181  ds_u.resize(Nd);
182  ds_u = zero;
183 
184 
185  /*
186  F_tmp = zero;
187  for(int i=0; i < chi.size(); i++) {
188  derivEvenEvenLinOp(F_tmp, chi[i], psi[i], isign);
189  ds_u += F_tmp;
190  }
191  */
192  }
193 
194  // Multipole derivatives
195  virtual void derivEvenOddLinOpMP(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
196  enum PlusMinus isign) const
197  {
198  // implement in terms existing derivatives:
199  ds_u.resize(Nd);
200  ds_u = zero;
201 
202  P F_tmp; // deriv will resize
203  for(int i=0; i < chi.size(); i++) {
204  this->derivEvenOddLinOp(F_tmp, chi[i], psi[i], isign);
205  ds_u += F_tmp;
206  }
207  }
208 
209  virtual void derivOddEvenLinOpMP(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
210  enum PlusMinus isign) const
211  {
212  // implement in terms existing derivatives:
213  ds_u.resize(Nd);
214  ds_u = zero;
215 
216  P F_tmp; // deriv will resize
217  for(int i=0; i < chi.size(); i++) {
218  this->derivOddEvenLinOp(F_tmp, chi[i], psi[i], isign);
219  ds_u += F_tmp;
220  }
221  }
222 
223  virtual void derivOddOddLinOpMP(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
224  enum PlusMinus isign) const
225  {
226  // Trivially zero since we are constdet?
227  ds_u.resize(Nd);
228  ds_u = zero;
229 
230  /*
231  F_tmp = zero;
232  for(int i=0; i < chi.size(); i++) {
233  derivOddOddLinOp(F_tmp, chi[i], psi[i], isign);
234  ds_u += F_tmp;
235  }
236  */
237  }
238 
239 
240  //! Apply the derivative of the operator onto a source std::vector
241  /*! User should make sure deriv routines do a resize */
242  virtual void derivMultipole(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
243  enum PlusMinus isign) const
244  {
245  // Need deriv of (A_oo - D_oe*Ainv_ee*D_eo*psi_e)
246  enum PlusMinus msign = (isign == PLUS) ? MINUS : PLUS;
247 
248  //
249  // Make sure the deriv routines do a resize !!!
250  //
251  multi1d<T> tmp2(chi.size()); // Need this for things like M chi_i
252 
253  P ds_1; // deriv routines should resize
254 
255  //
256  // NOTE: even with even-odd decomposition, the ds_u will still have contributions
257  // on all cb. So, no adding of ds_1 onto ds_u under a subset
258  //
259 
260  // ds_u -= chi^dag * D'_oe * Ainv_ee * D_eo * psi_o
261  for(int i=0; i < chi.size(); i++) {
262  T tmp1;
263  this->evenOddLinOp(tmp1, psi[i], isign);
264  this->evenEvenInvLinOp(tmp2[i], tmp1, isign);
265  }
266 
267  this->derivOddEvenLinOpMP(ds_u, chi, tmp2, isign);
268 
269 
270  // ds_u -= chi^dag * D_oe * Ainv_ee * D'_eo * psi_o
271  for(int i=0; i < chi.size(); i++) {
272  T tmp1;
273  this->evenOddLinOp(tmp1, chi[i], msign);
274  this->evenEvenInvLinOp(tmp2[i], tmp1, msign);
275  }
276 
277  this->derivEvenOddLinOpMP(ds_1, tmp2, psi, isign);
278  ds_u += ds_1;
279 
280  // This is yucky and ws should have a *= function
281  // so that I wouldn't have to expose the fact that I expect
282  // ds_u to be an Nd dimensional array
283  for(int mu=0; mu < Nd; mu++) {
284  ds_u[mu] *= Real(-1);
285  }
286 
287  getFermBC().zero(ds_u);
288  }
289 
290  };
291 
292 
293  //----------------------------------------------------------------
294  //! Even-odd preconditioned linear operator including derivatives for arrays
295  /*! @ingroup linop
296  *
297  * Support for even-odd preconditioned linear operators with derivatives
298  *
299  * Given a matrix M written in block form:
300  *
301  * [ A D ]
302  * [ E,E E,O ]
303  * [ ]
304  * [ D A ]
305  * [ O,E O,O ]
306  *
307  * The preconditioning consists of using the triangular matrices
308  *
309  * [ 1 0 ]
310  * [ E,E E,O ]
311  * L = [ ]
312  * [ D A^(-1) 1 ]
313  * [ O,E E,E O,O ]
314  *
315  * and
316  *
317  * [ A D ]
318  * [ E,E E,O ]
319  * U = [ ]
320  * [ 0 1 ]
321  * [ O,E O,O ]
322  *
323  * The preconditioned matrix is formed from
324  *
325  * M' = L^-1 * M * U^-1
326  *
327  * where
328  *
329  * [ 1 0 ]
330  * [ E,E E,O ]
331  * L^(-1) = [ ]
332  * [ - D A^(-1) 1 ]
333  * [ O,E E,E O,O ]
334  *
335  * and
336  *
337  * [ A^(-1) - A^(-1) D ]
338  * [ E,E E,E E,O ]
339  * U^(-1) = [ ]
340  * [ 0 1 ]
341  * [ O,E O,O ]
342  *
343  * Resulting in a new M
344  *
345  * [ 1 0 ]
346  * [ E,E E,O ]
347  * [ ]
348  * [ 0 A - D A^(-1) D ]
349  * [ O,E O,O O,E E,E E,O ]
350  *
351  *
352  * This class is used to implement the resulting linear operator
353  *
354  * ~
355  * M = A(o,o) - D(o,e) . A^-1(e,e) . D(e,o)
356  *
357  * By construction, the linear operator is ONLY defined on the odd subset
358  *
359  */
360 
361  template<typename T, typename P, typename Q>
363  {
364  public:
365  //! Virtual destructor to help with cleanup;
367 
368  //! Only defined on the odd lattice
369  const Subset& subset() const {return rb[1];}
370 
371  //! Expected length of array index
372  virtual int size(void) const = 0;
373 
374  //! Return the fermion BC object for this linear operator
375  virtual const FermBC<T,P,Q>& getFermBC() const = 0;
376 
377  //! Apply the operator onto a source std::vector
378  /*! User should make sure deriv routines do a resize */
379  virtual void deriv(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
380  enum PlusMinus isign) const
381  {
382  // Need deriv of (A_oo - D_oe*Ainv_ee*D_eo*psi_e)
383  enum PlusMinus msign = (isign == PLUS) ? MINUS : PLUS;
384 
385  //
386  // Make sure the deriv routines do a resize !!!
387  //
388  multi1d<T> tmp1(size()), tmp2(size()), tmp3(size()); // if an array is used here, the space is not reserved
389  moveToFastMemoryHint(tmp1);
390  moveToFastMemoryHint(tmp2);
391  // moveToFastMemoryHint(tmp3);
392 
393  P ds_1; // deriv routines should resize
394 
395  //
396  // NOTE: even with even-odd decomposition, the ds_u will still have contributions
397  // on all cb. So, no adding of ds_1 onto ds_u under a subset
398  //
399  // ds_u = chi^dag * A'_oo * psi
400  // derivOddOddLinOp(ds_u, chi, psi, isign);
401 
402 
403 
404 
405  // ds_u -= chi^dag * D'_oe * Ainv_ee * D_eo * psi_o
406  this->evenOddLinOp(tmp1, psi, isign);
407  this->evenEvenInvLinOp(tmp2, tmp1, isign);
408  this->derivOddEvenLinOp(ds_u, chi, tmp2, isign);
409 
410  // ds_u -= chi^dag * D_oe * Ainv_ee * D'_eo * psi_o
411  this->evenOddLinOp(tmp1, chi, msign);
412  this->evenEvenInvLinOp(tmp2, tmp1, msign);
413  this->derivEvenOddLinOp(ds_1, tmp2, psi, isign);
414  ds_u += ds_1;
415 
416  // This is yucky and ws should have a *= function
417  // so that I wouldn't have to expose the fact that I expect
418  // ds_u to be an Nd dimensional array
419  for(int mu=0; mu < Nd; mu++) {
420  ds_u[mu] *= Real(-1);
421  }
422 
423  getFermBC().zero(ds_u);
424  }
425 
426  //! Apply the even-even block onto a source std::vector
427  virtual void derivEvenEvenLinOp(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
428  enum PlusMinus isign) const
429  {
430  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
431  QDP_abort(1);
432  }
433 
434  //! Apply the the even-odd block onto a source std::vector
435  virtual void derivEvenOddLinOp(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
436  enum PlusMinus isign) const
437  {
438  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
439  QDP_abort(1);
440  }
441 
442  //! Apply the the odd-even block onto a source std::vector
443  virtual void derivOddEvenLinOp(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
444  enum PlusMinus isign) const
445  {
446  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
447  QDP_abort(1);
448  }
449 
450  //! Apply the the odd-odd block onto a source std::vector
451  virtual void derivOddOddLinOp(P& ds_u, const multi1d<T>& chi, const multi1d<T>& psi,
452  enum PlusMinus isign) const
453  {
454  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
455  QDP_abort(1);
456  }
457  };
458 
459 
460 
461 
462 }
463 #endif
Even-odd preconditioned linear operator including derivatives for arrays.
virtual void deriv(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
Apply the operator onto a source std::vector.
const Subset & subset() const
Only defined on the odd lattice.
virtual void derivOddOddLinOp(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
Apply the the odd-odd block onto a source std::vector.
virtual void derivEvenEvenLinOp(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
Apply the even-even block onto a source std::vector.
virtual int size(void) const =0
Expected length of array index.
virtual void derivOddEvenLinOp(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
Apply the the odd-even block onto a source std::vector.
virtual ~EvenOddPrecConstDetLinearOperatorArray()
Virtual destructor to help with cleanup;.
virtual const FermBC< T, P, Q > & getFermBC() const =0
Return the fermion BC object for this linear operator.
virtual void derivEvenOddLinOp(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
Apply the the even-odd block onto a source std::vector.
Even-odd preconditioned linear operator.
virtual void derivEvenOddLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the the even-odd block onto a source std::vector.
virtual void derivEvenOddLinOpMP(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
virtual ~EvenOddPrecConstDetLinearOperator()
Virtual destructor to help with cleanup;.
virtual void derivOddEvenLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the the odd-even block onto a source std::vector.
virtual void derivOddEvenLinOpMP(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
virtual void derivEvenEvenLinOpMP(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
virtual void derivEvenEvenLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the even-even block onto a source std::vector.
virtual const FermBC< T, P, Q > & getFermBC() const =0
Return the fermion BC object for this linear operator.
virtual void derivOddOddLinOpMP(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
virtual void derivOddOddLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the the odd-odd block onto a source std::vector.
virtual void derivMultipole(P &ds_u, const multi1d< T > &chi, const multi1d< T > &psi, enum PlusMinus isign) const
Apply the derivative of the operator onto a source std::vector.
virtual void deriv(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the derivative of the operator onto a source std::vector.
Even-odd preconditioned linear operator including derivatives for arrays.
Definition: eoprec_linop.h:312
Even-odd preconditioned linear operator.
Definition: eoprec_linop.h:92
Base class for all fermion action boundary conditions.
Definition: fermbc.h:20
int mu
Definition: cool.cc:24
Base class for even-odd preconditioned 4D and 5D Linop.
unsigned i
Definition: ldumul_w.cc:34
Nd
Definition: meslate.cc:74
Double tmp2
Definition: mesq.cc:30
Double tmp3
Definition: mesq.cc:31
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
LinOpSysSolverMGProtoClover::T T
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
Double zero
Definition: invbicg.cc:106
chi
Definition: pade_trln_w.cc:24
psi
Definition: pade_trln_w.cc:191
multi1d< LatticeColorMatrix > P
Definition: t_clover.cc:13