sequential_integration/engine/integrators/
third_integrator.rs1use core::marker::PhantomData;
2use fehler::throws;
3
4use super::utils as integrator_utils;
5use crate::{
6 engine::{
7 helper_equation_traits::{EquationOfThreeVariable, EquationOfTwoVariable},
8 quadrature::GetQuadratureRange,
9 Bounds, CalculationResult, CalculationStep,
10 },
11 errors::Error,
12};
13
14pub struct ThirdIntegrator<
15 'a,
16 G: GetQuadratureRange,
17 E: EquationOfThreeVariable,
18 F1: Fn(f64, f64) -> f64,
19 F2: Fn(f64, f64) -> f64,
20> {
21 a_equation: F1,
22 b_equation: F2,
23 h: f64,
24 equation: &'a E,
25 _p: PhantomData<G>,
26}
27
28impl<
29 'a,
30 G: GetQuadratureRange,
31 E: EquationOfThreeVariable,
32 F1: Fn(f64, f64) -> f64,
33 F2: Fn(f64, f64) -> f64,
34 > ThirdIntegrator<'a, G, E, F1, F2>
35{
36 #[throws]
37 pub fn new(a_equation: F1, b_equation: F2, h: f64, equation: &'a E) -> Self {
38 Self {
39 a_equation,
40 b_equation,
41 h,
42 equation,
43 _p: PhantomData,
44 }
45 }
46}
47
48impl<
49 'a,
50 G: GetQuadratureRange,
51 E: EquationOfThreeVariable,
52 F1: Fn(f64, f64) -> f64,
53 F2: Fn(f64, f64) -> f64,
54 > EquationOfTwoVariable for ThirdIntegrator<'a, G, E, F1, F2>
55{
56 #[throws]
57 fn calculate(
58 &self,
59 x: CalculationStep,
60 bounds_x: Bounds,
61 y: CalculationStep,
62 bounds_y: Bounds,
63 ) -> CalculationResult {
64 let a = (self.a_equation)(*x, *y);
65 let b = (self.b_equation)(*x, *y);
66 let borders_config = integrator_utils::BoundsConfigurator::configurate(a, b)?;
67
68 let mut result = CalculationResult::new();
69 let mut range = if let Some(range) = G::get_range_generator(borders_config.bounds, self.h)?
70 {
71 range
72 } else {
73 return result;
74 };
75
76 loop {
77 let step = range.next()?;
78 result +=
79 self.equation
80 .calculate(x, bounds_x, y, bounds_y, step, borders_config.bounds)?
81 * borders_config.direction_coeff;
82
83 if step.is_last() {
84 break;
85 }
86 }
87
88 result
89 }
90}