Example 2.2.3a  Diffusion with a Second Order Reaction 

Example 3.2.1 is solved using finite differences in Maple below.  The program developed for example 3.8 is modified to solve this example.  (Note that y is used as the dependent variable instead of c.) 

> restart:
 

> with(plots):
 

The number of node points is entered here: 

> N:=4;
 

4 (1)
 

The length of the domain is entered here: 

> L:=1;
 

1 (2)
 

The governing equation is entered below: 

> eq:=diff(y(x),x$2)-Phi^2*y(x)^2;
 

`+`(diff(diff(y(x), x), x), `-`(`*`(`^`(Phi, 2), `*`(`^`(y(x), 2))))) (3)
 

The boundary conditions are entered here: 

> bc1:=diff(y(x),x);
 

diff(y(x), x) (4)
 

> bc2:=y(x)-1;
 

`+`(y(x), `-`(1)) (5)
 

Next, a general program is written to convert the governing equation and the boundary conditions to finite difference form.  The central difference expression for the second and first derivatives are: 

> d2ydx2:=(y[m+1]-2*y[m]+y[m-1])/h^2;
 

`/`(`*`(`+`(y[`+`(m, 1)], `-`(`*`(2, `*`(y[m]))), y[`+`(m, `-`(1))])), `*`(`^`(h, 2))) (6)
 

> dydx:=(y[m+1]-y[m-1])/2/h;
 

`+`(`/`(`*`(`/`(1, 2), `*`(`+`(y[`+`(m, 1)], `-`(y[`+`(m, `-`(1))])))), `*`(h))) (7)
 

Three point forward and backward difference expressions for the derivative are: 

> dydxf:=(-y[2]+4*y[1]-3*y[0])/(2*h);
 

`+`(`/`(`*`(`/`(1, 2), `*`(`+`(`-`(y[2]), `*`(4, `*`(y[1])), `-`(`*`(3, `*`(y[0])))))), `*`(h))) (8)
 

> dydxb:=(y[N-1]-4*y[N]+3*y[N+1])/(2*h);
 

`+`(`/`(`*`(`/`(1, 2), `*`(`+`(y[3], `-`(`*`(4, `*`(y[4]))), `*`(3, `*`(y[5]))))), `*`(h))) (9)
 

The governing equation in finite difference form is: 

> Eq[m]:=subs(diff(y(x),x$2)=d2ydx2,diff(y(x),x)=dydx,y(x)=y[m],x=m*h,eq);
 

`+`(`/`(`*`(`+`(y[`+`(m, 1)], `-`(`*`(2, `*`(y[m]))), y[`+`(m, `-`(1))])), `*`(`^`(h, 2))), `-`(`*`(`^`(Phi, 2), `*`(`^`(y[m], 2))))) (10)
 

The boundary conditions in finite difference form are: 

> Eq[0]:=subs(diff(y(x),x)=dydxf,y(x)=y[0],bc1);
 

`+`(`/`(`*`(`/`(1, 2), `*`(`+`(`-`(y[2]), `*`(4, `*`(y[1])), `-`(`*`(3, `*`(y[0])))))), `*`(h))) (11)
 

> Eq[N+1]:=subs(diff(y(x),x)=dydxb,y(x)=y[N+1],bc2);
 

`+`(y[5], `-`(1)) (12)
 

A 'for loop' can be written for the interior node points as 

> for i to N do Eq[i]:=subs(m=i,Eq[m]);od;
 

 

 

 

`+`(`/`(`*`(`+`(y[2], `-`(`*`(2, `*`(y[1]))), y[0])), `*`(`^`(h, 2))), `-`(`*`(`^`(Phi, 2), `*`(`^`(y[1], 2)))))
`+`(`/`(`*`(`+`(y[3], `-`(`*`(2, `*`(y[2]))), y[1])), `*`(`^`(h, 2))), `-`(`*`(`^`(Phi, 2), `*`(`^`(y[2], 2)))))
`+`(`/`(`*`(`+`(y[4], `-`(`*`(2, `*`(y[3]))), y[2])), `*`(`^`(h, 2))), `-`(`*`(`^`(Phi, 2), `*`(`^`(y[3], 2)))))
`+`(`/`(`*`(`+`(y[5], `-`(`*`(2, `*`(y[4]))), y[3])), `*`(`^`(h, 2))), `-`(`*`(`^`(Phi, 2), `*`(`^`(y[4], 2))))) (13)
 

The node spacing is given by: 

> h:=L/(N+1);
 

`/`(1, 5) (14)
 

The value for Φ is sustained  in the governing equations.  The governing equations are stored in eqs: 

> eqs:=seq(eval(subs(Phi=1,Eq[i])),i=0..N+1);
 

`+`(`-`(`*`(`/`(5, 2), `*`(y[2]))), `*`(10, `*`(y[1])), `-`(`*`(`/`(15, 2), `*`(y[0])))), `+`(`*`(25, `*`(y[2])), `-`(`*`(50, `*`(y[1]))), `*`(25, `*`(y[0])), `-`(`*`(`^`(y[1], 2)))), `+`(`*`(25, `*`(...
`+`(`-`(`*`(`/`(5, 2), `*`(y[2]))), `*`(10, `*`(y[1])), `-`(`*`(`/`(15, 2), `*`(y[0])))), `+`(`*`(25, `*`(y[2])), `-`(`*`(50, `*`(y[1]))), `*`(25, `*`(y[0])), `-`(`*`(`^`(y[1], 2)))), `+`(`*`(25, `*`(...
(15)
 

The variables are stored in vars: 

> vars:=seq(y[i],i=0..N+1);
 

y[0], y[1], y[2], y[3], y[4], y[5] (16)
 

The 'fsolve' command sometimes gives negative values when guess values for the dependent variables are not provided.  To avoid this, an initial guess of 1 is provided: 

> fsolve({eqs},{vars});
 

{y[5] = 1.000000000, y[2] = -2.960037328, y[0] = -4.145136024, y[1] = -3.848861350, y[3] = -1.720740468, y[4] = -.3630056965}
{y[5] = 1.000000000, y[2] = -2.960037328, y[0] = -4.145136024, y[1] = -3.848861350, y[3] = -1.720740468, y[4] = -.3630056965}
(17)
 

> vars:=seq(y[i]=1,i=0..N+1);
 

y[0] = 1, y[1] = 1, y[2] = 1, y[3] = 1, y[4] = 1, y[5] = 1 (18)
 

> sol:=fsolve({eqs},{vars});
 

{y[5] = 1., y[2] = .7539844610, y[0] = .7122065043, y[1] = .7226509935, y[3] = .8080576312, y[4] = .8882490868} (19)
 

The solution obtained is assigned and plotted: 

> assign(sol):
 

> plot([seq([i*h,y[i]],i=0..N+1)],thickness=4,axes=boxed,title="Figure Exp. 3.2.6.",labels=[x,y]);
 

Plot_2d
 

The accuracy of the solution obtained can be checked by following the concentration at the center y[0] and increasing the number of node points: 

> y[0];
 

.7122065043 (20)
 

>