Estuaryscape
Model was written in NetLogo 6.0.2
•
Viewed 663 times
•
Downloaded 47 times
•
Run 0 times
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.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Estuaryscape.png | preview | Preview for 'Estuaryscape' | about 8 years ago, by Miguel Pais | Download |
This model does not have any ancestors.
This model does not have any descendants.