@@ -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
741813def 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
870877class SlabGenerator :
0 commit comments