|
1 | 1 | -- submitted by Jie
|
2 |
| -type Position = [Double] |
3 |
| -type Speed = [Double] |
4 |
| -type Time = Double |
5 |
| -type Particle = (Position, Speed, Acceleration, Time) |
6 |
| -type Acceleration = [Double] |
7 |
| - |
8 |
| -verletStep :: (Particle -> Acceleration) |
9 |
| - -> Time |
10 |
| - -> Particle |
11 |
| - -> Particle |
12 |
| - -> Particle |
13 |
| -verletStep acc dt (xOld, _, aOld, _) (x, v, a, t) = (x', v', a', t+dt) |
| 2 | +type Time = Double |
| 3 | + |
| 4 | +type Position = Double |
| 5 | + |
| 6 | +type Speed = Double |
| 7 | + |
| 8 | +type Acceleration = Double |
| 9 | + |
| 10 | +type Particle = (Position, Speed, Acceleration, Time) |
| 11 | + |
| 12 | +type Model = Particle -> Acceleration |
| 13 | + |
| 14 | +type Method = Model -> Time -> Particle -> Particle -> Particle |
| 15 | + |
| 16 | +verlet :: Method |
| 17 | +verlet acc dt (xOld, _, _, _) (x, _, a, t) = (x', v', a', t + dt) |
14 | 18 | where
|
15 |
| - x' = zipWith3 (\xOld x a -> 2*x - xOld + a*dt^2 ) xOld x a |
16 |
| - v' = zipWith3 (\v a aOld -> v + 0.5*(aOld + a)*dt) v a aOld |
17 |
| - a' = acc (x', v', [], t+dt) |
18 |
| - |
19 |
| -trajectory :: (Particle -> Acceleration) |
20 |
| - -> Time |
21 |
| - -> Particle |
22 |
| - -> [Particle] |
23 |
| -trajectory acc dt p0@(x, v, a, t0) = t |
| 19 | + x' = 2 * x - xOld + a * dt ^ 2 |
| 20 | + v' = 0 |
| 21 | + a' = acc (x', v', a, t + dt) |
| 22 | + |
| 23 | +stormerVerlet :: Method |
| 24 | +stormerVerlet acc dt (xOld, _, _, _) (x, _, a, t) = (x', v', a', t + dt) |
| 25 | + where |
| 26 | + x' = 2 * x - xOld + a * dt ^ 2 |
| 27 | + v' = (x' - x) / dt |
| 28 | + a' = acc (x', v', a, t + dt) |
| 29 | + |
| 30 | +velocityVerlet :: Method |
| 31 | +velocityVerlet acc dt (xOld, _, aOld, _) (x, v, a, t) = (x', v', a', t + dt) |
24 | 32 | where
|
25 |
| - t = p0 : p1 : zipWith (verletStep acc dt) t (tail t) |
26 |
| - p1 = (x', v', acc (x', v', [], t0+dt), t0+dt) |
27 |
| - x' = zipWith3 (\x v a -> x + v*dt + 0.5*a*dt^2 ) x v a |
28 |
| - v' = zipWith (\v a -> v + a*dt) v a |
| 33 | + x' = 2 * x - xOld + a * dt ^ 2 |
| 34 | + v' = v + 0.5 * (aOld + a) * dt |
| 35 | + a' = acc (x', v', a, t + dt) |
29 | 36 |
|
30 |
| -freeFall :: Particle |
31 |
| -freeFall = last $ takeWhile (\([x],_,_,_) -> x > 0) $ trajectory acc dt p0 |
| 37 | +trajectory :: Method -> Model -> Time -> Particle -> [Particle] |
| 38 | +trajectory method acc dt p0@(x, v, a, t0) = traj |
32 | 39 | where
|
33 |
| - p0 = ([5], [0], [-10], 0) |
34 |
| - dt = 0.001 |
35 |
| - acc _ = [-10] |
| 40 | + traj = p0 : p1 : zipWith (method acc dt) traj (tail traj) |
| 41 | + p1 = (x', v', acc (x', v', a, t0 + dt), t0 + dt) |
| 42 | + x' = x + v * dt + 0.5 * a * dt ^ 2 |
| 43 | + v' = v + a * dt |
36 | 44 |
|
| 45 | +main :: IO () |
| 46 | +main = do |
| 47 | + let p0 = (5, 0, -10, 0) |
| 48 | + dt = 0.001 |
| 49 | + freefall _ = -10 |
| 50 | + aboveGround (x, _, _, _) = x > 0 |
| 51 | + integrate m = last $ takeWhile aboveGround $ trajectory m freefall dt p0 |
| 52 | + print $ integrate verlet |
| 53 | + print $ integrate stormerVerlet |
| 54 | + print $ integrate velocityVerlet |
0 commit comments