[docs]defcompare_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.atomsvols=[]vors=[]foratominatoms:ifatom.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=Falseif(len(vvx)!=len(vrx)):warnings.warn("Different voronoi polyhedra with same volume! Fingerprint wont be printed. Maybe change precision?")length_mismatch=Trueifprecision>3:warnings.warn("More than 3 digits of precision selected!")ifprint_results:print("%d clusters found"%len(vvx))ifnotlength_mismatch:foriinrange(len(vvx)):print("voro fingerprint = <%s>, vol = %.3f, counts = %d"%(vrx[i],vvx[i],vvc[i]))else:foriinrange(len(vvx)):print("voro fingerprint = <x x x x>, vol = %.3f, counts = %d"%(vvx[i],vvc[i]))ifreturn_system:returnsyselse:ifreturn_system:returnnp.array([vvx,vrx,vvc]),syselse:returnnp.array([vvx,vrx,vvc])
[docs]deffind_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.atomsvolumes=[]pos=[]types=[]box=sys.boxboxx=box[0][1]-box[0][0]boxy=box[1][1]-box[1][0]boxz=box[2][1]-box[2][0]iflen(atoms)<21:warnings.warn("Very less number of atoms, results maybe wrong. See https://github.com/srmnitc/pyscal/issues/63 ")foratominatoms:ifatom.vorovector[1]==4:#first to prevent small cells we need to filterneighs=np.unique(atom.neighbors)dists=np.array([sys.get_distance(atom,atoms[x])forxinneighs])mindist=dists[np.argsort(dists)][0]mindistcount=0foriinrange(len(dists)):ifmindist*(1.0-precision)<=dists[i]<=mindist*(1.0+precision):mindistcount+=1ifmindistcount==4:volumes.append(atom.volume)ifdirect_coordinates:p=atom.pospos.append([p[0]/boxx,p[1]/boxy,p[2]/boxz])else:pos.append(atom.pos)types.append(atom.type)ifprint_results:iflen(volumes)>0:print("%d atoms found in tetrahedral position"%len(volumes))foriinrange(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")ifreturn_system:returntypes,volumes,pos,syselse:returntypes,volumes,pos