CHROMA
seoprec_logdet_linop.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! @file
3  * @brief Symmetric preconditioned linear pperators where the even-even and odd-odd parts depends on the gauge field.
4  *
5  * We assume we can evaluate Log Det E and Log Det O, where E/E is the (Even Even)[Odd Odd] part.
6  * Essentially this is for things like clover.
7  */
8 
9 #ifndef __seoprec_logdet_linop_h__
10 #define __seoprec_logdet_linop_h__
11 
12 #include "seoprec_constdet_linop.h"
13 
14 using namespace QDP::Hints;
15 
16 namespace Chroma
17 {
18 
19 //----------------------------------------------------------------
20 //! Even-odd preconditioned linear operator
21 /*! @ingroup linop
22  *
23  * Support for even-odd preconditioned linear operators
24  * Given a matrix M written in block form:
25  *
26  * [ A D ]
27  * [ E,E E,O ]
28  * [ ]
29  * [ D A ]
30  * [ O,E O,O ]
31  *
32  * The preconditioning consists of factorizing as
33  *
34  *
35  * M_unprec = M_diag x M'
36  *
37  *
38  * M_diag = [ A_E,E 0 ]
39  * [ 0 A_O,O ]
40  *
41  * [ 1 M_E,O ]
42  * M' = [ ]
43  * [ M_O,E 1 ]
44  *
45  *
46  * M_E,O = A^{-1}_E,E D_E,O
47  * M_O,E = A^{-1}_O,O D_E,O
48  *
49  * We then do a schur precondition of M'
50  *
51  * as M' = L M R
52  *
53  *
54  * L = [ 1 0 ]
55  * [ ]
56  * [ M_O,E 1 ]
57  *
58  *
59  *
60  * R = [ 1 M_E,O ]
61  * [ ]
62  * [ 0 1 ]
63  *
64  *
65  * M = [ 1 0 ]
66  * [ ]
67  * [ 0 S ]
68  *
69  * where S = 1 - ( M_O,E )( M_E,O )
70  *
71  *
72  * L^{-1} = [ 1 0 ]
73  * [ ]
74  * [- M_O,E 1 ]
75  *
76  *
77  *
78  * R^{-1} = [ 1 - M_E,O ]
79  * [ ]
80  * [ 0 1 ]
81  *
82  *
83  *
84  * For props we need to solve:
85  *
86  * M x' = L^{-1} (M_diag)^{-1} b
87  *
88  * and then x = R^{-1} x' (backsubstitution)
89  *
90  * for HMC we have det(L)=1 det(R)=1
91  * det(M_diag) is handled by TraceLog/LogDet calls to clover
92  * and we pseudofermionize only the 'S' operators
93  *
94  *
95  * Structure: capture D_oe, D_eo, A_ee, A_oo, A^{-1}_oo and A^{-1}_ee
96  * as
97  * unprecEvenOddLinOp
98  * unprecOddEvenLinOp
99  * unprecEvenEvenLinOp
100  * unprecOddOddLinOp
101  * unprecOddOddInvLinOp
102  * unprecEvenEvenInvLinOp
103  *
104  * then we can write category defaults for:
105  *
106  * then
107  * evenOddLinOp is M_eo = A^{-1}_ee D_eo or h.c.
108  * oddEvenLinOp is M_oe = A^{-1}_oo D_oe or h.c.
109  *
110  * the so called Jacobi Operator:
111  * [ 1 M_eo ]
112  * [ M_oe 1 ]
113  *
114  * the Schur Operator: S = 1 - M_oe M_eo
115  *
116  * the Unprec Operator: diag( A_ee A_oo ) M_jacobi
117  *
118  * We can also write category default for the forces in terms
119  * of
120  * derivEvenOddLinOp
121  * and derivOddEvenLinOp
122  *
123  * Const-detness or log-det ness will depend on how the
124  * derivEvenOdd and derivOddEven operators are coded
125 
126  *
127  */
128 
129 
130  // Inherit from ConstDet and extend structure -- Then in Monomials we can pass this as a constdet
131  template<typename T, typename P, typename Q>
133  {
134  public:
135  //! Virtual destructor to help with cleanup;
137 
138  //! Only defined on the odd lattice
139  const Subset& subset() const {return rb[1];}
140 
141  //! Return the fermion BC object for this linear operator
142  virtual const FermBC<T,P,Q>& getFermBC() const = 0;
143 
144  //! Apply the even-even block onto a source std::vector
145  /*! This does not need to be optimized */
146  virtual void unprecEvenEvenLinOp(T& chi, const T& psi,
147  enum PlusMinus isign) const override = 0;
148 
149  //! Apply the inverse of the even-even block onto a source std::vector
150  virtual void unprecEvenEvenInvLinOp(T& chi, const T& psi,
151  enum PlusMinus isign) const override = 0;
152 
153  //! Apply the the odd-odd block onto a source std::vector
154  virtual void unprecOddOddLinOp(T& chi, const T& psi,
155  enum PlusMinus isign) const override = 0;
156 
157  //! Apply the inverse of the odd-odd block onto a source std::vector
158  virtual void unprecOddOddInvLinOp(T& chi, const T& psi,
159  enum PlusMinus isign) const override = 0;
160 
161  //! Apply the the even-odd block onto a source std::vector
162  virtual void unprecEvenOddLinOp(T& chi, const T& psi,
163  enum PlusMinus isign) const override = 0;
164 
165  //! Apply the the odd-even block onto a source std::vector
166  virtual void unprecOddEvenLinOp(T& chi, const T& psi,
167  enum PlusMinus isign) const override = 0;
168 
169  // Deriv of A_ee
170  virtual void derivUnprecEvenEvenLinOp(P& ds_u, const T& chi, const T& psi,
171  enum PlusMinus isign) const = 0;
172 
173  // Deriv of A_oo
174  virtual void derivUnprecOddOddLinOp(P& ds_u, const T& chi, const T& psi,
175  enum PlusMinus isign) const = 0;
176 
177  // Deriv of D_eo
178  virtual void derivUnprecEvenOddLinOp(P& ds_u, const T& chi, const T& psi,
179  enum PlusMinus isign) const override = 0;
180 
181  // Deriv of D_eo
182  virtual void derivUnprecOddEvenLinOp(P& ds_u, const T& chi, const T& psi,
183  enum PlusMinus isign) const override = 0;
184 
185  //! deriv of A^{-1} = - A^{-1} deriv(A) A^{-1}
186  virtual void derivUnprecEvenEvenInvLinOp(P& ds_u, const T& chi, const T& psi,
187  enum PlusMinus isign) const
188  {
189  enum PlusMinus msign = ( isign == PLUS ) ? MINUS : PLUS;
190  T Achi = zero;
191  T Apsi = zero;
192  unprecEvenEvenInvLinOp(Achi,chi, msign);
193  unprecEvenEvenInvLinOp(Apsi,psi, isign);
194  derivUnprecEvenEvenLinOp(ds_u, Achi,Apsi, isign);
195  for(int mu=0; mu < Nd; ++mu) {
196  ds_u[mu] *= Real(-1);
197  }
198  getFermBC().zero(ds_u);
199 
200  }
201 
202  //! deriv of A^{-1} = - A^{-1} deriv(A) A^{-1}
203  virtual void derivUnprecOddOddInvLinOp(P& ds_u, const T& chi, const T& psi,
204  enum PlusMinus isign) const
205  {
206  enum PlusMinus msign = ( isign == PLUS ) ? MINUS : PLUS;
207  T Achi = zero;
208  T Apsi = zero;
209  unprecOddOddInvLinOp(Achi,chi, msign);
210  unprecOddOddInvLinOp(Apsi,psi, isign);
211  derivUnprecOddOddLinOp(ds_u, Achi,Apsi, isign);
212  for(int mu=0; mu < Nd; ++mu) ds_u[mu] *= Real(-1);
213  getFermBC().zero(ds_u);
214 
215  }
216 
217  //! Apply the the even-odd block onto a source std::vector
218  //
219  // Connect chi_even through a derivative with psi_odd
220  virtual void derivEvenOddLinOp(P& ds_u, const T& chi, const T& psi,
221  enum PlusMinus isign) const override
222  {
223  T tmp; moveToFastMemoryHint(tmp);
224 
225  P ds_tmp;
226  if( isign == PLUS ) {
227  unprecEvenOddLinOp(tmp,psi, PLUS);
228  derivUnprecEvenEvenInvLinOp(ds_u, chi, tmp, PLUS);
229 
230  unprecEvenEvenInvLinOp(tmp, chi, MINUS);
231  derivUnprecEvenOddLinOp(ds_tmp, tmp,psi, PLUS);
232  ds_u += ds_tmp;
233  }
234  else {
235  // W_o = A^{-dag}_oo Y_o
236  unprecOddOddInvLinOp(tmp, psi, MINUS);
237  // X_e^\dagger d [ D^\dagger ]_eo W_o
238  derivUnprecEvenOddLinOp(ds_u, chi, tmp, MINUS);
239 
240  unprecOddEvenLinOp(tmp,chi,PLUS);
241  derivUnprecOddOddInvLinOp(ds_tmp, tmp,psi, MINUS);
242  ds_u += ds_tmp;
243  }
244  getFermBC().zero(ds_u);
245 
246  }
247 
248  //! Apply the the odd-even block onto a source std::vector
249  //
250  // Connect chi_odd with psi_even
251  virtual void derivOddEvenLinOp(P& ds_u, const T& chi, const T& psi,
252  enum PlusMinus isign) const override
253  {
254  T tmp; moveToFastMemoryHint(tmp);
255 
256  P ds_tmp;
257  if( isign == PLUS ) {
258  unprecOddEvenLinOp(tmp,psi, PLUS);
259  derivUnprecOddOddInvLinOp(ds_u, chi, tmp, PLUS);
260 
261  unprecOddOddInvLinOp(tmp, chi, MINUS);
262  derivUnprecOddEvenLinOp(ds_tmp, tmp,psi, PLUS);
263  ds_u += ds_tmp;
264  }
265  else {
266  unprecEvenEvenInvLinOp(tmp, psi, MINUS);
267  derivUnprecOddEvenLinOp(ds_u, chi, tmp, MINUS);
268 
269  unprecEvenOddLinOp(tmp,chi,PLUS);
270  derivUnprecEvenEvenInvLinOp(ds_tmp, tmp,psi, MINUS);
271  ds_u += ds_tmp;
272  }
273  getFermBC().zero(ds_u);
274 
275  }
276 
277 
278  //! Get the force from the EvenEven Trace Log
279  virtual void derivLogDetEvenEvenLinOp(P& ds_u, enum PlusMinus isign) const = 0;
280 
281  //! Get the log det of the even even part
282  virtual Double logDetEvenEvenLinOp(void) const = 0;
283 
284  //! Get the force from the OddOdd Trace Log
285  virtual void derivLogDetOddOddLinOp(P& ds_u, enum PlusMinus isign) const = 0;
286 
287  //! Get the log det of the odd odd part
288  virtual Double logDetOddOddLinOp(void) const = 0;
289  };
290 
291 
292 }
293 #endif
Base class for all fermion action boundary conditions.
Definition: fermbc.h:20
Even-odd preconditioned linear operator.
Even-odd preconditioned linear operator.
virtual const FermBC< T, P, Q > & getFermBC() const =0
Return the fermion BC object for this linear operator.
virtual void unprecEvenEvenInvLinOp(T &chi, const T &psi, enum PlusMinus isign) const override=0
Apply the inverse of the even-even block onto a source std::vector.
virtual void derivUnprecOddOddLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const =0
const Subset & subset() const
Only defined on the odd lattice.
virtual void derivUnprecEvenOddLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const override=0
virtual void unprecEvenEvenLinOp(T &chi, const T &psi, enum PlusMinus isign) const override=0
Apply the even-even block onto a source std::vector.
virtual void unprecOddOddInvLinOp(T &chi, const T &psi, enum PlusMinus isign) const override=0
Apply the inverse of the odd-odd block onto a source std::vector.
virtual void unprecEvenOddLinOp(T &chi, const T &psi, enum PlusMinus isign) const override=0
Apply the the even-odd block onto a source std::vector.
virtual Double logDetOddOddLinOp(void) const =0
Get the log det of the odd odd part.
virtual ~SymEvenOddPrecLogDetLinearOperator()
Virtual destructor to help with cleanup;.
virtual void derivUnprecEvenEvenLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const =0
virtual void derivUnprecEvenEvenInvLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
deriv of A^{-1} = - A^{-1} deriv(A) A^{-1}
virtual void derivEvenOddLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const override
Apply the the even-odd block onto a source std::vector.
virtual void derivUnprecOddEvenLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const override=0
virtual Double logDetEvenEvenLinOp(void) const =0
Get the log det of the even even part.
virtual void unprecOddOddLinOp(T &chi, const T &psi, enum PlusMinus isign) const override=0
Apply the the odd-odd block onto a source std::vector.
virtual void derivUnprecOddOddInvLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
deriv of A^{-1} = - A^{-1} deriv(A) A^{-1}
virtual void derivLogDetEvenEvenLinOp(P &ds_u, enum PlusMinus isign) const =0
Get the force from the EvenEven Trace Log.
virtual void derivOddEvenLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const override
Apply the the odd-even block onto a source std::vector.
virtual void derivLogDetOddOddLinOp(P &ds_u, enum PlusMinus isign) const =0
Get the force from the OddOdd Trace Log.
virtual void unprecOddEvenLinOp(T &chi, const T &psi, enum PlusMinus isign) const override=0
Apply the the odd-even block onto a source std::vector.
int mu
Definition: cool.cc:24
Double tmp
Definition: meslate.cc:60
Nd
Definition: meslate.cc:74
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
FloatingPoint< double > Double
Definition: gtest.h:7351
chi
Definition: pade_trln_w.cc:24
psi
Definition: pade_trln_w.cc:191
Preconditioned 4D Linop with Gauge Independent Even-Even part.
multi1d< LatticeColorMatrix > P
Definition: t_clover.cc:13