1use crate::atom_struct::AtomType;
7use crate::{OrbProj, SpinDirection};
8use ndarray::{Array1, Array2, ShapeError};
9use num_complex::Complex;
10use thiserror::Error;
11
12#[derive(Error, Debug)]
14pub enum TbError {
15 #[error("I/O error: {0}")]
17 Io(#[from] std::io::Error),
18
19 #[error("Failed to parse data from file '{file}': {message}")]
20 FileParse { file: String, message: String },
21
22 #[error("Invalid orbital projection string: '{0}'")]
23 InvalidOrbitalProjection(String),
24
25 #[error("Invalid atom type string: '{0}'")]
26 InvalidAtomType(String),
27
28 #[error("Failed to create directory '{path}': {message}")]
29 DirectoryCreation { path: String, message: String },
30
31 #[error("Failed to create file '{path}': {message}")]
32 FileCreation { path: String, message: String },
33
34 #[error("Linear algebra operation failed: {0}")]
36 Linalg(#[from] ndarray_linalg::error::LinalgError),
37
38 #[error("LAPACK routine '{routine}' failed with non-zero info code: {info}")]
39 Lapack { routine: &'static str, info: i32 },
40
41 #[error("Matrix inversion failed: matrix is singular or ill-conditioned")]
42 MatrixInversionFailed,
43
44 #[error("Eigenvalue computation failed")]
45 EigenvalueComputationFailed,
46
47 #[error("SVD computation failed")]
48 SvdComputationFailed,
49
50 #[error("Dimension mismatch for '{context}': expected {expected}, got {found}")]
52 DimensionMismatch {
53 context: String,
54 expected: usize,
55 found: usize,
56 },
57
58 #[error("Invalid array shape: expected {expected:?}, got {found:?}")]
59 InvalidArrayShape {
60 expected: Vec<usize>,
61 found: Vec<usize>,
62 },
63
64 #[error("The path for the Wilson Loop is not closed. Remainder vector: {0:?}")]
65 UnclosedWilsonLoop(Array1<f64>),
66
67 #[error("The provided direction index '{index}' is out of bounds for dimension '{dim}'")]
68 InvalidDirectionIndex { index: usize, dim: usize },
69
70 #[error("Invalid supercell size 'num' for cut_piece: {0}. Must be >= 1.")]
71 InvalidSupercellSize(usize),
72
73 #[error("Invalid shape identifier for cut_dot: {0}. Supported shapes are 3, 4, 6, 8.")]
74 InvalidShapeIdentifier(usize),
75
76 #[error(
77 "The supercell transformation matrix U must have integer elements and a non-zero determinant."
78 )]
79 InvalidSupercellMatrix,
80
81 #[error("Spin direction '{0:?}' is invalid for a model without spin.")]
82 SpinNotAllowed(SpinDirection),
83
84 #[error("Invalid k-point mesh dimensions: {0:?}")]
85 InvalidKmeshDimensions(Array1<usize>),
86
87 #[error("Invalid energy range: min={min}, max={max}")]
88 InvalidEnergyRange { min: f64, max: f64 },
89
90 #[error("On-site hopping energy must be a real number, but got {0}")]
92 OnsiteHoppingMustBeReal(Complex<f64>),
93
94 #[error(
95 "Internal model inconsistency: Hopping for vector R={r:?} exists, but its Hermitian conjugate for -R does not."
96 )]
97 MissingHermitianConjugateHopping { r: Array1<isize> },
98
99 #[error("Invalid operation for a zero-dimensional model.")]
100 InvalidOperationForZeroDimension,
101
102 #[error("Model has not been properly initialized")]
103 ModelNotInitialized,
104
105 #[error("No bands found in the specified energy range")]
106 NoBandsInEnergyRange,
107
108 #[error("Convergence failed after {iterations} iterations")]
109 ConvergenceFailed { iterations: usize },
110
111 #[error(
113 "Missing Slater-Koster parameter '{param}' for atom pair {atom1:?}-{atom2:?} at shell {shell}"
114 )]
115 SkParameterMissing {
116 param: String,
117 atom1: AtomType,
118 atom2: AtomType,
119 shell: usize,
120 },
121
122 #[error("Unsupported orbital combination: {0:?} - {1:?}")]
123 UnsupportedOrbitalCombination(OrbProj, OrbProj),
124
125 #[error("Invalid neighbor search range: {0}")]
126 InvalidSearchRange(i32),
127
128 #[error("No neighbor shells found")]
129 NoShellsFound,
130
131 #[error("Hybrid orbital projection '{0}' is not currently supported for this operation")]
133 HybridOrbitalNotSupported(String),
134
135 #[error("Feature '{0}' is not yet implemented")]
136 NotImplemented(String),
137
138 #[error(
140 "Lattice matrix dimension error: second dimension length must equal dim_r, but got {actual} (expected {expected})"
141 )]
142 LatticeDimensionError { expected: usize, actual: usize },
143
144 #[error("R vector length error: expected {expected}, got {actual}")]
145 RVectorLengthError { expected: usize, actual: usize },
146
147 #[error("Invalid k-path operation for zero-dimensional model")]
148 ZeroDimKPathError,
149
150 #[error("Path length mismatch: expected {expected}, got {actual}")]
151 PathLengthMismatch { expected: usize, actual: usize },
152
153 #[error("Invalid direction index: {index} for dimension {dim}")]
154 InvalidDirection { index: usize, dim: usize },
155
156 #[error("Invalid shape: {shape}. Supported shapes: {supported:?}")]
157 InvalidShape { shape: usize, supported: Vec<usize> },
158
159 #[error("Invalid dimension for operation: {dim}. Supported dimensions: {supported:?}")]
160 InvalidDimension { dim: usize, supported: Vec<usize> },
161
162 #[error("Duplicate orbitals found in orbital list")]
163 DuplicateOrbitals,
164
165 #[error("Invalid supercell transformation matrix determinant: {det}")]
166 InvalidSupercellDet { det: f64 },
167
168 #[error("Invalid atom positions or count in unit cell")]
169 InvalidAtomConfiguration,
170
171 #[error("Transformation matrix dimension mismatch: expected {expected}, got {actual}")]
172 TransformationMatrixDimMismatch { expected: usize, actual: usize },
173
174 #[error("Missing Hermitian conjugate for R vector: {r:?}")]
175 MissingHermitianConjugate { r: Array1<isize> },
176
177 #[error("Invalid spin value: {spin}. Supported values: {supported:?}")]
178 InvalidSpinValue { spin: usize, supported: Vec<usize> },
179
180 #[error("Temperature T=0 not supported for this operation")]
181 ZeroTemperatureNotSupported,
182
183 #[error("Invalid k-vector length: expected {expected}, got {actual}")]
184 KVectorLengthMismatch { expected: usize, actual: usize },
185
186 #[error("LAPACK eigenvalue computation failed with info code: {info}")]
187 LapackEigenFailed { info: i32 },
188
189 #[error("Unexpected error: {0}")]
191 Other(String),
192}
193
194pub type Result<T> = std::result::Result<T, TbError>;