use deep_causality_algebra::RealField;
use deep_causality_tensor::CausalTensor;
use deep_causality_topology::{LatticeComplex, Manifold};
use std::ops::{Add, Mul};
use super::validate_graded_field;
use crate::error::physics_error::PhysicsError;
#[derive(Debug, Clone, PartialEq)]
pub struct VelocityOneForm<R: RealField> {
field: CausalTensor<R>,
}
impl<R: RealField> VelocityOneForm<R> {
pub fn new<const D: usize>(
field: CausalTensor<R>,
manifold: &Manifold<LatticeComplex<D, R>, R>,
) -> Result<Self, PhysicsError> {
validate_graded_field(&field, 1, "VelocityOneForm", manifold)?;
Ok(Self { field })
}
pub fn from_raw(field: CausalTensor<R>) -> Self {
Self { field }
}
pub fn as_tensor(&self) -> &CausalTensor<R> {
&self.field
}
pub fn len(&self) -> usize {
self.field.len()
}
pub fn is_empty(&self) -> bool {
self.field.len() == 0
}
}
impl<R: RealField> Add for VelocityOneForm<R> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
assert_eq!(
self.field.len(),
rhs.field.len(),
"VelocityOneForm + VelocityOneForm requires matching edge counts"
);
let data: alloc::vec::Vec<R> = self
.field
.as_slice()
.iter()
.zip(rhs.field.as_slice().iter())
.map(|(a, b)| *a + *b)
.collect();
let len = data.len();
Self {
field: CausalTensor::new(data, alloc::vec![len])
.expect("1-D tensor allocation cannot fail"),
}
}
}
impl<R: RealField> Mul<R> for VelocityOneForm<R> {
type Output = Self;
fn mul(self, rhs: R) -> Self {
let data: alloc::vec::Vec<R> = self.field.as_slice().iter().map(|a| *a * rhs).collect();
let len = data.len();
Self {
field: CausalTensor::new(data, alloc::vec![len])
.expect("1-D tensor allocation cannot fail"),
}
}
}