Exemple #1
0
    def test_untile_wrong_usage(self):
        # one should not untile
        geometry = Geometry([0] * 3, Atom(1, R=1.001), SuperCell(1,
                                                                 nsc=[1] * 3))
        geometry = geometry.tile(4, 0)
        s = SparseAtom(geometry)
        s.construct([[0.1, 1.01], [1, 2]])
        s[0, 3] = 2
        s[3, 0] = 2

        # check that untiling twice is not the same as untiling 4 times and coupling it
        s2 = s.untile(2, 0)
        s4 = s.untile(4, 0).tile(2, 0)
        ds = s2 - s4
        ds.finalize()
        assert np.absolute(ds)._csr._D.sum() > 0
Exemple #2
0
    def test_untile_segment_single(self):
        # one should not untile
        geometry = Geometry([0] * 3, Atom(1, R=1.001), SuperCell(1,
                                                                 nsc=[1] * 3))
        geometry = geometry.tile(4, 0)
        s = SparseAtom(geometry)
        s.construct([[0.1, 1.01], [1, 2]])
        s[0, 3] = 2
        s[3, 0] = 2

        # check that untiling twice is not the same as untiling 4 times and coupling it
        s4 = s.untile(4, 0).tile(2, 0)
        for seg in range(1, 4):
            sx = s.untile(4, 0, segment=seg).tile(2, 0)
            ds = s4 - sx
            ds.finalize()
            assert np.absolute(ds)._csr._D.sum() == pytest.approx(0.)
Exemple #3
0
    def test_tile3(self):
        R, param = [0.1, 1.1, 2.1, 3.1], [1., 2., 3., 4.]

        # Create reference
        g = Geometry([[0] * 3], Atom('H', R=[4.]), sc=[1.] * 3)
        g.set_nsc([7] * 3)

        # Now create bigger geometry
        G = g.tile(2, 0).tile(2, 1).tile(2, 2)

        HG = Hamiltonian(G.tile(2, 0).tile(2, 1).tile(2, 2))
        HG.construct([R, param])
        HG.finalize()
        H = Hamiltonian(G)
        H.construct([R, param])
        H.finalize()
        H = H.tile(2, 0).tile(2, 1).tile(2, 2)
        assert_true(HG.spsame(H))
Exemple #4
0
def test_sparse_orbital_sub_orbital():
    a0 = Atom(1, R=(1.1, 1.4, 1.6))
    a1 = Atom(2, R=(1.3, 1.1))
    g = Geometry([[0, 0, 0], [1, 1, 1]], [a0, a1], sc=SuperCell(2, nsc=[3, 1, 1]))
    g = g.tile(3, 0)
    assert g.no == 15

    spo = SparseOrbital(g)
    for io in range(g.no):
        spo[io, io] = io + 1
        spo[io, io + g.no - 1] = io - 2
        spo[io, io + 1] = io + 2
    # Ensure we have a Hermitian matrix
    spo = spo + spo.transpose()

    # orbitals on first atom (a0)
    rem_sub = [
        (0, [1, 2]),
        ([0, 2], 1),
        (2, [0, 1]),
        (a0[0], [1, 2])
    ]
    for rem, sub in rem_sub:
        spo_rem = spo.remove_orbital(0, rem)
        spo_sub = spo.sub_orbital(0, sub)
        assert spo_rem.spsame(spo_sub)
        atoms = spo_rem.geometry.atoms
        assert atoms == spo_sub.geometry.atoms
        assert atoms.nspecie == 3
        assert (atoms.specie == 0).sum() == 2
        assert (atoms.specie == 1).sum() == 3
        assert (atoms.specie == 2).sum() == 1

        spo_rem = spo.remove_orbital(a0, rem)
        spo_sub = spo.sub_orbital(a0, sub)
        assert spo_rem.spsame(spo_sub)
        atoms = spo_rem.geometry.atoms
        assert atoms == spo_sub.geometry.atoms
        assert atoms.nspecie == 2
        assert (atoms.specie == 0).sum() == 3
        assert (atoms.specie == 1).sum() == 3

    # orbitals on second atom (a1)
    rem_sub = [
        (0, [1]),
        (a1[0], 1),
        (0, a1[1]),
    ]
    for rem, sub in rem_sub:
        spo_rem = spo.remove_orbital(1, rem)
        spo_sub = spo.sub_orbital(1, sub)
        assert spo_rem.spsame(spo_sub)
        atoms = spo_rem.geometry.atoms
        assert atoms == spo_sub.geometry.atoms
        assert atoms.nspecie == 3
        assert (atoms.specie == 0).sum() == 3
        assert (atoms.specie == 1).sum() == 2
        assert (atoms.specie == 2).sum() == 1

        spo_rem = spo.remove_orbital(a1, rem)
        spo_sub = spo.sub_orbital(a1, sub)
        assert spo_rem.spsame(spo_sub)
        atoms = spo_rem.geometry.atoms
        assert atoms == spo_sub.geometry.atoms
        assert atoms.nspecie == 2
        assert (atoms.specie == 0).sum() == 3
        assert (atoms.specie == 1).sum() == 3

    spo_rem = spo.remove_orbital([0, 1], 0)
    spo_sub = spo.sub_orbital(0, [1, 2]).sub_orbital(1, 1)
    assert spo_rem.spsame(spo_sub)

    spo_rem = spo.remove_orbital([0, 1], 1)
    spo_sub = spo.sub_orbital(0, [0, 2]).sub_orbital(1, 0)
    assert spo_rem.spsame(spo_sub)
Exemple #5
0
class TestHamiltonian(object):
    def setUp(self):
        bond = 1.42
        sq3h = 3.**.5 * 0.5
        self.sc = SuperCell(np.array(
            [[1.5, sq3h, 0.], [1.5, -sq3h, 0.], [0., 0., 10.]], np.float64) *
                            bond,
                            nsc=[3, 3, 1])

        C = Atom(Z=6, R=bond * 1.01, orbs=1)
        self.g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) *
                          bond,
                          atom=C,
                          sc=self.sc)
        self.H = Hamiltonian(self.g)
        self.HS = Hamiltonian(self.g, orthogonal=False)

        C = Atom(Z=6, R=bond * 1.01, orbs=2)
        self.g2 = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) *
                           bond,
                           atom=C,
                           sc=self.sc)
        self.H2 = Hamiltonian(self.g2)
        self.HS2 = Hamiltonian(self.g2, orthogonal=False)

    def tearDown(self):
        del self.sc
        del self.g
        del self.H
        del self.HS
        del self.g2
        del self.H2
        del self.HS2

    def test_objects(self):
        assert_true(len(self.H.xyz) == 2)
        assert_true(self.g.no == len(self.H))
        assert_true(len(self.HS.xyz) == 2)
        assert_true(self.g.no == len(self.HS))

        assert_true(len(self.H2.xyz) == 2)
        assert_true(self.g2.no == len(self.H2))
        assert_true(len(self.HS2.xyz) == 2)
        assert_true(self.g2.no == len(self.HS2))

    def test_dtype(self):
        assert_true(self.H.dtype == np.float64)
        assert_true(self.HS.dtype == np.float64)
        assert_true(self.H2.dtype == np.float64)
        assert_true(self.HS2.dtype == np.float64)

    def test_ortho(self):
        assert_true(self.H.orthogonal)
        assert_false(self.HS.orthogonal)

    def test_set1(self):
        self.H.H[0, 0] = 1.
        assert_true(self.H[0, 0] == 1.)
        assert_true(self.H[1, 0] == 0.)
        self.H.empty()

        self.HS.H[0, 0] = 1.
        assert_true(self.HS.H[0, 0] == 1.)
        assert_true(self.HS.H[1, 0] == 0.)
        assert_true(self.HS.S[0, 0] == 0.)
        assert_true(self.HS.S[1, 0] == 0.)
        self.HS.S[0, 0] = 1.
        assert_true(self.HS.H[0, 0] == 1.)
        assert_true(self.HS.H[1, 0] == 0.)
        assert_true(self.HS.S[0, 0] == 1.)
        assert_true(self.HS.S[1, 0] == 0.)

        # delete before creating the same content
        self.HS.empty()
        # THIS IS A CHECK FOR BACK_WARD COMPATIBILITY!
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')
            self.HS[0, 0] = 1., 1.
        assert_true(self.HS.H[0, 0] == 1.)
        assert_true(self.HS.S[0, 0] == 1.)
        self.HS.empty()

    def test_set2(self):
        self.H.construct([(0.1, 1.5), (1., 0.1)])
        assert_true(self.H[0, 0] == 1.)
        assert_true(self.H[1, 0] == 0.1)
        assert_true(self.H[0, 1] == 0.1)
        self.H.empty()

    def test_set3(self):
        self.HS.construct([(0.1, 1.5), ((1., 2.), (0.1, 0.2))])
        assert_true(self.HS.H[0, 0] == 1.)
        assert_true(self.HS.S[0, 0] == 2.)
        assert_true(self.HS.H[1, 1] == 1.)
        assert_true(self.HS.S[1, 1] == 2.)
        assert_true(self.HS.H[1, 0] == 0.1)
        assert_true(self.HS.H[0, 1] == 0.1)
        assert_true(self.HS.S[1, 0] == 0.2)
        assert_true(self.HS.S[0, 1] == 0.2)
        assert_true(self.HS.nnz == len(self.HS) * 4)
        self.HS.empty()

    def test_set4(self):
        for ia, io in self.H:
            # Find atoms close to 'ia'
            idx = self.H.geom.close(ia, R=(0.1, 1.5))
            self.H[io, idx[0]] = 1.
            self.H[io, idx[1]] = 0.1
        assert_true(self.H.H[0, 0] == 1.)
        assert_true(self.H.H[1, 1] == 1.)
        assert_true(self.H.H[1, 0] == 0.1)
        assert_true(self.H.H[0, 1] == 0.1)
        assert_true(self.H.nnz == len(self.H) * 4)
        self.H.empty()

    @attr('slow')
    def test_set5(self):
        # Test of HUGE construct
        g = self.g.tile(10, 0).tile(10, 1).tile(10, 2)
        H = Hamiltonian(g)
        H.construct([(0.1, 1.5), (1., 0.1)])
        assert_true(H.H[0, 0] == 1.)
        assert_true(H.H[1, 1] == 1.)
        assert_true(H.H[1, 0] == 0.1)
        assert_true(H.H[0, 1] == 0.1)
        # This is graphene
        # on-site == len(H)
        # nn == 3 * len(H)
        assert_true(H.nnz == len(H) * 4)
        del H

    def test_iter1(self):
        self.HS.construct([(0.1, 1.5), ((1., 2.), (0.1, 0.2))])
        nnz = 0
        for io, jo in self.HS.iter_nnz():
            nnz = nnz + 1
        assert_equal(nnz, self.HS.nnz)
        nnz = 0
        for io, jo in self.HS.iter_nnz(0):
            nnz = nnz + 1
        # 3 nn and 1 onsite
        assert_equal(nnz, 4)
        self.HS.empty()

    def test_iter2(self):
        self.HS.H[0, 0] = 1.
        nnz = 0
        for io, jo in self.HS.iter_nnz():
            nnz = nnz + 1
        assert_equal(nnz, self.HS.nnz)
        assert_equal(nnz, 1)
        self.HS.empty()

    @raises(ValueError)
    def test_construct_raise(self):
        # Test that construct fails with more than one
        # orbital
        self.H2.construct([(0.1, 1.5), (1., 0.1)])

    def test_getitem1(self):
        H = self.H
        # graphene Hamiltonian
        H.construct([(0.1, 1.5), (0.1, 0.2)])
        # Assert all connections
        assert_equal(H[0, 0], 0.1)
        assert_equal(H[0, 1], 0.2)
        assert_equal(H[0, 1, (-1, 0)], 0.2)
        assert_equal(H[0, 1, (0, -1)], 0.2)
        assert_equal(H[1, 0], 0.2)
        assert_equal(H[1, 1], 0.1)
        assert_equal(H[1, 0, (1, 0)], 0.2)
        assert_equal(H[1, 0, (0, 1)], 0.2)
        H[0, 0, (0, 1)] = 0.3
        assert_equal(H[0, 0, (0, 1)], 0.3)
        H[0, 1, (0, 1)] = -0.2
        assert_equal(H[0, 1, (0, 1)], -0.2)
        H.empty()

    def test_delitem1(self):
        H = self.H
        H.construct([(0.1, 1.5), (0.1, 0.2)])
        assert_equal(H[0, 1], 0.2)
        del H[0, 1]
        assert_equal(H[0, 1], 0.0)
        H.empty()

    def test_sp2HS(self):
        csr = self.H.tocsr(0)
        H = Hamiltonian.fromsp(self.H.geom, csr)
        assert_true(H.spsame(self.H))

    def test_op1(self):
        g = Geometry([[i, 0, 0] for i in range(100)],
                     Atom(6, R=1.01),
                     sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = i

            # i+
            H += 1
            for jj in j:
                assert_equal(H[0, jj], i + 1)
                assert_equal(H[1, jj], 0)

            # i-
            H -= 1
            for jj in j:
                assert_equal(H[0, jj], i)
                assert_equal(H[1, jj], 0)

            # i*
            H *= 2
            for jj in j:
                assert_equal(H[0, jj], i * 2)
                assert_equal(H[1, jj], 0)

            # //
            H //= 2
            for jj in j:
                assert_equal(H[0, jj], i)
                assert_equal(H[1, jj], 0)

            # i**
            H **= 2
            for jj in j:
                assert_equal(H[0, jj], i**2)
                assert_equal(H[1, jj], 0)

    def test_op2(self):
        g = Geometry([[i, 0, 0] for i in range(100)],
                     Atom(6, R=1.01),
                     sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = i

            # +
            s = H + 1
            for jj in j:
                assert_equal(s[0, jj], i + 1)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # -
            s = H - 1
            for jj in j:
                assert_equal(s[0, jj], i - 1)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # -
            s = 1 - H
            for jj in j:
                assert_equal(s[0, jj], 1 - i)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # *
            s = H * 2
            for jj in j:
                assert_equal(s[0, jj], i * 2)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # //
            s = s // 2
            for jj in j:
                assert_equal(s[0, jj], i)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # **
            s = H**2
            for jj in j:
                assert_equal(s[0, jj], i**2)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # ** (r)
            s = 2**H
            for jj in j:
                assert_equal(s[0, jj], 2**H[0, jj])
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

    def test_op3(self):
        g = Geometry([[i, 0, 0] for i in range(100)],
                     Atom(6, R=1.01),
                     sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        Hc = H.copy()
        del Hc

        # Create initial stuff
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = i

        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.int32)
            h = func(1.)
            assert_equal(h.dtype, np.float64)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

        H = H.copy(dtype=np.float64)
        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.float64)
            h = func(1.)
            assert_equal(h.dtype, np.float64)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

        H = H.copy(dtype=np.complex128)
        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.complex128)
            h = func(1.)
            assert_equal(h.dtype, np.complex128)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

    def test_op4(self):
        g = Geometry([[i, 0, 0] for i in range(100)],
                     Atom(6, R=1.01),
                     sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        # Create initial stuff
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = i

        h = 1 + H
        assert_equal(h.dtype, np.int32)
        h = 1. + H
        assert_equal(h.dtype, np.float64)
        h = 1.j + H
        assert_equal(h.dtype, np.complex128)

        h = 1 - H
        assert_equal(h.dtype, np.int32)
        h = 1. - H
        assert_equal(h.dtype, np.float64)
        h = 1.j - H
        assert_equal(h.dtype, np.complex128)

        h = 1 * H
        assert_equal(h.dtype, np.int32)
        h = 1. * H
        assert_equal(h.dtype, np.float64)
        h = 1.j * H
        assert_equal(h.dtype, np.complex128)

        h = 1**H
        assert_equal(h.dtype, np.int32)
        h = 1.**H
        assert_equal(h.dtype, np.float64)
        h = 1.j**H
        assert_equal(h.dtype, np.complex128)

    def test_cut1(self):
        # Test of eigenvalues using a cut
        # Hamiltonian
        R, param = [0.1, 1.5], [1., 0.1]

        # Create reference
        Hg = Hamiltonian(self.g)
        Hg.construct([R, param])
        g = self.g.tile(2, 0).tile(2, 1)
        H = Hamiltonian(g)
        H.construct([R, param])
        # Create cut Hamiltonian
        Hc = H.cut(2, 1).cut(2, 0)
        eigc = Hc.eigh()
        eigg = Hg.eigh()
        assert_true(np.allclose(eigc, eigg))
        assert_true(np.allclose(Hg.eigh(), Hc.eigh()))
        del Hc, H

    def test_cut2(self):
        # Test of eigenvalues using a cut
        # Hamiltonian
        R, param = [0.1, 1.5], [(1., 1.), (0.1, 0.1)]

        # Create reference
        Hg = Hamiltonian(self.g, orthogonal=False)
        Hg.construct([R, param])

        g = self.g.tile(2, 0).tile(2, 1)
        H = Hamiltonian(g, orthogonal=False)
        H.construct([R, param])
        # Create cut Hamiltonian
        Hc = H.cut(2, 1).cut(2, 0)
        eigc = Hc.eigh()
        eigg = Hg.eigh()
        assert_true(np.allclose(Hg.eigh(), Hc.eigh()))
        del Hc, H

    def test_eig1(self):
        # Test of eigenvalues
        R, param = [0.1, 1.5], [1., 0.1]
        g = self.g.tile(2, 0).tile(2, 1).tile(2, 2)
        H = Hamiltonian(g)
        H.construct((R, param), eta=True)
        eig1 = H.eigh()
        for i in range(2):
            assert_true(np.allclose(eig1, H.eigh()))
        H.eigsh(n=4)
        H.empty()
        del H

    def test_eig2(self):
        # Test of eigenvalues
        HS = self.HS.copy()
        HS.construct([(0.1, 1.5), ((1., 1.), (0.1, 0.1))])
        eig1 = HS.eigh()
        for i in range(2):
            assert_true(np.allclose(eig1, HS.eigh()))
        self.HS.empty()

    def test_eig3(self):
        self.HS.construct([(0.1, 1.5), ((1., 1.), (0.1, 0.1))])
        BS = PathBZ(self.HS, [[0, 0, 0], [0.5, 0.5, 0]], 10)
        eigs = BS.array().eigh()
        assert_equal(len(BS), eigs.shape[0])
        assert_equal(len(self.HS), eigs.shape[1])
        eig2 = np.array([eig for eig in BS.yields().eigh()])
        assert_true(np.allclose(eigs, eig2))
        self.HS.empty()

    def test_spin1(self):
        g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.int32, spin=2)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = (i, i * 2)

        H2 = Hamiltonian(g, 2, dtype=np.int32)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H2[0, j] = (i, i * 2)
        assert_true(H.spsame(H2))

    def test_spin2(self):
        g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.int32, spin=2)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = (i, i * 2)

        H2 = Hamiltonian(g, 2, dtype=np.int32)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H2[0, j] = (i, i * 2)
        assert_true(H.spsame(H2))

        H2 = Hamiltonian(g, Spin(2), dtype=np.int32)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H2[0, j] = (i, i * 2)
        assert_true(H.spsame(H2))

        H2 = Hamiltonian(g, Spin('polarized'), dtype=np.int32)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H2[0, j] = (i, i * 2)
        assert_true(H.spsame(H2))

    def test_non_colinear1(self):
        g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.float64, spin=4)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[i, i, 0] = 0.
            H[i, i, 1] = 0.
            H[i, i, 2] = 0.1
            H[i, i, 3] = 0.1
            if i > 0:
                H[i, i - 1, 0] = 1.
                H[i, i - 1, 1] = 1.
            if i < 9:
                H[i, i + 1, 0] = 1.
                H[i, i + 1, 1] = 1.
        eig1 = H.eigh()
        # Check TimeSelector
        for i in range(2):
            assert_true(np.allclose(H.eigh(), eig1))
        assert_true(len(eig1) == len(H))

        H1 = Hamiltonian(g, dtype=np.float64, spin=Spin('non-colinear'))
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H1[i, i, 0] = 0.
            H1[i, i, 1] = 0.
            H1[i, i, 2] = 0.1
            H1[i, i, 3] = 0.1
            if i > 0:
                H1[i, i - 1, 0] = 1.
                H1[i, i - 1, 1] = 1.
            if i < 9:
                H1[i, i + 1, 0] = 1.
                H1[i, i + 1, 1] = 1.
        assert_true(H1.spsame(H))
        eig1 = H1.eigh()
        # Check TimeSelector
        for i in range(2):
            assert_true(np.allclose(H1.eigh(), eig1))
        assert_true(np.allclose(H.eigh(), H1.eigh()))

    def test_so1(self):
        g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.float64, spin=8)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[i, i, 0] = 0.
            H[i, i, 1] = 0.
            H[i, i, 2] = 0.1
            H[i, i, 3] = 0.1
            H[i, i, 4] = 0.1
            H[i, i, 5] = 0.1
            H[i, i, 6] = 0.1
            H[i, i, 7] = 0.1
            if i > 0:
                H[i, i - 1, 0] = 1.
                H[i, i - 1, 1] = 1.
            if i < 9:
                H[i, i + 1, 0] = 1.
                H[i, i + 1, 1] = 1.
        eig1 = H.eigh()
        # Check TimeSelector
        for i in range(2):
            assert_true(np.allclose(H.eigh(), eig1))
        assert_true(len(H.eigh()) == len(H))

        H1 = Hamiltonian(g, dtype=np.float64, spin=Spin('spin-orbit'))
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H1[i, i, 0] = 0.
            H1[i, i, 1] = 0.
            H1[i, i, 2] = 0.1
            H1[i, i, 3] = 0.1
            if i > 0:
                H1[i, i - 1, 0] = 1.
                H1[i, i - 1, 1] = 1.
            if i < 9:
                H1[i, i + 1, 0] = 1.
                H1[i, i + 1, 1] = 1.
        assert_true(H1.spsame(H))
        eig1 = H1.eigh()
        # Check TimeSelector
        for i in range(2):
            assert_true(np.allclose(H1.eigh(), eig1))
        assert_true(np.allclose(H.eigh(), H1.eigh()))

    def test_finalized(self):
        assert_false(self.H.finalized)
        self.H.H[0, 0] = 1.
        self.H.finalize()
        assert_true(self.H.finalized)
        assert_true(self.H.nnz == 1)
        self.H.empty()
        assert_false(self.HS.finalized)
        self.HS.H[0, 0] = 1.
        self.HS.S[0, 0] = 1.
        self.HS.finalize()
        assert_true(self.HS.finalized)
        assert_true(self.HS.nnz == 1)
        self.HS.empty()

    @attr('slow')
    def test_tile1(self):
        R, param = [0.1, 1.5], [1., 0.1]

        # Create reference
        Hg = Hamiltonian(self.g.tile(2, 0).tile(2, 1).tile(2, 2))
        Hg.construct([R, param])
        Hg.finalize()
        H = Hamiltonian(self.g)
        H.construct([R, param])
        H = H.tile(2, 0).tile(2, 1).tile(2, 2, eta=True)
        assert_true(Hg.spsame(H))

    @attr('slow')
    def test_tile2(self):
        R, param = [0.1, 1.5], [1., 0.1]

        # Create reference
        Hg = Hamiltonian(self.g.tile(2, 0))
        Hg.construct([R, param])
        Hg.finalize()
        H = Hamiltonian(self.g)
        H.construct([R, param])
        H = H.tile(2, 0)
        assert_true(Hg.spsame(H))

    @attr('slow')
    def test_tile3(self):
        R, param = [0.1, 1.1, 2.1, 3.1], [1., 2., 3., 4.]

        # Create reference
        g = Geometry([[0] * 3], Atom('H', R=[4.]), sc=[1.] * 3)
        g.set_nsc([7] * 3)

        # Now create bigger geometry
        G = g.tile(2, 0).tile(2, 1).tile(2, 2)

        HG = Hamiltonian(G.tile(2, 0).tile(2, 1).tile(2, 2))
        HG.construct([R, param])
        HG.finalize()
        H = Hamiltonian(G)
        H.construct([R, param])
        H.finalize()
        H = H.tile(2, 0).tile(2, 1).tile(2, 2)
        assert_true(HG.spsame(H))

    def test_tile4(self):
        def func(self, ia, idxs, idxs_xyz=None):
            idx = self.geom.close(ia, R=[0.1, 1.43], idx=idxs)
            io = self.geom.a2o(ia)
            # Set on-site on first and second orbital
            odx = self.geom.a2o(idx[0])
            self[io, odx] = -1.
            self[io + 1, odx + 1] = 1.

            # Set connecting
            odx = self.geom.a2o(idx[1])
            self[io, odx] = 0.2
            self[io, odx + 1] = 0.01
            self[io + 1, odx] = 0.01
            self[io + 1, odx + 1] = 0.3

        self.H2.construct(func)
        Hbig = self.H2.tile(3, 0).tile(3, 1)

        gbig = self.H2.geom.tile(3, 0).tile(3, 1)
        H = Hamiltonian(gbig)
        H.construct(func)
        assert_true(H.spsame(Hbig))
        self.H2.empty()

    @attr('slow')
    def test_repeat1(self):
        R, param = [0.1, 1.5], [1., 0.1]

        # Create reference
        Hg = Hamiltonian(self.g.repeat(2, 0))
        Hg.construct([R, param])
        Hg.finalize()
        H = Hamiltonian(self.g)
        H.construct([R, param])
        H = H.repeat(2, 0)
        assert_true(Hg.spsame(H))

    @attr('slow')
    def test_repeat2(self):
        R, param = [0.1, 1.5], [1., 0.1]

        # Create reference
        Hg = Hamiltonian(self.g.repeat(2, 0).repeat(2, 1).repeat(2, 2))
        Hg.construct([R, param])
        Hg.finalize()
        H = Hamiltonian(self.g)
        H.construct([R, param])
        H = H.repeat(2, 0).repeat(2, 1).repeat(2, 2, eta=True)
        assert_true(Hg.spsame(H))

    @attr('slow')
    def test_repeat3(self):
        R, param = [0.1, 1.1, 2.1, 3.1], [1., 2., 3., 4.]

        # Create reference
        g = Geometry([[0] * 3], Atom('H', R=[4.]), sc=[1.] * 3)
        g.set_nsc([7] * 3)

        # Now create bigger geometry
        G = g.repeat(2, 0).repeat(2, 1).repeat(2, 2)

        HG = Hamiltonian(G.repeat(2, 0).repeat(2, 1).repeat(2, 2))
        HG.construct([R, param])
        HG.finalize()
        H = Hamiltonian(G)
        H.construct([R, param])
        H.finalize()
        H = H.repeat(2, 0).repeat(2, 1).repeat(2, 2)
        assert_true(HG.spsame(H))

    @attr('slow')
    def test_repeat4(self):
        def func(self, ia, idxs, idxs_xyz=None):
            idx = self.geom.close(ia, R=[0.1, 1.43], idx=idxs)
            io = self.geom.a2o(ia)
            # Set on-site on first and second orbital
            odx = self.geom.a2o(idx[0])
            self[io, odx] = -1.
            self[io + 1, odx + 1] = 1.

            # Set connecting
            odx = self.geom.a2o(idx[1])
            self[io, odx] = 0.2
            self[io, odx + 1] = 0.01
            self[io + 1, odx] = 0.01
            self[io + 1, odx + 1] = 0.3

        self.H2.construct(func)
        Hbig = self.H2.repeat(3, 0).repeat(3, 1)

        gbig = self.H2.geom.repeat(3, 0).repeat(3, 1)
        H = Hamiltonian(gbig)
        H.construct(func)

        assert_true(H.spsame(Hbig))
        self.H2.empty()

    def test_sub1(self):
        R, param = [0.1, 1.5], [1., 0.1]

        # Create reference
        H = Hamiltonian(self.g)
        H.construct([R, param])
        H.finalize()
        # Tiling in this direction will not introduce
        # any new connections.
        # So tiling and removing is a no-op (but
        # increases vacuum in 3rd lattice vector)
        Hg = Hamiltonian(self.g.tile(2, 2))
        Hg.construct([R, param])
        Hg = Hg.sub(range(len(self.g)))
        Hg.finalize()
        assert_true(Hg.spsame(H))
Exemple #6
0
class TestGeometry(object):
    def setUp(self):
        bond = 1.42
        sq3h = 3.0 ** 0.5 * 0.5
        self.sc = SuperCell(
            np.array([[1.5, sq3h, 0.0], [1.5, -sq3h, 0.0], [0.0, 0.0, 10.0]], np.float64) * bond, nsc=[3, 3, 1]
        )
        C = Atom(Z=6, R=bond * 1.01, orbs=2)
        self.g = Geometry(np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]], np.float64) * bond, atom=C, sc=self.sc)

        self.mol = Geometry([[i, 0, 0] for i in range(10)], sc=[50])

    def tearDown(self):
        del self.g
        del self.sc
        del self.mol

    def test_objects(self):
        # just make sure __repr__ works
        print(self.g)
        assert_true(len(self.g) == 2)
        assert_true(len(self.g.xyz) == 2)
        assert_true(np.allclose(self.g[0, :], np.zeros([3])))

        i = 0
        for ia in self.g:
            i += 1
        assert_true(i == len(self.g))
        assert_true(self.g.no_s == 2 * len(self.g) * np.prod(self.g.sc.nsc))

    def test_iter1(self):
        i = 0
        for ia in self.g:
            i += 1
        assert_true(i == 2)

    def test_iter2(self):
        for ia in self.g:
            assert_true(np.allclose(self.g[ia, :], self.g.xyz[ia, :]))

    def test_tile1(self):
        cell = np.copy(self.g.sc.cell)
        cell[0, :] *= 2
        t = self.g.tile(2, 0)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[1, :] *= 2
        t = t.tile(2, 1)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[2, :] *= 2
        t = t.tile(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_tile2(self):
        cell = np.copy(self.g.sc.cell)
        cell[:, :] *= 2
        t = self.g.tile(2, 0).tile(2, 1).tile(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_repeat1(self):
        cell = np.copy(self.g.sc.cell)
        cell[0, :] *= 2
        t = self.g.repeat(2, 0)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[1, :] *= 2
        t = t.repeat(2, 1)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[2, :] *= 2
        t = t.repeat(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_repeat2(self):
        cell = np.copy(self.g.sc.cell)
        cell[:, :] *= 2
        t = self.g.repeat(2, 0).repeat(2, 1).repeat(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_a2o1(self):
        assert_true(0 == self.g.a2o(0))
        assert_true(self.g.atom[0].orbs == self.g.a2o(1))
        assert_true(self.g.no == self.g.a2o(self.g.na))

    def test_sub1(self):
        assert_true(len(self.g.sub([0])) == 1)
        assert_true(len(self.g.sub([0, 1])) == 2)
        assert_true(len(self.g.sub([-1])) == 1)

    def test_sub2(self):
        assert_true(len(self.g.sub(range(1))) == 1)
        assert_true(len(self.g.sub(range(2))) == 2)

    def test_cut(self):
        assert_true(len(self.g.cut(1, 1)) == 2)
        assert_true(len(self.g.cut(2, 1)) == 1)
        assert_true(len(self.g.cut(2, 1, 1)) == 1)

    def test_cut2(self):
        c1 = self.g.cut(2, 1)
        c2 = self.g.cut(2, 1, 1)
        assert_true(np.allclose(c1.xyz[0, :], self.g.xyz[0, :]))
        assert_true(np.allclose(c2.xyz[0, :], self.g.xyz[1, :]))

    def test_remove1(self):
        assert_true(len(self.g.remove([0])) == 1)
        assert_true(len(self.g.remove([])) == 2)
        assert_true(len(self.g.remove([-1])) == 1)
        assert_true(len(self.g.remove([-0])) == 1)

    def test_remove2(self):
        assert_true(len(self.g.remove(range(1))) == 1)
        assert_true(len(self.g.remove(range(0))) == 2)

    def test_copy(self):
        assert_true(self.g == self.g.copy())

    def test_nsc1(self):
        nsc = np.copy(self.g.nsc)
        self.g.sc.set_nsc([5, 5, 0])
        assert_true(np.allclose([5, 5, 1], self.g.nsc))
        assert_true(len(self.g.sc_off) == np.prod(self.g.nsc))

    def test_nsc2(self):
        nsc = np.copy(self.g.nsc)
        self.g.sc.set_nsc([0, 1, 0])
        assert_true(np.allclose([1, 1, 1], self.g.nsc))
        assert_true(len(self.g.sc_off) == np.prod(self.g.nsc))

    def test_rotation1(self):
        rot = self.g.rotate(180, [0, 0, 1])
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True)
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1])
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_rotation2(self):
        rot = self.g.rotate(180, [0, 0, 1], only="abc")
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True, only="abc")
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1], only="abc")
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_rotation3(self):
        rot = self.g.rotate(180, [0, 0, 1], only="xyz")
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True, only="xyz")
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1], only="xyz")
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_translate(self):
        t = self.g.translate([0, 0, 1])
        assert_true(np.allclose(self.g[:, 0], t[:, 0]))
        assert_true(np.allclose(self.g[:, 1], t[:, 1]))
        assert_true(np.allclose(self.g[:, 2] + 1, t[:, 2]))
        t = self.g.move([0, 0, 1])
        assert_true(np.allclose(self.g[:, 0], t[:, 0]))
        assert_true(np.allclose(self.g[:, 1], t[:, 1]))
        assert_true(np.allclose(self.g[:, 2] + 1, t[:, 2]))

    def test_iter(self):
        for i, iaaspec in enumerate(self.g.iter_species()):
            ia, a, spec = iaaspec
            assert_true(i == ia)
            assert_true(self.g.atom[ia] == a)
        for ia in self.g:
            assert_true(ia >= 0)
        i = 0
        for ias, idx in self.g.iter_block():
            for ia in ias:
                i += 1
        assert_true(i == len(self.g))

    def test_swap(self):
        s = self.g.swap(0, 1)
        for i in [0, 1, 2]:
            assert_true(np.allclose(self.g[::-1, i], s[:, i]))

    def test_append1(self):
        for axis in [0, 1, 2]:
            s = self.g.append(self.g, axis)
            assert_equal(len(s), len(self.g) * 2)
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.prepend(self.g, axis)
            assert_equal(len(s), len(self.g) * 2)
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.append(self.g.sc, axis)
            assert_equal(len(s), len(self.g))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.prepend(self.g.sc, axis)
            assert_equal(len(s), len(self.g))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))

    def test_swapaxes(self):
        s = self.g.swapaxes(0, 1)
        assert_true(np.allclose(self.g[:, 0], s[:, 1]))
        assert_true(np.allclose(self.g[:, 1], s[:, 0]))
        assert_true(np.allclose(self.g.cell[0, :], s.cell[1, :]))
        assert_true(np.allclose(self.g.cell[1, :], s.cell[0, :]))

    def test_center(self):
        one = self.g.center(atom=[0])
        assert_true(np.allclose(self.g[0, :], one))
        al = self.g.center()
        assert_true(np.allclose(np.mean(self.g.xyz, axis=0), al))

    def test_add(self):
        double = self.g.add(self.g)
        assert_equal(len(double), len(self.g) * 2)
        assert_true(np.allclose(self.g.cell, double.cell))

    def test_insert(self):
        double = self.g.insert(0, self.g)
        assert_equal(len(double), len(self.g) * 2)
        assert_true(np.allclose(self.g.cell, double.cell))

    def test_a2o(self):
        # There are 2 orbitals per C atom
        assert_equal(self.g.a2o(1), self.g.atom[0].orbs)

    def test_o2a(self):
        # There are 2 orbitals per C atom
        assert_equal(self.g.o2a(2), 1)

    def test_reverse(self):
        rev = self.g.reverse()
        assert_true(len(rev) == 2)
        assert_true(np.allclose(rev.xyz[::-1, :], self.g.xyz))
        rev = self.g.reverse(atom=list(range(len(self.g))))
        assert_true(len(rev) == 2)
        assert_true(np.allclose(rev.xyz[::-1, :], self.g.xyz))

    def test_close1(self):
        three = range(3)
        for ia in self.mol:
            i = self.mol.close(ia, dR=(0.1, 1.1), idx=three)
            if ia < 3:
                assert_equal(len(i[0]), 1)
            else:
                assert_equal(len(i[0]), 0)
            # Will only return results from [0,1,2]
            # but the fourth atom connects to
            # the third
            if ia in [0, 2, 3]:
                assert_equal(len(i[1]), 1)
            elif ia == 1:
                assert_equal(len(i[1]), 2)
            else:
                assert_equal(len(i[1]), 0)

    def test_close2(self):
        mol = range(3, 5)
        for ia in self.mol:
            i = self.mol.close(ia, dR=(0.1, 1.1), idx=mol)
            assert_equal(len(i), 2)
        i = self.mol.close([100, 100, 100], dR=0.1)
        assert_equal(len(i), 0)
        i = self.mol.close([100, 100, 100], dR=0.1, ret_dist=True)
        for el in i:
            assert_equal(len(el), 0)
        i = self.mol.close([100, 100, 100], dR=0.1, ret_dist=True, ret_coord=True)
        for el in i:
            assert_equal(len(el), 0)

    def test_close_sizes(self):
        point = 0

        # Return index
        idx = self.mol.close(point, dR=0.1)
        assert_equal(len(idx), 1)
        # Return index of two things
        idx = self.mol.close(point, dR=(0.1, 1.1))
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 1)
        assert_false(isinstance(idx[0], list))
        # Longer
        idx = self.mol.close(point, dR=(0.1, 1.1, 2.1))
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 1)

        # Return index
        idx = self.mol.close(point, dR=0.1, ret_coord=True)
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 1)
        assert_equal(len(idx[1]), 1)
        assert_equal(idx[1].shape[0], 1)  # equivalent to above
        assert_equal(idx[1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, dR=(0.1, 1.1), ret_coord=True)
        # [[idx-1, idx-2], [coord-1, coord-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, dR=(0.1, 1.1), ret_coord=True, ret_dist=True)
        # [[idx-1, idx-2], [coord-1, coord-2], [dist-1, dist-2]]
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)
        # dist-1
        assert_equal(len(idx[2][0].shape), 1)
        assert_equal(idx[2][0].shape[0], 1)
        # dist-2
        assert_equal(idx[2][1].shape[0], 1)

        # Return index of two things
        idx = self.mol.close(point, dR=(0.1, 1.1), ret_dist=True)
        # [[idx-1, idx-2], [dist-1, dist-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # dist-1
        assert_equal(len(idx[1][0].shape), 1)
        assert_equal(idx[1][0].shape[0], 1)
        # dist-2
        assert_equal(idx[1][1].shape[0], 1)

    def test_close_sizes_none(self):
        point = [100.0, 100.0, 100.0]

        # Return index
        idx = self.mol.close(point, dR=0.1)
        assert_equal(len(idx), 0)
        # Return index of two things
        idx = self.mol.close(point, dR=(0.1, 1.1))
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 0)
        assert_false(isinstance(idx[0], list))
        # Longer
        idx = self.mol.close(point, dR=(0.1, 1.1, 2.1))
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 0)

        # Return index
        idx = self.mol.close(point, dR=0.1, ret_coord=True)
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 0)
        assert_equal(len(idx[1]), 0)
        assert_equal(idx[1].shape[0], 0)  # equivalent to above
        assert_equal(idx[1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, dR=(0.1, 1.1), ret_coord=True)
        # [[idx-1, idx-2], [coord-1, coord-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, dR=(0.1, 1.1), ret_coord=True, ret_dist=True)
        # [[idx-1, idx-2], [coord-1, coord-2], [dist-1, dist-2]]
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[0], 0)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[0], 0)
        assert_equal(idx[1][1].shape[1], 3)
        # dist-1
        assert_equal(len(idx[2][0].shape), 1)
        assert_equal(idx[2][0].shape[0], 0)
        # dist-2
        assert_equal(idx[2][1].shape[0], 0)

        # Return index of two things
        idx = self.mol.close(point, dR=(0.1, 1.1), ret_dist=True)
        # [[idx-1, idx-2], [dist-1, dist-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # dist-1
        assert_equal(len(idx[1][0].shape), 1)
        assert_equal(idx[1][0].shape[0], 0)
        # dist-2
        assert_equal(idx[1][1].shape[0], 0)

    def test_bond_correct(self):
        # Create ribbon
        rib = self.g.tile(2, 1)
        # Convert the last atom to a H atom
        rib.atom[-1] = Atom[1]
        ia = len(rib) - 1
        # Get bond-length
        idx, d = rib.close(ia, dR=(0.1, 1000), ret_dist=True)
        i = np.argmin(d[1])
        d = d[1][i]
        rib.bond_correct(ia, idx[1][i])
        idx, d2 = rib.close(ia, dR=(0.1, 1000), ret_dist=True)
        i = np.argmin(d2[1])
        d2 = d2[1][i]
        assert_false(d == d2)
        # Calculate actual radius
        assert_true(d2 == (Atom[1].radius() + Atom[6].radius()))

    def test_unit_cell_estimation1(self):
        # Create new geometry with only the coordinates
        # and atoms
        geom = Geometry(self.g.xyz, Atom[6])
        # Only check the two distances we know have sizes
        for i in range(2):
            # It cannot guess skewed axis
            assert_false(np.allclose(geom.cell[i, :], self.g.cell[i, :]))

    def test_unit_cell_estimation2(self):
        # Create new geometry with only the coordinates
        # and atoms
        s1 = SuperCell([2, 2, 2])
        g1 = Geometry([[0, 0, 0], [1, 1, 1]], sc=s1)
        g2 = Geometry(np.copy(g1.xyz))
        assert_true(np.allclose(g1.cell, g2.cell))

        # Assert that it correctly calculates the bond-length in the
        # directions of actual distance
        g1 = Geometry([[0, 0, 0], [1, 1, 0]], atom="H", sc=s1)
        g2 = Geometry(np.copy(g1.xyz))
        for i in range(2):
            assert_true(np.allclose(g1.cell[i, :], g2.cell[i, :]))
        assert_false(np.allclose(g1.cell[2, :], g2.cell[2, :]))

    def test_argumentparser(self):
        self.g.ArgumentParser()

    def test_set_sc(self):
        # Create new geometry with only the coordinates
        # and atoms
        s1 = SuperCell([2, 2, 2])
        g1 = Geometry([[0, 0, 0], [1, 1, 1]], sc=[2, 2, 1])
        g1.set_sc(s1)
        assert_true(g1.sc == s1)

    def test_attach1(self):
        g = self.g.attach(0, self.mol, 0, dist=1.42, axis=2)
        g = self.g.attach(0, self.mol, 0, dist="calc", axis=2)
        g = self.g.attach(0, self.mol, 0, dist=[0, 0, 1.42])

    def test_mirror1(self):
        for plane in ["xy", "xz", "yz"]:
            self.g.mirror(plane)

    def test_pickle(self):
        import pickle as p

        s = p.dumps(self.g)
        n = p.loads(s)
        assert_true(n == self.g)
        assert_false(n != self.g)
Exemple #7
0
class TestGeometry(object):
    def setUp(self):
        bond = 1.42
        sq3h = 3.**.5 * 0.5
        self.sc = SuperCell(np.array(
            [[1.5, sq3h, 0.], [1.5, -sq3h, 0.], [0., 0., 10.]], np.float64) *
                            bond,
                            nsc=[3, 3, 1])
        C = Atom(Z=6, R=bond * 1.01, orbs=2)
        self.g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) *
                          bond,
                          atom=C,
                          sc=self.sc)

        self.mol = Geometry([[i, 0, 0] for i in range(10)], sc=[50])

    def tearDown(self):
        del self.g
        del self.sc
        del self.mol

    def test_objects(self):
        # just make sure __repr__ works
        print(self.g)
        assert_true(len(self.g) == 2)
        assert_true(len(self.g.xyz) == 2)
        assert_true(np.allclose(self.g[0, :], np.zeros([3])))

        i = 0
        for ia in self.g:
            i += 1
        assert_true(i == len(self.g))
        assert_true(self.g.no_s == 2 * len(self.g) * np.prod(self.g.sc.nsc))

    def test_iter1(self):
        i = 0
        for ia in self.g:
            i += 1
        assert_true(i == 2)

    def test_iter2(self):
        for ia in self.g:
            assert_true(np.allclose(self.g[ia, :], self.g.xyz[ia, :]))

    def test_tile1(self):
        cell = np.copy(self.g.sc.cell)
        cell[0, :] *= 2
        t = self.g.tile(2, 0)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[1, :] *= 2
        t = t.tile(2, 1)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[2, :] *= 2
        t = t.tile(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_tile2(self):
        cell = np.copy(self.g.sc.cell)
        cell[:, :] *= 2
        t = self.g.tile(2, 0).tile(2, 1).tile(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_repeat1(self):
        cell = np.copy(self.g.sc.cell)
        cell[0, :] *= 2
        t = self.g.repeat(2, 0)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[1, :] *= 2
        t = t.repeat(2, 1)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[2, :] *= 2
        t = t.repeat(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_repeat2(self):
        cell = np.copy(self.g.sc.cell)
        cell[:, :] *= 2
        t = self.g.repeat(2, 0).repeat(2, 1).repeat(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_a2o1(self):
        assert_true(0 == self.g.a2o(0))
        assert_true(self.g.atom[0].orbs == self.g.a2o(1))
        assert_true(self.g.no == self.g.a2o(self.g.na))

    def test_sub1(self):
        assert_true(len(self.g.sub([0])) == 1)
        assert_true(len(self.g.sub([0, 1])) == 2)
        assert_true(len(self.g.sub([-1])) == 1)

    def test_sub2(self):
        assert_true(len(self.g.sub(range(1))) == 1)
        assert_true(len(self.g.sub(range(2))) == 2)

    def test_fxyz(self):
        assert_true(np.allclose(self.g.fxyz, [[0, 0, 0], [1. / 3, 1. / 3, 0]]))

    def test_cut(self):
        assert_true(len(self.g.cut(1, 1)) == 2)
        assert_true(len(self.g.cut(2, 1)) == 1)
        assert_true(len(self.g.cut(2, 1, 1)) == 1)

    def test_cut2(self):
        c1 = self.g.cut(2, 1)
        c2 = self.g.cut(2, 1, 1)
        assert_true(np.allclose(c1.xyz[0, :], self.g.xyz[0, :]))
        assert_true(np.allclose(c2.xyz[0, :], self.g.xyz[1, :]))

    def test_remove1(self):
        assert_true(len(self.g.remove([0])) == 1)
        assert_true(len(self.g.remove([])) == 2)
        assert_true(len(self.g.remove([-1])) == 1)
        assert_true(len(self.g.remove([-0])) == 1)

    def test_remove2(self):
        assert_true(len(self.g.remove(range(1))) == 1)
        assert_true(len(self.g.remove(range(0))) == 2)

    def test_copy(self):
        assert_true(self.g == self.g.copy())

    def test_nsc1(self):
        nsc = np.copy(self.g.nsc)
        self.g.sc.set_nsc([5, 5, 0])
        assert_true(np.allclose([5, 5, 1], self.g.nsc))
        assert_true(len(self.g.sc_off) == np.prod(self.g.nsc))

    def test_nsc2(self):
        nsc = np.copy(self.g.nsc)
        self.g.sc.set_nsc([0, 1, 0])
        assert_true(np.allclose([1, 1, 1], self.g.nsc))
        assert_true(len(self.g.sc_off) == np.prod(self.g.nsc))

    def test_rotation1(self):
        rot = self.g.rotate(180, [0, 0, 1])
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True)
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1])
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_rotation2(self):
        rot = self.g.rotate(180, [0, 0, 1], only='abc')
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True, only='abc')
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1], only='abc')
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_rotation3(self):
        rot = self.g.rotate(180, [0, 0, 1], only='xyz')
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True, only='xyz')
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1], only='xyz')
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_translate(self):
        t = self.g.translate([0, 0, 1])
        assert_true(np.allclose(self.g[:, 0], t[:, 0]))
        assert_true(np.allclose(self.g[:, 1], t[:, 1]))
        assert_true(np.allclose(self.g[:, 2] + 1, t[:, 2]))
        t = self.g.move([0, 0, 1])
        assert_true(np.allclose(self.g[:, 0], t[:, 0]))
        assert_true(np.allclose(self.g[:, 1], t[:, 1]))
        assert_true(np.allclose(self.g[:, 2] + 1, t[:, 2]))

    def test_iter(self):
        for i, iaaspec in enumerate(self.g.iter_species()):
            ia, a, spec = iaaspec
            assert_true(i == ia)
            assert_true(self.g.atom[ia] == a)
        for ia in self.g:
            assert_true(ia >= 0)
        i = 0
        for ias, idx in self.g.iter_block():
            for ia in ias:
                i += 1
        assert_true(i == len(self.g))

    def test_swap(self):
        s = self.g.swap(0, 1)
        for i in [0, 1, 2]:
            assert_true(np.allclose(self.g[::-1, i], s[:, i]))

    def test_append1(self):
        for axis in [0, 1, 2]:
            s = self.g.append(self.g, axis)
            assert_equal(len(s), len(self.g) * 2)
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.prepend(self.g, axis)
            assert_equal(len(s), len(self.g) * 2)
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.append(self.g.sc, axis)
            assert_equal(len(s), len(self.g))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.prepend(self.g.sc, axis)
            assert_equal(len(s), len(self.g))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))

    def test_swapaxes(self):
        s = self.g.swapaxes(0, 1)
        assert_true(np.allclose(self.g[:, 0], s[:, 1]))
        assert_true(np.allclose(self.g[:, 1], s[:, 0]))
        assert_true(np.allclose(self.g.cell[0, :], s.cell[1, :]))
        assert_true(np.allclose(self.g.cell[1, :], s.cell[0, :]))

    def test_center(self):
        one = self.g.center(atom=[0])
        assert_true(np.allclose(self.g[0, :], one))
        al = self.g.center()
        assert_true(np.allclose(np.mean(self.g.xyz, axis=0), al))

    def test_add(self):
        double = self.g.add(self.g)
        assert_equal(len(double), len(self.g) * 2)
        assert_true(np.allclose(self.g.cell, double.cell))

    def test_insert(self):
        double = self.g.insert(0, self.g)
        assert_equal(len(double), len(self.g) * 2)
        assert_true(np.allclose(self.g.cell, double.cell))

    def test_a2o(self):
        # There are 2 orbitals per C atom
        assert_equal(self.g.a2o(1), self.g.atom[0].orbs)

    def test_o2a(self):
        # There are 2 orbitals per C atom
        assert_equal(self.g.o2a(2), 1)

    def test_reverse(self):
        rev = self.g.reverse()
        assert_true(len(rev) == 2)
        assert_true(np.allclose(rev.xyz[::-1, :], self.g.xyz))
        rev = self.g.reverse(atom=list(range(len(self.g))))
        assert_true(len(rev) == 2)
        assert_true(np.allclose(rev.xyz[::-1, :], self.g.xyz))

    def test_close1(self):
        three = range(3)
        for ia in self.mol:
            i = self.mol.close(ia, dR=(0.1, 1.1), idx=three)
            if ia < 3:
                assert_equal(len(i[0]), 1)
            else:
                assert_equal(len(i[0]), 0)
            # Will only return results from [0,1,2]
            # but the fourth atom connects to
            # the third
            if ia in [0, 2, 3]:
                assert_equal(len(i[1]), 1)
            elif ia == 1:
                assert_equal(len(i[1]), 2)
            else:
                assert_equal(len(i[1]), 0)

    def test_close2(self):
        mol = range(3, 5)
        for ia in self.mol:
            i = self.mol.close(ia, dR=(0.1, 1.1), idx=mol)
            assert_equal(len(i), 2)
        i = self.mol.close([100, 100, 100], dR=0.1)
        assert_equal(len(i), 0)
        i = self.mol.close([100, 100, 100], dR=0.1, ret_dist=True)
        for el in i:
            assert_equal(len(el), 0)
        i = self.mol.close([100, 100, 100],
                           dR=0.1,
                           ret_dist=True,
                           ret_coord=True)
        for el in i:
            assert_equal(len(el), 0)

    def test_close_within1(self):
        three = range(3)
        for ia in self.mol:
            shapes = [Sphere(0.1, self.mol[ia]), Sphere(1.1, self.mol[ia])]
            i = self.mol.close(ia, dR=(0.1, 1.1), idx=three)
            ii = self.mol.within(shapes, idx=three)
            assert_true(np.all(i[0] == ii[0]))
            assert_true(np.all(i[1] == ii[1]))

    def test_close_within2(self):
        g = self.g.repeat(6, 0).repeat(6, 1)
        for ia in g:
            shapes = [Sphere(0.1, g[ia, :]), Sphere(1.5, g[ia, :])]
            i = g.close(ia, dR=(0.1, 1.5))
            ii = g.within(shapes)
            assert_true(np.all(i[0] == ii[0]))
            assert_true(np.all(i[1] == ii[1]))

    def test_close_within3(self):
        g = self.g.repeat(6, 0).repeat(6, 1)
        args = {'ret_coord': True, 'ret_dist': True}
        for ia in g:
            shapes = [Sphere(0.1, g[ia, :]), Sphere(1.5, g[ia, :])]
            i, xa, d = g.close(ia, dR=(0.1, 1.5), **args)
            ii, xai, di = g.within(shapes, **args)
            for j in [0, 1]:
                assert_true(np.all(i[j] == ii[j]))
                assert_true(np.allclose(xa[j], xai[j]))
                assert_true(np.allclose(d[j], di[j]))

    def test_close_sizes(self):
        point = 0

        # Return index
        idx = self.mol.close(point, dR=.1)
        assert_equal(len(idx), 1)
        # Return index of two things
        idx = self.mol.close(point, dR=(.1, 1.1))
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 1)
        assert_false(isinstance(idx[0], list))
        # Longer
        idx = self.mol.close(point, dR=(.1, 1.1, 2.1))
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 1)

        # Return index
        idx = self.mol.close(point, dR=.1, ret_coord=True)
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 1)
        assert_equal(len(idx[1]), 1)
        assert_equal(idx[1].shape[0], 1)  # equivalent to above
        assert_equal(idx[1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, dR=(.1, 1.1), ret_coord=True)
        # [[idx-1, idx-2], [coord-1, coord-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point,
                             dR=(.1, 1.1),
                             ret_coord=True,
                             ret_dist=True)
        # [[idx-1, idx-2], [coord-1, coord-2], [dist-1, dist-2]]
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)
        # dist-1
        assert_equal(len(idx[2][0].shape), 1)
        assert_equal(idx[2][0].shape[0], 1)
        # dist-2
        assert_equal(idx[2][1].shape[0], 1)

        # Return index of two things
        idx = self.mol.close(point, dR=(.1, 1.1), ret_dist=True)
        # [[idx-1, idx-2], [dist-1, dist-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # dist-1
        assert_equal(len(idx[1][0].shape), 1)
        assert_equal(idx[1][0].shape[0], 1)
        # dist-2
        assert_equal(idx[1][1].shape[0], 1)

    def test_close_sizes_none(self):
        point = [100., 100., 100.]

        # Return index
        idx = self.mol.close(point, dR=.1)
        assert_equal(len(idx), 0)
        # Return index of two things
        idx = self.mol.close(point, dR=(.1, 1.1))
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 0)
        assert_false(isinstance(idx[0], list))
        # Longer
        idx = self.mol.close(point, dR=(.1, 1.1, 2.1))
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 0)

        # Return index
        idx = self.mol.close(point, dR=.1, ret_coord=True)
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 0)
        assert_equal(len(idx[1]), 0)
        assert_equal(idx[1].shape[0], 0)  # equivalent to above
        assert_equal(idx[1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, dR=(.1, 1.1), ret_coord=True)
        # [[idx-1, idx-2], [coord-1, coord-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point,
                             dR=(.1, 1.1),
                             ret_coord=True,
                             ret_dist=True)
        # [[idx-1, idx-2], [coord-1, coord-2], [dist-1, dist-2]]
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[0], 0)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[0], 0)
        assert_equal(idx[1][1].shape[1], 3)
        # dist-1
        assert_equal(len(idx[2][0].shape), 1)
        assert_equal(idx[2][0].shape[0], 0)
        # dist-2
        assert_equal(idx[2][1].shape[0], 0)

        # Return index of two things
        idx = self.mol.close(point, dR=(.1, 1.1), ret_dist=True)
        # [[idx-1, idx-2], [dist-1, dist-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # dist-1
        assert_equal(len(idx[1][0].shape), 1)
        assert_equal(idx[1][0].shape[0], 0)
        # dist-2
        assert_equal(idx[1][1].shape[0], 0)

    def test_bond_correct(self):
        # Create ribbon
        rib = self.g.tile(2, 1)
        # Convert the last atom to a H atom
        rib.atom[-1] = Atom[1]
        ia = len(rib) - 1
        # Get bond-length
        idx, d = rib.close(ia, dR=(.1, 1000), ret_dist=True)
        i = np.argmin(d[1])
        d = d[1][i]
        rib.bond_correct(ia, idx[1][i])
        idx, d2 = rib.close(ia, dR=(.1, 1000), ret_dist=True)
        i = np.argmin(d2[1])
        d2 = d2[1][i]
        assert_false(d == d2)
        # Calculate actual radius
        assert_true(d2 == (Atom[1].radius() + Atom[6].radius()))

    def test_unit_cell_estimation1(self):
        # Create new geometry with only the coordinates
        # and atoms
        geom = Geometry(self.g.xyz, Atom[6])
        # Only check the two distances we know have sizes
        for i in range(2):
            # It cannot guess skewed axis
            assert_false(np.allclose(geom.cell[i, :], self.g.cell[i, :]))

    def test_unit_cell_estimation2(self):
        # Create new geometry with only the coordinates
        # and atoms
        s1 = SuperCell([2, 2, 2])
        g1 = Geometry([[0, 0, 0], [1, 1, 1]], sc=s1)
        g2 = Geometry(np.copy(g1.xyz))
        assert_true(np.allclose(g1.cell, g2.cell))

        # Assert that it correctly calculates the bond-length in the
        # directions of actual distance
        g1 = Geometry([[0, 0, 0], [1, 1, 0]], atom='H', sc=s1)
        g2 = Geometry(np.copy(g1.xyz))
        for i in range(2):
            assert_true(np.allclose(g1.cell[i, :], g2.cell[i, :]))
        assert_false(np.allclose(g1.cell[2, :], g2.cell[2, :]))

    def test_argumentparser(self):
        self.g.ArgumentParser()

    def test_set_sc(self):
        # Create new geometry with only the coordinates
        # and atoms
        s1 = SuperCell([2, 2, 2])
        g1 = Geometry([[0, 0, 0], [1, 1, 1]], sc=[2, 2, 1])
        g1.set_sc(s1)
        assert_true(g1.sc == s1)

    def test_attach1(self):
        g = self.g.attach(0, self.mol, 0, dist=1.42, axis=2)
        g = self.g.attach(0, self.mol, 0, dist='calc', axis=2)
        g = self.g.attach(0, self.mol, 0, dist=[0, 0, 1.42])

    def test_mirror1(self):
        for plane in ['xy', 'xz', 'yz']:
            self.g.mirror(plane)

    def test_pickle(self):
        import pickle as p
        s = p.dumps(self.g)
        n = p.loads(s)
        assert_true(n == self.g)
        assert_false(n != self.g)
class TestHamiltonian(object):
    def setUp(self):
        bond = 1.42
        sq3h = 3.**.5 * 0.5
        self.sc = SuperCell(np.array(
            [[1.5, sq3h, 0.], [1.5, -sq3h, 0.], [0., 0., 10.]], np.float64) *
                            bond,
                            nsc=[3, 3, 1])

        C = Atom(Z=6, R=bond * 1.01, orbs=1)
        self.g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) *
                          bond,
                          atom=C,
                          sc=self.sc)
        self.H = Hamiltonian(self.g)
        self.HS = Hamiltonian(self.g, orthogonal=False)

        C = Atom(Z=6, R=bond * 1.01, orbs=2)
        self.g2 = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) *
                           bond,
                           atom=C,
                           sc=self.sc)
        self.H2 = Hamiltonian(self.g2)
        self.HS2 = Hamiltonian(self.g2, orthogonal=False)

    def tearDown(self):
        del self.sc
        del self.g
        del self.H
        del self.HS
        del self.g2
        del self.H2
        del self.HS2

    def test_objects(self):
        print(self.H)
        assert_true(len(self.H.xyz) == 2)
        assert_true(self.g.no == len(self.H))
        assert_true(len(self.HS.xyz) == 2)
        assert_true(self.g.no == len(self.HS))

        assert_true(len(self.H2.xyz) == 2)
        assert_true(self.g2.no == len(self.H2))
        assert_true(len(self.HS2.xyz) == 2)
        assert_true(self.g2.no == len(self.HS2))

    def test_dtype(self):
        assert_true(self.H.dtype == np.float64)
        assert_true(self.HS.dtype == np.float64)
        assert_true(self.H2.dtype == np.float64)
        assert_true(self.HS2.dtype == np.float64)

    def test_ortho(self):
        assert_true(self.H.orthogonal)
        assert_false(self.HS.orthogonal)

    def test_set1(self):
        self.H.H[0, 0] = 1.
        assert_true(self.H[0, 0] == 1.)
        assert_true(self.H[1, 0] == 0.)
        self.H.empty()

        self.HS.H[0, 0] = 1.
        assert_true(self.HS.H[0, 0] == 1.)
        assert_true(self.HS.H[1, 0] == 0.)
        assert_true(self.HS.S[0, 0] == 0.)
        assert_true(self.HS.S[1, 0] == 0.)
        self.HS.S[0, 0] = 1.
        assert_true(self.HS.H[0, 0] == 1.)
        assert_true(self.HS.H[1, 0] == 0.)
        assert_true(self.HS.S[0, 0] == 1.)
        assert_true(self.HS.S[1, 0] == 0.)

        # delete before creating the same content
        self.HS.empty()
        # THIS IS A CHECK FOR BACK_WARD COMPATIBILITY!
        import warnings
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')
            self.HS[0, 0] = 1., 1.
        assert_true(self.HS.H[0, 0] == 1.)
        assert_true(self.HS.S[0, 0] == 1.)
        self.HS.empty()

    def test_set2(self):
        self.H.construct([(0.1, 1.5), (1., 0.1)])
        assert_true(self.H[0, 0] == 1.)
        assert_true(self.H[1, 0] == 0.1)
        assert_true(self.H[0, 1] == 0.1)
        self.H.empty()

    def test_set3(self):
        self.HS.construct([(0.1, 1.5), ((1., 2.), (0.1, 0.2))])
        assert_true(self.HS.H[0, 0] == 1.)
        assert_true(self.HS.S[0, 0] == 2.)
        assert_true(self.HS.H[1, 1] == 1.)
        assert_true(self.HS.S[1, 1] == 2.)
        assert_true(self.HS.H[1, 0] == 0.1)
        assert_true(self.HS.H[0, 1] == 0.1)
        assert_true(self.HS.S[1, 0] == 0.2)
        assert_true(self.HS.S[0, 1] == 0.2)
        assert_true(self.HS.nnz == len(self.HS) * 4)
        self.HS.empty()

    def test_set4(self):
        for ia, io in self.H:
            # Find atoms close to 'ia'
            idx = self.H.geom.close(ia, dR=(0.1, 1.5))
            self.H[io, idx[0]] = 1.
            self.H[io, idx[1]] = 0.1
        assert_true(self.H.H[0, 0] == 1.)
        assert_true(self.H.H[1, 1] == 1.)
        assert_true(self.H.H[1, 0] == 0.1)
        assert_true(self.H.H[0, 1] == 0.1)
        assert_true(self.H.nnz == len(self.H) * 4)
        self.H.empty()

    @attr('slow')
    def test_set5(self):
        # Test of HUGE construct
        g = self.g.tile(10, 0).tile(10, 1).tile(10, 2)
        H = Hamiltonian(g)
        H.construct([(0.1, 1.5), (1., 0.1)])
        assert_true(H.H[0, 0] == 1.)
        assert_true(H.H[1, 1] == 1.)
        assert_true(H.H[1, 0] == 0.1)
        assert_true(H.H[0, 1] == 0.1)
        # This is graphene
        # on-site == len(H)
        # nn == 3 * len(H)
        assert_true(H.nnz == len(H) * 4)
        del H

    def test_iter1(self):
        self.HS.construct([(0.1, 1.5), ((1., 2.), (0.1, 0.2))])
        nnz = 0
        for io, jo in self.HS.iter_nnz():
            nnz = nnz + 1
        assert_equal(nnz, self.HS.nnz)
        nnz = 0
        for io, jo in self.HS.iter_nnz(0):
            nnz = nnz + 1
        # 3 nn and 1 onsite
        assert_equal(nnz, 4)
        self.HS.empty()

    def test_iter2(self):
        self.HS.H[0, 0] = 1.
        nnz = 0
        for io, jo in self.HS.iter_nnz():
            nnz = nnz + 1
        assert_equal(nnz, self.HS.nnz)
        assert_equal(nnz, 1)
        self.HS.empty()

    @raises(ValueError)
    def test_construct_raise(self):
        # Test that construct fails with more than one
        # orbital
        self.H2.construct([(0.1, 1.5), (1., 0.1)])

    def test_op1(self):
        g = Geometry([[i, 0, 0] for i in range(100)],
                     Atom(6, R=1.01),
                     sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = i

            # i+
            H += 1
            for jj in j:
                assert_equal(H[0, jj], i + 1)
                assert_equal(H[1, jj], 0)

            # i-
            H -= 1
            for jj in j:
                assert_equal(H[0, jj], i)
                assert_equal(H[1, jj], 0)

            # i*
            H *= 2
            for jj in j:
                assert_equal(H[0, jj], i * 2)
                assert_equal(H[1, jj], 0)

            # //
            H //= 2
            for jj in j:
                assert_equal(H[0, jj], i)
                assert_equal(H[1, jj], 0)

            # i**
            H **= 2
            for jj in j:
                assert_equal(H[0, jj], i**2)
                assert_equal(H[1, jj], 0)

    def test_op2(self):
        g = Geometry([[i, 0, 0] for i in range(100)],
                     Atom(6, R=1.01),
                     sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = i

            # +
            s = H + 1
            for jj in j:
                assert_equal(s[0, jj], i + 1)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # -
            s = H - 1
            for jj in j:
                assert_equal(s[0, jj], i - 1)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # -
            s = 1 - H
            for jj in j:
                assert_equal(s[0, jj], 1 - i)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # *
            s = H * 2
            for jj in j:
                assert_equal(s[0, jj], i * 2)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # //
            s = s // 2
            for jj in j:
                assert_equal(s[0, jj], i)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # **
            s = H**2
            for jj in j:
                assert_equal(s[0, jj], i**2)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # ** (r)
            s = 2**H
            for jj in j:
                assert_equal(s[0, jj], 2**H[0, jj])
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

    def test_op3(self):
        g = Geometry([[i, 0, 0] for i in range(100)],
                     Atom(6, R=1.01),
                     sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        Hc = H.copy()
        del Hc

        # Create initial stuff
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = i

        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.int32)
            h = func(1.)
            assert_equal(h.dtype, np.float64)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

        H = H.copy(dtype=np.float64)
        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.float64)
            h = func(1.)
            assert_equal(h.dtype, np.float64)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

        H = H.copy(dtype=np.complex128)
        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.complex128)
            h = func(1.)
            assert_equal(h.dtype, np.complex128)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

    def test_op4(self):
        g = Geometry([[i, 0, 0] for i in range(100)],
                     Atom(6, R=1.01),
                     sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        # Create initial stuff
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = i

        h = 1 + H
        assert_equal(h.dtype, np.int32)
        h = 1. + H
        assert_equal(h.dtype, np.float64)
        h = 1.j + H
        assert_equal(h.dtype, np.complex128)

        h = 1 - H
        assert_equal(h.dtype, np.int32)
        h = 1. - H
        assert_equal(h.dtype, np.float64)
        h = 1.j - H
        assert_equal(h.dtype, np.complex128)

        h = 1 * H
        assert_equal(h.dtype, np.int32)
        h = 1. * H
        assert_equal(h.dtype, np.float64)
        h = 1.j * H
        assert_equal(h.dtype, np.complex128)

        h = 1**H
        assert_equal(h.dtype, np.int32)
        h = 1.**H
        assert_equal(h.dtype, np.float64)
        h = 1.j**H
        assert_equal(h.dtype, np.complex128)

    def test_cut1(self):
        # Test of eigenvalues using a cut
        # Hamiltonian
        dR, param = [0.1, 1.5], [1., 0.1]

        # Create reference
        Hg = Hamiltonian(self.g)
        Hg.construct([dR, param])
        g = self.g.tile(2, 0).tile(2, 1)
        H = Hamiltonian(g)
        H.construct([dR, param])
        # Create cut Hamiltonian
        Hc = H.cut(2, 1).cut(2, 0)
        eigc = Hc.eigh()
        eigg = Hg.eigh()
        assert_true(np.allclose(Hg.eigh(), Hc.eigh()))
        del Hc, H

    def test_cut2(self):
        # Test of eigenvalues using a cut
        # Hamiltonian
        dR, param = [0.1, 1.5], [(1., 1.), (0.1, 0.1)]

        # Create reference
        Hg = Hamiltonian(self.g, orthogonal=False)
        Hg.construct([dR, param])

        g = self.g.tile(2, 0).tile(2, 1)
        H = Hamiltonian(g, orthogonal=False)
        H.construct([dR, param])
        # Create cut Hamiltonian
        Hc = H.cut(2, 1).cut(2, 0)
        eigc = Hc.eigh()
        eigg = Hg.eigh()
        assert_true(np.allclose(Hg.eigh(), Hc.eigh()))
        del Hc, H

    def test_eig1(self):
        # Test of eigenvalues
        dR, param = [0.1, 1.5], [1., 0.1]
        g = self.g.tile(2, 0).tile(2, 1).tile(2, 2)
        H = Hamiltonian(g)
        H.construct((dR, param), eta=True)
        H.eigh()
        H.eigsh(n=4)
        H.empty()
        del H

    def test_eig2(self):
        # Test of eigenvalues
        self.HS.construct([(0.1, 1.5), ((1., 1.), (0.1, 0.1))])
        self.HS.eigh()
        self.HS.empty()

    def test_spin2(self):
        g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.int32, spin=2)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[0, j] = (i, i * 2)

    def test_non_collinear1(self):
        g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.float64, spin=4)
        for i in range(10):
            j = range(i * 4, i * 4 + 3)
            H[i, i, 0] = 0.
            H[i, i, 1] = 0.
            H[i, i, 2] = 0.1
            H[i, i, 3] = 0.1
            if i > 0:
                H[i, i - 1, 0] = 1.
                H[i, i - 1, 1] = 1.
            if i < 9:
                H[i, i + 1, 0] = 1.
                H[i, i + 1, 1] = 1.
        assert_true(len(H.eigh()) == len(H) * 2)

    def test_finalized(self):
        assert_false(self.H.finalized)
        self.H.H[0, 0] = 1.
        self.H.finalize()
        assert_true(self.H.finalized)
        assert_true(self.H.nnz == 1)
        self.H.empty()
        assert_false(self.HS.finalized)
        self.HS.H[0, 0] = 1.
        self.HS.S[0, 0] = 1.
        self.HS.finalize()
        assert_true(self.HS.finalized)
        assert_true(self.HS.nnz == 1)
        self.HS.empty()
Exemple #9
0
def bcc_slab(alat, atoms, miller, layers=None, vacuum=20., *, orthogonal=False, start=None, end=None):
    r""" Construction of a surface slab from a body-centered cubic (BCC) crystal

    The slab layers are stacked along the :math:`z`-axis. The default stacking is the first
    layer as an A-layer, defined as the plane containing an atom at :math:`(x,y)=(0,0)`.

    Several vacuum separated segments can be created by specifying specific positions through
    either `layers` being a list, or by having spaces in its `str` form, see Examples.

    Parameters
    ----------
    alat : float
        lattice constant of the fcc crystal
    atoms : Atom
        the atom that the crystal consists of
    miller : int or str or (3,)
        Miller indices of the surface facet
    layers : int or str or array_like of ints, optional
        Number of layers in the slab or explicit layer specification.
        For array like arguments vacuum will be placed between each index of the layers.
        Each element can either be an int or a str to specify number of layers or an explicit
        order of layers.
        If a `str` it can contain spaces to specify vacuum positions (then equivalent to ``layers.split()``).
        If there are no vacuum positions specified a vacuum will be placed *after* the layers.
        See examples for details.
    vacuum : float or array_like, optional
        size of vacuum at locations specified in `layers`. The vacuum will always
        be placed along the :math:`z`-axis (3rd lattice vector).
        Each segment in `layers` will be appended the vacuum as found by ``zip_longest(layers, vacuum)``.
    orthogonal : bool, optional
        if True returns an orthogonal lattice
    start : int or str or array_like, optional
        sets the first layer in the slab. Only one of `start` or `end` must be specified.
        Discouraged to pass if `layers` is a str.
    end : int or str or array_like, optional
        sets the last layer in the slab. Only one of `start` or `end` must be specified.
        Discouraged to pass if `layers` is a str.

    Examples
    --------

    Please see `fcc_slab` for examples, they are equivalent to this method.

    Raises
    ------
    NotImplementedError
        In case the Miller index has not been implemented or a stacking fault is
        introduced in `layers`.

    See Also
    --------
    bcc : Fully periodic equivalent of this slab structure
    fcc_slab : Slab in FCC structure
    rocksalt_slab : Slab in rocksalt/halite structure
    """
    geom = _slab_with_vacuum(bcc_slab, alat, atoms, miller,
                             vacuum=vacuum, orthogonal=orthogonal,
                             layers=layers,
                             start=start, end=end)
    if geom is not None:
        return geom

    miller = _convert_miller(miller)

    if miller == (1, 0, 0):

        info = _calc_info(start, end, layers, 2)

        sc = SuperCell(np.array([1, 1, 0.5]) * alat)
        g = Geometry([0, 0, 0], atoms=atoms, sc=sc)
        g = g.tile(info.nlayers, 2)

        # slide AB layers relative to each other
        B = (info.offset + 1) % 2
        g.xyz[B::2] += (sc.cell[0] + sc.cell[1]) / 2

    elif miller == (1, 1, 0):

        info = _calc_info(start, end, layers, 2)

        if orthogonal:
            sc = SuperCell(np.array([1, 2, 0.5]) ** 0.5 * alat)
            g = Geometry(np.array([[0, 0, 0],
                                   [0.5, 0.5 ** 0.5, 0]]) * alat,
                         atoms=atoms, sc=sc)
            g = g.tile(info.nlayers, 2)

            # slide ABC layers relative to each other
            B = 2 * (info.offset + 1) % 4
            vec = sc.cell[1] / 2
            g.xyz[B::4] += vec
            g.xyz[B+1::4] += vec

        else:
            sc = SuperCell(np.array([[1, 0, 0],
                                     [0.5, 0.5 ** 0.5, 0],
                                     [0, 0, 0.5 ** 0.5]]) * alat)
            g = Geometry([0, 0, 0], atoms=atoms, sc=sc)
            g = g.tile(info.nlayers, 2)

            # slide AB layers relative to each other
            B = (info.offset + 1) % 2
            g.xyz[B::2] += sc.cell[0] / 2

    elif miller == (1, 1, 1):

        info = _calc_info(start, end, layers, 3)

        if orthogonal:
            sc = SuperCell(np.array([2, 4 * 1.5, 1 / 12]) ** 0.5 * alat)
            g = Geometry(np.array([[0, 0, 0],
                                   [0.5, 1.5, 0]]) ** 0.5 * alat,
                         atoms=atoms, sc=sc)
            g = g.tile(info.nlayers, 2)

            # slide ABC layers relative to each other
            B = 2 * (info.offset + 1) % 6
            C = 2 * (info.offset + 2) % 6
            vec = (sc.cell[0] + sc.cell[1]) / 3
            for i in range(2):
                g.xyz[B+i::6] += vec
                g.xyz[C+i::6] += 2 * vec

        else:
            sc = SuperCell(np.array([[2, 0, 0],
                                     [0.5, 1.5, 0],
                                     [0, 0, 1 / 12]]) ** 0.5 * alat)
            g = Geometry([0, 0, 0], atoms=atoms, sc=sc)
            g = g.tile(info.nlayers, 2)

            # slide ABC layers relative to each other
            B = (info.offset + 1) % 3
            C = (info.offset + 2) % 3
            vec = (sc.cell[0] + sc.cell[1]) / 3
            g.xyz[B::3] += vec
            g.xyz[C::3] += 2 * vec

    else:
        raise NotImplementedError(f"bcc_slab: miller={miller} is not implemented")

    g = _finish_slab(g, vacuum)
    return g
Exemple #10
0
def fcc_slab(alat, atoms, miller, layers=None, vacuum=20., *, orthogonal=False, start=None, end=None):
    r""" Surface slab forming a face-centered cubic (FCC) crystal

    The slab layers are stacked along the :math:`z`-axis. The default stacking is the first
    layer as an A-layer, defined as the plane containing an atom at :math:`(x,y)=(0,0)`.

    Several vacuum separated segments can be created by specifying specific positions through
    either `layers` being a list, or by having spaces in its `str` form, see Examples.

    Parameters
    ----------
    alat : float
        lattice constant of the fcc crystal
    atoms : Atom
        the atom that the crystal consists of
    miller : int or str or (3,)
        Miller indices of the surface facet
    layers : int or str or array_like of ints, optional
        Number of layers in the slab or explicit layer specification.
        For array like arguments vacuum will be placed between each index of the layers.
        Each element can either be an int or a str to specify number of layers or an explicit
        order of layers.
        If a `str` it can contain spaces to specify vacuum positions (then equivalent to ``layers.split()``).
        If there are no vacuum positions specified a vacuum will be placed *after* the layers.
        See examples for details.
    vacuum : float or array_like, optional
        size of vacuum at locations specified in `layers`. The vacuum will always
        be placed along the :math:`z`-axis (3rd lattice vector).
        Each segment in `layers` will be appended the vacuum as found by ``zip_longest(layers, vacuum)``.
    orthogonal : bool, optional
        if True returns an orthogonal lattice
    start : int or str or array_like, optional
        sets the first layer in the slab. Only one of `start` or `end` must be specified.
        Discouraged to pass if `layers` is a str since a `ValueError` will be raised if they do
        not match.
    end : int or str or array_like, optional
        sets the last layer in the slab. Only one of `start` or `end` must be specified.
        Discouraged to pass if `layers` is a str since a `ValueError` will be raised if they do
        not match.

    Examples
    --------
    111 surface, starting with the A layer

    >>> fcc_slab(alat, atoms, "111", start=0)

    111 surface, starting with the B layer

    >>> fcc_slab(alat, atoms, "111", start=1)

    111 surface, ending with the B layer

    >>> fcc_slab(alat, atoms, "111", end='B')

    111 surface, with explicit layers in a given order

    >>> fcc_slab(alat, atoms, "111", layers='BCABCA')

    111 surface, with (1 Ang vacuum)BCA(2 Ang vacuum)ABC(3 Ang vacuum)

    >>> fcc_slab(alat, atoms, "111", layers=' BCA ABC ', vacuum=(1, 2, 3))

    111 surface, with (20 Ang vacuum)BCA

    >>> fcc_slab(alat, atoms, "111", layers=' BCA', vacuum=20)

    111 surface, with (2 Ang vacuum)BCA(1 Ang vacuum)ABC(1 Ang vacuum)
    The last item in `vacuum` gets repeated.

    >>> fcc_slab(alat, atoms, "111", layers=' BCA ABC ', vacuum=(2, 1))

    111 periodic structure with ABC(20 Ang vacuum)BC
    The unit cell parameters will be periodic in this case, and it will not be
    a slab.

    >>> fcc_slab(alat, atoms, "111", layers='ABC BC', vacuum=20.)

    111 surface in an orthogonal (4x5) cell, maintaining the atom ordering
    according to `lattice=[2, 1, 0]`:

    >>> fcc_slab(alat, atoms, "111", orthogonal=True).repeat(5, axis=1).repeat(4, axis=0)

    111 surface with number specifications of layers together with start
    Between each number an implicit vacuum is inserted, only the first and last
    are required if vacuum surrounding the slab is needed. The following two calls
    are equivalent.
    Structure: (10 Ang vacuum)(ABC)(1 Ang vacuum)(BCABC)(2 Ang vacuum)(CAB)

    >>> fcc_slab(alat, atoms, "111", layers=(' ', 3, 5, 3), start=(0, 1, 2), vacuum=(10, 1, 2))
    >>> fcc_slab(alat, atoms, "111", layers=' ABC BCABC CAB', vacuum=(10, 1, 2))

    Raises
    ------
    NotImplementedError
        In case the Miller index has not been implemented or a stacking fault is
        introduced in `layers`.

    ValueError
        For wrongly specified `layers` and `vacuum` arguments.

    See Also
    --------
    fcc : Fully periodic equivalent of this slab structure
    bcc_slab : Slab in BCC structure
    rocksalt_slab : Slab in rocksalt/halite structure
    """
    geom = _slab_with_vacuum(fcc_slab, alat, atoms, miller,
                             vacuum=vacuum, orthogonal=orthogonal,
                             layers=layers,
                             start=start, end=end)
    if geom is not None:
        return geom

    miller = _convert_miller(miller)

    if miller == (1, 0, 0):

        info = _calc_info(start, end, layers, 2)

        sc = SuperCell(np.array([0.5 ** 0.5, 0.5 ** 0.5, 0.5]) * alat)
        g = Geometry([0, 0, 0], atoms=atoms, sc=sc)
        g = g.tile(info.nlayers, 2)

        # slide AB layers relative to each other
        B = (info.offset + 1) % 2
        g.xyz[B::2] += (sc.cell[0] + sc.cell[1]) / 2

    elif miller == (1, 1, 0):

        info = _calc_info(start, end, layers, 2)

        sc = SuperCell(np.array([1., 0.5, 0.125]) ** 0.5 * alat)
        g = Geometry([0, 0, 0], atoms=atoms, sc=sc)
        g = g.tile(info.nlayers, 2)

        # slide AB layers relative to each other
        B = (info.offset + 1) % 2
        g.xyz[B::2] += (sc.cell[0] + sc.cell[1]) / 2

    elif miller == (1, 1, 1):

        info = _calc_info(start, end, layers, 3)

        if orthogonal:
            sc = SuperCell(np.array([0.5, 4 * 0.375, 1 / 3]) ** 0.5 * alat)
            g = Geometry(np.array([[0, 0, 0],
                                   [0.125, 0.375, 0]]) ** 0.5 * alat,
                         atoms=atoms, sc=sc)
            g = g.tile(info.nlayers, 2)

            # slide ABC layers relative to each other
            B = 2 * (info.offset + 1) % 6
            C = 2 * (info.offset + 2) % 6
            vec = (3 * sc.cell[0] + sc.cell[1]) / 6
            g.xyz[B::6] += vec
            g.xyz[B+1::6] += vec
            g.xyz[C::6] += 2 * vec
            g.xyz[C+1::6] += 2 * vec

        else:
            sc = SuperCell(np.array([[0.5, 0, 0],
                                     [0.125, 0.375, 0],
                                     [0, 0, 1 / 3]]) ** 0.5 * alat)
            g = Geometry([0, 0, 0], atoms=atoms, sc=sc)
            g = g.tile(info.nlayers, 2)

            # slide ABC layers relative to each other
            B = (info.offset + 1) % 3
            C = (info.offset + 2) % 3
            vec = (sc.cell[0] + sc.cell[1]) / 3
            g.xyz[B::3] += vec
            g.xyz[C::3] += 2 * vec

    else:
        raise NotImplementedError(f"fcc_slab: miller={miller} is not implemented")

    g = _finish_slab(g, vacuum)
    return g
Exemple #11
0
class TestGeometry(object):
    def setUp(self):
        bond = 1.42
        sq3h = 3.**.5 * 0.5
        self.sc = SuperCell(np.array(
            [[1.5, sq3h, 0.], [1.5, -sq3h, 0.], [0., 0., 10.]], np.float64) *
                            bond,
                            nsc=[3, 3, 1])
        C = Atom(Z=6, R=bond * 1.01, orbs=2)
        self.g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) *
                          bond,
                          atom=C,
                          sc=self.sc)

        self.mol = Geometry([[i, 0, 0] for i in range(10)], sc=[50])

    def tearDown(self):
        del self.g
        del self.sc
        del self.mol

    def test_objects(self):
        # just make sure __repr__ works
        repr(self.g)
        str(self.g)
        assert_true(len(self.g) == 2)
        assert_true(len(self.g.xyz) == 2)
        assert_true(np.allclose(self.g[0], np.zeros([3])))
        assert_true(np.allclose(self.g[None, 0], self.g.xyz[:, 0]))

        i = 0
        for ia in self.g:
            i += 1
        assert_true(i == len(self.g))
        assert_true(self.g.no_s == 2 * len(self.g) * np.prod(self.g.sc.nsc))

    def test_properties(self):
        assert_true(2 == len(self.g))
        assert_true(2 == self.g.na)
        assert_true(3 * 3 == self.g.n_s)
        assert_true(2 * 3 * 3 == self.g.na_s)
        assert_true(2 * 2 == self.g.no)
        assert_true(2 * 2 * 3 * 3 == self.g.no_s)

    def test_iter1(self):
        i = 0
        for ia in self.g:
            i += 1
        assert_true(i == 2)

    def test_iter2(self):
        for ia in self.g:
            assert_true(np.allclose(self.g[ia], self.g.xyz[ia, :]))

    def test_iter3(self):
        i = 0
        for ia, io in self.g.iter_orbitals(0):
            assert_equal(ia, 0)
            assert_true(io < 2)
            i += 1
        for ia, io in self.g.iter_orbitals(1):
            assert_equal(ia, 1)
            assert_true(io < 2)
            i += 1
        assert_true(i == 4)
        i = 0
        for ia, io in self.g.iter_orbitals():
            assert_true(ia in [0, 1])
            assert_true(io < 2)
            i += 1
        assert_true(i == 4)

        i = 0
        for ia, io in self.g.iter_orbitals(1, local=False):
            assert_equal(ia, 1)
            assert_true(io >= 2)
            i += 1
        assert_true(i == 2)

    @raises(ValueError)
    def test_tile0(self):
        t = self.g.tile(0, 0)

    def test_tile1(self):
        cell = np.copy(self.g.sc.cell)
        cell[0, :] *= 2
        t = self.g.tile(2, 0)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[1, :] *= 2
        t = t.tile(2, 1)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[2, :] *= 2
        t = t.tile(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_tile2(self):
        cell = np.copy(self.g.sc.cell)
        cell[:, :] *= 2
        t = self.g.tile(2, 0).tile(2, 1).tile(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_tile3(self):
        cell = np.copy(self.g.sc.cell)
        cell[:, :] *= 2
        t1 = self.g * 2
        cell = np.copy(self.g.sc.cell)
        cell[0, :] *= 2
        t1 = self.g * (2, 0)
        assert_true(np.allclose(cell, t1.sc.cell))
        t = self.g * ((2, 0), 'tile')
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))
        cell[1, :] *= 2
        t1 = t * (2, 1)
        assert_true(np.allclose(cell, t1.sc.cell))
        t = t * ((2, 1), 'tile')
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))
        cell[2, :] *= 2
        t1 = t * (2, 2)
        assert_true(np.allclose(cell, t1.sc.cell))
        t = t * ((2, 2), 'tile')
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))

        # Full
        t = self.g * [2, 2, 2]
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))
        t = self.g * ([2, 2, 2], 't')
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))

    def test_tile4(self):
        t1 = self.g.tile(2, 0).tile(2, 2)
        t = self.g * ([2, 0], 't') * [2, 2]
        assert_true(np.allclose(t1.xyz, t.xyz))

    def test_tile5(self):
        t = self.g.tile(2, 0).tile(2, 2)
        assert_true(np.allclose(t[:len(self.g), :], self.g.xyz))

    @raises(ValueError)
    def test_repeat0(self):
        t = self.g.repeat(0, 0)

    def test_repeat1(self):
        cell = np.copy(self.g.sc.cell)
        cell[0, :] *= 2
        t = self.g.repeat(2, 0)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[1, :] *= 2
        t = t.repeat(2, 1)
        assert_true(np.allclose(cell, t.sc.cell))
        cell[2, :] *= 2
        t = t.repeat(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_repeat2(self):
        cell = np.copy(self.g.sc.cell)
        cell[:, :] *= 2
        t = self.g.repeat(2, 0).repeat(2, 1).repeat(2, 2)
        assert_true(np.allclose(cell, t.sc.cell))

    def test_repeat3(self):
        cell = np.copy(self.g.sc.cell)
        cell[0, :] *= 2
        t1 = self.g.repeat(2, 0)
        assert_true(np.allclose(cell, t1.sc.cell))
        t = self.g * ((2, 0), 'repeat')
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))
        cell[1, :] *= 2
        t1 = t.repeat(2, 1)
        assert_true(np.allclose(cell, t1.sc.cell))
        t = t * ((2, 1), 'r')
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))
        cell[2, :] *= 2
        t1 = t.repeat(2, 2)
        assert_true(np.allclose(cell, t1.sc.cell))
        t = t * ((2, 2), 'repeat')
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))

        # Full
        t = self.g * ([2, 2, 2], 'r')
        assert_true(np.allclose(cell, t.sc.cell))
        assert_true(np.allclose(t1.xyz, t.xyz))

    def test_repeat4(self):
        t1 = self.g.repeat(2, 0).repeat(2, 2)
        t = self.g * ([2, 0], 'repeat') * ([2, 2], 'r')
        assert_true(np.allclose(t1.xyz, t.xyz))

    def test_repeat5(self):
        t = self.g.repeat(2, 0).repeat(2, 2)
        assert_true(np.allclose(t.xyz[::4, :], self.g.xyz))

    def test_a2o1(self):
        assert_true(0 == self.g.a2o(0))
        assert_true(self.g.atom[0].orbs == self.g.a2o(1))
        assert_true(self.g.no == self.g.a2o(self.g.na))

    def test_sub1(self):
        assert_true(len(self.g.sub([0])) == 1)
        assert_true(len(self.g.sub([0, 1])) == 2)
        assert_true(len(self.g.sub([-1])) == 1)

    def test_sub2(self):
        assert_true(len(self.g.sub(range(1))) == 1)
        assert_true(len(self.g.sub(range(2))) == 2)

    def test_fxyz(self):
        assert_true(np.allclose(self.g.fxyz, [[0, 0, 0], [1. / 3, 1. / 3, 0]]))

    def test_axyz(self):
        assert_true(np.allclose(self.g[:], self.g.xyz[:]))
        assert_true(np.allclose(self.g[0], self.g.xyz[0, :]))
        assert_true(np.allclose(self.g[2], self.g.axyz(2)))
        isc = self.g.a2isc(2)
        off = self.g.sc.offset(isc)
        assert_true(np.allclose(self.g.xyz[0] + off, self.g.axyz(2)))

    def test_rij1(self):
        assert_true(np.allclose(self.g.rij(0, 1), 1.42))
        assert_true(np.allclose(self.g.rij(0, [0, 1]), [0., 1.42]))

    def test_orij1(self):
        assert_true(np.allclose(self.g.orij(0, 2), 1.42))
        assert_true(np.allclose(self.g.orij(0, [0, 2]), [0., 1.42]))

    def test_cut(self):
        with warn.catch_warnings():
            warn.simplefilter('ignore', category=UserWarning)
            assert_true(len(self.g.cut(1, 1)) == 2)
            assert_true(len(self.g.cut(2, 1)) == 1)
            assert_true(len(self.g.cut(2, 1, 1)) == 1)

    def test_cut2(self):
        c1 = self.g.cut(2, 1)
        c2 = self.g.cut(2, 1, 1)
        assert_true(np.allclose(c1.xyz[0, :], self.g.xyz[0, :]))
        assert_true(np.allclose(c2.xyz[0, :], self.g.xyz[1, :]))

    def test_remove1(self):
        assert_true(len(self.g.remove([0])) == 1)
        assert_true(len(self.g.remove([])) == 2)
        assert_true(len(self.g.remove([-1])) == 1)
        assert_true(len(self.g.remove([-0])) == 1)

    def test_remove2(self):
        assert_true(len(self.g.remove(range(1))) == 1)
        assert_true(len(self.g.remove(range(0))) == 2)

    def test_copy(self):
        assert_true(self.g == self.g.copy())

    def test_nsc1(self):
        nsc = np.copy(self.g.nsc)
        self.g.sc.set_nsc([5, 5, 0])
        assert_true(np.allclose([5, 5, 1], self.g.nsc))
        assert_true(len(self.g.sc_off) == np.prod(self.g.nsc))

    def test_nsc2(self):
        nsc = np.copy(self.g.nsc)
        self.g.sc.set_nsc([0, 1, 0])
        assert_true(np.allclose([1, 1, 1], self.g.nsc))
        assert_true(len(self.g.sc_off) == np.prod(self.g.nsc))

    def test_rotation1(self):
        rot = self.g.rotate(180, [0, 0, 1])
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True)
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1])
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_rotation2(self):
        rot = self.g.rotate(180, [0, 0, 1], only='abc')
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True, only='abc')
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(-rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1], only='abc')
        rot.sc.cell[2, 2] *= -1
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_rotation3(self):
        rot = self.g.rotate(180, [0, 0, 1], only='xyz')
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = self.g.rotate(np.pi, [0, 0, 1], radians=True, only='xyz')
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(-rot.xyz, self.g.xyz))

        rot = rot.rotate(180, [0, 0, 1], only='xyz')
        assert_true(np.allclose(rot.sc.cell, self.g.sc.cell))
        assert_true(np.allclose(rot.xyz, self.g.xyz))

    def test_rotation4(self):
        rot = self.g.rotatea(180, only='xyz')
        rot = self.g.rotateb(180, only='xyz')
        rot = self.g.rotatec(180, only='xyz')

    def test_translate(self):
        t = self.g.translate([0, 0, 1])
        assert_true(np.allclose(self.g.xyz[:, 0], t.xyz[:, 0]))
        assert_true(np.allclose(self.g.xyz[:, 1], t.xyz[:, 1]))
        assert_true(np.allclose(self.g.xyz[:, 2] + 1, t.xyz[:, 2]))
        t = self.g.move([0, 0, 1])
        assert_true(np.allclose(self.g.xyz[:, 0], t.xyz[:, 0]))
        assert_true(np.allclose(self.g.xyz[:, 1], t.xyz[:, 1]))
        assert_true(np.allclose(self.g.xyz[:, 2] + 1, t.xyz[:, 2]))

    def test_iter_block1(self):
        for i, iaaspec in enumerate(self.g.iter_species()):
            ia, a, spec = iaaspec
            assert_true(i == ia)
            assert_true(self.g.atom[ia] == a)
        for ia, a, spec in self.g.iter_species([1]):
            assert_true(1 == ia)
            assert_true(self.g.atom[ia] == a)
        for ia in self.g:
            assert_true(ia >= 0)
        i = 0
        for ias, idx in self.g.iter_block():
            for ia in ias:
                i += 1
        assert_true(i == len(self.g))

        i = 0
        for ias, idx in self.g.iter_block(atom=1):
            for ia in ias:
                i += 1
        assert_true(i == 1)

    @attr('slow')
    def test_iter_block2(self):
        g = self.g.tile(30, 0).tile(30, 1)
        i = 0
        for ias, _ in g.iter_block():
            i += len(ias)
        assert_true(i == len(g))

    def test_iter_shape1(self):
        i = 0
        for ias, _ in self.g.iter_block(method='sphere'):
            i += len(ias)
        assert_true(i == len(self.g))
        i = 0
        for ias, _ in self.g.iter_block(method='cube'):
            i += len(ias)
        assert_true(i == len(self.g))

    @attr('slow')
    def test_iter_shape2(self):
        g = self.g.tile(30, 0).tile(30, 1)
        i = 0
        for ias, _ in g.iter_block(method='sphere'):
            i += len(ias)
        assert_true(i == len(g))
        i = 0
        for ias, _ in g.iter_block(method='cube'):
            i += len(ias)
        assert_true(i == len(g))

    @attr('slow')
    def test_iter_shape3(self):
        g = self.g.tile(50, 0).tile(50, 1)
        i = 0
        for ias, _ in g.iter_block(method='sphere'):
            i += len(ias)
        assert_true(i == len(g))
        i = 0
        for ias, _ in g.iter_block(method='cube'):
            i += len(ias)
        assert_true(i == len(g))

    def test_swap(self):
        s = self.g.swap(0, 1)
        for i in [0, 1, 2]:
            assert_true(np.allclose(self.g.xyz[::-1, i], s.xyz[:, i]))

    def test_append1(self):
        for axis in [0, 1, 2]:
            s = self.g.append(self.g, axis)
            assert_equal(len(s), len(self.g) * 2)
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.prepend(self.g, axis)
            assert_equal(len(s), len(self.g) * 2)
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.append(self.g.sc, axis)
            assert_equal(len(s), len(self.g))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            s = self.g.prepend(self.g.sc, axis)
            assert_equal(len(s), len(self.g))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))
            assert_true(np.allclose(s.cell[axis, :], self.g.cell[axis, :] * 2))

    def test_swapaxes(self):
        s = self.g.swapaxes(0, 1)
        assert_true(np.allclose(self.g.xyz[:, 0], s.xyz[:, 1]))
        assert_true(np.allclose(self.g.xyz[:, 1], s.xyz[:, 0]))
        assert_true(np.allclose(self.g.cell[0, :], s.cell[1, :]))
        assert_true(np.allclose(self.g.cell[1, :], s.cell[0, :]))

    def test_center(self):
        one = self.g.center(atom=[0])
        assert_true(np.allclose(self.g[0], one))
        al = self.g.center()
        assert_true(np.allclose(np.mean(self.g.xyz, axis=0), al))
        al = self.g.center(which='mass')

    @raises(ValueError)
    def test_center_raise(self):
        al = self.g.center(which='unknown')

    def test___add__(self):
        n = len(self.g)
        double = self.g + self.g
        assert_equal(len(double), n * 2)
        assert_true(np.allclose(self.g.cell, double.cell))
        assert_true(np.allclose(self.g.xyz[:n, :], double.xyz[:n, :]))

        double = (self.g, 1) + self.g
        d = self.g.prepend(self.g, 1)
        assert_equal(len(double), n * 2)
        assert_true(np.allclose(self.g.cell[::2, :], double.cell[::2, :]))
        assert_true(np.allclose(double.xyz, d.xyz))

        double = self.g + (self.g, 1)
        d = self.g.append(self.g, 1)
        assert_equal(len(double), n * 2)
        assert_true(np.allclose(self.g.cell[::2, :], double.cell[::2, :]))
        assert_true(np.allclose(double.xyz, d.xyz))

    def test___mul__(self):
        g = self.g.copy()
        assert_equal(g * 2, g.tile(2, 0).tile(2, 1).tile(2, 2))
        assert_equal(g * [2, 1], g.tile(2, 1))
        assert_equal(g * (2, 2, 2), g.tile(2, 0).tile(2, 1).tile(2, 2))
        assert_equal(g * [1, 2, 2], g.tile(1, 0).tile(2, 1).tile(2, 2))
        assert_equal(g * [1, 3, 2], g.tile(1, 0).tile(3, 1).tile(2, 2))
        assert_equal(g * ([1, 3, 2], 'r'),
                     g.repeat(1, 0).repeat(3, 1).repeat(2, 2))
        assert_equal(g * ([1, 3, 2], 'repeat'),
                     g.repeat(1, 0).repeat(3, 1).repeat(2, 2))
        assert_equal(g * ([1, 3, 2], 'tile'),
                     g.tile(1, 0).tile(3, 1).tile(2, 2))
        assert_equal(g * ([1, 3, 2], 't'), g.tile(1, 0).tile(3, 1).tile(2, 2))
        assert_equal(g * ([3, 2], 't'), g.tile(3, 2))
        assert_equal(g * ([3, 2], 'r'), g.repeat(3, 2))

    def test_add(self):
        double = self.g.add(self.g)
        assert_equal(len(double), len(self.g) * 2)
        assert_true(np.allclose(self.g.cell, double.cell))

    def test_insert(self):
        double = self.g.insert(0, self.g)
        assert_equal(len(double), len(self.g) * 2)
        assert_true(np.allclose(self.g.cell, double.cell))

    def test_a2o(self):
        # There are 2 orbitals per C atom
        assert_equal(self.g.a2o(1), self.g.atom[0].orbs)
        assert_true(np.all(self.g.a2o(1, True) == [2, 3]))

    def test_o2a(self):
        # There are 2 orbitals per C atom
        assert_equal(self.g.o2a(2), 1)

    def test_2uc(self):
        # functions for any-thing to UC
        assert_equal(self.g.sc2uc(2), 0)
        assert_true(np.all(self.g.sc2uc([2, 3]) == [0, 1]))
        assert_equal(self.g.asc2uc(2), 0)
        assert_true(np.all(self.g.asc2uc([2, 3]) == [0, 1]))
        assert_equal(self.g.osc2uc(4), 0)
        assert_equal(self.g.osc2uc(5), 1)
        assert_true(np.all(self.g.osc2uc([4, 5]) == [0, 1]))

    def test_2sc(self):
        # functions for any-thing to SC
        c = self.g.cell

        # check indices
        assert_true(np.all(self.g.a2isc([1, 2]) == [[0, 0, 0], [-1, -1, 0]]))
        assert_true(np.all(self.g.a2isc(2) == [-1, -1, 0]))
        assert_true(np.allclose(self.g.a2sc(2), -c[0, :] - c[1, :]))
        assert_true(np.all(self.g.o2isc([1, 5]) == [[0, 0, 0], [-1, -1, 0]]))
        assert_true(np.all(self.g.o2isc(5) == [-1, -1, 0]))
        assert_true(np.allclose(self.g.o2sc(5), -c[0, :] - c[1, :]))

        # Check off-sets
        assert_true(
            np.allclose(self.g.a2sc([1, 2]),
                        [[0., 0., 0.], -c[0, :] - c[1, :]]))
        assert_true(
            np.allclose(self.g.o2sc([1, 5]),
                        [[0., 0., 0.], -c[0, :] - c[1, :]]))

    def test_reverse(self):
        rev = self.g.reverse()
        assert_true(len(rev) == 2)
        assert_true(np.allclose(rev.xyz[::-1, :], self.g.xyz))
        rev = self.g.reverse(atom=list(range(len(self.g))))
        assert_true(len(rev) == 2)
        assert_true(np.allclose(rev.xyz[::-1, :], self.g.xyz))

    def test_scale1(self):
        two = self.g.scale(2)
        assert_true(len(two) == len(self.g))
        assert_true(np.allclose(two.xyz[:, :] / 2., self.g.xyz))

    def test_close1(self):
        three = range(3)
        for ia in self.mol:
            i = self.mol.close(ia, R=(0.1, 1.1), idx=three)
            if ia < 3:
                assert_equal(len(i[0]), 1)
            else:
                assert_equal(len(i[0]), 0)
            # Will only return results from [0,1,2]
            # but the fourth atom connects to
            # the third
            if ia in [0, 2, 3]:
                assert_equal(len(i[1]), 1)
            elif ia == 1:
                assert_equal(len(i[1]), 2)
            else:
                assert_equal(len(i[1]), 0)

    def test_close2(self):
        mol = range(3, 5)
        for ia in self.mol:
            i = self.mol.close(ia, R=(0.1, 1.1), idx=mol)
            assert_equal(len(i), 2)
        i = self.mol.close([100, 100, 100], R=0.1)
        assert_equal(len(i), 0)
        i = self.mol.close([100, 100, 100], R=0.1, ret_rij=True)
        for el in i:
            assert_equal(len(el), 0)
        i = self.mol.close([100, 100, 100], R=0.1, ret_rij=True, ret_xyz=True)
        for el in i:
            assert_equal(len(el), 0)

    @attr('slow')
    def test_close4(self):
        # 2 * 200 ** 2
        g = self.g * (200, 200, 1)
        i = g.close(0, R=(0.1, 1.43))
        assert_equal(len(i), 2)
        assert_equal(len(i[0]), 1)
        assert_equal(len(i[1]), 3)

    def test_close_within1(self):
        three = range(3)
        for ia in self.mol:
            shapes = [Sphere(0.1, self.mol[ia]), Sphere(1.1, self.mol[ia])]
            i = self.mol.close(ia, R=(0.1, 1.1), idx=three)
            ii = self.mol.within(shapes, idx=three)
            assert_true(np.all(i[0] == ii[0]))
            assert_true(np.all(i[1] == ii[1]))

    def test_close_within2(self):
        g = self.g.repeat(6, 0).repeat(6, 1)
        for ia in g:
            shapes = [Sphere(0.1, g[ia]), Sphere(1.5, g[ia])]
            i = g.close(ia, R=(0.1, 1.5))
            ii = g.within(shapes)
            assert_true(np.all(i[0] == ii[0]))
            assert_true(np.all(i[1] == ii[1]))

    def test_close_within3(self):
        g = self.g.repeat(6, 0).repeat(6, 1)
        args = {'ret_xyz': True, 'ret_rij': True}
        for ia in g:
            shapes = [Sphere(0.1, g[ia]), Sphere(1.5, g[ia])]
            i, xa, d = g.close(ia, R=(0.1, 1.5), **args)
            ii, xai, di = g.within(shapes, **args)
            for j in [0, 1]:
                assert_true(np.all(i[j] == ii[j]))
                assert_true(np.allclose(xa[j], xai[j]))
                assert_true(np.allclose(d[j], di[j]))

    def test_close_sizes(self):
        point = 0

        # Return index
        idx = self.mol.close(point, R=.1)
        assert_equal(len(idx), 1)
        # Return index of two things
        idx = self.mol.close(point, R=(.1, 1.1))
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 1)
        assert_false(isinstance(idx[0], list))
        # Longer
        idx = self.mol.close(point, R=(.1, 1.1, 2.1))
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 1)

        # Return index
        idx = self.mol.close(point, R=.1, ret_xyz=True)
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 1)
        assert_equal(len(idx[1]), 1)
        assert_equal(idx[1].shape[0], 1)  # equivalent to above
        assert_equal(idx[1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, R=(.1, 1.1), ret_xyz=True)
        # [[idx-1, idx-2], [coord-1, coord-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, R=(.1, 1.1), ret_xyz=True, ret_rij=True)
        # [[idx-1, idx-2], [coord-1, coord-2], [dist-1, dist-2]]
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)
        # dist-1
        assert_equal(len(idx[2][0].shape), 1)
        assert_equal(idx[2][0].shape[0], 1)
        # dist-2
        assert_equal(idx[2][1].shape[0], 1)

        # Return index of two things
        idx = self.mol.close(point, R=(.1, 1.1), ret_rij=True)
        # [[idx-1, idx-2], [dist-1, dist-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 1)
        # idx-2
        assert_equal(idx[0][1].shape[0], 1)
        # dist-1
        assert_equal(len(idx[1][0].shape), 1)
        assert_equal(idx[1][0].shape[0], 1)
        # dist-2
        assert_equal(idx[1][1].shape[0], 1)

    def test_close_sizes_none(self):
        point = [100., 100., 100.]

        # Return index
        idx = self.mol.close(point, R=.1)
        assert_equal(len(idx), 0)
        # Return index of two things
        idx = self.mol.close(point, R=(.1, 1.1))
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 0)
        assert_false(isinstance(idx[0], list))
        # Longer
        idx = self.mol.close(point, R=(.1, 1.1, 2.1))
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 0)

        # Return index
        idx = self.mol.close(point, R=.1, ret_xyz=True)
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 0)
        assert_equal(len(idx[1]), 0)
        assert_equal(idx[1].shape[0], 0)  # equivalent to above
        assert_equal(idx[1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, R=(.1, 1.1), ret_xyz=True)
        # [[idx-1, idx-2], [coord-1, coord-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[1], 3)

        # Return index of two things
        idx = self.mol.close(point, R=(.1, 1.1), ret_xyz=True, ret_rij=True)
        # [[idx-1, idx-2], [coord-1, coord-2], [dist-1, dist-2]]
        assert_equal(len(idx), 3)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # coord-1
        assert_equal(len(idx[1][0].shape), 2)
        assert_equal(idx[1][0].shape[0], 0)
        assert_equal(idx[1][0].shape[1], 3)
        # coord-2
        assert_equal(idx[1][1].shape[0], 0)
        assert_equal(idx[1][1].shape[1], 3)
        # dist-1
        assert_equal(len(idx[2][0].shape), 1)
        assert_equal(idx[2][0].shape[0], 0)
        # dist-2
        assert_equal(idx[2][1].shape[0], 0)

        # Return index of two things
        idx = self.mol.close(point, R=(.1, 1.1), ret_rij=True)
        # [[idx-1, idx-2], [dist-1, dist-2]]
        assert_equal(len(idx), 2)
        assert_equal(len(idx[0]), 2)
        assert_equal(len(idx[1]), 2)
        # idx-1
        assert_equal(len(idx[0][0].shape), 1)
        assert_equal(idx[0][0].shape[0], 0)
        # idx-2
        assert_equal(idx[0][1].shape[0], 0)
        # dist-1
        assert_equal(len(idx[1][0].shape), 1)
        assert_equal(idx[1][0].shape[0], 0)
        # dist-2
        assert_equal(idx[1][1].shape[0], 0)

    def test_sparserij1(self):
        rij = self.g.sparserij()

    def test_bond_correct(self):
        # Create ribbon
        rib = self.g.tile(2, 1)
        # Convert the last atom to a H atom
        rib.atom[-1] = Atom[1]
        ia = len(rib) - 1
        # Get bond-length
        idx, d = rib.close(ia, R=(.1, 1000), ret_rij=True)
        i = np.argmin(d[1])
        d = d[1][i]
        rib.bond_correct(ia, idx[1][i])
        idx, d2 = rib.close(ia, R=(.1, 1000), ret_rij=True)
        i = np.argmin(d2[1])
        d2 = d2[1][i]
        assert_false(d == d2)
        # Calculate actual radius
        assert_true(d2 == (Atom[1].radius() + Atom[6].radius()))

    def test_unit_cell_estimation1(self):
        # Create new geometry with only the coordinates
        # and atoms
        geom = Geometry(self.g.xyz, Atom[6])
        # Only check the two distances we know have sizes
        for i in range(2):
            # It cannot guess skewed axis
            assert_false(np.allclose(geom.cell[i, :], self.g.cell[i, :]))

    def test_unit_cell_estimation2(self):
        # Create new geometry with only the coordinates
        # and atoms
        s1 = SuperCell([2, 2, 2])
        g1 = Geometry([[0, 0, 0], [1, 1, 1]], sc=s1)
        g2 = Geometry(np.copy(g1.xyz))
        assert_true(np.allclose(g1.cell, g2.cell))

        # Assert that it correctly calculates the bond-length in the
        # directions of actual distance
        g1 = Geometry([[0, 0, 0], [1, 1, 0]], atom='H', sc=s1)
        g2 = Geometry(np.copy(g1.xyz))
        for i in range(2):
            assert_true(np.allclose(g1.cell[i, :], g2.cell[i, :]))
        assert_false(np.allclose(g1.cell[2, :], g2.cell[2, :]))

    @raises(ValueError)
    def test_distance1(self):
        geom = Geometry(self.g.xyz, Atom[6])
        # maxR is undefined
        d = geom.distance()

    @raises(ValueError)
    def test_distance2(self):
        geom = Geometry(self.g.xyz, Atom[6])
        d = geom.distance(R=1.42, method='unknown_numpy_function')

    def test_distance3(self):
        geom = self.g.copy()
        d = geom.distance()
        assert_equal(len(d), 1)
        assert_true(np.allclose(d, [1.42]))

    def test_distance4(self):
        geom = self.g.copy()
        d = geom.distance(method=np.min)
        assert_equal(len(d), 1)
        assert_true(np.allclose(d, [1.42]))
        d = geom.distance(method=np.max)
        assert_equal(len(d), 1)
        assert_true(np.allclose(d, [1.42]))
        d = geom.distance(method='max')
        assert_equal(len(d), 1)
        assert_true(np.allclose(d, [1.42]))

    def test_distance5(self):
        geom = self.g.copy()
        d = geom.distance(R=np.inf)
        assert_equal(len(d), 6)
        d = geom.distance(0, R=1.42)
        assert_equal(len(d), 1)
        assert_true(np.allclose(d, [1.42]))

    def test_distance6(self):
        # Create a 1D chain
        geom = Geometry([0] * 3, Atom(1, R=1.), sc=1)
        geom.set_nsc([77, 1, 1])
        d = geom.distance(0)
        assert_equal(len(d), 1)
        assert_true(np.allclose(d, [1.]))

        # Do twice
        d = geom.distance(R=2)
        assert_equal(len(d), 2)
        assert_true(np.allclose(d, [1., 2.]))

        # Do all
        d = geom.distance(R=np.inf)
        assert_equal(len(d), 77 // 2)
        # Add one due arange not adding the last item
        assert_true(np.allclose(d, range(1, 78 // 2)))

        # Create a 2D grid
        geom.set_nsc([3, 3, 1])
        d = geom.distance(R=2, tol=[.4, .3, .2, .1])
        assert_equal(len(d), 2)  # 1, sqrt(2)
        # Add one due arange not adding the last item
        assert_true(np.allclose(d, [1, 2**.5]))

        # Create a 2D grid
        geom.set_nsc([5, 5, 1])
        d = geom.distance(R=2, tol=[.4, .3, .2, .1])
        assert_equal(len(d), 3)  # 1, sqrt(2), 2
        # Add one due arange not adding the last item
        assert_true(np.allclose(d, [1, 2**.5, 2]))

    def test_distance7(self):
        # Create a 1D chain
        geom = Geometry([0] * 3, Atom(1, R=1.), sc=1)
        geom.set_nsc([77, 1, 1])
        # Try with a short R and a long tolerance list
        d = geom.distance(R=1, tol=np.ones(10) * .5)
        assert_equal(len(d), 1)
        assert_true(np.allclose(d, [1.]))

    def test_distance8(self):
        geom = Geometry([0] * 3, Atom(1, R=1.), sc=1)
        geom.set_nsc([77, 1, 1])
        d = geom.distance(0, method='min')
        assert_equal(len(d), 1)
        d = geom.distance(0, method='median')
        assert_equal(len(d), 1)
        d = geom.distance(0, method='mode')
        assert_equal(len(d), 1)

    def test_optimize_nsc1(self):
        # Create a 1D chain
        geom = Geometry([0] * 3, Atom(1, R=1.), sc=1)
        geom.set_nsc([77, 77, 77])
        assert_true(np.allclose(geom.optimize_nsc(), [3, 3, 3]))
        geom.set_nsc([77, 77, 77])
        assert_true(np.allclose(geom.optimize_nsc(1), [77, 3, 77]))
        geom.set_nsc([77, 77, 77])
        assert_true(np.allclose(geom.optimize_nsc([0, 2]), [3, 77, 3]))
        geom.set_nsc([77, 77, 77])
        assert_true(np.allclose(geom.optimize_nsc([0, 2], R=2), [5, 77, 5]))
        geom.set_nsc([1, 1, 1])
        assert_true(np.allclose(geom.optimize_nsc([0, 2], R=2), [5, 1, 5]))

    def test_argumentparser1(self):
        self.g.ArgumentParser()
        self.g.ArgumentParser(**self.g._ArgumentParser_args_single())

    def test_argumentparser2(self, **kwargs):
        p, ns = self.g.ArgumentParser(**kwargs)

        # Try all options
        opts = [
            '--origin',
            '--center-of',
            'mass',
            '--center-of',
            'xyz',
            '--center-of',
            'position',
            '--center-of',
            'cell',
            '--unit-cell',
            'translate',
            '--unit-cell',
            'mod',
            '--rotate',
            'x',
            '90',
            '--rotate',
            'y',
            '90',
            '--rotate',
            'z',
            '90',
            '--add',
            '0,0,0',
            '6',
            '--swap',
            '0',
            '1',
            '--repeat',
            'x',
            '2',
            '--repeat',
            'y',
            '2',
            '--repeat',
            'z',
            '2',
            '--tile',
            'x',
            '2',
            '--tile',
            'y',
            '2',
            '--tile',
            'z',
            '2',
            '--cut',
            'z',
            '2',
            '--cut',
            'y',
            '2',
            '--cut',
            'x',
            '2',
        ]
        if kwargs.get('limit_arguments', True):
            opts.extend([
                '--rotate', 'x', '-90', '--rotate', 'y', '-90', '--rotate',
                'z', '-90'
            ])
        else:
            opts.extend([
                '--rotate-x', ' -90', '--rotate-y', ' -90', '--rotate-z',
                ' -90', '--repeat-x', '2', '--repeat-y', '2', '--repeat-z', '2'
            ])

        args = p.parse_args(opts, namespace=ns)

        if len(kwargs) == 0:
            self.test_argumentparser2(**self.g._ArgumentParser_args_single())

    def test_set_sc(self):
        # Create new geometry with only the coordinates
        # and atoms
        s1 = SuperCell([2, 2, 2])
        g1 = Geometry([[0, 0, 0], [1, 1, 1]], sc=[2, 2, 1])
        g1.set_sc(s1)
        assert_true(g1.sc == s1)

    def test_attach1(self):
        g = self.g.attach(0, self.mol, 0, dist=1.42, axis=2)
        g = self.g.attach(0, self.mol, 0, dist='calc', axis=2)
        g = self.g.attach(0, self.mol, 0, dist=[0, 0, 1.42])

    def test_mirror1(self):
        for plane in ['xy', 'xz', 'yz']:
            self.g.mirror(plane)

    def test_pickle(self):
        import pickle as p
        s = p.dumps(self.g)
        n = p.loads(s)
        assert_true(n == self.g)
        assert_false(n != self.g)
Exemple #12
0
class TestHamiltonian(object):
    # Base test class for MaskedArrays.

    def setUp(self):
        bond = 1.42
        sq3h = 3.**.5 * 0.5
        self.sc = SuperCell(np.array([[1.5, sq3h, 0.],
                                      [1.5, -sq3h, 0.],
                                      [0., 0., 10.]], np.float64) * bond, nsc=[3, 3, 1])

        C = Atom(Z=6, R=bond * 1.01, orbs=1)
        self.g = Geometry(np.array([[0., 0., 0.],
                                    [1., 0., 0.]], np.float64) * bond,
                          atom=C, sc=self.sc)
        self.H = Hamiltonian(self.g)
        self.HS = Hamiltonian(self.g, orthogonal=False)

        C = Atom(Z=6, R=bond * 1.01, orbs=2)
        self.g2 = Geometry(np.array([[0., 0., 0.],
                                    [1., 0., 0.]], np.float64) * bond,
                          atom=C, sc=self.sc)
        self.H2 = Hamiltonian(self.g2)
        self.HS2 = Hamiltonian(self.g2, orthogonal=False)


    def tearDown(self):
        del self.sc
        del self.g
        del self.H
        del self.HS
        del self.g2
        del self.H2
        del self.HS2

    def test_objects(self):
        print(self.H)
        assert_true(len(self.H.xyz) == 2)
        assert_true(self.g.no == len(self.H))
        assert_true(len(self.HS.xyz) == 2)
        assert_true(self.g.no == len(self.HS))

        assert_true(len(self.H2.xyz) == 2)
        assert_true(self.g2.no == len(self.H2))
        assert_true(len(self.HS2.xyz) == 2)
        assert_true(self.g2.no == len(self.HS2))

    def test_dtype(self):
        assert_true(self.H.dtype == np.float64)
        assert_true(self.HS.dtype == np.float64)
        assert_true(self.H2.dtype == np.float64)
        assert_true(self.HS2.dtype == np.float64)

    def test_ortho(self):
        assert_true(self.H.orthogonal)
        assert_false(self.HS.orthogonal)

    def test_set1(self):
        self.H.H[0,0] = 1.
        assert_true(self.H[0,0] == 1.)
        assert_true(self.H[1,0] == 0.)
        self.H.empty()

        self.HS.H[0,0] = 1.
        assert_true(self.HS.H[0,0] == 1.)
        assert_true(self.HS.H[1,0] == 0.)
        assert_true(self.HS.S[0,0] == 0.)
        assert_true(self.HS.S[1,0] == 0.)
        self.HS.S[0,0] = 1.
        assert_true(self.HS.H[0,0] == 1.)
        assert_true(self.HS.H[1,0] == 0.)
        assert_true(self.HS.S[0,0] == 1.)
        assert_true(self.HS.S[1,0] == 0.)

        # delete before creating the same content
        self.HS.empty()
        self.HS[0,0] = 1., 1.
        assert_true(self.HS.H[0,0] == 1.)
        assert_true(self.HS.S[0,0] == 1.)
        self.HS.empty()

    def test_set2(self):
        self.H.construct((0.1,1.5), (1.,0.1))
        assert_true(self.H[0,0] == 1.)
        assert_true(self.H[1,0] == 0.1)
        assert_true(self.H[0,1] == 0.1)
        self.H.empty()

    def test_set3(self):
        self.HS.construct((0.1, 1.5), ((1., 2.), (0.1, 0.2)))
        assert_true(self.HS.H[0,0] == 1.)
        assert_true(self.HS.S[0,0] == 2.)
        assert_true(self.HS.H[1,1] == 1.)
        assert_true(self.HS.S[1,1] == 2.)
        assert_true(self.HS.H[1,0] == 0.1)
        assert_true(self.HS.H[0,1] == 0.1)
        assert_true(self.HS.S[1,0] == 0.2)
        assert_true(self.HS.S[0,1] == 0.2)
        assert_true(self.HS.nnz == len(self.HS) * 4)
        self.HS.empty()

    def test_set4(self):
        for ia, io in self.H:
            # Find atoms close to 'ia'
            idx = self.H.geom.close(ia, dR=(0.1, 1.5) )
            self.H[io, idx[0]] = 1.
            self.H[io, idx[1]] = 0.1
        assert_true(self.H.H[0,0] == 1.)
        assert_true(self.H.H[1,1] == 1.)
        assert_true(self.H.H[1,0] == 0.1)
        assert_true(self.H.H[0,1] == 0.1)
        assert_true(self.H.nnz == len(self.H) * 4)
        self.H.empty()

    @attr('slow')
    def test_set5(self):
        # Test of HUGE construct
        g = self.g.tile(10, 0).tile(10, 1).tile(10, 2)
        H = Hamiltonian(g)
        H.construct( (0.1, 1.5), (1., 0.1) )
        assert_true(H.H[0,0] == 1.)
        assert_true(H.H[1,1] == 1.)
        assert_true(H.H[1,0] == 0.1)
        assert_true(H.H[0,1] == 0.1)
        # This is graphene
        # on-site == len(H)
        # nn == 3 * len(H)
        assert_true(H.nnz == len(H) * 4)
        del H

    def test_op1(self):
        g = Geometry([[i, 0,0] for i in range(100)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        for i in range(10):
            j = range(i*4, i*4+3)
            H[0, j] = i

            # i+
            H += 1
            for jj in j:
                assert_equal(H[0, jj], i+1)
                assert_equal(H[1, jj], 0)

            # i-
            H -= 1
            for jj in j:
                assert_equal(H[0, jj], i)
                assert_equal(H[1, jj], 0)

            # i*
            H *= 2
            for jj in j:
                assert_equal(H[0, jj], i*2)
                assert_equal(H[1, jj], 0)

            # //
            H //= 2
            for jj in j:
                assert_equal(H[0, jj], i)
                assert_equal(H[1, jj], 0)

            # i**
            H **= 2
            for jj in j:
                assert_equal(H[0, jj], i**2)
                assert_equal(H[1, jj], 0)

    def test_op2(self):
        g = Geometry([[i, 0,0] for i in range(100)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        for i in range(10):
            j = range(i*4, i*4+3)
            H[0, j] = i

            # +
            s = H + 1
            for jj in j:
                assert_equal(s[0, jj], i+1)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # -
            s = H - 1
            for jj in j:
                assert_equal(s[0, jj], i-1)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # -
            s = 1 - H
            for jj in j:
                assert_equal(s[0, jj], 1-i)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # *
            s = H * 2
            for jj in j:
                assert_equal(s[0, jj], i*2)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # //
            s = s // 2
            for jj in j:
                assert_equal(s[0, jj], i)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # **
            s = H ** 2
            for jj in j:
                assert_equal(s[0, jj], i**2)
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

            # ** (r)
            s = 2 ** H
            for jj in j:
                assert_equal(s[0, jj], 2 ** H[0, jj])
                assert_equal(H[0, jj], i)
                assert_equal(s[1, jj], 0)

    def test_op3(self):
        g = Geometry([[i, 0,0] for i in range(100)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        # Create initial stuff
        for i in range(10):
            j = range(i*4, i*4+3)
            H[0, j] = i

        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.int32)
            h = func(1.)
            assert_equal(h.dtype, np.float64)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

        H = H.copy(dtype=np.float64)
        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.float64)
            h = func(1.)
            assert_equal(h.dtype, np.float64)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

        H = H.copy(dtype=np.complex128)
        for op in ['add', 'sub', 'mul', 'pow']:
            func = getattr(H, '__{}__'.format(op))
            h = func(1)
            assert_equal(h.dtype, np.complex128)
            h = func(1.)
            assert_equal(h.dtype, np.complex128)
            if op != 'pow':
                h = func(1.j)
                assert_equal(h.dtype, np.complex128)

    def test_op4(self):
        g = Geometry([[i, 0,0] for i in range(100)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.int32)
        # Create initial stuff
        for i in range(10):
            j = range(i*4, i*4+3)
            H[0, j] = i

        h = 1 + H
        assert_equal(h.dtype, np.int32)
        h = 1. + H
        assert_equal(h.dtype, np.float64)
        h = 1.j + H
        assert_equal(h.dtype, np.complex128)

        h = 1 - H
        assert_equal(h.dtype, np.int32)
        h = 1. - H
        assert_equal(h.dtype, np.float64)
        h = 1.j - H
        assert_equal(h.dtype, np.complex128)
        
        h = 1 * H
        assert_equal(h.dtype, np.int32)
        h = 1. * H
        assert_equal(h.dtype, np.float64)
        h = 1.j * H
        assert_equal(h.dtype, np.complex128)

        h = 1 ** H
        assert_equal(h.dtype, np.int32)
        h = 1. ** H
        assert_equal(h.dtype, np.float64)
        h = 1.j ** H
        assert_equal(h.dtype, np.complex128)

    def test_eig1(self):
        # Test of eigenvalues
        g = self.g.tile(2, 0).tile(2, 1).tile(2, 2)
        H = Hamiltonian(g)
        H.construct((0.1,1.5), (1.,0.1))
        H.eigh()
        H.eigsh(n=4)
        H.empty()
        del H

    def test_eig2(self):
        # Test of eigenvalues
        self.HS.construct((0.1,1.5), ((1.,1.), (0.1,0.1)))
        self.HS.eigh()
        self.HS.empty()

    def test_spin2(self):
        g = Geometry([[i, 0,0] for i in range(10)], Atom(6, R=1.01), sc=[100])
        H = Hamiltonian(g, dtype=np.int32, spin=2)
        for i in range(10):
            j = range(i*4, i*4+3)
            H[0, j] = (i, i*2)


    def test_finalized(self):
        assert_false(self.H.finalized)
        self.H.H[0,0] = 1.
        self.H.finalize()
        assert_true(self.H.finalized)
        assert_true(self.H.nnz == 1)
        self.H.empty()
        assert_false(self.HS.finalized)
        self.HS[0,0] = 1., 1.
        self.HS.finalize()
        assert_true(self.HS.finalized)
        assert_true(self.HS.nnz == 1)
        self.HS.empty()