1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
use core::marker::PhantomData; use fehler::throws; use mexprp::{Context, Expression}; use snafu::ensure; use crate::{ engine::{ helper_equation_traits::{Bounds, EquationOfThreeVariable, EquationOfTwoVariable}, quadrature::GetQuadratureRange, utils, CalculationResult, CalculationStep, }, errors::{self, Error}, }; pub struct ThirdIntegrator<G: GetQuadratureRange, E: EquationOfThreeVariable> { a_equation: Expression<f64>, b_equation: Expression<f64>, h: f64, equation: E, _p: PhantomData<G>, } impl<G: GetQuadratureRange, E: EquationOfThreeVariable> ThirdIntegrator<G, E> { #[throws] pub fn new(a_equation: &str, b_equation: &str, h: f64, equation: E) -> Self { let a_equation = Expression::parse(a_equation)?; let b_equation = Expression::parse(b_equation)?; Self { a_equation, b_equation, h, equation, _p: PhantomData, } } } impl<G: GetQuadratureRange, E: EquationOfThreeVariable> EquationOfTwoVariable for ThirdIntegrator<G, E> { #[throws] fn calculate( &self, x: CalculationStep, bounds_x: Bounds, y: CalculationStep, bounds_y: Bounds, ) -> CalculationResult { let mut context = Context::new(); context.set_var("x", *x); context.set_var("y", *y); let a = utils::calculate_expression_one_value_result(&context, &self.a_equation)?; let b = utils::calculate_expression_one_value_result(&context, &self.b_equation)?; ensure!(a <= b, errors::BeginBoundGreaterThanEndBound { a, b }); let mut result = CalculationResult::new(); let mut range = if let Some(range) = G::get_range_generator(a, b, self.h)? { range } else { return result; }; loop { let step = range.next()?; result += self .equation .calculate(x, bounds_x, y, bounds_y, step, (a, b))?; if step.is_last() { break; } } result } }