Began adding the rosenbrock integrator
This commit is contained in:
@@ -1,43 +1,31 @@
|
||||
use super::ode::SystemTrait;
|
||||
use num_traits::Float;
|
||||
|
||||
pub trait Controller<T,F, const D: usize>
|
||||
where
|
||||
f64: From<T>,
|
||||
F: SystemTrait<T,D>,
|
||||
T: Copy + From<f64>,
|
||||
{
|
||||
fn determine_step(&mut self, h: T, err: T) -> (bool, T);
|
||||
pub trait Controller<const D: usize> {
|
||||
fn determine_step(&mut self, h: f64, err: f64) -> (bool, f64);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PIController<T> where f64: From<T> {
|
||||
pub alpha: T,
|
||||
pub beta: T,
|
||||
pub factor_c1: T,
|
||||
pub factor_c2: T,
|
||||
pub factor_old: T,
|
||||
pub h_max: T,
|
||||
pub safety_factor: T,
|
||||
pub old_h: T,
|
||||
pub struct PIController {
|
||||
pub alpha: f64,
|
||||
pub beta: f64,
|
||||
pub factor_c1: f64,
|
||||
pub factor_c2: f64,
|
||||
pub factor_old: f64,
|
||||
pub h_max: f64,
|
||||
pub safety_factor: f64,
|
||||
pub old_h: f64,
|
||||
}
|
||||
|
||||
impl<T,F,const D:usize> Controller<T,F,D> for PIController<T>
|
||||
where
|
||||
f64: From<T>,
|
||||
F: SystemTrait<T,D>,
|
||||
T: Copy + From<f64> + Float,
|
||||
{
|
||||
impl<const D:usize> Controller<D> for PIController {
|
||||
/// Determines if the previously run step size and error were valid or not. Either way, it also
|
||||
/// returns what the next step size should be
|
||||
fn determine_step(&mut self, h: T, err: T) -> (bool, T) {
|
||||
fn determine_step(&mut self, h: f64, err: f64) -> (bool, f64) {
|
||||
let factor_11 = err.powf(self.alpha);
|
||||
let factor = self.factor_c2.max(self.factor_c1.min(factor_11 * self.factor_old.powf(-self.beta) / self.safety_factor));
|
||||
let mut h_new = h / factor;
|
||||
if err <= 1.0.into() {
|
||||
println!("{:?}", f64::from(h));
|
||||
// let mut h_new = 0.9 * h * err.powf(-1.0 / 5.0);
|
||||
println!("err: {}\th_new: {}", err, h_new);
|
||||
if err <= 1.0 {
|
||||
// Accept the stepsize
|
||||
self.factor_old = err.max(1.0e-4.into());
|
||||
self.factor_old = err.max(1.0e-4);
|
||||
if h_new.abs() > self.h_max {
|
||||
// If the step is too big
|
||||
h_new = self.h_max.copysign(h_new);
|
||||
@@ -52,18 +40,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PIController<T>
|
||||
where
|
||||
f64: From<T>,
|
||||
T: Copy + From<f64> + Float,
|
||||
{
|
||||
pub fn new(alpha:T, beta:T, max_factor: T, min_factor: T, h_max: T, safety_factor: T, initial_h: T) -> Self {
|
||||
impl PIController {
|
||||
pub fn new(alpha:f64, beta:f64, max_factor: f64, min_factor: f64, h_max: f64, safety_factor: f64, initial_h: f64) -> Self {
|
||||
Self {
|
||||
alpha: alpha,
|
||||
beta: beta,
|
||||
factor_c1: <T as From<T>>::from(1.0.into()) / min_factor,
|
||||
factor_c2: <T as From<T>>::from(1.0.into()) / max_factor,
|
||||
factor_old: 1.0e-4.into(),
|
||||
factor_c1: 1.0 / min_factor,
|
||||
factor_c2: 1.0 / max_factor,
|
||||
factor_old: 1.0e-4,
|
||||
h_max: h_max.abs(),
|
||||
safety_factor: safety_factor,
|
||||
old_h: initial_h,
|
||||
@@ -87,6 +71,5 @@ mod tests {
|
||||
assert!(controller.h_max == 10.0);
|
||||
assert!(controller.safety_factor == 0.9);
|
||||
assert!(controller.old_h == 1e-4);
|
||||
// assert!(controller.determine_step(0.1, 0.1) == (true, 0.01));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user