1#![cfg_attr(feature = "strict", deny(warnings), deny(unused_crate_dependencies))]
3#![warn(missing_docs)]
4
5mod rules;
6
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
10#[repr(u8)]
11pub enum Domain {
12 Interval = 0,
14 Quadrilateral = 1,
16 EdgeAdjacentQuadrilaterals = 2,
18 VertexAdjacentQuadrilaterals = 3,
20 Triangle = 4,
22 EdgeAdjacentTriangleAndQuadrilateral = 5,
24 VertexAdjacentTriangleAndQuadrilateral = 6,
26 EdgeAdjacentTriangles = 7,
28 VertexAdjacentTriangles = 8,
30 Hexahedron = 9,
32 Tetrahedron = 10,
34 SquareBasedPyramid = 11,
36 TriangularPrism = 12,
38}
39
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
43#[repr(u8)]
44pub enum QuadratureRule {
45 GaussLegendre = 1,
47 GaussLobattoLegendre = 3,
49 HammerMarloweStroud = 6,
51 SauterSchwab = 7,
53 XiaoGimbutas = 2,
55 CentroidQuadrature = 5,
57 ClosedNewtonCotes = 8,
59 OpenNewtonCotes = 9,
61 VertexQuadrature = 4,
63}
64
65pub fn single_integral_quadrature(
67 rtype: QuadratureRule,
68 domain: Domain,
69 order: usize,
70) -> Result<(Vec<f64>, Vec<f64>), &'static str> {
71 match rtype {
72 QuadratureRule::GaussLegendre => rules::gauss_legendre(domain, order),
73 QuadratureRule::GaussLobattoLegendre => rules::gauss_lobatto_legendre(domain, order),
74 QuadratureRule::HammerMarloweStroud => rules::hammer_marlowe_stroud(domain, order),
75 QuadratureRule::XiaoGimbutas => rules::xiao_gimbutas(domain, order),
76 QuadratureRule::CentroidQuadrature => rules::centroid_quadrature(domain, order),
77 QuadratureRule::ClosedNewtonCotes => rules::closed_newton_cotes(domain, order),
78 QuadratureRule::OpenNewtonCotes => rules::open_newton_cotes(domain, order),
79 QuadratureRule::VertexQuadrature => rules::vertex_quadrature(domain, order),
80 _ => Err("Unsupported rule for single integral"),
81 }
82}
83
84pub fn double_integral_quadrature(
86 rtype: QuadratureRule,
87 domain: Domain,
88 order: usize,
89) -> Result<(Vec<f64>, Vec<f64>, Vec<f64>), &'static str> {
90 match rtype {
91 QuadratureRule::SauterSchwab => rules::sauter_schwab(domain, order),
92 _ => Err("Unsupported rule for double integral"),
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use approx::*;
100
101 #[test]
102 fn test_sum_weights_1() {
103 let weights =
104 single_integral_quadrature(QuadratureRule::GaussLegendre, Domain::Interval, 1)
105 .unwrap()
106 .1;
107 assert_relative_eq!(weights.iter().sum::<f64>(), 1.0);
108 }
109
110 #[test]
111 fn test_sum_weights_2() {
112 let weights =
113 single_integral_quadrature(QuadratureRule::GaussLegendre, Domain::Interval, 2)
114 .unwrap()
115 .1;
116 assert_relative_eq!(weights.iter().sum::<f64>(), 1.0);
117 }
118
119 #[test]
120 fn test_sum_weights_3() {
121 let weights =
122 single_integral_quadrature(QuadratureRule::GaussLegendre, Domain::Interval, 3)
123 .unwrap()
124 .1;
125 assert_relative_eq!(weights.iter().sum::<f64>(), 1.0);
126 }
127}