Guest User

symplectic.nim

a guest
Mar 16th, 2021
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.50 KB | None | 0 0
  1.  
  2. # Symplectic integrators for separable Hamiltonian systems
  3. #
  4. # (c) 2018-2021 [email protected] (Ian Smith), for licencing see the LICENCE file
  5.  
  6. import std/strutils
  7. import math
  8.  
  9. type
  10. ArgumentError* = object of ValueError
  11.  
  12. func log_error*(error: float): float =
  13. 10.0 * log10(if abs(error) >= 1e-36: abs(error) else: 1e-36)
  14.  
  15. proc solve*[T](args: seq[string], p: var T, u_q, u_p: proc(p: var T, cd: float), output: proc(p: T, t: float)) =
  16. let
  17. order: int64 = parseInt(args[1])
  18. h: float = parseFloat(args[2])
  19. steps: int64 = parseInt(args[3])
  20. z1: float = 1.0 / (4.0 - pow(4.0, (1.0 / 3.0)))
  21. y1: float = 1.0 / (4.0 - pow(4.0, (1.0 / 5.0)))
  22. x1: float = 1.0 / (4.0 - pow(4.0, (1.0 / 7.0)))
  23. z0: float = 1.0 - 4.0 * z1
  24. y0: float = 1.0 - 4.0 * y1
  25. x0: float = 1.0 - 4.0 * x1
  26. cd: seq[float] = case order
  27. of 2: # Stormer-Verlet
  28. @[0.5 * h, h]
  29. of 4: # m4r35n357_4
  30. @[0.5 * h * z1, h * z1, h * z1, h * z1, 0.5 * h * (z1 + z0), h * z0]
  31. of 6: # m4r35n357_6
  32. @[0.5 * h * z1 * y1, h * z1 * y1, h * z1 * y1, h * z1 * y1, 0.5 * h * (z1 + z0) * y1, h * z0 * y1, 0.5 * h * (z0 + z1) * y1, h * z1 * y1, h * z1 * y1, h * z1 * y1, h * z1 * y1, h * z1 * y1, h * z1 * y1, h * z1 * y1, 0.5 * h * (z1 + z0) * y1, h * z0 * y1, 0.5 * h * (z0 + z1) * y1, h * z1 * y1, h * z1 * y1, h * z1 * y1, 0.5 * h * z1 * (y1 + y0), h * z1 * y0, h * z1 * y0, h * z1 * y0, 0.5 * h * (z1 + z0) * y0, h * z0 * y0]
  33. of 8: # m4r35n357_8
  34. @[0.5 * h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * (z1 + z0) * y1 * x1, h * z0 * y1 * x1, 0.5 * h * (z0 + z1) * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * (z1 + z0) * y1 * x1, h * z0 * y1 * x1, 0.5 * h * (z0 + z1) * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * z1 * (y1 + y0) * x1, h * z1 * y0 * x1, h * z1 * y0 * x1, h * z1 * y0 * x1, 0.5 * h * (z1 + z0) * y0 * x1, h * z0 * y0 * x1, 0.5 * h * (z0 + z1) * y0 * x1, h * z1 * y0 * x1, h * z1 * y0 * x1, h * z1 * y0 * x1, 0.5 * h * z1 * (y1 + y0) * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * (z1 + z0) * y1 * x1, h * z0 * y1 * x1, 0.5 * h * (z0 + z1) * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * (z1 + z0) * y1 * x1, h * z0 * y1 * x1, 0.5 * h * (z0 + z1) * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * (z1 + z0) * y1 * x1, h * z0 * y1 * x1, 0.5 * h * (z0 + z1) * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * (z1 + z0) * y1 * x1, h * z0 * y1 * x1, 0.5 * h * (z0 + z1) * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * z1 * (y1 + y0) * x1, h * z1 * y0 * x1, h * z1 * y0 * x1, h * z1 * y0 * x1, 0.5 * h * (z1 + z0) * y0 * x1, h * z0 * y0 * x1, 0.5 * h * (z0 + z1) * y0 * x1, h * z1 * y0 * x1, h * z1 * y0 * x1, h * z1 * y0 * x1, 0.5 * h * z1 * (y1 + y0) * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * (z1 + z0) * y1 * x1, h * z0 * y1 * x1, 0.5 * h * (z0 + z1) * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * (z1 + z0) * y1 * x1, h * z0 * y1 * x1, 0.5 * h * (z0 + z1) * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, h * z1 * y1 * x1, 0.5 * h * z1 * y1 * (x1 + x0), h * z1 * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, 0.5 * h * (z1 + z0) * y1 * x0, h * z0 * y1 * x0, 0.5 * h * (z0 + z1) * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, 0.5 * h * (z1 + z0) * y1 * x0, h * z0 * y1 * x0, 0.5 * h * (z0 + z1) * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, h * z1 * y1 * x0, 0.5 * h * z1 * (y1 + y0) * x0, h * z1 * y0 * x0, h * z1 * y0 * x0, h * z1 * y0 * x0, 0.5 * h * (z1 + z0) * y0 * x0, h * z0 * y0 * x0]
  35. else:
  36. echo "invalid order value ", order, ", should be 2, 4, 6, or 8"
  37. raise newException(ArgumentError, "Invalid integrator")
  38. output(p, 0.0)
  39. for step in 1 .. steps:
  40. for i in countup(0, cd.len - 1):
  41. if (i mod 2) == 0: u_q(p, cd[i]) else: u_p(p, cd[i])
  42. for i in countdown(cd.len - 2, 0):
  43. if (i mod 2) == 0: u_q(p, cd[i]) else: u_p(p, cd[i])
  44. output(p, step.float * h)
  45.  
Advertisement
Add Comment
Please, Sign In to add comment