use std::fmt;
use crate::ReferenceSolveError;
pub const MAX_ANALYTIC_RELATIVE_ERROR: f64 = 1.0e-12;
pub const MAX_METAMORPHIC_RELATIVE_ERROR: f64 = 1.0e-12;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct VerificationReport {
pub analytic_max_error: f64,
pub reciprocity_relative: f64,
pub linearity_relative: f64,
pub rigid_motion_relative: f64,
pub global_phase_relative: f64,
pub source_permutation_identical: bool,
pub helmholtz_observed_order: f64,
}
#[derive(Clone, Debug, PartialEq)]
pub enum VerificationError {
Reference {
cause: Box<ReferenceSolveError>,
},
RelativeErrorExceeded {
check: &'static str,
measured: f64,
limit: f64,
},
SourcePermutationChanged,
HelmholtzOrderOutOfRange {
fixture: &'static str,
observed: f64,
minimum: f64,
maximum: f64,
},
}
impl From<ReferenceSolveError> for VerificationError {
fn from(cause: ReferenceSolveError) -> Self {
Self::Reference {
cause: Box::new(cause),
}
}
}
impl fmt::Display for VerificationError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Reference { cause } => write!(formatter, "verification fixture failed: {cause}"),
Self::RelativeErrorExceeded {
check,
measured,
limit,
} => write!(
formatter,
"verification check `{check}` measured relative error {measured:e}, \
exceeding {limit:e}"
),
Self::SourcePermutationChanged => {
formatter.write_str("canonical source permutations changed field component bits")
}
Self::HelmholtzOrderOutOfRange {
fixture,
observed,
minimum,
maximum,
} => write!(
formatter,
"Helmholtz fixture `{fixture}` observed order {observed}, outside \
[{minimum}, {maximum}]"
),
}
}
}
impl std::error::Error for VerificationError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Reference { cause } => Some(cause.as_ref()),
Self::RelativeErrorExceeded { .. }
| Self::SourcePermutationChanged
| Self::HelmholtzOrderOutOfRange { .. } => None,
}
}
}