Алгоритм компактного хранения и решения СЛАУ высокого порядка

Страница 4

Из Таблицы 1 легко видеть, что результаты решения СЛАУ методом Гаусса и методом Ланцоша хорошо согласуются между собой, при этом время решения вторым способом почти в два раза меньше, чем в случае использования метода Гаусса.

ВЫВОДЫ.

В данной работе были рассмотрены способы компактного хранения матрицы коэффициентов системы линейных алгебраических уравнений (СЛАУ) и методы ее решения. Разработан алгоритм компактного хранения матрицы жесткости, позволяющий в несколько раз (иногда более чем в десятки раз) сократить объем требуемой памяти для хранения такой матрицы жесткости.

Классические методы хранения, учитывающие симметричную и ленточную структуру матриц жесткости, возникающих при применении метода конечных элементов (МКЭ), как правило, не применимы при решении контактных задач, так как при их решении матрицы жесткости нескольких тел объединяются в одну общую матрицу, ширина ленты которой может стремиться к порядку системы.

Предложенная в работе методика компактного хранения матриц коэффициентов СЛАУ и использования метода Ланцоша позволили на примере решения контактных задач добиться существенной экономии процессорного времени и затрат оперативной памяти.

СПИСОК ССЫЛОК.

1. Зенкевич О., Морган К. Конечные методы и аппроксимация // М.: Мир, 1980

2. Зенкевич О., Метод конечных элементов // М.: Мир., 1975

3. Стрэнг Г., Фикс Дж. Теория метода конечных элементов // М.: Мир, 1977

4. Бахвалов Н.С.,Жидков Н.П., Кобельков Г.М. Численные методы // М.: наука, 1987

5. Воеводин В.В., Кузнецов Ю.А. Матрицы и вычисления // М.:Наука, 1984

6. Бахвалов Н.С. Численные методы // М.: Наука, 1975

7. Годунов С.К. Решение систем линейных уравнений // Новосибирск: Наука, 1980

8. Гоменюк С.И., Толок В.А. Инструментальная система анализа задач механики деформируемого твердого тела // Приднiпровський науковий вiсник – 1997. – №4.

9. F.G. Gustavson, “Some basic techniques for solving sparse matrix algoriths”, // editer by D.J. Rose and R.A.Willoughby, Plenum Press, New York, 1972

10. А.Джордж, Дж. Лиу, Численное решение больших разреженных систем уравнений // Москва, Мир, 1984

11. D.J. Rose, “A graph theoretic study of the numerical solution of sparse positive definite system of linear equations” // New York, Academic Press, 1972

12. Мосаковский В.И., Гудрамович В.С., Макеев Е.М., Контактные задачи теории оболочек и стержней // М.:”Машиностроение”, 1978

ПРИЛОЖЕНИЕ 1

Исходный текст программы, реализующий анализ структуры КЭ-разбиения объекта.

#include <math.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <fstream.h>

#include "matrix.h"

#define BASE3D_4 4

#define BASE3D_8 8

#define BASE3D_10 10

const double Eps = 1.0E-10;

DWORD CurrentType = BASE3D_10;

void PrintHeader(void)

{

printf("Command format: AConvert -<switch> <file1.in> <file2.in> <file3.out> [/Options] ");

printf("Switch: -t10 - Tetraedr(10) ");

printf(" -c8 - Cube(8) ");

printf(" -s4 - Shell(4) ");

printf(" -s8 - Shell(8) ");

printf("Optins: /8 - convert Tetraedr(10)->8*Tetraedr(4) ");

printf(" /6 - convert Cube(8)->6*Tetraedr(4) ");

}

bool Output(char* fname,Vector<double>& x,Vector<double>& y,Vector<double>& z, Matrix<DWORD>& tr, DWORD n,

DWORD NumNewPoints,DWORD ntr,Matrix<DWORD>& Bounds,DWORD CountBn)

{

char* Label = "NTRout";

int type = CurrentType,

type1 = (type==BASE3D_4 || type==BASE3D_10) ? 3 : 4;

DWORD NewSize,

i,

j;

ofstream Out;

if (type==BASE3D_4) type1 = 3;

else if (type==BASE3D_8) type1 = 4;

else if (type==BASE3D_10) type1 = 6;

Out.open(fname,ios::out | ios:: binary);

if (Out.bad()) return true;

Out.write((const char*)Label,6 * sizeof(char));

if (Out.fail()) return true;

Out.write((const char*)&type,sizeof(int));

if (Out.fail()) return true;

Out.write((const char*)&CountBn,sizeof(DWORD));

if (Out.fail())

{

Out.close();

return true;

}

Out.write((const char*)&(NewSize = n + NumNewPoints),sizeof(DWORD));

if (Out.fail()) return true;

Out.write((const char*)&(NumNewPoints),sizeof(DWORD));

if (Out.fail())

{

Out.close();

return true;

}

for (DWORD i = 0; i < n; i++)

{

Out.write((const char*)&x[i],sizeof(double));

Out.write((const char*)&y[i],sizeof(double));

Out.write((const char*)&z[i],sizeof(double));

if (Out.fail())

{

Out.close();

return true;

}

}

for (i = 0; i < NumNewPoints; i++)

{

Out.write((const char*)&x[n + i],sizeof(double));

Out.write((const char*)&y[n + i],sizeof(double));

if (Out.fail())

{

Out.close();

return true;

}

}

Out.write((const char*)&(ntr),sizeof(DWORD));

if (Out.fail())

{

Out.close();

return true;

}

for (i = 0; i < ntr; i++)

for (j = 0; j < (DWORD)type; j++)

{

DWORD out = tr[i][j];

Out.write((const char*)&out,sizeof(DWORD));

if (Out.fail())

{

Out.close();

return true;

}

}

for (i = 0; i < CountBn; i++)

for (j = 0; j < (DWORD)type1; j++)

{

DWORD out = Bounds[i][j];

Out.write((const char*)&out,sizeof(DWORD));

if (Out.fail())

{

Out.close();

return true;

}

}

{

//*********************

// Create Links

printf("Create links . ");

Vector<DWORD> Link(n),

Size(n);

Matrix<DWORD> Links(n,n);

DWORD Count;

int type = CurrentType;

for (DWORD i = 0; i < n; i++)

{

for (DWORD j = 0; j < ntr; j++)

for (DWORD k = 0; k < (DWORD)type; k++)

if (tr[j][k] == i)

for (DWORD m = 0; m < (DWORD)type; m++) Link[tr[j][m]] = 1;

Count = 0;

for (DWORD m = 0; m < n; m++)

if (Link[m]) Count++;

Size[i] = Count;

Count = 0;

for (DWORD m = 0; m < n; m++)

if (Link[m])

Links[i][Count++] = m;

//Set zero

Link.ReSize(n);

}

// Output

//*********************

for (DWORD i = 0; i < n; i++)

{

DWORD Sz = Size[i];

Out.write((const char*)&Sz,sizeof(DWORD));

for (DWORD j = 0; j < Sz; j++)

Out.write((const char*)&(Links[i][j]),sizeof(DWORD));

}

//*********************

}

printf(" ");

printf("Points: %ld ",n);

printf("FE: %ld ",ntr);

Out.close();

return false;

}

bool Test(DWORD* a,DWORD* b)

{

bool result;

int NumPoints = 3;

if (CurrentType == BASE3D_8) NumPoints = 4;

else if (CurrentType == BASE3D_10) NumPoints = 6;

for (int i = 0; i < NumPoints; i++)

{

result = false;

for (int j = 0; j < NumPoints; j++)

if (b[j] == a[i])

{

result = true;

break;

}

if (result == false) return false;

}

return true;

}

void Convert(Vector<double>& X,Vector<double>& Y,Vector<double>& Z, Matrix<DWORD>& FE,DWORD NumTr,Matrix<DWORD>& Bounds,DWORD& BnCount)

{

int cData8[6][5] = {{0,4,5,1,7},

{6,2,3,7,0},

{4,6,7,5,0},

{2,0,1,3,5},

{1,5,7,3,4},

{6,4,0,2,1}},

cData4[4][4] = {{0,1,2,3},

{1,3,2,0},

{3,0,2,1},

{0,3,1,2}},

cData10[4][7] = {{0,1,2,4,5,6,3},

{0,1,3,4,8,7,2},

{1,3,2,8,9,5,0},

{0,2,3,6,9,7,1}},

cData[6][7],

Data[6],

l,

Num1,

Num2,

m;

DWORD i,

j,

p[6],

pp[6],

Index;

Matrix<DWORD> BoundList(4 * NumTr,6);