Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix usage of strict=True for zip in cp2k.outputs #4084

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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