CHROMA
teoprec_linop.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! @file
3  * @brief Even-odd Time-preconditioned Linear Operators
4  */
5 
6 #ifndef __teoprec_linop_h__
7 #define __teoprec_linop_h__
8 
9 #include "linearop.h"
10 
11 namespace Chroma
12 {
13 
14  //-----------------------------------------------------------------------------------
15  //! Even-odd and time preconditioned linear operator
16  /*! @ingroup linop
17  *
18  * Given a matrix M written in separate time and space operators
19  *
20  * M = D_t + D_s
21  *
22  * The time preconditioning consists of multiplying by the inverse
23  * of the time operator to give
24  *
25  * M' = 1 + D_t^(-1)*D_s
26  *
27  * For spatial even-odd precond., this interface requires the D_t to
28  * be diagonal in spatial components - have no space-space or space-time
29  * components. Hence, this means no even-odd component.
30  * Also, the D_s must no time coupling, and no even-even or odd-odd
31  * component - e.g. all diagonal terms have been pushed into D_t.
32  *
33  * Rewrite M' into block form:
34  *
35  * [ A D ]
36  * [ E,E E,O ]
37  * M' = [ ]
38  * [ D A ]
39  * [ O,E O,O ]
40  *
41  * where the E,O refer to only the spatial dimensions and
42  *
43  * A(e,e) = 1 + D_t^(-1)(e,e) * D_s(e,e) -> 1 # D_s(e,e)=0
44  * D(e,o) = D_t^(-1)(e,e) * D_s(e,o) # is a matrix in time-time
45  * D(o,e) = D_t^(-1)(o,o) * D_s(o,e) # is a matrix in time-time
46  * A(o,o) = 1 + D_t^(-1)(o,o) * D_s(o,o) -> 1 # D_s(o,o)=0
47  *
48  * A(e,e)^(-1) = <diagonal in space, matrix in time-time components>
49  *
50  * Spatial even-odd preconditioning consists of using the triangular matrices
51  *
52  * [ 1 0 ]
53  * [ E,E E,O ]
54  * L = [ ]
55  * [ D A^(-1) 1 ]
56  * [ O,E E,E O,O ]
57  *
58  * and
59  *
60  * [ A D ]
61  * [ E,E E,O ]
62  * U = [ ]
63  * [ 0 1 ]
64  * [ O,E O,O ]
65  *
66  * The preconditioned matrix is formed from
67  *
68  * ~
69  * M = L^-1 * M' * U^-1
70  *
71  * where
72  *
73  * [ 1 0 ]
74  * [ E,E E,O ]
75  * L^(-1) = [ ]
76  * [ - D A^(-1) 1 ]
77  * [ O,E E,E O,O ]
78  *
79  * and
80  *
81  * [ A^(-1) - A^(-1) D ]
82  * [ E,E E,E E,O ]
83  * U^(-1) = [ ]
84  * [ 0 1 ]
85  * [ O,E O,O ]
86  *
87  * Resulting in a new M
88  *
89  * [ 1 0 ]
90  * ~ [ E,E E,O ]
91  * M = [ ]
92  * [ 0 A - D A^(-1) D ]
93  * [ O,E O,O O,E E,E E,O ]
94  *
95  *
96  * This class is used to implement the resulting linear operator
97  *
98  * ~
99  * M = A(o,o) - D(o,e) * A^-1(e,e) * D(e,o)
100  * = 1 - D_t^(-1)(o,o) * D_s(o,e) * D_t^(-1)(e,e) * D_s(e,o)
101  *
102  * ~
103  * M^dag = 1 - D_s(o,e)^dag * D_t^(-1)(e,e)^dag * D_s(e,o)^dag * D_t^(-1)(o,o)^dag
104  *
105  * By construction, the linear operator is ONLY defined on the odd subset
106  *
107  * The non-symmetrical nature of the daggered version means the two
108  * cases (no-dagger and dagger) must be handled separately. This is
109  * in contrast to the standard (4D) even-odd precond. case where the
110  * the daggered version has the same structure, except the dagger
111  * is pushed down into the individual pieces.
112  */
113 
114  template<typename T, typename P, typename Q>
116  {
117  public:
118  //! Virtual destructor to help with cleanup;
120 
121  //! Only defined on the odd lattice
122  const Subset& subset() const {return rb[1];} // not correct, need space-rb
123 
124  //! Apply the even-even block onto a source std::vector
125  /*! This does not need to be optimized */
126  virtual void evenEvenTimeLinOp(T& chi, const T& psi,
127  enum PlusMinus isign) const = 0;
128 
129  //! Apply the inverse of the even-even block onto a source std::vector
130  virtual void evenEvenTimeInvLinOp(T& chi, const T& psi,
131  enum PlusMinus isign) const = 0;
132 
133  //! Apply the the even-odd block onto a source std::vector
134  virtual void evenOddSpaceLinOp(T& chi, const T& psi,
135  enum PlusMinus isign) const = 0;
136 
137  //! Apply the the odd-even block onto a source std::vector
138  virtual void oddEvenSpaceLinOp(T& chi, const T& psi,
139  enum PlusMinus isign) const = 0;
140 
141  //! Apply the the odd-odd block onto a source std::vector
142  virtual void oddOddTimeLinOp(T& chi, const T& psi,
143  enum PlusMinus isign) const = 0;
144 
145  //! Apply the operator onto a source std::vector
146  virtual void operator() (T& chi, const T& psi,
147  enum PlusMinus isign) const
148  {
149  T tmp1, tmp2; moveToFastMemoryHint(tmp1); moveToFastMemoryHint(tmp2);
150 
151  switch (isign)
152  {
153  case PLUS:
154  // chi = psi - D_t^(-1)(o,o)*D_s(o,e)*D_t^(-1)(e,e)*D_s(e,o)*psi
155  evenOddSpaceLinOp(tmp1, psi, isign);
157  OddEvenSpaceLinOp(tmp1, tmp2, isign);
158  oddOddTimeInvLinOp(tmp2, tmp1, isign);
159  chi[rb[1]] = psi - tmp2;
160  break;
161 
162  case MINUS:
163  // chi = psi - D_s(o,e)^dag * D_t^(-1)(e,e)^dag * D_s(e,o)^dag * D_t^(-1)(o,o)^dag*psi
164  oddOddTimeInvLinOp(tmp1, psi, isign);
165  evenOddSpaceLinOp(tmp2, tmp1, isign);
167  OddEvenSpaceLinOp(tmp2, tmp1, isign);
168  chi[rb[1]] = psi - tmp2;
169  break;
170 
171  default:
172  QDPIO::cerr << "unknown sign" << std::endl;
173  QDP_abort(1);
174  }
175  }
176 
177  //! Apply the UNPRECONDITIONED operator onto a source std::vector
178  /*! Mainly intended for debugging */
179  virtual void unprecLinOp(T& chi, const T& psi,
180  enum PlusMinus isign) const
181  {
182  T tmp1, tmp2; moveToFastMemoryHint(tmp1); moveToFastMemoryHint(tmp2);
183 
184  // chi = D_t*psi + D_s*psi
185  evenEvenTimeLinOp(tmp1, psi, isign);
187  chi[rb[0]] = tmp1 + tmp2;
188 
189  oddOddTimeLinOp(tmp1, psi, isign);
191  chi[rb[1]] = tmp1 + tmp2;
192  }
193 
194  //! Apply the even-even block onto a source std::vector
195  virtual void derivEvenEvenTimeLinOp(P& ds_u, const T& chi, const T& psi,
196  enum PlusMinus isign) const = 0;
197 
198  //! Apply the the even-odd block onto a source std::vector
199  virtual void derivEvenOddSpaceLinOp(P& ds_u, const T& chi, const T& psi,
200  enum PlusMinus isign) const = 0;
201 
202  //! Apply the the odd-even block onto a source std::vector
203  virtual void derivOddEvenSpaceLinOp(P& ds_u, const T& chi, const T& psi,
204  enum PlusMinus isign) const = 0;
205 
206  //! Apply the the odd-odd block onto a source std::vector
207  virtual void derivOddOddTimeLinOp(P& ds_u, const T& chi, const T& psi,
208  enum PlusMinus isign) const = 0;
209 
210  //! Apply the derivative of the operator onto a source std::vector
211  /*! User should make sure deriv routines do a resize */
212  virtual void deriv(P& ds_u, const T& chi, const T& psi,
213  enum PlusMinus isign) const = 0;
214 
215  //! Apply the derivative of the UNPRECONDITIONED operator onto a source std::vector
216  /*! Mainly intended for debugging */
217  virtual void derivUnprecLinOp(P& ds_u, const T& chi, const T& psi,
218  enum PlusMinus isign) const
219  {
220  T tmp1, tmp2; moveToFastMemoryHint(tmp1); moveToFastMemoryHint(tmp2);
221  P ds_tmp; moveToFastMemoryHint(ds_tmp);
222 
223  // chi = D_t*psi + D_s*psi
224 
225  // ds_u = chi^dag * (D_t)'_ee * psi
227 
228  // ds_u += chi^dag * (D_s)'_eo * psi
229  derivEvenOddSpaceLinOp(ds_tmp, chi, psi, isign);
230  ds_u += ds_tmp;
231 
232  // ds_u += chi^dag * (D_t)'_oo * psi
233  derivOddOddTimeLinOp(ds_tmp, chi, psi, isign);
234  ds_u += ds_tmp;
235 
236  // ds_u += chi^dag * (D_s)'_oe * psi
237  derivOddEvenSpaceLinOp(ds_tmp, chi, psi, isign);
238  ds_u += ds_tmp;
239  }
240 
241  };
242 
243 
244 }
245 
246 
247 
248 #endif
Differentiable Linear Operator.
Definition: linearop.h:98
Even-odd and time preconditioned linear operator.
virtual void oddOddTimeLinOp(T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the the odd-odd block onto a source std::vector.
virtual void evenOddSpaceLinOp(T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the the even-odd block onto a source std::vector.
virtual void unprecLinOp(T &chi, const T &psi, enum PlusMinus isign) const
Apply the UNPRECONDITIONED operator 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.
virtual void evenEvenTimeLinOp(T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the even-even block onto a source std::vector.
virtual void derivOddEvenSpaceLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the the odd-even block onto a source std::vector.
virtual void derivEvenEvenTimeLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the even-even block onto a source std::vector.
virtual void deriv(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the derivative of the operator onto a source std::vector.
virtual void oddEvenSpaceLinOp(T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the the odd-even block onto a source std::vector.
const Subset & subset() const
Only defined on the odd lattice.
virtual ~EvenOddTimePrecLinearOperator()
Virtual destructor to help with cleanup;.
virtual void operator()(T &chi, const T &psi, enum PlusMinus isign) const
Apply the operator onto a source std::vector.
virtual void evenEvenTimeInvLinOp(T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the inverse of the even-even block onto a source std::vector.
virtual void derivOddOddTimeLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the the odd-odd block onto a source std::vector.
virtual void derivEvenOddSpaceLinOp(P &ds_u, const T &chi, const T &psi, enum PlusMinus isign) const =0
Apply the the even-odd block onto a source std::vector.
Linear Operators.
Double tmp2
Definition: mesq.cc:30
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
multi1d< LatticeColorMatrix > P
Definition: t_clover.cc:13