def Meooe(self, src, dst): assert (dst != src) dst[:] = 0 for mu in range(4): src_plus = self.U[mu] * g.cshift(src, mu, +1) dst += 1. / 2. * g.gamma[mu] * src_plus - 1. / 2. * src_plus src_minus = g.cshift(self.Udag[mu] * src, mu, -1) dst += -1. / 2. * g.gamma[mu] * src_minus - 1. / 2. * src_minus
def staple(U, mu, nu): assert mu != nu U_nu_x_plus_mu = g.cshift(U[nu], mu, 1) U_mu_x_plus_nu = g.cshift(U[mu], nu, 1) U_nu_x_minus_nu = g.cshift(U[nu], nu, -1) return g( U[nu] * U_mu_x_plus_nu * g.adj(U_nu_x_plus_mu) + g.adj(U_nu_x_minus_nu) * g.cshift(U[mu] * U_nu_x_plus_mu, nu, -1) )
def field_strength(U, mu, nu): assert mu != nu # v = staple_up - staple_down v = g.eval( g.cshift(U[nu], mu, 1) * g.adj(g.cshift(U[mu], nu, 1)) * g.adj(U[nu]) - g.cshift(g.adj(g.cshift(U[nu], mu, 1)) * g.adj(U[mu]) * U[nu], nu, -1)) F = g.eval(U[mu] * v + g.cshift(v * U[mu], mu, -1)) F @= 0.125 * (F - g.adj(F)) return F
def plaquette(U): # U[mu](x)*U[nu](x+mu)*adj(U[mu](x+nu))*adj(U[nu](x)) tr = 0.0 vol = float(U[0].grid.gsites) for mu in range(4): for nu in range(mu): tr += g.sum( g.trace(U[mu] * g.cshift(U[nu], mu, 1) * g.adj(g.cshift(U[mu], nu, 1)) * g.adj(U[nu]))) return 2. * tr.real / vol / 4. / 3. / 3.
def Udelta_average(U): """ compute < tr Udelta * Udelta^\dagger > """ Volume = float(U[0].grid.fsites) Udelta = g.lattice(U[0].grid, U[0].otype) Udelta[:] = 0.0 for [i, j, k] in permutations([0, 1, 2]): Udelta += U[i] * g.cshift(U[j], i, 1) * g.cshift( g.cshift(U[k], i, 1), j, 1) return g.sum(g.trace(Udelta * g.adj(Udelta))).real / Volume / 36.0
def plaquette(U): # U[mu](x)*U[nu](x+mu)*adj(U[mu](x+nu))*adj(U[nu](x)) tr = 0.0 vol = float(U[0].grid.fsites) Nd = len(U) ndim = U[0].otype.shape[0] for mu in range(Nd): for nu in range(mu): tr += g.sum( g.trace(U[mu] * g.cshift(U[nu], mu, 1) * g.adj(g.cshift(U[mu], nu, 1)) * g.adj(U[nu]))) return 2.0 * tr.real / vol / Nd / (Nd - 1) / ndim
def _Meooe(self, dst, src): assert dst != src cb = src.checkerboard() scb = self.checkerboard[cb] scbi = self.checkerboard[cb.inv()] phases_cb = self.phases[cb.inv()] dst.checkerboard(cb.inv()) dst[:] = 0 if self.chiral: theta_cb = self.theta[cb] theta_cbi = self.theta[cb.inv()] if self.mu5: s_cbi = self.s[cb.inv()] for mu in range(4): # eval() does numerical evaluation and may give higher performance src_plus = g.eval(scbi.forward[mu] * src) src_minus = g.eval(scb.backward[mu] * src) if self.chiral: src_plus = g.eval(theta_cbi[mu] * src_plus) src_minus = g.eval(g.cshift(theta_cb[mu], mu, -1) * src_minus) dst += phases_cb[mu] * (src_plus - src_minus) / 2.0 if self.mu5: for [i, j, k] in permutations([0, 1, 2]): src_plus = g.eval( scbi.forward[i] * scb.forward[j] * scbi.forward[k] * src ) src_minus = g.eval( scb.backward[k] * scbi.backward[j] * scb.backward[i] * src ) dst += s_cbi * (src_plus + src_minus) * self.mu5 / (-12.0)
def gradient(self, phi): J = g.lattice(phi) frc = g.lattice(phi) J[:] = 0 for mu in range(phi.grid.nd): J += g.cshift(phi, mu, +1) J += g.cshift(phi, mu, -1) frc @= -2.0 * self.kappa * J frc += 2.0 * phi if self.l != 0.0: frc += 4.0 * self.l * phi * g.adj(phi) * phi frc -= 4.0 * self.l * phi return frc
def ishift(self, x, i): if i == 0: return self.ones elif i == 1: return x d, s = self.shifts[i - 2] return g.cshift(x, d, -s)
def correlate_test_4d(a, b, x): # c[x] = (1/vol) sum_y a[y]*b[y+x] bprime = b L = a.grid.gdimensions vol = L[0] * L[1] * L[2] * L[3] for i in range(4): # see core test: dst = g.cshift(src, 0, 1) -> dst[x] = src[x+1] bprime = g.cshift(bprime, i, x[i]) # bprime[y] = b[y+x] return g.sum(a * bprime) / vol
def correlate_test_3d(a, b, x): # c[x] = (1/vol) sum_y a[y]*adj(b[y+x]) bprime = g(g.adj(b)) L = a.grid.gdimensions vol = L[0] * L[1] * L[2] for i in range(3): # see core test: dst = g.cshift(src, 0, 1) -> dst[x] = src[x+1] bprime = g.cshift(bprime, i, x[i]) # bprime[y] = b[y+x] return g.slice(a * bprime, 3)[x[3]] / vol
def divergence(f, current): resN = g.lattice(f) resN[:] = 0 for mu in range(4): c_mu = current(f, f, mu) resN += c_mu - g.cshift(c_mu, mu, -1) return g.norm2(resN)
def divergence(f, current): resN = g.lattice(f) resN[:] = 0 b = g(g.gamma[5] * g.adj(f) * g.gamma[5]) for mu in range(4): c_mu = current(f, b, mu) resN += c_mu - g.cshift(c_mu, mu, -1) return g.norm2(resN)
def gradient(self, V): A = [ g(g.qcd.gauge.project.traceless_anti_hermitian(u) / 1j) for u in g.qcd.gauge.transformed(self.U, V) ] dmuAmu = g.lattice(V.grid, V.otype.cartesian()) dmuAmu[:] = 0 for mu, Amu in enumerate(A): dmuAmu += Amu - g.cshift(Amu, mu, -1) return dmuAmu
def polyakov_loop(U, mu): # tr[ prod_j U_{\mu}(m, j) ] vol = float(U[0].grid.fsites) Nc = U[0].otype.Nc tmp_polyakov_loop = g.copy(U[mu]) for n in range(1, U[0].grid.fdimensions[mu]): tmp = g.cshift(tmp_polyakov_loop, mu, 1) tmp_polyakov_loop = g.eval(U[mu] * tmp) return g.sum(g.trace(tmp_polyakov_loop)) / Nc / vol
def communicate_links(A, dirdisps_forward, make_hermitian): assert type(A) == list assert len(A) == 2 * len(dirdisps_forward) + 1 for p, (mu, fb) in enumerate(dirdisps_forward): p_other = p + 4 shift_fb = fb * -1 Atmp = gpt.copy(A[p]) if not make_hermitian: nbasis = A[0].otype.shape[0] assert nbasis % 2 == 0 nb = nbasis // 2 Atmp[:, :, :, :, 0:nb, nb:nbasis] *= -1.0 # upper right block Atmp[:, :, :, :, nb:nbasis, 0:nb] *= -1.0 # lower left block A[p_other] @= gpt.adj(gpt.cshift(Atmp, mu, shift_fb))
def transformed(obj, V): if isinstance(obj, g.matrix_operator): M = obj def _mat(dst, src): dst @= V * M * g.adj(V) * src return g.matrix_operator(_mat, vector_space=M.vector_space) else: U = obj return [g(V * U[mu] * g.cshift(g.adj(V), mu, 1)) for mu in range(len(U))]
def __call__(self, phi): J = None act = 0.0 for p in g.core.util.to_list(phi): if J is None: J = g.lattice(p) J[:] = 0 for mu in range(p.grid.nd): J += g.cshift(p, mu, 1) act += -2.0 * self.kappa * g.inner_product(J, g.adj(p)).real p2 = g.norm2(p) act += p2 if self.l != 0.0: p4 = g.norm2(p * g.adj(p)) act += self.l * (p4 - 2.0 * p2 + p.grid.fsites) return act
def transformed(obj, V): if isinstance(obj, g.matrix_operator): M = obj def _mat(dst, src): src_prime = [g(g.adj(V) * s) for s in src] M(dst, src_prime) for d in dst: d @= V * d return g.matrix_operator(_mat, vector_space=M.vector_space, accept_list=True) else: U = obj return [ g(V * U[mu] * g.cshift(g.adj(V), mu, 1)) for mu in range(len(U)) ]
4.842216185352299e-06, 7.341488071688218e-06, 7.706037649768405e-06, ] eps = np.linalg.norm(np.array(J5q) - np.array(J5q_ref)) g.message(f"J5q test: {eps}") assert eps < 1e-5 # compute conserved current divergence div = g.mspin(grid) div[:] = 0 for mu in range(4): tmp = qm.conserved_vector_current(dst_qm_bulk, src, dst_qm_bulk, src, mu) tmp -= g.cshift(tmp, mu, -1) div += g.color_trace(tmp) div = g(g.trace(g.adj(div) * div)) g.message("div(conserved_current) contact term", div[0, 1, 0, 0].real) div[0, 1, 0, 0] = 0 eps = g.sum(div).real g.message(f"div(conserved_current) = {eps} without contact term") assert eps < 1e-11 # compute partially conserved axial current divergence (zero momentum projected) AP = g.slice( g.trace(
assert nodes == grid_sp.Nprocessors a = np.array([[1.0, 2.0, 3.0], [4, 5, 6j]], dtype=np.complex64) b = np.copy(a) grid_sp.globalsum(a) eps = a / nodes - b assert np.linalg.norm(eps) < 1e-7 ################################################################################ # Test Cshifts ################################################################################ # create a complex lattice on the grid src = g.complex(grid_sp) # zero out all points and set the value at global position 0,0,0,0 to 2 src[:] = 0 src[0, 0, 0, 0] = complex(2, 1) # create a new lattice that is compatible with another new = g.lattice(src) # create a new lattice that is a copy of another original = g.copy(src) # or copy the contents from one lattice to another g.copy(new, src) # cshift into a new lattice dst dst = g.cshift(src, 0, 1) # dst[x] = src[x+1] -> src[0] == dst[15] assert abs(dst[15, 0, 0, 0] - complex(2, 1)) < 1e-6
def jacobian(self, fields, fields_prime, src): nd = fields[0].grid.nd U = fields[0:nd] U_prime = fields_prime[0:nd] rho = get_rho(U, self.params) C = g.qcd.gauge.staple_sum(U, rho=rho) assert len(src) == nd dst = [g.lattice(s) for s in src] exp_iQ = [None] * nd Lambda = [None] * nd Sigma_prime = [None] * nd # (75) of https://arxiv.org/pdf/hep-lat/0311018.pdf for mu in range(nd): # # Sigma == g.adj(U) * gradient * 1j # Sigma_prime[mu] = g(g.adj(U_prime[mu]) * src[mu] * 1j) U_Sigma_prime_mu = g(U[mu] * Sigma_prime[mu]) iQ_mu = g.qcd.gauge.project.traceless_anti_hermitian(C[mu] * g.adj(U[mu])) exp_iQ[mu], Lambda[mu] = g.matrix.exp.function_and_gradient( iQ_mu, U_Sigma_prime_mu) dst[mu] @= Sigma_prime[mu] * exp_iQ[mu] + g.adj( C[mu]) * 1j * Lambda[mu] for mu in range(nd): for nu in range(nd): if mu == nu: continue rho_mu_nu = rho[mu, nu] rho_nu_mu = rho[nu, mu] if abs(rho_nu_mu) != 0.0 or abs(rho_mu_nu) != 0.0: U_nu_x_plus_mu = g.cshift(U[nu], mu, 1) U_mu_x_plus_nu = g.cshift(U[mu], nu, 1) Lambda_nu_x_plus_mu = g.cshift(Lambda[nu], mu, 1) Lambda_mu_x_plus_nu = g.cshift(Lambda[mu], nu, 1) dst[mu] -= (1j * rho_nu_mu * U_nu_x_plus_mu * g.adj(U_mu_x_plus_nu) * g.adj(U[nu]) * Lambda[nu]) dst[mu] += (1j * rho_nu_mu * Lambda_nu_x_plus_mu * U_nu_x_plus_mu * g.adj(U_mu_x_plus_nu) * g.adj(U[nu])) dst[mu] -= (1j * rho_mu_nu * U_nu_x_plus_mu * g.adj(U_mu_x_plus_nu) * Lambda_mu_x_plus_nu * g.adj(U[nu])) dst[mu] += g.cshift( 1j * rho_nu_mu * g.adj(U_nu_x_plus_mu) * g.adj(U[mu]) * Lambda[nu] * U[nu] - 1j * rho_mu_nu * g.adj(U_nu_x_plus_mu) * g.adj(U[mu]) * Lambda[mu] * U[nu] - 1j * rho_nu_mu * g.adj(U_nu_x_plus_mu) * Lambda_nu_x_plus_mu * g.adj(U[mu]) * U[nu], nu, -1, ) for mu in range(nd): dst[mu] @= U[mu] * dst[mu] * (-1j) dst[mu] @= g.qcd.gauge.project.traceless_hermitian(dst[mu]) return dst
def wrap(dst, src): dst @= ref_U[mu] * gpt.cshift(src, mu, +1)
def wrap(dst, src): dst @= gpt.cshift(ref_Udag[mu] * src, mu, -1)
def wrap(dst, src): dst @= gpt.cshift(self.Udag[mu] * src, mu, -1)
def wrap(dst, src): dst @= self.U[mu] * gpt.cshift(src, mu, +1)
# zero out all points and set the value at global position 0,0,0,0 to 2 src[:] = 0 src[0, 0, 0, 0] = complex(2, 1) # create a new lattice that is compatible with another new = g.lattice(src) # create a new lattice that is a copy of another original = g.copy(src) # or copy the contents from one lattice to another g.copy(new, src) # cshift into a new lattice dst dst = g.cshift(src, 0, 1) # show current memory usage g.meminfo() del original # free lattice and remove from scope g.meminfo() # or re-use an existing lattice object as target g.cshift(dst, src, 0, 1) # create a lattice expression expr = g.trace(-(dst * dst) + 2 * dst) + 0.5 * ( g.cshift(src, 0, 1) * dst + g.cshift(src, 0, -1)) / 3 - g.adj(dst + dst / 2) # and convert the expression to a new lattice or an existing one,
def A(dst, src, mass): assert dst != src dst @= (mass ** 2.0) * src for i in range(4): dst += g.cshift(src, i, 1) + g.cshift(src, i, -1) - 2 * src