#![cfg_attr(feature = "strict", deny(warnings), deny(unused_crate_dependencies))]
#![warn(missing_docs)]
mod rules;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[repr(u8)]
pub enum Domain {
Interval = 0,
Quadrilateral = 1,
EdgeAdjacentQuadrilaterals = 2,
VertexAdjacentQuadrilaterals = 3,
Triangle = 4,
EdgeAdjacentTriangleAndQuadrilateral = 5,
VertexAdjacentTriangleAndQuadrilateral = 6,
EdgeAdjacentTriangles = 7,
VertexAdjacentTriangles = 8,
Hexahedron = 9,
Tetrahedron = 10,
SquareBasedPyramid = 11,
TriangularPrism = 12,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[repr(u8)]
pub enum QuadratureRule {
GaussLegendre = 1,
GaussLobattoLegendre = 3,
HammerMarloweStroud = 6,
SauterSchwab = 7,
XiaoGimbutas = 2,
CentroidQuadrature = 5,
ClosedNewtonCotes = 8,
OpenNewtonCotes = 9,
VertexQuadrature = 4,
}
pub fn single_integral_quadrature(
rtype: QuadratureRule,
domain: Domain,
order: usize,
) -> Result<(Vec<f64>, Vec<f64>), &'static str> {
match rtype {
QuadratureRule::GaussLegendre => rules::gauss_legendre(domain, order),
QuadratureRule::GaussLobattoLegendre => rules::gauss_lobatto_legendre(domain, order),
QuadratureRule::HammerMarloweStroud => rules::hammer_marlowe_stroud(domain, order),
QuadratureRule::XiaoGimbutas => rules::xiao_gimbutas(domain, order),
QuadratureRule::CentroidQuadrature => rules::centroid_quadrature(domain, order),
QuadratureRule::ClosedNewtonCotes => rules::closed_newton_cotes(domain, order),
QuadratureRule::OpenNewtonCotes => rules::open_newton_cotes(domain, order),
QuadratureRule::VertexQuadrature => rules::vertex_quadrature(domain, order),
_ => Err("Unsupported rule for single integral"),
}
}
pub fn double_integral_quadrature(
rtype: QuadratureRule,
domain: Domain,
order: usize,
) -> Result<(Vec<f64>, Vec<f64>, Vec<f64>), &'static str> {
match rtype {
QuadratureRule::SauterSchwab => rules::sauter_schwab(domain, order),
_ => Err("Unsupported rule for double integral"),
}
}
#[cfg(test)]
mod tests {
use super::*;
use approx::*;
#[test]
fn test_sum_weights_1() {
let weights =
single_integral_quadrature(QuadratureRule::GaussLegendre, Domain::Interval, 1)
.unwrap()
.1;
assert_relative_eq!(weights.iter().sum::<f64>(), 1.0);
}
#[test]
fn test_sum_weights_2() {
let weights =
single_integral_quadrature(QuadratureRule::GaussLegendre, Domain::Interval, 2)
.unwrap()
.1;
assert_relative_eq!(weights.iter().sum::<f64>(), 1.0);
}
#[test]
fn test_sum_weights_3() {
let weights =
single_integral_quadrature(QuadratureRule::GaussLegendre, Domain::Interval, 3)
.unwrap()
.1;
assert_relative_eq!(weights.iter().sum::<f64>(), 1.0);
}
}