To follow up on the discussion in https://forum.orekit.org/t/cant-find-org-jpype-jar-support-library-error-after-update-to-orekit-jpype-13-1-2-1-jpype-1-6-0/5119/7:
I have noticed a performance issue with the jpype wrapper during numerical propagation. I think I’ve narrowed down the performance problem to the release 13.0.2.0 of orekit-jpype. It doesn’t seem to be an issue with the jpype version though:
-
13.0.1.1 seems to work with jpype versions 1.5.0 and 1.6.0
-
13.0.2.0 does not work with the same performance as JCC even with jpype 1.5.0
-
orekit+jcc has no change in performance between 13.0.1 and 13.1
Here’s what I’m doing: we have our own build of orekit+jcc to make it installable via pip. I’ve built a poetry environment where both wrappers are installed at the same time, and wrote a quick numerical propagation script. I’m measuring the time spent in the propagate method.
The propagation runs twice and I’m timing both runs, because the caching by orekit speeds up the second time.
Usually the performance between JCC and jpype is similar (+/- 10% one way or the other), but in the failing cases I see big differences like 7s for JCC vs 18s for jpype.
Here is the script I am using to measure the propagation time. Nothing fancy, it’s a basic numerical propagation with a gravity field. I’ve set up the propagation duration and tolerance so that the whole thing runs in a few seconds.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--wrapper")
parser.add_argument("--orekit-data")
args = parser.parse_args()
if args.wrapper == "jcc":
import orekit
orekit.initVM()
from orekit.pyhelpers import setup_orekit_curdir
vm = setup_orekit_curdir(args.orekit_data)
elif args.wrapper == "jpype":
import orekit_jpype
import os
import jdk4py
os.environ["JAVA_HOME"] = str(jdk4py.JAVA_HOME)
orekit_jpype.initVM()
from orekit_jpype.pyhelpers import setup_orekit_curdir
vm = setup_orekit_curdir(args.orekit_data)
from org.orekit.bodies import OneAxisEllipsoid
from org.orekit.orbits import KeplerianOrbit
from org.orekit.time import AbsoluteDate
from org.orekit.bodies import CelestialBodyFactory
from org.orekit.forces.gravity import HolmesFeatherstoneAttractionModel
from org.orekit.forces.gravity.potential import GravityFieldFactory
from org.orekit.frames import FramesFactory
from org.orekit.orbits import OrbitType
from org.orekit.orbits import PositionAngleType
from org.orekit.propagation import SpacecraftState
from org.orekit.propagation.numerical import NumericalPropagator
from org.orekit.time import TimeScalesFactory
from org.orekit.utils import Constants
from org.orekit.utils import IERSConventions
from org.hipparchus.ode.nonstiff import DormandPrince853Integrator
import numpy as np
def propagate():
utc = TimeScalesFactory.getUTC()
initial_date = AbsoluteDate(2025, 1, 1, 12, 0, 0.0, utc)
propagation_duration_sec = 15 * 86400.
position_tolerance = 1e-8
target_date = initial_date.shiftedBy(propagation_duration_sec)
mass_kg = 5.0
a = Constants.WGS84_EARTH_EQUATORIAL_RADIUS + 500000.0
e = 0.001
i = float(np.rad2deg(98.2))
pa = float(np.rad2deg(90.0))
raan = float(np.rad2deg(45.0))
anomaly = float(np.rad2deg(0.0))
mu = Constants.WGS84_EARTH_MU
inertial_frame = FramesFactory.getEME2000()
earth_fixed_frame = FramesFactory.getITRF(IERSConventions.IERS_2010, False)
initial_orbit = KeplerianOrbit(
a, e, i, pa, raan, anomaly,
PositionAngleType.TRUE,
inertial_frame,
initial_date,
mu
)
initial_state = SpacecraftState(initial_orbit, mass_kg)
if args.wrapper == "jcc":
tolerances = NumericalPropagator.tolerances(float(position_tolerance), initial_orbit, OrbitType.CARTESIAN)
integrator = DormandPrince853Integrator(
float(1e-5),
float(300),
orekit.JArray_double.cast_(tolerances[0]),
orekit.JArray_double.cast_(tolerances[1])
)
elif args.wrapper == "jpype":
tolerances = NumericalPropagator.tolerances(float(position_tolerance), initial_orbit, OrbitType.CARTESIAN)
integrator = DormandPrince853Integrator(
float(1e-5),
float(300),
tolerances[0],
tolerances[1],
)
propagator = NumericalPropagator(integrator)
propagator.setOrbitType(OrbitType.CARTESIAN)
propagator.setInitialState(initial_state)
gravity_provider = GravityFieldFactory.getNormalizedProvider(20, 20)
gravity_force = HolmesFeatherstoneAttractionModel(earth_fixed_frame, gravity_provider)
propagator.addForceModel(gravity_force)
propagator.propagate(target_date)
import datetime
start = datetime.datetime.now()
propagate()
end = datetime.datetime.now()
print(f"Ran propagation with {args.wrapper} in {(end - start).total_seconds():.2f} seconds.")
start = datetime.datetime.now()
propagate()
end = datetime.datetime.now()
print(f"Ran propagation with {args.wrapper} in {(end - start).total_seconds():.2f} seconds.")
Example usage:
poetry run python propagate.py --wrapper jcc --orekit-data “C:/Logiciels/orekit-data”
I’ll try to make a more rigorous check of which versions work tomorrow.