三体到底是啥?用Python跑一遍就明白了

文章目录

    • 拉格朗日方程
    • 推导方程组
    • 微分方程算法化
    • 求解+画图
    • 动图绘制

温馨提示,只想看图的画直接跳到最后一节

拉格朗日方程

此前所做的一切三体和太阳系的动画,都是基于牛顿力学的,而且直接对微分进行差分化,从而精度非常感人,用不了几年就得撞一起去。

为了给三体人提供一个更加有价值的推导,这次通过求解拉格朗日方程的数值解来实现。

首先假设三个质点的质量分别为m1,m2,m3m_1, m_2, m_3m1,m2,m3,坐标为x⃗1,x⃗2,x⃗3\vec x_1, \vec x_2, \vec x_3x1,x2,x3,质点速度可以表示为x⃗˙\dot{\vec x}x˙。假设三体在二维平面上运动,则第iii个质点的动能为

Ti=12mi(x˙i2+y˙i2)T_i=\frac{1}{2}m_i(\dot x_i^2+\dot y_i^2) Ti=21mi(x˙i2+y˙i2)

引力势能为−Gmimjrij-G\frac{m_im_j}{r_{ij}}Grijmimj,其中GGG为万有引力常量,rijr_{ij}rij为质点i,ji,ji,j之间的距离,则系统的拉格朗日量为

L=∑i12mi(x˙i2+y˙i2)−∑i≠jGmimj∥x⃗i−x⃗j∥L=\sum_i\frac{1}{2}m_i(\dot x_i^2+\dot y_i^2)-\sum_{i\not=j}G\frac{m_im_j}{\Vert\vec x_i-\vec x_j\Vert} L=i21mi(x˙i2+y˙i2)i=jGxixjmimj

有了拉格朗日量,将其带入拉格朗日方程

ddt∂L∂x˙i−∂L∂xi=0\frac{\text d}{\text dt}\frac{\partial L}{\partial\dot x_i}-\frac{\partial L}{\partial x_i}=0 dtdx˙iLxiL=0

就可以得到拉格朗日方程组。

推导方程组

对于三体系统而言,总计有3个粒子,每个粒子有x,yx,yx,y两个自由度,也就是说最后会得到6组方程。考虑到公式推导过程中可能会出现错误,所以下面采用sympy来进行公式推导。

首先定义符号变量

from sympy import symbols
from sympy.physics.mechanics import dynamicsymbols
m = symbols('m1:4')
x = dynamicsymbols('x1:4')
y = dynamicsymbols('y1:4')

接下来,需要构造系统的拉格朗日量LLL,其实质是系统的动能减去势能,对于上面构建的三体系统而言,动能和势能可分别表示为

计算每个质点的动能和势能。动能是由速度决定的,而速度是由位置对时间的导数决定的。我们可以用 sympy 的 diff 函数来求导:

from sympy import diff
# 此为速度的平方
v2 = [diff(x[i],t)**2 + diff(y[i])**2 for i in range(3)]
T = 0
for i in range(3):T += m[i]*v2[i]/2

势能是由万有引力决定的,而万有引力是由两个质点之间的距离决定的。我们可以用 sympy 的 sqrt 函数来求距离:

from sympy import sqrt,cos
G = symbols('G') # 引力常数
ijs = [(0,1), (0,2),(1,2)]
dij = [sqrt((x[i]-x[j])**2+(y[i]-y[j])**2) for i,j in ijs]
U = 0
for k in range(3):i,j = ijs[k]U -= G*m[i]*m[j]/dij[k]

有了动能和势能,就可以愉快地求拉格朗日量了,有了拉格朗日量,就可以列拉格朗日方程了

L=T−UdLdxi−ddt∂L∂x˙iL = T – U\\ \frac{\text dL}{\text dx_i}-\frac{\text d}{\text dt}\frac{\partial L}{\partial \dot x_i} L=TUdxidLdtdx˙iL

三个粒子的每一个坐标维度,都可以列出一组拉格朗日方程,所以总共有6个拉格朗日方程组

from sympy import solve
L = T - U
eqLag = lambda x : diff(L, x)-diff(diff(L, diff(x, t)), t)
# 拉格朗日方程组
eqs = [eqLag(xi) for xi in x+y]

xij=xi−xj,yij=yi−yjx_{ij}=x_i-x_j, y_{ij}=y_i-y_jxij=xixj,yij=yiyj,则

−Gm1m2x12(x122+y122)32+−Gm1m3x13(x132+y132)32−m1d2dt2x1=0Gm1m2x12(x122+y122)32+−Gm2m3x23(x232+y232)32−m2d2dt2x2=0Gm1m3x13(x132+y132)32+Gm2m3x23(x232+y232)32−m3d2dt2x3=0−Gm1m2y12(x122+y122)32+−Gm1m3y13(x132+y132)32−m1d2dt2y1=0Gm1m2y12(x122+y122)32+−Gm2m3y23(x232+y232)32−m2d2dt2y2=0Gm1m3y13(x132+y132)32+Gm2m3y23(x232+y232)32−m3d2dt2y3=0\frac{-G m_1 m_2x_{12}}{\left(x_{12}^{2} + y_{12}^{2}\right)^{\frac{3}{2}}} + \frac{-G m_1 m_{3}x_{13}}{\left(x_{13}^{2} + y_{13}^{2}\right)^{\frac{3}{2}}} – m_1 \frac{d^{2}}{d t^2} x_1=0\\ \frac{G m_1 m_2 x_{12}}{\left(x_{12}^{2} + y_{12}^{2}\right)^{\frac{3}{2}}} + \frac{-G m_2 m_{3}x_{23}}{\left(x_{23}^{2} + y_{23}^{2}\right)^{\frac{3}{2}}} – m_2 \frac{d^{2}}{d t^2} x_2=0\\ \frac{G m_1 m_{3} x_{13}}{\left(x_{13}^{2} + y_{13}^{2}\right)^{\frac{3}{2}}} + \frac{G m_2 m_{3} x_{23}}{\left(x_{23}^{2} + y_{23}^{2}\right)^{\frac{3}{2}}} – m_{3} \frac{d^{2}}{d t^2} x_{3}=0\\ \frac{-G m_1 m_2 y_{12}}{\left(x_{12}^{2} + y_{12}^{2}\right)^{\frac{3}{2}}} + \frac{-G m_1 m_{3} y_{13}}{\left(x_{13}^{2} + y_{13}^{2}\right)^{\frac{3}{2}}} – m_1 \frac{d^{2}}{d t^2} y_1=0\\ \frac{G m_1 m_2 y_{12}}{\left(x_{12}^{2} + y_{12}^{2}\right)^{\frac{3}{2}}} + \frac{-G m_2 m_{3}y_{23}}{\left(x_{23}^{2} + y_{23}^{2}\right)^{\frac{3}{2}}} – m_2 \frac{d^{2}}{d t^2} y_2=0\\ \frac{G m_1 m_{3} y_{13}}{\left(x_{13}^{2} + y_{13}^{2}\right)^{\frac{3}{2}}} + \frac{G m_2 m_{3} y_{23}}{\left(x_{23}^{2} + y_{23}^{2}\right)^{\frac{3}{2}}} – m_{3} \frac{d^{2}}{d t^2} y_{3}=0\\ (x122+y122)23Gm1m2x12+(x132+y132)23Gm1m3x13m1dt2d2x1=0(x122+y122)23Gm1m2x12+(x232+y232)23Gm2m3x23m2dt2d2x2=0(x132+y132)23Gm1m3x13+(x232+y232)23Gm2m3x23m3dt2d2x3=0(x122+y122)23Gm1m2y12+(x132+y132)23Gm1m3y13m1dt2d2y1=0(x122+y122)23Gm1m2y12+(x232+y232)23Gm2m3y23m2dt2d2y2=0(x132+y132)23Gm1m3y13+(x232+y232)23Gm2m3y23m3dt2d2y3=0

微分方程算法化

接下来就要调用Python的odeint来计算这个微分方程组的数值解,odeint的调用方法大致为odeint(func, y, t, args),其中func是一个函数,这个函数必须为func(y,t,...),且返回值为dydt\frac{\text dy}{\text dt}dtdy

为此,需要将上述方程组再行拆分,以消去其中的二次导数,以x1x_1x1为例,令u1=dx1dtu_1=\frac{\text dx_1}{\text dt}u1=dtdx1,则此方程变为方程组

x˙1(t)=u1(t)u˙1(t)=−Gm1m2x12(x122+y122)32+−Gm1m3x13(x132+y132)32\begin{aligned} \dot x_1(t)&=u_1(t)\\ \dot u_1(t)&= \frac{-G m_1 m_2x_{12}}{\left(x_{12}^{2} + y_{12}^{2}\right)^{\frac{3}{2}}} + \frac{-G m_1 m_{3}x_{13}}{\left(x_{13}^{2} + y_{13}^{2}\right)^{\frac{3}{2}}}\\ \end{aligned} x˙1(t)u˙1(t)=u1(t)=(x122+y122)23Gm1m2x12+(x132+y132)23Gm1m3x13

由于三体系统中有3个粒子,共6个独立变量,所以要列12个方程。记u(t)=textdxdt,v(t)=dydtu(t)=\frac{text dx}{\text dt}, v(t)=\frac{\text dy}{\text dt}u(t)=dttextdx,v(t)=dtdy,则odeint输入的y的形式为

[x1,x2,x3,y1,y2,y3,u1,u2,u3,v1,v2,v3][x_1, x_2, x_3, y_1, y_2, y_3, u_1, u_2, u_3, v_1, v_2, v_3] [x1,x2,x3,y1,y2,y3,u1,u2,u3,v1,v2,v3]

从而func的具体形式为

import numpy as np
dxy = lambda x,y : np.sqrt(x**2+y**2)**(3/2)
def triSys(Y, t, m, G):jk = [(1,2),(0,2),(0,1)]x,y = Y[:3], Y[3:6]u,v = Y[6:9], Y[9:]du, dv = [], []for i in range(3):j, k = jk[i]xji, xki = x[j]-x[i], x[k]-x[i]yji, yki = y[j]-y[i], y[k]-y[i]dji, dki = dxy(xji, yji), dxy(yji, yki)mji, mki = G*m[i]*m[j], G*m[i]*m[k]du.append(mji*xji/dji + mki*xki/dki)dv.append(mji*yji/dji + mki*yki/dki)dydt = [*u, *v, *du, *dv]return dydt

求解+画图

接下来就是见证奇迹的时刻,首先创建一个随机的起点,作为三体运动的初值,然后带入开整就完事儿了

from scipy.integrate import odeint
np.random.seed(42)
y0 = np.random.rand(12)
m = np.random.rand(3)
t = np.linspace(0, 20, 1001)
sol = odeint(triSys, y0, t, args=(m, 1))

然后绘制一下这三颗星的轨迹

import matplotlib.pyplot as plt
plt.plot(sol[:,0], sol[:,3])
plt.plot(sol[:,1], sol[:,4])
plt.plot(sol[:,2], sol[:,5])
plt.show()

在这里插入图片描述

光是看这个轨迹就十分惊险了有木有。

如果把其中的第一颗星作为坐标原点,那么另外两颗星的轨迹大致为

plt.plot(sol[:,1]-sol[:,0], sol[:,4]-sol[:,3])
plt.plot(sol[:,2]-sol[:,0], sol[:,5]-sol[:,3])
plt.scatter([0],[0], c='g', marker='*')
plt.show()

结果为

在这里插入图片描述

动图绘制

最后,以中间这颗星为原点,绘制一下另外两颗星运动的动态过程

import matplotlib.animation as animation fig = plt.figure(figsize=(9,4))
ax = fig.add_subplot(xlim=(-1.8,1.8),ylim=(-1.8,1.5))
ax.grid()traces = [ax.plot([],[],'-',lw=0.5)[0] for _ in range(2)]
pts = [ax.plot([],[] ,marker='*')[0] for _ in range(2)]
ax.plot([0],[0], marker="*", c='r')X1 = sol[:,1]-sol[:,0]
Y1 = sol[:,4]-sol[:,3]
X2 = sol[:,2]-sol[:,0]
Y2 = sol[:,5]-sol[:,3]def animate(n):traces[0].set_data(X1[:n], Y1[:n])traces[1].set_data(X2[:n], Y2[:n])pts[0].set_data([X1[n], Y1[n]])pts[1].set_data([X2[n], Y2[n]])return traces + ptsani = animation.FuncAnimation(fig, animate, range(1000), interval=10, blit=True)
ani.save('tri.gif')

在这里插入图片描述

查看全文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dgrt.cn/a/1795832.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章:

在这里插入图片描述

三体到底是啥?用Python跑一遍就明白了

文章目录拉格朗日方程推导方程组微分方程算法化求解画图动图绘制温馨提示,只想看图的画直接跳到最后一节拉格朗日方程
此前所做的一切三体和太阳系的动画,都是基于牛顿力学的,而且直接对微分进行差分化,从而精度非常感人&#xf……

mysql数据库之innodb存储引擎架构之内存架构

一、逻辑存储结构 mysql5.5版本开始,默认使用innodb存储引擎,它擅长事务处理,具有崩溃恢复特性,在日常开发中使用非常广泛。
架构图(左侧为内存架构,右侧为磁盘架构) 二、 内存架构。
1、缓冲……

数据库设计三大范式(简单易懂)

数据库设计的三大范式
为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就叫做范式。
范式就是符合某一种设计要求的总结,要想设计一个结构合理的关系型数据库,必须满足一定的范式。
在实际……

mysql5.7主从(Master/Slave)同步配置

环境:
mysql版本都是5.7(以前的版本配置可能不一样)
主(Master) windows:192.168.0.68
从(Slave) centos7:192.168.0.4 基本环境配置:
要保证防火墙3306端口开放,如果只是为了学习,可以直接关闭防火墙。……

Thinkphp5.1里面使用Memcached的bug

在tp5.1里面使用缓存数据库memcached,我安装了memcached拓展。填好配置之后报以下错误Call to undefined method Memcached::has()。
查看代码发现tp5.1里面使用了has这个函数 protected function setTagItem($name){if ($this->tag) {$tagName $this->getT……

chrome浏览器的一个特性

用chrome浏览器(版本 74.0.3729.131)测试并发的时候无意中发现chrome浏览器一个小小的特性。凡是同一个请求(一定是要同一个请求),你连续按F5,即使你开多个窗口或者只是一个窗口,你请求一个页面……

花菁染料IR:IR808 Maleimide,IR 808 Mal,IR-808马来酰亚胺具有光稳定性好

【中文名称】IR-808马来酰亚胺【英文名称】 IR-808 Maleimide,IR-808 Mal【IR-808结 构 式】【CAS号】N/A【基团部分】IR-808【纯度标准】95%【包装规格】10mg,25mg,50mg,可以提供核磁图谱及相关质量证明图谱【是否接受定制】是【……

php flock文件锁通俗讲解几种锁的用法

使用共享锁(读锁)LOCK_SH,如果是读取,不需要等待,但如果是写入,需要等待读取完成。使用独占锁也叫排它锁(写锁)LOCK_EX,无论写入/读取都需要等待。LOCK_UN,无……

docker里面使用crontab遇到的坑

业务需要在docker里面使用crontab,安装好crontab之后。我在想怎样不进入容器就能自己添加或者修改cron任务。因为我的docker环境都是通过docker-compose配置的,首先想到的方法是通过dokcer-compose里面的volumes映射cron任务文件则crontab -e的操作对象文件。路径是……

swoole实例化对象的两种写法

最近在深入学习swoole看到官方文档里面实例化对象有两种写法,两种写法都能执行成功。一种是这样
$server new \Swoole\WebSocket\Server("0.0.0.0", 9501);
另外一种是这样
$server new \Swoole_WebSocket_Server("0.0.0.0", 9501);
第一……

反序列化渗透与攻防(五)之shiro反序列化漏洞

Shiro反序列化漏洞
Shiro介绍
Apache Shiro是一款开源安全框架,提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性
Apache Shiro 1.2.4及以前版本中,加密的用户信息序列化后存储在名为remember-me的Cookie中。攻击者可以使用Shiro的默……

vue2+vue3

vue2vue3尚硅谷vue2vue2 课程简介【02:24】vue2 Vue简介【17:59】vue2 Vue官网使用指南【14:07】vue2 搭建Vue开发环境【13:54】vue2 Hello小案例【22:25】了解: 不常用常用:id 更常用 简单class差值总结vue 实例vue 模板 : 先 取 &#xff0……

【hello Linux】环境变量

目录 1. 环境变量的概念 2. 常见的环境变量 3. 查看环境变量 4. 和环境变量相关的命令 5. 环境变量的组织方式 6. 通过代码获取环境变量 7. 通过系统调用获取环境变量 Linux🌷 在开始今天的内容之前,先来看一幅图片吧! 不知道你们是否和我一……

【Linux基础】常用命令整理

ls命令
-a选项,可以展示隐藏的文件和文件夹-l选项,以列表形式展示内容-h,需要和-l搭配使用,可以展示文件的大小单位ls -lah等同于la -a -l -h
cd命令(change directory)
语法:cd [Linux路径]……

客快物流大数据项目(一百一十二):初识Spring Cloud

文章目录
初识Spring Cloud
一、Spring Cloud简介
二、SpringCloud 基础架构图…

C和C++中的struct有什么区别

区别一: C语言中: Struct是用户自定义数据类型(UDT)。 C语言中: Struct是抽象数据类型(ADT),支持成员函数的定义。
区别二:
C中的struct是没有权限设置的&#xff0c……

docker的数据卷详解

数据卷 数据卷是宿主机中的一个目录或文件,当容器目录和数据卷目录绑定后,对方修改会立即同步
一个数据卷可以同时被多个容器同时挂载,一个容器也可以被挂载多个数据卷
数据卷作用:容器数据持久化 /外部机器和容器间接通信 /容器……

13、Qt生成dll-QLibrary方式使用

Qt创建dll,使用QLibrary类方式调用dll
一、创建项目
1、新建项目->其他项目->Empty qmake Project->Choose 2、输入项目名,选择项目位置,下一步 3、选择MinGW,下一步 4、完成 5、.pro中添加TEMPLATE subdirs&#xff……

基于mapreduce 的 minHash 矩阵压缩

Minhash作用: 对大矩阵进行降维处理,在进行计算俩个用户之间的相似度。
比如: 俩个用户手机下载的APP的相似度,在一个矩阵中会有很多很多的用户要比较没俩个用户之间的相似度是一个很大的计算任务 如果首先对这个矩阵降维处理&am……

关于hashmap使用迭代器的问题

keySet获得的只是key值的集合,valueSet获得的是value集合,entryset获得的是键值对的集合。 package com.test2.test;import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;public class mapiterator……

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注