|
Текст подпрограммы и версий de59r_p.zip de59e_p.zip de60r_p.zip de60e_p.zip de57r_p.zip de57e_p.zip de58r_p.zip de58e_p.zip |
Тексты тестовых примеров tde59r_p.zip tde59e_p.zip tde60r_p.zip tde60e_p.zip tde57r_p.zip tde57e_p.zip tde58r_p.zip tde58e_p.zip |
Вычисление решения двухточечной краевой задачи для обыкноновенного линейного самосопряженного дифференциального уравнения второго порядка с разрывными коэффициентами на равномерной сетке с помощью однородной консервативной разностной схемы второго порядка точности.
Решается двухточечная краевая задача для линейного самосопряженного уравнения второго порядка
(1) d (k(x) dy/dx) / dx - g(x) y = - r(x) , xN < x < xK
с разрывными коэффициентами
(2) k(x) , g(x) , r(x) ∈ Q( 2 ) [xN, xK]
( Q ( 2 ) [xN, xK] - класс функций, кусочно - непрерывных на [xN, xK] вместе со вторыми производными ), удовлетворяющими неpавенствам
(3) k(x) ≥ c > 0 , g(x) ≥ 0 .
Hа концах отрезка [xN, xK] задаются произвольные комбинации следующих краевых условий
при x = xN (4) 1) y( xN ) = GN , (5) 2) k dy/dx - ( σN y - μN ) = 0 , σN ≥ 0 , при x = xK (6) 1) y( xK ) = GK , (7) 2) - k dy/dx - ( σK y - μK ) = 0 , σK ≥ 0 ;
при σN > 0 условие (5) (а при σK > 0 условие (7)) является условием третьего рода, при σN = 0 (или при σK = 0) - условием второго рода.
Решение вычисляется на равномерной сетке узлов, заданной на [xN, xK], с помощью однородной консервативной разностной схемы, имеющей на указанном классе коэффициентов (2) второй порядок точности, при этом предполагается, что точки разрыва коэффициентов k (x), g (x) и r (x) уравнения (1) совпадают с узлами этой сетки.
Самарский A.A., Теория разностных схем, "Hаука", M., 1977.
procedure DE59R(var CK :Array of Real; var CG :Array of Real;
var CR :Array of Real; NX :Integer; XN :Real;
XK :Real; GN1 :Boolean; var GN :Array of Real;
GK1 :Boolean; var GK :Array of Real;
var Y :Array of Real; var ALP :Array of Extended;
var BET :Array of Extended; var IERR :Integer);
Параметры
| NX - | число узлов равномерной сетки, включая концы отрезка интегрирования, в которых требуется вычислить решение краевой задачи; NX > 1 (тип: целый); |
| XN, XK - | концы отрезка интегрирования, в которых задаются граничные условия (4) или (5) и (6) или (7), соответственно; XK > XN (тип: вещественный); |
| CK - |
одномерный вещественный массив длины NX - 1,
содержащий на входе в подпрограмму значения
коэффициента k (x) уравнения, а именно:
I - й элемент CK (I) массива содержит значение
функции k (x) в точке x = XN + (I - 1/2) * (XK - XN)/(NX - 1); функция k (x) должна принимать положительные значения; |
| CG, CR - |
одномерные вещественные массивы длины 2*NX - 2,
содержащие на входе в подпрограмму значения коэффициентов
g (x) и r (x), соответственно, а именно: CG (1) содержит предел справа функции g (x) в начале XN отрезка интегрирования, (2*I) - й и (2*I + 1) - й элементы CG (2*I), CG (2*I + 1) массива CG содержат, соответственно, пределы слева и справа функции g (x) в узле сетки x = XN + I*(XK - XN)/(NX - 1) (I = 1, 2, ..., NX - 2), (2*NХ - 2) - й элемент CG (2*NX - 2) массива CG содержит предел слева функции g (x) в конце XK отрезка интегрирования, элементы массива CR содержат аналогичные значения, вычисленные для функции r (x); |
| GN1 - | логическая переменная (или логическая константа), имеющая на входе в подпрограмму значение TRUE, если в начале XN отрезка интегрирования задано граничное условие первого рода (4), и FALSE в противном случае, т.е. когда в XN задано условие 2 - го или 3 - его рода (5); |
| GN - |
если GN1 = TRUE, то GN представляет значение
решения в начале XN отрезка интегрирования; если GN1 = FALSE, то GN является именем одномерного массива длины 2, первый элемент GN (1) которого содержит значение σN, а второй элемент GN (2) - значение μN, входящие в граничное условие (5) (тип: вещественный); |
| GK1 - | логическая переменная (или логическая константа), имеющая на входе в подпрограмму значение TRUE, если в конце XK отрезка интегрирования задано граничное условие первого рода (6), и FALSE в противном случае, т.е. когда в XK задано условие 2 - го (σK = 0) или 3 - го (σK > 0) рода (7); |
| GK - |
если GK1 = TRUE, то GK представляет значение
решения в конце отрезка интегрирования; если GK1 = FALSE, то GK является именем одномерного массива длины 2, первый элемент GK (1) которого содержит значение σK, а второй элемент GK (2) - значение μK, входящие в граничное условие (7) (тип: вещественный); |
| Y - |
одномерный вещественный массив длины NX,
содержащий на выходе из подпрограммы решение
краевой задачи, вычисленное на равномерной
сетке; при этой I - й элемент Y (I) этого
массива содержит приближенное значение решения в узле XN + (I - 1)*(XK - XN)/(NX - 1); |
|
ALP - BET | одномерные вещественные рабочие массивы расширенной (Extended) точности длины NX - 1; |
| IERR - | целая переменная, служащая для сообщения об ошибках, обнаруженных в процессе работы подпрограммы; при этом: |
| IERR=65 - | если в граничном условии (5) коэффициент σN < 0; |
| IERR=66 - | если в граничном условии (7) коэффициент σK < 0; |
| IERR=67 - | если какое - нибудь значение коэффициента k (x), заданного в массиве CK, меньше или pавно 0; |
| IERR=68 - | если какое - нибудь значение коэффициента g (x), заданного в массиве CG, меньше 0; |
| IERR=69 - | если значение NX ≤ 1; |
| IERR=70 - | если XK ≤ XN; |
| во всех указанных случаях интегрирование уравнения прекращается. |
Версии
| DE60R - | вычисление решения двухточечной краевой задачи для обыкновенного линейного самосопряженного дифференциального уравнения второго порядка с разрывными коэффициентами на неравномерной сетке. |
| DE57R - | вычисление решения двухточечной краевой задачи для обыкновенного линейного самосопряженного дифференциального уравнения второго порядка с непрерывными коэффициентами на равномерной сетке. |
| DE58R - | вычисление решения двухточечной краевой задачи для обыкновенного линейного самосопряженного дифференциального уравнения второго порядка с непрерывными коэффициентами на неравномерной сетке. |
| DE57E - | то же, что и DE57R, при этом все арифметические операции с вещественными числами выполняются с удвоенным числом значащих цифр. |
| DE58E - | то же, что и DE58R, при этом все арифметические операции с вещественными числами выполняются с удвоенным числом значащих цифр. |
| DE59E - | то же, что и DE59R, при этом все арифметические операции с вещественными числами выполняются с удвоенным числом значащих цифр. |
| DE60E - | то же, что и DE60R, при этом все арифметические операции с вещественными числами выполняются с удвоенным числом значащих цифр. |
|
Первые операторы этих подпрограмм имеют следующий вид:
procedure DE60R(var CK :Array of Real; var CG :Array of Real;
var CR :Array of Real; NX :Integer;
var X :Array of Real; GN1 :Boolean;
var GN :Array of Real; GK1 :Boolean;
var GK :Array of Real; var Y :Array of Real;
var ALP :Array of Extended; var BET :Array of Extended;
var IERR :Integer);
Параметр X в подпрограммах DE60R и DE58R - имя одномерного вещественного массива длины NX, в последовательных элементах которого, начиная с первого, размещаются в возрастающем порядке узлы неравномерной сетки, причем начало и конец отрезка интегрирования, в которых заданы граничные условия (4) - (7), хранятся, соответственно, в первом и последнем элементах X (1), X (NX) этого массива. Параметры FK, FG, FR в подпрограммах DE57R и DE58R - имена вещественных подпрограмм - функций function FK (X :Real): Real; function FG (X :Real): Real; function FR (X :Real): Real; вычисляющих значения коэффициентов уравнения k (x), g (x) и r (x), соответственно, при вещественном значении аргумента x = X. Остальные параметры указанных версий имеют такой же смысл, что и одноименные параметры подпрограммы DE59R. При этом значение параметра IERR = 70 в подпрограммах DE60R и DE58R указывает на то, что узлы сетки расположены в массиве X не в возрастающем порядке, значения IERR = 67, 68 в п/п DE58R и DE57R - что значения коэффициентов k (x) и g (x) уравнения, вычисленные с помощью подпрограмм - функций FK и FG, не удовлетворяют требуемое неpавенство (3). B подпрограмме DE60R в массиве CK размещаются значения коэффициента k (x) уравнения, вычисленные в "потоковых" точках, т.е. в середине между узлами сетки, а в массивах CG и CR - пределы слева и справа функций g (x) и r (x) в узлах неравномерной сетки. Kpоме того, каждая из подпрограмм DE57R, DE58R, DE59R и DE60R имеет версию DE57E, DE58E, DE59E и DE60E, соответственно, с теми же самыми эффектом и списком параметpов, выполняющую все операции над действительными числами с удвоенным числом значащих цифр. При этом параметры FK, FG, FR (в подпрограммах DE57E,
DE58E), являются именами подпрограмм - функций |
|
CK, CG - CR | (в подпрограммах DE59E, DE60E), |
| XN, XK - | (в подпрограммах DE57E, DE59E), |
| X - | (в подпрограммах DE58E, DE60E), |
|
GN, GK - Y, ALP BET | (во всех подпрограммах) |
|
должны иметь тип Extended. Тип остальных параметров не изменяется. В версиях подпрограмм DE57R, DE58R, DE59R и DE60R, формальные параметры ALP и BET имеют тип Extended. |
Вызываемые подпрограммы
| UTDE14 - | подпрограмма выдачи диагностических сообщений при работе подпрограмм DE57R, DE58R, DE59R и DE60R. |
| UTDE15 - | подпрограмма выдачи диагностических сообщений при работе подпрограмм DE57E, DE58E, DE59E и DE60E. |
Замечания по использованию
|
Значение параметра NX, задаваемое при обращении к подпрограмме, должно быть достаточно большим, чтобы получить хорошее приближение численного решения к точному решению задачи. При интегрировании дифференциального уравнения (1) с непрерывными коэффициентами с помощью подпрограмм DE57R, DE58R, DE57E, DE58E значения коэффициента k (x) вычисляются в "потоковых" точках, т.е. в середине между узлами, а значения коэффициентов g (x) и r (x) - в узлах сетки последовательно слева направо (начало и конец XN, XK отрезка интегрирования также считаются узлами сетки). Поэтому эти продпрограммы можно использовать также и в случае, когда какой - нибудь из коэффициентов k (x), g (x) и r (x) (или, быть может, все) задан в виде массива значений в указанных точках. Эти значения должны быть расположены в последовательных элементах массива, начиная с первого. При этом: если в XN задано граничное условие 2 - го или 3 - го рода, то значения коэффициентов g (x) и r (x) должны быть заданы, начиная с первого узла XN сетки, а если 1 - го рода, то начиная со второго узла XN + (XK - XN)/(NX - 1); если в конце промежутка XK задано условие 1 - го рода, то значения коэффициентов g (x) и r (x) используются только до (NХ - 1) - го узла включительно. B этом случае каждое обращение к соответствующей подпрограмме - функции вычисления коэффициента сводится к выборке значения очередного элемента массива (см. примеp использования N 3). Значения параметров CK, CG, CR, NX, XK, X, GN1, GN, GK1, GK сохраняются. |
d (k(x) dy/dx) / dx = 0 , y(0) = 1 , y(1) = 0 ,
k(x) = 1 , x ≤ 0.55 ,
k(x) = 10 , x > 0.55 ;
Точное решение:
y = 1 - x/0.595 , x ≤ 0.55 , (1 - x) / 5.95 , x > 0.55 .
Unit TDE59R_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc, UtRes_p, DE59R_p;
function TDE59R: String;
implementation
function TDE59R: String;
var
NX,I,_i,IERR :Integer;
XN,XK,GN,GK :Real;
GN1,GK1 :Boolean;
ALP :Array [0..19] of Extended;
ВЕТ :Array [0..19] of Extended;
Y :Array [0..20] of Real;
СК :Array [0..19] of Real;
CG :Array [0..39] of Real;
CR :Array [0..39] of Real;
label
_200,_5,_15;
begin
Result := ''; { результат функции }
NX := 21;
XN := 0.0;
ХК := 1.0;
GN1 := True;
GN := 1.0;
GK1 := True;
GK := 0.0;
for I:=1 to 40 do
begin
CG[I-1] := 0.0;
CR[I-1] := 0.0;
_200:
end;
for I:=1 to 10 do
begin
_5:
CK[I-1] := 1.0;
end;
for I:=11 to 20 do
begin
_15:
CK[I-1] := 10.0;
end;
DE59R(CK,CG,CR,NX,XN,XK,GN1,GN,GK1,GK,Y,ALP,BET,IERR);
Result := Result + Format('%s',[' IERR=']);
Result := Result + Format('%2d ',[IERR]) + #$0D#$0A;
Result := Result + Format('%s',[' XN=']);
Result := Result + Format('%20.16f ',[XN]);
Result := Result + Format('%s',[' XK=']);
Result := Result + Format('%20.16f ',[XK]);
Result := Result + Format('%s',[' NX=']);
Result := Result + Format('%5d ',[NX]) + #$0D#$0A;
Result := Result + #$0D#$0A;
for _i:=0 to 20 do
begin
Result := Result + Format('%20.16f ',[Y[_i]]);
if ( ((_i+1) mod 4)=0 )
then Result := Result + #$0D#$0A;
end;
Result := Result + #$0D#$0A;
UtRes('TDE59R',Result); { вывод результатов в файл TDE59R.res }
exit;
end;
end.
Результаты:
IERR = 0
Y(1) = 1.00000000000 + 00 Y(11) = 9.09090909100 - 02
Y(2) = 9.09090909089 - 01 Y(12) = 8.18181818191 - 02
Y(3) = 8.18181818179 - 01 Y(13) = 7.27272727281 - 02
Y(4) = 7.27272727271 - 01 Y(14) = 6.36363636372 - 02
Y(5) = 6.36363636362 - 01 Y(15) = 5.45454545463 - 02
Y(6) = 5.45454545453 - 01 Y(16) = 4.54545454552 - 02
Y(7) = 4.54545454545 - 01 Y(17) = 3.63636363643 - 02
Y(8) = 3.63636363636 - 01 Y(18) = 2.72727272732 - 02
Y(9) = 2.72727272727 - 01 Y(19) = 1.81818181822 - 02
Y(10) = 1.81818181818 - 01 Y(20) = 9.09090909109 - 03
Абсолютная погрешность во всех узлах сетки pавна 0.00000000000
2). d ((2 + x) dy/dx) / dx - xy = - 4sin x - 4x sin x + 2cos x , 0 < x < π / 2 ;
2 dy/dx - (1000y + 4) = 0 при x = 0 ,
y = 2 при x = π / 2 .
Решение вычисляется на неравномерной сетке.
Unit tde58r_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc, UtRes_p, FFKDE58R_p, FFGDE58R_p, FFRDE58R_p, DE58R_p;
function tde58r: String;
implementation
function tde58r: String;
var
NX,J,K,I,NXM1,IERR :Integer;
XN,XK,H,GK :Real;
GN1,GK1 :Boolean;
ALP :Array [0..281] of Extended;
BET :Array [0..281] of Extended;
Y :Array [0..282] of Real;
YT :Array [0..282] of Real;
Z :Array [0..282] of Real;
X :Array [0..282] of Real;
GN :Array [0..1] of Real;
label
_1,_100,_20;
begin
Result := ''; { результат функции }
NX := 283;
XN := 0.0;
XK := 1.57079632679;
H := 0.001;
X[0] := XN;
X[281] := XK-0.02;
X[282] := XK;
J := 0;
for K:=1 to 28 do
begin
for I:=1 to 10 do
begin
J := J+1;
_1:
X[J+0] := X[J-1]+(I)*H;
end;
end;
GN1 := False;
GN[0] := 1000.0;
GN[1] := -4.0;
GK1 := True;
GK := 2.0;
DE58R(FFKDE58R,FFGDE58R,FFRDE58R,NX,X,GN1,GN,GK1,GK,Y,ALP,BET,IERR);
Result := Result + Format('%s',[' IERR=']);
Result := Result + Format('%2d ',[IERR]) + #$0D#$0A;
Result := Result + Format('%s',[' XN=']);
Result := Result + Format('%20.16f ',[XN]);
Result := Result + Format('%s',[' XK=']);
Result := Result + Format('%20.16f ',[XK]);
Result := Result + Format('%s',[' NX=']);
Result := Result + Format('%5d ',[NX]);
Result := Result + Format('%s',[' Y']);
Result := Result + Format('%s',[' YT']);
Result := Result + Format('%s',[' Z' + #$0D#$0A]);
NXM1 := NX-1;
for I:=1 to NX do
begin
YT[I-1] := 2.0*Sin(X[I-1]);
Z[I-1] := Y[I-1]-YT[I-1];
_100:
end;
for I:=1 to NXM1 do
begin
Result := Result + Format('%20.16f %20.16f %20.16f ',
[Y[I-1],YT[I-1],Z[I-1]]) + #$0D#$0A;
_20:
end;
Result := Result + Format('%20.16f %20.16f %20.16f ',
[Y[NX-1],YT[NX-1],Z[NX-1]]) + #$0D#$0A;
UtRes('tde58r',Result); { вывод результатов в файл tde58r.res }
exit;
end;
end.
Unit ffkde58r_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc;
function ffkde58r(X :Real): Real;
implementation
function ffkde58r(X :Real): Real;
begin
{ Result - прототип имени функции FK на FORTRANe }
Result := 2.0+X;
exit;
end;
end.
Unit ffgde58r_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc;
function ffgde58r(X :Real): Real;
implementation
function ffgde58r(X :Real): Real;
begin
{ Result - прототип имени функции FG на FORTRANe }
Result := X;
exit;
end;
end.
Unit ffrde58r_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc;
function ffrde58r(X :Real): Real;
implementation
function ffrde58r(X :Real): Real;
begin
{ Result - прототип имени функции FR на FORTRANe }
Result := 4.0*Sin(X)*(1.0+X)-2.0*Cos(X);
exit;
end;
end.
Результаты: (приводятся только для первых 10 узлов)
IERR = 0
Y YT - точное решение
- 4.11615097562 - 08 0.00000000000 + 00
1.99993826288 - 03 1.99999966667 - 03
5.99989114401 - 03 5.99999100000 - 03
1.19997755539 - 02 1.19999280001 - 02
1.99994536197 - 02 1.99996666683 - 02
2.99986015503 - 02 2.99988750126 - 02
4.19965896832 - 02 4.19969130680 - 02
5.59923325737 - 02 5.59926829533 - 02
7.19841091670 - 02 7.19844490075 - 02
3). d ((2 + x) dy/dx) / dx - xy = - 4sin x - 4x sin x + 2cos x , 0 < x < π / 2 ,
y = 0 при x = 0 ,
y = 2 при x = π / 2 ;
Подпрограммы - функции для вычисления значений
коэффициентов k (x) = 2 + x,
g (x) = x  и
r (x) = - 4sin x - 4x sin x + 2cos x ;
те же, что и в примере N 2.
Unit tde57r_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc, UtRes_p, FFKDE57R_p, FFGDE57R_p, FFRDE57R_p, DE57R_p;
function tde57r: String;
implementation
function tde57r: String;
var
NX,NXM1,I,IERR :Integer;
XN,XK,GN,GK,H,X :Real;
GN1,GK1 :Boolean;
Y :Array [0..314] of Real;
ALP :Array [0..313] of Extended;
BET :Array [0..313] of Extended;
YT :Array [0..314] of Real;
label
_100,_20;
begin
Result := ''; { результат функции }
NX := 315;
XN := 0.0;
XK := 1.57079632679;
GN1 := True;
GN := 0.0;
GK1 := True;
GK := 2.0;
DE57R(FFKDE57R,FFGDE57R,FFRDE57R,NX,XN,XK,GN1,GN,GK1,GK,Y,ALP,BET,IERR);
Result := Result + Format('%s',[' IERR=']);
Result := Result + Format('%2d ',[IERR]) + #$0D#$0A;
NXM1 := NX-1;
H := (XK-XN)/NXM1;
X := XN-H;
for I:=1 to NX do
begin
X := X+H;
YT[I-1] := 2.0*Sin(X);
_100:
end;
Result := Result + Format('%s',[' XN=']);
Result := Result + Format('%20.16f ',[XN]);
Result := Result + Format('%s',[' XK=']);
Result := Result + Format('%20.16f ',[XK]);
Result := Result + Format('%s',[' NX=']);
Result := Result + Format('%5d ',[NX]) + #$0D#$0A;
for I:=1 to NXM1 do
begin
Result := Result + Format(' %20.16f %20.16f ',
[Y[I-1],YT[I-1]]) + #$0D#$0A;
_20:
end;
Result := Result + Format(' %20.16f %20.16f ',
[Y[NX-1],YT[NX-1]]) + #$0D#$0A;
UtRes('tde57r',Result); { вывод результатов в файл tde57r.res }
exit;
end;
end.
Unit ffkde57r_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc;
function ffkde57r(X :Real): Real;
implementation
function ffkde57r(X :Real): Real;
begin
{ Result - прототип имени функции FK на FORTRANe }
Result := 2.0+X;
exit;
end;
end.
Unit ffgde57r_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc;
function ffgde57r(X :Real): Real;
implementation
function ffgde57r(X :Real): Real;
begin
{ Result - прототип имени функции FG на FORTRANe }
Result := X;
exit;
end;
end.
Unit ffrde57r_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc;
function ffrde57r(X :Real): Real;
implementation
function ffrde57r(X :Real): Real;
begin
{ Result - прототип имени функции FR на FORTRANe }
Result := 4.0*Sin(X)*(1.0+X)-2.0*Cos(X);
exit;
end;
end.
Результаты: (приводятся только для первых 10 узлов)
IERR = 0
Y YT - точное решение
0.00000000000 + 00 0.00000000000 + 00
1.00050273414 - 02 1.00050304151 - 02
2.00098044150 - 02 2.00098104511 - 02
3.00140808468 - 02 3.00140897354 - 02
4.00176062755 - 02 4.00176179076 - 02
5.00201303585 - 02 5.00201446263 - 02
6.00214027785 - 02 6.00214195751 - 02
7.00211732491 - 02 7.00211924689 - 02
8.00191915218 - 02 8.00192130604 - 02