Skip to content

Commit

Permalink
Fix usage of strict=True for zip in cp2k.outputs (#4084)
Browse files Browse the repository at this point in the history
* revert to strict=False for some zip

* add some return types

* Revert "add some return types"

This reverts commit 0663667.

* make test names follow naming convention

* avoid module level variable

* separate tests for basis and potential
  • Loading branch information
DanielYang59 authored Oct 2, 2024
1 parent b4bc03d commit 47b1b42
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 59 deletions.
10 changes: 5 additions & 5 deletions src/pymatgen/io/cp2k/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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]:
Expand Down Expand Up @@ -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

Expand Down
112 changes: 59 additions & 53 deletions tests/io/cp2k/test_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
Expand All @@ -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],
[
Expand All @@ -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

Expand All @@ -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)
Expand All @@ -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

Expand Down Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion tests/io/cp2k/test_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 47b1b42

Please sign in to comment.