anl/
implicit_function_gradient.rs

1use super::implicit_base::ImplicitModuleBase;
2use super::{ImplicitModule, ScalarParameter};
3
4use std::rc::Rc;
5use std::cell::RefCell;
6
7pub enum FunctionGradientAxis {
8    X,
9    Y,
10    Z,
11    W,
12    U,
13    V,
14}
15
16pub struct ImplicitFunctionGradient {
17    base: ImplicitModuleBase,
18    axis: FunctionGradientAxis,
19    source: ScalarParameter,
20    spacing: f64,
21}
22
23impl ImplicitFunctionGradient {
24    pub fn with_axis(a: FunctionGradientAxis) -> ImplicitFunctionGradient {
25        ImplicitFunctionGradient {
26            base: Default::default(),
27            source: ScalarParameter::Value(0.0),
28            axis: a,
29            spacing: 0.0,
30        }
31    }
32
33    pub fn set_axis(&mut self, a: FunctionGradientAxis) {
34        self.axis = a;
35    }
36    pub fn set_spacing(&mut self, s: f64) {
37        self.spacing = s;
38    }
39
40    pub fn set_source_module(&mut self, m: Rc<RefCell<ImplicitModule>>) {
41        self.source = ScalarParameter::Source(m);
42    }
43    pub fn set_source_value(&mut self, v: f64) {
44        self.source = ScalarParameter::Value(v);
45    }
46}
47
48impl ImplicitModule for ImplicitFunctionGradient {
49    fn get_2d(&mut self, x: f64, y: f64) -> f64 {
50        match self.axis {
51            FunctionGradientAxis::X => (self.source.get_2d(x - self.spacing, y) - self.source.get_2d(x + self.spacing, y)) / self.spacing,
52            FunctionGradientAxis::Y => (self.source.get_2d(x, y - self.spacing) - self.source.get_2d(x, y + self.spacing)) / self.spacing,
53            FunctionGradientAxis::Z => 0.0,
54            FunctionGradientAxis::W => 0.0,
55            FunctionGradientAxis::U => 0.0,
56            FunctionGradientAxis::V => 0.0,
57        }
58    }
59    fn get_3d(&mut self, x: f64, y: f64, z: f64) -> f64 {
60        match self.axis {
61            FunctionGradientAxis::X => (self.source.get_3d(x - self.spacing, y, z) - self.source.get_3d(x + self.spacing, y, z)) / self.spacing,
62            FunctionGradientAxis::Y => (self.source.get_3d(x, y - self.spacing, z) - self.source.get_3d(x, y + self.spacing, z)) / self.spacing,
63            FunctionGradientAxis::Z => (self.source.get_3d(x, y, z - self.spacing) - self.source.get_3d(x, y, z + self.spacing)) / self.spacing,
64            FunctionGradientAxis::W => 0.0,
65            FunctionGradientAxis::U => 0.0,
66            FunctionGradientAxis::V => 0.0,
67        }
68    }
69    fn get_4d(&mut self, x: f64, y: f64, z: f64, w: f64) -> f64 {
70        match self.axis {
71            FunctionGradientAxis::X => (self.source.get_4d(x - self.spacing, y, z, w) - self.source.get_4d(x + self.spacing, y, z, w)) / self.spacing,
72            FunctionGradientAxis::Y => (self.source.get_4d(x, y - self.spacing, z, w) - self.source.get_4d(x, y + self.spacing, z, w)) / self.spacing,
73            FunctionGradientAxis::Z => (self.source.get_4d(x, y, z - self.spacing, w) - self.source.get_4d(x, y, z + self.spacing, w)) / self.spacing,
74            FunctionGradientAxis::W => (self.source.get_4d(x, y, z, w - self.spacing) - self.source.get_4d(x, y, z, w + self.spacing)) / self.spacing,
75            FunctionGradientAxis::U => 0.0,
76            FunctionGradientAxis::V => 0.0,
77        }
78    }
79    fn get_6d(&mut self, x: f64, y: f64, z: f64, w: f64, u: f64, v: f64) -> f64 {
80        match self.axis {
81            FunctionGradientAxis::X => (self.source.get_6d(x - self.spacing, y, z, w, u, v) - self.source.get_6d(x + self.spacing, y, z, w, u, v)) / self.spacing,
82            FunctionGradientAxis::Y => (self.source.get_6d(x, y - self.spacing, z, w, u, v) - self.source.get_6d(x, y + self.spacing, z, w, u, v)) / self.spacing,
83            FunctionGradientAxis::Z => (self.source.get_6d(x, y, z - self.spacing, w, u, v) - self.source.get_6d(x, y, z + self.spacing, w, u, v)) / self.spacing,
84            FunctionGradientAxis::W => (self.source.get_6d(x, y, z, w - self.spacing, u, v) - self.source.get_6d(x, y, z, w + self.spacing, u, v)) / self.spacing,
85            FunctionGradientAxis::U => (self.source.get_6d(x, y, z, w, u - self.spacing, v) - self.source.get_6d(x, y, z, w, u + self.spacing, v)) / self.spacing,
86            FunctionGradientAxis::V => (self.source.get_6d(x, y, z, w, u, v - self.spacing) - self.source.get_6d(x, y, z, w, u, v + self.spacing)) / self.spacing,
87        }
88    }
89
90    fn spacing(&self) -> f64 {
91        self.base.spacing
92    }
93    fn set_deriv_spacing(&mut self, s: f64) {
94        self.base.spacing = s;
95    }
96}