% solve Fisher's equation c_t = D c_xx + a*c*(1-c) with D > 0 and a >= 0 % given constants. Solve on the interval 0 < x < L, with % BC c(0,t)=g0, c_x(L,t)=0 -- I will use g0=1. % and specified initial conditions % % Uses Crank-Nicolson scheme % % Use discrete approximations with spatial points xj = (j-1)*dx for % j=1,...,N+2 where (N+1)*dx=L, i.e. (N+1)=L/dx % % Uses Crank-Nicolson discretization % % We want to find approximations to the solution of the PDE % at the N+2 points xj for j=1,...,N+2; % % define parameters cross = 1; D = 0.001; a = 0.; L = 10.; g0 = 1; % N = input(' enter number of spatial points N '); tend = input(' enter final time tend '); a = input(' enter parameter a '); lambda = input(' enter ratio lambda '); init = input(' which initial data 0,1,2? '); plotfreq = input(' time interval between plots '); if cross == 1 ncount = 0 c_star = input(' enter c_star '); end; tplot = min(plotfreq,tend); dx = L/(N+1); dt = lambda*(dx*dx)/D; b1 = D*dt/(dx*dx); b2 = a*dt; x = dx*[0:1:N+1]; c_old = zeros(N+2,1); c_new = zeros(N+2,1); ZERO = 1; ONE = 2; TWO = 3; THREE = 4; LASTM1 = N+1; LAST = N+2; % % define matrices needed for CN method % [ML,MR,R] = matrixdefine(N,lambda); % % define initial conditions % epsilon = 0.1; if init == 0, xleft = 0.5; for j=ZERO:LAST; xx = x(j); c_old(j) = 1.0 - .50*(1.0 + tanh((xx-xleft)/epsilon)); end elseif init == 1, xleft = .5; xright = 1.5; epsilon = 0.1; for j=ZERO:LAST; xx = x(j); c_old(j) = 1.0 - .25*(1.0 + tanh((xx-xleft)/epsilon)) ... - .25*(1.0 + tanh((xx-xright)/epsilon)); end elseif init == 2, xleft = .5; xmid = 1.0; xright = 1.5; epsilon = 0.1; for j=ZERO:LAST; xx = x(j); c_old(j) = 1.0 - .25*(1.0 + tanh((xx-xleft )/epsilon))... + .25*(1.0 + tanh((xx-xmid )/epsilon))... - .50*(1.0 + tanh((xx-xright)/epsilon)); end end; % subplot(2,1,1) plot(x,c_old,'r-*'),axis([0 L 0 1.1]) hold on; % % define boundary condition vector % (assumes boundary conditions do NOT vary in time) % bcvector = zeros(N+1,1); bcvector(1 ) = (lambda/2)*(g0 + g0); % % march forward in time % t = dt; tcount = 0; while(t < tend); % % use 4th order Runge-Kutta to solve dc/dt = a*c*(1-c) for one timestep % k1 = a*c_old(ONE:LAST,1).*(1-c_old(ONE:LAST,1)); ctemp = c_old(ONE:LAST,1) + .5*dt*k1; k2 = a*ctemp.*(1-ctemp); ctemp = c_old(ONE:LAST,1) + .5*dt*k2; k3 = a*ctemp.*(1-ctemp); ctemp = c_old(ONE:LAST,1) + dt*k3; k4 = a*ctemp.*(1-ctemp); ctemp = c_old(ONE:LAST,1) + (1/6)*dt*(k1+2*k2+2*k3+k4); % % now compute effect of diffusion % [ctempnew,outputflag]=matsolve(ML,MR,ctemp,R,bcvector); % set c_new at x=0 to g0 c_new = [g0;ctempnew(:,1)]; tcount = tcount+1; if(t > tplot) tplot = tplot+plotfreq; plot(x,c_new,'b-') end; c_old = c_new; % % determine location of point at which c_old = c_star % ncount = ncount+1; x_star(ncount) = L; for j=LASTM1:-1:ZERO if c_old(j) > c_star slope = (c_old(j+1)-c_old(j))/dx; x_star(ncount) = (c_star-c_old(j))/slope + (j-1)*dx; break; end; end; t = t + dt; end; name = strcat(' Fishers Eq: D=',num2str(D),' a=',num2str(a)) title(name,'Fontsize',14) if cross == 1, subplot(2,1,2) times = [1:1:ncount]*dt; plot(times,x_star,'k-','Linewidth',2) hold on; title(strcat(' x^*(t) for c^* =',num2str(c_star)),'Fontsize',14) % % do least-square line fit to last m points of (times,x_star) % m = floor(tcount/10); ts = times (ncount-m+1:ncount); xs = x_star(ncount-m+1:ncount); tavg = sum(ts)/m; xavg = sum(xs)/m; ttavg = sum(ts.*ts)/m; xtavg = sum(xs.*ts)/m; slope = (xtavg - xavg*tavg)/(ttavg - tavg*tavg); inter = (xavg - slope*tavg); speed = slope xfit = slope*ts + inter; plot(ts,xfit,'g-','Linewidth',2) wavespeed = sqrt(4*D*a); title(strcat(' x^*(t) for c^* =',num2str(c_star),' Speed=',num2str(speed),... ' sqrt(4aD) =',num2str(wavespeed)),'Fontsize',14) end;