HILA
Loading...
Searching...
No Matches
energy_and_topo_charge_log.h
Go to the documentation of this file.
1/** @file energy_and_topo_charge_log.h */
2
3#ifndef ENERGY_AND_TOPO_CHARGE_LOG_H_
4#define ENERGY_AND_TOPO_CHARGE_LOG_H_
5
6#include "hila.h"
7
8template <typename group, typename atype = hila::arithmetic_type<group>>
9void measure_topo_charge_and_energy_log(const GaugeField<group> &U, atype &qtopo_out,
10 atype &energy_out) {
11 // measure topological charge and field strength energy of the gauge field, using the
12 // matrix logarithms of the plaquettes as components of the field strength tensor
13
14 Reduction<double> qtopo = 0;
15 Reduction<double> energy = 0;
16 qtopo.allreduce(false).delayed(true);
17 energy.allreduce(false).delayed(true);
18
19#if NDIM == 4
20 Field<group> F[6];
21 // F[0]: F[0][1], F[1]: F[0][2], F[2]: F[0][3],
22 // F[3]: F[1][2], F[4]: F[1][3], F[5]: F[2][3]
23 Field<group> tF0, tF1;
24
25 int k = 0;
26 // (Note: by replacing log(...).expand() in the following by Lie-algebra projection,
27 // one would end up computing the clover field strength)
28 foralldir(dir1) foralldir(dir2) if (dir1 < dir2) {
29 U[dir2].start_gather(dir1, ALL);
30 U[dir1].start_gather(dir2, ALL);
31
32 onsites(ALL) {
33 // log of dir1-dir2-plaquette that starts and ends at X; corresponds to F[dir1][dir2]
34 // at center location X+dir1/2+dir2/2 of plaquette:
35 tF0[X] =
36 log((U[dir1][X] * U[dir2][X + dir1] * (U[dir2][X] * U[dir1][X + dir2]).dagger()))
37 .expand();
38 // parallel transport to X+dir1
39 tF1[X] = U[dir1][X].dagger() * tF0[X] * U[dir1][X];
40 }
41
42 tF1.start_gather(-dir1, ALL);
43 onsites(ALL) {
44 tF0[X] += tF1[X - dir1];
45 }
46
47 U[dir2].start_gather(-dir2, ALL);
48 tF0.start_gather(-dir2, ALL);
49 onsites(ALL) {
50 // get F[dir1][dir2] at X from average of the (parallel transported) F[dir1][dir2] from
51 // the centers of all dir1-dir2-plaquettes that touch X :
52 F[k][X] =
53 (tF0[X] + U[dir2][X - dir2].dagger() * tF0[X - dir2] * U[dir2][X - dir2]) * 0.25;
54 }
55 ++k;
56 }
57 onsites(ALL) {
58 qtopo += real(mul_trace(F[0][X], F[5][X]));
59 qtopo += -real(mul_trace(F[1][X], F[4][X]));
60 qtopo += real(mul_trace(F[2][X], F[3][X]));
61
62 energy += F[0][X].squarenorm();
63 energy += F[1][X].squarenorm();
64 energy += F[2][X].squarenorm();
65 energy += F[3][X].squarenorm();
66 energy += F[4][X].squarenorm();
67 energy += F[5][X].squarenorm();
68 }
69#endif
70 qtopo_out = (atype)qtopo.value() / (4.0 * M_PI * M_PI);
71 energy_out = (atype)energy.value();
72}
73
74
75#endif
Array< n, m, hila::arithmetic_type< T > > real(const Array< n, m, T > &arg)
Return real part of Array.
Definition array.h:688
Array< n, m, T > log(Array< n, m, T > a)
Logarithm.
Definition array.h:1069
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Definition field.h:61
double squarenorm() const
Squarenorm.
Definition field.h:1083
dir_mask_t start_gather(Direction d, Parity p=ALL) const
Definition field_comm.h:262
Gauge field class.
Definition gaugefield.h:22
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
Complex< T > dagger(const Complex< T > &val)
Return dagger of Complex number.
Definition cmplx.h:1223
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:78
constexpr Parity ALL
bit pattern: 011
auto mul_trace(const Mtype1 &a, const Mtype2 &b)
Returns trace of product of two matrices.
Definition matrix.h:2309