Source code for vayesta.misc.solids.solids

import numpy as np

SQRT2 = np.sqrt(2)


[docs]def bcc(atoms, a): """Body-centered cubic. Li: 3.51 A """ amat = a * np.eye(3) coords = a * np.asarray([[0, 0, 0], [1, 1, 1]]) / 2 atom = _make_atom(atoms, coords) return amat, atom
[docs]def diamond(atoms=["C", "C"], a=3.57): """Silicon: a=5.431 A""" amat = a * np.asarray([[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]) coords = a * np.asarray([[0, 0, 0], [1, 1, 1]]) / 4 atom = _make_atom(atoms, coords) return amat, atom
[docs]def graphene(atoms=["C", "C"], a=2.46, c=20.0): """ hBN: a=2.5A hBeO: a=2.68A (VASP)""" amat = np.asarray([[a, 0, 0], [a / 2, a * np.sqrt(3.0) / 2, 0], [0, 0, c]]) coords_internal = np.asarray([[2.0, 2.0, 3.0], [4.0, 4.0, 3.0]]) / 6 coords = np.dot(coords_internal, amat) atom = _make_atom(atoms, coords) return amat, atom
[docs]def graphite(atoms=["C", "C", "C", "C"], a=2.461, c=6.708): """a = 2.461 A , c = 6.708 A""" amat = np.asarray([[a / 2, -a * np.sqrt(3.0) / 2, 0], [a / 2, +a * np.sqrt(3.0) / 2, 0], [0, 0, c]]) coords_internal = np.asarray( [[0, 0, 1.0 / 4], [2.0 / 3, 1.0 / 3, 1.0 / 4], [0, 0, 3.0 / 4], [1.0 / 3, 2.0 / 3, 3.0 / 4]] ) coords = np.dot(coords_internal, amat) atom = _make_atom(atoms, coords) return amat, atom
[docs]def rocksalt(atoms=["Na", "Cl"], a=5.6402, unitcell="primitive"): """ LiH: a=4.0834 LiF: a=4.0351 """ if unitcell == "primitive": amat = a * np.asarray([[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]) internal = np.asarray([[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]) coords = np.dot(internal, amat) atom = _make_atom(atoms, coords) return amat, atom if unitcell == "primitive-af1": # wrong: # amat = a * np.asarray([ # [1/SQRT2, 0, 0], # [0, 1/SQRT2, 0], # [0, 0, 1]]) # internal = np.asarray([ # [0.0, 0.0, 0.0], # [0.5, 0.5, 0.0], # [0.0, 0.0, 0.5], # [0.5, 0.5, 0.5]]) # arXiv:2207.12064v1: amat = a * np.asarray([[0.5, 0, 0.5], [0.5, 0, -0.5], [0, 1, 0.0]]) coords = a / 2 * np.asarray([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]) atom = _make_atom(2 * atoms, coords) return amat, atom if unitcell == "primitive-af2": amat = a * np.asarray([[1.00, 0.50, 0.50], [0.50, 1.00, 0.50], [0.50, 0.50, 1.00]]) internal = np.asarray([[0.00, 0.00, 0.00], [0.25, 0.25, 0.25], [0.50, 0.50, 0.50], [0.75, 0.75, 0.75]]) coords = np.dot(internal, amat) atom = _make_atom(2 * atoms, coords) return amat, atom if unitcell == "cubic": amat = a * np.eye(3) internal = np.asarray( [ # Atom 1: [0, 0, 0], [0, 1 / 2, 1 / 2], [1 / 2, 0, 1 / 2], [1 / 2, 1 / 2, 0], # Atom 2: [0, 0, 1 / 2], [0, 1 / 2, 0], [1 / 2, 0, 0], [1 / 2, 1 / 2, 1 / 2], ] ) coords = np.dot(internal, amat) atom = _make_atom(4 * [atoms[0]] + 4 * [atoms[1]], coords) return amat, atom raise ValueError
[docs]def perovskite(atoms=["Sr", "Ti", "O"], a=3.905): if len(atoms) == 3: atoms = [atoms[0], atoms[1]] + 3 * [atoms[2]] amat = a * np.eye(3) coords = a * np.asarray([[0, 0, 0], [1 / 2, 1 / 2, 1 / 2], [0, 1 / 2, 1 / 2], [1 / 2, 0, 1 / 2], [1 / 2, 1 / 2, 0]]) atom = _make_atom(atoms, coords) return amat, atom
[docs]def perovskite_tetragonal(atoms=["Sr", "Ti", "O"], a=5.507, c=7.796, u=0.241): """This is the crystallographic ('quadruple') cell, not the primitive ('double') cell. Lattice constants from PHYSICAL REVIEW MATERIALS 2, 013807 (2018). DOI:10.1103/PhysRevMaterials.2.013807 becomes cubic with parameters: a = 5.522 A, c = 2a0 = 7.810 A , u = 0.25 (see DOI: 10.1103/PhysRevB.83.134108) """ if a is None: a = c / np.sqrt(2) if c is None: c = np.sqrt(2) * a if len(atoms) == 3: atoms = [atoms[0], atoms[1]] + 3 * [atoms[2]] if len(atoms) == 5: atoms = 4 * atoms amat = a * np.eye(3) amat[2, 2] = c # coords_internal = a*np.asarray([ # [0 , 0.5 , 0.25], # Sr # [0.5 , 0 , 0.75], # Sr # [0.5 , 0 , 0.25], # Sr # [0 , 0.5 , 0.75], # Sr # [0 , 0 , 0], # Ti # [0.5 , 0.5 , 0.5], # Ti # [0 , 0 , 0.5], # Ti # [0.5 , 0.5 , 0], # Ti # [0 , 0 , 0.25], # O (4a) # [0.5 , 0.5 , 0.75], # O (4a) # [0 , 0 , 0.75], # O (4a) # [0.5 , 0.5 , 0.25], # O (4a) # [u , 0.5+u , 0], # O # [0.5+u , u , 0.5], # O # [-u , 0.5-u , 0], # O # [0.5-u , -u , 0.5], # O # [0.5-u , u , 0], # O # [-u , 0.5+u , 0.5], # O # [0.5+u , -u , 0], # O # [u , 0.5-u , 0.5], # O # ]) # Order? coords_internal = np.asarray( [ [0, 0.5, 0.25], # Sr [0, 0, 0], # Ti [0, 0, 0.25], # O (4a) [u, 0.5 + u, 0], # O [0.5 + u, u, 0.5], # O [0.5, 0, 0.75], # Sr [0.5, 0.5, 0.5], # Ti [0.5, 0.5, 0.75], # O (4a) [-u, 0.5 - u, 0], # O [0.5 - u, -u, 0.5], # O [0.5, 0, 0.25], # Sr [0, 0, 0.5], # Ti [0, 0, 0.75], # O (4a) [0.5 - u, u, 0], # O [-u, 0.5 + u, 0.5], # O [0, 0.5, 0.75], # Sr [0.5, 0.5, 0], # Ti [0.5, 0.5, 0.25], # O (4a) [0.5 + u, -u, 0], # O [u, 0.5 - u, 0.5], # O ] ) coords = np.dot(coords_internal, amat) atom = _make_atom(atoms, coords) return amat, atom
def _make_atom(atoms, coords): atom = [] for i in range(len(atoms)): if atoms[i] is not None: atom.append([atoms[i], coords[i]]) return atom