Source code for site_analysis.voronoi_site_collection

"""Collection manager for Voronoi sites in crystal structures.

This module provides the VoronoiSiteCollection class, which manages a
collection of VoronoiSite objects and implements methods for assigning
atoms to these sites based on their positions in a crystal structure.

The VoronoiSiteCollection extends the base SiteCollection class with
specific functionality for Voronoi sites, implementing a different assignment
logic than other site collections:

For atom assignment, the collection:

1. Calculates distances from each site centre to each atom
2. Assigns each atom to the site with the nearest centre
3. Uses minimum-image convention distances to correctly handle periodic
   boundaries

Unlike other site types where individual sites can determine containment,
Voronoi site assignment is a global operation that depends on the relative
positions of all sites. This collection efficiently implements the Voronoi
tessellation logic using distance calculations rather than explicit
geometric construction of the Voronoi cells.
"""

import numpy as np
from pymatgen.core import Structure
from site_analysis.site_collection import SiteCollection
from site_analysis.atom import Atom
from site_analysis.site import Site
from site_analysis.voronoi_site import VoronoiSite
from site_analysis.distances import all_mic_distances

[docs] class VoronoiSiteCollection(SiteCollection): def __init__(self, sites: list[Site]) -> None: """Create a VoronoiSiteCollection instance. Args: sites (list(VoronoiSite)): list of VoronoiSite objects. Returns: None """ for s in sites: if not isinstance(s, VoronoiSite): raise TypeError super(VoronoiSiteCollection, self).__init__(sites) self.sites: list[VoronoiSite]
[docs] def analyse_structure(self, atoms: list[Atom], structure: Structure) -> None: """Analyse a structure to assign atoms to Voronoi sites. This method: 1. Assigns fractional coordinates to each atom based on the structure 2. Delegates to assign_site_occupations to determine which atoms belong in which sites based on Voronoi tessellation principles Args: atoms: List of Atom objects to be assigned to sites structure: Pymatgen Structure containing the atom positions Returns: None """ all_frac_coords = structure.frac_coords for a in atoms: a.assign_coords(all_frac_coords) self.assign_site_occupations(atoms, structure.lattice.matrix)
[docs] def assign_site_occupations(self, atoms: list[Atom], lattice_matrix: np.ndarray) -> None: """Assign atoms to Voronoi sites based on closest site centres. Uses minimum-image convention distances to assign each atom to the nearest site centre. Args: atoms: List of Atom objects to be assigned to sites. lattice_matrix: (3, 3) lattice matrix where rows are lattice vectors. """ self.reset_site_occupations() if not atoms: return site_coords = np.array([s.frac_coords for s in self.sites]) atom_coords = np.array([a.frac_coords for a in atoms]) dist_matrix = all_mic_distances(site_coords, atom_coords, lattice_matrix) site_list_indices = np.argmin(dist_matrix, axis=0) for atom, site_list_index in zip(atoms, site_list_indices): site = self.sites[site_list_index] self.update_occupation(site, atom)