e2m2e.integrators#

Rust 积分器扩展的公共 Python 适配层。

Attributes#

Classes#

RustEomKernel

Rust 内置 EOM 内核标识,替代 Python RHS 回调传入 solve_ivp_events()。

Functions#

differential_correction_cr3bp_py(→ dict[str, Any])

调用 Rust CR3BP 微分修正,并返回规范化字典。

multiple_shooting_correct_py(→ _ShootingResult)

调用 Rust 多重打靶,并立即校验最终状态三元组。

planar_full_period_pal_py(→ _ShootingResult)

调用 Rust 平面全周期 PAL,并立即校验最终状态三元组。

segmented_shooting_correct_py(→ _ShootingResult)

调用 Rust 分段打靶,并立即校验最终状态三元组。

require_rust_extension(→ None)

确保 Rust 扩展可用且指定的模块级符号存在;否则抛 RustExtensionUnavailableError。

rk_step(method, t, y, h, tol, f[, state_error_dim])

使用 Rust 积分器内核执行单个 Runge-Kutta 步。

multistep_step(method, t, y, h, tol, f, history)

执行单个多步预测-校正步。

initialize_abm_history(→ tuple[float, numpy.ndarray, ...)

以 n_stages 个 RK89 步启动 ABM history。

cowell_step(t, h, tol, accel, history)

对 x'' = a(t, x) 执行单个 Cowell(Störmer-Cowell)8 阶步。

initialize_cowell_history(→ tuple[float, ...)

以 n_startup 个 RK89 步启动 8 阶 Cowell history。

solve_ivp_events(→ dict[str, Any])

带事件检测的 Rust solve_ivp 封装(scipy 事件语义)。

wsb_search_rust(→ tuple[list[dict[str, Any]], int, int])

WSB 三维网格搜索的 Rust 后端。

low_energy_patch_rust(→ list[dict[str, Any]])

低能转移流形截面态配对的 Rust 后端。

grid_search_rust_serial(→ list[dict[str, Any]])

转移网格搜索 Rust 串行后端(阶段 B)。

grid_search_rust(→ list[dict[str, Any]])

转移网格搜索 Rust 后端(阶段 C,Rayon 并行 + GIL 释放)。

Module Contents#

e2m2e.integrators.augmented_eom_7d_py: Any#
e2m2e.integrators.differential_correction_cr3bp_py(*args: Any, **kwargs: Any) → dict[str, Any]#

调用 Rust CR3BP 微分修正,并返回规范化字典。

e2m2e.integrators.multiple_shooting_correct_py(*args: Any, **kwargs: Any) → _ShootingResult#

调用 Rust 多重打靶,并立即校验最终状态三元组。

e2m2e.integrators.planar_full_period_pal_py(*args: Any, **kwargs: Any) → _ShootingResult#

调用 Rust 平面全周期 PAL,并立即校验最终状态三元组。

e2m2e.integrators.segmented_shooting_correct_py(*args: Any, **kwargs: Any) → _ShootingResult#

调用 Rust 分段打靶,并立即校验最终状态三元组。

e2m2e.integrators.require_rust_extension(*required_symbols: str) → None#

确保 Rust 扩展可用且指定的模块级符号存在;否则抛 RustExtensionUnavailableError。

在使用 Rust 扩展符号的每个入口调用。扩展未构建、构建不含 spice feature、或符号缺失时,抛带 make dev 指引的 RustExtensionUnavailableError,不允许静默回退到 Python/scipy。 required_symbols 是 e2m2e.integrators 模块级 符号名;扩展缺失时符号为 None。

Example:
>>> require_rust_extension("propagate_compiled", "spice_furnsh")
class e2m2e.integrators.RustEomKernel(kernel: str, params: dict[str, float])#

Rust 内置 EOM 内核标识,替代 Python RHS 回调传入 solve_ivp_events()。

携带动力学标识 kernel 与无量纲参数表 params;积分器据此把每步 RHS 求值留在 Rust 内(复用 e2m2e-forces 的 CR3BP/BCR4BP EOM/STM 实现,issue #594),事件函数仍为 Python 回调。

标识与所需参数:

  • "cr3bp":{"mu": ...},6 维右端

  • "cr3bp-with-stm":{"mu": ...},42 维增广右端(状态 + STM)

  • "bcr4bp":{"mu", "mu_sun", "sun_distance", "sun_angular_rate", "sun_phase0"},6 维右端(显式含时)

  • "bcr4bp-with-stm":同 "bcr4bp" 参数,42 维增广右端

Args:

kernel: 动力学标识(上表之一,未知标识在构造时报错)。 params: 参数表;值经 float() 强制转换。

__slots__ = ('kernel', 'params')#
kernel: str#
params: dict[str, float]#
__setattr__(name: str, value: Any) → None#
__repr__() → str#
e2m2e.integrators.rk_step(method: RkMethod, t: float, y: numpy.typing.ArrayLike, h: float, tol: float, f: collections.abc.Callable[[float, numpy.typing.NDArray[numpy.floating]], numpy.typing.NDArray[numpy.floating]], state_error_dim: int | None = None)#

使用 Rust 积分器内核执行单个 Runge-Kutta 步。

回调 f 接收 NumPy ndarray,并须返回同长度数组。返回的 StepResult 包含 y_new、error、h_next。

state_error_dim:步长误差控制只统计前 N 维(None 时统计全部)。 STM 增广传播时传 6,让状态转移矩阵的 36 个分量不主导步长控制。

e2m2e.integrators.multistep_step(method: MultistepMethod, t: float, y: numpy.typing.ArrayLike, h: float, tol: float, f: collections.abc.Callable[[float, numpy.typing.NDArray[numpy.floating]], numpy.typing.NDArray[numpy.floating]], history: list[numpy.typing.ArrayLike])#

执行单个多步预测-校正步。

history 须按从旧到新的顺序保存 method.steps() 个导数样本,每个样本 与 y 等长,间隔均为 h。回调 f 的签名与 rk_step() 相同。 返回 MultistepResult,其 history 是供下一步使用的滚动缓冲区。

假定步长固定;改变 h 后须重新初始化 history(见 initialize_abm_history())。

e2m2e.integrators.initialize_abm_history(t0: float, y0: numpy.typing.ArrayLike, h: float, f: collections.abc.Callable[[float, numpy.typing.NDArray[numpy.floating]], numpy.typing.NDArray[numpy.floating]], n_stages: int = 3, tol: float = 1e-12) → tuple[float, numpy.ndarray, list[list[float]]]#

以 n_stages 个 RK89 步启动 ABM history。

ABM 方法使用 4 个导数样本;默认 n_stages=3 时返回 (t0 + 3h, y(3h), [f_0, f_1, f_2, f_3]),其中 history 可直接传给 multistep_step()。

e2m2e.integrators.cowell_step(t: float, h: float, tol: float, accel: collections.abc.Callable[[float, numpy.typing.NDArray[numpy.floating]], numpy.typing.NDArray[numpy.floating]], history: list[numpy.typing.ArrayLike])#

对 x'' = a(t, x) 执行单个 Cowell(Störmer-Cowell)8 阶步。

history = [x_{n-1}, x_n, a_{n-7}, ..., a_n] (10 个向量:2 个位置 样本与 8 个加速度样本,按从旧到新排列)。accel(t, x) 返回只依赖位置的 加速度(引力、J2)。输出仅含位置,步长固定。

返回的 CowellResult 包含 x_new、error、h_next、history。

e2m2e.integrators.initialize_cowell_history(t0: float, x0: numpy.typing.ArrayLike, v0: numpy.typing.ArrayLike, h: float, accel: collections.abc.Callable[[float, numpy.typing.NDArray[numpy.floating]], numpy.typing.NDArray[numpy.floating]], n_startup: int = 7, tol: float = 1e-12) → tuple[float, numpy.ndarray, numpy.ndarray, list[list[float]]]#

以 n_startup 个 RK89 步启动 8 阶 Cowell history。

返回 (t, x, v, history),其中 history = [x_{n-1}, x_n, a_{n-7}, ..., a_n] (2 个位置与 8 个加速度, 可直接传给 cowell_step())。n_startup 须不小于 7,以获得最近的 8 个加速度样本;默认 n_startup=7 时状态推进至 t0 + 7h。

e2m2e.integrators.solve_ivp_events(t_span: tuple[float, float], y0: numpy.typing.ArrayLike, t_eval: numpy.typing.ArrayLike, rtol: float, atol: float, f: collections.abc.Callable[[float, numpy.typing.NDArray[numpy.floating]], numpy.typing.NDArray[numpy.floating]] | RustEomKernel, events: list[tuple[collections.abc.Callable[[float, numpy.typing.NDArray[numpy.floating]], float], bool, float]], method: RkMethod | None = None, max_step: float | None = None, max_steps: int | None = None, state_error_dim: int | None = None) → dict[str, Any]#

带事件检测的 Rust solve_ivp 封装(scipy 事件语义)。

事件检测在 Rust 积分内循环完成:每个接受步的端点评估事件函数, 符号变化(经 direction 过滤)时在步内对线性插值态二分求精(无稠密输出)。

Args:

t_span: 积分区间 (t0, tf)。 y0: 初始状态向量。 t_eval: 输出时间点数组。 rtol: 相对容差。 atol: 绝对容差。 f: ODE 右端,两种形态二选一:Python callable

f(t, y) -> dy/dt``(每步求值跨语言回调),或 :class:`RustEomKernel` 内核标识(每步 RHS 求值留在 Rust 内, 复用 ``e2m2e-forces 的 EOM/STM 内核,issue #594;事件函数 仍为 Python 回调)。

events: [(g, terminal, direction), ...],g(t, y) -> float,

零点即事件面;terminal=True 触发即停;direction > 0 只记 上行穿越(g 由负到正)、< 0 只记下行、0 双向。

method: RK 方法,默认 PD78(DOP853)。 max_step: 最大步长。求精精度受步内线性插值误差(~h²/8·|ÿ|)限制,

需要更紧的事件时刻时请设小 max_step。

max_steps: 最大积分步数。 state_error_dim: 步长误差控制只统计前 N 维(用于 STM 增广传播)。

Returns:

dict:states/time (t_eval 前缀,terminal 截断时末点为求精后的 事件点)、t_events/y_events (逐事件的触发时刻与状态列表)、 terminal_event (触发终止的事件索引或 None)、n_steps。

e2m2e.integrators.wsb_search_rust(departure_state: numpy.typing.ArrayLike, target_state: numpy.typing.ArrayLike, *, mu: float, mu_sun: float, sun_distance: float, sun_angular_rate: float, sun_phase_range: tuple[float, float], n_sun_phase: int, departure_phase_range: tuple[float, float], n_departure_phase: int, tof_range_sec: tuple[float, float], n_tof: int, perilune_alt_range_km: tuple[float, float], max_total_dv: float, h2_energy_threshold: float, tli_speed_factor: float, n_propagation_samples: int, rtol: float, atol: float, max_step: float, max_steps: int, secondary_radius_km: float, characteristic_length_km: float, characteristic_time_sec: float, parallel: bool | None = None, n_workers: int | None = None, progress_callback: collections.abc.Callable[[int], Any] | None = None) → tuple[list[dict[str, Any]], int, int]#

WSB 三维网格搜索的 Rust 后端。

参数全部是已无量纲化的 POD 数值;BCR4BP 传播、截面求精和候选筛选均在 Rust 内完成。parallel=None 时由 E2M2E_WSB_PARALLEL 控制 Rayon。

e2m2e.integrators.low_energy_patch_rust(states_a: numpy.typing.ArrayLike, states_b: numpy.typing.ArrayLike, weights: tuple[float, float], *, parallel: bool | None = None, n_workers: int | None = None, progress_callback: collections.abc.Callable[[int], Any] | None = None) → list[dict[str, Any]]#

低能转移流形截面态配对的 Rust 后端。

输入为两组 (n, 6) 截面态,Rust 完成全部配对、位置/速度范数、 加权代价和稳定排序。parallel=None 时由 E2M2E_LOW_ENERGY_PARALLEL 决定是否使用 Rayon;显式 n_workers 为本次调用建立一次性线程池。

e2m2e.integrators.grid_search_rust_serial(dep_states: numpy.typing.ArrayLike, dep_times: numpy.typing.ArrayLike, alpha_grid: numpy.typing.ArrayLike, arrival_states: numpy.typing.ArrayLike, *, mu: float, max_transfer_time: float, integration_dt: float, intersection_threshold: float, min_distance_threshold: float, collision_earth_radius: float, collision_moon_radius: float, rtol: float, atol: float, max_step: float, progress_callback: collections.abc.Callable[[int], Any] | None = None) → list[dict[str, Any]]#

转移网格搜索 Rust 串行后端(阶段 B)。

展平 POD 输入 → 调 transfer_grid_search_serial_py → 转 list[dict]。 返回字段对齐 search_parallel.grid_search_sequential,便于逐候选等价 对照(整数索引精确相等、浮点 allclose)。

本 wrapper 只做数组→dict 转换,不依赖 transfer 算法层(分层:算法层调 数值层合法,数值层不反向依赖)。出发轨道采样(sample_departure_points) 与 Orbit 展平由调用方完成;阶段 D 的 grid_search_rust 编排器会在此之上 接入 TransferSearch。

Args:

dep_states: (n_dep, 6) 或展平 n_dep*6 出发状态。 dep_times: (n_dep,) 出发时刻。 alpha_grid: (n_alpha,) 切向速度比 α 网格。 arrival_states: (n_arrival, 6) 或展平目标轨道状态。 mu / max_transfer_time / integration_dt / intersection_threshold /

min_distance_threshold / collision_earth_radius / collision_moon_radius: CR3BP 与搜索标量配置。

rtol / atol / max_step: 积分器容差与最大步长。 progress_callback: cb(delta: int) -> None,每个 departure 完成

调一次(出发粒度);None 不回调。Rust 端走 channel + drainer 线程,释放 GIL 后实时回调。

Returns:

list[dict],长度 n_dep * n_alpha,顺序为外层 departure、 内层 alpha(与 grid_search_sequential 一致)。

e2m2e.integrators.grid_search_rust(dep_states: numpy.typing.ArrayLike, dep_times: numpy.typing.ArrayLike, alpha_grid: numpy.typing.ArrayLike, arrival_states: numpy.typing.ArrayLike, *, mu: float, max_transfer_time: float, integration_dt: float, intersection_threshold: float, min_distance_threshold: float, collision_earth_radius: float, collision_moon_radius: float, rtol: float, atol: float, max_step: float, parallel: bool | None = None, n_workers: int | None = None, progress_callback: collections.abc.Callable[[int], Any] | None = None) → list[dict[str, Any]]#

转移网格搜索 Rust 后端(阶段 C,Rayon 并行 + GIL 释放)。

展平 POD 输入 → 调 transfer_grid_search_py (py.allow_threads 释放 GIL + Rayon par_iter 真并行)→ 转 list[dict]。返回字段与 顺序与 grid_search_rust_serial() 完全一致——并行与串行逐位相同 (par_iter``+``collect 保序、evaluate_point 纯函数)。 其余参数同 grid_search_rust_serial()。

Args:
parallel: None (默认)时由 E2M2E_SEARCH_PARALLEL 环境变量决定

("0"``→串行,其余/未设→并行);显式 ``True/False 覆盖。 串/并一致性对照用 parallel=False 与 parallel=True 各跑一遍。

n_workers: None (默认)时用 Rayon 全局线程池,线程数由

RAYON_NUM_THREADS 决定(未设则 cpu 核数);显式传入时 Rust 端 建一次性 ThreadPoolBuilder 限定 max(n_workers, 1) 个线程并 install 本次 compute,覆盖 RAYON_NUM_THREADS。串行模式 (parallel=False)下无线程池,此参数被忽略。

progress_callback: cb(delta: int) -> None,每个 departure 完成

调一次(出发粒度);None 不回调。Rust 端走 channel + drainer 线程,释放 GIL 后实时回调。

Returns:

list[dict],长度 n_dep * n_alpha,顺序为外层 departure、内层 alpha。