Skip to content

Commit

Permalink
fix: 781 pymatgen structure bug (#782)
Browse files Browse the repository at this point in the history
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
	- Enhanced support for PyMatGen structure format conversion
	- Improved handling of periodic boundary conditions (PBC)

- **Tests**
	- Added new test class for PyMatGen structure conversion
	- Expanded test data with additional element types (Fe, Li, O, P)

- **Bug Fixes**
	- Refined atomic species list generation
	- Improved error handling for structure periodicity

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Han Wang <[email protected]>
  • Loading branch information
wanghan-iapcm and Han Wang authored Jan 17, 2025
1 parent 961b591 commit 5ebe959
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 38 deletions.
9 changes: 4 additions & 5 deletions dpdata/plugins/pymatgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,15 @@ def to_system(self, data, **kwargs):
"""Convert System to Pymatgen Structure obj."""
structures = []
try:
from pymatgen.core import Structure
from pymatgen.core import Lattice, Structure
except ModuleNotFoundError as e:
raise ImportError("No module pymatgen.Structure") from e

species = []
for name, numb in zip(data["atom_names"], data["atom_numbs"]):
species.extend([name] * numb)
species = [data["atom_names"][tt] for tt in data["atom_types"]]
pbc = not (data.get("nopbc", False))
for ii in range(data["coords"].shape[0]):
structure = Structure(
data["cells"][ii],
Lattice(data["cells"][ii], pbc=[pbc] * 3),
species,
data["coords"][ii],
coords_are_cartesian=True,
Expand Down
11 changes: 10 additions & 1 deletion dpdata/pymatgen/structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@


def from_system_data(structure) -> dict:
symbols = [site.species_string for site in structure]
"""Convert one pymatgen structure to dpdata's datadict."""
symbols = [ii.specie.symbol for ii in structure]
atom_names = list(structure.symbol_set)
atom_numbs = [symbols.count(symbol) for symbol in atom_names]
atom_types = np.array([atom_names.index(symbol) for symbol in symbols]).astype(int)
coords = structure.cart_coords
cells = structure.lattice.matrix
if all(structure.pbc):
pbc = True
elif not any(structure.pbc):
pbc = False
else:
raise ValueError(f"Partial pbc condition {structure.pbc} is not supported")

info_dict = {
"atom_names": atom_names,
"atom_numbs": atom_numbs,
"atom_types": atom_types,
"coords": np.array([coords]),
"cells": np.array([cells]),
"orig": np.zeros(3),
"nopbc": not pbc,
}
return info_dict
Binary file added tests/pymatgen_data/deepmd/set.000/box.npy
Binary file not shown.
Binary file added tests/pymatgen_data/deepmd/set.000/coord.npy
Binary file not shown.
Binary file added tests/pymatgen_data/deepmd/set.000/energy.npy
Binary file not shown.
Binary file added tests/pymatgen_data/deepmd/set.000/force.npy
Binary file not shown.
Binary file added tests/pymatgen_data/deepmd/set.000/virial.npy
Binary file not shown.
98 changes: 98 additions & 0 deletions tests/pymatgen_data/deepmd/type.raw
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
4 changes: 4 additions & 0 deletions tests/pymatgen_data/deepmd/type_map.raw
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fe
Li
O
P
32 changes: 0 additions & 32 deletions tests/test_from_pymatgen.py

This file was deleted.

61 changes: 61 additions & 0 deletions tests/test_pymatgen_structure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from __future__ import annotations

import os
import unittest

from comp_sys import CompSys, IsNoPBC, IsPBC
from context import dpdata

try:
from pymatgen.core import Structure # noqa: F401

exist_module = True
except Exception:
exist_module = False


@unittest.skipIf(not exist_module, "skip pymatgen")
class TestFormPytmatgen(unittest.TestCase, CompSys):
def setUp(self):
structure = Structure.from_file(os.path.join("poscars", "POSCAR.P42nmc"))
self.system_1 = dpdata.System(structure, fmt="pymatgen/structure")
self.system_2 = dpdata.System(
os.path.join("poscars", "POSCAR.P42nmc"), fmt="poscar"
)
self.places = 6
self.e_places = 6
self.f_places = 6
self.v_places = 6


@unittest.skipIf(not exist_module, "skip pymatgen")
class TestFormToPytmatgen(unittest.TestCase, CompSys, IsPBC):
def setUp(self):
self.system = dpdata.System("pymatgen_data/deepmd/", fmt="deepmd/npy")
self.system_1 = self.system
self.system_2 = dpdata.System().from_pymatgen_structure(
self.system.to("pymatgen/structure")[0]
)
self.places = 6
self.e_places = 6
self.f_places = 6
self.v_places = 6


@unittest.skipIf(not exist_module, "skip pymatgen")
class TestFormToPytmatgenNopbc(unittest.TestCase, CompSys, IsNoPBC):
def setUp(self):
self.system = dpdata.System("pymatgen_data/deepmd/", fmt="deepmd/npy")
self.system.data["nopbc"] = True
self.system_1 = self.system
self.system_2 = dpdata.System().from_pymatgen_structure(
self.system.to("pymatgen/structure")[0]
)
self.places = 6
self.e_places = 6
self.f_places = 6
self.v_places = 6


if __name__ == "__main__":
unittest.main()

0 comments on commit 5ebe959

Please sign in to comment.