use crate::Density;
use crate::PhysicsError;
use crate::kernels::dynamics::quantities::{Length, Speed};
use crate::kernels::fluids::quantities::{KinematicViscosity, Viscosity, WallShearStress};
use deep_causality_num::RealField;
pub fn wall_shear_stress_newtonian_kernel<R>(
mu: &Viscosity<R>,
du_dy_wall: R,
) -> Result<WallShearStress<R>, PhysicsError>
where
R: RealField,
{
let abs_gradient = if du_dy_wall < R::zero() {
-du_dy_wall
} else {
du_dy_wall
};
WallShearStress::new(mu.value() * abs_gradient)
}
pub fn friction_velocity_kernel<R>(
tau_w: &WallShearStress<R>,
rho: &Density<R>,
) -> Result<Speed<R>, PhysicsError>
where
R: RealField,
{
let r = rho.value();
if r == R::zero() {
return Err(PhysicsError::PhysicalInvariantBroken(
"friction_velocity_kernel: density is zero".into(),
));
}
Speed::new((tau_w.value() / r).sqrt())
}
pub fn viscous_length_scale_kernel<R>(
nu: &KinematicViscosity<R>,
u_tau: &Speed<R>,
) -> Result<Length<R>, PhysicsError>
where
R: RealField,
{
let u = u_tau.value();
if u == R::zero() {
return Err(PhysicsError::PhysicalInvariantBroken(
"viscous_length_scale_kernel: friction velocity is zero".into(),
));
}
Length::new(nu.value() / u)
}
pub fn y_plus_kernel<R>(
y: &Length<R>,
u_tau: &Speed<R>,
nu: &KinematicViscosity<R>,
) -> Result<R, PhysicsError>
where
R: RealField,
{
let v = nu.value();
if v == R::zero() {
return Err(PhysicsError::PhysicalInvariantBroken(
"y_plus_kernel: kinematic viscosity is zero".into(),
));
}
Ok(y.value() * u_tau.value() / v)
}
pub fn viscous_sublayer_velocity_kernel<R>(y_plus: R) -> R
where
R: RealField,
{
y_plus
}
pub fn log_law_velocity_kernel<R>(y_plus: R, kappa: R, b: R) -> Result<R, PhysicsError>
where
R: RealField,
{
if kappa == R::zero() {
return Err(PhysicsError::PhysicalInvariantBroken(
"log_law_velocity_kernel: kappa is zero".into(),
));
}
if y_plus <= R::zero() {
return Err(PhysicsError::PhysicalInvariantBroken(
"log_law_velocity_kernel: y_plus must be > 0".into(),
));
}
Ok(y_plus.ln() / kappa + b)
}
pub fn skin_friction_coefficient_kernel<R>(
tau_w: &WallShearStress<R>,
rho: &Density<R>,
u_inf: &Speed<R>,
) -> Result<R, PhysicsError>
where
R: RealField,
{
let r = rho.value();
let u = u_inf.value();
if r == R::zero() {
return Err(PhysicsError::PhysicalInvariantBroken(
"skin_friction_coefficient_kernel: density is zero".into(),
));
}
if u == R::zero() {
return Err(PhysicsError::PhysicalInvariantBroken(
"skin_friction_coefficient_kernel: u_inf is zero".into(),
));
}
let two = R::one() + R::one();
Ok(tau_w.value() * two / (r * u * u))
}