找回密码
 注册
X系列官方授权正版
搜索
查看: 8028|回复: 19

[求助] 求水星近日点轨道进动模拟轨道代码,关键是用python编写的

  [复制链接]
发表于 2011-4-26 18:18:44 | 显示全部楼层 |阅读模式
本帖最后由 尼奇怪 于 2011-4-27 16:38 编辑

RT
这是咱本周计算物理的作业,本来上周的FFT(快速傅立叶变换)就够痛苦了……
以下是我用kepler轨道改编的,不过怎么画出来都觉得不像进动轨道……
  1. from pylab import *
  2. import matplotlib as mpl
  3. from math import sqrt, pi
  4. from mpl_toolkits.mplot3d import axes3d, Axes3D
  5. import numpy as np
  6. import matplotlib.pyplot as plt


  7. class Mecury():

  8.     def __init__(self, initx=0.47, inity=0, initvx=0, initvy=8.2, dt=0.001, powerlaw=2., alpha=0.008, outputfile=''):
  9.         self.dt=dt
  10.         self.beta=powerlaw
  11.         self.alpha=alpha
  12.         self.filename=outputfile
  13.         self.calculate(sqrt(initx*initx+inity*inity), initx, inity, initvx, initvy, 0.)
  14.         self.dth=0.

  15.     def stepOne(self, r, x, y, vx, vy, t):
  16.         r=sqrt(x*x+y*y)
  17.         vx=vx-(4*pi*pi*x*self.dt)/r**(self.beta+1)/(1+self.alpha/r**(self.beta))
  18.         vy=vy-(4*pi*pi*y*self.dt)/r**(self.beta+1)/(1+self.alpha/r**(self.beta))
  19.         x=x+vx*self.dt
  20.         y=y+vy*self.dt
  21.         t=t+self.dt
  22.         return r, x, y, vx, vy, t

  23.     def calculate(self, r, x ,y ,vx, vy, t):
  24.         self.data=[(r, x,y,vx,vy,t)]
  25.         while t<100:
  26.             r, x, y, vx, vy, t=self.stepOne(r, x ,y ,vx, vy, t)
  27.             self.data.append((r, x,y,vx,vy,t))
  28.         if self.filename!='':
  29.             self.store()



  30.     def store(self):
  31.         pass

  32.     def plotMecury(self, figType=1):
  33.         x=[]; y=[]; z=[0.]; vx=[]; vy=[]; t=[]; r=[]; xp=[]; yp=[]; k=[]
  34.         for i in range(5000):
  35.             (r1, x1, y1, vx1, vy1, t1)=self.data[i]
  36.             x.append(x1); y.append(y1); vx.append(vx1); vy.append(vy1)
  37.             t.append(t1); z.append(0.); r.append(r1)
  38.             if i>2:
  39.                 dr1=r[i-1]-r[i-2]
  40.                 dr2=r[i]-r[i-1]
  41.                 if dr1>0 and dr2<0:
  42.                     xp.append(x[i-1])
  43.                     yp.append(y[i-1])
  44.             m=len(self.data)
  45.         if figType==1:
  46.             plot(x,y)
  47.             plot(0,0,'r*')
  48.             for j in range(len(xp)):
  49.                 plot([0,xp[j]], [0,yp[j]],'k-')
  50.             xlim(-0.55,0.55)
  51.             ylim(-0.55,0.55)
  52.             show()
  53.         else:
  54.             fig=plt.figure()
  55.             ax=Axes3D(fig)
  56.             ax.plot(x[0:m], y[0:m], z[0:m], label='Kepler')
  57.             ax.legend()
  58.             plt.show()
  59.             
  60.     def plotPrecessionrate(self, figType=1):
  61.         x=[]; y=[]; z=[0.]; vx=[]; vy=[]; t=[]; r=[]; xp=[]; yp=[]; tp=[]; k=[];
  62.         theta=[]; th=0.; dth=0.#dth=[]
  63.         for i in range(3000):
  64.             (r1, x1, y1, vx1, vy1, t1)=self.data[i]
  65.             x.append(x1); y.append(y1); vx.append(vx1); vy.append(vy1)
  66.             t.append(t1); z.append(0.); r.append(r1)
  67.             if i>2:
  68.                 dr1=r[i-1]-r[i-2]
  69.                 dr2=r[i]-r[i-1]
  70.                 if dr1>0 and dr2<0:
  71.                     xp.append(x[i-1])
  72.                     yp.append(y[i-1])
  73.                     tp.append(t[i-1]-0.24500000000000019)
  74.             m=len(self.data)
  75.             n=len(xp)
  76.         if figType==1:
  77.             for j in range(n):
  78.                 k.append(yp[j]/xp[j])
  79.                 theta.append((180/pi)*(arctan((k[0]-k[j])/(1+k[0]*k[j]))))
  80.             for l in range(n-1):
  81.                 th=th+theta[l+1]/tp[l+1]
  82.             dth=th/n
  83.             print theta
  84.             print tp
  85.             print dth

  86.             
  87.                
  88.             #print th
  89.             #print theta[0]/tp[0]
  90.             plot(tp,theta)
  91.             #plot(0,0,'r*')
  92.             xlim(0,3)
  93.             ylim(0,20)
  94.             show()
  95.             
  96.         else:
  97.             fig=plt.figure()
  98.             ax=Axes3D(fig)
  99.             ax.plot(x[0:m], y[0:m], z[0:m], label='Kepler')
  100.             ax.legend()
  101.             plt.show()
  102.         #return dth
  103.    


  104.     def calculatedth(self, figType=1):
  105.         x=[]; y=[]; z=[0.]; vx=[]; vy=[]; t=[]; r=[]; xp=[]; yp=[]; tp=[]; k=[];
  106.         theta=[]; th=0.; dth=0.#dth=[]
  107.         for i in range(3000):
  108.             (r1, x1, y1, vx1, vy1, t1)=self.data[i]
  109.             x.append(x1); y.append(y1); vx.append(vx1); vy.append(vy1)
  110.             t.append(t1); z.append(0.); r.append(r1)
  111.             if i>2:
  112.                 dr1=r[i-1]-r[i-2]
  113.                 dr2=r[i]-r[i-1]
  114.                 if dr1>0 and dr2<0:
  115.                     xp.append(x[i-1])
  116.                     yp.append(y[i-1])
  117.                     tp.append(t[i-1]-0.24500000000000019)
  118.             m=len(self.data)
  119.             n=len(xp)
  120.         if figType==1:
  121.             for j in range(n):
  122.                 k.append(yp[j]/xp[j])
  123.                 theta.append((180/pi)*(arctan((k[0]-k[j])/(1+k[0]*k[j]))))
  124.             for l in range(n-1):
  125.                 th=th+theta[l+1]/tp[l+1]
  126.             self.dth=th/n

  127. def calculaterate():
  128.     listalpha=[]
  129.     listdth=[]
  130.     list1=[0,1,2,4,8,16]
  131.     rate=0.
  132.     for k in range(6):
  133.         list1[k]=0.0002*list1[k]
  134.         c=Mecury(alpha=list1[k])
  135.         c.calculatedth()
  136.         listalpha.append(c.alpha)
  137.         #print c.alpha
  138.         listdth.append(c.dth)
  139.         #print c.dth
  140.     print listalpha,listdth   
  141.     plot(listalpha, listdth, 'ro')
  142.     for m in range(5):
  143.         rate+=listdth[m+1]/listalpha[m+1]
  144.     drate=rate/6
  145.     print drate
  146.     show()

  147. a=Mecury(alpha=0.01)
  148. a.plotMecury()
  149. #b=Mecury(alpha=0.0008)
  150. #b.plotPrecessionrate()

  151. #calculaterate()

复制代码
最终成品:

图中黑线为太阳与远日点连线
看起来好圆,好假,而且运算出来的进动角速度和理论值差了25%……

评分

参与人数 1UCC +2 好评 +1 收起 理由
skulldownz + 2 + 1 让我开了眼界..

查看全部评分

发表于 2011-5-15 14:07:27 | 显示全部楼层
[S::funk:]没仔细看代码,好多4*pi*pi  
看了半天说明,我也没看懂,下面就当我胡说把
R要是有公式可以得N步以后的R
也许你可以把每圈的r分成2区间,然后各取一个最有代表性的R再按条件比较,得R,如此反复迭代得R(x,y)
就是不断划分R,去逼近远日点
另外水星轨道每一圈的世界坐标系旋转后好象都是一样的?也许计算机图形学里面的坐标旋转Matrix可以用在这里减少计算量
回复

使用道具 举报

发表于 2011-5-2 17:29:25 | 显示全部楼层
嗯,各种看不懂
回复

使用道具 举报

发表于 2011-5-2 15:40:11 | 显示全部楼层
你们再说些什么
完全没有看懂啊
回复

使用道具 举报

发表于 2011-5-2 14:45:25 | 显示全部楼层
我连基本的经典物理学直线运动相关方程都想不起来了
回复

使用道具 举报

发表于 2011-4-27 21:01:03 | 显示全部楼层
本帖最后由 黑暗枪骑兵 于 2011-4-27 08:01 编辑
尼奇怪 发表于 2011-4-26 23:10
回复 黑暗枪骑兵 的帖子

我需要的效果不是那么简单的


我擦。。。我完全理解错了= =
回复

使用道具 举报

 楼主| 发表于 2011-4-27 20:53:20 | 显示全部楼层
本帖最后由 尼奇怪 于 2011-4-27 20:56 编辑
2qwer 发表于 2011-4-27 18:34
那你為何不用大小姐的方法來取r的極大值後才代入公式中計算呢?

喵~


是这个样子的,x,y为自变量,r为x,y所决定的一个因变量(在这里就是r为x,y的平方和),所以不是简单的说知道了r的极值后代入算式就能获得对应的x,y值(满足条件的x,y可有无穷组)

呃……其实我已经做完了,不过现在觉得原来解决这个问题的办法十分蛋疼(x,y,r各使用了一个长度为n的数组保存所有数据,然后把r极值处的元素序号对应的x,y抽出来)所以想知道有没有更简洁的思路
回复

使用道具 举报

发表于 2011-4-27 18:34:17 | 显示全部楼层
尼奇怪 发表于 2011-4-27 12:10
回复 黑暗枪骑兵 的帖子

我需要的效果不是那么简单的

那你為何不用大小姐的方法來取r的極大值後才代入公式中計算呢?

喵~
p.s.其實一點也不懂的路過的說~~~
回复

使用道具 举报

 楼主| 发表于 2011-4-27 12:10:05 | 显示全部楼层
回复 黑暗枪骑兵 的帖子

我需要的效果不是那么简单的
1.我要找的是r的极大值,而不是最大值,就是说在一定区间内的最大值,而非全区间内最大值
2.我需要的不是r的极值,而是对应于r出现极大值时的x,y的值

点评

黑骑中文很弱的~~偶尔也会理解错~~ 我其实也看错了~~路过~~  发表于 2011-4-27 12:23
回复

使用道具 举报

发表于 2011-4-27 07:16:50 | 显示全部楼层
尼奇怪 发表于 2011-4-26 08:07
回复 黑暗枪骑兵 的帖子

询问一下:

你把那些数值放入一个Array里,然后用max(array名)来得到最大值
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|DeepTimes.NET 太空游戏站