Idealized Multizone Migration

This model simulates the entirety of an idealized salmon smolt migration. In the Spring of each year, salmon egss hatch in the streams and hatcheries of tributaries of rivers leading to the ocean. These very large populations of salmon grow into a juvenile stage in which they are known as smolts, but any further development will need to occur in the oceans themselves. Thus, nearly simultaneously they begin a migration to the ocean.

Mortality is very high -- even independent of human involvement -- but the migration occurs relatively rapidly. This model simulates the movement of the smolts through zone 1 from the streams and hatcheries where they were spawned, which is represented by zone 0. However, mortality is not incorporated into this model.

powered by NetLogo

view/download model file: Zone0toZone7(NoMortality).nlogo


HOW IT WORKS

The Setup command initializes the system and the plots by creating "Initial-Population" numbers of smolts in zone 0. In this simulation, the initial population consists of thousands of smolts, whereas actual populations often involve millions of them. The Go command starts the random migration out of zone 0, and each smolt randomly moves about zone 0 until it encounters the channel exiting the zone. Once in the channel, it is highly unlikely that the smolt will backtrack into zone0 itself. The degree to which each smolt in zone 0 is controled by the flow of the zone toward the channel can be adjusted using the "Relative-flow-in-lake" slider.


HOW TO USE IT

Adjust the Initial-Population, ticks-per-unit-time, and Relative-Flow-In-Lake sliders to desired settings. Press Setup and then Go (press Step for one tick of the model at a time). Press setup and then go. To "smooth out" the measurements of Emigration and the percentage migration rate, the number of ticks per unit time can be varied up to 20 ticks per unit time. There is also a flow in each of the lakes (i.e., the large "boxes" ) toward the channels leading away from the lakes, and the "Relative-Flow-In-Lake" slider adjusts this from no influence at 0 to flow-controlled at 1.


THINGS TO NOTICE

The smolts swim "randomly" as a group regardless of the relative-flow settings. In fact, if the Relative-Flow-In-Lake setting is close to 0, then the probability of a smolt being in "zone j" is approximately Poisson distributed. Thus, at high values of j, the population curves will more and more resemble bell curves -- i.e., normal distributions -- as we see the Central Limit theorem in action here!!

However, as the Relative-Flow-In-Lake parameter is increased, the accuracy of this model decreases as m is not nearly as close to being constant during the migration.


THINGS TO TRY

Try varying the Initial-Population. Also, try changing the relative rate of flow of the smolts (relative to the flow of the lake, that is). Changing this slider during the migration also may lead to some interesting results, especially if the initial population is quite large.


RELATED MODELS

This model created by Dr. Jeff Knisley as part of the Symbiosis project module on migratory models in differential calculus. It is one of the simulations located at http://math.etsu.edu/symbiosis/migrations.


PROCEDURES

globals [ InitPop MaxDist Current-Time Previous-Time AllTime N0P N1P zonewidth m0 Departures-per-tick 
          Z0P Z1P Z2P Z3P Z4P Z5P Z6P Z7P 
           ]

patches-own [ iswater? inlake? pzone flow-heading flow-strength ] ; flow-strength is 0 to 1, percentage of main-channel flow speed
turtles-own [ zone ]

to setup
  clear-all
  
  set Previous-Time 0
  set Current-Time 0
  set zonewidth 24
  
  setup-patches
  
  
  CreateSmolts

  set Z0P 1
  set Z1P 0
  set Z2P 0
  set Z3P 0
  set Z4P 0
  set Z5P 0 
  set Z6P 0
  set Z7P 0
  
  set InitPop Initial-Population
  
  set-current-plot "N0(t)"   
  set-plot-y-range 0 Initial-Population 
  set-current-plot-pen "N0(t)"
  plotxy 0 Initial-Population
  
  set-current-plot "N1(t)"   
  set-plot-y-range 0 Initial-Population 
  set-current-plot-pen "N1(t)"
  plotxy 0 0
  
  set-current-plot "N2(t)"   
  set-plot-y-range 0 Initial-Population 
  set-current-plot-pen "N2(t)"
  plotxy 0 0
  
  set-current-plot "N3(t)"   
  set-plot-y-range 0 Initial-Population 
  set-current-plot-pen "N3(t)"
  plotxy 0 0
  
  set-current-plot "N4(t)"   
  set-plot-y-range 0 Initial-Population 
  set-current-plot-pen "N4(t)"
  plotxy 0 0
  
  set-current-plot "N5(t)"   
  set-plot-y-range 0 Initial-Population 
  set-current-plot-pen "N5(t)"
  plotxy 0 0
  
  set-current-plot "N6(t)"   
  set-plot-y-range 0 Initial-Population 
  set-current-plot-pen "N6(t)"
  plotxy 0 0
  
  set-current-plot "N7(t)"   
  set-plot-y-range 0 Initial-Population 
  set-current-plot-pen "N7(t)"
  plotxy 0 0
  
end


to CreateSmolts
  
  set-default-shape turtles  "fish"
  
  create-turtles Initial-Population   
    [   
       set color green
       move-to one-of patches with [ pzone = 0 ]
                 
       set heading random 360 
       set zone 0
       
    ]
        
  
end  

to setup-patches 
  ;set source info and zone transition points
  ask patches 
  [ 
      ifelse ( pxcor > min-pxcor and pycor > -4 and pycor < 4 ) 
       [ set pcolor blue
         set iswater? true 
         set inlake? false
         set pzone -1
         set flow-heading 90   
         set flow-strength 1     
       ]
       [ set pzone -1 
         set iswater? false
         set inlake? false 
       ]
   ]
  make-compartment   min-pxcor                   ( min-pxcor + zonewidth     ) 0 
  make-compartment ( min-pxcor +     zonewidth ) ( min-pxcor + 2 * zonewidth ) 1
  make-compartment ( min-pxcor + 2 * zonewidth ) ( min-pxcor + 3 * zonewidth ) 2
  make-compartment ( min-pxcor + 3 * zonewidth ) ( min-pxcor + 4 * zonewidth ) 3
  make-compartment ( min-pxcor + 4 * zonewidth ) ( min-pxcor + 5 * zonewidth ) 4
  make-compartment ( min-pxcor + 5 * zonewidth ) ( min-pxcor + 6 * zonewidth ) 5
  make-compartment ( min-pxcor + 6 * zonewidth ) ( min-pxcor + 7 * zonewidth ) 6
  make-compartment ( min-pxcor + 7 * zonewidth ) ( min-pxcor + 8 * zonewidth ) 7
    
end
      
to make-compartment [ L R zn ]
  let U max-pycor
  let B min-pycor 
  set MaxDist sqrt ( ( R - 4 - L ) ^ 2 + U ^ 2 )
  ask patches [ 
    if ( pxcor > min-pxcor and pxcor > L and pxcor < ( R - 4 ) and pycor < U and pycor > B ) 
       [ set pcolor blue
         set iswater? true
         set inlake? true 
         set pzone zn
         set flow-heading towardsxy ( R - 4 ) 0   
         set flow-strength 1 - sqrt ( ( pxcor - R ) ^ 2 +  pycor ^ 2) / MaxDist      ]  
    if ( pxcor <= R  and pxcor >= ( R - 4 ) and pxcor <= max-pxcor and pycor > -4 and pycor < 4 ) 
       [ set pcolor blue
         set iswater? true 
         set inlake? false
         set pzone -1
         set flow-heading 90   
         set flow-strength 1     ]
  ]
  
end 



to go 
   if( not any? turtles  ) [ stop ]
   
   ask turtles [
      if ( random-float 1 < 1 / ticks-per-unit-time ) 
        [ smoltMove
          smoltLearn
        ]
   ]
   smoltCount 
end 

to smoltMove 
   rt random 90
   lt random 90
   let p [ flow-strength ] of patch-here
   if( [ pzone ] of patch-here >= 0 ) [ set p p * Relative-Flow-In-Lake ] 
   ifelse ( heading <  270 ) 
     [ set heading ( ( 1 - p ) * heading + p * ( [ flow-heading ] of patch-here )  ) ]
     [ set heading ( ( 1 - p ) * heading + p * ( [ flow-heading ] of patch-here + 360 ) ) ]
   if not ( member?  patch-ahead 1  neighbors with [ iswater? ] ) 
     [  set heading towards one-of neighbors with [ iswater? ]  ]
   fd 1
   
   set zone [pzone] of patch-here

   if ( xcor >= max-pxcor ) 
     [  die  ]
   
end



to smoltCount 
  tick
  
  set Current-time precision ( ticks / ticks-per-unit-time ) 4
  
  set N0P ( count turtles with [ zone = 0 ] )
  
  set Z0P precision ( ( count turtles with [ zone = 0 ] ) / InitPop ) 4
  set Z1P precision ( ( count turtles with [ zone = 1 ] ) / InitPop ) 4
  set Z2P precision ( ( count turtles with [ zone = 2 ] ) / InitPop ) 4
  set Z3P precision ( ( count turtles with [ zone = 3 ] ) / InitPop ) 4
  set Z4P precision ( ( count turtles with [ zone = 4 ] ) / InitPop ) 4
  set Z5P precision ( ( count turtles with [ zone = 5 ] ) / InitPop ) 4
  set Z6P precision ( ( count turtles with [ zone = 6 ] ) / InitPop ) 4
  set Z7P precision ( ( count turtles with [ zone = 7 ] ) / InitPop ) 4
    
  if( Current-Time < Previous-Time ) 
    [ clear-all-plots 
      reset-ticks  
      set Current-Time 0
    ]
  
  if( 2 * N0P > InitPop  and Current-Time > 0 ) 
    [ set m0 precision ( ln( InitPop / N0P ) / Current-Time ) 4 ]
    
  set-current-plot "N0(t)"   
  set-current-plot-pen "N0(t)"
  plotxy Current-Time  count turtles with[ zone = 0 ]
  
  set-current-plot "N1(t)"
  set-current-plot-pen "N1(t)"
  plotxy Current-Time count turtles with [ zone = 1 ]
  
  set-current-plot "N2(t)"
  set-current-plot-pen "N2(t)"
  plotxy Current-Time count turtles with [ zone = 2 ]
  
  set-current-plot "N3(t)"
  set-current-plot-pen "N3(t)"
  plotxy Current-Time count turtles with [ zone = 3 ]
  
  set-current-plot "N4(t)"
  set-current-plot-pen "N4(t)"
  plotxy Current-Time count turtles with [ zone = 4 ]
  
  set-current-plot "N5(t)"
  set-current-plot-pen "N5(t)"
  plotxy Current-Time count turtles with [ zone = 5 ]
  
  set-current-plot "N6(t)"
  set-current-plot-pen "N6(t)"
  plotxy Current-Time count turtles with [ zone = 6 ]
  
  set-current-plot "N7(t)"
  set-current-plot-pen "N7(t)"
  plotxy Current-Time count turtles with [ zone = 7 ]
       
  set Previous-Time Current-Time 
  
end

to smoltLearn
   ; Zone number, simple flow concept means no going to earlier zone 
   
end