altrios_core/train/resistance/method/
point.rs1use super::super::kind::*;
2use super::super::ResMethod;
3use super::*;
4use crate::imports::*;
5use crate::track::{LinkPoint, PathResCoeff};
6
7#[serde_api]
8#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
9#[cfg_attr(feature = "pyo3", pyclass(module = "altrios", subclass, eq))]
10pub struct Point {
11 bearing: bearing::Basic,
12 rolling: rolling::Basic,
13 davis_b: davis_b::Basic,
14 aerodynamic: aerodynamic::Basic,
15 grade: path_res::Point,
16 curve: path_res::Point,
17}
18
19#[pyo3_api]
20impl Point {}
21
22impl Init for Point {}
23impl SerdeAPI for Point {}
24
25impl ResMethod for Point {
26 fn update_res(
27 &mut self,
28 state: &mut TrainState,
29 path_tpc: &PathTpc,
30 dir: &Dir,
31 ) -> anyhow::Result<()> {
32 state.offset_back.update(
33 *state.offset.get_fresh(|| format_dbg!())?
34 - *state.length.get_fresh(|| format_dbg!())?,
35 || format_dbg!(),
36 )?;
37 state.weight_static.update(
38 state
39 .mass()
40 .with_context(|| format_dbg!())?
41 .with_context(|| "{}\nExpected `Some`.")?
42 * uc::ACC_GRAV,
43 || format_dbg!(),
44 )?;
45 state
46 .res_bearing
47 .update(self.bearing.calc_res(), || format_dbg!())?;
48 state
49 .res_rolling
50 .update(self.rolling.calc_res(state)?, || format_dbg!())?;
51 state
52 .res_davis_b
53 .update(self.davis_b.calc_res(state)?, || format_dbg!())?;
54 state
55 .res_aero
56 .update(self.aerodynamic.calc_res(state)?, || format_dbg!())?;
57 state.res_grade.update(
58 self.grade.calc_res(path_tpc.grades(), state, dir)?,
59 || format_dbg!(),
60 )?;
61 state.res_curve.update(
62 self.curve.calc_res(path_tpc.curves(), state, dir)?,
63 || format_dbg!(),
64 )?;
65 state.grade_front.update(
66 self.grade.res_coeff_front(path_tpc.grades()),
67 || format_dbg!(),
68 )?;
69 state.elev_front.update(
70 self.grade.res_net_front(path_tpc.grades(), state)?,
71 || format_dbg!(),
72 )?;
73
74 Ok(())
75 }
76
77 fn fix_cache(&mut self, link_point_del: &LinkPoint) {
78 self.grade.fix_cache(link_point_del.grade_count);
79 self.curve.fix_cache(link_point_del.curve_count);
80 }
81}
82
83impl Valid for Point {
84 fn valid() -> Self {
85 Self {
86 bearing: bearing::Basic::new(40.0 * 100.0 * uc::LBF),
87 rolling: rolling::Basic::new(1.5 * uc::LB / uc::TON),
88 davis_b: davis_b::Basic::new(0.03 / uc::MPH * uc::LB / uc::TON),
89 aerodynamic: aerodynamic::Basic::new(
90 5.0 * 100.0 * uc::FT2 / 10000.0 / 1.225 * uc::MPS / uc::MPH * uc::MPS / uc::MPH
91 * uc::LBF
92 / uc::N
93 * 100.0,
94 ),
95 grade: path_res::Point::new(&Vec::<PathResCoeff>::valid(), &TrainState::valid())
96 .unwrap(),
97 curve: path_res::Point::new(&Vec::<PathResCoeff>::valid(), &TrainState::valid())
98 .unwrap(),
99 }
100 }
101}