Source code for pyscal.crystal_structures

"""
pyscal module for creating crystal structures.
"""

import numpy as np
import warnings
import os
from functools import partial
from functools import update_wrapper


from pyscal.attributes import read_yaml
from pyscal.core import System
from pyscal.structure_creator import make_crystal

structures = read_yaml(os.path.join(os.path.dirname(__file__), "data/structure_data.yaml"))
elements = read_yaml(os.path.join(os.path.dirname(__file__), "data/element_data.yaml"))


#wrapper methods
[docs]def structure_creator(structure, lattice_constant = 1.00, repetitions = None, ca_ratio = 1.633, noise = 0, element=None): """ Create a crystal structure and return it as a System object. Parameters ---------- structure : {'sc', 'bcc', 'fcc', 'hcp', 'diamond', 'a15' or 'l12'} type of the crystal structure lattice_constant : float, optional lattice constant of the crystal structure, default 1 repetitions : list of ints of len 3, optional of type `[nx, ny, nz]`, repetions of the unit cell in x, y and z directions. default `[1, 1, 1]`. ca_ratio : float, optional ratio of c/a for hcp structures, default 1.633 noise : float, optional If provided add normally distributed noise with standard deviation `noise` to the atomic positions. element : string, optional The chemical element Returns ------- System: pyscal System system will be populated with given atoms and simulation box Examples -------- >>> sys = structure_creator('bcc', lattice_constant=3.48, repetitions=[2,2,2]) """ return System.from_structure(structure, lattice_constant=lattice_constant, repetitions=repetitions, ca_ratio=ca_ratio, noise=noise, element=element)
[docs]class Structure: """ A class for structure creation Attributes ---------- element: create elementary structures lattice: create structures by specifying lattice """
[docs] def __init__(self): #create by element name self.element = ElementCreator(elements) #create by lattice name self.lattice = LatticeCreator(structures) #create a general structure self.custom = general_lattice #complete dict self._structure_dict = structures
[docs] def structure_dict(self, structure): return self._structure_dict[structure]
[docs]class ElementCreator: """ Create an elementary structure """
[docs] def __init__(self, element_dict): self._element_dict = element_dict
def __dir__(self): return list(self._element_dict.keys()) def __getattr__(self, key): #this is the element based creater if key in self._element_dict.keys(): structure = self._element_dict[key]['structure'] pfunc = partial(structure_creator, structure, lattice_constant=self._element_dict[key]['lattice_constant'], element = key) update_wrapper(pfunc, structure_creator) return pfunc
[docs]class LatticeCreator(ElementCreator): """ Create a lattice """ def __getattr__(self, key): if key in self._element_dict.keys(): pfunc = partial(structure_creator, key) update_wrapper(pfunc, structure_creator) return pfunc
#general structure creator
[docs]def general_lattice(species, positions, scaling_factors=[1.0, 1.0, 1.0], lattice_constant = 1.00, repetitions = None, noise = 0, element=None): """ Create a general lattice structure. species: list list of per-atom species positions: list of relative positions positions of reach atom (between 0-1) scaling_fractors: factors with which the unit cell should be scaled, for example hcp could have [1,1.73, 1.63]. Default [1,1,1] lattice_constant : float, optional lattice constant of the crystal structure, default 1 repetitions : list of ints of len 3, optional of type `[nx, ny, nz]`, repetions of the unit cell in x, y and z directions. default `[1, 1, 1]`. noise : float, optional If provided add normally distributed noise with standard deviation `noise` to the atomic positions. element : string, optional The chemical element """ if not (len(species) == len(positions)): raise ValueError("Species and positions should have same length!") sdict = {"custom": {"natoms": len(positions), "species": species, "scaling_factors": scaling_factors, "positions": positions} } atoms, box = make_crystal("custom", lattice_constant=lattice_constant, repetitions=repetitions, noise=noise, element=element, structures=sdict) sys = System() sys.box = box sys.atoms = atoms sys.atoms._lattice = None sys.atoms._lattice_constant = lattice_constant sys._structure_dict = sdict["custom"] return sys