use crate::allocators::{BiDimAllocator, DimAllocator};
use crate::assembly::operators::{EllipticContraction, EllipticEnergy, EllipticOperator, Operator};
use crate::nalgebra::{DefaultAllocator, OMatrix, OVector, U1};
use crate::{Real, SmallDim, Symmetry};
use numeric_literals::replace_float_literals;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LaplaceOperator;
impl<T, GeometryDim> Operator<T, GeometryDim> for LaplaceOperator {
type SolutionDim = U1;
type Parameters = ();
}
impl<T, D> EllipticEnergy<T, D> for LaplaceOperator
where
T: Real,
D: SmallDim,
DefaultAllocator: BiDimAllocator<T, D, Self::SolutionDim>,
{
#[replace_float_literals(T::from_f64(literal).unwrap())]
fn compute_energy(&self, gradient: &OMatrix<T, D, Self::SolutionDim>, _parameters: &Self::Parameters) -> T {
0.5 * gradient.dot(&gradient)
}
}
impl<T, D> EllipticOperator<T, D> for LaplaceOperator
where
T: Real,
D: SmallDim,
DefaultAllocator: BiDimAllocator<T, D, Self::SolutionDim>,
{
fn compute_elliptic_operator(
&self,
gradient: &OMatrix<T, D, Self::SolutionDim>,
_data: &Self::Parameters,
) -> OMatrix<T, D, Self::SolutionDim> {
gradient.clone()
}
}
impl<T, D> EllipticContraction<T, D> for LaplaceOperator
where
T: Real,
D: SmallDim,
DefaultAllocator: DimAllocator<T, D>,
{
fn contract(
&self,
_gradient: &OMatrix<T, D, Self::SolutionDim>,
a: &OVector<T, D>,
b: &OVector<T, D>,
_data: &Self::Parameters,
) -> OMatrix<T, Self::SolutionDim, Self::SolutionDim> {
OVector::<T, U1>::new(a.dot(&b))
}
fn symmetry(&self) -> Symmetry {
Symmetry::Symmetric
}
}