Nplants simulator implementing Bown et al 2007's ecological model.
powered by NetLogo
view/download model file: nplants.nlogo
This simulation implements the ecological model published in Bown et al 2007 ( http://dx.doi.org/10.1016/j.ecolmodel.2007.05.004 ), which studies the distribution and abundance of plant species, within a certain environment.
The aim of this work is to address the ecological "holy grail", meaning to study the relation between environmental properties, individual properties and community composition.
The environment is a square lattice with all boundaries fixed (not torroidal). Each lattice cell (patch) contains a resource substrate from which plants uptake resources.
A plant executs four biological processes: resource uptake, resource allocation, development and reproduction. In addition, death occurs either due to random events or from starvation.
The simulation starts with a number of unique individuals defined by the input 'species'. Each of this will undergo the biological processes which will eventually lead to verious species dissapear, while others will flourish.
The aim of the simulation is to observ the progress of the 'richness' barometer, and it's relation to the 'environment' size and other parameters.
Pressing the 'setup' button will initialise the environment, according to the parameters specified on the interface. You can vary:
- the initial number of species ('species' input)
- simulation length
- substrate value: each patch contains a resource substrate that is filled up to a given value
There are a couple of switches which alter the information displayed on the screen:
- links? controlls the display of links between plants and the seeds they disperse
- plotting? controlls the update of the plots. If it is on, plots will be updated according to the state of the simulation
- output? controlls standard output to the Command Center (not visible in applet mode).
This section could give some ideas of things for the user to notice while running the model.
This section could give some ideas of things for the user to try to do (move sliders, switches, etc.) with the model.
This section could give some ideas of things to add or change in the procedures tab to make the model more complicated, detailed, accurate, etc.
This section could point out any especially interesting or unusual features of NetLogo that the model makes use of, particularly in the Procedures tab. It might also point out places where workarounds were needed because of missing features.
This section could give the names of models in the NetLogo Models Library or elsewhere which are of related interest.
This section could contain a reference to the model's URL on the web if it has one, as well as any other necessary credits or references.
extensions [array] ;;;;;;;;;;;;;;;;;;;;; ;;; Data types ;;; ;;;;;;;;;;;;;;;;;;;;; breed [ plants plant ] undirected-link-breed [plant-links plant-link] plant-links-own [ time ] plants-own [ rcdt eu_y0 eu_b reur strr surr tdfv ps rsp rst pdp tref ;; traits dvs age ss stl su ;; states csl ; cumulative resource requirement according to development stage tot-aru tot-rqd rsv ;; resource shortfall value ( rst * ( essential_uptake_trait i ) ) tot-rhs ;; total resource in history rhs ;; resource history ] patches-own [ ini cur sat rel rep ;; substrate req-id req-v ;; requests tot-req ;; total resource request over a timestep ] ;; Global vars globals [ richness abundance species-colors plc ;; index in resource history mpr ;; # of periods that resource history is considered mdi ;; max distance reached by resource capture system mdm ;; # of cells in the max res. capture syst.; related to mdi mds ;; # of development stages sdp ;; # seed dispersal pattern epochs ;; traits a_mean y0_mean; y0_dev b_mean b_dev x0_mean reur_mean reur_dev rca_defs ps_mean tim_mean tim_dev strr_mean strr_dev surr_mean surr_dev rtp_mean rtt_mean pdp_mean ;; statistics max-dvs max-age max-seeds max-seeds-px max-seeds-py ;; movie last-record? record? ] ;;;;;;;;;;;;;;;;;;;;;;;; ;;; Setup procedures ;;; ;;;;;;;;;;;;;;;;;;;;;;;; to setup clear-all setup-globals setup-environment setup-population if ( plotting? ) [ set-current-plot "Development stage" set-plot-y-range 0 mds set-histogram-num-bars mds / 2 set-current-plot "Ages" set-histogram-num-bars mds / 2 do-plotting ] set last-record? false end to setup-globals set richness 0 set plc 0 set abundance array:from-list (n-values species [ 0 ]) set species-colors array:from-list (n-values species [ 0 ]) set mpr 6 set mdi 1 set mdm 49 set mds 50 set sdp 5 set epochs 5 ;; traits set a_mean 10.52 set y0_mean 0.24 set y0_dev 0.31 set b_mean 8.12 set b_dev 2.65 set x0_mean 29.09 set reur_mean 1.1 set reur_dev 0.58 set rca_defs array:from-list [ 1 0.9 0.8 0.7 0.6 ;; 0/mdi 0 0 0.1 0.2 0.3 0.4 ;; 0/mdi 1 1 0.8 0.6 0.4 0.2 ;; 1/mdi 0 0 0.2 0.4 0.6 0.8 ;; 1/mdi 1 ] ;/rcdt/mdi/ep set ps_mean 0.8 ;;unusable_store_proportion_trait set tim_mean 45 ;; Rumex parabola fitting set tim_dev 8.6 ;; Rumex set strr_mean 0.28 set strr_dev 0.143 set surr_mean 0.4 set surr_dev 0.153 set rtp_mean 5 ;; resource shortfall period trait (must be < mdr) set rtt_mean 0.1 ;;resource_shortfall_threshold_trait set pdp_mean 0.001 ;;statistics set max-dvs 0 set max-age 0 set max-seeds 0 set max-seeds-px 0 set max-seeds-py 0 end to setup-environment resize-world 0 (environment - 1) 0 (environment - 1) if ( environment * environment < species ) [ set species environment * environment ] ask patches [ ;; chessboard ;ifelse ( remainder ( pxcor + pycor * max-pxcor ) 2 = 0 ) ;[ set pcolor white ] ;[ set pcolor black ] set pcolor white set ini substrate set cur substrate set sat substrate set rel substrate set rep substrate set req-id  set req-v  ] end to setup-population set-default-shape plants "leaf" ;; creation create-plants species [ ;; location setxy random-pxcor random-pycor while [ count turtles-here > 1 ] [ setxy random-pxcor random-pycor ;show (word "was placed on a occupied location") ] ;; color set color ( rgb random 256 random 256 random 256 ) array:set species-colors who color ;; sampling traits set rcdt (random 2) set eu_y0 y0_mean + (random-normal 0 1) * y0_dev if (eu_y0 < 0) [ set eu_y0 0 ] set eu_b b_mean + (random-normal 0 1) * b_dev set reur reur_mean + (random-normal 0 1) * reur_dev if ( reur < 1 ) [ set reur 1 ] set ps ps_mean set tdfv floor ( tim_mean + (random-normal 0 1) * tim_dev ) set strr strr_mean + (random-normal 0 1) * strr_dev ifelse ( strr < 0 ) [ set strr 0 ] [ if ( strr > 1 ) [ set strr 1 ] ] set surr surr_mean + (random-normal 0 1) * surr_dev ifelse ( surr < 0 ) [ set surr 0 ] [ if ( surr > 1 ) [ set surr 1 ] ] set rsp rtp_mean set rst rtt_mean set pdp pdp_mean if output? [ show (word "rcdt=" rcdt " eu_y0=" eu_y0 " eu_b=" eu_b " reur=" reur " tdfv=" tdfv " strr=" strr " surr=" surr) ;; states ] ;; states set rhs array:from-list n-values mpr  set dvs 0 set age 0 set stl 0 set su 0 set ss 0 set tref who array:set abundance who 1 set csl (essential_uptake_trait 0) ] set richness species end ;;;;;;;;;;;;;;;;;;;;; ;;; Go procedures ;;; ;;;;;;;;;;;;;;;;;;;;; to go-step go end to go if ticks >= sim-length [ stop ] if count plants = 0 [ stop ] resource-acquisition resource-usage tick if ( links? ) [ ask plant-links [ set time time + 1 if ( time > 10 ) [ die ] ] ] set plc ( remainder ticks mpr ) if ( plotting? ) [ do-plotting ] end to resource-acquisition ;; observer ask plants [ request-resources ] ask patches [ normalise-requests ] ask plants [ uptake-resources ] ask patches [ replenish-substrate rep ] end to request-resources ;; a plant requests resources from its neighbours set tot-rqd 0 ; for patch at distance 0 let req ( resource_capture_proportion_trait 0 ) * requested_uptake_trait set tot-rqd req ;show (word "resource-requests (0)=" req ) let plant-id who ask patch-here [ receive-request req plant-id ] ;; for patches at distance 1 set req ( resource_capture_proportion_trait 1 ) * requested_uptake_trait ;show (word "resource-requests (1)=" req ) ask neighbors [ receive-request req plant-id ] set tot-rqd tot-rqd + 8 * req ;show (word "resource-requests=" tot-rqd ) end to receive-request [ req plant-id] ;; a patch receives and stores a resource request set req-id ( fput plant-id req-id ) set req-v ( fput req req-v ) end to normalise-requests ;; a patch normalises the requests according to the resources it has set tot-req sum req-v ;set plabel precision req-sum 2 if (tot-req > 0 and tot-req > cur) [ ;* > 0 added and because cur becomes negative ;if (cur < 0 ) [ show (word "cur=" cur) ] let r cur / tot-req set req-v ( map [ r * ? ] req-v ) ] if (substrate-color?) [ ifelse (tot-req <= sat) [ set pcolor 9.9999 - 5 * tot-req / sat ] [ set pcolor 4.9999 ] ] end to uptake-resources ;; plant let aru 0 let plant-id who ask patch-here [ set aru release-resource plant-id ] ask neighbors [ set aru aru + ( release-resource plant-id ) ] set tot-aru aru ;show (word "uptake-resources: aru=" aru) ;show (word "plc=" plc) array:set rhs plc aru ;; memorise uptake ;; allocate resources let rqd ( essential_uptake_trait dvs ) let sur ( surr * su ) if ( aru > rqd) [ set su su + ( aru - rqd ) set aru rqd ] if ( aru < rqd ) [ let dif rqd - aru ifelse ( dif <= sur ) [ ; take dif from Su set aru aru + dif set su su - dif ] [ ; take sur from Su set aru aru + sur set su su - sur ] ] set ss ss + aru * ps set stl ( stl + aru * ( 1 - ps) ) ;show (word "ss=" ss " stl=" stl " su=" su) ;show rhs end to replenish-substrate [ res ] ;; patch if ( cur < 0 ) [ set cur 0 ] set cur cur + res if ( cur > sat ) [ set cur sat ] end to-report release-resource [ plant-id ] ;; a patch reports the resources a plant has been allocated let res 0 let i 0 foreach req-id [ if (? = plant-id ) [ set res ( item i req-v) set req-v remove-item i req-v set req-id remove-item i req-id set cur cur - res ; depleting the substrate ; if (cur < 0) [ set cur 0 ] ; for float correction report res ] set i i + 1 ] end to receive-resource [ res ] ;; a patch receives resources (from a plant that died) set cur cur + res if ( cur > sat ) [ set cur sat ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;; resource-usage to resource-usage ask plants [ individual_development ] ask plants [ reproduce ] end to individual_development ;; a plant may die or develop ;; verifying death conditions if ( ( random-float 1 ) <= pdp ) [ ;show (word " dieing because of random death") individual-death ] ; resource shortfall set tot-rhs sum array:to-list rhs set rsv rst * (essential_uptake_trait dvs ) if ( tot-rhs < rsv ) [ if output? [ show (word " dieing because of resource shortfall") ] individual-death ] ;; development set age age + 1 if ( age > max-age ) [ set max-age age ] let dst csl + (essential_uptake_trait (dvs + 1)) ;developmental_storage_requirement_evaluation ; TODO: Use csl instead of this costly function let tls stl + ss if (tls > dst and (dvs < mds)) [ set dvs dvs + 1 set csl dst;csl + (essential_uptake_trait dvs) ] ;if ( dvs > max-dvs ) [ set max-dvs dvs ] end to individual-death ;; plant returns resources and dies ;; returning resources let tot-res stl + su + ss let rcpt ( resource_capture_proportion_trait 0 ) ask patch-here [ receive-resource rcpt * tot-res ] set rcpt ( resource_capture_proportion_trait 1 ) ask neighbors [ receive-resource rcpt * tot-res ] ; statistics update array:set abundance tref ( array:item abundance tref ) - 1 if ( array:item abundance tref = 0 ) [ set richness richness - 1 ] if ( true ) [ die ] end to reproduce ;; plant let num 0 ; num seeds let sr 0.0 ; seed resource let fecund? false ;; check fecundity if ( ( remainder age tdfv ) = 0 ) [ set fecund? true ] if ( fecund? ) [ ;show (word "is fecund") let tsl su + (stl * strr) set num floor ( tsl / ( essential_uptake_trait 1 ) ) if (num > 0) [ ;; max-seeds monitor if (num > max-seeds) [ set max-seeds num ask patch-here [ set pcolor black ] ask patch max-seeds-px max-seeds-py [ set pcolor white ] set max-seeds-px pxcor set max-seeds-py pycor ] ;; calculate seed numbers set sr tsl / num ; allocate resources set stl stl - ( tsl - su ) set su 0 ;; disperse offsprings repeat num [ ; position let ver ( random ( 2 * sdp + 1 ) - sdp ) let hor ( random ( 2 * sdp + 1 ) - sdp ) let destination patch-at hor ver if not ( nobody = destination ) [ ; if destination is valid if ( ( count plants-on destination ) = 0 ) [ ;show (word "hatched at " ver " " hor) array:set abundance tref ( array:item abundance tref ) + 1 let lcolor color hatch 1 [ move-to destination if links? [ create-plant-link-with myself [ set time 0 set color lcolor ] ] set su 0 set stl 0 set ss 0 set dvs 0 set age 0 set csl (essential_uptake_trait 0) ] ask destination [ replenish-substrate sr ] ] ] ] ;; amend development stage set tsl (stl + ss) let fin 0 if ( csl < tsl ) [ set fin 1 ] ; requirement is smaller than what already possessed while [(fin = 0) and (dvs > 0)] [ set dvs dvs - 1 set csl csl - (essential_uptake_trait dvs) if (csl < tsl) [ set fin 1 ] ;show (word "dvs--") ] ] ] end ;;;;;;;;;;;;;;;;;;;;; ;;; Traits ;;; ;;;;;;;;;;;;;;;;;;;;; to-report essential_uptake_trait [ i_dvs ] ;; essential uptake trait let a a_mean let x0 x0_mean let rrr ( eu_y0 + a / ( 1 + exp (-( i_dvs - x0 ) / eu_b )) ) if (rrr < 0) [ show (word "rrr<0") set rrr 0 ] report rrr end to-report requested_uptake_trait ;; plant report reur * (essential_uptake_trait dvs) end to-report resource_capture_proportion_trait [ rng ] ;; plant let ep floor ( dvs * 5.0 / mds) if (ep > 4) [ set ep 4 ] let idx (rcdt * 10) + ( rng * 5 ) + ep ;show (word "idx=" idx ", ep=" ep ", rng=" rng) let rcp array:item rca_defs ( idx ) if (rng > 0) [ set rcp ( rcp / (8 * rng) ) ] report rcp end to-report developmental_storage_requirement_evaluation let dst 0 let i 0 while [ i <= ( dvs + 1 ) ] [ set dst ( dst + (essential_uptake_trait i) ) set i i + 1 ] report dst ; * reur end to do-plotting set-current-plot "Richness" set-current-plot-pen "richness" plot richness set-current-plot "Abundance" ;;let labundance array:to-list abundance ;;set-plot-x-range 0 max labundance ;;histogram labundance clear-plot set-plot-x-range 0 species set-plot-y-range 0 ( max array:to-list abundance + 1 ) let i 0 while [ i < species ] [ ;set-plot-pen-color array:item species-colors i plotxy i array:item abundance i set i i + 1 ] set-current-plot "Development stage" histogram [dvs] of plants set-current-plot "Ages" set-plot-x-range 0 ( max-age + 1 ) set-histogram-num-bars 25 histogram [age] of plants end to reset set max-dvs 0 set max-age 0 set max-seeds 0 set max-seeds-px 0 set max-seeds-py 0 end to trim ask plants [ if ( age > beyond-age ) [ individual-death ] ] end