Skip to content

Commit f59f8b2

Browse files
Update tests for new integrator method enum
1 parent 859cca5 commit f59f8b2

File tree

20 files changed

+289
-194
lines changed

20 files changed

+289
-194
lines changed

src/mc/montecarlo.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ where
8989

9090
/// Generate states and propagate each independently until a specific event is found `trigger` times.
9191
#[allow(clippy::needless_lifetimes)]
92-
pub fn run_until_nth_event<'a, D, E, F>(
92+
pub fn run_until_nth_event<D, E, F>(
9393
self,
94-
prop: Propagator<'a, D, E>,
94+
prop: Propagator<D, E>,
9595
almanac: Arc<Almanac>,
9696
max_duration: Duration,
9797
event: &F,
@@ -113,9 +113,9 @@ where
113113
/// Generate states and propagate each independently until a specific event is found `trigger` times.
114114
#[must_use = "Monte Carlo result must be used"]
115115
#[allow(clippy::needless_lifetimes)]
116-
pub fn resume_run_until_nth_event<'a, D, E, F>(
116+
pub fn resume_run_until_nth_event<D, E, F>(
117117
&self,
118-
prop: Propagator<'a, D, E>,
118+
prop: Propagator<D, E>,
119119
almanac: Arc<Almanac>,
120120
skip: usize,
121121
max_duration: Duration,
@@ -188,9 +188,9 @@ where
188188
/// Generate states and propagate each independently until a specific event is found `trigger` times.
189189
#[must_use = "Monte Carlo result must be used"]
190190
#[allow(clippy::needless_lifetimes)]
191-
pub fn run_until_epoch<'a, D, E>(
191+
pub fn run_until_epoch<D, E>(
192192
self,
193-
prop: Propagator<'a, D, E>,
193+
prop: Propagator<D, E>,
194194
almanac: Arc<Almanac>,
195195
end_epoch: Epoch,
196196
num_runs: usize,
@@ -209,9 +209,9 @@ where
209209
/// Resumes a Monte Carlo run by skipping the first `skip` items, generating states only after that, and propagate each independently until the specified epoch.
210210
#[must_use = "Monte Carlo result must be used"]
211211
#[allow(clippy::needless_lifetimes)]
212-
pub fn resume_run_until_epoch<'a, D, E>(
212+
pub fn resume_run_until_epoch<D, E>(
213213
&self,
214-
prop: Propagator<'a, D, E>,
214+
prop: Propagator<D, E>,
215215
almanac: Arc<Almanac>,
216216
skip: usize,
217217
end_epoch: Epoch,

src/md/opti/multipleshooting/altitude_heuristic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl<'a, E: ErrorCtrl> MultipleShooting<'a, E, Node, 3, 3> {
4242
node_count: usize,
4343
angular_velocity_deg_s: f64,
4444
body_frame: Frame,
45-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
45+
prop: &'a Propagator<SpacecraftDynamics, E>,
4646
almanac: Arc<Almanac>,
4747
) -> Result<Self, MultipleShootingError> {
4848
if node_count < 3 {

src/md/opti/multipleshooting/equidistant_heuristic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl<'a, E: ErrorCtrl> MultipleShooting<'a, E, Node, 3, 3> {
3333
x0: Spacecraft,
3434
xf: Orbit,
3535
node_count: usize,
36-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
36+
prop: &'a Propagator<SpacecraftDynamics, E>,
3737
) -> Result<Self, TargetingError> {
3838
if node_count < 3 {
3939
error!("At least three nodes are needed for a multiple shooting optimization");

src/md/opti/multipleshooting/multishoot.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub struct MultipleShooting<
4747
const OT: usize,
4848
> {
4949
/// The propagator setup (kind, stages, etc.)
50-
pub prop: &'a Propagator<'a, SpacecraftDynamics, E>,
50+
pub prop: &'a Propagator<SpacecraftDynamics, E>,
5151
/// List of nodes of the optimal trajectory
5252
pub targets: Vec<T>,
5353
/// Starting point, must be a spacecraft equipped with a thruster
@@ -357,9 +357,9 @@ impl<T: MultishootNode<O>, const O: usize> fmt::Display for MultipleShootingSolu
357357
impl<T: MultishootNode<O>, const O: usize> MultipleShootingSolution<T, O> {
358358
/// Allows building the trajectories between different nodes
359359
/// This will rebuild the targeters and apply the solutions sequentially
360-
pub fn build_trajectories<'a, E: ErrorCtrl>(
360+
pub fn build_trajectories<E: ErrorCtrl>(
361361
&self,
362-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
362+
prop: &Propagator<SpacecraftDynamics, E>,
363363
almanac: Arc<Almanac>,
364364
) -> Result<Vec<ScTraj>, MultipleShootingError> {
365365
let mut trajz = Vec::with_capacity(self.nodes.len());

src/md/opti/optimizer.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use super::solution::TargeterSolution;
3535
#[derive(Clone)]
3636
pub struct Optimizer<'a, E: ErrorCtrl, const V: usize, const O: usize> {
3737
/// The propagator setup (kind, stages, etc.)
38-
pub prop: &'a Propagator<'a, SpacecraftDynamics, E>,
38+
pub prop: &'a Propagator<SpacecraftDynamics, E>,
3939
/// The list of objectives of this targeter
4040
pub objectives: [Objective; O],
4141
/// An optional frame (and Cosm) to compute the objectives in.
@@ -68,7 +68,7 @@ impl<'a, E: ErrorCtrl, const V: usize, const O: usize> fmt::Display for Optimize
6868
impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 3, O> {
6969
/// Create a new Targeter which will apply an impulsive delta-v correction.
7070
pub fn delta_v(
71-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
71+
prop: &'a Propagator<SpacecraftDynamics, E>,
7272
objectives: [Objective; O],
7373
) -> Self {
7474
Self {
@@ -87,7 +87,7 @@ impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 3, O> {
8787

8888
/// Create a new Targeter which will MOVE the position of the spacecraft at the correction epoch
8989
pub fn delta_r(
90-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
90+
prop: &'a Propagator<SpacecraftDynamics, E>,
9191
objectives: [Objective; O],
9292
) -> Self {
9393
Self {
@@ -105,10 +105,7 @@ impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 3, O> {
105105
}
106106

107107
/// Create a new Targeter which will apply an impulsive delta-v correction on all components of the VNC frame. By default, max step is 0.5 km/s.
108-
pub fn vnc(
109-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
110-
objectives: [Objective; O],
111-
) -> Self {
108+
pub fn vnc(prop: &'a Propagator<SpacecraftDynamics, E>, objectives: [Objective; O]) -> Self {
112109
Self {
113110
prop,
114111
objectives,
@@ -127,7 +124,7 @@ impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 3, O> {
127124
impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 4, O> {
128125
/// Create a new Targeter which will apply a continuous thrust for the whole duration of the segment
129126
pub fn thrust_dir(
130-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
127+
prop: &'a Propagator<SpacecraftDynamics, E>,
131128
objectives: [Objective; O],
132129
) -> Self {
133130
Self {
@@ -149,7 +146,7 @@ impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 4, O> {
149146
impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 7, O> {
150147
/// Create a new Targeter which will apply a continuous thrust for the whole duration of the segment
151148
pub fn thrust_dir_rate(
152-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
149+
prop: &'a Propagator<SpacecraftDynamics, E>,
153150
objectives: [Objective; O],
154151
) -> Self {
155152
Self {
@@ -174,7 +171,7 @@ impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 7, O> {
174171
impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 10, O> {
175172
/// Create a new Targeter which will apply a continuous thrust for the whole duration of the segment
176173
pub fn thrust_profile(
177-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
174+
prop: &'a Propagator<SpacecraftDynamics, E>,
178175
objectives: [Objective; O],
179176
) -> Self {
180177
Self {
@@ -202,7 +199,7 @@ impl<'a, E: ErrorCtrl, const O: usize> Optimizer<'a, E, 10, O> {
202199
impl<'a, E: ErrorCtrl, const V: usize, const O: usize> Optimizer<'a, E, V, O> {
203200
/// Create a new Targeter which will apply an impulsive delta-v correction.
204201
pub fn new(
205-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
202+
prop: &'a Propagator<SpacecraftDynamics, E>,
206203
variables: [Variable; V],
207204
objectives: [Objective; O],
208205
) -> Self {
@@ -218,7 +215,7 @@ impl<'a, E: ErrorCtrl, const V: usize, const O: usize> Optimizer<'a, E, V, O> {
218215

219216
/// Create a new Targeter which will apply an impulsive delta-v correction.
220217
pub fn in_frame(
221-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
218+
prop: &'a Propagator<SpacecraftDynamics, E>,
222219
variables: [Variable; V],
223220
objectives: [Objective; O],
224221
objective_frame: Frame,
@@ -235,7 +232,7 @@ impl<'a, E: ErrorCtrl, const V: usize, const O: usize> Optimizer<'a, E, V, O> {
235232

236233
/// Create a new Targeter which will apply an impulsive delta-v correction on the specified components of the VNC frame.
237234
pub fn vnc_with_components(
238-
prop: &'a Propagator<'a, SpacecraftDynamics, E>,
235+
prop: &'a Propagator<SpacecraftDynamics, E>,
239236
variables: [Variable; V],
240237
objectives: [Objective; O],
241238
) -> Self {

src/propagators/instance.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ where
4848
/// The state of this propagator instance
4949
pub state: D::StateType,
5050
/// The propagator setup (kind, stages, etc.)
51-
pub prop: &'a Propagator<'a, D, E>,
51+
pub prop: &'a Propagator<D, E>,
5252
/// Stores the details of the previous integration step
5353
pub details: IntegrationDetails,
5454
/// Should progress reports be logged
@@ -342,14 +342,14 @@ where
342342
.context(DynamicsSnafu)?;
343343
self.k[0] = ki;
344344
let mut a_idx: usize = 0;
345-
for i in 0..(self.prop.stages - 1) {
345+
for i in 0..(self.prop.method.stages() - 1) {
346346
// Let's compute the c_i by summing the relevant items from the list of coefficients.
347347
// \sum_{j=1}^{i-1} a_ij ∀ i ∈ [2, s]
348348
let mut ci: f64 = 0.0;
349349
// The wi stores the a_{s1} * k_1 + a_{s2} * k_2 + ... + a_{s, s-1} * k_{s-1} +
350350
let mut wi = OVector::<f64, <D::StateType as State>::VecLength>::from_element(0.0);
351351
for kj in &self.k[0..i + 1] {
352-
let a_ij = self.prop.a_coeffs[a_idx];
352+
let a_ij = self.prop.method.a_coeffs()[a_idx];
353353
ci += a_ij;
354354
wi += a_ij * kj;
355355
a_idx += 1;
@@ -374,9 +374,9 @@ where
374374
let mut error_est =
375375
OVector::<f64, <D::StateType as State>::VecLength>::from_element(0.0);
376376
for (i, ki) in self.k.iter().enumerate() {
377-
let b_i = self.prop.b_coeffs[i];
377+
let b_i = self.prop.method.b_coeffs()[i];
378378
if !self.fixed_step {
379-
let b_i_star = self.prop.b_coeffs[i + self.prop.stages];
379+
let b_i_star = self.prop.method.b_coeffs()[i + self.prop.method.stages()];
380380
error_est += step_size * (b_i - b_i_star) * ki;
381381
}
382382
next_state += step_size * b_i * ki;
@@ -407,7 +407,7 @@ where
407407
let proposed_step = 0.9
408408
* step_size
409409
* (self.prop.opts.tolerance / self.details.error)
410-
.powf(1.0 / f64::from(self.prop.order));
410+
.powf(1.0 / f64::from(self.prop.method.order()));
411411
step_size = if proposed_step > self.prop.opts.max_step.to_seconds() {
412412
self.prop.opts.max_step.to_seconds()
413413
} else {
@@ -424,7 +424,7 @@ where
424424
let proposed_step = 0.9
425425
* step_size
426426
* (self.prop.opts.tolerance / self.details.error)
427-
.powf(1.0 / f64::from(self.prop.order - 1));
427+
.powf(1.0 / f64::from(self.prop.method.order() - 1));
428428
step_size = if proposed_step < self.prop.opts.min_step.to_seconds() {
429429
self.prop.opts.min_step.to_seconds()
430430
} else {

src/propagators/propagator.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::sync::Arc;
2121
use anise::almanac::Almanac;
2222

2323
use super::error_ctrl::{ErrorCtrl, RSSCartesianStep};
24-
use super::{Dormand78, IntegrationDetails, PropInstance, PropOpts, RK, RK89};
24+
use super::{IntegrationDetails, IntegratorMethod, PropInstance, PropOpts};
2525
use crate::dynamics::Dynamics;
2626
use crate::linalg::allocator::Allocator;
2727
use crate::linalg::{DefaultAllocator, OVector};
@@ -32,7 +32,7 @@ use crate::State;
3232
/// It is an EventTracker, without any event tracking. It includes the options, the integrator
3333
/// details of the previous step, and the set of coefficients used for the monomorphic instance.
3434
#[derive(Clone, Debug)]
35-
pub struct Propagator<'a, D: Dynamics, E: ErrorCtrl>
35+
pub struct Propagator<D: Dynamics, E: ErrorCtrl>
3636
where
3737
DefaultAllocator: Allocator<<D::StateType as State>::Size>
3838
+ Allocator<<D::StateType as State>::Size, <D::StateType as State>::Size>
@@ -41,29 +41,23 @@ where
4141
{
4242
pub dynamics: D, // Stores the dynamics used. *Must* use this to get the latest values
4343
pub opts: PropOpts<E>, // Stores the integration options (tolerance, min/max step, init step, etc.)
44-
pub(crate) order: u8, // Order of the integrator
45-
pub(crate) stages: usize, // Number of stages, i.e. how many times the derivatives will be called
46-
pub(crate) a_coeffs: &'a [f64],
47-
pub(crate) b_coeffs: &'a [f64],
44+
pub method: IntegratorMethod,
4845
}
4946

5047
/// The `Propagator` trait defines the functions of a propagator and of an event tracker.
51-
impl<'a, D: Dynamics, E: ErrorCtrl> Propagator<'a, D, E>
48+
impl<D: Dynamics, E: ErrorCtrl> Propagator<D, E>
5249
where
5350
DefaultAllocator: Allocator<<D::StateType as State>::Size>
5451
+ Allocator<<D::StateType as State>::Size, <D::StateType as State>::Size>
5552
+ Allocator<<D::StateType as State>::Size, <D::StateType as State>::Size>
5653
+ Allocator<<D::StateType as State>::VecLength>,
5754
{
5855
/// Each propagator must be initialized with `new` which stores propagator information.
59-
pub fn new<T: RK>(dynamics: D, opts: PropOpts<E>) -> Self {
56+
pub fn new(dynamics: D, method: IntegratorMethod, opts: PropOpts<E>) -> Self {
6057
Self {
6158
dynamics,
6259
opts,
63-
stages: T::STAGES,
64-
order: T::ORDER,
65-
a_coeffs: T::A_COEFFS,
66-
b_coeffs: T::B_COEFFS,
60+
method,
6761
}
6862
}
6963

@@ -83,19 +77,19 @@ where
8377

8478
/// An RK89 propagator (the default) with custom propagator options.
8579
pub fn rk89(dynamics: D, opts: PropOpts<E>) -> Self {
86-
Self::new::<RK89>(dynamics, opts)
80+
Self::new(dynamics, IntegratorMethod::RungeKutta89, opts)
8781
}
8882

8983
/// A Dormand Prince 7-8 propagator with custom propagator options: it's about 20% faster than an RK98, and more stable in two body dynamics.
9084
/// WARNINGS: Dormand Prince may have issues with generating proper trajectories, leading to glitches in event finding.
9185
pub fn dp78(dynamics: D, opts: PropOpts<E>) -> Self {
92-
Self::new::<Dormand78>(dynamics, opts)
86+
Self::new(dynamics, IntegratorMethod::DormandPrince78, opts)
9387
}
9488

95-
pub fn with(&'a self, state: D::StateType, almanac: Arc<Almanac>) -> PropInstance<'a, D, E> {
89+
pub fn with(&self, state: D::StateType, almanac: Arc<Almanac>) -> PropInstance<D, E> {
9690
// Pre-allocate the k used in the propagator
97-
let mut k = Vec::with_capacity(self.stages + 1);
98-
for _ in 0..self.stages {
91+
let mut k = Vec::with_capacity(self.method.stages() + 1);
92+
for _ in 0..self.method.stages() {
9993
k.push(OVector::<f64, <D::StateType as State>::VecLength>::zeros());
10094
}
10195
PropInstance {
@@ -115,7 +109,7 @@ where
115109
}
116110
}
117111

118-
impl<'a, D: Dynamics> Propagator<'a, D, RSSCartesianStep>
112+
impl<D: Dynamics> Propagator<D, RSSCartesianStep>
119113
where
120114
DefaultAllocator: Allocator<<D::StateType as State>::Size>
121115
+ Allocator<<D::StateType as State>::Size, <D::StateType as State>::Size>
@@ -124,13 +118,13 @@ where
124118
{
125119
/// Default propagator is an RK89 with the default PropOpts.
126120
pub fn default(dynamics: D) -> Self {
127-
Self::new::<RK89>(dynamics, PropOpts::default())
121+
Self::rk89(dynamics, PropOpts::default())
128122
}
129123

130124
/// A default Dormand Prince 78 propagator with the default PropOpts.
131125
/// Faster and more stable than an RK89 (`default`) but seems to cause issues for event finding.
132126
/// WARNINGS: Dormand Prince may have issues with generating proper trajectories, leading to glitches in event finding.
133127
pub fn default_dp78(dynamics: D) -> Self {
134-
Self::new::<Dormand78>(dynamics, PropOpts::default())
128+
Self::dp78(dynamics, PropOpts::default())
135129
}
136130
}

src/propagators/rk_methods/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl IntegratorMethod {
8484
}
8585
}
8686

87-
/// Returns the stages of this integrator (as usize because it's used as indexing)
87+
/// Returns the stages of this integrator, i.e. how many times the derivatives will be called
8888
pub const fn stages(self) -> usize {
8989
match self {
9090
Self::RungeKutta89 => RK89::STAGES,

tests/mission_design/orbitaldyn.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ fn energy_conservation(almanac: Arc<Almanac>) {
5353
eme2k,
5454
);
5555

56-
let rk89_final = Propagator::new::<RK89>(
56+
let rk89_final = Propagator::new(
5757
SpacecraftDynamics::new(OrbitalDynamics::two_body()),
58+
IntegratorMethod::RungeKutta89,
5859
PropOpts::default(),
5960
)
6061
.with(Spacecraft::from(start_state), almanac.clone())
@@ -74,8 +75,9 @@ fn energy_conservation(almanac: Arc<Almanac>) {
7475
}
7576
println!();
7677

77-
let dp78_final = Propagator::new::<Dormand78>(
78+
let dp78_final = Propagator::new(
7879
SpacecraftDynamics::new(OrbitalDynamics::two_body()),
80+
IntegratorMethod::DormandPrince78,
7981
PropOpts::default(),
8082
)
8183
.with(start_state.into(), almanac)
@@ -1196,7 +1198,11 @@ fn val_cislunar_dynamics(almanac_gmat: Arc<Almanac>) {
11961198
);
11971199

11981200
let dynamics = SpacecraftDynamics::new(OrbitalDynamics::point_masses(vec![EARTH, SUN, MOON]));
1199-
let setup = Propagator::new::<RK4Fixed>(dynamics, PropOpts::with_fixed_step_s(0.5));
1201+
let setup = Propagator::new(
1202+
dynamics,
1203+
IntegratorMethod::RungeKutta4,
1204+
PropOpts::with_fixed_step_s(0.5),
1205+
);
12001206
let mut prop = setup.with(state.into(), almanac);
12011207
prop.for_duration(prop_time).unwrap();
12021208

0 commit comments

Comments
 (0)