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_results( self, pures=None, allElectronic=False, allIonic=False, mustHave=['free energy', 'stress', 'species', 'formation energy']): if self.directory is not None and self.status() == 'done': with chdir(self.directory): self.crystal.results = {} self.crystal.results["warning"] = False self.crystal.results["energyF"], self.crystal.results[ "energyZ"] = self.read_energy(allElectronic=allElectronic) self.crystal.results["forces"] = self.read_forces( allIonic=allIonic) self.crystal.results["stress"] = self.read_stress() #self.POTCAR = POTCAR.from_POTCAR() # self.crystal.results["species"] = self.POTCAR.species self.crystal.results["energypatom"] = self.crystal.results[ "energyF"] / self.crystal.nAtoms if 'pure' in self.directory: self.crystal.results["fEnth"] = 0 elif pures is not None: self.crystal.results["fEnth"] = self.formationEnergy(pures) else: self.crystal.results["fEnth"] = 1000 msg.info("Succesfully read in results") else: if self.crystal is not None: self.crystal.results = None msg.info( "Unable to extract necessary information from directory! ({}). Status: {} " .format(self.directory, self.status()))
def buildFolder(self): self.crystal.write('POSCAR.orig', keepZeros=True) self.crystal.write('POSCAR', keepZeros=False) self.writeaflowfromposcar('POSCAR') if os.path.getsize('aflow.in') < 10: return False print(self.kpoints_auto_build, 'check') if not self.kpoints_auto_build: # Now build the KPOINTs file success = self.KPOINTS.writeKPOINTS() if not success: currentMethod = self.KPOINTS.specs["method"] if currentMethod == 'autogr': self.KPOINTS.specs["method"] = 'mueller' self.KPOINTS.specs["mindistance"] = self.KPOINTS.specs[ "rmin"] self.KPOINTS.specs["includegamma"] = "True" retrySuccess = self.KPOINTS.writeKPOINTS() self.KPOINTS.specs["method"] = currentMethod if not retrySuccess: msg.info("KPOINTS build failed, reverting to MP grid") self.kpoints_auto_build = True else: self.KPOINTS.specs["method"] = 'autogr' self.KPOINTS.specs["rmin"] = self.KPOINTS.specs[ "mindistance"] self.KPOINTS.specs["eps"] = '1e-12' retrySuccess = self.KPOINTS.writeKPOINTS() self.KPOINTS.specs["method"] = currentMethod if not retrySuccess: msg.info("KPOINTS build failed, reverting to MP grid") self.kpoints_auto_build = True self.modifyaflowin() return True
def read_results(self, pures=None): if self.directory is not None and self.status() in [ 'done', 'unconverged' ]: with chdir(self.directory): self.crystal.results = {} self.crystal.results["warning"] = False self.crystal.results["energyZ"], self.crystal.results[ "energyF"], self.crystal.results[ "forces"] = self.read_energy_and_forces() self.crystal.results["stress"] = self.read_stress() #self.POTCAR = POTCAR.from_POTCAR() self.crystal.results["species"] = self.POTCAR.species self.crystal.results["energypatom"] = self.crystal.results[ "energyF"] / self.crystal.nAtoms if 'pure' in self.directory: self.crystal.results["fEnth"] = 0 elif True not in [x is None for x in pures]: self.crystal.results["fEnth"] = self.formationEnergy(pures) else: self.crystal.results["fEnth"] = 10000 self.crystal.results["distToHull"] = None else: print(self.status(), 'not reading results') if self.crystal is not None: self.crystal.results = None msg.info( "Unable to extract necessary information from directory! ({}) Status: {}" .format(self.directory, self.status()))
def __init__(self, specs, arrows=None, name="enum", overwrite=False): from aBuild.database.crystal import Lattice self.root = specs["root"] self.lattice = Lattice(specs) # self._get_lattice(specs["lattice"]) from os import path, makedirs if "Enum" not in self.root: self.root = path.join(self.root, "Enum") if not path.isdir(self.root): makedirs(self.root) msg.info('Making Enum directory.') self.inputFileExists = path.isfile( path.join(self.root, "struct_enum.in." + self.lattice.lattice_name)) self.enumerationComplete = path.isfile( path.join(self.root, "struct_enum.out." + self.lattice.lattice_name)) #self._get_basis(specs["basis"]) self.knary = specs["knary"] self.sizeRange = specs["sizes"] self.eps = specs["eps"] self.nConfigs = specs["nconfigs"] self.latticeExpand = specs[ "latticeExpand"] #In case we want to increase/decrease atomic spacings self._processConcRestrictions(specs["concs"]) self._processSiteRestrictions(specs["site_res"]) if 'arrows' in specs: self.arrow_res = True self.arrows = specs["arrows"] else: self.arrow_res = False
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 nEnumStructs(self): from os import path target = path.join(self.root,'struct_enum.out.' + self.lattice.lattice_name) if not path.isfile(target): msg.info("No struct_enum.out found.") return 0 with open(target,'r') as f: lines = f.readlines() try: return int(lines[-1].split()[0]) except: return 0
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 write_blank_pot(self,nSpecies): from os import path settings = {} settings["n_species"] = nSpecies from jinja2 import Environment, PackageLoader # Package for building files from a template env = Environment(loader=PackageLoader('aBuild','templates')) #print(self.settings) template = env.get_template(self.settings['pot']) #"pot.mtp" target = path.join(self.root, "pot.mtp") if not path.isfile(target): with open(target,'w') as f: f.write(template.render(**settings)) else: msg.info("File pot.mtp exists already. You must have copied over Trained.pot_ previously")
def setup_train(self, trainingRoot, species): from os import path, remove from glob import glob from aBuild.calculators.vasp import VASP from aBuild.fitting.mtp import MTP from aBuild.jobs import Job from aBuild.database.dataset import dataset # 1. Pull all VASP data and compile into file train.cfg # 2. Copy/Build a blank potential file called pot.mtp # 3. Build a submission script with chdir(trainingRoot): enumdirs = glob("E.*") # activedirs = [] activedirs = glob("A.*") #puredirs = glob("pure*") dirs = [path.join(trainingRoot, x) for x in enumdirs + activedirs] if dirs != []: import sys print('Building dataset') trainingSet = dataset.from_paths(dirs, species) ##### if path.isfile(path.join(self.root, 'train.cfg')): msg.info( 'train.cfg file found! Deleting and building from scratch.') remove(path.join(self.root, 'train.cfg')) with open(path.join(self.root, 'train.cfg'), 'a+') as f: for crystal in trainingSet.crystals: if (crystal.results["fEnth"] == None or crystal.results["fEnth"] < 100 ) and crystal.minDist > 1.5: print("Building: {}".format(crystal.title)) f.writelines('\n'.join(crystal.lines('mtptrain'))) else: print( "Not adding structure {}. Seems like an extreme one.". format(crystal.title)) print("Energy: {}".format(crystal.results["energyF"])) print("MinDist: {}".format(crystal.minDist)) self.write_blank_pot(len(species)) self.calc_grade() self.train(self.settings["execution"])
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 __init__(self, inputFile): from aBuild.io import read from os import path, getcwd self.root = getcwd() self.inputFile = path.expanduser( path.abspath(inputFile)) # Get full path to the input file. # Get the folder and file to the input file if path.isabs(inputFile): root, inputFile = path.split(inputFile) else: root, inputFile = path.dirname(self.inputFile), inputFile # Read the input file self.specs = read(root, inputFile) if "directory" not in self.specs["calculator"]["vasp"][ "potcars"] or self.specs["calculator"]["vasp"]["potcars"][ "directory"] is None: print( "You did not provide a directory for the POTCARS. Using the environment variable that I found: {}" .format(config.POTCAR_DIR)) self.specs["calculator"]["potcars"][ "directory"] = config.POTCAR_DIR self.root = path.expanduser( self.specs["root"]) # Set the working directory if getcwd().replace("zhome", "fslhome") != self.root: infoMsg = 'You have specified a working directory ({}) that is different from your current working directory ({}) .'.format( self.root, getcwd()) msg.info(infoMsg) self.title = self.specs['title'] self.species = sorted(self.specs["species"], reverse=True) self.fpExecution = self.specs.get( "execution", {} ) # Second argument is the default in case the key doesn't exist. self.calculator = self.specs.get( "calculator", {} ) # Second argument is the default in case the key doesn't exist. # self.nEnumStructuresToSelect = self.specs["trainingset"]["nconfigs"] self.knary = len(self.species) self.fitting = self.specs.get("fitting", {})
def read_results(self, allElectronic=False, allIonic=False): print(self.directory, 'dir') if self.directory is not None and self.status() is 'done': with chdir(self.directory): #print(self.directory) self.crystal.results = {} self.crystal.results["energyF"], self.crystal.results[ "energyZ"] = self.read_energy(allElectronic=allElectronic) self.crystal.results["forces"] = self.read_forces( allIonic=allIonic) self.crystal.results["stress"] = self.read_stress() #self.POTCAR = POTCAR.from_POTCAR() self.crystal.results["species"] = self.POTCAR.species else: self.crystal.results = None msg.info( "Unable to extract necessary information from directory! ({})". format(self.directory))
def buildInputFile(self,overwrite=False): from os import path if self.inputFileExists: msg.info("The file you are trying to generate already exists") if overwrite: msg.info("but you said to overwrite it, so I'm moving forward") else: msg.info("and you told me not to overwrite. Stopping, no new files generated.!") return else: msg.info("File: struct_enum.in({}) not found! Building it".format(self.lattice.lattice_name)) from jinja2 import Environment, PackageLoader # Package for building files from a template knaryDict = {2:" Binary", 3: " Ternary", 4: " Quaternary"} settings = {} settings["title"] = self.lattice.lattice_name + knaryDict[self.knary] settings["template"] = "struct_enum.in" settings["eps"] = self.eps settings["size_low"] = self.sizeRange[0] settings["size_high"] = self.sizeRange[1] if self.conc_res: settings["conc_res"] = "T" if self.arrow_res: temp = [] for i, a in enumerate(self.arrows): temp.append("{0} {1}".format(" ".join([str(j) for j in self.concs[i]]),a)) else: temp = [" ".join([str(i) for i in j]) for j in self.concRestrictions] settings["concentrations"] = temp else: settings["conc_res"] = "F" if self.arrow_res: settings["incl_arrows"] = "T" else: settings["incl_arrows"] = "F" settings["lattice"] = [" ".join([str(i) for i in j ]) for j in self.lattice.lattice] settings["k_nary"] = self.knary settings["atomic_basis"] = [" ".join([str(k) for k in self.lattice.basis[i]]) + " " + self.siteRestrictions[i] for i in range(self.lattice.nBasis)] settings["n_basis"] = self.lattice.nBasis env = Environment(loader=PackageLoader('aBuild', 'templates')) template = env.get_template("struct_enum.in") target = path.join(self.root, "struct_enum.in") with open(target,'w') as f: f.write(template.render(**settings)) self.inputFileExists = True
def handleSpecialTags(self,specs): special = ["AFM","FM"] if "FM" in specs.keys(): specs["incar"]["ispin"] = 2 specs["incar"]["magmom"] = '' for idx,species in enumerate(sorted(specs["FM"],reverse = True)): specs["incar"]["magmom"] += ' '.join(map(str, [ specs["FM"][species] ] * self.crystal.atom_counts[idx])) specs["incar"]["magmom"] += ' ' elif "AFM" in specs.keys(): if self.crystal.AFMPlanes == None: self.crystal.getAFMPlanes([1,0,0]) if self.crystal.AFMPlanes == None: msg.info("You supposedly had an AFM crystal, but I'm not finding the planes") return specs["incar"]["ispin"] = 2 #Put in nonzero spin values specs["incar"]["magmom"] = ' '.join(map(str,self.crystal.AFMPlanes)) + ' ' atomsLeft = self.crystal.nAtoms - len(self.crystal.AFMPlanes) specs["incar"]["magmom"] += ' '.join(map(str,[0 for x in range(atomsLeft)]))
def read_results(self, allElectronic = False, allIonic=False): if self.directory is not None and self.status() in ['done','unconverged']: with chdir(self.directory): self.crystal.results = {} self.crystal.results["warning"] = False self.crystal.results["energyF"],self.crystal.results["energyZ"] = self.read_energy(allElectronic=allElectronic) self.crystal.results["forces"] = self.read_forces(allIonic=allIonic) self.crystal.results["stress"] = self.read_stress() #self.POTCAR = POTCAR.from_POTCAR() self.crystal.results["species"] = self.POTCAR.species self.crystal.results["energypatom"] = self.crystal.results["energyF"]/self.crystal.nAtoms if abs(self.crystal.results["energyF"]) > 1000: self.crystal.results["warning"] = True if 'pure' not in self.directory: self.crystal.results["fEnth"] = self.formationEnergy else: self.crystal.results["fEnth"] = 0 else: print(self.status(), 'not reading results') self.crystal.results = None msg.info("Unable to extract necessary information from directory! ({})".format(self.directory))
def _add_zeros(self): if len(self.systemSpecies) == self.nTypes: #msg.info("No need to add zeros to the atom_types list, the number of types matches the species list") return elif any(x is None for x in [self.systemSpecies, self.crystalSpecies]): self.speciesMismatch = True msg.info( "I need to know the species list for the system and this crystal to proceed adding zeros in " ) return if len(self.crystalSpecies) != self.nTypes: print(self.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. if len(self.systemSpecies) != len(self.crystalSpecies): from numpy import insert lacking = list(set(self.systemSpecies) - set(self.crystalSpecies)) indices = [ self.systemSpecies.index(x) for x in sorted(lacking, reverse=True) ] for idx, ele in enumerate(indices): self.atom_counts = insert(self.atom_counts, ele, 0) # + idx ??? self.nTypes = len(self.atom_counts) self.crystalSpecies = self.systemSpecies if len(self.crystalSpecies) != self.nTypes: msg.fatal( 'Species list ({})is not consistent with the number of atom types ({})' .format(self.crystalSpecies, self.nTypes)) if self.crystalSpecies != self.systemSpecies: msg.fatal("Function add_zeros unsuccessful")
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 statusReport(self): from os import path, listdir, remove from glob import glob from aBuild.calculators.vasp import VASP from aBuild.calculators.aflow import AFLOW from numpy import argsort trainingRoot = path.join(self.root, 'validation_set') with chdir(trainingRoot): enumdirs = glob("E.*") activedirs = glob("A.*") delFiles = glob("status.*") for i in delFiles: remove(i) dirs = [path.join(trainingRoot, x) for x in enumdirs + activedirs] nDirs = len(dirs) numdirs = [int(y.split('.')[-1]) for y in dirs] count = 0 for idx, directory in enumerate([dirs[x] for x in argsort(numdirs)]): if count % 100 == 0: print("checking directories {} - {}".format( dirs[argsort(numdirs)[count + 1]], dirs[argsort(numdirs)[count + 100 if count + 100 < nDirs else nDirs - 1]])) count += 1 if 'aflow.in' in listdir(directory): thisAFLOW = AFLOW.from_path(directory, self.species) thisStat = thisAFLOW.status() else: thisVASP = VASP.from_path(directory, self.species) thisStat = thisVASP.status() if thisStat == 'errors' or thisStat == 'running': msg.info("Directory {} is {} ".format(directory, thisStat)) with open('status.' + thisStat, 'a') as f: f.write(directory.split('/')[-1] + ' ')
def buildFolders(self, buildpath, calculator, runGetKpoints=True, foldername='A', onlyCloseToHull=False, distToHull=5e-3): from os import path from aBuild.calculators.vasp import VASP from aBuild.calculators.aflow import AFLOW from aBuild.calculators.lammps import LAMMPS from aBuild.calculators.espresso import ESPRESSO from aBuild.jobs import Job from math import floor 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) lookupCalc = { 'aflow': lambda specs: AFLOW.from_dictionary(specs), 'vasp': lambda specs: VASP.from_dictionary(specs), 'qe': lambda specs: ESPRESSO(specs, self.species), 'lammps': lambda specs: LAMMPS(specs, self.species) } lookupBuild = { 'aflow': lambda obj: obj.buildFolder(), 'vasp': lambda obj: obj.buildFolder(runGetKPoints=runGetKpoints), 'qe': lambda obj: obj.buildFolder(), 'lammps': lambda obj: obj.buildFolder() } for crystal in self.crystals: if onlyCloseToHull: if crystal.results["distToHull"] is None: msg.fatal( "You asked only for cystals that are close to the hull, but I don't have a value for that distance." ) elif crystal.results["distToHull"] > distToHull: continue print("Building crystal {}".format(crystal.title)) runpath = path.join(buildpath, foldername + ".{}".format(configIndex)) #Augment the existing dictionary in preparation for sending it in calculator[calculator["active"]]["crystal"] = crystal calculator[calculator["active"]]["directory"] = runpath # Initialize the calculation object print('initializing VASP object') thisCalc = lookupCalc[calculator["active"]]( calculator[calculator["active"]]) # Build the path 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)) # Change the directory and build the folder print("Building folder for structure: {}".format(crystal.title)) with chdir(runpath): success = lookupBuild[calculator["active"]](thisCalc) if not success: if calculator["active"] == 'aflow': retryCalc = lookupCalc["vasp"](calculator['vasp']) with chdir(runpath): success = lookupBuild["vasp"](retryCalc) if not success: msg.fatal( "I tried building an aflow dir and it failed, then I tried building a VASP dir and it failed too. I give up" ) else: msg.warn( "VASP(??) directory build failed, and I'm not sure why" ) configIndex += 1 # Build the submission script exdir = path.join(buildpath, 'A.') if calculator['active'] == 'aflow': calculator["execution"]["exec_path"] = "aflow --run" elif calculator["active"] == 'vasp': calculator["execution"]["exec_path"] = "vasp6_serial" startAdder = int(floor(startPoint / 1000)) * 1000 endAdder = int(floor((configIndex - 1) / 1000)) * 1000 if startAdder == endAdder: # Don't need to submit two jobs in this case. Just one, but we might have to add an offset if the numbers are too high. msg.info("Building one job submission file") calculator["execution"]["offset"] = startAdder mljob = Job(calculator["execution"], exdir, calculator["execution"]["exec_path"], arrayStart=startPoint - startAdder, arrayEnd=configIndex - 1 - endAdder) with chdir(buildpath): print('Building job file') mljob.write_jobfile('jobscript_vasp.sh') else: # We're going to have to submit two jobs to span the whole job array. msg.info("Building two job submission files") #First job.. calculator["execution"]["offset"] = startAdder mljob = Job(calculator["execution"], exdir, calculator["execution"]["exec_path"], arrayStart=startPoint - startAdder, arrayEnd=999) with chdir(buildpath): print('Building job file') mljob.write_jobfile('jobscript_vasp_1.sh') calculator["execution"]["offset"] = endAdder - 1 mljob = Job(calculator["execution"], exdir, calculator["execution"]["exec_path"], arrayStart=1, arrayEnd=configIndex - endAdder) with chdir(buildpath): print('Building job file') mljob.write_jobfile('jobscript_vasp_2.sh')
trainingRoot = path.join(self.root, 'training_set') with chdir(trainingRoot): enumdirs = glob("E.*") activedirs = glob("A.*") dirs = [path.join(trainingRoot,x) for x in enumdirs + activedirs] <<<<<<< HEAD stat = {'done':[],'running':[], 'not started': [], 'too long':[], 'not setup':[],'warning':[],'idk':[],'unconverged':[],'sgrcon':[],'error':[]} ======= stat = {'done':[],'running':[], 'not started': [], 'too long':[], 'not setup':[],'warning':[],'idk':[],'unconverged':[]} >>>>>>> 03893ba98eddd6991de841e54e88613fa8b4165d for dir in dirs: thisVASP = VASP(dir,systemSpecies = self.species) stat[thisVASP.status()].append(dir.split('/')[-1]) # msg.info("Status of directory {} is {} ".format(dir,thisVASP.status())) msg.info('Done (' + str(len(stat['done'])) + ')') msg.info(' '.join(stat['done'])) msg.info('Running (' + str(len(stat['running'])) + ')') msg.info(' '.join(stat['running'])) msg.info('Not Started (' + str(len(stat['not started'])) + ')') msg.info(' '.join(stat['not started'])) msg.info('Not Setup (' + str(len(stat['not setup'])) + ')') msg.info(' '.join(stat['not setup'])) msg.info('Too Long (' + str(len(stat['too long'])) + ') (last write was > 1 hr ago) ') msg.info(' '.join(stat['too long'])) msg.info('Warnings (' + str(len(stat['warning'])) + ')') msg.info(' '.join(stat['warning'])) msg.info('Not sure (' + str(len(stat['idk'])) + ') (Found finish tags but couldn''t find final energy. It''s probably in the process of finishing.)') msg.info(' '.join(stat['idk'])) msg.info('Unconverged (' + str(len(stat['unconverged'])) + ')') msg.info(' '.join(stat['unconverged']))
def setup_select(self): from os import path, remove from shutil import copy from glob import glob from aBuild.utility import cat from aBuild.fitting.mtp import MTP # 1. Concatenate all of the candidate.cfg_# into one candidate.cfg # and remove all of the other ones. # 2. Concatenate all of the selection.log_* files into one file. # 3. Concatenate all of the relaxed.cfg_# into one file. This file should # get bigger and bigger with each iteration (Hopefully), but we don't ever # want to delete one of these files. # 4. Build a submission script. # Find what iteration we are currently on. candIterationFiles = glob(path.join(self.root, "candidate_iteration_*")) relaxedIterationFiles = glob( path.join(self.root, "relaxed_iteration_*")) unrelaxedIterationFiles = glob( path.join(self.root, "unrelaxed_iteration_*")) if len(candIterationFiles) != len(relaxedIterationFiles) or len( candIterationFiles) != len(unrelaxedIterationFiles): msg.fatal( " I can't figure out what iteration we're on based on the files present. Have a look at all of the *_iteration_* files" ) if candIterationFiles != []: iteration = len(candIterationFiles) + 1 else: iteration = 1 # 1. Bring all of the candidate.cfg_* files together into one candFiles = glob(path.join(self.root, "candidate.cfg_*")) if candFiles != []: cat(candFiles, path.join(self.root, "candidate.temp"), remove=True) # Save a record copy( path.join(self.root, 'candidate.temp'), path.join(self.root, "candidate_iteration_" + str(iteration) + ".cfg")) # Prepare to select, which needs this file. copy(path.join(self.root, 'candidate.temp'), path.join(self.root, "candidate.cfg")) remove(path.join(self.root, 'candidate.temp')) else: msg.info("Can't find candidate.cfg_* files to concatenate") # 2. selection.log_* logFiles = glob(path.join(self.root, "selection.log_*")) if logFiles != []: cat(logFiles, path.join(self.root, "selection.temp"), remove=True) copy( path.join(self.root, 'selection.temp'), path.join(self.root, "selection_iteration_" + str(iteration) + ".log")) remove(path.join(self.root, 'selection.temp')) else: msg.info("Can't find selection.log_* files to concatenate") # 3. relaxed.cfg_* relaxedFiles = glob(path.join(self.root, "relaxed.cfg_*")) if relaxedFiles != []: cat(relaxedFiles, path.join(self.root, "relaxed.temp"), remove=True) copy( path.join(self.root, 'relaxed.temp'), path.join(self.root, "relaxed_iteration_" + str(iteration) + ".cfg")) remove(path.join(self.root, 'relaxed.temp')) else: msg.info("Can't find relaxed.cfg_* files to concatenate") # 4. unrelaxed.cfg_* unrelaxedFiles = glob(path.join(self.root, "unrelaxed.cfg_*")) if unrelaxedFiles != []: cat(unrelaxedFiles, path.join(self.root, "unrelaxed.temp"), remove=True) # Save a record of this iteration. May consider copying this file to to-relax.cfg next time we relax copy( path.join(self.root, 'unrelaxed.temp'), path.join(self.root, "unrelaxed_iteration_" + str(iteration) + ".cfg")) remove(path.join(self.root, 'unrelaxed.temp')) else: msg.info("Can't find unrelaxed.cfg_* files to concatenate") # 5. relax_log.txt_* relaxLogFiles = glob(path.join(self.root, "relax_log.txt_*")) if relaxLogFiles != []: cat(relaxLogFiles, path.join(self.root, "relax_log.temp"), remove=True) copy( path.join(self.root, 'relax_log.temp'), path.join(self.root, "relax_log_iteration_" + str(iteration) + ".txt")) remove(path.join(self.root, 'relax_log.temp')) else: msg.info("Can't find relax_log.txt_* files to concatenate") # 6. Build job submission script. self.select_add(self.settings["execution"])
def setup_relax(self, enumDicts, species, freshStart=False, AFM=False, start=1, end=None): from os import remove, path, rename from aBuild.fitting.mtp import MTP from glob import glob from shutil import copy self.dataset = "gss" # 1. If to-relax.cfg does not exist, build it. This # takes a while because we are putting a bunch of # structures in there. # 2. If to-relax.cfg does exist (iteration > 1), then # copy unrelaxed.cfg from previous iteration to to-relax.cfg # Note that there may be many unrelaxed.cfg_# from the parallel run # 3. Copy Trained.mtp to pot.mtp in preparation for the relaxation # 4. Build a relax.ini from template if it's not already there. # 5. Run calc-grade # 6. Build a submission script. filePath = path.join(self.root, 'to_relax.cfg') #unrelaxedfilePath = path.join(fittingRoot,'unrelaxed.cfg') torelax = path.isfile(filePath) #unrelaxed = path.isfile(unrelaxedfilePath) # 1. if not torelax: #This must be the first iteration print('Building a new to-relax.cfg file') self.build_ToRelax(enumDicts, species, AFM=AFM, start=start, end=end) # Write a bland potential file if this is the firt iteration self.write_blank_pot(len(species)) # Create an empty training set if this is the first iteration train = path.join(self.root, 'train.cfg') open(train, 'a').close() # 2. else: # What iteration is it? if freshStart: remove(filePath) self.build_ToRelax(enumDicts, species, AFM=AFM, start=start, end=end) # elif unrelaxed: #Iteration must be > 1 ## unrelaxedFiles = glob(path.join(fittingRoot,"unrelaxed.cfg_*")) ## cat(unrelaxedFiles,path.join(fittingRoot,"to-relax.cfg")) # remove(unrelaxedFiles) else: #"to-relax.cfg is present and I don't wanta fresh start. Don't do anything." # self.build_ToRelax(enumDicts,species) msg.info( "to-relax.cfg found and you told me to not start fresh. Proceeding with the to-relax.cfg that's there." ) #elif path.isfile(filePath): # Iteration # must be > 1 # rename(path.join(self.root,'fitting/mtp') # 3. try: print('copying Trained.mtp to pot.mtp') copy(path.join(self.root, 'Trained.mtp_'), path.join(self.root, 'pot.mtp')) except: if not path.isfile(path.join(self.root, 'Trained.mtp_')): msg.info( "Can't find Trained.mtp_ .You don't appear to have a trained potential ready" ) else: msg.info( "Not sure why the copy of Trained.mtp_ -> pot.mtp failed. You should investigate" ) # if path.isfile(path.join(self.root,'pot.mtp')): # msg.info('It looks like you have already copied Trained.mtp -> pot.mtp previously') # else: # msg.fatal("Can't find a pot.mtp or a Trained.mtp. Problems") # 4. self.write_relaxin() # 5. self.calc_grade() # 6. self.relax(self.settings["execution"])
def buildFolders(self, buildpath, calculator, runGetKpoints=True, foldername='E'): from os import path from aBuild.calculators.vasp import VASP from aBuild.calculators.lammps import LAMMPS from aBuild.calculators.espresso import ESPRESSO 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) lookupCalc = { 'vasp': lambda specs: VASP(specs), 'qe': lambda specs: ESPRESSO(specs, self.species), 'lammps': lambda specs: LAMMPS(specs, self.species) } lookupSpecs = { 'vasp': lambda crystal: { "incar": calculator["vasp"]["incar"], "kpoints": calculator["vasp"]["kpoints"], 'potcar': calculator["vasp"]["potcars"], "crystal": crystal }, 'qe': lambda crystal: { "crystal": crystal, "pseudopotentials": calculator["qe"]["pseudopotentials"] }, 'lammps': lambda crystal: { "crystal": crystal, "potential": calculator["lammps"]["potential"] } } lookupBuild = { 'vasp': lambda obj: obj.buildFolder(runGetKPoints=runGetKpoints), 'qe': lambda obj: obj.buildFolder(), 'lammps': lambda obj: obj.buildFolder() } for crystal in self.crystals: print("Building crystal {}".format(crystal.title)) #Augment the existing dictionary in preparation for sending it in calculator[calculator["active"]]["crystal"] = crystal calculator[calculator["active"]]["species"] = self.species # Initialize the calculation object print(calculator[calculator["active"]], 'check here') thisCalc = lookupCalc[calculator["active"]]( calculator[calculator["active"]]) # thisCalc = lookupCalc[calculator["active"]](lookupSpecs[calculator["active"]](crystal)) if 'AFM' in calculator[calculator[ "active"]] and thisCalc.crystal.AFMPlanes == None: msg.info( "Skipping this structure because I can't find the AFM planes" ) continue # Build the path 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)) # Change the directory and build the folder print("Building folder for structure: {}".format(crystal.title)) with chdir(runpath): lookupBuild[calculator["active"]](thisCalc) configIndex += 1 # Build the submission script exdir = path.join(buildpath, 'A.') mljob = Job(calculator["execution"], exdir, calculator["execution"]["exec_path"], arrayStart=startPoint, arrayEnd=configIndex - 1) with chdir(buildpath): print('Building job file') mljob.write_jobfile('jobscript_vasp.sh')
def statusReport(self): from os import path from glob import glob from aBuild.calculators.vasp import VASP trainingRoot = path.join(self.root, 'training_set') with chdir(trainingRoot): enumdirs = glob("E.*") activedirs = glob("A.*") dirs = [path.join(trainingRoot, x) for x in enumdirs + activedirs] stat = { 'done': [], 'running': [], 'not started': [], 'error': [], 'not setup': [] } for dir in dirs: thisVASP = VASP(dir, self.species) stat[thisVASP.status()].append(dir.split('/')[-1]) # msg.info("Status of directory {} is {} ".format(dir,thisVASP.status())) msg.info('Done') msg.info(' '.join(stat['done'])) msg.info('Running') msg.info(' '.join(stat['running'])) msg.info('Not Started') msg.info(' '.join(stat['not started'])) msg.info('Not Setup') msg.info(' '.join(stat['not setup'])) msg.info('Errors') msg.info(' '.join(stat['error']))
def setup_relax(self, enums, species, freshStart=False, AFM=False, start=1, end=None): from os import remove, path, rename from aBuild.fitting.mtp import MTP from glob import glob from shutil import copy self.dataset = "gss" # 1. If to-relax.cfg does not exist, build it. This # takes a while because we are putting a bunch of # structures in there. # 2. If to_relax.cfg does exist (iteration > 1), then # copy unrelaxed.cfg from previous iteration to to-relax.cfg # Note that there may be many unrelaxed.cfg_# from the parallel run # 3. Copy Trained.mtp to pot.mtp in preparation for the relaxation # 4. Build a relax.ini from template if it's not already there. # 5. Run calc-grade # 6. Build a submission script. filePath = path.join(self.root, 'to_relax.cfg') torelax = path.isfile(filePath) # 1. if not torelax: #This must be the first iteration print('Building a new to-relax.cfg file') self.build_ToRelax(enums, species, AFM=AFM, start=start, end=end) # Write a bland potential file if this is the first iteration self.write_blank_pot(len(species)) # Create an empty training set if this is the first iteration train = path.join(self.root, 'train.cfg') open(train, 'a').close() # 2. else: # What iteration is it? if freshStart: remove(filePath) self.build_ToRelax(enums, species, AFM=AFM, start=start, end=end) else: #"to-relax.cfg is present and I don't wanta fresh start. Don't do anything." msg.info( "to_relax.cfg found and you told me to not start fresh. Proceeding with the to-relax.cfg that's there." ) # 3. if path.isfile(path.join(self.root, 'Trained.mtp_')): copy(path.join(self.root, 'Trained.mtp_'), path.join(self.root, 'pot.mtp')) elif not path.isfile(path.join(self.root, 'pot.mtp')): self.write_blank_pot(len(species)) else: msg.info( 'Trained.mtp_ not found, but pot.mtp was found. Must have setup a first iteration previously! ' ) if not path.isfile(path.join(self.root, 'train.cfg')): train = path.join(self.root, 'train.cfg') open(train, 'a').close() else: msg.info("Found train.cfg. Iteration > 1?") # 4. self.write_relaxin() # 5. self.calc_grade() # 6. self.relax(self.settings["execution"])
def setup_select(self): from os import path, remove from shutil import copy from glob import glob from aBuild.utility import sed, grep, tail, cat from aBuild.fitting.mtp import MTP from math import ceil # 1. Concatenate all of the candidate.cfg_# into one candidate.cfg # and remove all of the other ones. # 2. Concatenate all of the selection.log_* files into one file. # 3. Concatenate all of the relaxed.cfg_# into one file. This file should # get bigger and bigger with each iteration (Hopefully), but we don't ever # want to delete one of these files. # 4. Save the old new_training.cfg # 5. Build a submission script. # Find what iteration we are currently on. candIterationFiles = glob(path.join(self.root, "candidate_iteration_*")) relaxedIterationFiles = glob( path.join(self.root, "relaxed_iteration_*")) unrelaxedIterationFiles = glob( path.join(self.root, "unrelaxed_iteration_*")) if len(candIterationFiles) != len(relaxedIterationFiles) or len( candIterationFiles) != len(unrelaxedIterationFiles): msg.fatal( " I can't figure out what iteration we're on based on the files present. Have a look at all of the *_iteration_* files" ) if candIterationFiles != []: iteration = len(candIterationFiles) + 1 else: iteration = 1 # 1. Bring all of the candidate.cfg_* files together into one candFiles = glob(path.join(self.root, "candidate.cfg_*")) if candFiles != []: cat(candFiles, path.join(self.root, "candidate.temp"), remove=True) # Save a record copy( path.join(self.root, 'candidate.temp'), path.join(self.root, "candidate_iteration_" + str(iteration) + ".cfg")) # Prepare to select, which needs this file. copy(path.join(self.root, 'candidate.temp'), path.join(self.root, "candidate.cfg")) remove(path.join(self.root, 'candidate.temp')) else: msg.info("Can't find candidate.cfg_* files to concatenate") candidatesFile = path.join(self.root, 'candidate.cfg') grepResults = grep(candidatesFile, 'begin', '-in') nCandidates = len(grepResults) print(nCandidates, 'Found this many candidates') # Sometimes the candidate.cfg file is really big and it is best to split it up into 2 or 3 files and select in quasi-parallel fashion if nCandidates > 1e6: with open(candidatesFile, 'r') as f: for i, l in enumerate(f): pass nLines = i + 1 nFiles = ceil(nCandidates / 1e6) nConfigs = ceil(nCandidates / nFiles) msg.info("Found lots of candidates, splitting into multiple files") start = 1 for fileNo in range(1, nFiles + 1): print("Building candidate file no: {}".format(fileNo)) if fileNo < nFiles: end = int(grepResults[nConfigs * fileNo].split(':')[0]) - 1 sed( '-n', str(start) + ',' + str(end) + ' p', candidatesFile, "> " + path.join(self.root, 'candidate_part_' + str(fileNo) + '.cfg')) else: tail( candidatesFile, nLines - end + 1, "> " + path.join(self.root, 'candidate_part_' + str(fileNo) + '.cfg')) self.settings["execution"]["mem_per_cpu"] = '72' self.select_add( self.settings["execution"], exeCommand= 'mlp_release_version select-add pot.mtp train.cfg candidate_part_' + str(fileNo) + '.cfg new_training_' + str(fileNo) + '.cfg', jobfile='jobscript_select_' + str(fileNo) + '.sh') start = end + 1 # 2. selection.log_* logFiles = glob(path.join(self.root, "selection.log_*")) if logFiles != []: cat(logFiles, path.join(self.root, "selection.temp"), remove=True) copy( path.join(self.root, 'selection.temp'), path.join(self.root, "selection_iteration_" + str(iteration) + ".log")) remove(path.join(self.root, 'selection.temp')) else: msg.info("Can't find selection.log_* files to concatenate") # 3. relaxed.cfg_* relaxedFiles = glob(path.join(self.root, "relaxed.cfg_*")) if relaxedFiles != []: cat(relaxedFiles, path.join(self.root, "relaxed.temp"), remove=True) copy( path.join(self.root, 'relaxed.temp'), path.join(self.root, "relaxed_iteration_" + str(iteration) + ".cfg")) remove(path.join(self.root, 'relaxed.temp')) else: msg.info("Can't find relaxed.cfg_* files to concatenate") # 4. unrelaxed.cfg_* unrelaxedFiles = glob(path.join(self.root, "unrelaxed.cfg_*")) if unrelaxedFiles != []: cat(unrelaxedFiles, path.join(self.root, "unrelaxed.temp"), remove=True) # Save a record of this iteration. May consider copying this file to to-relax.cfg next time we relax copy( path.join(self.root, 'unrelaxed.temp'), path.join(self.root, "unrelaxed_iteration_" + str(iteration) + ".cfg")) remove(path.join(self.root, 'unrelaxed.temp')) else: msg.info("Can't find unrelaxed.cfg_* files to concatenate") # 5. relax_log.txt_* relaxLogFiles = glob(path.join(self.root, "relax_log.txt_*")) if relaxLogFiles != []: cat(relaxLogFiles, path.join(self.root, "relax_log.temp"), remove=True) copy( path.join(self.root, 'relax_log.temp'), path.join(self.root, "relax_log_iteration_" + str(iteration) + ".txt")) remove(path.join(self.root, 'relax_log.temp')) else: msg.info("Can't find relax_log.txt_* files to concatenate") #6. save the new_training.cfg if path.isfile(path.join(self.root, 'new_training.cfg')): copy( path.join(self.root, 'new_training.cfg'), path.join( self.root, "new_training_iteration_" + str(iteration - 1) + ".cfg")) remove(path.join(self.root, 'new_training.cfg')) # 7. Build job submission script. self.select_add(self.settings["execution"])
'qe': lambda obj:obj.buildFolder(), 'lammps': lambda obj: obj.buildFolder()} for crystal in self.crystals: <<<<<<< HEAD print("Building crystal {}".format(crystal.title)) #Augment the existing dictionary in preparation for sending it in calculator[calculator["active"]]["crystal"] = crystal calculator[calculator["active"]]["species"] = self.species # Initialize the calculation object thisCalc = lookupCalc[calculator["active"]](calculator[calculator["active"]]) # thisCalc = lookupCalc[calculator["active"]](lookupSpecs[calculator["active"]](crystal)) if 'AFM' in calculator[calculator["active"]] and thisCalc.crystal.AFMPlanes == None: msg.info("Skipping this structure because I can't find the AFM planes") continue ======= ################################################################################ # crystal.validateCrystal() if self.special_settings["AFM"]: #if there's an AFM section in special settings crystal.get_spin( self.special_settings["AFM"]["plane"] , self.special_settings["AFM"]["spin_type"], eps = self.special_settings["eps"] ) #go get the spins ################################################################################ calculator[calculator["active"]]["crystal"] = crystal calculator[calculator["active"]]["species"] = self.species # Initialize the calculation object thisCalc = lookupCalc[calculator["active"]](calculator[calculator["active"]]) # thisCalc = lookupCalc[calculator["active"]](lookupSpecs[calculator["active"]](crystal)) >>>>>>> 03893ba98eddd6991de841e54e88613fa8b4165d
# 2. else: # What iteration is it? if freshStart: remove(filePath) <<<<<<< HEAD self.build_ToRelax(enumDicts,species,AFM = AFM,start = start,end = end) ======= self.build_ToRelax(enumDicts,species, start = start) >>>>>>> 03893ba98eddd6991de841e54e88613fa8b4165d # elif unrelaxed: #Iteration must be > 1 ## unrelaxedFiles = glob(path.join(fittingRoot,"unrelaxed.cfg_*")) ## cat(unrelaxedFiles,path.join(fittingRoot,"to-relax.cfg")) # remove(unrelaxedFiles) else: #"to-relax.cfg is present and I don't wanta fresh start. Don't do anything." # self.build_ToRelax(enumDicts,species) msg.info("to-relax.cfg found and you told me to not start fresh. Proceeding with the to-relax.cfg that's there.") #elif path.isfile(filePath): # Iteration # must be > 1 # rename(path.join(self.root,'fitting/mtp') # 3. try: print('copying Trained.mtp to pot.mtp') copy(path.join(self.root,'Trained.mtp_'),path.join(self.root,'pot.mtp')) except: if not path.isfile(path.join(self.root,'Trained.mtp_')): msg.info("Can't find Trained.mtp_ .You don't appear to have a trained potential ready" ) else: msg.info("Not sure why the copy of Trained.mtp_ -> pot.mtp failed. You should investigate") # if path.isfile(path.join(self.root,'pot.mtp')): # msg.info('It looks like you have already copied Trained.mtp -> pot.mtp previously')