HILA
Loading...
Searching...
No Matches
wilson.h
1#ifndef __DIRAC_WILSON_H__
2#define __DIRAC_WILSON_H__
3
4#include "plumbing/defs.h"
5#include "datatypes/cmplx.h"
6#include "datatypes/matrix.h"
7#include "datatypes/wilson_vector.h"
8#include "plumbing/field.h"
9#include "hmc/gauge_field.h"
10
11template <int N, typename radix>
12Field<half_Wilson_vector<N, radix>> wilson_dirac_temp_vector[2 * NDIM];
13
14/// Apply the hopping term to v_out and add to v_in
15template <int N, typename radix, typename matrix>
16inline void Dirac_Wilson_hop(const Field<matrix> *gauge, const double kappa,
17 const Field<Wilson_vector<N, radix>> &v_in,
18 Field<Wilson_vector<N, radix>> &v_out, Parity par,
19 int sign) {
20 Field<half_Wilson_vector<N, radix>>(&vtemp)[2 * NDIM] =
21 wilson_dirac_temp_vector<N, radix>;
22 for (int dir = 0; dir < 2 * NDIM; dir++) {
23 vtemp[dir].copy_boundary_condition(v_in);
24 }
25
26 // Run neighbour gathers and multiplications
27 foralldir(dir) {
28 // First multiply the by conjugate before communicating
29 onsites(opp_parity(par)) {
30 half_Wilson_vector<N, radix> h(v_in[X], dir, -sign);
31 vtemp[-dir][X] = gauge[dir][X].adjoint() * h;
32 }
33 onsites(opp_parity(par)) {
34 half_Wilson_vector<N, radix> h(v_in[X], dir, sign);
35 vtemp[dir][X] = h;
36 }
37
38 vtemp[dir].start_gather(dir, par);
39 vtemp[-dir].start_gather(-dir, par);
40 }
41
42 // Calculate the derivatives. This
43 foralldir(dir) {
44 onsites(par) {
45 v_out[X] = v_out[X] -
46 (kappa * gauge[dir][X] * vtemp[dir][X + dir]).expand(dir, sign) -
47 (kappa * vtemp[dir][X + dir]).expand(dir, -sign);
48 }
49 }
50}
51
52/// Apply the hopping term to v_in and overwrite v_out
53template <int N, typename radix, typename matrix>
54inline void Dirac_Wilson_hop_set(const Field<matrix> *gauge, const double kappa,
55 const Field<Wilson_vector<N, radix>> &v_in,
56 Field<Wilson_vector<N, radix>> &v_out, Parity par,
57 int sign) {
58 Field<half_Wilson_vector<N, radix>>(&vtemp)[2 * NDIM] =
59 wilson_dirac_temp_vector<N, radix>;
60 for (int dir = 0; dir < 2 * NDIM; dir++) {
61 vtemp[dir].copy_boundary_condition(v_in);
62 }
63
64 // Run neighbour gathers and multiplications
65 foralldir(dir) {
66 // First multiply the by conjugate before communicating
67 onsites(opp_parity(par)) {
68 half_Wilson_vector<N, radix> h(v_in[X], dir, -sign);
69 vtemp[-dir][X] = gauge[dir][X].adjoint() * h;
70 }
71 onsites(opp_parity(par)) {
72 half_Wilson_vector<N, radix> h(v_in[X], dir, sign);
73 vtemp[dir][X] = h;
74 }
75
76 vtemp[dir].start_gather(dir, par);
77 vtemp[-dir].start_gather(-dir, par);
78 }
79 // Set on first Direction
80 Direction dir = Direction(0);
81 onsites(par) {
82 v_out[X] = -(kappa * gauge[dir][X] * vtemp[dir][X + dir]).expand(dir, sign) -
83 (kappa * vtemp[dir][X + dir]).expand(dir, -sign);
84 }
85 // Add for all other directions
86 for (int d = 1; d < NDIM; d++) {
87 Direction dir = Direction(d);
88 onsites(par) {
89 half_Wilson_vector<N, radix> h1(v_in[X + dir], dir, sign);
90 v_out[X] = v_out[X] -
91 (kappa * gauge[dir][X] * vtemp[dir][X + dir]).expand(dir, sign) -
92 (kappa * vtemp[dir][X + dir]).expand(dir, -sign);
93 }
94 }
95}
96
97/// The diagonal part of the operator. Without clover this is just the identity
98template <int N, typename radix>
99inline void Dirac_Wilson_diag(const Field<Wilson_vector<N, radix>> &v_in,
100 Field<Wilson_vector<N, radix>> &v_out, Parity par) {
101 v_out[par] = v_in[X];
102}
103
104/// Inverse of the diagonal part. Without clover this does nothing.
105template <int N, typename radix>
106inline void Dirac_Wilson_diag_inverse(Field<Wilson_vector<N, radix>> &v, Parity par) {}
107
108/// Calculate derivative d/dA_x,mu (chi D psi)
109/// Necessary for the HMC force calculation.
110template <int N, typename radix, typename gaugetype, typename momtype>
111inline void Dirac_Wilson_calc_force(const Field<gaugetype> *gauge, const double kappa,
112 const Field<Wilson_vector<N, radix>> &chi,
113 const Field<Wilson_vector<N, radix>> &psi,
114 Field<momtype> (&out)[NDIM], Parity par, int sign) {
115 Field<half_Wilson_vector<N, radix>>(&vtemp)[2 * NDIM] =
116 wilson_dirac_temp_vector<N, radix>;
117 vtemp[0].copy_boundary_condition(chi);
118 vtemp[1].copy_boundary_condition(chi);
119
120 foralldir(dir) {
121 onsites(opp_parity(par)) {
122 half_Wilson_vector<N, radix> hw(chi[X], dir, -sign);
123 vtemp[0][X] = hw;
124 }
125 onsites(par) {
126 half_Wilson_vector<N, radix> hw(psi[X], dir, sign);
127 vtemp[1][X] = hw;
128 }
129
130 out[dir][ALL] = 0;
131 out[dir][par] =
132 -kappa * ((vtemp[0][X + dir].expand(dir, -sign)).outer_product(psi[X]));
133 out[dir][opp_parity(par)] =
134 out[dir][X] -
135 kappa * ((vtemp[1][X + dir].expand(dir, sign)).outer_product(chi[X]));
136 }
137}
138
139/// An operator class that applies the Wilson Dirac operator
140/// D.apply(in, out) aplies the operator
141/// D.dagger(int out) aplies the conjugate of the operator
142///
143/// This is useful for defining inverters as composite
144/// operators. For example the conjugate gradient inverter
145/// is CG<Dirac_Wilson>.
146template <typename matrix> class Dirac_Wilson {
147 private:
148 /// A reference to the gauge links used in the dirac operator
149 Field<matrix> (&gauge)[NDIM];
150
151 public:
152 /// The hopping parameter, kappa = 1/(8-2m)
153 double kappa;
154 /// Size of the gauge matrix and color dimension of the Wilson vector
155 static constexpr int N = matrix::size;
156
157 using radix = hila::arithmetic_type<matrix>;
158 /// The wilson vector type
159 using vector_type = Wilson_vector<N, radix>;
160 /// The matrix type
161 using matrix_type = matrix;
162
163 /// Single precision type in case the base type is double precision.
164 /// This is used to precondition the inversion of this operator
166
167 /// The parity this operator applies to
169
170 /// Constructor: initialize mass and gauge
171 Dirac_Wilson(Dirac_Wilson &d) : gauge(d.gauge), kappa(d.kappa) {}
172 /// Constructor: initialize mass and gauge
173 Dirac_Wilson(double k, Field<matrix> (&U)[NDIM]) : gauge(U), kappa(k) {}
174 /// Constructor: initialize mass and gauge
175 Dirac_Wilson(double k, gauge_field_base<matrix> &g) : gauge(g.gauge), kappa(k) {}
176
177 /// Construct from another Dirac_Wilson operator of a different type.
178 template <typename M>
180 : gauge(g.gauge), kappa(d.kappa) {}
181
182 /// Applies the operator to in
183 inline void apply(const Field<vector_type> &in, Field<vector_type> &out) {
184 Dirac_Wilson_diag(in, out, ALL);
185 Dirac_Wilson_hop(gauge, kappa, in, out, ALL, 1);
186 }
187
188 /// Applies the conjugate of the operator
189 inline void dagger(const Field<vector_type> &in, Field<vector_type> &out) {
190 Dirac_Wilson_diag(in, out, ALL);
191 Dirac_Wilson_hop(gauge, kappa, in, out, ALL, -1);
192 }
193
194 /// Applies the derivative of the Dirac operator with respect
195 /// to the gauge Field
196 template <typename momtype>
197 inline void force(const Field<vector_type> &chi, const Field<vector_type> &psi,
198 Field<momtype> (&force)[NDIM], int sign = 1) {
199 Dirac_Wilson_calc_force(gauge, kappa, chi, psi, force, ALL, sign);
200 }
201};
202
203/// Multiplying from the left applies the standard Dirac operator
204template <int N, typename radix, typename matrix>
206 const Field<Wilson_vector<N, radix>> &in) {
208 D.apply(in, out);
209 return out;
210}
211
212/// Multiplying from the right applies the conjugate
213template <int N, typename radix, typename matrix>
214Field<Wilson_vector<N, radix>> operator*(const Field<Wilson_vector<N, radix>> &in,
217 D.dagger(in, out);
218 return out;
219}
220
221/// An even-odd decomposed Wilson Dirac operator. Applies
222/// D_{even to odd} D_{diag}^{-1} D_{odd to even} on the even
223/// sites of the vector.
224///
225/// The fermion partition function is
226/// det(D) = det(D_eveneodd) + det(D_{diag odd}).
227/// Dirac_Wilson_evenodd can be used to replace D_Wilson
228/// in the HMC action, as long as the diagonal odd to odd
229/// part is accounted for.
230///
231/// This is useful for defining inverters as composite
232/// operators. For example the conjugate gradient inverter
233/// is CG<Dirac_Wilson_evenodd>.
234template <typename matrix> class Dirac_Wilson_evenodd {
235 private:
236 /// A reference to the gauge links used in the dirac operator
237 Field<matrix> (&gauge)[NDIM];
238
239 public:
240 /// The hopping parameter, kappa = 1/(8-2m)
241 double kappa;
242 /// Size of the gauge matrix and color dimension of the Wilson vector
243 static constexpr int N = matrix::size;
244 /// The wilson vector type
245 using radix = hila::arithmetic_type<matrix>;
246 using vector_type = Wilson_vector<N, radix>;
247 /// The matrix type
248 using matrix_type = matrix;
249
250 /// Single precision type in case the base type is double precision.
251 /// This is used to precondition the inversion of this operator
252 using type_flt =
254
255 /// The parity this operator applies to
257
258 /// Constructor: initialize mass and gauge
260 /// Constructor: initialize mass and gauge
261 Dirac_Wilson_evenodd(double k, Field<matrix> (&U)[NDIM]) : gauge(U), kappa(k) {}
262 /// Constructor: initialize mass and gauge
264 : gauge(g.gauge), kappa(k) {}
265
266 /// Construct from another Dirac_Wilson operator of a different type.
267 template <typename M>
269 : gauge(g.gauge), kappa(d.kappa) {}
270
271 /// Applies the operator to in
272 inline void apply(const Field<vector_type> &in, Field<vector_type> &out) {
273 Dirac_Wilson_diag(in, out, EVEN);
274
275 Dirac_Wilson_hop_set(gauge, kappa, in, out, ODD, 1);
276 Dirac_Wilson_diag_inverse(out, ODD);
277 Dirac_Wilson_hop(gauge, -kappa, out, out, EVEN, 1);
278 out[ODD] = 0;
279 }
280
281 /// Applies the conjugate of the operator
282 inline void dagger(const Field<vector_type> &in, Field<vector_type> &out) {
283 Dirac_Wilson_diag(in, out, EVEN);
284
285 Dirac_Wilson_hop_set(gauge, kappa, in, out, ODD, -1);
286 Dirac_Wilson_diag_inverse(out, ODD);
287 Dirac_Wilson_hop(gauge, -kappa, out, out, EVEN, -1);
288 out[ODD] = 0;
289 }
290
291 /// Applies the derivative of the Dirac operator with respect
292 /// to the gauge Field
293 template <typename momtype>
294 inline void force(const Field<vector_type> &chi, const Field<vector_type> &psi,
295 Field<momtype> (&force)[NDIM], int sign) {
296 Field<momtype> force2[NDIM];
299
300 tmp[ALL] = 0;
301 Dirac_Wilson_hop_set(gauge, kappa, chi, tmp, ODD, -sign);
302 Dirac_Wilson_diag_inverse(tmp, ODD);
303 Dirac_Wilson_calc_force(gauge, -kappa, tmp, psi, force, EVEN, sign);
304
305 tmp[ALL] = 0;
306 Dirac_Wilson_hop_set(gauge, kappa, psi, tmp, ODD, sign);
307 Dirac_Wilson_diag_inverse(tmp, ODD);
308 Dirac_Wilson_calc_force(gauge, -kappa, chi, tmp, force2, ODD, sign);
309
310 foralldir(dir) force[dir][ALL] = force[dir][X] + force2[dir][X];
311 }
312};
313
314#endif
void apply(const Field< vector_type > &in, Field< vector_type > &out)
Applies the operator to in.
Definition wilson.h:272
matrix matrix_type
The matrix type.
Definition wilson.h:248
Dirac_Wilson_evenodd(Dirac_Wilson_evenodd &d)
Constructor: initialize mass and gauge.
Definition wilson.h:259
Parity par
The parity this operator applies to.
Definition wilson.h:256
void dagger(const Field< vector_type > &in, Field< vector_type > &out)
Applies the conjugate of the operator.
Definition wilson.h:282
double kappa
The hopping parameter, kappa = 1/(8-2m)
Definition wilson.h:241
Dirac_Wilson_evenodd(double k, Field< matrix >(&U)[4])
Constructor: initialize mass and gauge.
Definition wilson.h:261
void force(const Field< vector_type > &chi, const Field< vector_type > &psi, Field< momtype >(&force)[4], int sign)
Definition wilson.h:294
hila::arithmetic_type< matrix > radix
The wilson vector type.
Definition wilson.h:245
Dirac_Wilson_evenodd(double k, gauge_field_base< matrix > &g)
Constructor: initialize mass and gauge.
Definition wilson.h:263
static constexpr int N
Size of the gauge matrix and color dimension of the Wilson vector.
Definition wilson.h:243
Dirac_Wilson_evenodd(Dirac_Wilson_evenodd< M > &d, gauge_field_base< matrix > &g)
Construct from another Dirac_Wilson operator of a different type.
Definition wilson.h:268
static constexpr int N
Size of the gauge matrix and color dimension of the Wilson vector.
Definition wilson.h:155
void apply(const Field< vector_type > &in, Field< vector_type > &out)
Applies the operator to in.
Definition wilson.h:183
Parity par
The parity this operator applies to.
Definition wilson.h:168
void dagger(const Field< vector_type > &in, Field< vector_type > &out)
Applies the conjugate of the operator.
Definition wilson.h:189
Dirac_Wilson(Dirac_Wilson< M > &d, gauge_field_base< matrix > &g)
Construct from another Dirac_Wilson operator of a different type.
Definition wilson.h:179
Dirac_Wilson(double k, gauge_field_base< matrix > &g)
Constructor: initialize mass and gauge.
Definition wilson.h:175
Dirac_Wilson(double k, Field< matrix >(&U)[4])
Constructor: initialize mass and gauge.
Definition wilson.h:173
Dirac_Wilson(Dirac_Wilson &d)
Constructor: initialize mass and gauge.
Definition wilson.h:171
double kappa
The hopping parameter, kappa = 1/(8-2m)
Definition wilson.h:153
void force(const Field< vector_type > &chi, const Field< vector_type > &psi, Field< momtype >(&force)[4], int sign=1)
Definition wilson.h:197
matrix matrix_type
The matrix type.
Definition wilson.h:161
Wilson_vector< N, radix > vector_type
The wilson vector type.
Definition wilson.h:159
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Definition field.h:61
void copy_boundary_condition(const Field< A > &rhs)
Copy the boundary condition from another field.
Definition field.h:650
Definition of Complex types.
Parity
Parity enum with values EVEN, ODD, ALL; refers to parity of the site. Parity of site (x,...
constexpr Parity EVEN
bit pattern: 001
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:78
constexpr Parity ODD
bit pattern: 010
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
Definition coordinates.h:34
constexpr Parity ALL
bit pattern: 011
This file defines all includes for HILA.
This files containts definitions for the Field class and the classes required to define it such as fi...
Definition of Matrix types.
std::ostream out
this is our default output file stream