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 hcp(a, atom, coa=1.63333, orthogonal=False): """ Returns a geometry with the FCC crystal structure (1 atom) """ # height of hcp structure c = a * coa a2sq = a / 2 ** .5 if orthogonal: sc = SuperCell([[a + a * _c60 * 2, 0, 0], [0, a * _c30 * 2, 0], [0, 0, c / 2]]) gt = Geometry([[0, 0, 0], [a, 0, 0], [a * _s30, a * _c30, 0], [a * (1 + _s30), a * _c30, 0]], atom, sc=sc) # Create the rotated one on top gr = gt.copy() # mirror structure gr.xyz[0, 1] += sc.cell[1, 1] gr.xyz[1, 1] += sc.cell[1, 1] gr = gr.translate(-np.amin(gr.xyz, axis=0)) # Now displace to get the correct offset gr = gr.translate([0, a * _s30 / 2, 0]) g = gt.append(gr, 2) else: sc = SuperCell([a, a, c, 90, 90, 60], nsc=[3, 3, 3]) g = Geometry( [[0, 0, 0], [a2sq * _c30, a2sq * _s30, c / 2]], atom, sc=sc) return g
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 __init__(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] * 3) self.g = Geometry( np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) * bond, atom=C, sc=self.sc) self.D = DynamicalMatrix(self.g) def func(D, ia, idxs, idxs_xyz): idx = D.geometry.close(ia, R=(0.1, 1.44), idx=idxs, idx_xyz=idxs_xyz) ia = ia * 3 i0 = idx[0] * 3 i1 = idx[1] * 3 # on-site p = 1. D.D[ia, i0] = p D.D[ia + 1, i0 + 1] = p D.D[ia + 2, i0 + 2] = p # nn p = 0.1 # on-site directions D.D[ia, ia + 1] = p D.D[ia, ia + 2] = p D.D[ia + 1, ia] = p D.D[ia + 1, ia + 2] = p D.D[ia + 2, ia] = p D.D[ia + 2, ia + 1] = p D.D[ia, i1 + 1] = p D.D[ia, i1 + 2] = p D.D[ia + 1, i1] = p D.D[ia + 1, i1 + 2] = p D.D[ia + 2, i1] = p D.D[ia + 2, i1 + 1] = p self.func = func
def read_geometry(self): """ Read geometry from the contained file """ # First we read in the geometry sc = self.read_supercell() # Try and go to the first model record in_model, l = self._step_record('MODEL') idx = [] tags = [] xyz = [] Z = [] if in_model: l = self.readline() def is_atom(line): return l.startswith('ATOM') or l.startswith('HETATM') def is_end_model(line): return l.startswith('ENDMDL') or l == '' while not is_end_model(l): if is_atom(l): idx.append(int(l[6:11])) tags.append(l[12:16].strip()) xyz.append( [float(l[30:38]), float(l[38:46]), float(l[46:54])]) Z.append(l[76:78].strip()) l = self.readline() # First sort all atoms according to the idx array idx = np.array(idx) idx = np.argsort(idx) xyz = np.array(xyz)[idx, :] tags = [tags[i] for i in idx] Z = [Z[i] for i in idx] # Create the atom list atoms = Atoms(Atom(Z[0], tag=tags[0]), na=len(Z)) for i, a in enumerate(map(Atom, Z, tags)): try: s = atoms.index(a) except: s = len(atoms.atom) atoms._atom.append(a) atoms._specie[i] = s return Geometry(xyz, atoms, sc=sc)
def honeycomb(bond, atom, orthogonal=False): """ Honeycomb lattice with 2 or 4 atoms per unit-cell, latter orthogonal cell This enables creating BN lattices with ease, or graphene lattices. Parameters ---------- bond : float bond length between atoms (*not* lattice constant) atom : Atom the atom (or atoms) that the honeycomb lattice consists of orthogonal : bool, optional if True returns an orthogonal lattice See Also -------- graphene: the equivalent of this, but with default of Carbon atoms bilayer: create bilayer honeycomb lattices """ sq3h = 3.**.5 * 0.5 if orthogonal: sc = SuperCell(np.array( [[3., 0., 0.], [0., 2 * sq3h, 0.], [0., 0., 10.]], np.float64) * bond, nsc=[3, 3, 1]) g = Geometry(np.array([[0., 0., 0.], [0.5, sq3h, 0.], [1.5, sq3h, 0.], [2., 0., 0.]], np.float64) * bond, atom, sc=sc) else: sc = SuperCell(np.array( [[1.5, sq3h, 0.], [1.5, -sq3h, 0.], [0., 0., 10.]], np.float64) * bond, nsc=[3, 3, 1]) g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) * bond, atom, sc=sc) return g
def test_wavefunction2(): N = 50 o1 = SphericalOrbital( 0, (np.linspace(0, 2, N), np.exp(-np.linspace(0, 100, N)))) G = Geometry([[1] * 3, [2] * 3], Atom(6, o1), sc=[4, 4, 4]) H = Hamiltonian(G) R, param = [0.1, 1.5], [1., 0.1] H.construct([R, param]) ES = H.eigenstate(dtype=np.float64) # This is effectively plotting outside where no atoms exists # (there could however still be psi weight). grid = Grid(0.1, sc=SuperCell([2, 2, 2], origo=[2] * 3)) grid.fill(0.) ES.sub(0).wavefunction(grid)
def honeycomb(bond, atom, orthogonal=False): """ Returns a honeycomb geometry with the graphene unit-cell (2 atoms) """ sq3h = 3.**.5 * 0.5 if orthogonal: sc = SuperCell(np.array( [[3., 0., 0.], [0., 2 * sq3h, 0.], [0., 0., 10.]], np.float64) * bond, nsc=[3, 3, 1]) g = Geometry(np.array([[0., 0., 0.], [0.5, sq3h, 0.], [1.5, sq3h, 0.], [2., 0., 0.]], np.float64) * bond, atom, sc=sc) else: sc = SuperCell(np.array( [[1.5, sq3h, 0.], [1.5, -sq3h, 0.], [0., 0., 10.]], np.float64) * bond, nsc=[3, 3, 1]) g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) * bond, atom, sc=sc) return g
def _r_geometry_ase(self, na, header, sp, xyz, sc): """ Read the geometry as though it was created with ASE """ # Convert F T to nsc # F = 1 # T = 3 nsc = list( map(lambda x: "FT".index(x) * 2 + 1, header.pop("pbc").strip('"').split())) cell = _a.fromiterd(header.pop("Lattice").strip('"').split()).reshape( 3, 3) if sc is None: sc = SuperCell(cell, nsc=nsc) return Geometry(xyz, atoms=sp, sc=sc)
def __init__(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]) 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] * 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 test_spin1(self, setup): g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=SuperCell(100, nsc=[3, 3, 1])) H = Hamiltonian(g, dtype=np.int32, spin=Spin.POLARIZED) for i in range(10): j = range(i * 2, i * 2 + 3) H[0, j] = (i, i * 2) H2 = Hamiltonian(g, 2, dtype=np.int32) for i in range(10): j = range(i * 2, i * 2 + 3) H2[0, j] = (i, i * 2) assert H.spsame(H2)
def test_imaginary_fail_geometry(sisl_tmp): fr = sisl_tmp('GRID_real.cube', _dir) fi = sisl_tmp('GRID_imag.cube', _dir) geom = Geometry(np.random.rand(10, 3), np.random.randint(1, 70, 10), sc=[10, 10, 10, 45, 60, 90]) grid = Grid(0.2, geometry=geom, dtype=np.complex128) grid.grid = np.random.rand(*grid.shape) + 1j * np.random.rand(*grid.shape) grid.write(fr) # Assert it fails on geometry grid2 = Grid(0.3, dtype=np.complex128) grid2.write(fi, imag=True) grid.read(fr, imag=fi)
def test_grid_tile_geom(): grid = Grid([4, 5, 6], geometry=Geometry([0] * 3, Atom[4], sc=4.)) grid2 = grid.tile(2, 2) assert grid.shape[:2] == grid2.shape[:2] assert grid.shape[2] == grid2.shape[2] // 2 assert grid.volume * 2 == pytest.approx(grid2.volume) assert grid.geometry.na * 2 == grid2.geometry.na grid4 = grid2.tile(2, 1) assert grid.shape[0] == grid4.shape[0] assert grid.shape[1] == grid4.shape[1] // 2 assert grid.shape[2] == grid4.shape[2] // 2 assert grid.volume * 4 == pytest.approx(grid4.volume) assert grid.geometry.na * 4 == grid4.geometry.na
def diamond(alat=3.57, atom=None): """ Returns a geometry with the diamond unit-cell (2 atoms) """ dist = alat * 3.**.5 / 4 if atom is None: atom = Atom(Z=6, R=dist * 1.01) sc = SuperCell(np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]], np.float64) * alat / 2, nsc=[3, 3, 3]) dia = Geometry(np.array([[0, 0, 0], [1, 1, 1]], np.float64) * alat / 4, atom, sc=sc) return dia
def test_so1(self, setup): g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=[100]) H = Hamiltonian(g, dtype=np.float64, spin=Spin.SPINORBIT) 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(dtype=np.complex64) assert np.allclose(H.eigh(dtype=np.complex128), eig1) assert 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 H1.spsame(H) eig1 = H1.eigh(dtype=np.complex64) assert np.allclose(H1.eigh(dtype=np.complex128), eig1) assert np.allclose(H.eigh(dtype=np.complex64), H1.eigh(dtype=np.complex128)) es = H.eigenstate(dtype=np.complex128) assert np.allclose(es.eig, eig1) es.spin_moment() PDOS = es.PDOS(np.linspace(-1, 1, 100)) DOS = es.DOS(np.linspace(-1, 1, 100)) assert np.allclose(PDOS.sum(1)[0, :], DOS)
def test_non_colinear_non_orthogonal(self, setup): g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=SuperCell(100, nsc=[3, 3, 1])) H = Hamiltonian(g, dtype=np.float64, orthogonal=False, spin=Spin.NONCOLINEAR) for i in range(10): j = range(i*2, i*2+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. H.S[i, i] = 1. eig1 = H.eigh(dtype=np.complex64) assert np.allclose(H.eigh(dtype=np.complex128), eig1) assert len(eig1) == len(H) H1 = Hamiltonian(g, dtype=np.float64, orthogonal=False, spin=Spin('non-collinear')) for i in range(10): j = range(i*2, i*2+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. H1.S[i, i] = 1. assert H1.spsame(H) eig1 = H1.eigh(dtype=np.complex64) assert np.allclose(H1.eigh(dtype=np.complex128), eig1) assert np.allclose(H.eigh(dtype=np.complex64), H1.eigh(dtype=np.complex128)) es = H1.eigenstate(dtype=np.complex128) assert np.allclose(es.eig, eig1) sm = es.spin_moment() om = es.spin_orbital_moment() assert np.allclose(sm, om.sum(1)) PDOS = es.PDOS(np.linspace(-1, 1, 100)) DOS = es.DOS(np.linspace(-1, 1, 100)) assert np.allclose(PDOS.sum(1)[0, :], DOS)
def bcc(alat, atoms, orthogonal=False): """ Body centered cubic lattice with 1 (non-orthogonal) or 2 atoms (orthogonal) Parameters ---------- alat : float lattice parameter atoms : Atom the atom(s) in the BCC lattice orthogonal : bool, optional whether the lattice is orthogonal (2 atoms) """ if orthogonal: sc = SuperCell( np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], np.float64) * alat) ah = alat / 2 g = Geometry([[0, 0, 0], [ah, ah, ah]], atoms, sc=sc) else: sc = SuperCell( np.array([[-1, 1, 1], [1, -1, 1], [1, 1, -1]], np.float64) * alat / 2) g = Geometry([0, 0, 0], atoms, sc=sc) geometry_define_nsc(g) return g
def sc(alat, atom): """ Simple cubic lattice with 1 atom Parameters ---------- alat : float lattice parameter atom : Atom the atom in the SC lattice """ sc = SuperCell( np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], np.float64) * alat) g = Geometry([0, 0, 0], atom, sc=sc) geometry_define_nsc(g) return g
def test_wavefunction_eta(): N = 50 o1 = SphericalOrbital( 0, (np.linspace(0, 2, N), np.exp(-np.linspace(0, 100, N)))) G = Geometry([[1] * 3, [2] * 3], Atom(6, o1), sc=[4, 4, 4]) H = Hamiltonian(G, spin=Spin('nc')) R, param = [0.1, 1.5], [[0., 0., 0.1, -0.1], [1., 1., 0.1, -0.1]] H.construct([R, param]) ES = H.eigenstate() # Plot in the full thing grid = Grid(0.1, dtype=np.complex128, sc=SuperCell([2, 2, 2], origo=[-1] * 3)) grid.fill(0.) ES.sub(0).wavefunction(grid, eta=True)
def hcp(a, atoms, coa=1.63333, orthogonal=False): """ Hexagonal closed packed lattice with 2 (non-orthogonal) or 4 atoms (orthogonal) Parameters ---------- a : float lattice parameter for 1st and 2nd lattice vectors atoms : Atom the atom(s) in the HCP lattice coa : float, optional c over a parameter where c is the 3rd lattice vector length orthogonal : bool, optional whether the lattice is orthogonal (4 atoms) """ # height of hcp structure c = a * coa a2sq = a / 2**.5 if orthogonal: sc = SuperCell([[a + a * _c60 * 2, 0, 0], [0, a * _c30 * 2, 0], [0, 0, c / 2]]) gt = Geometry([[0, 0, 0], [a, 0, 0], [a * _s30, a * _c30, 0], [a * (1 + _s30), a * _c30, 0]], atoms, sc=sc) # Create the rotated one on top gr = gt.copy() # mirror structure gr.xyz[0, 1] += sc.cell[1, 1] gr.xyz[1, 1] += sc.cell[1, 1] gr = gr.translate(-np.amin(gr.xyz, axis=0)) # Now displace to get the correct offset gr = gr.translate([0, a * _s30 / 2, 0]) g = gt.append(gr, 2) else: sc = SuperCell([a, a, c, 90, 90, 60]) g = Geometry([[0, 0, 0], [a2sq * _c30, a2sq * _s30, c / 2]], atoms, sc=sc) if np.all(g.maxR(True) > 0.): g.optimize_nsc() return g
def test_non_colinear1(self, setup): g = Geometry([[i, 0, 0] for i in range(10)], Atom(6, R=1.01), sc=[100]) H = Hamiltonian(g, dtype=np.float64, spin=Spin.NONCOLINEAR) 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(4): assert np.allclose(H.eigh(), eig1) assert len(eig1) == len(H) H1 = Hamiltonian(g, dtype=np.float64, spin=Spin('non-collinear')) 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 H1.spsame(H) eig1 = H1.eigh() # Check TimeSelector for i in range(4): assert np.allclose(H1.eigh(), eig1) assert np.allclose(H.eigh(), H1.eigh()) es = H1.eigenstate() assert np.allclose(es.eig, eig1) es.spin_moment() PDOS = es.PDOS(np.linspace(-1, 1, 100)) DOS = es.DOS(np.linspace(-1, 1, 100)) assert np.allclose(PDOS.sum(1)[0, :], DOS)
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 __init__(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]) n = 60 rf = np.linspace(0, bond * 1.01, n) rf = (rf, rf) orb = SphericalOrbital(1, rf, 2.) C = Atom(6, orb.toAtomicOrbital()) self.g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) * bond, atoms=C, sc=self.sc) self.S = Overlap(self.g)
def read_geom(self): """ Returns `Geometry` object from the CUBE file """ na, sc = self.read_sc(na=True) # Start reading the geometry xyz = np.empty([na, 3], np.float64) atom = [] for ia in range(na): tmp = self.readline().split() atom.append(Atom(int(tmp[0]))) xyz[ia, 0] = float(tmp[2]) xyz[ia, 1] = float(tmp[3]) xyz[ia, 2] = float(tmp[4]) xyz /= Ang2Bohr return Geometry(xyz, atom, sc=sc)
def test_orbital_momentum(self, setup): bond = 1.42 sq3h = 3.**.5 * 0.5 sc = SuperCell(np.array([[1.5, sq3h, 0.], [1.5, -sq3h, 0.], [0., 0., 10.]], np.float64) * bond, nsc=[3, 3, 1]) orb = AtomicOrbital('px', R=bond * 1.001) C = Atom(6, orb) g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) * bond, atoms=C, sc=sc) D = DensityMatrix(g, spin=Spin('SO')) D.construct([[0.1, bond + 0.01], [(1., 0.5, 0.01, 0.01, 0.01, 0.01, 0., 0.), (0.1, 0.1, 0.1, 0.1, 0., 0., 0., 0.)]]) D.orbital_momentum("atom") D.orbital_momentum("orbital")
def read_hamiltonian(self, **kwargs): """ Returns the electronic structure from the siesta.TSHS file """ # Now read the sizes used... Gamma, spin, no, no_s, nnz = _siesta.read_hsx_sizes(self.file) ncol, col, dH, dS, dxij = _siesta.read_hsx_hsx(self.file, Gamma, spin, no, no_s, nnz) # Try and immediately attach a geometry geom = kwargs.get('geometry', kwargs.get('geom', None)) if geom is None: # We have *no* clue about the if np.allclose(dxij, 0.): # We truly, have no clue, # Just generate a boxed system xyz = [[x, 0, 0] for x in range(no)] geom = Geometry(xyz, Atom(1), sc=[no, 1, 1]) else: # Try to figure out the supercell warn( self.__class__.__name__ + ".read_hamiltonian (currently we can not calculate atomic positions from" " xij array)") if geom.no != no: raise ValueError( "Reading HSX files requires the input geometry to have the " "correct number of orbitals {} / {}.".format(no, geom.no)) # Create the Hamiltonian container H = Hamiltonian(geom, spin, nnzpr=1, dtype=np.float32, orthogonal=False) # Create the new sparse matrix H._csr.ncol = ncol.astype(np.int32, copy=False) H._csr.ptr = np.insert(np.cumsum(ncol, dtype=np.int32), 0, 0) # Correct fortran indices H._csr.col = col.astype(np.int32, copy=False) - 1 H._csr._nnz = len(col) H._csr._D = np.empty([nnz, spin + 1], np.float32) H._csr._D[:, :spin] = dH[:, :] H._csr._D[:, spin] = dS[:] return H
def _read_geometry(self, sc, *args, **kwargs): """ Defered routine """ is_frac = True f, _ = self.step_to('atoms_frac', case=False) if not f: is_frac = False self.fh.seek(0) f, _ = self.step_to('atoms_cart', case=False) if not f: raise ValueError( "The geometry coordinates (atoms_frac/cart) could not be found in the seed-file." ) # Species and coordinate list s = [] xyz = [] # Read the next line to determine the units if is_frac: unit = 1. else: unit = self.readline() if len(unit.split()) > 1: l = unit.split() s.append(l[0]) xyz.append(list(map(float, l[1:4]))) unit = 1. else: unit = unit_convert(unit.strip().capitalize(), 'Ang') l = self.readline() while not 'end' in l: # Get the species and l = l.split() s.append(l[0]) xyz.append(list(map(float, l[1:4]))) l = self.readline() # Convert xyz = np.array(xyz, np.float64) * unit if is_frac: xyz = np.dot(sc.cell.T, xyz.T).T return Geometry(xyz, atoms=s, sc=sc)
def read_geometry(self): """ Returns Geometry object from the XV file """ sc = self.read_supercell() # Read number of atoms na = int(self.readline()) atms = [None] * na xyz = np.empty([na, 3], np.float64) line = np.empty(8, np.float64) for ia in range(na): line[:] = list(map(float, self.readline().split()[:8])) atms[ia] = Atom[int(line[1])] xyz[ia, :] = line[2:5] xyz *= Bohr2Ang return Geometry(xyz, atms, sc=sc)
def read_geom(self): """ Returns Geometry object from the XV file """ sc = self.read_sc() # Read number of atoms na = int(self.readline()) atms = [None] * na xyz = np.empty([na, 3], np.float64) line = np.empty(8, np.float64) for ia in range(na): line[:] = np.fromstring(self.readline(), dtype=float, sep=' ')[0:8] atms[ia] = Atom[int(line[1])] xyz[ia, :] = line[2:5] xyz *= Bohr2Ang return Geometry(xyz, atms, sc=sc)
def test_rho2(self, setup): bond = 1.42 sq3h = 3.**.5 * 0.5 sc = SuperCell(np.array( [[1.5, sq3h, 0.], [1.5, -sq3h, 0.], [0., 0., 10.]], np.float64) * bond, nsc=[3, 3, 1]) n = 60 rf = np.linspace(0, bond * 1.01, n) rf = (rf, rf) orb = SphericalOrbital(1, rf, 2.) C = Atom(6, orb) g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) * bond, atom=C, sc=sc) D = DensityMatrix(g) D.construct([[0.1, bond + 0.01], [1., 0.1]]) grid = Grid(0.2, geometry=D.geom) D.density(grid) D = DensityMatrix(g, spin=Spin('P')) D.construct([[0.1, bond + 0.01], [(1., 0.5), (0.1, 0.1)]]) grid = Grid(0.2, geometry=D.geom) D.density(grid) D.density(grid, [1., -1]) D.density(grid, 0) D.density(grid, 1) D = DensityMatrix(g, spin=Spin('NC')) D.construct([[0.1, bond + 0.01], [(1., 0.5, 0.01, 0.01), (0.1, 0.1, 0.1, 0.1)]]) grid = Grid(0.2, geometry=D.geom) D.density(grid) D.density(grid, [[1., 0.], [0., -1]]) D = DensityMatrix(g, spin=Spin('SO')) D.construct([[0.1, bond + 0.01], [(1., 0.5, 0.01, 0.01, 0.01, 0.01, 0., 0.), (0.1, 0.1, 0.1, 0.1, 0., 0., 0., 0.)]]) grid = Grid(0.2, geometry=D.geom) D.density(grid) D.density(grid, [[1., 0.], [0., -1]]) D.density(grid, Spin.X) D.density(grid, Spin.Y) D.density(grid, Spin.Z)
def __init__(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]) self.g = Geometry(np.array([[0., 0., 0.], [1., 0., 0.]], np.float64) * bond, atom=C, sc=self.sc) self.H = Hamiltonian(self.g) func = self.H.create_construct([0.1, bond+0.1], [0., -2.7]) self.H.construct(func) self.HS = Hamiltonian(self.g, orthogonal=False) func = self.HS.create_construct([0.1, bond+0.1], [(0., 1.), (-2.7, 0.)]) self.HS.construct(func)
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])) assert g.no == 5 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() # Ensure sub and remove does the same for i in [0, a0]: spo_rem = spo.remove_orbital(i, 0) spo_sub = spo.sub_orbital(i, [1, 2]) assert spo_rem.spsame(spo_sub) spo_rem = spo.remove_orbital(i, [0, 2]) spo_sub = spo.sub_orbital(i, 1) assert spo_rem.spsame(spo_sub) spo_rem = spo.remove_orbital(i, 2) spo_sub = spo.sub_orbital(i, [0, 1]) assert spo_rem.spsame(spo_sub) spo_rem = spo.remove_orbital(i, a0[0]) spo_sub = spo.sub_orbital(i, [1, 2]) assert spo_rem.spsame(spo_sub) for i in [1, a1]: spo_rem = spo.remove_orbital(i, a1[0]) spo_sub = spo.sub_orbital(i, a1[1]) assert spo_rem.spsame(spo_sub) 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)
def read_geometry(self, species_Z=False): """ Returns a `Geometry` object from the STRUCT file Parameters ---------- species_Z : bool, optional if ``True`` the atomic numbers are the species indices (useful when reading the ChemicalSpeciesLabel block simultaneously). Returns ------- Geometry """ sc = self.read_supercell() # Read number of atoms na = int(self.readline()) xyz = np.empty([na, 3], np.float64) atms = [None] * na sp = np.empty([na], np.int32) for ia in range(na): line = self.readline().split() sp[ia] = int(line[0]) if species_Z: atms[ia] = Atom(sp[ia]) else: atms[ia] = Atom(int(line[1])) xyz[ia, :] = line[2:5] xyz = xyz @ sc.cell # Ensure correct sorting max_s = sp.max() sp -= 1 # Ensure we can remove the atom after having aligned them atms2 = Atoms(AtomUnknown(1000), na=na) for i in range(max_s): idx = (sp[:] == i).nonzero()[0] if len(idx) == 0: # Always ensure we have "something" for the unoccupied places atms2[idx] = AtomUnknown(1000 + i) else: atms2[idx] = atms[idx[0]] return Geometry(xyz, atms2.reduce(), sc=sc)
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)
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()
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)
def nanotube(bond, atom=None, chirality=(1, 1)): """ Create a nano-tube geometry This routine is implemented as in ``ASE`` with few changes. Parameters ---------- bond: float length between atoms in nano-tube atom: Atom(6) nanotube atoms chirality: (int, int) chirality of nanotube (n, m) """ if atom is None: atom = Atom[6] # Correct the input... n, m = chirality if n < m: m, n = n, m sign = -1 else: sign = 1 sq3 = 3.0 ** .5 a = sq3 * bond l2 = n * n + m * m + n * m l = l2 ** .5 def gcd(a, b): while a != 0: a, b = b % a, a return b nd = gcd(n, m) if (n - m) % (3 * nd) == 0: ndr = 3 * nd else: ndr = nd nr = (2 * m + n) // ndr ns = -(2 * n + m) // ndr nn = 2 * l2 // ndr ichk = 0 if nr == 0: n60 = 1 else: n60 = nr * 4 absn = abs(n60) nnp = [] nnq = [] for i in range(-absn, absn + 1): for j in range(-absn, absn + 1): j2 = nr * j - ns * i if j2 == 1: j1 = m * i - n * j if j1 > 0 and j1 < nn: ichk += 1 nnp.append(i) nnq.append(j) if ichk == 0: raise RuntimeError('not found p, q strange!!') if ichk >= 2: raise RuntimeError('more than 1 pair p, q strange!!') nnnp = nnp[0] nnnq = nnq[0] lp = nnnp * nnnp + nnnq * nnnq + nnnp * nnnq r = a * lp ** .5 c = a * l t = sq3 * c / ndr rs = c / (2.0 * np.pi) q1 = np.arctan((sq3 * m) / (2 * n + m)) q2 = np.arctan((sq3 * nnnq) / (2 * nnnp + nnnq)) q3 = q1 - q2 q4 = 2.0 * np.pi / nn q5 = bond * np.cos((np.pi / 6.0) - q1) / c * 2.0 * np.pi h1 = abs(t) / abs(np.sin(q3)) h2 = bond * np.sin((np.pi / 6.0) - q1) xyz = np.empty([nn*2, 3], np.float64) for i in range(nn): ix = i * 2 k = np.floor(i * abs(r) / h1) xyz[ix,0] = rs * np.cos(i * q4) xyz[ix,1] = rs * np.sin(i * q4) z = (i * abs(r) - k * h1) * np.sin(q3) kk2 = abs(np.floor((z + 0.0001) / t)) if z >= t - 0.0001: z -= t * kk2 elif z < 0: z += t * kk2 xyz[ix,2] = z * sign # Next ix += 1 xyz[ix, 0] = rs * np.cos(i * q4 + q5) xyz[ix, 1] = rs * np.sin(i * q4 + q5) z = (i * abs(r) - k * h1) * np.sin(q3) - h2 if z >= 0 and z < t: pass else: z -= h1 * np.sin(q3) kk = abs(np.floor(z / t)) if z >= t - 0.0001: z -= t * kk elif z < 0: z += t * kk xyz[ix, 2] = z * sign # Sort the atomic coordinates according to z idx = np.argsort(xyz[:,2]) xyz = xyz[idx,:] sc = SuperCell([rs * 4, rs * 4, t], nsc=[1,1,3]) geom = Geometry(xyz, atom, sc=sc) # Return a geometry with the first atom at (0,0,0) return geom.translate(-np.amin(geom.xyz, axis=0))
def ArgumentParser(self, *args, **kwargs): """ Returns the arguments that is available for this Sile """ newkw = Geometry._ArgumentParser_args_single() newkw.update(kwargs) return self.read_geom().ArgumentParser(*args, **newkw)