Julia makes it easy to write your own types, which are similar to structs in C-family languages. Multiple dispatch adds a powerful way to handle tasks like default values or different behaviours really easily.

Here we'll look at how you could construct a simple N-body code. We'll assume everything has mass 1 to keep it simple.

Tasks:

- define an abstract type representing the bodies in the simulation
- define subtypes of this representing two different kinds of bodies in 2D: a moving body and a fixed body
- define a type which holds all the bodies in the simulation
- make a few of these bodies in various positions to start
- write a movement function to move the bodies as necessary
- write a force function to give an inverse square law force between bodies
- write an acceleration function to apply gravity to the bodies
- write a step function to bring it all together (acceleration and movement)

Extras:

- write plot functions for individual points and for the whole system
- plot it and watch the carnage

```
In [1]:
```abstract Body

This code block demonstrates how to define "concrete types" which actually contain values. We declare two types, MovingBody and FixedBody, and make them subtypes of Body (by writing ** <: Body**). We also write a function

`MovingBody(x,y)`

which makes a MovingBody that defaults to zero movement.```
In [2]:
```type MovingBody <: Body
x::Float64
y::Float64
dx::Float64
dy::Float64
end
MovingBody(x, y) = MovingBody(x, y, 0, 0)
type FixedBody <: Body
x::Float64
y::Float64
end

```
In [3]:
```type System
bodies::Vector{Body}
end

```
In [4]:
```function setup()
p1 = FixedBody(0,0)
p2 = MovingBody(1,0) # defaults to no motion ... like writing MovingBody(1,0,0,0)
p3 = MovingBody(1,1,1,1)
p4 = MovingBody(0,1,1,-1)
bodies = [p1, p2, p3, p4]
System(bodies)
end
sys = setup()

```
Out[4]:
```

```
In [5]:
```const dt = 0.1 # declare it as const because it's not in a function
function move!(b::MovingBody)
b.x += b.dx * dt
b.y += b.dy * dt
b # we return the body here - its coordinates have now been altered
end
move!(b::FixedBody) = b

```
Out[5]:
```

See how we just wrote a second version of ** move!** but defined it to only be applicable to a FixedBody? Now we can call

`move!`

This code block shows how you can use Unicode characters like ² (type `\^2`

and press `Tab`) in variable names to make them more compehensible.

```
In [6]:
```function force(b1::Body, b2::Body)
dx = b2.x - b1.x
dy = b2.y - b1.y
d² = dx^2 + dy^2 + 1e-9 # we add a 1e-9 softening term to avoid dividing by zero
inv_d² = 1 / d²
Fx = dx * inv_d²
Fy = dy * inv_d²
Fx, Fy
end

```
Out[6]:
```

This function needs to include the system (group of bodies) as an argument, because each body is affected by the gravity of all other bodies in the system. Another option would be to make `sys`

, the `System`

, a global variable. But this option is nicer style and lets us make multiple `System`

s if we want.

```
In [7]:
```function accelerate!(sys::System, b::MovingBody)
d2x = 0.0
d2y = 0.0
for other in sys.bodies
if b !== other
Fx, Fy = force(b, other)
d2x += Fx
d2y += Fy
end
end
b.dx += d2x * dt
b.dy += d2y * dt
b
end
accelerate!(sys::System, b::FixedBody) = b

```
Out[7]:
```

```
In [8]:
```function step!(sys::System, b::Body)
accelerate!(sys, b)
move!(b)
end
function step!(sys::System)
for b in sys.bodies
step!(sys, b)
end
end

```
Out[8]:
```

Since the `plot`

and `scatter`

(etc) commands from Matplotlib overlay plots by default, we can take advantage of this by writing different `plot`

commands for different points. We make fixed things red, moving things black with direction arrows, and then write a third `plot`

command to plot everything in the system by just calling `plot`

on each individual point.

```
In [9]:
```using PyPlot
function plot(b::FixedBody)
scatter(b.x, b.y, s=50, color="Red")
end
function plot(b::MovingBody)
scatter(b.x, b.y, s=50, color="Black")
arrow(b.x, b.y, b.dx * dt/2, b.dy * dt/2, facecolor="Black")
end
function plot(s::System)
for b in s.bodies
plot(b)
end
axis("equal")
end

```
Out[9]:
```

```
In [11]:
```sys = setup()
plot(sys)

```
Out[11]:
```

```
In [12]:
```for t = 0:dt:5
plot(sys)
step!(sys)
end

```
```