Building a Simulation for Coronavirus and Social Isolation using Repast Simphony

Nimish Verma
7 min readApr 12, 2020

--

COVID-2019 has been spreading around the world. Many countries are on lockdown to mitigate the spread of this deadly virus. Everyone around the world has adopted the practice of social distancing( or isolation). In this article, We will be going through a popular agent-based modelling Java framework — Repast Simphony. We will attempt to build a basic simulation to monitor the spread of coronavirus in various settings. The only prerequisite is the basic knowledge of object-oriented programming.

Getting Started with Repast Simphony

Repast Simphony downloads are available here. A getting started documentation is provided by the Repast Development Team which can be viewed in the embedded PDF below. I will be explaining how to initialize the project in this blog, which can also be found in the documentation below..

Repast Development Team’s Documentation. ( I do not own any content/the PDF)

The system used in this project operates on Windows 10. For Windows, Repast Simphony comes with Java Environment (Eclipse) as a stand-alone application. Once, you have installed Repast Simphony, you should see an Eclipse executable file in your startup menu.

Now, the first step is to switch the Perspective to Repast Simphony. Go to Window>Persepcetive>Open Perspective>Other..

Choose Repast Simphony from the list.

Now, we will create a new Repast Simphony Project,

Go to File>New>Repast Simphony Project.

A wizard should open, type the project name “SocialIsolationSimulator” in this field. You should see a new directory in the Navigator on the left, with a few folders and files created for you.

Time to code our Agents now.

Here comes the coding!

Let’s start with the agents first. Since we will be modelling the spread of coronavirus we can have the following agents:-

  1. Healthy Agents
  2. Infected Agents
  3. Recovered Agents
  4. Dead Agents
  5. Hospitals

Note:- You can create agents in a different manner, it all depends on how you decide the layout of your project.

Creating an agent is really simple, in the navigator, go to src>SocialIsolationSimulator, right-click and create a new Class.

Let’s create the Healthy Agent first, since they are the most basic. We write the name of the class and click on Finish.

This should create a file named Healthy.java in the source folder.

Our next step is to define a constructor for this agent first, and the data members.

In Repast Simphony, each agent moves around a ContinuousSpace and the Grid location is determined by rounding the location in the ContinuousSpace.

We initialize the data members — space and grid, and assign them in the constructor using the following code.

Make sure you make the necessary imports of the classes ContinuousSpace, and Grid. This can be done using Control+O (in Windows), which is a shortcut in Eclipse. Or by adding the following lines on top of the file :

import repast.simphony.space.continuous.ContinuousSpace;

import repast.simphony.space.grid.Grid;

Now, after writing the code for the constructor, we have to define a step function in our Healthy agent. A step function will contain our code that is executed for each agent at each tick.

We will be referring to the Human code in the documentation above

the function moveTowards() is a function that we define to make an agent move towards a target position.

Let’s understand the code now

In step() function, first we get the location of this agent in the grid in line 50,

then we obtain the neighbouring GridCells using the helper function GridCellNgh.getNeighborhood().

After we get the 8-neighbour grid cells, we shuffle the list, and choose the 0th index of that list. This ensures that at every step our agent moves in a random position. After obtaining the target gridPoint in line 60, we move our agent towards that position.

The function moveTowards takes the GridPoint target location, and finds the angle between the current GridPoint and the target GridPoint in Line 70. In line 72, we move our agent in the space using moveByVector function, by a magnitude of 2. As mentioned before, we need to update the position in the grid by rounding the position in space, this is done in line 74.

Always remember to move agents in the space and update the location in grid by rounding.

Now, the last step is to put the schedule decorator on the step function.

Writing @ScheduledMethod(start = 1, interval = 1) above the step function schedules it at every tick starting from the 1st tick.

Make sure you make the necessary imports below:-

import repast.simphony.engine.schedule.ScheduledMethod;

import repast.simphony.query.space.grid.GridCell;

import repast.simphony.query.space.grid.GridCellNgh;

import repast.simphony.random.RandomHelper;

import repast.simphony.space.SpatialMath;

import repast.simphony.space.continuous.ContinuousSpace;

import repast.simphony.space.continuous.NdPoint;

import repast.simphony.space.grid.Grid;

import repast.simphony.space.grid.GridPoint;

import repast.simphony.util.SimUtilities;

Similarly, we will write the code for our infected agents, which is very similar to the nature of Zombies in the documentation example.

We have defined various data members in our infected agents, like the number of days since they've been infected (days_infected), are they symptomatic, are they hospitalized, and a hospital member to link a Hospital agent to Infected Agent. Just like all agents, we need to assign the space and grid in the constructor.

For Infected agents, the step function is the same as Healthy agents, random movement in any of the 8 possible directions, but we add a new feature to infected agents. We give them the ability to infect healthy agents (not so good, eh?). We add a line — infect() to the step function which is the same as Healthy agents.

The infect() function has to do the following:-

  1. Get the list of healthy agents in the location of infected agents
  2. Infect the healthy agents based on a probability
  3. Delete the healthy agent
  4. Spawn an infected agent in place of it.

The following code is for the infect function:-

context represents the group of agents that participate in the simulation.

chance_to_infect is a float that represents the probability of transmission, and we will be discussing social_isolate field for a Healthy agent later…

Pretty basic right?

Let’s also add a new feature to our infected agent, we make them go to the hospital on a probability basis, but first, we define a function to get the nearest hospital from an agent.

We still have to define the Hospital Agent for now but this code is self-explanatory. We start with a minimum distance equal to positive infinity, and we iterate over all agents in our context that are of Hospital type. We then get the Euclidian distance between our infected agent and the hospital agent during that iteration, and we find the hospital with minimum distance (as long as it has at least 1 empty bed)

Now we define the function to make an infected person go to the hospital which would call the function defined above

Now we just call this function in our step function for Infected defined above.

Going to the next type of agent now- Hospital agent. We start with space, and grid, and also add the field current capacity to our hospitals.

You can see at line 8 we are getting parameters for our simulation. In this project, I have parameterized every probability, and numbers to user input to make it more dynamic and tunable. Line 8 gets all the parameters and line 9 will get the value of a certain parameter from the params object.

We will be discussing parameters, intiliazing agents, data sinks, and setting up GUI in part 2 of this tutorial.

Lastly, let’s add a parameter of social isolation to our agents, when they are socially isolated, they don't move from their location, and hence don't get infected.

To do that, either take a parameter of social isolation or define the probability in your Healthy.java file and add this to the constructor

Now add line 47, 48 in top of the step function for Healthy to make them skip the remaining code of moving around if they are isolated. Repeat this for the Infected agent as well.

Now, you are free to experiment around, play with parameters, add new methods and new agents to your simulation. The Github repo here covers the code for the simulation I worked on, which has the following features:-

  1. Infected agent dies on the basis of a probability after developing symptoms (after a certain number of days of infection)
  2. The event of an infected agent going to the hospital is only possible after symptoms are developed
  3. Infected agents have a chance to recover when at the hospital, and then they become Recovered agents (immunized to the virus)
  4. Agents additional to this tutorial — Recovered, and Dead
  5. An infected person may also die, in or outside Hospital, based on a probability. They then become Dead agent, no step function.

--

--