use plotpy::{Curve, Plot};
use russell_lab::StrError;
use russell_ode::prelude::*;
fn main() -> Result<(), StrError> {
let (system, x0, y0, mut args) = Samples::robertson();
let x1 = 0.3;
let h_ini = 1e-6;
let rel_tol = 1e-2;
let abs_tol = 1e-6 * rel_tol;
let mut params1 = Params::new(Method::Radau5);
let mut params2 = Params::new(Method::DoPri5);
let mut params3 = Params::new(Method::DoPri5);
params1.step.h_ini = h_ini;
params2.step.h_ini = h_ini;
params3.step.h_ini = h_ini;
params1.set_tolerances(abs_tol, rel_tol, None)?;
params2.set_tolerances(abs_tol, rel_tol, None)?;
let rel_tol = 1e-3;
let abs_tol = 1e-6 * rel_tol;
params3.set_tolerances(abs_tol, rel_tol, None)?;
params2.erk.lund_beta = 0.0;
params3.erk.lund_beta = 0.0;
let mut radau5 = OdeSolver::new(params1, system.clone())?;
let mut dopri5 = OdeSolver::new(params2, system)?;
let sel = 1;
let mut out_radau5 = Output::new();
out_radau5.set_step_recording(&[sel]);
let mut y = y0.clone();
radau5.solve(&mut y, x0, x1, None, &mut args, Some(&mut out_radau5))?;
println!("{}", radau5.stats());
let n_accepted1 = radau5.stats().n_accepted;
let mut out_dopri5a = Output::new();
out_dopri5a.set_step_recording(&[sel]);
let mut y = y0.clone();
dopri5.solve(&mut y, x0, x1, None, &mut args, Some(&mut out_dopri5a))?;
println!("\nTol = 1e-2\n{}", dopri5.stats());
let n_accepted2 = dopri5.stats().n_accepted;
let out2_x = out_dopri5a.step_x().to_vec();
let out2_y = out_dopri5a.step_y(sel).to_vec();
let mut out_dopri5b = Output::new();
out_dopri5b.set_step_recording(&[sel]);
let mut y = y0.clone();
dopri5.update_params(params3)?;
dopri5.solve(&mut y, x0, x1, None, &mut args, Some(&mut out_dopri5b))?;
println!("\nTol = 1e-3\n{}", dopri5.stats());
let n_accepted3 = dopri5.stats().n_accepted;
let mut curve1 = Curve::new();
curve1
.set_label(&format!("Radau5, n_accepted = {}", n_accepted1))
.set_marker_style("o")
.draw(out_radau5.step_x(), out_radau5.step_y(sel));
let mut curve2 = Curve::new();
let mut curve3 = Curve::new();
let mut curve4 = Curve::new();
curve2
.set_label(&format!("DoPri5, Tol = 1e-2, n_accepted = {}", n_accepted2))
.draw(&out2_x, &out2_y);
curve3
.set_label(&format!("DoPri5, Tol = 1e-3, n_accepted = {}", n_accepted3))
.draw(out_dopri5b.step_x(), out_dopri5b.step_y(sel));
curve4.draw(out_dopri5b.step_x(), out_dopri5b.step_h());
let mut plot1 = Plot::new();
plot1
.set_title("Robertson - second element of the solution")
.add(&curve1)
.add(&curve2)
.add(&curve3)
.grid_and_labels("$x$", &format!("$y_{}$", sel))
.legend()
.set_ymin(0.000032)
.set_figure_size_points(600.0, 400.0)
.save("/tmp/russell_ode/robertson_a.svg")?;
let mut plot2 = Plot::new();
plot2
.set_title("Robertson - step sizes - DoPri5 - Tol = 1e-2")
.add(&curve4)
.set_ymin(0.001)
.grid_and_labels("$x$", "$h$")
.set_figure_size_points(600.0, 200.0)
.save("/tmp/russell_ode/robertson_b.svg")
}