sidereon_core/astro/propagator/
api.rs1use crate::astro::error::PropagationError;
2use crate::astro::frames::orientation::EarthOrientationProvider;
3use crate::constants::SECONDS_PER_HOUR;
4use std::sync::Arc;
5
6#[derive(Clone, Default)]
13pub struct PropagationContext {
14 body_fixed_frame_provider: Option<Arc<dyn EarthOrientationProvider>>,
15}
16
17impl core::fmt::Debug for PropagationContext {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 f.debug_struct("PropagationContext")
20 .field(
21 "body_fixed_frame_provider",
22 &self.body_fixed_frame_provider.is_some(),
23 )
24 .finish()
25 }
26}
27
28impl PropagationContext {
29 pub fn new() -> Self {
31 Self::default()
32 }
33
34 pub fn with_body_fixed_frame_provider(
36 mut self,
37 provider: Arc<dyn EarthOrientationProvider>,
38 ) -> Self {
39 self.body_fixed_frame_provider = Some(provider);
40 self
41 }
42
43 pub fn body_fixed_frame_provider(&self) -> Option<&dyn EarthOrientationProvider> {
45 self.body_fixed_frame_provider
46 .as_deref()
47 .map(|provider| provider as &dyn EarthOrientationProvider)
48 }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq)]
52pub struct IntegratorOptions {
53 pub abs_tol: f64,
54 pub rel_tol: f64,
55 pub min_step: f64,
56 pub max_step: f64,
57 pub initial_step: f64,
58 pub max_steps: u32,
59 pub dense_output: bool,
60}
61
62impl Default for IntegratorOptions {
63 fn default() -> Self {
64 Self {
65 abs_tol: 1e-9,
66 rel_tol: 1e-12,
67 min_step: 1e-6,
68 max_step: SECONDS_PER_HOUR,
69 initial_step: 60.0,
70 max_steps: 1_000_000,
71 dense_output: false,
72 }
73 }
74}
75
76pub(crate) fn validate_integrator_options(
77 opts: &IntegratorOptions,
78) -> Result<(), PropagationError> {
79 validate_step_options(opts)
80}
81
82pub(crate) fn validate_adaptive_integrator_options(
83 opts: &IntegratorOptions,
84) -> Result<(), PropagationError> {
85 validate_step_options(opts)?;
86 crate::validate::finite_positive(opts.abs_tol, "abs_tol").map_err(map_field_error)?;
87 crate::validate::finite_positive(opts.rel_tol, "rel_tol").map_err(map_field_error)?;
88 Ok(())
89}
90
91pub(crate) fn validate_integrator_epoch(
92 value: f64,
93 field: &'static str,
94) -> Result<(), PropagationError> {
95 crate::validate::finite(value, field)
96 .map(|_| ())
97 .map_err(map_field_error)
98}
99
100fn validate_step_options(opts: &IntegratorOptions) -> Result<(), PropagationError> {
101 crate::validate::positive_step(opts.initial_step, "initial_step").map_err(map_field_error)?;
102 crate::validate::positive_step(opts.min_step, "min_step").map_err(map_field_error)?;
103 crate::validate::positive_step(opts.max_step, "max_step").map_err(map_field_error)?;
104 Ok(())
105}
106
107fn map_field_error(error: crate::validate::FieldError) -> PropagationError {
108 PropagationError::InvalidInput(format!("{} {}", error.field(), error.reason()))
109}