#[cfg(feature = "pml")]
use crate::math::Vector;
use bytemuck::{Pod, Zeroable};
pub use drucker_prager::{DruckerPrager, DruckerPragerPlasticState};
mod drucker_prager;
fn lame_lambda_mu(young_modulus: f32, poisson_ratio: f32) -> (f32, f32) {
(
young_modulus * poisson_ratio / ((1.0 + poisson_ratio) * (1.0 - 2.0 * poisson_ratio)),
shear_modulus(young_modulus, poisson_ratio),
)
}
fn shear_modulus(young_modulus: f32, poisson_ratio: f32) -> f32 {
young_modulus / (2.0 * (1.0 + poisson_ratio))
}
#[derive(Copy, Clone, PartialEq, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct ElasticCoefficients {
pub lambda: f32,
pub mu: f32,
pub cfl_coeff: f32,
}
#[cfg(feature = "pml")]
#[derive(Copy, Clone, PartialEq, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct PmlModel {
pub elastic: ElasticCoefficients,
pub stretch: [f32; 3],
}
#[cfg(feature = "pml")]
pub const DEFAULT_PML_MAX_STRETCH: f32 = 4.0;
#[cfg(feature = "pml")]
pub fn pml_stretch(
position: Vector,
interior_mins: Vector,
interior_maxs: Vector,
thickness: f32,
max_stretch: f32,
) -> Vector {
let below = (interior_mins - position).max(Vector::ZERO);
let above = (position - interior_maxs).max(Vector::ZERO);
let depth = ((below + above) / thickness.max(1.0e-6)).min(Vector::ONE);
depth * max_stretch
}
impl ElasticCoefficients {
pub fn from_young_modulus(young_modulus: f32, poisson_ratio: f32) -> Self {
let (lambda, mu) = lame_lambda_mu(young_modulus, poisson_ratio);
Self {
lambda,
mu,
cfl_coeff: 0.5,
}
}
}