Beispiel #1
0
    def setup(self, initdir):
        """ mv all files and directories (besides initdir) into initdir """

        print("Moving files into initial run directory:", initdir)
        initdir = os.path.abspath(initdir)
        for my_prop in os.listdir(self.propdir):
            if (my_prop in io.VASP_INPUT_FILE_LIST +
                    self.settings["extra_input_files"]) and (os.path.join(
                        self.propdir, my_prop) != initdir):
                os.rename(os.path.join(self.propdir, my_prop),
                          os.path.join(initdir, my_prop))
        print("")
        sys.stdout.flush()

        # Keep a backup copy of the base INCAR
        shutil.copyfile(os.path.join(initdir, "INCAR"),
                        os.path.join(self.propdir, "INCAR.base"))

        # If an initial incar is called for, copy it in and set the appropriate flag
        if (self.settings["initial"] != None) and (os.path.isfile(
                os.path.join(self.propdir, self.settings["initial"]))):
            new_values = io.Incar(
                os.path.join(self.propdir, self.settings["initial"])).tags
            io.set_incar_tag(new_values, initdir)
            print("  Set INCAR tags:", new_values, "\n")
            sys.stdout.flush()
Beispiel #2
0
 def fix(self, err_jobdir, new_jobdir, settings):
     """ Up symprec, or turn off symmetry"""
     continue_job(err_jobdir, new_jobdir, settings)
     symprec = io.get_incar_tag("SYMPREC", jobdir=new_jobdir)
     if symprec is None or symprec > 1.1e-8:
         print("  Set SYMPREC = 1e-8")
         io.set_incar_tag({"SYMPREC": 1e-8}, jobdir=new_jobdir)
     elif io.get_incar_tag("ISYM", jobdir=new_jobdir) != 0:
         print("  Set ISYM = 0")
         io.set_incar_tag({"ISYM": 0}, jobdir=new_jobdir)
Beispiel #3
0
 def fix(self, err_jobdir, new_jobdir, settings):
     """ Try to fix the error by changing the algo"""
     continue_job(err_jobdir, new_jobdir, settings)
     # Replace the potentially bad POSCAR
     shutil.copyfile(os.path.join(err_jobdir, "POSCAR"),
                     os.path.join(new_jobdir, "POSCAR"))
     # First, see if a change of ALGO helps
     curr_algo = io.get_incar_tag("ALGO", new_jobdir).upper()
     if curr_algo == 'FAST':
         io.set_incar_tag({
             "ALGO": "Normal",
             "IALGO": None
         },
                          jobdir=new_jobdir)
         print("  Set ALGO = Normal")
     elif curr_algo == 'NORMAL':
         io.set_incar_tag({"ALGO": "All", "IALGO": None}, jobdir=new_jobdir)
         print("  Set ALGO = All")
     elif curr_algo == 'ALL':
         io.set_incar_tag({
             "ALGO": "Damped",
             "IALGO": None
         },
                          jobdir=new_jobdir)
         io.set_incar_tag({"TIME": "0.4"}, jobdir=new_jobdir)
         print("  Set ALGO = Damped, TIME = 0.4")
Beispiel #4
0
 def fix(self, err_jobdir, new_jobdir, settings):
     """ First attempt:
             Set ALGO = VeryFast
             Unset IALGO
         Second attempt:
             Set IBRION = 1 and POTIM = 0.1
         Final attempt:
             Set LREAL = .FALSE.
     """
     continue_job(err_jobdir, new_jobdir, settings)
     if io.get_incar_tag("ALGO", jobdir=new_jobdir) != "VeryFast":
         print("  Set Algo = VeryFast, and Unset IALGO")
         io.set_incar_tag({
             "IALGO": None,
             "ALGO": "VeryFast"
         },
                          jobdir=new_jobdir)
     elif io.get_incar_tag("IBRION", jobdir=new_jobdir) != 1:
         print("  Set IBRION = 1 and POTIM = 0.1")
         sys.stdout.flush()
         io.set_incar_tag({"IBRION": 1, "POTIM": 0.1}, jobdir=new_jobdir)
     elif io.get_incar_tag("LREAL", jobdir=new_jobdir) != "False":
         print("  Set LREAL = .FALSE.")
         sys.stdout.flush()
         io.set_incar_tag({"LREAL": False}, jobdir=new_jobdir)
     else:
         print("  Set Algo = Normal, and Unset IALGO")
         sys.stdout.flush()
         io.set_incar_tag({
             "IALGO": None,
             "ALGO": "Normal"
         },
                          jobdir=new_jobdir)
Beispiel #5
0
 def fix(self, err_jobdir, new_jobdir, settings):
     """ Try to fix the error by increasing the number of bands"""
     continue_job(err_jobdir, new_jobdir, settings)
     with open(os.path.join(err_jobdir, 'OUTCAR')) as f:
         err_outcar = f.read().splitlines()
     nbands_line = []
     for line in err_outcar:
         if "NBANDS" in line:
             nbands_line.append(line)
     if len(nbands_line) < 1:
         print("SERIOUS WARNING :  ")
         print(
             "        Couldn't find any reference to nbands in the OUTCAR. Continuing without fixing"
         )
     else:
         for l in nbands_line:
             if 'k-points' in l.strip().split():
                 print("  Set NBANDS = " +
                       str(int(1.1 * float(l.strip().split()[-1]))))
                 sys.stdout.flush()
                 io.set_incar_tag(
                     {"NBANDS": int(1.1 * float(l.strip().split()[-1]))},
                     jobdir=new_jobdir)
                 break
Beispiel #6
0
    def setup(self, initdir, settings):
        """ mv all files and directories (besides initdir) into initdir """
        ### still has to handle the images

        print("Moving files and directories into initial run directory:",
              initdir)
        initdir = os.path.abspath(initdir)
        for p in os.listdir(self.calcdir):
            if (p in (io.VASP_INPUT_FILE_LIST +
                      self.settings["extra_input_files"])) and (os.path.join(
                          self.calcdir, p) != initdir):
                os.rename(os.path.join(self.calcdir, p),
                          os.path.join(initdir, p))
        ## copying the folders with image poscars into initdir
        for i in range(settings["n_images"] + 2):
            folder_name = str(i).zfill(
                2)  #max(2, len(str(settings["n_images"]))+1 )) ##too fancy!!!
            shutil.copytree(os.path.join(self.calcdir, "poscars", folder_name),
                            os.path.join(initdir, folder_name))

        print("")
        sys.stdout.flush()

        # Keep a backup copy of the base INCAR
        shutil.copyfile(os.path.join(initdir, "INCAR"),
                        os.path.join(self.calcdir, "INCAR.base"))
        os.rename(os.path.join(initdir, "POSCAR"),
                  os.path.join(self.calcdir, "POSCAR.start"))
        # If an initial incar is called for, copy it in and set the appropriate flag
        if (self.settings["initial"] != None) and (os.path.isfile(
                os.path.join(self.calcdir, self.settings["initial"]))):
            new_values = io.Incar(
                os.path.join(self.calcdir, self.settings["initial"])).tags
            io.set_incar_tag(new_values, initdir)
            print("  Set INCAR tags:", new_values, "\n")
            sys.stdout.flush()
Beispiel #7
0
 def fix(self, err_jobdir, new_jobdir, settings):
     """ First attempt:
             Set IBRION = 2
         Second attempt:
             Reduce POTIM to 0.1
         Final attempt:
             Reduce POTIM to 0.01
     """
     continue_job(err_jobdir, new_jobdir, settings)
     if io.get_incar_tag("IBRION", jobdir=new_jobdir) != 2:
         print("  Set IBRION = 2")
         io.set_incar_tag({"IBRION": 2}, jobdir=new_jobdir)
     elif io.get_incar_tag("POTIM", jobdir=new_jobdir) > 0.1:
         print("  Set POTIM = 0.1")
         sys.stdout.flush()
         io.set_incar_tag({"POTIM": 0.1}, jobdir=new_jobdir)
     elif io.get_incar_tag("POTIM", jobdir=new_jobdir) > 0.01:
         print("  Set POTIM = 0.01")
         sys.stdout.flush()
         io.set_incar_tag({"POTIM": 0.01}, jobdir=new_jobdir)
Beispiel #8
0
def run(jobdir=None,
        stdout="std.out",
        stderr="std.err",
        npar=None,
        ncore=None,
        command=None,
        ncpus=None,
        kpar=None,
        poll_check_time=5.0,
        err_check_time=60.0,
        err_types=None,
        is_neb=False):
    """ Run vasp using subprocess.

        The 'command' is executed in the directory 'jobdir'.

        Args:
            jobdir:     directory to run vasp.  If jobdir is None, the current directory is used.
            stdout:     filename to write to.  If stdout is None, "std.out" is used.
            stderr:     filename to write to.  If stderr is None, "std.err" is used.
            npar:       (int or None) VASP INCAR NPAR setting. If npar is None, then NPAR is removed from INCAR
            kpar:       (int or None) VASP INCAR KPAR setting. If kpar is None, then KPAR is removed from INCAR
            ncore:      (int or None) VASP INCAR NCORE setting. If not npar is None or ncore is None, then NCORE is removed from INCAR
            command:    (str or None) vasp execution command
                        If command != None: then 'command' is run in a subprocess
                        Else, if ncpus == 1, then command = "vasp"
                        Else, command = "mpirun -np {NCPUS} vasp"
            ncpus:      (int) if '{NCPUS}' is in 'command' string, then 'ncpus' is substituted in the command.
                        if ncpus==None, $PBS_NP is used if it exists, else 1
            poll_check_time: how frequently to check if the vasp job is completed
            err_check_time: how frequently to parse vasp output to check for errors
            err_types:  List of error types to check for. Supported errors: 'IbzkptError', 'SubSpaceMatrixError', 'NbandsError'. Default: None, in which case only SubSpaceMatrixErrors are checked.

    """
    print("Begin vasp run:")
    sys.stdout.flush()

    if jobdir is None:
        jobdir = os.getcwd()

    currdir = os.getcwd()
    os.chdir(jobdir)

    if ncpus is None:
        if "PBS_NP" in os.environ:
            ncpus = os.environ["PBS_NP"]
        elif "SLURM_NTASKS" in os.environ:
            ncpus = os.environ["SLURM_NTASKS"]
        else:
            ncpus = 1

    if command is None:
        if ncpus == 1:
            command = "vasp"
        else:
            command = "mpirun -np {NCPUS} vasp"

    if re.search("\{NCPUS\}", command):
        command = command.format(NCPUS=str(ncpus))

    ### Expand remaining environment variables
    command = os.path.expandvars(command)

    if npar is not None:
        ncore = None

    if npar is not None or ncore is not None:
        io.set_incar_tag({"NPAR": npar, "NCORE": ncore}, jobdir)

    if kpar is not None:
        io.set_incar_tag({"KPAR": kpar}, jobdir)

    print("  jobdir:", jobdir)
    print("  exec:", command)
    sys.stdout.flush()

    if is_neb:
        # checkdir = os.path.join(jobdir, "01")
        sout = open(os.path.join(jobdir, stdout), 'w')
    else:
        # checkdir = jobdir
        sout = open(os.path.join(jobdir, stdout), 'w')
    serr = open(os.path.join(jobdir, stderr), 'w')
    err = None
    p = subprocess.Popen(command.split(), stdout=sout, stderr=serr)

    # wait for process to end, and periodically check for errors
    poll = p.poll()
    last_check = time.time()
    stopcar_time = None
    while poll is None:
        time.sleep(poll_check_time)

        if time.time() - last_check > err_check_time:
            last_check = time.time()
            if is_neb:
                err = error_check_neb(jobdir, os.path.join(jobdir, stdout),
                                      err_types)
            else:
                err = error_check(jobdir, os.path.join(jobdir, stdout),
                                  err_types)
            if err != None:
                # FreezeErrors are fatal and usually not helped with STOPCAR
                if "FreezeError" in err.keys():
                    print("  VASP is frozen, killing job")
                    sys.stdout.flush()
                    # Sometimes p.kill doesn't work if the process is on multiple nodes
                    os.kill(p.pid, signal.SIGKILL)
                    p.kill()
                    # If the job is re-invoked (e.g. via mpirun or srun) too quickly
                    #   after the previous job ended, infinitiband clusters can have
                    #   some issues with resource allocation. A 30s sleep solves this.
                    time.sleep(30)
                # Other errors can be killed with STOPCAR, which is safer
                elif stopcar_time is None:
                    print("  Found errors:", end='')
                    for e in err:
                        print(e, end='')
                    print("\n  Killing job with STOPCAR")
                    sys.stdout.flush()
                    io.write_stopcar('e', jobdir)
                    stopcar_time = time.time()
                    time.sleep(30)
                # If the STOPCAR exists, wait 5 min before manually killing the job
                elif time.time() - stopcar_time > 300:
                    print("  VASP is non-responsive, killing job")
                    sys.stdout.flush()
                    os.kill(p.pid, signal.SIGKILL)
                    p.kill()
                    # If the job is re-invoked (e.g. via mpirun or srun) too quickly
                    #   after the previous job ended, infinitiband clusters can have
                    #   some issues with resource allocation. A 30s sleep solves this.
                    time.sleep(30)

        poll = p.poll()

    # close output files
    sout.close()
    serr.close()

    os.chdir(currdir)

    print("Run complete")
    sys.stdout.flush()

    # check finished job for errors
    if err is None:
        # Crash-type errors take priority over any other error that may show up
        if is_neb:  #if its neb it checks for crashes in the first image
            err = crash_check(os.path.join(jobdir, "01"),
                              os.path.join(jobdir, stdout), err_types)
        else:
            err = crash_check(jobdir, os.path.join(jobdir, stdout), err_types)
        if err is None:
            if is_neb:
                err = error_check_neb(jobdir, os.path.join(jobdir, stdout),
                                      err_types)
            else:
                err = error_check(jobdir, os.path.join(jobdir, stdout),
                                  err_types)
    if err != None:
        print("  Found errors:", end='')
        for e in err:
            print(e, end='')
    print("\n")
    sys.stdout.flush()

    return err
Beispiel #9
0
    def run(self):
        """ Perform a series of vasp jobs to relax a structure. Performs a series of vasp calculations until
            convergence is reached according to the criteria in 'status()'. Then performs a final constant volume run
            {"ISIF":2, "ISMEAR":-5, "NSW":0, "IBRION":-1}.
        """

        print("Begin VASP convergence run")
        sys.stdout.flush()

        # get current status of the relaxation:
        (status, task) = self.status()
        print("\n++  status:", status, "  next task:", task)
        sys.stdout.flush()

        while status == "incomplete":
            if task == "setup":
                self.add_rundir()
                self.setup(self.rundir[-1])

            elif task == "relax":
                self.add_rundir()
                continue_job(self.rundir[-2], self.rundir[-1], self.settings)
                shutil.copyfile(os.path.join(self.propdir, "INCAR.base"),
                                os.path.join(self.rundir[-1], "INCAR"))

            elif task == "constant":
                self.add_rundir()
                continue_job(self.rundir[-2], self.rundir[-1], self.settings)

                # set INCAR to ISIF = 2, ISMEAR = -5, NSW = 0, IBRION = -1
                if (self.settings["final"] != None) and (os.path.isfile(
                        os.path.join(self.propdir, self.settings["final"]))):
                    new_values = io.Incar(
                        os.path.join(self.propdir,
                                     self.settings["final"])).tags
                else:
                    new_values = {
                        "ISIF": 2,
                        "ISMEAR": -5,
                        "NSW": 0,
                        "IBRION": -1
                    }

                # set INCAR system tag to denote 'final'
                if io.get_incar_tag("SYSTEM", self.rundir[-1]) is None:
                    new_values["SYSTEM"] = "final"
                else:
                    new_values["SYSTEM"] = io.get_incar_tag(
                        "SYSTEM", self.rundir[-1]) + " final"

                io.set_incar_tag(new_values, self.rundir[-1])
                print("  Set INCAR tags:", new_values, "\n")
                sys.stdout.flush()

            else:
                # probably hit walltime
                self.add_rundir()
                continue_job(self.rundir[-2], self.rundir[-1], self.settings)

            while True:
                # run vasp
                result = run(self.rundir[-1],
                             npar=self.settings["npar"],
                             ncore=self.settings["ncore"],
                             command=self.settings["vasp_cmd"],
                             ncpus=self.settings["ncpus"],
                             kpar=self.settings["kpar"],
                             err_types=self.settings["err_types"])

                # if no errors, continue
                if result is None or self.not_converging():
                    # Check for actions that should be taken after the initial run
                    if len(self.rundir) == 1:
                        if self.settings["fine_ngx"]:
                            outcarfile = os.path.join(self.rundir[-1],
                                                      "OUTCAR")
                            if not os.path.isfile(outcarfile):
                                # This is an error but I'm not sure what to do about it
                                pass
                            else:
                                init_outcar = io.Outcar(outcarfile)
                                if not init_outcar.complete:
                                    # This is an error but I'm not sure what to do about it
                                    pass
                                elif (init_outcar.ngx is None
                                      or init_outcar.ngy is None
                                      or init_outcar.ngz is None):
                                    # This is an error but I'm not sure what to do about it
                                    pass
                                else:
                                    ng_tags = {
                                        "ngx": init_outcar.ngx * 2,
                                        "ngy": init_outcar.ngy * 2,
                                        "ngz": init_outcar.ngz * 2
                                    }
                                    print(ng_tags)
                                    io.set_incar_tag(ng_tags, self.propdir,
                                                     "INCAR.base")

                    break

                # else, attempt to fix first error
                self.add_errdir()
                os.mkdir(self.rundir[-1])
                # self.add_rundir()
                err = result.itervalues().next()

                print("\n++  status:", "error", "  next task:", "fix_error")
                sys.stdout.flush()

                print("Attempting to fix error:", str(err))
                err.fix(self.errdir[-1], self.rundir[-1], self.settings)
                print("")
                sys.stdout.flush()

                if (self.settings["backup"] != None) and len(self.rundir) > 1:
                    print("Restoring from backups:")
                    for my_file in self.settings["backup"]:
                        if os.path.isfile(
                                os.path.join(self.rundir[-2],
                                             my_file + "_BACKUP.gz")):
                            f_in = gzip.open(
                                os.path.join(self.rundir[-2],
                                             my_file + "_BACKUP.gz", 'rb'))
                            f_out = open(
                                os.path.join(self.rundir[-1], my_file, 'wb'))
                            f_out.write(f_in.read())
                            f_in.close()
                            f_out.close()
                            print(my_file, " restored!")
                    sys.stdout.flush()

            (status, task) = self.status()
            print("\n++  status:", status, "  next task:", task)
            sys.stdout.flush()

        if status == "complete":
            if not os.path.isdir(self.finaldir):
                # mv final results to relax.final
                print("mv", os.path.basename(self.rundir[-1]),
                      os.path.basename(self.finaldir))
                sys.stdout.flush()
                os.rename(self.rundir[-1], self.finaldir)
                self.rundir.pop()
                complete_job(self.finaldir, self.settings)

        return (status, task)
Beispiel #10
0
    def run(self):
        """ Perform a series of vasp jobs to run calculations. Performs a series of vasp calculations until
            convergence is reached according to the criteria in 'status()'.
        """

        print("Begin VASP relaxation run")
        sys.stdout.flush()

        # get current status of the relaxation:
        (status, task) = self.status()
        print("\n++  status:", status, "  next task:", task)
        sys.stdout.flush()

        while status == "incomplete":
            if task == "setup":
                self.add_rundir()
                self.setup(self.rundir[-1], self.settings)

            elif task == "new_run":
                self.add_rundir()
                # if "n_images" in settings then image CONTCARs will be copied
                casm.vasp.continue_job(self.rundir[-2], self.rundir[-1],
                                       self.settings)
                shutil.copyfile(
                    os.path.join(self.calcdir, "INCAR.base"),
                    os.path.join(self.rundir[-1],
                                 "INCAR"))  ## should it be enforced??
            elif task == "constant":
                self.add_rundir()
                # if "n_images" in settings then image CONTCARs will be copied
                casm.vasp.continue_job(self.rundir[-2], self.rundir[-1],
                                       self.settings)

                # set INCAR to ISIF = 2, ISMEAR = -5, NSW = 0, IBRION = -1
                if (self.settings["final"] != None) and (os.path.isfile(
                        os.path.join(self.calcdir, self.settings["final"]))):
                    new_values = io.Incar(
                        os.path.join(self.calcdir,
                                     self.settings["final"])).tags
                else:
                    new_values = {
                        "ISIF": 2,
                        "ISMEAR": -5,
                        "NSW": 0,
                        "IBRION": -1
                    }

                # set INCAR system tag to denote 'final'
                if io.get_incar_tag("SYSTEM", self.rundir[-1]) is None:
                    new_values["SYSTEM"] = "final"
                else:
                    new_values["SYSTEM"] = io.get_incar_tag(
                        "SYSTEM", self.rundir[-1]) + " final"

                io.set_incar_tag(new_values, self.rundir[-1])
                print("  Set INCAR tags:", new_values, "\n")
                sys.stdout.flush()

            else:  ## redundent
                self.add_rundir()
                casm.vasp.continue_job(self.rundir[-2], self.rundir[-1],
                                       self.settings)

            while True:
                # run vasp
                result = casm.vasp.run(self.rundir[-1],
                                       stdout="stdout",
                                       npar=self.settings["npar"],
                                       ncore=self.settings["ncore"],
                                       command=self.settings["vasp_cmd"],
                                       ncpus=self.settings["ncpus"],
                                       kpar=self.settings["kpar"],
                                       err_types=self.settings["err_types"],
                                       is_neb=True)

                # if no errors, continue
                if result is None or self.not_converging():
                    break

                # else, attempt to fix first error
                self.add_errdir()
                os.mkdir(self.rundir[-1])
                # self.add_rundir()
                err = result.itervalues().next()

                print("\n++  status:", "error", "  next task:", "fix_error")
                sys.stdout.flush()

                print("Attempting to fix error:", str(err))
                err.fix(self.errdir[-1], self.rundir[-1], self.settings)
                print("")
                sys.stdout.flush()

            (status, task) = self.status()
            print("\n++  status:", status, "  next task:", task)
            sys.stdout.flush()

        if status == "complete":
            if not os.path.isdir(self.finaldir):
                # mv final results to relax.final
                print("mv", os.path.basename(self.rundir[-1]),
                      os.path.basename(self.finaldir))
                sys.stdout.flush()
                os.rename(self.rundir[-1], self.finaldir)
                self.rundir.pop()
                casm.vasp.complete_job(self.finaldir, self.settings)

        return (status, task)