HILA
Loading...
Searching...
No Matches
suN_hmc_stout_comp.cpp
1#include "hila.h"
2#include "gauge/polyakov.h"
4
5#ifndef NCOLOR
6#define NCOLOR 3
7#endif
8
9#ifdef HMCACTION
10#define HMCS HMCACTION
11#else
12#define HMCS 1
13#endif
14
15#if HMCS == 1
17#elif HMCS > 1
19#if HMCS < 5
21#elif HMCS == 5
23#endif
24#endif
25
26
27#include "gauge/gradient_flow.h"
28#include "tools/string_format.h"
30
31#ifdef STOUTSMEAR
32hila::timer sms_timer("Smearing (action)");
33hila::timer smf_timer("Smearing (force)");
34#if defined STOUTMODE && STOUTMODE>0
35#if STOUTMODE==1
36#include "gauge/stout_smear_nch.h"
37#elif STOUTMODE==2
38#include "gauge/stout_smear_nchm.h"
39#else
40#include "gauge/stout_smear.h"
41#endif
42#else
43#define STOUTMODE 0
44#include "gauge/stout_smear.h"
45#endif
46#define STOUTSTEPS STOUTSMEAR
47#else
48#define STOUTSTEPS 0
49#endif
50
51
52using ftype = double;
54
55ftype stoutc = 0.5;
56int stout_nsteps = STOUTSTEPS;
57
58
59// define a struct to hold the input parameters: this
60// makes it simpler to pass the values around
61struct parameters {
62 ftype beta; // inverse gauge coupling
63 ftype dt; // HMC time step
64 int trajlen; // number of HMC time steps per trajectory
65 int n_traj; // number of trajectories to generate
66 int n_therm; // number of thermalization trajectories (counts only accepted traj.)
67 int gflow_freq; // number of trajectories between gflow measurements
68 ftype gflow_max_l; // flow scale at which gradient flow stops
69 ftype gflow_l_step; // flow scale interval between flow measurements
70 ftype gflow_a_accu; // desired absolute accuracy of gradient flow integration steps
71 ftype gflow_r_accu; // desired relative accuracy of gradient flow integration steps
72 int n_save; // number of trajectories between config. check point
73 std::string config_file;
74 ftype time_offset;
75};
76
77
78///////////////////////////////////////////////////////////////////////////////////
79// HMC functions
80
81template <typename group, typename atype = hila::arithmetic_type<group>>
82double measure_s(const GaugeField<group> &U) {
83 // compute the value of the chosen gauge action (without beta/N factor)
84#if STOUTSTEPS > 0
85 sms_timer.start();
87#if STOUTMODE == 0
88 stout_smear(U, tU, stoutc, stout_nsteps);
89#elif STOUTMODE == 1
90 nch_stout_smear(U, tU, stoutc, stout_nsteps);
91#elif STOUTMODE == 2
92 std::vector<std::array<Field<int>, NDIM>> niterl(stout_nsteps);
93 nchm_stout_smear(U, tU, niterl, stoutc);
94 int maxiter = 0;
95 for(int i=0; i<niterl.size(); ++i) {
96 maxiter = 0;
97 Field<double> titerl;
98 foralldir(d) {
99 onsites(ALL) {
100 titerl[X] = (double)niterl[i][d][X];
101 }
102 int tmaxiter = titerl.max();
103 if(tmaxiter>maxiter) {
104 maxiter = tmaxiter;
105 }
106 }
107 hila::out0 << "stout step "<<i<<" exp niter: " << maxiter << "\n";
108 }
109#else
110 stout_smear(U, tU, stoutc, stout_nsteps);
111#endif
112 sms_timer.stop();
113#else
114
115 const GaugeField<group> &tU = U;
116
117#endif
118
119#if HMCS == 1 // BP
120 double res = measure_s_bp(tU);
121#elif HMCS == 2 // LW
122 atype c12 = -1.0 / 12.0; // rectangle weight
123 atype c11 = 1.0 - 8.0 * c12; // plaquette weight
124 double res = measure_s_impr(tU, c11, c12);
125#elif HMCS == 3 // IWASAKI
126 atype c12 = -0.331; // rectangle weight
127 atype c11 = 1.0 - 8.0 * c12; // plaquette weight
128 double res = measure_s_impr(tU, c11, c12);
129#elif HMCS == 4 // DBW2
130 atype c12 = -1.4088; // rectangle weight
131 atype c11 = 1.0 - 8.0 * c12; // plaquette weight
132 double res = measure_s_impr(tU, c11, c12);
133#elif HMCS == 5 // LOG-PLAQUETTE
134 double res = measure_s_log_plaq(tU);
135#else // WILSON
136 double res = measure_s_wplaq(tU);
137#endif // END HMCS
138
139 return res;
140}
141
142template <typename group, typename atype = hila::arithmetic_type<group>>
143void update_E(const GaugeField<group> &U, VectorField<Algebra<group>> &E, atype delta) {
144 // compute the force for the chosen action and use it to evolve E
145 atype eps = delta / group::size();
146
147#if STOUTSTEPS > 0
148 sms_timer.start();
149 std::vector<GaugeField<group>> tUl(stout_nsteps + 1);
150 std::vector<VectorField<group>> tstapl(stout_nsteps);
151
152#if STOUTMODE == 0
153 stout_smear(U, tUl, tstapl, stoutc);
154#elif STOUTMODE == 1
155 nch_stout_smear(U, tUl, tstapl, stoutc);
156#elif STOUTMODE == 2
157 std::vector<std::array<Field<int>, NDIM>> niterl(stout_nsteps);
158 nchm_stout_smear(U, tUl, tstapl, niterl, stoutc);
159#else
160 std::vector<VectorField<group>> tUKl(stout_nsteps);
161 stout_smeark(U, tUl, tstapl, tUKl, stoutc);
162#endif
163
165
166 foralldir(d1) onsites(ALL) tE[d1][X] = 0;
167
168 GaugeField<group> &tU = tUl[stout_nsteps];
169 sms_timer.stop();
170
171#else // STOUTSTEPS==0
172
173 const GaugeField<group> &tU = U;
175
176#endif // END STOUTSTEPS
177
178#if HMCS == 1 // BP
179 get_force_bp_add(tU, tE, eps);
180#elif HMCS == 2 // LW
181 atype c12 = -1.0 / 12.0; // rectangle weight
182 atype c11 = 1.0 - 8.0 * c12; // plaquette weight
183 get_force_impr_add(tU, tE, eps * c11, eps * c12);
184#elif HMCS == 3 // IWASAKI
185 atype c12 = -0.331; // rectangle weight
186 atype c11 = 1.0 - 8.0 * c12; // plaquette weight
187 get_force_impr_add(tU, tE, eps * c11, eps * c12);
188#elif HMCS == 4 // DBW2
189 atype c12 = -1.4088; // rectangle weight
190 atype c11 = 1.0 - 8.0 * c12; // plaquette weight
191 get_force_impr_add(tU, tE, eps * c11, eps * c12);
192#elif HMCS == 5 // LOG-PLAQUETTE
193 get_force_log_plaq_add(tU, tE, eps);
194#else // WILSON
195 get_force_wplaq_add(tU, tE, eps);
196#endif // END HMCS
197
198#if STOUTSTEPS > 0
199 smf_timer.start();
201
202#if STOUTMODE == 0
203 stout_smear_force(tUl, tstapl, tE, KS, stoutc);
204#elif STOUTMODE == 1
205 nch_stout_smear_force(tUl, tstapl, tE, KS, stoutc);
206#elif STOUTMODE == 2
207 nchm_stout_smear_force(tUl, tstapl, tE, KS, niterl, stoutc);
208#else
209 stout_smeark_force(tUl, tstapl, tUKl, tE, KS, stoutc);
210#endif
211
212 foralldir(d1) {
213 onsites(ALL) E[d1][X] += KS[d1][X];
214 }
215 smf_timer.stop();
216#endif // END STOUTSTEPS
217
218}
219
220template <typename group, typename atype = hila::arithmetic_type<group>>
221void update_U(GaugeField<group> &U, const VectorField<Algebra<group>> &E, atype delta) {
222 // evolve U with momentum E over time step delta
223 foralldir(d) {
224 onsites(ALL) U[d][X] = chexp(E[d][X].expand_scaled(delta)) * U[d][X];
225 }
226}
227
228template <typename group>
229double measure_e2(const VectorField<Algebra<group>> &E) {
230 // compute gauge kinetic energy from momentum field E
231 Reduction<double> e2 = 0;
232 e2.allreduce(false).delayed(true);
233 foralldir(d) {
234 onsites(ALL) e2 += E[d][X].squarenorm();
235 }
236 return e2.value() / 2;
237}
238
239template <typename group>
240double measure_action(const GaugeField<group> &U, const VectorField<Algebra<group>> &E,
241 const parameters &p, double &plaq) {
242 // measure the total action, consisting of plaquette and momentum term
243 plaq = p.beta * measure_s(U);
244 double e2 = measure_e2(E);
245 return plaq + e2 / 2;
246}
247
248template <typename group>
249double measure_action(const GaugeField<group> &U, const VectorField<Algebra<group>> &E,
250 const parameters &p) {
251 // measure the total action, consisting of plaquette and momentum term
252 double plaq = 0;
253 return measure_action(U, E, p, plaq);
254}
255
256
257template <typename group, typename atype = hila::arithmetic_type<group>>
258void do_trajectory(GaugeField<group> &U, VectorField<Algebra<group>> &E, const parameters &p) {
259 // leap frog integration for normal action
260
261 // start trajectory: advance U by half a time step
262 update_U(U, E, p.dt / 2);
263 // main trajectory integration:
264 for (int n = 0; n < p.trajlen - 1; ++n) {
265 update_E(U, E, p.beta * p.dt);
266 update_U(U, E, p.dt);
267 }
268 // end trajectory: bring U and E to the same time
269 update_E(U, E, p.beta * p.dt);
270 update_U(U, E, p.dt / 2);
271
273}
274
275// end HMC functions
276///////////////////////////////////////////////////////////////////////////////////
277// measurement functions
278
279template <typename group>
281 // perform measurements on current gauge and momentum pair (U, E) and
282 // print results in formatted form to standard output
283 static bool first = true;
284 if (first) {
285 // print legend for measurement output
287 << "LMEAS: s-local plaq E^2 P.real P.imag\n";
288 first = false;
289 }
290 auto slocal = measure_s(U) / (lattice.volume() * NDIM * (NDIM - 1) / 2);
291 auto plaq = measure_s_wplaq(U) / (lattice.volume() * NDIM * (NDIM - 1) / 2);
292 auto e2 = measure_e2(E) / (lattice.volume() * NDIM);
293 auto poly = measure_polyakov(U, e_t);
294 hila::out0 << string_format("MEAS % 0.6e % 0.6e % 0.6e % 0.6e % 0.6e", slocal, plaq, e2,
295 poly.real(), poly.imag())
296 << '\n';
297}
298
299// end measurement functions
300///////////////////////////////////////////////////////////////////////////////////
301// load/save config functions
302
303template <typename group>
304void checkpoint(const GaugeField<group> &U, int trajectory, const parameters &p) {
305 double t = hila::gettime();
306 // name of config with extra suffix
307 std::string config_file =
308 p.config_file + "_" + std::to_string(abs((trajectory + 1) / p.n_save) % 2);
309 // save config
310 U.config_write(config_file);
311 // write run_status file
312 if (hila::myrank() == 0) {
313 std::ofstream outf;
314 outf.open("run_status", std::ios::out | std::ios::trunc);
315 outf << "trajectory " << trajectory + 1 << '\n';
316 outf << "seed " << static_cast<uint64_t>(hila::random() * (1UL << 61)) << '\n';
317 outf << "time " << hila::gettime() << '\n';
318 // write config name to status file:
319 outf << "config name " << config_file << '\n';
320 outf.close();
321 }
322 std::stringstream msg;
323 msg << "Checkpointing, time " << hila::gettime() - t;
324 hila::timestamp(msg.str().c_str());
325}
326
327template <typename group>
328bool restore_checkpoint(GaugeField<group> &U, int &trajectory, parameters &p) {
329 uint64_t seed;
330 bool ok = true;
331 p.time_offset = 0;
332 hila::input status;
333 if (status.open("run_status", false, false)) {
334 hila::out0 << "RESTORING FROM CHECKPOINT:\n";
335 trajectory = status.get("trajectory");
336 seed = status.get("seed");
337 p.time_offset = status.get("time");
338 // get config name with suffix from status file:
339 std::string config_file = status.get("config name");
340 status.close();
341 hila::seed_random(seed);
342 U.config_read(config_file);
343 ok = true;
344 } else {
345 std::ifstream in;
346 in.open(p.config_file, std::ios::in | std::ios::binary);
347 if (in.is_open()) {
348 in.close();
349 hila::out0 << "READING initial config\n";
350 U.config_read(p.config_file);
351 ok = true;
352 } else {
353 ok = false;
354 }
355 }
356 return ok;
357}
358
359// end load/save config functions
360///////////////////////////////////////////////////////////////////////////////////
361
362
363int main(int argc, char **argv) {
364
365 // hila::initialize should be called as early as possible
366 hila::initialize(argc, argv);
367
368 // hila provides an input class hila::input, which is
369 // a convenient way to read in parameters from input files.
370 // parameters are presented as key - value pairs, as an example
371 // " lattice size 64, 64, 64, 64"
372 // is read below.
373 //
374 // Values are broadcast to all MPI nodes.
375 //
376 // .get() -method can read many different input types,
377 // see file "input.h" for documentation
378
379#if HMCS == 1
380 hila::out0 << "SU(" << mygroup::size() << ") HMC with bulk-prevention gauge action\n";
381#elif HMCS == 2
382 hila::out0 << "SU(" << mygroup::size() << ") HMC with Luscher-Weisz gauge action\n";
383#elif HMCS == 3
384 hila::out0 << "SU(" << mygroup::size() << ") HMC with Iwasaki gauge action\n";
385#elif HMCS == 4
386 hila::out0 << "SU(" << mygroup::size() << ") HMC with DBW2 gauge action\n";
387#elif HMCS == 5
388 hila::out0 << "SU(" << mygroup::size() << ") HMC with log-plaquette gauge action\n";
389#elif HMCS == 6
390 hila::out0 << "SU(" << mygroup::size() << ") HMC with topology suppressing gauge action\n";
391#else
392 hila::out0 << "SU(" << mygroup::size() << ") HMC with Wilson's plaquette gauge action\n";
393#endif
394
395 hila::out0 << "Using floating point epsilon: " << fp<ftype>::epsilon << "\n";
396
397 parameters p;
398
399 hila::input par("parameters");
400
401 CoordinateVector lsize;
402 // reads NDIM numbers
403 lsize = par.get("lattice size");
404 // inverse gauge coupling
405 p.beta = par.get("beta");
406 // HMC step size
407 p.dt = par.get("dt");
408 // trajectory length in steps
409 p.trajlen = par.get("trajectory length");
410 // number of trajectories
411 p.n_traj = par.get("number of trajectories");
412 // number of thermalization trajectories
413 p.n_therm = par.get("thermalization trajs");
414 // wilson flow frequency (number of traj. between w. flow measurement)
415 p.gflow_freq = par.get("gflow freq");
416 // wilson flow max. flow-distance
417 p.gflow_max_l = par.get("gflow max lambda");
418 // wilson flow flow-distance step size
419 p.gflow_l_step = par.get("gflow lambda step");
420 // wilson flow absolute accuracy (per integration step)
421 p.gflow_a_accu = par.get("gflow abs. accuracy");
422 // wilson flow relative accuracy (per integration step)
423 p.gflow_r_accu = par.get("gflow rel. accuracy");
424 // random seed = 0 -> get seed from time
425 long seed = par.get("random seed");
426 // save config and checkpoint
427 p.n_save = par.get("trajs/saved");
428 // measure surface properties and print "profile"
429 p.config_file = par.get("config name");
430
431 par.close(); // file is closed also when par goes out of scope
432
433#if STOUTSTEPS > 0
434 hila::out0 << "using stout smearing: nsteps=" << stout_nsteps << " , c=" << stoutc << " , ";
435#if STOUTMODE == 0
436 hila::out0 << "mode=CH\n";
437#elif STOUTMODE == 1
438 hila::out0 << "mode=NCH\n";
439#elif STOUTMODE == 2
440 hila::out0 << "mode=NCHM\n";
441#else
442 hila::out0 << "mode=CHK\n";
443#endif
444#endif
445
446 // set up the lattice
447 lattice.setup(lsize);
448
449 // We need random number here
450 hila::seed_random(seed);
451
452 // Alloc gauge field and momenta (E)
455
456 int start_traj = 0;
457 if (!restore_checkpoint(U, start_traj, p)) {
458 U = 1;
459 hila::out0 << "cold start: initial link variables set to identity\n";
460 }
461
462 hila::timer update_timer("Updates");
463 hila::timer measure_timer("Measurements");
464 hila::timer gf_timer("Gradient Flow");
465
466 auto orig_dt = p.dt;
467 auto orig_trajlen = p.trajlen;
469 int nreject = 0;
470 ftype t_step0 = 0.0;
471 double g_act_old, act_old, g_act_new, act_new;
472 g_act_old = p.beta * measure_s(U);
473
474 for (int trajectory = start_traj; trajectory < p.n_traj; ++trajectory) {
475 if (trajectory < p.n_therm) {
476 // during thermalization: start with 10% of normal step size (and trajectory length)
477 // and increse linearly with number of accepted thermalization trajectories. normal
478 // step size is reached after 3/4*p.n_therm accepted thermalization trajectories.
479 if (trajectory < p.n_therm * 3.0 / 4.0) {
480 p.dt = orig_dt * (0.1 + 0.9 * 4.0 / 3.0 * trajectory / p.n_therm);
481 p.trajlen = orig_trajlen;
482 } else {
483 p.dt = orig_dt;
484 p.trajlen = orig_trajlen;
485 }
486 if (nreject > 1) {
487 // if two consecutive thermalization trajectories are rejected, decrese the
488 // step size by factor 0.5 (but keeping trajectory length constant, since
489 // thermalization becomes inefficient if trajectory length decreases)
490 for (int irej = 0; irej < nreject - 1; ++irej) {
491 p.dt *= 0.5;
492 p.trajlen *= 2;
493 }
494 hila::out0 << " thermalization step size(reduzed due to multiple reject) dt="
495 << std::setprecision(8) << p.dt << '\n';
496 } else {
497 hila::out0 << " thermalization step size dt=" << std::setprecision(8) << p.dt
498 << '\n';
499 }
500 } else if (trajectory == p.n_therm) {
501 p.dt = orig_dt;
502 p.trajlen = orig_trajlen;
503 hila::out0 << " normal stepsize dt=" << std::setprecision(8) << p.dt << '\n';
504 }
505
506 update_timer.start();
507
508 U_old = U;
509 ftype ttime = hila::gettime();
510
511 foralldir(d) onsites(ALL) E[d][X].gaussian_random();
512
513 act_old = g_act_old + measure_e2(E) / 2;
514
515 do_trajectory(U, E, p);
516
517 act_new = measure_action(U, E, p, g_act_new);
518
519
520 bool reject = hila::broadcast(exp(act_old - act_new) < hila::random());
521
522 if (trajectory < p.n_therm) {
523 // during thermalization: keep track of number of rejected trajectories
524 if (reject) {
525 ++nreject;
526 --trajectory;
527 } else {
528 if (nreject > 0) {
529 --nreject;
530 }
531 }
532 }
533
534 hila::out0 << std::setprecision(12) << "HMC " << trajectory << " S_TOT_start " << act_old
535 << " dS_TOT " << std::setprecision(6) << act_new - act_old
536 << std::setprecision(12);
537 if (reject) {
538 hila::out0 << " REJECT" << " --> S_GAUGE " << g_act_old;
539 U = U_old;
540 } else {
541 hila::out0 << " ACCEPT" << " --> S_GAUGE " << g_act_new;
542 g_act_old = g_act_new;
543 }
544 update_timer.stop();
545
546 hila::out0 << " time " << std::setprecision(3) << hila::gettime() - ttime << '\n';
547
548
549 hila::out0 << "Measure_start " << trajectory << '\n';
550
551 measure_timer.start();
552
553 measure_stuff(U, E);
554
555 measure_timer.stop();
556
557 hila::out0 << "Measure_end " << trajectory << '\n';
558
559 if (trajectory >= p.n_therm) {
560
561 if (p.gflow_freq > 0 && trajectory % p.gflow_freq == 0) {
562 int gtrajectory = trajectory / p.gflow_freq;
563 if (p.gflow_l_step > 0) {
564
565 gf_timer.start();
566
567 int nflow_steps = (int)(p.gflow_max_l / p.gflow_l_step);
568
569 ftype gftime = hila::gettime();
570 hila::out0 << "Gflow_start " << gtrajectory << '\n';
571
573
574 ftype t_step = t_step0;
575 measure_gradient_flow_stuff(V, (ftype)0.0, t_step);
576 t_step = do_gradient_flow_adapt(V, (ftype)0.0, p.gflow_l_step, p.gflow_a_accu,
577 p.gflow_r_accu, t_step);
578 measure_gradient_flow_stuff(V, p.gflow_l_step, t_step);
579 t_step0 = t_step;
580
581 for (int i = 1; i < nflow_steps; ++i) {
582
583 t_step =
584 do_gradient_flow_adapt(V, i * p.gflow_l_step, (i + 1) * p.gflow_l_step,
585 p.gflow_a_accu, p.gflow_r_accu, t_step);
586
587 measure_gradient_flow_stuff(V, (i + 1) * p.gflow_l_step, t_step);
588 }
589
590 gf_timer.stop();
591
592 hila::out0 << "Gflow_end " << gtrajectory << " time " << std::setprecision(3)
593 << hila::gettime() - gftime << '\n';
594 }
595 }
596 }
597
598 if (p.n_save > 0 && trajectory>=0 && (trajectory + 1) % p.n_save == 0) {
599 checkpoint(U, trajectory, p);
600 }
601 }
602
604}
Array< n, m, T > exp(Array< n, m, T > a)
Exponential.
Definition array.h:1059
Definition su2.h:7
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Definition field.h:61
T max(Parity par=ALL) const
Find maximum value from Field.
Definition reduction.h:424
Gauge field class.
Definition gaugefield.h:22
void reunitarize_gauge()
Reunitarize Gauge Field consisting of matrices.
Definition gaugefield.h:94
void config_write(const std::string &filename) const
config_write writes the gauge field to file, with additional "verifying" header
Definition gaugefield.h:155
static constexpr int size()
Returns size of Vector or square Matrix.
Definition matrix.h:248
Special reduction class: enables delayed and non-blocking reductions, which are not possible with the...
Definition reduction.h:14
const T value()
Return value of the reduction variable. Wait for the comms if needed.
Definition reduction.h:157
Reduction & allreduce(bool b=true)
allreduce(bool) turns allreduce on or off. By default on.
Definition reduction.h:130
Reduction & delayed(bool b=true)
deferred(bool) turns deferred on or off. By default turns on.
Definition reduction.h:148
Class for SU(N) matrix.
Definition sun_matrix.h:110
hila::input - Class for parsing runtime parameter files.
Definition input.h:52
void close()
Closes input parameter file.
Definition input.cpp:79
returntype get(const std::string &key)
Get next value in stack of read in input string from parameters file.
Definition input.h:269
bool open(const std::string &fname, bool use_cmdline=true, bool exit_on_error=true)
Open file that parameters are read from.
Definition input.cpp:22
void setup(const CoordinateVector &siz)
General lattice setup.
Definition lattice.cpp:33
T abs(const Complex< T > &a)
Return absolute value of Complex number.
Definition cmplx.h:1187
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:78
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.
Definition matrix.h:2933
double random()
Real valued uniform random number generator.
Definition hila_gpu.cpp:121
int myrank()
rank of this node
Definition com_mpi.cpp:234
std::ostream out0
This writes output only from main process (node 0)
void initialize(int argc, char **argv)
Read in command line arguments. Initialise default stream and MPI communication.
void seed_random(uint64_t seed, bool device_rng=true)
Seed random generators with 64-bit unsigned value. On MPI shuffles the seed so that different MPI ran...
Definition random.cpp:86
T broadcast(T &var, int rank=0)
Broadcast the value of var to all MPI ranks from rank (default=0).
Definition com_mpi.h:152
double gettime()
Definition timing.cpp:163
void finishrun()
Normal, controlled exit - all nodes must call this. Prints timing information and information about c...
Complex< double > measure_polyakov(const GaugeField< T > &U, Direction dir=Direction(NDIM - 1))
Measure Polyakov lines to direction dir.
Definition polyakov.h:17
void do_trajectory(GaugeField< group > &U, const parameters &p)
Evolve gauge field.
void measure_stuff(const GaugeField< group > &U, const parameters &p)
Measures Polyakov lines and Wilson action.
Definition suN_gauge.cpp:41