HILA
Loading...
Searching...
No Matches
wilson_line_and_force.h
Go to the documentation of this file.
1/** @file wilson_line_and_force.h */
2
3#ifndef WILSON_LINE_AND_FORCE_H_
4#define WILSON_LINE_AND_FORCE_H_
5
6#include "hila.h"
7#include <vector>
8
9// functions to compute general Wilson lines and gauge force for closed Wilson lines
10
11template <typename group>
12void get_wilson_line(const GaugeField<group> &U, const std::vector<Direction> &path,
13 out_only Field<group> &R) {
14 // compute the Wilson line defined by the list of directions "path"
15 int i, ip;
16 int L = path.size();
17 int udirs[NDIRS] = {0};
18 Direction dir;
19 for (i = 0; i < L; ++i) {
20 dir = path[i];
21 if (is_up_dir(dir)) {
22 if ((udirs[(int)dir]++) == 0) {
23 U[dir].start_gather(-dir, ALL);
24 }
25 }
26 }
27
28 Field<group> R0[2];
29
30 i = 0;
31 ip = 0;
32 dir = path[i];
33 // initialize R0[0] with first link variable of the Wilson line:
34 if (is_up_dir(dir)) {
35 // link points in positive direction
36 onsites(ALL) R0[ip][X] = U[dir][X - dir];
37 } else {
38 // link points in negative direction
39 onsites(ALL) R0[ip][X] = U[-dir][X].dagger();
40 }
41
42 // multiply R0[ip] successively with the L-2 intermediate link variables of the Wilson line
43 // and store the result in R0[1-ip]
44 for (i = 1; i < L - 1; ++i) {
45 dir = path[i];
46 R0[ip].start_gather(-dir, ALL);
47 if (is_up_dir(dir)) {
48 // link points in positive direction
49 onsites(ALL) mult(R0[ip][X - dir], U[dir][X - dir], R0[1 - ip][X]);
50 } else {
51 // link points in negative direction
52 onsites(ALL) mult(R0[ip][X - dir], U[-dir][X].dagger(), R0[1 - ip][X]);
53 }
54 ip = 1 - ip;
55 }
56
57 // multiply R0[ip] by the last link variable of the Wilson line and store the result in R
58 dir = path[i];
59 R0[ip].start_gather(-dir, ALL);
60 if (is_up_dir(dir)) {
61 // link points in positive direction
62 onsites(ALL) mult(R0[ip][X - dir], U[dir][X - dir], R[X]);
63 } else {
64 // link points in negative direction
65 onsites(ALL) mult(R0[ip][X - dir], U[-dir][X].dagger(), R[X]);
66 }
67}
68
69template <typename group, typename atype = hila::arithmetic_type<group>>
70void get_wloop_force_from_wl_add(const GaugeField<group> &U, const std::vector<Direction> &path,
71 const Field<group> &W, atype eps, VectorField<Algebra<group>> &K) {
72 // compute gauge force of Wilson loop "W", corresponding to "path" and add result to vector
73 // field "K"
74 Field<group> R = W;
75 Field<group> R0;
76 int L = path.size();
77 int udirs[NDIRS] = {0};
78 Direction dir;
79 for (int i = 0; i < L; ++i) {
80 dir = path[i];
81 if (is_up_dir(dir)) {
82 if ((udirs[(int)dir]++) == 0) {
83 U[dir].start_gather(-dir, ALL);
84 }
85 }
86 }
87
88 for (int i = 0; i < L; ++i) {
89 dir = path[i];
90 R.start_gather(-dir, ALL);
91 if (is_up_dir(dir)) {
92 // link points in positive direction
93 onsites(ALL) K[dir][X] -= R[X].project_to_algebra_scaled(eps);
94
95 onsites(ALL) mult(U[dir][X - dir].dagger(), R[X - dir], R0[X]);
96 onsites(ALL) mult(R0[X], U[dir][X - dir], R[X]);
97 } else {
98 // link points in negative direction
99 onsites(ALL) mult(U[-dir][X], R[X - dir], R0[X]);
100 onsites(ALL) mult(R0[X], U[-dir][X].dagger(), R[X]);
101
102 onsites(ALL) K[-dir][X] += R[X].project_to_algebra_scaled(eps);
103 }
104 }
105}
106
107template <typename group, typename atype = hila::arithmetic_type<group>>
108void get_wloop_force_from_wl(const GaugeField<group> &U, const std::vector<Direction> &path,
109 const Field<group> &W, atype eps,
110 out_only VectorField<Algebra<group>> &K) {
111 // compute gauge force of Wilson loop "W", corresponding to "path" and store result in vector
112 // field "K"
113 foralldir(d1) {
114 K[d1][ALL] = 0;
115 }
116 get_wloop_froce_add(U, path, W, eps, K);
117}
118
119template <typename group, typename atype = hila::arithmetic_type<group>>
120void get_wloop_force_add(const GaugeField<group> &U, const std::vector<Direction> &path, atype eps,
122 // compute gauge force of Wilson loop along "path" and add result to vector field "K"
123 Field<group> R, R0;
124 int L = path.size();
125 get_wilson_line(U, path, R);
126
127 Direction dir;
128 int udirs[NDIRS] = {0};
129 for (int i = 0; i < L; ++i) {
130 dir = path[i];
131 if (is_up_dir(dir)) {
132 if ((udirs[(int)dir]++) == 0) {
133 U[dir].start_gather(-dir, ALL);
134 }
135 }
136 }
137
138 for (int i = 0; i < L; ++i) {
139 dir = path[i];
140 R.start_gather(-dir, ALL);
141 if (is_up_dir(dir)) {
142 // link points in positive direction
143 onsites(ALL) K[dir][X] -= R[X].project_to_algebra_scaled(eps);
144
145 onsites(ALL) mult(U[dir][X - dir].dagger(), R[X - dir], R0[X]);
146 onsites(ALL) mult(R0[X], U[dir][X - dir], R[X]);
147 } else {
148 // link points in negative direction
149 onsites(ALL) mult(U[-dir][X], R[X - dir], R0[X]);
150 onsites(ALL) mult(R0[X], U[-dir][X].dagger(), R[X]);
151
152 onsites(ALL) K[-dir][X] += R[X].project_to_algebra_scaled(eps);
153 }
154 }
155}
156
157template <typename group, typename atype = hila::arithmetic_type<group>>
158void get_wloop_force(const GaugeField<group> &U, const std::vector<Direction> &path, atype eps,
159 out_only VectorField<Algebra<group>> &K) {
160 // compute gauge force of Wilson loop defined by "path" and store result in vector field "K"
161 foralldir(d1) {
162 K[d1][ALL] = 0;
163 }
164 get_wloop_froce_add(U, path, eps, K);
165}
166
167
168/*
169* old, slow implementation:
170template <typename group,int L>
171void get_wilson_line_b(const GaugeField<group>& U,const Direction(&path)[L],Field<group>& R) {
172 // compute the Wilson line defined by the list of directions "path"
173 CoordinateVector v=0;
174 // initialize R with first link of the Wilson line:
175 if(path[0]<NDIM) {
176 // link points in positive direction
177 onsites(ALL) R[X]=U[path[0]][X];
178 v+=path[0];
179 } else {
180 // link points in negative direction
181 v+=path[0];
182 onsites(ALL) R[X]=U[-path[0]][X+v].dagger();
183 }
184
185 // multiply R successively with the remaining links of the Wilson line
186 for(int i=1; i<L; ++i) {
187 if(path[i]<NDIM) {
188 // link points in positive direction
189 onsites(ALL) R[X]*=U[path[i]][X+v];
190 v+=path[i];
191 } else {
192 // link points in negative direction
193 v+=path[i];
194 onsites(ALL) R[X]*=U[-path[i]][X+v].dagger();
195 }
196 }
197}
198
199template <typename group,int L>
200void get_wloop_force_add_b(const GaugeField<group>& U,const Direction(&path)[L],ftype
201eps,VectorField<Algebra<group>>& K) {
202 // compute gauge force of Wilson loop defined by "path" and add result to vector field "K"
203 Field<group> R;
204 get_wilson_line_b(U,path,R);
205
206 CoordinateVector v=0;
207 for(int i=0; i<L; ++i) {
208 if(path[i]<NDIM) {
209 // link points in positive direction
210 onsites(ALL) K[path[i]][X]-=R[X-v].project_to_algebra_scaled(eps);
211
212 onsites(ALL) R[X]=U[path[i]][X+v].dagger()*R[X]*U[path[i]][X+v];
213
214 v+=path[i];
215 } else {
216 // link points in negative direction
217 v+=path[i];
218
219 onsites(ALL) R[X]=U[-path[i]][X+v]*R[X]*U[-path[i]][X+v].dagger();
220
221 onsites(ALL) K[-path[i]][X]+=R[X-v].project_to_algebra_scaled(eps);
222 }
223 }
224}
225*/
226
227
228#endif
Definition su2.h:7
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Definition field.h:61
dir_mask_t start_gather(Direction d, Parity p=ALL) const
Definition field_comm.h:262
Gauge field class.
Definition gaugefield.h:22
Complex< T > dagger(const Complex< T > &val)
Return dagger of Complex number.
Definition cmplx.h:1223
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:78
constexpr unsigned NDIRS
Number of directions.
Definition coordinates.h:57
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
void mult(const Mt1 &a, const Mt2 &b, Mt3 &res)
compute product of two matrices and write result to existing matrix
Definition matrix.h:2327