Skip to main content

gizmo_physics_soft/
error.rs

1//! Concrete error type for fallible soft-body operations.
2//!
3//! This replaces the previous "swallow + log", `Option`, and silent-clamp
4//! failure surfaces with an explicit, matchable [`SoftBodyError`]. The success
5//! path of every converted function is unchanged; only the failure surface is
6//! now a `Result`.
7
8/// Errors produced by fallible soft-body construction and simulation operations.
9#[derive(Debug, Clone, PartialEq)]
10#[non_exhaustive]
11pub enum SoftBodyError {
12    /// A tetrahedral element referenced a node index that does not exist yet.
13    ///
14    /// `index` is the offending node index and `node_count` is the number of
15    /// nodes currently present in the mesh.
16    NodeIndexOutOfBounds { index: u32, node_count: u32 },
17
18    /// Poisson's ratio was outside the physically valid range `[0.0, 0.5)`.
19    ///
20    /// Values `>= 0.5` produce a singular / negative Lamé `lambda`
21    /// (incompressible limit) and values `< 0.0` are unsupported here.
22    InvalidPoissonsRatio { value: f32 },
23
24    /// Young's modulus was not a finite, strictly-positive value.
25    InvalidYoungsModulus { value: f32 },
26
27    /// A tetrahedral element was (near-)degenerate: its rest volume is not a
28    /// finite, strictly-positive value above the acceptance epsilon.
29    ///
30    /// Such elements have a singular reference shape matrix (`Dm`), so the
31    /// deformation gradient and the derived elastic forces are undefined
32    /// (near-zero stiffness / NaN propagation). `volume` is the offending rest
33    /// volume that was computed.
34    DegenerateTetrahedron { volume: f32 },
35
36    /// The flattened GPU node offset overflowed `u32` (too many nodes across
37    /// all soft bodies in a single step).
38    NodeOffsetOverflow,
39
40    /// No compatible GPU adapter could be acquired.
41    NoCompatibleAdapter,
42
43    /// Requesting a logical GPU device from the adapter failed.
44    DeviceRequestFailed(String),
45}
46
47impl std::fmt::Display for SoftBodyError {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        match self {
50            SoftBodyError::NodeIndexOutOfBounds { index, node_count } => write!(
51                f,
52                "soft body node index {index} out of bounds (node count {node_count})"
53            ),
54            SoftBodyError::InvalidPoissonsRatio { value } => write!(
55                f,
56                "invalid Poisson's ratio {value} (must be in [0.0, 0.5))"
57            ),
58            SoftBodyError::InvalidYoungsModulus { value } => write!(
59                f,
60                "invalid Young's modulus {value} (must be finite and > 0)"
61            ),
62            SoftBodyError::DegenerateTetrahedron { volume } => write!(
63                f,
64                "degenerate tetrahedral element (rest volume {volume} must be finite and > 0)"
65            ),
66            SoftBodyError::NodeOffsetOverflow => {
67                write!(f, "soft body node offset overflowed u32 (too many nodes)")
68            }
69            SoftBodyError::NoCompatibleAdapter => {
70                write!(f, "no compatible GPU adapter available for soft-body compute")
71            }
72            SoftBodyError::DeviceRequestFailed(msg) => {
73                write!(f, "failed to request GPU device for soft-body compute: {msg}")
74            }
75        }
76    }
77}
78
79impl std::error::Error for SoftBodyError {}