use scirs2_core::ndarray::{array, ArrayView1};
use scirs2_integrate::bvp::solve_bvp;
use std::f64::consts::PI;
#[allow(dead_code)]
fn main() {
println!("Boundary Value Problem Solver Example");
println!("--------------------------------------");
println!("Example 1: Harmonic Oscillator");
let fun = |_x: f64, y: ArrayView1<f64>| array![y[1], -y[0]];
let bc = |ya: ArrayView1<f64>, yb: ArrayView1<f64>| {
array![ya[0], yb[0]]
};
let n_points = 10;
let mut x = Vec::with_capacity(n_points);
for i in 0..n_points {
x.push(PI * (i as f64) / (n_points as f64 - 1.0));
}
let mut y_init = Vec::with_capacity(n_points);
for i in 0..n_points {
let t = i as f64 / (n_points as f64 - 1.0);
let y_val = (PI * t).sin() * 0.1; y_init.push(array![y_val, y_val * PI * (PI * t).cos()]); }
match solve_bvp(fun, bc, Some(x.clone()), y_init, None) {
Ok(result) => {
let idx_mid = result.x.len() / 2;
let scale = if result.y[idx_mid][0].abs() > 1e-10 {
result.y[idx_mid][0] / (PI / 2.0).sin()
} else {
1.0
};
println!("Solution for harmonic oscillator (should be proportional to sin(x)):");
println!(
"{:>10} {:>15} {:>15} {:>15}",
"x", "y_numerical", "y_exact", "error"
);
println!("{:->10} {:->15} {:->15} {:->15}", "", "", "", "");
for i in 0..result.x.len() {
let x_val = result.x[i];
let y_val = result.y[i][0];
let sin_val = scale * x_val.sin();
let error = (y_val - sin_val).abs();
println!("{x_val:10.6} {y_val:15.6} {sin_val:15.6} {error:15.6e}");
}
println!();
println!("Number of iterations: {}", result.n_iter);
println!("Residual norm: {:.6e}", result.residual_norm);
println!("Successful convergence: {}", result.success);
println!("\nExample 2: Second Order ODE with Non-zero Boundary Conditions");
let fun2 = |_x: f64, y: ArrayView1<f64>| array![y[1], -y[0]];
let bc2 = |ya: ArrayView1<f64>, yb: ArrayView1<f64>| {
array![ya[0] - 1.0, yb[0] + 1.0]
};
let mut y_init2 = Vec::with_capacity(n_points);
for i in 0..n_points {
let t = i as f64 / (n_points as f64 - 1.0);
let x_val = PI * t;
let y_val = x_val.cos(); y_init2.push(array![y_val, -x_val.sin()]); }
match solve_bvp(fun2, bc2, Some(x), y_init2, None) {
Ok(result2) => {
println!("Solution for y'' = -y with y(0) = 1, y(π) = -1:");
println!(
"{:>10} {:>15} {:>15} {:>15}",
"x", "y_numerical", "y_exact", "error"
);
println!("{:->10} {:->15} {:->15} {:->15}", "", "", "", "");
for i in 0..result2.x.len() {
let x_val = result2.x[i];
let y_val = result2.y[i][0];
let cos_val = x_val.cos();
let error = (y_val - cos_val).abs();
println!("{x_val:10.6} {y_val:15.6} {cos_val:15.6} {error:15.6e}");
}
println!();
println!("Number of iterations: {}", result2.n_iter);
println!("Residual norm: {:.6e}", result2.residual_norm);
println!("Successful convergence: {}", result2.success);
}
Err(e) => {
println!("Error solving second BVP: {e}");
}
}
}
Err(e) => {
println!("Error solving first BVP: {e}");
}
}
}