Exemple #1
0
 def _get_fields(self, fields):
     U = fields[0:-1]
     phi = fields[-1]
     phi_o = g.lattice(self.M.F_grid_eo, phi.otype)
     phi_e = g.lattice(self.M.F_grid_eo, phi.otype)
     g.pick_checkerboard(g.odd, phi_o, phi)
     g.pick_checkerboard(g.even, phi_e, phi)
     return [U, phi_e, phi_o]
Exemple #2
0
    def _Mdiag(self, dst, src):
        assert dst != src

        g.pick_checkerboard(g.even, self.src_e, src)
        g.pick_checkerboard(g.odd, self.src_o, src)

        self.dst_o @= self.Mooee * self.src_o
        self.dst_e @= self.Mooee * self.src_e

        g.set_checkerboard(dst, self.dst_o)
        g.set_checkerboard(dst, self.dst_e)
Exemple #3
0
    def draw(self, fields, rng):
        U = fields[0:-1]
        phi = fields[-1]

        phi_o = g.lattice(self.M.F_grid_eo, phi.otype)
        g.pick_checkerboard(g.odd, phi_o, phi)
        act_o = self.two_flavor_evenodd_schur.draw(U + [phi_o], rng)

        phi[:] = 0
        g.set_checkerboard(phi, phi_o)
        return act_o
Exemple #4
0
    def _M(self, dst, src):
        assert dst != src

        g.pick_checkerboard(g.even, self.src_e, src)
        g.pick_checkerboard(g.odd, self.src_o, src)

        self.dst_o @= self.Meooe * self.src_e + self.Mooee * self.src_o
        self.dst_e @= self.Meooe * self.src_o + self.Mooee * self.src_e

        g.set_checkerboard(dst, self.dst_o)
        g.set_checkerboard(dst, self.dst_e)

        self.apply_boundaries(dst)
Exemple #5
0
def verify_projected_even_odd(M, Meo, dst_p, src_p, src):
    src_proj_p = g.lattice(src)
    src_proj_p[:] = 0
    g.set_checkerboard(src_proj_p, src_p)

    dst_proj_p = g.eval(M * src_proj_p)
    g.pick_checkerboard(dst_p.checkerboard(), dst_p, dst_proj_p)

    reference = g.copy(dst_p)

    dst_p @= Meo * src_p

    eps = (g.norm2(dst_p - reference) / g.norm2(reference)) ** 0.5
    eps_ref = src.grid.precision.eps * finger_print_tolerance
    g.message(f"Test projected full matrix result versus eo matrix: {eps}")
    assert eps < eps_ref
Exemple #6
0
    def __init__(self, U, params):

        # initialize full lattice
        super().__init__(U, params)
        U = None  # do not use anymore / force use including boundary phase

        # create checkerboard version
        self.checkerboard = {}

        # add even/odd functionality
        grid_eo = self.U[0].grid.checkerboarded(gpt.redblack)
        for cb in [gpt.even, gpt.odd]:
            _U = [gpt.lattice(grid_eo, self.U[0].otype) for u in self.U]
            for mu in range(self.nd):
                gpt.pick_checkerboard(cb, _U[mu], self.U[mu])

            self.checkerboard[cb] = shift_base(_U, None)
Exemple #7
0
def read_openqcd_fermion(fname, cb=None):
    """
    Read a spinor field written by openqcd into a vspincolor object.
    Extracts only the values on the sites corresponding to 'cb' if this parameter is set.
    """
    g.message(f"Reading spinor from file {fname} with checkerboard = {cb}")

    # read into numpy array
    lat, norm, fld = read_sfld(fname)

    # change the order in numpy and convert to gpt field
    # openqcd in memory, slow to fast: t x y z,
    # we in memory, slow to fast: t z y x,
    # -> need to swap x and z
    fld = np.swapaxes(fld, 1, 3)
    grid = g.grid(fdimensions_from_openqcd(lat), g.double)
    field = g.vspincolor(grid)
    field[:] = fld.flatten(order="C")
    norm2_file = norm[0]
    norm2_field = g.norm2(field)

    assert fields_agree_openqcd(norm2_file, norm2_field)
    assert fields_agree(norm2_file, norm2_field, g.double.eps)

    if not cb:
        return field

    assert cb in [g.even, g.odd]
    cbgrid = g.grid(
        grid.gdimensions,
        grid.precision,
        g.redblack,
        parent=grid.parent,
        mpi=grid.mpi,
    )
    cbfield = g.vspincolor(cbgrid)
    g.pick_checkerboard(cb, cbfield, field)
    return cbfield
Exemple #8
0
 def import_parity(self, i):
     gpt.pick_checkerboard(self.parity, self.in_p, i)
     gpt.pick_checkerboard(self.parity.inv(), self.in_np, i)
Exemple #9
0
 def project(self, dst, src):
     gpt.pick_checkerboard(self.checkerboard, dst, src)
Exemple #10
0
    def __init__(self, U, params):

        assert U[0].grid.nd == 4, "Only 4 dimensions implemented for now."

        # there could be a chiral U(1) field after U
        shift_eo.__init__(self, U[0:4], params)

        # stuff that's needed later on
        Ndim = U[0].otype.Ndim
        otype = g.ot_vector_color(Ndim)
        grid = U[0].grid
        grid_eo = grid.checkerboarded(g.redblack)
        self.F_grid = grid
        self.U_grid = grid
        self.F_grid_eo = grid_eo
        self.U_grid_eo = grid_eo

        self.src_e = g.vector_color(grid_eo, Ndim)
        self.src_o = g.vector_color(grid_eo, Ndim)
        self.dst_e = g.vector_color(grid_eo, Ndim)
        self.dst_o = g.vector_color(grid_eo, Ndim)
        self.dst_e.checkerboard(g.even)
        self.dst_o.checkerboard(g.odd)

        self.mass = (
            params["mass"] if "mass" in params and params["mass"] != 0.0 else None
        )
        self.mu5 = params["mu5"] if "mu5" in params and params["mu5"] != 0.0 else None
        self.chiral = params["chiral"] if "chiral" in params else None

        # matrix operators
        self.Mooee = g.matrix_operator(
            lambda dst, src: self._Mooee(dst, src), otype=otype, grid=grid_eo
        )
        self.Meooe = g.matrix_operator(
            lambda dst, src: self._Meooe(dst, src), otype=otype, grid=grid_eo
        )
        matrix_operator.__init__(
            self, lambda dst, src: self._M(dst, src), otype=otype, grid=grid
        )
        self.Mdiag = g.matrix_operator(
            lambda dst, src: self._Mdiag(dst, src), otype=otype, grid=grid
        )

        # staggered phases
        # see also Grid/Grid/qcd/action/fermion/StaggeredImpl.h
        _phases = [g.complex(grid) for i in range(4)]
        for mu in range(4):
            _phases[mu][:] = 1.0
        for x in range(0, grid.fdimensions[0], 2):
            _phases[1][x + 1, :, :, :] = -1.0
            for y in range(0, grid.fdimensions[1], 2):
                _phases[2][x, y + 1, :, :] = -1.0
                _phases[2][x + 1, y, :, :] = -1.0
                for z in range(0, grid.fdimensions[2], 2):
                    _phases[3][x, y, z + 1, :] = -1.0
                    _phases[3][x, y + 1, z, :] = -1.0
                    _phases[3][x + 1, y, z, :] = -1.0
                    _phases[3][x + 1, y + 1, z + 1, :] = -1.0
        # use stride > 1 once it is implemented:
        # _phases[1][1::2, :, :, :] = -1.0
        # _phases[2][0::2, 1::2, :, :] = -1.0
        # _phases[2][1::2, 0::2, :, :] = -1.0
        # _phases[3][0::2, 0::2, 1::2, :] = -1.0
        # _phases[3][0::2, 1::2, 0::2, :] = -1.0
        # _phases[3][1::2, 0::2, 0::2, :] = -1.0
        # _phases[3][1::2, 1::2, 1::2, :] = -1.0
        self.phases = {}
        for cb in [g.even, g.odd]:
            _phases_eo = [g.lattice(grid_eo, _phases[0].otype) for i in range(4)]
            for mu in range(4):
                g.pick_checkerboard(cb, _phases_eo[mu], _phases[mu])
            self.phases[cb] = _phases_eo

        # theta is the chiral U(1) gauge field
        if self.chiral:
            # for now, allow both mu5 and chiral U(1) field for testing purposes
            # assert "mu5" not in params, "should not have both mu5 and chiral in params"
            assert len(U) == 8, "chiral U(1) field missing?"
            self.theta = {}
            for cb in [g.even, g.odd]:
                _theta_eo = [g.lattice(grid_eo, U[4].otype) for i in range(4)]
                for mu in range(4):
                    g.pick_checkerboard(cb, _theta_eo[mu], U[4 + mu])
                self.theta[cb] = _theta_eo

        # s(x) is defined between (2.2) and (2.3) in
        # https://link.springer.com/content/pdf/10.1007/JHEP06(2015)094.pdf
        if self.mu5:
            self.s = {}
            _s = g.complex(grid)
            for y in range(0, grid.fdimensions[1], 2):
                _s[:, y, :, :] = 1.0
                _s[:, y + 1, :, :] = -1.0
            for cb in [g.even, g.odd]:
                _s_eo = g.lattice(grid_eo, _s.otype)
                g.pick_checkerboard(cb, _s_eo, _s)
                self.s[cb] = _s_eo
Exemple #11
0
    def __init__(self, U, params):

        shift_eo.__init__(self, U, boundary_phases=params["boundary_phases"])

        Nc = U[0].otype.Nc
        otype = g.ot_vector_spin_color(4, Nc)
        grid = U[0].grid
        grid_eo = grid.checkerboarded(g.redblack)
        self.F_grid = grid
        self.U_grid = grid
        self.F_grid_eo = grid_eo
        self.U_grid_eo = grid_eo

        self.vector_space_F = g.vector_space.explicit_grid_otype(self.F_grid, otype)
        self.vector_space_U = g.vector_space.explicit_grid_otype(self.U_grid, otype)
        self.vector_space_F_eo = g.vector_space.explicit_grid_otype(
            self.F_grid_eo, otype
        )

        self.src_e = g.vspincolor(grid_eo)
        self.src_o = g.vspincolor(grid_eo)
        self.dst_e = g.vspincolor(grid_eo)
        self.dst_o = g.vspincolor(grid_eo)
        self.dst_e.checkerboard(g.even)
        self.dst_o.checkerboard(g.odd)

        if params["kappa"] is not None:
            assert params["mass"] is None
            self.m0 = 1.0 / params["kappa"] / 2.0 - 4.0
        else:
            self.m0 = params["mass"]

        self.xi_0 = params["xi_0"]
        self.csw_r = params["csw_r"] / self.xi_0
        self.csw_t = params["csw_t"]
        self.nu = params["nu"]

        self.kappa = 1.0 / (2.0 * (self.m0 + 1.0 + 3.0 * self.nu / self.xi_0))

        self.open_bc = params["boundary_phases"][self.nd - 1] == 0.0
        if self.open_bc:
            assert all(
                [
                    self.xi_0 == 1.0,
                    self.nu == 1.0,
                    self.csw_r == self.csw_t,
                    "cF" in params,
                ]
            )  # open bc only for isotropic case, require cF passed
            self.cF = params["cF"]
            T = self.L[self.nd - 1]

        # compute field strength tensor
        if self.csw_r != 0.0 or self.csw_t != 0.0:
            self.clover = g.mspincolor(grid)
            self.clover[:] = 0
            I = g.identity(self.clover)
            for mu in range(self.nd):
                for nu in range(mu + 1, self.nd):
                    if mu == (self.nd - 1) or nu == (self.nd - 1):
                        cp = self.csw_t
                    else:
                        cp = self.csw_r
                    self.clover += (
                        -0.5
                        * cp
                        * g.gamma[mu, nu]
                        * I
                        * g.qcd.gauge.field_strength(U, mu, nu)
                    )

            if self.open_bc:
                # set field strength tensor to unity at the temporal boundaries
                value = -0.5 * self.csw_t
                self.clover[:, :, :, 0, :, :, :, :] = 0.0
                self.clover[:, :, :, T - 1, :, :, :, :] = 0.0
                for alpha in range(4):
                    for a in range(Nc):
                        self.clover[:, :, :, 0, alpha, alpha, a, a] = value
                        self.clover[:, :, :, T - 1, alpha, alpha, a, a] = value

                if self.cF != 1.0:
                    # add improvement coefficients next to temporal boundaries
                    value = self.cF - 1.0
                    for alpha in range(4):
                        for a in range(Nc):
                            self.clover[:, :, :, 1, alpha, alpha, a, a] += value
                            self.clover[:, :, :, T - 2, alpha, alpha, a, a] += value

            # integrate kappa into clover matrix for inversion
            self.clover += 1.0 / 2.0 * 1.0 / self.kappa * I

            self.clover_inv = g.matrix.inv(self.clover)

            self.clover_eo = {
                g.even: g.lattice(grid_eo, self.clover.otype),
                g.odd: g.lattice(grid_eo, self.clover.otype),
            }
            self.clover_inv_eo = {
                g.even: g.lattice(grid_eo, self.clover.otype),
                g.odd: g.lattice(grid_eo, self.clover.otype),
            }
            for cb in self.clover_eo:
                g.pick_checkerboard(cb, self.clover_eo[cb], self.clover)
                g.pick_checkerboard(cb, self.clover_inv_eo[cb], self.clover_inv)
        else:
            self.clover = None
            self.clover_inv = None

        self.Meooe = g.matrix_operator(
            mat=lambda dst, src: self._Meooe(dst, src),
            vector_space=self.vector_space_F_eo,
        )
        self.Mooee = g.matrix_operator(
            mat=lambda dst, src: self._Mooee(dst, src),
            inv_mat=lambda dst, src: self._MooeeInv(dst, src),
            vector_space=self.vector_space_F_eo,
        )
        self.Dhop = g.matrix_operator(
            mat=lambda dst, src: self._Dhop(dst, src), vector_space=self.vector_space_F
        )
        matrix_operator.__init__(
            self, lambda dst, src: self._M(dst, src), vector_space=self.vector_space_F
        )
        self.G5M = g.matrix_operator(
            lambda dst, src: self._G5M(dst, src), vector_space=self.vector_space_F
        )
        self.Mdiag = g.matrix_operator(
            lambda dst, src: self._Mdiag(dst, src), vector_space=self.vector_space_F
        )
        self.ImportPhysicalFermionSource = g.matrix_operator(
            lambda dst, src: g.copy(dst, src), vector_space=self.vector_space_F
        )
        self.ExportPhysicalFermionSolution = g.matrix_operator(
            lambda dst, src: g.copy(dst, src), vector_space=self.vector_space_F
        )
        self.ExportPhysicalFermionSource = g.matrix_operator(
            lambda dst, src: g.copy(dst, src), vector_space=self.vector_space_F
        )
        self.Dminus = g.matrix_operator(
            lambda dst, src: g.copy(dst, src), vector_space=self.vector_space_F
        )
Exemple #12
0
        vec_full(),
        vec_full(),
        vec_full(),
    )
    src_e, src_o, tmp_e, tmp_o, tmp2_e, tmp2_o, res_e, res_o = (
        vec_half(),
        vec_half(),
        vec_half(),
        vec_half(),
        vec_half(),
        vec_half(),
        vec_half(),
        vec_half(),
    )
    rng.cnormal(src)
    g.pick_checkerboard(g.even, src_e, src)
    g.pick_checkerboard(g.odd, src_o, src)

    # Meo + Moe = Dhop
    mat.Dhop.mat(ref, src)
    mat.Meooe.mat(res_o, src_e)
    mat.Meooe.mat(res_e, src_o)
    g.set_checkerboard(res, res_e)
    g.set_checkerboard(res, res_o)
    rel_dev = g.norm2(ref - res) / g.norm2(ref)
    g.message(f"""
Test: Meo + Moe = Dhop
    src = {g.norm2(src)}
    ref = {g.norm2(ref)}
    res = {g.norm2(res)}
    rel. dev. = {rel_dev} -> test {'passed' if rel_dev <= 1e-15 else 'failed'}"""
Exemple #13
0
def verify_matrix_element(fermion, dst, src, tag):
    mat = get_matrix(fermion_dp, tag)
    src_prime = g.eval(mat * src)
    dst.checkerboard(src_prime.checkerboard())
    X = g.inner_product(dst, src_prime)
    eps_ref = src.grid.precision.eps * finger_print_tolerance
    if mat.adj_mat is not None:
        X_from_adj = g.inner_product(src, g.adj(mat) * dst).conjugate()
        eps = abs(X - X_from_adj) / abs(X)
        g.message(f"Test adj({tag}): {eps}")
        assert eps < eps_ref
        if mat.inv_mat is not None:
            eps = (g.norm2(src - mat * g.inv(mat) * src) / g.norm2(src)) ** 0.5
            g.message(f"Test inv({tag}): {eps}")
            assert eps < eps_ref
            Y = g.inner_product(dst, g.inv(g.adj(mat)) * src)
            Y_from_adj = g.inner_product(src, g.inv(mat) * dst).conjugate()
            eps = abs(Y - Y_from_adj) / abs(Y)
            g.message(f"Test adj(inv({tag})): {eps}")
            assert eps < eps_ref
    # do even/odd tests
    even_odd_operators = {"": ("Mooee", "Meooe")}
    if tag in even_odd_operators:
        g.message(f"Test eo versions of {tag}")
        grid_rb = fermion.F_grid_eo
        src_p = g.vspincolor(grid_rb)
        dst_p = g.vspincolor(grid_rb)

        tag_Mooee, tag_Meooe = even_odd_operators[tag]
        mat_Mooee = get_matrix(fermion, tag_Mooee)
        mat_Meooe = get_matrix(fermion, tag_Meooe)
        for parity in [g.even, g.odd]:
            g.pick_checkerboard(parity, src_p, src)
            g.pick_checkerboard(parity, dst_p, src)
            verify_matrix_element(fermion, dst_p, src_p, tag_Mooee)
            verify_projected_even_odd(mat, mat_Mooee, dst_p, src_p, src)

            g.pick_checkerboard(parity.inv(), dst_p, src)
            verify_matrix_element(fermion, dst_p, src_p, tag_Meooe)
            verify_projected_even_odd(mat, mat_Meooe, dst_p, src_p, src)
    # perform derivative tests
    projected_gradient_operators = {"": "M_projected_gradient"}
    if tag in projected_gradient_operators and isinstance(
        fermion, g.qcd.fermion.differentiable_fine_operator
    ):
        # Test projected gradient for src^dag M^dag M src
        g.message(f"Test projected_gradient of {tag} via src^dag M^dag M src")
        mat_pg = get_matrix(fermion, projected_gradient_operators[tag])
        dst_pg = g(mat * src)

        class df(g.group.differentiable_functional):
            def __call__(self, Uprime):
                return g.norm2(get_matrix(fermion.updated(Uprime), tag) * src)

            def gradient(self, Uprime, dUprime):
                assert dUprime == Uprime
                return [
                    g.qcd.gauge.project.traceless_hermitian(g.eval(a + b))
                    for a, b in zip(mat_pg(dst_pg, src), mat_pg.adj()(src, dst_pg))
                ]

        dfv = df()
        dfv.assert_gradient_error(rng, U, U, 1e-3, 1e-6)

        # Test projected gradient for src^dag G5 M src
        if isinstance(fermion, g.qcd.fermion.gauge_independent_g5_hermitian):
            g.message(f"Test projected_gradient of {tag} via src^dag G5 M src")

            class df(g.group.differentiable_functional):
                def __call__(self, Uprime):
                    return g.inner_product(
                        src, fermion.G5 * get_matrix(fermion.updated(Uprime), tag) * src
                    ).real

                def gradient(self, Uprime, dUprime):
                    assert dUprime == Uprime
                    return g.qcd.gauge.project.traceless_hermitian(
                        mat_pg(fermion.G5 * src, src)
                    )

            dfv = df()
            dfv.assert_gradient_error(rng, U, U, 1e-3, 1e-6)

            g.message(f"Test projected_gradient of {tag} via src^dag M^dag G5 src")

            class df(g.group.differentiable_functional):
                def __call__(self, Uprime):
                    return g.inner_product(
                        src,
                        get_matrix(fermion.updated(Uprime), tag).adj()
                        * fermion.G5
                        * src,
                    ).real

                def gradient(self, Uprime, dUprime):
                    assert dUprime == Uprime
                    return g.qcd.gauge.project.traceless_hermitian(
                        mat_pg.adj()(src, fermion.G5 * src)
                    )

            dfv = df()
            dfv.assert_gradient_error(rng, U, U, 1e-3, 1e-6)

    # perform even-odd derivative tests
    projected_gradient_operators = {"Meooe": "Meooe_projected_gradient"}
    if tag in projected_gradient_operators and isinstance(
        fermion, g.qcd.fermion.differentiable_fine_operator
    ):
        # Test projected gradient for src_p^dag M^dag M src_p
        g.message(f"Test projected_gradient of {tag} via src^dag M^dag M src")
        mat_pg = get_matrix(fermion, projected_gradient_operators[tag])
        src_p = g.lattice(fermion.F_grid_eo, fermion.otype)

        for parity in [g.even, g.odd]:
            g.pick_checkerboard(parity, src_p, src)
            dst_p = g(mat * src_p)

            class df(g.group.differentiable_functional):
                def __call__(self, Uprime):
                    return g.norm2(get_matrix(fermion.updated(Uprime), tag) * src_p)

                def gradient(self, Uprime, dUprime):
                    assert dUprime == Uprime
                    R = g.group.cartesian(Uprime)
                    for r, x in zip(
                        R + R, mat_pg(dst_p, src_p) + mat_pg.adj()(src_p, dst_p)
                    ):
                        g.set_checkerboard(
                            r, g.qcd.gauge.project.traceless_hermitian(x)
                        )
                    return R

        dfv = df()
        dfv.assert_gradient_error(rng, U, U, 1e-3, 1e-6)

    return X
Exemple #14
0
p = {
    "kappa": 0.13465,
    "csw_r": 0.0,
    "csw_t": 0.0,
    "xi_0": 1,
    "nu": 1,
    "isAnisotropic": False,
    "boundary_phases": [1.0, 1.0, 1.0, 1.0],
}
M2 = g.qcd.fermion.wilson_clover(U, p)

psi = g.vspincolor(M.F_grid)
psi_o = g.vspincolor(M.F_grid_eo)
rng.normal(psi)
g.pick_checkerboard(g.odd, psi_o, psi)

inv = g.algorithms.inverter
sol = inv.cg({"eps": 1e-10, "maxiter": 1024})
a = g.qcd.pseudofermion.action

acts = []
acts += [(a.two_flavor(M, sol), "two_flavor", psi)]
acts += [(a.two_flavor_evenodd(M, sol), "two_flavor_evenodd", psi)]
acts += [(a.two_flavor_ratio([M, M2], sol), "two_flavor_ratio", psi)]
acts += [(
    a.two_flavor_ratio_evenodd_schur([M, M2], sol),
    "two_flavor_ratio_evenodd_schur",
    psi_o,
)]