3#ifndef GRADIENT_FLOW_H_
4#define GRADIENT_FLOW_H_
14#define GFLOWS GFLOWACTION
32template <
typename group,
typename atype = hila::arithmetic_type<group>>
44 get_force_bp(U, E, eps);
46 atype c12 = -1.0 / 12.0;
47 atype c11 = 1.0 - 8.0 * c12;
48 get_force_impr(U, E, eps * c11, eps * c12);
51 atype c11 = 1.0 - 8.0 * c12;
52 get_force_impr(U, E, eps * c11, eps * c12);
55 atype c11 = 1.0 - 8.0 * c12;
56 get_force_impr(U, E, eps * c11, eps * c12);
58 get_force_log_plaq(U, E, eps);
60 get_force_wplaq(U, E, eps);
68template <
typename group,
typename atype = hila::arithmetic_type<group>>
73 atype res = measure_s_bp(U);
75 atype c12 = -1.0 / 12.0;
76 atype c11 = 1.0 - 8.0 * c12;
77 atype res = measure_s_impr(U, c11, c12);
80 atype c11 = 1.0 - 8.0 * c12;
81 atype res = measure_s_impr(U, c11, c12);
84 atype c11 = 1.0 - 8.0 * c12;
85 atype res = measure_s_impr(U, c11, c12);
87 atype res = measure_s_log_plaq(U);
89 atype res = measure_s_wplaq(U);
98template <
typename group,
typename atype = hila::arithmetic_type<group>>
104 get_force_wplaq(U, Kc, -2.0);
107 de += Kc[d][X].dot(K[d][X]);
110 return (atype)de.
value();
113template <
typename group,
typename atype = hila::arithmetic_type<group>>
119 get_force_clover(U, Kc, -2.0);
122 de += Kc[d][X].dot(K[d][X]);
125 return (atype)de.
value();
128template <
typename group,
typename atype = hila::arithmetic_type<group>>
134 get_force_log(U, Kc, -2.0);
137 de += Kc[d][X].dot(K[d][X]);
140 return (atype)de.
value();
143template <
typename group,
typename atype = hila::arithmetic_type<group>>
144void measure_gradient_flow_stuff(
const GaugeField<group> &V, atype flow_l, atype t_step) {
148 static bool first =
true;
152 hila::out0 <<
"GFINFO using bulk-prevention action\n";
154 hila::out0 <<
"GFINFO using Luscher-Weisz action\n";
156 hila::out0 <<
"GFINFO using Iwasaki action\n";
160 hila::out0 <<
"GFINFO using log-plaquette action\n";
162 hila::out0 <<
"GFINFO using Wilson's plaquette action\n";
165 hila::out0 <<
"LGFLMEAS l(ambda) S-flow S-plaq E_plaq dE_plaq/dl "
166 " E_clv dE_clv/dl Qtopo_clv E_log dE_log/dl "
167 "Qtopo_log [t_step_size] [max_S-plaq]\n";
170 atype slocal = measure_gf_s(V) /
171 (lattice.volume() * NDIM * (NDIM - 1) / 2);
174 atype plaq = measure_s_wplaq(V, max_plaq) /
175 (lattice.volume() * NDIM * (NDIM - 1) / 2);
176 atype eplaq = plaq * NDIM * (NDIM - 1) *
182 measure_topo_charge_and_energy_clover(V, qtopocl, ecl);
183 ecl /= lattice.volume();
187 atype qtopolog, elog;
188 measure_topo_charge_and_energy_log(V, qtopolog, elog);
189 elog /= lattice.volume();
192 atype deplaqdt = measure_dE_wplaq_dt(V) / lattice.volume();
195 atype declovdt = measure_dE_clov_dt(V) / lattice.volume();
198 atype delogdt = measure_dE_log_dt(V) / lattice.volume();
201 hila::out0 << string_format(
"GFLMEAS % 9.3f % 0.6e % 0.6e % 0.6e % 0.6e % 0.6e % 0.6e % 0.6e "
202 "% 0.6e % 0.6e % 0.6e [%0.3e] [%0.3e]",
203 flow_l, slocal, plaq, eplaq, 0.25 * flow_l * deplaqdt, ecl,
204 0.25 * flow_l * declovdt, qtopocl, elog, 0.25 * flow_l * delogdt,
205 qtopolog, t_step, max_plaq)
209template <
typename group,
typename atype = hila::arithmetic_type<group>>
210atype do_gradient_flow_adapt(
GaugeField<group> &V, atype l_start, atype l_end, atype atol = 1.0e-6,
211 atype rtol = 1.0e-4, atype tstep = 0.0) {
219 atype iesp = 1.0 / esp;
222 atype maxstepmf = 10.0;
223 atype minstepmf = 0.1;
227 atype t = l_start * l_start / 8.0;
228 atype tmax = l_end * l_end / 8.0;
230 atype ubstep = (tmax - t) / 2.0;
232 atype tatol = atol *
sqrt(2.0);
252 atype a21 = -17.0 / 36.0, a22 = 8.0 / 9.0;
263 atype b21 = -1.25, b22 = 2.0;
265 atype step = min(tstep, ubstep);
267 if (t == 0 || step == 0) {
273 atype maxstk = 1.0e-1;
280 reldiff[X] = (tk[d][X].squarenorm());
282 atype tmaxtk = reldiff.
max();
287 maxtk =
sqrt(0.5 * maxtk);
290 if (maxtk > maxstk) {
291 step = min(maxstk / maxtk,
293 hila::out0 <<
"GFINFO using max. gauge force (max_X |F(X)|=" << maxtk
294 <<
") to set initial flow time step size: " << step <<
"\n";
296 step = min((atype)1.0, ubstep);
298 }
else if (step * maxtk > maxstk) {
299 step = min(maxstk / maxtk,
301 hila::out0 <<
"GFINFO using max. gauge force (max_X |F(X)|=" << maxtk
302 <<
") to set initial flow time step size: " << step <<
"\n";
309 while (t < tmax && !stop) {
311 if (t + step >= tmax) {
319 V[d][X] =
chexp(k1[d][X] * (step * a11)) * V[d][X];
327 tk[d][X] *= (step * b22);
328 tk[d][X] += k1[d][X] * (step * b21);
329 V2[d][X] =
chexp(tk[d][X]) * V[d][X];
332 k2[d][X] *= (step * a22);
333 k2[d][X] += k1[d][X] * (step * a21);
334 V[d][X] =
chexp(k2[d][X]) * V[d][X];
340 k1[d][X] *= (step * a33);
341 k1[d][X] -= k2[d][X];
342 V[d][X] =
chexp(k1[d][X]) * V[d][X];
350 reldiff[X] = (V2[d][X] * V[d][X].dagger()).project_to_algebra().
norm() /
351 (tatol + rtol * tk[d][X].norm() / step);
355 atype trelerr = reldiff.
max();
356 if (trelerr > relerr) {
373 stepmf =
pow(relerr, -iesp);
374 if (stepmf <= minstepmf) {
376 }
else if (stepmf >= maxstepmf) {
381 step = min((atype)0.9 * stepmf * step, ubstep);
Array< n, m, T > sqrt(Array< n, m, T > a)
Square root.
Array< n, m, T > pow(Array< n, m, T > a, int b)
Power.
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
T max(Parity par=ALL) const
Find maximum value from Field.
void reunitarize_gauge()
Reunitarize Gauge Field consisting of matrices.
Special reduction class: enables delayed and non-blocking reductions, which are not possible with the...
const T value()
Return value of the reduction variable. Wait for the comms if needed.
Reduction & allreduce(bool b=true)
allreduce(bool) turns allreduce on or off. By default on.
Reduction & delayed(bool b=true)
deferred(bool) turns deferred on or off. By default turns on.
#define foralldir(d)
Macro to loop over (all) Direction(s)
constexpr Parity ALL
bit pattern: 011
int chexp(const Matrix_t< n, m, T, MT > &mat, Matrix_t< n, m, T, MT > &omat, Mt(&pl)[n])
Calculate exp of a square matrix.
std::ostream out0
This writes output only from main process (node 0)