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 872 times • Downloaded 61 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.)


PURPOSE

This model attempts to simulate spatial interaction of 2 flatfish and 3 prey types in an estuary, featuring two different habitats, simple prey population dynamics, reproduction and competition. The model has simplified bioenergetics governing the state of each agent.

Lots of monitors help parameterise, but there are a lot of parameters! Try to see how many days your species can survive!

I am aware the model still has bugs here and there, this was done in 3 days, so not much time to debug... but I will be improving the code in my spare time.

BACKGROUND

The common sole (Solea solea) and the Senegalese sole (Solea senegalensis) have come to share the same habitats, as climate change allows the latter species to move further North and overlap the habitat of the common sole. These very similar species now have to survive the fierce competition for similar resources. On the first year, they mostly eat zooplankton in the water column, but then they feed on both worms (polychaetes such as Hediste diversicolor) and bivalves (such as Scrobicularia plana).

AGENT TYPES

The only moving agents are 2 fish species acting as competing predators. Three prey types are mostly fixed to a patch, varying only in their population densities. These are worms, bivalves and zooplankton.

AGENT ATTRIBUTES

Both fish species have similar properties, which can be set equally or differently:

  • age-at-maturity: age at which a fish becomes an adult and is fit for reproduction
  • max age: maximum age
  • maximum feeding rate: maximum total size of prey a fish can eat in a day
  • energy reserve size: the size of the energy reserve, measured in arbitrary energy units, which limits feeding rates
  • maintenance cost: energy required to support life
  • small-movement cost: energy cost of staying in the same patch
  • large-movement cost: energy cost of moving to another patch
  • reproduction threshold: surplus energy level at which an adult fish becomes fit to produce gametes and starts to seek females
  • cost-per-gamete: energy cost of producing one gamete. This is used to calculate the number of eggs to generate.
  • Days until hatch: days from egg fecundation to hatch.
  • Egg mortality: fraction of eggs that die during the days it takes to hatch
  • Plankton eating period: amount of days post-settlement during which the fish only eats plankton.

Fish state variables include:

  • coordinates of their current patch
  • sex
  • an energy reserve compartment that stores energy assimilated from consumed prey, minus the maintenance costs
  • age (days)
  • life stage: juvenile or adult

All three prey types have similar fixed properties, but they can be different between types:

  • weight per prey: this impacts feeding rate, because larger prey occupy more volume in a stomach.
  • energy gain from prey: this is the amount of energy contained in 1 gram of prey, minus the energy required to eat it (chase, chew, filter…).
  • Growth rate, as in a fixed number of new individuals per day.
  • Carrying capacity in mudflats: maximum number of prey in mudflats
  • Carrying capacity in canals: maximum number of prey of this type in canals

ENVIRONMENT

The environment is a spatially explicit depiction of a generic estuary with patches representing 2 habitats, mudflats and sandy canals. A third patch color is used to represent land, where nothing happens.

A patch represents 4 square meters. Each habitat can better support different types of prey. By default, worms prefer mudflats, bivalves prefer the canals and free-swimming plankton have no preference. Depth and water currents are ignored.

AGENT BEHAVIOUR

Fish move by examining surrounding patches and deciding to stay or move to another patch based on the competition existing on the current patch, potential energy gains, current energy levels and whether or not they are ready to reproduce. Although there is a grid movement, fish are "jittered" for better visualisation (to avoid all fish in a patch being overlapped).

While on a patch, fish eat prey based on the energy requirements and feeding rate. Because fish can only pick one prey type per day, prey choice involves a decision process based on the potential energy gains.

Adults with enough energy reproduce if an adult of the opposite sex with enough energy to do so is present. Surviving fish eggs will remain in the patch of origin for the required time. Once they hatch, juveniles are randomly distributed across mudflat patches (less water flow, more protection) across the map. If they can eat given the current competition in the patch, they will be added as fish agents, if not the settlement is not successful and larvae die. Prey grow with a pre-defined fixed rate, limited by carrying capacities.

MODEL SCHEDULE

At the beggining, the map is loaded and fish are placed randomly on non-land patches, species and sexes are chosen randomly and ages are distributed normally around the middle of life expectancy.

Each model cycle represents one day, and events occur in this order:

  • fish die if too old
  • fish increase age, juveniles change to adults if they reach maturity, max energy, feeding rate and maintenance costs are proportional to age, until they reach the maximum at maturity.
  • fish pay maintenance-costs or die!
  • fish move or stay by scanning the environment
  • fish eat-prey, larger fish get to eat first
  • eggs age advances
  • eggs that reach full development hatch
  • fish reproduce
  • prey grows back

INPUTS AND OUTPUTS

Inputs

The initial number of fish from each breed, the percentage cover of each habitat type and all the parameters described for fish and prey.

Outputs

The population of each fish species, the number of days/years until population collapses, the spatial distribution of species and sizes.

Ultimately, it serves to attempt if two competing predators can find a way to survive and avoid the heavy costs of competition, even if the preferences for a certain habitat or prey are not specifically stated.

WHAT TO DO

The mode has a lot of parameters, but it is still a very simplistic representation, so it can be hard to parameterise! Experimenting with species attributes and prey availabilities can lead to catastrophic outcomes very easily. Try to see how many days the populations can last. Try to give advantages to a species, such as faster maturity or more fecundity.

There is a map editor so you can draw your own estuary using the mouse! And then save the map as an .asc file to use later! See how the fish do in your estuary.

REFERENCES

Cabral, H. N., Costa, M. J. (1999) Differential use of nursery areas within the Tagus estuary by sympatric soles, Solea solea and Solea senegalensis. Environmental Biology of Fishes 56, 389–397.

Froese, R., Pauly, D. (Eds.) (2016) FishBase. World Wide Web electronic publication. www.fishbase.org, ( 06/2016 ).

Lagardère, J.P. (1987) Feeding ecology and daily food consumption of common sole, Solea vulgaris Quensel, juveniles on the French Atlantic coast. Journal of Fish Biology 30, 91-104.

Vinagre, C., Cabral, H. N. (2008) Prey consumption by the juvenile soles, Solea solea and Solea senegalensis, in the Tagus estuary, Portugal. Estuarine, Coastal and Shelf Science 78, 45–50.

COPYRIGHT AND LICENSE

Copyright 2017 Miguel P. Pais

CC BY-NC-SA 3.0

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/

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 almost 8 years ago Updated to work with NetLogo 6.0.2 Download this version
Miguel Pais almost 9 years ago Initial upload Download this version

Attached files

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

This model does not have any ancestors.

This model does not have any descendants.