Skip to content

Commit

Permalink
magnetic dataset with pyo3
Browse files Browse the repository at this point in the history
  • Loading branch information
lan496 committed Feb 10, 2025
1 parent a87f793 commit 5714727
Show file tree
Hide file tree
Showing 17 changed files with 1,182 additions and 260 deletions.
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ build-python:
install-python:
python -m pip install uv maturin
maturin develop --release --manifest-path moyopy/Cargo.toml
python -m uv pip install -e "moyopy[dev]"
python -m pip install -e "moyopy[dev]"
pre-commit install

test-python:
Expand Down
10 changes: 9 additions & 1 deletion moyo/src/base/lattice.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use nalgebra::base::{Matrix3, Vector3};
use nalgebra::base::{Matrix3, OMatrix, RowVector3, Vector3};
use serde::{Deserialize, Serialize};

use crate::math::{
Expand All @@ -22,6 +22,14 @@ impl Lattice {
}
}

pub fn from_basis(basis: [[f64; 3]; 3]) -> Self {
Self::new(OMatrix::from_rows(&[
RowVector3::from(basis[0]),
RowVector3::from(basis[1]),
RowVector3::from(basis[2]),
]))
}

/// Return Minkowski reduced lattice and transformation matrix to it
pub fn minkowski_reduce(&self) -> Result<(Self, Matrix3<i32>), MoyoError> {
let (reduced_basis, trans_mat) = minkowski_reduce(&self.basis);
Expand Down
4 changes: 2 additions & 2 deletions moyo/src/base/magnetic_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub trait MagneticMoment: Sized + Clone {
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Collinear(pub f64);

impl MagneticMoment for Collinear {
Expand Down Expand Up @@ -66,7 +66,7 @@ impl MagneticMoment for Collinear {
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NonCollinear(pub Vector3<f64>);

impl MagneticMoment for NonCollinear {
Expand Down
2 changes: 1 addition & 1 deletion moyo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ use nalgebra::Matrix3;
/// A dataset containing symmetry information of the input crystal structure.
pub struct MoyoDataset {
// ------------------------------------------------------------------------
// Space-group type
// Identification
// ------------------------------------------------------------------------
/// Space group number.
pub number: Number,
Expand Down
57 changes: 57 additions & 0 deletions moyopy/python/moyopy/_base.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,52 @@ class Cell:
def positions(self) -> list[list[float]]: ...
@property
def numbers(self) -> list[int]: ...
@property
def num_atoms(self) -> int: ...
def serialize_json(self) -> str: ...
@classmethod
def deserialize_json(cls, json_str: str) -> Cell: ...

class CollinearMagneticCell:
def __init__(
self,
basis: list[list[float]],
positions: list[list[float]],
numbers: list[int],
magnetic_moments: list[float],
): ...
@property
def basis(self) -> list[list[float]]: ...
@property
def positions(self) -> list[list[float]]: ...
@property
def numbers(self) -> list[int]: ...
@property
def magnetic_moments(self) -> list[float]: ...
@property
def num_atoms(self) -> int: ...
def serialize_json(self) -> str: ...
@classmethod
def deserialize_json(cls, json_str: str) -> Cell: ...

class NonCollinearMagneticCell:
def __init__(
self,
basis: list[list[float]],
positions: list[list[float]],
numbers: list[int],
magnetic_moments: list[list[float]],
): ...
@property
def basis(self) -> list[list[float]]: ...
@property
def positions(self) -> list[list[float]]: ...
@property
def numbers(self) -> list[int]: ...
@property
def magnetic_moments(self) -> list[list[float]]: ...
@property
def num_atoms(self) -> int: ...
def serialize_json(self) -> str: ...
@classmethod
def deserialize_json(cls, json_str: str) -> Cell: ...
Expand All @@ -23,3 +69,14 @@ class Operations:
@property
def num_operations(self) -> int: ...
def __len__(self) -> int: ...

class MagneticOperations:
@property
def rotations(self) -> list[list[list[float]]]: ...
@property
def translations(self) -> list[list[float]]: ...
@property
def time_reversals(self) -> list[bool]: ...
@property
def num_operations(self) -> int: ...
def __len__(self) -> int: ...
270 changes: 270 additions & 0 deletions moyopy/python/moyopy/_dataset.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
from moyopy._base import (
Cell,
CollinearMagneticCell,
MagneticOperations,
NonCollinearMagneticCell,
Operations,
)
from moyopy._data import (
Setting,
)

class MoyoDataset:
"""A dataset containing symmetry information of the input crystal structure."""
def __init__(
self,
cell: Cell,
symprec: float = 1e-4,
angle_tolerance: float | None = None,
setting: Setting | None = None,
):
"""
Parameters
----------
cell: Cell
Input crystal structure.
symprec: float
Symmetry search tolerance in the unit of cell.basis.
angle_tolerance: float | None
Symmetry search tolerance in the unit of radians.
setting: Setting | None
Preference for the setting of the space group.
"""
# Space-group type
@property
def number(self) -> int:
"""Space group number."""
@property
def hall_number(self) -> int:
"""Hall symbol number."""
# Symmetry operations in the input cell
@property
def operations(self) -> Operations:
"""Symmetry operations in the input cell."""
# Site symmetry
@property
def orbits(self) -> list[int]:
"""Spglib's `crystallographic_orbits` not `equivalent_atoms`.
The `i`th atom in the input cell is equivalent to the `orbits[i]`th atom in the **input**
cell. For example, orbits=[0, 0, 2, 2, 2, 2] means the first two atoms are equivalent
and the last four atoms are equivalent to each other.
"""
@property
def wyckoffs(self) -> list[str]:
"""Wyckoff letters for each site in the input cell."""
@property
def site_symmetry_symbols(self) -> list[str]:
"""Site symmetry symbols for each site in the input cell.
The orientation of the site symmetry is w.r.t. the standardized cell.
"""
# Standardized cell
@property
def std_cell(self) -> Cell:
"""Standardized cell."""
@property
def std_linear(self) -> list[list[float]]:
"""Linear part of transformation from the input cell to the standardized cell."""
@property
def std_origin_shift(self) -> list[float]:
"""Origin shift of transformation from the input cell to the standardized cell."""
@property
def std_rotation_matrix(self) -> list[list[float]]:
"""Rigid rotation."""
@property
def pearson_symbol(self) -> str:
"""Pearson symbol for standardized cell."""
# Primitive standardized cell
@property
def prim_std_cell(self) -> Cell:
"""Primitive standardized cell."""
@property
def prim_std_linear(self) -> list[list[float]]:
"""Linear part of transformation from the input cell to the primitive standardized cell."""
@property
def prim_std_origin_shift(self) -> list[float]:
"""Origin shift of transformation from the input cell to the primitive standardized
cell."""
@property
def mapping_std_prim(self) -> list[int]:
"""Mapping sites in the input cell to those in the primitive standardized cell.
The `i`th atom in the input cell is mapped to the `mapping_to_std_prim[i]`th atom in the
primitive standardized cell.
"""
# Final parameters
@property
def symprec(self) -> float:
"""Actually used `symprec` in iterative symmetry search."""
@property
def angle_tolerance(self) -> float | None:
"""Actually used `angle_tolerance` in iterative symmetry search."""

class MoyoCollinearMagneticDataset:
"""A dataset containing magnetic symmetry information of the input collinear magnetic
structure."""
def __init__(
self,
magnetic_cell: CollinearMagneticCell,
symprec: float = 1e-4,
angle_tolerance: float | None = None,
mag_symprec: float | None = None,
is_axial: bool = False,
):
"""
Parameters
----------
magnetic_cell: CollinearMagneticCell
Input collinear magnetic structure.
symprec: float
Symmetry search tolerance in the unit of magnetic_cell.basis.
angle_tolerance: float | None
Symmetry search tolerance in the unit of radians.
mag_symprec: float | None
Symmetry search tolerance in the unit of magnetic moments.
is_axial: bool
Whether the magnetic moments are axial on improper operations.
"""
# Magnetic space-group type
@property
def uni_number(self) -> int:
"""UNI number for magnetic space-group type."""
# Magnetic symmetry operations in the input cell
@property
def magnetic_operations(self) -> MagneticOperations:
"""Magnetic symmetry operations in the input cell."""
# Site symmetry
@property
def orbits(self) -> list[int]:
"""The `i`th atom in the input magnetic cell is equivalent to the `orbits[i]`th atom
in the **input** magnetic cell. For example, orbits=[0, 0, 2, 2, 2, 2] means
the first two atoms are equivalent and the last four atoms are equivalent to each other.
"""
# Standardized magnetic cell
@property
def std_mag_cell(self) -> CollinearMagneticCell:
"""Standardized magnetic cell."""
@property
def std_linear(self) -> list[list[float]]:
"""Linear part of transformation from the input magnetic cell to the standardized
magnetic cell."""
@property
def std_origin_shift(self) -> list[float]:
"""Origin shift of transformation from the input magnetic cell to the standardized
magnetic cell."""
@property
def std_rotation_matrix(self) -> list[list[float]]:
"""Rigid rotation."""
# Primitive standardized magnetic cell
@property
def prim_std_mag_cell(self) -> CollinearMagneticCell:
"""Primitive standardized magnetic cell."""
@property
def prim_std_linear(self) -> list[list[float]]:
"""Linear part of transformation from the input magnetic cell to the primitive
standardized magnetic cell."""
@property
def prim_std_origin_shift(self) -> list[float]:
"""Origin shift of transformation from the input magnetic cell to the primitive
standardized magnetic cell."""
@property
def mapping_std_prim(self) -> list[int]:
"""Mapping sites in the input magnetic cell to those in the primitive standardized magnetic
cell. The `i`th atom in the input magnetic cell is mapped to the `mapping_to_std_prim[i]`th
atom in the primitive standardized magnetic cell.
"""
# Final parameters
@property
def symprec(self) -> float:
"""Actually used `symprec` in iterative symmetry search."""
@property
def angle_tolerance(self) -> float | None:
"""Actually used `angle_tolerance` in iterative symmetry search."""
@property
def mag_symprec(self) -> float | None:
"""Actually used `mag_symprec` in iterative symmetry search."""

class MoyoNonCollinearMagneticDataset:
"""A dataset containing magnetic symmetry information of the input non-collinear magnetic
structure."""
def __init__(
self,
magnetic_cell: NonCollinearMagneticCell,
symprec: float = 1e-4,
angle_tolerance: float | None = None,
mag_symprec: float | None = None,
is_axial: bool = True,
):
"""
Parameters
----------
magnetic_cell: NonCollinearMagneticCell
Input non-collinear magnetic structure.
symprec: float
Symmetry search tolerance in the unit of magnetic_cell.basis.
angle_tolerance: float | None
Symmetry search tolerance in the unit of radians.
mag_symprec: float | None
Symmetry search tolerance in the unit of magnetic moments.
is_axial: bool
Whether the magnetic moments are axial on improper operations.
"""
# Magnetic space-group type
@property
def uni_number(self) -> int:
"""UNI number for magnetic space-group type."""
# Magnetic symmetry operations in the input cell
@property
def magnetic_operations(self) -> MagneticOperations:
"""Magnetic symmetry operations in the input cell."""
# Site symmetry
@property
def orbits(self) -> list[int]:
"""The `i`th atom in the input magnetic cell is equivalent to the `orbits[i]`th atom
in the **input** magnetic cell. For example, orbits=[0, 0, 2, 2, 2, 2] means
the first two atoms are equivalent and the last four atoms are equivalent to each other.
"""
# Standardized magnetic cell
@property
def std_mag_cell(self) -> NonCollinearMagneticCell:
"""Standardized magnetic cell."""
@property
def std_linear(self) -> list[list[float]]:
"""Linear part of transformation from the input magnetic cell to the standardized
magnetic cell."""
@property
def std_origin_shift(self) -> list[float]:
"""Origin shift of transformation from the input magnetic cell to the standardized
magnetic cell."""
@property
def std_rotation_matrix(self) -> list[list[float]]:
"""Rigid rotation."""
# Primitive standardized magnetic cell
@property
def prim_std_mag_cell(self) -> NonCollinearMagneticCell:
"""Primitive standardized magnetic cell."""
@property
def prim_std_linear(self) -> list[list[float]]:
"""Linear part of transformation from the input magnetic cell to the primitive
standardized magnetic cell."""
@property
def prim_std_origin_shift(self) -> list[float]:
"""Origin shift of transformation from the input magnetic cell to the primitive
standardized magnetic cell."""
@property
def mapping_std_prim(self) -> list[int]:
"""Mapping sites in the input magnetic cell to those in the primitive standardized magnetic
cell. The `i`th atom in the input magnetic cell is mapped to the `mapping_to_std_prim[i]`th
atom in the primitive standardized magnetic cell.
"""
# Final parameters
@property
def symprec(self) -> float:
"""Actually used `symprec` in iterative symmetry search."""
@property
def angle_tolerance(self) -> float | None:
"""Actually used `angle_tolerance` in iterative symmetry search."""
@property
def mag_symprec(self) -> float | None:
"""Actually used `mag_symprec` in iterative symmetry search."""
Loading

0 comments on commit 5714727

Please sign in to comment.