Sepehr fa480ed303 feat: implement mass balance validation for Story 7.1
- Added port_mass_flows to Component trait and implements for core components.
- Added System::check_mass_balance and integrated it into the solver.
- Restored connect methods for ExpansionValve, Compressor, and Pipe to fix integration tests.
- Updated Python and C bindings for validation errors.
- Updated sprint status and story documentation.
2026-02-21 23:21:34 +01:00

170 lines
4.6 KiB
Rust

use thiserror::Error;
use crate::builder::SystemBuilderError;
/// Unified error type for all Entropyk operations.
///
/// This enum wraps all possible errors that can occur when using the library,
/// providing a single error type for the public API.
#[derive(Error, Debug)]
pub enum ThermoError {
/// Error from component operations.
#[error("Component error: {0}")]
Component(entropyk_components::ComponentError),
/// Error from solver operations.
#[error("Solver error: {0}")]
Solver(entropyk_solver::SolverError),
/// Error from fluid property calculations.
#[error("Fluid error: {0}")]
Fluid(entropyk_fluids::FluidError),
/// Error from topology operations.
#[error("Topology error: {0}")]
Topology(entropyk_solver::TopologyError),
/// Error adding an edge to the system.
#[error("Edge error: {0}")]
AddEdge(entropyk_solver::AddEdgeError),
/// Error from connection operations.
#[error("Connection error: {0}")]
Connection(entropyk_components::ConnectionError),
/// Error from constraint operations.
#[error("Constraint error: {0}")]
Constraint(entropyk_solver::ConstraintError),
/// Error from initialization.
#[error("Initialization error: {0}")]
Initialization(entropyk_solver::InitializerError),
/// Error from calibration validation.
#[error("Calibration error: {0}")]
Calibration(entropyk_core::CalibValidationError),
/// Error from mixture operations.
#[error("Mixture error: {0}")]
Mixture(entropyk_fluids::MixtureError),
/// Error from system builder operations.
#[error("Builder error: {0}")]
Builder(SystemBuilderError),
/// Invalid input was provided.
#[error("Invalid input: {0}")]
InvalidInput(String),
/// Operation is not supported.
#[error("Operation not supported: {0}")]
NotSupported(String),
/// System was not finalized before an operation.
#[error("System must be finalized before this operation")]
NotFinalized,
/// Simulation validation error (e.g., mass/energy balance constraints violated)
#[error("Validation failed: mass error = {mass_error:.3e} kg/s, energy error = {energy_error:.3e} W")]
Validation {
/// Mass balance error in kg/s
mass_error: f64,
/// Energy balance error in W
energy_error: f64,
},
}
impl ThermoError {
/// Creates a new `InvalidInput` error with the given message.
#[inline]
pub fn invalid_input(msg: impl Into<String>) -> Self {
Self::InvalidInput(msg.into())
}
/// Creates a new `NotSupported` error with the given message.
#[inline]
pub fn not_supported(msg: impl Into<String>) -> Self {
Self::NotSupported(msg.into())
}
}
impl From<entropyk_components::ComponentError> for ThermoError {
#[inline]
fn from(e: entropyk_components::ComponentError) -> Self {
Self::Component(e)
}
}
impl From<entropyk_solver::SolverError> for ThermoError {
#[inline]
fn from(e: entropyk_solver::SolverError) -> Self {
Self::Solver(e)
}
}
impl From<entropyk_fluids::FluidError> for ThermoError {
#[inline]
fn from(e: entropyk_fluids::FluidError) -> Self {
Self::Fluid(e)
}
}
impl From<entropyk_solver::TopologyError> for ThermoError {
#[inline]
fn from(e: entropyk_solver::TopologyError) -> Self {
Self::Topology(e)
}
}
impl From<entropyk_solver::AddEdgeError> for ThermoError {
#[inline]
fn from(e: entropyk_solver::AddEdgeError) -> Self {
Self::AddEdge(e)
}
}
impl From<entropyk_components::ConnectionError> for ThermoError {
#[inline]
fn from(e: entropyk_components::ConnectionError) -> Self {
Self::Connection(e)
}
}
impl From<entropyk_solver::ConstraintError> for ThermoError {
#[inline]
fn from(e: entropyk_solver::ConstraintError) -> Self {
Self::Constraint(e)
}
}
impl From<entropyk_solver::InitializerError> for ThermoError {
#[inline]
fn from(e: entropyk_solver::InitializerError) -> Self {
Self::Initialization(e)
}
}
impl From<entropyk_core::CalibValidationError> for ThermoError {
#[inline]
fn from(e: entropyk_core::CalibValidationError) -> Self {
Self::Calibration(e)
}
}
impl From<entropyk_fluids::MixtureError> for ThermoError {
#[inline]
fn from(e: entropyk_fluids::MixtureError) -> Self {
Self::Mixture(e)
}
}
impl From<SystemBuilderError> for ThermoError {
#[inline]
fn from(e: SystemBuilderError) -> Self {
Self::Builder(e)
}
}
/// A specialized `Result` type for Entropyk operations.
pub type ThermoResult<T> = Result<T, ThermoError>;