3ba2149533750bee68d90592a993cf7edd377ff2
[ghc.git] / testsuite / tests / dph / nbody / Body.hs
1 {-# LANGUAGE BangPatterns #-}
2
3 -- | Massful bodies in the simulation.
4 module Body
5 ( Velocity
6 , Accel
7 , MassPoint
8 , Body
9
10 , unitBody
11 , massPointOfBody
12 , setMassOfBody
13 , setAccelOfBody
14 , setStartVelOfBody
15 , advanceBody)
16 where
17 import Util
18
19
20 -- Types ----------------------------------------------------------------------
21 -- We're using tuples instead of ADTs so we can put them in unboxed vectors.
22
23 -- | The velocity of a point.
24 type Velocity = (Double, Double)
25
26 -- | The acceleration of a point.
27 type Accel = (Double, Double)
28
29 -- | A point in 2D space with its mass.
30 type MassPoint = (Double, Double, Double)
31
32 -- | Bodies consist of a MassPoint, but also carry their velocity
33 -- and acceleration between steps of the simulation.
34 type Body = (MassPoint, Velocity, Accel)
35
36
37 -- Body -----------------------------------------------------------------------
38 -- | Make a body with unit mass and zero vel and acc.
39 unitBody :: Double -> Double -> Body
40 unitBody x y
41 = ((x, y, 1), (0, 0), (0, 0))
42
43
44 -- | Take the MassPoint of a body.
45 massPointOfBody :: Body -> MassPoint
46 massPointOfBody (mp, vel, acc)
47 = mp
48
49
50 -- | Set the mass of a body.
51 setMassOfBody :: Double -> Body -> Body
52 setMassOfBody mass ((x, y, _), vel, acc)
53 = ((x, y, mass), vel, acc)
54
55
56 -- | Set the acceleration of a body.
57 setAccelOfBody :: Accel -> Body -> Body
58 setAccelOfBody acc' (mp, vel, _)
59 = (mp, vel, acc')
60
61
62 -- | Set the starting velocity of a body.
63 -- It is set to rotate around the origin, with the speed proportional
64 -- to the sqrt of the distance from it. This seems to make nice simulations.
65 setStartVelOfBody :: Double -> Body -> Body
66 setStartVelOfBody startVel (mp@(x, y, mass), vel, acc)
67 = let pos = (x, y)
68 (x', y') = normaliseV (x, y)
69 vel' = (y', -x')
70 vel'' = mulSV (sqrt (magV pos) * startVel) vel'
71
72 in (mp, vel'', acc)
73
74
75 -- | Advance a body forwards in time.
76 advanceBody :: Double -> Body -> Body
77 advanceBody time
78 ( (px, py, mass)
79 , (vx, vy)
80 , acc@(ax, ay))
81
82 = ( (px + time * vx, py + time * vy, mass)
83 , (vx + time * ax, vy + time * ay)
84 , acc)
85