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 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, VectorField<Algebra<group>> &K) {
110 // compute gauge force of Wilson loop "W", corresponding to "path" and store result in vector
111 // field "K"
112 foralldir(d1) {
113 K[d1][ALL] = 0;
114 }
115 get_wloop_froce_add(U, path, W, eps, K);
116}
117
118template <typename group, typename atype = hila::arithmetic_type<group>>
119void get_wloop_force_add(const GaugeField<group> &U, const std::vector<Direction> &path, atype eps,
121 // compute gauge force of Wilson loop along "path" and add result to vector field "K"
122 Field<group> R, R0;
123 int L = path.size();
124 get_wilson_line(U, path, R);
125
126 Direction dir;
127 int udirs[NDIRS] = {0};
128 for (int i = 0; i < L; ++i) {
129 dir = path[i];
130 if (is_up_dir(dir)) {
131 if ((udirs[(int)dir]++) == 0) {
132 U[dir].start_gather(-dir, ALL);
133 }
134 }
135 }
136
137 for (int i = 0; i < L; ++i) {
138 dir = path[i];
139 R.start_gather(-dir, ALL);
140 if (is_up_dir(dir)) {
141 // link points in positive direction
142 onsites(ALL) K[dir][X] -= R[X].project_to_algebra_scaled(eps);
143
144 onsites(ALL) mult(U[dir][X - dir].dagger(), R[X - dir], R0[X]);
145 onsites(ALL) mult(R0[X], U[dir][X - dir], R[X]);
146 } else {
147 // link points in negative direction
148 onsites(ALL) mult(U[-dir][X], R[X - dir], R0[X]);
149 onsites(ALL) mult(R0[X], U[-dir][X].dagger(), R[X]);
150
151 onsites(ALL) K[-dir][X] += R[X].project_to_algebra_scaled(eps);
152 }
153 }
154}
155
156template <typename group, typename atype = hila::arithmetic_type<group>>
157void get_wloop_force(const GaugeField<group> &U, const std::vector<Direction> &path, atype eps,
159 // compute gauge force of Wilson loop defined by "path" and store result in vector field "K"
160 foralldir(d1) {
161 K[d1][ALL] = 0;
162 }
163 get_wloop_froce_add(U, path, eps, K);
164}
165
166
167/*
168* old, slow implementation:
169template <typename group,int L>
170void get_wilson_line_b(const GaugeField<group>& U,const Direction(&path)[L],Field<group>& R) {
171 // compute the Wilson line defined by the list of directions "path"
172 CoordinateVector v=0;
173 // initialize R with first link of the Wilson line:
174 if(path[0]<NDIM) {
175 // link points in positive direction
176 onsites(ALL) R[X]=U[path[0]][X];
177 v+=path[0];
178 } else {
179 // link points in negative direction
180 v+=path[0];
181 onsites(ALL) R[X]=U[-path[0]][X+v].dagger();
182 }
183
184 // multiply R successively with the remaining links of the Wilson line
185 for(int i=1; i<L; ++i) {
186 if(path[i]<NDIM) {
187 // link points in positive direction
188 onsites(ALL) R[X]*=U[path[i]][X+v];
189 v+=path[i];
190 } else {
191 // link points in negative direction
192 v+=path[i];
193 onsites(ALL) R[X]*=U[-path[i]][X+v].dagger();
194 }
195 }
196}
197
198template <typename group,int L>
199void get_wloop_force_add_b(const GaugeField<group>& U,const Direction(&path)[L],ftype
200eps,VectorField<Algebra<group>>& K) {
201 // compute gauge force of Wilson loop defined by "path" and add result to vector field "K"
202 Field<group> R;
203 get_wilson_line_b(U,path,R);
204
205 CoordinateVector v=0;
206 for(int i=0; i<L; ++i) {
207 if(path[i]<NDIM) {
208 // link points in positive direction
209 onsites(ALL) K[path[i]][X]-=R[X-v].project_to_algebra_scaled(eps);
210
211 onsites(ALL) R[X]=U[path[i]][X+v].dagger()*R[X]*U[path[i]][X+v];
212
213 v+=path[i];
214 } else {
215 // link points in negative direction
216 v+=path[i];
217
218 onsites(ALL) R[X]=U[-path[i]][X+v]*R[X]*U[-path[i]][X+v].dagger();
219
220 onsites(ALL) K[-path[i]][X]+=R[X-v].project_to_algebra_scaled(eps);
221 }
222 }
223}
224*/
225
226
227#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 Mt &a, const Mt &b, Mt &res)
compute product of two square matrices and write result to existing matrix
Definition matrix.h:2327