3#include "gauge/degauss.h"
6 #error "!!! Specify which SU(N) in Makefile: eg. -DNSU=3"
12std::ofstream measureFile;
16template <
typename group>
26 E[d][X] -= delta * (U[d][X] * staple[X].
dagger()).project_to_algebra();
31template <
typename group>
37 U[d][X] =
exp(E[d][X] * delta) * U[d][X];
43template <
typename group>
47 U[d][X].reunitarize();
52template <
typename group>
62 plaq += group::size() -
real(trace(U[dir1][X] * U[dir2][X + dir1] *
63 U[dir1][X + dir2].
dagger() *
80template <
typename group>
94 P1 = U[d2][X] * U[d3][X + d2] * U[d2][X + d3].dagger() * U[d3][X].dagger();
95 P2 = U[d3][X] * U[d2][X + d3 - d2].dagger() * U[d3][X - d2].dagger() * U[d2][X - d2];
96 P3 = U[d2][X - d2].dagger() * U[d3][X - d2 - d3].dagger() * U[d2][X - d3 - d2] * U[d3][X - d3];
97 P4 = U[d3][X - d3].dagger() * U[d2][X - d3] * U[d3][X + d2 - d3] * U[d2][X].dagger();
99 Q[X] = P1 + P2 + P3 + P4;
107 }
else if (d3 > d1) {
115 B[d1][X] += -(1.0/ 8.0) * sign * (Q[X] - Q[X].
dagger());
126template <
typename group>
129 double c_chi = 1.0 / (64.0 * M_PI*M_PI);
130 onsites(
ALL) result[X] = 0;
134 get_magnetic_field(U, B);
139 result[X] += 16.0 * c_chi *
real( trace(E[d1][X].expand() * B[d1][X]) );
146static double degauss_quality = 1e-12;
149template <
typename group>
152 auto plaq = measure_plaq(U);
156 e2 += E[d].squarenorm();
160 double energy = e2 + 2.0 * plaq;
163 get_gauss_violation(U, E, g);
172 E_imp[d1][X] = 0.5 * (E[d1][X] +
173 (U[d1][X-d1].dagger() * E[d1][X-d1].expand() * U[d1][X-d1]).project_to_algebra() );
175 calc_topoCharge(U, E_imp, chi);
177 double chi_avg = 0.0;
181 chi_avg /= lattice.volume();
185 sprintf(buf,
"%d %.10g %.8g %.8g %.8g %.8g %.8g", trajectory, t, plaq, e2, viol, energy, chi_avg);
186 if (
hila::myrank() == 0) measureFile << std::string(buf) <<
"\n";
193template <
typename group>
195 int iterations,
double dt) {
202 for (
int loop = 0; loop < iterations; loop++) {
205 E[d][X].gaussian_random(
sqrt(g2Ta));
207 degauss(U, E, degauss_quality);
210 update_U(U, E, dt / 2);
212 for (
int steps = 0; steps < 1.0 / dt - 1; steps++) {
218 update_U(U, E, dt / 2);
236template <
typename group>
238 int trajlen,
int measure_interval,
double dt) {
245 for (
int n = 0; n < trajlen; n += measure_interval) {
246 update_U(U, E, dt / 2);
248 for (
int steps = 0; steps < measure_interval - 1; steps++) {
254 update_U(U, E, dt / 2);
256 t += dt * measure_interval;
265int main(
int argc,
char **argv) {
270 hila::out0 <<
"---- Hamiltonian time evolution for SU(N) theory, using N=" << NSU <<
" ----\n";
286 lsize = par.get(
"lattice size");
288 double g2Ta = par.get(
"g^2 Ta");
289 double dt = par.get(
"dt");
290 int trajlen = par.get(
"trajectory length");
291 int n_traj = par.get(
"number of trajectories");
292 int measure_interval = par.get(
"measurement interval");
293 int n_thermal = par.get(
"thermalisation");
294 int n_thermal_start = par.get(
"thermalisation start");
295 long seed = par.get(
"random seed");
296 std::string meas_fname = par.get(
"measurement file");
302 lattice.
setup(lsize);
309 measureFile.open(meas_fname, std::ios_base::app);
311 hila::out0 <<
"!!! Error opening measurement file\n";
318 std::ofstream labelFile;
319 std::string labelFileName =
"labels_" + meas_fname;
320 labelFile.open(labelFileName);
322 hila::out0 <<
"!!! Error opening file " << labelFileName <<
"\n";
325 labelFile <<
"1 trajectory\n" <<
"2 time (lattice units)\n" <<
"3 plaq avg: sum_i<j (N - Tr Re P_ij)\n"
326 <<
"4 Tr E_i^2\n" <<
"5 Gauss violation (G^a G^a over the whole system)\n" <<
"6 total energy\n"
327 <<
"7 average chi\n";
343 U[d][X].gaussian_random(0.3).reunitarize();
348 thermalize(U, E, g2Ta, n_thermal_start, dt);
350 for (
int trajectory = 0; trajectory < n_traj; trajectory++) {
351 thermalize(U, E, g2Ta, n_thermal, dt);
352 if (trajectory % 500 == 0) {
353 hila::out0 <<
"Trajectory " << trajectory <<
"\n";
355 do_trajectory(U, E, trajectory, trajlen, measure_interval, dt);
Array< n, m, T > exp(Array< n, m, T > a)
Exponential.
Array< n, m, T > sqrt(Array< n, m, T > a)
Square root.
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...
Field< A > dagger() const
Returns dagger or Hermitian conjugate of Field depending on how it is defined for Field type T.
double squarenorm() const
Squarenorm.
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.
void setup(const CoordinateVector &siz)
General lattice setup.
Complex< T > dagger(const Complex< T > &val)
Return dagger of Complex number.
#define foralldir(d)
Macro to loop over (all) Direction(s)
constexpr Parity ALL
bit pattern: 011
int myrank()
rank of this node
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...
void finishrun()
Normal, controlled exit - all nodes must call this. Prints timing information and information about c...
void staplesum(const GaugeField< T > &U, Field< T > &staples, Direction d1, Parity par=ALL)
Sum the staples of link matrices to direction dir.
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.