Литература / Козин Р.Г. Алгоритмы численных методов линейной алгебры и их программная реализация
.pdfprintf("\nПовторить вычисления для новых параметров итерационного процесса - введите 0, иначе 1: ");
scanf("%d",&fl);
}
break; case 1:
printf("\nВ матрице системы есть диагональный компонент = 0 !"); fl=1;
break; case 2:
printf("\nМетод разошелся !"); break;
}
}
printf("\nДля завершения программы нажмите любую клавишу и ENTER "); scanf("%s",s); printf("\n");
return 0;
}
//п/п реализует итерационный метод верхней релаксации int iter_Up(){
int i,j,k,fl=0;
float nt,buf,norm,norm_old=0,t1=1-t; //нормировка системы for(i=0;i<n;i++){
A(i,n+1)=A(i,n);
if (fabs(A(i,i)<1.E-30))return 1; //есть A(i,i)=0 A(i,n)=t*A(i,n)/A(i,i); for(j=0;j<n;j++)if(i!=j)A(i,j)=t*A(i,j)/A(i,i);
}
it=0; //число выполненных итераций for(k=1;k<=iter;k++){ //цикл по итерациям
it=it+1; norm=0;
for(i=0;i<n;i++){ //цикл по уравнениям buf=t1*A(i,n+1)+A(i,n);
for(j=0;j<n;j++) if(i!=j)buf=buf-A(i,j)*A(j,n+1); nt=fabs(buf-A(i,n+1)); A(i,n+1)=buf; if(nt>norm) norm=nt;
}
epst=norm;
if(norm<=eps)return 0; //все хорошо if(norm>norm_old)fl=fl+1;else fl=0; if(fl>3)return 2; //процесс расходится norm_old=norm;
}
return 0;
}
//п/п симметрезует систему void var_M(){
int i,j,k;
for(i=0;i<n;i++){
for(j=0;j<=n;j++){
A(i,j)=0.;
51
for (k=0;k<n;k++)A(i,j)=A(i,j)+B(k,i)*B(k,j);
}
}
}
//п/п вычисляет невязку void Ax_b(){
int i,j; for(i=0;i<n;i++){
B(i,n+1)=B(i,n);
for(j=0;j<n;j++) B(i,n+1)=B(i,n+1)-B(i,j)*A(j,n+1);
}
}
Скриншоты с результатами работы программы:
52
Итерационные методы целесообразно применять для систем линейных уравнений с сильно разреженными нерегулярными матрицами. Подобные системы обыно возникают при решении разностными методами задач математической физики.
Рассмотрим пример использования метода Зейделя при решении задачи стационарной теплопроводности.
Словесная (вербальная) формулировка задачи: при заданной плотности источников q(x, y) найти распределение температуры
T(x, y) в плоской прямоугольной области, две границы которой
теплоизолированы, а через другие происходит теплообмен. Математически эта задача записывается следующим образом:
|
2 |
|
2 |
|
q(x, y), |
(x, y) [0,lx ; 0,ly ], |
k |
T2 |
|
T2 |
|
||
|
x |
|
y |
|
|
|
|
|
|
T |
0, x 0; |
T 0, y 0, |
|
|
||||
|
|
|
x |
|
|
|
y |
|
|
|
|
k |
T |
x |
(T T ), |
x l |
; |
k T |
y |
(T T ), y l |
. |
||
|
x |
|
0 |
x |
|
y |
0 |
y |
|
||
|
|
|
|
|
|
|
|
|
|
||
Здесь k,T0 , x , y – соответственно коэффициент теплопроводно-
сти, температура окружающей среды и коэффициенты поверхностной теплопроводности.
Для уменьшения зависимости задачи от исходных параметров перейдем к новым величинам:
|
|
y |
|
y |
, x |
|
x |
|
|
|
|
|
|
|
||||
|
|
|
ly |
|
|
|
|
|
|
|||||||||
|
|
|
|
ly |
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
l |
x |
|
|
||
y [0,1], x 0, lx |
|
|
, |
|||||||||||||||
|
|
|||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
ly |
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
T T T |
, |
|
q |
q l2 |
, |
|
|
|
|
|||||||||
|
|
|
|
|
|
0 |
|
|
|
|
|
k y |
|
|
|
|
|
|
|
|
|
x l |
, |
|
|
|
|
y |
|
l |
|
. |
|
||||
|
|
|
k |
|
|
|||||||||||||
|
x |
|
k y |
|
|
|
|
y |
|
|
y |
|
|
|
||||
53
С учетом этих изменений исходная задача примет вид |
||||
2T |
2T q(x, y), |
(x, y) [0,l |
; 0,1], |
|
x2 |
y2 |
|
x |
|
|
T 0, x 0; |
T |
0, y 0, |
|
|
x |
y |
|
|
T |
xT , x lx ; |
T |
yT , y 1. |
|
x |
|
y |
|
|
Рис. 2.6. Разностная сетка, используемая при решении задачи теплопроводности |
||||
|
для плоской прямоугольной области. |
|||
Приведенную задачу будем решать разностным методом. Для этого область покроем прямоугольной сеткой (рис. 2.6), а уравнение теплопроводности и граничные условия запишем через значе-
ния искомой функции T (x, y) в узлах сетки (Tij ):
Ti 1 j 2Tij Ti 1 j |
|
Tij 1 |
2Tij Tij 1 |
q |
, |
(i, j) [0, N |
|
;0, N |
|
], |
|
|
h 2 |
x |
y |
||||||
h 2 |
i, j |
|
|
|
|
|||||
x |
y |
|
|
|
|
|
|
|
||
54
|
T1 j T 1 j |
0, |
j [0, Ny ]; |
Ti1 Ti 1 |
0, i [0, Nx ], |
|
|
|
||||||||
|
|
2hx |
|
2hy |
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
TNx 1 j TNx 1 j |
|
T |
, |
j [0, N |
y |
]; |
Ti N y 1 Ti Ny 1 |
|
T |
, i [0, |
N |
x |
]. |
|||
|
|
|
|
|||||||||||||
2hx |
|
x |
Nx j |
|
|
|
2hy |
|
|
y i N y |
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
Разностная задача аппроксимирует исходную с точностью порядка O(hx2 , hy2 ) . Последнее легко проверить, если в разностные
аппроксимации всех производных подставить соответствующее разложение Тейлора, подобное данному:
T |
T (x , y |
|
) h |
T |
(x , y |
|
) 1 h2 2T |
(x , y |
|
) |
||||||||
i 1 j |
|
i |
j |
|
x x |
i |
|
j |
2 |
x x2 |
|
|
i |
j |
|
|||
|
|
1 h3 3T |
(x , y |
|
) |
1 |
h4 4T |
( |
, y |
|
), |
|
|
|||||
|
|
|
|
|
|
|||||||||||||
|
|
6 x x3 |
i |
|
j |
|
24 |
x x4 |
x |
|
|
j |
|
|
|
|||
где x [xi , xi hx ].
Исключив с помощью граничных условий из разностных уравнений для граничных узлов значения Tij , связанные с внешними
узлами, и разрешив после этого все линейные уравнения относительно диагональных элементов разреженной матрицы, получим систему уравнений в форме, соответствующей методу Зейделя.
Процедура реализация метода Зейделя для данной системы выглядит следующим образом:
все узлы сетки обрабатываются слева направо слой за слоем, начиная с нижнего слоя ( i 0 );
выход из итерационного процесса происходит по критерию
max |
T k T k 1 |
eps , где k – номер итерации, или по исчерпанию |
|
i, j |
ij |
ij |
|
|
|
|
|
заданного числа итераций.
Реализация метода Зейделя для решения приведенной задачи теплопроводности выполнена в рамках пакета Maxima. Листинг соотвествующей программы и некоторые результаты ее работы приведены на рис 2.7–2.10. При тестировании использовались следующие исходные данные:
lx 2, hx hy 0,1, Nx 20, Ny 10,x y 1, q(x, y) (2 x)(1 y).
55
kill(all);
/* подпрограмма рассчитывает коэффициенты разностной разреженной системы */ /* линейных уравнений */
coef(hx,hy,alfx,alfy):=block
(
M:zeromatrix(9,3),
M[1,3]:hx^2*hy^2/(2*(hx^2+hy^2)), M[1,1]:M[1,3]*2/hx^2, M[1,2]:M[1,3]*2/hy^2, M[2,3]:M[1,3], M[2,1]:M[2,3]/hx^2, M[2,2]:M[1,2], M[3,3]:hx^2*hy^2/(2*(hx^2+hy^2+alfx*hx*hy^2)), M[3,1]:M[3,3]*2/hx^2,
M[3,2]:M[3,3]*2/hy^2,
M[4,3]:M[1,3], M[4,1]:M[1,1], M[4,2]:M[4,3]/hy^2,
M[5,3]:M[1,3], M[5,1]:M[5,3]/hx^2, M[5,2]:M[4,2],
M[6,3]:M[3,3], M[6,1]:M[3,1], M[6,2]:M[6,3]/hy^2, M[7,3]:hx^2*hy^2/(2*(hx^2+hy^2+alfy*hy*hx^2)), M[7,1]:M[7,3]*2/hx^2,
M[7,2]:M[7,3]*2/hy^2,
M[8,3]:M[7,3], M[8,1]:M[8,3]/hx^2, M[8,2]:M[7,2], M[9,3]:hx^2*hy^2/(2*(hx^2+hy^2+alfx*hx*hy^2+alfy*hy*hx^2)), M[9,1]:M[9,3]*2/hx^2,
M[9,2]:M[9,3]*2/hy^2
);
define(f(x,y),(2-x)*(1-y)); /* заданная функция тепловыделения */
/* подпрограмма рассчитывает значения плотности тепловыделения в узлах сетки */ create_q(Nx,Ny,hx,hy):=block
(
[i,j,x,y],
q:zeromatrix(Nx+1,Ny+1), for i thru Nx+1 do
(
x:hx*(i-1), for j thru Ny+1 do (y:hy*(j-1), q[i,j]:f(x,y))
)
);
/* подпрограмма реализует итерационный метод Зейделя для разностной системы */ /* линейных уравнений */
zadel(Nx,Ny,iter,eps):=block
(
[i,j,k,buf,nt],
it:0, T:zeromatrix(Nx+1,Ny+1), for k thru iter do
(
it:it+1, norm:0,
/* обработка нижнего слоя сетки */ buf:M[1,1]*T[2,1]+M[1,2]*T[1,2]+M[1,3]*q[1,1], nt:abs(T[1,1]-buf), T[1,1]:buf, if nt>norm then norm:nt, for i:2 thru Nx do
(
buf:M[2,1]*(T[i-1,1]+T[i+1,1])+M[2,2]*T[i,2]+M[2,3]*q[i,1], nt:abs(T[i,1]-buf), T[i,1]:buf, if nt>norm then norm:nt
Рис. 2.7. Листинг программы, рассчитывающей температуру над прямоугольной областью (начало)
56
),
buf:M[3,1]*T[Nx,1]+M[3,2]*T[Nx+1,2]+M[3,3]*q[Nx+1,1], nt:abs(T[Nx+1,1]-buf), T[Nx+1,1]:buf, if nt>norm then norm:nt, /* обработка промежуточных слоев сетки */
for j:2 thru Ny do
(
buf:M[4,1]*T[2,j]+M[4,2]*(T[1,j-1]+T[1,j+1])+M[4,3]*q[1,j], nt:abs(T[1,j]-buf), T[1,j]:buf, if nt>norm then norm:nt,
for i:2 thru Nx do
(
buf:M[5,1]*(T[i-1,j]+T[i+1,j])+M[5,2]*(T[i,j-1]+T[i,j+1])+M[5,3]*q[i,j], nt:abs(T[i,j]-buf), T[i,j]:buf, if nt>norm then norm:nt
), buf:M[6,1]*T[Nx,j]+M[6,2]*(T[Nx+1,j-1]+T[Nx+1,j+1])+M[6,3]*q[Nx+1,j], nt:abs(T[Nx+1,j]-buf), T[Nx+1,j]:buf, if nt>norm then norm:nt
), /* обработка последнего слоя сетки */
buf:M[7,1]*T[2,Ny+1]+M[7,2]*T[1,Ny]+M[7,3]*q[1,Ny+1], nt:abs(T[1,Ny+1]-buf), T[1,Ny+1]:buf, if nt>norm then norm:nt, for i:2 thru Nx do
(
buf:M[8,1]*(T[i-1,Ny+1]+T[i+1,Ny+1])+M[8,2]*T[i,Ny]+M[8,3]*q[i,Ny+1], nt:abs(T[i,Ny+1]-buf), T[i,Ny+1]:buf, if nt>norm then norm:nt
),
buf:M[9,1]*T[Nx,Ny+1]+M[9,2]*T[Nx+1,Ny]+M[9,3]*q[Nx+1,Ny+1], nt:abs(T[Nx+1,Ny+1]-buf), T[Nx+1,Ny+1]:buf, if nt>norm then norm:nt, if norm<=eps then return(0) /* 0 - заданная точность достигнута */
)
);
/* главная программа */ numer:true; fpprintprec:5;
hx:0.1; hy:0.1; alfx:1; alfy:1; coef(hx,hy,alfx,alfy); M; Nx:20; Ny:10; create_q(Nx,Ny,hx,hy); q;
h(x,y):=('q[round(x)+1,round(y)+1]);
plot3d(h(x,y),[x,0,20],[y,0,10],[grid,20,10], [legend, "График распределение плотности источников"]);
eps:0.00001; iter:1500; zadel(Nx,Ny,iter,eps); it;norm; tem(x,y):=('T[round(x)+1,round(y)+1]); plot3d(tem(x,y),[x,0,20],[y,0,10],[grid,20,10],[legend, "График распределение темпера-
туры"]);
/* поток через верхнюю границу y=1, численное интегрирование методом трапеций */ Ly:submatrix(T,1,2,3,4,5,6,7,8,9,10); s1:((Ly[1,1]+Ly[21,1])/2+sum(Ly[i,1],i,2,20))*hx*alfy; /* поток через правую границу x=2 */ Lx:submatrix(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,T); s2:((Lx[1,1]+Lx[1,11])/2+sum(Lx[1,j],j,2,10))*hy*alfx;
print("Суммарный поток энергии через границу области = ",s:s1+s2); print("Суммарная плотность тепловыделения внутри области = ",integrate(2-x, x,0,2)*integrate(1-y,y,0,1));
Рис. 2.7. Окончание
57
Рис. 2.8. Некоторые результаты выполнения программы пакетом Maxima: матрицы коэффициентов системы и рассчитанных значений температуры в узлах сетки, число использованных итераций и достигнутая точность.
Было выполнено 1500 итераций методом Зейделя. При этом достигнута точность
max |
T k T k 1 |
0,00735 , где k – номер итерации метода Зейделя |
|
i, j |
ij |
ij |
|
|
|
58 |
|
|
|
|
|
Рис. 2.9. График распределения заданной плотности тепловыделения q(x, y) (2 x)(1 y)
Рис. 2.10. График распределения температуры, рассчитанной методом Зейделя для разностной задачи теплопроводности
