Skip to content

Commit d926cb9

Browse files
Trashtalk217berquist
authored andcommitted
Verlet implementation in Common Lisp (#608)
1 parent afcaf4d commit d926cb9

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
;;;; Verlet integration implementation in Common Lisp
2+
3+
(defun verlet (pos acc dt)
4+
"Integrates Newton's equation for motion while pos > 0 using Verlet integration."
5+
(loop
6+
with prev-pos = pos
7+
for time = 0 then (incf time dt)
8+
while (> pos 0)
9+
;; The starting speed is assumed to be zero.
10+
do (psetf
11+
pos (+ (* pos 2) (- prev-pos) (* acc dt dt))
12+
prev-pos pos)
13+
finally (return time)))
14+
15+
(defun stormer-verlet (pos acc dt)
16+
"Integrates Newton's equation for motion while pos > 0 using the Stormer-Verlet method."
17+
(loop
18+
with prev-pos = pos
19+
for time = 0 then (incf time dt)
20+
for vel = 0 then (incf vel (* acc dt))
21+
while (> pos 0)
22+
;; Variables are changed simultaneously by 'psetf', so there's no need for a temporary variable.
23+
do (psetf
24+
pos (+ (* pos 2) (- prev-pos) (* acc dt dt))
25+
prev-pos pos)
26+
finally (return (list time vel))))
27+
28+
(defun velocity-verlet (pos acc dt)
29+
"Integrates Newton's equation for motion while pos > 0 using the velocity in calculations."
30+
(loop
31+
for time = 0 then (incf time dt)
32+
for vel = 0 then (incf vel (* acc dt))
33+
for p = pos then (incf p (+ (* vel dt) (* 0.5 acc dt dt)))
34+
while (> p 0)
35+
finally (return (list time vel))))
36+
37+
(format T "Time for Verlet integration: ~d~%" (verlet 5 -10 0.01))
38+
39+
(defvar stormer-verlet-result (stormer-verlet 5 -10 0.01))
40+
(format T "Time for Stormer Verlet integration is: ~d~%" (first stormer-verlet-result))
41+
(format T "Velocity for Stormer Verlet integration is: ~d~%" (second stormer-verlet-result))
42+
43+
(defvar velocity-verlet-result (velocity-verlet 5 -10 0.01))
44+
(format T "Time for velocity Verlet integration is: ~d~%" (first velocity-verlet-result))
45+
(format T "Velocity for velocity Verlet integration is: ~d~%" (second velocity-verlet-result))

contents/verlet_integration/verlet_integration.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ Unfortunately, this has not yet been implemented in LabVIEW, so here's Julia cod
6969
[import:3-15, lang:"kotlin"](code/kotlin/verlet.kt)
7070
{% sample lang="nim" %}
7171
[import:1-14, lang:"nim"](code/nim/verlet.nim)
72+
{% sample lang="lisp" %}
73+
[import:3-13, lang:"lisp"](code/clisp/verlet.lisp)
7274
{% endmethod %}
7375

7476
Now, obviously this poses a problem; what if we want to calculate a term that requires velocity, like the kinetic energy, $$\frac{1}{2}mv^2$$? In this case, we certainly cannot get rid of the velocity! Well, we can find the velocity to $$\mathcal{O}(\Delta t^2)$$ accuracy by using the Stormer-Verlet method, which is the same as before, but we calculate velocity like so
@@ -125,6 +127,8 @@ Unfortunately, this has not yet been implemented in LabVIEW, so here's Julia cod
125127
[import:17-30, lang:"kotlin"](code/kotlin/verlet.kt)
126128
{% sample lang="nim" %}
127129
[import:16-32, lang:"nim"](code/nim/verlet.nim)
130+
{% sample lang="lisp" %}
131+
[import:15-26, lang:"lisp"](code/clisp/verlet.lisp)
128132
{% endmethod %}
129133

130134

@@ -195,6 +199,8 @@ Unfortunately, this has not yet been implemented in LabVIEW, so here's Julia cod
195199
[import:32-42, lang:"kotlin"](code/kotlin/verlet.kt)
196200
{% sample lang="nim" %}
197201
[import:34-45, lang:"nim"](code/nim/verlet.nim)
202+
{% sample lang="lisp" %}
203+
[import:28-35, lang:"lisp"](code/clisp/verlet.lisp)
198204
{% endmethod %}
199205

200206
Even though this method is more widely used than the simple Verlet method mentioned above, it unforunately has an error term of $$\mathcal{O}(\Delta t^2)$$, which is two orders of magnitude worse. That said, if you want to have a simulaton with many objects that depend on one another --- like a gravity simulation --- the Velocity Verlet algorithm is a handy choice; however, you may have to play further tricks to allow everything to scale appropriately. These types of simulatons are sometimes called *n-body* simulations and one such trick is the Barnes-Hut algorithm, which cuts the complexity of n-body simulations from $$\sim \mathcal{O}(n^2)$$ to $$\sim \mathcal{O}(n\log(n))$$.
@@ -256,6 +262,8 @@ Submitted by P. Mekhail
256262
[import, lang:"kotlin"](code/kotlin/verlet.kt)
257263
{% sample lang="nim" %}
258264
[import, lang="nim"](code/nim/verlet.nim)
265+
{% sample lang="lisp" %}
266+
[import, lang:"lisp"](code/clisp/verlet.lisp)
259267
{% endmethod %}
260268

261269

0 commit comments

Comments
 (0)