spintronics 0.3.0

Pure Rust library for simulating spin dynamics, spin current generation, and conversion phenomena in magnetic and topological materials
Documentation
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
//! Topological Insulator Materials
//!
//! Topological insulators (TIs) are quantum materials that are insulating in the bulk
//! but host conducting surface states protected by time-reversal symmetry. These
//! surface states exhibit spin-momentum locking and are promising for spintronics.
//!
//! ## Physics Background
//!
//! ### Key Properties:
//! - **Bulk bandgap**: Insulating behavior in the material interior
//! - **Topological surface states**: Gapless Dirac cone at the surface
//! - **Spin-momentum locking**: Electron spin is perpendicular to momentum
//! - **Time-reversal symmetry**: Protected against non-magnetic impurities
//!
//! ### Spintronics Applications:
//! - **Edelstein effect**: Charge current → spin accumulation
//! - **Spin-charge conversion**: Efficient at room temperature
//! - **Low-power spin devices**: No need for ferromagnetic layers
//! - **Spin-orbit torques**: Current-induced magnetization switching
//!
//! ## Key References
//!
//! - M. Z. Hasan and C. L. Kane, "Colloquium: Topological insulators",
//!   Rev. Mod. Phys. 82, 3045 (2010)
//! - Y. Ando, "Topological Insulator Materials",
//!   J. Phys. Soc. Jpn. 82, 102001 (2013)
//! - A. R. Mellnik et al., "Spin-transfer torque generated by a topological insulator",
//!   Nature 511, 449 (2014)
//! - Y. Fan et al., "Magnetization switching through giant spin–orbit torque in a
//!   magnetically doped topological insulator heterostructure",
//!   Nat. Mater. 13, 699 (2014)

use std::fmt;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::vector3::Vector3;

/// Types of topological insulator materials
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TopologicalClass {
    /// 3D topological insulator (e.g., Bi₂Se₃, Bi₂Te₃)
    ThreeDimensional,
    /// 2D topological insulator / Quantum spin Hall insulator (e.g., HgTe quantum wells)
    TwoDimensional,
}

/// Topological insulator material properties
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TopologicalInsulator {
    /// Material name
    pub name: String,

    /// Topological class
    pub ti_class: TopologicalClass,

    /// Bulk bandgap \[eV\]
    pub bulk_gap: f64,

    /// Fermi velocity of surface states \[m/s\]
    /// Typically ~5×10⁵ m/s for Bi₂Se₃
    pub fermi_velocity: f64,

    /// Edelstein length \[nm\]
    /// Characterizes spin-charge conversion efficiency
    /// λ_E = ℏ/(2e·E_F) for Dirac surface states
    pub edelstein_length: f64,

    /// Spin Hall conductivity [ℏ/(2e) · (Ω·m)⁻¹]
    /// For TI surface states
    pub spin_hall_conductivity: f64,

    /// Surface state carrier density [m⁻²]
    pub surface_carrier_density: f64,

    /// Lattice constant \[nm\]
    pub lattice_constant: f64,
}

impl Default for TopologicalInsulator {
    /// Default to Bi₂Se₃ parameters
    fn default() -> Self {
        Self::bi2se3()
    }
}

impl TopologicalInsulator {
    /// Create Bi₂Se₃ (Bismuth Selenide)
    ///
    /// The prototypical 3D topological insulator
    /// Reference: Y. Xia et al., Nat. Phys. 5, 398 (2009)
    pub fn bi2se3() -> Self {
        Self {
            name: "Bi₂Se₃".to_string(),
            ti_class: TopologicalClass::ThreeDimensional,
            bulk_gap: 0.3,                   // eV
            fermi_velocity: 5.0e5,           // m/s
            edelstein_length: 1.0,           // nm (typical)
            spin_hall_conductivity: 1.0e6,   // (Ω·m)⁻¹
            surface_carrier_density: 1.0e17, // m⁻²
            lattice_constant: 0.414,         // nm (c-axis)
        }
    }

    /// Create Bi₂Te₃ (Bismuth Telluride)
    ///
    /// 3D TI with better air stability than Bi₂Se₃
    /// Also used in thermoelectrics
    pub fn bi2te3() -> Self {
        Self {
            name: "Bi₂Te₃".to_string(),
            ti_class: TopologicalClass::ThreeDimensional,
            bulk_gap: 0.17,                  // eV
            fermi_velocity: 4.0e5,           // m/s
            edelstein_length: 0.8,           // nm
            spin_hall_conductivity: 8.0e5,   // (Ω·m)⁻¹
            surface_carrier_density: 5.0e16, // m⁻²
            lattice_constant: 0.304,         // nm
        }
    }

    /// Create Bi₂Se₂Te (mixed compound)
    ///
    /// Optimized bandgap and surface properties
    pub fn bi2se2te() -> Self {
        Self {
            name: "Bi₂Se₂Te".to_string(),
            ti_class: TopologicalClass::ThreeDimensional,
            bulk_gap: 0.22,                  // eV
            fermi_velocity: 4.5e5,           // m/s
            edelstein_length: 0.9,           // nm
            spin_hall_conductivity: 9.0e5,   // (Ω·m)⁻¹
            surface_carrier_density: 7.0e16, // m⁻²
            lattice_constant: 0.35,          // nm
        }
    }

    /// Create (Bi₁₋ₓSbₓ)₂Te₃ with optimized composition
    ///
    /// Tunable Fermi level through Sb doping
    /// Reference: J. Zhang et al., Nat. Commun. 2, 574 (2011)
    pub fn bi_sb_te3(sb_fraction: f64) -> Self {
        let bulk_gap = 0.17 + sb_fraction * 0.13; // Linear interpolation
        let fermi_velocity = 4.0e5 * (1.0 + 0.25 * sb_fraction);

        Self {
            name: format!("(Bi₁₋ₓSbₓ)₂Te₃ (x={:.2})", sb_fraction),
            ti_class: TopologicalClass::ThreeDimensional,
            bulk_gap,
            fermi_velocity,
            edelstein_length: 0.85,
            spin_hall_conductivity: 8.5e5,
            surface_carrier_density: 6.0e16,
            lattice_constant: 0.304,
        }
    }

    /// Create Sb₂Te₃ (Antimony Telluride)
    ///
    /// Related to Bi₂Te₃ but with different properties
    pub fn sb2te3() -> Self {
        Self {
            name: "Sb₂Te₃".to_string(),
            ti_class: TopologicalClass::ThreeDimensional,
            bulk_gap: 0.28,                  // eV
            fermi_velocity: 3.5e5,           // m/s
            edelstein_length: 0.7,           // nm
            spin_hall_conductivity: 7.0e5,   // (Ω·m)⁻¹
            surface_carrier_density: 4.0e16, // m⁻²
            lattice_constant: 0.304,         // nm
        }
    }

    /// Calculate Edelstein effect efficiency
    ///
    /// The Edelstein effect (also called inverse Rashba-Edelstein effect)
    /// converts charge current to spin accumulation at the TI surface.
    ///
    /// Spin accumulation: S = λ_E · J_c
    ///
    /// # Arguments
    /// * `current_density` - Charge current density \[A/m²\]
    ///
    /// # Returns
    /// Spin accumulation [J·s/m³]
    pub fn edelstein_spin_accumulation(&self, current_density: f64) -> f64 {
        self.edelstein_length * 1e-9 * current_density
    }

    /// Calculate spin Hall angle for topological surface states
    ///
    /// θ_SH = σ_SH / σ_charge
    ///
    /// # Arguments
    /// * `charge_conductivity` - Charge conductivity \[S/m\]
    ///
    /// # Returns
    /// Spin Hall angle (dimensionless)
    pub fn spin_hall_angle(&self, charge_conductivity: f64) -> f64 {
        self.spin_hall_conductivity / charge_conductivity
    }

    /// Calculate spin-orbit torque from topological surface states
    ///
    /// Similar to heavy-metal SOT but from topological surface states
    ///
    /// # Arguments
    /// * `current_density` - In-plane current density \[A/m²\]
    /// * `magnetization` - Magnetization of adjacent ferromagnet \[A/m\]
    ///
    /// # Returns
    /// Torque efficiency (dimensionless)
    pub fn sot_efficiency(&self, current_density: f64, magnetization: f64) -> f64 {
        let spin_accum = self.edelstein_spin_accumulation(current_density);
        // Simplified: torque ∝ spin accumulation / magnetization
        spin_accum / (magnetization * 1e-9) // Convert to dimensionless
    }

    /// Check if material is suitable for spin-orbitronics
    ///
    /// Criteria: large bandgap, high Fermi velocity, strong spin-orbit coupling
    pub fn is_suitable_for_spintronics(&self) -> bool {
        self.bulk_gap > 0.15 && // Sufficient bandgap (eV)
        self.fermi_velocity > 3.0e5 && // High carrier mobility
        self.edelstein_length > 0.5 // Strong spin-charge conversion
    }

    /// Builder method to set Edelstein length
    pub fn with_edelstein_length(mut self, length: f64) -> Self {
        self.edelstein_length = length;
        self
    }

    /// Builder method to set surface carrier density
    pub fn with_carrier_density(mut self, density: f64) -> Self {
        self.surface_carrier_density = density;
        self
    }
}

/// Calculate spin texture on topological surface
///
/// For a Dirac cone with momentum p, the spin is locked perpendicular:
/// s(p) = ẑ × p
///
/// # Arguments
/// * `momentum` - In-plane momentum vector [ℏ/m]
///
/// # Returns
/// Spin direction (normalized)
pub fn surface_spin_texture(momentum: Vector3<f64>) -> Vector3<f64> {
    let z_axis = Vector3::new(0.0, 0.0, 1.0);
    z_axis.cross(&momentum).normalize()
}

impl fmt::Display for TopologicalClass {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TopologicalClass::ThreeDimensional => write!(f, "3D TI"),
            TopologicalClass::TwoDimensional => write!(f, "2D TI (QSHI)"),
        }
    }
}

impl fmt::Display for TopologicalInsulator {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{} [{}]: E_gap={:.2} eV, v_F={:.2e} m/s, λ_E={:.1} nm",
            self.name, self.ti_class, self.bulk_gap, self.fermi_velocity, self.edelstein_length
        )
    }
}

impl super::traits::TopologicalMaterial for TopologicalInsulator {
    fn bulk_gap(&self) -> f64 {
        self.bulk_gap
    }

    fn surface_fermi_velocity(&self) -> f64 {
        self.fermi_velocity
    }
}

impl super::traits::SpinChargeConverter for TopologicalInsulator {
    fn spin_hall_angle(&self) -> f64 {
        // For TI surface states, the spin Hall angle can be estimated from
        // the Edelstein effect: θ_SH ~ λ_E * k_F
        // Using k_F ~ E_F / (ℏ * v_F) and typical Fermi energies
        self.edelstein_length * 1e-9 * 1e9 // Simplified: order of λ_E in nm
    }

    fn spin_hall_conductivity(&self) -> f64 {
        self.spin_hall_conductivity
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_bi2se3() {
        let ti = TopologicalInsulator::bi2se3();
        assert_eq!(ti.ti_class, TopologicalClass::ThreeDimensional);
        assert!(ti.bulk_gap > 0.2);
        assert!(ti.fermi_velocity > 4.0e5);
    }

    #[test]
    fn test_bi2te3() {
        let ti = TopologicalInsulator::bi2te3();
        assert_eq!(ti.ti_class, TopologicalClass::ThreeDimensional);
        assert!(ti.bulk_gap > 0.15);
    }

    #[test]
    fn test_bi_sb_te3_composition() {
        let ti_pure_bi = TopologicalInsulator::bi_sb_te3(0.0);
        let ti_half_sb = TopologicalInsulator::bi_sb_te3(0.5);

        // Higher Sb content should increase bandgap
        assert!(ti_half_sb.bulk_gap > ti_pure_bi.bulk_gap);
    }

    #[test]
    fn test_edelstein_spin_accumulation() {
        let ti = TopologicalInsulator::bi2se3();
        let j_c = 1.0e10; // A/m²

        let spin_accum = ti.edelstein_spin_accumulation(j_c);

        // Should be proportional to current and Edelstein length
        assert!(spin_accum > 0.0);
    }

    #[test]
    fn test_spin_hall_angle() {
        let ti = TopologicalInsulator::bi2se3();
        let sigma_c = 1.0e5; // S/m

        let theta_sh = ti.spin_hall_angle(sigma_c);

        // Should be positive and order of 1-10
        assert!(theta_sh > 0.0);
        assert!(theta_sh < 100.0);
    }

    #[test]
    fn test_sot_efficiency() {
        let ti = TopologicalInsulator::bi2se3();
        let j_c = 1.0e10; // A/m²
        let ms = 1.0e6; // A/m

        let efficiency = ti.sot_efficiency(j_c, ms);

        assert!(efficiency > 0.0);
    }

    #[test]
    fn test_spintronics_suitability() {
        let bi2se3 = TopologicalInsulator::bi2se3();
        assert!(bi2se3.is_suitable_for_spintronics());

        // Material with small gap shouldn't be suitable
        let weak_ti = TopologicalInsulator::bi2se3().with_edelstein_length(0.1);
        assert!(!weak_ti.is_suitable_for_spintronics());
    }

    #[test]
    fn test_builder_pattern() {
        let ti = TopologicalInsulator::bi2se3()
            .with_edelstein_length(2.0)
            .with_carrier_density(1.0e18);

        assert_eq!(ti.edelstein_length, 2.0);
        assert_eq!(ti.surface_carrier_density, 1.0e18);
    }

    #[test]
    fn test_surface_spin_texture() {
        let momentum = Vector3::new(1.0, 0.0, 0.0); // k_x direction
        let spin = surface_spin_texture(momentum);

        // Spin should be perpendicular to momentum (in y-direction)
        assert!(spin.dot(&momentum).abs() < 1e-10);
        assert!((spin.magnitude() - 1.0).abs() < 1e-10);

        // For k_x, spin should be in ±y direction
        assert!(spin.y.abs() > 0.9);
    }

    #[test]
    fn test_spin_momentum_locking() {
        let k1 = Vector3::new(1.0, 0.0, 0.0);
        let k2 = Vector3::new(0.0, 1.0, 0.0);

        let s1 = surface_spin_texture(k1);
        let s2 = surface_spin_texture(k2);

        // Orthogonal momenta should give orthogonal spins
        assert!(s1.dot(&s2).abs() < 1e-10);
    }

    #[test]
    fn test_comparison_bi_compounds() {
        let bi2se3 = TopologicalInsulator::bi2se3();
        let bi2te3 = TopologicalInsulator::bi2te3();

        // Bi₂Se₃ should have larger bandgap
        assert!(bi2se3.bulk_gap > bi2te3.bulk_gap);

        // Both should be suitable for spintronics
        assert!(bi2se3.is_suitable_for_spintronics());
        assert!(bi2te3.is_suitable_for_spintronics());
    }
}