def str_template(name, scale, cell): from pylada.crystal import Structure structure = Structure() structure.name = name structure.scale = scale structure.cell = cell return structure
def test_system(): from pylada.crystal import Structure from pylada.vasp import Vasp a = Vasp() b = Structure() assert a.system is None assert a._input['system'].keyword == 'system' assert a._input['system'].output_map(vasp=a, structure=b) is None a.system = 'system' assert a.system == 'system' assert 'system' in a._input['system'].output_map(vasp=a, structure=b) assert a._input['system'].output_map(vasp=a, structure=b)['system'] == 'system' b.name = 'hello' assert 'system' in a._input['system'].output_map(vasp=a, structure=b) assert a._input['system'].output_map( vasp=a, structure=b)['system'] == 'system: hello' a.system = None assert a.system is None assert 'system' in a._input['system'].output_map(vasp=a, structure=b) assert a._input['system'].output_map(vasp=a, structure=b)['system'] == 'hello' a.system = None assert a.system is None assert 'system' in a._input['system'].output_map(vasp=a, structure=b) assert a._input['system'].output_map(vasp=a, structure=b)['system'] == 'hello'
def test_system(): from pylada.crystal import Structure from pylada.vasp import Vasp a = Vasp() b = Structure() assert a.system is None assert a._input['system'].keyword == 'system' assert a._input['system'].output_map(vasp=a, structure=b) is None a.system = 'system' assert a.system == 'system' assert 'system' in a._input['system'].output_map(vasp=a, structure=b) assert a._input['system'].output_map(vasp=a, structure=b)['system'] == 'system' b.name = 'hello' assert 'system' in a._input['system'].output_map(vasp=a, structure=b) assert a._input['system'].output_map(vasp=a, structure=b)['system'] == 'system: hello' a.system = None assert a.system is None assert 'system' in a._input['system'].output_map(vasp=a, structure=b) assert a._input['system'].output_map(vasp=a, structure=b)['system'] == 'hello' a.system = None assert a.system is None assert 'system' in a._input['system'].output_map(vasp=a, structure=b) assert a._input['system'].output_map(vasp=a, structure=b)['system'] == 'hello'
structure = Structure() structure.set_cell = (4, 0, 0.5),\ (0, 1, 0),\ (0, 0, 0.5) structure = fill_structure(structure.cell) for i, atom in enumerate(structure.atoms): atom.type = "Si" if i < len(structure.atoms)/2 else "Ge" result_str = Structure() result_str.scale = 5.450000e+00 result_str.set_cell = (4.068890e+00, -4.235770e-18, 5.083297e-01),\ (-1.694308e-17, 1.016103e+00, 2.238072e-18),\ (-2.252168e-03, 8.711913e-18, 5.083297e-01) result_str.weight = 1.000000e+00 result_str.name = "" result_str.energy = 0.0938967086716 result_str.add_atom = (0.000000e+00, 0.000000e+00, 0.000000e+00), "Si", 0, 0 result_str.add_atom = (2.541649e-01, 2.473273e-01, 2.541649e-01), "Si", 1, 0 result_str.add_atom = (3.567265e+00, 5.062000e-01, -8.956567e-03), "Si", 0, 0 result_str.add_atom = (3.821430e+00, 7.572301e-01, 2.452083e-01), "Si", 1, 0 result_str.add_atom = (3.065136e+00, -1.851371e-03, -1.515736e-02), "Si", 0, 0 result_str.add_atom = (3.319301e+00, 2.491787e-01, 2.390075e-01), "Si", 1, 0 result_str.add_atom = (2.563510e+00, 5.080514e-01, -2.186176e-02), "Si", 0, 0 result_str.add_atom = (2.817675e+00, 7.553787e-01, 2.323031e-01), "Si", 1, 0 result_str.add_atom = (2.055673e+00, -6.642716e-03, -2.235452e-02), "Ge", 0, 0 result_str.add_atom = (2.309838e+00, 2.539701e-01, 2.318104e-01), "Ge", 1, 0 result_str.add_atom = (1.539450e+00, 5.026981e-01, -1.446032e-02), "Ge", 0, 0 result_str.add_atom = (1.793614e+00, 7.607320e-01, 2.397046e-01), "Ge", 1, 0 result_str.add_atom = (1.024061e+00, -5.353269e-03, -7.401445e-03), "Ge", 0, 0 result_str.add_atom = (1.278226e+00, 2.526806e-01, 2.467634e-01), "Ge", 1, 0
def poscar(path="POSCAR", types=None): """ Tries to read a VASP POSCAR file. :param path: Path to the POSCAR file. Can also be an object with file-like behavior. :type path: str or file object :param types: Species in the POSCAR. :type types: None or sequence of str :return: `pylada.crystal.Structure` instance. """ import re from os.path import join, exists, isdir from copy import deepcopy from numpy import array, dot, transpose from numpy.linalg import det from quantities import angstrom from . import Structure from .. import error # if types is not none, converts to a list of strings. if types is not None: if isinstance(types, str): types = [types] # can't see another way of doing this... elif not hasattr(types, "__iter__"): types = [str(types)] # single lone vasp.specie.Specie else: types = [str(s) for s in types] if path is None: path = "POSCAR" if not hasattr(path, 'read'): assert exists(path), IOError("Could not find path %s." % (path)) if isdir(path): assert exists(join(path, "POSCAR")), IOError("Could not find POSCAR in %s." % (path)) path = join(path, "POSCAR") result = Structure() poscar = path if hasattr(path, "read") else open(path, 'r') try: # gets name of structure result.name = poscar.readline().strip() if len(result.name) > 0 and result.name[0] == "#": result.name = result.name[1:].strip() # reads scale scale = float(poscar.readline().split()[0]) # gets cell vectors. cell = [] for i in range(3): line = poscar.readline() assert len(line.split()) >= 3,\ RuntimeError("Could not read column vector from poscar: %s." % (line)) cell.append([float(f) for f in line.split()[:3]]) result.cell = transpose(array(cell)) vol = det(cell) if scale < 1.E-8: scale = abs(scale / vol) ** (1.0 / 3) print(result) print(scale) result.scale = scale * angstrom # checks for vasp 5 input. is_vasp_5 = True line = poscar.readline().split() for i in line: if not re.match(r"[A-Z][a-z]?", i): is_vasp_5 = False break if is_vasp_5: text_types = deepcopy(line) if types is not None and not set(text_types).issubset(set(types)): raise error.ValueError("Unknown species in poscar: {0} not in {1}." .format(text_types, types)) types = text_types line = poscar.readline().split() if types is None: raise RuntimeError("No atomic species given in POSCAR or input.") # checks/reads for number of each specie if len(types) < len(line): raise RuntimeError("Too many atomic species in POSCAR.") nb_atoms = [int(u) for u in line] # Check whether selective dynamics, cartesian, or direct. first_char = poscar.readline().strip().lower()[0] selective_dynamics = False if first_char == 's': selective_dynamics = True first_char = poscar.readline().strip().lower()[0] # Checks whether cartesian or direct. is_direct = first_char not in ['c', 'k'] # reads atoms. for n, specie in zip(nb_atoms, types): for i in range(n): line = poscar.readline().split() pos = array([float(u) for u in line[:3]], dtype="float64") if is_direct: pos = dot(result.cell, pos) result.add_atom(pos=pos, type=specie) if selective_dynamics: for which, freeze in zip(line[3:], ['x', 'y', 'z']): if which.lower()[0] == 't': result[-1].freeze = getattr(result[-1], 'freeze', '') + freeze finally: poscar.close() return result
def poscar(path="POSCAR", types=None): """ Tries to read a VASP POSCAR file. :param path: Path to the POSCAR file. Can also be an object with file-like behavior. :type path: str or file object :param types: Species in the POSCAR. :type types: None or sequence of str :return: `pylada.crystal.Structure` instance. """ import re from os.path import join, exists, isdir from copy import deepcopy from numpy import array, dot, transpose from numpy.linalg import det from quantities import angstrom from . import Structure # if types is not none, converts to a list of strings. if types is not None: if isinstance(types, str): types = [types] # can't see another way of doing this... elif not hasattr(types, "__iter__"): types = [str(types)] # single lone vasp.specie.Specie else: types = [str(s) for s in types] if path is None: path = "POSCAR" if not hasattr(path, 'read'): assert exists(path), IOError("Could not find path %s." % (path)) if isdir(path): assert exists(join(path, "POSCAR")), IOError("Could not find POSCAR in %s." % (path)) path = join(path, "POSCAR") result = Structure() poscar = path if hasattr(path, "read") else open(path, 'r') try: # gets name of structure result.name = poscar.readline().strip() if len(result.name) > 0: if result.name[0] == "#": result.name = result.name[1:].strip() # reads scale scale = float(poscar.readline().split()[0]) # gets cell vectors. cell = [] for i in range(3): line = poscar.readline() assert len(line.split()) >= 3,\ RuntimeError("Could not read column vector from poscar: %s." % (line)) cell.append( [float(f) for f in line.split()[:3]] ) result.cell = transpose(array(cell)) vol = det(cell) if scale < 1.E-8 : scale = abs(scale/vol) **(1.0/3) result.scale = scale * angstrom # checks for vasp 5 input. is_vasp_5 = True line = poscar.readline().split() for i in line: if not re.match(r"[A-Z][a-z]?", i): is_vasp_5 = False break if is_vasp_5: text_types = deepcopy(line) if types is not None and not set(text_types).issubset(set(types)): raise RuntimeError( "Unknown species in poscar: {0} not in {1}."\ .format(text_types, types) ) types = text_types line = poscar.readline().split() assert types is not None, RuntimeError("No atomic species given in POSCAR or input.") # checks/reads for number of each specie assert len(types) >= len(line), RuntimeError("Too many atomic species in POSCAR.") nb_atoms = [int(u) for u in line] # Check whether selective dynamics, cartesian, or direct. first_char = poscar.readline().strip().lower()[0] selective_dynamics = False if first_char == 's': selective_dynamics = True first_char = poscar.readline().strip().lower()[0] # Checks whether cartesian or direct. is_direct = first_char not in ['c', 'k'] # reads atoms. for n, specie in zip(nb_atoms, types): for i in range(n): line = poscar.readline().split() pos = array([float(u) for u in line[:3]], dtype="float64") if is_direct: pos = dot(result.cell, pos) result.add_atom(pos=pos, type=specie) if selective_dynamics: for which, freeze in zip(line[3:], ['x', 'y', 'z']): if which.lower()[0] == 't': result[-1].freeze = getattr(result[-1], 'freeze', '') + freeze finally: poscar.close() return result
# Structure definition. from pylada.crystal import Structure from pylada.crystal.defects import third_order_charge_correction from quantities import eV structure = Structure() structure.name = 'Ga2CdO4: b5' structure.scale = 1.0 structure.energy = -75.497933000000003 structure.weight = 1.0 structure.set_cell = (-0.0001445, 4.3538020, 4.3537935),\ (4.3538700, -0.0001445, 4.3538615),\ (4.3538020, 4.3537935, -0.0001445) structure.add_atoms = [(7.61911540668, 7.61923876219, 7.61912846850), 'Cd'],\ [(1.08833559332, 1.08834823781, 1.08832253150), 'Cd'],\ [(4.35372550000, 4.35379350000, 4.35372550000), 'Ga'],\ [(4.35379775000, 2.17685850000, 2.17682450000), 'Ga'],\ [(2.17682450000, 4.35386575000, 2.17682875000), 'Ga'],\ [(2.17682875000, 2.17686275000, 4.35379775000), 'Ga'],\ [(2.32881212361, 2.32884849688, 2.32881647755), 'O'],\ [(2.32887187256, 4.20174404476, 4.20169148188), 'O'],\ [(4.20168277385, 2.32891695560, 4.20168347161), 'O'],\ [(4.20168782554, 4.20174474241, 2.32887622633), 'O'],\ [(6.37863887654, 6.37873414925, 6.37863016865), 'O'],\ [(6.37857477364, 4.50584295539, 4.50575516433), 'O'],\ [(4.50576822615, 6.37867004441, 4.50576752839), 'O'],\ [(4.50576317445, 4.50584225759, 6.37857477367), 'O'] # this is converged to less than 1meV third = third_order_charge_correction(structure, epsilon=10.0, n=20) assert abs(third - 0.11708438633232088*eV) < 1e-12