def test_zeta_Z_deprecate(self): rf = r_f(6) r = np.linspace(0, 6, 999).reshape(-1, 3) o = AtomicOrbital(l=1, m=1, spherical=rf) with pytest.deprecated_call(): assert o.Z == o.zeta with pytest.deprecated_call(): o = AtomicOrbital(l=1, m=1, spherical=rf, Z=1)
def test_phi1(self): rf = r_f(6) r = np.linspace(0, 6, 999).reshape(-1, 3) for l in range(5): so = SphericalOrbital(l, rf) for m in range(-l, l + 1): o = AtomicOrbital(l=l, m=m, spherical=rf) assert np.allclose(so.psi(r, m), o.psi(r))
def test_init4(self): rf = r_f(6) o1 = AtomicOrbital(2, 1, 0, 1, True, rf) o2 = AtomicOrbital('pzP', rf) o3 = AtomicOrbital('pzZP', rf) o4 = AtomicOrbital('pzZ1P', rf) o5 = AtomicOrbital('2pzZ1P', rf) assert o1 == o2 assert o1 == o3 assert o1 == o4 assert o1 == o5
def test_pickle1(self): import pickle as p rf = r_f(6) o0 = AtomicOrbital(2, 1, 0, 1, True, rf, tag='hello', q0=1.) o1 = AtomicOrbital(l=1, m=0, Z=1, P=False, spherical=rf) p0 = p.dumps(o0) p1 = p.dumps(o1) l0 = p.loads(p0) l1 = p.loads(p1) assert o0 == l0 assert o1 == l1 assert o0 != l1 assert o1 != l0
def test_radial1(self): rf = r_f(6) r = np.linspace(0, 6, 100) for l in range(5): so = SphericalOrbital(l, rf) sor = so.radial(r) for m in range(-l, l + 1): o = AtomicOrbital(l=l, m=m, spherical=rf) assert np.allclose(sor, o.radial(r)) o.set_radial(rf[0], rf[1]) assert np.allclose(sor, o.radial(r))
def test_init1(self): rf = r_f(6) a = [] a.append(AtomicOrbital(2, 1, 0, 1, True, rf)) a.append(AtomicOrbital(l=1, m=0, Z=1, P=True, spherical=rf)) f = interp.interp1d(rf[0], rf[1], fill_value=(0., 0.), bounds_error=False, kind='cubic') a.append(AtomicOrbital(l=1, m=0, Z=1, P=True, spherical=f)) a.append(AtomicOrbital('pzP', f)) a.append(AtomicOrbital('pzP', rf)) a.append(AtomicOrbital('2pzP', rf)) for i in range(len(a) - 1): for j in range(i+1, len(a)): assert a[i] == a[j] and a[i].equal(a[j], psi=True, radial=True)
def read_data(self, as_dataarray=False): r""" Returns data associated with the PDOS file For spin-polarized calculations the returned values are up/down, orbitals, energy. For non-collinear calculations the returned values are sum/x/y/z, orbitals, energy. Parameters ---------- as_dataarray: bool, optional If True the returned PDOS is a `xarray.DataArray` with energy, spin and orbital information as coordinates in the data. The geometry, unit and Fermi level are stored as attributes in the DataArray. Returns ------- geom : Geometry instance with positions, atoms and orbitals. The orbitals of these atoms are `AtomicOrbital` instances. E : the energies at which the PDOS has been evaluated at (if the Fermi-level is present the energies are shifted to :math:`E - E_F = 0`, this will *only* be done from Siesta 4.0.2 and later). PDOS : an array of DOS, for non-polarized calculations it has dimension ``(atom.no, len(E))``, else it has dimension ``(nspin, atom.no, len(E))``. DataArray : if `as_dataarray` is True, only this data array is returned, in this case all data can be post-processed using the `xarray` selection routines. """ # Get the element-tree ET = ElementTree('pdos', self.file) root = ET.getroot() # Get number of orbitals nspin = int(root.find('nspin').text) # Try and find the fermi-level Ef = root.find('fermi_energy') E = arrayd(list(map(float, root.find('energy_values').text.split()))) if Ef is not None: Ef = float(Ef.text) E -= Ef ne = len(E) # All coordinate, atoms and species data xyz = [] atoms = [] atom_species = [] def ensure_size(ia): while len(atom_species) <= ia: atom_species.append(None) xyz.append(None) def ensure_size_orb(ia, i): while len(atoms) <= ia: atoms.append([]) while len(atoms[ia]) <= i: atoms[ia].append(None) if nspin == 4: def process(D): tmp = np.empty(D.shape[0], D.dtype) tmp[:] = D[:, 3] D[:, 3] = D[:, 0] - D[:, 1] D[:, 0] = D[:, 0] + D[:, 1] D[:, 1] = D[:, 2] D[:, 2] = tmp[:] return D else: def process(D): return D if as_dataarray: import xarray as xr if nspin == 1: spin = ['sum'] elif nspin == 2: spin = ['up', 'down'] elif nspin == 4: spin = ['sum', 'x', 'y' 'z'] # Dimensions of the PDOS data-array dims = ['E', 'spin', 'n', 'l', 'm', 'zeta', 'polarization'] shape = (ne, nspin, 1, 1, 1, 1, 1) def to(o, DOS): # Coordinates for this dataarray coords = [E, spin, [o.n], [o.l], [o.m], [o.Z], [o.P]] return xr.DataArray(data=process(DOS).reshape(shape), dims=dims, coords=coords, name='PDOS') else: def to(o, DOS): return process(DOS) D = [] for orb in root.findall('orbital'): # Short-hand function to retrieve integers for the attributes def oi(name): return int(orb.get(name)) # Get indices ia = oi('atom_index') - 1 i = oi('index') - 1 species = orb.get('species') # Create the atomic orbital try: Z = oi('Z') except: try: Z = PeriodicTable().Z(species) except: # Unknown Z = -1 try: P = orb.get('P') == 'true' except: P = False ensure_size(ia) xyz[ia] = list(map(float, orb.get('position').split())) atom_species[ia] = Z # Construct the atomic orbital O = AtomicOrbital(n=oi('n'), l=oi('l'), m=oi('m'), Z=oi('z'), P=P) # We know that the index is far too high. However, # this ensures a consecutive orbital ensure_size_orb(ia, i) atoms[ia][i] = O # it is formed like : spin-1, spin-2 (however already in eV) DOS = arrayd(list(map(float, orb.find('data').text.split()))).reshape( -1, nspin) if as_dataarray: if len(D) == 0: D = to(O, DOS) else: D = D.combine_first(to(O, DOS)) else: D.append(process(DOS)) # Now we need to parse the data # First reduce the atom atoms = [[o for o in a if o] for a in atoms] atoms = Atoms([Atom(Z, os) for Z, os in zip(atom_species, atoms)]) geom = Geometry(arrayd(xyz) * Bohr2Ang, atoms) if as_dataarray: # Add attributes D.attrs['geometry'] = geom D.attrs['units'] = '1/eV' if Ef is None: D.attrs['Ef'] = 'Unknown' else: D.attrs['Ef'] = Ef return D return geom, E, np.moveaxis(np.stack(D, axis=0), 2, 0)
def test_init5(self): with pytest.raises(ValueError): AtomicOrbital(5, 5, 0)
def test_init3(self): rf = r_f(6) for l in range(5): a = AtomicOrbital(l=l, m=0, spherical=rf) a.name() a.name(True) str(a) a = AtomicOrbital(l=l, m=0, P=True, spherical=rf, tag='hello') a.name() a.name(True) str(a)
def test_init2(self): assert AtomicOrbital('pzP') == AtomicOrbital(n=2, l=1, m=0, P=True)
def test_init5(self): AtomicOrbital(5, 5, 0)
def test_init2(self): AtomicOrbital('pzP')
def test_zeta_Z_deprecate(self): rf = r_f(6) r = np.linspace(0, 6, 999).reshape(-1, 3) o = AtomicOrbital(l=1, m=1, spherical=rf) assert o.Z == o.zeta