diff --git a/src/pymatgen/io/cp2k/outputs.py b/src/pymatgen/io/cp2k/outputs.py index 7cc2a18e763..aa9e0acf3c2 100644 --- a/src/pymatgen/io/cp2k/outputs.py +++ b/src/pymatgen/io/cp2k/outputs.py @@ -297,7 +297,7 @@ def parse_structures(self, trajectory_file=None, lattice_file=None): self.structures = [] gs = self.initial_structure.site_properties.get("ghost") if not self.is_molecule: - for mol, latt in zip(mols, lattices, strict=True): + for mol, latt in zip(mols, lattices, strict=False): self.structures.append( Structure( lattice=latt, @@ -520,7 +520,7 @@ def parse_ionic_steps(self): if not self.data.get("stress_tensor"): self.parse_stresses() - for i, (structure, energy) in enumerate(zip(self.structures, self.data.get("total_energy"), strict=True)): + for i, (structure, energy) in enumerate(zip(self.structures, self.data.get("total_energy"), strict=False)): self.ionic_steps.append( { "structure": structure, @@ -627,8 +627,8 @@ def parse_dft_params(self): suffix = "" for ll in self.data.get("vdw"): for _possible, _name in zip( - ["RVV10", "LMKLL", "DRSLL", "DFT-D3", "DFT-D2"], - ["RVV10", "LMKLL", "DRSLL", "D3", "D2"], + ("RVV10", "LMKLL", "DRSLL", "DFT-D3", "DFT-D2"), + ("RVV10", "LMKLL", "DRSLL", "D3", "D2"), strict=True, ): if _possible in ll[0]: @@ -1463,7 +1463,7 @@ def _gauss_smear(densities, energies, npts, width): dct = np.zeros(npts) e_s = np.linspace(min(energies), max(energies), npts) - for e, _pd in zip(energies, densities, strict=True): + for e, _pd in zip(energies, densities, strict=False): weight = np.exp(-(((e_s - e) / width) ** 2)) / (np.sqrt(np.pi) * width) dct += _pd * weight diff --git a/tests/io/cp2k/test_inputs.py b/tests/io/cp2k/test_inputs.py index 8dfa114dabc..09797a70b5d 100644 --- a/tests/io/cp2k/test_inputs.py +++ b/tests/io/cp2k/test_inputs.py @@ -26,19 +26,6 @@ TEST_DIR = f"{TEST_FILES_DIR}/io/cp2k" -si_struct = Structure( - lattice=[[0, 2.734364, 2.734364], [2.734364, 0, 2.734364], [2.734364, 2.734364, 0]], - species=["Si", "Si"], - coords=[[0, 0, 0], [0.25, 0.25, 0.25]], -) - -nonsense_struct = Structure( - lattice=[[-1.0, -10.0, -100.0], [0.1, 0.01, 0.001], [7.0, 11.0, 21.0]], - species=["H"], - coords=[[-1, -1, -1]], -) - -ch_mol = Molecule(species=["C", "H"], coords=[[0, 0, 0], [1, 1, 1]]) BASIS_FILE_STR = """ H SZV-MOLOPT-GTH SZV-MOLOPT-GTH-q1 @@ -52,26 +39,9 @@ 0.066918004004 0.037148121400 0.021708243634 -0.001125195500 """ -ALL_HYDROGEN_STR = """ -H ALLELECTRON ALL - 1 0 0 - 0.20000000 0 -""" -POT_HYDROGEN_STR = """ -H GTH-PBE-q1 GTH-PBE - 1 - 0.20000000 2 -4.17890044 0.72446331 - 0 -""" -CP2K_INPUT_STR = """ -&GLOBAL - RUN_TYPE ENERGY - PROJECT_NAME CP2K ! default name -&END -""" -class TestBasisAndPotential(PymatgenTest): +class TestBasis(PymatgenTest): def test_basis_info(self): # Ensure basis metadata can be read from string basis_info = BasisInfo.from_str("cc-pc-DZVP-MOLOPT-q1-SCAN") @@ -93,25 +63,13 @@ def test_basis_info(self): assert basis_info3.polarization == 1 assert basis_info3.contracted, True - def test_potential_info(self): - # Ensure potential metadata can be read from string - pot_info = PotentialInfo.from_str("GTH-PBE-q1-NLCC") - assert pot_info.potential_type == "GTH" - assert pot_info.xc == "PBE" - assert pot_info.nlcc - - # Ensure one-way soft-matching works - pot_info2 = PotentialInfo.from_str("GTH-q1-NLCC") - assert pot_info2.softmatch(pot_info) - assert not pot_info.softmatch(pot_info2) - def test_basis(self): # Ensure cp2k formatted string can be read for data correctly mol_opt = GaussianTypeOrbitalBasisSet.from_str(BASIS_FILE_STR) assert mol_opt.nexp == [7] # Basis file can read from strings bf = BasisFile.from_str(BASIS_FILE_STR) - for obj in [mol_opt, bf.objects[0]]: + for obj in (mol_opt, bf.objects[0]): assert_allclose( obj.exponents[0], [ @@ -133,22 +91,49 @@ def test_basis(self): assert_array_equal(kw.values, ["AUX_FIT", "SZV-MOLOPT-GTH"]) mol_opt.info.admm = False + +class TestPotential(PymatgenTest): + all_hydrogen_str = """ +H ALLELECTRON ALL + 1 0 0 + 0.20000000 0 +""" + + pot_hydrogen_str = """ +H GTH-PBE-q1 GTH-PBE + 1 + 0.20000000 2 -4.17890044 0.72446331 + 0 +""" + + def test_potential_info(self): + # Ensure potential metadata can be read from string + pot_info = PotentialInfo.from_str("GTH-PBE-q1-NLCC") + assert pot_info.potential_type == "GTH" + assert pot_info.xc == "PBE" + assert pot_info.nlcc + + # Ensure one-way soft-matching works + pot_info2 = PotentialInfo.from_str("GTH-q1-NLCC") + assert pot_info2.softmatch(pot_info) + assert not pot_info.softmatch(pot_info2) + def test_potentials(self): # Ensure cp2k formatted string can be read for data correctly - h_all_elec = GthPotential.from_str(ALL_HYDROGEN_STR) + h_all_elec = GthPotential.from_str(self.all_hydrogen_str) assert h_all_elec.potential == "All Electron" - pot = GthPotential.from_str(POT_HYDROGEN_STR) + pot = GthPotential.from_str(self.pot_hydrogen_str) assert pot.potential == "Pseudopotential" assert pot.r_loc == approx(0.2) assert pot.nexp_ppl == approx(2) assert_allclose(pot.c_exp_ppl, [-4.17890044, 0.72446331]) # Basis file can read from strings - pot_file = PotentialFile.from_str(POT_HYDROGEN_STR) + pot_file = PotentialFile.from_str(self.pot_hydrogen_str) assert pot_file.objects[0] == pot pot_file_path = self.tmp_path / "potential-file" - pot_file_path.write_text(POT_HYDROGEN_STR) + pot_file_path.write_text(self.pot_hydrogen_str) pot_from_file = PotentialFile.from_file(pot_file_path) assert pot_file != pot_from_file # unequal because pot_from_file has filename != None @@ -159,12 +144,33 @@ def test_potentials(self): assert kw.values[0] == "ALL" -class TestInput(PymatgenTest): +class TestCp2kInput(PymatgenTest): + si_struct = Structure( + lattice=[[0, 2.734364, 2.734364], [2.734364, 0, 2.734364], [2.734364, 2.734364, 0]], + species=["Si", "Si"], + coords=[[0, 0, 0], [0.25, 0.25, 0.25]], + ) + + invalid_struct = Structure( + lattice=[[-1.0, -10.0, -100.0], [0.1, 0.01, 0.001], [7.0, 11.0, 21.0]], + species=["H"], + coords=[[-1, -1, -1]], + ) + + ch_mol = Molecule(species=["C", "H"], coords=[[0, 0, 0], [1, 1, 1]]) + + cp2k_input_str = """ +&GLOBAL + RUN_TYPE ENERGY + PROJECT_NAME CP2K ! default name +&END +""" + def setUp(self): self.ci = Cp2kInput.from_file(f"{TEST_DIR}/cp2k.inp") def test_basic_sections(self): - cp2k_input = Cp2kInput.from_str(CP2K_INPUT_STR) + cp2k_input = Cp2kInput.from_str(self.cp2k_input_str) assert cp2k_input["GLOBAL"]["RUN_TYPE"] == Keyword("RUN_TYPE", "energy") assert cp2k_input["GLOBAL"]["PROJECT_NAME"].description == "default name" self.assert_msonable(cp2k_input) @@ -190,13 +196,13 @@ def test_basic_keywords(self): assert "[Ha]" in kwd.get_str() def test_coords(self): - for struct in [nonsense_struct, si_struct, ch_mol]: + for struct in (self.invalid_struct, self.si_struct, self.ch_mol): coords = Coord(struct) for val in coords.keywords.values(): assert isinstance(val, Keyword | KeywordList) def test_kind(self): - for struct in [nonsense_struct, si_struct, ch_mol]: + for struct in (self.invalid_struct, self.si_struct, self.ch_mol): for spec in struct.species: assert spec == Kind(spec).specie @@ -246,7 +252,7 @@ def test_preprocessor(self): assert self.ci["FORCE_EVAL"]["DFT"]["SCF"]["MAX_SCF"] == Keyword("MAX_SCF", 1) def test_mongo(self): - cp2k_input = Cp2kInput.from_str(CP2K_INPUT_STR) + cp2k_input = Cp2kInput.from_str(self.cp2k_input_str) cp2k_input.inc({"GLOBAL": {"TEST": 1}}) assert cp2k_input["global"]["test"] == Keyword("TEST", 1) diff --git a/tests/io/cp2k/test_outputs.py b/tests/io/cp2k/test_outputs.py index cd3214af175..b3c8245a89c 100644 --- a/tests/io/cp2k/test_outputs.py +++ b/tests/io/cp2k/test_outputs.py @@ -12,7 +12,7 @@ TEST_DIR = f"{TEST_FILES_DIR}/io/cp2k" -class TestSet(TestCase): +class TestCp2kOutput(TestCase): def setUp(self): self.out = Cp2kOutput(f"{TEST_DIR}/cp2k.out", auto_load=True)