From fb3742e5da96e0d9bbf79e20ee105839d9b1b835 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Mon, 14 Oct 2024 18:02:43 -0700 Subject: [PATCH] update: add use cartesian to point defects and used functions --- src/py/mat3ra/made/tools/analyze.py | 23 +++++++++++++++---- .../made/tools/build/defect/builders.py | 1 + .../made/tools/build/defect/configuration.py | 10 ++++++-- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/py/mat3ra/made/tools/analyze.py b/src/py/mat3ra/made/tools/analyze.py index 12d7e88a..4c596238 100644 --- a/src/py/mat3ra/made/tools/analyze.py +++ b/src/py/mat3ra/made/tools/analyze.py @@ -77,25 +77,34 @@ def get_chemical_formula(atoms: ASEAtoms): return atoms.get_chemical_formula() -def get_closest_site_id_from_coordinate(material: Material, coordinate: List[float]) -> int: +def get_closest_site_id_from_coordinate( + material: Material, coordinate: List[float], use_cartesian_coordinates: bool = False +) -> int: """ Get the site ID of the closest site to a given coordinate in the crystal. Args: material (Material): The material object to find the closest site in. coordinate (List[float]): The coordinate to find the closest site to. + use_cartesian_coordinates (bool): Whether to use Cartesian coordinates for the calculation. Returns: int: The site ID of the closest site. """ - coordinates = np.array(material.coordinates_array) + new_material = material.clone() + if use_cartesian_coordinates: + new_material.to_cartesian() + coordinates = np.array(new_material.coordinates_array) coordinate = np.array(coordinate) # type: ignore distances = np.linalg.norm(coordinates - coordinate, axis=1) return int(np.argmin(distances)) def get_closest_site_id_from_coordinate_and_element( - material: Material, coordinate: List[float], chemical_element: Optional[str] = None + material: Material, + coordinate: List[float], + chemical_element: Optional[str] = None, + use_cartesian_coordinates: bool = False, ) -> int: """ Get the site ID of the closest site with a given element to a given coordinate in the crystal. @@ -104,16 +113,20 @@ def get_closest_site_id_from_coordinate_and_element( material (Material): The material object to find the closest site in. coordinate (List[float]): The coordinate to find the closest site to. chemical_element (str): The element of the site to find. + use_cartesian_coordinates (bool): Whether to use Cartesian coordinates for the calculation. Returns: int: The site ID of the closest site with the given element. """ - coordinates = np.array(material.basis.coordinates.values) + new_material = material.clone() + if use_cartesian_coordinates: + new_material.to_cartesian() + coordinates = np.array(new_material.basis.coordinates.values) coordinate = np.array(coordinate) # type: ignore distances = np.linalg.norm(coordinates - coordinate, axis=1) if chemical_element is not None: - elements = np.array(material.basis.elements.values) + elements = np.array(new_material.basis.elements.values) element_indices = np.where(elements == chemical_element)[0] distances = distances[element_indices] return int(element_indices[np.argmin(distances)]) diff --git a/src/py/mat3ra/made/tools/build/defect/builders.py b/src/py/mat3ra/made/tools/build/defect/builders.py index c3e67936..283d9c2e 100644 --- a/src/py/mat3ra/made/tools/build/defect/builders.py +++ b/src/py/mat3ra/made/tools/build/defect/builders.py @@ -76,6 +76,7 @@ def _generate(self, configuration: BaseBuilder._ConfigurationType) -> List[_Gene pymatgen_periodic_site = PymatgenPeriodicSite( species=self._get_species(configuration), coords=configuration.coordinate, + coords_are_cartesian=configuration.use_cartesian_coordinates, lattice=pymatgen_structure.lattice, ) # oxi_state set to 0 to allow for 2D materials, otherwise oxi_state search takes infinite loop in pymatgen diff --git a/src/py/mat3ra/made/tools/build/defect/configuration.py b/src/py/mat3ra/made/tools/build/defect/configuration.py index 6a2dbb98..732b498c 100644 --- a/src/py/mat3ra/made/tools/build/defect/configuration.py +++ b/src/py/mat3ra/made/tools/build/defect/configuration.py @@ -41,8 +41,9 @@ class PointDefectConfiguration(BaseDefectConfiguration, InMemoryEntity): """ defect_type: PointDefectTypeEnum - coordinate: List[float] = [0, 0, 0] # crystal coordinates + coordinate: List[float] = [0, 0, 0] chemical_element: Optional[str] = None + use_cartesian_coordinates: bool = False @classmethod def from_site_id( @@ -60,10 +61,15 @@ def from_approximate_position( defect_type: PointDefectTypeEnum, approximate_coordinate: List[float], chemical_element: Optional[str] = None, + use_cartesian_coordinates: bool = False, ): if not crystal: raise RuntimeError("Crystal is not defined") - closest_site_id = get_closest_site_id_from_coordinate(crystal, approximate_coordinate) + closest_site_id = get_closest_site_id_from_coordinate( + material=crystal, + coordinate=approximate_coordinate, + use_cartesian_coordinates=use_cartesian_coordinates, + ) return cls.from_site_id( crystal=crystal, defect_type=defect_type, site_id=closest_site_id, chemical_element=chemical_element )