Example #1
0
    def setup(self):
        """
        Performs initial setup for VaspJob, including overriding any settings
        and backing up.
        """
        decompress_dir('.')

        if self.backup:
            for f in VASP_INPUT_FILES:
                shutil.copy(f, "{}.orig".format(f))

        if self.auto_npar:
            try:
                incar = Incar.from_file("INCAR")
                # Only optimized NPAR for non-HF and non-RPA calculations.
                if not (incar.get("LHFCALC") or incar.get("LRPA") or
                        incar.get("LEPSILON")):
                    if incar.get("IBRION") in [5, 6, 7, 8]:
                        # NPAR should not be set for Hessian matrix
                        # calculations, whether in DFPT or otherwise.
                        del incar["NPAR"]
                    else:
                        import multiprocessing
                        # try sge environment variable first
                        # (since multiprocessing counts cores on the current
                        # machine only)
                        ncores = os.environ.get('NSLOTS') or \
                            multiprocessing.cpu_count()
                        ncores = int(ncores)
                        for npar in range(int(math.sqrt(ncores)),
                                          ncores):
                            if ncores % npar == 0:
                                incar["NPAR"] = npar
                                break
                    incar.write_file("INCAR")
            except:
                pass

        if self.auto_continue:
            if os.path.exists("continue.json"):
                actions = loadfn("continue.json").get("actions")
                logger.info("Continuing previous VaspJob. Actions: {}".format(actions))
                backup(VASP_BACKUP_FILES, prefix="prev_run")
                VaspModder().apply_actions(actions)

            else:
                # Default functionality is to copy CONTCAR to POSCAR and set
                # ISTART to 1 in the INCAR, but other actions can be specified
                if self.auto_continue is True:
                    actions = [{"file": "CONTCAR",
                                "action": {"_file_copy": {"dest": "POSCAR"}}},
                               {"dict": "INCAR",
                                "action": {"_set": {"ISTART": 1}}}]
                else:
                    actions = self.auto_continue
                dumpfn({"actions": actions}, "continue.json")

        if self.settings_override is not None:
            VaspModder().apply_actions(self.settings_override)
Example #2
0
    def correct(self):
        backup(VASP_BACKUP_FILES)
        vi = VaspInput.from_directory(".")
        potim = float(vi["INCAR"].get("POTIM", 0.5))
        ibrion = int(vi["INCAR"].get("IBRION", 0))
        if potim < 0.2 and ibrion != 3:
            actions = [{
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "IBRION": 3,
                        "SMASS": 0.75
                    }
                }
            }]
        else:
            actions = [{
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "POTIM": potim * 0.5
                    }
                }
            }]

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": ["POTIM"], "actions": actions}
Example #3
0
    def correct(self):
        backup(VASP_BACKUP_FILES)
        actions = []
        vi = VaspInput.from_directory(".")

        incar = vi["INCAR"]
        outcar = Outcar("OUTCAR")

        # Move CONTCAR to POSCAR
        actions.append({"file": "CONTCAR",
                        "action": {"_file_copy": {"dest": "POSCAR"}}})

        # First try adding ADDGRID
        if not incar.get("ADDGRID", False) :
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ADDGRID": True}}})
        # Otherwise set PREC to High so ENAUG can be used to control Augmentation Grid Size
        elif incar.get("PREC", "Accurate").lower() != "high":
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"PREC": "High"}}})
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ENAUG": incar.get("ENCUT", 520) * 2}}})
        # PREC is already high and ENAUG set so just increase it
        else:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ENAUG": int(incar.get("ENAUG", 1040) * self.enaug_multiply)}}})


        curr_drift = outcar.data.get("drift", [])[::-1][:self.to_average]
        curr_drift = np.average([np.linalg.norm(d) for d in curr_drift])
        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": "Excessive drift {} > {}".format(curr_drift, self.max_drift), "actions": actions}
Example #4
0
 def test_seg_fault(self):
     vi = VaspInput.from_directory(".")
     from custodian.vasp.interpreter import VaspModder
     VaspModder(vi=vi).apply_actions([{
         "dict": "INCAR",
         "action": {
             "_set": {
                 "KPAR": 4
             }
         }
     }])
     h = StdErrHandler("std_err.txt.seg_fault", correct_seg_fault=True)
     self.assertEqual(h.check(), True)
     d = h.correct()
     self.assertEqual(d["errors"], ['seg_fault'])
     self.assertEqual(d["actions"], [{
         'dict': 'INCAR',
         'action': {
             '_set': {
                 'ISMEAR': '0'
             }
         }
     }])
     self.assertEqual(h.check(), True)
     d = h.correct()
     self.assertEqual(d["errors"], ['seg_fault'])
     # no fix if still seg fault
     self.assertEqual(d["actions"], [])
Example #5
0
    def setup(self):
        """
        Performs initial setup for VaspNEBJob, including overriding any settings
        and backing up.
        """
        neb_dirs = self.neb_dirs

        if self.backup:
            # Back up KPOINTS, INCAR, POTCAR
            for f in VASP_NEB_INPUT_FILES:
                shutil.copy(f, "{}.orig".format(f))
            # Back up POSCARs
            for path in neb_dirs:
                poscar = os.path.join(path, "POSCAR")
                shutil.copy(poscar, "{}.orig".format(poscar))

        if self.half_kpts and os.path.exists("KPOINTS"):
            kpts = Kpoints.from_file("KPOINTS")
            kpts.kpts = np.maximum(np.array(kpts.kpts) / 2, 1)
            kpts.kpts = kpts.kpts.astype(int).tolist()
            if tuple(kpts.kpts[0]) == (1, 1, 1):
                kpt_dic = kpts.as_dict()
                kpt_dic["generation_style"] = 'Gamma'
                kpts = Kpoints.from_dict(kpt_dic)
            kpts.write_file("KPOINTS")

        if self.auto_npar:
            try:
                incar = Incar.from_file("INCAR")
                import multiprocessing
                # Try sge environment variable first
                # (since multiprocessing counts cores on the current
                # machine only)
                ncores = os.environ.get(
                    'NSLOTS') or multiprocessing.cpu_count()
                ncores = int(ncores)
                for npar in range(int(math.sqrt(ncores)), ncores):
                    if ncores % npar == 0:
                        incar["NPAR"] = npar
                        break
                incar.write_file("INCAR")
            except:
                pass

        if self.auto_continue and \
                os.path.exists("STOPCAR") and \
                not os.access("STOPCAR", os.W_OK):
            # Remove STOPCAR
            os.chmod("STOPCAR", 0o644)
            os.remove("STOPCAR")

            # Copy CONTCAR to POSCAR
            for path in self.neb_sub:
                contcar = os.path.join(path, "CONTCAR")
                poscar = os.path.join(path, "POSCAR")
                shutil.copy(contcar, poscar)

            if self.settings_override is not None:
                VaspModder().apply_actions(self.settings_override)
Example #6
0
    def setup(self):
        """
        Method is identical to custodian.vasp.jobs.setup(), except that the
        environment variable PBS_NUM_PPN is checked first when auto_npar =
        True.
        """
        files = os.listdir(".")
        num_structures = 0
        if not set(files).issuperset(VASP_INPUT_FILES):
            for f in files:
                try:
                    struct = read_structure(f)
                    num_structures += 1
                except:
                    pass
            if num_structures != 1:
                raise RuntimeError(
                    "{} structures found. Unable to continue.".format(
                        num_structures))
            else:
                self.default_vis.write_input(struct, ".")

        if self.backup:
            for f in VASP_INPUT_FILES:
                shutil.copy(f, "{}.orig".format(f))

        if self.auto_npar:
            try:
                incar = Incar.from_file("INCAR")
                # Only optimized NPAR for non-HF and non-RPA calculations.
                if not (incar.get("LHFCALC") or incar.get("LRPA")
                        or incar.get("LEPSILON")):
                    if incar.get("IBRION") in [5, 6, 7, 8]:
                        # NPAR should not be set for Hessian matrix
                        # calculations, whether in DFPT or otherwise.
                        del incar["NPAR"]
                    else:
                        import multiprocessing
                        # try pbs environment variable first
                        # try sge environment variable second
                        # Note!
                        # multiprocessing.cpu_count() will include hyperthreads
                        # in the CPU count, which will set NPAR to be too large
                        # and can cause the job to hang if you use compute
                        # nodes with scratch partitions.
                        ncores = (os.environ.get("PBS_NUM_PPN")
                                  or os.environ.get('NSLOTS')
                                  or multiprocessing.cpu_count())
                        ncores = int(ncores)
                        for npar in range(int(math.sqrt(ncores)), ncores):
                            if ncores % npar == 0:
                                incar["NPAR"] = npar
                                break
                    incar.write_file("INCAR")
            except:
                pass

        if self.settings_override is not None:
            VaspModder().apply_actions(self.settings_override)
Example #7
0
    def correct(self):
        # if change_algo is True, change ALGO = Fast to Normal if ALGO is
        # Fast. If still not converging, following Kresse's
        # recommendation, we will try two iterations of different mixing
        # parameters. If this error is caught again, then kil the job
        vi = VaspInput.from_directory(".")
        algo = vi["INCAR"].get("ALGO", "Normal")
        amix = vi["INCAR"].get("AMIX", 0.4)
        bmix = vi["INCAR"].get("BMIX", 1.0)
        amin = vi["INCAR"].get("AMIN", 0.1)
        actions = []
        if self.change_algo:
            if algo == "Fast":
                backup(VASP_BACKUP_FILES)
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ALGO": "Normal"
                        }
                    }
                })

            elif amix > 0.1 and bmix > 0.01:
                #try linear mixing
                backup(VASP_BACKUP_FILES)
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "AMIX": 0.1,
                            "BMIX": 0.01,
                            "ICHARG": 2
                        }
                    }
                })

            elif bmix < 3.0 and amin > 0.01:
                #Try increasing bmix
                backup(VASP_BACKUP_FILES)
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "AMIN": 0.01,
                            "BMIX": 3.0,
                            "ICHARG": 2
                        }
                    }
                })

        if actions:
            VaspModder(vi=vi).apply_actions(actions)
            return {"errors": ["Non-converging job"], "actions": actions}

        #Unfixable error. Just return None for actions.
        else:
            return {"errors": ["Non-converging job"], "actions": None}
Example #8
0
 def correct(self):
     backup(VASP_BACKUP_FILES | {self.output_filename})
     vi = VaspInput.from_directory(".")
     m = reduce(operator.mul, vi["KPOINTS"].kpts[0])
     m = max(int(round(m ** (1 / 3))), 1)
     if vi["KPOINTS"].style.name.lower().startswith("m"):
         m += m % 2
     actions = [{"dict": "KPOINTS",
                 "action": {"_set": {"kpoints": [[m] * 3]}}}]
     VaspModder(vi=vi).apply_actions(actions)
     return {"errors": ["mesh_symmetry"], "actions": actions}
Example #9
0
    def setup(self):
        """
        Performs initial setup for VaspJob, including overriding any settings
        and backing up.
        """

        if self.backup:
            for f in VASP_INPUT_FILES:
                shutil.copy(f, "{}.orig".format(f))

        if self.auto_npar:
            try:
                incar = Incar.from_file("INCAR")
                # Only optimized NPAR for non-HF and non-RPA calculations.
                if not (incar.get("LHFCALC") or incar.get("LRPA")
                        or incar.get("LEPSILON")):
                    if incar.get("IBRION") in [5, 6, 7, 8]:
                        # NPAR should not be set for Hessian matrix
                        # calculations, whether in DFPT or otherwise.
                        del incar["NPAR"]
                    else:
                        import multiprocessing
                        # try sge environment variable first
                        # (since multiprocessing counts cores on the current
                        # machine only)
                        ncores = os.environ.get('NSLOTS') or \
                            multiprocessing.cpu_count()
                        ncores = int(ncores)
                        for npar in range(int(math.sqrt(ncores)), ncores):
                            if ncores % npar == 0:
                                incar["NPAR"] = npar
                                break
                    incar.write_file("INCAR")
            except:
                pass

        # Auto continue if a read-only STOPCAR is present
        if self.auto_continue and \
           os.path.exists("STOPCAR") and \
           not os.access("STOPCAR", os.W_OK):
            # Remove STOPCAR
            os.chmod("STOPCAR", 0o644)
            os.remove("STOPCAR")

            # Setup INCAR to continue
            incar = Incar.from_file("INCAR")
            incar['ISTART'] = 1
            incar.write_file("INCAR")

            shutil.copy('CONTCAR', 'POSCAR')

        if self.settings_override is not None:
            VaspModder().apply_actions(self.settings_override)
Example #10
0
    def setup(self):
        """
        Performs initial setup for VaspJob, including overriding any settings
        and backing up.
        """
        files = os.listdir(".")
        num_structures = 0
        if not set(files).issuperset(VASP_INPUT_FILES):
            for f in files:
                try:
                    struct = read_structure(f)
                    num_structures += 1
                except:
                    pass
            if num_structures != 1:
                raise RuntimeError(
                    "{} structures found. Unable to continue.".format(
                        num_structures))
            else:
                self.default_vis.write_input(struct, ".")

        if self.backup:
            for f in VASP_INPUT_FILES:
                shutil.copy(f, "{}.orig".format(f))

        if self.auto_npar:
            try:
                incar = Incar.from_file("INCAR")
                #Only optimized NPAR for non-HF and non-RPA calculations.
                if not (incar.get("LHFCALC") or incar.get("LRPA")
                        or incar.get("LEPSILON")):
                    if incar.get("IBRION") in [5, 6, 7, 8]:
                        # NPAR should not be set for Hessian matrix
                        # calculations, whether in DFPT or otherwise.
                        del incar["NPAR"]
                    else:
                        import multiprocessing
                        # try sge environment variable first
                        # (since multiprocessing counts cores on the current machine only)
                        ncores = os.environ.get(
                            'NSLOTS') or multiprocessing.cpu_count()
                        ncores = int(ncores)
                        for npar in range(int(round(math.sqrt(ncores))),
                                          ncores):
                            if ncores % npar == 0:
                                incar["NPAR"] = npar
                                break
                    incar.write_file("INCAR")
            except:
                pass

        if self.settings_override is not None:
            VaspModder().apply_actions(self.settings_override)
Example #11
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})

        vi = VaspInput.from_directory('.')
        actions = []
        if vi["INCAR"].get("ALGO", "Normal") == "Fast":
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ALGO": "Normal"}}})

        VaspModder(vi=vi).apply_actions(actions)

        return {"errors": ["Frozen job"], "actions": actions}
Example #12
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        vi = VaspInput.from_directory(".")
        ediff = float(vi["INCAR"].get("EDIFF", 1e-4))
        ediffg = float(vi["INCAR"].get("EDIFFG", ediff * 10))
        actions = [{"file": "CONTCAR",
                    "action": {"_file_copy": {"dest": "POSCAR"}}},
                   {"dict": "INCAR",
                    "action": {"_set": {"EDIFFG": ediffg * 0.5}}}]
        VaspModder(vi=vi).apply_actions(actions)

        return {"errors": ["MaxForce"], "actions": actions}
Example #13
0
 def test_oom(self):
     vi = VaspInput.from_directory(".")
     from custodian.vasp.interpreter import VaspModder
     VaspModder(vi=vi).apply_actions([{"dict": "INCAR",
                                       "action": {"_set": {"KPAR": 4}}}])
     h = StdErrHandler("std_err.txt.oom")
     self.assertEqual(h.check(), True)
     d = h.correct()
     self.assertEqual(d["errors"], ['out_of_memory'])
     self.assertEqual(d["actions"],
                      [{'dict': 'INCAR',
                        'action': {'_set': {'KPAR': 2}}}])
Example #14
0
 def correct(self):
     backup(VASP_BACKUP_FILES)
     actions = [{"file": "CONTCAR",
                 "action": {"_file_copy": {"dest": "POSCAR"}}},
                {"dict": "INCAR",
                 "action": {"_set": {"ISTART": 1,
                                     "ALGO": "Normal",
                                     "NELMDL": -6,
                                     "BMIX": 0.001,
                                     "AMIX_MAG": 0.8,
                                     "BMIX_MAG": 0.001}}}]
     VaspModder().apply_actions(actions)
     return {"errors": ["Unconverged"], "actions": actions}
Example #15
0
 def correct(self):
     # change ALGO = Fast to Normal if ALGO is !Normal
     vi = VaspInput.from_directory(".")
     algo = vi["INCAR"].get("ALGO", "Normal")
     if algo.lower() not in ['normal', 'n']:
         backup(VASP_BACKUP_FILES)
         actions = [{"dict": "INCAR",
                     "action": {"_set": {"ALGO": "Normal"}}}]
         VaspModder(vi=vi).apply_actions(actions)
         return {"errors": ["Positive energy"], "actions": actions}
     # Unfixable error. Just return None for actions.
     else:
         return {"errors": ["Positive energy"], "actions": None}
Example #16
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if "lrf_comm" in self.errors:
            if Outcar(zpath(os.path.join(
                    os.getcwd(), "OUTCAR"))).is_stopped is False:
                if not vi["INCAR"].get("LPEAD"):
                    actions.append({"dict": "INCAR",
                                    "action": {"_set": {"LPEAD": True}}})

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Example #17
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if "subspacematrix" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "All"
                    }
                }
            })

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Example #18
0
 def correct(self):
     backup(VASP_BACKUP_FILES)
     v = Vasprun(self.output_filename)
     actions = [{"file": "CONTCAR",
                 "action": {"_file_copy": {"dest": "POSCAR"}}}]
     if not v.converged_electronic:
         actions.append({"dict": "INCAR",
                         "action": {"_set": {"ISTART": 1,
                                             "ALGO": "Normal",
                                             "NELMDL": -6,
                                             "BMIX": 0.001,
                                             "AMIX_MAG": 0.8,
                                             "BMIX_MAG": 0.001}}})
     if not v.converged_ionic:
         actions.append({"dict": "INCAR",
                         "action": {"_set": {"IBRION":1}}})
     VaspModder().apply_actions(actions)
     return {"errors": ["Unconverged"], "actions": actions}
Example #19
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if "aliasing" in self.errors:
            with open("OUTCAR") as f:
                grid_adjusted = False
                changes_dict = {}
                r = re.compile(".+aliasing errors.*(NG.)\s*to\s*(\d+)")
                for line in f:
                    m = r.match(line)
                    if m:
                        changes_dict[m.group(1)] = int(m.group(2))
                        grid_adjusted = True
                    # Ensure that all NGX, NGY, NGZ have been checked
                    if grid_adjusted and 'NGZ' in line:
                        actions.append(
                            {"dict": "INCAR", "action": {"_set": changes_dict}})
                        if vi["INCAR"].get("ICHARG", 0) < 10:
                            actions.extend([{"file": "CHGCAR",
                                             "action": {"_file_delete": {
                                                 'mode': "actual"}}},
                                            {"file": "WAVECAR",
                                             "action": {"_file_delete": {
                                                 'mode': "actual"}}}])
                        break

        if "aliasing_incar" in self.errors:
            # vasp seems to give different warnings depending on whether the
            # aliasing error was caused by user supplied inputs
            d = {k: 1 for k in ['NGX', 'NGY', 'NGZ'] if k in vi['INCAR'].keys()}
            actions.append({"dict": "INCAR", "action": {"_unset": d}})

            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.extend([{"file": "CHGCAR",
                                 "action": {
                                     "_file_delete": {'mode': "actual"}}},
                                {"file": "WAVECAR",
                                 "action": {
                                     "_file_delete": {'mode': "actual"}}}])

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Example #20
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        # If we encounter a DAV Sub-Space-Matrix error
        if "subspacematrix" or "edddav" in self.errors:
            # Switch to the CG algorithm
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "All"
                    }
                }
            })

        # If we encounter a ZBRENT error
        if "zbrent" in self.errors:
            # Switch to Quasi-Newton algorithm
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "IBRION": 1
                    }
                }
            })
            # Move CONTCAR to POSCAR
            actions.append({
                "file": "CONTCAR",
                "action": {
                    "_file_copy": {
                        "dest": "POSCAR"
                    }
                }
            })

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Example #21
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if "lrf_comm" in self.errors:
            if self.error_count['lrf_comm'] == 0:
                if Outcar(zpath(os.path.join(os.getcwd(),
                                             "OUTCAR"))).is_stopped is False:
                    # simply rerun the job and increment
                    # error count for next time
                    actions.append({
                        "dict": "INCAR",
                        "action": {
                            "_set": {
                                "ISTART": 1
                            }
                        }
                    })
                    self.error_count['lrf_comm'] += 1

        if "kpoints_trans" in self.errors:
            if self.error_count["kpoints_trans"] == 0:
                m = reduce(operator.mul, vi["KPOINTS"].kpts[0])
                m = max(int(round(m**(1 / 3))), 1)
                if vi["KPOINTS"].style.name.lower().startswith("m"):
                    m += m % 2
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "kpoints": [[m] * 3]
                        }
                    }
                })
                self.error_count['kpoints_trans'] += 1

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Example #22
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if "kpoints_trans" in self.errors:
            if self.error_count["kpoints_trans"] == 0:
                m = reduce(operator.mul, vi["KPOINTS"].kpts[0])
                m = max(int(round(m ** (1 / 3))), 1)
                if vi["KPOINTS"].style.name.lower().startswith("m"):
                    m += m % 2
                actions.append({"dict": "KPOINTS", "action": {"_set": {"kpoints": [[m] * 3]}}})
                self.error_count['kpoints_trans'] += 1

        if "out_of_memory" in self.errors:
            if vi["INCAR"].get("KPAR", 1) > 1:
                reduced_kpar = max(vi["INCAR"].get("KPAR", 1) // 2, 1)
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"KPAR": reduced_kpar}}})

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Example #23
0
    def correct(self):
        backup(VASP_BACKUP_FILES)
        v = Vasprun(self.output_filename)
        actions = [{"file": "CONTCAR",
                    "action": {"_file_copy": {"dest": "POSCAR"}}}]
        if not v.converged_electronic:
            new_settings = {"ISTART": 1,
                            "ALGO": "Normal",
                            "NELMDL": -6,
                            "BMIX": 0.001,
                            "AMIX_MAG": 0.8,
                            "BMIX_MAG": 0.001} 

            if all([v.incar.get(k,"") == val for k,val in new_settings.items()]):
                return {"errors": ["Unconverged"], "actions": None}

            actions.append({"dict": "INCAR",
                            "action": {"_set": new_settings}})
        if not v.converged_ionic:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"IBRION": 1}}})
        VaspModder().apply_actions(actions)
        return {"errors": ["Unconverged"], "actions": actions}
Example #24
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISMEAR": 0}}})

        if "inv_rot_mat" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8}}})

        if "brmix" in self.errors:
            # If there is not a valid OUTCAR already, increment
            # error count to 1 to skip first fix
            if self.error_count['brmix'] == 0:
                try:
                    assert (Outcar(zpath(os.path.join(
                        os.getcwd(), "OUTCAR"))).is_stopped is False)
                except:
                    self.error_count['brmix'] += 1

            if self.error_count['brmix'] == 0:
                # Valid OUTCAR - simply rerun the job and increment
                # error count for next time
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISTART": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] == 1:
                # Use Kerker mixing w/default values for other parameters
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] == 2 and vi["KPOINTS"].style \
                    == Kpoints.supported_modes.Gamma:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style":
                                                        "Monkhorst"}}})
                actions.append({"dict": "INCAR",
                                "action": {"_unset": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] in [2, 3] and vi["KPOINTS"].style \
                    == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style":
                                                        "Gamma"}}})
                actions.append({"dict": "INCAR",
                                "action": {"_unset": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

                if vi["KPOINTS"].num_kpts < 1:
                    all_kpts_even = all([
                        bool(n % 2 == 0) for n in vi["KPOINTS"].kpts[0]
                    ])
                    print("all_kpts_even = {}".format(all_kpts_even))
                    if all_kpts_even:
                        new_kpts = (
                            tuple(n + 1 for n in vi["KPOINTS"].kpts[0]),)
                        print("new_kpts = {}".format(new_kpts))
                        actions.append({"dict": "KPOINTS", "action": {"_set": {
                            "kpoints": new_kpts
                        }}})

            else:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})

                if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                    actions.append({"dict": "KPOINTS",
                                    "action": {
                                        "_set": {"generation_style": "Gamma"}}})

                # Based on VASP forum's recommendation, you should delete the
                # CHGCAR and WAVECAR when dealing with this error.
                if vi["INCAR"].get("ICHARG", 0) < 10:
                    actions.append({"file": "CHGCAR",
                                    "action": {
                                        "_file_delete": {'mode': "actual"}}})
                    actions.append({"file": "WAVECAR",
                                    "action": {
                                        "_file_delete": {'mode': "actual"}}})

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.  If a static run
            # try turning off symmetry.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append(
                    {"dict": "INCAR",
                     "action": {"_set": {"ISYM": 0, "POTIM": potim}}})
            elif vi["INCAR"].get("NSW", 0) == 0 \
                    or vi["INCAR"].get("ISIF", 0) in range(3):
                actions.append(
                    {"dict": "INCAR", "action": {"_set": {"ISYM": 0}}})
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({"dict": "POSCAR",
                                "action": {"_set": {"structure": s.as_dict()}}})

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
                actions.append({"file": "WAVECAR",
                                "action": {"_file_delete": {'mode': "actual"}}})

        if self.errors.intersection(["subspacematrix", "rspher",
                                     "real_optlay", "nicht_konv"]):
            s = vi["POSCAR"].structure
            if len(s) < self.natoms_large_cell:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"LREAL": False}}})
            else:
                # for large supercell, try an in-between option LREAL = True
                # prior to LREAL = False
                if self.error_count['real_optlay'] == 0:
                    # use real space projectors generated by pot
                    actions.append({"dict": "INCAR",
                                    "action": {"_set": {"LREAL": True}}})
                    self.error_count['real_optlay'] += 1
                elif self.error_count['real_optlay'] == 1:
                    actions.append({"dict": "INCAR",
                                    "action": {"_set": {"LREAL": False}}})
                    self.error_count['real_optlay'] += 1

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {
                                    "_set": {"generation_style": "Gamma"}}})

        if "rot_matrix" in self.errors:
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {
                                    "_set": {"generation_style": "Gamma"}}})
            else:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})

        if "amin" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"AMIN": "0.01"}}})

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({"dict": "POSCAR",
                            "action": {"_set": {"structure": new_s.as_dict()}},
                            "transformation": trans.as_dict()})

        if "pricel" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8, "ISYM": 0}}})

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"POTIM": potim}}})

        if "zbrent" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"IBRION": 1}}})
            actions.append({"file": "CONTCAR",
                            "action": {"_file_copy": {"dest": "POSCAR"}}})

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"NBANDS": int(1.1 * nbands)}}})

        if "pssyevx" in self.errors:
            actions.append({"dict": "INCAR", "action":
                {"_set": {"ALGO": "Normal"}}})
        if "eddrmm" in self.errors:
            # RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({"dict": "INCAR", "action":
                    {"_set": {"ALGO": "Normal"}}})
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"POTIM": potim}}})
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
                actions.append({"file": "WAVECAR",
                                "action": {"_file_delete": {'mode': "actual"}}})

        if "edddav" in self.errors:
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
            actions.append({"dict": "INCAR", "action":
                {"_set": {"ALGO": "All"}}})

        if "grad_not_orth" in self.errors:
            if vi["INCAR"].get("ISMEAR", 1) < 0:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISMEAR": "0"}}})

        if "zheev" in self.errors:
            if vi["INCAR"].get("ALGO", "Fast").lower() != "exact":
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ALGO": "Exact"}}})
        if "elf_kpar" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"KPAR": 1}}})

        if "rhosyg" in self.errors:
            if vi["INCAR"].get("SYMPREC", 1e-4) == 1e-4:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-4}}})

        if "posmap" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-6}}})

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Example #25
0
    def correct(self):
        vi = VaspInput.from_directory(".")
        algo = vi["INCAR"].get("ALGO", "Normal")
        amix = vi["INCAR"].get("AMIX", 0.4)
        bmix = vi["INCAR"].get("BMIX", 1.0)
        amin = vi["INCAR"].get("AMIN", 0.1)
        actions = []

        # Ladder from VeryFast to Fast to Fast to All
        # These progressively switches to more stable but more
        # expensive algorithms
        if algo == "VeryFast":
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "Fast"
                    }
                }
            })
        elif algo == "Fast":
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "Normal"
                    }
                }
            })
        elif algo == "Normal":
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "All"
                    }
                }
            })
        elif amix > 0.1 and bmix > 0.01:
            # Try linear mixing
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "AMIX": 0.1,
                        "BMIX": 0.01,
                        "ICHARG": 2
                    }
                }
            })
        elif bmix < 3.0 and amin > 0.01:
            # Try increasing bmix
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "AMIN": 0.01,
                        "BMIX": 3.0,
                        "ICHARG": 2
                    }
                }
            })

        if actions:
            backup(VASP_BACKUP_FILES)
            VaspModder(vi=vi).apply_actions(actions)
            return {"errors": ["Non-converging job"], "actions": actions}
        # Unfixable error. Just return None for actions.
        else:
            return {"errors": ["Non-converging job"], "actions": None}
Example #26
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ISMEAR": 0
                    }
                }
            })

        if "inv_rot_mat" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-8
                    }
                }
            })

        if "brmix" in self.errors:

            if self.error_count['brmix'] == 0 and vi[
                    "KPOINTS"].style == Kpoints.supported_modes.Gamma:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Monkhorst"
                        }
                    }
                })
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] <= 1 and vi[
                    "KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })
                self.error_count['brmix'] += 1

                if vi["KPOINTS"].num_kpts < 1:
                    all_kpts_even = all(
                        [bool(n % 2 == 0) for n in vi["KPOINTS"].kpts[0]])
                    print("all_kpts_even = {}".format(all_kpts_even))
                    if all_kpts_even:
                        new_kpts = (tuple(n + 1
                                          for n in vi["KPOINTS"].kpts[0]), )
                        print("new_kpts = {}".format(new_kpts))
                        actions.append({
                            "dict": "KPOINTS",
                            "action": {
                                "_set": {
                                    "kpoints": new_kpts
                                }
                            }
                        })

            else:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })

                if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                    actions.append({
                        "dict": "KPOINTS",
                        "action": {
                            "_set": {
                                "generation_style": "Gamma"
                            }
                        }
                    })

                # Based on VASP forum's recommendation, you should delete the
                # CHGCAR and WAVECAR when dealing with this error.
                actions.append({
                    "file": "CHGCAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })
                actions.append({
                    "file": "WAVECAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0,
                            "POTIM": potim
                        }
                    }
                })
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({
                    "dict": "POSCAR",
                    "action": {
                        "_set": {
                            "structure": s.as_dict()
                        }
                    }
                })

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.

            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "file": "WAVECAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })

        if self.errors.intersection(
            ["subspacematrix", "rspher", "real_optlay"]):
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "LREAL": False
                    }
                }
            })

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })

        if "rot_matrix" in self.errors:
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })
            else:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })

        if "amin" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "AMIN": "0.01"
                    }
                }
            })

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({
                "dict": "POSCAR",
                "action": {
                    "_set": {
                        "structure": new_s.as_dict()
                    }
                },
                "transformation": trans.as_dict()
            })

        if "pricel" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-8,
                        "ISYM": 0
                    }
                }
            })

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "POTIM": potim
                    }
                }
            })

        if "zbrent" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "IBRION": 1
                    }
                }
            })

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "NBANDS": int(1.1 * nbands)
                    }
                }
            })

        if "pssyevx" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "Normal"
                    }
                }
            })
        if "eddrmm" in self.errors:
            #RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ALGO": "Normal"
                        }
                    }
                })
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "POTIM": potim
                        }
                    }
                })

            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "file": "WAVECAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
        if "edddav" in self.errors:
            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "All"
                    }
                }
            })

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}