Решил протестировать работу различных методов решения систем линейных уравнений.
Занимаюсь МКЭ , поэтому матрица всегда получается симметричной и положительно определенной (стержневые системы). Поэтому для решения СЛАУ чаще всего приходится пользоваться прямым методом Холесского(квадратных корней) и итерационным методом
Сопряженных Градиентов. На некоторых задачах различные методы дают различное друг от друга решение. Приведу вам небольшой пример:
Тип конструкции: плоская стержневая рама.
см.изображение
В узлах 0 и 2 есть граничные условия 1-ого рода - запрет перемещений по оси Y. Т.е
в узле 0 и 2 перемещения по оси Y равны 0. В узле 1 приложена нагрузка 12 Кн.
Тогда с учетом граничных условий матрица жесткости будет выглядеть так:
Код:
K1 =
1.306165061 0 0.238778392 -1.306165061 1.112148398 0.238778392 0 0 0
0 1 0 0 0 0 0 0 0
0.238778392 0 0.955462467 -0.238778392 -0.245320266 0.477731234 0 0 0
-1.306165061 0 -0.238778392 1.981800485 -0.253351604 -0.422206912 -0.675635424 0 -0.18342852
1.112148398 0 -0.245320266 -0.253351604 2.581973396 -0.119320301 -0.858796794 0 0.125999965
0.238778392 0 0.477731234 -0.422206912 -0.119320301 1.72580511 0.18342852 0 0.385171321
0 0 0 -0.675635424 -0.858796794 0.18342852 0.675635424 0 0.18342852
0 0 0 0 0 0 0 1 0
0 0 0 -0.18342852 0.125999965 0.385171321 0.18342852 0 0.770342643
Вектор узловых нагрузок:
Код:
b1 =
0
0
0
0
12
0
0
0
0
Решаем эту систему, воспользовавшись функцией lsolve из MatCAD:
Код:
x11 = lsolve(K1,b1)
x11 =
-81.084
40.16
-1.362
84.392
2.863
116.913
-43.398
Проверим получившийся результат – вычислим вектор невязки:
Код:
r11 = K1*x11 - b1
r11 =
-1.745E-15
4.943E-15
1.844E-15
-1.243E-14
0
0
-2.089E-15
Близко к нулю, но в идеале хотелось бы получить чтобы все элементы вектора невязки были равны точно нулю.
Решаем эту систему методом Холесского:
Код:
x12 =
7.574879788886595
40.160100751029
87.29667559086803
84.39245474872334
2.8625983863313795
205.57242051314614
-43.39780790330944
r12 = K1*x12 - b1
r12 =
-7.373E-15
5.223E-15
3.634E-15
-2.309E-14
3.178E-15
-6.035E-15
-7.248E-15
Решаем эту систему методом LU - разложения:
Код:
x16 =
-21.787510139058092
40.16010075102904
57.93428566292343
84.39245474872344
2.8625983863313835
176.21003058520168
-43.397807903309484
r16 = K1*x16 - b1
r16 =
6.508E-15
3.741E-15
-1.048E-14
3.553E-15
9.307E-15
-2.537E-15
0
Решаем эту систему методом сопряженных градиентов с точностью 1e -10:
Код:
x13 =
-92.57311217541384
40.16010075102908
-12.851316373432214
84.39245474872354
2.8625983863313724
105.42442854884612
-43.39780790330953
r13 = K1*x13 - b1
Решаем эту систему методом сопряженных градиентов с точностью 1e -17:
Код:
-124.79332268534779
40.160100751029056
-45.07152688336625
84.39245474872347
2.862598386331376
73.20421803891205
-43.3978079033095
r13 =
-1.392E-14
-1.705E-14
5.428E-14
5.507E-14
-2.826E-14
-3.902E-14
-8.573E-15
Воспользуемся функцией pcg(Точность 1e-10) из MatLab:
Код:
x15 =
-92.5731
40.1601
-12.8513
84.3925
2.8626
105.4244
-43.3978
r15 = K1*x15 - b1
r15 =
-92.5731
40.1601
-12.8513
84.3925
2.8626
105.4244
-43.3978
Казалось бы ничего сложного решаем эту систему и получаем перемещения в узлах, но какое решение взять? Как вы видите найденные перемещения вдоль оси Х ,получаются разными для разных методов решения.
Кроме того решения получаются также различными при выборе разных вариантов учёта граничных условий. Так как в выше приведенном примере перемещения по направлению закрепленных связей заведомо равны нулю(x[2]=0,x[8]=0; i=2,i=8) то учёт граничных условий производится путём вычеркивания i-ой строки и i – ого столбца матрицы жесткости (а также i-тых элементов векторов перемещений и нагрузок ).
Поэтому удаляем 2 и 8 – ую строку и 2 и 8 –ой столбец из матрицы жесткости а также
2 –ой и 8-ой элементы из векторов нагрузки и перемещений. Порядок матрицы уменьшается с 9 – ти до 7-ми Такой способ учета граничных условий подходит только для ручных расчетов небольших матриц а удалять строки и столбцы из статических больших матриц, изменяя этим самым их размерность очень дорогостоящая операция на ЭВМ , поэтому на практике i- ую строку и i-ый столбец делают нулевыми , а диагональный коэффициент K[i][i] = 1. Также в i-ую позицию вектора нагрузки засылают 0. При таком способе учёта граничных условий не изменяется размерность матрицы , никакие строки и столбцы не исключаются.
Посмотрим теперь как измениться решение при таком способе учёта граничных условий всё того же ,ранее приведенного примера:
Матрица жесткости 9 x 9:
Код:
K =
1.306165061 0 0.238778392 -1.306165061 1.112148398 0.238778392 0 0 0
0 1 0 0 0 0 0 0 0
0.238778392 0 0.955462467 -0.238778392 -0.245320266 0.477731234 0 0 0
-1.306165061 0 -0.238778392 1.981800485 -0.253351604 -0.422206912 -0.675635424 0 -0.18342852
1.112148398 0 -0.245320266 -0.253351604 2.581973396 -0.119320301 -0.858796794 0 0.125999965
0.238778392 0 0.477731234 -0.422206912 -0.119320301 1.72580511 0.18342852 0 0.385171321
0 0 0 -0.675635424 -0.858796794 0.18342852 0.675635424 0 0.18342852
0 0 0 0 0 0 0 1 0
0 0 0 -0.18342852 0.125999965 0.385171321 0.18342852 0 0.770342643
Вектор нагрузок:
Код:
b =
0
0
0
0
12
0
0
0
0
Решаем функцией lsolve из MatCad:
Код:
x = lsolve(K,b)
x =
1.26E+17
0
47.923
1.26E+17
98.239
3.348E-15
1.26E+17
0
-47.678
r = K*x - b
r =
-4.697
0
-1.235
0.519
-6.546
-0.204
4.184
0
2.063
Как вы видите здесь вектор невязки получается далеко не нулевой и это говорит о том что это решение никуда не годиться.
Решаем методом Холесского:
Код:
x2 =
-49.766265919852245
0.0
40.160100751028956
29.955529882129103
84.39245474872327
2.862598386331361
148.23127480440712
0.0
-43.39780790330938
r2 = K*x2 - b
r2 =
-5.126E-9
0
-5.82E-8
1.229E-9
-2.656E-8
-5.497E-8
3.896E-9
0
-5.109E-8
Решаем эту систему методом LU - разложения:
Код:
x6 =
-12.612695546824247
0.0
40.160100751029006
67.10910025515724
84.39245474872341
2.862598386331378
185.38484517743547
0.0
-43.39780790330947
r6 = K*x6 -b
r6 =
-5.126E-9
0
-5.82E-8
1.229E-9
-2.656E-8
-5.497E-8
3.896E-9
0
-5.109E-8
Решаем эту систему методом сопряженных градиентов с точностью 1e -10:
Код:
x3 =
-92.57311217541357
0.0
40.16010075102897
-12.85131637343223
84.39245474872334
2.8625983863313635
105.42442854884582
0.0
-43.397807903309406
r3 = K*x3-b
r3 =
-5.126E-9
0
-5.82E-8
1.229E-9
-2.656E-8
-5.497E-8
3.896E-9
0
-5.109E-8
Решаем эту систему методом сопряженных градиентов с точностью 1e -17:
Код:
x4 =
-732.6769555414033
0.0
40.160100751029034
-652.9551597394219
84.39245474872342
2.862598386331401
-534.6794148171435
0.0
-43.39780790330951
r4 = K*x4 - b
r4 =
-5.126E-9
0
-5.82E-8
1.229E-9
-2.656E-8
-5.497E-8
3.896E-9
0
-5.109E-8
PCG из Matlab (Точность 1e-10):
Код:
x5 =
-92.5731
0
40.1601
-12.8513
84.3925
2.8626
105.4244
0
-43.3978
r5 = K*x5 - b
r5 =
4.504E-5
0
-1.211E-5
2.242E-5
1.517E-4
-9.227E-6
-6.746E-5
0
4.12E-6
И что получается решение также различаются при выборе другого способа учёта граничных условий. К примеру сравните решение по Cholesky или LU c вычеркиванием столбцов и строк и без него.
Для более наглядного представления см
здесь