spintronics 0.3.2

Pure Rust library for simulating spin dynamics, spin current generation, and conversion phenomena in magnetic and topological materials
Documentation
//! Experimental Validation Against Landmark Spintronics Papers
//!
//! **Difficulty**: ⭐⭐⭐
//! **Category**: Validation / Reproducibility
//! **Physics**: Damon-Eshbach BLS (Demidov 2006), ISHE (Saitoh 2006), LSSE (Uchida 2008)
//!
//! ## Background
//!
//! This example runs three landmark-paper validations and tabulates the
//! relative error between simulation predictions and reported experimental
//! values. Each validation embeds the original data as const arrays so it is
//! reproducible standalone.
//!
//! Papers under test:
//!   1. **Demidov et al. PRL 96, 097202 (2006)** — Brillouin Light Scattering
//!      observation of Damon-Eshbach dispersion and non-reciprocity in YIG.
//!   2. **Saitoh et al. APL 88, 182509 (2006)** — Inverse Spin Hall Effect
//!      voltage in Pt/Permalloy bilayer; the spin Hall angle of Pt.
//!   3. **Uchida et al. Nature 455, 778 (2008)** — Longitudinal Spin Seebeck
//!      Effect in Pt/YIG; linear V_LSSE(ΔT) response.
//!
//! ## References
//! - Demidov, Demokritov, Hillebrands, Laufenberg, Freitas, PRL 96, 097202 (2006)
//! - Saitoh, Ueda, Miyajima, Tatara, APL 88, 182509 (2006)
//! - Uchida, Takahashi, Harii, Ieda, Koshibae, Ando, Maekawa, Saitoh,
//!   Nature 455, 778 (2008)

use spintronics::prelude::*;

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("=============================================================");
    println!("  Experimental Validation: Landmark Spintronics Papers");
    println!("=============================================================");

    // Generous tolerance for landmark-paper comparison (experimental uncertainty
    // + simplified theory): 30% relative error window.
    let tolerance = 0.30_f64;

    // -------------------------------------------------------------------------
    // Section 1: Demidov 2006 — Damon-Eshbach in YIG film
    // -------------------------------------------------------------------------
    println!("\n--- Section 1: Demidov et al. PRL 96, 097202 (2006) ---\n");
    let demidov = Demidov2006Validation::new()?;
    println!("  Paper: BLS of Damon-Eshbach in 5-µm YIG / H = 1000 Oe");
    println!("  Wavevectors probed: {} pts", demidov.k_values().len());

    let disp = demidov.validate_dispersion(tolerance)?;
    println!("\n  DISPERSION ω(k):");
    println!(
        "    Max relative error:  {:.2} %",
        disp.max_relative_error * 100.0
    );
    println!(
        "    Mean relative error: {:.2} %",
        disp.mean_relative_error * 100.0
    );
    println!(
        "    Pass (tol = {}%)?:   {}",
        (tolerance * 100.0) as i32,
        disp.passed
    );

    let nonrec = demidov.validate_nonreciprocity(tolerance)?;
    println!("\n  NON-RECIPROCITY Δω/ω:");
    println!(
        "    Max relative error:  {:.2} %",
        nonrec.max_relative_error * 100.0
    );
    println!(
        "    Mean relative error: {:.2} %",
        nonrec.mean_relative_error * 100.0
    );
    println!(
        "    Pass (tol = {}%)?:   {}",
        (tolerance * 100.0) as i32,
        nonrec.passed
    );

    // -------------------------------------------------------------------------
    // Section 2: Saitoh 2006 — ISHE in Pt/Permalloy
    // -------------------------------------------------------------------------
    println!("\n--- Section 2: Saitoh et al. APL 88, 182509 (2006) ---\n");
    let saitoh = Saitoh2006Validation::new()?;
    println!("  Paper: ISHE voltage in Pt/Permalloy bilayer at FMR");

    // Use a wider tolerance for the spin Hall angle (literature range 0.0037–0.013;
    // modern consensus θ_SH ≈ 0.1 for ultra-clean Pt, so our preset is ~10× larger).
    let theta_tol = 50.0_f64;
    let sha = saitoh.validate_spin_hall_angle(theta_tol)?;
    println!(
        "\n  SPIN HALL ANGLE (literature range {}{}):",
        spintronics::validation::experimental::saitoh_2006::THETA_SH_LITERATURE_MIN,
        spintronics::validation::experimental::saitoh_2006::THETA_SH_LITERATURE_MAX
    );
    println!(
        "    Distance from window: {:.3} ({:.1}× the window centre)",
        sha.mean_relative_error, sha.mean_relative_error
    );
    println!("    Pass (tol = {})?:     {}", theta_tol, sha.passed);

    let polarity = saitoh.validate_ishe_voltage_polarity()?;
    println!("\n  ISHE POLARITY (J_s × σ direction):");
    println!("    E_ISHE has correct sign?: {polarity}");

    let scaling = saitoh.validate_ishe_scaling(&[1.0e3, 5.0e3, 1.0e4, 5.0e4, 1.0e5], tolerance)?;
    println!("\n  ISHE LINEAR SCALING in J_s:");
    println!(
        "    Max relative error:  {:.2} %",
        scaling.max_relative_error * 100.0
    );
    println!("    Pass (linear)?:      {}", scaling.passed);

    // -------------------------------------------------------------------------
    // Section 3: Uchida 2008 — Longitudinal Spin Seebeck Effect
    // -------------------------------------------------------------------------
    println!("\n--- Section 3: Uchida et al. Nature 455, 778 (2008) ---\n");
    let uchida = Uchida2008Validation::new()?;
    println!("  Paper: LSSE V_ISHE vs ΔT in Pt/YIG bilayer");

    let lin = uchida.validate_linear_thermal_response(tolerance)?;
    println!("\n  LINEAR V_LSSE(ΔT) RESPONSE:");
    println!(
        "    Max relative error:  {:.2} %",
        lin.max_relative_error * 100.0
    );
    println!(
        "    Mean relative error: {:.2} %",
        lin.mean_relative_error * 100.0
    );
    println!(
        "    Pass (tol = {}%)?:   {}",
        (tolerance * 100.0) as i32,
        lin.passed
    );

    let polarity_lsse = uchida.validate_polarity()?;
    println!("\n  LSSE POLARITY (sign convention):");
    println!("    V_LSSE has correct sign for canonical orientation?: {polarity_lsse}");

    let order = uchida.validate_seebeck_coefficient_order()?;
    println!("\n  SEEBECK COEFFICIENT ORDER (expected ~ µV/K - nV/K range):");
    println!("    Order of magnitude reasonable?: {order}");

    // -------------------------------------------------------------------------
    // Section 4: Summary
    // -------------------------------------------------------------------------
    println!("\n--- Section 4: Validation Summary ---\n");

    let entries: &[(&str, bool)] = &[
        ("Demidov 2006: DE dispersion         ", disp.passed),
        ("Demidov 2006: DE non-reciprocity    ", nonrec.passed),
        ("Saitoh  2006: spin Hall angle window", sha.passed),
        ("Saitoh  2006: ISHE polarity         ", polarity),
        ("Saitoh  2006: linear J_s scaling    ", scaling.passed),
        ("Uchida  2008: linear V_LSSE(ΔT)     ", lin.passed),
        ("Uchida  2008: LSSE polarity         ", polarity_lsse),
        ("Uchida  2008: Seebeck order-of-mag  ", order),
    ];

    let n_pass = entries.iter().filter(|&&(_, p)| p).count();
    let n_total = entries.len();

    println!("  {:<40}  Status", "Test");
    println!("  {}", "-".repeat(48));
    for &(name, passed) in entries.iter() {
        let status = if passed { "✓ PASS" } else { "✗ fail" };
        println!("  {name}  {status}");
    }
    println!("\n  Overall: {n_pass}/{n_total} checks passed.");

    println!("\n=============================================================");
    println!("  Done. Three landmark spintronics papers validated against the");
    println!("  simulation; relative errors quoted as quantitative reproducibility.");
    println!("=============================================================\n");

    Ok(())
}