Результат вычислений равен NaN
Всем доброго дня. Подскажите мне, пожалуйста, в чем может быть проблема. Решаю задачу Пуассона для двумерного пространства. Программа н-ое количество раз делает вычисления правильно, на на (н+1) разе получаю ошибку (error = Nan). Ошибка возникает в этом месте кода:
for i := 2 to n1 - 1 do
begin
for j := 1 to m1 do ui[j] := Unew[i, j];
Prog(1, m1, ui, 1, ui[1], 0, 1, ui[m1], 0, 1, 0, coef1);
for j := 1 to m1 do unew1[i, j] := ui[j];
end;
Когда использовал assignfile(output, 'гoutput.txt'); rewrite(output); write(output, ui [j]); closefile(output)  , то в массиве ui были значения NaN. Сама функция Prog мне недоступна, поскольку ее дал мне преподаватель и она, по его словам, работает отлично. Он сказал, что, возможно, проблема связана с использованием глобальных переменных i, j, что они принимают значения, для которых массив не создавался.
ProgInit(ui, n); - создания одномерного массива n-ого размера
getmem1(y, sizeoffloat, m); - создания одномерного массива m -ого размера
getmem1(x, sizeoffloat, n); - создания одномерного массива n-ого размера
getmem2(u, sizeoffloat, n, m); - создания двумерного массива n х m -ого размера
getmem2(Unew, sizeoffloat, n, m); - создания двумерного массива n х m -ого размера
getmem2(unew1, sizeoffloat, n, m); - создания двумерного массива n х m -ого размера
getmem2(Func, sizeoffloat, n, m); - создания двумерного массива n х m -ого размера
Ну а это соответственно очистка массивов
Freemem1(y, sizeoffloat, m);
Freemem1(x, sizeoffloat, n);
Freemem2(u, sizeoffloat, n, m);
Freemem2(Unew, sizeoffloat, n, m);
Freemem2(Unew1, sizeoffloat, n, m);
Freemem2(Func, sizeoffloat, n, m);
ProgFree(ui, n);
Ехе файл во вложениях
Код:
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls;
type
TForm3 = class(TForm)
Image1: TImage;
Button2: TButton;
Button3: TButton;
Label1: TLabel;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
Label3: TLabel;
Edit3: TEdit;
Label4: TLabel;
Edit4: TEdit;
Label5: TLabel;
Edit5: TEdit;
Label6: TLabel;
Edit6: TEdit;
Label7: TLabel;
Edit7: TEdit;
Label8: TLabel;
Label9: TLabel;
Edit8: TEdit;
Label10: TLabel;
Edit9: TEdit;
Label11: TLabel;
Edit10: TEdit;
Label12: TLabel;
Edit11: TEdit;
Label13: TLabel;
Edit12: TEdit;
Label14: TLabel;
Edit13: TEdit;
Label15: TLabel;
Edit14: TEdit;
Label16: TLabel;
Edit15: TEdit;
Label17: TLabel;
Edit16: TEdit;
Label18: TLabel;
Edit17: TEdit;
Label19: TLabel;
Edit18: TEdit;
CheckBox1: TCheckBox;
Memo1: TMemo;
Label20: TLabel;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
CheckBox4: TCheckBox;
CheckBox5: TCheckBox;
ProgressBar1: TProgressBar;
Button1: TButton;
Label21: TLabel;
Edit19: TEdit;
Label22: TLabel;
Edit20: TEdit;
Label23: TLabel;
Edit21: TEdit;
Label24: TLabel;
Edit22: TEdit;
Label25: TLabel;
Edit23: TEdit;
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
uses typedef, arrdef, progon;
{$R *.dfm}
var
pixelMaxx, pixelMaxy: word;
i,j: word;
x0gr, y0gr, xgr, ygr, dx, dy: float;
TimeStr, Date1: TdateTime;
num: byte;
gizoline: float;
error: float;
var
u, Unew, unew1, Func: arr2ptr;
x, y: arr1ptr;
A, B, C, D: float;
dt, k: float;
ui: arr1ptr;
{$I izoline}
// -------------------------------------------------------------------------------
procedure coef1(j: word; var a, b, c, d: float; w, w1: float);
begin
A := k * dt / sqr(dx);
C := A;
B := -(2 * A + 2 * k * dt / sqr(dy) + 1);
D := -u[i, j] - dt * k * (Unew[i + 1, j] + Unew[i - 1, j]) / sqr(dy) - dt * Func[i, j];
end;
procedure Progonka2D(leftx1, lefty1, rightx1, righty1, n1, m1, k21, k31, k41, k51: integer);
var
error1:float;
begin
for i := 2 to n1 - 1 do
begin
for j := 1 to m1 do ui[j] := Unew[i, j];
Prog(1, m1, ui, 1, ui[1], 0, 1, ui[m1], 0, 1, 0, coef1);
for j := 1 to m1 do unew1[i, j] := ui[j];
end;
error := 0;
for i := leftx1 to rightx1 do for j := lefty1 to righty1 do
begin
error1 := abs(unew1[i, j] - Unew[i, j]);
if error <= error1 then error := error1;
end;
for i := 2 to n1 - 1 do for j := 2 to m1-1 do
Unew[i, j] := unew1[i, j];
if (k21 = 1) then for j := 1 to m1 do
Unew[1, j] := Unew[2, j];
if (k31 = 1) then for j := 1 to m1 do
Unew[n1, j] := Unew[n1 - 1, j];
if (k41 = 1) then for i := 1 to n1 do
Unew[i, 1] := Unew[i, 2];
if (k51 = 1) then for i := 1 to n1 do
Unew[i, m1] := Unew[i, m1 - 1];
for i := 1 to n1 do for j := 1 to m1 do u[i, j] := Unew[i, j];
end;
//----------------------------------------------------------------------------------------
procedure TForm3.Button3Click(Sender: TObject);
var
k2, k3, k4, k5: integer;
iii, jjj, kk: integer;
Koef: float;
Stat: integer;
nitr: integer;
m,n:integer;
liva, prava, nyznja, verxnja, seredyna: float;
leftx, lefty, rightx, righty: integer;
begin
TimeStr := time;
pixelMaxx := 300;
pixelMaxy := 300;
KodGr := 1;
MaxColor := 1000;
ColorMode := 1;
x0gr := 0.02;
y0gr := 0.02;
xgr := 0.98;
ygr := 0.98;
num := 10;
gizoline := 1;
Edit13.Clear;
Edit14.Clear;
Edit19.Clear;
Edit20.Clear;
Edit21.Clear;
Edit22.Clear;
Edit23.Clear;
Image1.Picture := nil;
n := StrToInt(Edit1.Text);
leftx := StrToInt(Edit15.Text);
lefty := StrToInt(Edit16.Text);
rightx := StrToInt(Edit17.Text);
righty := StrToInt(Edit18.Text);
m := StrToInt(Edit2.Text);
k := StrToFloat(Edit3.Text);
Koef := StrToFloat(Edit4.Text);
liva := StrToFloat(Edit8.Text);
prava := StrToFloat(Edit9.Text);
nyznja := StrToFloat(Edit10.Text);
verxnja := StrToFloat(Edit11.Text);
seredyna := StrToFloat(Edit12.Text);
dt := 0.001 * StrToFloat(Edit6.Text);
// --------------------------------
dx := 1 / (n - 1);
dy := 1 / (m - 1);
ProgInit(ui, n);
getmem1(y, sizeoffloat, m);
getmem1(x, sizeoffloat, n);
getmem2(u, sizeoffloat, n, m);
getmem2(Unew, sizeoffloat, n, m);
getmem2(unew1, sizeoffloat, n, m);
getmem2(Func, sizeoffloat, n, m);
x[1] := 0;
for iii := 1 to n - 1 do x[iii + 1] := x[iii] + dx;
y[1] := 0;
for jjj := 1 to m - 1 do y[jjj + 1] := y[jjj] + dy;
for iii := 1 to n do for jjj := 1 to m do
Func[iii, jjj] := Koef * (sqr(x[iii]) + sqr(y[jjj]));
for iii := 2 to n - 1 do for jjj := 2 to m - 1 do
u[iii, jjj] := seredyna;
for jjj := 1 to m do u[1, jjj] := liva;
for jjj := 1 to m do u[n, jjj] := prava;
for iii := 1 to n do u[iii, 1] := nyznja;
for iii := 1 to n do u[iii, m] := verxnja;
for iii := 1 to n do for jjj := 1 to m do
Unew[iii, jjj] := u[iii, jjj];
for iii := 1 to n do for jjj := 1 to m do
unew1[iii, jjj] := u[iii, jjj];
if ((CheckBox2.Checked = False) and (CheckBox3.Checked = False) and
(CheckBox4.Checked = False) and (CheckBox5.Checked = False)) then
kk := 0
else
kk := 1;
{ условия Дирихле}
if (CheckBox2.Checked = True) then k2 := 1;
if (CheckBox3.Checked = True) then k3 := 1;
if (CheckBox4.Checked = True) then k4 := 1;
if (CheckBox5.Checked = True) then k5 := 1;
nitr := 0;
Stat:= 0;
repeat
Stat:=Stat+1;
nitr := nitr + 1;
Progonka2D(leftx, lefty, rightx, righty, n, m, k2, k3, k4, k5);
Edit13.Text := IntToStr(nitr);
Edit19.Text := FloatToStr(error);
Application.ProcessMessages;
if (Stat>100) then Stat:=0;
ProgressBar1.Position:=Stat;
until (error < 0.00001);
// очищаем память
Freemem1(y, sizeoffloat, m);
Freemem1(x, sizeoffloat, n);
Freemem2(u, sizeoffloat, n, m);
Freemem2(Unew, sizeoffloat, n, m);
Freemem2(Unew1, sizeoffloat, n, m);
Freemem2(Func, sizeoffloat, n, m);
ProgFree(ui, n);
Edit13.Text := IntToStr(nitr);
Edit14.Text := IntToStr(kk);
Edit20.Text := IntToStr(k2);
Edit21.Text := IntToStr(k3);
Edit22.Text := IntToStr(k4);
Edit23.Text := IntToStr(k5);
Date1 := time - TimeStr;
Edit7.Text := TimeToStr(Date1);
end;
end.
|