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
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.)
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_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)
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))
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)
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()
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
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
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)
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()