deep_causality_physics/dynamics/
kinematics.rs1use crate::{Frequency, Mass, MomentOfInertia, PhysicsError};
7use deep_causality_multivector::{CausalMultiVector, MultiVector};
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct PhysicalVector(pub CausalMultiVector<f64>);
11
12impl Default for PhysicalVector {
13 fn default() -> Self {
14 Self(
16 CausalMultiVector::new(vec![0.0], deep_causality_multivector::Metric::Euclidean(0))
17 .unwrap(),
18 )
19 }
20}
21
22impl PhysicalVector {
23 pub fn new(val: CausalMultiVector<f64>) -> Self {
24 Self(val)
25 }
26 pub fn inner(&self) -> &CausalMultiVector<f64> {
27 &self.0
28 }
29 pub fn into_inner(self) -> CausalMultiVector<f64> {
30 self.0
31 }
32}
33
34pub fn kinetic_energy_kernel(
44 mass: Mass,
45 velocity: &CausalMultiVector<f64>,
46) -> Result<f64, PhysicsError> {
47 let v_sq = velocity.squared_magnitude();
49 if !v_sq.is_finite() {
50 return Err(PhysicsError::NumericalInstability(
51 "Velocity squared magnitude is not finite".into(),
52 ));
53 }
54 if v_sq < -1e-12 {
55 return Err(PhysicsError::PhysicalInvariantBroken(
56 "Negative squared speed in kinetic energy calculation".into(),
57 ));
58 }
59 let v_sq_clamped = if v_sq < 0.0 { 0.0 } else { v_sq };
60 let e = 0.5 * mass.value() * v_sq_clamped;
61 Ok(e)
62}
63
64pub fn rotational_kinetic_energy_kernel(
73 inertia: MomentOfInertia,
74 omega: Frequency,
75) -> Result<f64, PhysicsError> {
76 let w = omega.value();
78 let e = 0.5 * inertia.value() * w * w;
79 Ok(e)
80}
81
82pub fn torque_kernel(
93 radius: &CausalMultiVector<f64>,
94 force: &CausalMultiVector<f64>,
95) -> Result<PhysicalVector, PhysicsError> {
96 if radius.metric() != force.metric() {
99 return Err(PhysicsError::DimensionMismatch(format!(
100 "Metric mismatch: {:?} != {:?}",
101 radius.metric(),
102 force.metric()
103 )));
104 }
105 let t = radius.outer_product(force);
106 Ok(PhysicalVector(t))
107}
108
109pub fn angular_momentum_kernel(
118 radius: &CausalMultiVector<f64>,
119 momentum: &CausalMultiVector<f64>,
120) -> Result<PhysicalVector, PhysicsError> {
121 if radius.metric() != momentum.metric() {
123 return Err(PhysicsError::DimensionMismatch(format!(
124 "Metric mismatch: {:?} != {:?}",
125 radius.metric(),
126 momentum.metric()
127 )));
128 }
129 let l = radius.outer_product(momentum);
130 Ok(PhysicalVector(l))
131}