Migration-Land Systems Model

No preview image

3 collaborators

Default-person Rekha Warrier (Author)
Default-person Jonathan Salerno (Author)
Randy Boone (Author)

Tags

migration 

Tagged by Rekha Warrier about 1 year ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 6.1.1 • Viewed 83 times • Downloaded 8 times • Run 0 times
Download the 'Migration-Land Systems Model' 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

extensions [ profiler ]

globals [
  middle-edge    ; Two cell wide split between regions
  month year
  annual-rainfall-site-1  monthly-rainfall-site-1
  annual-rainfall-site-2  monthly-rainfall-site-2
  annual-rain-site1-drought annual-rain-site1-low annual-rain-site1-high



  enviro-function  social-function  landowned-function  ownland-function  conflict-function
  enviro-value-1   social-value-1   landowned-value-1   ownland-value-1   conflict-value-1
  enviro-value-2   social-value-2   landowned-value-2   ownland-value-2   conflict-value-2
  enviro-value-3   social-value-3   landowned-value-3   ownland-value-3   conflict-value-3

  enviro-list    social-list    landowned-list    ownland-list    conflict-list                       ; Lists from 0 to 100
  temp-list
  temp-score
  upper-bio   elev-mean  long-dist-moves-total        ;;REKHA EDITS                                                      ; Used in standardizing the environmental index

  comfort-threshold
  migration-tracker tick-max-mig tick-50-mig
]

patches-own [ elev soil-color soil-hue monthly-greenness  annual-biomass  current-biomass  biomass-per-cell  site-1? site-2?                                  ; Site 1 and 2 could be set with a single binary, but this will be clearer.
  is-land? owned? core-conflict? near-conflict? conflict-score temp? temp-count ]
breed [ people person ]
breed [ temp a-temp ]

people-own [ local-move-count distant-move-count social-network
  own-land       ; Own-land is now a score of 1, 2 or 3, for low, medium, or high
  area-1? area-2? origin dist_move        ;;;REKHA EDITS
  env-x  social-x  landowned-x  ownland-x  conflict-x
  env-y  social-y  landowned-y  ownland-y  conflict-y
  comfort-score  contentedness-index offtake temp-content conf-loc site-awareness

  current-score
  best-local-score  best-local-x  best-local-y
  best-distant-score  best-distant-x  best-distant-y
]

to setup
  clear-all
  setup-parms
  setup-landscape
  set annual-rain-site1-drought [400 420 380 350 310 305 280 350 380 405 410 425]
  set annual-rain-site1-low [197 231 208 199 198 247 230 250 224 228 249 224]
  set annual-rain-site1-high [646 585 574 537 624 635 634 604 580 578 626 618]
  get-annual-rainfall
  get-monthly-rainfall
  draw-production
  setup-people
  setup-parcels
  setup-conflict
  restore-defaults
  update-display
  test-to-hide-folks
  set migration-tracker []
  profiler:start
  reset-ticks
end 

to go
  ; Each tick is one month ...
  test-to-hide-folks
  manage-time

  if month = 1 [ get-annual-rainfall ]                                ; Also clears current-biomass (and so biomass-per-cell by extension)
  get-monthly-rainfall
  draw-production

  ; ENVIRONMENT score needs standardized, but the target is changing each month.  I'm going to use mean + 2 * standard deviation as the upper limit for 100%
  ; That way, the score will be able to be near 100% regardless of the month
  let bio-mean mean [ current-biomass ] of patches with [ is-land? = TRUE ]
  let bio-sd standard-deviation [ current-biomass ] of patches with [ is-land? = TRUE ]
  set upper-bio  bio-mean + ( 2 * bio-sd )

  ask people [                        ; Everyone decides whether or not to move each month, and they can move back and forth as they wish (although frequent movements would suggest things are out of balance)
    set dist_move 0 ;; REKHA EDITS
    ; First, current location
    feed-livestock

    get-independent-vars xcor ycor    ; Get the x-axis values.  Some will need scaled.
    get-dependent-vars                ; Get the y-axis values.
    get-score
    set current-score temp-score

    ; Second, the local locations
    repeat 3 [                                                         ; REKHA EDITS Site-awarenes replaced with 3
      let x 0 let y 0 set best-local-score -999999
      ifelse area-1? = TRUE [
        ask one-of patches with [ site-1? = TRUE ] [                       ; NOTE sites match
          set x pxcor
          set y pycor
        ]
      ]
      [
        ask one-of patches with [ site-2? = TRUE ] [
          set x pxcor
          set y pycor
        ]
      ]
      get-independent-vars x y          ; Get the x-axis values.  Some will need scaled.
      get-dependent-vars                ; Get the y-axis values.
      get-score
      if temp-score > best-local-score [
        set best-local-score temp-score
        set best-local-x x
        set best-local-y y
      ]
    ]
    ; Third, the distant location
    repeat Site-awareness [
      let x 0 let y 0 set best-distant-score -999999
      ifelse area-1? = TRUE [
        ask one-of patches with [ site-2? = TRUE ] [                        ; NOTE sites don't match
          set x pxcor
          set y pycor
        ]
      ]
      [
        ask one-of patches with [ site-1? = TRUE ] [
          set x pxcor
          set y pycor
        ]
      ]
      get-independent-vars x y          ; Get the x-axis values.  Some will need scaled.
      get-dependent-vars                ; Get the y-axis values.
      get-score
      if temp-score > best-distant-score [
        set best-distant-score temp-score
        set best-distant-x x
        set best-distant-y y
      ]
    ]
    migrate-decision                  ; The main integration procedure.

  ]
  let temp-mig count people with [origin = 1 and distant-move-count > 0]
  set  migration-tracker lput temp-mig migration-tracker
  if year = 11 [stop]

  tick
  calc-summary
;  profiler:stop
;  print profiler:report
;  stop
end 

to calc-summary
  let tot-mig  map [i -> i + 1] migration-tracker
  let tot-mig-enh lput (last tot-mig) tot-mig
  set tot-mig-enh remove-item 0 tot-mig-enh
  let temp-rate (map [[i j] ->  (j - i) / (last tot-mig)] tot-mig tot-mig-enh)
  let max-rate max temp-rate
  set tick-max-mig position max-rate temp-rate + 1
  let temp-mig-prop map [i ->  i / (last tot-mig)] tot-mig
  let temp-50 map [i -> (i - 0.6)] temp-mig-prop
  let low []
  foreach temp-50 [x -> ifelse x < 0 [set low lput 1 low] [set low lput x low]]
  set tick-50-mig position (min low) low
end 

to feed-livestock
  ; Calculate offtake.  Assuming each cell is 250 m on a side.
  set offtake  Herd-size * ( ( ( 250 * 0.025 ) * 30 ) * 1000 )                       ; Herd x 250 kg x 2.5% per day x 30 days x kg to g
  let per-cell-offtake  offtake / 113                                                ; NOTE HARDWIRED VALUE THAT EQUALS IN-RADIUS 6.

  ; Going to try just removing biomass, and if the livestock don't get enough, that is ok, those animals will go hungry.
  ; IN-RADIUS 6 yields 113 patches.  That is a large area - we'll try that.
  ask patches in-radius 6 [
    set biomass-per-cell  biomass-per-cell - per-cell-offtake
    if biomass-per-cell < 0 [ set biomass-per-cell 0 ]
    set current-biomass  biomass-per-cell / ( 250 * 250 )
  ]
end 

to get-score
  set comfort-score ( enviro-weight * env-y ) + ( social-weight * social-y ) + ( landowned-weight * landowned-y ) + ( ownland-weight * ownland-y ) + ( conflict-weight * conflict-y)
  set temp-score comfort-score
  if Debug? = TRUE [
    output-type who  output-type "   In area 1?  " output-type area-1?   output-type "   In area 2?  " output-type area-2?
    output-type "    Comfort Score:  " output-type precision comfort-score 1  output-type "   Contentedness:  "  output-type precision contentedness-index 1  output-type "                 Env-Y: " output-type precision env-y 2 output-type "  Social-Y: " output-type precision social-y 2 output-type "  Land Owned-Y: " output-type precision landowned-y 2 output-type "  Own Land-Y: " output-type precision ownland-y 2  output-type "  Conflict-Y: " output-print precision conflict-y 2
  ]
end 

to migrate-decision
  ; SET THE MAXIMUM COMFORT SCORE to be able to calculate the deviation from the maximum score, to be incorporated into the contentedness score.
  ; set comfort-score     =      ( enviro-weight * env-y ) + ( social-weight * social-y ) + ( landowned-weight * landowned-y ) + ( ownland-weight * ownland-y ) + ( conflict-weight * conflict-y)
  let max-score ( enviro-weight * 100 ) + ( social-weight * 100 ) + ( landowned-weight * 100 ) + ( ownland-weight * 100 ) + ( conflict-weight * 100 )
  ; Return the comfort score and x and y values to the local (current) position.  These may change, but comfort-score is used and is only relevant locally, so it needs to be updated.
  get-independent-vars xcor ycor
  get-dependent-vars
  get-score
  if comfort-score <  comfort-threshold [
    set contentedness-index  contentedness-index - ( max-score - comfort-score )
    set temp-content contentedness-index
;    type "CONTENTED:   " type "          CONTENTEDNESS INDEX " type contentedness-index  type "Comfort threshold:  " type Comfort-threshold   type "           MAX SCORE " type max-score type "     COMFORT SCORE "  print comfort-score
  ]

  ; People in great spots don't move, but their contentedness indices can plumet FAR below zero (e.g., -10,000).
  ; There should be some chance that people will move when they are in nice locations but have contentedness indices less than 0.
  if contentedness-index <= 0 [
    ; MAY NOT MOVE if scores are not adequately high
    ifelse ( best-local-score > ( current-score + Short-migration-threshold ) ) or ( random-float 1.0 < 0.1 )
    [  ; Move locally, within the site in question
      setxy best-local-x best-local-y
      right random 360
      forward 0.5
      set contentedness-index ( Contentedness-reset-multiplier * max-score )
      set local-move-count local-move-count + 1
      set size size + 0.2
    ]
    [
      if ( best-distant-score > ( current-score + Long-migration-threshold ) ) ;   NO ... DON'T FORCE LONG-DISTANCE MIGRATION REGARDLESS OF CONTENTEDNESS-INDEX or ( random-float 1.0 < 0.05 )
      [
        setxy best-distant-x best-distant-y
        right random 360
        forward 0.5
        set area-1?  not area-1?
        set area-2?  not area-2?
        set contentedness-index ( Contentedness-reset-multiplier * max-score )
        set distant-move-count distant-move-count + 1
        set size size + 0.2
        set dist_move 1
      ]
    ]
  ]
  ; Update the X and Y values.  The values are updated as movements are considered, and so can be out of balance relative to the current location.  This isn't required, but will help align values stored with the local site.
;  type "CONTENTED:     CONFLICT  " type conflict-y type "          CONTENTEDNESS INDEX " type contentedness-index type "           MAX SCORE " type max-score type "     COMFORT SCORE "  print comfort-score
  get-independent-vars xcor ycor
  get-dependent-vars
  get-score
end 

to get-independent-vars [ x y ]
  let ex 0  let l 0  let c 0

  ask patch x y [
    ; set ex monthly-greenness * 0.3921
    set ex ( current-biomass / upper-bio ) * 100.0
    if ex > 100 [ set ex 100 ]
    ifelse x < middle-edge
    [ set l Land-owned-site-1 ]
    [ set l Land-owned-site-2 ]
    set c conflict-score
  ]

  set env-x ex
  set social-x  social-network
  set landowned-x l
  if own-land = 1 [ set ownland-x 20 ]
  if own-land = 2 [ set ownland-x 50 ]
  if own-land = 3 [ set ownland-x 80 ]
  set conflict-x c
end 

to get-dependent-vars
  set env-y item int ( env-x ) enviro-list
  set social-y item int ( social-x ) social-list
  set conflict-y item int ( conflict-x ) conflict-list
  set landowned-y item int ( landowned-x ) landowned-list
  set ownland-y item int ( ownland-x ) ownland-list

  if Debug? [
    type "Xs  Person: " type who type "   Env: " type precision env-x 2  type "   Social: " type precision social-x 2 type "   Landowned: " type landowned-x
    type "   Own land: " type ownland-x type "   Conflict: " print conflict-x
    type "Ys  Person: " type who type "   Env: " type precision env-y 2  type "   Social: " type precision social-y 2 type "   Landowned: " type landowned-y
    type "   Own land: " type ownland-y type "   Conflict: " print conflict-y
    print " "
  ]
end 

to-report alint [ var x ]
  ; NOTE...NOTE: Assuming linear connections between individual points in the curves
  let x1 floor x
  let y1 item x1 var
  let x2 ceiling x
  let y2 item x2 var
  let x-remain x - x1                         ; Get remainder.  It will aways be a fractional measure given that x2 - x1 is always 1.
  let y y1 + ( ( y2 - y1 ) * x-remain )
  report y
end 

to draw-production
  let per-meter  250 * 250
  ask patches with [ is-land? = TRUE ] [
    let c biomass-per-cell / per-meter
    set pcolor scale-color green c 0 600
  ]
end 

to manage-time
  set month month + 1
  if month = 13 [
    set month 1
    set year year + 1
  ]
end 

to get-annual-rainfall
  ; Making use of Deshmukh (2008) A common relationship between precipitation and grassland peak biomass for East and Southern Africa.  Af. Journal of Ecology 22:181-186.

  set annual-rainfall-site-1 random-normal Average-precipitation-Site-1 Precipitation-CV-Site-1
  ;set annual-rainfall-site-1 item year annual-rain-site1-drought ;; REKHA EDITS
  if annual-rainfall-site-1 < 100 [
    set annual-rainfall-site-1 100          ; Or set a higher minimum value? ... YES, setting a higher amount
  ]
  ifelse Use-the-same-climate-for-both-sites? = FALSE
  [
    set annual-rainfall-site-2 random-normal Average-precipitation-Site-2 Precipitation-CV-Site-2
    if annual-rainfall-site-2 < 100 [
      set annual-rainfall-site-2 100          ; Or set a higher minimum value?
    ]
  ]
  [
    set annual-rainfall-site-2 annual-rainfall-site-1
  ]

  ask patches with [ is-land? = TRUE ] [
    set current-biomass 0                                                               ; Biomass is not held over between years.
    ; MODIFYING ANNUAL BIOMASS to incorporate the spatial texture.  Using ELEV for that.  This will  include a hardwired stretch value
    if site-1? = TRUE [
      set annual-biomass ( 8.4888 * annual-rainfall-site-1 - 195.768 ) / 10.0             ; Divide 10 to convert to g / m2  from kg / ha
    ]
    if site-2? = TRUE [
      set annual-biomass ( 8.4888 * annual-rainfall-site-2 - 195.768 ) / 10.0             ; Divide 10 to convert to g / m2  from kg / ha
    ]
    let modifier  elev / elev-mean * 1.0
    set annual-biomass  annual-biomass * modifier
  ]
end 

to get-monthly-rainfall
  ; Brute force to determine seasonality.  Coefficients should sum to 1.0
  if month = 1  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.05 ]
  if month = 2  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.06 ]
  if month = 3  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.10 ]
  if month = 4  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.18 ]
  if month = 5  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.15 ]
  if month = 6  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.08 ]
  if month = 7  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.01 ]
  if month = 8  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.02 ]
  if month = 9  [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.05 ]
  if month = 10 [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.10 ]
  if month = 11 [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.12 ]
  if month = 12 [ set monthly-rainfall-site-1 annual-rainfall-site-1 * 0.08 ]

  if month = 1  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.05 ]
  if month = 2  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.06 ]
  if month = 3  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.10 ]
  if month = 4  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.18 ]
  if month = 5  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.15 ]
  if month = 6  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.08 ]
  if month = 7  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.01 ]
  if month = 8  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.02 ]
  if month = 9  [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.05 ]
  if month = 10 [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.10 ]
  if month = 11 [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.12 ]
  if month = 12 [ set monthly-rainfall-site-2 annual-rainfall-site-2 * 0.08 ]

  ask patches with [ is-land? = TRUE ] [
    if month = 1  [ set current-biomass  current-biomass + ( annual-biomass * 0.05 ) ]
    if month = 2  [ set current-biomass  current-biomass + ( annual-biomass * 0.06 ) ]
    if month = 3  [ set current-biomass  current-biomass + ( annual-biomass * 0.10 ) ]
    if month = 4  [ set current-biomass  current-biomass + ( annual-biomass * 0.18 ) ]
    if month = 5  [ set current-biomass  current-biomass + ( annual-biomass * 0.15 ) ]
    if month = 6  [ set current-biomass  current-biomass + ( annual-biomass * 0.08 ) ]
    if month = 7  [ set current-biomass  current-biomass + ( annual-biomass * 0.01 ) ]
    if month = 8  [ set current-biomass  current-biomass + ( annual-biomass * 0.02 ) ]
    if month = 9  [ set current-biomass  current-biomass + ( annual-biomass * 0.05 ) ]
    if month = 10 [ set current-biomass  current-biomass + ( annual-biomass * 0.10 ) ]
    if month = 11 [ set current-biomass  current-biomass + ( annual-biomass * 0.12 ) ]
    if month = 12 [ set current-biomass  current-biomass + ( annual-biomass * 0.08 ) ]

    set biomass-per-cell current-biomass * 250 * 250                             ; Assuming cells 250 m on a side.  NOTE THE USE OF AN EXPLICIT SCALE
  ]
end 

to update-display
  if Display-layer = "Soils" [
    paint-landscape
  ]
  if Display-layer = "Owned lands" [
    ask patches with [ owned? ] [
      set pcolor hsb ( soil-color * 0.50 + 20 ) 70 99
    ]
  ]
  if Display-layer = "Conflict zones" [
    ask patches with [ conflict-score > 0 ] [
      ; set pcolor hsb ( soil-color * 0.50 + 20 ) 70 ( 100 - conflict-score )
      set pcolor hsb 0 70 conflict-score
    ]
  ]
  if Display-layer = "Production" [
    ask patches with [ is-land? = TRUE ] [
      set pcolor scale-color green current-biomass 0 600
    ]
  ]
end 

to test-to-hide-folks
  ifelse Hide-people?
  [ ask people [ set hidden? TRUE ] ]
  [ ask people [ set hidden? FALSE ] ]

  ask people [ set label "" ]
  if Show-local-moves? = TRUE
  [
    set Show-distant-moves? FALSE
    ask people [ set label local-move-count ]
  ]

  if Show-distant-moves? = TRUE
  [
    set Show-local-moves? FALSE
    ask people [ set label distant-move-count ]
  ]
end 

to setup-people
  let S1 (Percent-of-people-in-Site-1 / 100) * 1000
  let max-score ( enviro-weight * 100 ) + ( social-weight * 100 ) + ( landowned-weight * 100 ) + ( ownland-weight * 100 ) + ( conflict-weight * 100 )
  set comfort-threshold ( max-score * Comfort-threshold-multiplier )
  create-people S1 [              ; Can be made a variable
    set shape "circle"
    set size 2
    set origin 1
    setxy random-xcor random-ycor
    while [ site-1? = FALSE ] [
      setxy random-xcor random-ycor
    ]
    set social-network random-normal social-network-mean social-network-sd
    if social-network < 0.0 [ set social-network 0.0 ]
    if social-network > 100.0 [ set social-network 100.0 ]
    set site-awareness  random-normal site-awareness-mean site-awareness-sd
    if site-awareness < 0.0 [ set site-awareness 1]
    set color red + ( random 4 - 2)
    set local-move-count 0
    set distant-move-count 0
    set own-land 0                        ; This is reset on a population basis below
    set area-1? TRUE
    set area-2? FALSE
    set contentedness-index ( Contentedness-reset-multiplier * max-score )
  ]
  create-people 1000 - S1 [              ; Can be made a variable
    set shape "circle"
    set size 2
    set origin 2
    setxy random-xcor random-ycor
    while [ site-2? = FALSE ] [
      setxy random-xcor random-ycor
    ]
    set social-network random-normal social-network-mean social-network-sd
    if social-network < 0.0 [ set social-network 0.0 ]
    if social-network > 100.0 [ set social-network 100.0 ]
    set color blue + ( random 4 - 2)
    set local-move-count 0
    set distant-move-count 0
    set own-land 0                         ; This is reset on a population basis below
    set area-1? FALSE
    set area-2? TRUE
    set contentedness-index ( Contentedness-reset-multiplier * max-score )
  ]
  let c int ( S1 * ( Percent-owning-land-site-1 / 100.0 ) )
  ask n-of c people with [ area-1? = TRUE ] [
    set own-land one-of [ 1 2 3 ]
  ]
  set c int ( (1000 - S1 ) * ( Percent-owning-land-site-2 / 100.0 ) )
  ask n-of c people with [ area-2? = TRUE ] [
    set own-land one-of [ 1 2 3 ]
  ]
end 

to setup-conflict           ; Making this specific to location just for simplicity using a brute-force approach.
  if Core-area-in-conflict-site-1 > 0 [
    ask patches [
      set core-conflict? FALSE
      set temp? FALSE
      set conflict-score 0
    ]
    let core-cnt 0
    let core-target ( Core-area-in-conflict-site-1 / 100.0 ) * count patches with [ site-1? = TRUE ]
    create-temp 1 [
      setxy 290 100          ; START ON THE SITE-2 SO THAT TEMP? GETS SET BELOW.  Important.
      while [ site-1? = FALSE ] [
        setxy random-xcor random-ycor
        set temp? TRUE
        ask neighbors with [ site-1? = TRUE ] [ set temp? TRUE ]
      ]
    ]
    while [ core-cnt < core-target ] [                                      ; Note that this limit is approximate.  A few more cells may be owned than the math indicates
      ; Refresh the edges every 20 times edges expand
      ask patches with [ site-1? = TRUE and core-conflict? = TRUE ] [
        let temp-cnt count neighbors with [ core-conflict? = FALSE ]
        ifelse temp-cnt > 0
        [ set temp? TRUE ]
        [ set temp? FALSE ]
      ]

      repeat 20 [
        if any? patches with [ temp? = TRUE ] [
          ask one-of patches with [ temp? = TRUE ] [
            set temp? FALSE
            set pcolor red
            ask neighbors with [ core-conflict? = FALSE and site-1? = TRUE ] [                 ; Painting all neighbors, so may exceed limit, but not by too much.
              set core-conflict? TRUE
              set temp? TRUE
              set pcolor red
            ]
          ]
        ]
      ]
      set core-cnt count patches with [ core-conflict? = TRUE and site-1? = TRUE]
    ]
    ask patches with [ core-conflict? ] [ set conflict-score 100 ]
    ask temp [ die ]

    do-ring 100
    do-ring 90
    do-ring 80
    do-ring 70
    do-ring 60
    do-ring 50
    do-ring 40
    do-ring 30
    do-ring 20
    do-ring 10
  ]

  if Core-area-in-conflict-site-2 > 0 [
    let core-cnt 0
    let core-target ( Core-area-in-conflict-site-2 / 100.0 ) * count patches with [ site-2? = TRUE ]
    create-temp 1 [
      setxy 10 100          ; START ON THE SITE-1 SO THAT TEMP? GETS SET BELOW.  Important.
      while [ site-2? = FALSE ] [
        setxy random-xcor random-ycor
        set temp? TRUE
        ask neighbors with [ site-2? = TRUE ] [ set temp? TRUE ]
      ]
    ]
    while [ core-cnt < core-target ] [                                      ; Note that this limit is approximate.  A few more cells may be owned than the math indicates
      ; Refresh the edges every 20 times edges expand
      ask patches with [ site-2? = TRUE and core-conflict? = TRUE ] [
        let temp-cnt count neighbors with [ core-conflict? = FALSE ]
        ifelse temp-cnt > 0
        [ set temp? TRUE ]
        [ set temp? FALSE ]
      ]

      repeat 20 [
        if any? patches with [ temp? = TRUE ] [
          ask one-of patches with [ temp? = TRUE ] [
            set temp? FALSE
            set pcolor red
            ask neighbors with [ core-conflict? = FALSE and site-2? = TRUE ] [                 ; Painting all neighbors, so may exceed limit, but not by too much.
              set core-conflict? TRUE
              set temp? TRUE
              set pcolor red
            ]
          ]
        ]
      ]
      set core-cnt count patches with [ core-conflict? = TRUE and site-2? = TRUE]
    ]
    ask patches with [ core-conflict? ] [ set conflict-score 100 ]
    ask temp [ die ]

    do-ring 100
    do-ring 90
    do-ring 80
    do-ring 70
    do-ring 60
    do-ring 50
    do-ring 40
    do-ring 30
    do-ring 20
    do-ring 10
  ]
end 

to do-ring  [ v ]
  let v2 v - 10
  ask patches with [ conflict-score = v and sum [ conflict-score ] of neighbors < ( v * 8 ) ] [
    ask neighbors with [ conflict-score < v and is-land? ] [
      set conflict-score v2
      set pcolor v - 5
    ]
  ]
  repeat 2 [
    ask patches with [ conflict-score = v2 and sum [ conflict-score ] of neighbors < ( v2 * 8 ) ] [
      ask neighbors with [ conflict-score = 0 and is-land? ] [
        set conflict-score v2
        set pcolor v - 5
      ]
    ]
  ]
end 

to setup-landscape
  ; Set some initial conditions and values
  set middle-edge 150
  ask patches [
    set site-1? FALSE
    set site-2? FALSE
    ifelse pxcor >= middle-edge and pxcor <= middle-edge + 1
    [
      set pcolor white
      set is-land? FALSE
    ]
    [ set is-land? TRUE ]
    if pxcor < middle-edge [ set site-1? TRUE  set site-2? FALSE]
    if pxcor > ( middle-edge + 1 ) [ set site-1? FALSE  set site-2? TRUE]
    set owned? FALSE
    set temp? FALSE
  ]
  let n-bumps 0
  let meander 3
  let bumpiness 96

  ask patches with [ is-land? = TRUE ] [
    set elev 150
  ]

  ; Now add small texture to the landscape
  set n-bumps int ( sqrt ( world-width * world-height ) * ( bumpiness * 0.004 ) )
  ask n-of n-bumps patches with [ is-land? ] [
    let bump-size 1 + max-pxcor * 0.001 * ( random-float bumpiness )
    ask patches in-radius bump-size [
      set elev elev + ( bump-size - ( distance myself ) )
    ]
  ]

  ; Standarize elevation to be between 0 and 1, just for each of analyses
  let emin min [ elev ] of patches
  let emax max [ elev ] of patches
  ask patches with [ is-land? ] [
    set elev  ( elev - emin ) / ( emax - emin )
  ]

  ; Calculate soil-color, now that the DEM is complete.  Aim for drier yellow soils in the east, and darker richer soils in the west
  ask patches with [ is-land? ] [
    let xer  ( ( world-width -  pxcor ) + int ( world-width / 2 ) ) / world-width            ; Standardize the X position to a value between 0 and 1
    ; Add soil-color related to topography, but trimmed to 0 to 1
    set soil-color  ( ( xer * 1.5 ) + elev ) / 2.5
  ]

  ; Standarize AGAIN soil-color to be between 0 and 100, to make painting and modeling straightforward
  set emin min [ soil-color ] of patches
  set emax max [ soil-color ] of patches
  ask patches with [ is-land? ] [
    set soil-color 100 - ( int ( ( soil-color - emin ) / ( emax - emin ) * 100.0 ) )
  ]

  paint-landscape

  ; Save the RGB of the patches.  NOTE that the HSB complexity is not relevant once colors are assigned to soil.
  ask patches with [ is-land? ] [
    let temp-hsb extract-hsb pcolor
    set soil-hue item 0 temp-hsb
  ]

  set elev-mean mean [ elev ] of patches with [ is-land? = TRUE ]
end 

to paint-landscape
  ask patches with [ is-land? ] [
    set pcolor hsb ( soil-color * 0.50 + 20 ) 70 70
  ]
end 

to setup-parcels
  ; Do calculations to set limits to grow to and numbers of owners to grow.  NOTE that people can live on owned land and not be designated initial owners.
  let num-owning-land  ( count people with [ area-1? = TRUE ] ) * ( Percent-owning-land-site-1 / 100.0 )
  ask n-of num-owning-land people with [ area-1? = TRUE ] [
    set owned? TRUE                      ; Patch
  ]
  ; Initialize the patches occupied by owners as yellow and owned.
  ask patches with [ owned? = TRUE and site-1? = TRUE ] [
    set pcolor yellow
    ask neighbors with [ site-1? = TRUE ] [ set temp? TRUE ]
  ]
  let total-patches-owned  count patches with [ site-1? = TRUE ] * ( Land-owned-site-1 / 100.0 )    ; The limit to which to grown
  let own 0

  while [ own < total-patches-owned ] [                                      ; Note that this limit is approximate.  A few more cells may be owned than the math indicates
    ; Refresh the edges every 50 times edges expand
    ask patches with [ site-1? = TRUE and owned? = TRUE ] [
      set temp-count count neighbors with [ owned? = FALSE and site-1? = TRUE ]
      ifelse temp-count > 0
      [ set temp? TRUE ]
      [ set temp? FALSE ]
    ]

    repeat 50 [
      ask one-of patches with [ temp? = TRUE ] [
        set temp? FALSE
        set pcolor yellow
        ask neighbors with [ owned? = FALSE and site-1? = TRUE ] [                 ; Painting all neighbors, so may exceed limit, but not by too much.
          set owned? TRUE
          set temp? TRUE
          set pcolor yellow
        ]
      ]
    ]
    set own count patches with [ site-1? = TRUE and owned? = TRUE ]
  ]

  ;********************************************************************************************************
  ; Do calculations to set limits to grow to and numbers of owners to grow.  NOTE that people can live on owned land and not be designated initial owners.
  set num-owning-land  ( count people with [ area-2? = TRUE ] ) * ( Percent-owning-land-site-2 / 100.0 )
  ask n-of num-owning-land people with [ area-2? = TRUE ] [
    set owned? TRUE                      ; Patch
  ]
  ; Initialize the patches occupied by owners as yellow and owned.
  ask patches with [ owned? = TRUE and site-2? = TRUE ] [
    set pcolor yellow
    ask neighbors with [ site-2? = TRUE ] [ set temp? TRUE ]
  ]
  set total-patches-owned  count patches with [ site-2? = TRUE ] * ( Land-owned-site-2 / 100.0 )    ; The limit to which to grown
  set own 0

  while [ own < total-patches-owned ] [                                      ; Note that this limit is approximate.  A few more cells may be owned than the math indicates
    ; Refresh the edges every 50 times edges expand
    ask patches with [ site-2? = TRUE and owned? = TRUE ] [
      set temp-count count neighbors with [ owned? = FALSE and site-2? = TRUE ]
      ifelse temp-count > 0
      [ set temp? TRUE ]
      [ set temp? FALSE ]
    ]

    repeat 50 [
      ask one-of patches with [ temp? = TRUE ] [
        set temp? FALSE
        set pcolor yellow
        ask neighbors with [ owned? = FALSE and site-2? = TRUE ] [                 ; Painting all neighbors, so may exceed limit, but not by too much.
          set owned? TRUE
          set temp? TRUE
          set pcolor yellow
        ]
      ]
    ]
    set own count patches with [ site-2? = TRUE and owned? = TRUE ]
  ]

  ; Paint the final image of owned lands
  paint-landscape
  ask patches with [ owned? ] [
    set pcolor hsb ( soil-color * 0.50 + 20 ) 70 99
  ]
end 

to setup-parms
  set enviro-list []
  set social-list []
  set landowned-list []
  set ownland-list []
  set conflict-list []

  set temp-list []
end 

to restore-defaults
  set-current-plot "Coefficients-1"
  clear-plot
  set-current-plot-pen "Environment"
  set enviro-function  "Sigmoid"   set enviro-value-1 0  set enviro-value-2 0  set enviro-value-3 0           ; Values aer not used
  plot-coefficient enviro-function enviro-value-1 enviro-value-2 enviro-value-3
  set enviro-list temp-list
  set-current-plot-pen "Conflict"
  set conflict-function  "Asymptotic"   set conflict-value-1 100.0  set conflict-value-2 0.04  set conflict-value-3 0             ; Note asymptote is higher than end result.
  plot-coefficient conflict-function conflict-value-1 conflict-value-2 conflict-value-3
  set conflict-list temp-list
  set-current-plot-pen "LandOwned"
  set landowned-function  "Linear"   set landowned-value-1 100  set landowned-value-2 -1.0  set landowned-value-3 0
  plot-coefficient landowned-function landowned-value-1 landowned-value-2 landowned-value-3
  set landowned-list temp-list
  set-current-plot "Coefficients-2"
  clear-plot
  set-current-plot-pen "Social"
  set social-function  "Sigmoid"   set social-value-1 0  set social-value-2 0  set social-value-3 0           ; Values aer not used
  plot-coefficient social-function social-value-1 social-value-2 social-value-3
  set social-list temp-list
  set-current-plot-pen "OwnLand"
  let x 0
  set temp-list []
  while [ x < 33 ] [ set temp-list lput Low-owned-land temp-list  set x x + 1 ]
  while [ x < 67 ] [ set temp-list lput Mid-owned-land temp-list  set x x + 1 ]
  while [ x < 100 ] [ set temp-list lput High-owned-land temp-list  set x x + 1 ]
  set ownland-list temp-list
  set x 0
  while [ x < 100 ] [
    let y item x ownland-list
    plotxy  x  y
    set x x + 1
  ]

  set Focal-relationship "Environment"
  set Function-family enviro-function
  set Value-1 enviro-value-1
  set Value-2 enviro-value-2
  set Value-3 enviro-value-3
end 

to plot-coefficient   [ c v1 v2 v3 ]
  let x -5.0
  let y 0
  set temp-list []
  if c = "Sigmoid" [
    while [ x < 5.0 ] [
      set y ( 1 / ( 1 + exp ( -1 * x ) ) * 100 )
      let tx int ( x * 10 + 50 )
      plotxy tx y
      set temp-list lput y temp-list
      set x x + 0.1
    ]
  ]                                                      ; Confirmed 101 entries in temp-list for SIGMOID, as needed, 0 to 100.
  set x 1
  let d 1 ; v2 - v3                                          ; Shift the curve to the left or right to match the X intercept requested.  Also need to add it to the X loop
  if c = "Asymptotic" [
    while [ x <= ( 100 + d ) ] [
    ;  set y -1 * ( v1 * ( v2 - x ) ) / x                ; V2 shapes the line, x3 is x intercept, x1 is asymptote
    ; REPLACING THIS WITH A DECAYING FUNCTION
      set y v1 * ( 1 - v2 ) ^ x
      let tx x - d
      if y >= 0  [
        set temp-list lput y temp-list
        plotxy  tx  y
      ]
      set x x + 1
    ]
  ]                                                       ; Confirmed 101 entries in temp-list for Asymptotic, as needed
  set x 0
  set y 0
  if c = "Linear" [
    while [ x <= 100.0 ] [
      set y v1 + v2 * x
      set temp-list lput y temp-list
      plotxy x y
      set x x + 1
    ]
  ]                                                        ; Confirmed 101 entries in temp-list for Asymptotic, as needed
  set x -10
  set y 0
  if c = "Quadratic" [
    while [ x < 10.0 ] [
      set y ( v1 * x * x ) + v2 * x + v3
;      type x type "  " print y
      let tx ( x + 10 ) * 5
      set temp-list lput y temp-list
      plotxy tx y
      set x x + 0.2
    ]
  ]                                                         ; Confirmed 101 entries in temp-list for Asymptotic, as needed
end 

to update-function
  if Focal-relationship = "Environment" [
    set-current-plot "Coefficients-1"
    clear-plot
    set-current-plot-pen "Environment"
    set enviro-function  Function-family   set enviro-value-1 Value-1  set enviro-value-2 Value-2  set enviro-value-3 Value-3
    plot-coefficient enviro-function enviro-value-1 enviro-value-2 enviro-value-3
    set enviro-list temp-list
    ; Plot the remaining entries.  No need to recalculate, use existing lists
    set-current-plot-pen "Conflict"     one-plot conflict-list
    set-current-plot-pen "Availland"    one-plot landowned-list
  ]
  if Focal-relationship = "Conflict" [
    set-current-plot "Coefficients-1"
    clear-plot
    set-current-plot-pen "Conflict"
    set conflict-function  Function-family   set conflict-value-1 Value-1  set conflict-value-2 Value-2  set conflict-value-3 Value-3
    plot-coefficient conflict-function conflict-value-1 conflict-value-2 conflict-value-3
    set conflict-list temp-list
    ; Plot the remaining entries.  No need to recalculate, use existing lists
    set-current-plot-pen "Environment"     one-plot enviro-list
    set-current-plot-pen "Availland"    one-plot landowned-list
  ]
  if Focal-relationship = "Available Land" [
    set-current-plot "Coefficients-1"
    clear-plot
    set-current-plot-pen "Available land"
    set landowned-function  Function-family   set landowned-value-1 Value-1  set landowned-value-2 Value-2  set landowned-value-3 Value-3
    plot-coefficient landowned-function landowned-value-1 landowned-value-2 landowned-value-3
    set landowned-list temp-list
    ; Plot the remaining entries.  No need to recalculate, use existing lists
    set-current-plot-pen "Conflict"     one-plot conflict-list
    set-current-plot-pen "Environment"    one-plot enviro-list
  ]

  if Focal-relationship = "Environment" [
    set-current-plot "Coefficients-2"
    clear-plot
    set-current-plot-pen "Social"
    set enviro-function  Function-family   set enviro-value-1 Value-1  set enviro-value-2 Value-2  set enviro-value-3 Value-3           ; Values aer not used
    plot-coefficient enviro-function enviro-value-1 enviro-value-2 enviro-value-3
    set enviro-list temp-list
    ; Plot the remaining entries.  No need to recalculate, use existing lists
    set-current-plot-pen "Ownland"     one-plot conflict-list
  ]
  if Focal-relationship = "Owning land" [
    set-current-plot "Coefficients-2"
    clear-plot
    set-current-plot-pen "Ownland"
    set ownland-function  Function-family   set ownland-value-1 Value-1  set ownland-value-2 Value-2  set ownland-value-3 Value-3           ; Values aer not used
    plot-coefficient ownland-function ownland-value-1 ownland-value-2 ownland-value-3
    set ownland-list temp-list
    ; Plot the remaining entries.  No need to recalculate, use existing lists
    set-current-plot-pen "Social"     one-plot social-list
  ]
end 

to one-plot [ lst ]
  let i 0
  while [ i <= 100 ] [
    let y item i lst
    plotxy i y
    set i i + 1
  ]
end 

to show-values
  if Focal-relationship = "Environment"    [ set Function-family enviro-function     set Value-1 enviro-value-1   set Value-2 enviro-value-2   set Value-3 enviro-value-3 ]
  if Focal-relationship = "Social network" [ set Function-family social-function     set Value-1 social-value-1   set Value-2 social-value-2   set Value-3 social-value-3 ]
  if Focal-relationship = "Conflict"       [ set Function-family conflict-function   set Value-1 conflict-value-1   set Value-2 conflict-value-2   set Value-3 conflict-value-3 ]
  if Focal-relationship = "Available land" [ set Function-family landowned-function  set Value-1 landowned-value-1   set Value-2 landowned-value-2   set Value-3 landowned-value-3 ]
  if Focal-relationship = "Owning land"    [ set Function-family ownland-function    set Value-1 ownland-value-1   set Value-2 ownland-value-2   set Value-3 ownland-value-3 ]
end 

to force-2-to-1
  set Average-precipitation-site-2 Average-precipitation-site-1
  set Precipitation-CV-site-2 Precipitation-CV-site-1
  set Land-owned-site-2 Land-owned-site-1
  set Percent-owning-land-site-2 Percent-owning-land-site-1
  set Core-area-in-conflict-site-2 Core-area-in-conflict-site-1
end 

to restore-slider-defaults
  set Precipitation-CV-site-2  30
  set Long-migration-threshold  17
  set Percent-owning-land-site-2  20
  set Show-local-moves?  false
  set Social-network-mean  24
  set Display-layer  "Conflict zones"
  set Show-distant-moves?  false
  set LandOwned-weight  1
  set High-owned-land  10
  set Percent-of-people-in-Site-1  50
  set Debug?  false
  set Average-precipitation-site-1  230
  set Land-owned-site-1  10
  set Average-precipitation-site-2  400
  set Social-weight  1
  set Focal-relationship  "Environment"
  set Herd-size  20
  set Comfort-threshold-multiplier  0.39
  set Conflict-weight  1
  set Enviro-weight  1
  set Social-network-sd  22
  set Low-owned-land  10
  set Short-migration-threshold  10
  set Ownland-weight  1
  set Core-area-in-conflict-site-1  3
  set Contentedness-reset-multiplier  3.0
  set Core-area-in-conflict-site-2  3
  set Function-family  "Sigmoid"
  set Mid-owned-land  90
  set Site-awareness-mean  3
  set Site-awareness-sd 0
  set Value-1  0
  set Hide-people?  false
  set Value-2  0
  set Use-the-same-climate-for-both-sites?  false
  set Value-3  0
  set Precipitation-CV-site-1  30
  set Percent-owning-land-site-1  20
  set Land-owned-site-2  25
end 

There is only one version of this model, created about 1 year ago by Rekha Warrier.

Attached files

No files

This model does not have any ancestors.

This model does not have any descendants.