Default bodies with a limited valid time range
The regular default body settings use the spice toolbox to determine the ephemerides of solar system bodies. Consequently, when using these defaults, each time the state of a solar system body is required, the corresponding spice function is called, and a celestial body state is computed. The downside of this is that the process of extracting a state from spice is fairly slow, and may present a computational bottleneck in certain cases. This is especially true when the dynamics you are using is fairly simple (no high-order spherical harmonics, no complex guidance model, no detailed atmosphere model), in which you require the states of numerous solar system bodies, for instance for the computation of third-body perturbations. To mitigate this, we offer an alternative method of defining default body settings:
Required Show/Hide
# import statements required from tudatpy.kernel.numerical_simulation import environment_setup from tudatpy.kernel.interface import spice # load spice kernels spice_interface.load_standard_kernels()# define bodies in simulation bodies_to_create = ["Sun", "Earth", "Moon", "Mars", "Jupiter"] # create body settings dictionary global_frame_origin = "SSB" global_frame_orientation = "J2000" initial_time = 2.0 * constants.JULIAN_YEAR final_time = 4.0 * constants.JULIAN_YEAR time_step = 300.0 body_settings = environment_setup.get_default_body_settings_time_limited( bodies_to_create, initial_time, final_time, global_frame_origin, global_frame_orientation time_step)// required include statements #include <tudat/simulation/simulation.h> // required using-declarations using tudat::simulation_setup; using tudat;
The difference w.r.t. the regular creation<creation_celestial_body_settings> of default body settings being the use of the get_default_body_settings_time_limited()
function (instead of get_default_body_settings()
). What is done when using this alternative setup:
When creating the bodies, spice is queried at a linearly spaced set of times (defined by the
initial_time
,final_time
andtime_step
, the latter of which has a default of 300 s), resulting in a table of states for each body that is to be createdA 6-point
lagrange_interpolation()
is created for each body using these tables of states, and is used to define the ephemeris of the bodyWhen requiring the state of a body during the simulation, the interpolator is queried, instead of spice
Extracting a state from the interpolator is significantly faster than extracting it from spice. However, this approach comes with a number of downsides:
This setup require large tables of states (and associated data for the interpolator) to be stored in active memory, leading to significant memory usage when used for large simulation time intervals
Using the interpolator will produce a slightly different result for the states that if they would be extracted from spice directly. For most solar system bodies, this is limited, but for bodies with short orbital periods (e.g. solar system moons), the interpolation error may be excessive. In such cases, users can define a different
time_step
for a single body by using theget_default_single_body_settings_time_limited()
function.The ephemeris that is created in this manner is only valid within a given time range, which means that you need to know beforehand which the time interval of your simulation will be
Warning
The Lagrange interpolator that is created in the above flow is not valid within the full range [initial_time
, final_time
]. At the edges of this domain, it will return unreliable results, due to the onset of Runge’s phenomenon. See this page<lagrange_interpolator_issues> for a more detailed description. In short, the interpolator is only valid in the range [initial_time
+ 3 \(\cdot\) time_step
, final_time
- 3 \(\cdot\) time_step
]