Skip to content

Commit 9523e3c

Browse files
CompRhysmkhortonshyuep
authored
Add method to get the Pearson symbol to SpaceGroupAnalyzer (#4281)
* fea: add method to get the pearson symbol * test: test the pearson symbols * clean: clean and comment sga tests * fix: LiPo4 actually FePO4 * fix linting and supress warning. --------- Signed-off-by: Matthew Horton <[email protected]> Co-authored-by: Matthew Horton <[email protected]> Co-authored-by: Shyue Ping Ong <[email protected]>
1 parent 4ca6092 commit 9523e3c

File tree

3 files changed

+51
-15
lines changed

3 files changed

+51
-15
lines changed

src/pymatgen/analysis/local_env.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -3745,25 +3745,28 @@ def get_nn_info(self, structure: Structure, n: int):
37453745

37463746
if self.use_fictive_radius:
37473747
# calculate fictive ionic radii
3748-
fict_ionic_radii = [_get_fictive_ionic_radius(site, neighbor) for neighbor in neighbors]
3748+
fictive_ionic_radii = [_get_fictive_ionic_radius(site, neighbor) for neighbor in neighbors]
37493749
else:
37503750
# just use the bond distance
3751-
fict_ionic_radii = [neighbor.nn_distance for neighbor in neighbors]
3751+
fictive_ionic_radii = [neighbor.nn_distance for neighbor in neighbors]
37523752

37533753
# calculate mean fictive ionic radius
3754-
mefir = _get_mean_fictive_ionic_radius(fict_ionic_radii)
3754+
mean_fictive_ionic_radius = _get_mean_fictive_ionic_radius(fictive_ionic_radii)
37553755

37563756
# iteratively solve MEFIR; follows equation 4 in Hoppe's EconN paper
3757-
prev_mefir = float("inf")
3758-
while abs(prev_mefir - mefir) > 1e-4:
3757+
prev_mean_fictive_ionic_radius = float("inf")
3758+
while abs(prev_mean_fictive_ionic_radius - mean_fictive_ionic_radius) > 1e-4:
37593759
# this is guaranteed to converge
3760-
prev_mefir = mefir
3761-
mefir = _get_mean_fictive_ionic_radius(fict_ionic_radii, minimum_fir=mefir)
3760+
prev_mean_fictive_ionic_radius = mean_fictive_ionic_radius
3761+
mean_fictive_ionic_radius = _get_mean_fictive_ionic_radius(
3762+
fictive_ionic_radii,
3763+
minimum_fir=mean_fictive_ionic_radius,
3764+
)
37623765

37633766
siw = []
3764-
for nn, fir in zip(neighbors, fict_ionic_radii, strict=True):
3767+
for nn, fictive_ionic_radius in zip(neighbors, fictive_ionic_radii, strict=True):
37653768
if nn.nn_distance < self.cutoff:
3766-
w = math.exp(1 - (fir / mefir) ** 6)
3769+
w = math.exp(1 - (fictive_ionic_radius / mean_fictive_ionic_radius) ** 6)
37673770
if w > self.tol:
37683771
bonded_site = {
37693772
"site": nn,

src/pymatgen/symmetry/analyzer.py

+23
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,29 @@ def get_lattice_type(self) -> LatticeType:
246246
return "rhombohedral"
247247
return "hexagonal" if system == "trigonal" else system
248248

249+
def get_pearson_symbol(self) -> str:
250+
"""Get the Pearson symbol for the structure.
251+
252+
Returns:
253+
str: Pearson symbol for structure.
254+
"""
255+
cry_sys = self.get_crystal_system()
256+
spg_sym = self.get_space_group_symbol()
257+
centering = "C" if spg_sym[0] in ("A", "B", "C", "S") else spg_sym[0]
258+
259+
CRYSTAL_FAMILY_SYMBOLS = {
260+
"triclinic": "a",
261+
"monoclinic": "m",
262+
"orthorhombic": "o",
263+
"tetragonal": "t",
264+
"trigonal": "h",
265+
"hexagonal": "h",
266+
"cubic": "c",
267+
}
268+
269+
num_sites_conventional = len(self._space_group_data.std_types)
270+
return f"{CRYSTAL_FAMILY_SYMBOLS[cry_sys]}{centering}{num_sites_conventional}"
271+
249272
def get_symmetry_dataset(self) -> SpglibDataset:
250273
"""Get the symmetry dataset as a SpglibDataset.
251274

tests/symmetry/test_analyzer.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,25 @@
2626

2727
class TestSpacegroupAnalyzer(PymatgenTest):
2828
def setUp(self):
29+
# FePO4
2930
self.structure = Structure.from_file(f"{VASP_IN_DIR}/POSCAR")
3031
self.sg = SpacegroupAnalyzer(self.structure, 0.001)
32+
33+
# Li10GeP2S12
3134
self.disordered_structure = self.get_structure("Li10GeP2S12")
3235
self.disordered_sg = SpacegroupAnalyzer(self.disordered_structure, 0.001)
36+
37+
# FePO4 with order of sites changed so the atoms aren't grouped by element.
3338
struct = self.structure.copy()
3439
site = struct[0]
3540
del struct[0]
3641
struct.append(site.species, site.frac_coords)
3742
self.sg3 = SpacegroupAnalyzer(struct, 0.001)
38-
graphite = self.get_structure("Graphite")
39-
graphite.add_site_property("magmom", [0.1] * len(graphite))
40-
self.sg4 = SpacegroupAnalyzer(graphite, 0.001)
41-
self.structure4 = graphite
43+
44+
# Graphite
45+
self.structure4 = self.get_structure("Graphite")
46+
self.structure4.add_site_property("magmom", [0.1] * len(self.structure4))
47+
self.sg4 = SpacegroupAnalyzer(self.structure4, 0.001)
4248

4349
def test_primitive(self):
4450
struct = Structure.from_spacegroup("Fm-3m", np.eye(3) * 3, ["Cu"], [[0, 0, 0]])
@@ -49,9 +55,7 @@ def test_primitive(self):
4955
def test_is_laue(self):
5056
struct = Structure.from_spacegroup("Fm-3m", np.eye(3) * 3, ["Cu"], [[0, 0, 0]])
5157
assert SpacegroupAnalyzer(struct).is_laue()
52-
5358
assert self.sg.is_laue()
54-
5559
assert self.disordered_sg.is_laue()
5660

5761
def test_magnetic(self):
@@ -86,6 +90,12 @@ def test_get_pointgroup(self):
8690
assert self.sg.get_point_group_symbol() == "mmm"
8791
assert self.disordered_sg.get_point_group_symbol() == "4/mmm"
8892

93+
def test_get_pearson_symbol(self):
94+
assert self.sg.get_pearson_symbol() == "oP24"
95+
assert self.disordered_sg.get_pearson_symbol() == "tP58"
96+
assert self.sg3.get_pearson_symbol() == "oP24"
97+
assert self.sg4.get_pearson_symbol() == "hP4"
98+
8999
def test_get_point_group_operations(self):
90100
sg: SpacegroupAnalyzer
91101
rng = np.random.default_rng()

0 commit comments

Comments
 (0)