Relocation 18-22

Relocation 18-22 preview image

1 collaborator

Default-person Artem Serdyuk (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.4.0 • Viewed 23 times • Downloaded 0 times • Run 0 times
Download the 'Relocation 18-22' modelDownload this modelEmbed this model

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


Relocation 18-22 Model Documentation

WHAT IS IT?

This model simulates war-induced migration patterns and refugee return decisions during and after armed conflict. It examines how civilians make relocation decisions under stress, integrating multiple theoretical frameworks from psychology and migration studies to understand forced displacement and voluntary return migration.

The model specifically investigates: - Push and pull factors driving initial displacement from conflict zones - The role of stress appraisal in triggering migration decisions - Refugee adaptation processes in host cities - Conditions that promote or inhibit return migration after conflict - The impact of migration policies and border controls on population movements - Demographic-specific restrictions (particularly affecting males aged 18-22)

HOW IT WORKS

Theoretical Foundation

The model is grounded in three major psychological stress theories:

  1. Lazarus & Folkman's Transactional Stress Theory: Agents perform primary appraisal (evaluating threats from bombing, conscription, economic hardship) and secondary appraisal (assessing coping resources including economic state, social networks, and movement options).

  2. Hobfoll's Conservation of Resources (COR) Theory: Migration decisions are driven by actual or threatened resource loss, including:

    • Material resources (economic state, property damage)
    • Condition resources (safety, employment, freedom of movement)
    • Personal resources (adaptation capacity, stress tolerance)
    • Social resources (family and friend networks)
  3. Prospect Theory: Decision-making under uncertainty with loss aversion, where losses weigh more heavily than equivalent gains in triggering migration.

Agent Decision-Making Process

Phase 1: Stress Accumulation - Acute stressors: Direct bombing (weight: 3.7), severe personal damage (3.3), family/friend evacuation (4.2) - Chronic stressors: Perceived unsafety (5.8), poor economic conditions, social isolation - Conscription stress for military-age males - Exit restriction stress for demographically restricted groups

Phase 2: Migration Evaluation When combined stress factors exceed individual thresholds, agents evaluate potential destinations using weighted factors: - Safety expectations (0.83) - Economic expectations (0.22) - Social expectations (0.33) - Distance penalty (0.14)

Phase 3: Border Crossing - Legal crossing attempts based on border-control-strictness parameter - Illegal crossing attempts when stress > 90 and legal crossing fails - Successful illegal crossing creates additional vulnerabilities

Phase 4: Refugee Adaptation Once relocated, refugees undergo adaptation processes: - Nostalgia depreciation (homesickness decreases over time) - Job-seeking behavior based on city economic conditions - Social network rebuilding - Adaptation rate influenced by employment and social integration

Phase 5: Return Migration Evaluation Using prospect theory framework with empirically-derived weights: - Safety expectations for return (0.37) - Economic expectations (0.40) - Social expectations (0.00) - Home restoration expectations (0.16)

City-Level Dynamics

Cities have varying: - War exposure levels (1-3 scale) - Economic conditions and recovery rates - Damage accumulation from bombing - Post-war reconstruction capabilities - Refugee support infrastructure

HOW TO USE IT

Setup Parameters

Population Settings: - number-of-citizens: Initial population size (100-5000) - friends-and-family: Average social network size per agent

War Intensity Controls: - war-start-day: Day when conflict begins (0-1095) - war-end-day: Day when conflict ends (365-1460) - hostilities: War severity level (0=none, 1=moderate, 2=severe)

Migration Policy Controls: - border-control-strictness: Percentage chance of denying legal border crossing (0-100%) - migration-restrictions-enabled?: Toggle demographic-specific exit restrictions - restricted-genders: Select which gender faces restrictions ("male", "female", or "both") - min-restricted-age / max-restricted-age: Age range for restrictions (typically 18-60)

Economic Support Parameters: - refugee-monthly-allowance: Monthly support for refugees during war - post-war-refugee-allowance: Continued support after war ends - pay-for-return: Financial incentive for return migration - post-war-return-payment: One-time payment for returnees - rebuild-percentage: City reconstruction investment level

Output Monitors

Population Tracking: - Citizens remaining in each city - Total refugee population - Illegal crossing attempts and successes - Return migration rates

Stress Indicators: - Mean stress levels by demographic - Conscription stress for military-age males - Exit restriction stress for restricted groups

Demographic Distributions: - Age pyramids for origin and destination cities - Gender-specific migration patterns - Working-age population changes

THINGS TO NOTICE

  1. Threshold Effects: Migration often occurs in waves when bombing intensity crosses critical stress thresholds for population clusters.

  2. Demographic Selectivity: Young males (18-22) face unique pressures from both conscription risk and potential exit restrictions, creating distinct migration patterns.

  3. Resource Spirals: Following COR theory, initial resource losses can trigger cascading effects—damaged economic state reduces coping capacity, increasing vulnerability to future stressors.

  4. Network Effects: Social connections serve as both anchoring factors (keeping people in place) and migration facilitators (following evacuated friends/family).

  5. Adaptation Paradox: Well-adapted refugees with employment show lower return rates even after conflict ends, while poorly adapted refugees may lack resources to return.

  6. Border Policy Impacts: Strict border controls don't stop migration but shift it toward dangerous illegal crossings when stress is extreme.

THINGS TO TRY

  1. Vary Border Strictness: Compare population distributions with strictness at 0%, 50%, and 100%. Notice how illegal crossings compensate for legal restrictions.

  2. Test Demographic Restrictions: Enable restrictions for males 18-22 and observe:

    • Gender imbalance in destination cities
    • Increased illegal crossing attempts
    • Family separation patterns
  3. Economic Incentives: Experiment with different combinations of:

    • High refugee allowance + low return payment
    • Low refugee allowance + high return payment
    • Observe effects on return migration timing
  4. War Duration: Compare short intense conflicts (6 months, severity 2) with prolonged moderate conflicts (2 years, severity 1). Which produces more permanent displacement?

  5. Reconstruction Investment: Test how rebuild-percentage affects return migration. Is there a threshold where return accelerates?

  6. Social Network Size: Vary friends-and-family from 2 to 20. How do dense vs. sparse networks affect migration clustering?

EXTENDING THE MODEL

Suggested Enhancements

  1. Multi-Country Destinations: Add choice between multiple safe countries with varying economic opportunities and cultural distance.

  2. Information Dynamics: Model how information about destination conditions spreads through networks, affecting migration decisions.

  3. Traumatic Stress: Implement PTSD-like effects where severe bombing exposure creates lasting impacts on stress recovery.

  4. Family Units: Model household-level decisions where families migrate together or separate based on restrictions.

  5. Economic Sectors: Differentiate employment opportunities by skill level, affecting refugee job-finding success.

  6. Seasonal Effects: Add weather/seasonal factors affecting migration timing and route difficulty.

  7. International Aid: Model NGO assistance varying by city and time, affecting both refugee support and reconstruction.

  8. Return Obstacles: Add property rights issues, unexploded ordnance, or infrastructure damage affecting return feasibility.

NETLOGO FEATURES

The model employs several sophisticated NetLogo techniques:

  1. Mixture Distributions: Uses Gaussian mixture models to create realistic age distributions matching demographic data.

  2. Weighted Random Selection: Implements roulette-wheel selection for destination choice based on utility scores.

  3. Dynamic Agentsets: Maintains 40 age-gender population bins updated annually for demographic tracking.

  4. Network Visualization: Link connections show social networks with thickness representing relationship strength.

  5. Cooldown Mechanisms: Prevents unrealistic rapid re-migration using timer variables.

  6. Caching Optimization: Pre-calculates city maximum values for economic and damage scores to speed normalization.

  7. Behavioral State Machines: Agents transition through states (resident → considering move → refugee → considering return) with specific transition rules.

RELATED MODELS

NetLogo Models Library: - Segregation: Explores Schelling's model of spatial sorting - Rebellion: Models population uprising against authority - Wealth Distribution: Examines economic inequality dynamics

Migration Models: - Epstein's Agent-Based Computational Model of Civil Violence - Kniveton's Climate Change Migration ABM - SimMig: Simulation of Migration Dynamics

Stress and Coping Models: - COPE: Computational model of emotion regulation - Trauma Recovery ABM

CREDITS AND REFERENCES

Model Development

Model developed by Artem Serdyuk, Sociology Department at National University of Kyiv-Mohyla Academy (a.serdiuk@ukma.edu.ua, artem.serdyuk@gmail.com, https://orcid.org/0000-0002-0060-1311) for studying war-induced displacement and return migration patterns, with particular focus on demographic-specific restrictions and their impacts on population dynamics. Relocation 18-22 © 2025 by Artem Serdyuk is licensed under CC BY 4.0

Theoretical Foundations

Stress and Coping: - Lazarus, R. S., & Folkman, S. (1984). Stress, Appraisal, and Coping. New York: Springer. - Hobfoll, S. E. (1989). Conservation of resources: A new attempt at conceptualizing stress. American Psychologist, 44(3), 513-524. - Hobfoll, S. E. (2001). The influence of culture, community, and the nested-self in the stress process. Applied Psychology, 50(3), 337-421.

Migration and Displacement: - Kahneman, D., & Tversky, A. (1979). Prospect theory: An analysis of decision under risk. Econometrica, 47(2), 263-291. - Kunz, E. F. (1973). The refugee in flight: Kinetic models and forms of displacement. International Migration Review, 7(2), 125-146. - Czaika, M., & Kis-Katos, K. (2009). Civil conflict and displacement: Village-level determinants of forced migration in Aceh. Journal of Peace Research, 46(3), 399-418.

Demographic Data Source: - Population Pyramid. (2025). Ukraine demographic structure. https://www.populationpyramid.net/ukraine/2025/

Implementation Notes

  • Built in NetLogo 6.4.0
  • Simulation time unit: 1 tick = 1 day
  • Spatial scale: Abstract representation of cities and distances
  • Empirical weights derived from refugee survey data

Comments and Questions

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

Click to Run Model

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MODEL DESCRIPTION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Model of war-induced migration patterns examining push/pull factors for refugee decisions
; Based on Lazarus stress theory, prospect theory, and social support networks

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GLOBAL VARIABLES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
globals [
  ;; War and environment parameters
  war-intensity        ; Intensity scaling factor for war
  hostilities          ; War severity (0=none, 1=moderate, 2=severe)
  support-others       ; Whether agents can support each other
  max-damage-seen      ; Maximum damage for color scaling
  frontline-color      ; For frontline visualization
  recent-timeframe     ; Window for tracking recent changes (7 days)
  war-ended?           ; Flag to indicate if war has ended

  ;; Decision weights for relocation evaluation
  economic-expectations-weight     ; Weight for economic expectations (default 0.22)
  social-expectations-weight       ; Weight for social expectations (default 0.33)
  distance-penalty-weight          ; Weight for distance penalty (default 0.14)
  safety-over-economy              ; Safety weight (default 0.83)

  ;; Border control and migration policy
  ;border-control-strictness    ; 0-100% scale for border strictness
  illegal-crossing-threshold   ; Stress level required for illegal crossing attempts
  illegal-crossings-attempted ; Counter for tracking
  illegal-crossings-succeeded ; Counter for tracking

  ;; Migration restriction policy
  ;migration-restrictions-enabled?  ; Whether restrictions are active
  ;restricted-genders              ; List of restricted genders ["male"] or ["female"] or ["male" "female"]
  ;min-restricted-age             ; Minimum age for restriction
  ;max-restricted-age             ; Maximum age for restriction

  ;; Decision weights for return migration
  safety-expectations-return-weight        ; Weight for safety expectations on return
  social-expectations-return-weight        ; Weight for social expectations on return
  economic-expectations-return-weight      ; Weight for economic expectations on return
  restoration-expectations-return-weight   ; Weight for home restoration expectations

  ;; Normalization reference values
  max-economic-score   ; Cache maximum economic score across cities
  max-damage-score     ; Cache maximum damage score across cities

 rebuild-percentage
 refugee-monthly-allowance
 post-war-refugee-allowance
 pay-for-return
 post-war-return-payment

  ;; Men by age bins (20 lists for ages 0-4, 5-9, ..., 95-99)
  men-0-4 men-5-9 men-10-14 men-15-19 men-20-24 men-25-29 men-30-34 men-35-39 men-40-44 men-45-49
  men-50-54 men-55-59 men-60-64 men-65-69 men-70-74 men-75-79 men-80-84 men-85-89 men-90-94 men-95-100

  ;; Women by age bins (20 lists for ages 0-4, 5-9, ..., 95-99)
  women-0-4 women-5-9 women-10-14 women-15-19 women-20-24 women-25-29 women-30-34 women-35-39 women-40-44 women-45-49
  women-50-54 women-55-59 women-60-64 women-65-69 women-70-74 women-75-79 women-80-84 women-85-89 women-90-94 women-95-100
]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; AGENT BREEDS AND PROPERTIES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
breed [home-cities home-city]
breed [citizens citizen]
breed [refugees refugee]

home-cities-own [
  ;; War and recovery characteristics
  city-war-exposure    ; Proximity to conflict (1=far, 2=close, 3=combat)
  city-recovery-rate   ; Recovery capability (1=weak, 2=medium, 3=strong)

  ;; Physical damage and recovery
  damage               ; Current damage from warfare
  recovery             ; Current recovery amount
  rebuilt-percentage   ; Percent of city rebuilt

  ;; Economic and safety metrics
  city-damage-score    ; Cumulative damage for safety calculations
  city-economic-score  ; Total economic capacity (facilities + citizen wealth)
  city-facilities      ; Infrastructure state
  initial-facilities   ; Starting value for sensitivity analysis

  ;; Population tracking
  refugees-back        ; Number of returned refugees

  male-pop-distribution     ; List of male population counts by age bin
  female-pop-distribution   ; List of female population counts by age bin
  male-stress-distribution  ; List of average male stress levels by age bin
  female-stress-distribution ; List of average female stress levels by age bin

]

citizens-own [
  ;; Demographics
  gender              ; "male" or "female"
  age                 ; Age in years, progresses with time

  ;; City affiliations
  city-of-origin      ; Original home city
  current-city        ; Current residence city

  ;; Recovery capabilities
  economic-recovery-rate    ; Economic growth rate (~15% annually)
  sensitivity-to-trauma     ; Impact of traumatic events

  ;; Current states
  economic-state      ; Financial resources
  safety-state        ; Perceived safety
  stress-level        ; Accumulated stressors
  conscription-stress ; Stress specifically from conscription fears
  exit-restriction-stress ; NEW: Stress from inability to migrate when restricted

  ;; Trauma tracking
  bombing-days        ; Consecutive days of bombing
  last-damage         ; Most recent damage amount
  considering-move?   ; Whether evaluating relocation

  ;; Personal thresholds
  acceptable-stress-level
  acceptable-safety-state
  acceptable-economic-state
  acceptable-social-isolation
  acceptable-others-economic-state
  acceptable-home-restoration
  movement-threshold  ; Threshold for decision to move
  relocation-cooldown    ;; Minimum days before next relocation

  ;; Refugee adaptation
  nostalgia-level         ; Homesickness (100-0)
  days-since-relocation   ; Time as refugee
  adaptation-rate         ; Speed of adaptation (-0.1 to 0.1)
  current-adaptation      ; Total adaptation (-100 to 100)
  last-move-tick          ; Time of last move
  has-job?                ; Whether refugee has found a job
  base-salary             ; Refugee's salary
  considering-return?     ; Whether considering return to home

  ;; Border crossing and restrictions
  illegal-attempt-cooldown ; Days before can attempt illegal crossing again
  illegally-crossed?  ; Flag if citizen crossed illegally
]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MODEL SETUP PROCEDURES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Initialize the model

to setup
  clear-all

  ;; Set default model parameters
  set recent-timeframe 7    ; Default tracking window for recent changes
  set war-intensity 1
  set support-others true
  set max-damage-seen 1     ; Initialize damage scaling
  set war-ended? false

 set rebuild-percentage 50
 set refugee-monthly-allowance 30
 set post-war-refugee-allowance 10
 set pay-for-return 0
 set post-war-return-payment 100

  ;; Decision weights for migration
  set economic-expectations-weight 0.22
  set social-expectations-weight 0.33
  set distance-penalty-weight 0.14
  set safety-over-economy 0.83

  ;; Decision weights for return migration
  set safety-expectations-return-weight 0.37
  set economic-expectations-return-weight 0.4
  set social-expectations-return-weight 0
  set restoration-expectations-return-weight 0.16

  ;; Border control settings
  ;;set border-control-strictness 50  ; Default 50% strictness
  set illegal-crossing-threshold 90  ; High stress required
  set illegal-crossings-attempted 0
  set illegal-crossings-succeeded 0

  ;; Migration restriction policy defaults
  ;set migration-restrictions-enabled? false
  ;set restricted-genders ["male"]  ; Default: restrict males
  ;set min-restricted-age 18
  ;set max-restricted-age 60

  initialize-age-bins-empty

  ;; Create city grid and populate with citizens
  setup-cities
  create-citizens-for-cities
  draw-frontline

  reset-ticks
end 

;; Initialize city grid with varying war exposure and recovery rates

to setup-cities
  let max-exposure 2  ; Changed from 3 to 2
  let max-recovery 2  ; Changed from 3 to 2

  ;; Calculate grid spacing for 2x2 - make it more sparse
  let x-spacing (max-pxcor - min-pxcor) / (max-exposure * 0.5)  ; Changed from (max-exposure - 1)
  let y-spacing (max-pycor - min-pycor) / (max-recovery * 0.5)   ; Changed from (max-recovery - 1)

  clear-turtles

  ;; Create 2x2 grid of cities
  foreach range max-exposure [ i ->
    foreach range max-recovery [ j ->
       create-home-cities 1 [
        setxy (min-pxcor + i * x-spacing)
              (min-pycor + j * y-spacing)

        ;; Binary war exposure: 0=safe, 1=war-exposed
        set city-war-exposure i
        set city-recovery-rate (j + 1)

        set shape "circle"
        set color white
        set size 2

        set city-economic-score 0
        set city-damage-score 0
        set city-facilities number-of-citizens * (50 + random 50)
        set initial-facilities city-facilities
        set rebuilt-percentage 0
        set refugees-back 0
      ]
    ]
  ]
end 

;; Create initial population with social networks

to create-citizens-for-cities
  ask home-cities [
    let this-city self

    ;; Create citizens with random initial properties
    hatch-citizens number-of-citizens [
      set label ""
      set city-of-origin this-city
      set current-city this-city
      set shape "person"
      set size 1
      set color red
      right random 360
      forward random 10
      initiate-citizen this-city
    ]
  ]
end 

;; Initialize citizen with random but sensible starting values

to initiate-citizen[city]

  ;; Visual distinction for restricted demographics
  ifelse is-restricted-demographic? [set shape "person business"]  ; Different shape for restricted
  [set shape "person"]          ; Default shape for non-restricted

   ;; Demographics
  set gender one-of ["male" "female"]
  set age realisticaly-distributed-age gender

  ;; Economic state follows normal distribution around 300
  set economic-state max list 0 min list 500 (random-normal 300 200)

  ;; Initial wellbeing inversely related to war exposure
  set stress-level min list 100 (random (30 * ([city-war-exposure] of current-city - 1)))
  set safety-state max list 0 (100 - random (30 * ([city-war-exposure] of current-city - 1)))
  set conscription-stress 0 ;; Conscription stress
  set exit-restriction-stress 0 ;; NEW: Initialize exit restriction stress

  ;; Set recovery capabilities
  set economic-recovery-rate random-float 0.0003   ; ~15% annual growth
  set sensitivity-to-trauma random-float 0.2

  ;; Set personal thresholds
  set acceptable-safety-state max list 1 (10 + random 10)
  set acceptable-economic-state max list 1 (50 - random 10)
  set acceptable-others-economic-state max list 1 (30 - random 10)
  set acceptable-social-isolation max list 1 (random 100 - 50)
  set acceptable-home-restoration 25 + random 40
  set movement-threshold max list 1 (random-normal 8 3) * (1 + economic-state / 500) * (1 + ((count link-neighbors) / friends-and-family))

  ;; Border crossing
  set illegally-crossed? false

  ;; Initialize cooldown
  set relocation-cooldown 0
  set illegal-attempt-cooldown 0

  ;; Initialize adaptation variables
  set adaptation-rate 0
  set current-adaptation 0

  ;; Reset tracking variables
  set bombing-days 0
  set last-damage 0
  set last-move-tick 0
  set days-since-relocation 0
  set has-job? false
  set base-salary 0
  set considering-move? false
  set considering-return? false

  ;; Create social network if enough citizens present
  if count citizens with [current-city = city] > friends-and-family [
    create-links-with n-of (max list 1 (random friends-and-family)) other citizens with [current-city = city]
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MAIN SIMULATION PROCEDURES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Main simulation loop

to go
  ;; Age progression (once per year)
  if ticks mod 365 = 0 [
    ask citizens [set age age + 1]
    populate-age-bins
  ]

  ;; Update war intensity if war is ongoing
  if not war-ended? [
    if (ticks mod recent-timeframe = 0) [set hostilities round (1 + sin (ticks * 3)) * war-intensity]
    draw-frontline
  ]

  ;; Cache maximum scores used in normalization
  set max-economic-score max [city-economic-score] of home-cities
  set max-damage-score max [city-damage-score] of home-cities

  ;; Process each city and update refugee states
  ask home-cities
  [
    impact-city
    update-city-distributions self
  ]
  update-refugee-state

  ask citizens [
    accumulate-chronic-stress
    update-stress-visualization
    if relocation-cooldown > 0 [set relocation-cooldown relocation-cooldown - 1] ;; Reduce relocation cooldown
    if illegal-attempt-cooldown > 0 [set illegal-attempt-cooldown illegal-attempt-cooldown - 1]  ;; Reduce illegal attempts cooldown
  ]

  tick
end 

;; Apply war effects to city and its citizens
;; Apply war effects to city and its citizens with proper war-ended handling

to impact-city
  let current-citizens count(citizens with [current-city = myself])

  ;; Check war status before calculating damage
  ifelse war-ended? [
    ;; No new damage during peacetime, only recovery
    set damage 0
    set recovery random (city-recovery-rate * 100 * current-citizens / number-of-citizens)
  ][
    ;; Normal wartime damage calculations
    set damage random (hostilities * city-war-exposure) * 100
    set recovery random (((9 - (hostilities * city-war-exposure)) * city-recovery-rate * 100 * current-citizens) / number-of-citizens)
  ]

  let impact damage - recovery

  ;; Update city state
  set city-facilities city-facilities - impact
  set city-economic-score city-facilities + (sum [economic-state] of citizens with [current-city = myself])

  ;; Only accumulate damage during war
  if not war-ended? [
    set city-damage-score city-damage-score + damage
  ]

  ;; Update all citizens in the city
  ask citizens with [current-city = myself] [
    ;; Only traumatize during war
    ifelse not war-ended? [
      traumatize-citizen([damage] of current-city)
    ][
      ;; During peace, reset trauma indicators
      set bombing-days 0
      set last-damage 0
    ]

    recover-citizen

    if (support-others = true) [support-significant-others]
    ;; Only check acute triggers during war
    if not war-ended? and not considering-move? [check-acute-triggers]
    if considering-move? [migrate]
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; CITIZEN TRAUMA AND RECOVERY PROCEDURES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Apply trauma effects based on city damage and individual sensitivity

to traumatize-citizen [city-impact]
  ;; Skip trauma processing entirely if war has ended
  if war-ended? [stop]

  ;; Probability of trauma increases with war exposure and hostilities
  ifelse random ([city-war-exposure] of current-city * hostilities) > 0 [
    ;; Calculate personal economic damage
    let personal-damage random round(city-impact / 20)

    ;; Apply emotional and safety impacts based on trauma sensitivity
    set economic-state max list 0 (economic-state - personal-damage)
    set safety-state max list 0 (safety-state - (personal-damage * (1 + sensitivity-to-trauma)))
    set stress-level min list 100 (stress-level + (personal-damage * (1 + sensitivity-to-trauma) / 5) + random 10)
    ;; Track trauma for acute stress triggers
    set last-damage personal-damage
    set bombing-days bombing-days + 1
  ][
    set bombing-days 0
  ]
end 

;; Apply recovery processes when conditions allow

to recover-citizen
  ;; Recovery possible when hostilities and exposure are low enough
  if random (hostilities * [city-war-exposure] of current-city) < 3 [
    ;; Apply economic recovery (~15% annual growth)
    set economic-state economic-state * (1 + economic-recovery-rate)

    ;; Stress recovery
    set stress-level max list 0 (stress-level - random 3 * (1 - sensitivity-to-trauma))

    ;; Safety perception improves with economic recovery
    set safety-state min list 100 (safety-state + round(economic-state / 300))
  ]
end 

;; Calculate and apply chronic stress changes to citizens

to accumulate-chronic-stress
  ;; Variable to store the total stress change for this tick
  let total-stress-change 0

  ;; ===== COMMON STRESS FACTORS FOR ALL CITIZENS =====

  ;; Basic economic stress component - applies to everyone
  let economic-stress ifelse-value (economic-state < acceptable-economic-state)
    [(acceptable-economic-state - economic-state) / 200]
    [(acceptable-economic-state - economic-state) / 150]

  ;; Basic safety stress component - applies to everyone
  let safety-stress ifelse-value (safety-state < acceptable-safety-state)
    [(acceptable-safety-state - safety-state) / 100]
    [(acceptable-safety-state - safety-state) / 50]

  ;; Basic social network stress - applies to everyone
  let social-stress 0
  let friends-here count link-neighbors with [current-city = [current-city] of myself]
  let total-links count link-neighbors

  set social-stress ifelse-value (total-links > 0)
  [ifelse-value (friends-here / total-links * 100 < acceptable-social-isolation)
      [(acceptable-social-isolation - (friends-here / total-links * 100)) / 200]
      [(acceptable-social-isolation - (friends-here / total-links * 100)) / 100]
  ]
  [0.2]  ;; Having no social links causes moderate stress


  ;; Apply common factors to everyone
  set total-stress-change economic-stress + safety-stress + social-stress

  ;; ===== SPECIFIC STRESS FACTORS BASED ON LOCATION =====

  ifelse current-city = city-of-origin
  [
    ;; ===== ADDITIONAL FACTORS FOR THOSE WHO STAYED HOME =====

    ;; War environment stress dominates for those in war zones
    ;; War stress based on exposure level
    let war-environment-stress ifelse-value war-ended?[-0.5][0.7 + ([city-war-exposure] of current-city) * hostilities * 0.6]

    set total-stress-change total-stress-change + war-environment-stress
  ]
  [
    ;; ===== ADDITIONAL FACTORS FOR REFUGEES =====

    ;; Enhanced economic impact for refugees (additional to basic economic stress)
    ;; Use quotient instead of separate ifelse clauses
    let refugee-economic-factor ifelse-value (economic-state < acceptable-economic-state)
      [(acceptable-economic-state - economic-state) / 150][0]

    ;; Employment is critical for refugees only
    let employment-stress ifelse-value (has-job? = true) [-0.3][0.1]

    ;; Enhanced social impact for refugees using quotient approach
    let refugee-social-factor ifelse-value (total-links > 0 and (friends-here / total-links) < 0.3) [0.2][0]

    ;; Nostalgia impacts refugees only
    let nostalgia-stress nostalgia-level / 100

    ;; Adaptation has significant impact on refugees only
    let adaptation-stress (current-adaptation / -150)

    ;; Add refugee-specific factors to total
    set total-stress-change total-stress-change + refugee-economic-factor + refugee-social-factor + nostalgia-stress
    + adaptation-stress + employment-stress
  ]

  ;; Update conscription stress
  update-anticipation-anxiety
  update-exit-restriction-stress
  let cognitive-stress-contribution ((conscription-stress / 100) * 0.3) + ((exit-restriction-stress / 100) * 0.4)

  ;; Apply a small random variation
  let random-variation random-float 0.1 - 0.05

  ;; Update stress level (only bounded between 0 and 100)
  set stress-level min list 100 max list 0 (stress-level + total-stress-change + cognitive-stress-contribution + random-variation)
end 

;; Implement social support network assistance

to support-significant-others
  let my-economic-state economic-state

  ;; Only help network members in same city
  ifelse count link-neighbors with [current-city = [current-city] of myself] > 0 [
    ask link-neighbors with [current-city = [current-city] of myself][
      ;; Provide economic support if needed and able
      if (economic-state < acceptable-others-economic-state and (my-economic-state > acceptable-economic-state)) [
        let original-economic economic-state
        set my-economic-state round(my-economic-state * 0.9)
        set economic-state economic-state + round(my-economic-state * 0.1)
      ]
    ]
  ]
  [
    ;; observing suffering of important others without ability to help
    set stress-level min list 100 (stress-level + random 10)
  ]
  set economic-state my-economic-state
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; REFUGEE DECISION MAKING PROCEDURES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check for acute triggers that might cause relocation consideration

to check-acute-triggers
  ;; Skip if already considering move
  if considering-move? or relocation-cooldown > 0 [stop]

  ;; Initialize decision variables
  let triggered? false
  let trigger-reasons ""
  let combined-score 0

;; 1. Check bombing days trigger - "Exposure to Violence" category
  let bombing-ratio bombing-days / recent-timeframe
  ifelse bombing-days >= recent-timeframe [
    ;log-event who EVENT_BOMBING_TRIGGER (word "Bombing days: " bombing-days " | Threshold: " recent-timeframe)
    set triggered? true
    set trigger-reasons (word trigger-reasons "Sustained bombing (" bombing-days " days). ")
  ][
    if bombing-days > 0 [
      set trigger-reasons (word trigger-reasons "Bombing days: " bombing-days "/" recent-timeframe ". ")
      set combined-score combined-score + (bombing-ratio * 3.7)  ;; Weight adjusted based on "Exposure to Violence" importance
    ]
  ]

  ;; 2. Check damage threshold trigger - corresponds to "Loss" category
  let damage-threshold max list 1 (economic-state / 2)
  let damage-ratio last-damage / damage-threshold
  ifelse last-damage > damage-threshold [
    ;log-event who EVENT_DAMAGE_TRIGGER (word "Damage: " (precision last-damage 2) " | Threshold: " (precision damage-threshold 2))
    set triggered? true
    set trigger-reasons (word trigger-reasons "Severe damage (" (precision last-damage 2) " vs threshold " (precision damage-threshold 2) "). ")
  ][
    if last-damage > 0 [
      set trigger-reasons (word trigger-reasons "Damage: " (precision last-damage 2) "/" (precision damage-threshold 2) ". ")
      set combined-score combined-score + (damage-ratio * 3.3)  ;; Weight adjusted for "Loss" impact
    ]
  ]

  ;; 3. Check social network disruption trigger - relates to both "Loss" and "Negative Feelings"
  let total-links count link-neighbors
  if total-links > 0 [
    let social-threshold (total-links / 3)
    let recent-departed count link-neighbors with [
      current-city != [current-city] of myself and
      (ticks - last-move-tick) <= recent-timeframe
    ]
    let network-ratio recent-departed / social-threshold

    ifelse recent-departed >= social-threshold [
      ;log-event who EVENT_NETWORK_DISRUPTION (word "Friends departed: " recent-departed "/" total-links)
      set triggered? true
      set trigger-reasons (word trigger-reasons "Social network disruption (" recent-departed "/" total-links " friends left). ")
    ][
      if recent-departed > 0 [
        set trigger-reasons (word trigger-reasons "Friends departed: " recent-departed "/" social-threshold ". ")
        set combined-score combined-score + (network-ratio * 4.2)  ;; Weight increased for social factors from research
      ]
    ]
  ]

  ;; 4. Add safety concerns to combined score - "Negative Feelings" category
  if safety-state <= acceptable-safety-state [
    let safety-ratio (safety-state / acceptable-safety-state)
    set trigger-reasons (word trigger-reasons "Safety concern (" safety-state " approaching " acceptable-safety-state "). ")
    set combined-score combined-score + ((1 - safety-ratio) * 5.8)  ;; Weight increased for "Negative Feelings" impact
  ]

   ;; 5. Conscription anxiety effect: makes people more likely to flee
  if conscription-stress > 70 [set movement-threshold movement-threshold * 0.7]

  ;; 6. Exit restriction creates desperation
  if exit-restriction-stress > 60 and migration-restrictions-enabled?
  [
    ;; Desperation adds to stress (helps reach illegal crossing threshold)
    set combined-score min list 100 (combined-score + exit-restriction-stress * 0.3)
    ;; Also lowers movement threshold
    set movement-threshold movement-threshold * 0.6
  ]

  ;; 7. Check if combined triggers exceed threshold
  if not triggered? and combined-score >= movement-threshold [set triggered? true]

  ;; Set consideration flag if any trigger activated
  if triggered? [
    set considering-move? true
    set color orange
  ]
end 

;; Evaluate potential relocation based on prospect theory

to-report evaluate-relocation [target-city]

  ;; Apply randomness proportional to stress level
  let decision-noise random-float (stress-level / 50) - (stress-level / 100)

  ;; Calculate normalized scores for comparison
  let economic-score normalize-economic-score target-city
  let safety-score normalize-safety-score target-city
  let social-score normalize-social-score target-city

  ;; Get reference scores from current city
  let reference-economic-score normalize-economic-score current-city
  let reference-safety-score normalize-safety-score current-city
  let reference-social-score normalize-social-score current-city

  ;; Calculate expected changes with explicit calibration weights

  ;; Economic expectations with cost and weight
  let economic-expectations (economic-score - reference-economic-score) * economic-expectations-weight

  ;; Safety expectations with safety-over-economy weight
  let safety-expectations (safety-score - reference-safety-score) * safety-over-economy

  ;; Social expectations with weight
  let social-expectations (social-score - reference-social-score) * social-expectations-weight

  ;; Apply distance penalty with explicit weight
  let distance-penalty distance (target-city) * distance-penalty-weight

  ;; Return total expected value
  report economic-expectations + safety-expectations + social-expectations - distance-penalty + decision-noise
end 

;; Simplified migrate procedure that excludes current city

to migrate
  if considering-move?
  [
   let leaving-war-zone? ([city-war-exposure] of current-city = 1) ;; Check if trying to leave war-exposed city

    ifelse leaving-war-zone?
    [
      ;; Check exit barriers
      ifelse has-exit-permission? [proceed-with-legal-migration]        ;; Proceed with normal legal migration
      [
        ;; Consider illegal crossing if stress is high enough
        if (stress-level >= illegal-crossing-threshold and illegal-attempt-cooldown = 0) [attempt-illegal-crossing]
        ;; If no illegal attempt, stay and increase stress
        set stress-level min list 100 (stress-level + 10)
        set considering-move? false
        set color red
      ]
    ]
    [proceed-with-legal-migration]   ;; Normal migration within safe zones
  ]
end 

;; Execute relocation to new city

to leave-for-city[city]
  if (current-city != city) [
    ;; Use the same cost calculation as in migrate (with a discount due to extraordinary circumstances)
    let relocation-cost (distance city * 0.2)

    ;; Physical relocation
    move-to city
    set current-city city
    set color yellow
    right random 360
    forward random 3

      ;; Add logging after the move is complete
    ;log-event who EVENT_RELOCATION (word "From: " [who] of city-of-origin
     ;                            " To: " [who] of current-city
      ;                           " | Economic: " (precision economic-state 2))
                                 ;" | Nostalgia: " (precision nostalgia-level 2))


    ;; Apply economic and emotional impacts of moving
    set economic-state max list 0 (economic-state - relocation-cost) * 0.8
    ;; Add stress from displacement
    set stress-level min list 100 (stress-level + 15 + random 10)

     ;; Initialize refugee adaptation tracking
    set days-since-relocation 0
    set nostalgia-level 50 + random 20 ;; adjusted for CES wave 4 data

    ;; Set relocation cooldown (30 days minimum before next move)
    set relocation-cooldown 30

    set last-move-tick ticks
    set considering-move? false
    set considering-return? false

    ;; Set initial adaptation rate based on stress level
    ifelse stress-level > acceptable-stress-level
    [set adaptation-rate random-float 0.15 - 0.1]
    [set adaptation-rate random-float 0.15 - 0.05]

    set current-adaptation 0
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; REFUGEE ADAPTATION AND RETURN PROCEDURES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Update states of all refugees

to update-refugee-state
  ask home-cities [
    ask citizens with [current-city != city-of-origin] [
      update-refugee-employment
      update-refugee-economic-state
      update-refugee-nostalgia
      update-refugee-adaptation

      evaluate-return

      ifelse (considering-return? = true)
      [return-home]
      [set days-since-relocation days-since-relocation + 1]
    ]
  ]
end 

;; Job finding with both hiring and firing

to update-refugee-employment
  ;; Calculate months since relocation
  let months days-since-relocation / 30
  let target-rate 0

  ;; Calculate target rate (40% to 60% over 24 months)
  ifelse months < 18 [set target-rate 0.40] [set target-rate 0.60]

  ;; Get current percentage of employed refugees
  let total-refugees count citizens with [current-city != city-of-origin]
  let employed-refugees count citizens with [current-city != city-of-origin and has-job?]
  let current-employment-rate 0
  if total-refugees > 0 [set current-employment-rate employed-refugees / total-refugees]

  ;; Calculate wish-to-work based on economic and emotional state
  ;; Higher economic state reduces wish to work
  ;; Lower emotional state reduces wish to work
  let economic-factor 1 - (economic-state / 500)  ;; Normalized to 0-1 range, reversed
  let stress-factor stress-level / 100      ;; Normalized to 0-1 range
  let wish-to-work (economic-factor + stress-factor) / 2  ;; Average of both factors

  ;; Clamp wish-to-work between 0.1 and 0.9 to avoid extremes
  set wish-to-work max list 0.1 (min list wish-to-work 0.9)

  ;; Calculate job opportunity probability based on adaptation level
  let adaptation-bonus 0
  if current-adaptation > 0 [
    set adaptation-bonus current-adaptation / 100  ;; Normalize to 0-1 range
  ]

  ;; Determine if we need job gain or job loss
  ifelse current-employment-rate < target-rate [
    ;; Need more jobs - only for unemployed refugees
    if not has-job? [
      ;; Gap determines base probability - larger gap means higher chance
      let gap target-rate - current-employment-rate
      let market-chance gap * 0.1  ;; Base market probability

      ;; Apply wish-to-work as a multiplier on market probability
      let job-search-chance market-chance * wish-to-work

      ;; Add adaptation bonus to final chance
      let final-chance job-search-chance * (1 + adaptation-bonus)

      ;; Try to find a job opportunity
      if random-float 1.0 < final-chance [
        ;; Generate job offer with salary
        let proposed-salary 0.4 + random-float 0.8  ;; Range: 0.4 to 1.2

        ;; Calculate monthly allowance (from daily allowance)
        let monthly-allowance refugee-monthly-allowance / 30

        ;; Decision to accept job depends on comparison with allowance
        ifelse proposed-salary > monthly-allowance [
          ;; Accept job if salary exceeds allowance
          set has-job? true
          set base-salary proposed-salary
          set current-adaptation current-adaptation + 30

          ;; Log job gain with comparison details
          ;log-event who EVENT_JOB_GAINED (word
          ;  "Salary: " (precision proposed-salary 2)
          ;  " | Allowance: " (precision monthly-allowance 2)
          ;  " | Accepted: yes"
          ;  " | Days as refugee: " days-since-relocation)
        ][
          ;; Low economic state might force acceptance despite low salary
          ifelse economic-state < 100 or random-float 1.0 < 0.3 [  ;; 30% chance to accept anyway
            set has-job? true
            set base-salary proposed-salary
            set current-adaptation current-adaptation + 20  ;; Less adaptation bonus for reluctant acceptance

            ;; Log reluctant job acceptance
            ;log-event who EVENT_JOB_GAINED (word
             ; "Salary: " (precision proposed-salary 2)
              ;" | Allowance: " (precision monthly-allowance 2)
              ;" | Accepted: reluctantly"
              ;" | Days as refugee: " days-since-relocation)
          ][
            ;; Declined job offer
;            log-event who "job-declined" (word
 ;             "Salary: " (precision proposed-salary 2)
  ;            " | Allowance: " (precision monthly-allowance 2)
   ;           " | Economic state: " economic-state)
          ]
        ]
      ]
    ]
  ][
    ;; Too many jobs - only for employed refugees
    if has-job? [
      ;; Excess determines probability - larger excess means higher chance
      let excess current-employment-rate - target-rate
      let daily-chance excess * 0.1  ;; Adjust multiplier as needed

      ;; Higher adaptation reduces chance of job loss
      let job-security adaptation-bonus
      let final-firing-chance daily-chance * (1 - job-security)

      ;; Potential job loss (firing)
      if random-float 1.0 < final-firing-chance [
        set has-job? false
        set base-salary 0

        ;; Losing job reduces adaptation and emotional state
        set current-adaptation current-adaptation - 20
        set stress-level min list 100 (stress-level + 20)

        ;; Log job loss
        ;log-event who EVENT_JOB_LOST (word
         ; "Days as refugee: " days-since-relocation
          ;" | Adaptation: " current-adaptation
          ;" | Job security factor: " (precision job-security 2))
      ]
    ]
  ]
end 

to update-refugee-economic-state
  let base-allowance refugee-monthly-allowance / 30

  let income-adjusted-allowance 0

  ifelse has-job?
  [set income-adjusted-allowance 0]  ;; No allowance for employed refugees
  [
    if economic-state < 50 [set income-adjusted-allowance base-allowance]
    if economic-state >= 50 and economic-state < 100 [set income-adjusted-allowance base-allowance * 0.8]
    if economic-state >= 100 and economic-state < 200 [set income-adjusted-allowance base-allowance * 0.5]
    if economic-state >= 200 and economic-state < 300 [set income-adjusted-allowance base-allowance * 0.2]
    if economic-state >= 300 [set income-adjusted-allowance 0]
  ]

  ;; Get actual available allowance (limited by city resources)
  let actual-allowance income-adjusted-allowance
  ask current-city [set actual-allowance min list income-adjusted-allowance city-facilities]

  ;; Apply income from allowance and salary
  set economic-state economic-state + actual-allowance + base-salary

  ;; Deduct from city facilities
  ask current-city [set city-facilities city-facilities - actual-allowance]

  ;; Add stress if allowance was reduced
  if (actual-allowance < income-adjusted-allowance) and (income-adjusted-allowance > 0)
  [set stress-level min list 100 (stress-level + 5)]
end 

to update-refugee-adaptation
  ;; Update adaptation progress
  set current-adaptation current-adaptation + adaptation-rate
  set current-adaptation max list -100 min list 100 current-adaptation

  ;; Adjust adaptation rate based on multiple factors
  let stress-component ifelse-value (stress-level < acceptable-stress-level) [-0.01] [0.01]
  let employment-component ifelse-value has-job? [-0.02] [0.01]

  let social-component 0
  let friends-here count link-neighbors with [current-city = [current-city] of myself]
  if count link-neighbors > 0
  [set social-component ifelse-value (friends-here / count link-neighbors > 0.3) [-0.01] [0.01] ]

  ;; Higher nostalgia makes adaptation more difficult
  let nostalgia-component 0
  set nostalgia-component ifelse-value (nostalgia-level > 50) [0.02] [-0.01]  ;; Strong nostalgia slows adaptation, and vice versa

  ;; Combine factors - stress still matters but isn't the only factor
  set adaptation-rate adaptation-rate + stress-component + employment-component + social-component + nostalgia-component
  set adaptation-rate max list -0.1 min list 0.1 adaptation-rate
end 

to update-refugee-nostalgia
  ;; Update nostalgia with variable depreciation
  if nostalgia-level > 0 [
    let base-depreciation-rate 0.03 ;; deprecation adjust to CES wave 4 data
    let job-modifier ifelse-value has-job? [0.02] [0]
    let variation (random-float 0.2 - 0.1)
    let nostalgia-depreciation-rate base-depreciation-rate * (1 + variation + job-modifier)
    set nostalgia-level max list 0 (nostalgia-level - nostalgia-depreciation-rate)
    ;; High adaptation reduces nostalgia, poor adaptation reinforces it

    if current-adaptation > 50 and random 10 < 3 [
      ;; Well-adapted refugees occasionally experience nostalgia reduction
      set nostalgia-level max list 0 (nostalgia-level - 0.5)
    ]

    if current-adaptation < -20 and random 10 < 3 [
      ;; Poorly adapted refugees occasionally experience nostalgia increase
      set nostalgia-level min list 100 (nostalgia-level + 0.2)
    ]
  ]
end 

;; Evaluate conditions for return migration using prospect theory

to evaluate-return
  ;; Skip evaluation if in cooldown period
  if relocation-cooldown > 0 [stop]

  set considering-return? false

  ;; Reset movement threshold based on current conditions
  ;; Similar to initial setting but adjusted for current circumstances
  set movement-threshold max list 0 (random-normal 2 1) * (1 + economic-state / 500) * (1 + (count link-neighbors / friends-and-family))

    ;; Restrict return for anyone who is currently in restricted demographic
  if migration-restrictions-enabled? and is-restricted-demographic?
  [
    ;; Significantly raise the threshold for considering return
    set movement-threshold movement-threshold * 1.2  ; decrease probability to return on 90%

    ;; Add stress from being unable to return home
    set stress-level min list 100 (stress-level + 1)
  ]

  ;; Only consider return if economically feasible
  if (economic-state + pay-for-return) > (distance city-of-origin) [
    let lambda 2  ;; Risk aversion parameter adjusted by CES / AUK research - all risks looks two times more scary

    ;; Calculate normalized changes relative to current reference point
    ;; For safety - negative means less safe at home than current location
    let home-safety normalize-safety-score city-of-origin
    let current-safety normalize-safety-score current-city
    let safety-change home-safety - current-safety
    let safety-value ifelse-value (safety-change >= 0)
      [safety-change]
      [lambda * safety-change]

    ;; For economics - negative means worse economic prospects at home
    let home-economy normalize-economic-score city-of-origin
    let current-economy normalize-economic-score current-city
    let economic-change home-economy - current-economy
    let economic-value ifelse-value (economic-change >= 0)
      [economic-change]
      [lambda * economic-change]

    ;; For social network - compare friends/family at home vs current
    let home-social count link-neighbors with [current-city = [city-of-origin] of myself]
    let current-social count link-neighbors with [current-city = [current-city] of myself]
    let total-social count link-neighbors
    let social-change (home-social - current-social)
    let social-value ifelse-value (social-change >= 0)
      [social-change]
      [lambda * social-change]

    ;; Get home city's restoration percentage with survey coefficient
    let home-restoration [rebuilt-percentage] of city-of-origin
    let restoration-factor 0
    if home-restoration > acceptable-home-restoration [
      set restoration-factor ((home-restoration - acceptable-home-restoration) / 100) * (1 + restoration-expectations-return-weight)
    ]

    ;; Add nostalgia as part of decision-making (calibrated to CES wave 4 data)
    let nostalgia-factor nostalgia-level / 100

    ;; Add adaptation factor
    let adaptation-factor current-adaptation / -100

    ;; Add economic hardship factor
    let economic-factor ifelse-value (economic-state <= acceptable-economic-state) [1] [-1]

    ;; Add employment status as negative factor for return
    let employment-factor 0
    if has-job? [
      ;; Having a job significantly decreases likelihood of return
      set employment-factor -1.0
    ]

    ;; Add stress influence
    let stress-factor 0
    ifelse stress-level > acceptable-stress-level [
      ;; High stress in host country increases likelihood of return
      set stress-factor (stress-level - acceptable-stress-level) / 50
    ][
      ;; Low stress decreases likelihood of return
      set stress-factor (stress-level - acceptable-stress-level) / 100  ;; Less impact for low stress
    ]

    ;; Calculate total expected value with prospect theory and survey coefficients
    let total-value safety-value * (1 + safety-expectations-return-weight) +
                    economic-value * (1 + economic-expectations-return-weight) +
                    social-value * (1 + social-expectations-return-weight) +
                    restoration-factor * (1 + restoration-expectations-return-weight) +
                    nostalgia-factor +
                    economic-factor +
                    adaptation-factor +
                    employment-factor +
                    stress-factor

    if (total-value > movement-threshold) [set considering-return? true]
  ]
end 

;; Execute return migration

to return-home
  let return-payment 0
  ;; Calculate return costs
  let return-cost distance city-of-origin + random 50

  ;; Update economic state and stress level
  set economic-state max list 0 (economic-state - return-cost + pay-for-return)
  ask current-city [set city-facilities city-facilities - return-payment]   ;; Update city finance
  set stress-level max list 0 (stress-level - 30)

  ;; Log return completion at the end
  ;log-event who EVENT_RETURN_COMPLETED (word "Total days as refugee: " days-since-relocation
   ;                                  " | From: " [who] of city-of-origin
    ;                                 " | Economic: " economic-state)

  ;; Execute physical return
  move-to city-of-origin
  set current-city city-of-origin
  ask city-of-origin [set refugees-back refugees-back + 1]   ;; Update city accounting

  ;; Reset refugee status variables
  set days-since-relocation 0
  set nostalgia-level 0
  set current-adaptation 0
  set adaptation-rate 0
  set has-job? false
  set considering-move? false
  set considering-return? false
  set illegally-crossed? false

  right random 360
  forward random 3
  set relocation-cooldown 30   ;; Set cooldown period
  set last-move-tick ticks
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MIGRATION-RELATED FUNCTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to-report is-restricted-demographic?
 ;; Only return true if restrictions are actually enabled
  if not migration-restrictions-enabled? [report false]

  ;; Check if citizen's gender matches exactly using string comparison
  let gender-restricted? false

  if restricted-genders = "male" [
    set gender-restricted? (gender = "male")
  ]
  if restricted-genders = "female" [
    set gender-restricted? (gender = "female")
  ]
  if restricted-genders = "male female" [
    set gender-restricted? (gender = "male" or gender = "female")
  ]

  ;; Check if citizen's age is in restricted range
  let age-restricted? (age >= min-restricted-age and age <= max-restricted-age)

  ;; Both conditions must be true for restriction to apply
  report (gender-restricted? and age-restricted?)
end 

to-report is-conscription-eligible?
  ;; Check if citizen's gender matches exactly using string comparison
  let gender-conscripted? false

  if conscripted-genders = "male" [
    set gender-conscripted? (gender = "male")
  ]
  if conscripted-genders = "female" [
    set gender-conscripted? (gender = "female")
  ]
  if conscripted-genders  = "male female" [
    set gender-conscripted? (gender = "male" or gender = "female")
  ]

  ;; Check if citizen's age is in restricted range
  let age-conscripted? (age >= min-conscription-age and age <= max-conscription-age)

  ;; Both conditions must be true for restriction to apply
  report (gender-conscripted? and age-conscripted?)
end 

to-report has-exit-permission?
  ;; If migration restrictions are enabled, check if this person is restricted
  ifelse migration-restrictions-enabled? and is-restricted-demographic? [report false][report true]

  ;; If migration restrictions are disabled, everyone can leave legally
  ;; Non-restricted demographics can always leave legally
end 

to proceed-with-legal-migration
  ;; Original migration logic
  let best-destination nobody
  let best-value -999999

  ask home-cities with [self != [current-city] of myself] [
    let this-city self
    let city-value [evaluate-relocation this-city] of myself
    if city-value > best-value [
      set best-destination this-city
      set best-value city-value
    ]
  ]

  let stress-quotient max list 0.1 (2 - stress-level / 100)
  let min-relocation-funds (distance best-destination) * stress-quotient

  if economic-state >= min-relocation-funds and best-destination != nobody [
    leave-for-city best-destination
  ]
  set considering-move? false
end 

to attempt-illegal-crossing
  set illegal-crossings-attempted illegal-crossings-attempted + 1
  set illegal-attempt-cooldown 30

  ;; Higher cost for illegal crossing (only restricted demographics reach this function)
  let crossing-cost economic-state * 0.3  ; 90% of economic state as base cost for illegal crossing

  ;; Improved success rate calculation with stronger border control effect
  let wealth-factor (economic-state / 500)  ; 0 to 1.0 range
  let border-factor (border-control-strictness / 100)  ; 0 to 1.0 range

  ;; Base success for restricted demographics attempting illegal crossing
  ;; Max success when border-control = 0: 0.35 (25% base + 10% wealth)
  ;; Max success when border-control = 100: 0.05 (85% reduction + wealth partially helps)
  let base-success-rate 0.25 + (wealth-factor * 0.10)  ; Lower base rate for illegal crossing
  let border-penalty (border-factor ^ 1.5) * 0.85  ; Non-linear penalty, max 85% reduction
  let success-chance base-success-rate * (1 - border-penalty)

  ifelse random-float 1 < success-chance [
    ;; Successful illegal crossing
    set illegal-crossings-succeeded illegal-crossings-succeeded + 1
    set illegally-crossed? true
    set color violet  ; Special color for illegal immigrants

    ;; Pay the illegal crossing cost upfront
    set economic-state economic-state - crossing-cost

    ;; Use existing migration logic for destination selection and relocation
    proceed-with-legal-migration
  ][
    ;; Failed illegal crossing - consequences
    ;; Failed attempts have higher economic penalty (caught, fined, etc.)
    set economic-state economic-state - (crossing-cost * 1.3)  ; 30% higher cost for failure
    set stress-level min list 100 (stress-level + 40)
    set conscription-stress min list 100 (conscription-stress + 20)
  ]

  set considering-move? false
end 

;; Perseverative Cognition - Anticipation Anxiety (Simplified)

to update-anticipation-anxiety
  ifelse is-conscription-eligible? and [city-war-exposure] of current-city >= 1
  [

   ;; Base worry about future conscription
   let worry-increment 0.5 * (1 + hostilities * 0.3)

   ;; Network effect: contagious worry from those still here
   if count link-neighbors > 0
    [if mean [conscription-stress] of link-neighbors > 50 [set worry-increment worry-increment * 1.2]]

   ;; Update with decay to prevent spirals (0.95 ensures convergence)
    set conscription-stress min list 100 (conscription-stress * 0.95 + worry-increment)
  ]
  [
    set conscription-stress max list 0 (conscription-stress * 0.9)
  ]
end 

;; Conservation of Resources - Exit Restriction Stress

to update-exit-restriction-stress
    ifelse migration-restrictions-enabled? and is-restricted-demographic? and [city-war-exposure] of current-city >= 1
    [
    ;; Core stress from lost freedom to migrate
    let freedom-loss 0.8

    ;; Amplified if actively trying to leave but blocked
    if considering-move? [set freedom-loss freedom-loss * 1.5]

    ;; Network effect: contagious worry from those still here
    if count link-neighbors > 0
    [if mean [exit-restriction-stress] of link-neighbors > 60 [set freedom-loss freedom-loss * 1.2]]

    ;; Relative deprivation - seeing others escape while you're trapped
    let escaped-friends count link-neighbors with [(is-restricted-demographic?) and [city-war-exposure] of current-city = 0]

    ;; This gets added to freedom-loss and then naturally decays with the 0.9 factor
    if escaped-friends > 0 [set freedom-loss freedom-loss + (escaped-friends * 0.1)]  ;; +0.3 stress points per escaped friend

    ;; Update with strong decay (0.9) to prevent spirals
    set exit-restriction-stress min list 100 (exit-restriction-stress * 0.9 + freedom-loss)
  ]
  [
    set exit-restriction-stress max list 0 (exit-restriction-stress * 0.85)
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; UTILITY AND SCORING FUNCTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Calculate normalized economic score for city comparison

to-report normalize-economic-score [target-city]
  if target-city = nobody [
    write "Economic Problem with city "
    report 0
  ]
  let economic-score [city-economic-score] of target-city
  if max-economic-score = 0 [ report 0 ]
  report precision (economic-score / max-economic-score * 1.0) 3
end 

;; Calculate normalized safety score for city comparison

to-report normalize-safety-score [target-city]
  if target-city = nobody [
    write "Safety Problem with city "
    report 0
  ]
  let damage-score [city-damage-score] of target-city
  if max-damage-score = 0 [ report 1 ]
  report precision (1 - (damage-score / max-damage-score) * 1.0) 3
end 

;; Calculate normalized social network score for city comparison

to-report normalize-social-score [target-city]
  if target-city = nobody [
    write "Invalid city reference"
    report 0
  ]
  let my-links1 link-neighbors
  let social-score count my-links1 with [current-city = target-city]
  let max-social max [count my-links1 with [current-city = myself]] of home-cities
  if max-social = 0 [ report 0 ]
  report precision (social-score / max-social * 1.0) 3
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; VISUALIZATION AND ENVIRONMENT PROCEDURES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Draw the frontline between cities

to draw-frontline
  ask patches with [pcolor != black] [set pcolor black]

  if any? home-cities with [city-war-exposure = 1] [
    let combat-cities home-cities with [city-war-exposure = 1]
    let combat-pairs []

    ask combat-cities [
      let city1 self
      ask other combat-cities [
        set combat-pairs lput (list ([xcor] of city1) ([ycor] of city1) xcor ycor) combat-pairs
      ]
    ]

    foreach combat-pairs [ pair ->
      draw-gradient-line (item 0 pair) (item 1 pair) (item 2 pair) (item 3 pair)
    ]
  ]
end 

;; Draw gradient line for frontline visualization

to draw-gradient-line [x1 y1 x2 y2]
  let max-width 4
  let affected-patches patches with [
    distancexy-to-line x1 y1 x2 y2 < max-width
  ]
  ask affected-patches [
    let dist distancexy-to-line x1 y1 x2 y2
    let intensity (1 - (dist / max-width)) * hostilities
    set pcolor scale-color red intensity 0 3
  ]
end 

;; Calculate point-to-line distance for frontline visualization

to-report distancexy-to-line [x1 y1 x2 y2]
  let A y2 - y1
  let B x1 - x2
  let C (x2 * y1) - (x1 * y2)
  report (abs (A * pxcor + B * pycor + C)) /
         (sqrt (A * A + B * B))
end 

to update-stress-visualization
    ;; Color based on dominant stress type
    if conscription-stress > exit-restriction-stress and conscription-stress > 50 [
      set color orange  ;; Anticipation anxiety dominant
    ]
    if exit-restriction-stress > conscription-stress and exit-restriction-stress > 50 [
      set color violet  ;; Restriction stress dominant
    ]
    ;; Keep existing color coding for other states
end 

to-report mean-conscription-stress
    if any? citizens with [is-conscription-eligible?]
  [    report mean [conscription-stress] of citizens with [is-conscription-eligible?]
  ]
  report 0
end 

to-report mean-restriction-stress
  if any? citizens with [is-restricted-demographic?]
  [    report mean [exit-restriction-stress] of citizens with [is-restricted-demographic?]
  ]
  report 0
end 

;; age distribution similar to Ukraine age pyramyd from https://www.populationpyramid.net/ukraine/2025/

to-report realisticaly-distributed-age [gender1]
 ;; choose parameter set by gender
  let p1 0
  let p2 0
  let p3 0
  let mu1 0
  let mu2 0
  let mu3 0
  let sd1 0
  let sd2 0
  let sd3 9

  ;; --- MALE ---
  let p1m 0.19150
  let p2m 0.45810
  let p3m (1 - p1m - p2m)
  let mu1m 10.684
  let mu2m 35.488
  let mu3m 61.513
  let sd1m  6.192
  let sd3m 12.076
  let sd2m 11.298
  ;; --- FEMALE ---
  let p1f 0.15001
  let p2f 0.44385
  let p3f (1 - p1f - p2f)
  let mu1f 10.482
  let mu2f 36.822
  let mu3f 66.378
  let sd1f  6.122
  let sd2f 12.488
  let sd3f 12.606

  ;; pick the right mixture for this turtle
  ifelse gender1 = "male"
  [
    set p1 p1m
    set p2 p2m
    set p3 p3m
    set mu1 mu1m
    set mu2 mu2m
    set mu3 mu3m
    set sd1 sd1m
    set sd2 sd2m
    set sd3 sd3m
  ]
  [
    set p1 p1f
    set p2 p2f
    set p3 p3f
    set mu1 mu1f
    set mu2 mu2f
    set mu3 mu3f
    set sd1 sd1f
    set sd2 sd2f
    set sd3 sd3f
  ]

  ;; choose component
  let r random-float 1
  let mu 0
  let sd 1

  (ifelse
    r < p1
    [
      set mu mu1
      set sd sd1
    ]
    r < (p1 + p2)
    [
      set mu mu2
      set sd sd2
    ]
    ; elsecommands
    [
      set mu mu3
      set sd sd3
    ]
  )

  report round max list 0 min list 100 random-normal mu sd
end 


;; FUNCTION TO POPULATE ALL 40 LISTS:

to populate-age-bins
 ;; Men agentsets
  set men-0-4 citizens with [gender = "male" and age >= 0 and age <= 4]
  set men-5-9 citizens with [gender = "male" and age >= 5 and age <= 9]
  set men-10-14 citizens with [gender = "male" and age >= 10 and age <= 14]
  set men-15-19 citizens with [gender = "male" and age >= 15 and age <= 19]
  set men-20-24 citizens with [gender = "male" and age >= 20 and age <= 24]
  set men-25-29 citizens with [gender = "male" and age >= 25 and age <= 29]
  set men-30-34 citizens with [gender = "male" and age >= 30 and age <= 34]
  set men-35-39 citizens with [gender = "male" and age >= 35 and age <= 39]
  set men-40-44 citizens with [gender = "male" and age >= 40 and age <= 44]
  set men-45-49 citizens with [gender = "male" and age >= 45 and age <= 49]
  set men-50-54 citizens with [gender = "male" and age >= 50 and age <= 54]
  set men-55-59 citizens with [gender = "male" and age >= 55 and age <= 59]
  set men-60-64 citizens with [gender = "male" and age >= 60 and age <= 64]
  set men-65-69 citizens with [gender = "male" and age >= 65 and age <= 69]
  set men-70-74 citizens with [gender = "male" and age >= 70 and age <= 74]
  set men-75-79 citizens with [gender = "male" and age >= 75 and age <= 79]
  set men-80-84 citizens with [gender = "male" and age >= 80 and age <= 84]
  set men-85-89 citizens with [gender = "male" and age >= 85 and age <= 89]
  set men-90-94 citizens with [gender = "male" and age >= 90 and age <= 94]
  set men-95-100 citizens with [gender = "male" and age >= 95 and age <= 100]

  ;; Women agentsets
  set women-0-4 citizens with [gender = "female" and age >= 0 and age <= 4]
  set women-5-9 citizens with [gender = "female" and age >= 5 and age <= 9]
  set women-10-14 citizens with [gender = "female" and age >= 10 and age <= 14]
  set women-15-19 citizens with [gender = "female" and age >= 15 and age <= 19]
  set women-20-24 citizens with [gender = "female" and age >= 20 and age <= 24]
  set women-25-29 citizens with [gender = "female" and age >= 25 and age <= 29]
  set women-30-34 citizens with [gender = "female" and age >= 30 and age <= 34]
  set women-35-39 citizens with [gender = "female" and age >= 35 and age <= 39]
  set women-40-44 citizens with [gender = "female" and age >= 40 and age <= 44]
  set women-45-49 citizens with [gender = "female" and age >= 45 and age <= 49]
  set women-50-54 citizens with [gender = "female" and age >= 50 and age <= 54]
  set women-55-59 citizens with [gender = "female" and age >= 55 and age <= 59]
  set women-60-64 citizens with [gender = "female" and age >= 60 and age <= 64]
  set women-65-69 citizens with [gender = "female" and age >= 65 and age <= 69]
  set women-70-74 citizens with [gender = "female" and age >= 70 and age <= 74]
  set women-75-79 citizens with [gender = "female" and age >= 75 and age <= 79]
  set women-80-84 citizens with [gender = "female" and age >= 80 and age <= 84]
  set women-85-89 citizens with [gender = "female" and age >= 85 and age <= 89]
  set women-90-94 citizens with [gender = "female" and age >= 90 and age <= 94]
  set women-95-100 citizens with [gender = "female" and age >= 95 and age <= 100]
end 

to initialize-age-bins-empty
  ;; Initialize all age bins as empty agentsets
  set men-0-4 no-turtles    set women-0-4 no-turtles
  set men-5-9 no-turtles    set women-5-9 no-turtles
  set men-10-14 no-turtles  set women-10-14 no-turtles
  set men-15-19 no-turtles  set women-15-19 no-turtles
  set men-20-24 no-turtles  set women-20-24 no-turtles
  set men-25-29 no-turtles  set women-25-29 no-turtles
  set men-30-34 no-turtles  set women-30-34 no-turtles
  set men-35-39 no-turtles  set women-35-39 no-turtles
  set men-40-44 no-turtles  set women-40-44 no-turtles
  set men-45-49 no-turtles  set women-45-49 no-turtles
  set men-50-54 no-turtles  set women-50-54 no-turtles
  set men-55-59 no-turtles  set women-55-59 no-turtles
  set men-60-64 no-turtles  set women-60-64 no-turtles
  set men-65-69 no-turtles  set women-65-69 no-turtles
  set men-70-74 no-turtles  set women-70-74 no-turtles
  set men-75-79 no-turtles  set women-75-79 no-turtles
  set men-80-84 no-turtles  set women-80-84 no-turtles
  set men-85-89 no-turtles  set women-85-89 no-turtles
  set men-90-94 no-turtles  set women-90-94 no-turtles
  set men-95-100 no-turtles  set women-95-100 no-turtles
end 

;; Procedure to update distribution lists for a specific city

to update-city-distributions [target-city]
  ;; Define age ranges for the 20 bins
  let age-ranges [[0 4] [5 9] [10 14] [15 19] [20 24] [25 29] [30 34] [35 39]
                  [40 44] [45 49] [50 54] [55 59] [60 64] [65 69] [70 74]
                  [75 79] [80 84] [85 89] [90 94] [95 100]]

  ;; Initialize empty lists for this city
  let male-pop-dist []
  let female-pop-dist []
  let male-stress-dist []
  let female-stress-dist []

  ;; Calculate distributions for each age bin
  foreach age-ranges [ age-range ->
    let min-age first age-range
    let max-age last age-range

    ;; Get citizens in this city and age range
    let city-citizens citizens with [current-city = target-city and age >= min-age and age <= max-age]
    let males city-citizens with [gender = "male"]
    let females city-citizens with [gender = "female"]

    ;; Population counts
    let male-count count males
    let female-count count females

    ;; Average stress levels (0 if no people in this age group)
    let male-avg-stress 0
    let female-avg-stress 0

    if male-count > 0 [set male-avg-stress round mean [stress-level] of males]
    if female-count > 0 [set female-avg-stress round mean [stress-level] of females]

    ;; Add to distribution lists
    set male-pop-dist lput male-count male-pop-dist
    set female-pop-dist lput female-count female-pop-dist
    set male-stress-dist lput male-avg-stress male-stress-dist
    set female-stress-dist lput female-avg-stress female-stress-dist
  ]

  ;; Update the city's distribution variables
  ask target-city [
    set male-pop-distribution male-pop-dist
    set female-pop-distribution female-pop-dist
    set male-stress-distribution male-stress-dist
    set female-stress-distribution female-stress-dist
  ]
end 

There is only one version of this model, created 2 days ago by Artem Serdyuk.

Attached files

File Type Description Last updated
Relocation 18-22.png preview Preview for 'Relocation 18-22' 2 days ago, by Artem Serdyuk Download

This model does not have any ancestors.

This model does not have any descendants.