Kurs:Räumliche Modellbildung/Gruppe 1
Gruppenseite - NWG
[Bearbeiten]Diese Seite enthält die gesammelten Materialien der Gruppe 1 - NWG für die Portfolioprüfung.
Teilnehmer-innen
[Bearbeiten]- Geiß, Annika
- Nebel, Ve
- Wolf, Sarah
Ziel der Veranstaltung
[Bearbeiten]Das Modul M11: Entwicklung der Mathematik in Längs- und Querschnitten unterteilt sich in zwei Teilbereiche, einmal die diskreten Prozesse (Herr Niehaus) und einmal die Kontinuierlichen Diffusionsprozesse (Frau Hundertmark). Beide dienen am Ende einer Modellierung der COVID-19-Pandemie. In beiden Teilen wurde sowohl die zeitliche als auch die räumliche Betrachtung eingebaut.
Diskrete Diffusionsprozesse (Niehaus)
[Bearbeiten]Thema und Ziel der Modellierung
[Bearbeiten]In der folgenden Modellierung soll zunächst mithilfe des sogenannten SIR-Modells (siehe Kompartimentmodelle) und danach mithilfe eines Schachbrettmusters einer 10x10-Matrix und einer Transportmatrix, die Verbreitung des Corona-Virus sowohl räumlich als auch zeitlich implementiert werden. Die Modellierung erfolgt mittels CoCalc, sodass die Modelle als Gruppenarbeit mit Octave implementiert werden können.
Arbeitsauftrag 1: SIR-Modell
[Bearbeiten]Versuch 1: Transportmatrix [1]
[Bearbeiten]Festlegung der Werte zum Startzeitpunkt
[Bearbeiten]Betrachtet wird das Beispiel Landau. Somit ergeben sich für S (Susceptible), I (Infected) und R (Removed) zum Zeitpunkt T0 vor der Infektion folgende Werte:
Der Vektor T0 setzt sich damit aus S,I und R zusammen und zeigt den Startzustand an.
Erstellen der Transportmatrix
[Bearbeiten]Die Transportmatrix gibt den Verlauf des Virus pro Tag an. Wir nehmen an, dass während der Krise 98 Prozent der infizierbaren Einwohner empfänglich für den Virus bleiben, während sich 2 Prozent wirklich infizieren. Von den infizerbaren Einwohnern wird keiner resistent. Betrachten wir nun die Infizierten. Hier nehmen wir an, dass 70 Prozent infiziert bleiben und 30 Prozent immun gegen den Virus werden.Bei den immunisierten Einwohnern nehmen wir an, dass diese sich nicht infizieren können sondern immun bleiben.
Somit ergibt sich folgende Transportmatrix :
Beispielsweise beträgt der Anteil an Empfänglichen, welche infiziert werden 0,02, also 2 %.
Anwendung des Virus auf die Stadt Landau
[Bearbeiten]Mit Hilfe einer Schleife (50 Tage) wird der Vektor , mit , und , täglich mit der Transportmatrix (in diesem Fall) multipliziert.
for hold on plot (i, Si, 'b') plot (i, Ii, 'r') plot (i, Ri, 'g') legend ("Succeptible","Infected","Recoverd" ) hold off endfor
Graphische Darstellung: SIR-Modell über eine Transportmatrix
[Bearbeiten]Da man den genauen Verlauf der Infizierten im oberen Graphen nicht genau sehen kann, haben wir ihn in unterem Graphen neu geplottet.
Verbesserungsideen
[Bearbeiten]Bemerkung
[Bearbeiten]Im Rahmenlehrplan Mathematik Rheinland-Pfalz sind Matrizen in den Wahlpflichtgebieten der Oberstufe vorgeschrieben. Im Grundfach gibt es das Wahlpflichtgebiet "Matrizen in der praktischen Anwendung", in welchem sich eine solche Modellierung durchaus eignet.
Versuch 2: Funktionen [2]
[Bearbeiten]Im zweiten Versuch soll der Verlauf der Infizierungen mehr einer Glockenkurve gleichen. Deshalb wird das Modell verbessert, indem wir anstelle einer Transportmatrix Funktionen für S, I und R erstellen, die den Verlauf der Pandemie möglichst gut abbilden.
Definition der Parameter
[Bearbeiten]* Infektionsrate: * Genesungsrate: * Anzahl der Tage:
t = linspace(0, N_t, N_t+1);
Erstellung der Vektoren
[Bearbeiten]In diesem Schritt werden jeweils Vektoren für S, I und R erstellt. Es handelt sich hierbei um Spaltenvektoren, die alle mit 0 versehen sind und die Dimension N_t+1 besitzen.
zeros; zeros; zeros;
Bestimmung der Anfangswerte
[Bearbeiten]Wir betrachten an dieser Stelle die Einwohnerzahl für die Stadt Landau (46677). Die Anfangswerte sehen dann wie folgt aus (relativer Anteil):
; ; %relativer Anteil eines Infizierten Einwohners ;
Zeitschleife
[Bearbeiten]Wir lassen nun eine Zeitschleife über die Anzahl der festgelegten Tage 1 bis 160 laufen und implementieren für S, I und R jeweils Funktionen, welche den Wechsel von S nach I, I nach R usw. beschreiben. Für die erste Funktion betrachten wir die Anzahl der Infizierbaren am Tag n+1. Dafür benötigen wir die Anzahl der Infizierbaren am Tag zuvor, also am Tag n. Da die Anzahl von S abnimmt muss nun die Anzahl der Infizierten subtrahiert werden. Dies erfolgt durch die Multiplikation von S mit I und der Infektionsrate beta. Die Multiplikation von S und I beschreibt die Anzahl der Möglichkeiten, sich bei einer gewissen Anzahl von Menschen zu infizieren (vgl. Kombinatorik). Die Anzahl der Infizierten, welche in der ersten Funktion abgezogen wurden, werden in der zweiten Funktion dazu addiert, da die Zahl der Infizierten ansteigt. Hinzu kommt bei I, dass diejenigen, die wieder gesund sind, von der Anzahl der Infizierten abgezogen werden und in der dritten Funktion bei R dazu addiert werden. Hier wird also die Genesungsrate gamma benötigt, um den Anteil von Genesenen der Infizierten zu berechnen. So findet ein Wechsel zwischen S, I und R statt.
for endfor
Graphische Darstellung: SIR-Modell über Funktionen
[Bearbeiten]hold on plot(t,S,'b'); plot(t,I,'r'); plot(t,R,'g'); axis([0 160 0 1.03]); legend ("Succeptible","Infected","Recoverd","location","east" ) hold off
Der dargestellte Graph zeigt den Verlauf unseres SIR-Modells. Die Kurve der Infizierten (rot) gleicht einer Glockenkurve und erreicht nach ca. 30 Tagen ihr Maximum.
mögliche Änderungen
[Bearbeiten]Verbesserungsideen
[Bearbeiten]- unterschiedlich lange Genesungsraten
- unterschiedliche Infektionsraten (angepasst an die Maßnahmen, z.B. Lockdown)
- räumliche Betrachtung
Arbeitsauftrag 2: Schachbrettmuster [3]
[Bearbeiten]Im folgenden Modell soll mithilfe eines Schachbrettmusters einer 10x10-Matrix und einer Transportmatrix, die Verbreitung des Corona-Virus sowohl räumlich als auch zeitlich implementiert werden.
Erzeugung des Schachbrettmusters
[Bearbeiten]Im ersten Schritt erzeugen wir ein Schachbrettmuster einer 10x10-Matrix. Anschaulich und in der realen Situation stehen die einzelnen Knoten des Schachbrettes für einen Ort oder zum Beispiel für einen Flughafen.
Nx=10;
Ny=10;
x=[1:Nx];
y=[1:Ny];
[x,y]=meshgrid(x,y);
figure (1)
hold on;
plot (x,y,'*k')
axis([1 10 1 10]);
hold off;
SIR: Anfangswerte generieren
[Bearbeiten]Nun müssen für jeden Gitterpunkt Anfangswerte für S, I und R festgelegt werden. Dazu werden die Anfangswerte für S zufällig gewählt. Für die Infizierten soll eine Matrix vorliegen die überall Nulleinträge besitzt, außer einem einzigen Wert. In diesem Ort beginnt die Infizierung. Die R-Anfangsmatrix ist eine Nullmatrix, da noch niemand die Infizierung überstanden hat.
round(rand round(ones round(zeros
Gesamtanzahl der einzelnen Orte werden bestimmt.
for a=1:10 for b=1:10 G(a,b)=S0(a,b)+I0(a,b)+R0(a,b); endfor endfor
Von S,I und R werden relative Anteile zum weiterrechnen erstellt.
S0=S0./G; I0=I0./G; R0=R0./G;
Nun soll die zeitliche Änderung betrachtet werden.
SIR: Funktionen einbauen
[Bearbeiten]Im folgenden werden für die drei Angfangsmatrizen jeweils neue Matrizen für die folgenden Tage berechnet. Dies kann man sich dann als eine 3D-Matrix vorstellen. Jeder weitere Tag bildet eine neue Matrix, die auf die vorherigen "gelegt" wird. Das ganze muss einmal für die Succesible, einmal für die Infected und schließlich für die Removed durchgeführt werden.
Definition der Parameter
[Bearbeiten]* Anzahl der Tage: * Infektionsrate: * Genesungsrate:
Aufstellung der Funktionen
[Bearbeiten]Die Funktionen entsprechen denen, die auch im Arbeitsauftrag 1 verwendet wurden. Eine solche Implementierung kann folgendermaßen aussehen:
Sx=S0; Ix=I0; Rx=R0; for t=1:N_t Sx=Sx-beta*Sx.*Ix; Ix=Ix+beta*Sx.*Ix-gamma*Ix; Rx=Rx+gamma*Ix; S=round(Sx.*G); I=round(Ix.*G); R=round(Rx.*G); hold on plot(t,S(7,7),'b',t,I(7,7),'r',t,R(7,7),'g',t,S(1,1),'bd',t,I(1,1),'rd',t,R(1,1),'gd',t,S(3,4),'bs',t,I(3,4),'rs',t,R(3,4),'gs') legend ("S (7,7) ","I (7,7) ","R (7,7) ","S (1,1) ","I (1,1) ","R (1,1) ","S (3,4) ","I (3,4) ","R (3,4) ","location","southeast" ) endfor
Plots für 3 Orte
[Bearbeiten]Transportmatrix
[Bearbeiten]Zufällige Transportmatrix
[Bearbeiten]Da für die Orte eine 10x10 Matrix gewählt wurde, muss für die Transportmatrix eine 100x100 Matrix generiert werden. Zunächst soll diese zufällig gewählt werden. Dabei muss aber die Summe der einzelnen Spalten 100% bzw. 1 ergeben da von einem Ort nicht mehr als 100% der Personen existieren.
for rand; sum; ; endfor
Anwendung auf Anfansmatrizen
[Bearbeiten]Um die 100x100-Transportmatrix auf die 10x10-S0-Matrix anwenden zu können, muss die S0-Matrix in einen langen Vektor mit 100x1 umgeformt werden. Nach der Matrizenmultiplikation kann der entstandene Vektor wieder in eine 10x10-Matrix umgeformt werden.
Sx=S0; Ix=I0; Rx=R0; for t=1:N_t Sx=Sx-beta*Sx.*Ix; Ix=Ix+beta*Sx.*Ix-gamma*Ix; Rx=Rx+gamma*Ix; Sx=reshape(Sx,100,1); Sx=T*Sx; Sx=reshape(Sx,10,10); S=round(Sx.*G); Ix=reshape(Ix,100,1); Ix=T*Ix; Ix=reshape(Ix,10,10); I=round(Ix.*G); Rx=reshape(Rx,100,1); Rx=T*Rx; Rx=reshape(Rx,10,10); R=Rx.*G; hold on plot(t,S(7,7),'b',t,I(7,7),'r',t,R(7,7),'g',t,S(1,1),'bd',t,I(1,1),'rd',t,R(1,1),'gd',t,S(3,4),'bs',t,I(3,4),'rs',t,R(3,4),'gs') legend ("S (7,7) ","I (7,7) ","R (7,7) ","S (1,1) ","I (1,1) ","R (1,1) ","S (3,4) ","I (3,4) ","R (3,4) ","location","southeast" ) endfor
Plots für 3 Orte
[Bearbeiten]Verbesserte Transportmatrix
[Bearbeiten]Nun soll berücksichtigt werden, dass die meisten Menschen den Ort nicht wechseln. Dies entspricht der Diagonale auf der Transportmatrix. Dazu soll zunächst eine Matrix mit passenderen Werten erstellt werden, die im nächsten Schritt normiert wird, sodass die einzelnen Spalten der Matrix wieder 1 ergeben.
Für die Diagonale werden nun Werte zwischen 50 und 90 festgelegt.
rand; ; ;
Dazu wird eine zweite Matix mit Werten zwischen 0 und 10 festgelegt. Alternativ hätte man die Werte hier auch kleiner wählen können.
B=rand(100,100)*10;
Die beiden Matrizen werden im nächsten Schritt addiert und anschließend normiert.
; for sum; ; ; endfor
Anwendung auf Anfansmatrizen
[Bearbeiten]Sx=S0; Ix=I0; Rx=R0; for t=1:N_t Sx=Sx-beta*Sx.*Ix; Ix=Ix+beta*Sx.*Ix-gamma*Ix; Rx=Rx+gamma*Ix; Sx=reshape(Sx,100,1); Sx=Tneu*Sx; Sx=reshape(Sx,10,10); S=round(Sx.*G); Ix=reshape(Ix,100,1); Ix=Tneu*Ix; Ix=reshape(Ix,10,10); I=round(Ix.*G); Rx=reshape(Rx,100,1); Rx=Tneu*Rx; Rx=reshape(Rx,10,10); R=round(Rx.*G); hold on plot(t,S(7,7),'b',t,I(7,7),'r',t,R(7,7),'g',t,S(1,1),'bd',t,I(1,1),'rd',t,R(1,1),'gd',t,S(3,4),'bs',t,I(3,4),'rs',t,R(3,4),'gs') legend ("S (7,7) ","I (7,7) ","R (7,7) ","S (1,1) ","I (1,1) ","R (1,1) ","S (3,4) ","I (3,4) ","R (3,4) ","location","southeast" ) endfor
Plots für 3 Orte
[Bearbeiten]Transportmatrix mit Berücksitigung der Distanz
[Bearbeiten]Für die Ortswechsel soll nun die Distanz der einzelnen Orte berücksichtigt werden. Je näher Orte aneinander liegen, desto eher findet ein Austausch statt. Eine Möglichkeit die Distanz zu berücksichtigen ist, diese reziprok in die Transportmatrix einzubauen. Dadurch folgt, je näher die Orte, desto größer der Wert in der Matrix. Damit jedoch nicht durch Null geteilt wird, wenn der Abstand eines Ortes zu sich selbst bestimmt wird, wird eingesetzt.
Zunächst wird die Distanz in einer Funktion definiert.
function ret=norm(i,j); ret =sqrt(i^2+j^2); endfunction function dist=distanz(i,j,k,l); dist = norm(i-k,j-l); endfunction
In einer Schleife wird nun ein Vektor XX gebildet, der die Distanz zwischen allen Punkten in der Form enthält. Anschließend wird der Vektor in eine 100x100-Matrix überführt.
XX=0; for i=1:Nx for j=1:Ny norm(i,j); for k=1:Nx for l=1:Ny Xneu=(1/(1+norm(i-k,j-l))); XX=[XX Xneu]; endfor endfor endfor endfor XX(2:10001); XXX=reshape(XX(2:10001),100,100);
for n=1:100 P=XXX(1:100,n)/sum(XXX(1:100,n)); Tneu2(1:100,n)=P; endfor
Anwendung auf Anfansmatrizen
[Bearbeiten]Sx=S0; Ix=I0; Rx=R0; for t=1:N_t Sx=Sx-beta*Sx.*Ix; Ix=Ix+beta*Sx.*Ix-gamma*Ix; Rx=Rx+gamma*Ix; Sx=reshape(Sx,100,1); Sx=Tneu2*Sx; Sx=reshape(Sx,10,10); S=round(Sx.*G); Ix=reshape(Ix,100,1); Ix=Tneu2*Ix; Ix=reshape(Ix,10,10); I=round(Ix.*G); Rx=reshape(Rx,100,1); Rx=Tneu2*Rx; Rx=reshape(Rx,10,10); R=round(Rx.*G); hold on plot(t,S(7,7),'b',t,I(7,7),'r',t,R(7,7),'g',t,S(1,1),'bd',t,I(1,1),'rd',t,R(1,1),'gd',t,S(3,4),'bs',t,I(3,4),'rs',t,R(3,4),'gs') legend ("S (7,7) ","I (7,7) ","R (7,7) ","S (1,1) ","I (1,1) ","R (1,1) ","S (3,4) ","I (3,4) ","R (3,4) ","location","southeast" ) endfor
Plots für 3 Orte
[Bearbeiten]Transportmatrix mit Berücksitigung der Infiziertenbewegung
[Bearbeiten]Da sich die Infizierten kaum bewegen soll für die Infizierten die Zuhausebleibematrix und für beide anderen Gruppen die Distanzmatrix gelten (s.o.).
Plots für 3 Orte
[Bearbeiten]Weitere Vorgehensweise - Möglichkeiten
[Bearbeiten]- Zeitschritte variieren (z.B. in jedem Zeitschritt, wöchentlich usw.)
- Reelle Orte und Distanzen einbauen
Skripte in Cocalc
[Bearbeiten]A1:SIR-Modell über Transportmatrix [4]
A1:SIR-Modell über Funktionen [5]
A2:Schachbrettmuster [6]
Kontinuierliche Diffusionsprozesse (Hundertmark)
[Bearbeiten]Thema und Ziel der Modellierung
[Bearbeiten]Im folgenden werden verschiedenen Modelle auf die Corona-Situation angewendet. Die Berechnungen sollen möglichst aussagekräftige bzw. realistische Vorhersagen über die Verbreitung des Virus treffen.
1.Tutoriumsaufgabe: Kontaktmodell [7]
[Bearbeiten]Das Kontaktmodell beschreibt die räumliche Ausbreitung einer Infektion durch direkten Kontakt von sich bewegenden Menschen. Ab einem gewissen Abstand erfolgt automatisch eine Infizierung.
Erstellung eines 20x20 Schachbrettmusters
[Bearbeiten]Zunächst wird eine 20x20-Matrix erstellt, sowie einige Parameter festgelegt.
; ; ; %Bewegungsgeschwindigkeit ; %Zeiteinheit ; %pro Zeiteinheit ; ; ; meshgrid;
Damit dieses als Schachbrettmuster angezeigt wird, werden folgende Befehle benötigt. Hierbei werden die Matrixeinträge als Blaue Sterne festgelegt. Diese entsprechen jeweils einer realen Person, zunächst nur statisch, also ohne Bewegung.
figure (1)
hold on;
plot(x,y, '*b') ;
axis([-5 25 -5 25]);
hold off;
Generieren einer Bewegung
[Bearbeiten]Im nächsten Schritt soll die Bewegung generiert werden, damit sich die einzelnen Punkte des Schachbrettmusters (also Personen) bewegen. Die Bewegungsrichtung sowie die zurückgelegte Entfernung soll zufällig sein, was durch den Befehl "rand" gewährleistet wird.
Mit dem Befehl rand wird eine NyxNx-Matrix, also in unserem Fall eine 20x20-Matrix mit Werten zwischen 0 uns 1 erstellt. Durch Subtraktion von 0.5 werden die Zufallszahlen in das Intervall verschoben. Somit wird die neue Position jeders Punktes durch Addition der Zufallszahl zwischen -0.5 und 0.5 zur ensprechenden x,y-Koordinate generiert und mit der Geschwindigkeit g skalliert.
neuPosX=x.+g.*rand(Ny,Nx)-0.5*g; neuPosY=y.+g.*rand(Ny,Nx)-0.5*g;
Die neue Position wird jedoch nicht in einem Schritt erreicht. In jedem Zeitschritt wird nur der entsprechende Bruchteil zur alten Position addiert. Daher muss eine Zeitschleife generiert werden.
for i=1:T*Zeitschritte neuX=x.+1*(neuPosX.-x)*i*dt; % dt = 1/Zeitschritte neuY=y.+1*(neuPosY.-y)*i*dt; figure (i+1) title (['t=' num2str(i·dt)]) axis([-5 25 -5 25]); hold on; plot(neuX,neuY, '*b') ; hold off; endfor
Infizierter hinzufügen
[Bearbeiten]Nun soll ein Infizierter hinzukommen. Dieser ist durch ein rotes Quadrat gekennzeichnet und wird zunächst in die Mitte des Schachbrettmusters gesetzt. Außerdem wird ein Ansteckungsradius als Abstandsschranke festgelegt.
%Ansteckungsradius
figure (11) hold on; plot(x,y, '*b') ; plot(xInf,yInf, "sr") axis([-5 25 -5 25]); hold off;
Bewegung mit Infiziertem
[Bearbeiten]Die neue Position der einzelnen Individuen ist unabhägig von einer Infizierung und entspricht daher der normalen Generierung einer Bewegung.
neuPosX=x.+g.*rand(Ny,Nx)-0.5*g; neuPosY=y.+g.*rand(Ny,Nx)-0.5*g;
Allerdings muss die Zeitschleife angepasst werden, da nicht nur in der Endposition, sondern in jedem Zeitschritt der Abstand zwischen den einzelnen Individuen überprüft werden muss. Ist dieser kleiner als der Ansteckungsradius, so wird die Infektion übertragen und es entsteht ein neuer Infizierter.
for i=1:T*Zeitschritte neuX=x.+1*(neuPosX.-x)*i*dt; neuY=y.+1*(neuPosY.-y)*i*dt; figure (i+20) title(['t=' num2str(i*dt)]) axis([-5 25 -5 25]); hold on plot(neuX,neuY, '*b'); for k1=1:length(IndInf1) for j=1:Nx for l=1:Ny abstand=norm([neuX(l,j)-neuX(IndInf1(k1),IndInf2(k1)), neuY(l,j)-neuY(IndInf1(k1),IndInf2(k1))]); if abstand<radiusInf1 %Abstand<Asteckungsradius? abstand; plot(neuX(l,j),neuY(l,j), 'sr') %Färbe rot k2=1; while k2 <=length(IndInf1)&&(l!=IndInf1neu(k2) || j!=IndInf2neu(k2)) % Überprüfen: Schon in Vektor der Infizierten enthalten? k2=k2+1; endwhile if k2 >length(IndInf1) IndInf1neu=[IndInf1neu l]; IndInf2neu=[IndInf2neu j]; endif endif endfor endfor endfor IndInf1=IndInf1neu; IndInf2=IndInf2neu; hold off lengt=length(IndInf1); endfor
Änderung Ansteckradius
[Bearbeiten]Im folgenden soll die Auswirkung eines veränderten Ansteckungsradius demonstriert werden. Dabei bleibt der Code der Implementierung gleich. Nur der Wert des Ansteckungsradius wird variiert.
- größerer Ansteckradius:
radiusInf1=0.95 %vorher 0.80
- kleinerer Ansteckradius:
radiusInf2=0.60
Ergebnis: An den Animationen auf der rechten Seite kann man erkennen, dass sich der Verlauf der Infizierungen deutlich verändert, sobald der Ansteckungsradius variiert wird. So zeigt sich zum Beispiel, dass sich bei einem größeren Ansteckungsradius mehr Menschen in kürzerer Zeit infizieren als bei einem kleineren Ansteckungsradius.
Änderung Bewegungsgeschwindigkeit
[Bearbeiten]Ebenso soll der Einfluss der Bewegungsgeschwindigkeit demonstriert werden. Dazu werden folgende Veränderungen im Code vorgenommen:
- höhere Geschwindigkeit:
neuX=x.+5*(neuPosX.-x)*i*dt;
neuY=y.+5*(neuPosY.-y)*i*dt; %vorher neuY=y.+1*(neuPosY.-y)*i*dt
- niedrigere Geschwindigkeit:
neuX=x.+0.2·(neuPosX.-x)·i·dt; neuY=y.+0.2·(neuPosY.-y)*i·dt;
Ergebnis:Auch hier kann man erkennen, dass die Veränderung der Bewegungsgeschwindigkeit Auswirkungen auf den Verlauf der Infizierung hat. Bei einer höheren Geschwindigkeit werden deutlich mehr Menschen infiziert. Bei geringerer Geschwindigkeit verläuft die Infizierung langsamer.
Änderung Bewegungsrichtung
[Bearbeiten]Richtungsänderung in jedem Zeitschritt
for i=1:T*Zeitschritte x=neuX; y=neuY; neuPosX=x.+g.*rand(Ny,Nx)-0.5*g; neuPosY=y.+g*rand(Ny,Nx)-0.5*g; neuX=x.+1*(neuPosX.-x)*i*dt; neuY=y.+1*(neuPosY.-y)*i*dt; ... endfor
Um die Schritte besser nachvollziehen zu können werden Richtungspfeile angezeigt:
quiver(neuX,neuY,neuPosX.-x, neuPosY.-y)
Änderung Anfangsposition des Infizierten
[Bearbeiten]- Rand:
xInf=x(1,Nx/2);
yInf=y(1); %vorher yInf=y(Ny/2);
IndInf2=Nx/2;
IndInf1=1;
- Ecke:
xInf=x(1,1); yInf=y( 1); IndInf2=1; IndInf1=1;
Ergebnis: Je weiter die infizierte Person am Rand ist, desto weniger Menschen werden angesteckt. Je mehr Menschen sich um den Infizierten befinden, desto höher ist die Gefahr, dass diese infiziert werden.
Verbesserungsideen
[Bearbeiten]- Wenn Abstand < Infektionsradius, folgt nur unter einer bestimmten Warscheinlichkeit eine Ansteckung
Vorteile dieses Modells
[Bearbeiten]- Betrachtung der Verbreitung auf kleinstem Raum (Bsp: Supermarkt, Straße)
2.Tutoriumsaufgabe: Fundamentallösungen der Poisson und der Diffusionsgleichung [8]
[Bearbeiten]Der folgenden Modellierung ist die räumliche Diffusion zu Grunde gelegt. Dies meint die zufällige Bewegung von Teilchen, sodass ein vorliegender Konzentrationsunterschied ausgeglichen wird und mit der Zeit eine vollständige Durchmischung eintritt. Mathematisch wird ein Diffusionsprozess folgendermaßen beschrieben:
Dabei ist
- die unbekannte Teilchenkonzentrationsdichte/Temperaturdichte und
- der ortsabhängige Diffusion-/Wärmeleitkoeffizient.
Teil 1: Stationäre Diffusion
[Bearbeiten]Wird jedoch nur der stationäre Fall , also der Gleichgewichtszustand betrachtet, so ist die Zeitableitung gleich Null. Gilt außerdem , so liegt die bekannte Laplace-Gleichung vor.
Die in dieser Tutoriumsaufgabe verwendete Poisson-Gleichung entspricht der inhomogenen Laplace-Gleichung. Hier ist die Funktion der rechten Seite, welche die Dichtefunktion der Flussgeschwindigkeit in das System hinein beschreibt. Anders formuliert entspricht der kontinuierlichen Infektionsquelle, also einem oder mehreren Hotspots.
Für die Modellierung muss vorrausgesetzt werden, dass einen kompakten (beschränkten)Träger inerhalb des Gebietes besitzt.
Funktion der rechten Seite
[Bearbeiten]Zunächst wird die Funktion der rechten Seite definiert.
function wert=Quellfunktion(x,y) if sqrt((x.-6).^2+(y.-6).^2)<=0.15 wert=1; else wert=0; if sqrt((x.-6).^2+(y.-0).^2)<=0.15 wert=1; else wert=0; if sqrt((x.-0).^2+(y.-6).^2)<=0.15 wert=1; else wert=0; if sqrt((x.-0).^2+(y.-0).^2)<=0.15 wert=1; else wert=0; if sqrt((x.-3).^2+(y.-3).^2)<=0.15 wert=0.5; else wert=0; endif endif endif endif endif endfunction
Definition des Gebietes
[Bearbeiten]Im folgenden wird ein rechteckiges Gebiet mit Hilfe eines Gitters definiert, wobei die Schrittweite mit festgelegt wird.
step=0.1; X=[0:step:6]; Y=[0:step:6]; [x,y]=meshgrid(X,Y);
Speichern der Funktionswerte von f in jedem Gitterpunkt
[Bearbeiten]Auf dem definierten Gebiet soll nun die Infektionsquelle festgelegt werden. Dazu müssen die Funktionswerte von f in jeden einzelnen Gitterpunkt der Matrix gespeichert werden.
for i=1:(length(X)) for j=1:(length(Y)) f(j,i)=1*Quellfunktion(x(j,i),y(j,i)); endfor endfor
Graphisch sieht dies nun folgendermaßen aus:
Die Abbildung zeigt in unserem Fall 4 Träger, also 4 Infektionsquellen, an denen kontinuierlich ein Stoff aus einer Quelle hinzugefügt wird. Übertragen auf die Corona-Ausbreitung finden wir hier 4 Hotspots von Infizierten vor.
Implementierung der Poisson-Gleichung
[Bearbeiten]Die Lösung der Poisson-Gleichung lässt sich mithilfe der Faltung der Fundamentallösung der Laplace-Gleichung und der Funktion der rechten Seite berechnen.
Die Fundamentallösung der Laplace-Gleichung für hat folgende Formel:
Zuerst werden die Werte der Fundamentalfunktion für jeden Gitterpunkt um ein festes verschoben und in der Matrix 'phi' gespeichert.
Dazu wird als Matrix mit konstanten Einträgen durch Konstruktion einer Schleife definiert, damit die Differenz der Funktionsargumente als Differenz von Matrizen möglich ist.
Nun muss noch beachtet werden, dass singulär wird (d.h. ), wenn . Um diesen Punkt der Singularität auszuschneiden, setzen wir für . Durch die klein gewählte Schrittweite beeinflusst dies das Ergebnis kaum.
Das doppelte Integral kann mit der Trapezregel berechnet werden.
fori=1:(length(X)) for j=1:(length(Y)) xstar=x(j,i)*ones(length(Y),length(X)); ystar=y(j,i)*ones(length(Y),length(X)); % Phi mit verschobenem Argument: phi=-log(sqrt((xstar.-x).^2+(ystar.-y).^2))/(2*pi); phi(j,i)=0; % numerische Integration: I(j,i) = trapz(Y,trapz(X,phi.*f,2)); endfor endfor
Die Graphik dazu wird durch folgenden Befehl von Octave ausgegeben.
figure 1 meshc(x,y,I) grid on title ('Losung von Poissongleichung') xlabel('x') xlabel ('y')
Die Abbildung zeigt die Lösung der Poissongleichung, die durch doppelte Integration auf unserem Gebiet von 0 bis 2 entsteht. Diese beschreibt die Verteilung des Stoffes (ausgehend von unserer oben definierten Funktion der rechten Seite).
Teil 2: Instätionäre Diffusion
[Bearbeiten]Weiterführend soll außerdem die instationäre Diffusion betrachtet werden. Dabei wird eine zeitabhängige Diffusion als Anfangswertproblem betrachtet. Mit einem konstanten Diffusionskoeffizienten folgt die homogene Differenzialgleichung , für welche eine spezielle Lösungsformel existiert: wobei das Quadrat der euklidischen Norm von ist.
Anfangsfunktion
[Bearbeiten]Zunächst wird eine neue Anfangsfunktion mit kompaktem Träger aufgestellt.
function wert=Anfangslosung(x,y) if sqrt((x.-2).^2+(y.-4).^2)<=0.05 wert=1; else wert=0; if sqrt((x.-4).^2+(y.-2).^2)<=0.04 wert=0.5; else wert=0; if sqrt((x.-1).^2+(y.-1).^2)<=0.04 wert=1; else wert=0; endif endif endfunction
Auch hier müssen die Funktionswerte von in jeden Gitterpunkt der Matrix gespeichert werden.
for i=1:(length(X)) for j=1:(length(Y)) u0(j,i)=1*Anfangslosung(x(j,i),y(j,i)); endfor endfor
Zeitparameter
[Bearbeiten]Im folgenden wird der Zeitrahmen festgelegt. Außerdem wird der Diffusionskoeffizient a festgelegt. Um zu verhindern, dass singulär wird (d.h. ), wählen wir .
T=2; Zeitschritte=2; dt=1/Zeitschritte; t0=0.001; a=0.2;
Immplementieren der Lösungsformel
[Bearbeiten]Ähnlich wie im stationären Fall kann die Lösung mithilfe einer Faltung der Fundamentallösung und der Anfangsfunktion berechntet werden.
In hat die Fundametallösung nun folgende Form:
Die Berechnung der Fundamentallösungsmatrizen 'psi' zu den verschiedenen Zeitpunkten erfolgt mittels einer Zeitschleife. Ebenso wie in der Zeitunabhängigen Diffusion werden zuerst die Werte der Fundamentalfunktion für jeden Gitterpunkt um ein festes verschoben und in der Matrix 'psi' gespeichert.
Auch hier kann das doppelte Integral mit der Trapezregel berechnet werden. Damit nach der Zeitschleife auf die verschiedenen Lösungen zugegriffen werden kann, werden diese mit dem Befehl gespeichert.
for k=0:T*Zeitschritte t=t0+k*dt for i=1:(length(X)) for j=1:(length(Y)) xstar=x(j,i)*ones(length(Y),length(X)); ystar=y(j,i)*ones(length(Y),length(X)); psi= (1/(4*pi*a*t))*(exp(-((xstar.-x).^2+(ystar.-y).^2))/(4*a*t)); J(j,i) = trapz(Y,trapz(X,psi.*u0,2)); endfor endfor Losung(:,:,k+1)=J; endfor
Durch eine weitere Schleife können die Grahiken ausgegeben werden
for k=0:T*Zeitschritte figure(k+1) meshc(x,y,Losung(:,:,k+1)) grid on title(['Losung der Differenzialgleichung in t=', num2str(t0+k*dt)]) xlabel('x') ylabel('y') test=["Fig_", num2str(k+1),".jpg"] %Speichern der Bilder saveas(k+1, test) endfor
Veränderungen
[Bearbeiten]3.Tutoriumsaufgabe: Kompartimentmodelle für die dynamische Beschreibung der Infektionsverbreitung und die Datenlage [9]
[Bearbeiten]In dieser Tutoriumsaufgabe soll die Verbreitung des Corona-Virus mithilfe der sogenannten Kompartimentmodelle beschrieben werden. Diese gehören zum logistischen Wachstumsmodell, welches ein Populationswachstum beschreiben, dass eine Verlangsamung erfährt, wenn es weniger Kapazität im System gibt. Bezogen auf den Corona-Virus meint die freie Kapazität die Gesamtbevölkerung abzüglich aller Infizierten, Immunen, und Verstorbenen . Die Ausbreitung des Virus wird also langsamer, wenn nicht mehr so viele noch nicht infizierte Individuen übrig sind, um sich anzustecken. Auf diesem Prinzip beruht auch die Herdenimmunität.
Mathematisch besagt das logistische Wachstumsmodell, dass Anstieg der Infizierungen in neuen Zeitpunkt , proportional zum Bestand und der freien Kapazität ist. Dabei ist die logistische Wachstumsrate bzw. Infektionsrate. Damit gilt:
Über die Division von und den Grenzübergang erhält man die Differenzialgleichung
mit der Lösung:
Bei den Kompartimentmodellen werden nun unterschiedliche Populationgruppen und deren Wechselwirkungen betrachtet. Zunächst betrachten wir das vereinfachte SI-Modell, anschließend das SIR- und zuletzt das modifizierte SIR-Modell.
SI Modell
[Bearbeiten]Im SI Modell steht für susceptible (Empfängliche) und für infected (Infizierte). In diesem Modell gelten folgende Gleichungen:
- ;
- ;
- ;
- ;
Dabei ist die Infektionsrate und die Gesamtbevölkerung.
Es soll angenommen werden, dass die Kapazität der deutschen Bevölkerung (83 Mio.), die sich infizieren wird 2 Drittel beträgt, also 55.000.000.
Es gilt hier das Erhaltungsgesetz , das beschreibt, dass die Gesamtpopulation konstant erhalten bleibt.
Definition der Parameter
[Bearbeiten]B= 55000 %Kapazität (in Tausend) k= 0.32450 %Infektionsrate times=(0:0.1:180); %Zeitspanne I0= 16/1000 %Anzahl der Infizierten in T0
%Anfangswerte als Spaltenvektor
yo=[B-I0; I0;]
Funktion der rechten Seite einbauen
[Bearbeiten]Definiere die Funktion f der rechten Seite des DGL-Systems
% Vektorwertige Funktion f
f=@(y,x) [-k*y(1)*y(2)/B;k*y(1)*y(2)/B;]
%numerische Lösung
y = lsode (f, yo, times);
Graphische Darstellung SI Modell
[Bearbeiten]Betrachtung verschiedener Infektionsraten
[Bearbeiten]Wir betrachten hier verschiedene allgemeine Infektionsraten, erst einmal unabhängig von der Corona-Verbreitung.
k0= 0.1; k1= 0.2; k2= 0.5; k3= 0.8; k4= 0.99;
Es werden nun für jede Infektionsrate die jeweilige Funktion der rechten Seite gebildet:
% Vektorwertige Funktion f
t=@(y,x) [-k0*y(1)*y(2)/B;k0*y(1)*y(2)/B];
g=@(y,x) [-k1*y(1)*y(2)/B;k1*y(1)*y(2)/B];
h=@(y,x) [-k2*y(1)*y(2)/B;k2*y(1)*y(2)/B];
m=@(y,x) [-k3*y(1)*y(2)/B;k3*y(1)*y(2)/B];
n=@(y,x) [-k4*y(1)*y(2)/B;k4*y(1)*y(2)/B];
Ergebnis
[Bearbeiten]Die gewählten Infektionsraten zeigen große Unterschiede in Bezug auf die Ausbreitungsgeschwindigkeit. Je größer die Infektionsrate desto schneller findet die Infizierung statt. Bei einer Infektionsrate k>0.4 sind die Verläufe allerdings in Bezug auf die aktuelle Corona-Verbreitung unrealistisch (siehe Datenvergleich), da die tatsächliche Übertragung von Corona langsamer verläuft.
SIR Modell
[Bearbeiten]Das SIR Modell betrachtet im Vergleich zum SI Modell eine neue Gruppe der genesenen Individuen, die nach der Genesung die Gruppe der Infizierten verlassen und in die Gruppe der Genesenen oder Toten (R) mit einer bestimmten Rate wechseln.
Im SIR Modell steht S für susceptible (Empfängliche), I für infected (Infizierte) und R für removed (Genesene). In diesem Modell gelten folgende Gleichungen:
Dabei ist die Infektionsrate, die Gesamtbevölkerung und der Umkehrwert der Genesungszeit .
Es soll angenommen werden, dass die Kapazität der deutschen Bevölkerung 2 Drittel beträgt. Damit gilt für B (in Tausend):
Es gilt hier das Erhaltungsgesetz , das beschreibt, dass die Gesamtpopulation konstant erhalten bleibt.
Definition der Parameter
[Bearbeiten]B= 55000 %Kapazität (in Tausend) k= 0.32450 %Infektionsrate w=1/14 % Wechselrate zu den Genesenen times=(0:0.1:180);%Zeitspanne I0= 16/1000 %Anzahl der Infizierten in T0 R0= 0 %Anzahl der Genesenen in T0
%Anfangswerte als Spaltenvektor
yo=[B-I0; I0; R0]
Funktion der rechten Seite einbauen
[Bearbeiten]% Vektorwertige Funktion f
f=@(y,x) [-k*y(1)*y(2)/B;k*y(1)*y(2)/B-w*y(2);w*y(2)];
%numerische Lösung
y = lsode (f, yo, times);
Graphische Darstellung
[Bearbeiten]Betrachtung verschiedener Infektionsraten
[Bearbeiten]Wir betrachten hier verschiedene Infektionsraten für allgemeine Verbreitungen. Die Raten k>0.4 sind für die Corona-Verbreitung unrealistisch, aber zeigen interessante Verhalten der Kurven.
k0= 0.1; k1= 0.2; k2= 0.5; k3= 0.8; k4= 0.99;
% Vektorwertige Funktion f
t=@(y,x) [-k0*y(1)*y(2)/B;k0*y(1)*y(2)/B-w*y(2);w*y(2)];
g=@(y,x) [-k1*y(1)*y(2)/B;k1*y(1)*y(2)/B-w*y(2);w*y(2)];
h=@(y,x) [-k2*y(1)*y(2)/B;k2*y(1)*y(2)/B-w*y(2);w*y(2)];
m=@(y,x) [-k3*y(1)*y(2)/B;k3*y(1)*y(2)/B-w*y(2);w*y(2)];
n=@(y,x) [-k4*y(1)*y(2)/B;k4*y(1)*y(2)/B-w*y(2);w*y(2)];
Im Graphen für k0=0.1 kann der Verlauf nicht erfasst werden, da dieser außerhalb des betrachteten Zeitraums liegt. Daher soll im folgenden eine größere Zeitspanne betrachtet werden.
Ergebnis
[Bearbeiten]Auch hier kann man erkennen, dass die Infektionsraten für k>0.4 unrealistisch für die Corona-Verbreitung ist. Bei k=0.99 wäre die Infektion bereits im März überstanden. Das macht, bezogen auf Corona, keinen Sinn.
Modifiziertes SIR Modell
[Bearbeiten]Das modifizierte SIR Modell soll eine Anpassung des ursprünglichen SIR Modells darstellen. Es ist vor allem relevant bei der Betrachtung der aktuellen Daten, also der gemeldeten Infizierten-Zahlen. Bei wurde die Annahme getroffen, dass lediglich 10% der Infizierten gemeldet wurden. Die tatsächlich Infizierten zeigen zum Beispiel keine Symptome und wurden daher nicht als krank erfasst. In diesem Modell gelten folgende Gleichungen:
Zu den Parametern:
- ist die Kapazitätsgrenze (Bevölkerung, die sich insgesamt ansteckt)
- verschiedene Infektionsraten,
- ist die konstante Sterberate, mit der die Infizierten aus der Gesamtpopulation ausscheiden,
- beschreibt die Population der Genesenen (ohne Tote),
- ist ein konstanter Faktor, der den prozentualen Anteil, der durch Tests erfassten Infizierten (Erkrankten) beschreibt
- ist die tägliche Wechselrate der Infizierten in die Gruppe der Genesenen (oder Toten), 14 Tage Genesungszeit
Es gilt hier das Erhaltungsgesetz , das besagt, dass sich die Gesamtpopulation um die verstorbenen Infizierten verringert. Falls werden die Toten in der Gruppe R der Genesenen mitgezählt und es folgt . Gilt zusätzlich erhalten wir das original SIR Modell.
Aktuelle Daten
[Bearbeiten]Um die aktuellen Daten der Corona-Verbreitung darzustellen, wird eine vorgegebene coronaData-Datei verwendet, welche die vom RKI ermittelten täglichen Daten der Corona-Infizierten in Deutschland seit dem 26. Februar 2020 enthält. Wir erhalten so eine Rückgabe-Matrix, die uns in der ersten Zeile die kumulierten Infizierten, in der zweiten Zeile die Todesfälle und in der dritten Zeile die Genesenen speichert.
A=coronaData(); Infizierte=A(1,:); Tote=A(2,:); Genesene=A(3,:);
Die aktuell Infizierten ergeben sich aus der Differenz aller Infizierten und der Genesenen:
Infizierte_aktuell=Infizierte-Genesene; n=length(Infizierte); times=[0:1:n-1];
Graphische Darstellung
Bestimmung einer geeigneten Infektionsrate
[Bearbeiten]Es soll nun eine geeignete Infektionsrate c bestimmt werden, die das exponentielle Wachstum (bis ca. Ende April 2020) einigermaßen gut abbildet. Hierfür wird folgende exponentielle Funktion mit den Daten des RKIs bzgl. der Infizierten in Deutschland verglichen.
Wir betrachten für die folgende Funktion die ersten 30 Tage, da dieser Teil der Glockenkurve am ehesten einer exponentiellen Funktion gleicht. Werden deutlich mehr Tage betrachtet, kann die Exponentialfunktion nicht mehr als Annäherung dienen:
t_0=0; I_0=16; k=0.254; %Bestimmung siehe unten t=[1:1:30];
In der folgenden Abbildung sind die Graphen der gewählten Exponentialfunktion (orange) und der RKI Daten (blau) dargestellt.
Bestimmung des Residuums
[Bearbeiten]Im folgenden soll das Residuum bestimmt werden. Dies gilt als Abweichung von einem gewünschten Ergebnis. Es gilt: Je kleiner das Residuum ist, desto näher liegt die Näherung bei der Lösung. Das Residuum kann somit als Maß der Abweichung der Näherung von der exakten Lösung betrachtet werden (siehe Residuum).
Zunächst wird die Abweichung für jeden Punkt bestimmt. Die Summe gibt den gesamten Fehler in Form des Residuums an.
for i=1:30 %Berechnung für jeden der 30 Tage Infizierte=A(1,i); I(i)=I_0*exp(k*(i-t_0)); S(i)=(Infizierte.-I(i)).^2; endfor j=[1:30]; S(j) Summe=sum(S(j)) %Gesamtabweichung aller Tage
Anpassung von c
Das Residuum kann für verschiedene Infektionsraten bestimmt werden. Dafür wird die Infektionsrate zwischen 0.2 und 0.3 in 0.002er Schritten verwendet. Durch Augenmaß konnten kleinere und größere Infektionsraten ausgeschlossen werden.
Summe=0; for k=[0.2:0.002:0.3] for i=1:30 Infizierte=A(1,i); I(i)=I_0*exp(k*(i-t_0)); S(i)=sum((Infizierte.-I(i)).^2); endfor j=[1:30]; S(j); Summe=[Summe , sum(S(j))]; endfor
Davon wird das minimale Residuum bestimmt. Außerdem sollen die verschiedenen Residuen graphisch gegenübergestellt werden.
MIN=min (Summe(2:length(Summe))); index=find(Summe==MIN); k=[0.2:0.002:0.3]; optim_Infrate=k(index)
Ergebnis
[Bearbeiten]Nachdem wir nun das Minimum der Residuen bestimmt haben und den zugehörigen Graphen analysiert haben, folgt, dass damit die geeignete Basisinfektionsrate bei liegt.
Einbauen einer Slowdown-Funktion
[Bearbeiten]Im folgenden Schritt sollen zwei verschiedene Slowdown-Funktionen zur Verlangsamung der Infektionsrate eingebaut und miteinander verglichen werden. Es soll überprüft werden, welche der beiden Funktionen besser in Einklang mit den Kontakt- und Lockerungsmaßnahmen stehen.
Folgende Kontakt- und Lockerungsmaßnahmen spielen dabei eine Rolle:
* Schulschließung am 15.März (Tag 19) * Kontaktverbot am 22.März (Tag 26) * Lockerung der Maßnahmen ab 27.April (Tag 61)
Slowdown-Funktion-1
Ab Tag t (Argument der Funktion) wird die Infektionsrate in mehreren Schritten sinken.
function val=slowdown(x,t) if x<t val=1 ; else if x<t +10 val=t./(x.^1.05); else if x<t +22 val=t./(x.^1.2); else val=t./(x.^1.27) ; endif endif endif if x> 80 val=0.5; endif endfunction
Die beispielhafte Lockerung der Maßnahmen gilt ab Tag 80, welche die Infektionsrate wieder auf 50% der Basisinfektionsrate erhöht. So kann der Effekt der Lockerung zu beispielhaft beobachtbar gemacht werden.
Slowdown-Funktion-2
function val=slowdown2(x,t) if x<t val=1 ; else if x<t +8 val=t./(x.^1.1); else if x<t +16 val=t./(x.^1.25); else if x<t +22 val=t./(x.^1.4); else val=t./(x.^1.5) endif endif endif endif if x> 80 val=0.5; endif endfunction
Vergleich RKI Daten mit Slowdown-Funktion
[Bearbeiten]Im folgenden wird die Infektionsrate aus den RKI- Daten berechnet: , wobei die kumulative Anzahl der Infizierten (RKI-Data) bezeichnet, t- Zeit in Tagen.
A=coronaData(); Infizierte=A(1,:); Genesene=A(3,:); Tote=A(2,:); Infizierte_aktuell=Infizierte-Genesene; n=length(Infizierte); times=[0:1:n-1]; c=0.3245; k=0.254; for i=1:length(times) cc(i)=slowdown (times (i), 25)*c; hh(i)=slowdown2(times (i), 25)*c; kk(i)=slowdown2 (times (i), 25)*k; endfor
Berechnung der Infektionsrate aus den RKI-Daten:
T=1; ccc(1)=cc(1); for i=T+1:n ccc(i-T)=(Infizierte(i)-Infizierte(i-T))/(Infizierte(i-T) ); endfor
Ergebnis In der obigen Abbildung kann man erkennen, dass die 2. Slowdown-Funktion mit der zuvor angepassten Infektionsrate von 0.254 am besten zu den tatsächlichen Daten des RKI passt.
Relativer Fehler
[Bearbeiten]Um das vorherige Ergebnis zu verifizieren, wird im folgenden Abschnitt der relative Fehler der Infizierten berechnet.
B=55000; I0=16/1000; R0=0; r=0.1; w=1/14; t=(0:0.1:180); yo=[B-I0; I0; R0];
f=@(y,x) [-c*slowdown(x,25)*y(1)*y(2)/(r*B);c*slowdown(x,25)*y(1)*y(2)/B-w*y(2);w*y(2)-0*y(2)]; g=@(y,x) [-c*slowdown2(x,25)*y(1)*y(2)/(r*B);c*slowdown2(x,25)*y(1)*y(2)/B-w*y(2);w*y(2)-0*y(2)]; h=@(y,x) [-k*slowdown2(x,25)*y(1)*y(2)/(r*B);k*slowdown2(x,25)*y(1)*y(2)/B-w*y(2);w*y(2)-0*y(2)]; y1= lsode (f, yo, t); y2= lsode (g, yo, t); y3= lsode (h, yo, t);
%Interpolation der Funktionswerte an die RKI-Zeiten (Tage) I1=interp1 (t, y1(:,2), times); I2=interp1 (t, y2(:,2), times); I3=interp1 (t, y3(:,2), times);
%Relativer Fehler: Slowdown 2 und k=0.254 rel_I3=abs(I3-Infizierte_aktuell./1000)./(Infizierte_aktuell./1000);
%Relativer Fehler: Slowdown 2 und k=0.3245 rel_I2=abs(I2-Infizierte_aktuell./1000)./(Infizierte_aktuell./1000);
%Relativer Fehler: Slowdown 1 und k=0.3245 rel_I1=abs(I1-Infizierte_aktuell./1000)./(Infizierte_aktuell./1000);
plot (times,rel_I1,'y',times,rel_I2,'g',times,rel_I3,'b') title ('Relativer Fehler I') legend('I1','I2','I3')
Ergebnis: Grundsätzlich sind in den ersten 40 Tagen alle drei Fehler relativ gleich, wobei die ursprüngliche Slowdownfunktion mit c=0.3245 am günstigsten ist. Für die zukünftige Betrachtung hat dann aber die andere Slowdownfunktion einen deutlich geringeren Fehler.
Modifiziertes SIR-Modell und aktuelle Daten
[Bearbeiten]Im folgenden Abschnitt wird die Slowdown-Funktion2 in das modifizierte SIR-Modell eingebaut und zusammen mit den aktuellen Daten implementiert:
function val=slowdown2(x,t) if x<t val=1 ; else if x<t +8 val=t./(x.^1.1); else if x<t +16 val=t./(x.^1.25); else if x<t +22 val=t./(x.^1.4); else val=t./(x.^1.5) endif endif endif endif if x> 80 val=0.5; endif endfunction
Implementierung des modifizierten SIR-Modells
Die optimale Infektionsrate c=0.254, die wir in den vorherigen Schritten bestimmt haben, passt zwar sehr gut zur berechneten Infektionsrate der RKI-Daten, aber nicht mehr zu unserer Verbreitung innerhalb des modifizierten SIR-Modells und dem Slowdown-Geschehen. Deshalb wurde diese Infektionsrate im folgenden Modell auf c=0.35 erhöht und angepasst. Würde hier die Infektionsrate c=0.254 verwendet werden, ergibt sich ein deutlich größerer relativer Fehler bis zu 95%.
B=55000; %Kapazitätsgrenze, 2/3 der deutschen Bevölkerung c=0.35; %Basisinfektionsrate- die Rate des exponentiellen Wachstums am Anfang der Pandemie w=1/14; %Wechselrate zu den Genesenen d=0.003; %Todesrate r=0.1; %Anteil der erfassten Infizierten I0=16/1000; %Anzahl der Infizierten in T0 R0=0; %Anzahl der Genesenen in T0
times=(0:0.1:180);
%Anfangswerte
yo=[B-I0;I0;R0];
%Funktion f der rechten Seite des DGL-Systems y'=f(y,t)
f=@(y,x) [-c*slowdown2(x, 25)*y(1)*y(2)/(r*B);c*slowdown2(x, 25)*y(1)*y(2)/B-w*y(2);w*y(2)-d*y(2)];
y = lsode (f, yo, times);
Einfluss der Lockerung der Maßnahmen
[Bearbeiten]Nun soll anhand des SIR Modells untersucht werden, welchen Einfluss ein Anstieg der Infektionsrate in Folge der Lockerung der Kontaktverbot-Maßnahmen auf die Anzahl der Infizierten hat. Die Lockerung der Maßnahmen erfolgte am 27. April, also am Tag 61, die die Infektionsrate wieder auf 50% der Basisinfektionsrate erhöht.
Hierfür erstellen wir eine dritte Slowdown-Funktion, welche zum oben genannten Geschehen passt:
function val=slowdown3(x,t) if x<t val=1 ; else if x<t +8 val=t./(x.^1.1); else if x<t +16 val=t./(x.^1.25); else if x<t +22 val=t./(x.^1.4); else val=t./(x.^1.5); endif endif endif endif if x> 61 val=0.5 ; endif endfunction
n=length(Infizierte); times=[0:1:n-1]; k=0.35; for i=1:length(times) kk(i)=slowdown3 (times (i), 25)*k; endfor
Einfluss von r
[Bearbeiten]Zum Schluss soll ein Szenario der Pandemie in Deutschland dargestellt werden, welches möglicherweise ohne die kontaktreduzierenden Maßnahmen, also ohne Slowdown-Funktion auftreten könnte. Es wird untersucht, welchen Einfluss der Parameter r (Anteil der tatsächlich Infizierten) in dieser Modellierung hat. Dazu wird das modifizierte SIR-Modell implementiert. Zunächst erhalten wir für r=1 das original SIR-Modell:
Parameter
B=55000; c=0.250; w=1/14; d=0.003; r=1; I0=16/1000; %Anzahl der Infizierten in T0 R0=0; %Anzahl der Genesenen in T0
times=(0:0.1:180);
%Anfangswerte
yo=[B-I0;I0;R0];
%Funktion f der rechten Seite des DGL-Systems y'=f(y,t)
f=@(y,x) [-c*y(1)*y(2)/(r*B);c*y(1)*y(2)/B-w*y(2);w*y(2)-d*y(2)];
y = lsode (f, yo, times);
Danach betrachten wir verschiedene Werte r<1:
r1=0.8; r2=0.5; r3=0.3; r4=0.1;
Ergebnis Je größer man r wählt, desto mehr der tatsächlich Infizierten können erfasst werden. Je kleiner man r wählt, desto flacher werden die Graphen. Für r=1 erhalten wir dann unser SIR-Modell (Ausgangsmodell). Würde man r>1 festlegen, dann würden mehr Infizierte erfasst werden als tatsächlich vorliegen.
4.Tutoriumsaufgabe: Randwertaufgabe für Poissongleichung mit Finite-Differenzen-Verfahren [10]
[Bearbeiten]In diesem Skript wird stationäre Diffusion mithilfe der Poissongleichung auf einem recheckigem Gebiet mithilfe der Finiten Differenzen Methode implementiert. Diese Methode ist dabei ein Gitter-basiertes Verfahren, welches die unbekannte Funktion auf endlich vielen Gitterpunkten approximiert.
Quelldichtefunktion f der rechten Seite der Poissongleichung
[Bearbeiten]Als Quelldichtefunktion beschreibt die Flussgeschwindigkeit in das System hinein, also die Neuinfizierungen die kontinuierlich hinzukommen.
function wert=Quellfunktion(x,y) if sqrt((x.-5).^2+(y.-3).^2)<=0.35 wert=1; else wert=0; endif endfunction
Gebiet D
[Bearbeiten]Um das Gebiet festzulegen, müssen zunächst die Kantenlängen des Rechtecks festgelegt werden. Außerdem wird die Anzahl an Gitterpunkten in X-Richtung festgelegt.
xend=8;
yend=5;
N=30 %Anzahl von X-Punkten (ohne Randpunkten)
Um das äquidistane Gitter zu erstellen, muss der Abstand zwischen den einzelnen Gitterpunkten bestimmt werden. Dafür muss die x-Kantenlänge durch geteilt werden. Dies liegt daran, dass der 0-te, und (N+1)-te, Index den Rändern entsprechen und somit nicht zu den Gitterpunkten zählen.
hx=xend/(N+1)
hy=hx;
M=floor((yend/hy))-1
%Koordinatenmatrix der Gitterpunkte
[x,y]=meshgrid(hx:hx:xend-hx,hy:hy:yend-hy);
a=1.0; %konstanter Diffusionskoeffizient (beschreibt die Verbreitungsgeschwindigkeit; je größer, desto schneller)
Randbedingungen
[Bearbeiten]Bei einem Dirichlet Randwertproblem wird die gesuchte Funktion am Rand durch eine Funktion festgelegt.
In unserem Fall soll die Funktion für die verschiedenen Ränder einen konstanten Wert annehmen.
%Dirichlet RB:
wert_unten=-0.025;
wert_oben=0.025;
wert_links=0.025;
wert_rechts=-0.025;
Systemmatrix
[Bearbeiten]Theorie
Um die gesuchte Funktion zu berechnen, muss eine Approximation für gefunden werden.
Eindimensional kann dabei betrachtet werden. Die zweite Ableitung kann dabei mit Hilfe des zentralen Differenzenquotienten diskretisiert werden:
- für jedes .
Hier bezeichnet .
Dieser ergibt sich aus der Differenz der ersten Differenzenquotienten , wobei der Rückwärtsdifferenzenquotient vom Vorwärtsdifferenzenquotient abgezogen wird.
Unsere Betrachtung soll jedoch zweidimensional sein, da wir ein rechteckiges Gebiet betrachten. Daher müssen zwei Raumrichtungen x und y berücksichtigt werden und somit auch zwei Differenzenquotienten aufgestellt werden.
Diese werden durch die folgenden partiellen Ableitungen im Punkt approximiert:
- ,
Damit ergibt sich:
Um nun eine Systemmatrix aufzustellen zu können, müssen zunächst unsere unbekannten Funktionswerte aller Gitterpunkte, sowie die Funktionswerte der rechten Seite in je einen langen Vektor eingeordnet werden. Diese sollen folgendermaßen (in der selben Reihenfolge) aufgestellt werden:
Damit kann nun ein lineares Gleichungssystem aufgestellt werden, wobei unsere blockdiagonale Matrix ist. Dabei gilt:
- mit Diagonalblock
und der Einheitsmatrix auf der Nebendiagonale.
Implementierung
Diese Systemmatrix soll nun aufgestellt werden.
Vec1=ones(N*M,1); % erzeugt Vektor der Länge N*M BB=diag(-4.*Vec1,0)+diag(ones(N*M-1,1),1)+ diag(ones(N*M-1,1),-1)+diag(ones(N*(M-1),1),N)+diag(ones(N*(M-1),1),-N); %Systemmatrix N^2xM^2 mit -4 auf der Diagonale und 1 auf den Nebendiagonalen und 1 auf N und -N-ter Nebendiagonale
Nun muss jedoch noch berücksichtigt werden, dass beim Übergang in die nächste Blockmatrix B die Nebendiagonalen aus Einsen unterbrochen werden und je ein Nulleintrag vorliegt.
Dies muss also noch korrigiert werden.
%Korrektur der Matrix (Blockdiagonalität) for i=1:(M-1) BB(i*N+1,i*N)=0;BB(i*N,i*N+1)=0; endfor %Matrix mit Diffkoeffizient a/h^2 multiplizieren BB=BB*a/hx^2; %Matrixdarstellung figure (1); spy (BB); xlabel("Spalten") ylabel("Zeilen") zlabel("Matrix B") title ("Systematrix B");
rechte Seite des Systems
[Bearbeiten]Um die rechte Seite des Sytems aufzustellen, wird zunächst die Quellfunktion für jeden Gitterpunkt eingespeichert. Anschließend werden die Dirichlet Randbedingungen hinzugefügt.
clear f; for i=1:N for j=1:M f(j,i)=1*Quellfunktion(x(j,i),y(j,i)); %Dirichlet Randbedingung unten und oben: if j==1 f(j,i)=1*Quellfunktion(x(j,i),y(j,i))+wert_unten*a/hx^2; endif if j==M f(j,i)=1*Quellfunktion(x(j,i),y(j,i))+wert_oben*a/hx^2; endif %Dirichlet Randbedingung links und rechts: if i==1 f(j,i)=1*Quellfunktion(x(j,i),y(j,i))+ wert_links*a/hx^2; endif if i==N f(j,i)=1*Quellfunktion(x(j,i),y(j,i))+ wert_rechts*a/hx^2; endif endfor endfor
Ecken-Beiträge
[Bearbeiten]Die Eckbeiträge müssen gesondert betrachtet werden, da hier zwei Randbedingungen eingehen.
f(1,1)=1*Quellfunktion(x(j,i),y(j,i))+(wert_links+wert_unten)*a/hx^2; f(1,N)=1*Quellfunktion(x(j,i),y(j,i))+(wert_rechts+wert_unten)*a/hx^2; f(M,1)=1*Quellfunktion(x(j,i),y(j,i))+(wert_links+wert_oben)*a/hx^2; f(M,N)=1*Quellfunktion(x(j,i),y(j,i))+(wert_rechts+wert_oben)*a/hx^2;
Schließlich kann die rechte Seite in den Vektor umgeformt werden. Außerdem fließt hier das aus der Poisson-Gleichung ein.
b=-1*reshape(f',N*M,1); %Muss transporniert werden, damit die Zeilen untereinander aufgestellt werden
%Lösungsschritt
sol=BB\b;
sol_matrix=reshape(sol,N,M);% Matrix mit N(Zeilen)x M(Spalten) sol_matrix=sol_matrix'; % Rücktransponierung nach reshape
Graphische Darstellung
[Bearbeiten]figure(2); surfc(x,y,sol_matrix); title ("Loesung"); ylabel("y") xlabel("x") figure(3); surfc(x,y,f); title ("Quellfunktion"); ylabel("y") xlabel("x")
Erweiterung des Modells mit Neumann-Randbedingungen
[Bearbeiten]Im folgenden sollen die Dirichlet-Randbedingung mit den Neumann-Randbedingungen verknüpft werden. Dabei müssen die Richtungsableitungen der Funktion in der Richtung des äußeren Normalenvektors gegeben sein, wodurch die Neumann-Randbedingung erfüllt:
Da wir ein rechteckiges Gebiet gewählt haben, gilt insbesondere oder
- linker Rand:
- rechter Rand:
- unterer Rand:
- oberer Rand:
Im Folgenden wird allerdings die Finite-Differenzen-Methode (FDM) für Neumann-RB auf dem Rechteck D mit homogenen Randbedingungen mit implementiert.
Folglich muss unser betrachtetes Gitter um die Randwerte erweitert werden.
%Koordinatenfeld
[x,y]=meshgrid(0:hx:xend,0:hy:yend);
N=N+2;
M=M+2;
Systemmatrix
[Bearbeiten]Durch die Erweiterung des Gitters gibt es nun auch weitere unbekannte Funktionswerte . Der lange Vektor soll folgendermaßen aufgestellt werden:
Dabei sind die Punkte des ersten Spaltenabschnitts, die des unteren Gitterrandes. Die Punkte des letzten Spaltenabschnittes entsprechen den Gitterpunkten des oberen Randes. Zudem wurde jeder Spaltenabschnitt um einen neuen ersten und letzten Punkte erweitert. Dabei liegt der erste Punkt auf dem linken und der letzte Punkt auf dem rechten Rand.
Erweiterung: Neumann-Randbedungungen auf dem linken und rechten Rand
Die Dirichlet-Randbedingungen sollen nur an manchen Rändern durch Neumann-Randbedingungen ergänzt werden, jedoch nicht vollständig ersetzt, da sonst kein brauchbares Ergebnis herauskommt. Hier geschieht dies auf dem linken und rechten Rand. Das Gitter wird jedoch nicht darauf angepasst, wodurch ein kleiner Fehler entsteht.
Nun soll wieder das lineare Gleichungssystem aufgestellt werden. Dazu muss unsere blockdiagonale Matrix ebenfalls um Einträge erweitert werden, damit . Dabei wird der Diagonalblock jeweils um eine Zeile oben und unten erweitert. Diese ensprechen den Werten des linken und rechten Randes, weshalb hier ein anderer Eintrag erfolgen muss. Dieser leitet sich aus dem Differenzenquotienten her. So gilt beispielsweise für den linken Rand , weshalb in der oberen Zeile eingetragen werden muss.
Insgesamt sieht die Systemmatrix damit folgendermaßen aus:
- mit Diagonalblock und null-erweiterter Einheitsmatrix .
Implementierung Zunächst wird die Systemmantrix genauso wie oben aufgestellt. Einziger Unterschied ist, dass hier gilt und .
Vec1=ones(N*M,1); % erzeugt vektor der Länge N*M BB=diag(-4.*Vec1,0)+diag(ones(N*M-1,1),1)+ diag(ones(N*M-1,1),-1)+diag(ones(N*(M-1),1),N)+diag(ones(N*(M-1),1),-N); %Systemmatrix N^2xM^2 mit -4 auf der Diagonale und 1 auf den Nebendiagonalen und 1 auf den N und -N-ter Nebendiagonale
%Korrektur der Matrix (Blockdiagonalität) for i=1:(M-1) BB(i*N+1,i*N)=0;BB(i*N,i*N+1)=0; endfor
% Matrix mit Diffkoeff/h^2 multiplizieren
BB=BB*a/hx^2;
Neumann RB auf dem oberen und unteren Rand -einzelne Blöcke der Matrix ersetzen
[Bearbeiten]Würde man auch Neumann-Randbedingungen auf dem oberen und unteren Rand implementieren wollen, so müsste man die Systemmatrix anpassen. Da dies in der Tutoriumsaufgabe 5 gebraucht wird, soll hier eine Auskommentierung vorbereitend stattfinden. Dabei werden oben und unten eine Blockzeile ergänzt, wobei einmal eine Diagonalmatrix aus und einmal aus sowie Null-Matrizen ergänzt werden.
h=hx; block=diag((a/h)*ones(N,1)); %a/h, denn a/h^2*h %unterer Rand %BB(1:N,1:N)=block; %BB(1:N,N+1:2*N)=-block; %oberer Rand %BB(N*(M-1)+1:N*M,N*(M-1)+1:N*M)=block; %BB(N*(M-1)+1:N*M,N*(M-2)+1:N*(M-1))=-block;
Neumann RB linker und rechter Rand - einzelne Zeilen der Matrix ersetzen
[Bearbeiten]Wie oben beschrieben müssen die oberste und unterse Zeile der Blockmatrizen geändert werden. Dies geschieht in einer Schleife.
for i=1:(M-2) vector_up=zeros(1,N*M); vector_up(N*i+1)=a/h; %a/h eintragen, denn a/h = a/h^2*h (Matrix wurde schon mit a/h^2 multipliziert vector_up(N*i+2)=-a/h; vector_down=zeros(1,N*M); vector_down(N*i+N)=a/h; vector_down(N*i+N-1)=-a/h; BB(i*N+1,:)=vector_up ; % Ersetzt entsprechende Zeile mit Vektor BB(i*N+N,:)=vector_down ; endfor
Matrixdarstellung
[Bearbeiten]figure (1); spy (BB); xlabel("Spalten") ylabel("Zeilen") zlabel("Matrix B") title ("Systematrix B");
rechte Seite des Systems
[Bearbeiten]for i=1:N for j=1:M f(j,i)=1*Quellfunktion(x(j,i),y(j,i)); %Neumann Randbedingung links und rechts: if i==1 f(j,i)=1*Quellfunktion(x(j,i),y(j,i)); endif if i==N f(j,i)=1*Quellfunktion(x(j,i),y(j,i)); endif %Dirichlet Randbedingung oben und unten: if j==1 f(j,i)=1*Quellfunktion(x(j,i),y(j,i))+wert_unten*a/hx^2; endif if j==M f(j,i)=1*Quellfunktion(x(j,i),y(j,i))+wert_oben*a/hx^2; endif endfor endfor
Ecken-Beiträge
[Bearbeiten]Da wir in unserem Fall in allen vier Ecken sowohl Neumann-RB als auch Dirichlet-RB haben, addieren sich keine zusätzlichen Eckbeiträge hinzu.
f(1,1)=1*Quellfunktion(x(j,i),y(j,i)); f(1,N)=1*Quellfunktion(x(j,i),y(j,i)); f(M,1)=1*Quellfunktion(x(j,i),y(j,i)); f(M,N)=1*Quellfunktion(x(j,i),y(j,i));
b=-1*reshape(f',N*M,1);
% Lösungsschritt
sol=BB\b;
sol_matrix=reshape(sol,N,M); % Matrix mit N(Zeilen)x M(Spalten) sol_matrix=sol_matrix'; % Transponiert, wegen reshape
Graphische Darstellung
[Bearbeiten]figure(2); surfc(x,y,sol_matrix); title ("Loesung"); ylabel("y") xlabel("x")
figure(3); surfc(x,y,f); title ("Quellfunktion"); ylabel("y") xlabel("x")
5.Tutoriumsaufgabe: Epidemiologische Modellierung durch numerische Diskretisierung des Reaktionsdiffusionprozess [11]
[Bearbeiten]Anmerkung: Diese Aufgabe ist in Zusammenarbeit mit Gruppe 3 entstanden.
In der letzten Tutoriumsaufgabe wird das Finite-Differenzen-Verfahren zur Lösung der Reaktionsdiffusionsgleichung
für die zeitlich-räumliche Modellierung der Corona-Ausbreitung auf einem rechteckigen Gebiet D implementiert.
In unserem Fall modellieren wir die Corona-Ausbreitung für die Stadt Landau. Die Informationen bezüglich der Fläche und Bevölkerungsdichte von Landau erhalten wir unter folgendem Link: Landau in der Pfalz
Wir betrachten in unserer Modellierung die Bevölkerungsdichte für die Kernstadt Landau.
Fläche: 83 km2 (ungefähre Quadratsfläche: 9 km *9 km) Bevölkerungsdichte in Landau Zentrum: 2619,9 Einwohner pro km2
Von Runkelbold - Eigenes Werk, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=3663743
Festlegung des Gebietes als Gitter
[Bearbeiten]In der Abbildung oben kann man erkennen, dass Landau geographisch grob als Quadrat gesehen werden kann. Mit der bekannten Fläche können dann damit die Kantenlängen festgelegt werden.
xend=9.0; %in km yend=9.0; %in km N=60 % Anzahl von Gitterpunkten in x-Richtung(0-te und N-te Index entsprechen den Rändern, keine Gitterpunkte am Rand) a=0.01; %konstanter Diffusionskoeffizient %Beschreibt die Verbreitungsgeschwindigkeit(Je größer, desto schneller) T=100; %Zeitintervall in Tagen delta_t=0.03; %Zeitschritt
Um das Gitter zu konstruieren, muss die Kantenlänge der Quadrates durch geteilt werden, um die Gitterpunkte in gleichgroßem Abstand auf der Kante zu verteilen, bzw. den Abstand der Gitterpunkte zu berechnen. Da ein Quadrat vorliegt, ist die Anzahl der Gitterpunkte in x- und y-Richtung gleich groß.
hx=xend/(N+1) %Abstand Gitterpunkte hy=hx; % setze so, damit sich Quadrate bilden %M=floor((yend/hy))-1 -> Anzahl der Gitterpunkte in y-Richtung M=N; %Im Falle eines Quadrates
Nr_timesteps=floor (T/delta_t) %Anzahl der Zeitschritte
Parameter für die Reaktionsdiffusionsgleichung
[Bearbeiten]B=2619,9; %Bevölkerungsdichte Einwohner pro Quadratkilometer(Landau Zentrum) k=0.254; %Infektionsrate aus SIR-Abgabe3 w=1/14;%Wechselrate
Definition der Anfangsfunktion
[Bearbeiten]function wert=initialfunction(x,y) wert=0; r=0.25; %Fläche des Kreises: 0.20km2 entspricht ca. 523 Einwohnern if sqrt((x.-4.5).^2+(y.-4.5).^2)<=r wert=1/(pi*r^2); %Infektionen im Zentrum von Landau (ein Infizierter) endif endfunction
Systemmatrix
[Bearbeiten]Das erstellte Gitter muss nun um die Randpunkte erweitert werden.
[x,y]=meshgrid(0:hx:xend,0:hy:yend); N=N+2; M=M+2;
Die folgende Systemmatrix wird nach dem gleichen Schema wie oben erstellt (siehe Tutoriumsaufgabe 4)
Vec1=ones(N*M,1); %erzeugt Vektor der Länge N*M BB=diag(-4.*Vec1,0)+diag(ones(N*M-1,1),1)+ diag(ones(N*M-1,1),-1)+diag(ones(N*(M-1),1),N)+diag(ones(N*(M-1),1),-N); %Systemmatrix N^2xN^2 mit -4 auf der Diagonale und 1 auf den Nebendiagonalen und 1 auf der N-ten und -N-ten Nebendiagonale
for i=1:(M-1) BB(i*N+1,i*N)=0;BB(i*N,i*N+1)=0; %Korrektur der Blockmatrix (Blockdiagonalität) endfor
BB=BB*a/hx^2;
Festlegen der Neumann Randbedingungen
Im folgenden sollen die Neumann-Randbedingungen festgelegt werden. Dabei sollen die jeweiligen Ableitungen der Ränder null sein. Dies beschreibt einen freien Fluss der Infizierung in die angerenzenden Gebiete. Für Neumann Randbedingungen auf dem oberen und unteren Rand müssen in unserer Systemmatrix die erste und letzte Blockzeile angepasst werden.
% Neumann RB für y: a* partial_y u=0 - einzelne Blöcke der Matrix ersetzen block=diag((a/hx)*ones(N,1)); %Matrix mit h bzw. -h auf Diagonale %Unterer Rand BB(1:N,1:N)=-block; BB(1:N,N+1:2*N)=block; %Oberer Rand BB(N*(M-1)+1:N*M,N*(M-1)+1:N*M)=-block; BB(N*(M-1)+1:N*M,N*(M-2)+1:N*(M-1))=block;
Für Neumann Randbedingungen auf dem linken und rechten Rand müssen die oberste und unterste Zeile unserer Diagonalblöcke von BB ersetzt werden.
% Neumann RB für x: a* partial_x u=0 - einzelne Zeilen der Matrix ersetzen for i=1:(M-2) vector_up=zeros(1,N*M); vector_up(N*i+1)=a/hx; vector_up(N*i+2)=-a/hx; vector_down=zeros(1,N*M); vector_down(N*i+N)=a/hx; vector_down(N*i+N-1)=-a/hx; BB(i*N+1,:) =-vector_up ; %Vektor der kompletten ersten Zeile BB(i*N+N,:) =-vector_down ;%Vektor der kompletten letzten Zeile endfor
Graphische Darstellung der Systemmatrix
figure (67); spy (BB); xlabel("Spalten") ylabel("Zeilen") zlabel("Matrix B") title ("Systematrix B");
Anfangslösung als Matrix
[Bearbeiten]Durch den Parameter I0 ist die Wahl der Anfangsinfizierungen variabel. Wir gehen in diesem Fall von einem Infizierten im Zentrum von Landau aus.
I0=1 %Anzahl der Anfangsinfizierungen pro gegebene Fläche pi*r^2 for i=1:N for j=1:M initial(j,i)=I0*initialfunction(x(j,i),y(j,i)); endfor endfor
size (initial)
sol_old=1*reshape(initial',N*M,1);
%reshape funktioniert Spaltenmäßig: Sp1,Sp2, wir wollen Zeilenmäßig --> Matrix f' ist N(Zeilen) x M (Spalten)
Einlesen der Graphik zur Einwohnerzahl
[Bearbeiten]In diesem Abschnitt wird eine Graphik zur Einwohnerzahl als Bevölkerungsmatrix eingelesen. Danach wählen wir einen für Landau geeigneten Bildausschnitt.
A=imread ('Monitor_Einwohnerzahl_detail.png'); size(A); %Zeigt die Dimension der Bildmatrix S=A(21:29,16:24); imshow (S) %Bildanzeige S=double (S); [s1 s2]=size(S); Max=max(max(S)) S=Max-S; %Farbumkehrung/Anpassung
Interpolation der Werte an die Koordinatenmatrix
[Bearbeiten]Die oben aufgestellte Matrix S ist eine 9 x 9 Matrix. Diese Matrix ist allerdings gröber eingeteilt, als unser vorher definiertes Gitter mit viel kleineren Schritten. Das bedeutet, dass wir die Werte von S auf unsere Gitterpunkte interpolieren müssen. Dabei verwenden wir eine zweidimensionale kubische Interpolation.
Sint=interp2(S,xend*(1*x.+2)/(xend+2),yend*(1*y.+2)/(yend+2), 'cubic');
Sint=flipud (Sint); %Bild flippen oben <--> unten
size (Sint)
figure(66); surface(x,y, (B/Max)*Sint) title ("Bevoelkerungsdichte"); ylabel("y") xlabel("x") colorbar
B=reshape((B/Max)*Sint',N*M,1).+0.1*Max; %Angepasste Bevölkerungsdichte
size (B)
Bild links: Von Runkelbold - Eigenes Werk, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=3663743
Von Runkelbold - Eigenes Werk, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=3663743
Zwischenfazit Die Gegenüberstellung der beiden Bilder zeigt, dass wir einen geeigneten Ausschnitt unserer Bildmatrix für die Bevölkerungsdichte in Landau gewählt haben. Die Bevölkerungsdichte ist im Zentrum (Kernstadt Landau) am größten und wird in den umliegenden Ortschaften deutlich geringer.
Teil 1: Lösungsschritt - Reaktionsterm für kumulierte Infizierte
[Bearbeiten]Im ersten Teil der Implementierung stellen wir einen Reaktionsterm für die kumulierten Infizierten auf, das heißt, dass wir Infizierte und Genesene betrachten (einmal infiziert, immer infiziert)
Reaktionsterm für kumulierte Infizierte
Im nachfolgenden Reaktionsterm wird die Bevölkerungsdichte geographisch differenziert als Funktion einer Raumvariable betrachtet:
F=@(u) (k./B).*u.*(B.-u);
Dieser Term wird nun zu unserem System von gewöhnlichen Differentialgleichungen des räumlich diskretisierten Neumann-Randwertproblems für die Diffusion hinzugefügt.
Würde man die homogene Differentialgleichung betrachten gilt folgendes:
Dabei lässt sich hier das Stern-Approximationsschema anwenden:
Aus diesem ursprünglichen System ergibt sich also , welches nun zur Reaktionsdiffusionsgleichung ergänzt werden kann:
- .
Zeitschleife
Der numerische Lösungsschritt (Zeitdiskretisierung) erfolgt hier mithilfe des Expliziten Eulerverfahrens: Nach der Anwendung des Vorwärtsdifferenzenquotienten erhält man folgende Berechnungsformel: , die sich in der implementierten Zeitschleife widerspiegelt:
for i=1:Nr_timesteps sol= sol_old+ BB*sol_old*delta_t + 1*F(sol_old)*delta_t; sol_old=sol; matrix_solution(:,i)=sol; endfor
Auswahl an Bildern - jedes fünfte Bild
fig_index=floor([0.05:0.05:1]*Nr_timesteps) j=0 for i=fig_index sol_matrix=reshape(matrix_solution(:,i),N,M);%Matrix mit N(Zeilen) x M(Spalten) sol_matrix=sol_matrix'; disp(['Figure ',num2str(round(i/fig_index(1)))]); j=j+1; figure(j); surface(x,y,sol_matrix*hx^2, "EdgeColor", "none") %multipliziert mit hx^2, damit Anzahl der Infizierten pro Raster und nicht Dichte dargestellt wird colormap ("jet") axis([0 xend 0 yend 0 1.1*max(max(B))*hx^2]) colorbar title (["Loesung in t=", num2str(round(delta_t*i))]); ylabel("y") xlabel("x") test=["Fig_", num2str(j),".jpg"] endfor
Anfangslösung
Die Abbildung zeigt, dass wir zu Beginn der Corona-Ausbreitung ca. einen Infizierten im Zentrum haben.
Animation
Teil 2: Lösungsschritt - Reaktionsterm für aktuell Infizierte
[Bearbeiten]In diesem Teil möchten wir die gleiche Implementation wie oben durchführen, aber nun anstatt der kumulierten Infizierten die aktuell Infizierten betrachten. Hierfür benötigen wir unsere Kenntnisse aus dem SIR-Modell. Dabei wird unser SIR-Modell auf die räumliche Verbreitung ausgeweitet, indem der Diffusionsterm hinzugefügt wird. Unsere Funktionen heißen deshalb nicht mehr nur S, I und R, sondern u_S bzw. u_I (u_R wird an dieser Stelle ignoriert) und sind nicht mehr nur von der Zeit t abhängig, sondern auch von einer Raumvariable.
Es werden zwei gekoppelte Reaktionsdiffusionsgleichungen für die Dichtefunktionen gelöst. Die entsprechenden Reaktionsterme sehen wie folgt aus:
Vorbereitung der alten Lösung
sol_old=1*reshape(initial',N*M,1); %Aktuell Infizierte sol_old_susp=B.-sol_old; %Infektionsanfällige
Definition der Slowdown-Funktion
Wir benötigen für den Reaktionsterm eine Slowdown-Funktion. Diese übernehmen wir aus unserer Implementierung des SIR-Modells aus der dritten Tutoriumsaufgabe.
function val=slowdown3(x,t) if x<t val=1 ; else if x<t +8 val=t./(x.^1.1); else if x<t +16 val=t./(x.^1.25); else if x<t +22 val=t./(x.^1.4); else val=t./(x.^1.5); endif endif endif endif if x> 61 val=0.5 ; endif %Lockerungen endfunction
Reaktionsterm aktuell Infizierte
Nun definieren wir eine nichtlineare Funktion von u (aktuell Infizierte), v (Empfängliche) und der Zeit t.
F=@(u,v,t) (k*slowdown3(25,t)./B).*u.*v;
Zeitschleife
Der Zeitdiskretisierung erfolgt an dieser Stelle auch wieder mithilfe des expliziten Eulerverfahrens.
for i=1:Nr_timesteps Reakt=F(sol_old,sol_old_susp, i*delta_t); %Nichtlinearer Term, wird aus alten Werten berechnet in der Form F=@(u,v,t) sol_susp= sol_old_susp+ BB*sol_old_susp*delta_t - Reakt*delta_t; %Erster Reaktionsterm: Empfängliche sol= sol_old+ BB*sol_old*delta_t+ (Reakt-w.*sol_old)*delta_t; %Zweiter Reaktionsterm: Aktuell Infizierte (um Term -w*I erweitert)
sol_old=sol; %Speicherung für den nächsten Zeitschritt (alte Lösung wird auf neue Lösung überschrieben) sol_old_susp=sol_susp; matrix_solution1(:,i)=sol;%Speicherung der aktuell Infizierten in einer Matrix, Speicherung der Anfälligen (S) nicht implementiert endfor
Animation
Anschließend erhalten wir mit dem gleichen Octave-Befehl wie im ersten Teil unsere Animation für die aktuell Infizierten.
Skripte in Cocalc
[Bearbeiten]Tut1: Kontaktmodell [12]
Tut2: Fundamentallösungen der Poisson und der Diffusionsgleichung [13]
Tut3: Kompartimentmodelle für die dynamische Beschreibung der Infektionsverbreitung und die Datenlage [14]
Tut4: Randwertaufgabe für Poissongleichung mit Finite-Differenzen-Verfahren [15]
Tut5: Epidemiologische Modellierung durch numerische Diskretisierung des Reaktionsdiffusionprozess [16]