Explicit Methods
Therewith an ordinary differential equation can be solved, it is necessary, that it is writable in explicit form:
Given $f$, a function of $x$, $y$, and derivatives of $y$. Then an equation of the form
$$ f ( x , y , y′ , \dots, y^{ (n − 1) } ) = y^{(n)} $$
is called an explicit ordinary differential equation of order $n$.
$$ \begin{pmatrix} y_{1} \\ y_{2} \\ y_{3} \\ \end{pmatrix}^{’} = \begin{pmatrix} (I_{2} - I_{3})/I_{1} y_{2} y_{3} \\ (I_{3} - I_{1})/I_{2} y_{3} y_{1} \\ (I_{1} - I_{2})/I_{3} y_{1} y_{2} + f(x) \\ \end{pmatrix} $$ $$ f(x) = \begin{cases} 0.25 sin^2(x) & if 3\pi \leq x \leq 4 \pi \\ 0 & otherwise \\ \end{cases} $$
We choose the constants and initial condition as:
$$ I_{1} = 0.5, I_{2} = 2, I_{3} = 3, i_{1}(0) = 1.0, i_{2}(0) = 0.0, i_{3}(0) = 0.9 $$
and solve the initial value problem in the interval $t \in [0, 20.0]$
pub struct Euler<T>
{
i1: T,
i2: T,
i3: T,
time_span: (T, T),
init_cond: Vector<T>
}
impl<T> Default for Euler<T>
where T: Real
{
fn default() -> Euler<T> {
Euler
{
i1: T::from_f64(0.5),
i2: T::from_f64(2.0),
i3: T::from_f64(3.0),
time_span: (T::from_f64(0.0), T::from_f64(20.0)),
init_cond: vector![T::from_f64(1.0); T::from_f64(0.0); T::from_f64(0.9)]
}
}
}
impl<T> ExplicitODE<T> for Euler<T>
where T: Real
{
fn func(self: &Self, x: &T, y: &Vector<T>) -> Vector<T> {
let y_1s: T = ((self.i2 - self.i3) / self.i1) * (*y.get(1) * *y.get(2));
let y_2s: T = ((self.i3 - self.i1) / self.i2) * (*y.get(2) * *y.get(0));
let f: T;
if *x >= T::from_f64(3.0) * T::pi() && *x <= T::from_f64(4.0) * T::pi()
{
f = T::from_f64(0.25) * x.sin() * x.sin();
}
else
{
f = T::zero();
}
let y_3s: T = ((self.i1 - self.i2) / self.i3) * (*y.get(0) * *y.get(1)) + f;
return vector![y_1s; y_2s; y_3s];
}
fn time_span(self: &Self) -> (T, T) {
return self.time_span;
}
fn init_cond(self: &Self) -> Vector<T> {
return self.init_cond.clone();
}
}
Now we solve this ODE with the Dormand-Prince method:
|
|
The following picture illustrates the solution for this ODE: