C C This is the FORTRAN version of program 2.3 from page 35 of C "Modeling Infectious Disease in humans and animals" C by Keeling & Rohani. C C It is the SIR model with a probability of mortality and C unequal births and deaths. This code assumes Density- C Dependent Transmission C C This code is written to be simple, transparent and readily compiled. C Far more elegant and efficient code can be written. C C This code can be compiled using the intel fortran compiler: C ifort -Vaxlib -o Program_2_3 Program_2_3.f C C Main program starts here. program main REAL beta REAL gamma REAL mu, nu, rho REAL X,Y,Z REAL X0, Y0, N0 REAL MaxTime REAL EVERY, step, t INTEGER GivesName CHARACTER*2000 str, FileName COMMON /parameters/ beta, gamma, mu, nu, rho COMMON /variables/ X, Y, Z GivesName=iargc() if (GivesName.eq.0) then beta=1.4247 gamma=0.14286 mu=0.0000391 nu=0.0000391 rho=0.5 X0=0.2 Y0=0.000001 N0=1 MaxTime=100000 else c c READ IN ALL THE VARIABLES c call getarg(1,FileName) open(1,file=FileName,STATUS='OLD',ACCESS='SEQUENTIAL') read(1,*) str read(1,*) beta read(1,*) str read(1,*) gamma read(1,*) str read(1,*) mu read(1,*) str read(1,*) nu read(1,*) str read(1,*) rho read(1,*) str read(1,*) X0 read(1,*) str read(1,*) Y0 read(1,*) str read(1,*) N0 read(1,*) str read(1,*) MaxTime close(1) endif C C Check all variables are OK & set up intitial conditions */ C if ( X0.le.0) then write(*,*) "ERROR: Initial level of susceptibles (",X0,") is . less than or equal to zero." STOP endif if ( Y0.le.0) then write(*,*) "ERROR: Initial level of infecteds (",Y0,") is . less than or equal to zero." STOP endif if ( N0.le.0) then write(*,*) "ERROR: Initial population level (",N0,") is . less than or equal to zero." STOP endif if ( beta.le.0) then write(*,*) "ERROR: Transmission rate beta (",beta,") is . less than or equal to zero." STOP endif if ( gamma.le.0) then write(*,*) "ERROR: Recovery rate gamma (",gamma,") is . less than or equal to zero." STOP endif if ( mu.le.0) then write(*,*) "ERROR: Death rate mu (",mu,") is . less than or equal to zero." STOP endif if ( nu.le.0) then write(*,*) "ERROR: Birth rate nu (",nu,") is . less than or equal to zero." STOP endif if ( MaxTime.le.0) then write(*,*) "ERROR: Maximum run time (",MaxTime,") is . less than or equal to zero." STOP endif if (S0+I0.ge.N0) then write(*,*) "WARNING: Initial level of susceptibles+infecteds . (",X0,"+",Y0,"=",X0+Y0,") is greater than population . size ",N0,"." endif X=X0 Y=Y0 Z=N0-X0-Y0 C C Find a suitable time-scale for outputs C step=N0*0.01/((beta+gamma+mu)*X0) Every=N0/((beta+gamma+mu)*X0) if (Every.gt.1) then Every=10.0**INT(log10(Every)) else Every=10.0**INT(log10(Every)-1) endif DO WHILE (MaxTime/Every.gt.10000) Every=Every*10.0 ENDDO open(1,recl=3000,file='Output',ACCESS='SEQUENTIAL') C for F77 use C open(1,file='Output_Risk',ACCESS='SEQUENTIAL') C C C The main iteration routine C t=0 DO WHILE (t.lt.MaxTime) CALL Runge_Kutta(step) t=t+step C If time has moved on sufficiently, output the current data if( INT(t/Every).gt.INT((t-step)/Every) ) then write(1,*) t,X,Y,Z endif ENDDO END SUBROUTINE Runge_Kutta(step) REAL InitialPop(3), tmpPop(3) REAL dPop1(3), dPop2(3), dPop3(3), dPop4(3) REAL X,Y,Z, step COMMON /variables/ X, Y, Z C C Integrates the equations one step, using Runge-Kutta 4 C Note: we work with arrays rather than variables to make the C coding easier C InitialPop(1)=X InitialPop(2)=Y InitialPop(3)=Z CALL Diff(InitialPop,dPop1) do k=1,3 tmpPop(k)=InitialPop(k)+step*dPop1(k)/2.0 ENDDO CALL Diff(tmpPop,dPop2) do k=1,3 tmpPop(k)=InitialPop(k)+step*dPop2(k)/2.0 ENDDO CALL Diff(tmpPop,dPop3) do k=1,3 tmpPop(k)=InitialPop(k)+step*dPop3(k) ENDDO CALL Diff(tmpPop,dPop4) do k=1,3 tmpPop(k)=InitialPop(k)+step*(dPop1(k)/6 + dPop2(k)/3 + . dPop3(k)/3 + dPop4(k)/6) ENDDO X=tmpPop(1) Y=tmpPop(2) Z=tmpPop(3) RETURN END C The Main Differential Equations. SUBROUTINE Diff(Pop, dPop) REAL Pop(3), dPop(3) REAL beta REAL gamma REAL mu, nu, rho COMMON /parameters/ beta, gamma, mu, nu, rho C Set up temporary variables to make the equations look neater REAL tmpX, tmpY, tmpZ tmpX=Pop(1) tmpY=Pop(2) tmpZ=Pop(3) C C The differential equations C C dX/dt = dPop(1) = nu - beta*tmpX*tmpY - mu*tmpX C dY/dt = dPop(2) = beta*tmpX*tmpY - (gamma+ mu)*tmpY/(1-rho) C dZ/dt = dPop(3) = gamma*tmpY - mu*tmpZ RETURN END