def _verify_inputs(self): user_incar = Incar.from_file(os.path.join(os.getcwd(), "INCAR")) ref_incar = Incar.from_file(os.path.join(self["ref_dir"], "inputs", "INCAR")) # perform some BASIC tests # check INCAR params_to_check = self.get("params_to_check", []) defaults = {"ISPIN": 1, "ISMEAR": 1, "SIGMA": 0.2} for p in params_to_check: if user_incar.get(p, defaults.get(p)) != ref_incar.get(p, defaults.get(p)): raise ValueError("INCAR value of {} is inconsistent!".format(p)) # check KPOINTS user_kpoints = Kpoints.from_file(os.path.join(os.getcwd(), "KPOINTS")) ref_kpoints = Kpoints.from_file(os.path.join(self["ref_dir"], "inputs", "KPOINTS")) if user_kpoints.style != ref_kpoints.style or user_kpoints.num_kpts != ref_kpoints.num_kpts: raise ValueError("KPOINT files are inconsistent! Paths are:\n{}\n{}".format( os.getcwd(), os.path.join(self["ref_dir"], "inputs"))) # check POSCAR user_poscar = Poscar.from_file(os.path.join(os.getcwd(), "POSCAR")) ref_poscar = Poscar.from_file(os.path.join(self["ref_dir"], "inputs", "POSCAR")) if user_poscar.natoms != ref_poscar.natoms or user_poscar.site_symbols != ref_poscar.site_symbols: raise ValueError("POSCAR files are inconsistent! Paths are:\n{}\n{}".format( os.getcwd(), os.path.join(self["ref_dir"], "inputs"))) # check POTCAR user_potcar = Potcar.from_file(os.path.join(os.getcwd(), "POTCAR")) ref_potcar = Potcar.from_file(os.path.join(self["ref_dir"], "inputs", "POTCAR")) if user_potcar.symbols != ref_potcar.symbols: raise ValueError("POTCAR files are inconsistent! Paths are:\n{}\n{}".format( os.getcwd(), os.path.join(self["ref_dir"], "inputs"))) logger.info("RunVaspFake: verified inputs successfully")
def test_continue(self): # Test the continuation functionality with cd(os.path.join(test_dir, 'postprocess')): # Test default functionality with ScratchDir('.', copy_from_current_on_enter=True) as d: v = VaspJob("hello", auto_continue=True) v.setup() self.assertTrue(os.path.exists("continue.json"), "continue.json not created") v.setup() self.assertEqual(Poscar.from_file("CONTCAR").structure, Poscar.from_file("POSCAR").structure) self.assertEqual(Incar.from_file('INCAR')['ISTART'], 1) v.postprocess() self.assertFalse(os.path.exists("continue.json"), "continue.json not deleted after postprocessing") # Test explicit action functionality with ScratchDir('.', copy_from_current_on_enter=True) as d: v = VaspJob("hello", auto_continue=[{"dict": "INCAR", "action": {"_set": {"ISTART": 1}}}]) v.setup() v.setup() self.assertNotEqual(Poscar.from_file("CONTCAR").structure, Poscar.from_file("POSCAR").structure) self.assertEqual(Incar.from_file('INCAR')['ISTART'], 1) v.postprocess()
def setUpClass(cls): if not os.environ.get("VASP_PSP_DIR"): os.environ["VASP_PSP_DIR"] = os.path.join(module_dir, "reference_files") print( 'Note: This system is not set up to run VASP jobs. ' 'Please set your VASP_PSP_DIR environment variable.') cls.struct_si = PymatgenTest.get_structure("Si") cls.ref_incar = Incar.from_file( os.path.join(module_dir, "reference_files", "setup_test", "INCAR")) cls.ref_poscar = Poscar.from_file( os.path.join(module_dir, "reference_files", "setup_test", "POSCAR")) cls.ref_potcar = Potcar.from_file( os.path.join(module_dir, "reference_files", "setup_test", "POTCAR")) cls.ref_kpoints = Kpoints.from_file( os.path.join(module_dir, "reference_files", "setup_test", "KPOINTS")) cls.ref_incar_preserve = Incar.from_file(os.path.join(module_dir, "reference_files", "preserve_incar", "INCAR"))
def test_static_run_correction(self): shutil.copy("OSZICAR.empty", "OSZICAR") s1 = Structure.from_file("POSCAR") incar = Incar.from_file("INCAR") # Test for NSW 0 incar.update({"NSW": 0}) incar.write_file("INCAR") h = VaspErrorHandler("vasp.out") self.assertEqual(h.check(), True) d = h.correct() self.assertEqual(d['errors'], ['zpotrf']) s2 = Structure.from_file("POSCAR") self.assertAlmostEqual(s2.volume, s1.volume, 3) self.assertEqual(Incar.from_file("INCAR")["ISYM"], 0) # Test for ISIF 0-2 incar.update({"NSW":99, "ISIF":2}) incar.write_file("INCAR") h = VaspErrorHandler("vasp.out") self.assertEqual(h.check(), True) d = h.correct() self.assertEqual(d['errors'], ['zpotrf']) s2 = Structure.from_file("POSCAR") self.assertAlmostEqual(s2.volume, s1.volume, 3) self.assertEqual(Incar.from_file("INCAR")["ISYM"], 0)
def _verify_inputs(self): """Validation of input files under user NEB directory.""" user_incar = Incar.from_file(os.path.join(self.user_dir, "INCAR")) ref_incar = Incar.from_file(os.path.join(self.ref_dir_input, "INCAR")) # Check INCAR params_to_check = self.get("params_to_check", []) defaults = {"ICHAIN": 0, "LCLIMB": True} for p in params_to_check: if user_incar.get(p, defaults.get(p)) != ref_incar.get(p, defaults.get(p)): raise ValueError("INCAR value of {} is inconsistent!".format(p)) # Check KPOINTS user_kpoints = Kpoints.from_file(os.path.join(self.user_dir, "KPOINTS")) ref_kpoints = Kpoints.from_file(os.path.join(self.ref_dir_input, "KPOINTS")) if user_kpoints.style != ref_kpoints.style or user_kpoints.num_kpts != ref_kpoints.num_kpts: raise ValueError("KPOINT files are inconsistent! " "Paths are:\n{}\n{} with kpts = {} {}".format( self.user_dir, self.ref_dir_input, user_kpoints, ref_kpoints)) # Check POTCAR user_potcar = Potcar.from_file(os.path.join(self.user_dir, "POTCAR")) ref_potcar = Potcar.from_file(os.path.join(self.ref_dir_input, "POTCAR")) if user_potcar.symbols != ref_potcar.symbols: raise ValueError("POTCAR files are inconsistent! " "Paths are:\n{}\n{}".format(self.user_dir, self.ref_dir_input)) # Check POSCARs for u, r in zip(self.user_sdir, self.ref_sdir_input): user_poscar = Poscar.from_file(os.path.join(u, "POSCAR")) ref_poscar = Poscar.from_file(os.path.join(r, "POSCAR")) if user_poscar.natoms != ref_poscar.natoms or \ user_poscar.site_symbols != ref_poscar.site_symbols: raise ValueError("POSCAR files are inconsistent! Paths are:\n{}\n{}".format(u, r))
def test_rhosyg(self): h = VaspErrorHandler("vasp.rhosyg") self.assertEqual(h.check(), True) self.assertEqual(h.correct()["errors"], ["rhosyg"]) i = Incar.from_file("INCAR") self.assertEqual(i["SYMPREC"], 1e-4) self.assertEqual(h.correct()["errors"], ["rhosyg"]) i = Incar.from_file("INCAR") self.assertEqual(i["ISYM"], 0)
def _verify_files(self, skip_kpoints=False, preserve_incar=False): if not preserve_incar: self.assertEqual(Incar.from_file(os.path.join(module_dir, "INCAR")), self.ref_incar) self.assertEqual(str(Poscar.from_file(os.path.join(module_dir, "POSCAR"))), str(self.ref_poscar)) self.assertEqual((Potcar.from_file(os.path.join(module_dir, "POTCAR"))).symbols, self.ref_potcar.symbols) if not skip_kpoints: self.assertEqual(str(Kpoints.from_file(os.path.join(module_dir, "KPOINTS"))), str(self.ref_kpoints)) else: self.assertEqual(Incar.from_file(os.path.join(module_dir, "INCAR")), self.ref_incar_preserve)
def test_eddrmm(self): h = VaspErrorHandler("vasp.eddrmm") self.assertEqual(h.check(), True) self.assertEqual(h.correct()["errors"], ["eddrmm"]) i = Incar.from_file("INCAR") self.assertEqual(i["ALGO"], "Normal") self.assertEqual(h.correct()["errors"], ["eddrmm"]) i = Incar.from_file("INCAR") self.assertEqual(i["POTIM"], 0.25)
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)
def test_run(self): with ScratchDir(".") as d: for f in ["INCAR", "POSCAR", "POTCAR", "KPOINTS"]: shutil.copy(os.path.join('..', test_dir, f), f) oldincar = Incar.from_file("INCAR") v = GenerateVaspInputJob("pymatgen.io.vasp.sets.MPNonSCFSet", contcar_only=False) v.run() incar = Incar.from_file("INCAR") self.assertEqual(incar["ICHARG"], 11) self.assertEqual(oldincar["ICHARG"], 1) kpoints = Kpoints.from_file("KPOINTS") self.assertEqual(str(kpoints.style), "Reciprocal")
def setUpClass(cls): if not SETTINGS.get("VASP_PSP_DIR"): SETTINGS["VASP_PSP_DIR"] = os.path.join(module_dir, "reference_files") print( "This system is not set up to run VASP jobs. " "Please set VASP_PSP_DIR variable in your ~/.pmgrc.yaml file." ) cls.struct_si = PymatgenTest.get_structure("Si") cls.ref_incar = Incar.from_file(os.path.join(module_dir, "reference_files", "setup_test", "INCAR")) cls.ref_poscar = Poscar.from_file(os.path.join(module_dir, "reference_files", "setup_test", "POSCAR")) cls.ref_potcar = Potcar.from_file(os.path.join(module_dir, "reference_files", "setup_test", "POTCAR")) cls.ref_kpoints = Kpoints.from_file(os.path.join(module_dir, "reference_files", "setup_test", "KPOINTS")) cls.ref_incar_preserve = Incar.from_file(os.path.join(module_dir, "reference_files", "preserve_incar", "INCAR"))
def test_check(self): shutil.copy("INCAR", "INCAR.orig") h = DriftErrorHandler(max_drift=0.05, to_average=11) self.assertFalse(h.check()) h = DriftErrorHandler(max_drift=0.05) self.assertFalse(h.check()) h = DriftErrorHandler(max_drift=0.0001) self.assertFalse(h.check()) incar = Incar.from_file("INCAR") incar["EDIFFG"] = -0.01 incar.write_file("INCAR") h = DriftErrorHandler(max_drift=0.0001) self.assertTrue(h.check()) h = DriftErrorHandler() h.check() self.assertEqual(h.max_drift,0.01) clean_dir() shutil.move("INCAR.orig", "INCAR")
def postprocess(self): """ Postprocessing includes renaming and gzipping where necessary. Also copies the magmom to the incar if necessary """ for f in VASP_OUTPUT_FILES + [self.output_file]: if os.path.exists(f): if self.final and self.suffix != "": shutil.move(f, "{}{}".format(f, self.suffix)) elif self.suffix != "": shutil.copy(f, "{}{}".format(f, self.suffix)) if self.copy_magmom and not self.final: try: outcar = Outcar("OUTCAR") magmom = [m['tot'] for m in outcar.magnetization] incar = Incar.from_file("INCAR") incar['MAGMOM'] = magmom incar.write_file("INCAR") except: logger.error('MAGMOM copy from OUTCAR to INCAR failed') # Remove continuation so if a subsequent job is run in # the same directory, will not restart this job. if os.path.exists("continue.json"): os.remove("continue.json")
def test_nicht_konv(self): h = VaspErrorHandler("vasp.nicht_konvergent") h.natoms_large_cell = 5 self.assertEqual(h.check(), True) self.assertEqual(h.correct()["errors"], ["nicht_konv"]) i = Incar.from_file("INCAR") self.assertEqual(i["LREAL"], True)
def test_setup(self): if "VASP_PSP_DIR" not in os.environ: os.environ["VASP_PSP_DIR"] = test_dir os.chdir(os.path.join(test_dir, 'setup_neb')) v = VaspNEBJob("hello", half_kpts=True) v.setup() incar = Incar.from_file("INCAR") count = multiprocessing.cpu_count() if count > 1: self.assertGreater(incar["NPAR"], 1) kpt = Kpoints.from_file("KPOINTS") kpt_pre = Kpoints.from_file("KPOINTS.orig") self.assertEqual(kpt_pre.style.name, "Monkhorst") self.assertEqual(kpt.style.name, "Gamma") shutil.copy("KPOINTS.orig", "KPOINTS") os.remove("INCAR.orig") os.remove("KPOINTS.orig") os.remove("POTCAR.orig") poscars = glob.glob("[0-9][0-9]/POSCAR.orig") for p in poscars: os.remove(p)
def test_aliasing_incar(self): os.chdir(os.path.join(test_dir, "aliasing")) shutil.copy("INCAR", "INCAR.orig") h = AliasingErrorHandler("vasp.aliasing_incar") h.check() d = h.correct() self.assertEqual(d["errors"], ['aliasing_incar']) self.assertEqual(d["actions"], [{'action': {'_unset': {'NGY':1, 'NGZ': 1}}, 'dict': 'INCAR'}, {"file": "CHGCAR", "action": {"_file_delete": {'mode': "actual"}}}, {"file": "WAVECAR", "action": {"_file_delete": {'mode': "actual"}}}]) incar = Incar.from_file('INCAR.orig') incar["ICHARG"] = 10 incar.write_file("INCAR") d = h.correct() self.assertEqual(d["errors"], ['aliasing_incar']) self.assertEqual(d["actions"], [{'action': {'_unset': {'NGY': 1, 'NGZ': 1}}, 'dict': 'INCAR'}]) shutil.move("INCAR.orig", "INCAR") clean_dir() os.chdir(test_dir)
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)
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)
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)
def test_correct(self): shutil.copy("INCAR", "INCAR.orig") h = DriftErrorHandler(max_drift=0.0001,enaug_multiply=2) h.check() d = h.correct() incar = Incar.from_file("INCAR") self.assertTrue(incar.get("ADDGRID",False)) d = h.correct() incar = Incar.from_file("INCAR") self.assertEqual(incar.get("PREC"),"High") self.assertEqual(incar.get("ENAUG",0),incar.get("ENCUT",2)*2) clean_dir() shutil.move("INCAR.orig", "INCAR")
def setUpClass(cls): cls.struct_si = PymatgenTest.get_structure("Si") cls.ref_incar = Incar.from_file( os.path.join(module_dir, "..", "..", "test_files", "setup_test", "INCAR")) cls.ref_poscar = Poscar.from_file( os.path.join(module_dir, "..", "..", "test_files", "setup_test", "POSCAR")) cls.ref_potcar = Potcar.from_file( os.path.join(module_dir, "..", "..", "test_files", "setup_test", "POTCAR")) cls.ref_kpoints = Kpoints.from_file( os.path.join(module_dir, "..", "..", "test_files", "setup_test", "KPOINTS")) cls.ref_incar_preserve = Incar.from_file(os.path.join(module_dir, "..", "..", "test_files", "preserve_incar", "INCAR"))
def _verify_files(self): self.assertEqual(Incar.from_file(os.path.join(module_dir, "INCAR")), self.ref_incar) self.assertEqual(str(Poscar.from_file(os.path.join(module_dir, "POSCAR"))), str(self.ref_poscar)) self.assertEqual(Potcar.from_file(os.path.join(module_dir, "POTCAR")).symbols, self.ref_potcar.symbols) self.assertEqual(str(Kpoints.from_file(os.path.join(module_dir, "KPOINTS"))), str(self.ref_kpoints))
def test_postprocess(self): os.chdir(os.path.join(test_dir, 'postprocess')) shutil.copy('INCAR', 'INCAR.backup') v = VaspJob("hello", final=False, suffix=".test", copy_magmom=True) v.postprocess() incar = Incar.from_file("INCAR") incar_prev = Incar.from_file("INCAR.test") for f in ['INCAR', 'KPOINTS', 'CONTCAR', 'OSZICAR', 'OUTCAR', 'POSCAR', 'vasprun.xml']: self.assertTrue(os.path.isfile('{}.test'.format(f))) os.remove('{}.test'.format(f)) shutil.move('INCAR.backup', 'INCAR') self.assertAlmostEqual(incar['MAGMOM'], [3.007, 1.397, -0.189, -0.189]) self.assertAlmostEqual(incar_prev["MAGMOM"], [5, -5, 0.6, 0.6])
def test_correct(self): shutil.copy("INCAR", "INCAR.orig") h = DriftErrorHandler(max_drift=0.0001, enaug_multiply=2) h.check() d = h.correct() incar = Incar.from_file("INCAR") self.assertTrue(incar.get("ADDGRID", False)) d = h.correct() incar = Incar.from_file("INCAR") self.assertEqual(incar.get("PREC"), "High") self.assertEqual(incar.get("ENAUG", 0), incar.get("ENCUT", 2) * 2) clean_dir() shutil.move("INCAR.orig", "INCAR")
def __add__(self, other: Incar) -> "ViseIncar": """Add all the values of another INCAR object to this object. """ original_settings = {k: v for k, v in self.items()} for key, value in other.items(): if key in self and value != self[key]: raise ValueError("INCARs have conflicting values!") else: original_settings[key] = value return ViseIncar(original_settings)
def __add__(self, other: Incar) -> "ViseIncar": """ Add all the values of another INCAR object to this object. """ params = {k: v for k, v in self.items()} for k, v in other.items(): if k in self and v != self[k]: raise ValueError("Incars have conflicting values!") else: params[k] = v return ViseIncar(params)
def test_postprocess(self): with cd(os.path.join(test_dir, 'postprocess')): with ScratchDir('.', copy_from_current_on_enter=True) as d: shutil.copy('INCAR', 'INCAR.backup') v = VaspJob("hello", final=False, suffix=".test", copy_magmom=True) v.postprocess() incar = Incar.from_file("INCAR") incar_prev = Incar.from_file("INCAR.test") for f in ['INCAR', 'KPOINTS', 'CONTCAR', 'OSZICAR', 'OUTCAR', 'POSCAR', 'vasprun.xml']: self.assertTrue(os.path.isfile('{}.test'.format(f))) os.remove('{}.test'.format(f)) shutil.move('INCAR.backup', 'INCAR') self.assertAlmostEqual(incar['MAGMOM'], [3.007, 1.397, -0.189, -0.189]) self.assertAlmostEqual(incar_prev["MAGMOM"], [5, -5, 0.6, 0.6])
def test_setup(self): with cd(test_dir): with ScratchDir('.', copy_from_current_on_enter=True) as d: v = VaspJob("hello") v.setup() incar = Incar.from_file("INCAR") count = multiprocessing.cpu_count() if count > 1: self.assertGreater(incar["NPAR"], 1)
def test_setup(self): with cd(test_dir): with ScratchDir('.', copy_from_current_on_enter=True) as d: v = VaspJob("hello", auto_npar=True) v.setup() incar = Incar.from_file("INCAR") count = multiprocessing.cpu_count() # Need at least 3 CPUs for NPAR to be greater than 1 if count > 3: self.assertGreater(incar["NPAR"], 1)
def _verify_inputs(self): """Validation of input files under user NEB directory.""" user_incar = Incar.from_file(os.path.join(self.user_dir, "INCAR")) ref_incar = Incar.from_file(os.path.join(self.ref_dir_input, "INCAR")) # Check INCAR params_to_check = self.get("params_to_check", []) defaults = {"ICHAIN": 0, "LCLIMB": True} for p in params_to_check: if user_incar.get(p, defaults.get(p)) != ref_incar.get( p, defaults.get(p)): raise ValueError( "INCAR value of {} is inconsistent!".format(p)) # Check KPOINTS user_kpoints = Kpoints.from_file(os.path.join(self.user_dir, "KPOINTS")) ref_kpoints = Kpoints.from_file( os.path.join(self.ref_dir_input, "KPOINTS")) if user_kpoints.style != ref_kpoints.style or user_kpoints.num_kpts != ref_kpoints.num_kpts: raise ValueError("KPOINT files are inconsistent! " "Paths are:\n{}\n{} with kpts = {} {}".format( self.user_dir, self.ref_dir_input, user_kpoints, ref_kpoints)) # Check POTCAR user_potcar = Potcar.from_file(os.path.join(self.user_dir, "POTCAR")) ref_potcar = Potcar.from_file( os.path.join(self.ref_dir_input, "POTCAR")) if user_potcar.symbols != ref_potcar.symbols: raise ValueError("POTCAR files are inconsistent! " "Paths are:\n{}\n{}".format( self.user_dir, self.ref_dir_input)) # Check POSCARs for u, r in zip(self.user_sdir, self.ref_sdir_input): user_poscar = Poscar.from_file(os.path.join(u, "POSCAR")) ref_poscar = Poscar.from_file(os.path.join(r, "POSCAR")) if user_poscar.natoms != ref_poscar.natoms or \ user_poscar.site_symbols != ref_poscar.site_symbols: raise ValueError( "POSCAR files are inconsistent! Paths are:\n{}\n{}".format( u, r))
def test_potim_correction(self): shutil.copy("OSZICAR.one_step", "OSZICAR") s1 = Structure.from_file("POSCAR") h = VaspErrorHandler("vasp.out") self.assertEqual(h.check(), True) d = h.correct() self.assertEqual(d['errors'], ['zpotrf']) s2 = Structure.from_file("POSCAR") self.assertAlmostEqual(s2.volume, s1.volume, 3) self.assertAlmostEqual(Incar.from_file("INCAR")['POTIM'], 0.25)
def _verify_inputs(self): user_incar = Incar.from_file(os.path.join(os.getcwd(), "INCAR")) ref_incar = Incar.from_file( os.path.join(self["ref_dir"], "inputs", "INCAR")) # perform some BASIC tests # check INCAR params_to_check = self.get("params_to_check", []) defaults = {"ISPIN": 1, "ISMEAR": 1, "SIGMA": 0.2} for p in params_to_check: if user_incar.get(p, defaults.get(p)) != ref_incar.get( p, defaults.get(p)): raise ValueError( "INCAR value of {} is inconsistent!".format(p)) # check KPOINTS user_kpoints = Kpoints.from_file(os.path.join(os.getcwd(), "KPOINTS")) ref_kpoints = Kpoints.from_file( os.path.join(self["ref_dir"], "inputs", "KPOINTS")) if user_kpoints.style != ref_kpoints.style or user_kpoints.num_kpts != ref_kpoints.num_kpts: raise ValueError( "KPOINT files are inconsistent! Paths are:\n{}\n{}".format( os.getcwd(), os.path.join(self["ref_dir"], "inputs"))) # check POSCAR user_poscar = Poscar.from_file(os.path.join(os.getcwd(), "POSCAR")) ref_poscar = Poscar.from_file( os.path.join(self["ref_dir"], "inputs", "POSCAR")) if user_poscar.natoms != ref_poscar.natoms or user_poscar.site_symbols != ref_poscar.site_symbols: raise ValueError( "POSCAR files are inconsistent! Paths are:\n{}\n{}".format( os.getcwd(), os.path.join(self["ref_dir"], "inputs"))) # check POTCAR user_potcar = Potcar.from_file(os.path.join(os.getcwd(), "POTCAR")) ref_potcar = Potcar.from_file( os.path.join(self["ref_dir"], "inputs", "POTCAR")) if user_potcar.symbols != ref_potcar.symbols: raise ValueError( "POTCAR files are inconsistent! Paths are:\n{}\n{}".format( os.getcwd(), os.path.join(self["ref_dir"], "inputs"))) logger.info("RunVaspFake: verified inputs successfully")
def test_SCAN_incar_override(self): # user incar settings should be passed all the way through the workflow structure = Structure.from_file( os.path.join(reference_dir, "PBESol_pre_opt_for_SCAN_LiH/inputs", "POSCAR")) my_wf = get_wf(structure, "metagga_optimization.yaml", common_params={ "vasp_input_set_params": { "user_potcar_functional": "PBE_52", "user_incar_settings": { "NSW": 10, "SYMPREC": 1e-6, "SIGMA": 0.1 } } }) fw_ids = self._run_scan_relax(my_wf, "LiH") # Check PBESol INCAR incar1 = Incar.from_file( os.path.join(self._get_launch_dir()[0], "INCAR.gz")) self.assertEqual(incar1["NSW"], 10) self.assertEqual(incar1["SYMPREC"], 1e-6) self.assertEqual(incar1["SIGMA"], 0.1) # Check SCAN INCAR incar2 = Incar.from_file( os.path.join(self._get_launch_dir()[1], "INCAR.gz")) self.assertEqual(incar2["NSW"], 10) self.assertEqual(incar2["SYMPREC"], 1e-6) self.assertEqual(incar2["SIGMA"], 0.1) # get a fw that can be used to identify the workflow fw_id = list(fw_ids.values())[0] # check workflow finished without error wf = self.lp.get_wf_by_fw_id(fw_id) is_completed = [s == "COMPLETED" for s in wf.fw_states.values()] self.assertTrue(all(is_completed))
def test_SCAN_no_bandgap(self): # A structure with bandgap = 0 (default) should have KSPACING equal to 0.22 structure = Structure.from_file(os.path.join(reference_dir, "SCAN_structure_optimization_Al/inputs", "POSCAR")) my_wf = get_wf(structure, "SCAN_optimization.yaml", vis=MPScanRelaxSet(structure), common_params={"vasp_cmd": VASP_CMD}) self._run_scan_relax(my_wf, "SCAN_structure_optimization_Al") # Check INCAR.orig incar_orig = Incar.from_file(os.path.join(self._get_launch_dir(), "INCAR.orig.gz")) ref_incar = Incar.from_file(os.path.join(reference_dir, "SCAN_structure_optimization_Al/inputs", "INCAR.orig")) for p in incar_orig.keys(): if p == "MAGMOM": # Ignore MAGMOM b/c structure initialized from POSCAR cannot have a MAGMOM pass else: self.assertEqual(incar_orig[p], ref_incar[p]) # Check INCAR.relax1 incar = Incar.from_file(os.path.join(self._get_launch_dir(), "INCAR.relax1.gz")) self.assertEqual(incar["METAGGA"], "None") self.assertEqual(incar["EDIFFG"], -0.05) self.assertEqual(incar["LWAVE"], False) # Check INCAR.relax2 incar = Incar.from_file(os.path.join(self._get_launch_dir(), "INCAR.relax2.gz")) self.assertEqual(incar["METAGGA"], "None") self.assertEqual(incar["LWAVE"], True) self.assertEqual(incar["NSW"], 0) self.assertEqual(incar["EDIFFG"], -0.05) self.assertEqual(incar["ICHARG"], 1) self.assertEqual(incar["ISTART"], 0) # Check INCAR.relax3 incar = Incar.from_file(os.path.join(self._get_launch_dir(), "INCAR.relax3.gz")) for p in incar.keys(): if p == "KSPACING": self.assertEqual(incar[p], 0.22) elif p == "ICHARG" or p == "ISTART": self.assertEqual(incar[p], 1) else: self.assertEqual(incar_orig[p], incar[p])
def _check_incar_ele_temp(testCase, idx, ele_temp): fp_path = os.path.join('iter.%06d' % idx, '02.fp') tasks = glob.glob(os.path.join(fp_path, 'task.*')) cwd = os.getcwd() for ii in tasks : os.chdir(ii) bname = os.path.basename(ii) sidx = int(bname.split('.')[1]) tidx = int(bname.split('.')[2]) with open('INCAR') as fp: incar = fp.read() incar0 = Incar.from_string(incar) # make_fake_md: the frames in a system shares the same ele_temp incar1 = Incar.from_string(vasp_incar_ele_temp_ref%(ele_temp[sidx][0] * pc.Boltzmann / pc.electron_volt)) for ii in incar0.keys(): # skip checking nbands... if ii == 'NBANDS': continue testCase.assertAlmostEqual(incar0[ii], incar1[ii], msg = 'key %s differ' % (ii), places = 5) os.chdir(cwd)
def test_ioset_params(self): ft = WriteVaspFromIOSet( dict(structure=self.struct_si, vasp_input_set="MPRelaxSet", vasp_input_params={"user_incar_settings": {"ISMEAR": 1000}})) ft = load_object(ft.to_dict()) # simulate database insertion ft.run_task({}) incar = Incar.from_file("INCAR") self.assertEqual(incar["ISMEAR"], 1000) # make sure override works incar['ISMEAR'] = -5 # switch back to default incar.write_file("INCAR") self._verify_files(skip_kpoints=True)
def _verify_files(self, skip_kpoints=False, preserve_incar=False): if not preserve_incar: self.assertEqual( Incar.from_file(os.path.join(module_dir, "INCAR")), self.ref_incar) self.assertEqual( str(Poscar.from_file(os.path.join(module_dir, "POSCAR"))), str(self.ref_poscar)) self.assertEqual( (Potcar.from_file(os.path.join(module_dir, "POTCAR"))).symbols, self.ref_potcar.symbols) if not skip_kpoints: self.assertEqual( str(Kpoints.from_file(os.path.join(module_dir, "KPOINTS"))), str(self.ref_kpoints)) else: self.assertEqual( Incar.from_file(os.path.join(module_dir, "INCAR")), self.ref_incar_preserve)
def test_make_input_file_2(self): self.VASP.make_input_file(self.equi_path, 'relaxation', self.task_param) self.assertTrue( os.path.isfile(os.path.join(self.equi_path, "task.json"))) self.assertTrue(os.path.isfile(os.path.join(self.equi_path, "KPOINTS"))) self.assertTrue(os.path.isfile(os.path.join(self.equi_path, "INCAR"))) incar = incar_upper( Incar.from_file(os.path.join(self.equi_path, "INCAR"))) self.assertTrue(incar['ISIF'], 3)
def test_make_input_file_3(self): param = self.task_param.copy() param["cal_setting"] = { "relax_pos": True, "relax_shape": False, "relax_vol": False } self.VASP.make_input_file(self.equi_path, 'relaxation', param) incar = incar_upper( Incar.from_file(os.path.join(self.equi_path, "INCAR"))) self.assertTrue(incar['ISIF'], 2)
def test_make_eos(self): confs = self.jdata["structures"] inter_param = self.jdata["interaction"] property_list = self.jdata["properties"] target_path = 'confs/std-fcc/eos_00' equi_path = 'confs/std-fcc/relaxation/relax_task' source_path = 'equi/vasp' if not os.path.exists(equi_path): os.makedirs(equi_path) shutil.copy(os.path.join(source_path, 'CONTCAR_Al_fcc'), os.path.join(equi_path, 'CONTCAR')) make_property(confs, inter_param, property_list) dfm_dirs = glob.glob(os.path.join(target_path, 'task.*')) incar0 = Incar.from_file(os.path.join('vasp_input', 'INCAR.rlx')) incar0['ISIF'] = 4 with open(os.path.join('vasp_input', 'POT_Al')) as fp: pot0 = fp.read() for ii in dfm_dirs: self.assertTrue(os.path.isfile(os.path.join(ii, 'KPOINTS'))) incar1 = Incar.from_file(os.path.join(ii, 'INCAR')) self.assertTrue(incar0 == incar1) self.assertTrue(os.path.isfile(os.path.join(ii, 'INCAR'))) self.assertTrue(os.path.isfile(os.path.join(ii, 'POSCAR'))) self.assertTrue(os.path.isfile(os.path.join(ii, 'POTCAR'))) self.assertTrue(os.path.isfile(os.path.join(ii, 'task.json'))) inter_json_file = os.path.join(ii, 'inter.json') self.assertTrue(os.path.isfile(inter_json_file)) inter_json = loadfn(inter_json_file) self.assertEqual(inter_json, inter_param) self.assertEqual( os.path.realpath(os.path.join(ii, 'POSCAR.orig')), os.path.realpath(os.path.join(equi_path, 'CONTCAR'))) with open(os.path.join(ii, 'POTCAR')) as fp: poti = fp.read() self.assertEqual(pot0, poti)
def test_continue(self): # Test the continuation functionality with cd(os.path.join(test_dir, "postprocess")): # Test default functionality with ScratchDir(".", copy_from_current_on_enter=True): v = VaspJob("hello", auto_continue=True) v.setup() self.assertTrue(os.path.exists("continue.json"), "continue.json not created") v.setup() self.assertEqual( Poscar.from_file("CONTCAR").structure, Poscar.from_file("POSCAR").structure, ) self.assertEqual(Incar.from_file("INCAR")["ISTART"], 1) v.postprocess() self.assertFalse( os.path.exists("continue.json"), "continue.json not deleted after postprocessing", ) # Test explicit action functionality with ScratchDir(".", copy_from_current_on_enter=True): v = VaspJob( "hello", auto_continue=[{ "dict": "INCAR", "action": { "_set": { "ISTART": 1 } } }], ) v.setup() v.setup() self.assertNotEqual( Poscar.from_file("CONTCAR").structure, Poscar.from_file("POSCAR").structure, ) self.assertEqual(Incar.from_file("INCAR")["ISTART"], 1) v.postprocess()
def test_make_vasp_norlx_cell_shape (self): jdata = { 'relax_incar' : 'vasp_input/INCAR.rlx', 'potcar_map': {'Si': 'vasp_input/POTCAR' }, 'vol_start': 15, 'vol_end': 25, 'vol_step': 1.0, 'eos_relax_cell_shape': False, } make_vasp(jdata, 'confs/si/mp-149') target_path = '01.eos/si/mp-149/vasp-relax_incar' equi_path = '00.equi/si/mp-149/vasp-relax_incar' dfm_dirs = glob.glob(os.path.join(target_path, 'vol*')) # check root INCAR incar0 = Incar.from_file(os.path.join('vasp_input', 'INCAR.rlx')) incar1 = Incar.from_file(os.path.join(target_path, 'INCAR')) self.assertFalse(incar0 == incar1) incar0['ISIF'] = 2 self.assertTrue(incar0 == incar1)
def _verify_files(self): self.assertEqual(Incar.from_file(os.path.join(module_dir, "INCAR")), self.ref_incar) self.assertEqual( str(Poscar.from_file(os.path.join(module_dir, "POSCAR"))), str(self.ref_poscar)) self.assertEqual( Potcar.from_file(os.path.join(module_dir, "POTCAR")).symbols, self.ref_potcar.symbols) self.assertEqual( str(Kpoints.from_file(os.path.join(module_dir, "KPOINTS"))), str(self.ref_kpoints))
def wrangle_incar(directory, calculation_parameters_to_update): """ updating an incar file in a given directory, with a given set of flags and values args: directory (str): directory to update INCAR in calculation_parameters_to_update (dict): dictionary of calc paramters to be changed, where the key is the relevant VASP flag, and the values are the incar values. """ home = os.getcwd() incar = Incar.from_file(f'{home}/{directory}/INCAR') incar.update(calculation_parameters_to_update) incar.write_file(f'{home}/{directory}/INCAR')
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)
def diff_incar(args): """ Handle diff commands. :param args: Args from command. """ filepath1 = args.incars[0] filepath2 = args.incars[1] incar1 = Incar.from_file(filepath1) incar2 = Incar.from_file(filepath2) def format_lists(v): if isinstance(v, (tuple, list)): return " ".join([f"{len(tuple(group))}*{i:.2f}" for (i, group) in itertools.groupby(v)]) return v d = incar1.diff(incar2) output = [ ["SAME PARAMS", "", ""], ["---------------", "", ""], ["", "", ""], ["DIFFERENT PARAMS", "", ""], ["----------------", "", ""], ] output.extend( [(k, format_lists(d["Same"][k]), format_lists(d["Same"][k])) for k in sorted(d["Same"].keys()) if k != "SYSTEM"] ) output.extend( [ ( k, format_lists(d["Different"][k]["INCAR1"]), format_lists(d["Different"][k]["INCAR2"]), ) for k in sorted(d["Different"].keys()) if k != "SYSTEM" ] ) print(tabulate(output, headers=["", filepath1, filepath2])) return 0
def test_make_vasp_rlx_cell_shape (self): jdata = { 'relax_incar' : 'vasp_input/INCAR.rlx', 'potcar_map': {'Si': 'vasp_input/POTCAR' }, 'vol_start': 15, 'vol_end': 25, 'vol_step': 1.0, 'eos_relax_cell_shape': True, } make_vasp(jdata, 'confs/si/mp-149') target_path = '01.eos/si/mp-149/vasp-relax_incar' equi_path = '00.equi/si/mp-149/vasp-relax_incar' dfm_dirs = glob.glob(os.path.join(target_path, 'vol*')) # check root INCAR incar0 = Incar.from_file(os.path.join('vasp_input', 'INCAR.rlx')) incar1 = Incar.from_file(os.path.join(target_path, 'INCAR')) self.assertFalse(incar0 == incar1) incar0['ISIF'] = 4 self.assertTrue(incar0 == incar1) # check root POTCAR with open(os.path.join('vasp_input', 'POTCAR')) as fp: pot0 = fp.read() with open(os.path.join(target_path, 'POTCAR')) as fp: pot1 = fp.read() self.assertEqual(pot0, pot1) # check subdir for ii in dfm_dirs: self.assertTrue(os.path.isfile(os.path.join(ii, 'KPOINTS'))) self.assertEqual(os.path.realpath(os.path.join(ii, 'POSCAR.orig')), os.path.realpath(os.path.join(equi_path, 'CONTCAR'))) self.assertEqual(os.path.realpath(os.path.join(ii, 'INCAR')), os.path.realpath(os.path.join(target_path, 'INCAR'))) self.assertEqual(os.path.realpath(os.path.join(ii, 'POTCAR')), os.path.realpath(os.path.join(target_path, 'POTCAR'))) sys = dpdata.System(os.path.join(ii, 'POSCAR')) vol = float(ii.split('/')[-1].split('-')[1]) natoms = sys.get_natoms() self.assertAlmostEqual(vol, np.linalg.det(sys['cells'][0]) / natoms)
def check(self): incar = Incar.from_file("INCAR") is_npt = incar.get("MDALGO") == 3 if not is_npt: return False outcar = Outcar("OUTCAR") patterns = {"MDALGO": "MDALGO\s+=\s+([\d]+)"} outcar.read_pattern(patterns=patterns) if outcar.data["MDALGO"] == [['3']]: return False else: return True
def _verify_files(self, skip_kpoints=False, preserve_incar=False, potcar_spec=False): if not preserve_incar: self.assertEqual(Incar.from_file("INCAR"), self.ref_incar) poscar = Poscar.from_file("POSCAR") self.assertEqual(str(poscar), str(self.ref_poscar)) if potcar_spec: symbols = Path("POTCAR.spec").read_text().split() self.assertEqual(symbols, self.ref_potcar.symbols) else: potcar = Potcar.from_file("POTCAR") self.assertEqual(potcar.symbols, self.ref_potcar.symbols) if not skip_kpoints: kpoints = Kpoints.from_file("KPOINTS") self.assertEqual(str(kpoints), str(self.ref_kpoints)) else: self.assertEqual(Incar.from_file("INCAR"), self.ref_incar_preserve)
def test_setup(self): os.chdir(test_dir) v = VaspJob("hello") v.setup() incar = Incar.from_file("INCAR") count = multiprocessing.cpu_count() if count > 1: self.assertGreater(incar["NPAR"], 1) shutil.copy("INCAR.orig", "INCAR") os.remove("INCAR.orig") os.remove("KPOINTS.orig") os.remove("POTCAR.orig") os.remove("POSCAR.orig")
def diff_incar(args): filepath1 = args.incars[0] filepath2 = args.incars[1] incar1 = Incar.from_file(filepath1) incar2 = Incar.from_file(filepath2) def format_lists(v): if isinstance(v, (tuple, list)): return " ".join(["%d*%.2f" % (len(tuple(group)), i) for (i, group) in itertools.groupby(v)]) return v d = incar1.diff(incar2) output = [['SAME PARAMS', '', ''], ['---------------', '', ''], ['', '', ''], ['DIFFERENT PARAMS', '', ''], ['----------------', '', '']] output.extend([(k, format_lists(d['Same'][k]), format_lists(d['Same'][k])) for k in sorted(d['Same'].keys()) if k != "SYSTEM"]) output.extend([(k, format_lists(d['Different'][k]['INCAR1']), format_lists(d['Different'][k]['INCAR2'])) for k in sorted(d['Different'].keys()) if k != "SYSTEM"]) print(tabulate(output, headers=['', filepath1, filepath2]))
def test_get_defect_charge_state(tmpdir): tmpdir.chdir() structure = Structure(Lattice.cubic(10), ["H", "He"], [[0.0] * 3, [0.5] * 3]) fake_potcar_str = """ PAW_PBE H 15Jun2001 1.00000000000000 parameters from PSCTR are: VRHFIN =H: ultrasoft test LEXCH = PE TITEL = PAW_PBE H 15Jun2001 POMASS = 1.000; ZVAL = 1.000 mass and valenz ENMAX = 250.000; ENMIN = 200.000 eV END of PSCTR-controll parameters End of Dataset PAW_PBE He_pv 15Jun2001 1.00000000000000 parameters from PSCTR are: VRHFIN =He: ultrasoft test LEXCH = PE TITEL = PAW_PBE He_pv 15Jun2001 POMASS = 1.000; ZVAL = 1.000 mass and valenz ENMAX = 250.000; ENMIN = 200.000 eV END of PSCTR-controll parameters End of Dataset """ Path("POTCAR").write_text(fake_potcar_str) potcar = Potcar.from_file("POTCAR") incar = Incar.from_string("NELECT = 1") assert get_defect_charge_state(Poscar(structure), potcar, incar) == 2 - 1 structure = Structure(Lattice.cubic(10), ["H", "He", "H", "H"], [[0.0] * 3, [0.2] * 3, [0.4] * 3, [0.6] * 3]) with pytest.raises(ValueError): get_defect_charge_state(Poscar(structure), potcar, incar) incar = Incar.from_string("") assert get_defect_charge_state(Poscar(structure), potcar, incar) == 0