Skip to content

Commit

Permalink
update: add use cartesian to point defects and used functions
Browse files Browse the repository at this point in the history
  • Loading branch information
VsevolodX committed Oct 15, 2024
1 parent e040594 commit fb3742e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
23 changes: 18 additions & 5 deletions src/py/mat3ra/made/tools/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)])
Expand Down
1 change: 1 addition & 0 deletions src/py/mat3ra/made/tools/build/defect/builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions src/py/mat3ra/made/tools/build/defect/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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
)
Expand Down

0 comments on commit fb3742e

Please sign in to comment.