[关闭]
@2014301020054 2016-11-21T12:23:50.000000Z 字数 9981 阅读 407

Exercise_09 : The Billiard Problem

python physics 陈佩卓 2014301020054


Abstract

Here we consider the problem of a ball moving without friction on a horizontal table. We imagine that there are walls at the edges of the table that reflect the ball perfectly and that there is no friction force between the ball and the table. We can think of this as a billiard ball that moves without friction on a perfect billiard table. The ball is given some initial velocity,and the problem is to calculate and understand the resulting trajectory. This is known as the stadium billiard problem.


Background

In this problem, I will not consider the effect of friction, which means the billiard ball will move without friction on a perfect billiard table.

The moving

Except for the collisions with the walls, the motion of the billiard is quite simple. Between collisions the velocity is constant so we have:

where and change only through collisions with the walls. These equations can be solved using our Euler algorithm.

The collision

It is then useful to calculate the components of parallel and perpendicular to the wall.
These are just:

After reflection, the velocity becomes:

The Chaos Theory

We know Chaos theory is the field of study in mathematics that studies the behavior of dynamical systems that are highly sensitive to initial conditions—a response popularly referred to as the butterfly effect. Small differences in initial conditions (such as those due to rounding errors in numerical computation) yield widely diverging outcomes for such dynamical systems, rendering long-term prediction impossible in general. This happens even though these systems are deterministic, meaning that their future behavior is fully determined by their initial conditions, with no random elements involved. In other words, the deterministic nature of these systems does not make them predictable. This behavior is known as deterministic chaos, or simply chaos.

The Lorenz Attractor

Having been aware of them,we can safely say that it will not be hard for us to draw all the plot we needed.One points need to be mentioed.A hall mark of a chaotic system is an extreme sensitivity to intial conditions.This property is also found in the Lorentz attractor:

The Lorenz variables are derived from the temperature, density and velocity variables in the original Navier-Stokes equations, and the parameters are measures of the temperature difference across the fluid and other fluid parameters.


Main Body

Problem3.31

Study the behavior for other types of tables. One interesting possibility is a square table with a circular interior wall located either in the center, or slightly off-center. Another possibility is an elliptical table.

For the trajectory of the billiard ball in the case of square boundary

Code

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. class billiard_rectangular:
  4. def __init__(self,x_0,y_0,vx_0,vy_0,N,dt):
  5. self.x_0 = x_0
  6. self.y_0 = y_0
  7. self.vx_0 = vx_0
  8. self.vy_0 = vy_0
  9. self.N = N
  10. self.dt = dt
  11. def motion_calculate(self):
  12. self.x = []
  13. self.y = []
  14. self.vx = []
  15. self.vy = []
  16. self.t = [0]
  17. self.x.append(self.x_0)
  18. self.y.append(self.y_0)
  19. self.vx.append(self.vx_0)
  20. self.vy.append(self.vy_0)
  21. for i in range(1,self.N):
  22. self.x.append(self.x[i - 1] + self.vx[i - 1]*self.dt)
  23. self.y.append(self.y[i - 1] + self.vy[i - 1]*self.dt)
  24. self.vx.append(self.vx[i - 1])
  25. self.vy.append(self.vy[i - 1])
  26. if (self.x[i] < -1.0):
  27. self.x[i],self.y[i] = self.correct('x>-1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  28. self.vx[i] = - self.vx[i]
  29. elif(self.x[i] > 1.0):
  30. self.x[i],self.y[i] = self.correct('x<1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  31. self.vx[i] = - self.vx[i]
  32. elif(self.y[i] < -1.0):
  33. self.x[i],self.y[i] = self.correct('y>-1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  34. self.vy[i] = -self.vy[i]
  35. elif(self.y[i] > 1.0):
  36. self.x[i],self.y[i] = self.correct('y<1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  37. self.vy[i] = -self.vy[i]
  38. else:
  39. pass
  40. self.t.append(self.t[i - 1] + self.dt)
  41. return self.x, self.y
  42. def correct(self,condition,x,y,vx,vy):
  43. vx_c = vx/100.0
  44. vy_c = vy/100.0
  45. while eval(condition):
  46. x = x + vx_c*self.dt
  47. y = y + vy_c*self.dt
  48. return x-vx_c*self.dt,y-vy_c*self.dt
  49. def reflect(self):
  50. pass
  51. def plot(self):
  52. plt.figure(figsize = (8,8))
  53. plt.xlim(-1,1)
  54. plt.ylim(-1,1)
  55. plt.xlabel('x')
  56. plt.ylabel('y')
  57. plt.plot(self.x,self.y,'g')
  58. plt.show()

When N=2000

For the trajectory of the billiard ball in the case of elliptical boundary

Code

  1. class billiard_ellipse(billiard_circle): ### x^2/3+y^2/2 = 1
  2. def motion_calculate(self):
  3. self.x = []
  4. self.y = []
  5. self.vx = []
  6. self.vy = []
  7. self.t = [0]
  8. self.x.append(self.x_0)
  9. self.y.append(self.y_0)
  10. self.vx.append(self.vx_0)
  11. self.vy.append(self.vy_0)
  12. for i in range(1,self.N):
  13. self.x.append(self.x[i - 1] + self.vx[i - 1]*self.dt)
  14. self.y.append(self.y[i - 1] + self.vy[i - 1]*self.dt)
  15. self.vx.append(self.vx[i - 1])
  16. self.vy.append(self.vy[i - 1])
  17. if (self.x[i]**2/3+self.y[i]**2/2 > 1.0):
  18. self.x[i],self.y[i] = self.correct('x**2/3+y**2/2 < 1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  19. self.vx[i],self.vy[i] = self.reflect((2./3)*self.x[i],self.y[i],self.vx[i - 1], self.vy[i - 1])
  20. self.t.append(self.t[i - 1] + self.dt)
  21. return self.x, self.y
  22. def plot(self):
  23. plt.figure(figsize = (8,6))
  24. plt.xlim(-2.2,2.2)
  25. plt.ylim(-2,2)
  26. plt.xlabel('x')
  27. plt.ylabel('y')
  28. self.plot_boundary()
  29. plt.plot(self.x,self.y,'b')
  30. plt.show()
  31. def plot_boundary(self):
  32. theta = 0
  33. x = []
  34. y = []
  35. while theta < 2*np.pi:
  36. x.append(np.sqrt(3)*np.cos(theta))
  37. y.append(np.sqrt(2)*np.sin(theta))
  38. theta+= 0.01
  39. plt.title(r'Elliptical stadium $\frac{x^2}{4}+\frac{y^2}{3} = 3$')
  40. plt.plot(x,y)

Result

For the trajectory of the billiard ball in the case of square with an inner circle boundary, and the circle is in the center.

Code

  1. class billiard_innercircle(billiard_circle):
  2. def motion_calculate(self):
  3. self.x = []
  4. self.y = []
  5. self.vx = []
  6. self.vy = []
  7. self.t = [0]
  8. self.x.append(self.x_0)
  9. self.y.append(self.y_0)
  10. self.vx.append(self.vx_0)
  11. self.vy.append(self.vy_0)
  12. for i in range(1,self.N):
  13. self.x.append(self.x[i - 1] + self.vx[i - 1]*self.dt)
  14. self.y.append(self.y[i - 1] + self.vy[i - 1]*self.dt)
  15. self.vx.append(self.vx[i - 1])
  16. self.vy.append(self.vy[i - 1])
  17. if (self.x[i] < -1.0):
  18. self.x[i],self.y[i] = self.correct('x>-1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  19. self.vx[i] = - self.vx[i]
  20. elif(self.x[i] > 1.0):
  21. self.x[i],self.y[i] = self.correct('x<1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  22. self.vx[i] = - self.vx[i]
  23. elif(self.y[i] < -1.0):
  24. self.x[i],self.y[i] = self.correct('y>-1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  25. self.vy[i] = -self.vy[i]
  26. elif(self.y[i] > 1.0):
  27. self.x[i],self.y[i] = self.correct('y<1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  28. self.vy[i] = -self.vy[i]
  29. elif(self.x[i]**2+self.y[i]**2<0.01):
  30. self.x[i],self.y[i] = self.correct('x**2+y**2 > 0.01',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  31. self.vx[i],self.vy[i] = self.reflect(self.x[i],self.y[i],self.vx[i - 1], self.vy[i - 1])
  32. self.t.append(self.t[i - 1] + self.dt)
  33. return self.x, self.y
  34. def plot_boundary(self):
  35. theta = 0
  36. x = []
  37. y = []
  38. while theta < 2*np.pi:
  39. x.append(0.1*np.cos(theta))
  40. y.append(0.1*np.sin(theta))
  41. theta+= 0.01
  42. plt.plot(x,y)

result

For the trajectory of the billiard ball in the case of square with an inner circle boundary and the circle is slightly off-center.

Code

  1. class billiard_innercircle2(billiard_circle):
  2. def motion_calculate(self):
  3. self.x = []
  4. self.y = []
  5. self.vx = []
  6. self.vy = []
  7. self.t = [0]
  8. self.x.append(self.x_0)
  9. self.y.append(self.y_0)
  10. self.vx.append(self.vx_0)
  11. self.vy.append(self.vy_0)
  12. for i in range(1,self.N):
  13. self.x.append(self.x[i - 1] + self.vx[i - 1]*self.dt)
  14. self.y.append(self.y[i - 1] + self.vy[i - 1]*self.dt)
  15. self.vx.append(self.vx[i - 1])
  16. self.vy.append(self.vy[i - 1])
  17. if (self.x[i] < -1.0):
  18. self.x[i],self.y[i] = self.correct('x>-1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  19. self.vx[i] = - self.vx[i]
  20. elif(self.x[i] > 1.0):
  21. self.x[i],self.y[i] = self.correct('x<1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  22. self.vx[i] = - self.vx[i]
  23. elif(self.y[i] < -1.0):
  24. self.x[i],self.y[i] = self.correct('y>-1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  25. self.vy[i] = -self.vy[i]
  26. elif(self.y[i] > 1.0):
  27. self.x[i],self.y[i] = self.correct('y<1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  28. self.vy[i] = -self.vy[i]
  29. elif((self.x[i] - 0.05)**2+self.y[i]**2<0.01):
  30. self.x[i],self.y[i] = self.correct('(x - 0.05)**2+y**2 > 0.01',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  31. self.vx[i],self.vy[i] = self.reflect(self.x[i]-0.05,self.y[i],self.vx[i - 1], self.vy[i - 1])
  32. self.t.append(self.t[i - 1] + self.dt)
  33. return self.x, self.y
  34. def plot_boundary(self):
  35. theta = 0
  36. x = []
  37. y = []
  38. plt.title(r'$(x-0.5)^2+y^2 = 0.01$')
  39. while theta < 2*np.pi:
  40. x.append(0.1*np.cos(theta)+0.5)
  41. y.append(0.1*np.sin(theta))
  42. theta+= 0.01
  43. plt.plot(x,y)

Result

For the trajectory of the billiard ball in the case of circular boundary.

Code

  1. class billiard_circle(billiard_rectangular):
  2. def motion_calculate(self):
  3. self.x = []
  4. self.y = []
  5. self.vx = []
  6. self.vy = []
  7. self.t = [0]
  8. self.x.append(self.x_0)
  9. self.y.append(self.y_0)
  10. self.vx.append(self.vx_0)
  11. self.vy.append(self.vy_0)
  12. for i in range(1,self.N):
  13. self.x.append(self.x[i - 1] + self.vx[i - 1]*self.dt)
  14. self.y.append(self.y[i - 1] + self.vy[i - 1]*self.dt)
  15. self.vx.append(self.vx[i - 1])
  16. self.vy.append(self.vy[i - 1])
  17. if (np.sqrt( self.x[i]**2+self.y[i]**2 ) > 1.0):
  18. self.x[i],self.y[i] = self.correct('np.sqrt(x**2+y**2) < 1.0',self.x[i - 1], self.y[i - 1], self.vx[i - 1], self.vy[i - 1])
  19. self.vx[i],self.vy[i] = self.reflect(self.x[i],self.y[i],self.vx[i - 1], self.vy[i - 1])
  20. self.t.append(self.t[i - 1] + self.dt)
  21. return self.x, self.y
  22. def reflect(self,x,y,vx,vy):
  23. module = np.sqrt(x**2+y**2) ### normalization
  24. x = x/module
  25. y = y/module
  26. v = np.sqrt(vx**2+vy**2)
  27. cos1 = (vx*x+vy*y)/v
  28. cos2 = (vx*y-vy*x)/v
  29. vt = -v*cos1
  30. vc = v*cos2
  31. vx_n = vt*x+vc*y
  32. vy_n = vt*y-vc*x
  33. return vx_n,vy_n
  34. def plot(self):
  35. plt.figure(figsize = (8,8))
  36. plt.xlim(-1,1)
  37. plt.ylim(-1,1)
  38. plt.xlabel('x')
  39. plt.ylabel('y')
  40. self.plot_boundary()
  41. plt.plot(self.x,self.y,'b')
  42. plt.show()
  43. def phase_space_plot(self):
  44. plt.figure(figsize = (16,8))
  45. plt.subplot(121)
  46. plt.xlabel('x')
  47. plt.ylabel(r'$v_x$')
  48. plt.scatter(self.x,self.vx, s=1)
  49. plt.subplot(122)
  50. plt.xlabel('y')
  51. plt.ylabel(r'$v_x$')
  52. plt.scatter(self.y,self.vx, s=1)
  53. plt.show()
  54. def phase_plot(self):
  55. plt.figure(figsize = (8,8))
  56. record_x = []
  57. record_vx = []
  58. for i in range(len(self.x)):
  59. if (abs(self.y[i] - 0)<0.001):
  60. record_vx.append(self.vx[i])
  61. record_x.append(self.x[i])
  62. plt.xlabel('x')
  63. plt.ylabel(r'$v_x$')
  64. plt.scatter(record_x,record_vx,s=1)
  65. plt.show()
  66. def plot_boundary(self):
  67. theta = 0
  68. x = []
  69. y = []
  70. while theta < 2*np.pi:
  71. x.append(np.cos(theta))
  72. y.append(np.sin(theta))
  73. theta+= 0.01
  74. plt.plot(x,y)

Result


Conclusion

Ths chaotic system will present when the boundary is composed by some shapes (different or same).
If the boundary is a simple regular shape, the chaotic situation cannot be observed.


Acknowledgment

Xiongpeiyu

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