Estuaryscape

Estuaryscape preview image

1 collaborator

Elphinstone_se_040 Miguel Pais (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by the author
Model was written in NetLogo 6.0.2 • Viewed 622 times • Downloaded 42 times • Run 0 times
Download the 'Estuaryscape' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Info tab cannot be displayed because of an encoding error

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;;;;;;;;;;;;;;;;;;;;;;
;;                  ;;     Created by Miguel Pessanha Pais as a final project for the intro to ABM MOOC 2016
;;ESTUARYSCAPE MODEL;;                     by Bill Rand @ Complexity Explorer
;;                  ;;
;;;;;;;;;;;;;;;;;;;;;;                         Contact: mppais@fc.ul.pt

extensions [gis]

breed [fishes fish]

globals[
  the-map
  non-land-patches       ; an agentset of patches that excludes land patches, to avoid unnecessary calculations happening in land
  ; other globals are on the interface
]

fishes-own [
  energy                  ; current energy level, limited by energy-reserve-size
  species                 ; green or red species
  sex                     ; male, female or undecided (joking, just male or female really)
  reserve-size            ; maximum energy reserve size
  maintenance-cost        ; energy cost to maintain bodily functions (metabolism,respiration, osmotic regulation, etc)
  age                     ; age (in days)
  stage                   ; juvenile or adult
  age-at-maturity         ; age at which a fish becomes and adult (able to reproduce) (days)
  max-age                 ; maximum age for fish (instant death lies beyond this point)
  nr-gametes              ; nr of gametes produced by adults
  feeding-rate            ; max amount of prey grams per day
  reproduction-threshold  ; energy amount over which an adult fish can produce and release gametes
  ]

patches-own [
  worms
  bivalves
  plankton
  habitat ; canal or mudflat
  green-newcomers
  red-newcomers
  red.eggs ; red fish eggs, coded as a list with the length equal to "days-until-hatch". The first item is the amount of eggs released on the present day, the last item is eggs who have been here for "days-until-hatch" days and are ready to hatch.
  green.eggs ; green fish eggs, see the description above
  ]

; Model setup and schedule

to startup
  set map-file "map.asc"
  load-map
end 

to setup
  clear-all
  load-map
  setup-environment
  setup-fishes
  reset-ticks
end 

to go
  if not any? fishes [
    stop
  ]
  ask fishes [
    grow                              ; die if too old, increase age otherwise (also controls life stage change)
    pay-maintenance                    ; pay maintenance-costs or die!
    move-or-stay                     ; move or stay based on the scan decision
  ]
  fish-eat-prey                       ; fish eat prey, larger fish get to eat first
  egg-development                     ; eggs age advances
  hatch-eggs                          ; eggs that reach full development hatch
  fish-reproduction                   ; fish reproduce
  regrow-prey                         ; prey grows back
  tick
end 


; SETUP PROCEDURES

to setup-fishes
  create-fishes initial-number-of-fishes [
    move-to-and-jitter one-of non-land-patches ; place fishes on a random patch that is not land and jitter
    set color one-of [red green]
    set sex one-of ["male" "female"]
    set shape "fish"
  ]

  ask fishes with [color = red] [                                  ; setup red fish attributes
    set species "red"
    set age-at-maturity age-at-maturity-red * 365                 ; convert age to days (ticks)
    set max-age max-age-red * 365
    set feeding-rate max-feeding-rate-red
    set reproduction-threshold reproduction-threshold-red
  ]

  ask fishes with [color = green] [                                 ; setup green fish attributes
    set species "green"
    set age-at-maturity age-at-maturity-green * 365                ; convert age to days (ticks)
    set max-age max-age-green * 365
    set feeding-rate max-feeding-rate-green
    set reproduction-threshold reproduction-threshold-green
  ]

  ask fishes [
    set reserve-size max-energy-reserve
    set age floor random-normal (max-age / 2) ((max-age / 2) * 0.3)     ; distribute ages with the mean as half the life expectancy and a CV of 30%
    if age < 0 [set age 0]                                        ; correct fish with negative age
    ifelse age >= age-at-maturity [set stage "adult"] [set stage "juvenile"]   ; assign life stages
    set size 0.3 + ((age / max-age) * 0.3)                        ; scale the size according to age
    scale-reserve-size
    scale-maintenance
    scale-feeding-rate
    set energy (0.7 * reserve-size) + (random-float 0.3 * reserve-size) ; initial energy varies randomly from 70 to 100% reserve size

  ]
end 



; setup the environment

to load-map      ;observer procedure
  carefully [
    set the-map gis:load-dataset map-file
    gis:apply-raster the-map pcolor
    ask patches [
      if pcolor = 96 [set habitat "canal"]
      if pcolor = 37 [set habitat "mudflat"]
      if pcolor = green [set habitat "land"]
    ]
    ] [create-map-file]

  set non-land-patches patches with [habitat != "land"]
end 

to setup-environment      ; observer procedure
  ask non-land-patches [
    set green.eggs n-values days-until-hatch [0]                    ; eggs are initialized as lists of length "days-until-hatch"
    set red.eggs n-values days-until-hatch [0]
  ]
  ask non-land-patches with [habitat = "mudflat"] [                 ; patches are populated with a random number of prey between half and total carrying capacity
    set worms random-between (floor max-worms-mudflat / 2) max-worms-mudflat
    set bivalves random-between (floor max-bivalves-mudflat / 2) max-bivalves-mudflat
    set plankton random-between (floor max-plankton-mudflat / 2) max-plankton-mudflat
  ]
  ask non-land-patches with [habitat = "canal"] [
    set worms random-between (floor max-worms-canal / 2) max-worms-canal
    set bivalves random-between (floor max-bivalves-canal / 2) max-bivalves-canal
    set plankton random-between (floor max-plankton-canal / 2) max-plankton-canal
  ]
end 


; this startup procedure generates an example map and saves the map as a raster file in the model folder. This only happens if the file is not found.

to create-map-file   ; observer procedure

set the-map
[
55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 96 96 96 96 96 96 96 96 96 96 96 96 96 55
55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 96 96 96 96 96 96 96 96 96 96 96 96 55 55
55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 96 96 96 96 96 96 96 96 96 96 96 96 55 55
55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 96 96 96 96 96 96 96 96 96 96 96 96 96 55 55
55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 96 96 96 96 96 96 96 96 96 96 96 96 55 55 55
55 55 55 55 55 55 55 37 37 37 37 37 37 37 37 37 37 37 37 37 55 55 55 55 55 55 55 55 55 55 55 55 55 37 96 96 96 96 96 96 96 96 96 96 96 96 55 55 55 55
55 55 55 55 55 55 37 96 96 96 37 37 37 37 37 37 37 37 37 37 37 55 55 55 55 55 55 55 55 55 55 55 37 37 96 96 96 96 96 96 96 96 96 96 96 55 55 55 55 55
55 55 55 55 55 55 37 37 37 96 96 37 37 37 37 37 96 96 37 37 37 37 37 37 37 37 55 55 55 55 37 37 37 96 96 96 96 96 96 96 96 96 96 96 55 55 55 55 55 55
55 55 55 55 55 55 37 37 37 37 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 55 55 55 55 55 55
55 55 55 55 55 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 37 55 55 55 55 55 55
55 55 55 55 55 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 55 55 55 55 55 55
55 55 55 55 55 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 55 55 55 55 55 55
55 55 55 55 55 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 55 55 55 55 55 55
55 55 55 55 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 55 55 55 55 55 55
55 55 55 55 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 55 55 55 55 55
55 55 55 55 37 37 37 37 37 37 96 96 96 96 37 37 37 96 96 96 96 96 96 96 96 96 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 55 55 55 55 55
55 55 55 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 55 55 55 55 55
55 55 55 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 55 55 55 55
55 55 37 37 37 96 96 96 37 37 37 37 37 37 37 96 96 96 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 55 55 55 55
55 55 37 96 96 96 96 96 37 37 37 37 37 96 96 96 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 55 55 55
55 55 37 96 96 96 37 37 37 37 37 96 96 96 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 37 96 96 96 96 96 37 37 37 37 37 55 55 55
55 37 37 96 37 37 37 37 37 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 37 37 96 96 96 96 96 96 37 37 37 37 37 55 55
55 37 37 37 37 37 37 37 37 96 96 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 37 37 96 96 96 96 96 96 96 37 37 37 37 55 55
55 37 37 37 37 37 37 96 37 37 96 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 96 96 96 96 37 96 96 37 37 37 55 55
55 37 37 37 37 37 37 96 96 96 96 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 96 96 96 96 37 37 96 96 37 37 37 37
55 37 37 37 37 37 96 96 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 96 96 96 96 96 37 37 96 37 37 96 37
37 37 37 37 37 37 96 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 96 96 96 96 37 37 96 96 37 96 37
37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 96 96 96 37 37 37 96 96 96 37
37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 96 96 96 37 37 37 37 37 37 37
37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 96 96 96 37 37 37 37 37 37 37
37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 96 96 96 96 37 37 37 37 37
37 37 37 37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 37 37 37 37
37 37 37 37 37 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 37 37 37
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 37 37
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 37
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 96 96 96 96 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 96 37 96 96 96 96 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 96 96 37 37 37 96 96 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 96 37 37 37 37 37 96 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 96 37 37 37 37 37 37 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 37 37 37 37 37 37 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 37 37 37 37 37 37 37
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 37 37 37 37 37 37 37
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 37 37 37 37 37 37
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 96 37 37 37 37 37
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 96 37 37 37 37 37
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 37 37 55 55 55 55 55 55 37 37 37 96 96 96 37 37 55 55 55
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 37 37 37 37 55 55 55 55 55 55 55 55 37 37 37 96 37 37 37 55 55 55 55
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 37 55 55 55 55 55 55 55 55 55 55 55 55 55 55 37 37 37 55 55 55 55 55 55
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 37 37 37 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 37 55 55 55 55 55 55 55
]

ask patches [set pcolor item (pxcor - ((pycor - 49) * 50)) the-map
  if pcolor = 96 [set habitat "canal"]
  if pcolor = 37 [set habitat "mudflat"]
  if pcolor = 55 [set habitat "land"]
]

gis:set-world-envelope (list min-pxcor max-pxcor min-pycor max-pycor)

set the-map gis:patch-dataset pcolor

gis:store-dataset the-map "map"

user-message "Welcome! The specified map file was not found or this is your first time here! The default map has been loaded and saved as a map.asc file in your model folder. This message will only appear again if you delete this file. If you are feeling creative, use the map editor to create maps and save them, but don't forget to give them a different name! Have fun exploring!"
end 

;; FISH-RELATED PROCEDURES

to scale-reserve-size  ; fish procedure                                           ; reserve size starts at 10% max when age = 0 and increases until 100% at age-at-maturity
  set maintenance-cost (0.1 * reserve-size) + ((age / (age-at-maturity)) * (0.9 * reserve-size))
end 

to scale-maintenance ; fish procedure                                                 ; maintenance cost starts at 10% max when age = 0 and increases until 100% at age-at-maturity
   set maintenance-cost (0.1 * max-maintenance-cost) + ((age / (age-at-maturity)) * (0.9 * max-maintenance-cost))
end 

to scale-feeding-rate   ; fish procedure                                              ; feeding rate starts at 10% max when age = 0 and increases until 100% at age-at-maturity
  set feeding-rate (0.1 * feeding-rate) + ((age / (age-at-maturity)) * (0.9 * feeding-rate))
end 

to pay-maintenance ; fish procedure
  set energy energy - maintenance-cost
  if energy <= 0 [die] ; fish die if they can't pay maintenance
end 

to move-to-and-jitter [p] ; fish procedure                                      ; moves to a patch and jitters fish coordinates within patch for easier visualization
  let x [pxcor] of p
  let y [pycor] of p
  setxy (x + random-float-between -0.49 0.49) (y + random-float-between -0.49 0.49)
end 

to grow ; fish procedure
  if age >= max-age [die]
  set age age + 1
  if age = age-at-maturity [set stage "adult"]                 ; puberty...
  set size 0.3 + ((age / max-age) * 0.3)                        ; scale the size according to age
  scale-reserve-size
  scale-maintenance
end 

; fishes decide whether to stay or move based on the conditions of the current patch

to move-or-stay ; fish procedure

  ifelse energy < (maintenance-cost + small-movement-cost) [stay] [              ; if really low on energy, just don't move. Else, it depends on who you are and what you need.

  if (stage = "adult") [
    ifelse energy > reproduction-threshold [
    ifelse any? fishes-here with [sex != [sex] of myself and species = [species] of myself] [stay] [move]   ; if ready to reproduce, check for opposite sex and same species, leave if not found
  ] [
  scan-prey                                                                     ; if an adult, but not ready to reproduce, scan prey options
  ]
  ]

  if (age > plankton-eating-period and stage = "juvenile") [                                     ; if a juvenile has left plankton eating period, scan prey options
    scan-prey
  ]

  if (age <= plankton-eating-period) [                                                  ; if in the plankton eating period
    let required-energy reserve-size - energy
    let potentially-available-energy 0
    ifelse any? other fishes-here with [age <= plankton-eating-period] [
      set potentially-available-energy energy-gain-from-plankton * ((plankton * weight-per-plankton) - sum [feeding-rate] of other fishes-here with [age <= plankton-eating-period])  ; if there are other young juveniles here, check energy gain from available plankton grams if everyone ate their max.
      ifelse potentially-available-energy < required-energy [move] [stay]
      ] [
      set potentially-available-energy (plankton * plankton-value)                                                               ; if there are not any young juveniles here, just check if there is enough plankton for me
      ifelse potentially-available-energy < required-energy [move] [stay]
      ]
  ]
  ]
end 

; fish evaluate the amount of energy they need and the available energy at the current patch, and wether larger fish will likely eat everything

to scan-prey   ; fish procedure
  let required-energy 0
  let worms-available-energy 0
  let bivalves-available-energy 0
  ifelse any? other fishes-here with [age > plankton-eating-period and size >= [size] of myself] [
    set required-energy reserve-size - energy
    set worms-available-energy energy-gain-from-worms * ((worms * weight-per-worm) - sum [feeding-rate] of other fishes-here with [age > plankton-eating-period and size >= [size] of myself])  ; if there are other larger fish here, check energy gain from available worms grams if everyone ate worms (exclude very young plankton eaters)
    set bivalves-available-energy energy-gain-from-bivalves * ((bivalves * weight-per-bivalve) - sum [feeding-rate] of other fishes-here with [age > plankton-eating-period and size >= [size] of myself])  ; if there are other fish here, check energy gain from available worms grams if everyone ate worms (exclude very young plankton eaters)
    ifelse (worms-available-energy < required-energy or bivalves-available-energy < required-energy) [move] [stay]
  ] [
  set required-energy reserve-size - energy
  set worms-available-energy (worms * worms-value)                                                               ; if there are not any other fish here, just check if there is enough food for me (exclude young plankton eaters)
  set bivalves-available-energy (bivalves * bivalves-value)
  ifelse (worms-available-energy < required-energy or bivalves-available-energy < required-energy) [move] [stay]
  ]
end 

to move          ; fish procedure                         ; fish move to a neighboring patch, spending more energy in locomotion
  set energy energy - large-movement-cost
  move-to-and-jitter one-of neighbors with [habitat != "land"]
end 

to stay          ; fish procedure                      ; fish just move within the patch, spending less energy
  set energy energy - small-movement-cost
end 


; The extremely complex thought process of fish as they pick which prey to eat based on their needs.

to eat       ; fish procedure
  ifelse age <= plankton-eating-period [                                                                   ; if you are a young plankton eater
    if plankton = 0 [stop]                                                              ; if there's no plankton here, I'm not eating today
    let required-amount ceiling ((reserve-size - energy) / (energy-gain-from-plankton)) ; required amount (in grams)
    if required-amount > feeding-rate [set required-amount feeding-rate]                ; required amount is limited by feeding rate
    let available-amount (plankton * weight-per-plankton)                               ; available amount (in grams)
    let consumed-amount  min list required-amount available-amount       ; each fish consumes the minimum value among required and available
    ask patch-here [
      set plankton plankton - ceiling (consumed-amount / weight-per-plankton)            ; eat the number of plankton required
    ]
    set energy energy + ceiling (consumed-amount / weight-per-plankton) * plankton-value ; replenish energy

  ] [ ; else                                                                                ; if you can eat big prey
  if worms = 0 and bivalves = 0 [stop]                                                      ; if there are no big prey, I'm not eating today
  let required-amount-worms ceiling ((reserve-size - energy) / (energy-gain-from-worms)) ; required amount of worms (in grams)
  let required-amount-bivalves ceiling ((reserve-size - energy) / (energy-gain-from-bivalves))  ; required amount of bivalves (in grams)
  if required-amount-worms > feeding-rate [set required-amount-worms feeding-rate]             ; required amounts are limited by feeding rates
  if required-amount-bivalves > feeding-rate [set required-amount-bivalves feeding-rate]
  let available-amount-worms (worms * weight-per-worm)                               ; available amount (in grams)
  let available-amount-bivalves (bivalves * weight-per-bivalve)
  let chosen-prey "none"                                             ; create local variable
  let consumed-amount 0                                             ; create local variable
  if ((required-amount-worms - available-amount-worms <= 0) and (required-amount-bivalves - available-amount-bivalves <= 0)) [   ; if any prey can fill up energy, pick the one that can do it with less quantity
    ifelse required-amount-worms < required-amount-bivalves [
      set chosen-prey "worms"
      set consumed-amount required-amount-worms
      ] [
      set chosen-prey "bivalves"
      set consumed-amount required-amount-bivalves
      ]
  ]
  if ((required-amount-worms - available-amount-worms <= 0) and (required-amount-bivalves - available-amount-bivalves > 0)) [   ; if only worms can fill up energy, eat  worms
    set chosen-prey "worms"
    set consumed-amount required-amount-worms
  ]
  if ((required-amount-worms - available-amount-worms > 0) and (required-amount-bivalves - available-amount-bivalves <= 0)) [   ; if only bivalves can fill up energy, eat bivalves
    set chosen-prey "bivalves"
    set consumed-amount required-amount-bivalves
  ]
  if ((required-amount-worms - available-amount-worms > 0) and (required-amount-bivalves - available-amount-bivalves > 0)) [   ; if none of the prey can fill up energy, pick the one which can provide more energy that day and eat what's available
    ifelse (available-amount-worms * energy-gain-from-worms) > (available-amount-bivalves * energy-gain-from-bivalves) [
      set chosen-prey "worms"
      set consumed-amount available-amount-worms
      ] [
      set chosen-prey "bivalves"
      set consumed-amount available-amount-bivalves
      ]
  ]
  ask patch-here [
    ifelse chosen-prey = "worms" [set worms worms - ceiling (consumed-amount / weight-per-worm)   ; deplete worms or bivalves from the patch depending on chosen prey
    ] [
    set bivalves bivalves - ceiling (consumed-amount / weight-per-bivalve)
    ]
  ]
  ifelse chosen-prey = "worms" [set energy energy + ceiling (consumed-amount / weight-per-worm) * worms-value ; gain energy from worms or bivalves depending on chosen prey
  ] [
  set energy energy + ceiling (consumed-amount / weight-per-bivalve) * bivalves-value
  ]
  ] ; end ifelse
end 

to fish-eat-prey  ; observer procedure
  ask fishes with [not any? other fishes-here] [eat]                          ; fish who are alone eat the most valuable prey if there is enough quantity

  ask non-land-patches with [count fishes-here > 1] [sort-out-competition]    ; when there are crowded patches, the patch handles prey distribution
end 

to sort-out-competition ; patch procedure
  foreach sort-on [0 - size] fishes-here [ ?1 ->          ; fishes eat in descending order of size (proxy of age)
   ask ?1 [eat]
  ]
end 


; If both sexes of adults ready for reproduction are present, they release gametes to the patch. Incubation is external, so it occurs on the patch, mixing up gametes from several males and females.

to fish-reproduction     ; observer procedure
  ask non-land-patches with [length (remove-duplicates [sex] of fishes-here with [species = "green" and stage = "adult" and energy > reproduction-threshold]) = 2] [  ; patches with both sexes of green adults fit for reproduction
    let green-reproductive-adults fishes-here with [species = "green" and stage = "adult" and energy > reproduction-threshold]
    ask green-reproductive-adults [
      set nr-gametes floor (energy - reproduction-threshold) / cost-per-gamete     ; the number of eggs procuced equals the surplus energy divided by the energetic cost per gamete
      set energy (energy - (nr-gametes * cost-per-gamete))                         ; energy of the gametes produced is removed from the fish
    ]
    let green-female-gametes sum [nr-gametes] of green-reproductive-adults with [sex = "female"]
    let green-male-gametes sum [nr-gametes] of green-reproductive-adults with [sex = "male"]
    set green.eggs replace-item 0 green.eggs ((min list green-female-gametes green-male-gametes) * (1 - (egg-mortality-green / 100))) ; the minimum number between female and male gametes is picked as the nr of eggs (two are needed). The other gametes are wasted.
    ask green-reproductive-adults [set nr-gametes 0]
  ]

  ask non-land-patches with [length (remove-duplicates [sex] of fishes-here with [species = "red" and stage = "adult" and energy > reproduction-threshold]) = 2] [  ; patches with both sexes of red adults fit for reproduction
    let red-reproductive-adults fishes-here with [species = "red" and stage = "adult" and energy > reproduction-threshold]
    ask red-reproductive-adults [
      set nr-gametes floor (energy - reproduction-threshold) / cost-per-gamete     ; the number of eggs procuced equals the surplus energy divided by the energetic cost per gamete
      set energy (energy - (nr-gametes * cost-per-gamete))
    ]
    let red-female-gametes sum [nr-gametes] of red-reproductive-adults with [sex = "female"]
    let red-male-gametes sum [nr-gametes] of red-reproductive-adults with [sex = "male"]
    set red.eggs replace-item 0 red.eggs ((min list red-female-gametes red-male-gametes) * (1 - (egg-mortality-red / 100)))  ; the minimum number between female and male gametes is picked as the nr of eggs (two are needed). The other gametes are wasted.
    ask red-reproductive-adults [set nr-gametes 0]
  ]
end 



;; PATCH-RELATED PROCEDURES

to egg-development             ; observer procedure
  ask non-land-patches [
    set green.eggs remove-item (days-until-hatch - 1) green.eggs                         ; the eggs list shifts one position to the right, the last item being the eggs ready to hatch on the current tick
    set red.eggs remove-item (days-until-hatch - 1) red.eggs

    set green.eggs fput 0 green.eggs
    set red.eggs fput 0 red.eggs
  ]
end 

; eggs that have reached "days-until-hatch" are sent to a random number of mudflat patches between half the total area and the total mudflat area

to hatch-eggs                  ; observer procedure
  let mudflat-patches non-land-patches with [habitat = "mudflat"]
  ask non-land-patches with [last green.eggs > 0] [          ; hatch green eggs
  let nr-green-eggs last green.eggs
  set green.eggs replace-item (days-until-hatch - 1) green.eggs 0       ;eggs hatched, so they are removed from the patch variable
  let number-patches 0
  ifelse nr-green-eggs > count mudflat-patches [
    set number-patches random-between (floor count mudflat-patches / 2) (floor count mudflat-patches)
    ] [
    set number-patches random-between 1 nr-green-eggs             ; if small amount of eggs, max patches is nr of eggs (1 egg per patch)
    ]
  ask n-of number-patches mudflat-patches [
    set green-newcomers green-newcomers + nr-green-eggs / number-patches
    ]
  ]
  ask non-land-patches with [last red.eggs > 0] [          ; hatch red eggs
  let nr-red-eggs last red.eggs
  set red.eggs replace-item (days-until-hatch - 1) red.eggs 0       ;eggs hatched, so they are removed from the patch variable
  let number-patches 0
  ifelse nr-red-eggs > count mudflat-patches [
    set number-patches random-between (floor count mudflat-patches / 2) (floor count mudflat-patches)
    ] [
    set number-patches random-between 1 nr-red-eggs
    ]
  ask n-of number-patches mudflat-patches [
    set red-newcomers red-newcomers + nr-red-eggs / number-patches
    ]
  ]

  ask mudflat-patches with [green-newcomers > 0 and red-newcomers > 0] [    ; patches with both species trying to settle. Each species scans 1/4 of the carrying capacity
    let carrying-capacity floor (plankton * weight-per-plankton) / (max-feeding-rate-green * 0.1)  ; 10% feeding rate at age 0
    let settled-greens min list (floor (carrying-capacity / 4)) green-newcomers   ; number of settlers limited by carrying capacity
    let settled-reds min list (floor (carrying-capacity / 4)) red-newcomers
    settle-greens settled-greens
    settle-reds settled-reds
    set red-newcomers 0
    set green-newcomers 0
  ]

  ask mudflat-patches with [green-newcomers = 0 and red-newcomers > 0] [  ; patches with only red settlers, scan 1/2 of the carrying capacity
    let carrying-capacity (plankton * weight-per-plankton) / (max-feeding-rate-red * 0.1)
    let settled-reds min list (carrying-capacity / 2) red-newcomers
    settle-reds settled-reds
    set red-newcomers 0
  ]

  ask mudflat-patches with [green-newcomers > 0 and red-newcomers = 0] [   ; patches with only green settlers, scan 1/2 of the carrying capacity
    let carrying-capacity (plankton * weight-per-plankton) / (max-feeding-rate-green * 0.1)
    let settled-greens min list (carrying-capacity / 2) green-newcomers
    settle-greens settled-greens
    set green-newcomers 0
  ]
end 

to settle-reds [nr] ; patch procedure
  sprout-fishes nr [
    set reserve-size max-energy-reserve
    set sex one-of ["male" "female"]
    set shape "fish"
    set species "red"
    set color red
    set age 0
    set size 0.3
    set age-at-maturity age-at-maturity-red * 365                ; convert age to days (ticks)
    set max-age max-age-red * 365
    set feeding-rate max-feeding-rate-red
    set reproduction-threshold reproduction-threshold-red
    scale-reserve-size
    scale-maintenance
    scale-feeding-rate
    set energy (0.7 * reserve-size) + (random-float 0.3 * reserve-size) ; initial energy varies randomly from 70 to 100% reserve size
    move-to-and-jitter patch-here ; jitter in the current patch
  ]
end 

to settle-greens [nr]   ; patch procedure
  sprout-fishes nr [
    set reserve-size max-energy-reserve
    set sex one-of ["male" "female"]
    set shape "fish"
    set species "green"
    set color green
    set age 0
    set size 0.3
    set age-at-maturity age-at-maturity-green * 365                ; convert age to days (ticks)
    set max-age max-age-green * 365
    set feeding-rate max-feeding-rate-green
    set reproduction-threshold reproduction-threshold-green
    scale-reserve-size
    scale-maintenance
    scale-feeding-rate
    set energy (0.7 * reserve-size) + (random-float 0.3 * reserve-size) ; initial energy varies randomly from 70 to 100% reserve size
    move-to-and-jitter patch-here   ; jitter in the current patch
    ]
end 

to regrow-prey              ; obsever procedure
  ask non-land-patches [
    if worms < 0 [set worms 0]
    if bivalves < 0 [set bivalves 0]
    if plankton < 0 [set plankton 0]
    set worms worms + worms-regrowth-rate
    set bivalves bivalves + bivalves-regrowth-rate
    set plankton plankton + plankton-regrowth-rate

    ; limit the amount of prey to the carrying capacity of the habitat

    if habitat = "mudflat" [
      if worms > max-worms-mudflat [set worms max-worms-mudflat]
      if bivalves > max-bivalves-mudflat [set bivalves max-bivalves-mudflat]
      if plankton > max-plankton-mudflat [set plankton max-plankton-mudflat]
    ]
    if habitat = "canal" [
      if worms > max-worms-canal [set worms max-worms-canal]
      if bivalves > max-bivalves-canal [set bivalves max-bivalves-canal]
      if plankton > max-plankton-canal [set plankton max-plankton-canal]
    ]
  ]
end 

;; PREY REPORTERS

to-report worms-value
report precision (energy-gain-from-worms * weight-per-worm) 3
end 

to-report bivalves-value
report precision (energy-gain-from-bivalves * weight-per-bivalve) 3
end 

to-report plankton-value
report precision (energy-gain-from-plankton * weight-per-plankton) 3
end 

; FISH REPORTERS (these were not fully implemented, but are based on real data from Solea solea and can be used to estimate parameters.)

to-report get-length [t]
  report 38 * (1 - exp(-0.43 * ((t / 365) + 0.1))) ; cm, t in days
end 

to-report get-weight [L]      ; g, L in cm
  report 0.0062 * (L ^ 3.13)
end 

to-report get-feeding-rate [t]  ; g / day, t in days
  let L get-length t
  let w get-weight L
  report 0.092 * w
end 


; PLOTTING AND OUTPUTS

; plot and monitor code is in the plots and monitors on the interface tap


; MAP EDITOR

to draw-canals
  if mouse-down?     ;; reports true or false to indicate whether mouse button is down
    [
      ask patch mouse-xcor mouse-ycor
        [ set pcolor 96
          set habitat "canal"
          display ]
    ]
end 

to draw-mudflats
  if mouse-down?     ;; reports true or false to indicate whether mouse button is down
    [
      ask patch mouse-xcor mouse-ycor
        [ set pcolor 37
          set habitat "mudflat"
          display ]
    ]
end 

to erase-map
   if mouse-down?     ;; reports true or false to indicate whether mouse button is down
    [
      ask patch mouse-xcor mouse-ycor
        [ set pcolor black
          set habitat ""
          display ]
    ]
end 

to fill-land
  ask patches with [pcolor = black] [
   set pcolor green
   set habitat "land"
  ]
end 


;; USEFUL REPORTERS

to-report random-float-between [a b]
  report a + random-float (b - a)
end 

to-report random-between [a b]
  report a + random (b - a)
end 

There are 2 versions of this model.

Uploaded by When Description Download
Miguel Pais over 6 years ago Updated to work with NetLogo 6.0.2 Download this version
Miguel Pais over 7 years ago Initial upload Download this version

Attached files

File Type Description Last updated
Estuaryscape.png preview Preview for 'Estuaryscape' over 7 years ago, by Miguel Pais Download

This model does not have any ancestors.

This model does not have any descendants.