Back to the student project listing page


powered by NetLogo

view/download model file: Molecular_Self_Organization.nlogo

WHAT IS IT?

This example demonstrates how to create a square grid for turtles to walk around on using links. When turtles come into contact they merge and become one. Different colors represent different charges (-/+/netural : red/blue/black). The total energy is calculated at each step according to nearest neighbor interactions.


PROCEDURES

globals [
  colors           ;; colors we are using
  energy           ;; total energy of the system
]

breed [nodes node]
breed [walkers walker]

walkers-own [location leader agg_id]  ;; holds a node



; Set up routine: creates a grid of patches. Puts nodes on each patch, links them and then puts 
; a number of walkers on the nodes. 
to setup
  clear-all
  set-default-shape nodes "square"
  ask patches
  [ sprout-nodes 1
    [ set color white ;; white
      set size 1.2
     ] 
   ]
  ;; connect the nodes to make a lattice
  ask nodes
  [ 
      create-links-with nodes-on patches at-points [[0 1] [1 0] ]    
  ]  
  ask links [ hide-link ]
 
 
  ;; put some "walker" turtles on the lattice
  set-default-shape walkers "square"
  set colors [red blue black] ; different colors represent -/+/neutral charges.
  let countr 0
  create-walkers number 
  [
    set color item random 3 colors
    set location one-of nodes
    set leader self
    set agg_id countr
    move-to location
    set countr countr + 1
  ]
end



;Main loop.
to go
  
choose_direction
    
ask walkers 
[
    let cands_on_neighbs walkers-on neighbors4
    let candidates cands_on_neighbs with [leader != [leader] of myself]  
            

    if any? candidates[
     create-links-with candidates [tie]
     ask candidates [merge]
     ] 

]
 
find_energy 
update-plot 
tick

end



;Takes test steps in each of the four directions.
to choose_direction
 
ask walkers with [leader = self] 
      [
        find_energy
        let energy_zero energy
        let left_right 0 let up_down 0
        set-location one-of [link-neighbors at-points [[0 -1] ] ] of location
        find_energy
        if energy < energy_zero [set up_down -1 set left_right 0 set energy_zero energy] 
        
        set-location one-of [link-neighbors at-points [[0 1] ] ] of location
        set-location one-of [link-neighbors at-points [[0 1] ] ] of location
        find_energy
        if energy < energy_zero [set up_down 1 set left_right 0 set energy_zero energy] 
        
        set-location one-of [link-neighbors at-points [[0 -1] ] ] of location
        set-location one-of [link-neighbors at-points [[1 0] ] ] of location
        find_energy
        if energy < energy_zero [set up_down 0 set left_right 1 set energy_zero energy]
                
        set-location one-of [link-neighbors at-points [[-1 0] ] ] of location
        set-location one-of [link-neighbors at-points [[-1 0] ] ] of location
        find_energy
        if energy < energy_zero [set up_down 0 set left_right -1 set energy_zero energy]
        set-location one-of [link-neighbors at-points [[1 0] ] ] of location
        
;        show up_down
;        show left_right
        
        if left_right = 0 and up_down = 1 [
        set-location one-of [link-neighbors at-points [[0 1] ] ] of location
        rt (random 4) * 90 
        ]
        if left_right = 1 and up_down = 0 [
        set-location one-of [link-neighbors at-points [[1 0] ] ] of location
        rt (random 4) * 90 
        ]
        if left_right = -1 and up_down = 0 [
        set-location one-of [link-neighbors at-points [[-1 0] ] ] of location
        rt (random 4) * 90 
        ]
        if left_right = 0 and up_down = -1 [
        set-location one-of [link-neighbors at-points [[0 -1] ] ] of location
        rt (random 4) * 90 
        ]
        if left_right = 0 and up_down = 0 [
        set-location one-of [link-neighbors] of location
        rt (random 4) * 90 
        ]
        
;        rt (random 4) * 90 
      ]      
end



;Finds the total energy (Note the /2 is to avoid double counting).
to find_energy
  set energy  0
  ask walkers [
    let cands_on_neighbs walkers-on neighbors4
    if [color] of self  = blue [                     ;show "blue"
      if any? cands_on_neighbs with [color = blue] [set energy energy + (9 / 2)]
      if any? cands_on_neighbs with [color = red] [set energy energy - (11 / 2)]
      if any? cands_on_neighbs with [color = black] [set energy energy - (1 / 2)]
      ]
    
    if [color] of self  = red [ 
      if any? cands_on_neighbs with [color = blue] [set energy energy - (11 / 2)]
      if any? cands_on_neighbs with [color = red] [set energy energy + (9 / 2)]
      if any? cands_on_neighbs with [color = black] [set energy energy - (1 / 2)]
      ]
    
    if [color] of self  = black [ 
      if any? cands_on_neighbs with [color = blue] [set energy energy - (1 / 2)]
      if any? cands_on_neighbs with [color = red] [set energy energy - (1 / 2)]
      if any? cands_on_neighbs with [color = black] [set energy energy - (1 / 2)]
      ]
  ]
  
end


; Merges agents when they are next to each other.
to merge 
      set leader [leader] of myself
      set agg_id [agg_id] of myself 
      ask link-neighbors with [leader != [leader] of myself]
      [ merge ]
end




; Required to move agants on the grid
to set-location [new-location]  ;; walker procedure
  set location new-location
  move-to new-location
end




;Basic plotting.
to update-plot
  set-current-plot "Energy"
  plot energy
end