Manifold Module
The manifold module provides high-level utilities for computing invariant manifolds of periodic orbits in the circular restricted three-body problem.
This module provides the fundamental classes for representing and computing invariant manifolds, including stable and unstable manifolds of periodic orbits.
Manifold()
Base class for invariant manifolds.
- class hiten.system.manifold.Manifold[source]
Bases:
_HitenBase
Compute and cache the invariant manifold of a periodic orbit.
- Parameters:
generating_orbit (
PeriodicOrbit
) – Orbit that seeds the manifold.stable (bool, default True) – True selects the stable manifold, False the unstable one.
direction ({'positive', 'negative'}, default 'positive') – Sign of the eigenvector used to initialise the manifold branch.
- generating_orbit
Orbit that seeds the manifold.
- Type:
- libration_point
Libration point associated with generating_orbit.
- Type:
- manifold_result
Cached result returned by the last successful compute call.
- Type:
ManifoldResult
or None
Notes
Re-invoking compute after a successful run returns the cached
ManifoldResult
without recomputation.- property generating_orbit: PeriodicOrbit
Orbit that seeds the manifold.
- Returns:
The generating periodic orbit.
- Return type:
- property libration_point
Libration point associated with the generating orbit.
- Returns:
The libration point associated with the generating orbit.
- Return type:
- property system: System
The system this manifold belongs to.
- Returns:
The system this manifold belongs to.
- Return type:
- property stable: int
1 for stable, -1 for unstable.
- Returns:
Encoded stability: 1 for stable, -1 for unstable.
- Return type:
- Type:
Encoded stability
- property direction: int
1 for ‘positive’, -1 for ‘negative’.
- Returns:
Encoded direction: 1 for ‘positive’, -1 for ‘negative’.
- Return type:
- Type:
Encoded direction
- property result
Cached result from the last successful compute call.
- Returns:
The cached manifold result, or None if not computed.
- Return type:
ManifoldResult
or None
- property trajectories: List[Trajectory]
The trajectories of the manifold.
- Returns:
The trajectories of the manifold.
- Return type:
List[
Trajectory
]
- compute(step=0.02, integration_fraction=0.75, NN=1, displacement=1e-06, dt=0.001, method='adaptive', order=8, **kwargs)[source]
Generate manifold trajectories and build a Poincare map.
The routine samples the generating orbit at equally spaced fractions of its period, displaces each point by displacement along the selected eigenvector and integrates the resulting initial condition for integration_fraction of one synodic period.
- Parameters:
step (float, default 0.02) – Increment of the dimensionless fraction along the orbit (i.e. 50 samples per orbit).
integration_fraction (float, default 0.75) – Portion of 2*pi nondimensional time units to integrate each trajectory.
NN (int, default 1) – Index of the real eigenvector to follow (1-based).
displacement (float, default 1e-6) – Dimensionless displacement applied along the eigenvector.
method ({'fixed', 'adaptive', 'symplectic'}, default 'adaptive') – Integration method to use.
order (int, default 8) – Integration order for fixed-step methods.
**kwargs –
Additional options:
- show_progressbool, default True
Display a tqdm progress bar.
- energy_tolfloat, default 1e-6
Maximum relative variation of the Jacobi constant allowed along a trajectory. Larger deviations indicate numerical error (often triggered by near-singular passages) and cause the trajectory to be discarded.
- safe_distancefloat, default 2.0
Safety multiplier applied to the physical radii of both primaries. A trajectory is rejected if it ever comes within safe_distance x radius of either body.
dt (float)
- Returns:
The computed manifold result containing trajectories and Poincare section data.
- Return type:
ManifoldResult
- Raises:
ValueError – If called after a previous run with incompatible settings or if requested eigenvector is not available.
Examples
>>> from hiten.system import System, Manifold >>> system = System.from_bodies("earth", "moon") >>> L2 = system.get_libration_point(2) >>> halo_L2 = L2.create_orbit('halo', amplitude_z=0.3, zenith='northern') >>> halo_L2.correct() >>> halo_L2.propagate() >>> manifold = halo_L2.manifold(stable=True, direction='positive') >>> result = manifold.compute(step=0.05) >>> print(f"Success rate: {result.success_rate:.0%}")
- plot(dark_mode=True, save=False, filepath='manifold.svg', **kwargs)[source]
Render a 3-D plot of the computed manifold.
- Parameters:
- Returns:
The generated plot figure.
- Return type:
- Raises:
ValueError – If manifold_result is None.
- to_csv(filepath, **kwargs)[source]
Export manifold trajectory data to a CSV file.
Each row in the CSV file represents a point in a trajectory, and includes a trajectory ID, timestamp, and the 6D state vector (x, y, z, vx, vy, vz).
- Parameters:
filepath (str) – Path to the output CSV file. Parent directories are created if they do not exist.
**kwargs – Reserved for future use.
- Raises:
ValueError – If manifold_result is None.
- __setstate__(state)[source]
Restore the Manifold instance after unpickling.
The heavy, non-serialisable dynamical system is reconstructed lazily using the stored value of stable and direction. secondary bodies.
- Parameters:
state (dict) – Dictionary containing the serialized state of the Manifold.
- classmethod load(filepath, **kwargs)[source]
Load a manifold from a file.
- Parameters:
filepath (str) – Path to the file containing the saved manifold.
- Returns:
The loaded Manifold instance.
- Return type:
- Raises:
FileNotFoundError – If the file does not exist.
ManifoldResult()
Container for manifold computation results.