Advertisement
Guest User

Untitled

a guest
May 5th, 2016
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.85 KB | None | 0 0
  1. from enum import Enum
  2. import math
  3. import matplotlib.pyplot as plt
  4. import matplotlib.animation as animation
  5. from math import cos, sin, exp
  6. import cmath
  7.  
  8. planc_const = 1e1
  9. class Grid:
  10. h = 0
  11. tau = 0
  12. l = 0
  13.  
  14. def __init__(self, h, tau, l):
  15. self.h, self.tau, self.l = h, tau, l
  16.  
  17. def getH(self):
  18. return self.h
  19.  
  20. def getL(self):
  21. return self.l
  22.  
  23. def getTau(self):
  24. return self.tau
  25.  
  26. def getStepCount(self):
  27. return math.ceil(self.l / self.h) + 1
  28.  
  29.  
  30. class ConditionMode(Enum):
  31. NormalFunction = 0,
  32. DeriviativeFunction = 1
  33.  
  34.  
  35. class Condition:
  36. def __init__(self, Condition, mode=ConditionMode):
  37. self.Condition, self.mode = Condition, mode
  38.  
  39.  
  40. class Task:
  41. def __init__(self, l, a, StartCondition, BoundaryConditions):
  42. assert isinstance(StartCondition, Condition)
  43. self.l, self.a = l, a
  44. self.StartCondition, self.BoundaryConditions = StartCondition, BoundaryConditions
  45.  
  46. def getL(self):
  47. return self.l
  48.  
  49. def getA(self):
  50. return self.a
  51.  
  52. def getStartConditions(self):
  53. return self.StartCondition
  54.  
  55. def getBoundaryConditions(self):
  56. return self.BoundaryConditions
  57.  
  58.  
  59. def buildGenerator(condition, stepCount, step):
  60. assert isinstance(condition, Condition)
  61. prevElement = 0
  62. for i in range(stepCount):
  63. if (condition.mode == ConditionMode.DeriviativeFunction):
  64. currentElement = prevElement + step * condition.Condition(i * step)
  65. yield currentElement
  66. prevElement = currentElement
  67. else:
  68. yield condition.Condition(i * step)
  69.  
  70.  
  71. def primeCalc(prevU, h, tau, a, BoundaryConditions, PotentialFunc, tick=0):
  72. ##u(x,t+1)-u(x,t)/tau = u(x-1,t) -2u(x,t) + u(x+1,t)/(h^2) + PotentialFunc
  73. ##assert a * tau / (h * h) < 0.5
  74. currentU = [0] * len(prevU)
  75. for j in range(1, len(prevU) - 1):
  76. currentU[j] = prevU[j] + a * tau * (prevU[j - 1] - 2 * prevU[j] + prevU[j + 1]) / (h * h) + tau * PotentialFunc(j * h, tick * tau) * prevU[j]
  77.  
  78. # u0-u1/h = u`(0)
  79. if (BoundaryConditions[0].mode == ConditionMode.DeriviativeFunction):
  80. currentU[0] = currentU[1] + h * BoundaryConditions[0].Condition(tick * tau)
  81. else:
  82. currentU[0] = BoundaryConditions[0].Condition(tick * tau)
  83. sc = len(prevU)
  84.  
  85.  
  86. # u(l-1)-ul/h=u`(l)
  87. if (BoundaryConditions[1].mode == ConditionMode.DeriviativeFunction):
  88. currentU[sc - 1] = currentU[sc - 2] - h * BoundaryConditions[1].Condition(tick * tau)
  89. else:
  90. currentU[sc - 1] = BoundaryConditions[1].Condition(tick * tau)
  91. return currentU
  92.  
  93.  
  94. def Solve(task, grid, iterationCount, recalcFunc, PotentialFunc):
  95. assert isinstance(task, Task)
  96. assert (task.getL() == grid.getL())
  97.  
  98. prevU = [x for x in buildGenerator(task.getStartConditions(), grid.getStepCount(), grid.getH())]
  99.  
  100. xx = []
  101. for i in range(grid.getStepCount()):
  102. xx.append(i * grid.getH())
  103.  
  104. currentU = prevU
  105. for i in range(iterationCount):
  106. #print(currentU)
  107. yield xx, currentU
  108. prevU = [x for x in currentU]
  109. h = grid.getH()
  110. tau = grid.getTau()
  111. a = task.getA()
  112. currentU = recalcFunc(prevU, h, tau, a, task.getBoundaryConditions(), PotentialFunc, i)
  113.  
  114.  
  115.  
  116. def shuttleCalc(prevU, h, tau, a, BoundaryConditions, PotentialFunc, tick=0):
  117. # ux,t+1 - ux,t/tau = a*(ux-1,t+1 -2ux,t+1 + ux+1,t+1)/h**2 + PotentialFunc(r, t) * u(x,t+1)
  118. # -a/h**2(ux-1,t+1 + ux+1,t+1) + (1/tau +2a/h**2) * ux,t+1 = 1/tau * ux,t
  119. #
  120. ## -a/h**2 (1/tau +2a/h**2) -a/h**2
  121. gamma = a * tau / (h ** 2)
  122. a_orig = -gamma
  123. b_orig = (1 + 2 * gamma)
  124. c_orig = a_orig
  125. n = len(prevU)
  126.  
  127. currentU = [0] * n
  128. ##i*h*psi^ = Hpsi ==
  129. ##i*h * psi^ = -h^2/2*m d2psi/dx2
  130. #psi^=-h/2mi
  131. ##psi^ = -h/i^3 d2psi/dx2
  132.  
  133. e = [a_orig] * n
  134. c = [c_orig] * n
  135. d = [b_orig] * n
  136.  
  137. ## u(x, t + 1) - u(x, t)/tau = a * (ux-1,t+1 - 2u(x,t+1) + u(x+1,t+1)/h**2 + p(r,t)*u(x,t +1)
  138. ## -gamma * u(x-1,t+1) -gamma * u(x + 1, t + 1) + (1 + 2gamma - p(r,t) * tau))*u(x,t + 1) = u(x,tau)
  139. for i in range(n):
  140. d[i] -= tau * complex(0, 1) / planc_const * PotentialFunc(i * h, tick * tau)
  141. #assert(abs(1 - tau * complex(0, 1) * PotentialFunc(i * h, tick * tau)) > 0)
  142.  
  143. ##e[0] = BoundaryConditions[0].Condition(tick * tau)
  144. ##e[n - 1] = BoundaryConditions[1].Condition(tick * tau)
  145. #psi1 = alpha * u(0, t + 1) + beta * ( u(0, t + 1) - u(1, t + 1)) /h
  146. #psi2 = alpha * u(l, t + 1) + beta * ( u(l, t + 1) - u(l - 1, t + 1)) /h
  147.  
  148. c[0] = complex(0, 0)
  149. if (BoundaryConditions[0].mode == ConditionMode.DeriviativeFunction):
  150. d[0] = complex(1.0 / h, 0)
  151. e[0] = complex(-1.0 / h, 0)
  152. else:
  153. d[0] = complex(1.0, 0)
  154. e[0] = complex(0.0, 0)
  155.  
  156. e[n - 1] = complex(0, 0)
  157. if (BoundaryConditions[1].mode == ConditionMode.DeriviativeFunction):
  158. d[n - 1] = complex(-1.0 / h, 0)
  159. c[n - 1] = complex(1.0 / h, 0)
  160. else:
  161. d[n - 1] = complex(1.0, 0)
  162. c[n - 1] = complex(0.0, 0)
  163.  
  164. prevU[0] = BoundaryConditions[0].Condition(tick * tau)
  165. prevU[n - 1] = BoundaryConditions[1].Condition(tick * tau)
  166.  
  167. # a_c[1] = -e[0] / d[0]
  168. # b_c[1] = prevU[0] / d[0]
  169. # for i in range(2, n):
  170. # a_c[i] = -e[i] / (d[i] + c[i] * a_c[i - 1])
  171. # b_c[i] = (-c[i] * b_c[i - 1] + prevU[i - 1]) / (d[i] + c[i] * a_c[i - 1])
  172. #
  173. # currentU[n - 1] = (-c[n - 1] * b_c[n - 1] + prevU[n - 1]) / (d[n - 1] + c[n - 1] * a_c[n - 1])
  174. # for i in range(n - 2, -1, -1):
  175. # currentU[i] = a_c[i + 1] * currentU[i + 1] + b_c[i + 1]
  176.  
  177. alpha = [0] * n
  178. beta = [0] * n
  179. ##CDE
  180. alpha[1] = -e[0]/ d[0]
  181. beta[1] = prevU[0] / d[0]
  182. for i in range(2, n):
  183. alpha[i] = (-e[i - 1])/(c[i - 1] * alpha[i - 1] + d[i - 1])
  184. beta[i] = (prevU[i - 1] - c[i - 1] * beta[i - 1]) / (c[i - 1] * alpha[i - 1] + d[i - 1])
  185.  
  186. currentU[n - 1] = (prevU[n - 1] - c[n - 1] * beta[n - 1]) / (c[n - 1] * alpha[n - 1] + d[n - 1])
  187. for i in range(n - 2, -1, -1):
  188. currentU[i] = alpha[i + 1] * currentU[i + 1] + beta[i + 1]
  189.  
  190. b2 = prevU[2]
  191. b1 = prevU[1]
  192.  
  193. g = gamma
  194. x1 = (b1 + g * b2) / (1 + 2 * g + g*g/(1+2 *g))
  195. x2=(b2 + g * x1)/(1 + 2 *g)
  196.  
  197.  
  198. return currentU
  199.  
  200.  
  201.  
  202. ## -h^2/2m * delta + Ep = ih|psi>/dt
  203. ## h/2m -i/h Ep = |psi>/dt
  204.  
  205.  
  206. #def osscilator
  207. #
  208.  
  209. #-h^2/2m delta + 0.5 m * omega *
  210. mass = 1.5*1e3
  211. #a = -planc_const * planc_const / (2 * mass)
  212. #
  213. a = complex(0, 1) * planc_const / (2 * mass)
  214.  
  215.  
  216. def origSolve(task, grid, iter, func, ep):
  217. prevU = [x for x in buildGenerator(task.getStartConditions(), grid.getStepCount(), grid.getH())]
  218.  
  219. xx = []
  220. for i in range(grid.getStepCount()):
  221. xx.append(i * grid.getH())
  222.  
  223. currentU = prevU
  224. for i in range(iter):
  225. #print(currentU)
  226. yield xx, currentU
  227. prevU = [x for x in currentU]
  228. h = grid.getH()
  229. tau = grid.getTau()
  230. a = task.getA()
  231. for p in range(len(currentU)):
  232. currentU[p] = cmath.exp(-math.pi * math.pi * task.getA() * i * tau) * sin(math.pi * p * grid.getH())
  233.  
  234.  
  235.  
  236.  
  237.  
  238. omega = math.pi / 16
  239. def Ep(r, tau):
  240. #return (0.5 * mass * r * r * omega) * complex(0, 1) / planc_const
  241. return complex(0, 0)
  242. #def Ep(r, tau):
  243. # return complex(0, -1 / planc_const)
  244.  
  245. l = 1
  246.  
  247. def startCondition(x):
  248.  
  249. return 0.5*complex(exp(-(x+1.5) * (x+1.5) / 2.0), 0)
  250. #return complex(sin(3 * math.pi * x / l), 0)
  251. if (abs(x) < eps):
  252. return complex(0.05 * exp(-15 *(x - 0.5) * (x - 0.5)), 0)
  253. else:
  254. return complex(0, 0)
  255.  
  256.  
  257. def boundaryCondition0(x):
  258. #return exp(-a * math.pi * math.pi * x)
  259. return complex(0, 0)
  260.  
  261.  
  262. def boundaryConditionL(x):
  263. #return -exp(-a * math.pi * math.pi * x)
  264. return complex(0, 0)
  265.  
  266. maxPlots=3
  267. gxmin, gxmax = 0, 1
  268. gymin, gymax = -1, 1
  269. fig, (axRe, axIm, axAbs) = plt.subplots(3, sharex=True, sharey= True)
  270. axRe.text("R")
  271. lineRe, = axRe.plot([], [], lw=2)
  272. lineIm, = axIm.plot([], [], lw=2)
  273. lineAbs, = axAbs.plot([], [], lw=2)
  274.  
  275. for i in [axRe, axIm, axAbs]:
  276. i.set_ylim(gymin, gymax)
  277. i.set_xlim(gxmin, gxmax)
  278.  
  279.  
  280. rescale = False
  281.  
  282. def updateAx(xdata, ydata, ax, line):
  283. xmin, xmax = ax.get_xlim()
  284. if rescale:
  285. if xdata[-1] >= xmax:
  286. ax.set_xlim(xmin, 2 * xmax)
  287. ax.figure.canvas.draw()
  288.  
  289. ymin, ymax = ax.get_ylim()
  290.  
  291.  
  292. curYmin = ydata[0]
  293. curYmax = ydata[0]
  294.  
  295. for i in range(len(ydata)):
  296. curYmax = max(curYmax, ydata[i])
  297. curYmin = min(curYmin, ydata[i])
  298. if curYmax >= ymax or curYmin <= ymin:
  299. if (curYmin < 0):
  300. curYmin *= 2
  301. else:
  302. curYmin /= 2
  303.  
  304. if (curYmax < 0):
  305. curYmax /= 2
  306. else:
  307. curYmax *= 2
  308.  
  309. ax.set_ylim(curYmin, curYmax)
  310. ax.figure.canvas.draw()
  311.  
  312. line.set_data(xdata, ydata)
  313. #ax.figure.canvas.draw()
  314.  
  315.  
  316.  
  317. def run(data):
  318. # update the data
  319. t, y = data
  320. xdata = t
  321. yRe = [el.real for el in y]
  322. yIm = [el.imag for el in y]
  323. yAbs = [abs(el) for el in y]
  324.  
  325. updateAx(xdata, yRe, axRe, lineRe)
  326. updateAx(xdata, yIm, axIm, lineIm)
  327. updateAx(xdata, yAbs, axAbs, lineAbs)
  328.  
  329.  
  330.  
  331. def potentialFunc(r, t):
  332. return (r+0.5)*(r+ 0.5) * 10
  333. #return complex(0, 0)/planc_const
  334. #return cmath.exp(complex(-vr * vr)/2.0)
  335. return 0
  336.  
  337. def Re(z):
  338. return z.real
  339.  
  340. def Im(z):
  341. return z.imag
  342.  
  343. def Abs(z):
  344. return abs(z)
  345.  
  346.  
  347. def main():
  348. startConditionWrapper = Condition(startCondition, ConditionMode.NormalFunction)
  349. boundCondition0Wrapper = Condition(boundaryCondition0, ConditionMode.NormalFunction)
  350. boundConditionLWrapper = Condition(boundaryConditionL, ConditionMode.NormalFunction)
  351.  
  352. l = 1
  353. h = 0.01
  354. #h(
  355. #tau = h * h / 4 *a
  356. tau = 0.08
  357. grid = Grid(h, tau, l)
  358.  
  359. stCond = [startCondition(x * h) for x in range(0, grid.getStepCount())]
  360. f = [Re, Im, Abs]
  361. axA = [axRe, axIm,axAbs]
  362. for i in range(len(axA)):
  363. maxHC = max(f[i](x) for x in stCond)
  364. axA[i].set_ylim(-1.2 * maxHC, 1.2 * maxHC)
  365. axA[i].set_xlim(0, l)
  366.  
  367.  
  368.  
  369. ## if we use primeCalc (a * tau) /h*h should be < 1/2
  370. task = Task(l, a, startConditionWrapper, [boundCondition0Wrapper, boundConditionLWrapper])
  371.  
  372. TimePeriod = 10
  373.  
  374. iter = 5000
  375.  
  376. #ani = animation.FuncAnimation(fig, run, Solve(task, grid, iter, shuttleCalc, Ep), blit=False, interval=TimePeriod,
  377. # repeat=False)
  378.  
  379. ani = animation.FuncAnimation(fig, run, Solve(task, grid, iter, shuttleCalc, potentialFunc), blit=False, interval=TimePeriod,
  380. repeat=True)
  381.  
  382.  
  383. plt.show()
  384.  
  385.  
  386. if __name__ == "__main__":
  387. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement