def deltaShannonCrystalRadii(picklestruct): ''' same as above function but ysing crystal radius instead of ionic radius :param picklestruct: :return: ''' initialVol = picklestruct.volume deltaVolList = list() for site in picklestruct.sites: elem = site.specie.value if (elem not in ShannonData.keys()): continue ShannonPoint = ShannonData[elem] maxSeen = 0 minSeen = float('Inf') for dictionary in ShannonPoint: rad = dictionary['crystal_radius'] if (rad > maxSeen): maxSeen = rad if (rad < minSeen): minSeen = rad deltaVol = ch.sphereVol(maxSeen) - ch.sphereVol(minSeen) deltaVolList.append(deltaVol) #scale devltaVolList deltaVolList = deltaVolList / (initialVol)**(1 / 3) if (len(deltaVolList) == 0): deltaVolList = [0] data = {'deltacrystal1': np.mean(deltaVolList), 'deltacrystal2': np.std(deltaVolList), 'deltacrystal3': np.min(deltaVolList),\ 'deltacrystal4': np.max(deltaVolList)} return data
def VolumeFlexibilityByShannonRadii(picklestruct): #change in volume when anion charge state is modified ''' :param picklestruct: :return: ''' startVol = VolumeByShannonRadii(picklestruct) startVol = startVol['ShannonRadii'] TotDeltaVol = 0 for site in picklestruct.sites: elem = site.specie.value if not hasattr(elem, 'coordination_no'): continue coordin_no = site.coordination_no if (elem not in ShannonData.keys()): continue ShannonPoint = ShannonData[elem] deltaVol = 0 if (sh.isAnion(ShannonPoint) == True): originalRad = sh.getIonicRadiusWithCoordination( ShannonPoint, coordin_no) originalOx = sh.getOxNumbGivenCoordination(ShannonPoint, coordin_no) newRad = sh.getIonicRadGivenOx(ShannonPoint, originalOx - 1) if (newRad == None): newRad = originalRad deltaVol = ch.sphereVol(originalRad) - ch.sphereVol(newRad) TotDeltaVol += deltaVol data = { 'volumeshannonflex': TotDeltaVol / startVol } return data
def deltaShannonRadii(picklestruct): ''' will not fail :param picklestruct: :return: ''' initialVol = picklestruct.volume deltaVolList = list() for site in picklestruct.sites: elem = site.specie.value if (elem not in ShannonData.keys()): continue ShannonPoint = ShannonData[elem] maxSeen = 0 minSeen = float('Inf') for dictionary in ShannonPoint: rad = dictionary['ionic_radius'] if (rad > maxSeen): maxSeen = rad if (rad < minSeen): minSeen = rad deltaVol = ch.sphereVol(maxSeen) - ch.sphereVol(minSeen) deltaVolList.append(deltaVol) deltaVolList = deltaVolList / (initialVol)**(1 / 3) if (len(deltaVolList) == 0): deltaVolList = [0] data = {'deltaShannon': np.mean(deltaVolList), 'deltaShannonstd': np.std(deltaVolList), \ 'deltashannonmin':np.min(deltaVolList), \ 'deltashannonmax':np.max(deltaVolList)} return data
def ionicityOfLattice(picklestruct): # AS a general rule, ionic bonds are stronger than covalent bonds # perhaps materials with more ionic bonds tend to resist lithium intercalation more r = 4 # four angstroms is a very good motivation for bond length (though this will overestimate small bonds) # we have to scale r as we play with fractional coordinates ''' we will compare nearest neighbors to see how much ionic contrast there is between elements... ''' #initialvol = picklestruct.volume; originalcell = copy.copy(picklestruct) ionicCount = list() ## iterate through the original cell for site in originalcell.sites: elementElectroneg = site.specie.X sitecoord = site.coords subcount = list() subionicity = list() neighborsArray = originalcell.get_neighbors(site, r) ionic = 0 for siteneighbor in neighborsArray: neighborElectroneg = siteneighbor[0].specie.X neighborcoord = siteneighbor[0].frac_coords # we should use fractional coordinates here... dist = ch.getDist(neighborcoord, sitecoord) if (abs(elementElectroneg - neighborElectroneg) > 2): ionic += 1 subionicity.append(abs(elementElectroneg - neighborElectroneg)) #seems like it would be natural to normalize ionicCount.append(ionic) data = { 'ioniccount': np.mean(ionicCount), 'ionicitymean': np.mean(subionicity) } return data
def getLiVolumeFraction(pickleStruct): LiVol = 0; TotVol = 0; for sites in pickleStruct: vol = ch.sphereVol(sites.specie.average_ionic_radius) if(sites.specie.name == 'Li'): LiVol += vol; TotVol += vol; return LiVol/TotVol; #this is like number of atoms normalized by volume fraction
def VolumeByAvgIonicRadius(pickleStruct): volume = pickleStruct.volume Vtot = 0 for site in pickleStruct.sites: elem = site.specie avgionicrad = elem.average_ionic_radius Vtot += ch.sphereVol(avgionicrad) return (volume - Vtot) / volume
def VolumeByShannonRadii(pickleStruct): volume = pickleStruct.volume picklestruct = pdf.ValenceIonicRadiusEvaluator(pickleStruct) #this automatically attempts to assign valences Vtot = 0 for ionicRadii in picklestruct._get_ionic_radii(): v = ch.sphereVol(ionicRadii) Vtot += v return (volume - Vtot) / volume
def oxidationStateVolumeFlexibility(pickleStruct): #how much does atomic volume change when charge state changes #we can use physical volumes as we normalize to teh volume of the unit cell volume = pickleStruct.volume VolChange = 0 for site in pickleStruct.sites: elem = site.specie.value ShannonPoint = ShannonData[elem] maxrad = 0 minrad = float('inf') for i in ShannonPoint: rad = i['ionic_radius'] if (rad > maxrad): maxrad = rad if (rad < minrad): minrad = rad volDiff = ch.sphereVol(maxrad) - ch.sphereVol(minrad) VolChange += volDiff return VolChange / volume
def deltaShannonCrystalRadii(pickleStruct): initialVol = pickleStruct.volume deltaVolList = list() for site in pickleStruct.sites: elem = site.specie.value ShannonPoint = ShannonData[elem] maxSeen = 0 minSeen = float('Inf') for dictionary in ShannonPoint: rad = dictionary['crystal_radius'] if (rad > maxSeen): maxSeen = rad if (rad < minSeen): minSeen = rad deltaVol = ch.sphereVol(maxSeen) - ch.sphereVol(minSeen) deltaVolList.append(deltaVol) return [ np.mean(deltaVolList), np.std(deltaVolList), np.min(deltaVolList), np.max(deltaVolList) ] / (initialVol)**(1 / 3)
def VolumeFlexibilityByShannonRadii( pickleStruct): #change in volume when anion charge state is modified startVol = VolumeByShannonRadii(pickleStruct) TotDeltaVol = 0 for site in pickleStruct.sites: elem = site.specie.value coordin_no = site.coordination_no ShannonPoint = ShannonData[elem] deltaVol = 0 if (sh.isAnion(ShannonPoint) == True): originalRad = sh.getIonicRadiusWithCoordination( ShannonPoint, coordin_no) originalOx = sh.getOxNumbGivenCoordination(ShannonPoint, coordin_no) newRad = sh.getIonicRadGivenOx(ShannonPoint, originalOx - 1) if (newRad == None): newRad = originalRad deltaVol = ch.sphereVol(originalRad) - ch.sphereVol(newRad) TotDeltaVol += deltaVol return TotDeltaVol / startVol
def deltaShannonRadii( pickleStruct ): #We need the shannon dictoinary as the pymatgen valence can't gauge 'maximal differences' initialVol = pickleStruct.volume deltaVolList = list() for site in pickleStruct.sites: elem = site.specie.value ShannonPoint = ShannonData[elem] maxSeen = 0 minSeen = float('Inf') for dictionary in ShannonPoint: rad = dictionary['ionic_radius'] if (rad > maxSeen): maxSeen = rad if (rad < minSeen): minSeen = rad deltaVol = ch.sphereVol(maxSeen) - ch.sphereVol(minSeen) deltaVolList.append(deltaVol) return [ np.mean(deltaVolList), np.std(deltaVolList), np.min(deltaVolList), np.max(deltaVolList) ] / (initialVol)**(1 / 3)
def VolumeByAvgIonicRadius(picklestruct): ''' volume calculated using AVERAGE ionic radii. :param picklestruct: :return: ''' volume = picklestruct.volume Vtot = 0 for site in picklestruct.sites: elem = site.specie avgionicrad = elem.average_ionic_radius Vtot += ch.sphereVol(avgionicrad) data = { 'avgIonicRadVol': (volume - Vtot) / volume } #should this be normalized return data
def avgDistanceOfNearestNeighbors( picklestruct ): # WE NEED TO CALCULATE WITH A SUPERCELL, and CANNOT USE FRACCOORDS==SLOW # also should take the ratio against the Li radius # we may need the pymatgen spacegroup analyzer # make a copy or else when we make supercell, we overwrite originalcell too initialvol = picklestruct.volume originalcell = copy.copy(picklestruct) # we need to displace the origiinal cell so it is in the center of the supercell!!!! radius = 4 # 4 angstroms is well motivated bond length, no scaling needed because we use physical dist to get nearest neighbors avgNNdist = list() #print(len(originalcell)) for site in originalcell: # could be on the order of 100 distances = list() neighborsArray = originalcell.get_neighbors(site, radius) # radius should be nearest neighbors # print(len(neighborsArray)) sitecoord = site.coords for siteneighbor in neighborsArray: # order of 10, let's say neighborcoord = siteneighbor[0].coords # we should use fractional coordinates here... dist = ch.getDist(neighborcoord, sitecoord) distances.append(dist) avgNNdist.append(np.mean(distances)) avgNNdist = [i / initialvol**(1 / 3) for i in avgNNdist] data = { 'NNdist': np.mean(avgNNdist), 'NNdiststd': np.std(avgNNdist), 'nndistmax': np.max(avgNNdist), 'nndistmin': np.min(avgNNdist) } return data # feature is already something we can find in the matdata miner # def getCrystalSystem(picklestruct): # symmetry = psa.SpacegroupAnalyzer(picklestruct); # numeric = cs.CrystalSysClassFeat(symmetry.get_crystal_system()); # data = {'Crystal System': numeric} # return data; # def Hall_Number(picklestruct): #return hall_number, which is just another way of listing a spacegroup number # symmetryDat = psa.SpacegroupAnalyzer(picklestruct); # data = {'Hall Number': symmetryDat.get_symmetry_dataset()['hall_number']} # return data;
def VolumeByShannonRadii(pickleStruct): volume = pickleStruct.volume Vtot = 0 for site in pickleStruct.sites: elem = site.specie.value coordin_no = site.coordination_no ShannonPoint = ShannonData[elem] v = 0 rad = 0 for i in ShannonPoint: #only positive shannon point data in our data set. if (i['coordination_no'] == coordin_no): rad = i['ionic_radius'] break #we've found the correct ionic radius, so stop searching Shannon points if ( rad == 0 ): #if rad is still zero, that means we didn't find the shannon point, so just use the avg ionic radius #as a suitable proxy for the average ionic radius rad = site.specie.average_ionic_radius v = ch.sphereVol(rad) Vtot += v return (volume - Vtot) / volume
def ionicityOfLattice(picklestruct): #AS a general rule, ionic bonds are stronger than covalent bonds #perhaps materials with more ionic bonds tend to resist lithium intercalation more r = 4; #four angstroms is a very good motivation for bond length (though this will overestimate small bonds) #we have to scale r as we play with fractional coordinates initialvol = picklestruct.volume; originalcell = copy.copy(picklestruct); ionicCount = list(); for site in originalcell.sites: elementElectroneg = site.specie.X; sitecoord = site.coords; subcount = list(); subionicity = list(); neighborsArray = originalcell.get_neighbors(site, r) ionic = 0; for siteneighbor in neighborsArray: neighborElectroneg = siteneighbor[0].specie.X; neighborcoord = siteneighbor[0].frac_coords; #we should use fractional coordinates here... dist = ch.getDist(neighborcoord, sitecoord); if(abs(elementElectroneg-neighborElectroneg) >2): ionic+=1; subionicity.append(abs(elementElectroneg-neighborElectroneg)) ionicCount.append(ionic) return [np.mean(ionicCount)/len(picklestruct.sites), np.mean(subionicity)];
def avgDistanceOfNearestNeighbors(picklestruct): #WE NEED TO CALCULATE WITH A SUPERCELL, and CANNOT USE FRACCOORDS #also should take the ratio against the Li radius #we may need the pymatgen spacegroup analyzer #make a copy or else when we make supercell, we overwrite originalcell too initialvol = picklestruct.volume; originalcell = copy.copy(picklestruct); #we need to displace the origiinal cell so it is in the center of the supercell!!!! radius = 4 #4 angstroms is well motivated bond length, no scaling needed because we use physical dist to get nearest neighbors avgNNdist = list(); print(len(originalcell)) for site in originalcell: #could be on the order of 100 time1 = time.time(); distances = list(); neighborsArray = originalcell.get_neighbors(site, radius); #radius should be nearest neighbors #print(len(neighborsArray)) sitecoord = site.coords; for siteneighbor in neighborsArray: #order of 10, let's say neighborcoord = siteneighbor[0].coords; #we should use fractional coordinates here... dist = ch.getDist(neighborcoord, sitecoord); distances.append(dist); avgNNdist.append(np.mean(distances)) time2 = time.time() #print(time2-time1) return [np.mean(avgNNdist), np.std(avgNNdist), np.max(avgNNdist), np.min(avgNNdist)]/initialvol**(1/3);
def VolumeByShannonRadii(picklestruct): ''' more precies than previous cuz it tries to use ionic radius using the shannon number :param picklestruct: :return: ''' volume = picklestruct.volume Vtot = 0 for site in picklestruct.sites: elem = site.specie.value if not hasattr(elem, 'coordination_no'): continue coordin_no = site.coordination_no if (elem not in ShannonData.keys()): continue ShannonPoint = ShannonData[elem] v = 0 rad = 0 for i in ShannonPoint: #only positive shannon point data in our data set. if (i['coordination_no'] == coordin_no): rad = i['ionic_radius'] break #we've found the correct ionic radius, so stop searching Shannon points ## =================== Potential source of inaccuracy right here ==================================## if ( rad == 0 ): #if rad is still zero, that means we didn't find the shannon point, so just use the avg ionic radius #as a suitable proxy for the average ionic radius rad = site.specie.average_ionic_radius v = ch.sphereVol(rad) Vtot += v data = { 'ShannonRadii': (volume - Vtot) / volume } return data