三体世界的模拟

Posted lief

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三体世界的模拟相关的知识,希望对你有一定的参考价值。

  1 ‘‘‘三体问题求解及可视化,去掉了动图模块‘‘‘
  2 ‘‘‘Coworker:聂嘉颖,张瀚文‘‘‘
  3 import numpy as np
  4 from numpy import arange
  5 import matplotlib.pyplot as plt
  6 from mpl_toolkits.mplot3d import Axes3D
  7 from math import sqrt
  8 
  9 
 10 # 得到太阳对行星夹角的cot值
 11 def sun_height(x0, y0, z0, x1, y1, z1):
 12     a0 = x1 - x0
 13     b0 = y1 - y0
 14     c0 = z1 - z0
 15     return a0 / sqrt(b0 ** 2 + c0 ** 2)
 16 
 17 
 18 # 得到两星体间的距离
 19 def distants(x0, y0, z0, x1, y1, z1):
 20     return sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2 + (z0 - z1) ** 2)
 21 
 22 
 23 # 计算某一瞬时某一星体对行星的辐射强度
 24 def sun_heat(d, sun_temperature, x0, y0, z0, x1, y1, z1):
 25     theta = d/distants(x0, y0, z0, x1, y1, z1)
 26     earth_temperature = 0.5 * sqrt(theta) * sun_temperature
 27     # print(earth_temperature)
 28     return earth_temperature
 29 
 30 # 定义星体质量
 31 # star_4选定为行星,其余为恒星
 32 star_1_mass = 3e30  # kg
 33 star_2_mass = 2e30  # kg
 34 star_3_mass = 3e30  # kg
 35 star_4_mass = 2e30  # kg
 36 
 37 diameter0 = 1.0392e10  #
 38 diameter1 = 1.0392e10  #
 39 diameter2 = 1.00392e11  #
 40 
 41 # 定义恒星表面温度
 42 sun_temperature0 = 60.  # K
 43 sun_temperature1 = 600.  # K
 44 sun_temperature2 = 60.  # K
 45 
 46 # 引力常数
 47 gravitational_constant = 6.67e-11  # m3 / kg s2
 48 
 49 # 行星运动总时长(按地球年计算)
 50 # 每两小时计算一次星体位置
 51 end_time = 16 * 365.26 * 24. * 3600.  # s
 52 h = 2. * 3600  # s
 53 num_steps = int(end_time / h)
 54 tpoints = arange(0, end_time, h)
 55 
 56 
 57 def three_body_problem():
 58     ‘‘‘主程序,计算星体位置和表面温度‘‘‘
 59     positions = np.zeros([num_steps + 1, 4, 3])  # m
 60     velocities = np.zeros([num_steps + 1, 4, 3])  # m / s
 61 
 62     positions[0] = np.array([[1., 3., 2.], [6., -5., 4.], [7., 8., -7.], [7., -2., 9.]]) * 1e11  # m
 63     velocities[0] = np.array([[-2., 0.5, 5.], [7., 0.5, 2.], [4., -0.5, 3.], [-10., 4., -2.]]) * 1e3  # m/s
 64     positions[0] = np.array([[1., 3., 2.], [3., -5., 1.], [2., 8., -7.], [-3., -2., 9.]]) * 1e11  # m
 65     velocities[0] = np.array([[0, 0., 0.], [0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]) * 1e3  # m/s
 66 
 67     def acceleration(positions):
 68         a = np.zeros([4, 3])
 69         a[0] = gravitational_constant * star_2_mass / np.linalg.norm(positions[0] - positions[1]) ** 3 * (
 70             positions[1] - positions[0]) + gravitational_constant * star_3_mass / np.linalg.norm(
 71             positions[0] - positions[2]) ** 3 * (positions[2] - positions[
 72             0]) + gravitational_constant * star_4_mass / np.linalg.norm(positions[0] - positions[3]) ** 3 * (
 73         positions[3] - positions[0])
 74         a[1] = gravitational_constant * star_1_mass / np.linalg.norm(positions[1] - positions[0]) ** 3 * (
 75             positions[0] - positions[1]) + gravitational_constant * star_3_mass / np.linalg.norm(
 76             positions[1] - positions[2]) ** 3 * (positions[2] - positions[
 77             1]) + gravitational_constant * star_4_mass / np.linalg.norm(positions[1] - positions[3]) ** 3 * (
 78         positions[3] - positions[1])
 79         a[2] = gravitational_constant * star_1_mass / np.linalg.norm(positions[2] - positions[0]) ** 3 * (
 80             positions[0] - positions[2]) + gravitational_constant * star_2_mass / np.linalg.norm(
 81             positions[2] - positions[1]) ** 3 * (positions[1] - positions[
 82             2]) + gravitational_constant * star_4_mass / np.linalg.norm(positions[2] - positions[3]) ** 3 * (
 83         positions[3] - positions[2])
 84         a[3] = gravitational_constant * star_1_mass / np.linalg.norm(positions[3] - positions[0]) ** 3 * (
 85         positions[0] - positions[3]) + gravitational_constant * star_2_mass / np.linalg.norm(
 86             positions[3] - positions[1]) ** 3 * (positions[1] - positions[
 87             3]) + gravitational_constant * star_3_mass / np.linalg.norm(positions[3] - positions[2]) ** 3 * (
 88         positions[2] - positions[3])
 89         return a
 90 
 91     def velocity(p, t, velo):
 92         v = np.zeros([4, 3])
 93         v[0] = acceleration(p)[0] * t + velo[0]
 94         v[1] = acceleration(p)[1] * t + velo[1]
 95         v[2] = acceleration(p)[2] * t + velo[2]
 96         v[3] = acceleration(p)[3] * t + velo[3]
 97         return velocities[step]
 98 
 99     heat_sum, t = [0.1], [0]
100 
101     per_0 = 0
102     for step in range(num_steps):
103         # 四阶龙格库塔法求星体位置
104         j1 = h * velocity(positions[step], h, velocities[step])
105         j2 = h * velocity(positions[step] + 0.5 * j1, h + 0.5 * h, velocities[step])
106         j3 = h * velocity(positions[step] + 0.5 * j2, h + 0.5 * h, velocities[step])
107         j4 = h * velocity(positions[step] + j3, h + h, velocities[step])
108         positions[step + 1] = positions[step] + (j1 + 2 * j2 + 2 * j3 + j4) / 6
109         velocities[step + 1] = velocities[step] + h * acceleration(positions[step + 1])
110 
111         # 从 positions 中取出坐标值
112         x0, y0, z0 = positions[step, 0, 0], positions[step, 0, 1], positions[step, 0, 2]
113         x1, y1, z1 = positions[step, 1, 0], positions[step, 1, 1], positions[step, 1, 2]
114         x2, y2, z2 = positions[step, 2, 0], positions[step, 2, 1], positions[step, 2, 2]
115         x3, y3, z3 = positions[step, 3, 0], positions[step, 3, 1], positions[step, 3, 2]
116 
117         # 计算三个太阳对行星表面的总辐射强度
118         heat0 = sun_heat(diameter0, sun_temperature0, x0, y0, z0, x3, y3, z3)
119         heat1 = sun_heat(diameter1, sun_temperature1, x1, y1, z1, x3, y3, z3)
120         heat2 = sun_heat(diameter2, sun_temperature2, x2, y2, z2, x3, y3, z3)
121         heat_sum.append(heat0 + heat1 + heat2)
122 
123         per = int(100 * step / num_steps)
124         if per > per_0:
125             print(per, %)
126             per_0 = per
127 
128         t.append(step)
129 
130     return positions, t, heat_sum
131 
132 positions, t, heat_sum = three_body_problem()
133 
134 
135 empty, extinction_line, frozen_line = [], [], []
136 
137 for i in range(len(t)):
138     empty.append(0)
139     extinction_line.append(100)
140     frozen_line.append(40)
141 
142 
143 fig, ax = plt.subplots()
144 fig.set_tight_layout(True)
145 plt.plot(t, heat_sum, b)
146 plt.plot(t, empty, g)
147 plt.plot(t, extinction_line, r)
148 plt.plot(t, frozen_line, r)
149 
150 ax.set_xlabel(X)
151 ax.set_xlim(0, len(t)+10e3)
152 ax.set_ylabel(Y)
153 plt.show()
154 
155 print("33[1;31;47m---Begin ploting image---33[0m")
156 
157 fig = plt.figure()
158 ax2 = Axes3D(fig)
159 
160 ax2.plot(positions[:, 0, 0], positions[:, 0, 1], positions[:, 0, 2], color=b)
161 ax2.plot(positions[:, 1, 0], positions[:, 1, 1], positions[:, 1, 2], color=y)
162 ax2.plot(positions[:, 2, 0], positions[:, 2, 1], positions[:, 2, 2], color=b)
163 ax2.plot(positions[:, 3, 0], positions[:, 3, 1], positions[:, 3, 2], color=r)
164 
165 zoom = 1.2e12
166 ax2.set_xlabel(X)
167 # ax2.set_xlim3d(-zoom, zoom + 3.e12)
168 ax2.set_ylabel(Y)
169 # ax2.set_ylim3d(-zoom, zoom)
170 ax2.set_zlabel(Z)
171 # ax2.set_zlim3d(-zoom, zoom + 2.e12)
172 print("100 %")
173 
174 plt.show()

 

以上是关于三体世界的模拟的主要内容,如果未能解决你的问题,请参考以下文章

利用threejs基于万有引力公式模拟宇宙三体

html 三体问题的基本模拟和可视化。

图书-科幻:《三体》

三体3"魔戒"说的话是啥意思

商汤三体梦幻联动,能遭遇水滴的那种元宇宙要来了!我在现场听见了次元壁破碎的声音...

三体浅论“黑暗森林”