def create_links(first, init, params): if type(first) == g.grid: # default representation is SU3 fundamental if params["otype"] is None: params["otype"] = g.ot_matrix_su_n_fundamental_group(3) # default dimension is grid's dimension if params["Nd"] is None: params["Nd"] = first.nd # create lattices U = [g.lattice(first, params["otype"]) for i in range(params["Nd"])] # initialize them create_links(U, init, params) return U elif type(first) == list: # if given a list, the dimensionality can be inferred if params["Nd"] is None: params["Nd"] = len(first) else: assert params["Nd"] == len(first) # initialize each link for x in first: create_links(x, init, params) return first elif type(first) == g.lattice: # if otype is given, make sure it is expected if params["otype"] is not None: assert params["otype"].__name__ == first.otype.__name__ init(first, params) return first else: assert 0
def load_cgpt(*a): result = [] r, metadata = cgpt.load(*a, gpt.default.is_verbose("io")) if r is None: raise gpt.LoadError() for gr in r: grid = gpt.grid(gr[1], eval("gpt." + gr[2]), eval("gpt." + gr[3]), gr[0]) result_grid = [] otype = gpt.ot_matrix_su_n_fundamental_group(3) for t_obj, s_ot, s_pr in gr[4]: assert s_pr == gr[2] # only allow loading su3 gauge fields from cgpt, rest done in python # in the long run, replace *any* IO from cgpt with gpt code assert s_ot == "ot_mcolor3" l = gpt.lattice(grid, otype, [t_obj]) l.metadata = metadata result_grid.append(l) result.append(result_grid) while len(result) == 1: result = result[0] return result
def __call__(self, link, staple, mask): verbose = g.default.is_verbose( "su2_heat_bath" ) # need verbosity categories [ performance, progress ] project_method = self.params["project_method"] # params niter = self.params["niter"] # temporaries grid = link.grid u2 = g.lattice(grid, g.ot_matrix_su_n_fundamental_group(2)) u2_eye = g.identity(u2) one = g.identity(g.complex(grid)) zero = g.complex(grid) zero[:] = 0 eps = g.complex(grid) eps[:] = grid.precision.eps * 10.0 xr = [g.complex(grid) for i in range(4)] a = [g.complex(grid) for i in range(4)] two_pi = g.complex(grid) two_pi[:] = 2.0 * np.pi accepted = g.complex(grid) d = g.complex(grid) V_eye = g.identity(link) # pauli pauli1, pauli2, pauli3 = tuple([g.lattice(u2) for i in range(3)]) ident = g.identity(u2) pauli1[:] = 1j * np.array([[0, 1], [1, 0]], dtype=grid.precision.complex_dtype) pauli2[:] = 1j * np.array([[0, 1j], [-1j, 0]], dtype=grid.precision.complex_dtype) pauli3[:] = 1j * np.array([[1, 0], [0, -1]], dtype=grid.precision.complex_dtype) # counter num_sites = round(g.norm2(g.where(mask, one, zero))) # shortcuts inv = g.component.pow(-1.0) # go through subgroups for subgroup in link.otype.su2_subgroups(): V = g.eval(link * g.adj(staple)) # extract u2 subgroup following Kennedy/Pendleton link.otype.block_extract(u2, V, subgroup) u2 @= u2 - g.adj(u2) + g.identity(u2) * g.trace(g.adj(u2)) udet = g.matrix.det(u2) adet = g.component.abs(udet) nzmask = adet > eps u2 @= g.where(nzmask, u2, u2_eye) udet = g.where(nzmask, udet, one) xi = g.eval(0.5 * g.component.sqrt(udet)) u2 @= 0.5 * u2 * inv(xi) # make sure that su2 subgroup projection worked assert g.group.defect(u2) < u2.grid.precision.eps * 10.0 xi @= 2.0 * xi alpha = g.component.real(xi) # main loop it = 0 num_accepted = 0 accepted[:] = 0 d[:] = 0 while (num_accepted < num_sites) and (it < niter): self.rng.uniform_real(xr, min=0.0, max=1.0) xr[1] @= -g.component.log(xr[1]) * inv(alpha) xr[2] @= -g.component.log(xr[2]) * inv(alpha) xr[3] @= g.component.cos(g.eval(xr[3] * two_pi)) xr[3] @= xr[3] * xr[3] xrsq = g.eval(xr[2] + xr[1] * xr[3]) d = g.where(accepted, d, xrsq) thresh = g.eval(one - d * 0.5) xrsq @= xr[0] * xr[0] newly_accepted = g.where(xrsq < thresh, one, zero) accepted = g.where(mask, g.where(newly_accepted, newly_accepted, accepted), zero) num_accepted = round(g.norm2(g.where(accepted, one, zero))) it += 1 if verbose: g.message(f"SU(2)-heatbath update needed {it} / {niter} iterations") # update link a[0] @= g.where(mask, one - d, zero) a123mag = g.component.sqrt(g.component.abs(one - a[0] * a[0])) phi, cos_theta = g.complex(grid), g.complex(grid) self.rng.uniform_real([phi, cos_theta]) phi @= phi * two_pi cos_theta @= (cos_theta * 2.0) - one sin_theta = g.component.sqrt(g.component.abs(one - cos_theta * cos_theta)) a[1] @= a123mag * sin_theta * g.component.cos(phi) a[2] @= a123mag * sin_theta * g.component.sin(phi) a[3] @= a123mag * cos_theta ua = g.eval(a[0] * ident + a[1] * pauli1 + a[2] * pauli2 + a[3] * pauli3) b = g.where(mask, g.adj(u2) * ua, ident) link.otype.block_insert(V, b, subgroup) link @= g.where(accepted, V * link, link) # check check = g.where(accepted, ua * g.adj(ua) - ident, 0.0 * ident) delta = (g.norm2(check) / g.norm2(ident)) ** 0.5 assert delta < grid.precision.eps * 10.0 check = g.where(accepted, b * g.adj(b) - ident, 0.0 * ident) delta = (g.norm2(check) / g.norm2(ident)) ** 0.5 assert delta < grid.precision.eps * 10.0 check = g.where(accepted, V * g.adj(V) - V_eye, 0.0 * V_eye) delta = (g.norm2(check) / g.norm2(V_eye)) ** 0.5 assert delta < grid.precision.eps * 10.0 # project g.project(link, project_method)
################################################################################ for eps_ref, grid in [(1e-6, grid_sp), (1e-12, grid_dp)]: for representation in [g.matrix_su2_adjoint, g.matrix_su3_fundamental]: g.message( f"Test {representation.__name__} on grid {grid.precision.__name__}" ) U = representation(grid) rng.element(U) check_unitarity(U, eps_ref) check_representation(U, eps_ref) ################################################################################ # Test su2 subalgebras ################################################################################ for eps_ref, grid in [(1e-12, grid_dp)]: U = g.lattice(grid, g.ot_matrix_su_n_fundamental_group(3)) u2 = g.lattice(grid, g.ot_matrix_su_n_fundamental_group(2)) u2p = g.lattice(grid, g.ot_matrix_su_n_fundamental_group(2)) for sg in U.otype.su2_subgroups(): rng.element(u2) u2p = g.eval(u2 - g.adj(u2) + g.identity(u2) * g.trace(g.adj(u2))) eps = (g.norm2(u2 - u2p) / g.norm2(u2))**0.5 g.message(eps, g.norm2(u2), g.norm2(u2p)) U.otype.block_insert(U, u2, sg) u2p[:] = 0 U.otype.block_extract(u2p, U, sg) eps = (g.norm2(u2 - u2p) / g.norm2(u2))**0.5 g.message(eps, g.norm2(u2), g.norm2(u2p))
def read_header(self): # make sure this is a file if not os.path.isfile(self.path): return False with open(self.path, "rb") as f: line = self.getline(f) if line != "BEGIN_HEADER": return False # need to be mute before this line since this is used to autodetect the file format if self.verbose: gpt.message(f"NERSC file format; reading {self.path}") gpt.message(f" {line}") line = self.getline(f) while line != "END_HEADER": if self.verbose: gpt.message(f"\t{line}") [field, val] = line.split("=", 1) self.metadata[field.strip()] = val.strip() line = self.getline(f) if self.verbose: gpt.message(f" {line}") self.bytes_header = f.tell() f.seek(0, 2) self.bytes_data = f.tell() - self.bytes_header self.fdimensions = [ int(self.metadata[f"DIMENSION_{i+1}"]) for i in range(4) ] self.floating_point = self.metadata["FLOATING_POINT"] self.data_type = self.metadata["DATATYPE"] if self.floating_point == "IEEE64BIG": self.munge = self.munge_ieee64big self.precision = gpt.double elif self.floating_point == "IEEE64LITTLE" or self.floating_point == "IEEE64": self.munge = self.munge_ieee64little self.precision = gpt.double elif self.floating_point == "IEEE32BIG": self.munge = self.munge_ieee32big self.precision = gpt.single elif self.floating_point == "IEEE32LITTLE" or self.floating_point == "IEEE32": self.munge = self.munge_ieee32little self.precision = gpt.single else: gpt.message( "Warning: unknown floating point format {self.floating_point}") return False gsites = int(numpy.prod(self.fdimensions)) assert self.bytes_data % gsites == 0 self.bytes_per_site = self.bytes_data // gsites assert self.bytes_per_site % self.precision.nbytes == 0 self.floats_per_site = self.bytes_per_site // self.precision.nbytes if self.data_type == "4D_SU3_GAUGE_3x3": assert 3 * 3 * 4 * 2 == self.floats_per_site self.otype = gpt.ot_matrix_su_n_fundamental_group(3) self.nfields = 4 self.reconstruct = self.reconstruct_none elif self.data_type == "4D_SU3_GAUGE": assert 3 * 2 * 4 * 2 == self.floats_per_site self.otype = gpt.ot_matrix_su_n_fundamental_group(3) self.reconstruct = self.reconstruct_third_row self.nfields = 4 else: gpt.message("Warning: unknown data type {self.data_type}") return False assert self.floats_per_site % self.nfields == 0 self.floats_per_field_site = self.floats_per_site // self.nfields return True