Soil network simulation

Soil network simulation preview image

2 collaborators

Default-person Natalie Davis (Author)
Default-person Gary Polhill (Advisor)

Tags

ecology 

Tagged by Natalie Davis about 4 years ago

ecosystem 

Tagged by Natalie Davis about 4 years ago

networks 

Tagged by Natalie Davis about 4 years ago

soil and water conservation 

Tagged by Natalie Davis about 4 years ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 6.1.1 • Viewed 220 times • Downloaded 23 times • Run 0 times
Download the 'Soil network simulation' modelDownload this modelEmbed this model

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


Comments and Questions

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

Click to Run Model

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GPL 3 license                                                                ;
;    This program is free software: you can redistribute it and/or modify      ;
;    it under the terms of the GNU General Public License as published by      ;
;    the Free Software Foundation, either version 3 of the License, or         ;
;    (at your option) any later version.                                       ;
;                                                                              ;
;    This program is distributed in the hope that it will be useful,           ;
;    but WITHOUT ANY WARRANTY; without even the implied warranty of            ;
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             ;
;    GNU General Public License for more details.                              ;
;                                                                              ;
;    You should have received a copy of the GNU General Public License         ;
;    along with this program.  If not, see .    ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
extensions [ csv table ]

globals [ this-seed links-list ]

breed [ resources resource ]
breed [ consumers consumer ]

consumers-own [ location target-location resource-requirement resource-stock metabolism active? spawn-energy consumption-rate ]
resources-own [ subnet-id node-id current-supply resource-capacity regrow-rate ]

to setup
  clear-all
  ; Set a random seed unless one is provided
  ifelse my-seed != 0 [ set this-seed my-seed ] [ set this-seed new-seed ]
  random-seed this-seed
  import-node-attributes
  import-links
  make-consumers
  reset-ticks
  ; Record initial state of model
  record-initial-consumer-state
  record-initial-resource-state
end 

to go
  if not any? consumers with [ active? = true ] [ stop ]
  ; All resources regrow by regrow-rate each tick (up to resource-capacity)
  regrow-resource
  ; Consumers wander randomly and consume resources
  consume-resource
  ; Consumers with enough energy spawn new consumers
  spawn-consumers
  ; All consumers check and consume basal metabolism from stocks
  check-supplies
  tick
  ; Record data - not currently done every tick or the file size quickly expands
  if (ticks = 10 or ticks = 100 or ticks = 250 or ticks = 500 or ticks = 750 or ticks = 1000) [
    write-consumer-state
  ]
  write-resource-state
end 

; Observer procedure to check if consumers have enough energy to meet basal metabolic requirements

to check-supplies
  ask consumers with [ active? = true ] [
    ; If they don't have enough energy, they become inactive
    ifelse resource-stock <= resource-requirement [
      become-inactive
    ] [
      ; Otherwise, metabolise basal requirement from resource stocks
      set resource-stock resource-stock - resource-requirement
    ]
  ]
end 

; Consumer procedure to set consumers without enough energy as 'inactive' - effectively dead, but
; still in the system to allow for expansion/future work

to become-inactive ; consumer procedure
  set resource-stock 0
  set active? false
  set hidden? true
end 

; Observer procedure to handle consumers eating resources - if there is nothing for them to eat, they move on, otherwise they consume
; what is available (up to their maximum consumption-rate per timestep)

to consume-resource
  ask consumers with [ active? = true ] [
    ifelse resource-stock < 0 [
      ; If consumer has used up all energy getting to the resource and is in negative resource stocks, it dies (but not if it is at 0)
      become-inactive
    ] [
      ; If there is nothing to eat here, consumers move on
      if not any? resources-here with [ current-supply > 0 ] [ move-on ]
    ]
  ]
  ; Only check resources with something for consumers to take, and that have consumers on them
  ask resources with [ current-supply > 0 ] [
    if any? consumers-here with [ active? = true ] [
      let active-consumers-here consumers-here with [ active? = true ]
      let total-resource-req sum [ consumption-rate ] of active-consumers-here
      ifelse total-resource-req <= current-supply [
        ; Let everyone take what they want for this tick
        ask active-consumers-here [
          set resource-stock resource-stock + consumption-rate
        ]
        ; Deplete resource
        set current-supply current-supply - total-resource-req
      ] [
        ; If there is not enough for everyone to take their fill, have consumers split what's available and move on
        let split-supply current-supply / count active-consumers-here
        ask active-consumers-here [
          set resource-stock resource-stock + split-supply
          move-on
        ]
        ; Drain resource
        set current-supply 0
      ]
    ]
  ]
end 

; Consumer procedure for moving toward a previously-identified target resource, or identifying a new target resource

to move-on
  ifelse patch-here != [ patch-here ] of target-location [
    ifelse distance target-location <= 1 [
      ; If consumer is right next to the target, move to it
      let small-step (distance target-location)
      face target-location
      move-to target-location
      let this-link link [ who ] of location [ who ] of target-location
      ; Energy consumed is proportional to distance travelled
      set resource-stock ( resource-stock - ( metabolism * small-step ) )
    ] [
      ; If >1 unit of distance to go, keep moving toward target
      face target-location
      fd 1
      let this-link link [ who ] of location [ who ] of target-location
      set resource-stock ( resource-stock - metabolism )
    ]
  ] [
    ; If arrived, update current location to (old) target location
    set location target-location
    ; Identify new target and move toward it, if there are any to move toward
    if count [ link-neighbors ] of location > 0 [
      set target-location one-of [ link-neighbors ] of location
      face target-location
      fd 1
      set resource-stock (resource-stock - metabolism)
    ]
  ]
end 

; Observer procedure to identify resources below maximum capacity and have them regrow

to regrow-resource
  ask resources with [ current-supply < resource-capacity ] [
    ifelse current-supply + regrow-rate <= resource-capacity [
      ; Resources fill up by regrow-rate
      set current-supply current-supply + regrow-rate
    ] [
      ; Resources that are nearly at full capacity fill up to full capacity, but not beyond that
      set current-supply resource-capacity
    ]
  ]
end 

; Observer procedure to identify consumers who are able to spawn, and have them reproduce

to spawn-consumers
  ask consumers with [ resource-stock > ( spawn-energy * 2 ) ] [
    ; Spawn a new consumer, set initial resource stock to the amount it took to spawn
    hatch-consumers 1 [ set resource-stock spawn-energy ]
    ; Deplete parent's resource stock by the amount it took to spawn
    set resource-stock resource-stock - spawn-energy
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                         ;
;             Setup functions             ;
;                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Observer procedure to read in a file that contains resource node-specific attributes,
; including an unique identification number, and creates the resources

to import-node-attributes
  let i 1
  file-open nodes-file
  ; Skip headers
  let headers csv:from-row file-read-line
  ; Data should be in this order: network-id xcor ycor node-id
  ; Network-id stores the subnetwork to which the node belongs - not currently used
  ; Node-id is just an incremented index
  while [not file-at-end?]
  [
    let items csv:from-row file-read-line
    create-resources 1 [
      set subnet-id item 0 items
      set xcor item 1 items
      set ycor item 2 items
      set node-id item 3 items
      set shape "square"
      set color yellow
      set resource-capacity random max-resource-capacity
      set regrow-rate random max-resource-regrow-rate
      set current-supply resource-capacity
    ]
  ]
  file-close
end 

; Observer procedure to read in a file that contains all the links.
; The first column contains the node-id of the resource originating the link.
; The second column is the node-id of the resource on the other end of the link.
; Links are not directed currently, so it doesn't make a difference which node is on which end.

to import-links
  file-open links-file
  let headers csv:from-row file-read-line
  while [not file-at-end?]
  [
    let items csv:from-row file-read-line
    ask get-node (item 0 items)
    [
      create-link-with get-node (item 1 items)
    ]
  ]
  file-close
end 

;; Helper procedure for looking up a node by node-id.

to-report get-node [id]
  report one-of resources with [node-id = id]
end 

; Observer procedure to create consumers

to make-consumers
  create-consumers n-consumers [
    set color red
    set shape "bug"
    set active? true
    set resource-requirement consumer-resource-requirement
    set resource-stock initial-resource-owned
    set metabolism consumer-metabolism
    set consumption-rate consumer-consumption-rate
    set spawn-energy consumer-spawn-energy
    set location one-of resources
    set target-location location
    move-to location
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                         ;
;       Data collection reporters         ;
;                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Report mean resource supply across consumers - for plotting and data collection

to-report mean-consumer-resource-stock
  ifelse count consumers with [ active? = true ] > 0 [
    report mean [ resource-stock ] of consumers with [ active? = true ]
  ] [
    report 0
  ]
end 

; Report standard deviation of resource supply across consumers - for plotting and data collection

to-report sd-consumer-resource-stock
  ifelse count consumers with [ active? = true ] > 3 [
    report standard-deviation [ resource-stock ] of consumers with [ active? = true ]
  ] [
    report "NA"
  ]
end 

; Report Gini coefficient of resource supply across consumers - for plotting and data collection
;; Adapted from Wilensky, U. (1998). NetLogo Wealth Distribution model.

to-report gini-consumer-resource-stock
  let active-consumers count consumers with [ active? = true ]
  let sorted-res-stocks sort [ resource-stock ] of consumers with [ active? = true ]
  let total-res-stock sum sorted-res-stocks
  let res-stock-sum-so-far 0
  let index 0
  let gini-index-sum 0

  ; Calculate the Gini index
  repeat active-consumers [
    set res-stock-sum-so-far (res-stock-sum-so-far + item index sorted-res-stocks)
    set index (index + 1)
    set gini-index-sum
      gini-index-sum +
      (index / active-consumers) -
      (res-stock-sum-so-far / total-res-stock)
  ]
  report (gini-index-sum / active-consumers / 0.5)
end 

; Report count of active (alive) consumers - for plotting and data collection

to-report count-active-consumers
  report (count consumers with [ active? = true ])
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                         ;
;           Recording functions           ;
;                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Observer procedure to record model's initial state - writes file headers and consumer data.
; NOTE: This subroutine will delete an existing file with the same name! If you are running the code locally,
; be sure to use different seeds to save the files with unique names if you don't want them to be overwritten.

to record-initial-consumer-state
  let consumer-output-file-bspace ""
  ifelse empty? behaviorspace-experiment-name [
    set consumer-output-file-bspace (word "x-1-" this-seed "_consumerdata.csv")
  ] [
    set consumer-output-file-bspace (word "x-" behaviorspace-experiment-name "_" this-seed "_" behaviorspace-run-number "_consumerdata.csv")
  ]
  if file-exists? consumer-output-file-bspace [
    file-delete consumer-output-file-bspace
  ]
  file-open consumer-output-file-bspace
  file-print "ticks,consumer,is-active,x,y,resource-stock"
  ask consumers [
    file-print (word ticks "," who "," active? "," xcor "," ycor "," resource-stock)
  ]
  file-close
end 

; Observer procedure to record model's initial state - writes file headers and resource data.
; NOTE: This subroutine will delete an existing file with the same name! If you are running the code locally,
; be sure to use different seeds to save the files with unique names if you don't want them to be overwritten.

to record-initial-resource-state
  let resource-output-file-bspace ""
  ifelse empty? behaviorspace-experiment-name [
    set resource-output-file-bspace (word "x-1-" this-seed "_resourcedata.csv")
  ] [
    set resource-output-file-bspace (word "x-" behaviorspace-experiment-name "_" this-seed "_" behaviorspace-run-number "_resourcedata.csv")
  ]
  if file-exists? resource-output-file-bspace [
    file-delete resource-output-file-bspace
  ]
  file-open resource-output-file-bspace
  file-print "ticks,resource,xcor,ycor,current-supply,resource-capacity,regrow-rate"
  ask resources [
    file-print (word ticks "," who "," xcor "," ycor "," current-supply "," resource-capacity "," regrow-rate)
  ]
  file-close
end 

; Observer procedure to record consumer location, status, and resource stock.

to write-consumer-state
  let consumer-output-file-bspace ""
  ifelse empty? behaviorspace-experiment-name [
    set consumer-output-file-bspace (word "x-1-" this-seed "_consumerdata.csv")
  ] [
    set consumer-output-file-bspace (word "x-" behaviorspace-experiment-name "_" this-seed "_" behaviorspace-run-number "_consumerdata.csv")
  ]
  file-open consumer-output-file-bspace
  ask consumers [
    file-print (word ticks "," who "," active? "," xcor "," ycor "," resource-stock)
  ]
  file-close
end 

; Observer procedure to record resource location, current supply, maximum supply, and regrowth rate

to write-resource-state
  let resource-output-file-bspace ""
  ifelse empty? behaviorspace-experiment-name [
    set resource-output-file-bspace (word "x-1-" this-seed "_resourcedata.csv")
  ] [
    set resource-output-file-bspace (word "x-" behaviorspace-experiment-name "_" this-seed "_" behaviorspace-run-number "_resourcedata.csv")
  ]
  file-open resource-output-file-bspace
  ask resources [
    file-print (word ticks "," who "," xcor "," ycor "," current-supply "," resource-capacity "," regrow-rate)
  ]
  file-close
end 

There are 3 versions of this model.

Uploaded by When Description Download
Natalie Davis over 3 years ago Added GPL 3 license Download this version
Natalie Davis over 3 years ago Updated comments and cleaned up code Download this version
Natalie Davis about 4 years ago Initial upload Download this version

Attached files

File Type Description Last updated
Soil network simulation.png preview Preview image showing consumers (red bugs) on resources (yellow squares) over 3 years ago, by Natalie Davis Download

This model does not have any ancestors.

This model does not have any descendants.