1#![allow(clippy::needless_range_loop)]
4
5mod boundary;
6mod convolution;
7mod element;
8mod node;
9mod weights;
10
11pub use boundary::{
12 BoundaryClass, BoundaryConds, BoundaryKind, DirichletParams, EmptyConditions, RadiativeParams,
13 ScalarConditions, SystemBoundaryConds, is_boundary_compatible,
14};
15pub use convolution::{Convolution, Gradient, Hessian};
16pub use element::Element;
17pub use node::{
18 NodeCartesianIter, NodePlaneIter, NodeSpace, NodeWindow, node_from_vertex, vertex_from_node,
19};
20pub use weights::{Derivative, Dissipation, Interpolation, SecondDerivative, Unimplemented, Value};
21
22use crate::IRef;
23
24#[derive(Debug, Clone, Copy)]
29pub enum Border {
30 Negative(usize),
31 Positive(usize),
32}
33
34impl Border {
35 pub fn side(self) -> bool {
36 match self {
37 Border::Negative(_) => false,
38 Border::Positive(_) => true,
39 }
40 }
41}
42
43pub trait Kernel {
48 fn border_width(&self) -> usize;
49 fn interior(&self) -> &[f64];
50 fn free(&self, border: Border) -> &[f64];
51 fn scale(&self, spacing: f64) -> f64;
52}
53
54impl<'a, T: Kernel> Kernel for IRef<'a, T> {
55 fn border_width(&self) -> usize {
56 self.0.border_width()
57 }
58
59 fn interior(&self) -> &[f64] {
60 self.0.interior()
61 }
62
63 fn free(&self, border: Border) -> &[f64] {
64 self.0.free(border)
65 }
66
67 fn scale(&self, spacing: f64) -> f64 {
68 self.0.scale(spacing)
69 }
70}
71
72pub trait Interpolant {
73 fn border_width(&self) -> usize;
74 fn interior(&self) -> &[f64];
75 fn free(&self, border: Border) -> &[f64];
76 fn scale(&self) -> f64;
77}
78
79impl<'a, T: Interpolant> Interpolant for IRef<'a, T> {
80 fn border_width(&self) -> usize {
81 self.0.border_width()
82 }
83
84 fn interior(&self) -> &[f64] {
85 self.0.interior()
86 }
87
88 fn free(&self, border: Border) -> &[f64] {
89 self.0.free(border)
90 }
91
92 fn scale(&self) -> f64 {
93 self.0.scale()
94 }
95}