def __init__(self, specs,systemSpecies = None, directory = None): from aBuild.database.crystal import Crystal #Initialize from a dictionary if isinstance(specs,dict): if self._all_present(specs): self.POTCAR = POTCAR(specs["potcars"]) self.KPOINTS = KPOINTS(specs["kpoints"]) if isinstance(specs["crystal"],Crystal): self.crystal = specs["crystal"] else: self.crystal = Crystal(specs["crystal"],specs["species"]) self.handleSpecialTags(specs) self.INCAR = INCAR(specs["incar"]) else: msg.fatal("I don't have all the necessary information to initialize: {}".format(specs.keys())) #Initialize from a path elif isinstance(specs, str): self.POTCAR = POTCAR(path.join(specs,'POTCAR')) self.KPOINTS = KPOINTS(path.join(specs,'KPOINTS')) self.crystal = Crystal(path.join(specs,'POSCAR'),systemSpecies,crystalSpecies = self.POTCAR.species) self.directory = specs else: msg.fatal("Unable to initialize a VASP object from the data that you passed in:", specs) if directory is not None: self.directory = directory
def _processSiteRestrictions(self, site_res): if site_res is None and self.knary is None and self.basis is None: self.site_res = None self.siteRestrictions = None return if site_res is not None: self.site_res = True self.siteRestrictions = site_res else: self.site_res = False self.siteRestrictions = [ "/".join([str(i) for i in range(self.knary)]) for j in self.lattice.basis ] if len(self.siteRestrictions) != self.lattice.nBasis: print(self.lattice.nBasis) print(self.siteRestrictions) msg.fatal( "The number of site restrictions is not equal to the number of atomic basis vectors" ) if any( [len(i.split('/')) != self.knary for i in self.siteRestrictions]): print(self.knary, [len(i.split('/')) for i in self.siteRestrictions]) msg.fatal( "Your site restrictions are not consistent with the system you chose" )
def _init_file(self, filepath): if 'poscar' in filepath.lower(): self.from_poscar(filepath) else: msg.fatal( "Not sure about the format of the file you want me to read")
def __init__(self, specs, systemSpecies, directory=None): from aBuild.database.crystal import Crystal if isinstance(specs, dict): self.INCAR = INCAR(specs["incar"]) self.POTCAR = POTCAR(specs["potcar"]) self.KPOINTS = KPOINTS(specs["kpoints"]) if isinstance(specs["crystal"], Crystal): self.crystal = specs["crystal"] else: self.crystal = Crystal(specs["crystal"], systemSpecies) elif isinstance(specs, str): self.POTCAR = POTCAR(path.join(specs, 'POTCAR')) self.KPOINTS = KPOINTS(path.join(specs, 'KPOINTS')) self.crystal = Crystal(path.join(specs, 'POSCAR'), systemSpecies, crystalSpecies=self.POTCAR.species) self.directory = specs else: msg.fatal( "Unable to initialize a VASP object from the data that you passed in:", specs) if directory is not None: self.directory = directory
def mtpLines(self, relax=False): import numpy as np if not relax and self.results is None: msg.fatal( "You want me to write result information but I don't have any." ) result = [] result.append('BEGIN_CFG') result.append('Size') result.append(str(self.nAtoms)) result.append('SuperCell') for lv in self.latpar * self.lattice: result.append('{:12.6f} {:12.6f} {:12.6f}'.format( lv[0], lv[1], lv[2])) if not relax: result.append( ' AtomData: id type cartes_x cartes_y cartes_z fx fy fz' ) else: result.append( ' AtomData: id type cartes_x cartes_y cartes_z' ) #counter = crystal.lattice.nTypes - 1 # Took me a few minutes to figure this one out. Very Pythonic # atomLabels = [ x for sublist in [ [ counter - i for k in range(crystal.lattice.atom_counts[i]) ] for i in range(counter + 1)] for x in sublist] atomLabels = [ x for sublist in [[i for k in range(self.atom_counts[i])] for i in range(self.nTypes)] for x in sublist ] for i in range(self.nAtoms): if not relax: forces = self.results["forces"][i] coords = self.Bv_cartesian[i] # print(forces,'forces') if not relax: result.append( '{:16d} {:3d} {:16.6f} {:12.6f} {:12.6f} {:18.6f} {:10.6f} {:10.6f}' .format(i + 1, atomLabels[i], coords[0], coords[1], coords[2], forces[0], forces[1], forces[2])) else: result.append('{:16d} {:3d} {:16.6f} {:12.6f} {:12.6f}'.format( i + 1, atomLabels[i], coords[0], coords[1], coords[2])) #line += ' '.join([map(str,crystal.lattice.Bv_cartesian[i]), crystal.forces[i]]) if not relax: result.append('Energy') result.append(str(self.results["energyZ"]) + '') result.append( ' Stress: xx yy zz yz xz xy' ) s = self.results["stress"] stressesline = '{:16.6f} {:12.6f} {:12.6f} {:12.6f} {:12.6f} {:12.6f}'.format( s[0], s[1], s[2], s[3], s[4], s[5]) result.append(stressesline) result.append(''.join( [' Feature conf_id ', ' '.join([self.symbol, self.title]), ''])) result.append('END_CFG\n') return result
def __init__(self, crystalSpecs): # The system species needs to always be passed in. The crystals species is optional because we may be able to extract # it from input files. required = [ "lattice", "basis", "atom_types", "crystalSpecies", "atom_counts", "latpar", "coordsys", "title", "results", "systemSpecies" ] if True in [x not in crystalSpecs.keys() for x in required]: msg.fatal( "Not enough information to initialize the Crystal object") for spec in required: setattr(self, spec, crystalSpecs[spec]) self.nAtoms = sum(self.atom_counts) self.nTypes = len(self.atom_counts) if self.basis is not None and self.nAtoms != len(self.basis): msg.fatal("We have a problem") # Let's check to see if we have a disagreement between the system species and # the crystal species self._add_zeros() if self.latpar is None and None not in [ self.crystalSpecies, self.lattice ]: self.set_latpar()
def enumerate(self,overwrite=False): import shutil from os import path if self.enumerationComplete: msg.info("It looks like you've already completed an enumeration") if overwrite: msg.info("but you said to overwrite it, so I'll continue") else: msg.info("and you said to not overwrite it. Stopping. No new file generated") return else: msg.info("File: struct_enum.out not found! Running enumeration code.") from os import waitpid from subprocess import Popen if config.ENUMX is not None: command = "cd {}; {} {} > {}".format(self.root, config.ENUMX, 'struct_enum.in',"output." + self.lattice.lattice_name ) else: msg.fatal("You haven't defined the environment variable: ENUMX, so I don't know how to enumerate") child=Popen(command, shell=True, executable="/bin/bash") waitpid(child.pid, 0) shutil.move(path.join(self.root,"struct_enum.out"),path.join(self.root,"struct_enum.out." + self.lattice.lattice_name)) shutil.move(path.join(self.root,"struct_enum.in"),path.join(self.root,"struct_enum.in." + self.lattice.lattice_name)) self.enumerationComplete = True
def autogr(self, execute=True): from os import waitpid, path from subprocess import Popen self.KPGEN() if config.AUTOGR is not None: print('Found AUTOGR executable') if execute: command = "{}".format(config.AUTOGR) child = Popen(command, shell=True, executable="/bin/bash") waitpid(child.pid, 0) else: msg.info("Not running the getKpoints script") else: msg.fatal( "You haven't defined the environment variable: AUTOGR, so I don't know how to generate KPOINT grids " ) if not path.isfile('KPOINTS'): print("Can't find KPOINTS") return False else: print("KPOINTS file FOUND") with open('KPOINTS', 'r') as f: lines = f.read() if '**' in lines: print("*** found in KPOINTS file") return False else: print("KPOINTS file looks good") return True
def read_forces(self,allIonic = True): with open('POSCAR','r') as file: poslines = file.readlines() nAtoms = sum([int(i) for i in poslines[5].split()]) with open('OUTCAR', 'r') as file: lines = file.readlines() n = 0 if allIonic: forces = [] n = 0 for line in lines: if line.rfind('TOTAL-FORCE') > -1: singleItForces = [] for i in range(nAtoms): singleItForces.append(np.array([float(f) for f in lines[n + i + 2].split()[3:6]])) msg.info('Found forces for {} atoms.'.format(nAtoms)) if not '--' in lines[n+nAtoms + 2]: print(lines[n+nAtoms + 2]) msg.fatal('It appears that there are forces for more atoms than I was expecting!') if allIonic: forces.append(singleItForces) n+=1 if not allIonic: forces = singleItForces if allIonic and len(forces) == 1: return forces[0] return forces
def generateConvexHull(self, file='dataReport_VASP.txt', plotAll=True): from os import path from aBuild.database.dataset import dataset dataFile = path.join(self.root, file) if not path.isfile(dataFile): msg.fatal('data file does not exist') data = dataset(dataFile, self.species) data.generateConvexHullPlot(plotAll=plotAll)
def _add_zeros(self, systemSpecies, crystalSpecies): self.species = systemSpecies if crystalSpecies is None: from numpy import array # If you don't tell me what atoms are in # the crystal, then I'll just riffle the system species # in, starting at the front. For example, when I read in the prototype # files, zeros are not included in the list of if len(systemSpecies) != self.nTypes: msg.fatal( "It appears that we need to insert zeros in atom_counts, but I don't know where to add them" ) diff = len(systemSpecies) - self.nTypes self.atom_counts = array( list(self.atom_counts) + [0 for x in range(diff)]) self.nTypes = len(self.atom_counts) # self.species = systemSpecies # else: #self.species = systemSpecies else: if len(crystalSpecies) != self.nTypes: msg.fatal( "The number of species that was read in (POTCAR) does not agree with atom_counts (POSCAR)" ) # This is the case when a crystal *with the atomic species* are read in # but it just so happens that the number of species in this crystal does not match # the number of species in the system being studied. In this case, we need to specify which # atomic system species are missing from this particular crystal. We do this by augmenting zeros # to atom_counts at the appropriate location. elif len(crystalSpecies) != len(systemSpecies): print(crystalSpecies, systemSpecies) from numpy import insert lacking = list(set(systemSpecies) - set(crystalSpecies)) indices = [ systemSpecies.index(x) for x in sorted(lacking, reverse=True) ] print(sorted(lacking, reverse=True), 'lacking') print(indices, 'indices') for idx, ele in enumerate(indices): print(self.atom_counts, 'atom counts') print(ele, idx, 'Adding zero here') self.atom_counts = insert(self.atom_counts, ele, 0) # + idx ??? if len(lacking) > 1: print( " I haven't tested this case, can you verify that it's working the way it should" ) print( "The system species is {}, and the crystal species is {} and our new atom counts is {}." .format(systemSpecies, crystalSpecies, self.atom_counts)) # import sys # sys.exit() # self.species = systemSpecies self.nTypes = len(self.atom_counts)
def generatePOSCAR(self,sNumber): from os import waitpid from subprocess import Popen import subprocess if config.MAKESTRX is not None: command = "cd {}; {} {}.{} {} > poscar.{}.{}; cd - ".format(self.root, config.MAKESTRX, 'struct_enum.out',self.lattice.lattice_name, sNumber, self.lattice.lattice_name,sNumber) else: msg.fatal("You haven't defined the environment variable: MAKESTRX, so I don't know how to generate POSCARs") child=Popen(command, shell=True, executable="/bin/bash",stdout = subprocess.PIPE) waitpid(child.pid, 0)
def set_latpar(self, modify=1.0): from aBuild.calculators import data #if self.latpar == 1.0 or self.latpar < 0: # We must first reverse sorte the species list so we get the right atom in the right place. if sorted(self.crystalSpecies, reverse=True) != self.crystalSpecies: msg.fatal( "Your species are not in reverse alphabetical order... OK?") self.latpar = data.vegardsVolume(self.crystalSpecies, self.atom_counts, self.volume) self.latpar = self.latpar * modify
def set_latpar(self): from aBuild.calculators import data #if self.latpar == 1.0 or self.latpar < 0: # We must first reverse sorte the species list so we get the right atom in the right place. if sorted(self.species, reverse=True) != self.species: msg.fatal( "Your species are not in reverse alphabetical order... OK?") self.latpar = data.vegard( self.species, [float(x) / self.nAtoms for x in self.atom_counts])
def minDist(self): from numpy import array, dot, min, einsum, add, roll, column_stack from numpy.linalg import norm from itertools import product import sys import numpy numpy.set_printoptions(threshold=sys.maxsize) # Need to make sure that all of the atoms are inside the first # unit cell before we compile list of distances self.validateCrystal() # Calculate all possible shifts. These are vectors of integers # representing the amount of each lattice vector that we are going # to add to each basis atom. We only do combinations of (-1,0,1) because # that should be enough to find all possible distances between atoms. # We're not trying to get all atoms out to some cutoff radius, we just want to # make sure we get enough atoms in there to find the min separation. offsets = array([x for x in product(range(-1, 2), repeat=3)]) # Now shift every basis atom by every shift previously calculated neighborsDirect = array([self.Bv_direct + array(x) for x in offsets]) #Convert list of atomic positions to cartesian coordinates neighborsCartesian = einsum('abc,cd', neighborsDirect, self.latpar * self.lattice) # Flatten the list down to a single list of position vectors neighborsCartesian.resize(len(offsets) * self.nAtoms, 3) # Build a matrix where each row is a shifted version of atomic positions. rolledNeighbors = array([ roll(neighborsCartesian, x, axis=0) for x in range(len(neighborsCartesian)) ]) # print(neighborsCartesian, 'nc') # print(rolledNeighbors,' rn') # print(rolledNeighbors.shape,' rn shape') # print(neighborsCartesian.shape,' nc shape') # import sys # sys.exit() #Now we can just subtract the first row (unshifted) from all of the other rows # and calculate the norm of each vector distances = norm(rolledNeighbors[0, :, :] - rolledNeighbors, axis=2) # Return the min, excluding 0 distances. from numpy import count_nonzero, nonzero, transpose nZeroOccurrences = count_nonzero(distances == 0) if nZeroOccurrences > self.nAtoms * len(offsets): ##import sys #import numpy #numpy.set_printoptions(threshold=sys.maxsize) #print(distances, 'distances') #print(transpose(nonzero(distances == 0))) msg.fatal("Atoms are on top of each other") return min(distances[distances > 1e-5])
def writePOTCAR(self,filename = 'POTCAR'): if not self._potcarsOK(): ermsg = "Can't find the POTCARS you specified: {}".format(self.versions) msg.fatal(ermsg) srcpaths = [path.join(self.srcdirectory,x + self.setups[x],'POTCAR') for x in self.species] from os import waitpid from subprocess import Popen command = "cat {} > {} ".format(' '.join(srcpaths), filename) child=Popen(command, shell=True, executable="/bin/bash") waitpid(child.pid, 0)
def __init__(self,specs): if isinstance(specs,dict): self.srcdirectory = specs["directory"] self.xc = specs["xc"] self.versions = specs["versions"] self.species = list(specs["versions"].keys()) self.species.sort(reverse=True) if sorted(self.species,reverse = True) != self.species: msg.fatal('Species are not in reverse alphabetical order... Problem?') self.setups = specs["setups"] elif isinstance(specs,str): self._init_path(specs)
def fromMLP(self, lines): from numpy import array import os from aBuild.calculators.vasp import VASP nAtoms = int(lines[2].split()[0]) latDict = {} self.results = {} self.lattice = array([list(map(float, x.split())) for x in lines[4:7]]) self.basis = array( [list(map(float, x.split()[2:5])) for x in lines[8:8 + nAtoms]]) self.nAtoms = len(self.basis) self.coordsys = 'C' self.atom_types = [int(x.split()[1]) for x in lines[8:8 + nAtoms]] self.results["forces"] = array( [list(map(float, x.split()[5:8])) for x in lines[8:8 + nAtoms]]) self.atom_counts = array([ self.atom_types.count(x) for x in set(self.atom_types) ]) #range(max(atoms)+1) self.nTypes = len(self.atom_counts) # THe add_zeros function is here in case you run into a config with few atom types than the # system being studied. Like running into a pure config for a binary system. Or a binary config # when studying a ternary system. self._add_zeros(self.species, [self.species[x] for x in list(set(self.atom_types))]) titleindex = ['conf_id' in x for x in lines].index(True) self.title = ' '.join(lines[titleindex].split()[2:]) if any(['Energy' in x for x in lines]): energyindex = ['Energy' in x for x in lines].index(True) self.results["energyF"] = float(lines[energyindex + 1].strip().split()[0]) # root = os.getcwd() # pures = [VASP(path.join(root,'training_set','pure' + x),systemSpecies = self.species) for x in self.species] # puresDict = {} # for ispec,spec in enumerate(self.species): # #thispure = VASP(path.join(root,'training_set','pure' + spec,systemSpecies = self.species)) # pures[ispec].read_results() ## thispure.read_results() # puresDict[spec] = pures[ispec].crystal.results["energypatom"] # self.results["fEnth"] = self.results["energyF"]/self.nAtoms - sum( [ pures[i].crystal.results["energyF"]/pures[i].crystal.nAtoms * self.concentrations[i] for i in range(self.nTypes)]) else: self.results = None self.latpar = 1.0 if sum(self.atom_counts) != nAtoms: msg.fatal('atomCounts didn\'t match up with total number of atoms') # self.set_latpar() self.latpar = 1.0 # MLP files are formatted with no lattice parameter. It's # already built into the lattice vectors. print(self.latpar, 'latpar')
def __init__(self, crystal): from aBuild.database.crystal import Crystal, Lattice """Create the text representation of the crystal in POSCAR format.""" #The label is the first line in the POSCAR file. ancle uses some #naming standards to help organize things. required = [ 'label', 'Lv', 'latpar', 'Bv', 'coordsys', 'species', 'atom_counts' ] if True in [x not in crystal.keys() for x in required]: msg.fatal( "You are lacking necessary information to initialize a POSCAR object" ) for spec in required: setattr(self, spec, crystal[spec])
def from_path(filepath, systemSpecies): #if self.filename is None: # msg.fatal("Not sure about the format of the file you want me to read") #filepath = path.join(self.directory,self.filename) if not path.isfile(filepath): print('POSCAR not found', filepath) return None if 'poscar' in filepath.lower(): return Crystal.from_poscar(filepath, systemSpecies) elif 'input.in' in filepath.lower(): self.from_lammpsin(filepath) else: msg.fatal( "Not sure about the format of the file you want me to read")
def __init__(self, specsDict): required = [ "directory", "xc", "versions", "setups", "build", "srcdirectory" ] if True in [x not in specsDict.keys() for x in required]: print([x not in specsDict.keys() for x in required]) msg.fatal("Missing information on initializing POTCAR") for spec in required: setattr(self, spec, specsDict[spec]) self.species = list(specsDict["versions"].keys()) self.species.sort(reverse=True) if sorted(self.species, reverse=True) != self.species: msg.fatal( 'Species are not in reverse alphabetical order... Problem?')
def read_forces(self, allIonic=True): with open('POSCAR', 'r') as f: poslines = f.readlines() if any(c.isalpha() for c in poslines[5].strip()): #It's a CONTCAR nAtoms = sum([int(i) for i in poslines[6].split()]) else: nAtoms = sum([int(i) for i in poslines[5].split()]) with open('OUTCAR', 'r') as f: lines = f.readlines() n = 0 if allIonic: forces = [] n = 0 found = False for line in lines: if line.rfind('TOTAL-FORCE') > -1: found = True singleItForces = [] for i in range(nAtoms): singleItForces.append( np.array( [float(f) for f in lines[n + i + 2].split()[3:6]])) msg.info('Found forces for {} atoms.'.format(nAtoms)) if not '--' in lines[n + nAtoms + 2]: msg.fatal( 'It appears that there are forces for more atoms than I was expecting!' ) if allIonic: forces.append(singleItForces) n += 1 if not found: msg.info("Couldn't find forces for this calc") return None if not allIonic: forces = singleItForces if allIonic and len(forces) == 1: return forces[0] return forces
def mueller(self,filename='KPOINTS',runGetKpoints = False): from os import waitpid from subprocess import Popen self.PRECALC() if config.GETKPTS is not None: print('found GETKPTS') if self.rGP: command = "{}".format(config.GETKPTS) child=Popen(command, shell=True, executable="/bin/bash") waitpid(child.pid, 0) else: msg.info("Not running the getKpoints script") else: msg.fatal("You haven't defined the environment variable: GETKPTS, so I don't know how to generate KPOINT grids ")
def buildFolders(self, buildpath, calculator, runGetKpoints=True, foldername='E'): from os import path from aBuild.calculators.vasp import VASP from aBuild.jobs import Job import os print("Building folders in {}".format(buildpath)) if not path.isdir(buildpath): os.mkdir(buildpath) print('Made path:', buildpath) configIndex = startPoint = self.starting_point(buildpath) for crystal in self.crystals: vaspspecs = { "incar": calculator["incar"], "kpoints": calculator["kpoints"], 'potcar': calculator["potcars"], "crystal": crystal } thisVASP = VASP(vaspspecs, self.species) runpath = path.join(buildpath, foldername + ".{}".format(configIndex)) if not path.isdir(runpath): os.mkdir(runpath) else: msg.fatal( "I'm gonna write over top of a current directory. ({}) I think I'll stop instead." .format(runpath)) print("Building folder for structure: {}".format(crystal.title)) with chdir(runpath): thisVASP.buildFolder(runGetKPoints=runGetKpoints) configIndex += 1 exdir = path.join(buildpath, 'E.') mljob = Job(calculator["execution"], exdir, calculator["execution"]["exec_path"], arrayStart=startPoint, arrayEnd=configIndex - 1) with chdir(buildpath): print('Building job file') mljob.write_jobfile()
def fromMLPSelect(self, lines): from numpy import array nAtoms = int(lines[2].split()[0]) latDict = {} self.lattice = array([list(map(float, x.split())) for x in lines[4:7]]) self.basis = array( [list(map(float, x.split()[2:])) for x in lines[8:8 + nAtoms]]) self.nAtoms = len(self.basis) self.coordsys = 'C' atoms = [int(x.split()[1]) for x in lines[8:8 + nAtoms]] self.atom_counts = array([atoms.count(x) for x in range(3)]) self.title = ' '.join(lines[7 + nAtoms + 2].split()[2:4]) self.latpar = None if sum(self.atom_counts) != nAtoms: msg.fatal('atomCounts didn\'t match up with total number of atoms') self.set_latpar() self.lattice = self.lattice / self.latpar
def from_poscar(filepath, systemSpecies): """Returns an initialized Lattice object using the contents of the POSCAR file at the specified filepath. :arg strN: an optional structure number. If the label in the POSCAR doesn't already include the strN, it will be added to the title. """ crystalDict = {} from aBuild.calculators.vasp import POSCAR lines = POSCAR.from_path(filepath) from numpy import array crystalDict["lattice"] = array( [list(map(float, l.strip().split()[0:3])) for l in lines.Lv]) crystalDict["basis"] = array( [list(map(float, b.strip().split()[:3])) for b in lines.Bv]) if lines.species is not None: # Found species inside POSCAR file crystalDict["crystalSpecies"] = lines.species else: # Assume that the passed in species apply to this crystal crystalDict["crystalSpecies"] = systemSpecies crystalDict["atom_counts"] = array( list(map(int, lines.atom_counts.split()))) if len(crystalDict["crystalSpecies"]) != len( crystalDict["atom_counts"]): msg.fatal( "Number of species does not agree with the number of atom types read in" ) typesList = [[idx] * aCount for idx, aCount in enumerate(crystalDict["atom_counts"])] atom_types = [] for i in typesList: atom_types += i crystalDict["atom_types"] = atom_types crystalDict["latpar"] = float(lines.latpar.split()[0]) crystalDict["coordsys"] = lines.coordsys crystalDict[ "title"] = lines.label # path.split(filepath)[0].split('/')[-1] + '_' + crystalDict["systemSpecies"] = systemSpecies crystalDict["results"] = {} return Crystal(crystalDict)
def _init_dict(self, enumdict): import numpy as np necessaryItems = ['lattice', 'basis', 'coordsys', 'name'] if not all([x in enumdict for x in necessaryItems]): msg.fatal('Missing information when initializing Lattice object') if len(enumdict["lattice"]) == 3 and len( enumdict["lattice"][0]) == 3 and np.linalg.det( enumdict["lattice"]) != 0: self.lattice = enumdict["lattice"] self.lattice_name = enumdict["name"] else: msg.fatal( "The lattice vectors must be a 3x3 matrix with the vectors as rows " "and the vectors must be linearly independent.") self.basis = enumdict["basis"] self.coordsys = enumdict["coordsys"] self.lattice_name = enumdict["name"] self.nBasis = len(self.basis)
def mueller(self, execute=True): from os import waitpid, path from subprocess import Popen self.PRECALC() if config.GETKPTS is not None: print('Found GETKPTS executable') if execute: command = "{}".format(config.GETKPTS) child = Popen(command, shell=True, executable="/bin/bash") waitpid(child.pid, 0) else: msg.info("Not running the getKpoints script") else: msg.fatal( "You haven't defined the environment variable: GETKPTS, so I don't know how to generate KPOINT grids " ) if not path.isfile('KPOINTS'): return False else: return True
def _init_dict(self, crystalDict): necessary = ['lattice', 'basis', 'atom_counts', 'coordsys', 'species'] if not all([x in crystalDict for x in necessary]): msg.fatal( "Some necessary information not set upon initialization of Crystal object" ) from numpy import array self.lattice = crystalDict["lattice"] self.basis = crystalDict["basis"] self.atom_counts = crystalDict["atom_counts"] typesList = [[idx] * aCount for idx, aCount in enumerate(self.atom_counts)] self.atom_types = [] for i in typesList: self.atom_types += i self.nAtoms = sum(self.atom_counts) self.nTypes = len(self.atom_counts) self.coordsys = crystalDict["coordsys"] self.species = crystalDict["species"] if sorted(self.species, reverse=True) != self.species: msg.fatal( "The order of your atomic species is not in reverse alphabetical order... OK?" ) if 'title' in crystalDict: self.title = crystalDict["title"] else: self.title = None if 'latpar' in crystalDict: self.latpar = crystalDict["latpar"] else: self.latpar = None
def writePOTCAR(self, indices=None, filename='POTCAR'): from numpy import array if self.build == 'aflow': return if not self._potcarsOK(): ermsg = "Can't find the POTCARS you specified: {}".format( self.versions) msg.fatal(ermsg) if indices is not None: srcpaths = [ path.join(self.srcdirectory, x + self.setups[x], 'POTCAR') for x in array(self.species)[indices] ] else: srcpaths = [ path.join(self.srcdirectory, x + self.setups[x], 'POTCAR') for x in self.species ] from os import waitpid from subprocess import Popen command = "cat {} > {} ".format(' '.join(srcpaths), filename) child = Popen(command, shell=True, executable="/bin/bash") waitpid(child.pid, 0)