40 std::string config_file;
60template <
typename group>
62 bool relax,
const plaqw_t<ftype> &plaqw) {
72 staples_timer.start();
74 staplesum(U, staples, d, plaqw, par);
83 if(plaqw[d][d][X] != 0) {
84#ifdef SUN_OVERRELAX_dFJ
85 suN_overrelax_dFJ(U[d][X], staples[X], p.beta);
98 if (plaqw[d][d][X] != 0) {
116template <
typename group>
118 for (
int i = 0; i < 2 * NDIM; ++i) {
121 int tpar = 1 + (tdp % 2);
138template <
typename group>
140 for (
int n = 0; n < p.n_update; n++) {
141 for (
int i = 0; i <= p.n_overrelax; i++) {
153template <
typename group>
155 const plaqw_t<ftype> &plaqw) {
157 int obdlsize = lattice.
size(obd);
160 plaql.allreduce(
false).delayed(
true);
161 double normf = 2.0 / (NDIM * (NDIM - 1) * lattice.
volume() / obdlsize);
164 U[dir2].start_gather(dir1,
ALL);
165 U[dir1].start_gather(dir2,
ALL);
167 double tplq = (1.0 -
real(trace(U[dir1][X] * U[dir2][X + dir1] *
168 (U[dir2][X] * U[dir1][X + dir2]).
dagger())) /
170 plaqw[dir1][dir2][X] * normf;
171 int obdind = X.coordinate(obd);
172 if (dir1 != obd && dir2 != obd) {
173 plaql[obdind] += tplq;
175 if (obdind > 0 && obdind < obdlsize - 1) {
177 plaql[obdind] += tplq;
178 plaql[obdind + 1] += 0.5 * tplq;
179 }
else if (obdind == obdlsize - 2) {
180 plaql[obdind] += 0.5 * tplq;
181 plaql[obdind + 1] += tplq;
183 plaql[obdind] += 0.5 * tplq;
184 plaql[obdind + 1] += 0.5 * tplq;
191 return plaql.vector();
209 for (
int plane = lattice.
size(dir) - 2; plane >= 0; plane--) {
216#pragma hila safe_access(polyakov)
218 if (X.coordinate(dir) == plane) {
219 polyakov[X] = U[dir][X] * polyakov[X + dir];
226 ploopl.allreduce(
false).delayed(
true);
228 int obdlsize = lattice.
size(obd);
229 double normf = 1.0 / (lattice.
volume() / (lattice.
size(dir) * obdlsize));
231 onsites(
ALL)
if (X.coordinate(dir) == 0) {
232 ploopl[X.coordinate(obd)] += trace(polyakov[X]) * normf;
236 return ploopl.vector();
239template <
typename group>
243 static bool first =
true;
244#if BCOPEN >= 0 && BCOPEN < NDIM
247 hila::out0 <<
"LMPLAQPS: plaq[1] plaq[2] plaq[3] plaq[4] ...\n";
248 hila::out0 <<
"LMPOLPS: P[1].re P[1].im P[2].re P[2].im ...\n";
252 auto plaql = measure_s_wplaq_ps(U, obd, plaqw);
253 auto polyl = measure_polyakov_ps(U, obd, e_t);
255 for (
int i = 1; i < lattice.
size(obd); ++i) {
256 hila::out0 << string_format(
" % 0.6e", plaql[i]);
260 for (
int i = 1; i < lattice.
size(obd); ++i) {
270 auto plaq = measure_s_wplaq(U) / (lattice.
volume() * NDIM * (NDIM - 1) / 2);
272 hila::out0 << string_format(
"MEAS % 0.6e % 0.6e % 0.6e", plaq, poly.real(), poly.imag())
281template <
typename group>
282void checkpoint(
const GaugeField<group> &U,
int trajectory,
const parameters &p) {
285 std::string config_file =
286 p.config_file +
"_" + std::to_string(
abs((trajectory + 1) / p.n_save) % 2);
292 outf.open(
"run_status", std::ios::out | std::ios::trunc);
293 outf <<
"trajectory " << trajectory + 1 <<
'\n';
294 outf <<
"seed " <<
static_cast<uint64_t
>(
hila::random() * (1UL << 61)) <<
'\n';
297 outf <<
"config name " << config_file <<
'\n';
300 std::stringstream msg;
302 hila::timestamp(msg.str().c_str());
305template <
typename group>
311 if (status.
open(
"run_status",
false,
false)) {
313 trajectory = status.
get(
"trajectory");
314 seed = status.
get(
"seed");
315 p.time_offset = status.
get(
"time");
317 std::string config_file = status.
get(
"config name");
320 U.config_read(config_file);
324 in.open(p.config_file, std::ios::in | std::ios::binary);
328 U.config_read(p.config_file);
341int main(
int argc,
char **argv) {
359 hila::out0 <<
"Using floating point epsilon: " << fp<ftype>::epsilon <<
"\n";
367 lsize = par.get(
"lattice size");
369 p.beta = par.get(
"beta");
371 p.n_traj = par.get(
"number of trajectories");
373 p.n_update = par.get(
"updates in trajectory");
375 p.n_overrelax = par.get(
"overrelax steps");
377 p.n_therm = par.get(
"thermalization trajs");
379 p.gflow_freq = par.get(
"gflow freq");
381 p.gflow_max_l = par.get(
"gflow max lambda");
383 p.gflow_l_step = par.get(
"gflow lambda step");
385 p.gflow_a_accu = par.get(
"gflow abs. accuracy");
387 p.gflow_r_accu = par.get(
"gflow rel. accuracy");
389 long seed = par.get(
"random seed");
391 p.n_save = par.get(
"trajs/saved");
393 p.config_file = par.get(
"config name");
398 lattice.
setup(lsize);
407 plaqw_t<ftype> plaqw;
411 plaqw[d1][d2][X] = 1.0;
416#if BCOPEN>=0 && BCOPEN<NDIM
418 hila::out0 <<
"Using open boundary conditions in " << obd <<
"-direction\n";
422 if (X.coordinate(obd) == 0) {
423 plaqw[d1][d2][X] = 0;
425 if (X.coordinate(obd) == 1) {
426 if (d1 != obd && d2 != obd) {
427 plaqw[d1][d2][X] = 0.5;
430 if (X.coordinate(obd) == lattice.
size(obd) - 1) {
431 if (d1 != obd && d2 != obd) {
432 plaqw[d1][d2][X] = 0.5;
434 plaqw[d1][d2][X] = 0;
443 int start_traj = -p.n_therm;
445 if (!restore_checkpoint(U, start_traj, p)) {
455 for (
int trajectory = start_traj; trajectory < p.n_traj; ++trajectory) {
459 update_timer.start();
464 hila::synchronize_threads();
467 measure_timer.start();
469 hila::out0 <<
"Measure_start " << trajectory <<
'\n';
473 hila::out0 <<
"Measure_end " << trajectory <<
'\n';
475 measure_timer.stop();
477 if (trajectory >= 0) {
479 if (p.gflow_freq > 0 && trajectory % p.gflow_freq == 0) {
482 int gtrajectory = trajectory / p.gflow_freq;
483 if (p.gflow_l_step > 0) {
487 int nflow_steps = (int)(p.gflow_max_l / p.gflow_l_step);
489 hila::out0 <<
"Gflow_start " << gtrajectory <<
'\n';
493 ftype t_step = t_step0;
494 measure_gradient_flow_stuff(V, (ftype)0.0, t_step);
495 t_step = do_gradient_flow_adapt(V, (ftype)0.0, p.gflow_l_step, p.gflow_a_accu,
496 p.gflow_r_accu, t_step);
497 measure_gradient_flow_stuff(V, p.gflow_l_step, t_step);
500 for (
int i = 1; i < nflow_steps; ++i) {
503 do_gradient_flow_adapt(V, i * p.gflow_l_step, (i + 1) * p.gflow_l_step,
504 p.gflow_a_accu, p.gflow_r_accu, t_step);
506 measure_gradient_flow_stuff(V, (i + 1) * p.gflow_l_step, t_step);
509 hila::out0 <<
"Gflow_end " << gtrajectory <<
" time " << std::setprecision(3)
517 if (p.n_save > 0 && (trajectory + 1) % p.n_save == 0) {
518 checkpoint(U, trajectory, p);
Array< n, m, hila::arithmetic_type< T > > imag(const Array< n, m, T > &arg)
Return imaginary part of Array.
Array< n, m, hila::arithmetic_type< T > > real(const Array< n, m, T > &arg)
Return real part of Array.
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
void reunitarize_gauge()
Reunitarize Gauge Field consisting of matrices.
void config_write(const std::string &filename) const
config_write writes the gauge field to file, with additional "verifying" header
void setup(const CoordinateVector &siz)
lattice.setup(CoordinateVector size) - set up the base lattice. Called at the beginning of the progra...
int size(Direction d) const
lattice.size() -> CoordinateVector or lattice.size(d) -> int returns the dimensions of the lattice,...
int64_t volume() const
lattice.volume() returns lattice volume Can be used inside onsites()-loops
static constexpr int size()
Returns size of Vector or square Matrix.
Complex< T > dagger(const Complex< T > &val)
Return dagger of Complex number.
T abs(const Complex< T > &a)
Return absolute value of Complex number.
Parity
Parity enum with values EVEN, ODD, ALL; refers to parity of the site. Parity of site (x,...
#define foralldir(d)
Macro to loop over (all) Direction(s)
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
constexpr Parity ALL
bit pattern: 011
double random()
Real valued uniform random number generator.
int myrank()
rank of this node
std::ostream out0
This writes output only from main process (node 0)
void initialize(int argc, char **argv)
Initial setup routines.
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...
T broadcast(T &var, int rank=0)
Broadcast the value of var to all MPI ranks from rank (default=0).
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.
void update(GaugeField< group > &U, const parameters &p, bool relax)
Wrapper update function.
void update_parity_dir(GaugeField< group > &U, const parameters &p, Parity par, Direction d, bool relax)
Wrapper function to updated GaugeField per direction.
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.
double suN_heatbath(SU< N, T > &U, const SU< N, T > &staple, double beta)
heatbath
int suN_overrelax(SU< N, T > &U, const SU< N, T > &staple, Btype beta)
overrelaxation using matrix obtained from max_staple_sum_rot() routine