use crate::PhysicsError;
use crate::kernels::fluids::quantities::{StrainRateTensor, Viscosity, ViscousStress};
use deep_causality_num::{FromPrimitive, RealField};
pub fn newtonian_viscous_stress_kernel<R>(
mu: &Viscosity<R>,
strain_rate: &StrainRateTensor<R>,
div_u: R,
) -> Result<ViscousStress<R>, PhysicsError>
where
R: RealField + FromPrimitive,
{
let two = R::from_f64(2.0)
.ok_or_else(|| PhysicsError::NumericalInstability("R::from_f64(2.0) failed".into()))?;
let two_thirds = R::from_f64(2.0 / 3.0)
.ok_or_else(|| PhysicsError::NumericalInstability("R::from_f64(2.0/3.0) failed".into()))?;
let m = mu.value();
let s = strain_rate.value();
let bulk_term = two_thirds * m * div_u;
let mut tau = [[R::zero(); 3]; 3];
for i in 0..3 {
for j in 0..3 {
tau[i][j] = two * m * s[i][j];
}
}
tau[0][0] -= bulk_term;
tau[1][1] -= bulk_term;
tau[2][2] -= bulk_term;
ViscousStress::new(tau)
}
pub fn newtonian_viscous_stress_with_bulk_kernel<R>(
mu: &Viscosity<R>,
zeta: &Viscosity<R>,
strain_rate: &StrainRateTensor<R>,
div_u: R,
) -> Result<ViscousStress<R>, PhysicsError>
where
R: RealField + FromPrimitive,
{
let two = R::from_f64(2.0)
.ok_or_else(|| PhysicsError::NumericalInstability("R::from_f64(2.0) failed".into()))?;
let two_thirds = R::from_f64(2.0 / 3.0)
.ok_or_else(|| PhysicsError::NumericalInstability("R::from_f64(2.0/3.0) failed".into()))?;
let m = mu.value();
let z = zeta.value();
let s = strain_rate.value();
let bulk_term = (-two_thirds * m + z) * div_u;
let mut tau = [[R::zero(); 3]; 3];
for i in 0..3 {
for j in 0..3 {
tau[i][j] = two * m * s[i][j];
}
}
tau[0][0] += bulk_term;
tau[1][1] += bulk_term;
tau[2][2] += bulk_term;
ViscousStress::new(tau)
}
pub fn power_law_apparent_viscosity_kernel<R>(
consistency: R,
flow_index: R,
shear_rate: R,
) -> Result<Viscosity<R>, PhysicsError>
where
R: RealField,
{
if shear_rate < R::zero() {
return Err(PhysicsError::PhysicalInvariantBroken(
"power_law_apparent_viscosity_kernel: shear_rate must be non-negative".into(),
));
}
let exponent = flow_index - R::one();
let mu_eff = consistency * shear_rate.powf(exponent);
Viscosity::new(mu_eff)
}