e2m2e package
e2m2e - Earth to Moon, Moon to Earth Transfer Orbit Design Library
一个用于设计和分析地月空间转移轨道的Python库,专注于圆型限制性三体问题 (CR3BP)中的轨道动力学。五层架构(ADR 0011):data/(数据层)、crates/ (数值层)、algorithm/(算法层)、api/(接口层)、tools/(工具层)。
主要能力:任务轨道设计、轨道保持、转移轨道设计、轨道预报、时空坐标转换。
作者: 天疆说
Subpackages
- e2m2e.algorithm package
- 顶层模块
- e2m2e.algorithm.propagation module
- e2m2e.algorithm.results module
- e2m2e.algorithm.stability module
- e2m2e.algorithm.coordinate package
- e2m2e.algorithm.design package
- e2m2e.algorithm.dynamics package
- e2m2e.algorithm.forces package
- e2m2e.algorithm.solver package
- e2m2e.algorithm.family package
- e2m2e.algorithm.normal_form package
- e2m2e.algorithm.manifold package
- e2m2e.algorithm.nominal_orbit package
- e2m2e.algorithm.proximity package
- e2m2e.algorithm.station_keeping package
- e2m2e.algorithm.transfer package
- e2m2e.algorithm.transfer.config module
- e2m2e.algorithm.transfer.cost module
- e2m2e.algorithm.transfer.propulsion module
- e2m2e.algorithm.transfer.terminal module
- e2m2e.algorithm.transfer.transfer module
- e2m2e.algorithm.transfer.transfer_optimization module
- e2m2e.algorithm.transfer.transfer_search module
- e2m2e.algorithm.transfer.search_geometry module
- e2m2e.algorithm.transfer.search_parallel module
- e2m2e.algorithm.transfer.search_progress module
- e2m2e.algorithm.transfer.solution_database module
- e2m2e.algorithm.transfer.mission_assessment module
- e2m2e.algorithm.transfer.lambert module
- e2m2e.algorithm.transfer.three_body_lambert module
- e2m2e.algorithm.transfer.porkchop module
- e2m2e.algorithm.transfer.multi_impulse module
- e2m2e.algorithm.transfer.hohmann module
- e2m2e.algorithm.transfer.low_energy module
- e2m2e.algorithm.transfer.lga module
- e2m2e.algorithm.transfer.wsb module
- e2m2e.algorithm.transfer.lowthrust_shooting module
- e2m2e.algorithm.transfer.lowthrust_collocation module
- e2m2e.algorithm.transfer.qlaw module
- e2m2e.algorithm.transfer.nlp_core module
- e2m2e.algorithm.transfer.nlp_scipy module
- e2m2e.algorithm.transfer.nlp_copt module
- e2m2e.algorithm.transfer.nsga2 module
- e2m2e.data package
- e2m2e.api package
- e2m2e.mbse package
Submodules
e2m2e.integrators module
Rust 积分器扩展的公共 Python 适配层。
- e2m2e.integrators.augmented_eom_7d_py(forces_py, observer, et, state7, thrust_spec)
7D 受控动力学单点求值(配点法用)。
包装 augmented_eom_7d :给定状态 [r,v,m] 与控制参数 (t_max, isp, throttle, θ₁, θ₂) ,返回 7D 导数。方向由角度参数化还原。
# 参数 - forces_py: 非推力 force 元组列表(格式同 propagate_compiled ) - observer: 传播系 origin - et: 历元时刻(SPICE et 秒) - state7: 状态 [x,y,z,vx,vy,vz,m] - thrust_spec: (t_max, isp, throttle, θ₁, θ₂)
# 返回 7D 导数 [vx,vy,vz, ax,ay,az, ṁ]
- e2m2e.integrators.batch_body_states_py(target, observer, ets)
批量天体状态查询:
target相对observer在 J2000 下的 6 维状态。对齐
SPICEManager.get_body_state(target, et, "J2000", observer)的 逐点循环(ELFO 月心根数提取等场景)。返回行优先(n, 6)展平。
- e2m2e.integrators.batch_et_to_utc_py(et)
批量 ET → UTC 日历分量(年/月/日/时/分/秒)。
对齐
SPICEManager.et_to_utc``("ISOC" 格式、0 位小数秒)的逐点循环, 直接返回六分量数组,免去 Python 侧 ``datetime.fromisoformat字符串解析。 秒为浮点(ISOC prec=0 下为整数秒)。
- e2m2e.integrators.batch_j2000_to_synodic_py(states_j2000, t_syn, et0, mu, t_c)
批量 J2000(km, km/s)→ synodic(无量纲)状态转换。
语义对齐
SynodicJ2000System.j2000_to_synodic``(逐点): ``pos_syn = Rᵀ @ r_j2000 / l_c - [μ,0,0],vel_syn = (Rᵀ @ (v_j2000 - Rdot @ (Rᵀ @ r_j2000)))·t_c / l_c。
- e2m2e.integrators.batch_synodic_to_j2000_py(states_syn, t_syn, et0, mu, t_c)
批量 synodic(无量纲)→ J2000(km, km/s)状态转换。
语义对齐
SynodicJ2000System.synodic_to_j2000``(逐点): ``et = et0 + t_syn·t_c,pos = R @ ((r_syn + [μ,0,0])·l_c),vel = R @ (v_syn·l_c/t_c) + Rdot @ ((r_syn + [μ,0,0])·l_c)。
- e2m2e.integrators.build_cr3bp_hamiltonian_py(mu, gamma, rho_e_ratio, max_degree)
CR3BP Hamiltonian 构造(Jorba-Masdemont
c_n·ρⁿ·P_n(x/ρ)形式)。H = ½‖p‖² + y·p_x − x·p_y − Σ_{n≥2} c_n·ρⁿ·P_n(x/ρ)(地心会合系、 平动点偏移坐标),c_n = (-1)ⁿ/γ³·[μ + (1−μ)·rho_e_ratioⁿ⁺¹](JM 1999 式 1)。Q_n = ρⁿ·P_n(x/ρ)用递推Q_n = ((2n−1)/n)·x·Q_{n−1} − ((n−1)/n)·ρ²·Q_{n−2}展开为(x, y, z)的多项式(纯数值,不依赖 sympy)。参数
mu: 质量比 μ。gamma: 共线平动点的 γ。rho_e_ratio:γ/(1+γ)(L2 的 JM 展开比)。max_degree: 截断阶数(≥2)。
返回
(pows, coefs):(K, 6)幂次(后 3 位动量为 0)与(K,)系数。动能与科里奥利项(½‖p‖²、y·p_x − x·p_y)已包含。
- e2m2e.integrators.center_manifold_reduce_py(tlist, lam, wp, wv, max_order, steps, higher_pows, higher_coefs)
中心流形化简完整 reduce。
参数
tlist: 等距时间采样。
lam, wp, wv: 双曲指数与平面/垂直中心频率(来自 QF 的 D)。
max_order: 截断阶。
steps: "invariant" / "center" 序列。
higher_pows: 高阶项幂次 (K, 6)。
higher_coefs: 高阶项实系数时间序列 (K, N) 或 (K, 1)。
返回
(w_entries, h_pows, h_coefs, pre_coupling, steps_done): - w_entries: (step, order, pow[6], re[N], im[N]) 列表; - h_pows / h_coefs: 化简后实 Hamiltonian; - pre_coupling: 化简前双曲-中心耦合度量; - steps_done: 实际执行步骤。
- e2m2e.integrators.check_collision_py(traj_states, mu, collision_earth_radius, collision_moon_radius)
转移搜索几何核:碰撞检测。
移植自 search_geometry.check_collision 。earth 中心 [-mu,0,0] 、moon 中心 [1-mu,0,0] ;earth 优先(首个命中即返回),无 earth 再扫 moon,比较为严格 < 。 返回 (collision, body|None, idx) ,body 为 "earth"/"moon" 。
- e2m2e.integrators.cm_to_qf_py(x_cm, w_series, rtol=None, atol=None)
中心流形 → quasi-Floquet(高阶 Lie 级数反向)。
- e2m2e.integrators.collinear_center_modes_py(mu, collinear_point)
返回共线点和线性中心模态参数 (x_l, omega_xy, omega_z, y_ratio)。
- class e2m2e.integrators.CowellResult
基类:
object单步 Cowell (Störmer-Cowell) 的结果。x_new 仅含位置; 历史缓冲混合位置与加速度采样(见 cowell_step )。
- error
- h_next
- history
- x_new
- e2m2e.integrators.cowell_step(t, h, tol, accel, history)[源代码]
对
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.compute_distance_series_py(traj_states, orbit_states)
转移搜索几何核:轨迹每步到目标轨道采样点集合的最近距离与索引。
移植自 search_geometry.compute_distance_series (纯数学,非 SPICE 门控)。 traj_states/orbit_states 为 n×6 行优先展平,只用前 3 维位置;n_traj×n_orbit 超过 1e7 时内部分块(与 numpy 同阈值)。argmin 取首个(numpy 约定)。
# 返回 (d_per_step, orbit_idx_per_step) :两个长度 n_traj 的 list。
- e2m2e.integrators.compute_min_distance_py(traj_states, orbit_states)
转移搜索几何核:全局最近点(min_dist, step_idx, orbit_idx)。
移植自 search_geometry.compute_min_distance 。step_idx 为 d_per_step 的 首个最小值索引,orbit_idx = orbit_idx_per_step[step_idx] 。
- e2m2e.integrators.differential_correction_cr3bp_py(*args, **kwargs)[源代码]
调用 Rust CR3BP 微分修正,并返回规范化字典。
- e2m2e.integrators.generate_cr3bp_family_py(family_type, mu, characteristic_length_km, secondary_radius_km, point, n_orbits, max_amplitude_km=None, min_amplitude_km=None, perilune_height_max_km=None, north_south=None, amplitude_in_km=None, amplitude_out_km=None, phase_in=None, phase_out=None, continuation_direction=None, match_tolerance_km=None, n_periods=3, rtol=1e-12, atol=1e-12, max_step=None)
- e2m2e.integrators.generate_cr3bp_family_windows_py(family_type, mu, characteristic_length_km, secondary_radius_km, point, n_orbits, jacobi_windows, max_amplitude_km=None, min_amplitude_km=None, perilune_height_max_km=None, north_south=None, amplitude_in_km=None, amplitude_out_km=None, phase_in=None, phase_out=None, continuation_direction=None, match_tolerance_km=None, n_periods=3, rtol=1e-12, atol=1e-12, max_step=None)
按 Jacobi 能量窗口批量生成轨道族:同一组生成参数下延拓 trace 只走 一次,返回与
jacobi_windows同序的结果列表(每窗口一条,成员 Jacobi 均落在窗口内,边界包含)。窗口成员超上限时按 trace 顺序取 前n_orbits条(与一维扫描的成员上限语义一致)。窗口零成员时 该窗口结果为零成员的结构化软失败;族生成参数与generate_cr3bp_family_py同集(走能量窗口时族延拓范围取各族 默认振幅/近月点上限,由调用方给定)。
- e2m2e.integrators.detect_intersection_py(traj_states, orbit_states, threshold)
转移搜索几何核:相交检测。
移植自 search_geometry.detect_intersection 。全局最近点距离 < threshold 时返回该点完整 6 维状态。返回 (found, point|None, step_idx) ,比较为严格 < 。
- e2m2e.integrators.detect_local_minimum_py(traj_states, orbit_states)
转移搜索几何核:局部极小检测。
移植自 search_geometry.detect_local_minimum 。在每步最近距离序列上找严格 局部极小(两侧严格大于),取所有极小中值最小者(首个并列)。返回 (found, dist, idx) ;无极小 (false, inf, -1) 。
- e2m2e.integrators.disable_ephem_cache()
关闭 Rust 星历缓存(回到逐次 cspice 查询)。
- e2m2e.integrators.enable_ephem_cache(targets, frame_pairs, et_start, et_end, dt=3600.0, *, sxform_pairs=None)
激活 Rust 星历预采样缓存。
在积分前把要用到的天体状态与帧旋转矩阵在均匀网格上预采样、建三次样条, 装入进程级缓存。此后 Rust 力模型(ThirdBody/IndirectTerm/GravityField/Relativistic) 每步查表,不再调 cspice FFI。需在 SPICE 内核已加载后调用。
参数
targets: 要缓存的天体对[(target, observer), ...],如[("MOON", "EARTH"), ("SUN", "EARTH"), ("EARTH", "SOLAR SYSTEM BARYCENTER")]frame_pairs: 要缓存的帧旋转对[(from, to), ...],如[("ITRF93", "J2000"), ("MOON_PA", "J2000")]sxform_pairs: 要缓存的 6×6 状态变换对[(from, to), ...],如[("ITRF93", "J2000")](Lense-Thirring 用)。关键字参数,默认None。et_start,et_end: 积分时间范围(SPICE et 秒)dt: 网格步长(秒),默认 3600
- e2m2e.integrators.ephem_ffi_call_count()
返回 cspice FFI 调用计数(验证"零 cspice"用)。
- e2m2e.integrators.grid_search_rust(dep_states, dep_times, alpha_grid, arrival_states, *, mu, max_transfer_time, integration_dt, intersection_threshold, min_distance_threshold, collision_earth_radius, collision_moon_radius, rtol, atol, max_step, parallel=None, n_workers=None, progress_callback=None)[源代码]
转移网格搜索 Rust 后端(阶段 C,Rayon 并行 + GIL 释放)。
展平 POD 输入 → 调
transfer_grid_search_py(py.allow_threads释放 GIL + Rayonpar_iter真并行)→ 转list[dict]。返回字段与 顺序与grid_search_rust_serial()完全一致——并行与串行逐位相同 (par_iter``+``collect保序、evaluate_point纯函数)。 其余参数同grid_search_rust_serial()。- 参数:
parallel (bool | None) --
None(默认)时由E2M2E_SEARCH_PARALLEL环境变量决定 ("0"``→串行,其余/未设→并行);显式 ``True/False覆盖。 串/并一致性对照用parallel=False与parallel=True各跑一遍。n_workers (int | None) --
None(默认)时用 Rayon 全局线程池,线程数由RAYON_NUM_THREADS决定(未设则 cpu 核数);显式传入时 Rust 端 建一次性ThreadPoolBuilder限定max(n_workers, 1)个线程并install本次 compute,覆盖RAYON_NUM_THREADS。串行模式 (parallel=False)下无线程池,此参数被忽略。progress_callback (Callable[[int], Any] | None) --
cb(delta: int) -> None,每个 departure 完成 调一次(出发粒度);None不回调。Rust 端走 channel + drainer 线程,释放 GIL 后实时回调。dep_states (ArrayLike)
dep_times (ArrayLike)
alpha_grid (ArrayLike)
arrival_states (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)
- 返回:
list[dict],长度n_dep * n_alpha,顺序为外层 departure、内层 alpha。- 返回类型:
- e2m2e.integrators.grid_search_rust_serial(dep_states, dep_times, alpha_grid, arrival_states, *, mu, max_transfer_time, integration_dt, intersection_threshold, min_distance_threshold, collision_earth_radius, collision_moon_radius, rtol, atol, max_step, progress_callback=None)[源代码]
转移网格搜索 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。- 参数:
dep_states (ArrayLike) --
(n_dep, 6)或展平n_dep*6出发状态。dep_times (ArrayLike) --
(n_dep,)出发时刻。alpha_grid (ArrayLike) --
(n_alpha,)切向速度比 α 网格。arrival_states (ArrayLike) --
(n_arrival, 6)或展平目标轨道状态。/ (mu / max_transfer_time / integration_dt / intersection_threshold) -- min_distance_threshold / collision_earth_radius / collision_moon_radius: CR3BP 与搜索标量配置。
max_step (float) -- 积分器容差与最大步长。
progress_callback (Callable[[int], Any] | None) --
cb(delta: int) -> None,每个 departure 完成 调一次(出发粒度);None不回调。Rust 端走 channel + drainer 线程,释放 GIL 后实时回调。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
- 返回:
list[dict],长度n_dep * n_alpha,顺序为外层 departure、 内层 alpha(与grid_search_sequential一致)。- 返回类型:
- e2m2e.integrators.hello_integrators()
占位函数,用于验证 FFI 路径端到端通畅。
- e2m2e.integrators.indirect_term_acceleration(et, target, observer, mu)
第三体间接项加速度:a = -μ · r_ob / |r_ob|³ 。
移植自 Python IndirectTerm.compute_acceleration 。
- e2m2e.integrators.initialize_abm_history(t0, y0, h, f, n_stages=3, tol=1e-12)[源代码]
以
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.initialize_cowell_history(t0, x0, v0, h, accel, n_startup=7, tol=1e-12)[源代码]
以
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.keys_by_order_py(pows)
按总阶数分组返回幂次键(每组内排序)。
- e2m2e.integrators.lambert_batch_py(geometries, tofs, mu, long_way, revs)
N×M 网格批量 Lambert 求解(porkchop 用)的 Python 接口。
# 参数 - geometries :几何列表,每项 [r0x, r0y, r0z, rfx, rfy, rfz] (km) - tofs :飞行时间列表(s),对每个几何都求解一遍 - mu/long_way/revs :同 lambert_izzo_py
# 返回 长度 len(geometries) * len(tofs) 的 list(几何在外,tof 在内), 每项为 dict 或 None(该组合无解)。
- e2m2e.integrators.lambert_izzo_py(r0, rf, tof, mu, long_way, revs)
二体 Lambert 求解(Izzo 算法)的 Python 接口。
# 参数 - r0/rf :出发/到达位置 [x, y, z](km) - tof :飞行时间(s) - mu :中心天体 GM(km³/s²) - long_way :True 取长程解(转移角 > π) - revs :完整圈数(≥ 1 时返回右分支低能解)
# 返回 Python dict:{"v0": [3], "vf": [3], "n_iter": int} ;无解/不收敛抛 ValueError。
- e2m2e.integrators.low_energy_patch_rust(states_a, states_b, weights, *, parallel=None, n_workers=None, progress_callback=None)[源代码]
低能转移流形截面态配对的 Rust 后端。
输入为两组
(n, 6)截面态,Rust 完成全部配对、位置/速度范数、 加权代价和稳定排序。parallel=None时由E2M2E_LOW_ENERGY_PARALLEL决定是否使用 Rayon;显式n_workers为本次调用建立一次性线程池。
- e2m2e.integrators.lowthrust_collocation_defects_py(states, controls, t0, tf, observer, forces_py, t_max, isp)
Hermite-Simpson 配点缺陷的批量求值。
- e2m2e.integrators.lowthrust_shooting_evaluate_py(controls, t0, tf, initial_state, observer, forces_py, t_max, isp, with_jacobian)
多段低推力打靶评估:接龙传播,并按需组装末端控制灵敏度。
- e2m2e.integrators.lissajous_bounded_trajectory_py(mu, collinear_point, char_length_km, amplitude_in_km, amplitude_out_km, phase_in, phase_out, n_periods=3, points_per_period=60)
Rust Lissajous 线性中心流多点轨迹。
面内与面外中心模态分别按独立频率解析推进;不把状态重新送入含双曲方向的 完整 CR3BP,因此轨迹按构造保持有界。该结果是参数采样轨迹,不宣称周期闭合。
- e2m2e.integrators.manifold_propagate_py(mu, seeds, kind, t_span, sample_dt, rtol, atol, max_step=None, *, n_workers=None, parallel=None)
Python 接口:不变流形批量弧传播。
输入展平种子
n*6;kind 决定积分方向;单弧失败跳过。n_workers>1 或环境变量E2M2E_MANIFOLD_PARALLEL!=0时走 Rayon。
- e2m2e.integrators.manifold_seeds_py(mu, initial_state, period, kind, branch_sign, epsilon, n_points, rtol, atol, max_step=None)
Python 接口:不变流形种子生成。
相位扫掠(STM)、单值矩阵双曲实特征选取、转运归一化与 ±ε 扰动均在 Rust 完成;全程
py.allow_threads,无 Python 数值回退。
- class e2m2e.integrators.MultistepMethod
基类:
object显式多步方法。与 RkMethod 分开,因为多步方法携带历史缓冲, 不能共享无状态的单步入口。启用 pyo3 feature 时暴露给 Python。
- ABM = MultistepMethod.ABM
- class e2m2e.integrators.MultistepResult
基类:
object单步多步的结果。携带滚动后的历史缓冲,供 Python 传播循环传入下一步调用。
- error
- h_next
- history
- y_new
- e2m2e.integrators.multistep_step(method, t, y, h, tol, f, history)[源代码]
执行单个多步预测-校正步。
history须按从旧到新的顺序保存method.steps()个导数样本,每个样本 与y等长,间隔均为h。回调f的签名与rk_step()相同。 返回MultistepResult,其history是供下一步使用的滚动缓冲区。假定步长固定;改变
h后须重新初始化 history(见initialize_abm_history())。
- e2m2e.integrators.nsga2_environmental_selection_py(rank, crowd, n_keep)
按
(rank, -crowding)进行环境选择。
- e2m2e.integrators.nsga2_sort_py(fit, viol)
Deb 可行支配规则的非支配排序与拥挤度距离。
- e2m2e.integrators.nsga2_tournament_selection_py(rank, crowd, draws)
使用 Python 已按原顺序产生的随机索引执行二元锦标赛。
- e2m2e.integrators.nsga2_variation_py(parents, lo, hi, crossover_prob, eta_c, mutation_prob, eta_m, crossover_draws, gene_draws, beta_draws, swap_draws, mutation_draws, mutation_value_draws)
执行 SBX 交叉与多项式变异。
随机抽样由 Python 按既有条件分支顺序准备;未使用的位置允许为 NaN。
- e2m2e.integrators.orbit_family_metric_py(mu, metric, point, initial_state, period, rtol=1e-12, atol=1e-12, max_step=None, sample_count=1000)
传播周期轨道并在 Rust 内测量族几何量。
metric 可取 moon-distance、l45-distance 或 z-amplitude;返回对应 绝对距离或振幅的 (minimum, maximum)(无量纲)。
- e2m2e.integrators.pal_f_df_tangent_py(mu, x, sv0, rtol, atol, max_step)
PAL 延拓:XZ 平面对称约束的 F/dF/切向量单次计算(#443)。
对应 Python continuation.compute_F_and_dF_symmetric_xz_plane + compute_tangent_vector (纯数值,非 SPICE 门控)。供延拓收敛轨道后的 切向量刷新;初始切向量两后端统一走 Python 参照计算(零空间符号约定 在 SVD 与广义叉积间无保证,首步方向由 Python 侧锁定)。
# 返回 Python dict:{"f": [3], "df": [[4], [4], [4]], "tangent": [4], "final_state": [6]}。
- e2m2e.integrators.pal_newton_step_py(mu, x_start, x_ref, sv0, tangent_ref, ds, tol, iter_max, rtol, atol, max_step)
PAL 延拓:单步牛顿迭代(#443)。
对应 Python pseudo_arclength_continuation 的内层牛顿循环:从预测点 x_start 出发解 G = [F; (Xnew - x_ref)·tangent_ref - ds] = 0 ,先判 收敛再更新,牛顿步按 [0.04, 0.12, 0.12, 0.08] 分量裁剪。无论收敛与否 都返回当前 x_new (对应 Python 循环 break/耗尽后继续用最后值)。
# 返回 Python dict:{"x_new": [4], "tangent": [4], "iterations": int, "residual": float, "converged": bool, "singular": bool}。
- e2m2e.integrators.pole_tide(et, xp, yp)
极潮(固体极潮 + 海洋极潮,IERS TN32)。返回长度 50 的
Vec<f64>(C25 + S25)。
- e2m2e.integrators.poly_poisson_py(pows1, coefs1_flat, pows2, coefs2_flat, series_len)
6-DOF 辛 Poisson 括号
{poly1, poly2}(标量或时间序列、实/复)。系数编码:
coefs_flat为n * series_len * 2的交错(re, im);series_len=1表示标量。
- e2m2e.integrators.poly_simplify_py(pows, coefs_flat, series_len, eps)
标量系数 simplify:合并同幂次,剔除模长 ≤ eps 的项(
|coef| ≤ eps)。与 Python
poly_simplify数值路径一致;series_len通常为 1, 但接口允许序列(按任一分量模阈值,同_is_zero)。
- e2m2e.integrators.polylist_simplify_py(pows, coefs_flat, series_len, eps)
时间序列 simplify:合并同幂次,剔除
mean(|coef|) ≤ eps的项。与 Python
polylist_simplify一致。
- e2m2e.integrators.porkchop_grid_py(t_dep, tof, dep_kind, dep_state, dep_t0, dep_period, arr_kind, arr_state, arr_t0, arr_period, mu_cr3bp, rtol, atol, max_step, mu_central, long_way, revs, *, parallel=None)
porkchop 网格扫描 Rust 后端(规格路径,#446):终端传播 + Lambert + ΔV 组装。
照搬
transfer_grid_search_py的py.allow_threads+ Rayon + 环境变量 开关范式(对称E2M2E_SEARCH_PARALLEL):默认并行,parallel=False或E2M2E_PORKCHOP_PARALLEL=0强制串行,两者逐位一致。参数
t_dep/tof:出发时刻与飞行时间网格。dep_kind/arr_kind:"orbit"(周期轨道终端:*_state为首点 状态、*_t0时间原点、*_period周期)或"state"(固定状态终端, 仅*_state有意义)。mu_cr3bp/rtol/atol/max_step:CR3BP 质量参数与终端 传播积分器配置;两端均为"state"时均传None(无需传播)。mu_central/long_way/revs:Lambert 求解配置。
返回
(dv1, dv2)展平列表,长度len(t_dep) * len(tof),行优先(t_dep 主序); 无解组合为 NaN。
- e2m2e.integrators.porkchop_grid_states_py(dep_states, arr_states, tof, mu_central, long_way, revs, *, parallel=None)
porkchop 网格扫描 Rust 后端(状态网格路径,#446):终端状态已由 Python 按 get_arrival_state 协议预提取,本入口只做 Lambert + ΔV 组装。
参数
dep_states:展平n*6,dep_states[i*6..]为t_dep[i]时刻出发状态。arr_states:展平n*m*6,行优先(t_dep 主序),arr_states[(i*m+j)*6..]为t_dep[i] + tof[j]时刻到达状态。tof/mu_central/long_way/revs/parallel:同porkchop_grid_py。
返回 同
porkchop_grid_py。
- e2m2e.integrators.project_hamiltonian_qf_py(pows, coefs, b_seq)
H→QF 投影:
X = B·Y单项式替换展开(对应 qiaoCode09)。- 参数:
pows --
(N_in, 6)输入单项式的幂次(平动点偏移坐标)。coefs --
(N_in,)输入单项式的标量系数(CR3BP 自治,常数)。b_seq --
(M, 36)每个采样时刻的 6×6 变换矩阵B(t)展平。
- 返回:
(out_pows, out_coefs):out_pows为(K, 6)展开后幂次 并集(排序),out_coefs为(M, K)逐时刻系数矩阵。
- e2m2e.integrators.qf_to_cm_py(x_qf, w_series, rtol=None, atol=None)
quasi-Floquet → 中心流形(高阶 Lie 级数,12 实维 DOP853)。
- 参数:
x_qf -- 长度 6 的实 QF 状态
w_series --
[(order, exps, coefs_re, coefs_im), ...]atol (rtol /) -- ODE 容差(默认与 Python 一致 1e-11 / 1e-13)
- e2m2e.integrators.qlaw_propagate_py(t0, tf, y0, target_oe, mu, t_max, isp, h_init, tol, max_steps)
Q-law 低推力反馈积分(完整热路径在 Rust,#442)。
- e2m2e.integrators.qlaw_segment_direction_py(state7, target_oe, mu, t_max)
Q-law 段中点评估:Q 值、开普勒根数和惯性系推力方向。
- e2m2e.integrators.trim_degree_py(pows, coefs_flat, series_len, max_degree)
截断总阶数大于
max_degree的项;空结果退回零多项式。
- e2m2e.integrators.propagate_compiled(method, t0, y0, h_init, tol, t_eval, observer, forces_py, max_steps)
全 Rust 力模型传播器(消除 Python↔Rust 跨界)。
Python 侧把所有 force 序列化为元组列表,Rust 在内部循环里直接调 compute_total_acceleration ,每个 RK 子阶段不再跨界回 Python。
# 参数 - method: RkMethod - t0/y0: 初始时刻与状态 - h_init: 初始步长 - tol: 容差 - t_eval: 评估时刻数组 - observer: 传播系 origin(如 "EARTH") - forces_py: force 元组列表 - max_steps: 最大步数
# 返回 Python dict:{"time": [...], "states": [[...]], "n_steps": int, "n_rejected": int}
- e2m2e.integrators.propagate_compiled_lowthrust(method, t0, y0, h_init, tol, t_eval, observer, forces_py, thrust_spec, max_steps)
7D 可变质量低推力传播:状态 [x, y, z, vx, vy, vz, m] 。
受控动力学复用 e2m2e-forces 的 augmented_eom_7d :重力走 compute_total_acceleration ,推力与质量流走 ThrustParams 。控制律为 常量 throttle 与常量方向(与 ThrustParams 的常量语义对齐);时变控制 留待求解器期次。
# 参数 - method: RK 方法 - t0: 起始时刻(SPICE et 秒) - y0: 初始状态,长度 7 - h_init: 初始步长 - tol: 步长误差容差 - t_eval: 评估时刻数组 - observer: 传播系 origin(如 "EARTH") - forces_py: 非推力 force 元组列表(格式同 propagate_compiled ) - thrust_spec: (t_max, isp, throttle, dir_x, dir_y, dir_z) - max_steps: 最大步数
# 返回 Python dict:{"time": [...], "states": [[7], ...], "n_steps": int, "n_rejected": int}
- e2m2e.integrators.propagate_compiled_lowthrust_sensitivity(method, t0, y0, h_init, tol, t_eval, observer, forces_py, thrust_spec, max_steps)
7D 可变质量低推力 + 灵敏度传播(64D 增广状态)。
在
propagate_compiled_lowthrust(7D 受控)基础上,同时积分: - Φ(6×6 状态对初值 STM,链式接龙用) - S(7×3 状态对控制参数 (throttle, θ₁, θ₂) 的灵敏度)一次传播同时产出末端状态、STM、灵敏度,供低推力求解器组装解析雅可比 (替代 SLSQP 数值差分)。详见
docs/plans/lowthrust-analytic-jacobian-prd.md。参数
method: RK 方法t0: 起始时刻(SPICE et 秒)y0: 初始状态,长度 7h_init,tol: 步长控制t_eval: 评估时刻数组(取首末两点即可)observer: 传播系 originforces_py: 非推力 force 元组列表thrust_spec:(t_max, isp, throttle, θ₁, θ₂)max_steps: 最大步数
返回
Python dict:
{"time": [...], "states": [[7]], "stm": [[36]], "sensitivity": [[21]], "n_steps": int, "n_rejected": int}(均为末端时刻的值序列)
- e2m2e.integrators.propagate_compiled_stm_py(observer, forces_py, t_span, t_eval, initial_state, rtol, atol, max_step=None, max_steps=None, method=Ellipsis)
编译型力模型 + STM 的 PD45 传播(消除 cspice 隔离)。
与
propagate_with_stm_py(纯 NBody)不同,本函数支持所有编译型力模型: PointMass、GravityField、ThirdBody、IndirectTerm、SRP、Relativistic。 使用 integrators crate 的 cspice 实例,避免跨 .so 内核池隔离问题。参数
observer: 传播系 origin 天体名(如 "EARTH")forces_py: force 元组列表(格式同propagate_compiled)t_span:(t_start, t_end)积分区间(SPICE et 秒)t_eval: 输出时间点数组initial_state: 初始状态[x, y, z, vx, vy, vz](km, km/s)rtol,atol: 积分容差max_step: 最大步长(秒),None则不限制max_steps: 最大步数,None则用默认上限
返回
Python dict:
{"states": [[6], ...], "stm": [[36], ...], "time": [...], "n_steps": int, "n_rejected": int}
- e2m2e.integrators.propagate_bcr4bp_py(mu, mu_sun, sun_distance, sun_angular_rate, sun_phase0, t_span, t_eval, initial_state, rtol, atol, max_step=None, max_steps=None)
Python 接口:BCR4BP 6 维纯状态传播(PD78)。
纯数学(无量纲),不依赖 SPICE。在 CR3BP 之上叠加太阳质点摄动,太阳 位置由解析公式 r_s(t) = a_s·(cos θ, sin θ, 0) 、θ = θ0 + ω_s·t 给出。 循环结构与 propagate_cr3bp_py 一致;RK callback 把当前步时间传入 EOM (BCR4BP 显式含时)。供 BCR4BP_Dynamics 透明走 Rust。
# 参数 - mu: 地月质量参数 μ = m₂/(m₁+m₂) - mu_sun: 太阳无量纲质量 m_s = GM_sun / GM_EMB - sun_distance: 太阳圆周轨道半径 a_s(无量纲) - sun_angular_rate: 太阳会合系角速度 ω_s(无量纲,负值表示逆行) - sun_phase0: t = 0 时刻的太阳相位角 θ0(弧度) - t_span: (t_start, t_end) 积分区间(无量纲时间) - t_eval: 输出时间点数组 - initial_state: 初始状态 [x, y, z, vx, vy, vz] - rtol, atol: 积分容差 - max_step: 最大步长,None 则不限制 - max_steps: 最大步数,None 则用默认上限
# 返回 Python dict:{"time": [...], "states": [[6], ...], "n_steps": int, "n_rejected": int}
- e2m2e.integrators.propagate_bcr4bp_stm_py(mu, mu_sun, sun_distance, sun_angular_rate, sun_phase0, t_span, t_eval, initial_state, rtol, atol, max_step=None, max_steps=None)
Python 接口:BCR4BP 42 维增广状态传播(状态 + STM,PD78)。
纯数学(无量纲),不依赖 SPICE。初始 STM 设为单位矩阵;步长误差控制只 统计前 6 维,避免 STM 分量主导步长。参数同 propagate_bcr4bp_py 。
# 返回 Python dict:{"states": [[6], ...], "stm": [[36], ...], "time": [...], "n_steps": int, "n_rejected": int};stm[k][i*6+j] = ∂state(t_k)[i]/∂state(t0)[j] 。
- e2m2e.integrators.propagate_cr3bp_py(mu, t_span, t_eval, initial_state, rtol, atol, max_step=None, max_steps=None)
Python 接口:CR3BP 6 维纯状态传播(PD78)。
纯数学(无量纲),不依赖 SPICE。供 CR3BP_Dynamics 透明走 Rust。 循环结构与 propagate_compiled_stm 一致,保证与带 STM 路径的 states 逐位相同。
# 参数 - mu: 质量参数 μ = m₂/(m₁+m₂) - t_span: (t_start, t_end) 积分区间(无量纲时间) - t_eval: 输出时间点数组 - initial_state: 初始状态 [x, y, z, vx, vy, vz] - rtol, atol: 积分容差 - max_step: 最大步长,None 则不限制 - max_steps: 最大步数,None 则用默认上限
# 返回 Python dict:{"time": [...], "states": [[6], ...], "n_steps": int, "n_rejected": int}
- e2m2e.integrators.propagate_cr3bp_stm_py(mu, t_span, t_eval, initial_state, rtol, atol, max_step=None, max_steps=None)
Python 接口:CR3BP 42 维增广状态传播(状态 + STM,PD78)。
纯数学(无量纲),不依赖 SPICE。初始 STM 设为单位矩阵;步长误差控制只 统计前 6 维,避免 STM 分量主导步长。
# 参数 同 propagate_cr3bp_py 。
# 返回 Python dict:{"states": [[6], ...], "stm": [[36], ...], "time": [...], "n_steps": int, "n_rejected": int};stm[k][i*6+j] = ∂state(t_k)[i]/∂state(t0)[j] 。
- e2m2e.integrators.propagate_segments_py(observer, forces, seg_t0, seg_t1, seg_states, t_eval_list, rtol, max_steps=500000, method=Ellipsis)
多段并发积分(segmented 逐段积分填 et_grid 用,issue #400 性能下沉)。
每段从
seg_states[i]积分到seg_t1[i],输出t_eval_list[i]逐点对应的状态序列(不追加段终点,语义同 propagate_compiled_core )。 段间独立(只依赖本段输入),rayon 并发;并行前提与多重打靶段积分相同 (strict + 预采样星历缓存,零 cspice FFI)。rayon 保序 collect + 各段 积分确定 → 并行与串行位级一致(E2M2E_MS_PARALLEL=0强制串行)。初值步长上限复刻 Python
ForceModel._estimate_initial_step(2πr/v/100), 与fm.propagate路径的步长控制语义一致。
- e2m2e.integrators.propagate_with_state_py(bodies, origin, gm_values, t_span, t_eval, initial_state, rtol, atol, max_step=None, max_steps=None)
Python 接口:6 维纯状态传播(不含 STM)。
纯 N 体模型,与 propagate_with_stm_py 同用 solve_ivp_capped ,保证 两条路径的 states 前 6 维逐位相等(parity)。供 EphemerisDynamics 的纯状态路径(with_stm=False )透明走 Rust,省去 42 维 STM 的开销。
# 参数 同 propagate_with_stm_py ,但不返回 STM。
# 返回 Python dict:{"states": [[6], ...], "time": [...]}
- e2m2e.integrators.propagate_with_stm_py(bodies, origin, gm_values, t_span, t_eval, initial_state, rtol, atol, max_step=None, max_steps=None)
Python 接口:42 维增广状态传播(状态 + STM)。
纯 N 体模型(EARTH/MOON/SUN 等),用于星历修正的逐段积分。 调用
e2m2e-forces的propagate_with_stm(DOP853 + STM 变分方程)。参数
bodies: 天体名称列表(如["EARTH", "MOON", "SUN"])origin: 原点天体名称(如"EARTH")gm_values: 各天体的 GM(km³/s²),与bodies一一对应t_span:(t_start, t_end)积分区间(SPICE et 秒)t_eval: 输出时间点数组initial_state: 初始状态[x, y, z, vx, vy, vz](km, km/s)rtol,atol: 积分容差max_step: 最大步长(秒),None则不限制max_steps: 最大步数,None则用默认上限
返回
Python dict:
{"states": [[6], ...], "stm": [[36], ...], "time": [...]}
- e2m2e.integrators.reset_ephem_ffi_call_count()
清零 cspice FFI 调用计数。
- e2m2e.integrators.rk_step(method, t, y, h, tol, f, state_error_dim=None)[源代码]
使用 Rust 积分器内核执行单个 Runge-Kutta 步。
回调
f接收 NumPy ndarray,并须返回同长度数组。返回的StepResult包含y_new、error、h_next。state_error_dim:步长误差控制只统计前 N 维(None时统计全部)。 STM 增广传播时传 6,让状态转移矩阵的 36 个分量不主导步长控制。
- class e2m2e.integrators.RkMethod
基类:
object单步 Runge-Kutta 方法枚举。启用 pyo3 feature 时暴露给 Python。
每种方法对应一张 Butcher 表(见 [crate::butcher::ButcherTable])。
- PD45 = RkMethod.PD45
- PD78 = RkMethod.PD78
- RK89 = RkMethod.RK89
- e2m2e.integrators.require_rust_extension(*required_symbols)[源代码]
确保 Rust 扩展可用且指定的模块级符号存在;否则抛
RustExtensionUnavailableError。在使用 Rust 扩展符号的每个入口调用。扩展未构建、构建不含 spice feature、或符号缺失时,抛带
make dev指引的RustExtensionUnavailableError——不允许静默回退到 Python/scipy (issue #378)。required_symbols是e2m2e.integrators模块级 符号名;扩展缺失时符号为None。示例
>>> require_rust_extension("propagate_compiled", "spice_furnsh")
- 参数:
required_symbols (str)
- 返回类型:
None
- e2m2e.integrators.solid_tide_step1(perturbers_flat, k_love_flat, k_plus_flat, mu_central, r_central)
固体潮 Step 1(频率无关,天体无关)。
Python 侧 earth_tide.solid_tide_step1 的 Rust 加速版。输入扰动体位置由 Python 完成坐标变换后传入(本函数不查 SPICE)。
参数
perturbers_flat:扁平化扰动体列表,每 4 个一组[px, py, pz, gm](位置 km、 gm km³/s²)。长度必须是 4 的倍数。k_love_flat:Love 数表 5×5 行优先扁平化,长度 25。k_plus_flat:弹性 Love 数 5 元素,或None(无贡献)。mu_central、r_central:中心天体 GM 与参考半径。
返回
长度 50 的
Vec<f64>:C(25) ++ S(25),各为 5×5 行优先扁平化。
- e2m2e.integrators.solid_tide_step2(et)
固体潮 Step 2(频率相关,地球专用)。返回长度 50 的
Vec<f64>(C25 + S25)。
- e2m2e.integrators.solve_ivp_events(t_span, y0, t_eval, rtol, atol, f, events, method=None, max_step=None, max_steps=None, state_error_dim=None)[源代码]
带事件检测的 Rust solve_ivp 封装(scipy 事件语义)。
事件检测在 Rust 积分内循环完成:每个接受步的端点评估事件函数, 符号变化(经 direction 过滤)时在步内对线性插值态二分求精(无稠密输出)。
- 参数:
y0 (ArrayLike) -- 初始状态向量。
t_eval (ArrayLike) -- 输出时间点数组。
rtol (float) -- 相对容差。
atol (float) -- 绝对容差。
f (Callable[[float, ndarray[tuple[Any, ...], dtype[floating]]], ndarray[tuple[Any, ...], dtype[floating]]]) -- ODE 右端函数
f(t, y) -> dy/dt。events (list[tuple[Callable[[float, ndarray[tuple[Any, ...], dtype[floating]]], float], bool, float]]) --
[(g, terminal, direction), ...],g(t, y) -> float, 零点即事件面;terminal=True触发即停;direction> 0 只记 上行穿越(g 由负到正)、< 0 只记下行、0 双向。method (RkMethod | None) -- RK 方法,默认 PD78(DOP853)。
max_step (float | None) -- 最大步长。求精精度受步内线性插值误差(
~h²/8·|ÿ|)限制, 需要更紧的事件时刻时请设小 max_step。max_steps (int | None) -- 最大积分步数。
state_error_dim (int | None) -- 步长误差控制只统计前 N 维(用于 STM 增广传播)。
- 返回:
dict:
states/time(t_eval 前缀,terminal 截断时末点为求精后的 事件点)、t_events/y_events(逐事件的触发时刻与状态列表)、terminal_event(触发终止的事件索引或 None)、n_steps。- 返回类型:
- e2m2e.integrators.solve_ivp_events_py(t_span, y0, t_eval, rtol, atol, f, events, method=None, max_step=None, max_steps=None, state_error_dim=None)
Python 接口:带事件检测的自适应步长 ODE 积分器。
事件检测在 Rust 积分内循环完成:每个接受步的端点评估事件函数, 符号变化(经 direction 过滤)时在步内对线性插值态二分求精(无稠密输出)。
参数
events:[(callable, terminal, direction), ...],callable 为g(t, y) -> float;terminal=True触发即停;direction> 0 只记 上行穿越、< 0 只记下行、0 双向(scipysolve_ivp语义)method: RK 方法(默认Pd78,即 DOP853)其余参数同
solve_ivp_py
返回
Python dict:
{"states", "time", "n_steps", "t_events", "y_events", "terminal_event"}; terminal 截断时time/states末点为求精后的事件点,terminal_event为触发终止的事件索引(未终止为 None)。
- e2m2e.integrators.solve_hjb_py(terminal, minimum, maximum, shape, t0, tf, dynamics, params, cfl, max_step)
通用 HJB 求解入口。
dynamics 为动力学标识,当前支持:
"planar_double_integrator":平面双积分器,参数 drift_x、drift_y、 max_accel、fuel_weight;"cr3bp_synodic":地月会合系无量纲平面 CR3BP,参数 mu、 max_accel、fuel_weight;"ephemeris_planar"``(需 spice):平面全星历脉动会合系(#498, ADR 0034),参数 mu_earth、mu_moon、mu_sun(km³/s²)、et0(求解器 t=0 对应的 SPICE et)、thrust(N)、isp(s)、g0(m/s²)、fuel_weight、 mass_mode(0 = 4 维固定质量,需 fixed_mass;1 = 5 维含质量轴, 单位 kg)。求解器 t 单位为秒;调用前须 ``enable_ephem_cache覆盖 [et0+t0, et0+tf],求解阶段零 cspice。
terminal 为终端代价 ψ 的扁平数组(C 序,长度等于网格节点数)。 返回字典:
times升序时刻、values逐快照拼接的值函数 (C 序,形状 (len(times), ×shape))、axes各维节点坐标、steps实际积分步数。快照按时间近似等距抽样,数量有上界, 高维网格不会返回完整时间序列。值函数产物落盘时,调用方须按 ADR 0033 决策 3 补足元数据:动力学 标识与参数表、状态维顺序、无量纲化口径、
times语义 (ephemeris_planar 为求解器秒,ET = et0 + times)、历元映射参数。
- e2m2e.integrators.solve_planar_lowthrust_hjb_py(terminal, minimum, maximum, shape, t0, tf, drift_accel, max_accel, fuel_weight, cfl, max_step)
geo-nrho 既有调用签名的兼容包装:平面双积分器低推力 HJB。
参数顺序与 geo-nrho algorithm/dp.py 的 solve_low_dim_hjb 调用一致, 语义等同 solve_hjb_py(dynamics="planar_double_integrator", ...)。
- e2m2e.integrators.spice_furnsh(path)
在 Rust cspice 内核池加载一个内核文件。
Rust cspice 与 Python spiceypy 是**独立的 CSPICE 实例** (静态链接,全局状态 不共享)。Python 侧 furnsh 的内核,Rust 看不见;反之亦然。要让 Rust 查询 可用,必须用本函数在 Rust 侧再 furnsh 一次(同一份文件,两边独立加载)。
同时在首次加载时把行星名注册到质心/本体 ID(register_bodies ),使本 实例对 "MARS"/"JUPITER" 等的解析与 Python spiceypy 实例(那边在 manager.load_kernel 里 boddef)以及 DFH 一致——否则 CSPICE 默认表会把 "MARS" 解析成不存在的本体 499。
- e2m2e.integrators.spice_pxform()
诊断用:在 Rust CSPICE 实例上查 pxform(与 spiceypy.pxform 同名函数对齐)。
用于对比 Python(spiceypy)与 Rust(cspice-sys)两个独立 CSPICE 实例的 帧旋转查询,排查内核加载同步问题。常规查询仍走
SPICEManager/ spiceypy。返回 3×3 行优先矩阵。
- e2m2e.integrators.spice_spkezr(target, et, frame, abcorr, observer)
诊断用:在 Rust CSPICE 实例上查 spkezr(与 spiceypy.spkezr 同名函数对齐)。
用于对比 Python(spiceypy)与 Rust(cspice-sys)两个独立 CSPICE 实例的 查询结果,排查内核加载 / boddef 同步问题。常规查询仍走
SPICEManager/ spiceypy。返回(state[6], lt)。
- e2m2e.integrators.spice_unload(path)
从 Rust cspice 内核池卸载一个内核文件(与 [spice_furnsh] 对称)。
Rust cspice 与 Python spiceypy 独立(见 [spice_furnsh] 文档)。 SPICEManager.load_kernel 双 furnsh,卸载必须对称:否则 Rust 内核池残留 已卸载文件,测试结果依赖同进程执行顺序(issue #387)。只卸载清单中 确已加载的文件,其余静默跳过(保持幂等语义)。
- e2m2e.integrators.spherical_harmonic_accel(r, c_flat, s_flat, mu, radius, degree, order)
球谐引力加速度(body-fixed 系)。
Python 侧 GravityField._compute_acceleration_in_input_frame 的 Rust 加速版。 输入位置 r 与输出加速度均在 body-fixed 系(坐标变换仍由 Python 完成)。 c_flat/s_flat 是 C/S 系数矩阵的行优先扁平化(shape=(degree+1)**2)。
- e2m2e.integrators.srp_acceleration(et, sc_pos, area, mass, cr, shadow_bodies, observer)
SRP 加速度(含阴影)。
移植自 Python SolarRadiationPressure.compute_acceleration 。
# 参数 - et :SPICE et 秒 - sc_pos :航天器位置 [x, y, z] km(observer 系下) - area/mass/cr :SRP cannonball 参数(area m²、mass kg、cr 无量纲) - shadow_bodies :遮挡体名称列表(如 ["EARTH", "MOON"]),空 = 无阴影 - observer :观察者天体(通常 "EARTH")
- e2m2e.integrators.third_body_acceleration(et, target, observer, sc_pos, mu)
第三体摄动加速度(含直接项 + 间接项)。
移植自 Python ThirdBodyGravity.compute_acceleration 。一次调用完成 "cspice 查扰动体位置 + 加速度公式",消除 Python↔cspice 跨界 + numpy 数组分配开销。
# 参数 - et :SPICE et 秒(past J2000 TDB) - target :摄动天体名("MOON"/"SUN"/"5"=JUPITER 等) - observer :原点天体名(通常 "EARTH") - sc_pos :航天器位置 [x, y, z] km(相对 observer),长度 3 - mu :摄动天体 GM(km³/s²)
# 返回 长度 3 的加速度 Vec<f64> ,单位 km/s²。
- e2m2e.integrators.wsb_search_rust(departure_state, target_state, *, mu, mu_sun, sun_distance, sun_angular_rate, sun_phase_range, n_sun_phase, departure_phase_range, n_departure_phase, tof_range_sec, n_tof, perilune_alt_range_km, max_total_dv, h2_energy_threshold, tli_speed_factor, n_propagation_samples, rtol, atol, max_step, max_steps, secondary_radius_km, characteristic_length_km, characteristic_time_sec, parallel=None, n_workers=None, progress_callback=None)[源代码]
WSB 三维网格搜索的 Rust 后端。
参数全部是已无量纲化的 POD 数值;BCR4BP 传播、截面求精和候选筛选均在 Rust 内完成。
parallel=None时由E2M2E_WSB_PARALLEL控制 Rayon。- 参数:
departure_state (ArrayLike)
target_state (ArrayLike)
mu (float)
mu_sun (float)
sun_distance (float)
sun_angular_rate (float)
n_sun_phase (int)
n_departure_phase (int)
n_tof (int)
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)
n_workers (int | None)
- 返回类型:
- class e2m2e.integrators.LowEnergyPatchCandidate
基类:
object低能转移流形截面态配对结果(PyO3 绑定)。
- cost
- delta_r
- delta_v
- i_a
- i_b
- state_a
- state_b
- class e2m2e.integrators.TransferPointResult
基类:
object单候选点评估结果(PyO3 绑定)。
字段对齐 Python search_single_departure 组装的候选解 dict (search_parallel.py:189-215 成功 + :135-150 失败分支)。get_all 让所有字段在 Python 侧只读可访问;wrapper grid_search_rust_serial 转为 list[dict] 返回,保持与 Python sequential 后端返回类型一致。
pyclass 在本 crate(e2m2e-forces 无 pyo3 依赖,纯数学结果由 [TransferPointResult::from] 转换)。
- alpha
- cause
- collision_body
- collision_found
- collision_idx
- departure_state
- departure_time
- dv_departure
- dv_insertion
- first_intersection_idx
- first_intersection_time
- first_min_distance_idx
- first_min_distance_time
- intersection_found
- intersection_idx
- intersection_point
- local_minimum_distance
- local_minimum_found
- local_minimum_idx
- message
- min_distance
- min_distance_idx
- min_distance_orbit_idx
- status
- transfer_time
- transfer_times
- transfer_trajectory
- e2m2e.integrators.transfer_grid_search_py(dep_states, dep_times, alpha_grid, arrival_states, mu, max_transfer_time, integration_dt, intersection_threshold, min_distance_threshold, collision_earth_radius, collision_moon_radius, rtol, atol, max_step, *, parallel=None, n_workers=None, progress_callback=None)
Python 接口:转移网格搜索(阶段 C,Rayon 并行 + GIL 释放)。
照搬
multiple_shooting_correct_py的py.allow_threads+ 环境变量开关范式(multiple_shooting.rs:660-676)。 默认走并行transfer_grid_search_parallel,parallel=False或E2M2E_SEARCH_PARALLEL=0回退串行transfer_grid_search_serial—— 供并行/串行位级一致性对照(两者结果逐位相同:par_iter``+``collect保序、evaluate_point纯函数)。参数
同
transfer_grid_search_serial_py,新增关键字参数:parallel:None(默认)时由E2M2E_SEARCH_PARALLEL决定("0"→ 串行, 其余/未设→并行);显式True/False覆盖环境变量。n_workers:None(默认)时用 Rayon 全局线程池(线程数由RAYON_NUM_THREADS决定,未设则 cpu 核数);显式Some(n)时建一次性ThreadPoolBuilder限定n.max(1)个线程并install本次 compute—— 覆盖RAYON_NUM_THREADS。串行模式忽略此参数(无线程池)。progress_callback: 同transfer_grid_search_serial_py。
GIL 与并行
py.allow_threads释放 GIL 是 Rayon 真并行 + drainer 实时回调的前提—— 不释放则 GIL 序列化所有 Rayon worker、drainer 拿不到 GIL。channel 创建 + ThreadPoolBuilder + compute + drainer join 全在闭包内,tx 在闭包内 drop, drainer 干净退出。内部直接调纯 Rusttransfer_grid_search核心,不绕道持 GIL 的propagate_cr3bp_py(这是最易踩的坑,见 transfer-grid-search-rust.md:109)。
- e2m2e.integrators.transfer_grid_search_serial_py(dep_states, dep_times, alpha_grid, arrival_states, mu, max_transfer_time, integration_dt, intersection_threshold, min_distance_threshold, collision_earth_radius, collision_moon_radius, rtol, atol, max_step, *, progress_callback=None)
Python 接口:转移网格搜索(串行版,阶段 B)。
展平 POD 输入,调纯 Rust
transfer_grid_search_serial, 返回Vec<TransferPointResult>(保序:外层 departure、内层 alpha)。 串行不用 Rayon,但传入progress_callback时仍走py.allow_threads释放 GIL——否则 drainer 线程拿不到 GIL,回调退化为 compute 结束后批量触发。参数
dep_states:n_dep*6展平(行优先)dep_times:n_depalpha_grid:n_alphaarrival_states:n_arrival*6展平(行优先)标量包:
mu/max_transfer_time/integration_dt/intersection_threshold/min_distance_threshold/collision_earth_radius/collision_moon_radius/rtol/atol/max_stepprogress_callback(关键字):cb(delta: int) -> None,每个 departure 完成 调一次(出发粒度);None不回调。
返回
list[TransferPointResult],长度n_dep * n_alpha。Python 侧grid_search_rust_serial转list[dict]。
e2m2e.exceptions module
e2m2e 统一异常层次。
所有 e2m2e 抛出的异常都以 E2M2EError 为共同基类,
便于调用方用 except E2M2EError 统一捕获库内部错误。
异常不属于任何一层,放顶层供 data/algorithm/api/tools 共享(ADR 0011 五层 结构)。
-
需要使用 Rust 扩展但扩展不可用/缺少所需符号时抛出。
spice 是默认且唯一支持的 feature(ADR 0009):核心计算路径必须由 Rust 扩展承载,不允许静默回退到 Python/scipy(issue #378)。扩展 未构建、构建不含 spice feature、或符号缺失时在使用处抛本异常, 错误信息含
make dev修复指引。同时继承
E2M2EError(库内统一捕获)与RuntimeError(兼容既有裸RuntimeError捕获点)。
- exception e2m2e.exceptions.PropagationFailure[源代码]
基类:
E2M2EError传播失败(ADR 0020 决策 2,取代字符串前缀匹配契约)。
步长塌缩到机器精度地板等确定性传播失败,在 Rust→Python FFI 边界 翻译成本异常,供下游
except PropagationFailure精确捕获;此前依赖"step size collapsed"错误消息前缀匹配(issue #317 第 3.1 项), 现已废弃。改写 Rust 侧错误消息措辞不再影响捕获。继承
E2M2EError(统一捕获契约),但不继承RuntimeError(与通用运行时错误区分;既有裸except RuntimeError不再兜住它)。
e2m2e.tools.logging module
结构化日志:配置工厂。
标准 logging + 关键事件键值对、零新依赖(ADR 0011):算法层保持
logger.info,打靶/延拓迭代等关键数值事件用键值对
(logger.info("correction_iter", iter=3, error=1e-8));本模块提供
配置工厂(Formatter 把键值对转 key=val)。
应用入口(examples/ 等,包外)调用 configure_logging 控制级别和
handler——库本身不配置日志(ADR 0012:api/ 不依赖 tools/)。