first
pc-1
This commit is contained in:
280
three_body_problem/config.py
Normal file
280
three_body_problem/config.py
Normal file
@@ -0,0 +1,280 @@
|
||||
"""
|
||||
三体问题配置管理模块
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from typing import List, Dict, Any, Optional
|
||||
from .particle import Particle
|
||||
|
||||
|
||||
class ThreeBodyConfig:
|
||||
"""三体问题配置类"""
|
||||
|
||||
@staticmethod
|
||||
def create_figure8_config() -> List[Particle]:
|
||||
"""
|
||||
创建8字形轨道配置(著名的稳定三体轨道)
|
||||
|
||||
返回:
|
||||
三个质点的列表
|
||||
"""
|
||||
# 8字形轨道的初始条件(等质量)
|
||||
m = 1.0 # 质量
|
||||
|
||||
# 位置 (Chenciner & Montgomery, 2000)
|
||||
r1 = np.array([0.97000436, -0.24308753, 0.0])
|
||||
r2 = np.array([-0.97000436, 0.24308753, 0.0])
|
||||
r3 = np.array([0.0, 0.0, 0.0])
|
||||
|
||||
# 速度
|
||||
v1 = np.array([0.466203685, 0.43236573, 0.0])
|
||||
v2 = np.array([0.466203685, 0.43236573, 0.0])
|
||||
v3 = np.array([-0.93240737, -0.86473146, 0.0])
|
||||
|
||||
particles = [
|
||||
Particle(mass=m, position=r1, velocity=v1, name="Star A", color="red"),
|
||||
Particle(mass=m, position=r2, velocity=v2, name="Star B", color="green"),
|
||||
Particle(mass=m, position=r3, velocity=v3, name="Star C", color="blue")
|
||||
]
|
||||
|
||||
return particles
|
||||
|
||||
@staticmethod
|
||||
def create_lagrange_point_config(lagrange_point: int = 4) -> List[Particle]:
|
||||
"""
|
||||
创建拉格朗日点配置
|
||||
|
||||
参数:
|
||||
lagrange_point: 拉格朗日点编号 (4=L4, 5=L5)
|
||||
|
||||
返回:
|
||||
三个质点的列表
|
||||
"""
|
||||
if lagrange_point not in [4, 5]:
|
||||
raise ValueError("lagrange_point 必须是 4 (L4) 或 5 (L5)")
|
||||
|
||||
# 大质量天体(类似太阳)
|
||||
m_sun = 1.0
|
||||
# 小质量天体(类似地球)
|
||||
m_earth = 3e-6 # 地球质量/太阳质量
|
||||
# 测试质点(类似小行星)
|
||||
m_test = 1e-8
|
||||
|
||||
# 大质量天体在原点
|
||||
r_sun = np.array([0.0, 0.0, 0.0])
|
||||
v_sun = np.array([0.0, 0.0, 0.0])
|
||||
|
||||
# 小质量天体在圆形轨道上(1 AU距离)
|
||||
r_earth = np.array([1.0, 0.0, 0.0])
|
||||
# 圆形轨道速度:v = sqrt(G*M/r)
|
||||
v_earth = np.array([0.0, 2*np.pi, 0.0]) # 2π AU/年
|
||||
|
||||
# 拉格朗日点位置(等边三角形)
|
||||
if lagrange_point == 4: # L4
|
||||
r_test = np.array([0.5, np.sqrt(3)/2, 0.0])
|
||||
else: # L5
|
||||
r_test = np.array([0.5, -np.sqrt(3)/2, 0.0])
|
||||
|
||||
# 测试质点的速度(与地球相同角速度)
|
||||
v_test = np.array([-np.sqrt(3)/2 * 2*np.pi, 0.5 * 2*np.pi, 0.0])
|
||||
|
||||
particles = [
|
||||
Particle(mass=m_sun, position=r_sun, velocity=v_sun, name="Sun", color="yellow"),
|
||||
Particle(mass=m_earth, position=r_earth, velocity=v_earth, name="Earth", color="blue"),
|
||||
Particle(mass=m_test, position=r_test, velocity=v_test, name="Test", color="gray")
|
||||
]
|
||||
|
||||
return particles
|
||||
|
||||
@staticmethod
|
||||
def create_random_config(masses: Optional[List[float]] = None,
|
||||
position_range: float = 2.0,
|
||||
velocity_scale: float = 1.0) -> List[Particle]:
|
||||
"""
|
||||
创建随机初始条件配置
|
||||
|
||||
参数:
|
||||
masses: 质量列表(如果为None则使用随机质量)
|
||||
position_range: 位置范围(±position_range)
|
||||
velocity_scale: 速度缩放因子
|
||||
|
||||
返回:
|
||||
三个质点的列表
|
||||
"""
|
||||
if masses is None:
|
||||
# 随机质量(在0.5到2.0之间)
|
||||
masses = np.random.uniform(0.5, 2.0, 3)
|
||||
|
||||
if len(masses) != 3:
|
||||
raise ValueError("需要恰好3个质量值")
|
||||
|
||||
particles = []
|
||||
colors = ['red', 'green', 'blue']
|
||||
names = ['Star A', 'Star B', 'Star C']
|
||||
|
||||
for i in range(3):
|
||||
# 随机位置
|
||||
position = np.random.uniform(-position_range, position_range, 3)
|
||||
|
||||
# 随机速度(确保系统总动量接近零)
|
||||
velocity = np.random.uniform(-velocity_scale, velocity_scale, 3)
|
||||
|
||||
particles.append(
|
||||
Particle(mass=masses[i], position=position, velocity=velocity,
|
||||
name=names[i], color=colors[i])
|
||||
)
|
||||
|
||||
# 调整速度使系统总动量接近零
|
||||
total_momentum = sum(p.mass * p.velocity for p in particles)
|
||||
total_mass = sum(p.mass for p in particles)
|
||||
|
||||
for p in particles:
|
||||
p.velocity -= total_momentum / total_mass
|
||||
|
||||
return particles
|
||||
|
||||
@staticmethod
|
||||
def create_binary_star_config() -> List[Particle]:
|
||||
"""
|
||||
创建双星系统+测试质点配置
|
||||
|
||||
返回:
|
||||
三个质点的列表
|
||||
"""
|
||||
# 双星质量
|
||||
m1 = 1.0
|
||||
m2 = 0.8
|
||||
|
||||
# 双星位置(在椭圆轨道上)
|
||||
# 半长轴
|
||||
a = 1.0
|
||||
# 偏心率
|
||||
e = 0.3
|
||||
|
||||
# 质心在原点
|
||||
r1 = np.array([-m2/(m1+m2) * a * (1+e), 0.0, 0.0])
|
||||
r2 = np.array([m1/(m1+m2) * a * (1+e), 0.0, 0.0])
|
||||
|
||||
# 计算轨道速度(简化圆形轨道近似)
|
||||
# 对于椭圆轨道,速度更复杂,这里使用简化
|
||||
orbital_speed = np.sqrt(4*np.pi**2 * (m1+m2) / (2*a))
|
||||
v1 = np.array([0.0, orbital_speed * m2/(m1+m2), 0.0])
|
||||
v2 = np.array([0.0, -orbital_speed * m1/(m1+m2), 0.0])
|
||||
|
||||
# 测试质点(小质量)
|
||||
m_test = 0.01
|
||||
r_test = np.array([0.0, 2.0, 0.0])
|
||||
v_test = np.array([0.5, 0.0, 0.0])
|
||||
|
||||
particles = [
|
||||
Particle(mass=m1, position=r1, velocity=v1, name="Primary", color="red"),
|
||||
Particle(mass=m2, position=r2, velocity=v2, name="Secondary", color="green"),
|
||||
Particle(mass=m_test, position=r_test, velocity=v_test, name="Test", color="blue")
|
||||
]
|
||||
|
||||
return particles
|
||||
|
||||
@staticmethod
|
||||
def create_custom_config(config_dict: Dict[str, Any]) -> List[Particle]:
|
||||
"""
|
||||
从字典创建自定义配置
|
||||
|
||||
参数:
|
||||
config_dict: 包含配置信息的字典
|
||||
|
||||
返回:
|
||||
三个质点的列表
|
||||
"""
|
||||
particles = []
|
||||
|
||||
for i in range(3):
|
||||
key = f"particle_{i+1}"
|
||||
if key not in config_dict:
|
||||
raise ValueError(f"配置中缺少 {key}")
|
||||
|
||||
p_config = config_dict[key]
|
||||
|
||||
particle = Particle(
|
||||
mass=p_config.get('mass', 1.0),
|
||||
position=np.array(p_config.get('position', [0.0, 0.0, 0.0])),
|
||||
velocity=np.array(p_config.get('velocity', [0.0, 0.0, 0.0])),
|
||||
name=p_config.get('name', f"Particle {i+1}"),
|
||||
color=p_config.get('color', None)
|
||||
)
|
||||
|
||||
particles.append(particle)
|
||||
|
||||
return particles
|
||||
|
||||
@staticmethod
|
||||
def save_config(particles: List[Particle], filename: str):
|
||||
"""
|
||||
保存配置到文件
|
||||
|
||||
参数:
|
||||
particles: 质点列表
|
||||
filename: 文件名
|
||||
"""
|
||||
config_dict = {}
|
||||
|
||||
for i, p in enumerate(particles):
|
||||
config_dict[f"particle_{i+1}"] = {
|
||||
'mass': float(p.mass),
|
||||
'position': p.position.tolist(),
|
||||
'velocity': p.velocity.tolist(),
|
||||
'name': p.name,
|
||||
'color': p.color
|
||||
}
|
||||
|
||||
import json
|
||||
with open(filename, 'w') as f:
|
||||
json.dump(config_dict, f, indent=2)
|
||||
|
||||
print(f"配置已保存到: {filename}")
|
||||
|
||||
@staticmethod
|
||||
def load_config(filename: str) -> List[Particle]:
|
||||
"""
|
||||
从文件加载配置
|
||||
|
||||
参数:
|
||||
filename: 文件名
|
||||
|
||||
返回:
|
||||
三个质点的列表
|
||||
"""
|
||||
import json
|
||||
with open(filename, 'r') as f:
|
||||
config_dict = json.load(f)
|
||||
|
||||
return ThreeBodyConfig.create_custom_config(config_dict)
|
||||
|
||||
@staticmethod
|
||||
def print_config_summary(particles: List[Particle]):
|
||||
"""打印配置摘要"""
|
||||
print("=" * 60)
|
||||
print("三体问题配置摘要")
|
||||
print("=" * 60)
|
||||
|
||||
total_mass = 0.0
|
||||
total_momentum = np.zeros(3)
|
||||
total_angular_momentum = np.zeros(3)
|
||||
|
||||
for i, p in enumerate(particles):
|
||||
print(f"\n质点 {i+1} ({p.name}):")
|
||||
print(f" 质量: {p.mass:.6f} M_sun")
|
||||
print(f" 位置: [{p.position[0]:.6f}, {p.position[1]:.6f}, {p.position[2]:.6f}] AU")
|
||||
print(f" 速度: [{p.velocity[0]:.6f}, {p.velocity[1]:.6f}, {p.velocity[2]:.6f}] AU/yr")
|
||||
|
||||
total_mass += p.mass
|
||||
total_momentum += p.mass * p.velocity
|
||||
angular_momentum = np.cross(p.position, p.mass * p.velocity)
|
||||
total_angular_momentum += angular_momentum
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("系统总质量: {:.6f} M_sun".format(total_mass))
|
||||
print("系统总动量: [{:.6e}, {:.6e}, {:.6e}]".format(
|
||||
total_momentum[0], total_momentum[1], total_momentum[2]))
|
||||
print("系统总角动量: [{:.6e}, {:.6e}, {:.6e}]".format(
|
||||
total_angular_momentum[0], total_angular_momentum[1], total_angular_momentum[2]))
|
||||
print("=" * 60)
|
||||
Reference in New Issue
Block a user