Beispiel #1
0
    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 != []:

            print('Building dataset')
            trainingSet = dataset(dirs, species, calculator='VASP')  #####

        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"] < 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.train(self.settings["execution"])
Beispiel #2
0
def read(context, yfile):
    """Reads in the specified YAML file, following any additional file
    directives to compile a full representation of the template hierarchy for
    the root file.

    Args:
        context (str): path to the root folder where the yaml file is
          located. Needed for relative paths of file links.
        yfile (str): name of the template YAML file *relative* to
        `context`. Should *not* include the `.yaml` or `.yml` extension.
    """
    with chdir(context):
        if yfile[0] == ":":
            root = path.abspath(yfile[1:])
        else:
            root = path.abspath(yfile)

    if path.isfile(root + ".yml"):
        target = root + ".yml"
    else:
        emsg = ("The specified template file '{}' was not found relative "
                "to the given context directory ('{}'). Note that all files"
                " should use the `.yml` extension, *not* `.yaml`.")
        raise ValueError(emsg.format(yfile, context))

    with open(target, 'r') as stream:
        result = yaml.load(stream)

    #Determine the new context for recursive file links within the values of
    #this file.
    ncontext = path.dirname(target)

    #The specification allows for a "local" context that describes folder
    #locations for specific items within the template.
    lcontext = None
    if isinstance(result, dict) and "context" in result:
        lcontext = result["context"]
        del result["context"]

    #The unpacking command will mutate the values in result so that file links
    #are expanded to be full-fledged python objects from their YAML files.
    _unpack_obj(ncontext, result, lcontext)
    return result
Beispiel #3
0
def _unpack_obj(context, obj, lcontext=None):
    """Unpacks each item of the specified object recursively so that all
    dictionary values are visited and all list items are also visited.

    .. warning:: `obj` will be mutated if any value it considers turns out to be
      a link (according to :func:`is_link`). In that case, the file descriptor
      will be placed by the actual contents of the YAML file that the link
      points to.

    Args:
        context (str): path to the root folder where the yaml file is
          located. Needed for relative paths of file links.
        lcontext (dict): local context for the items in `obj`. Keys are the
          names of keys in `obj`; values are relative folder paths that should
          be used as the context for reads within that item.
    """
    if isinstance(obj, dict):
        result = obj
        for k, o in obj.items():
            ncontext = context
            #If the template specifies a relative context for this item,
            #then switch out the context for all of its children.
            if lcontext is not None and k in lcontext:
                with chdir(context):
                    ncontext = path.abspath(lcontext[k])

            if is_link(o):
                result[k] = read(ncontext, o)
            else:
                result[k] = _unpack_obj(ncontext, o)
    elif isinstance(obj, (list, set, tuple)):
        result = []
        for o in obj:
            if is_link(o):
                result.append(read(context, o))
            else:
                result.append(_unpack_obj(context, o))
    else:
        result = obj

    return result
Beispiel #4
0
 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))
Beispiel #5
0
    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] + '  ')
Beispiel #6
0
    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')
Beispiel #7
0
<<<<<<< HEAD
        dSet = dataset(newTraining,self.species,lFormat = 'mlp')
=======
############################################################################3
        self.special_settings["eps"] = 5e-2 #epsilon for checking if atoms are in same layer
############################################################################
        dSet = dataset(newTraining,self.species,special_settings = self.special_settings,lFormat = 'mlpselect')######### ADDED SPECIAL_SETTINGS
>>>>>>> 03893ba98eddd6991de841e54e88613fa8b4165d
        dSet.buildFolders(trainingRoot,self.calculator,foldername = 'A')
        
    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]
<<<<<<< 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']))
Beispiel #8
0
    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')
Beispiel #9
0
>>>>>>> 03893ba98eddd6991de841e54e88613fa8b4165d
            # 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))

<<<<<<< HEAD
                # Change the directory and build the folder
            print("Building folder for structure: {}".format(crystal.title) )
=======
            # Change the directory and build the folder
            print("Building folder {} for structure: {}".format(configIndex,crystal.title) )
>>>>>>> 03893ba98eddd6991de841e54e88613fa8b4165d
            with chdir(runpath):
                lookupBuild[calculator["active"]](thisCalc)
            configIndex += 1
            

        # Build the submission script
        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('jobscript_vasp.sh')




Beispiel #10
0
    def status(self):
        from os import path
        from time import time
        from aBuild.utility import grep
        import os
        fTagStatic = '------------------------ aborting loop because EDIFF is reached ----------------------------------------\n'
        fTagRelax = ' writing wavefunctions'
        ctime = time()
        print('checking directory {}'.format(self.directory))
        with chdir(self.directory):
            outcar = self._check_file_exists('OUTCAR')
            incar = self._check_file_exists('INCAR')
            kpoints = self._check_file_exists('KPOINTS')
            potcar = self._check_file_exists('POTCAR')
            poscar = self._check_file_exists('POSCAR')
            output = self._check_file_exists('vasp_output')
            oszicar = self._check_file_exists('OSZICAR')
            

            inputs = incar and kpoints and potcar and poscar

            ''' Check to see if the input files are present
                if they aren't, no need to proceed, just return
                'not setup'
            '''
            if not inputs:
                return 'not setup'

                ''' If the OUTCAR file is present, we know that we're
                    either running, finished successfully, or finished
                    with errors!
                '''
            elif outcar: # OUTCAR present

                sgrcon = grep('vasp_output','SGRCON')
                tooclose = grep('vasp_output','HOPE')
                finalenergyline = grep('OUTCAR','free  energy')
                generalerror = grep('vasp_output','ERROR')
                # Check to make sure I've converged electonically.
                if grep('OSZICAR','DAV:') != []:
                    electronicIteration = int(grep('OSZICAR','DAV:')[-1].split()[1])
                else:
                    electronicIteration = 0
                if grep('INCAR','nsw') != []:
                    nsw = int(grep('INCAR','nsw')[0].split('=')[1])
                    if nsw == 0:
                        nsw = 1
                else:
                    nsw = 1
                if grep('OSZICAR','F=') != []:
                    ionicIteration = int(grep('OSZICAR','F=')[-1].split()[0])
                else:
                    ionicIteration = 1
                if grep('INCAR','nelm') != []:
                    maxelectronic = grep('INCAR','nelm')[0].split('=')[1]
                else:
                    maxelectronic = 60
                if ionicIteration == nsw and int(electronicIteration) == int(maxelectronic):
                    return 'unconverged'
                    
                ''' Let's first check to see if this is a static
                calculation or a relaxation because the tag 
                to check for is different.'''
                if incar:
                    relax = grep('INCAR','IBRION')
                    if '-1' not in relax or relax is []:
                            static = True
                    else:
                            static = False
                else:
                    return 'not setup'
                    
                ''' Check finish tag for static calc'''
                if static and self._check_tag_exists('OUTCAR', fTagStatic):  #finish tag found
                    if finalenergyline != []:  #Let's double check
                        return 'done'
                    else:  # Apparently not,  why?
                        return 'idk'
                    
                    ''' Check finish tag for relax calc'''
                elif self._check_tag_exists('OUTCAR',fTagRelax): #Looks like it's done
                    if finalenergyline != []:  # Let's double check
                        return 'done'
                    else:  # Apparently not, why?
                        return 'idk'
                else:
                        
                    ''' Check how long since the last file write.  If it was recent
                     then we're probably running.'''
                    time = path.getmtime('OUTCAR')
                    if (ctime - time) < 3600:  # If the OUTCAR was modified in the last hour
                                              # the calculation is probably still running.
                        return 'running'
                    elif sgrcon:
                        return 'sgrcon'
                    elif generalerror:
                        return 'error'
                    elif tooclose:
                        return 'warning'
                    else:
                        return 'too long'
                    
            else:
                    return 'not started'
                    
                        
            if output:
                    warning = grep('output','RRRRR') != [] or grep('output','AAAAAA') != []
                    if warning:
                        return 'warning'



                
        return folderstat