use crate::atom_struct::AtomType;
use crate::{OrbProj, SpinDirection};
use ndarray::{Array1, Array2, ShapeError};
use num_complex::Complex;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum TbError {
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("Failed to parse data from file '{file}': {message}")]
FileParse { file: String, message: String },
#[error("Invalid orbital projection string: '{0}'")]
InvalidOrbitalProjection(String),
#[error("Invalid atom type string: '{0}'")]
InvalidAtomType(String),
#[error("Failed to create directory '{path}': {message}")]
DirectoryCreation { path: String, message: String },
#[error("Failed to create file '{path}': {message}")]
FileCreation { path: String, message: String },
#[error("Linear algebra operation failed: {0}")]
Linalg(#[from] ndarray_linalg::error::LinalgError),
#[error("LAPACK routine '{routine}' failed with non-zero info code: {info}")]
Lapack { routine: &'static str, info: i32 },
#[error("Matrix inversion failed: matrix is singular or ill-conditioned")]
MatrixInversionFailed,
#[error("Eigenvalue computation failed")]
EigenvalueComputationFailed,
#[error("SVD computation failed")]
SvdComputationFailed,
#[error("Dimension mismatch for '{context}': expected {expected}, got {found}")]
DimensionMismatch {
context: String,
expected: usize,
found: usize,
},
#[error("Invalid array shape: expected {expected:?}, got {found:?}")]
InvalidArrayShape {
expected: Vec<usize>,
found: Vec<usize>,
},
#[error("The path for the Wilson Loop is not closed. Remainder vector: {0:?}")]
UnclosedWilsonLoop(Array1<f64>),
#[error("The provided direction index '{index}' is out of bounds for dimension '{dim}'")]
InvalidDirectionIndex { index: usize, dim: usize },
#[error("Invalid supercell size 'num' for cut_piece: {0}. Must be >= 1.")]
InvalidSupercellSize(usize),
#[error("Invalid shape identifier for cut_dot: {0}. Supported shapes are 3, 4, 6, 8.")]
InvalidShapeIdentifier(usize),
#[error(
"The supercell transformation matrix U must have integer elements and a non-zero determinant."
)]
InvalidSupercellMatrix,
#[error("Spin direction '{0:?}' is invalid for a model without spin.")]
SpinNotAllowed(SpinDirection),
#[error("Invalid k-point mesh dimensions: {0:?}")]
InvalidKmeshDimensions(Array1<usize>),
#[error("Invalid energy range: min={min}, max={max}")]
InvalidEnergyRange { min: f64, max: f64 },
#[error("On-site hopping energy must be a real number, but got {0}")]
OnsiteHoppingMustBeReal(Complex<f64>),
#[error(
"Internal model inconsistency: Hopping for vector R={r:?} exists, but its Hermitian conjugate for -R does not."
)]
MissingHermitianConjugateHopping { r: Array1<isize> },
#[error("Invalid operation for a zero-dimensional model.")]
InvalidOperationForZeroDimension,
#[error("Model has not been properly initialized")]
ModelNotInitialized,
#[error("No bands found in the specified energy range")]
NoBandsInEnergyRange,
#[error("Convergence failed after {iterations} iterations")]
ConvergenceFailed { iterations: usize },
#[error(
"Missing Slater-Koster parameter '{param}' for atom pair {atom1:?}-{atom2:?} at shell {shell}"
)]
SkParameterMissing {
param: String,
atom1: AtomType,
atom2: AtomType,
shell: usize,
},
#[error("Unsupported orbital combination: {0:?} - {1:?}")]
UnsupportedOrbitalCombination(OrbProj, OrbProj),
#[error("Invalid neighbor search range: {0}")]
InvalidSearchRange(i32),
#[error("No neighbor shells found")]
NoShellsFound,
#[error("Hybrid orbital projection '{0}' is not currently supported for this operation")]
HybridOrbitalNotSupported(String),
#[error("Feature '{0}' is not yet implemented")]
NotImplemented(String),
#[error(
"Lattice matrix dimension error: second dimension length must equal dim_r, but got {actual} (expected {expected})"
)]
LatticeDimensionError { expected: usize, actual: usize },
#[error("R vector length error: expected {expected}, got {actual}")]
RVectorLengthError { expected: usize, actual: usize },
#[error("Invalid k-path operation for zero-dimensional model")]
ZeroDimKPathError,
#[error("Path length mismatch: expected {expected}, got {actual}")]
PathLengthMismatch { expected: usize, actual: usize },
#[error("Invalid direction index: {index} for dimension {dim}")]
InvalidDirection { index: usize, dim: usize },
#[error("Invalid shape: {shape}. Supported shapes: {supported:?}")]
InvalidShape { shape: usize, supported: Vec<usize> },
#[error("Invalid dimension for operation: {dim}. Supported dimensions: {supported:?}")]
InvalidDimension { dim: usize, supported: Vec<usize> },
#[error("Duplicate orbitals found in orbital list")]
DuplicateOrbitals,
#[error("Invalid supercell transformation matrix determinant: {det}")]
InvalidSupercellDet { det: f64 },
#[error("Invalid atom positions or count in unit cell")]
InvalidAtomConfiguration,
#[error("Transformation matrix dimension mismatch: expected {expected}, got {actual}")]
TransformationMatrixDimMismatch { expected: usize, actual: usize },
#[error("Missing Hermitian conjugate for R vector: {r:?}")]
MissingHermitianConjugate { r: Array1<isize> },
#[error("Invalid spin value: {spin}. Supported values: {supported:?}")]
InvalidSpinValue { spin: usize, supported: Vec<usize> },
#[error("Temperature T=0 not supported for this operation")]
ZeroTemperatureNotSupported,
#[error("Invalid k-vector length: expected {expected}, got {actual}")]
KVectorLengthMismatch { expected: usize, actual: usize },
#[error("LAPACK eigenvalue computation failed with info code: {info}")]
LapackEigenFailed { info: i32 },
#[error("Unexpected error: {0}")]
Other(String),
}
pub type Result<T> = std::result::Result<T, TbError>;