home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1987 / 05 / partdgl.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-04-15  |  5.4 KB  |  156 lines

  1. {---------------------------------------------------------------------------}
  2. {                            PARTDGL.PAS                                    }
  3. {         Loesen von partiellen DGL-Systemen nach Runge-Kutta               }
  4. {---------------------------------------------------------------------------}
  5.  
  6. PROGRAM Partial_Dgl_Solver;
  7.  
  8. CONST  nm = 20;                                    { Max. Stuetzstellenzahl }
  9.  
  10. TYPE   Vektor = ARRAY[1..nm] OF REAL;
  11.  
  12. VAR    Y, Yo, dY :Vektor;
  13.        Xstart, Xend, x, dx, h, AbsErr, t, t0, tend, dt, ymin, ymax: REAL;
  14.        n, i, k, nmax: INTEGER;
  15.  
  16. {****************************************************************************
  17.  *                                                                          *
  18.  *            Schreibweise einer Partiellen DGL in Prozedur DGL             *
  19.  *                                                                          *
  20.  *            dy         d"y                                                *
  21.  *            --   =  k  ---   =  k ( y[i-1] - 2*y[i] + y[i+1] )            *
  22.  *            dt         dx"                                                *
  23.  *                                                                          *
  24.  ****************************************************************************}
  25.  
  26. PROCEDURE DGL (VAR dY, Y: Vektor; x: REAL);
  27.  
  28. CONST k=0.0023;
  29. VAR   i: INTEGER;
  30.  
  31. BEGIN                                             { Partielle DGL der Form: }
  32.   FOR i := 2 TO Pred(n) DO                        { dY[i]:=f(x,Y[1],..,Y[n] }
  33.     dY[i] :=  k * (Y[i-1] - 2*Y[i] + Y[i+1]);           { FOURIER-Gleichung }
  34.   dY[1] :=  Yo[1];
  35.   dY[n] :=  Yo[n];
  36. END;
  37.  
  38. {---------------------------------------------------------------------------}
  39.  
  40. PROCEDURE Ausgabe (VAR Y: Vektor; x, h: REAL; n, nmax: INTEGER);
  41.  
  42. CONST xpos=0; ypos=0;                                  { Bildschirmposition }
  43. VAR   i: INTEGER;
  44.  
  45. BEGIN
  46.   FOR i := 1 TO n DO
  47.   BEGIN
  48.     GotoXY(xpos,ypos+i);  WriteLn('Y[',i:2,'] =',y[i]);
  49.   END;
  50.   GotoXY(xpos,ypos+n+1);  WriteLn('x     =',x);
  51.   GotoXY(xpos,ypos+n+2);  WriteLn('h     =',h);
  52.   GotoXY(xpos,ypos+n+3);  WriteLn(nmax,' Teilintervalle');
  53. END;
  54.  
  55. {---------------------------------------------------------------------------}
  56.  
  57. PROCEDURE Plot (x, y, xmin, xmax, ymin, ymax: REAL; ch: CHAR);
  58.  
  59. CONST umax=78; vmax=28;                           { Bildschirmbreite/-hoehe }
  60. VAR   u, v: INTEGER;
  61.  
  62. BEGIN
  63.   u :=      Round((x-xmin)/(xmax-xmin)*umax);
  64.   v := vmax-Round((y-ymin)/(ymax-ymin)*vmax);
  65.   GotoXY(u,v);  Write(ch);
  66. END;
  67.  
  68. {---------------------------------------------------------------------------}
  69.  
  70. PROCEDURE RungeKutta (VAR Y, Yo: Vektor; Xstart, Xend: REAL;
  71.                       VAR h: REAL; AbsErr: REAL;
  72.                           n: INTEGER; VAR nmax: INTEGER);
  73.  
  74. VAR C1, C2, C3, C4, z, dY: Vektor;
  75.     x, xo, yalt, Tol: REAL;
  76.     j, k: INTEGER;
  77.  
  78. BEGIN
  79.   yalt := 0; nmax := 4;
  80.   REPEAT
  81.     h := ABS((Xend-Xstart)/nmax);                            { Schrittweite }
  82.     FOR k := 1 TO n DO Y[k] := Yo[k];                  { Anfangsbedingungen }
  83.     FOR j := 0 TO Pred(nmax) DO                     { Runge-Kutta-Iteration }
  84.     BEGIN
  85.       xo := Xstart+j*h;
  86.       DGL(dY, Y, xo);
  87.       FOR k := 1 TO n DO
  88.       BEGIN
  89.         C1[k] := h*dY[k];
  90.         z[k] := Y[k]+C1[k]/2;
  91.       END;
  92.       DGL(dY, z, (xo+h/2));
  93.       FOR k := 1 TO n DO
  94.       BEGIN
  95.         C2[k] := h*dY[k];
  96.         z[k] := Y[k]+C2[k]/2;
  97.       END;
  98.       DGL(dY, z, (xo+h/2));
  99.       FOR k := 1 TO n DO
  100.       BEGIN
  101.         C3[k] := h*dY[k];
  102.         z[k] := Y[k]+C3[k];
  103.       END;
  104.       DGL(dY, z, (xo+h));
  105.       FOR k := 1 TO n DO
  106.       BEGIN
  107.         C4[k] := h*dY[k];
  108.         y[k] := y[k]+(C1[k]+2*C2[k]+2*C3[k]+C4[k])/6;
  109.       END;
  110.     END;
  111.     Tol := ABS(yalt-y[1]);                               { Abbruchkriterium }
  112.     nmax := nmax*2;                                         { Intervallzahl }
  113.     yalt := Y[1];
  114.   UNTIL Tol <= AbsErr;
  115. END;
  116.  
  117. {---------------------------------------------------------------------------}
  118.  
  119. BEGIN { Partial_DGL_Solver }
  120.                                                       { Anfangsbedingungen: }
  121.   n     := 10;                                     { Zahl der Stuetzstellen }
  122.   t0    := 0.0;                    { Zeit }          { t-Anfangsbedingungen }
  123.   tend  := 1200.0;
  124.   dt    := 125.0;
  125.   Xstart:= 0.0;                    { Laenge }        { x-Anfangsbedingungen }
  126.   Xend  := 100.0;
  127.   dx    := (Xend-Xstart)/(n-1);                            { x-Schrittweite }
  128.   Yo[1] := 0.0;            { Temperatur }            { y-Anfangsbedingungen }
  129.   Yo[n] := 0.0;
  130.   FOR i := 2 TO Pred(n) DO
  131.   BEGIN
  132.     x := Xstart+Pred(i)*dx;                                 { Anfangsprofil }
  133.     Yo[i] := x;
  134.   END;
  135.   AbsErr:= 1.0E-3;                                       { Absoluter Fehler }
  136.   ymin  := 0.0;                                  { y-Ausdehnung der Graphik }
  137.   ymax  := 100.0;
  138.  
  139.   ClrScr;
  140.   t := t0;
  141.   k := 0;
  142.   WHILE t <= tend DO                         { Zeitlicher Verlauf: t0..tend }
  143.   BEGIN
  144.     RungeKutta(Y, Yo, t0, t, h, AbsErr, n, nmax);       { DGL-System loesen }
  145.     k := Succ(k);
  146.     FOR i := 1 TO n DO                                  { Loesungen plotten }
  147.     BEGIN
  148.       x := Xstart+Pred(i)*dx;
  149.       Plot(x, Y[i], Xstart, Xend, 0, 100, Chr(47+k));    { Zeichen: 0 bis 9 }
  150.     END;
  151.     Ausgabe(Y, x, h, n, nmax);                         { Loesungen ausgeben }
  152.     t := t+dt;
  153.   END;
  154.   GotoXY(0,0);
  155. END.
  156.