Skip to content

Commit

Permalink
Merge pull request #71 from spglib/moyopy-msg
Browse files Browse the repository at this point in the history
Python interface for MSG
  • Loading branch information
lan496 authored Feb 11, 2025
2 parents a87f793 + 287a311 commit 4fc015a
Show file tree
Hide file tree
Showing 29 changed files with 1,313 additions and 270 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
3 changes: 2 additions & 1 deletion moyo/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ pub use hall_symbol::{HallSymbol, MagneticHallSymbol};
pub use hall_symbol_database::{hall_symbol_entry, HallNumber, HallSymbolEntry, Number};
pub use magnetic_hall_symbol_database::{magnetic_hall_symbol_entry, MagneticHallSymbolEntry};
pub use magnetic_space_group::{
get_magnetic_space_group_type, ConstructType, UNINumber, NUM_MAGNETIC_SPACE_GROUP_TYPES,
get_magnetic_space_group_type, ConstructType, MagneticSpaceGroupType, UNINumber,
NUM_MAGNETIC_SPACE_GROUP_TYPES,
};
pub use setting::Setting;

Expand Down
5 changes: 5 additions & 0 deletions moyo/src/data/magnetic_space_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@ pub enum ConstructType {

#[derive(Debug, Clone)]
pub struct MagneticSpaceGroupType {
/// Serial number of UNI (and BNS) symbols
pub uni_number: UNINumber,
/// Serial number in Litvin's [Magnetic group tables](https://www.iucr.org/publ/978-0-9553602-2-0)
pub litvin_number: i32,
/// BNS number e.g. '151.32'
pub bns_number: &'static str,
/// OG number e.g. '153.4.1270'
pub og_number: &'static str,
/// ITA number for reference space group in BNS setting
pub number: Number,
/// Construct type of magnetic space group
pub construct_type: ConstructType,
}

Expand Down
32 changes: 26 additions & 6 deletions moyo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@ moyo = "*"
The basic usage of **moyo** is to create a [`moyo::base::Cell`](Cell) representing a crystal structure, and then create a [`moyo::MoyoDataset`](MoyoDataset) from the [`moyo::base::Cell`](Cell).
The [`moyo::MoyoDataset`](MoyoDataset) contains symmetry information of the input crystal structure: for example, the space group number, symmetry operations, and standardized cell.
Magnetic symmetry is also supported in **moyo**.
Magnetic moments are represented by a struct implementing the [`moyo::base::MagneticMoment`](MagneticMoment) trait: for example, [`moyo::base::Collinear`](Collinear) or [`moyo::base::NonCollinear`](NonCollinear).
Magnetic cell is represented by a [`moyo::base::MagneticCell`](MagneticCell) struct.
The [`moyo::MoyoMagneticDataset`](MoyoMagneticDataset) contains magnetic symmetry information of the input magnetic cell: for example, the magnetic space-group type, magnetic symmetry operations, and standardized magnetic cell.
```
use nalgebra::{matrix, vector, Matrix3, Vector3};
use moyo::MoyoDataset;
use moyo::base::{Cell, AngleTolerance, Lattice};
use moyo::{MoyoDataset, MoyoMagneticDataset};
use moyo::base::{Cell, MagneticCell, AngleTolerance, Lattice, NonCollinear, RotationMagneticMomentAction};
use moyo::data::Setting;
let lattice = Lattice::new(matrix![
Expand All @@ -39,15 +44,29 @@ let positions = vec![
Vector3::new(x_4f + 0.5, -x_4f + 0.5, 0.5), // O(4f)
];
let numbers = vec![0, 0, 1, 1, 1, 1];
let cell = Cell::new(lattice, positions, numbers);
let cell = Cell::new(lattice.clone(), positions.clone(), numbers.clone());
let symprec = 1e-5;
let symprec = 1e-4;
let angle_tolerance = AngleTolerance::Default;
let setting = Setting::Standard;
let dataset = MoyoDataset::new(&cell, symprec, angle_tolerance, setting).unwrap();
assert_eq!(dataset.number, 136); // P4_2/mnm
let magnetic_moments = vec![
NonCollinear(vector![0.0, 0.0, 0.7]),
NonCollinear(vector![0.0, 0.0, -0.7]),
NonCollinear(vector![0.0, 0.0, 0.0]),
NonCollinear(vector![0.0, 0.0, 0.0]),
NonCollinear(vector![0.0, 0.0, 0.0]),
NonCollinear(vector![0.0, 0.0, 0.0]),
];
let magnetic_cell = MagneticCell::new(lattice, positions, numbers, magnetic_moments);
let action = RotationMagneticMomentAction::Axial;
let magnetic_dataset = MoyoMagneticDataset::new(&magnetic_cell, symprec, angle_tolerance, None, action).unwrap();
assert_eq!(magnetic_dataset.uni_number, 1159); // BNS 136.499
```
## Features
Expand All @@ -57,6 +76,7 @@ assert_eq!(dataset.number, 136); // P4_2/mnm
- Space-group type identification
- Wyckoff position assignment
- Crystal structure symmetrization
- Magnetic space group support
*/
#[allow(unused_imports)]
Expand Down Expand Up @@ -90,7 +110,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
2 changes: 1 addition & 1 deletion moyo/src/symmetrize/magnetic_standardize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ impl<M: MagneticMoment> StandardizedMagneticCell<M> {
action,
);
let prim_std_mag_cell =
MagneticCell::from_cell(ref_std_cell.cell.clone(), prim_std_magnetic_moments);
MagneticCell::from_cell(ref_std_cell.prim_cell.clone(), prim_std_magnetic_moments);

// To (conventional) standardized magnetic cell
let refined_prim_mag_cell = ref_std_cell
Expand Down
2 changes: 1 addition & 1 deletion moyopy/examples/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
numbers = [0, 0, 1, 1]
cell = moyopy.Cell(basis, positions, numbers)

dataset = moyopy.MoyoDataset(cell, symprec=1e-5, angle_tolerance=None, setting=None)
dataset = moyopy.MoyoDataset(cell, symprec=1e-4, angle_tolerance=None, setting=None)
assert dataset.number == 186
assert dataset.hall_number == 480

Expand Down
2 changes: 1 addition & 1 deletion moyopy/examples/pymatgen_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class MoyoSpacegroupAnalyzer:
def __init__(
self,
structure: Structure,
symprec: float = 1e-5,
symprec: float = 1e-4,
angle_tolerance: float | None = None,
setting: moyopy.Setting | None = None,
):
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: ...
22 changes: 22 additions & 0 deletions moyopy/python/moyopy/_data.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,26 @@ class SpaceGroupType:
for string values.
"""

class MagneticSpaceGroupType:
"""Magnetic space-group type information."""
def __init__(self, uni_number: int): ...
@property
def uni_number(self) -> int:
"""Serial number of UNI (and BNS) symbols."""
@property
def litvin_number(self) -> int:
"""Serial number in Litvin's `Magnetic group tables <https://www.iucr.org/publ/978-0-9553602-2-0>`_."""
@property
def bns_number(self) -> str:
"""BNS number e.g. '151.32'"""
@property
def og_number(self) -> str:
"""OG number e.g. '153.4.1270'"""
@property
def number(self) -> int:
"""ITA number for reference space group in BNS setting."""
@property
def construct_type(self) -> int:
"""Construct type of magnetic space group from 1 to 4."""

def operations_from_number(number: int, setting: Setting) -> Operations: ...
Loading

0 comments on commit 4fc015a

Please sign in to comment.