use spintronics::prelude::*;
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== SimulationBuilder: Type-State Pattern ===\n");
println!("=== Simulation 1: YIG Magnetization Precession ===");
let yig = Ferromagnet::yig();
println!(" Material: YIG");
println!(" M_s = {:.3e} A/m", yig.ms);
println!(" alpha = {:.1e} (Gilbert damping)", yig.alpha);
let h_ext = Vector3::new(0.0, 0.0, 0.1); println!(
" External field: ({:.2}, {:.2}, {:.2}) T",
h_ext.x, h_ext.y, h_ext.z
);
let mut sim = SimulationBuilder::new()
.material(yig)
.external_field(h_ext)
.solver_rk4()
.num_steps(1000)
.build()
.expect("Failed to build YIG simulation");
let result = sim.run().expect("Failed to run YIG simulation");
println!(
" Initial m: ({:.4}, {:.4}, {:.4})",
result.trajectory[0].x, result.trajectory[0].y, result.trajectory[0].z
);
println!(
" Final m: ({:.4}, {:.4}, {:.4})",
result.final_magnetization.x, result.final_magnetization.y, result.final_magnetization.z
);
println!(" Steps: {}", result.trajectory.len() - 1);
println!(
" |m_final| = {:.8}",
result.final_magnetization.magnitude()
);
if !result.energies.is_empty() {
let e_initial = result.energies[0];
let e_final = result.energies[result.energies.len() - 1];
println!(" Initial energy density: {:.4e} J/m^3", e_initial);
println!(" Final energy density: {:.4e} J/m^3", e_final);
println!(" Energy change: {:.4e} J/m^3", e_final - e_initial);
}
println!("\n=== Simulation 2: Permalloy Relaxation ===");
let py = Ferromagnet::permalloy();
println!(" Material: Permalloy (Py)");
println!(" M_s = {:.3e} A/m", py.ms);
println!(
" alpha = {:.3} (higher damping -> faster relaxation)",
py.alpha
);
let h_z = Vector3::new(0.0, 0.0, 0.5);
let mut sim_py = SimulationBuilder::new()
.material(py)
.external_field(h_z)
.solver_rk4()
.num_steps(2000)
.build()
.expect("Failed to build Permalloy simulation");
let result_py = sim_py.run().expect("Failed to run Permalloy simulation");
println!(" External field: {:.2} T along z", h_z.z);
println!(
" Final m: ({:.6}, {:.6}, {:.6})",
result_py.final_magnetization.x,
result_py.final_magnetization.y,
result_py.final_magnetization.z
);
println!(" m_z alignment: {:.6}", result_py.final_magnetization.z);
println!("\n=== Simulation 3: Cobalt in Strong Field ===");
let co = Ferromagnet::cobalt();
println!(" Material: Cobalt (Co)");
println!(" M_s = {:.3e} A/m", co.ms);
let h_strong = Vector3::new(0.0, 0.0, 1.0);
let mut sim_co = SimulationBuilder::new()
.material(co)
.external_field(h_strong)
.solver_rk4()
.num_steps(500)
.build()
.expect("Failed to build Cobalt simulation");
let result_co = sim_co.run().expect("Failed to run Cobalt simulation");
println!(" H_ext = 1.0 T along z");
println!(
" Final m: ({:.6}, {:.6}, {:.6})",
result_co.final_magnetization.x,
result_co.final_magnetization.y,
result_co.final_magnetization.z
);
println!("\n=== Material Comparison Under Same Field ===");
let field = Vector3::new(0.0, 0.0, 0.2); let step_count = 1000;
let ferromagnets = [
("YIG", Ferromagnet::yig()),
("Permalloy", Ferromagnet::permalloy()),
("Cobalt", Ferromagnet::cobalt()),
("Iron", Ferromagnet::iron()),
("Nickel", Ferromagnet::nickel()),
];
println!(" H_ext = {:.2} T along z, {} steps\n", field.z, step_count);
println!(
" {:<12} {:>10} {:>10} {:>12} {:>12}",
"Material", "M_s (kA/m)", "alpha", "m_z final", "|dm|"
);
println!(" {}", "-".repeat(60));
for (name, mat) in &ferromagnets {
let mut sim_mat = SimulationBuilder::new()
.material(mat.clone())
.external_field(field)
.solver_rk4()
.num_steps(step_count)
.build()
.expect("Failed to build simulation");
let res = sim_mat.run().expect("Failed to run simulation");
let dm = res.final_magnetization - res.trajectory[0];
println!(
" {:<12} {:>10.0} {:>10.4} {:>12.6} {:>12.6}",
name,
mat.ms * 1e-3,
mat.alpha,
res.final_magnetization.z,
dm.magnitude()
);
}
println!("\n=== Field Scan: Precession Dynamics ===");
println!(" Material: YIG");
println!(
" {:>10} {:>15} {:>15}",
"H_z (T)", "m_z (final)", "|m_final|"
);
println!(" {}", "-".repeat(45));
let yig2 = Ferromagnet::yig();
for &h_z_val in &[0.01, 0.05, 0.1, 0.5, 1.0, 2.0] {
let h = Vector3::new(0.0, 0.0, h_z_val);
let mut sim_scan = SimulationBuilder::new()
.material(yig2.clone())
.external_field(h)
.solver_rk4()
.num_steps(500)
.build()
.expect("Failed to build scan simulation");
let res_scan = sim_scan.run().expect("Failed to run scan simulation");
println!(
" {:>10.2} {:>15.6} {:>15.8}",
h_z_val,
res_scan.final_magnetization.z,
res_scan.final_magnetization.magnitude()
);
}
println!("\n=== Summary ===");
println!("SimulationBuilder type-state pattern:");
println!(" - Compile-time guarantee: material + field + solver all required");
println!(" - RK4 integration of LLG equation");
println!(" - Magnetization conserved: |m| = 1 throughout dynamics");
println!(" - Higher damping (alpha) -> faster alignment with external field");
println!(" - Energy decreases monotonically during relaxation");
Ok(())
}