COVID-19 in the University

COVID-19 in the University preview image

1 collaborator

Bell_sheep Andrew Bell (Author)

Tags

covid-19 

Tagged by Andrew Bell over 3 years ago

network 

Tagged by Andrew Bell over 3 years ago

Visible to everyone | Changeable by everyone
Model was written in NetLogo 6.2.0 • Viewed 576 times • Downloaded 29 times • Run 0 times
Download the 'COVID-19 in the University' modelDownload this modelEmbed this model

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


WHAT IS IT?

A model of virus spreading in a school environment. Virus propagation is handled by a physical agent-based model approach in shared lunchrooms and classes, while it is handled by a network agent-based model for time in which students are outside of the shared university environment (i.e., socializing with each other or outside of the university network).

HOW IT WORKS

Student agents attend classes or eat lunch according to their fixed schedule, and interact stochastically with others in the network outside of their scheduled time. As well, students have individual specific likelihoods of wearing masks, which decay over time but are bumped back up by specific events - students observing jumps in overall infection rate, or experiencing that someone close to them in their network has become ill or died. Students are scheduled to participate in a testing program that takes students in up to some capacity each timestep.

HOW TO USE IT

The model can be run by first clicking 'setup' and then 'go.'

Parameter sets are grouped into i) general simulation parameters, ii) virus characteristics general to both physical and network approaches, iii) network-approach specific parameters, iv) physical-approach specific parameters, v) agent mask-wearing parameters, and vi) testing parameters.

All parameters have been given descriptive names. In case the meaning of a parameter is unclear, we encourage the user to look for its use in the code tab.

Most parameters are adjustable along the simulation. Parameters that are only adjustable before setup are: numberPeople, initialInfections, averageLinksPerAgent, classCap.

THINGS TO NOTICE

Watch the plot of susceptible, infected, immune, and quarantined - under what conditions do you see repeated waves of the virus? How much does the average likelihood of mask-wearing shape the likelihood of a return wave?

THINGS TO TRY

Consider how best to choose parameters such that transmission in the network model is meaningfully similar to transmission in the physical model.

Explore the relative importance of i) mask wearing, ii) quarantining, iii) in-person learning, iv) testing in shaping the path of the virus.

EXTENDING THE MODEL

The model does not differentiate symptomatic vs. asymptomatic cases, nor does it implement a vaccine program (or vaccine hesitancy). How would you add these?

NETLOGO FEATURES

Users may be interested to see how the model space is broken up into one part that is governed by physical processes (virus transmission) and one that is not.

CREDITS AND REFERENCES

This model was developed by Andrew Reid Bell, Bianka Kiedrowska, Noor Eatamadi, and Olivia Osborne Kato as part of the course 'Modeling Pandemics and the Environment' in Spring 2020 at New York University - Abu Dhabi.

Comments and Questions

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

Click to Run Model

globals [peopleShapes averageNumberLinksActual averagePContact averagePMask infectionRate networkSpaceColor roomColor ]

breed [people person]

people-own [infected infectedTime immune recoveredTime pContactPerLink pMask pCheck lastInfectionRate schedule testDate quarantined?]

patches-own [load spaceID airTurnover physical? masked?]

to setup
  clear-all
  reset-ticks

  set peopleShapes  ["person business" "person doctor" "person farmer" "person graduate" "person lumberjack"
  "person police" "person service" "person soldier" "person student"]

  set networkSpaceColor 3
  set roomColor 93

  set classCap 10

  ;;initialize patches
  ask patches [set load 0 set spaceID "N/A" set airTurnover 0 set physical? false]

   ;; set up the space
  ask patches with [pxcor < 0] [set spaceID "network" set pcolor networkSpaceColor]
  make-room 2 2 15 15 fracAirTurnover false "dining hall"
  make-room 18 2 5 10 fracAirTurnover true "class 1"
  make-room 24 2 5 10 fracAirTurnover true "class 2"
  make-room 18 20 5 10 fracAirTurnover true "class 3"
  make-room 24 20 5 10 fracAirTurnover true "class 4"
  make-room 2 20 5 10 fracAirTurnover true "class 5"
  make-room 8 20 5 10 fracAirTurnover true "class 6"


  ;;make default schedule (currently in 12 parts - 2h)
  let defaultSchedule (list "network" "network" "network" "network" "network" "network" "network" "network" "network" "network" "network" "network")

  create-people numberPeople [

    go-to-space "network"
    set color green
    set infected false
    set immune false
    set quarantined? false
    set testDate 0

    set pContactPerLink max list 0 random-normal pContactPerLinkPerDay_Mean pContactPerLink_SD
    set pCheck max list 0 random-normal pCheck_mean pCheck_SD

    set lastInfectionRate 0

    set pMask max list 0 random-normal pMask_Initial_Mean pMask_Initial_SD

    set schedule defaultSchedule

    ;;add mealtime to schedule
    if groupLunch? [
      let lunchDraw random-float 1
      if-else lunchDraw < 0.3 [set schedule replace-item 5 schedule "dining hall"] [
        if-else lunchDraw < 0.6 [set schedule replace-item 6 schedule "dining hall"] [
          set schedule replace-item 7 schedule "dining hall"]
      ]
    ]


    ;;assign a shape randomly
    set shape one-of peopleShapes
  ]

  ;;make schedules
  ask n-of classCap people with [item 4 schedule = "network"] [set schedule replace-item 4 schedule "class 1"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 5 schedule "class 1"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 6 schedule "class 1"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 7 schedule "class 1"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 8 schedule "class 1"]
  ask n-of classCap people with [item 9 schedule = "network"] [set schedule replace-item 9 schedule "class 1"]
  ask n-of classCap people with [item 10 schedule = "network"] [set schedule replace-item 10 schedule "class 1"]

  ask n-of classCap people with [item 4 schedule = "network"] [set schedule replace-item 4 schedule "class 2"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 5 schedule "class 2"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 6 schedule "class 2"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 7 schedule "class 2"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 8 schedule "class 2"]
  ask n-of classCap people with [item 9 schedule = "network"] [set schedule replace-item 9 schedule "class 2"]
  ask n-of classCap people with [item 10 schedule = "network"] [set schedule replace-item 10 schedule "class 2"]

  ask n-of classCap people with [item 4 schedule = "network"] [set schedule replace-item 4 schedule "class 3"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 5 schedule "class 3"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 6 schedule "class 3"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 7 schedule "class 3"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 8 schedule "class 3"]
  ask n-of classCap people with [item 9 schedule = "network"] [set schedule replace-item 9 schedule "class 3"]
  ask n-of classCap people with [item 10 schedule = "network"] [set schedule replace-item 10 schedule "class 3"]

  ask n-of classCap people with [item 4 schedule = "network"] [set schedule replace-item 4 schedule "class 4"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 5 schedule "class 4"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 6 schedule "class 4"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 7 schedule "class 4"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 8 schedule "class 4"]
  ask n-of classCap people with [item 9 schedule = "network"] [set schedule replace-item 9 schedule "class 4"]
  ask n-of classCap people with [item 10 schedule = "network"] [set schedule replace-item 10 schedule "class 4"]

  ask n-of classCap people with [item 4 schedule = "network"] [set schedule replace-item 4 schedule "class 5"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 5 schedule "class 5"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 6 schedule "class 5"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 7 schedule "class 5"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 8 schedule "class 5"]
  ask n-of classCap people with [item 9 schedule = "network"] [set schedule replace-item 9 schedule "class 5"]
  ask n-of classCap people with [item 10 schedule = "network"] [set schedule replace-item 10 schedule "class 5"]

  ask n-of classCap people with [item 4 schedule = "network"] [set schedule replace-item 4 schedule "class 6"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 5 schedule "class 6"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 6 schedule "class 6"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 7 schedule "class 6"]
  ask n-of classCap people with [item 8 schedule = "network"] [set schedule replace-item 8 schedule "class 6"]
  ask n-of classCap people with [item 9 schedule = "network"] [set schedule replace-item 9 schedule "class 6"]
  ask n-of classCap people with [item 10 schedule = "network"] [set schedule replace-item 10 schedule "class 6"]



  ;;inital infections
  ask n-of initialInfections people [
    set infected true
    set infectedTime ticks
  ]

  ;;create social network links
  let numLinks averageLinksPerAgent * numberPeople / 2
  while [numLinks > 0] [

    ask one-of people [create-link-with one-of other people]
    set numLinks numLinks - 1
  ]


  ;; update global variables
  update-globals
end 

to go


   ask links [
      if (any? both-ends with [infected = true]) and (count both-ends with [quarantined? = false] = 2) and (count both-ends with [physical? = false] = 2) [
        let currentPContact [pContactPerLink] of one-of both-ends * (timeStep / 24) ;;
        let currentPMasks [pMask] of both-ends
        let currentPInfection pInfectionPerContact
        if random-float 1 < item 0 currentPMasks [set currentPInfection currentPInfection / riskReductionFactor_mask ]
        if random-float 1 < item 1 currentPMasks [set currentPInfection currentPInfection / riskReductionFactor_mask ]
        if random-float 1 < currentPInfection * currentPContact [
          ask both-ends [
          if not immune and not infected [set infected true set infectedTime ticks]
          ]
        ]
      ]
    ]

    let numContacts numberRandomContactsPerStep
    while [numContacts > 0] [

      let currentPair n-of 2 people

      if any? currentPair with [infected = true] and (count currentPair with [quarantined? = false] = 2)  and (count currentPair with [physical? = false] = 2) [

        let currentPMasks [pMask] of currentPair
        let currentPInfection pInfectionPerContact
        if random-float 1 < item 0 currentPMasks [set currentPInfection currentPInfection / riskReductionFactor_mask ]
        if random-float 1 < item 1 currentPMasks [set currentPInfection currentPInfection / riskReductionFactor_mask ]

        if random-float 1 < currentPInfection  [
          ask currentPair [
            if not immune and not infected [set infected true set infectedTime ticks]
          ]
        ]

      ]

     set numContacts numContacts - 1
    ]


  ask people [


    ;; move people if they are in the wrong place for this time
    let localTime ticks mod (24 / timeStep)
    set  localTime floor localTime / (24 / timeStep / length schedule)

    if quarantined? = false and [spaceID] of patch-here != item localTime schedule [
      go-to-space item localTime schedule
    ]

    if [physical?] of patch-here = true [
      ;;let people move
      let currentRoom [spaceID] of patch-here
      if random-float 1 < probTurn [facexy [pxcor] of one-of patches with [spaceID = currentRoom] [pxcor] of one-of patches with [spaceID = currentRoom]]
      forward speed

      ;;drop viral load if infected]
      let factor 1
      if infected [
        ask patch-here [
          if masked? = true [set factor factor / riskReductionFactor_mask]
          set load load + viralLoad / factor]]

      ;;test if newly infected
      if (not immune and not infected and random-float 1 < pInfectionPerLoad / factor * load ) [
        set infected true
        set infectedTime ticks
      ]
    ]

    ;;test if died
    if (infected and random-float 1 < caseMortalityRate / (recoveryTimeFromInfection_Days * (24 / timeStep)) ) [

      let currentAgentSet self
      let currentDegrees degreesConsidered
      let currentBump pMaskBump_die
      while [currentDegrees > 0] [
        ask currentAgentSet [
          ask out-link-neighbors [set pMask pMask + currentBump]
        ]
        set currentBump currentBump * (1 - pMaskBumpDecay_degree)
        set currentAgentSet out-link-neighbors
        set currentDegrees currentDegrees - 1
      ]

      die
    ]

    ;;check if recovered
    if (infected and ticks - infectedTime > recoveryTimeFromInfection_Days * (24 / timeStep) ) [
      set infected false
      set immune true
      set recoveredTime ticks
    ]


    ;; test if immunity lost
    if (immune and ticks - recoveredTime > immunityTime_Days * (24 / timeStep) ) [
     set immune false
    ]

    ;;update agent color based on infection
    if infected [set color red]
    if not infected [set color green]
    if immune [set color blue]

    ;;update other visualization parameters
    if seeNetwork? = true [ ask links [set hidden? false]]
    if seeNetwork? = false [ ask links [set hidden? true]]


    ;;update individual parameters
    set pMask pMask * (1 - pMask_decay)
    if random-float 1 < pCheck [
      if infectionRate > lastInfectionRate [
        set pMask pMask + pMaskBump_rise
      ]
      set lastInfectionRate infectionRate
    ]
  ]


  ;;run testing program once per day
  if ticks mod (24 / timeStep) = 0 [
    ask up-to-n-of testingCapacityPerDay people with [testDate < ticks] [
      ifelse infected = true [set quarantined? true go-to-space "network"  ] [set quarantined? false]
      set testDate ticks + testingFrequency * (24 / timeStep)
    ]
  ]

  ;;update physical spaces
  ;;update patch color based on load
  ;;diffuse load diffuseShare
  ask patches with [physical? = false] [set load 0]
  ask patches with [physical? = true] [
    ;;set load load * (1 - 1 / virusLifetime)
    update-virus-in-space

    if-else seeCovid? [

     set pcolor scale-color yellow load 0 viralLoad
    ] [
     set pcolor black
    ]
  ]



  ;; update global variables
  update-globals

  tick
end 

to update-globals

  set averageNumberLinksActual count links / count people
  set averagePContact sum [pContactPerLink] of people / count people
  set averagePMask sum [pMask] of people / count people
  set infectionRate count people with [infected = true] / count people
end 

to make-room [x y h w a m id]
  ask patches with [pxcor >= x and pxcor < x + h and pycor >= y and pycor < y + w] [
    set spaceID id
    set airTurnover a
    set physical? true
    set masked? m
  ]

  draw-box x y h w
end 

to draw-box [x y h w]
  ask patches with [pxcor = x and pycor >= y and pycor < y + w] [
    sprout 1 [set shape "line" set color white set heading 0 set xcor xcor - 0.5 stamp die]
  ]
  ask patches with [pxcor = x + h - 1 and pycor >= y and pycor < y + w] [
    sprout 1 [set shape "line" set color white set heading 0 set xcor xcor + 0.5 stamp die]
  ]
  ask patches with [pycor = y and pxcor >= x and pxcor < x + h] [
    sprout 1 [set shape "line" set color white set heading 90 set ycor ycor - 0.5 stamp die]
  ]
  ask patches with [pycor = y + w - 1 and pxcor >= x and pxcor < x + h] [
    sprout 1 [set shape "line" set color white set heading 90 set ycor ycor + 0.5 stamp die]
  ]
end 

to go-to-space [id]
  let newPatch one-of patches with [spaceID = id]
  setxy [pxcor] of newPatch + (random 1 - 0.25) [pycor] of newPatch + (random 1 - 0.25)
end 

to update-virus-in-space

  ;;let virus diffuse
  let roomNeighbors neighbors with [spaceID = [spaceID] of self]
  let loadOut load * diffuseShare
  ask roomNeighbors [set load load + loadOut / count roomNeighbors]
  set load max (list 0 (load - loadOut))

  ;;let virus decay
  set load load * (1 - 1 / virusLifetime)

  ;;let air flow (flow is always from lower x to higher x, by default
  let movedLoad load * airTurnover
  set load load - movedLoad
  ask patch-at 1 0 [set load load + movedLoad]
end 

There is only one version of this model, created over 3 years ago by Andrew Bell.

Attached files

File Type Description Last updated
COVID-19 in the University.png preview Preview for 'COVID-19 in the University' over 3 years ago, by Andrew Bell Download

This model does not have any ancestors.

This model does not have any descendants.