Example #1
0
    def __init__(self, U, params):

        covariant_shift.__init__(self, U, params)

        Nc = U[0].otype.Nc
        otype = g.ot_vector_spin_color(4, Nc)
        grid = U[0].grid
        if "mass" in params:
            assert "kappa" not in params
            self.kappa = 1.0 / (params["mass"] + 4.0) / 2.0
        else:
            self.kappa = params["kappa"]

        self.Meooe = g.matrix_operator(lambda dst, src: self._Meooe(dst, src),
                                       otype=otype,
                                       grid=grid)
        self.Mooee = g.matrix_operator(lambda dst, src: self._Mooee(dst, src),
                                       otype=otype,
                                       grid=grid)
        matrix_operator.__init__(self,
                                 lambda dst, src: self._M(dst, src),
                                 otype=otype,
                                 grid=grid)
        self.G5M = g.matrix_operator(lambda dst, src: self._G5M(dst, src),
                                     otype=otype,
                                     grid=grid)
Example #2
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
Example #3
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
        )