This bouncing ball model illustrates the concept of entropy change as a result of the redistribution of energy in a system to available microstates. The system in this case is a simulation of a rubber ball composed of a number of particles that are bound together with Hookian springs, with particular equilibrium length and spring constants. The ball of particles starts above the ground and when allowed to fall under the influence of gravity rebounds off the ground. Energy is conserved in this process, nevertheless the height of the ball of particles decreases with each bounce as the initial potential energy of the system is transferred to disordered vibrations of the internal particles. External mechanical energy, such as potential energy and ordered kinetic energy is transferred to internal potential energy of the springs and disordered kinetic energy. It is possible to investigate how the rate at which this energy is redistributed relates to factors such as the strength of the springs and number of particles.

powered by NetLogo

view/download model file: Bouncing_Ball.nlogo


Particles are created randomly in a small area near the top of the world view. In the simulation each particle interacts pair-wise with every other particle via a Hooke's law F=-kx force, where x is the distance between the two interacting particles minus the equilibrium length of the spring. (Note: the particles do not interact in any other way, which means that they can pass through each other if they move fast enough to overcome the repulsion from the springs). The motion is simulated numerically based on Newton's second law F=ma. In order to have precision with the simulation and to conserve energy we use a fourth order Runge Kutta, rather than Euler's method. (Euler's method tends to result in energy loss over time due to numerical errors). There are options to include a number of other forces in the simulation. The initial default is to add a damping force that serves to gradually dampen out the motion so that the particles can reach an equilibrium configuration. When this equilibrium is established, damping can be turned off and gravity turned on to allow the ball to fall. It is also possible to have both damping and gravity at the same time, and neither. The elastic, gravitational and kinetic energy of each particle is calculated at each time step. The internal energy is set equal to the total elastic energy of the particles and the kinetic energy that is in excess of the center of mass kinetic energy. The total energy is the total gravitational potential energy and the center of mass kinetic energy.


Choose the number of particles, the rest length of the springs connecting them and the spring constant and the click setup. The particles are in a group near the top of the screen. Now click go. The default mode is "damping", in order that the particles will reach an equilibrium configuration corresponding to a ball of particles. When the particles have reached equilibrium change the mode to "gravity". Now gravity acts on the particles and there is no damping. Total energy is conserved, but as the ball bounces the distribution of energy between internal and external energy shifts, with the result that the ball of particles does not return to its original height.

It is possible to change the mode so that both damping and gravity apply or neither applies. The later mode is interesting to try out if you want to see how a large number of particles with springs interact. It is possible to add additional particles by using the add-particle button and clicking on the screen. Be aware that if you add particles a long way from the other particles you will be adding a large amount of elastic energy to the system, which may result in particles disappearing from the screen.


Notice that when the ball of particles bounces external energy is always converted to internal energy. The bounce allows other energy states (namely vibrations of the particles) to become available. Notice also that external energy is never totally lost, as long as damping and gravity are not both on at the same time.

Try changing the spring constant and rest length of the spring and see how this changes how quickly the ball of particles looses its external energy to internal energy. You can make a quantitative comparison using the behavior space feature of NetLogo.


Initially, with damping on, the particles settle into a configuration with symmetry depending on the number of particles. Try starting with a low number of particles and then adding particles. You should observe definite symmetry breaking transitions at particular numbers of particles.

With about 25 particles try putting gravity and damping on. The ball of particles will reach terminal velocity and settle on the ground in a configuration. Observe how the configuration changes with shape with different values of k.

Allow about 25 particles to come to an equilibrium configuration with damping on. Then turn the spring constant off. Now turn on gravity only and observe the particles falling. Because there is no internal interaction the particles gradually loose their cohesion, due to the difference in time it takes for the different parts of the ball to drop during each bounce.


It would be interesting to change the interaction force to be a more realistic force like the Lenard-Jones 6-12 potential, which is Hookian in a small range around the equilibrium length, but diminishes for larger extensions and becomes very large for high compression.


See the other Entropy Models in this series


Copyright 2006 David McAvity

This model was created at the Evergreen State College, in Olympia Washington
as part of a series of applets to illustrate principles in physics and biology.

Funding was provided by the Plato Royalty Grant.

The model may be freely used, modified and redistributed provided this copyright is included and it not used for profit.

Contact David McAvity at if you have questions about its use.


globals [g b dt k external-energy internal-energy total-energy gravity? damping? zero-point]
turtles-own[x y vx vy ax ay xtemp ytemp vxtemp vytemp kinetic-energy elastic-energy 
              kx1 kx2 kx3 ky1 ky2 ky3 jx1 jx2 jx3 jy1 jy2 jy3]

to setup
set dt 0.01
set mode "damping"
ask patches [ if pycor < (5 + min-pycor) [set pcolor green ]]
;ask patches with [pycor = 10 ][set pcolor white]
crt particle-number [;set color blue 
       set shape "circle" 
       set x (random-float (2 * rest-length  + 1)) -  rest-length
       set y (random-float (2 * rest-length + 1)) - rest-length + 10
       set vx 0
       set vy 0
       set ax 0
       set ay 0
       set elastic-energy 0
       set kinetic-energy 0
       setxy x y]
to go 

  if mode = "damping" [set gravity? false set damping? true]
  if mode = "gravity" [set gravity? true set damping? false]
  if mode = "neither" [set gravity? false set damping? false]
  if mode = "both"    [set gravity? true set damping? true]  
  ifelse gravity? [set g 9.81][set g 0]
  ifelse damping? [set b 2.0][set b 0 ]
  set k spring-constant
  ;; Here we solve the equations of motion using Runge-Kutta
  ask turtles [find-acceleration ]
  ask turtles [find-k1]
  ask turtles [find-acceleration ]
  ask turtles [find-k2]
  ask turtles [find-acceleration ]
  ask turtles [find-k3]
  ask turtles [find-acceleration-and-energy ]
  ask turtles [update-coordinates]
  if mode = "damping" [set zero-point internal-energy]
  if gravity?  [ do-plots ]
  ask turtles [set elastic-energy 0 ]

; find new velocity and position of particles based on Runge Kutta. 
to update-coordinates
      let kx4 vx
      let ky4 vy
      let jx4 (ax - b * vx )
      let jy4 (ay - b * vy - g) 
      set vx vxtemp + (dt / 6)*(jx1 + (2 * jx2) + (2 * jx3) + jx4)
      set vy vytemp + (dt / 6)*(jy1 + (2 * jy2) + (2 * jy3) + jy4)
      set x  xtemp + (dt / 6)*(kx1 + (2 * kx2) + (2 * kx3) + kx4)
      set y  ytemp + (dt / 6)*(ky1 + (2 * ky2) + (2 * ky3) + ky4)
      set ax 0
      set ay 0
      set kinetic-energy (vx * vx + vy * vy) / 2
;; If particle are found below the green ground then give them positive velocity. This process conserves 
;; energy and corresponds to a perfectly elastic collision with the ground.
      if y < 5 + min-pycor [ set vy abs vy  ]

;; Here we hide particles that have moved off screen. They are still part of the simulation, and
;; if they return on screen they become visible again.
      ifelse (y > max-pycor) or (y < min-pycor)
      [ set hidden? true
        setxy x max-pycor]
      [set hidden? false
      setxy x y      ]                         

;; The following three procedures are steps in the Runge Kutta process. 
to find-k1
      set xtemp x
      set ytemp y
      set vxtemp vx
      set vytemp vy
      set kx1 vx
      set ky1 vy
      set jx1 (ax - b * vx )
      set jy1 (ay - b * vy - g) 
      set vx vxtemp + jx1 * (dt / 2)
      set vy vytemp + jy1 * (dt / 2)
      set x  xtemp +  kx1 * (dt / 2)
      set y  ytemp +  ky1 * (dt / 2)
      set ax 0
      set ay 0                                

to find-k2
      set kx2 vx
      set ky2 vy
      set jx2 (ax - b * vx )
      set jy2 (ay - b * vy - g) 
      set vx vxtemp + jx2 * (dt / 2)
      set vy vytemp + jy2 * (dt / 2)
      set x  xtemp +  kx2 * (dt / 2)
      set y  ytemp +  ky2 * (dt / 2)
      set ax 0
      set ay 0                                

to find-k3
      set kx3 vx
      set ky3 vy
      set jx3 (ax - b * vx )
      set jy3 (ay - b * vy - g) 
      set vx vxtemp + jx3 * dt 
      set vy vytemp + jy3 * dt 
      set x  xtemp +  kx3 * dt 
      set y  ytemp +  ky3 * dt 
      set ax 0
      set ay 0                                

;; Using Newton's second law F=ma, find the acceleration of each particle based on the interaction with
;; each of the other particles. The mass is set to 1.
to find-acceleration
    ask turtles with [self != myself]
      let xrel  x - ( [x] of myself )
      let yrel  y - ( [y] of myself ) 
      let d sqrt( (xrel * xrel) + (yrel * yrel) ) ;; distance between particles
      if d = 0 [set d 0.0001]              ;; This avoids divide by zero errors 
                                           ;; when particles are on top of each other
      let extension (rest-length - d)
      set ax ax + ( k * extension ) * xrel / d
      set ay ay + ( k * extension ) * yrel / d ]

;; This procedure is almost the same as above, but computes the eleastic potentail energy of the particles
;; as well as the acceleration. The energy stored in a spring is kx^2/2, but since each spring is 
;; connects two particles we add kx^2/4 for each particle
to find-acceleration-and-energy
    ask turtles with [self != myself]
      let xrel  x - ( [x] of myself )
      let yrel  y - ( [y] of myself ) 
      let d sqrt( (xrel * xrel) + (yrel * yrel) )
      if d = 0 [set d 0.0001]
      let extension (rest-length - d)
      set ax ax + ( k * extension ) * xrel / d
      set ay ay + ( k * extension ) * yrel / d 
      set elastic-energy elastic-energy + k * ( extension * extension ) / 4 ]

;; computes total graviational energy, kinetic energy of particles and elastic energy and then separates
;; these into internal and external energy.
to find-energy
 let total-kinetic-energy sum [kinetic-energy] of turtles
 let x-cm mean [x] of turtles
 let y-cm mean [y] of turtles
 let vx-cm mean [vx] of turtles
 let vy-cm mean [vy] of turtles
 let kinetic-cm (count turtles )*((vx-cm * vx-cm) + (vy-cm * vy-cm)) / 2
 let total-elastic-energy sum [elastic-energy] of turtles
 set internal-energy total-elastic-energy + total-kinetic-energy - kinetic-cm
 set external-energy (9.81 * (sum [y + max-pycor - 5] of turtles) + kinetic-cm )
 set total-energy ( internal-energy + external-energy )

;; This procedure allows the user to add a new particle to the system at anytime by clicking
;; the mouse down. To avoid adding multiple particle there is a sligh delay after a particle is added.
to add-particle
  if mouse-down? [
  crt 1 [set color yellow
       set shape "circle"
       set x mouse-xcor
       set y mouse-ycor
       set vx 0
       set vy 0
       set ax 0
       set ay 0
       setxy x y  ] 
  wait 0.2]

;; plot energies
to do-plots
  set-current-plot-pen "total"
  plot total-energy - zero-point
  set-current-plot-pen "internal"
  plot internal-energy - zero-point
  set-current-plot-pen "external"
  plot external-energy