.

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

Язык: русский
Формат: реферат
Тип документа: Word Doc
101 1315
Скачать документ

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

ВВЕДЕНИЕ.

Метод конечных элементов является численным методом для дифференциальных
уравнений, встречающихся в физике [1]. Возникновение этого метода
связано с решением задач космических исследований (1950 г.). Впервые он
был опубликован в работе Тернера, Клужа, Мартина и Топпа. Эта работа
способствовала появлению других работ; был опубликован ряд статей с
применениями метода конечных элементов к задачам строительной механики и
механики сплошных сред. Важный вклад в теоретическую разработку метода
сделал в 1963 г. Мелош, который показал, что метод конечных элементов
можно рассматривать как один из вариантов хорошо известного метода
Рэлея-Ритца. В строительной механике метод конечных элементов
минимизацией потенциальной энергии позволяет свести задачу к системе
линейных уравнений равновесия [2,3].

Одной из существующих трудностей, возникающих при численной реализации
решения контактных задач теории упругости методом конечных элементов
(МКЭ), является решение систем линейных алгебраических уравнений (СЛАУ)
большого порядка вида

[5].

1 ОБЗОР МЕТОДОВ РЕШЕНИЯ СЛАУ, ВОЗНИКАЮЩИХ В МКЭ

Основная идея метода конечных элементов состоит в том, что любую
непрерывную величину, такую, как температура, давление и перемещение,
можно аппроксимировать дискретной моделью, которая строится на множестве
кусочно-непрерывных функций, определенных на конечном числе подобластей.
Кусочно-непрерывные функции определяются с помощью значений непрерывной
величины в конечном числе точек рассматриваемой области [1,2,3].

В общем случае непрерывная величина заранее неизвестна и нужно
определить значения этой величины в некоторых внутренних точках области.
Дискретную модель, однако, очень легко построить, если сначала
предположить, что числовые значения этой величины в каждой внутренней
точке области известны. После этого можно перейти к общему случаю.
Итак, при построении конкретной модели непрерывной величины поступают
следующим образом:

1. В рассматриваемой области фиксируется конечное число точек. Эти точки
называются узловыми точками или просто узлами.

2. Значение непрерывной величины в каждой узловой точке считается
переменной, которая должна быть определена.

3. Область определения непрерывной величины разбивается на конечное
число подобластей, называемых элементами. Эти элементы имеют общие
узловые точки и в совокупности аппроксимируют форму области.

4 .Непрерывная величина апроксимируется на каждом элементе функцией,
которая определяется с помощью узловых значений этой величины. Для
каждого элемента определяется своя функция, но функции подбираются таким
образом, чтобы сохранялась непрерывность величины вдоль границ элемента.

Для решения СЛАУ в МКЭ требуется выбрать метод решения. Окончательное
решение о применении итерационных или прямых методов решения СЛАУ
необходимо принимать на основе анализа структуры исследуемой
математической задачи. Прямые методы решения СЛАУ более выгодно
использовать, если необходимо решать много одинаковых систем с
различными правыми частями, или если матрица А не является
положительно-определенной. Кроме того, существуют задачи с такой
структурой матрицы, для которой прямые методы всегда предпочтительнее,
чем итерационные.

Точные методы решения СЛАУ

Рассмотрим ряд точных методов решения СЛАУ [4,5].

Решение систем n-линейных уравнении с n-неизвестными по формулам
Крамера.

Пусть дана система линейных уравнений, в которой число уравнений равно
числу неизвестных:

Предположим, что определитель системы d не равен нулю. Если теперь
заменить последовательно в определителе столбцы коэффициентов при
неизвестных хj столбцом свободных членов bj, то получатся соответственно
n определителей d1,…,dn.

Теорема Крамера. Система n линейных уравнений с n неизвестными,
определитель которой отличен от нуля, всегда совместна и имеет
единственное решение, вычисляемое по формулам:

x1=d1/d; x2=d2/d;….; xn-1=dn-1/d; xn=dn/d;

Решение произвольных систем линейных уравнений.

Пусть

min{m,n}, тогда в матрицах А и А найдутся r линейно независимых строк,
а остальные m-r строк окажутся их линейными комбинациями. Перестановкой
уравнений можно добиться того, что эти r линейно независимых строк
займут первые r мест.

Отсюда следует, что любое из последних m – r уравнений системы (3) можно
представить как сумму первых r уравнений (которые называются линейно
независимыми или базисными), взятых с некоторыми коэффициентами. Тогда
система эквивалентна следующей системе r уравнений с n неизвестными

0, т. е. является базисным минором. В этом случае неизвестные,
коэффициенты при которых составляют базисный минор, называются базисными
неизвестными, а остальные n – r – свободными неизвестными.

В каждом из уравнений системы (4) перенесем в правую часть все члены со
свободными неизвестными xr+1,…, xn. Тогда получим систему, которая
содержит r уравнений с r базисными неизвестными. Так как определитель
этой системы есть базисный минор Mr то система имеет единственное
решение относительно базисных неизвестных, которое можно найти по
формулам Крамера. Давая свободным неизвестным произвольные числовые
значения, получим общее решение исходной системы.

Однородная система линейных уравнений.

Пусть дана однородная система линейных уравнений n неизвестными

Так как добавление столбца из нулей не изменяет ранга матрицы системы,
то на основании теоремы Кронекера – Kaneлли эта система всегда совместна
и имеет, по крайней мере, нулевое решение. Если определитель системы (5)
отличен от нуля и число уравнений системы равно числу неизвестных, то по
теореме Крамера нулевое решение является единственным.

В том случае, когда ранг матрицы системы (5) меньше числа неизвестных,
т. е. r (А)1) учитываются уже найденные ранее (k+1)-е
приближения неизвестных xi-1.

Пусть дана линейная система, приведенная к нормальному виду:

(17)

Выбираем произвольно начальные приближения неизвестных и подставляем в
первое уравнение системы (17). Полученное первое приближение подставляем
во второе уравнение системы и так далее до последнего уравнения.
Аналогично строим вторые, третьи и т.д. итерации.

известны, методом Зейделя строим (k+1)-е приближение по следующим
формулам:

где k=0,1,…,n

Метод Ланцоша.

Для решения СЛАУ высокого порядка (1), матрица, коэффициентов которой
хранится в компактном нижеописанном виде, наиболее удобным итерационным
методом является метод Ланцоша [4], схема которого имеет вид:

(18)

где

. В качестве критерия остановки данного итерационного процесса обычно
используют соотношение

, (19)

– заданная точность. В качестве другого критерия сходимости иногда
удобнее использовать среднеквадратичную разность между решениями,
полученными на соседних итерациях:

(20)

Среднеквадратичную разность необходимо контролировать при выполнении
каждых k наперед заданных итераций.

, итерационный процесс (18) всегда сходится при любом выборе начального
приближения. При решении контактных задач, когда для уточнения граничных
условий в зоне предполагаемого контакта требуется большое количество
решений СЛАУ вида (1), в качестве начального приближения для первого
расчета используется правая часть системы (1), а для каждого
последующего пересчета – решение, полученное на предыдущем. Такая схема
позволяет значительно сократить количество итераций, необходимых для
достижения заданной точности (19) или (20) [10,11].

2 МЕТОДЫ КОМПАКТНОГО ХРАНЕНИЯ МАТРИЦЫ ЖЕСТКОСТИ

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

Первоначально, с целью выявления связей каждого узла с другими,
производится анализ структуры дискретизации области на КЭ. Например, для
КЭ – сетки, изображенной на рис. 1, соответствующая структура связей
будет иметь вид:

№ узла 1 2 3 4 5 6 7

Связи 1, 2, 5, 6, 7 1, 2, 3, 6 2, 3, 4, 6 3, 4, 5, 6, 7 1, 4, 5, 7 1, 2,
3, 4, 6, 7 1, 4, 5, 6, 7

Тогда, для хранения матрицы жесткости необходимо построчно запоминать
информацию о коэффициентах, соответствующих узлам, с которыми связан
данный узел. На рис. 2 приведены матрица жесткости и ее компактное
представление для сетки изображенной на рис 1 [9].

Текст подпрограммы, реализующий предложенный алгоритм анализа структуры
КЭ-разбиения тела, приведен в Приложении 1.

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

– ее компактное представление. Тогда для обратного преобразования
будут справедливы следующие соотношения:

, (*)

где m – количество степеней свободы (m=1,2,3).

Для прямого преобразования будут справедливы соотношения, обратные к
соотношениям (*).

3 ЧИСЛЕННЫЕ ЭКСПЕРИМЕНТЫ

Для проверки предлагаемого метода компактного хранения матрицы жесткости
была решена задача о контактном взаимодействии оболочечной конструкции и
ложемента [12] (рис. 4).

Данная задача часто возникает на практике при транспортировке или
хранении с горизонтальным расположением оси оболочечные конструкции
устанавливаются на круговые опоры – ложементы. Взаимодействие
подкрепленных оболочечных конструкций и ложементов осуществляется через
опорные шпангоуты, протяженность которых вдоль оси оболочки соизмерима с
шириной ложементов и много меньше радиуса оболочки и величины зоны
контакта.

Данная задача решалась методом конечных элементов при помощи системы
FORL [5]. Дискретная модель ложемента (в трехмерной постановке)
представлена на Рис. 5.

байт, что приблизительно равно 2,7 Мбайт оперативной памяти. Размер
упакованного представления составил около 315 Кбайт.

Данная задача решалась на ЭВМ с процессором Pentium 166 и 32 МБ ОЗУ
двумя способами – методом Гаусса и методом Ланцоша. Сопоставление
результатов решения приведено в Таблице 1.

Таблица 1.

Метод

Гаусса 280 2.2101 -2.4608 1.3756 -5.2501 1.7406 -2.3489

Метод Ланцоша 150 2.2137 -2.4669 1.3904 -5.2572 1.7433 -2.3883

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

ВЫВОДЫ.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ПРИЛОЖЕНИЕ 1

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

#include

#include

#include

#include

#include

#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 –
[/Options]\n”);

printf(“Switch: -t10 – Tetraedr(10)\n”);

printf(” -c8 – Cube(8)\n”);

printf(” -s4 – Shell(4)\n”);

printf(” -s8 – Shell(8)\n\n”);

printf(“Optins: /8 – convert Tetraedr(10)->8*Tetraedr(4)\n”);

printf(” /6 – convert Cube(8)->6*Tetraedr(4)\n”);

}

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

DWORD NumNewPoints,DWORD ntr,Matrix& 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 Link(n),

Size(n);

Matrix Links(n,n);

DWORD Count;

int type = CurrentType;

for (DWORD i = 0; i & X,Vector& Y,Vector& Z,
Matrix& FE,DWORD NumTr,Matrix& 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 BoundList(4 * NumTr,6);

double cx,

cy,

cz,

x1,

y1,

z1,

x2,

y2,

z2,

x3,

y3,

z3;

Bounds.ReSize(4 * NumTr,6);

switch (CurrentType)

{

case BASE3D_4:

Num1 = 4;

Num2 = 3;

for (l = 0; l 0)

{

if (CurrentType == BASE3D_4)

{

Data[0] = cData[j][0];

Data[1] = cData[j][2];

Data[2] = cData[j][1];

}

else

if (CurrentType == BASE3D_10)

{

Data[0] = cData[j][0];

Data[1] = cData[j][2];

Data[2] = cData[j][1];

Data[3] = cData[j][5];

Data[5] = cData[j][3];

}

else

{

Data[0] = cData[j][0];

Data[1] = cData[j][3];

Data[2] = cData[j][2];

Data[3] = cData[j][1];

}

}

for (l = 0; l FORL file convertor. ZSU(c) 1998.\n\n”);

if (argc 6)

{

PrintHeader();

return;

}

sw = argv[1];

input1 = argv[2];

input2 = argv[3];

input3 = argv[4];

if (!strcmp(sw,”-t10″))

CurrentType = BASE3D_10;

else

if (!strcmp(sw,”-c8″))

CurrentType = BASE3D_8;

else

{

printf(“Unknown switch %s\n\n”,sw);

PrintHeader();

return;

}

if (argc == 6)

{

op = argv[5];

if (strcmp(op,”/8″) && strcmp(op,”/6″))

{

printf(“Unknown options %s\n\n”,op);

PrintHeader();

return;

}

}

if (CreateFile(input1,input2,input3,op))

printf(“OK\n”);

}

bool CreateFile(char* fn1,char* fn2,char* fn3,char* Op)

{

FILE *in1,

*in2,

*in3;

Vector X(1000),

Y(1000),

Z(1000);

DWORD NumPoints,

NumFE,

NumBounds = 0,

tmp;

Matrix FE(1000,10),

Bounds;

bool
ReadTetraedrData(char*,char*,FILE*,FILE*,Vector&,Vector&
,Vector&,

Matrix&,DWORD&,DWORD&),

ReadCubeData(char*,char*,FILE*,FILE*,Vector&,Vector&,Vec
tor&,

Matrix&,DWORD&,DWORD&);

void Convert824(Matrix&,DWORD&),

Convert1024(Matrix&,DWORD&);

if ((in1 = fopen(fn1,”r”)) == NULL)

{

printf(“Unable open file %s”,fn1);

return false;

}

if ((in2 = fopen(fn2,”r”)) == NULL)

{

printf(“Unable open file %s”,fn2);

return false;

}

if (CurrentType == BASE3D_10)

{

if (!ReadTetraedrData(fn1,fn2,in1,in2,X,Y,Z,FE,NumPoints,NumFE))
return false;

if (!strcmp(Op,”/8″))

{

// Create 8*Tetraedr(4)

Convert1024(FE,NumFE);

}

Convert(X,Y,Z,FE,NumFE,Bounds,NumBounds);

return !Output(fn3,X,Y,Z,FE,NumPoints,0,NumFE,Bounds,NumBounds);

}

if (CurrentType == BASE3D_8)

{

if (!ReadCubeData(fn1,fn2,in1,in2,X,Y,Z,FE,NumPoints,NumFE))
return false;

if (!strcmp(Op,”/6″))

{

// Create 6*Tetraedr(4)

Convert824(FE,NumFE);

}

Convert(X,Y,Z,FE,NumFE,Bounds,NumBounds);

return !Output(fn3,X,Y,Z,FE,NumPoints,0,NumFE,Bounds,NumBounds);

}

return false;

}

void Convert824(Matrix& FE,DWORD& NumFE)

{

Matrix nFE(6 * NumFE,4);

DWORD data[][4] = {

{ 0,2,3,6 },

{ 4,5,1,7 },

{ 0,4,1,3 },

{ 6,7,3,4 },

{ 1,3,7,4 },

{ 0,4,6,3 }

},

Current = 0;

for (DWORD i = 0; i & FE,DWORD& NumFE)

{

Matrix nFE(8 * NumFE,4);

DWORD data[][4] = {

{ 3,7,8,9 },

{ 0,4,7,6 },

{ 2,5,9,6 },

{ 7,9,8,6 },

{ 4,8,5,1 },

{ 4,5,8,6 },

{ 7,8,4,6 },

{ 8,9,5,6 }

},

Current = 0;

for (DWORD i = 0; i & X,Vector& Y,Vector& Z,

Matrix& FE,DWORD& NumPoints,DWORD& NumFE)

{

double tx,

ty,

tz;

char TextBuffer[1001];

DWORD Current = 0L,

tmp;

while (!feof(in1))

{

if (fgets(TextBuffer,1000,in1) == NULL)

{

if (feof(in1)) break;

printf(“Unable read file %s”,fn1);

fclose(in1);

fclose(in2);

return false;

}

if (sscanf(TextBuffer,”%ld %lf %lf %lf”, &NumPoints,&tx,&ty,&tz)
!= 4) continue;

X[Current] = tx;

Y[Current] = ty;

Z[Current] = tz;

if (++Current == 999)

{

Vector t1 = X,

t2 = Y,

t3 = Z;

X.ReSize(2 * X.Size());

Y.ReSize(2 * X.Size());

Z.ReSize(2 * X.Size());

for (DWORD i = 0; i Eps)

X[FE[Current][4] – 1] = tx;

if (fabs((ty = 0.5*(Y[FE[Current][0] – 1] + Y[FE[Current][1] –
1])) – Y[FE[Current][4] – 1]) > Eps)

Y[FE[Current][4] – 1] = ty;

if (fabs((tz = 0.5*(Z[FE[Current][0] – 1] + Z[FE[Current][1] –
1])) – Z[FE[Current][4] – 1]) > Eps)

Z[FE[Current][4] – 1] = tz;

if (fabs((tx = 0.5*(X[FE[Current][2] – 1] + X[FE[Current][1] –
1])) – X[FE[Current][5] – 1]) > Eps)

X[FE[Current][5] – 1] = tx;

if (fabs((ty = 0.5*(Y[FE[Current][2] – 1] + Y[FE[Current][1] –
1])) – Y[FE[Current][5] – 1]) > Eps)

Y[FE[Current][5] – 1] = ty;

if (fabs((tz = 0.5*(Z[FE[Current][2] – 1] + Z[FE[Current][1] –
1])) – Z[FE[Current][5] – 1]) > Eps)

Z[FE[Current][5] – 1] = tz;

if (fabs((tx = 0.5*(X[FE[Current][0] – 1] + X[FE[Current][2] –
1])) – X[FE[Current][6] – 1]) > Eps)

X[FE[Current][6] – 1] = tx;

if (fabs((ty = 0.5*(Y[FE[Current][0] – 1] + Y[FE[Current][2] –
1])) – Y[FE[Current][6] – 1]) > Eps)

Y[FE[Current][6] – 1] = ty;

if (fabs((tz = 0.5*(Z[FE[Current][0] – 1] + Z[FE[Current][2] –
1])) – Z[FE[Current][6] – 1]) > Eps)

Z[FE[Current][6] – 1] = tz;

if (fabs((tx = 0.5*(X[FE[Current][0] – 1] + X[FE[Current][3] –
1])) – X[FE[Current][7] – 1]) > Eps)

X[FE[Current][7] – 1] = tx;

if (fabs((ty = 0.5*(Y[FE[Current][0] – 1] + Y[FE[Current][3] –
1])) – Y[FE[Current][7] – 1]) > Eps)

Y[FE[Current][7] – 1] = ty;

if (fabs((tz = 0.5*(Z[FE[Current][0] – 1] + Z[FE[Current][3] –
1])) – Z[FE[Current][7] – 1]) > Eps)

Z[FE[Current][7] – 1] = tz;

if (fabs((tx = 0.5*(X[FE[Current][3] – 1] + X[FE[Current][1] –
1])) – X[FE[Current][8] – 1]) > Eps)

X[FE[Current][8] – 1] = tx;

if (fabs((ty = 0.5*(Y[FE[Current][3] – 1] + Y[FE[Current][1] –
1])) – Y[FE[Current][8] – 1]) > Eps)

Y[FE[Current][8] – 1] = ty;

if (fabs((tz = 0.5*(Z[FE[Current][3] – 1] + Z[FE[Current][1] –
1])) – Z[FE[Current][8] – 1]) > Eps)

Z[FE[Current][8] – 1] = tz;

if (fabs((tx = 0.5*(X[FE[Current][3] – 1] + X[FE[Current][2] –
1])) – X[FE[Current][9] – 1]) > Eps)

X[FE[Current][9] – 1] = tx;

if (fabs((ty = 0.5*(Y[FE[Current][3] – 1] + Y[FE[Current][2] –
1])) – Y[FE[Current][9] – 1]) > Eps)

Y[FE[Current][9] – 1] = ty;

if (fabs((tz = 0.5*(Z[FE[Current][3] – 1] + Z[FE[Current][2] –
1])) – Z[FE[Current][9] – 1]) > Eps)

Z[FE[Current][9] – 1] = tz;

}

if (++Current == 999)

{

Matrix t = FE;

FE.ReSize(2 * FE.Size1(),10);

for (DWORD i = 0; i &
X,Vector& Y,Vector& Z,

Matrix& FE,DWORD& NumPoints,DWORD& NumFE)

{

double tx,

ty,

tz;

char TextBuffer[1001];

DWORD Current = 0L,

tmp;

while (!feof(in1))

{

if (fgets(TextBuffer,1000,in1) == NULL)

{

if (feof(in1)) break;

printf(“Unable read file %s”,fn1);

fclose(in1);

fclose(in2);

return false;

}

if (sscanf(TextBuffer,”%ld %lf %lf %lf”, &NumPoints,&tx,&ty,&tz)
!= 4) continue;

X[Current] = tx;

Y[Current] = ty;

Z[Current] = tz;

if (++Current == 999)

{

Vector t1 = X,

t2 = Y,

t3 = Z;

X.ReSize(2 * X.Size());

Y.ReSize(2 * X.Size());

Z.ReSize(2 * X.Size());

for (DWORD i = 0; i t = FE;

FE.ReSize(2 * FE.Size1(),10);

for (DWORD i = 0; i ПРИЛОЖЕНИЕ 2. Исходный текст программы, реализующей алгоритм компактного хранения и решения СЛАУ высокого порядка. #include "matrix.h" class RVector { private: Vector Buffer;

public:

RVector(void) {}

~RVector() {}

RVector(DWORD Size) { Buffer.ReSize(Size); }

RVector(RVector& right) { Buffer = right.Buffer; }

RVector(Vector& right) { Buffer = right; }

DWORD Size(void) { return Buffer.Size(); }

void ReSize(DWORD Size) { Buffer.ReSize(Size); }

double& operator [] (DWORD i) { return Buffer[i]; }

RVector& operator = (RVector& right) { Buffer = right.Buffer; return
*this; }

RVector& operator = (Vector& right) { Buffer = right; return
*this; }

void Sub(RVector&);

void Sub(RVector&,double);

void Mul(double);

void Add(RVector&);

friend double Norm(RVector&,RVector&);

};

class TSMatrix

{

private:

Vector Right;

Vector* Array;

Vector* Links;

uint Dim;

DWORD Size;

public:

TSMatrix(void) { Size = 0; Dim = 0; Array = NULL; Links = NULL; }

TSMatrix(Vector*,DWORD,uint);

~TSMatrix(void) { if (Array) delete [] Array; }

Vector& GetRight(void) { return Right; }

DWORD GetSize(void) { return Size; }

uint GetDim(void) { return Dim; }

Vector& GetVector(DWORD i) { return Array[i]; }

Vector* GetLinks(void) { return Links; }

void SetLinks(Vector* l) { Links = l; }

void Add(Matrix&,Vector&);

void Add(DWORD I, DWORD L, DWORD J, DWORD K, double v)

{

DWORD Row = I,

Col = L * Links[I].Size() * Dim + Find(I,J) * Dim + K;

Array[Row][Col] += v;

}

void Add(DWORD I, double v)

{

Right[I] += v;

}

DWORD Find(DWORD,DWORD);

void Restore(Matrix&);

void Set(DWORD,DWORD,double,bool);

void Set(DWORD Index1,DWORD Index2,double value)

{

DWORD I = Index1 / Dim,

L = Index1 % Dim,

J = Index2 / Dim,

K = Index2 % Dim,

Pos = Find(I,J),

Row = I,

Col;

if (Pos == DWORD(-1)) return;

Col = L * Links[I].Size() * Dim + Find(I,J) * Dim + K;

Array[Row][Col] = value;

}

bool Get(DWORD Index1,DWORD Index2,double& value)

{

DWORD I = Index1 / Dim,

L = Index1 % Dim,

J = Index2 / Dim,

K = Index2 % Dim,

Pos = Find(I,J),

Row = I,

Col;

value = 0;

if (Pos == DWORD(-1)) return false;

Col = L * Links[I].Size() * Dim + Find(I,J) * Dim + K;

value = Array[Row][Col];

return true;

}

void Mul(RVector&,RVector&);

double Mul(DWORD,RVector&);

void write(ofstream&);

void read(ifstream&);

};

class RMatrix

{

private:

Vector Buffer;

DWORD size;

public:

RMatrix(DWORD sz) { size = sz; Buffer.ReSize(size*(size + 1)*0.5); }

~RMatrix() {}

DWORD Size(void) { return size; }

double& Get(DWORD i,DWORD j) { return Buffer[(2*size + 1 – i)*0.5*i
+ j – i]; }

};

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

#include “smatrix.h”

double Norm(RVector& Left,RVector& Right)

{

double Ret = 0;

for (DWORD i = 0; i * links, DWORD size, uint dim)

{

Dim = dim;

Links = links;

Size = size;

Right.ReSize(Dim * Size);

Array = new Vector[Size];

for (DWORD i = 0; i & FEMatr,Vector& FE)

{

double Res;

DWORD RRow;

for (DWORD i = 0L; i & Matr)

{

DWORD i,

j,

NRow,

NPoint,

NLink,

Pos;

Matr.ReSize(Size * Dim,Size * Dim + 1);

for (i = 0; i [Size];

Right.ReSize(Size * Dim);

for (DWORD i = 0; i

Нашли опечатку? Выделите и нажмите CTRL+Enter

Похожие документы
Обсуждение

Ответить

Курсовые, Дипломы, Рефераты на заказ в кратчайшие сроки
Заказать реферат!
UkrReferat.com. Всі права захищені. 2000-2020