[关闭]
@zy-0815 2016-11-13T16:48:11.000000Z 字数 6534 阅读 1112

计算物理第八次作业

计算物理


摘要

经过上次的学习和作业练习,我们更深刻地理解了混沌运动的图像及其性质,在此基础上,我们将进一步探究混沌现象的性质,同时尝试使用Vpython对程序结果进行表达。本次作业主要对于习题3.18, 3.19, 3.20, 3.21的相关习题进行探究和解答,并借此练习Vpython的使用。

背景介绍

经过我们上次的学习,我们发现混沌现象与有关,但当我们连续改变值时,又会发现新的现象。同时,就3D动画演示来说,对于我们更形象理解物体的运动有极大的帮助,本次的新平台Vpython便是一个非常好的工具,因此对它的掌握也是十分必要的。

正文

1. Problem 3.18

1.1
首先我们先回顾上周的程序,即做出figure 3.9,此处我们对程序略作修改,将精度改为0.01,步长提高到50000步,
尽管运行时需要时间,但图像质量较好,如下:

  1. import pylab as pl
  2. import math
  3. class Simple_Pendulum :
  4. def __init__(self,i=0,initial_theta=0.2,time_step=0.04,total_time=50000,length=9.8,\
  5. g=9.8, initial_omega=0,q=0.5,Fd=1.2,omegaD=0.66667):
  6. self.theta=[initial_theta]
  7. self.theta0=[initial_theta]
  8. self.t=[0]
  9. self.omega=[initial_omega]
  10. self.dt=time_step
  11. self.time=total_time
  12. self.g=g
  13. self.l=length
  14. self.q=q
  15. self.Fd=Fd
  16. self.omegaD=omegaD
  17. self.a=[0]
  18. self.b=[0]
  19. def run(self):
  20. _time=0
  21. while(_time<self.time):
  22. self.omega.append(self.omega[-1]-((self.g/self.l)*math.sin(self.theta[-1])+\
  23. self.q*self.omega[-1]-self.Fd*math.sin(self.omegaD*self.t[-1]))*self.dt)
  24. self.theta.append(self.theta[-1]+self.omega[-1]*self.dt)
  25. self.t.append(_time)
  26. _time += self.dt
  27. if(self.theta[-1]>=math.pi):
  28. self.theta[-1]=self.theta[-1]-2*math.pi
  29. if(self.theta[-1]<=-math.pi):
  30. self.theta[-1]=self.theta[-1]+2*math.pi
  31. if((self.t[-1])%(2*math.pi/self.omegaD)<0.01 ):
  32. self.a.append(self.omega[-1])
  33. self.b.append(self.theta[-1])
  34. def show_results(self):
  35. pl.plot(self.b,self.a,'.',label='$F_{D}$=1.2')
  36. pl.xlabel('$\\theta$(rad)')
  37. pl.ylabel('$\omega$(rad)')
  38. pl.legend()
  39. pl.title('$\omega$ versus $\\theta$ ' )
  40. pl.show()
  41. a = Simple_Pendulum()
  42. a.run()
  43. a.show_results()

figure_1.png-29.7kB
当然,我们可以改变的取值以得到不同情况下的图像,如下:
figure_2.png-32.4kB
显然,混沌效应只在特殊的值附近出现,在图中即

1.2
然后我们进一步改变的取值,分别取为1.4,1.44,1.465,同时依据Figure 3.10修改其他参数,即:time step(dt)=0.01,q=1/2,l=g=9.8,
则图像如下:
1.png-19.7kB

2. Problem 3.20

这里我们将试图做出类似Figure 3.11的图像,即的关系图,其中取值范围为1.35-1.5

2.1
我们利用上次课的结论,做出和时间的图像,当我们取时获得如下图像:
figure_3.10-a.png-46.3kB
随着我们增加的值,令其为1.44,图像变为:
figure_3.10-b.png-48.4kB
发现此时相当于周期变为原来的两倍,我们继续增加,令其为1.465,图像如下:
figure_3.10-c.png-51.4kB
此时的函数图像周期显然为初始的四倍,这种现象即为“周期加倍”(Period doubling)
2.2
我们通过bifurcation diagram方法进行分析发现,在300个驱动力周期之后,将不受初始值影响,即此时应为周期振动,因此当我们取300周期后,且符合时,每相空间内每周期会打出一个点,且该点应为的函数。这样我们便可以画出 关于的图像。
我们修改的主体程序如下:

  1. import pylab as pl
  2. import math
  3. class Simple_Pendulum :
  4. def __init__(self,i=0,initial_theta=0.2,time_step=0.01,total_time=900*math.pi+10,length=9.8,\
  5. g=9.8, initial_omega=0,q=0.5,Fd=1.35,omegaD=0.666667):
  6. self.theta=[initial_theta]
  7. self.theta0=[initial_theta]
  8. self.t=[0]
  9. self.omega=[initial_omega]
  10. self.dt=time_step
  11. self.time=total_time
  12. self.g=g
  13. self.l=length
  14. self.q=q
  15. self.Fd=[Fd]
  16. self.F_d=[Fd]
  17. self.omegaD=omegaD
  18. self.a=[0]
  19. self.b=[0]
  20. self.a0=[0]
  21. self.b0=[0]
  22. self.b1=[0]
  23. def run(self):
  24. _time=0
  25. self.Fd=[1.35]
  26. while(1):
  27. while(_time<self.time):
  28. self.omega.append(self.omega[-1]-((self.g/self.l)*math.sin(self.theta[-1])+\
  29. self.q*self.omega[-1]-self.Fd[-1]*math.sin(self.omegaD*self.t[-1]))*self.dt)
  30. self.theta.append(self.theta[-1]+self.omega[-1]*self.dt)
  31. self.t.append(_time)
  32. _time += self.dt
  33. if(self.theta[-1]>=math.pi):
  34. self.theta[-1]=self.theta[-1]-2*math.pi
  35. if(self.theta[-1]<=-math.pi):
  36. self.theta[-1]=self.theta[-1]+2*math.pi
  37. if(self.t[-1]>(900*math.pi)):
  38. self.a0.append(self.omega[-1])
  39. self.b0.append(self.theta[-1])
  40. if((self.t[-1])%(3*math.pi)<0.01 ):
  41. self.a.append(self.a0[-1])
  42. self.b.append(self.b0[-1])
  43. self.b1.append(self.b[-1])
  44. self.Fd.append(self.Fd[-1]+0.01)
  45. if(self.Fd[-1]>1.5):
  46. break
  47. def show_results(self):
  48. pl.plot(self.Fd,self.b1,'.')
  49. pl.xlabel('$F_{D}$')
  50. pl.ylabel('$\\theta$(rad)')
  51. pl.legend()
  52. pl.title('$\omega$ versus $\\theta$ ' )
  53. pl.show()
  54. a = Simple_Pendulum()
  55. a.run()
  56. a.show_results()

做图如下:
image_1b1f8t5ov1jsb18on1nb81fs1dph3k.png-22.7kB

3.使用Vpython模拟摆的运动

对于混沌效应,我们可以进一步使用Vpython工具,将相空间内展示的东西通过动画做出,这里,我们以程序中自带例子来看:

  1. scene.title = 'Double Pendulum'
  2. scene.height = scene.width = 800
  3. g = 9.8
  4. M1 = 2.0
  5. M2 = 1.0
  6. L1 = 0.5 # physical length of upper assembly; distance between axles
  7. L2 = 1.0 # physical length of lower bar
  8. I1 = M1*L1**2/12 # moment of inertia of upper assembly
  9. I2 = M2*L2**2/12 # moment of inertia of lower bar
  10. d = 0.05 # thickness of each bar
  11. gap = 2*d # distance between two parts of upper, U-shaped assembly
  12. L1display = L1+d # show upper assembly a bit longer than physical, to overlap axle
  13. L2display = L2+d/2 # show lower bar a bit longer than physical, to overlap axle
  14. hpedestal = 1.3*(L1+L2) # height of pedestal
  15. wpedestal = 0.1 # width of pedestal
  16. tbase = 0.05 # thickness of base
  17. wbase = 8*gap # width of base
  18. offset = 2*gap # from center of pedestal to center of U-shaped upper assembly
  19. top = vector(0,0,0) # top of inner bar of U-shaped upper assembly
  20. scene.center = top-vector(0,(L1+L2)/2.,0)
  21. theta1 = 2.1 # initial upper angle (from vertical)
  22. theta2 = 2.4 # initial lower angle (from vertical)
  23. theta1dot = 0 # initial rate of change of theta1
  24. theta2dot = 0 # initial rate of change of theta2
  25. pedestal = box(pos=top-vector(0,hpedestal/2.,offset),
  26. height=1.1*hpedestal, length=wpedestal, width=wpedestal,
  27. color=(0.4,0.4,0.5))
  28. base = box(pos=top-vector(0,hpedestal+tbase/2.,offset),
  29. height=tbase, length=wbase, width=wbase,
  30. color=pedestal.color)
  31. axle = cylinder(pos=top-vector(0,0,gap/2.-d/4.), axis=(0,0,-offset), radius=d/4., color=color.yellow)
  32. frame1 = frame(pos=top)
  33. bar1 = box(frame=frame1, pos=(L1display/2.-d/2.,0,-(gap+d)/2.), size=(L1display,d,d), color=color.red)
  34. bar1b = box(frame=frame1, pos=(L1display/2.-d/2.,0,(gap+d)/2.), size=(L1display,d,d), color=color.red)
  35. axle1 = cylinder(frame=frame1, pos=(L1,0,-(gap+d)/2.), axis=(0,0,gap+d),
  36. radius=axle.radius, color=axle.color)
  37. frame1.axis = (0,-1,0)
  38. frame2 = frame(pos=frame1.axis*L1)
  39. bar2 = box(frame=frame2, pos=(L2display/2.-d/2.,0,0), size=(L2display,d,d), color=color.green)
  40. frame2.axis = (0,-1,0)
  41. frame1.rotate(axis=(0,0,1), angle=theta1)
  42. frame2.rotate(axis=(0,0,1), angle=theta2)
  43. frame2.pos = top+frame1.axis*L1
  44. dt = 0.00005 # energy constancy check fails for dt > 0.0003
  45. t = 0.
  46. C11 = (0.25*M1+M2)*L1**2+I1
  47. C22 = 0.25*M2*L2**2+I2
  48. #### For energy check:
  49. ##gdisplay(x=800)
  50. ##gK = gcurve(color=color.yellow)
  51. ##gU = gcurve(color=color.cyan)
  52. ##gE = gcurve(color=color.red)
  53. while True:
  54. rate(1/dt)
  55. # Calculate accelerations of the Lagrangian coordinates:
  56. C12 = C21 = 0.5*M2*L1*L2*cos(theta1-theta2)
  57. Cdet = C11*C22-C12*C21
  58. a = .5*M2*L1*L2*sin(theta1-theta2)
  59. A = -(.5*M1+M2)*g*L1*sin(theta1)-a*theta2dot**2
  60. B = -.5*M2*g*L2*sin(theta2)+a*theta1dot**2
  61. atheta1 = (C22*A-C12*B)/Cdet
  62. atheta2 = (-C21*A+C11*B)/Cdet
  63. # Update velocities of the Lagrangian coordinates:
  64. theta1dot += atheta1*dt
  65. theta2dot += atheta2*dt
  66. # Update Lagrangian coordinates:
  67. dtheta1 = theta1dot*dt
  68. dtheta2 = theta2dot*dt
  69. theta1 += dtheta1
  70. theta2 += dtheta2
  71. frame1.rotate(axis=(0,0,1), angle=dtheta1)
  72. frame2.pos = top+frame1.axis*L1
  73. frame2.rotate(axis=(0,0,1), angle=dtheta2)
  74. t = t+dt
  75. ## Energy check:
  76. ## K = .5*((.25*M1+M2)*L1**2+I1)*theta1dot**2+.5*(.25*M2*L2**2+I2)*theta2dot**2+\
  77. ## .5*M2*L1*L2*cos(theta1-theta2)*theta1dot*theta2dot
  78. ## U = -(.5*M1+M2)*g*L1*cos(theta1)-.5*M2*g*L2*cos(theta2)
  79. ## gK.plot(pos=(t,K))
  80. ## gU.plot(pos=(t,U))
  81. ## gE.plot(pos=(t,K+U))

该程序即展示了双摆的运动动画,其效果如下
捕获 07.gif-255.4kB

我们可以由此程序为基础进行进一步改进,但由于个人原因并未完全掌握Vpython,后续会对此次作业进行补充

结论

1.对于习题3.18
1.png-19.7kB
2.对于习题3.20
image_1b1f8s6d03gk1h491r5s17a6ft337.png-22.7kB

致谢

与张梓桐同学讨论了Problem 3.20的一些细节
与冉峰同学交流了一些思路和方法
Vpython自带程序

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