COVID-19 CEE-5114
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
COVID-19 Virus Spread Model is an Agent-Based-Model built from the skeleton of an SIR model developed by Paul Smaldino currently (2020) at the Cognitive and Information Sciences Department at the University of California, Merced; and was further developed by Nich Martin at the University of Florida, Department of Entomology and Nematology as a tool to help educate the public on how interaction models concerning the current COVID-19 pandemic are used to make predictions and recommendations to the public.
HOW IT WORKS
An initial population of agents (blue-colored humanoids) are randomly placed in the model space with an initial population of infected individuals (red). As time moves forward, agents move randomly through the model space according to specified parameters such as number of stationary individuals and mobility. Infected individuals transmit the virus to susceptible individuals by coming within a certain distance of each other. Whether the susceptible individual becomes infected is determined by a random probability, the likelihood of which increases as transmission rate increases. The model can be run with and without immune individuals; when ran with immunity, infected individuals will become immune (color changes to gray) according to a random probability, the liklihood of which increases with increasing recovery rate. Mortality rate can be adjusted. The ability of hospitals to cope with the proportion of infected individuals can be adjusted as well. Once the proportion of infected individuals is greater than health care capacity mortality increases an order of magnitude, as predicted by other current models.
HOW TO USE IT
After adjusting the parameters, described below, simply click the setup button and click go. The model will continue to run until there are either no more infected individuals or no more susceptible individuals.
Initial Population
Control population size by adjusting the init-population slider.
Initial Number of Infected Individuals
Controls initial number of infected using the init-infected slider.
Transmission Rate
Current estimates are between 0.50 and 0.70. Set transmission rate by moving the transmission.rate slider.
Number of Stationary Individuals
The stationary slider allows the user to control the number of individals not moving (represents physical/social distancing) in the model space.
Mobility
The mobility slider allows the user to set how much distance non-stationary individuals move throughout the model space.
Recovery Rate
Set the recovery.rate slider low for longer recovery time and high for quick recovery. Suggested recovery rate for the current virus is 0.15.
Immunity
Activate individuals' ability to recover from infection by turning on the immunity? switch.
Initial Number of Immune Individuals
Use the init-immune slider to adjust the number of individuals immune to the virus before the model runs.
Mobilize the Immune
By activating the mobilize-immune? switch, individuals who were once stationary are allowed to move throughout the model space once they become immune.
Quarantine Effort
By adjusting the quarantine.effort slider, users can control infected individuals' ability to infect susceptibles.
Health Care Capacity
The healthcare.capacity slider changes the proportion of infected individuals hospitals can provide care for. Once the proportion of infected individuals exceeds health care capacity (which I'm told should realistically be set at least below 0.30) mortality rate increases one order of magnitude from where it was initially set.
Mortality Rate
The infected.mortality slider changes the base-line mortality rate for those infected. Estimates for mortality rate range from 1 to 10%, averaging around 3.6 when not accounting for health care capacity.
THINGS TO NOTICE
You can watch the model space and individuals moving throughout it to see how disease spreads throughout a population.
The model has two plot outputs. The first shows the number of susceptible, infected, and immune individuals through time. This same figure also shows a line for health care capacity.
The plot below the first shows the total number of individuals who have died as the model moves through time.
There are also a number of indicator values including the maximum propotion of individuals infected, the proportion uninfected, the number of people who have died, and the current population size.
THINGS TO TRY
Try adjusting the init-population slider to see how more sparse, rural areas are affected vs. densely populated cities.
Adjust the stationary slider to see how many people "social distancing" it takes to "flatten the curve".
Adjust the init-immune slider to see what outcomes would look like if a vaccine was available, and how many individuals getting vaccinated it would take to see the effects of "herd immunity".
By adjusting the quarantine.effort you can see what the effects of isolating individuals already infected has on the dynamics of the system.
EXTENDING THE MODEL
If you have any suggestions for things to add or change in the model feel free to contact me at n.martin@ufl.edu. I (Nich Martin) am not an epidemiologist, so if there are epidemiologists out there who feel the model needs drastic improvement, please contact me. But please also bear in mind, this was developed as an educational tool so changes will likely only be made if they serve an educational benefit. Netlogo users are encouraged to adjust the code as they see fit; I would be delighted if you send me your updates; I am new to agent-based modeling and would like useful feedback.
RELATED MODELS
This model is based off an initial model by Paul Smaldino "SIR Model with random movement" http://smaldino.com/wp/
CREDITS AND REFERENCES
CREATIVE COMMONS LICENSE This code is distributed by Nich Martin under a Creative Commons License: Attribution-ShareAlike 4.0 International (CC 4.0) https://creativecommons.org/licenses/by/4.0/
Comments and Questions
;;SIR Model with random movement ;;Agents move around at random. ;;They are either Susceptible, Infected, or Recovered (or, equivalently, removed) globals [max-infected] turtles-own[ infected? immune? stationary? category? Essential-Worker? Co-Morbidity? CFR? Mobility? Age? ] to setup clear-all setup-turtles setup-infected setup-immune set max-infected (count turtles with [infected?]) setup-lockdown setup-Density reset-ticks end to setup-Density if Population-Density = "Very High - 30k/sqm (NYC)" [ set init-population (30 / 10 * 1000) ] if Population-Density = "High - 20k/sqm (Paris)" [ set init-population (20 / 10 * 1000) ] if Population-Density = "Average - 10k/sqm (Washighton DC)" [ set init-population (10 / 10 * 1000) ] if Population-Density = "Low - 2k/sqm (SLC)" [ set init-population (1 / 10 * 1000) ] if Population-Density = "Very Low - 700/sqm (Laramie)" [ set init-population (0.7 / 10 * 1000) ] end to setup-turtles create-turtles (init-population * 0.14) [ set color 56 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a0-10" set Essential-Worker? false set Co-Morbidity? false set CFR? 0 set Mobility? 2 set Age? "0-10" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.19) [ set color 54 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a10-24" set Essential-Worker? false set Co-Morbidity? false set CFR? 0.07 set Mobility? 5 set Age? "10-24" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.179) [ set color 76 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a25-44EW" set Essential-Worker? true set Co-Morbidity? false set CFR? 0.28 set Mobility? 10 set Age? "25-44" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.048) [ set color 73 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a25-44" set Essential-Worker? false set Co-Morbidity? false set CFR? 0.28 set Mobility? 10 set Age? "25-44" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.036) [ set color 77 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a25-44EWCM" set Essential-Worker? true set Co-Morbidity? true set CFR? 1.4 set Mobility? 10 set Age? "25-44" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.068) [ set color 74 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a25-44CM" set Essential-Worker? false set Co-Morbidity? true set CFR? 1.4 set Mobility? 10 set Age? "25-44" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.082) [ set color 96 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a45-64EW" set Essential-Worker? true set Co-Morbidity? false set CFR? 1.5 set Mobility? 10 set Age? "45-64" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.022) [ set color 93 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a45-64" set Essential-Worker? false set Co-Morbidity? false set CFR? 1.5 set Mobility? 10 set Age? "45-64" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.02) [ set color 97 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a45-64EWCM" set Essential-Worker? true set Co-Morbidity? true set CFR? 7.5 set Mobility? 10 set Age? "45-64" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.076) [ set color 94 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a45-64CM" set Essential-Worker? false set Co-Morbidity? true set CFR? 7.5 set Mobility? 10 set Age? "45-64" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.048) [ set color 116 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a65-85" set Essential-Worker? false set Co-Morbidity? false set CFR? 11.26 set Mobility? 10 set Age? "65-85" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.072) [ set color 114 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a65-85CM" set Essential-Worker? false set Co-Morbidity? true set CFR? 56.3 set Mobility? 7 set Age? "65-85" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.005) [ set color 136 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a85p" set Essential-Worker? false set Co-Morbidity? false set CFR? 44.4 set Mobility? 4 set Age? "85+" setxy random-pxcor random-pycor ] create-turtles (init-population * 0.015) [ set color 134 set shape "person" set size 2 set infected? false set immune? false set stationary? false set category? "a85pCM" set Essential-Worker? false set Co-Morbidity? true set CFR? 222 set Mobility? 3 set Age? "85+" setxy random-pxcor random-pycor ] end to setup-infected ask n-of init-infected turtles [ set color red set infected? true ] end to setup-immune ask n-of (a0-10Vaccine / 100 * (count turtles with [category? = "a0-10"])) turtles with [category? = "a0-10"] [ set immune? true ] ask n-of (a10-24Vaccine / 100 * (count turtles with [category? = "a10-24"])) turtles with [category? = "a10-24"] [ set immune? true ] ask n-of (a25-44Vaccine / 100 * (count turtles with [category? = "a25-44"])) turtles with [category? = "a25-44"] [ set immune? true ] ask n-of (a45-64Vaccine / 100 * (count turtles with [category? = "a45-64"])) turtles with [category? = "a45-64"] [ set immune? true ] ask n-of (a65-85Vaccine / 100 * (count turtles with [category? = "a65-85"])) turtles with [category? = "a65-85"] [ set immune? true ] ask n-of (a85+Vaccine / 100 * (count turtles with [category? = "a85p"])) turtles with [category? = "a85p"] [ set immune? true ] ask n-of (a25-44-with-Co-Morbidity-Vaccine / 100 * (count turtles with [category? = "a25-44CM"])) turtles with [category? = "a25-44CM"] [ set immune? true ] ask n-of (a45-64-with-Co-Morbidity-Vaccine / 100 * (count turtles with [category? = "a45-64CM"])) turtles with [category? = "a45-64CM"] [ set immune? true ] ask n-of (a65-85-with-Co-Morbidity-Vaccine / 100 * (count turtles with [category? = "a65-85CM"])) turtles with [category? = "a65-85CM"] [ set immune? true ] ask n-of (a85+-with-Co-Morbidity-Vaccine / 100 * (count turtles with [category? = "a85pCM"])) turtles with [category? = "a85pCM"] [ set immune? true ] ask n-of (a25-44-Essential-Worker-with-Co-Morbidity-Vaccine / 100 * (count turtles with [category? = "a25-44EWCM"])) turtles with [category? = "a25-44EWCM"] [ set immune? true ] ask n-of (a45-64-Essential-Worker-with-Co-Morbidity-Vaccine / 100 * (count turtles with [category? = "a45-64EWCM"])) turtles with [category? = "a45-64EWCM"] [ set immune? true ] ask n-of (a25-44-Essential-Worker-Vaccine / 100 * (count turtles with [category? = "a25-44EW"])) turtles with [category? = "a25-44EW"] [ set immune? true ] ask n-of (a45-64-Essential-Worker-Vaccine / 100 * (count turtles with [category? = "a45-64EW"])) turtles with [category? = "a45-64EW"] [ set immune? true ] end to setup-lockdown if LOCKDOWN = "Partial Shutdown" [ ask turtles with [Essential-Worker? = false][ set Mobility? 5 ] ask turtles with [category? = "a0-10"][ set Mobility? 1 ] ask turtles with [category? = "a10-24"][ set Mobility? 3 ] ask turtles with [category? = "a65-85"][ set Mobility? 4 ] ask turtles with [category? = "a65-85CM"][ set Mobility? 2 ] ask turtles with [category? = "a85p"][ set Mobility? 0 ] ask turtles with [category? = "a85pCM"][ set Mobility? 0 ] ] if LOCKDOWN = "Full Lockdown" [ ask turtles with [Essential-Worker? = true][ set Mobility? 8 ] ask turtles with [Essential-Worker? = false][ set Mobility? 2 ] ask turtles with [category? = "a0-10"][ set Mobility? 0 ] ask turtles with [category? = "a10-24"][ set Mobility? 0 ] ask turtles with [category? = "a65-85"][ set Mobility? 2 ] ask turtles with [category? = "a65-85CM"][ set Mobility? 2 ] ask turtles with [category? = "a85p"][ set Mobility? 0 ] ask turtles with [category? = "a85pCM"][ set Mobility? 0 ] ] end to go ;;stop if everyone or noone is infected if (count turtles with [infected?] = 0) or (count turtles with [infected?] = init-population) [stop] infect-susceptibles kill-susceptibles recover-infected recolor move calculate-max-infected tick end to infect-susceptibles ;; S -> I ask turtles [ let infected-neighbors (count other turtles with [color = red] in-radius 1) if (random-float 1 < 1 - (((1 - transmission.rate) ^ infected-neighbors)) and not immune?) [set infected? true] ] end to recolor ask turtles with [infected?] [ set color red] end to move ask turtles with [Category? = "a0-10"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a10-24"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a25-44"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a25-44EW"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a25-44CM"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a25-44EWCM"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a45-64"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a45-64CM"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a45-64EW"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a45-64EWCM"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a65-85"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a65-85CM"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a85p"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] ask turtles with [Category? = "a85pCM"] [ if (stationary? = false) [ right random 360 ;;get a new random heading forward random-normal (Mobility? / mobility-ratio) 0.01] ifelse mobilize-immune? [if (stationary? = true and immune? = true) [set stationary? false]] [if (stationary? = true and immune? = true) [set stationary? true] ] ] end to recover-infected ;;I -> R ask turtles with [infected?] [ if random-float 1 < recovery.rate [ set infected? false set immune? true set color gray ] ] end to-report prop-infected report (count turtles with [infected?] / count turtles) end to kill-susceptibles ask turtles with [infected? and category? = "a0-10"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a10-24"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a25-44"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a25-44CM"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a25-44EW"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a25-44EWCM"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a45-64"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a45-64CM"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a45-64EW"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a45-64EWCM"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a65-85"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a65-85CM"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a85p"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a85pCM"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a0-10"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a0-10"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a0-10"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a0-10"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] ask turtles with [infected? and category? = "a0-10"] [ifelse prop-infected < healthcare.capacity [if (random-float 1000 < CFR?) [die]] [if (random-float 1000 < (10 * CFR?)) [die]]] end to-report num-dead report (init-population - count turtles) end to-report num-dead-0-10 report (round (init-population * 0.14) - count turtles with [Age? = "0-10"]) end to-report num-dead-10-24 report (round (init-population * 0.19) - count turtles with [Age? = "10-24"]) end to-report num-dead-25-44 report (round (init-population * 0.33) - count turtles with [Age? = "25-44"]) end to-report num-dead-45-64 report (round (init-population * 0.2) - count turtles with [Age? = "45-64"]) end to-report num-dead-65-85 report (round (init-population * 0.12) - count turtles with [Age? = "65-85"]) end to-report num-dead-85+ report (round (init-population * 0.02) - count turtles with [Age? = "85+"]) end to-report population report (count turtles) end to calculate-max-infected let x (count turtles with [infected?]) if x > max-infected [set max-infected x] end to-report max-infected-prop report max-infected / init-population end to-report prop-uninfected report (count turtles with [not infected? and not immune?]) / init-population end
There is only one version of this model, created almost 4 years ago by Tommee Larochelle.
Attached files
No files
This model does not have any ancestors.
This model does not have any descendants.