use super::gauss::{
QuadraturePoint, gauss_hexahedron, gauss_quadrilateral, gauss_tetrahedron, gauss_triangle,
};
use crate::mesh::ElementType;
#[derive(Debug, Clone)]
pub struct QuadratureRule {
pub element_type: ElementType,
pub order: usize,
pub points: Vec<QuadraturePoint>,
}
impl QuadratureRule {
pub fn new(element_type: ElementType, order: usize) -> Self {
let points = match element_type {
ElementType::Triangle => gauss_triangle(order),
ElementType::Quadrilateral => gauss_quadrilateral(order),
ElementType::Tetrahedron => gauss_tetrahedron(order),
ElementType::Hexahedron => gauss_hexahedron(order),
};
Self {
element_type,
order,
points,
}
}
pub fn num_points(&self) -> usize {
self.points.len()
}
pub fn iter(&self) -> impl Iterator<Item = &QuadraturePoint> {
self.points.iter()
}
}
pub fn required_order_for_stiffness(polynomial_degree: usize) -> usize {
polynomial_degree.max(1)
}
pub fn required_order_for_mass(polynomial_degree: usize) -> usize {
polynomial_degree + 1
}
pub fn for_stiffness(element_type: ElementType, polynomial_degree: usize) -> QuadratureRule {
QuadratureRule::new(
element_type,
required_order_for_stiffness(polynomial_degree),
)
}
pub fn for_mass(element_type: ElementType, polynomial_degree: usize) -> QuadratureRule {
QuadratureRule::new(element_type, required_order_for_mass(polynomial_degree))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_quadrature_rule_creation() {
let rule = QuadratureRule::new(ElementType::Triangle, 2);
assert_eq!(rule.element_type, ElementType::Triangle);
assert_eq!(rule.order, 2);
assert!(!rule.points.is_empty());
}
#[test]
fn test_required_orders() {
assert_eq!(required_order_for_stiffness(1), 1);
assert_eq!(required_order_for_mass(1), 2);
assert_eq!(required_order_for_stiffness(2), 2);
assert_eq!(required_order_for_mass(2), 3);
assert_eq!(required_order_for_stiffness(3), 3);
assert_eq!(required_order_for_mass(3), 4);
}
#[test]
fn test_for_stiffness_and_mass() {
let stiffness_rule = for_stiffness(ElementType::Triangle, 2);
let mass_rule = for_mass(ElementType::Triangle, 2);
assert!(mass_rule.num_points() >= stiffness_rule.num_points());
}
}