Source code for pyscal.misc

import pyscal.core as pc
import numpy as np
import warnings

[docs] def compare_atomic_env(infile, atomtype=2, precision=2, format="poscar", print_results=True, return_system=False): """ Compare the atomic environment of given types of atoms in the inputfile. The comparison is made in terms of Voronoi volume and Voronoi fingerprint. Parameters ---------- infile : string name of the inputfile atomtype: int, optional type of the atom default 2 precision: float, optional precision for comparing Voronoi volumes default 3 format: string, optional format of the input file default poscar print_results: bool, optional if True, print the results. If False, return the data instead. default True return_system: bool, optional if True, return the system object. default False Returns ------- vvx : list of floats unique Voronoi volumes. Returned only if print results is False vrx : list of strings unique Voronoi polyhedra. Returned only if print results is False vvc : list of ints number of unique quantities specified above. Returned only if print results is False """ sys = pc.System() sys.read_inputfile(infile, format=format) sys.find_neighbors(method="voronoi") sys.calculate_vorovector() atoms = sys.atoms vols = [] vors = [] for atom in atoms: if atom.type == atomtype: vols.append(atom.volume) vors.append(" ".join(np.array(atom.vorovector).astype(str))) vols = np.array(vols) vols = np.round(vols, decimals=precision) vvx, vvc = np.unique(vols, return_counts=True) vrx, vrc = np.unique(vors, return_counts=True) length_mismatch = False if (len(vvx) != len(vrx)): warnings.warn("Different voronoi polyhedra with same volume! Fingerprint wont be printed. Maybe change precision?") length_mismatch = True if precision > 3: warnings.warn("More than 3 digits of precision selected!") if print_results: print("%d clusters found"%len(vvx)) if not length_mismatch: for i in range(len(vvx)): print("voro fingerprint = <%s>, vol = %.3f, counts = %d"%(vrx[i], vvx[i], vvc[i])) else: for i in range(len(vvx)): print("voro fingerprint = <x x x x>, vol = %.3f, counts = %d"%(vvx[i], vvc[i])) if return_system: return sys else: if return_system: return np.array([vvx, vrx, vvc]), sys else: return np.array([vvx, vrx, vvc])
[docs] def find_tetrahedral_voids(infile, format="poscar", print_results=True, return_system=False, direct_coordinates=True, precision=0.1): """ Check for tetrahedral voids in the system Parameters ---------- infile : string name of the input file format : string format of the input file, optional default poscar print_results: bool, optional if True, print the results. If False, return the data instead. default True return_system: bool, optional if True, return the system object. default False direct_coordinates: bool, optional if True, results are provided in direct coordinates default False precision: int, optional the number of digits to check for distances. default 1 Returns ------- types : list of atom types volumes : list of atom volumes pos : list of atom positions sys : system object, returns only if return_sys is True """ sys = pc.System() sys.read_inputfile(infile, format=format) sys.find_neighbors(method="voronoi") sys.calculate_vorovector() atoms = sys.atoms volumes = [] pos = [] types = [] box = sys.box boxx = box[0][1] - box[0][0] boxy = box[1][1] - box[1][0] boxz = box[2][1] - box[2][0] if len(atoms) < 21: warnings.warn("Very less number of atoms, results maybe wrong. See https://github.com/srmnitc/pyscal/issues/63 ") for atom in atoms: if atom.vorovector[1] == 4: #first to prevent small cells we need to filter neighs = np.unique(atom.neighbors) dists = np.array([sys.get_distance(atom, atoms[x]) for x in neighs]) mindist = dists[np.argsort(dists)][0] mindistcount = 0 for i in range(len(dists)): if mindist*(1.0-precision) <= dists[i] <= mindist*(1.0+precision): mindistcount += 1 if mindistcount == 4: volumes.append(atom.volume) if direct_coordinates: p = atom.pos pos.append([p[0]/boxx, p[1]/boxy, p[2]/boxz]) else: pos.append(atom.pos) types.append(atom.type) if print_results: if len(volumes) > 0: print("%d atoms found in tetrahedral position"%len(volumes)) for i in range(len(volumes)): print("%d volume %f type %d at %f, %f, %f"%(i+1, volumes[i], types[i], pos[i][0], pos[i][1], pos[i][2])) else: print("no atoms found in tetrahedral position") if return_system: return types, volumes, pos, sys else: return types, volumes, pos