satkit 0.3.6__tar.gz → 0.3.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. {satkit-0.3.6 → satkit-0.3.8}/Cargo.toml +1 -1
  2. {satkit-0.3.6/python/satkit.egg-info → satkit-0.3.8}/PKG-INFO +2 -2
  3. {satkit-0.3.6 → satkit-0.3.8}/pyproject.toml +2 -2
  4. {satkit-0.3.6 → satkit-0.3.8/python/satkit.egg-info}/PKG-INFO +2 -2
  5. satkit-0.3.8/python/satkit.egg-info/requires.txt +1 -0
  6. {satkit-0.3.6 → satkit-0.3.8}/src/earthgravity.rs +60 -48
  7. {satkit-0.3.6 → satkit-0.3.8}/src/lpephem/sun.rs +3 -2
  8. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rk_adaptive.rs +18 -9
  9. {satkit-0.3.6 → satkit-0.3.8}/src/ode/types.rs +2 -2
  10. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pypropagate.rs +23 -1
  11. satkit-0.3.6/python/satkit.egg-info/requires.txt +0 -1
  12. {satkit-0.3.6 → satkit-0.3.8}/LICENSE +0 -0
  13. {satkit-0.3.6 → satkit-0.3.8}/MANIFEST.in +0 -0
  14. {satkit-0.3.6 → satkit-0.3.8}/README.md +0 -0
  15. {satkit-0.3.6 → satkit-0.3.8}/python/docs/source/conf.py +0 -0
  16. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/__init__.py +0 -0
  17. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/__init__.pyi +0 -0
  18. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/density.pyi +0 -0
  19. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/frametransform.pyi +0 -0
  20. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/jplephem.pyi +0 -0
  21. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/moon.pyi +0 -0
  22. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/planets.pyi +0 -0
  23. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/py.typed +0 -0
  24. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/satkit.pyi +0 -0
  25. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/satprop.pyi +0 -0
  26. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/sun.pyi +0 -0
  27. {satkit-0.3.6 → satkit-0.3.8}/python/satkit/utils.pyi +0 -0
  28. {satkit-0.3.6 → satkit-0.3.8}/python/satkit.egg-info/SOURCES.txt +0 -0
  29. {satkit-0.3.6 → satkit-0.3.8}/python/satkit.egg-info/dependency_links.txt +0 -0
  30. {satkit-0.3.6 → satkit-0.3.8}/python/satkit.egg-info/top_level.txt +0 -0
  31. {satkit-0.3.6 → satkit-0.3.8}/python/test/download_data.py +0 -0
  32. {satkit-0.3.6 → satkit-0.3.8}/python/test/download_from_json.py +0 -0
  33. {satkit-0.3.6 → satkit-0.3.8}/python/test/download_testvecs.py +0 -0
  34. {satkit-0.3.6 → satkit-0.3.8}/python/test/orbitprop_gps_fit.py +0 -0
  35. {satkit-0.3.6 → satkit-0.3.8}/python/test/sp3file.py +0 -0
  36. {satkit-0.3.6 → satkit-0.3.8}/python/test/test.py +0 -0
  37. {satkit-0.3.6 → satkit-0.3.8}/setup.cfg +0 -0
  38. {satkit-0.3.6 → satkit-0.3.8}/src/astrotime.rs +0 -0
  39. {satkit-0.3.6 → satkit-0.3.8}/src/consts.rs +0 -0
  40. {satkit-0.3.6 → satkit-0.3.8}/src/duration.rs +0 -0
  41. {satkit-0.3.6 → satkit-0.3.8}/src/earth_orientation_params.rs +0 -0
  42. {satkit-0.3.6 → satkit-0.3.8}/src/frames.rs +0 -0
  43. {satkit-0.3.6 → satkit-0.3.8}/src/frametransform/ierstable.rs +0 -0
  44. {satkit-0.3.6 → satkit-0.3.8}/src/frametransform/mod.rs +0 -0
  45. {satkit-0.3.6 → satkit-0.3.8}/src/frametransform/qcirs2gcrs.rs +0 -0
  46. {satkit-0.3.6 → satkit-0.3.8}/src/itrfcoord.rs +0 -0
  47. {satkit-0.3.6 → satkit-0.3.8}/src/jplephem.rs +0 -0
  48. {satkit-0.3.6 → satkit-0.3.8}/src/kepler.rs +0 -0
  49. {satkit-0.3.6 → satkit-0.3.8}/src/lib.rs +0 -0
  50. {satkit-0.3.6 → satkit-0.3.8}/src/lpephem/mod.rs +0 -0
  51. {satkit-0.3.6 → satkit-0.3.8}/src/lpephem/moon.rs +0 -0
  52. {satkit-0.3.6 → satkit-0.3.8}/src/lpephem/planets.rs +0 -0
  53. {satkit-0.3.6 → satkit-0.3.8}/src/nrlmsise.rs +0 -0
  54. {satkit-0.3.6 → satkit-0.3.8}/src/ode/harmonic_oscillator.rs +0 -0
  55. {satkit-0.3.6 → satkit-0.3.8}/src/ode/mod.rs +0 -0
  56. {satkit-0.3.6 → satkit-0.3.8}/src/ode/nalgebra.rs +0 -0
  57. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rk_adaptive_settings.rs +0 -0
  58. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rk_explicit.rs +0 -0
  59. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkf45.rs +0 -0
  60. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkts54.rs +0 -0
  61. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkv65.rs +0 -0
  62. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkv65_table.rs +0 -0
  63. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkv87.rs +0 -0
  64. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkv87_table.rs +0 -0
  65. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkv98.rs +0 -0
  66. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkv98_nointerp.rs +0 -0
  67. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkv98_nointerp_table.rs +0 -0
  68. {satkit-0.3.6 → satkit-0.3.8}/src/ode/rkv98_table.rs +0 -0
  69. {satkit-0.3.6 → satkit-0.3.8}/src/orbitprop/drag.rs +0 -0
  70. {satkit-0.3.6 → satkit-0.3.8}/src/orbitprop/mod.rs +0 -0
  71. {satkit-0.3.6 → satkit-0.3.8}/src/orbitprop/point_gravity.rs +0 -0
  72. {satkit-0.3.6 → satkit-0.3.8}/src/orbitprop/propagator.rs +0 -0
  73. {satkit-0.3.6 → satkit-0.3.8}/src/orbitprop/satproperties.rs +0 -0
  74. {satkit-0.3.6 → satkit-0.3.8}/src/orbitprop/satstate.rs +0 -0
  75. {satkit-0.3.6 → satkit-0.3.8}/src/orbitprop/settings.rs +0 -0
  76. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/mod.rs +0 -0
  77. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/mod_utils.rs +0 -0
  78. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyastrotime.rs +0 -0
  79. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyconsts.rs +0 -0
  80. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pydensity.rs +0 -0
  81. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyduration.rs +0 -0
  82. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyframes.rs +0 -0
  83. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyframetransform.rs +0 -0
  84. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pygravity.rs +0 -0
  85. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyitrfcoord.rs +0 -0
  86. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyjplephem.rs +0 -0
  87. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pykepler.rs +0 -0
  88. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pylpephem_moon.rs +0 -0
  89. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pylpephem_planets.rs +0 -0
  90. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pylpephem_sun.rs +0 -0
  91. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pynrlmsise.rs +0 -0
  92. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pypropresult.rs +0 -0
  93. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pypropsettings.rs +0 -0
  94. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyquaternion.rs +0 -0
  95. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pysatproperties.rs +0 -0
  96. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pysatstate.rs +0 -0
  97. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pysgp4.rs +0 -0
  98. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pysolarsystem.rs +0 -0
  99. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pytle.rs +0 -0
  100. {satkit-0.3.6 → satkit-0.3.8}/src/pybindings/pyutils.rs +0 -0
  101. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/dpper.rs +0 -0
  102. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/dscom.rs +0 -0
  103. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/dsinit.rs +0 -0
  104. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/dspace.rs +0 -0
  105. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/getgravconst.rs +0 -0
  106. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/initl.rs +0 -0
  107. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/mod.rs +0 -0
  108. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/satrec.rs +0 -0
  109. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/sgp4.rs +0 -0
  110. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/sgp4_lowlevel.rs +0 -0
  111. {satkit-0.3.6 → satkit-0.3.8}/src/sgp4/sgp4init.rs +0 -0
  112. {satkit-0.3.6 → satkit-0.3.8}/src/solarsystem.rs +0 -0
  113. {satkit-0.3.6 → satkit-0.3.8}/src/spaceweather.rs +0 -0
  114. {satkit-0.3.6 → satkit-0.3.8}/src/tle.rs +0 -0
  115. {satkit-0.3.6 → satkit-0.3.8}/src/types.rs +0 -0
  116. {satkit-0.3.6 → satkit-0.3.8}/src/utils/datadir.rs +0 -0
  117. {satkit-0.3.6 → satkit-0.3.8}/src/utils/download.rs +0 -0
  118. {satkit-0.3.6 → satkit-0.3.8}/src/utils/mod.rs +0 -0
  119. {satkit-0.3.6 → satkit-0.3.8}/src/utils/skerror.rs +0 -0
  120. {satkit-0.3.6 → satkit-0.3.8}/src/utils/test.rs +0 -0
  121. {satkit-0.3.6 → satkit-0.3.8}/src/utils/update_data.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "satkit"
3
- version = "0.3.6"
3
+ version = "0.3.8"
4
4
  edition = "2021"
5
5
  description = "Satellite Toolkit"
6
6
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satkit
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: Satellite Orbital Dynamics Toolkit
5
5
  Author-email: Steven Michael <ssmichael@gmail.com>
6
6
  Maintainer-email: Steven Michael <ssmichael@gmail.com>
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Requires-Python: >=3.8
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: numpy>=1.20.0
18
+ Requires-Dist: numpy>=1.0.0
19
19
 
20
20
  # Satellite Toolkit with Rust
21
21
 
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "satkit"
7
- version = "0.3.6"
8
- dependencies = ["numpy>=1.20.0"]
7
+ version = "0.3.8"
8
+ dependencies = ["numpy>=1.0.0"]
9
9
  requires-python = ">= 3.8"
10
10
  authors = [{ name = "Steven Michael", email = "ssmichael@gmail.com" }]
11
11
  maintainers = [{ name = "Steven Michael", email = "ssmichael@gmail.com" }]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satkit
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: Satellite Orbital Dynamics Toolkit
5
5
  Author-email: Steven Michael <ssmichael@gmail.com>
6
6
  Maintainer-email: Steven Michael <ssmichael@gmail.com>
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Requires-Python: >=3.8
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: numpy>=1.20.0
18
+ Requires-Dist: numpy>=1.0.0
19
19
 
20
20
  # Satellite Toolkit with Rust
21
21
 
@@ -0,0 +1 @@
1
+ numpy>=1.0.0
@@ -330,13 +330,13 @@ impl Gravity {
330
330
  } else if order == 36 {
331
331
  self.accel_and_partials_t::<36, 40>(pos)
332
332
  } else if order == 37 {
333
- self.accel_and_partials_t::<37, 15>(pos)
333
+ self.accel_and_partials_t::<37, 41>(pos)
334
334
  } else if order == 38 {
335
- self.accel_and_partials_t::<38, 16>(pos)
335
+ self.accel_and_partials_t::<38, 42>(pos)
336
336
  } else if order == 39 {
337
- self.accel_and_partials_t::<39, 17>(pos)
337
+ self.accel_and_partials_t::<39, 43>(pos)
338
338
  } else {
339
- self.accel_and_partials_t::<40, 20>(pos)
339
+ self.accel_and_partials_t::<40, 44>(pos)
340
340
  }
341
341
  }
342
342
 
@@ -481,38 +481,57 @@ impl Gravity {
481
481
 
482
482
  fn compute_legendre<const NP4: usize>(&self, pos: &Vec3) -> (Legendre<NP4>, Legendre<NP4>) {
483
483
  let rsq = pos.norm_squared();
484
- let xfac = pos[0] * self.radius / rsq;
485
- let yfac = pos[1] * self.radius / rsq;
486
- let zfac = pos[2] * self.radius / rsq;
487
- let rfac = self.radius * self.radius / rsq;
484
+ let scale = self.radius / rsq;
485
+ let xfac = pos[0] * scale;
486
+ let yfac = pos[1] * scale;
487
+ let zfac = pos[2] * scale;
488
+ let rfac = self.radius * scale;
488
489
 
489
490
  let mut v = Legendre::<NP4>::zeros();
490
491
  let mut w = Legendre::<NP4>::zeros();
491
492
 
492
- v[(0, 0)] = self.radius / rsq.sqrt();
493
- w[(0, 0)] = 0.0;
493
+ let mut vmm1mm1 = self.radius / rsq.sqrt();
494
+ let mut wmm1mm1 = 0.0;
495
+ v[(0, 0)] = vmm1mm1;
496
+ w[(0, 0)] = wmm1mm1;
494
497
 
495
- for m in 0..(NP4 - 1) {
496
- // Along diagnoals
498
+ for m in 0..NP4 {
497
499
  if m > 0 {
498
- v[(m, m)] = self.divisor_table[(m, m)]
499
- * (xfac * v[(m - 1, m - 1)] - yfac * w[(m - 1, m - 1)]);
500
- w[(m, m)] = self.divisor_table[(m, m)]
501
- * (xfac * w[(m - 1, m - 1)] + yfac * v[(m - 1, m - 1)]);
500
+ let d = self.divisor_table[(m, m)];
501
+ v[(m, m)] = d * (xfac * vmm1mm1 - yfac * wmm1mm1);
502
+ w[(m, m)] = d * (xfac * wmm1mm1 + yfac * vmm1mm1);
502
503
  }
503
- // Work down tree
504
- let n = m + 1;
505
- v[(n, m)] = self.divisor_table[(n, m)] * zfac * v[(n - 1, m)];
506
- w[(n, m)] = self.divisor_table[(n, m)] * zfac * w[(n - 1, m)];
507
504
 
508
- for n in (m + 2)..(NP4 - 1) {
509
- v[(n, m)] = self.divisor_table[(n, m)] * zfac * v[(n - 1, m)]
510
- - self.divisor_table2[(n, m)] * rfac * v[(n - 2, m)];
505
+ vmm1mm1 = v[(m, m)];
506
+ wmm1mm1 = w[(m, m)];
507
+ let mut vnm2m = vmm1mm1;
508
+ let mut wnm2m = wmm1mm1;
511
509
 
512
- w[(n, m)] = self.divisor_table[(n, m)] * zfac * w[(n - 1, m)]
513
- - self.divisor_table2[(n, m)] * rfac * w[(n - 2, m)];
510
+ let n = m + 1;
511
+ if n >= NP4 {
512
+ continue;
513
+ }
514
+ let d = self.divisor_table[(n, m)] * zfac;
515
+ let mut vnm1m = d * vnm2m;
516
+ let mut wnm1m = d * wnm2m;
517
+ v[(n, m)] = vnm1m;
518
+ w[(n, m)] = wnm1m;
519
+
520
+ for n in (m + 2)..NP4 {
521
+ let d = self.divisor_table[(n, m)] * zfac;
522
+ let d2 = self.divisor_table2[(n, m)] * rfac;
523
+ let vnm = d * vnm1m - d2 * vnm2m;
524
+ let wnm = d * wnm1m - d2 * wnm2m;
525
+ v[(n, m)] = vnm;
526
+ w[(n, m)] = wnm;
527
+ vnm2m = vnm1m;
528
+ vnm1m = vnm;
529
+
530
+ wnm2m = wnm1m;
531
+ wnm1m = wnm;
514
532
  }
515
533
  }
534
+
516
535
  (v, w)
517
536
  }
518
537
 
@@ -609,35 +628,28 @@ impl Gravity {
609
628
  }
610
629
  }
611
630
 
631
+ let mut d1 = DivisorTable::zeros();
632
+ let mut d2 = DivisorTable::zeros();
633
+ for m in 0..43 {
634
+ if m > 0 {
635
+ d1[(m, m)] = (2 * m - 1) as f64
636
+ }
637
+ let n = m + 1;
638
+ d1[(n, m)] = (2 * n - 1) as f64 / (n - m) as f64;
639
+ for n in (m + 2)..43 {
640
+ d1[(n, m)] = (2 * n - 1) as f64 / (n - m) as f64;
641
+ d2[(n, m)] = (n + m - 1) as f64 / (n - m) as f64;
642
+ }
643
+ }
644
+
612
645
  Ok(Gravity {
613
646
  name: String::from(name),
614
647
  gravity_constant: gravity_constant,
615
648
  radius: radius,
616
649
  max_degree: max_degree,
617
650
  coeffs: cs,
618
- divisor_table: {
619
- let mut dt: DivisorTable = DivisorTable::zeros();
620
- for m in 0..43 {
621
- if m > 0 {
622
- dt[(m, m)] = 2.0 * m as f64 - 1.0;
623
- }
624
- let n = m + 1;
625
- dt[(n, m)] = (2.0 * n as f64 - 1.0) / (n - m) as f64;
626
- for n in (m + 2)..19 {
627
- dt[(n, m)] = (2.0 * n as f64 - 1.0) / (n - m) as f64;
628
- }
629
- }
630
- dt
631
- },
632
- divisor_table2: {
633
- let mut dt: DivisorTable = DivisorTable::zeros();
634
- for m in 0..19 {
635
- for n in (m + 2)..19 {
636
- dt[(n, m)] = (n as f64 + m as f64 - 1.0) / (n - m) as f64;
637
- }
638
- }
639
- dt
640
- },
651
+ divisor_table: d1,
652
+ divisor_table2: d2,
641
653
  })
642
654
  }
643
655
  }
@@ -105,13 +105,14 @@ pub fn shadowfunc(psun: &Vec3, psat: &Vec3) -> f64 {
105
105
  let c = (-psat.dot(&(psun - psat)) / snorm / (psun - psat).norm()).acos();
106
106
  if a + b <= c {
107
107
  1.0
108
- } else if c < b - a {
108
+ } else if c < (b - a) {
109
109
  0.0
110
110
  } else {
111
111
  let x = (c * c + a * a - b * b) / 2.0 / c;
112
112
  let y = (a * a - x * x).sqrt();
113
113
  let big_a = a * a * (x / a).acos() + b * b * ((c - x) / b).acos() - c * y;
114
- 1.0 - big_a / std::f64::consts::PI / a / a
114
+ let frac = 1.0 - big_a / std::f64::consts::PI / a / a;
115
+ frac
115
116
  }
116
117
  }
117
118
 
@@ -25,12 +25,21 @@ pub trait RKAdaptive<const N: usize, const NI: usize> {
25
25
  if sol.dense.is_none() {
26
26
  return Err(Box::new(ODEError::NoDenseOutputInSolution));
27
27
  }
28
+ let dense = sol.dense.as_ref().unwrap();
29
+
28
30
  if sol.x < xinterp {
29
- return Err(Box::new(ODEError::InterpExceedsSolutionBounds));
31
+ return Err(Box::new(ODEError::InterpExceedsSolutionBounds {
32
+ interp: xinterp,
33
+ start: dense.x[0],
34
+ stop: sol.x,
35
+ }));
30
36
  }
31
- let dense = sol.dense.as_ref().unwrap();
32
- if sol.x < dense.x[0] {
33
- return Err(Box::new(ODEError::InterpExceedsSolutionBounds));
37
+ if xinterp < dense.x[0] {
38
+ return Err(Box::new(ODEError::InterpExceedsSolutionBounds {
39
+ interp: xinterp,
40
+ start: dense.x[0],
41
+ stop: sol.x,
42
+ }));
34
43
  }
35
44
 
36
45
  // We know indices are monotonically increasing, so only search from
@@ -137,11 +146,9 @@ pub trait RKAdaptive<const N: usize, const NI: usize> {
137
146
  };
138
147
 
139
148
  // OK ... lets integrate!
140
- let mut runloop: bool = true;
141
- while runloop {
142
- if (tdir > 0.0 && x + h >= xend) || (tdir < 0.0 && x + h <= xend) {
149
+ loop {
150
+ if (tdir > 0.0 && (x + h) >= xend) || (tdir < 0.0 && (x + h) <= xend) {
143
151
  h = xend - x;
144
- runloop = false;
145
152
  }
146
153
  let mut karr = Vec::new();
147
154
  karr.push(system.ydot(x, &y)?);
@@ -223,7 +230,9 @@ pub trait RKAdaptive<const N: usize, const NI: usize> {
223
230
  h = h / q;
224
231
 
225
232
  naccept += 1;
226
- // If dense output, limit step size
233
+ if (tdir > 0.0 && x >= xend) || (tdir < 0.0 && x <= xend) {
234
+ break;
235
+ }
227
236
  } else {
228
237
  nreject += 1;
229
238
  h = h / f64::min(1.0 / settings.minfac, q11 / settings.gamma);
@@ -53,8 +53,8 @@ pub enum ODEError {
53
53
  StepErrorToSmall,
54
54
  #[error("No Dense Output in Solution")]
55
55
  NoDenseOutputInSolution,
56
- #[error("Interpolation exceeds solution bounds")]
57
- InterpExceedsSolutionBounds,
56
+ #[error("Interpolation exceeds solution bounds: {interp} not in [{start}, {stop}]")]
57
+ InterpExceedsSolutionBounds { interp: f64, start: f64, stop: f64 },
58
58
  #[error("Interpolation not implemented for this integrator")]
59
59
  InterpNotImplemented,
60
60
  }
@@ -175,6 +175,28 @@ pub fn propagate(
175
175
  }
176
176
  // Propagate with state transition matrix
177
177
  else {
178
- pyo3::Python::with_gil(|py| -> PyResult<PyObject> { Ok(py.None()) })
178
+ // Create the state to propagate
179
+ let mut pv = na::SMatrix::<f64, 6, 7>::zeros();
180
+ pv.fixed_view_mut::<3, 1>(0, 0)
181
+ .copy_from_slice(unsafe { pos.as_slice().unwrap() });
182
+ pv.fixed_view_mut::<3, 1>(3, 0)
183
+ .copy_from_slice(unsafe { vel.as_slice().unwrap() });
184
+ pv.fixed_view_mut::<6, 6>(0, 1)
185
+ .copy_from(&na::Matrix6::<f64>::identity());
186
+ let res = crate::orbitprop::propagate(
187
+ &pv,
188
+ &start.inner,
189
+ &stoptime,
190
+ &propsettings,
191
+ satproperties,
192
+ output_dense,
193
+ )
194
+ .unwrap();
195
+ pyo3::Python::with_gil(|py| -> PyResult<PyObject> {
196
+ Ok(PyPropResult {
197
+ inner: PyPropResultType::R7(res),
198
+ }
199
+ .into_py(py))
200
+ })
179
201
  }
180
202
  }
@@ -1 +0,0 @@
1
- numpy>=1.20.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes