use crate::allocators::BiDimAllocator;
use crate::assembly::local::UniformQuadratureTable;
use crate::element::Tet4Element;
use crate::element::*;
use crate::mesh::Mesh;
use crate::nalgebra::{DefaultAllocator, DimName, Scalar};
use crate::quadrature::QuadraturePair;
use crate::quadrature::{tensor, total_order};
use crate::Real;
pub trait CanonicalMassQuadrature {
type Quadrature;
fn canonical_mass_quadrature() -> Self::Quadrature;
}
pub trait CanonicalStiffnessQuadrature {
type Quadrature;
fn canonical_stiffness_quadrature() -> Self::Quadrature;
}
macro_rules! impl_canonical_mass_for_element {
($element:ty, $quadrature:expr) => {
impl<T> CanonicalMassQuadrature for $element
where
T: Real,
{
type Quadrature = QuadraturePair<T, <$element as ReferenceFiniteElement<T>>::ReferenceDim>;
fn canonical_mass_quadrature() -> Self::Quadrature {
$quadrature
}
}
};
}
macro_rules! impl_canonical_stiffness_for_element {
($element:ty, $quadrature:expr) => {
impl<T> CanonicalStiffnessQuadrature for $element
where
T: Real,
{
type Quadrature = QuadraturePair<T, <$element as ReferenceFiniteElement<T>>::ReferenceDim>;
fn canonical_stiffness_quadrature() -> Self::Quadrature {
$quadrature
}
}
};
}
impl_canonical_mass_for_element!(Tri3d2Element<T>, total_order::triangle(2).unwrap());
impl_canonical_mass_for_element!(Tri6d2Element<T>, total_order::triangle(4).unwrap());
impl_canonical_stiffness_for_element!(Tri3d2Element<T>, total_order::triangle(1).unwrap());
impl_canonical_stiffness_for_element!(Tri6d2Element<T>, total_order::triangle(2).unwrap());
impl_canonical_mass_for_element!(Quad4d2Element<T>, tensor::quadrilateral_gauss(2));
impl_canonical_mass_for_element!(Quad9d2Element<T>, tensor::quadrilateral_gauss(3));
impl_canonical_stiffness_for_element!(Quad4d2Element<T>, tensor::quadrilateral_gauss(2));
impl_canonical_stiffness_for_element!(Quad9d2Element<T>, tensor::quadrilateral_gauss(3));
impl_canonical_mass_for_element!(Tet4Element<T>, total_order::tetrahedron(2).unwrap());
impl_canonical_mass_for_element!(Tet10Element<T>, total_order::tetrahedron(4).unwrap());
impl_canonical_mass_for_element!(Tet20Element<T>, total_order::tetrahedron(6).unwrap());
impl_canonical_stiffness_for_element!(Tet4Element<T>, total_order::tetrahedron(1).unwrap());
impl_canonical_stiffness_for_element!(Tet10Element<T>, total_order::tetrahedron(2).unwrap());
impl_canonical_stiffness_for_element!(Tet20Element<T>, total_order::tetrahedron(4).unwrap());
impl_canonical_mass_for_element!(Hex8Element<T>, tensor::hexahedron_gauss(2));
impl_canonical_mass_for_element!(Hex20Element<T>, tensor::hexahedron_gauss(3));
impl_canonical_mass_for_element!(Hex27Element<T>, tensor::hexahedron_gauss(3));
impl_canonical_stiffness_for_element!(Hex8Element<T>, tensor::hexahedron_gauss(2));
impl_canonical_stiffness_for_element!(Hex20Element<T>, tensor::hexahedron_gauss(3));
impl_canonical_stiffness_for_element!(Hex27Element<T>, tensor::hexahedron_gauss(3));
impl<T, D, C> CanonicalMassQuadrature for Mesh<T, D, C>
where
T: Scalar,
D: DimName,
C: ElementConnectivity<T, GeometryDim = D>,
C::Element: CanonicalMassQuadrature<Quadrature = QuadraturePair<T, C::ReferenceDim>>,
DefaultAllocator: BiDimAllocator<T, C::GeometryDim, C::ReferenceDim>,
{
type Quadrature = UniformQuadratureTable<T, C::ReferenceDim>;
fn canonical_mass_quadrature() -> Self::Quadrature {
UniformQuadratureTable::from_quadrature(C::Element::canonical_mass_quadrature())
}
}
impl<T, D, C> CanonicalStiffnessQuadrature for Mesh<T, D, C>
where
T: Scalar,
D: DimName,
C: ElementConnectivity<T, GeometryDim = D>,
C::Element: CanonicalStiffnessQuadrature<Quadrature = QuadraturePair<T, C::ReferenceDim>>,
DefaultAllocator: BiDimAllocator<T, C::GeometryDim, C::ReferenceDim>,
{
type Quadrature = UniformQuadratureTable<T, C::ReferenceDim>;
fn canonical_stiffness_quadrature() -> Self::Quadrature {
UniformQuadratureTable::from_quadrature(C::Element::canonical_stiffness_quadrature())
}
}