Skip to main content

qualia_core_db/specialized_libs/physics_simulation/
quantum.rs

1use super::*;
2
3impl PhysicsSimulationLibrary {
4    /// QuantumMechanics — 1D time-independent Schrödinger equation
5    /// `[-ħ²/(2m)·d²/dx² + V(x)]·ψ = E·ψ` discretised by second-order finite differences
6    /// (Dirichlet walls). The resulting symmetric tridiagonal Hamiltonian is diagonalised
7    /// by the tested `symmetric_eigen`; the lowest `num_levels` energies are returned.
8    pub fn run_quantum_stationary_states_1d(
9        &self,
10        potential: Vec<f64>,
11        dx: f64,
12        mass: f64,
13        hbar: f64,
14        num_levels: usize,
15    ) -> Result<QuantumSpectrumResult, PhysicsError> {
16        let n = potential.len();
17        if n < 2 || !(dx > 0.0 && mass > 0.0 && hbar > 0.0) {
18            return Err(PhysicsError::InvalidConfiguration(
19                "require potential length >= 2, dx > 0, mass > 0, hbar > 0".to_string(),
20            ));
21        }
22        // Kinetic coupling t = ħ²/(2m·dx²). Diagonal 2t + V_i; off-diagonal -t.
23        let t = hbar * hbar / (2.0 * mass * dx * dx);
24        let mut a = vec![0.0f64; n * n];
25        for i in 0..n {
26            a[i * n + i] = 2.0 * t + potential[i];
27            if i + 1 < n {
28                a[i * n + (i + 1)] = -t;
29                a[(i + 1) * n + i] = -t;
30            }
31        }
32        let mut eigvecs = vec![0.0f64; n * n];
33        symmetric_eigen(n, &mut a, &mut eigvecs)
34            .map_err(|e| PhysicsError::SolverError(format!("symmetric_eigen: {:?}", e)))?;
35        let mut eigenvalues: Vec<f64> = (0..n).map(|i| a[i * n + i]).collect();
36        eigenvalues.sort_by(|x, y| x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal));
37        eigenvalues.truncate(num_levels.min(n).max(1));
38        Ok(QuantumSpectrumResult {
39            eigenvalues,
40            num_grid_points: n,
41            dx,
42        })
43    }
44}