Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Orbit.integrate only works with equidistant time inputs #700

Open
jikrant3 opened this issue Dec 26, 2024 · 1 comment
Open

Orbit.integrate only works with equidistant time inputs #700

jikrant3 opened this issue Dec 26, 2024 · 1 comment

Comments

@jikrant3
Copy link

🐛 Bug

The orbit integration using Orbit.integrate(t=) takes time as input. It is already required to have 0 in the t.

However, I wanted to integrate the orbit for a custom timespan: finer timesteps near the current position and sparse timesteps away from the object. Such a scheme could reduce unnecessary calculations.

e.g. instead of giving
t=np.arange(0, 1000, 0.001)*u.Myr # 1000000 points
I could give
t = np.concatenate([np.arange(0,1,0.001),np.arange(2,1000,1)])*u.Myr # 2000 points

However, when I tried the second t, the integration broke without any warning or errors.

Reproducible example

import matplotlib.pyplot as plt
import numpy as np
from astropy import units as u
from astropy.coordinates import SkyCoord
from galpy.orbit import Orbit
from galpy.potential import MWPotential2014

c = SkyCoord(x=-9000 * u.pc,y=0 * u.pc,z=0 * u.pc,v_x=0 * u.km / u.s,v_y=250 * u.km / u.s,v_z=0 * u.km / u.s,
frame="galactocentric",representation_type="cartesian").icrs

time_1 = np.linspace(0,50,26)*u.Myr
o_1 = Orbit(c)
o_1.integrate(t=time_1, pot=MWPotential2014)

time_2 = np.concatenate([np.linspace(0,10,21)*u.Myr, np.linspace(12,50,20)*u.Myr])
o_2 = Orbit(c)
o_2.integrate(t=time_2, pot=MWPotential2014)

fig, ax = plt.subplots()
ax.scatter(o_1.x(time_1),o_1.y(time_1), label='Equidistant time')
ax.scatter(o_2.x(time_2),o_1.y(time_2), marker='x', label='non-quidistant time')
ax.set(xlabel='x', ylabel='y')
ax.legend()

image

Expected behavior

The integration should either work with any randomly spaced times or raise an error if the times are not equidistant.
The latter could be easier to implement in the short term.

System Details

macOS-15.2-arm64-arm-64bit
Python 3.12.2 (v3.12.2:6abddd9f6a, Feb 6 2024, 17:02:06) [Clang 13.0.0 (clang-1300.0.29.30)]
numpy 1.26.4
scipy 1.12.0
matplotlib 3.8.4
galpy 1.10.1
astropy 6.0.1

@jobovy
Copy link
Owner

jobovy commented Jan 3, 2025

Thanks for opening the issue! Yes, the documentation should be more explicit about the time array needing to have equally-spaced times and it might be good to do an explicit check that this is the case in the code (although such checks are a bit tricky to implement given round-off errors).

For some of the integrators, actually supporting non equally-spaced time arrays might be pretty straightforward, but for others it would be harder. I don't think I will personally implement any non-equally-spaced time array support, because it's quite easy to do this already with a bit more code. As you are probably aware, in your case you can do

time_21 = np.linspace(0,10,21)*u.Myr
time_22 = np.linspace(10,50,20)*u.Myr]
o_21 = Orbit(c)
o_21.integrate(t=time_21, pot=MWPotential2014)
o_22 = o_21(time_21[-1])
o_22.integrate(t=time_22, pot=MWPotential2014)

One feature that I've thought about implementing is the ability to resume an orbit integration like this automatically, so do

time_21 = np.linspace(0,10,21)*u.Myr
time_22 = np.linspace(10,50,20)*u.Myr]
o_21 = Orbit(c)
o_21.integrate(t=time_21, pot=MWPotential2014)
o_21.integrate(t=time_22, pot=MWPotential2014,continue=True)

and then the second integration just continues from the end of the first one (more generally, this continue behavior could be automatically detected if the first new start time matches the final time from a previous integration). That could then also allow your desired behavior. But the priority for this feature is low.

@jobovy jobovy reopened this Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants