1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
use std::convert::TryFrom;
use std::ffi::{CStr, CString};
use spglib_sys as ffi;
use crate::cell::Cell;
use crate::error::SpglibError;
#[derive(Clone, Debug)]
pub struct Dataset {
pub spacegroup_number: i32,
pub hall_number: i32,
pub international_symbol: String,
pub hall_symbol: String,
pub choice: String,
pub transformation_matrix: [[f64; 3]; 3],
pub origin_shift: [f64; 3],
pub n_operations: i32,
pub rotations: Vec<[[i32; 3]; 3]>,
pub translations: Vec<[f64; 3]>,
pub n_atoms: i32,
pub wyckoffs: Vec<i32>,
pub site_symmetry_symbols: Vec<String>,
pub equivalent_atoms: Vec<i32>,
pub crystallographic_orbits: Vec<i32>,
pub primitive_lattice: [[f64; 3]; 3],
pub mapping_to_primitive: Vec<i32>,
pub n_std_atoms: i32,
pub std_lattice: [[f64; 3]; 3],
pub std_types: Vec<i32>,
pub std_positions: Vec<[f64; 3]>,
pub std_rotation_matrix: [[f64; 3]; 3],
pub std_mapping_to_primitive: Vec<i32>,
pub pointgroup_symbol: String,
}
impl TryFrom<*mut ffi::SpglibDataset> for Dataset {
type Error = SpglibError;
fn try_from(value: *mut ffi::SpglibDataset) -> Result<Self, Self::Error> {
let ptr = unsafe { &mut *value };
let spacegroup_number = ptr.spacegroup_number as i32;
let hall_number = ptr.hall_number as i32;
let international_symbol =
match CString::from(unsafe { CStr::from_ptr(ptr.international_symbol.as_ptr()) })
.to_str()
{
Ok(s) => String::from(s),
Err(_) => return Err(SpglibError::Unknown),
};
let hall_symbol =
match CString::from(unsafe { CStr::from_ptr(ptr.hall_symbol.as_ptr()) }).to_str() {
Ok(s) => String::from(s),
Err(_) => return Err(SpglibError::Unknown),
};
let choice = match CString::from(unsafe { CStr::from_ptr(ptr.choice.as_ptr()) }).to_str() {
Ok(s) => String::from(s),
Err(_) => return Err(SpglibError::Unknown),
};
let transformation_matrix = ptr.transformation_matrix;
let origin_shift = ptr.origin_shift;
let n_operations = ptr.n_operations as i32;
let rotations = unsafe {
Vec::from_raw_parts(ptr.rotations, n_operations as usize, n_operations as usize)
};
let translations = unsafe {
Vec::from_raw_parts(
ptr.translations,
n_operations as usize,
n_operations as usize,
)
};
let n_atoms = ptr.n_atoms as i32;
let wyckoffs =
unsafe { Vec::from_raw_parts(ptr.wyckoffs, n_atoms as usize, n_atoms as usize) };
let site_symmetry_symbols = Vec::new();
let equivalent_atoms = unsafe {
Vec::from_raw_parts(ptr.equivalent_atoms, n_atoms as usize, n_atoms as usize)
};
let crystallographic_orbits = unsafe {
Vec::from_raw_parts(
ptr.crystallographic_orbits,
n_atoms as usize,
n_atoms as usize,
)
};
let primitive_lattice = ptr.primitive_lattice;
let mapping_to_primitive = unsafe {
Vec::from_raw_parts(ptr.mapping_to_primitive, n_atoms as usize, n_atoms as usize)
};
let n_std_atoms = ptr.n_std_atoms as i32;
let std_lattice = ptr.std_lattice;
let std_types = unsafe {
Vec::from_raw_parts(ptr.std_types, n_std_atoms as usize, n_std_atoms as usize)
};
let std_positions = unsafe {
Vec::from_raw_parts(
ptr.std_positions,
n_std_atoms as usize,
n_std_atoms as usize,
)
};
let std_rotation_matrix = ptr.std_rotation_matrix;
let std_mapping_to_primitive = unsafe {
Vec::from_raw_parts(
ptr.std_mapping_to_primitive,
n_std_atoms as usize,
n_std_atoms as usize,
)
};
let pointgroup_symbol =
match CString::from(unsafe { CStr::from_ptr(ptr.pointgroup_symbol.as_ptr()) }).to_str()
{
Ok(s) => String::from(s),
Err(_) => return Err(SpglibError::Unknown),
};
Ok(Dataset {
spacegroup_number,
hall_number,
international_symbol,
hall_symbol,
choice,
transformation_matrix,
origin_shift,
n_operations,
rotations,
translations,
n_atoms,
wyckoffs,
site_symmetry_symbols,
equivalent_atoms,
crystallographic_orbits,
primitive_lattice,
mapping_to_primitive,
n_std_atoms,
std_lattice,
std_types,
std_positions,
std_rotation_matrix,
std_mapping_to_primitive,
pointgroup_symbol,
})
}
}
impl Dataset {
pub fn new(cell: &mut Cell, symprec: f64) -> Dataset {
let raw = unsafe {
ffi::spg_get_dataset(
cell.lattice.as_ptr() as *mut [f64; 3],
cell.positions.as_ptr() as *mut [f64; 3],
cell.types.as_ptr() as *const i32,
cell.positions.len() as i32,
symprec,
)
};
Dataset::try_from(raw).unwrap()
}
}