#[cfg(test)]
pub mod test;
mod almansi_hamel;
pub use almansi_hamel::AlmansiHamel;
use super::{
viscoelastic::{AppliedLoad, Viscoelastic},
*,
};
use crate::math::{
Matrix, Vector,
integrate::{ImplicitDaeFirstOrderMinimize, ImplicitDaeSecondOrderMinimize},
optimize::{EqualityConstraint, FirstOrderOptimization, SecondOrderOptimization},
};
pub trait ElasticHyperviscous
where
Self: Viscoelastic,
{
fn dissipation_potential(
&self,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate,
) -> Result<Scalar, ConstitutiveError> {
Ok(self
.first_piola_kirchhoff_stress(deformation_gradient, &ZERO_10)?
.full_contraction(deformation_gradient_rate)
+ self.viscous_dissipation(deformation_gradient, deformation_gradient_rate)?)
}
fn viscous_dissipation(
&self,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate,
) -> Result<Scalar, ConstitutiveError>;
}
pub trait FirstOrderMinimize {
fn minimize(
&self,
applied_load: AppliedLoad,
integrator: impl ImplicitDaeFirstOrderMinimize<
Scalar,
DeformationGradientRate,
DeformationGradientRates,
>,
solver: impl FirstOrderOptimization<Scalar, DeformationGradient>,
) -> Result<(Times, DeformationGradients, DeformationGradientRates), ConstitutiveError>;
}
pub trait SecondOrderMinimize {
fn minimize(
&self,
applied_load: AppliedLoad,
integrator: impl ImplicitDaeSecondOrderMinimize<
Scalar,
FirstPiolaKirchhoffStress,
FirstPiolaKirchhoffRateTangentStiffness,
DeformationGradientRate,
DeformationGradientRates,
>,
solver: impl SecondOrderOptimization<
Scalar,
FirstPiolaKirchhoffStress,
FirstPiolaKirchhoffRateTangentStiffness,
DeformationGradient,
>,
) -> Result<(Times, DeformationGradients, DeformationGradientRates), ConstitutiveError>;
}
impl<T> FirstOrderMinimize for T
where
T: ElasticHyperviscous,
{
fn minimize(
&self,
applied_load: AppliedLoad,
integrator: impl ImplicitDaeFirstOrderMinimize<
Scalar,
DeformationGradientRate,
DeformationGradientRates,
>,
solver: impl FirstOrderOptimization<Scalar, DeformationGradientRate>,
) -> Result<(Times, DeformationGradients, DeformationGradientRates), ConstitutiveError> {
match match applied_load {
AppliedLoad::UniaxialStress(deformation_gradient_rate_11, time) => {
let mut matrix = Matrix::zero(4, 9);
let mut vector = Vector::zero(4);
matrix[0][0] = 1.0;
matrix[1][1] = 1.0;
matrix[2][2] = 1.0;
matrix[3][5] = 1.0;
integrator.integrate(
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.dissipation_potential(
deformation_gradient,
deformation_gradient_rate,
)?)
},
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.first_piola_kirchhoff_stress(
deformation_gradient,
deformation_gradient_rate,
)?)
},
solver,
time,
DeformationGradient::identity(),
|t: Scalar| {
vector[0] = deformation_gradient_rate_11(t);
EqualityConstraint::Linear(matrix.clone(), vector.clone())
},
)
}
AppliedLoad::BiaxialStress(
deformation_gradient_rate_11,
deformation_gradient_rate_22,
time,
) => {
let mut matrix = Matrix::zero(5, 9);
let mut vector = Vector::zero(5);
matrix[0][0] = 1.0;
matrix[1][1] = 1.0;
matrix[2][2] = 1.0;
matrix[3][5] = 1.0;
matrix[4][4] = 1.0;
integrator.integrate(
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.dissipation_potential(
deformation_gradient,
deformation_gradient_rate,
)?)
},
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.first_piola_kirchhoff_stress(
deformation_gradient,
deformation_gradient_rate,
)?)
},
solver,
time,
DeformationGradient::identity(),
|t: Scalar| {
vector[0] = deformation_gradient_rate_11(t);
vector[4] = deformation_gradient_rate_22(t);
EqualityConstraint::Linear(matrix.clone(), vector.clone())
},
)
}
} {
Ok(results) => Ok(results),
Err(error) => Err(ConstitutiveError::Upstream(
format!("{error}"),
format!("{self:?}"),
)),
}
}
}
impl<T> SecondOrderMinimize for T
where
T: ElasticHyperviscous,
{
fn minimize(
&self,
applied_load: AppliedLoad,
integrator: impl ImplicitDaeSecondOrderMinimize<
Scalar,
FirstPiolaKirchhoffStress,
FirstPiolaKirchhoffRateTangentStiffness,
DeformationGradientRate,
DeformationGradientRates,
>,
solver: impl SecondOrderOptimization<
Scalar,
FirstPiolaKirchhoffStress,
FirstPiolaKirchhoffRateTangentStiffness,
DeformationGradientRate,
>,
) -> Result<(Times, DeformationGradients, DeformationGradientRates), ConstitutiveError> {
match match applied_load {
AppliedLoad::UniaxialStress(deformation_gradient_rate_11, time) => {
let mut matrix = Matrix::zero(4, 9);
let mut vector = Vector::zero(4);
matrix[0][0] = 1.0;
matrix[1][1] = 1.0;
matrix[2][2] = 1.0;
matrix[3][5] = 1.0;
integrator.integrate(
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.dissipation_potential(
deformation_gradient,
deformation_gradient_rate,
)?)
},
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.first_piola_kirchhoff_stress(
deformation_gradient,
deformation_gradient_rate,
)?)
},
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.first_piola_kirchhoff_rate_tangent_stiffness(
deformation_gradient,
deformation_gradient_rate,
)?)
},
solver,
time,
DeformationGradient::identity(),
|t: Scalar| {
vector[0] = deformation_gradient_rate_11(t);
EqualityConstraint::Linear(matrix.clone(), vector.clone())
},
None,
)
}
AppliedLoad::BiaxialStress(
deformation_gradient_rate_11,
deformation_gradient_rate_22,
time,
) => {
let mut matrix = Matrix::zero(5, 9);
let mut vector = Vector::zero(5);
matrix[0][0] = 1.0;
matrix[1][1] = 1.0;
matrix[2][2] = 1.0;
matrix[3][5] = 1.0;
matrix[4][4] = 1.0;
integrator.integrate(
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.dissipation_potential(
deformation_gradient,
deformation_gradient_rate,
)?)
},
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.first_piola_kirchhoff_stress(
deformation_gradient,
deformation_gradient_rate,
)?)
},
|_: Scalar,
deformation_gradient: &DeformationGradient,
deformation_gradient_rate: &DeformationGradientRate| {
Ok(self.first_piola_kirchhoff_rate_tangent_stiffness(
deformation_gradient,
deformation_gradient_rate,
)?)
},
solver,
time,
DeformationGradient::identity(),
|t: Scalar| {
vector[0] = deformation_gradient_rate_11(t);
vector[4] = deformation_gradient_rate_22(t);
EqualityConstraint::Linear(matrix.clone(), vector.clone())
},
None,
)
}
} {
Ok(results) => Ok(results),
Err(error) => Err(ConstitutiveError::Upstream(
format!("{error}"),
format!("{self:?}"),
)),
}
}
}