-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgauge_action.py
113 lines (88 loc) · 4.75 KB
/
gauge_action.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import tensorflow as tf
import lattice as lt
class yang_mills:
def __init__(self, cfg: lt.Configuration, beta):
self.beta = beta
self.cfg = cfg
def set_gauge_configuration(self, cfg):
self.cfg = cfg
def force(self):
"""Compute the gauge force for a gauge coupling beta"""
# ************************************************
# The gauge force, required for to integrate the equation of
# motion, is field equal to the sum of the staples.
# ************************************************
staples = tf.convert_to_tensor([
tf.math.accumulate_n(elem)
for elem in _get_staple_fields(self.cfg, no_direction=self.cfg.number_of_dimensions)])
return _gauge_force_from_staples(self.cfg, staples, self.beta)
def energy(self):
# Gather first the link fields
sup_gauge_fields = tf.convert_to_tensor(
[lt.translate(self.cfg.gauge_field, mu, +1) for mu in range(self.cfg.number_of_dimensions)])
gauge_energy = 0.
for mu in range(self.cfg.number_of_dimensions):
for nu in range(mu + 1, self.cfg.number_of_dimensions):
gauge_energy += trace_plaquette(self.cfg.gauge_field[mu],
sup_gauge_fields[mu, nu],
sup_gauge_fields[nu, mu],
self.cfg.gauge_field[nu])
return -self.beta * tf.math.real(gauge_energy) / self.cfg.colors
@tf.function
def _gauge_force_from_staples(cfg: lt.Configuration, staples, beta):
'''Compute the gauge force given the precomputed staples field'''
plaquette = tf.einsum("mijc,mkjc->mikc", cfg.gauge_field, tf.math.conj(staples))
force = (-0.25 * beta / cfg.colors) * (
tf.math.conj(tf.transpose(plaquette, [0, 2, 1, 3])) - plaquette)
trace = tf.add_n([force[:, i, i] for i in range(cfg.colors)]) / cfg.colors
return tf.convert_to_tensor([[
[force[mu, i, j] if i != j else force[mu, i, i] - trace[mu]
for j in range(cfg.colors)]
for i in range(cfg.colors)]
for mu in range(cfg.number_of_dimensions)])
def _get_staple_fields(cfg: lt.Configuration, no_direction: int = 3):
"""Compute the sum of the links in each plane for the staples around
each direction"""
# The planes where we compute the staple
planes = []
for mu in range(cfg.number_of_dimensions):
for nu in range(cfg.number_of_dimensions):
if mu != no_direction and nu != no_direction and mu != nu:
planes.append([mu, nu])
translated_field = {}
# First collect the required translated fields
for mu, nu in planes:
if not (mu, nu, +1) in translated_field:
translated_field[(mu, nu, +1)] = lt.translate(cfg.gauge_field[mu], nu, +1)
if not (nu, mu, +1) in translated_field:
translated_field[(nu, mu, +1)] = lt.translate(cfg.gauge_field[nu], mu, +1)
if not (mu, nu, -1) in translated_field:
translated_field[(mu, nu, -1)] = lt.translate(cfg.gauge_field[mu], nu, -1)
if not (nu, nu, -1) in translated_field:
translated_field[(nu, nu, -1)] = lt.translate(cfg.gauge_field[nu], nu, -1)
if not (nu, nu, -1, mu, +1) in translated_field:
translated_field[(nu, nu, -1, mu, +1)] = lt.translate(translated_field[(nu, nu, -1)], mu, +1)
staple_fields = [[] for _ in range(cfg.number_of_dimensions)]
for mu, nu in planes:
staple_fields[mu].append(_sup_staple_trace(cfg.gauge_field[nu],
translated_field[(mu, nu, +1)],
translated_field[(nu, mu, +1)]))
staple_fields[mu].append(_sdn_staple_trace(translated_field[(nu, nu, -1)],
translated_field[(mu, nu, -1)],
translated_field[(nu, nu, -1, mu, +1)]))
return staple_fields
@tf.function
def _sup_staple_trace(links1, links2, links3):
return tf.einsum("kmc,mnc,pnc->kpc", links1, links2, tf.math.conj(links3))
@tf.function
def _sdn_staple_trace(links1, links2, links3):
return tf.einsum("mkc,mnc,npc->kpc", tf.math.conj(links1), links2, links3)
# ************************************************
# The plaquette corresponds to the trace of the square of the
# field strength tensor F_\mu\nu^ab , and it is the basic
# ingredient to define the gauge action
# ************************************************
@tf.function
def trace_plaquette(links1, links2, links3, links4):
'''Compute the trace of the links in one plaquette'''
return tf.einsum("klc,lmc,nmc,knc", links1, links2, tf.math.conj(links3), tf.math.conj(links4))