Skip to main content

ndfunctionspace/
function.rs

1//! Functions in function spaces
2
3use crate::traits::FunctionSpace;
4use num::Zero;
5
6/// A function in a function space
7pub struct FunctionImpl<'a, S: FunctionSpace> {
8    /// The function space
9    #[allow(unused)]
10    space: &'a S,
11    /// The coefficients that define this function
12    #[allow(unused)]
13    coefficients: Vec<S::T>,
14}
15
16impl<'a, S: FunctionSpace> FunctionImpl<'a, S> {
17    /// Create a new function
18    pub fn new(space: &'a S, coefficients: Vec<S::T>) -> Self {
19        assert_eq!(
20            coefficients.len(),
21            space.process_size(),
22            "Incorrect number of coefficients!",
23        );
24        Self {
25            space,
26            coefficients,
27        }
28    }
29    /// Create a zero function
30    pub fn zero(space: &'a S) -> Self {
31        let coefficients = vec![S::T::zero(); space.process_size()];
32        Self {
33            space,
34            coefficients,
35        }
36    }
37}
38
39#[cfg(test)]
40mod test {
41    use super::*;
42    use crate::function_space::FunctionSpaceImpl;
43    use ndelement::{
44        ciarlet::{LagrangeElementFamily, LagrangeVariant},
45        types::{Continuity, ReferenceCellType},
46    };
47    use ndmesh::shapes::{unit_cube, unit_square};
48
49    #[test]
50    fn test_function_with_unit_square() {
51        let mesh = unit_square::<f64>(1, 1, ReferenceCellType::Triangle);
52        let family = LagrangeElementFamily::<f64>::new(
53            0,
54            Continuity::Discontinuous,
55            LagrangeVariant::Equispaced,
56        );
57
58        let space = FunctionSpaceImpl::new(&mesh, &family);
59
60        let function = FunctionImpl::zero(&space);
61
62        assert_eq!(function.coefficients.len(), 2);
63    }
64    #[test]
65    fn test_function_with_unit_cube() {
66        let mesh = unit_cube::<f64>(1, 1, 1, ReferenceCellType::Tetrahedron);
67        let family = LagrangeElementFamily::<f64>::new(
68            0,
69            Continuity::Discontinuous,
70            LagrangeVariant::Equispaced,
71        );
72
73        let space = FunctionSpaceImpl::new(&mesh, &family);
74
75        let function = FunctionImpl::zero(&space);
76
77        assert_eq!(function.coefficients.len(), 6);
78    }
79    #[test]
80    #[should_panic(expected = "Incorrect number of coefficients!")]
81    fn test_function_with_incorrect_coefficients() {
82        let mesh = unit_square::<f64>(1, 1, ReferenceCellType::Triangle);
83        let family = LagrangeElementFamily::<f64>::new(
84            0,
85            Continuity::Discontinuous,
86            LagrangeVariant::Equispaced,
87        );
88        let space = FunctionSpaceImpl::new(&mesh, &family);
89        let _function = FunctionImpl::new(&space, vec![0.0; space.process_size() + 1]);
90    }
91}