This page was automatically generated by NetLogo 5.0.3.

The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Oracle's Java site.

powered by NetLogo

view/download model file: slinky.nlogo

WHAT IS IT?

This is a dynamic model of a “slinky”. The “slinky” is a chain of nodes connected by springs, and pulled down by gravity. There is also “damping” in the system (a “friction” force, opposite to (and linear in) velocity).

This model was partly inspired by this video: http://youtu.be/wGIZKETKKdw .

(but also by the desire to explore dynamical systems and numerical solvers … )

Some aspects of this model (especially the basic form of the Runge Kutta solver) came from the Bouncing Ball netlogo model: http://ccl.northwestern.edu/netlogo/models/community/Bouncing_Ball

HOW IT WORKS

This model uses a 4th order Runge Kutta numerical solver for movement of the nodes. There are several modes:

Default: One node (the top) is fixed, the others are free to move. The moving nodes are pulled down by a fixed gravitational force. They also experience forces caused by “springs” attaching them to other nodes. These “springs” have a rest-length, and exert a (linear) force on their ends, trying to return to their rest-length.

Do-drop: This releases the top node, so they all fall (if gravity is on).

Drive: In this mode, the top node is “driven” – either oscillating up and down, or rotating in a circle.

There is also a “ground” at the bottom. If nodes hit the ground, they bounce back up (elastic collision). If nodes go off screen, they become invisible, but stay active in the model. The model wraps horizontally, but not vertically …

HOW TO USE IT

Click on setup to initialize the slinky. Click on go to start the model. While the model is running, you can change the various parameters. You also can grab a node with the mouse and move it around.

The plot shows the y coordinates of the top node, the bottom node, and the center-of-mass of the system.

You can slow things down to see better what is happening by using the Interface “speed” slider.

THINGS TO NOTICE

This is a fairly simple model.

THINGS TO TRY

Grab nodes with the mouse while the model is running. Change the various parameter settings while the model is running.

Movies: (Use this with local models, not via the web) You can make a sequence of images for creating a movie of the model. To do this, type ‘set filename “movie”’ in the command center immediately after clicking “setup”. When the model sees the filename has been set to a non-null value while running (“go”), it will take a picture every step of the model. The filenames will look like movie0001.png movie0002.png … etc. You can stop the process by clicking on “go” when you have enough images. Alternatively, the model can be stopped by “set stoptick 100” or some similar value, again using the command center.

EXTENDING THE MODEL

Go for it! :-)

I’m hoping to add a “pendulum” mode, but not yet …

NETLOGO FEATURES

Nothing particularly special – uses “links” …

RELATED MODELS

As noted above, the “Bouncing Ball” http://ccl.northwestern.edu/netlogo/models/community/Bouncing_Ball

CREDITS AND REFERENCES

There are a variety of (somewhat) related physics applets available here: http://www.myphysicslab.com/

CODE


globals [x-max y-max diam filename
  g b k dt xzero yzero]

turtles-own
[
  x y vx vy ax ay xtemp ytemp vxtemp vytemp
  kx1 kx2 kx3 ky1 ky2 ky3 jx1 jx2 jx3 jy1 jy2 jy3
]

to setup  ; Setup the model for a run, build a plot.
  ;; (for this model to work with NetLogo's new plotting features,
  ;; __clear-all-and-reset-ticks should be replaced with clear-all at
  ;; the beginning of your setup procedure and reset-ticks at the end
  ;; of the procedure.) ..
  __clear-all-and-reset-ticks
  setup-globals
  setup-patches
  setup-turtles
  setup-slinky
  set xzero 0
  set yzero y-max - 3
  ask turtle 0 [ setxy 0 yzero ]
  setup-plot
end

to go 

  set k spring-force
  set b mydamping
  set g mygravity
  
  ;; Now go use Runge-Kutta
  ifelse (do-drop)
     [ drop-slinky ]
     [ ifelse (drive)
       [driven ]
       [fixed-top]
     ]
     
  do-plots
  
  if filename = 0 [setup] ; an attempt to work even tho user forgets setup
  
  ; this allows us to grab a node and drag it . . .
  let t 0
  if mouse-down? [
    set t closest-xy mouse-xcor mouse-ycor turtles ;
    while [mouse-down?] [
      ask t [
        set x mouse-xcor
        set y mouse-ycor
        setxy x y
        ]
    ]
  ]
  check-movie
  ; if (ticks = 1000) [stop] ; stop after a while, if you want . . .
  tick
end

to setup-globals  ; separate procedure for setting globals
  set diam 1.5
  set x-max max-pxcor - (diam / 2) + 1   ; 0.5
  set y-max max-pycor - (diam / 2) + 1   ; 0.5
  set filename "" ; change to collect images (or just use command center after setup)
  set-default-shape turtles "circle"
  set dt 0.01  ; step size for Runge Kutta
end

to setup-patches
    ;   make the ground green
  ask patches [ if pycor < (5 + min-pycor) [set pcolor green ]]
end

to setup-turtles
  crt number-of-nodes [
    ifelse (who = 0)
       [set color blue]
       [ifelse (who = number-of-nodes - 1)
          [set color magenta]
          [set color yellow]
       ]
    set label-color black
    set size diam
;    set label who
    set vx 0
    set vy 0
    set ax 0
    set ay 0
    set x 0
    set y (y-max - who - 5)  ; start them out stacked . . .
    setxy x y
  ]
end

to setup-slinky  ; Build the slinky
  
  ask turtles with [(who > 0)] [ 
    let mywho who
    ask self [
      connect-edge turtle (mywho - 1)
      ]
  ]
  
end

; find new velocity and position of nodes using 4th order Runge Kutta. 
to update-coordinates
      let kx4 vx
      let ky4 vy
      ;
      ;   here is the first place where we put in the differential equation
      ;     we are solving
      ;     ax, ay is the acceleration from the springs (neighbors),
      ;     - b * vx, -b * vy is damping (friction) -- a simple model
      ;         where damping is linear in velocity
      ;     -g is the force of gravity (constant, - y direction . . .)
      ;
      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
      
; If a node found below the green ground we give it positive velocity.
; This corresponds to a perfectly elastic collision with the ground.
;
      if y < 5 + min-pycor [ set vy abs vy  ]

      
;; Here we hide nodes 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      ]                         
end

to oscillate
  ;
  ; this is for a driven system . . . either the top (blue) node
  ;   moves in a simple vertical oscillation,
  ;   or the top node moves in a circle
  ;
  ifelse (two-d-drive)
     [set x xzero + drive-amplitude * cos (ticks * drive-rate / ( 2 * pi))]
     [set x xzero]
  set y yzero + drive-amplitude * sin (ticks * drive-rate / ( 2 * pi))
  setxy x y
end

to fixed-top
  ; this is the Runge Kutta solver with the top node fixed
  ;
  ask turtles with [who != 0] [find-acceleration ]
  ask turtles with [who != 0][find-k1]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][find-k2]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][find-k3]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][update-coordinates]
end

to driven
  ; this is the Runge Kutta solver with driven top node
  ;
  ask turtle 0 [ oscillate ]
  ask turtles with [who != 0] [find-acceleration ]
  ask turtles with [who != 0][find-k1]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][find-k2]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][find-k3]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][update-coordinates]
end

to drop-slinky
  ; this is the Runge Kutta solver with all nodes
  ;    free to move
  ;
  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 ]
  ask turtles [update-coordinates]
end

; The following three procedures are steps in the Runge Kutta process.
;   note that our differential equation shows up in each of these . . .
; 
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                                
end

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                                
end

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                                
end

; Using Newton's second law F=ma, find the acceleration of each node
;   based on the interaction with link neighbors. 
;   The mass is set to 1.
; Note that when spring-length = 0, this is a simple spring with force linearly
;   dependent on length.
;   With positive spring-length, the spring pulls (or pushes) toward
;      a rest length of spring-length . . .
;
to find-acceleration
    ask my-links [
      let fx 0
      let fy 0
      ;let f (-1) * k * (link-length)
      let f k * (spring-length - link-length)
      let myheading link-heading
      ifelse (myself = [end2] of self)
         [set fx f * sin myheading
          set fy f * cos myheading
         ]
         [set fx (-1) * f * sin myheading
          set fy (-1) * f * cos myheading
         ]
      ask myself [set ax (ax + fx)]
      ask myself [set ay (ay + fy)]
    ]
end

to setup-plot
  
end

;; plot y locations
to do-plots
  set-current-plot-pen "top"
  let ytop 0
  ask turtle 0 [ set ytop y ]
  plot ytop
  set-current-plot-pen "bottom"
  ask turtle (number-of-nodes - 1) [ set ytop y ]
  plot ytop
  set-current-plot-pen "c-of-mass"
  plot (sum [y] of turtles) / number-of-nodes
end

to check-movie  ; if filename is non-empty, make another snapshot
  if length filename > 0 [
    if (1 = (ticks mod 10))
       [ export-view word word word filename (round log ticks 10) ticks ".png" ]
  ]
end

;;;; Edge & Node utilities
to connect-edge [other-node] ; node proc: attach an edge between self and other
  ask other-node [ create-link-with myself
      [
      set color gray
      ]
  ]
end

;;;; Utilities

to-report closest-xy [myx myy agent-set]  ; Return closest agent to x, y
  report min-one-of agent-set [distancexy-nowrap myx myy]
end