home *** CD-ROM | disk | FTP | other *** search
- program trapz2(input,output);
- (* Program solves second-order state model x' = Ax + f using the method *)
- (* of trapezoidal integration. *)
-
- type mat = array[1..2,1..2] of real;
- var x10,x20,t0,tr,h: real;
- np: integer;
- a: mat;
-
- function fn1(x: real): real; (* Forcing function # 1 *)
- begin
- fn1 := 20.0;
- end;
-
- function fn2(x: real): real; (* Forcing function # 2 *)
- begin
- fn2 := 20*exp(-5*x)-100.0;
- end;
-
- procedure integ2(b,c: mat; h1,t1,tr1,y10,y20: real; np1: integer); forward;
- (* Uses trapezoidal integration to solve a second-order state model with *)
- (* initial conditions y10 and y20 at t1. Integration increment: h1 *)
- (* Run time: tr1. Number of points between print: np1. *)
-
- var h2,y1,y2,y11,y12,y13,y21,y22,y23,t: real;
- k,i: integer;
-
- procedure constants(a: mat; h1: real; np1: integer);
- (* Evaluates two second-order matrices, and calculates inverse of one. *)
-
- var b,c,d: mat;
- h2,dtc,t1 : real;
- begin
- h2 := h1/2;
- c[1,1] := 1 - a[1,1]*h2; (* find matrix C = (U - A*h/2) *)
- c[1,2] := -a[1,2]*h2;
- c[2,1] := -a[2,1]*h2;
- c[2,2] := 1 - a[2,2]*h2;
- d[1,1] := 1 + a[1,1]*h2; (* find matrix D = (U + A*h/2) *)
- d[1,2] := a[1,2]*h2;
- d[2,1] := a[2,1]*h2;
- d[2,2] := 1 + a[2,2]*h2;
- dtc := c[1,1]*c[2,2] - c[1,2]*c[2,1]; (* find det C *)
- if dtc = 0 then writeln('Divide by zero. Change increment.');
- b[1,1] := c[2,2]/dtc; (* find the inverse of matrix C *)
- b[1,2] := -c[1,2]/dtc;
- b[2,1] := -c[2,1]/dtc;
- b[2,2] := c[1,1]/dtc;
- c[1,1] := b[1,1]*d[1,1] + b[1,2]*d[2,1]; (* Find C-inverse x D *)
- c[1,2] := b[1,1]*d[1,2] + b[1,2]*d[2,2];
- c[2,1] := b[2,1]*d[1,1] + b[2,2]*d[2,1];
- c[2,2] := b[2,1]*d[1,2] + b[2,2]*d[2,2];
- integ2(b,c,h1,0,tr,x10,x20,np1);
- end;
-
- procedure change(var h1: real; var np1: integer); forward;
- (* Halves the increment of integration, if desired. *)
-
- var b: char;
-
- procedure integ2; (* Comment above *)
-
- begin
- y1 := y10;
- y2 := y20;
- t := t1;
- h2 := h1/2;
- writeln(t:6:3,'':5,y1:9,' ',y2:9);
- while t <= t1 + tr1 + h1*np1 do
- begin
- for i := 1 to np1 do
- begin (* find Y(k+1) = C*Y(k) + B*(F(k) + F(k+1))*h/2 *)
- y11 := c[1,1]*y1 + c[1,2]*y2;
- y12 := b[1,1]*(fn1(t) + fn1(t+h1))*h2;
- y13 := b[1,2]*(fn2(t) + fn2(t+h1))*h2;
- y21 := c[2,1]*y1 + c[2,2]*y2;
- y22 := b[2,1]*(fn1(t) + fn1(t+h1))*h2;
- y23 := b[2,2]*(fn2(t) + fn2(t+h1))*h2;
- y1 := y11 + y12 + y13;
- y2 := y21 + y22 + y23;
- t := t + h1;
- end;
- writeln(t:6:3,'':5,y1:9,' ',y2:9);
- end;
- change(h1,np1);
- end;
-
-
- procedure change; (* Comment above *)
-
- begin
- write('Try a smaller increment? ');
- readln(b);
- writeln;
- if b = 'y' then
- begin
- h1 := h1/2;
- np1 := 2*np1;
- constants(a,h1,np1);
- end;
- end;
-
-
-
- begin (* main *)
- writeln('Forcing functions must be in function subprograms.');
- writeln;
- write('Input coefficients a(1,1) and a(1,2) (with space between): ');
- readln(a[1,1],a[1,2]);
- writeln;
- write('Input coefficients a(2,1) and a(2,2): ');
- readln(a[2,1],a[2,2]);
- writeln;
- write('Input initial values x1(0) and x2(0): ');
- readln(x10,x20);
- writeln;
- write('Input run time: ');
- readln(tr);
- writeln;
- write('Input time increment and no. of increments between print: ');
- readln(h,np);
- writeln;
- writeln(' Time':10,' x1':10,' x2':10);
- writeln;
- constants(a,h,np);
- end.