Skip to content

Commit 744dbcc

Browse files
committed
deprecate get_slab_regions as a method for Slab
1 parent 8a864c5 commit 744dbcc

File tree

2 files changed

+77
-71
lines changed

2 files changed

+77
-71
lines changed

src/pymatgen/core/surface.py

Lines changed: 76 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,78 @@ def get_equi_sites(slab: Slab, sites: list[int]) -> list[int]:
737737
else:
738738
warnings.warn("Equivalent sites could not be found for some indices. Surface unchanged.", stacklevel=2)
739739

740+
def get_slab_regions(
741+
self,
742+
blength: float = 3.5,
743+
) -> list[tuple[float, float]]:
744+
"""Find the z-ranges for the slab region.
745+
746+
Useful for discerning where the slab ends and vacuum begins
747+
if the slab is not fully within the cell.
748+
749+
Args:
750+
slab (Slab): The Slab to analyse.
751+
blength (float): The bond length between atoms in Angstrom.
752+
You generally want this value to be larger than the actual
753+
bond length in order to find atoms that are part of the slab.
754+
755+
TODO (@DanielYang59): maybe project all z coordinates to 1D?
756+
"""
757+
frac_coords: list = [] # TODO (@DanielYang59): zip site and coords?
758+
indices: list = []
759+
760+
all_indices: list = []
761+
762+
for site in self:
763+
neighbors = self.get_neighbors(site, blength)
764+
for nn in neighbors:
765+
# TODO (@DanielYang59): use z coordinate (z<0) to check
766+
# if a Slab is contiguous is suspicious (Slab could locate
767+
# entirely below z=0)
768+
769+
# Find sites with z < 0 (sites noncontiguous within cell)
770+
if nn[0].frac_coords[2] < 0:
771+
frac_coords.append(nn[0].frac_coords[2])
772+
indices.append(nn[-2])
773+
774+
if nn[-2] not in all_indices:
775+
all_indices.append(nn[-2])
776+
777+
# If slab is noncontiguous
778+
if frac_coords:
779+
# Locate the lowest site within the upper Slab
780+
last_frac_coords = []
781+
last_indices = []
782+
while frac_coords:
783+
last_frac_coords = copy.copy(frac_coords)
784+
last_indices = copy.copy(indices)
785+
786+
site = self[indices[frac_coords.index(min(frac_coords))]]
787+
neighbors = self.get_neighbors(site, blength, include_index=True, include_image=True)
788+
frac_coords, indices = [], []
789+
for nn in neighbors:
790+
if 1 > nn[0].frac_coords[2] > 0 and nn[0].frac_coords[2] < site.frac_coords[2]:
791+
# Sites are noncontiguous within cell
792+
frac_coords.append(nn[0].frac_coords[2])
793+
indices.append(nn[-2])
794+
if nn[-2] not in all_indices:
795+
all_indices.append(nn[-2])
796+
797+
# Locate the highest site within the lower Slab
798+
upper_fcoords: list = [
799+
site.frac_coords[2]
800+
for site in self
801+
if all(nn.index not in all_indices for nn in self.get_neighbors(site, blength))
802+
]
803+
coords: list = copy.copy(frac_coords) if frac_coords else copy.copy(last_frac_coords)
804+
min_top = self[last_indices[coords.index(min(coords))]].frac_coords[2]
805+
return [(0, max(upper_fcoords)), (min_top, 1)]
806+
807+
# If the entire slab region is within the cell, just
808+
# set the range as the highest and lowest site in the Slab
809+
sorted_sites = sorted(self, key=lambda site: site.frac_coords[2])
810+
return [(sorted_sites[0].frac_coords[2], sorted_sites[-1].frac_coords[2])]
811+
740812

741813
def center_slab(slab: Structure) -> Structure:
742814
"""Relocate the slab to the center such that its center
@@ -793,78 +865,13 @@ def center_slab(slab: Structure) -> Structure:
793865
return slab
794866

795867

796-
def get_slab_regions(
797-
slab: Slab,
798-
blength: float = 3.5,
799-
) -> list[tuple[float, float]]:
868+
@deprecated(Slab.get_slab_regions, message="use `Slab.get_slab_regions` instead.")
869+
def get_slab_regions(slab: Slab, blength: float = 3.5):
800870
"""Find the z-ranges for the slab region.
801871
802-
Useful for discerning where the slab ends and vacuum begins
803-
if the slab is not fully within the cell.
804-
805-
Args:
806-
slab (Slab): The Slab to analyse.
807-
blength (float): The bond length between atoms in Angstrom.
808-
You generally want this value to be larger than the actual
809-
bond length in order to find atoms that are part of the slab.
810-
811-
TODO (@DanielYang59): this should be a method for `Slab`?
812-
TODO (@DanielYang59): maybe project all z coordinates to 1D?
872+
Deprecated: use `Slab.get_slab_regions` instead.
813873
"""
814-
frac_coords: list = [] # TODO (@DanielYang59): zip site and coords?
815-
indices: list = []
816-
817-
all_indices: list = []
818-
819-
for site in slab:
820-
neighbors = slab.get_neighbors(site, blength)
821-
for nn in neighbors:
822-
# TODO (@DanielYang59): use z coordinate (z<0) to check
823-
# if a Slab is contiguous is suspicious (Slab could locate
824-
# entirely below z=0)
825-
826-
# Find sites with z < 0 (sites noncontiguous within cell)
827-
if nn[0].frac_coords[2] < 0:
828-
frac_coords.append(nn[0].frac_coords[2])
829-
indices.append(nn[-2])
830-
831-
if nn[-2] not in all_indices:
832-
all_indices.append(nn[-2])
833-
834-
# If slab is noncontiguous
835-
if frac_coords:
836-
# Locate the lowest site within the upper Slab
837-
last_frac_coords = []
838-
last_indices = []
839-
while frac_coords:
840-
last_frac_coords = copy.copy(frac_coords)
841-
last_indices = copy.copy(indices)
842-
843-
site = slab[indices[frac_coords.index(min(frac_coords))]]
844-
neighbors = slab.get_neighbors(site, blength, include_index=True, include_image=True)
845-
frac_coords, indices = [], []
846-
for nn in neighbors:
847-
if 1 > nn[0].frac_coords[2] > 0 and nn[0].frac_coords[2] < site.frac_coords[2]:
848-
# Sites are noncontiguous within cell
849-
frac_coords.append(nn[0].frac_coords[2])
850-
indices.append(nn[-2])
851-
if nn[-2] not in all_indices:
852-
all_indices.append(nn[-2])
853-
854-
# Locate the highest site within the lower Slab
855-
upper_fcoords: list = [
856-
site.frac_coords[2]
857-
for site in slab
858-
if all(nn.index not in all_indices for nn in slab.get_neighbors(site, blength))
859-
]
860-
coords: list = copy.copy(frac_coords) if frac_coords else copy.copy(last_frac_coords)
861-
min_top = slab[last_indices[coords.index(min(coords))]].frac_coords[2]
862-
return [(0, max(upper_fcoords)), (min_top, 1)]
863-
864-
# If the entire slab region is within the cell, just
865-
# set the range as the highest and lowest site in the Slab
866-
sorted_sites = sorted(slab, key=lambda site: site.frac_coords[2])
867-
return [(sorted_sites[0].frac_coords[2], sorted_sites[-1].frac_coords[2])]
874+
return slab.get_slab_regions(blength=blength)
868875

869876

870877
class SlabGenerator:

tests/core/test_surface.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
SlabGenerator,
1818
generate_all_slabs,
1919
get_d,
20-
get_slab_regions,
2120
get_symmetrically_distinct_miller_indices,
2221
get_symmetrically_equivalent_miller_indices,
2322
miller_index_from_sites,
@@ -309,7 +308,7 @@ def test_get_slab_regions(self):
309308
bottom_c.append(site.frac_coords[2])
310309
else:
311310
top_c.append(site.frac_coords[2])
312-
ranges = get_slab_regions(slab)
311+
ranges = slab.get_slab_regions()
313312
assert tuple(ranges[0]) == (0, max(bottom_c))
314313
assert tuple(ranges[1]) == (min(top_c), 1)
315314

0 commit comments

Comments
 (0)