HILA
Loading...
Searching...
No Matches
stout_smear_nchm.h
1#ifndef STOUT_SMEAR_NCHM_H_
2#define STOUT_SMEAR_NCHM_H_
3
4#include "hila.h"
5
7
8/////////////////////////////////////////////////////////////////////////////
9/// Do stout smearing for the gauge fields
10/// U' = exp( -coeff * Proj_to_Alg(U * Staples) ) * U
11
12/**
13 * @brief Compute sum of staples around all links
14 * @details Compute staple sums around all positively oriented links (i.e.
15 * corresponding plaquette sums are obtained by multiplying the staple sums
16 * by the corresponding positively oriented link variables)
17
18 * @tparam T Matrix element type
19 * @param U input gauge field of type T
20 * @param staples output vector/gauge field of type T
21 * @return void
22 */
23template <typename T>
24void nchm_staplesums(const GaugeField<T> &U, out_only GaugeField<T> &staples) {
25 Field<T> tF1, lw1;
26 foralldir(d1) {
27 foralldir(d2) if (d2 != d1) {
28 U[d2].start_gather(d1, ALL);
29 }
30 onsites(ALL) staples[d1][X] = 0;
31 }
32
33 foralldir(d1) foralldir(d2) if (d2 != d1) {
34 onsites(ALL) {
35 // tF1[X] = (U[d1][X] * U[d2][X + d1]).dagger();
36 mult_aa(U[d1][X], U[d2][X + d1], tF1[X]);
37 // lw1[X] = tF1[X] * U[d2][X];
38 mult(tF1[X], U[d2][X], lw1[X]);
39 }
40
41 lw1.start_gather(-d2, ALL);
42
43 onsites(ALL) {
44 // staple[d2][X] += U[d1][X + d2] * tF1[X];
45 mult_add(U[d1][X + d2], tF1[X], staples[d2][X]);
46 }
47 onsites(ALL) {
48 staples[d1][X] += lw1[X - d2];
49 }
50 }
51}
52
53template <typename T, typename atype = hila::arithmetic_type<T>>
54void nchm_stout_smear1(const GaugeField<T> &U, out_only GaugeField<T> &stout,
55 out_only std::array<Field<int>, NDIM> &niter, atype coeff) {
56 nchm_staplesums(U, stout);
57 foralldir(d) {
58 onsites(ALL) {
59 stout[d][X] = altexp((U[d][X] * stout[d][X]).project_to_algebra_scaled(-coeff).expand(),
60 niter[d][X]) * U[d][X];
61 }
62 }
63}
64
65template <typename T, typename atype = hila::arithmetic_type<T>>
66void nchm_stout_smear1(const GaugeField<T> &U, out_only GaugeField<T> &stout,
67 out_only std::array<Field<int>, NDIM> &niter,
68 out_only std::array<Field<atype>, NDIM> &imnorm, atype coeff) {
69 nchm_staplesums(U, stout);
70 foralldir(d) {
71 onsites(ALL) {
72 T tM = (U[d][X] * stout[d][X]).project_to_algebra_scaled(-coeff).expand();
73 imnorm[d][X] = tM.norm();
74 stout[d][X] = altexp(tM, niter[d][X]) * U[d][X];
75 }
76 }
77}
78
79
80template <typename T, typename atype = hila::arithmetic_type<T>>
81void nchm_stout_smear1(const GaugeField<T> &U, out_only GaugeField<T> &stout,
82 out_only VectorField<T> &stap,
83 out_only std::array<Field<int>, NDIM> &niter, atype coeff) {
84 nchm_staplesums(U, stap);
85 foralldir(d) {
86 onsites(ALL) {
87 stout[d][X] = altexp((U[d][X] * stap[d][X]).project_to_algebra_scaled(-coeff).expand(),
88 niter[d][X]) *
89 U[d][X];
90 }
91 }
92}
93
94
95template <typename T, typename atype = hila::arithmetic_type<T>>
96void nchm_stout_smear(const GaugeField<T> &U, out_only std::vector<GaugeField<T>> &stoutlist,
97 out_only std::vector<GaugeField<T>> &staplist,
98 out_only std::vector<std::array<Field<int>, NDIM>> &niterlist, atype coeff) {
99 // performs nst stout smearing steps on the gauge field U and stores the gague field obtained
100 // after the i-th smearing step in stoutlist[i]
101 stoutlist[0] = U; // original field
102 for (int i = 1; i < stoutlist.size(); ++i) {
103 nchm_stout_smear1(stoutlist[i - 1], stoutlist[i], staplist[i - 1], niterlist[i - 1], coeff);
104 }
105}
106
107
108template <typename T, typename atype = hila::arithmetic_type<T>>
109void nchm_stout_smear1(const GaugeField<T> &U, out_only GaugeField<T> &stout,
110 out_only VectorField<T> &stap, out_only std::array<Field<int>, NDIM> &niter,
111 out_only std::array<Field<atype>, NDIM> &imnorm, atype coeff) {
112 nchm_staplesums(U, stap);
113 foralldir(d) {
114 onsites(ALL) {
115 T tM = (U[d][X] * stap[d][X]).project_to_algebra_scaled(-coeff).expand();
116 imnorm[d][X] = tM.norm();
117 stout[d][X] = altexp(tM, niter[d][X]) * U[d][X];
118 }
119 }
120}
121
122template <typename T, typename atype = hila::arithmetic_type<T>>
123void nchm_stout_smear(const GaugeField<T> &U, out_only std::vector<GaugeField<T>> &stoutlist,
124 out_only std::vector<GaugeField<T>> &staplist,
125 out_only std::vector<std::array<Field<int>, NDIM>> &niterlist,
126 out_only std::vector<std::array<Field<atype>, NDIM>> &imnormlist, atype coeff) {
127 // performs nst stout smearing steps on the gauge field U and stores the gague field obtained
128 // after the i-th smearing step in stoutlist[i]
129 stoutlist[0] = U; // original field
130 for (int i = 1; i < stoutlist.size(); ++i) {
131 nchm_stout_smear1(stoutlist[i - 1], stoutlist[i], staplist[i - 1], niterlist[i - 1],
132 imnormlist[i - 1], coeff);
133 }
134}
135
136
137template <typename T, typename atype = hila::arithmetic_type<T>>
138void nchm_stout_smear1(const GaugeField<T> &U, out_only GaugeField<T> &stout, atype coeff) {
139 nchm_staplesums(U, stout);
140 foralldir(d) {
141 onsites(ALL) {
142 stout[d][X] =
143 altexp((U[d][X] * stout[d][X]).project_to_algebra_scaled(-coeff).expand()) *
144 U[d][X];
145 }
146 }
147}
148
149template <typename T, typename atype = hila::arithmetic_type<T>>
150void nchm_stout_smear1(const GaugeField<T> &U, out_only GaugeField<T> &stout,
151 out_only GaugeField<T> &stap, atype coeff) {
152 nchm_staplesums(U, stap);
153 foralldir(d) {
154 onsites(ALL) {
155 stout[d][X] =
156 altexp((U[d][X] * stap[d][X]).project_to_algebra_scaled(-coeff).expand()) * U[d][X];
157 }
158 }
159}
160
161template <typename T, typename atype = hila::arithmetic_type<T>>
162void nchm_stout_smear(const GaugeField<T> &U, GaugeField<T> &stout, atype coeff, int iter) {
163 GaugeField<T> tmp;
164 if (iter % 2 == 0) {
165 stout = U;
166 for (int i = 0; i < iter / 2; ++i) {
167 nchm_stout_smear1(stout, tmp, coeff);
168 nchm_stout_smear1(tmp, stout, coeff);
169 }
170 } else {
171 tmp = U;
172 for (int i = 0; i < iter / 2; ++i) {
173 nchm_stout_smear1(tmp, stout, coeff);
174 nchm_stout_smear1(stout, tmp, coeff);
175 }
176 nchm_stout_smear1(tmp, stout, coeff);
177 }
178}
179
180template <typename T, typename atype = hila::arithmetic_type<T>>
181void nchm_stout_smear(const GaugeField<T> &U, GaugeField<T> &stout,
182 std::vector<std::array<Field<int>, NDIM>> &niterlist, atype coeff) {
183 GaugeField<T> tmp;
184 int iter = niterlist.size();
185 if (iter % 2 == 0) {
186 stout = U;
187 for (int i = 0; i < iter / 2; ++i) {
188 nchm_stout_smear1(stout, tmp, niterlist[2 * i], coeff);
189 nchm_stout_smear1(tmp, stout, niterlist[2 * i + 1], coeff);
190 }
191 } else {
192 tmp = U;
193 for (int i = 0; i < iter / 2; ++i) {
194 nchm_stout_smear1(tmp, stout, niterlist[2 * i], coeff);
195 nchm_stout_smear1(stout, tmp, niterlist[2 * i + 1], coeff);
196 }
197 nchm_stout_smear1(tmp, stout, niterlist[iter - 1], coeff);
198 }
199}
200
201template <typename T, typename atype = hila::arithmetic_type<T>>
202void nchm_stout_smear(const GaugeField<T> &U, GaugeField<T> &stout,
203 std::vector<std::array<Field<int>, NDIM>> &niterlist,
204 std::vector<std::array<Field<atype>, NDIM>> &imnormlist,
205 atype coeff) {
206 GaugeField<T> tmp;
207 int iter = niterlist.size();
208 if (iter % 2 == 0) {
209 stout = U;
210 for (int i = 0; i < iter / 2; ++i) {
211 nchm_stout_smear1(stout, tmp, niterlist[2 * i], imnormlist[2 * i], coeff);
212 nchm_stout_smear1(tmp, stout, niterlist[2 * i + 1], imnormlist[2 * i + 1], coeff);
213 }
214 } else {
215 tmp = U;
216 for (int i = 0; i < iter / 2; ++i) {
217 nchm_stout_smear1(tmp, stout, niterlist[2 * i], imnormlist[2 * i], coeff);
218 nchm_stout_smear1(stout, tmp, niterlist[2 * i + 1], imnormlist[2 * i + 1], coeff);
219 }
220 nchm_stout_smear1(tmp, stout, niterlist[iter - 1], imnormlist[iter -1 ], coeff);
221 }
222}
223
224
225template <typename T, int N = T::rows(), int NSTP = 2 * (NDIM - 1),
226 typename atype = hila::arithmetic_type<T>>
227void nchm_stout_smear_force(const std::vector<GaugeField<T>> &stoutlist,
228 const std::vector<VectorField<T>> &staplist,
229 const VectorField<Algebra<T>> &K, out_only VectorField<Algebra<T>> &KS,
230 std::vector<std::array<Field<int>, NDIM>> &niterlist, atype coeff) {
231 // uses the list stoutlist[] of smeared gauge fields to compute the pullback of the
232 // algebra-valued force field K under the smearing and returns the force acting on the unsmeared
233 // link variables as algebra-valued field KS
234 // Note: our definition of the force field is different from the one used in
235 // [arXiv:hep-lat/0311018v1], in order to match the force field representation used by our HMC
236 // implementation.
238 Field<T> K21, K22, K23, K24;
239
240 foralldir(d1) onsites(ALL) KS[d1][X] = K[d1][X];
241
242 for (int i = stoutlist.size() - 2; i >= 0; --i) {
243 const GaugeField<T> &U0 = stoutlist[i + 1];
244 const GaugeField<T> &U = stoutlist[i];
245 const VectorField<T> &staps = staplist[i];
246 const std::array<Field<int>, NDIM> &niter = niterlist[i];
247
248 foralldir(d1) {
249 //get_stout_staples(U, d1, stapl, staps);
250 onsites(ALL) {
251 // compute stout smearing operator and its derivatives:
252
253 // temp. variables:
254 T mtexp;
255 T mdtexp;
256 // turn staple sum into plaquette sum by multiplying with link variable:
257 //T tplaqs = U[d1][X] * staps[X];
258 T tplaqs = U[d1][X] * staps[d1][X];
259 // the following function computes first for X = -coeff * tplaqs the smearing
260 // operator Q = exp(X) and its derivatives dQ/dX[][], and uses these to
261 // compute the two matrices:
262 // mtexp = Q.dagger() * KS[d1][X].expand() * Q
263 // and
264 // mdtexp[i][j] = trace(Q.dagger * KS[d1][X].expand() * dQ/dX[j][i]) :
265 mult_exp(tplaqs.project_to_algebra_scaled(-coeff).expand(),
266 U[d1][X] * U0[d1][X].dagger() * KS[d1][X].expand(), mtexp, mdtexp, niter[d1][X]);
267
268 // set K1[d1][X] to be the equivalent of the \Lambda matrix from eq.(73) in
269 // [arXiv:hep-lat/0311018v1]:
270 K1[d1][X] = mdtexp.project_to_algebra_scaled(coeff).expand();
271
272 // equivalent of first line and first term on second line of eq.(75) in
273 // [arXiv:hep-lat/0311018v1]:
274 KS[d1][X] = (mtexp - tplaqs * K1[d1][X]).project_to_algebra();
275
276 // multiply K1[d1] by U[d1]:
277 K1[d1][X] *= U[d1][X];
278 }
279 }
280
281 // equivalent of remaining terms of eq.(75) in [arXiv:hep-lat/0311018v1]:
282 foralldir(d1) foralldir(d2) if (d1 != d2) {
283 onsites(ALL) {
284 T U2, U4, tM1;
285
286 U2 = U[d2][X + d1];
287 U4 = U[d2][X].dagger();
288
289 tM1 = U2 * U[d1][X + d2].dagger();
290 K21[X] = U4 * K1[d1][X] * tM1;
291 tM1 *= U4;
292 K22[X] = tM1 * K1[d1][X];
293 K24[X] = K1[d1][X] * tM1;
294
295 tM1 = U2 * K1[d1][X + d2].dagger() * U4;
296 K23[X] = U[d1][X] * tM1;
297 K22[X] += tM1 * U[d1][X];
298
299 K24[X] += K23[X];
300 }
301
302 onsites(ALL) {
303 KS[d2][X] -= (K22[X - d1] - K24[X]).project_to_algebra();
304 KS[d1][X] -= (K23[X] - K21[X - d2]).project_to_algebra();
305 }
306 }
307 }
308}
309
310#endif
Definition su2.h:7
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Definition field.h:62
Field< A > dagger() const
Returns dagger or Hermitian conjugate of Field depending on how it is defined for Field type T.
Definition field.h:1188
dir_mask_t start_gather(Direction d, Parity p=ALL) const
Definition field_comm.h:262
Gauge field class.
Definition gaugefield.h:23
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:80
constexpr Parity ALL
bit pattern: 011
void mult_exp(const Matrix_t< n, m, T, MT > &mat, const Matrix_t< n, m, T, MT > &mmat, Matrix_t< n, m, T, MT > &r, Matrix_t< n, m, T, MT > &dr, const int order=20)
Calculate mmat*exp(mat) and trace(mmat*dexp(mat))
Definition matrix.h:3170
void mult_add(const Mt1 &a, const Mt2 &b, Mt3 &res)
compute product of two matrices and add result to existing matrix
Definition matrix.h:2714
void mult_aa(const Mt1 &a, const Mt2 &b, Mt3 &res)
compute hermitian conjugate of product of two matrices and write result to existing matrix
Definition matrix.h:2633
void mult(const Mt1 &a, const Mt2 &b, Mt3 &res)
compute product of two matrices and write result to existing matrix
Definition matrix.h:2604
Matrix_t< n, m, T, MT > altexp(const Matrix_t< n, m, T, MT > &mat, int &niter)
Calculate exp of a square matrix.
Definition matrix.h:3102