{"id":9405,"date":"2020-03-23T13:12:17","date_gmt":"2020-03-23T18:12:17","guid":{"rendered":"https:\/\/blogs.mathworks.com\/simulink\/?p=9405"},"modified":"2020-10-14T14:36:20","modified_gmt":"2020-10-14T18:36:20","slug":"covid-19-simulating-exponential-spread-in-simulink","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2020\/03\/23\/covid-19-simulating-exponential-spread-in-simulink\/","title":{"rendered":"COVID-19: Simulating exponential spread in Simulink"},"content":{"rendered":"<p><em><strong>Update (10\/14\/2020): <\/strong>The GitHub repository now contains a MATLAB App to simulate the model and visualize the results. We compiled the app as a <a href=\"https:\/\/www.mathworks.com\/help\/compiler\/web-apps.html\">MATLAB Web App<\/a> and host it in the cloud using the <a href=\"https:\/\/www.mathworks.com\/products\/matlab-web-app-server.html\">MATLAB Web App Server<\/a>.<\/em><\/p>\n<p>Last week, my colleague Mariano Lizarraga Fernandez pointed me to the <a href=\"https:\/\/www.washingtonpost.com\/graphics\/2020\/world\/corona-simulator\/\">Washington post simulation of COVID-19<\/a> and we thought it would be interesting to implement something similar using MathWorks products.<\/p>\n<p>Now that <a href=\"https:\/\/blogs.mathworks.com\/cleve\/\">Cleve<\/a> published a <a href=\"https:\/\/blogs.mathworks.com\/cleve\/2020\/03\/18\/covid-19-simulator\/\">MATLAB-based simulator<\/a>, it's time to for us to publish our simulation implemented using Simulink, Stateflow and SimEvents.<\/p>\n<p>Here is what the results looks like for a random set of 50 \"agents\" (green is before infection, red is infected and blue is recovered):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/virusSim.gif\" alt=\"Covid 19 simulator\" \/><\/p>\n<p>Let's see how I put that together.<\/p>\n<p><strong>Extending the Curling Simulator<\/strong><\/p>\n<p>The first thing that crossed my mind when thinking about how I would implement this simulation is that I could probably reuse some of the algorithm I put together for the <a href=\"https:\/\/blogs.mathworks.com\/simulink\/2019\/09\/06\/curling-game-update-app-designer-and-stateflow\">curling simulator<\/a> I published some time ago.<\/p>\n<p>With the dynamics of the stones bouncing against each other already implemented, I added bouncing against a boundary box and a logic to keep track of the infection propagation.<\/p>\n<p>To begin, let's look at the top level.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/covid_topModel.png\" alt=\"Covid 19 simulator\" \/><\/p>\n<p>and here is what the Stateflow chart looks like:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/covid_chart.png\" alt=\"Covid 19 simulator\" \/><\/p>\n<p><strong>The Details<\/strong><\/p>\n<p>Here is how it all works:<\/p>\n<ul>\n<li>Inside Stateflow, the Simulink State integrates the motion of the agents<\/li>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/covid_integ.png\" alt=\"Integrator block inside Stateflow\" \/><\/p>\n<li>At every time step, we call a MATLAB function to detect if an agent hit one of the border walls. If one agent did, we invert the sign of its velocity in the wall direction and re-initialize the Integrator block in the Simulink State with this updated velocity.<\/li>\n<li>At every time step, we call a MATLAB Function to detect if two agents get into contact. If they did, we compute the new velocities using a Simulink Function and reset the Integrator block in the Simulink State.<\/li>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/covid_contact.png\" alt=\"Monitoring infection spread\" \/><\/p>\n<li>When that happens, we call a Stateflow Graphical function to determine if the infection gets propagated. To keep track of  who is infected, we use a global Data Store<\/li>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/covid_GraphicalFcn.png\" alt=\"Monitoring infection spread\" \/><\/p>\n<li>If we determine that a new agent has been infected, the Stateflow chart calls a Simulink Function that generates a SimEvents Entity<\/li>\n<li>This entity is sent to a an Entity Server for a fixed amount of time to recover.<\/li>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/covid_getSick.png\" alt=\"Registering sick agent\" \/><\/p>\n<li>Once the recovery time is over, the Entity Server exit action calls a Simulink Function that updates the global data store accordingly.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/covid_healed.png\" alt=\"Registering healed agent\" \/><\/p>\n<p><strong>The Results<\/strong><\/p>\n<p>Here is a different result where I reduced the initial speed of the agents. It's interesting to see the impact on the propagation:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/virusSimGood.gif\" alt=\"Propagation at a slower rate.\" \/><\/p>\n<p><strong>Now it's your turn<\/strong><\/p>\n<p>Download our simulator on <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/75293-simulink-virus-simulator\">MATLAB Central<\/a> or directly from <a href=\"https:\/\/github.com\/guirlo\/Simulink-Virus-Simulator\">GitHub<\/a> and let us know what you think.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/simulink\/2020Q1\/virusSimGood.gif\" onError=\"this.style.display ='none';\" \/><\/div>\n<p>Update (10\/14\/2020): The GitHub repository now contains a MATLAB App to simulate the model and visualize the results. We compiled the app as a MATLAB Web App and host it in the cloud using the MATLAB... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2020\/03\/23\/covid-19-simulating-exponential-spread-in-simulink\/\">read more >><\/a><\/p>\n","protected":false},"author":41,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[34,56],"tags":[591,593],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/9405"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=9405"}],"version-history":[{"count":26,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/9405\/revisions"}],"predecessor-version":[{"id":9799,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/9405\/revisions\/9799"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=9405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=9405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=9405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}