Skip to main content

sidereon_core/astro/propagator/
controller.rs

1pub struct PIController {
2    pub safety_factor: f64,
3    pub min_scale: f64,
4    pub max_scale: f64,
5    pub order: f64,
6}
7
8impl Default for PIController {
9    fn default() -> Self {
10        Self {
11            safety_factor: 0.9,
12            min_scale: 0.33,
13            max_scale: 6.0,
14            order: 8.0,
15        }
16    }
17}
18
19impl PIController {
20    pub fn next_step(&self, current_h: f64, error: f64) -> f64 {
21        if error <= 1e-15 {
22            return current_h * self.max_scale;
23        }
24
25        // Classic Hairer/Wanner controller
26        let factor = self.safety_factor * (1.0 / error).powf(1.0 / (self.order + 1.0));
27        current_h * factor.clamp(self.min_scale, self.max_scale)
28    }
29}