CHROMA
tprec_logdet_linop.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! @file
3  * @brief Time-preconditioned Linear Operators
4  */
5 
6 #ifndef __tprec_logdet_linop_h__
7 #define __tprec_logdet_linop_h__
8 
9 #include "tprec_linop.h"
10 
11 namespace Chroma
12 {
13 
14  //-----------------------------------------------------------------------------------
15  //! Time preconditioned linear operator
16  /*! @ingroup linop
17  *
18  * Support for time preconditioned linear operators
19  * Given a matrix M written in block form:
20  *
21  * M = D_t + D_s
22  *
23  * The preconditioning consists of multiplying by the inverse
24  * of the time operator
25  *
26  * This class is used to implement the resulting linear operator
27  *
28  * M' = 1 + D_t^(-1)*D_s
29  *
30  * M'^dag = 1 + D_s^dag * (D_t^(-1))^dag
31  *
32  * The non-symmetrical nature of the daggered version means the two
33  * cases (no-dagger and dagger) must be handled separately. This is
34  * in contrast to the standard (4D) even-odd precond. case where the
35  * the daggered version has the same structure, except the dagger
36  * is pushed down into the individual pieces.
37  *
38  * Here we assume D_t does depend on the gauge fields, and that we can
39  * exactly simulate the determinant without pseudofermion fields.
40  * We know det D_t and can write it in the action as
41  * exp( log det D_t ) = exp( Tr Ln D_t )
42  *
43  * Since we can explicitly evaluate Tr Ln D_t for the action, we
44  * can also evaluate the force contribution
45  *
46  * d/dt ( Tr Ln D_t ) = Tr ( (d/dt)D_t D_t^{-1} )
47  *
48  * and d/dt ( D_t^{-1} ) = D_t^{-1} [ (d/dt)D_t ] D_t^{-1}
49  *
50  * hence we have functions logDetTimeLinOp()
51  * and derivTimeLinOp()
52  * and derivLogDetTimeLinOp()
53  */
54 
55  template<typename T, typename P, typename Q>
57  {
58  public:
59  //! Virtual destructor to help with cleanup;
61 
62  //! Defined on the entire lattice
63  const Subset& subset() const {return all;}
64 
65  //! Return the fermion BC object for this linear operator
66  virtual const FermBC<T,P,Q>& getFermBC() const = 0;
67 
68  //! The time direction
69  int tDir() const = 0;
70 
71  //! Apply the time block onto a source std::vector
72  /*! This does not need to be optimized */
73  virtual void timeLinOp(T& chi, const T& psi,
74  enum PlusMinus isign) const = 0;
75 
76  //! Apply the inverse of the time block onto a source std::vector
77  virtual void timeInvLinOp(T& chi, const T& psi,
78  enum PlusMinus isign) const = 0;
79 
80  //! Apply the the space block onto a source std::vector
81  virtual void spaceLinOp(T& chi, const T& psi,
82  enum PlusMinus isign) const = 0;
83 
84  //! Apply the even-even block onto a source std::vector
85  virtual void derivTimeLinOp(P& ds_u, const T& chi, const T& psi,
86  enum PlusMinus isign) const
87  {
88  QDPIO::cerr << "derivTime: not implemented" << std::endl;
89  QDP_abort(1);
90  }
91 
92  //! Apply the space block onto a source std::vector
93  virtual void derivSpaceLinOp(P& ds_u, const T& chi, const T& psi,
94  enum PlusMinus isign) const
95  {
96  QDPIO::cerr << "derivSpace: not implemented" << std::endl;
97  QDP_abort(1);
98  }
99 
100  //! Apply the derivative of the operator onto a source std::vector
101  /*! User should make sure deriv routines do a resize */
102  virtual void deriv(P& ds_u, const T& chi, const T& psi,
103  enum PlusMinus isign) const
104  {
105  // Need deriv of chi^dag*[psi + D_t^(-1)*D_s*psi]
106  enum PlusMinus msign = (isign == PLUS) ? MINUS : PLUS;
107 
108  //
109  // Make sure the deriv routines do a resize !!!
110  //
111  T tmp1, tmp2, tmp3; moveToFastMemoryHint(tmp1); moveToFastMemoryHint(tmp2);
112  P ds_1; moveToFastMemoryHint(ds_1);
113 
114  switch (isign)
115  {
116  case PLUS:
117  // ds_u = chi^dag * D_t^(-1) * D'_s * psi
118  timeInvLinOp(tmp1, chi, msign);
119  derivSpaceLinOp(ds_u, tmp1, psi, isign);
120 
121  // ds_u -= chi^dag * D_t^(-1) * D'_t * D_t^(-1) * D_s * psi
124  derivTimeLinOp(ds_1, tmp1, tmp3, isign);
125  ds_u -= ds_1;
126  break;
127 
128  case MINUS:
129  // ds_u = chi^dag * D'_s^dag * D_t^(-1)^dag * psi
130  timeInvLinOp(tmp1, psi, isign);
131  derivSpaceLinOp(ds_u, chi, tmp1, isign);
132 
133  // ds_u -= chi^dag * D_s^dag * D_t^(-1)^dag * D'_t^dag * D_t^(-1)^dag * psi
134  spaceLinOp(tmp2, chi, msign);
135  timeInvLinOp(tmp3, tmp2, msign);
136  derivTimeLinOp(ds_1, tmp3, tmp1, isign);
137  ds_u -= ds_1;
138  break;
139 
140  default:
141  QDPIO::cerr << "unknown sign" << std::endl;
142  QDP_abort(1);
143  }
144  }
145 
146  //! Apply the derivative of the UNPRECONDITIONED operator onto a source std::vector
147  /*! Mainly intended for debugging */
148  virtual void derivUnprecLinOp(P& ds_u, const T& chi, const T& psi,
149  enum PlusMinus isign) const
150  {
151  P ds_tmp; // deriv routines should resize
152 
153  // ds_u = chi^dag * D'_t*psi + chi^dag * D'_s * psi
154 
155  // ds_u = chi^dag * D'_t * psi
156  derivTimeLinOp(ds_u, chi, psi, isign);
157 
158  // ds_u += chi^dag * D'_s * psi
159  derivSpaceLinOp(ds_tmp, chi, psi, isign);
160  ds_u += ds_tmp;
161  }
162 
163  //! Get the force from the Time Trace Log
164  virtual void derivLogDetTimeLinOp(P& ds_u, enum PlusMinus isign) const
165  {
166  QDPIO::cerr << "EvenOdd: not implemented" << std::endl;
167  QDP_abort(1);
168  }
169 
170  //! Get the log det of the even even part
171  virtual Double logDetTimeLinOp(void) const = 0;
172  };
173 
174 }
175 
176 #endif
Base class for all fermion action boundary conditions.
Definition: fermbc.h:20
Time preconditioned linear operator.
Definition: tprec_linop.h:41
Time preconditioned linear operator.
virtual void derivTimeLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the even-even block onto a source std::vector.
virtual void timeLinOp(T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the time block onto a source std::vector.
virtual const FermBC< T, P, Q > & getFermBC() const =0
Return the fermion BC object for this linear operator.
const Subset & subset() const
Defined on the entire lattice.
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.
virtual void timeInvLinOp(T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the inverse of the time block onto a source std::vector.
virtual void derivLogDetTimeLinOp(P &ds_u, enum PlusMinus isign) const
Get the force from the Time Trace Log.
virtual void derivSpaceLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the space block onto a source std::vector.
virtual void derivUnprecLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const
Apply the derivative of the UNPRECONDITIONED operator onto a source std::vector.
int tDir() const =0
The time direction.
virtual void spaceLinOp(T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the the space block onto a source std::vector.
virtual ~TimePrecLogDetLinearOperator()
Virtual destructor to help with cleanup;.
virtual Double logDetTimeLinOp(void) const =0
Get the log det of the even even part.
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
multi1d< LatticeFermion > chi(Ncb)
LatticeFermion psi
Definition: mespbg5p_w.cc:35
FloatingPoint< double > Double
Definition: gtest.h:7351
multi1d< LatticeColorMatrix > P
Definition: t_clover.cc:13
Time-preconditioned Linear Operators.