3#ifndef GRADIENT_FLOW_H_
4#define GRADIENT_FLOW_H_
14#define GFLOWS GFLOWACTION
29template <
typename group,
typename atype = hila::arithmetic_type<group>>
41 get_force_bp(U, E, eps);
43 atype c12 = -1.0 / 12.0;
44 atype c11 = 1.0 - 8.0 * c12;
45 get_force_impr(U, E, eps * c11, eps * c12);
48 atype c11 = 1.0 - 8.0 * c12;
49 get_force_impr(U, E, eps * c11, eps * c12);
52 atype c11 = 1.0 - 8.0 * c12;
53 get_force_impr(U, E, eps * c11, eps * c12);
55 get_force_clover(U, E, eps);
57 get_force_log(U, E, eps);
59 get_force_wplaq(U, E, eps);
67template <
typename group,
typename atype = hila::arithmetic_type<group>>
72 atype res = measure_s_bp(U);
74 atype c12 = -1.0 / 12.0;
75 atype c11 = 1.0 - 8.0 * c12;
76 atype res = measure_s_impr(U, c11, c12);
79 atype c11 = 1.0 - 8.0 * c12;
80 atype res = measure_s_impr(U, c11, c12);
83 atype c11 = 1.0 - 8.0 * c12;
84 atype res = measure_s_impr(U, c11, c12);
86 atype res = measure_s_clover(U);
88 atype res = measure_s_log(U);
90 atype res = measure_s_wplaq(U);
99template <
typename group,
typename atype = hila::arithmetic_type<group>>
105 get_force_wplaq(U, Kc, 2.0);
108 de += Kc[d][X].dot(K[d][X]);
111 return (atype)de.
value();
114template <
typename group,
typename atype = hila::arithmetic_type<group>>
120 get_force_clover(U, Kc, 2.0);
123 de += Kc[d][X].dot(K[d][X]);
126 return (atype)de.
value();
129template <
typename group,
typename atype = hila::arithmetic_type<group>>
135 get_force_log(U, Kc, 2.0);
138 de += Kc[d][X].dot(K[d][X]);
141 return (atype)de.
value();
144template <
typename group,
typename atype = hila::arithmetic_type<group>>
145void measure_gradient_flow_stuff(
const GaugeField<group> &V, atype flow_l, atype t_step) {
149 static bool first =
true;
153 hila::out0 <<
"GFINFO using bulk-prevention action\n";
155 hila::out0 <<
"GFINFO using Luscher-Weisz action\n";
157 hila::out0 <<
"GFINFO using Iwasaki action\n";
163 hila::out0 <<
"GFINFO using log-clover action\n";
165 hila::out0 <<
"GFINFO using Wilson's plaquette action\n";
168 hila::out0 <<
"LGFLMEAS l(ambda) S-flow S-plaq E_plaq dE_plaq/dl "
169 " E_clv dE_clv/dl Qtopo_clv E_log dE_log/dl "
170 "Qtopo_log [t step size]\n";
173 atype slocal = measure_gf_s(V) /
174 (lattice.volume() * NDIM * (NDIM - 1) / 2);
175 atype plaq = measure_s_wplaq(V) /
176 (lattice.volume() * NDIM * (NDIM - 1) / 2);
177 atype eplaq = plaq * NDIM * (NDIM - 1) *
182 atype qtopolog, elog;
183 measure_topo_charge_and_energy_log(V, qtopolog, elog);
184 elog /= lattice.volume();
189 measure_topo_charge_and_energy_clover(V, qtopocl, ecl);
190 ecl /= lattice.volume();
193 atype deplaqdt = measure_dE_wplaq_dt(V) / lattice.volume();
196 atype declovdt = measure_dE_clov_dt(V) / lattice.volume();
199 atype delogdt = measure_dE_log_dt(V) / lattice.volume();
202 hila::out0 << string_format(
"GFLMEAS % 9.3f % 0.6e % 0.6e % 0.6e % 0.6e % 0.6e % 0.6e % 0.6e "
203 "% 0.6e % 0.6e % 0.6e [%0.3e]",
204 flow_l, slocal, plaq, eplaq, 0.25 * flow_l * deplaqdt, ecl,
205 0.25 * flow_l * declovdt, qtopocl, elog, 0.25 * flow_l * delogdt,
210template <
typename group,
typename atype = hila::arithmetic_type<group>>
211atype do_gradient_flow_adapt(
GaugeField<group> &V, atype l_start, atype l_end, atype atol = 1.0e-6,
212 atype rtol = 1.0e-6, atype tstep = 0.0) {
221 atype iesp = 1.0 / esp;
223 atype maxstepmf = 1.0e2;
224 atype minmaxreldiff =
pow(maxstepmf, -esp);
229 atype t = l_start * l_start / 8.0;
230 atype tmax = l_end * l_end / 8.0;
232 atype tatol =
sqrt(2.0) * atol;
253 atype a21 = -17.0 / 36.0, a22 = 8.0 / 9.0;
264 atype b21 = -1.25, b22 = 2.0;
266 atype step = min(min(tstep, (atype)0.501 * (tmax - t)), ubstep);
268 if (t == 0 || step == 0) {
274 atype maxstk = 1.0e-1;
281 reldiff[X] = (tk[d][X].squarenorm());
283 atype tmaxtk = reldiff.
max();
288 maxtk =
sqrt(0.5 * maxtk);
291 if (maxtk > maxstk) {
292 step = 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";
298 }
else if (step * maxtk > maxstk) {
299 step = maxstk / maxtk;
300 hila::out0 <<
"GFINFO using max. gauge force (max_X |F(X)|=" << maxtk
301 <<
") to set initial flow time step size: " << step <<
"\n";
309 while (t < tmax && !stop) {
310 if (t + step >= tmax) {
315 if (t + 2.0 * step >= tmax) {
316 step = 0.501 * (tmax - t);
323 V[d][X] =
chexp(k1[d][X] * (step * a11)) * V[d][X];
331 tk[d][X] *= (step * b22);
332 tk[d][X] += k1[d][X] * (step * b21);
333 V2[d][X] =
chexp(tk[d][X]) * V[d][X];
336 k2[d][X] *= (step * a22);
337 k2[d][X] += k1[d][X] * (step * a21);
338 V[d][X] =
chexp(k2[d][X]) * V[d][X];
344 k1[d][X] *= (step * a33);
345 k1[d][X] -= k2[d][X];
346 V[d][X] =
chexp(k1[d][X]) * V[d][X];
351 atype maxreldiff = 0.0;
354 reldiff[X] = (V2[d][X] * V[d][X].dagger()).project_to_algebra().
norm() /
355 (tatol + rtol * tk[d][X].norm());
357 atype tmaxreldiff = reldiff.
max();
358 if (tmaxreldiff > maxreldiff) {
359 maxreldiff = tmaxreldiff;
363 if (maxreldiff < 1.0) {
375 if (maxreldiff > minmaxreldiff) {
376 maxstep = step *
pow(maxreldiff, -iesp);
378 maxstep = step * maxstepmf;
382 step = min((atype)0.9 * maxstep, 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
void chexp(const Matrix_t< n, m, T, MT > &mat, Matrix_t< n, m, T, MT > &omat, Matrix_t< n, m, T, MT >(&pl)[n+1])
Calculate exp of a square matrix.
std::ostream out0
This writes output only from main process (node 0)