[关闭]
@rfhongyi 2016-12-11T03:29:12.000000Z 字数 8992 阅读 2924

Exercise_10 : Precession of the Perihelion of Mercury

Problem 4.10 & 4.11

冉峰 弘毅班 2014301020064


percession.gif


Abstract

Background

Kepler's Laws

The inverse-square law and the stability of plantery orbits

The precession of the perihelion of Mercury


The Main Body

Code

  1. Created on Sat Nov 26 18:04:56 2016
  2. @author: RanFeng
  3. import math
  4. import matplotlib.pyplot as plt
  5. GM=4*(math.pi**2)
  6. perihelion=0.39*(1-0.206)
  7. class Precession:
  8. def __init__(self,e=0.206,time=1,dt=0.0001,vcoefficient=1.1,beta=2.1,alpha=0.01):
  9. self.alpha=alpha
  10. self.beta=beta
  11. self.vcoefficient=vcoefficient
  12. self.e=e
  13. self.a=perihelion/(1-e)
  14. self.x0=self.a*(1+e)
  15. #self.x0=1
  16. self.y0=0
  17. self.vx0=0
  18. self.vy0=self.vcoefficient*math.sqrt((GM*(1-self.e))/(self.a*(1+self.e)))
  19. #self.vy0=2*math.pi
  20. self.X=[self.x0]
  21. self.Y=[self.y0]
  22. self.Vx=[self.vx0]
  23. self.Vy=[self.vy0]
  24. self.T=[0]
  25. self.dt=dt
  26. self.time=time
  27. self.ThetaPrecession=[]
  28. self.TimePrecession=[]
  29. def run(self):
  30. while self.T[-1]<self.time:
  31. r=math.sqrt(self.X[-1]**2+self.Y[-1]**2)
  32. newVx=self.Vx[-1]-(GM*(1+self.alpha/r**2)*self.X[-1]/r**(1+self.beta))*self.dt
  33. newX=self.X[-1]+newVx*self.dt
  34. newVy=self.Vy[-1]-(GM*(1+self.alpha/r**2)*self.Y[-1]/r**(1+self.beta))*self.dt
  35. newY=self.Y[-1]+newVy*self.dt
  36. if abs(newX*newVx+newY*newVy)<0.0014 and r<self.a:
  37. theta=math.acos(self.X[-1]/r)*180/math.pi
  38. if (self.Y[-1]/r)<0:
  39. theta=360-theta
  40. theta=abs(theta-180)
  41. self.ThetaPrecession.append(theta)
  42. self.TimePrecession.append(self.T[-1])
  43. self.Vx.append(newVx)
  44. self.Vy.append(newVy)
  45. self.X.append(newX)
  46. self.Y.append(newY)
  47. self.T.append(self.T[-1]+self.dt)
  48. def show_results(self):
  49. plt.plot(self.X,self.Y,'g')
  50. plt.legend(loc='upper right',frameon=False,fontsize='small')
  51. plt.grid(True)
  52. plt.title('Simulation of the precession of Mercury')
  53. plt.xlabel('x(AU)')
  54. plt.ylabel('y(AU)')
  55. ax = plt.gca()
  56. ax.set_aspect(1)
  57. #plt.xlim(-1,1)
  58. #plt.ylim(-0.6,0.6)
  59. #plt.scatter(0,0)
  60. A = Precession()
  61. A.run()
  62. A.show_results()

Result

3.png

2.png

1.png


11.png

12.png

13.png




22.png


24.png

25.png

26.png


VPython code

  1. from visual import *
  2. #from Numeric import *
  3. print '''
  4. Simple solar system model showing the orbits of the planets
  5. Note: In this version the orbits are not tilted so
  6. the longitude of the ascending node is not correct.
  7. created by Lensyl Urbano, Jan. 2006.
  8. '''
  9. class orbit:
  10. def __init__(self,e=0.0,rad=1.0, mu=10.0, planet_size=1.0, period=365,
  11. inclination=0.0, lap=0.0, frate=10000000):
  12. self.orbit_path = curve(color=color.green,radius=0.075)
  13. self.planet = sphere(color=color.yellow,radius=planet_size)
  14. if e >= 1.0:
  15. e = 0.99
  16. if e < 0.0:
  17. e = 0.0
  18. fx = 2.0 - 2.0*min(abs((1-e*e)/(1-e)), abs(-(1-e*e)/(1+e)))
  19. self.fx = fx
  20. self.e = e
  21. self.rad = rad
  22. self.dangle = 360./period
  23. self.inclination = inclination
  24. self.lap = lap
  25. for i in range(int(period)+1):
  26. rate(frate)
  27. theta = radians(float(360.*i/period))
  28. #h_sq = a*(1-e*e)*mu
  29. r = (1-e*e)/(1-e*cos(theta))
  30. nx = rad*(r*cos(theta) - fx)
  31. ny = rad*r*sin(theta)
  32. #print i, f, r, cos(theta), sin(theta), nx, ny
  33. #nz = rotate(vector(nx,ny,0.0), angle=inclination,
  34. posi = rotate(vector(nx,ny,0.0), angle=radians(inclination), axis=(0,1,0))
  35. posi = rotate(posi, angle=radians(lap), axis=(0,0,1))
  36. self.orbit_path.append(pos=posi)
  37. self.planet.pos=posi
  38. self.angle = 0.0
  39. def re_draw(self,e=0.0,rad=1.0,mu=10.0, frate=10000000):
  40. #redraw last path
  41. if e >= 1.0:
  42. e = 0.99
  43. if e < 0.0:
  44. e = 0.0
  45. fx = 2.0 - 2.0*min(abs((1-e*e)/(1-e)), abs(-(1-e*e)/(1+e)))
  46. self.fx = fx
  47. self.e = e
  48. self.rad = rad
  49. for i in range(361):
  50. rate(frate)
  51. theta = radians(float(i))
  52. #h_sq = a*(1-e*e)*mu
  53. r = (1-e*e)/(1-e*cos(theta))
  54. nx = rad*(r*cos(theta) - fx)
  55. ny = rad*r*sin(theta)
  56. self.orbit_path.pos[i]=vector(nx, ny, 0.0)
  57. def move_planet(self):
  58. self.angle = self.angle + self.dangle
  59. #to show the planet orbiting the Sun
  60. theta = radians(float(self.angle))
  61. r = (1-self.e*self.e)/(1-self.e*cos(theta))
  62. nx = self.rad*(r*cos(theta) - self.fx)
  63. ny = self.rad*r*sin(theta)
  64. posi=rotate(vector(nx,ny,0.0), angle=radians(self.inclination), axis=(0,1,0))
  65. posi = rotate(posi, angle=radians(self.lap), axis=(0,0,1))
  66. self.planet.pos = posi
  67. #class proton:
  68. origx = 0
  69. origy = 0
  70. w = 704 #+4+4
  71. h = 576 #+24+4
  72. scene.width=w
  73. scene.height=h
  74. scene.x = origx
  75. scene.y = origy
  76. mu = 10.0 #gravitational acceleration
  77. #e = 0.6 #eccentricity
  78. #a = 10.0 #distance of sun from center of elipse
  79. # to draw an elipse
  80. nucleus = frame()
  81. p1 = sphere(color=color.white, frame=nucleus)
  82. #orbitor = sphere()
  83. e1 = orbit(e=0.50, rad=15.0, mu=mu,
  84. planet_size=0.5, period=365,
  85. lap=90)
  86. ##e2 = orbit(e=0.0, rad=15.0, mu=mu,
  87. ## planet_size=1.0, period=365,
  88. ## lap=0, inclination=90)
  89. runtime = 0.0
  90. framerate = 60
  91. pick = None
  92. while 1:
  93. rate(framerate)
  94. runtime += 1.0/framerate
  95. e1.move_planet()
  96. ## e2.move_planet()

Result

2016-11-27 18_36_40.gif
2016-11-27 18_38_16.gif
2016-11-27 19_08_31.gif

2016-11-27 19_15_37.gif


Conclusion


Thanks For

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注