[关闭]
@rfhongyi 2016-11-14T03:24:43.000000Z 字数 9371 阅读 763

Exercise_08 : Period Doubling

Problem 3.18 & 3.19 & 3.20

冉峰 弘毅班 2014301020064


11.gif
录制_2016_11_14_11_17_18_547.gif

Abstract

Background


The Main Body

Question 3.18 : Calculate Poincare section for the pendulum as it undergoes the period-doubling route to chaos. Plot versus , with one point plotted for each drive cycle, as in Figure 3.9. Do this work with F_D =1.35,1.4, 1.44, 1.465, using the other parameters as given in connection with Figure 3.10.

  1. import pylab as pl
  2. import math
  3. class oscillatory:
  4. def __init__(self,g=9.8,l=9.8,q=0.5,F_D=1.2,O_D=2/3,time_step=3*math.pi/1000,\
  5. total_time=100,initial_theta=0.2,initial_omega=0):
  6. self.g=g
  7. self.l=l
  8. self.q=q
  9. self.F=F_D
  10. self.O=O_D
  11. self.t=[0]
  12. self.initial_theta=initial_theta
  13. self.initial_omega=initial_omega
  14. self.dt=time_step
  15. self.time= total_time
  16. self.omega= [initial_omega]
  17. self.theta= [initial_theta]
  18. self.nsteps=int(total_time//time_step+1)
  19. self.tmpo=[0]
  20. self.tmpt=[0]
  21. def run(self):
  22. for i in range(self.nsteps):
  23. tmpo=self.omega[i]+(-1*(self.g/self.l)*math.sin(self.theta[i])-\
  24. self.q*self.omega[i]+self.F*math.sin(self.O*self.t[i]))*self.dt
  25. tmpt=self.theta[i]+tmpo*self.dt
  26. while(tmpt<(-1*math.pi) or tmpt>math.pi):
  27. if tmpt<(-1*math.pi):
  28. tmpt+=2*math.pi
  29. if tmpt>math.pi:
  30. tmpt-=2*math.pi
  31. self.omega.append(tmpo)
  32. self.theta.append(tmpt)
  33. self.t.append(self.t[i]+self.dt)
  34. for i in range(len(self.t)):
  35. if self.t[i] // (3 * math.pi) > 300:
  36. if ((2 / 3 * self.t[i]) % (2 * math.pi)) <= (2 / 3 * self.dt * 0.5) or (2 * math.pi - ((2 / 3 * self.t[i]) % (2 * math.pi))) <= (2 / 3 * self.dt * 0.5):
  37. self.tmpo.append(self.omega[i])
  38. self.tmpt.append(self.theta[i])
  39. def show_results(self):
  40. font = {'family': 'serif',
  41. 'color': 'darkred',
  42. 'weight': 'normal',
  43. 'size': 16,}
  44. pl.plot(self.t,self.theta)
  45. #pl.scatter(self.tmpt, self.tmpo)
  46. pl.title(r'$\theta$ versus time', fontdict = font)
  47. pl.xlabel(r'$\theta$(radians)')
  48. pl.ylabel(r'$\omega$(rad/s)')
  49. #pl.xlim(0,3)
  50. #pl.ylim(-3,0)
  51. pl.legend((['$F_D$=1.2']))
  52. pl.show()
  53. a = oscillatory()
  54. a.run()
  55. a.show_results()

Result

8.1.png
8.2.png
8.3.png
8.4.png
8.5.png

It's easy to see that when , the system is in chaotic state. When , the system become well-aligned again, its period is the same as the drive period. When , its period is the twice as the drive period. When , its period is the fourth times as the drive period.


If we chose the time :

where n is integer and is a angle between .
We will have the result that:

8.6.png
8.7.png
8.8.png
8.9.png
It's easy to see that when , there is just one point,when , there is two points, when , there is four points.It's easy to understand this.


  1. import pylab as pl
  2. import math
  3. class oscillatory:
  4. def __init__(self,g=9.8,l=9.8,q=0.5,F_D=1.2,O_D=2/3,time_step=3*math.pi/1000,\
  5. total_time=100,initial_theta=0.2,initial_omega=0):
  6. self.g=g
  7. self.l=l
  8. self.q=q
  9. self.F=F_D
  10. self.O=O_D
  11. self.t=[0]
  12. self.initial_theta=initial_theta
  13. self.initial_omega=initial_omega
  14. self.dt=time_step
  15. self.time= total_time
  16. self.omega= [initial_omega]
  17. self.theta= [initial_theta]
  18. self.nsteps=int(total_time//time_step+1)
  19. self.tmpo=[0]
  20. self.tmpt=[0]
  21. def run(self):
  22. for i in range(self.nsteps):
  23. tmpo=self.omega[i]+(-1*(self.g/self.l)*math.sin(self.theta[i])-\
  24. self.q*self.omega[i]+self.F*math.sin(self.O*self.t[i]))*self.dt
  25. tmpt=self.theta[i]+tmpo*self.dt
  26. while(tmpt<(-1*math.pi) or tmpt>math.pi):
  27. if tmpt<(-1*math.pi):
  28. tmpt+=2*math.pi
  29. if tmpt>math.pi:
  30. tmpt-=2*math.pi
  31. self.omega.append(tmpo)
  32. self.theta.append(tmpt)
  33. self.t.append(self.t[i]+self.dt)
  34. for i in range(len(self.t)):
  35. if self.t[i] // (5 * math.pi) > 300:
  36. if ((2 / 5 * self.t[i]) % (2 * math.pi)) <= (2 / 3 * self.dt * 0.5) or (2 * math.pi - ((2/ 5 * self.t[i]) % (2 * math.pi))) <= (2 / 5 * self.dt * 0.5):
  37. self.tmpo.append(self.omega[i])
  38. self.tmpt.append(self.theta[i])
  39. def show_results(self):
  40. font = {'family': 'serif',
  41. 'color': 'darkred',
  42. 'weight': 'normal',
  43. 'size': 16,}
  44. #pl.plot(self.t,self.theta)
  45. pl.scatter(self.tmpt, self.tmpo)
  46. pl.title(r'$\theta$ versus time', fontdict = font)
  47. pl.xlabel(r'$\theta$(radians)')
  48. pl.ylabel(r'$\omega$(rad/s)')
  49. #pl.xlim(0,3)
  50. #pl.ylim(-3,0)
  51. pl.legend((['$F_D$=1.2']))
  52. pl.show()
  53. a = oscillatory()
  54. a.run()
  55. a.show_results()

Result

I chose the , but unfortunately, I didn't get the right answer. Because I did'n have enough time to solve the bug, so it's not completely.


Vpython run

  1. from __future__ import division
  2. from visual import *
  3. from math import *
  4. q=0.5
  5. l=9.8
  6. g=9.8
  7. f=2/3
  8. dt=0.04
  9. theta0=0.2
  10. omega0=0
  11. ceil=box(pos=(0,5,0),size=(5,0.5,2),material=materials.bricks)
  12. ball=sphere(pos=(l*sin(theta0),5-l*cos(theta0),0),radius=1,material=materials.emissive,color=color.green)
  13. ball.omega=omega0
  14. ball.theta=theta0
  15. ball.t=0
  16. ball.F=0.5
  17. string=curve(pos=[ceil.pos,ball.pos],color=color.blue)
  18. po=arrow(pos=ball.pos,axis=(9.8*ball.omega*cos(ball.theta),9.8*ball.omega*sin(ball.theta),0),color=color.blue)
  19. while True:
  20. rate(100)
  21. ball.omega=ball.omega-((g/l)*sin(ball.theta)+q*ball.omega-ball.F*sin(f*ball.t))*dt
  22. angle_new=ball.theta+ball.omega*dt
  23. while angle_new>pi:
  24. angle_new-=2*pi
  25. while angle_new<-pi:
  26. angle_new+=2*pi
  27. ball.theta=angle_new
  28. ball.pos=(l*sin(ball.theta),5-l*cos(ball.theta),0)
  29. string.pos=[ceil.pos,ball.pos]
  30. po.pos=ball.pos
  31. po.axis=(9.8*ball.omega*cos(ball.theta),9.8*ball.omega*sin(ball.theta),0)
  32. ball.t=ball.t+dt

Result


0.5.gif


1.2.gif


1.35.gif


1.465.gif


Question 3.20 : Calculate the bifurcation diagrams for the pendulum in the vicinity of F_D=1.35 to 1.5. Make a magnified plot of the diagram and obtain an estimate of the Feigenbaum parameter.

  1. import math
  2. import matplotlib.pyplot as pl
  3. pl.rc('text', usetex=True)
  4. pl.rc('font', family='serif')
  5. class bifurcation_diagram:
  6. '''docstring for assignment this week, using the Runga-Kutta method, with reseting process'''
  7. def __init__(self, total_time, time_interval,driving_force_interval):
  8. self.FD = [1.35]
  9. self.dFD = driving_force_interval
  10. self.dt = time_interval
  11. self.steps = int(total_time // time_interval) + 1
  12. self.t = [0]
  13. self.omega = [0]
  14. self.theta = [0.2]
  15. self.theta_in_phase = []
  16. self.theta_fixed = []
  17. while self.FD[-1] < 1.5:
  18. self.FD.append(self.FD[-1] + self.dFD)
  19. def calculate(self):
  20. for j in range(len(self.FD)):
  21. self.t = [0]
  22. self.omega = [0]
  23. self.theta = [0.2]
  24. self.omega_in_phase = []
  25. self.theta_in_phase = []
  26. for i in range(self.steps):
  27. midpoint_omega = self.omega[i] + 0.5 * (-math.sin(self.theta[i]) - 0.5 * self.omega[i] + self.FD[j] * math.sin(0.66666666667 * self.t[i])) * self.dt
  28. midpoint_time = self.t[i] + 0.5 * self.dt
  29. midpoint_theta = self.theta[i] + 0.5 * self.dt
  30. temporary_theta = self.theta[i] + midpoint_omega * self.dt
  31. temporary_omega = self.omega[i] + (-math.sin(midpoint_theta) - 0.5 * midpoint_omega + self.FD[j] * math.sin(0.66666666667 * midpoint_time)) * self.dt
  32. if math.fabs(temporary_theta) > math.pi :
  33. if temporary_theta > 0 :
  34. while temporary_theta > math.pi :
  35. temporary_theta = temporary_theta - 2 * math.pi
  36. else :
  37. while temporary_theta < -math.pi :
  38. temporary_theta = temporary_theta + 2 * math.pi
  39. self.theta.append(temporary_theta)
  40. self.omega.append(temporary_omega)
  41. self.t.append(self.t[i] + self.dt)
  42. for i in range(len(self.t)):
  43. if self.t[i] // (3 * math.pi) > 300:
  44. if ((2 / 3 * self.t[i]) % (2 * math.pi)) <= (2 / 3 * self.dt * 0.5) or (2 * math.pi - ((2 / 3 * self.t[i]) % (2 * math.pi))) <= (2 / 3 * self.dt * 0.5):
  45. self.theta_in_phase.append(self.theta[i])
  46. pl.plot([self.FD[j]] * len(self.theta_in_phase), self.theta_in_phase,'b.', linewidth = 0, alpha = 0.1)
  47. pl.xlim(1.35,1.5)
  48. pl.ylim(1,3)
  49. pl.xlabel("$F_D$")
  50. pl.ylabel(r'$\theta$(radians)')
  51. pl.title(r'Bifurcation diagram $\theta$ versus $F_D$')
  52. pl.show()
  53. a1 = bifurcation_diagram(total_time = 4000, time_interval = 0.01, driving_force_interval = 0.001)
  54. a1.calculate()

Result

Bifurcation_diagram_original_frequency.png


Conclusion


Thanks For

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