Memoize the flux average the fixture generator computes

This commit is contained in:
connor committed 2026-10-02 22:12:26 -04:00
1 parent c9c069b0a6
commit 98f19b700a
3 files changed
+35 -3

No files matched your search

+6
View File
@@ -10,6 +10,12 @@
//! scenario. A ratio of times is therefore close to a ratio of per-step cost, which is //! scenario. A ratio of times is therefore close to a ratio of per-step cost, which is
//! the thing worth comparing. If a future scenario's step counts diverge, its timing //! the thing worth comparing. If a future scenario's step counts diverge, its timing
//! ratio means nothing until they are brought back together. //! ratio means nothing until they are brought back together.
//!
//! One scenario is not like for like however the steps come out. Orekit's radiation
//! pressure registers eclipse event detectors, so its integrator locates the shadow
//! boundaries by root finding; this crate integrates straight through them. That is work
//! Orekit does and this does not, and it is arguably the better treatment, so the
//! radiation row is not purely a speed difference.
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
+28 -2
View File
@@ -177,6 +177,13 @@ public class Generate {
*/ */
static class UnroundedWeather implements NRLMSISE00InputParameters { static class UnroundedWeather implements NRLMSISE00InputParameters {
private final CssiSpaceWeatherData inner; private final CssiSpaceWeatherData inner;
/** One average per day, because that is how often it changes.
*
* Without this the eighty-one lookups run on every density evaluation, which is
* every stage of every step: measured at 279 ms of a 641 ms arc, so the timing
* would have been reporting this wrapper rather than Orekit.
*/
private final java.util.Map<Long, Double> cache = new java.util.HashMap<>();
UnroundedWeather(CssiSpaceWeatherData inner) { UnroundedWeather(CssiSpaceWeatherData inner) {
this.inner = inner; this.inner = inner;
@@ -195,11 +202,19 @@ public class Generate {
} }
public double getAverageFlux(AbsoluteDate date) { public double getAverageFlux(AbsoluteDate date) {
long day = (long) Math.floor(date.durationFrom(AbsoluteDate.MODIFIED_JULIAN_EPOCH)
/ 86400.0);
Double known = cache.get(day);
if (known != null) {
return known;
}
double sum = 0.0; double sum = 0.0;
for (int offset = -39; offset <= 41; offset++) { for (int offset = -39; offset <= 41; offset++) {
sum += inner.getDailyFlux(date.shiftedBy(offset * 86400.0)); sum += inner.getDailyFlux(date.shiftedBy(offset * 86400.0));
} }
return sum / 81.0; double average = sum / 81.0;
cache.put(day, average);
return average;
} }
public double[] getAp(AbsoluteDate date) { public double[] getAp(AbsoluteDate date) {
@@ -558,7 +573,7 @@ public class Generate {
*/ */
static void time() throws Exception { static void time() throws Exception {
String[] names = { "two-body", "gravity-8", "gravity-20", "third-body", "radiation", String[] names = { "two-body", "gravity-8", "gravity-20", "third-body", "radiation",
"drag-harris-priester", "drag-msis" }; "drag-harris-priester", "drag-msis", "drag-msis-plain" };
for (String name : names) { for (String name : names) {
// Build it fresh each run: a propagator carries its state, and reusing one // Build it fresh each run: a propagator carries its state, and reusing one
// would time a different thing the second time round. // would time a different thing the second time round.
@@ -637,6 +652,17 @@ public class Generate {
new OneAxisEllipsoid(EARTH_RADIUS, EARTH_FLATTENING, itrf), BULGE_EXPONENT), new OneAxisEllipsoid(EARTH_RADIUS, EARTH_FLATTENING, itrf), BULGE_EXPONENT),
new IsotropicDrag(AREA, CD))); new IsotropicDrag(AREA, CD)));
} }
if (name.equals("drag-msis-plain")) {
// The same thing with CSSI's published average, to show what the recomputing
// wrapper costs rather than assuming it is free.
p.addForceModel(new DragForce(new NRLMSISE00(
new CssiSpaceWeatherData(CssiSpaceWeatherData.DEFAULT_SUPPORTED_NAMES),
(ExtendedPositionProvider) CelestialBodyFactory.getSun(),
new OneAxisEllipsoid(EARTH_RADIUS, EARTH_FLATTENING, itrf))
.withLocalSolarTimeMode(NRLMSISE00.LocalSolarTimeMode.MEAN)
.withSwitch(9, -1),
new IsotropicDrag(AREA, CD)));
}
if (name.equals("drag-msis")) { if (name.equals("drag-msis")) {
p.addForceModel(new DragForce(new NRLMSISE00( p.addForceModel(new DragForce(new NRLMSISE00(
new UnroundedWeather(new CssiSpaceWeatherData( new UnroundedWeather(new CssiSpaceWeatherData(
+1 -1
View File
@@ -1451,6 +1451,6 @@
{ "elapsed": 86220.0, "position": [-6.655014145e+06, -1.271109816e+06, 1.780541525e-02], "velocity": [1.438812276e+03, -7.534656147e+03, -2.631428161e-06] }, { "elapsed": 86220.0, "position": [-6.655014145e+06, -1.271109816e+06, 1.780541525e-02], "velocity": [1.438812276e+03, -7.534656147e+03, -2.631428161e-06] },
{ "elapsed": 86280.0, "position": [-6.553405536e+06, -1.719910498e+06, 1.760646718e-02], "velocity": [1.946838261e+03, -7.419614578e+03, -3.997873341e-06] }, { "elapsed": 86280.0, "position": [-6.553405536e+06, -1.719910498e+06, 1.760646718e-02], "velocity": [1.946838261e+03, -7.419614578e+03, -3.997873341e-06] },
{ "elapsed": 86340.0, "position": [-6.421573259e+06, -2.160779117e+06, 1.732600875e-02], "velocity": [2.445880382e+03, -7.270355853e+03, -5.347406004e-06] }, { "elapsed": 86340.0, "position": [-6.421573259e+06, -2.160779117e+06, 1.732600875e-02], "velocity": [2.445880382e+03, -7.270355853e+03, -5.347406004e-06] },
{ "elapsed": 86400.0, "position": [-6.260125651e+06, -2.591682544e+06, 1.696524000e-02], "velocity": [2.933636216e+03, -7.087569454e+03, -6.673865269e-06] } { "elapsed": 86400.0, "position": [-6.260125651e+06, -2.591682544e+06, 1.696524000e-02], "velocity": [2.933636216e+03, -7.087569454e+03, -6.673865270e-06] }
] ]
} }