Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Проведенные исследования и выводы




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

 

Тексты основных модулей программ

Листинг программы

#include "solver.h" //решение СЛАУ

#include "paint.h" //визуализация решения

#include "task.h" //постановка задач

//глобальная матрицы в разреженном строчном формате и вектор

int *ig, *jg, *ia, kk;

double *di, *ggl, *ggu, *gB;

double *gr, *gphi, *hr, *hphi, *q; //сетка

int **xyk, **coord, **cnd1, **cnd2, **cnd3;

int nr, nphi, L, N, K, size, n1, n2, n3;

void AddElemenit(int i, int j, double a);

void nforming(int);

double numIn(double r1, double phi1, double r2, double phi2, int i, int j, int k);

//считывание/формирование сетки

void grid()

{

FILE *fi;

fopen_s(&fi, "g.txt", "r");

fscanf_s(fi, "%d", &nr);

gr = new double[nr];

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

fscanf_s(fi, "%lf", &gr[i]);

fscanf_s(fi, "%d", &nphi);

gphi = new double[nphi];

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

fscanf_s(fi, "%lf", &gphi[i]);

fscanf_s(fi, "%d", &L);

hr = new double[L];

hphi = new double[L];

xyk = new int*[5];

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

xyk[i] = new int[L];

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

{

fscanf_s(fi, "%d %d %d %d %d", &xyk[i][0], &xyk[i][1], &xyk[i][2], &xyk[i][3], &xyk[i][4]);

--xyk[i][0]; --xyk[i][1]; --xyk[i][2]; --xyk[i][3]; --xyk[i][4];

}

fscanf_s(fi, "%d", &N);

coord = new int*[N];

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

{

coord[i] = new int[2];

fscanf_s(fi, "%d %d", &coord[i][0], &coord[i][1]);

--coord[i][0];

--coord[i][1];

}

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

{

hr[i] = gr[xyk[i][2]]-gr[xyk[i][1]];

hphi[i] = gphi[xyk[i][4]]-gphi[xyk[i][3]];

}

gB = new double[N];

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

gB[i] = 0;

di = new double[N];

q = new double[N];

}

//получение краевых условий

void cond()

{

FILE *fi;

fopen_s(&fi, "cond.txt", "r");

fscanf_s(fi, "%d", &n1);

cnd1 = new int*[n1];

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

cnd1[i] = new int[6];

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

{

fscanf_s(fi, "%d %d %d %d %d %d", &cnd1[i][0], &cnd1[i][1], &cnd1[i][2], &cnd1[i][3], &cnd1[i][4], &cnd1[i][5]);

--cnd1[i][0]; --cnd1[i][1]; --cnd1[i][2]; --cnd1[i][3]; --cnd1[i][4]; --cnd1[i][5];

}

fscanf_s(fi, "%d", &n2);

cnd2 = new int*[n2];

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

cnd2[i] = new int[6];

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

{

fscanf_s(fi, "%d %d %d %d %d %d", &cnd2[i][0], &cnd2[i][1], &cnd2[i][2], &cnd2[i][3], &cnd2[i][4], &cnd2[i][5]);

--cnd2[i][0]; --cnd2[i][1]; --cnd2[i][2]; --cnd2[i][3]; --cnd2[i][4]; --cnd2[i][5];

}

fscanf_s(fi, "%d", &n3);

cnd3 = new int*[n3];

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

cnd3[i] = new int[6];

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

{

fscanf_s(fi, "%d %d %d %d %d %d", &cnd3[i][0], &cnd3[i][1], &cnd3[i][2], &cnd3[i][3], &cnd3[i][4], &cnd3[i][5]);

--cnd3[i][0]; --cnd3[i][1]; --cnd3[i][2]; --cnd3[i][3]; --cnd3[i][4]; --cnd3[i][5];

}

fclose(fi);

}

//поиск номера узла

int search(int r, int phi)

{

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

if(coord[i][0] == r)

if(coord[i][1] == phi)

return i;

return -1;

}

//возвращает глобальный номер l-конечного элемента i-локального узла

int GlobalNum(int l, int i)

{

switch(i)

{

case 0: return search(xyk[l][1], xyk[l][3]);

case 1: return search(xyk[l][2], xyk[l][3]);

case 2: return search(xyk[l][1], xyk[l][4]);

case 3: return search(xyk[l][2], xyk[l][4]);

}

return -1;

}

//теперь генерация портрета матрицы

void GeneratePortrait()

{

int i = 0, j = 0, k = 0, ver[2][6];

int **vx;

vx = new int*[2];

vx[0] = new int[6*L];

vx[1] = new int[6*L];

ig = new int[N+1];

int *flags;//массив флагов для всех узлов

flags = new int[6*L];

for(; i < L*6; ++i)

flags[i] = 0; //вначале мы ещё не заносили узлы

for(i = 0; i < N + 1; ++i)

ig[i] = 0;

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

di[i] = 0;

//проходим по каждой области

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

{

ver[0][0] = GlobalNum(i, 0);

ver[1][0] = GlobalNum(i, 1);

ver[0][1] = GlobalNum(i, 0);

ver[1][1] = GlobalNum(i, 2);

ver[0][2] = GlobalNum(i, 1);

ver[1][2] = GlobalNum(i, 2);

ver[0][3] = GlobalNum(i, 0);

ver[1][3] = GlobalNum(i, 3);

ver[0][4] = GlobalNum(i, 1);

ver[1][4] = GlobalNum(i, 3);

ver[0][5] = GlobalNum(i, 2);

ver[1][5] = GlobalNum(i, 3);

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

{

int kk = i*6 + j;

vx[0][kk] = ver[0][j];

vx[1][kk] = ver[1][j];

}

}

for(i = 0; i < L*6; ++i)

for(j = i; j < L*6; ++j)

if(vx[0][i] == vx[0][j])

if(vx[1][i] == vx[1][j])

++flags[j];

for(k = 0; k < L*6; ++k)

if(1 == flags[k])

++ig[vx[1][k]+1];

for(i = 1; i < N + 1; ++i)

ig[i] = ig[i-1] + ig[i];

size = ig[N];

jg = new int[size];

int jj = 0;

sort(vx, flags, L);

for(i = 0; i < L*6; ++i)

{

if(2 == flags[i])

++jj;

jg[i-jj] = vx[0][i];

}

ggu = new double[size];

ggl = new double[size];

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

ggu[i] = ggl[i] = 0;

}

//теперь занесение элеменита в глобальную матрицу

void AddElemenit(int i, int j, double a)

{

int ind;

if(i == j)

{

di[i] += a;

return;

}

if(i < j)

{

for(ind = ig[j]; ind < ig[j+1]; ++ind)

if(jg[ind] == i)

break;

ggu[ind] += a;

}

else

{

for(ind = ig[i]; ind < ig[i+1]-1; ++ind)

if(jg[ind] == j)

break;

ggl[ind] += a;

}

}

//теперь формирование глобальной матрицы, ухх, наконец-то я до этого дошёл =D

void BuildGlobal()

{

int i;

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

//в каждой области формируем матрицу

nforming(i);

}

//теперь мы учимся применять вторые краевые условия

void second()

{

double lb[2], h, lM[2][2], s = 0;

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

{

kk = i;

if(cnd2[i][2] == cnd2[i][3])

//вдоль ребра по phi

for(int k = 0; k < 2; ++k)

lb[k] = numIn(gr[cnd2[i][2]], gphi[cnd2[i][4]], gr[cnd2[i][3]], gphi[cnd2[i][5]], k, k, 3);

else

//вдоль ребра по r

for(int k = 0; k < 2; ++k)

lb[k] = numIn(gr[cnd2[i][2]], gphi[cnd2[i][4]], gr[cnd2[i][3]], gphi[cnd2[i][5]], k, k, 4);

gB[search(cnd2[i][2], cnd2[i][4])] += lb[0];

gB[search(cnd2[i][3], cnd2[i][5])] += lb[1];

}

}

//теперь учитываем третьи магические условия

void third()

{

double h, ub[2], local_b[2], s = 0, s1;

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

{

kk = i;

if(cnd3[i][2] == cnd3[i][3])

for(int k = 0; k < 2; ++k)

{

for(int m = 0; m < 2; ++m)

{

s1 = beta*numIn(gr[cnd3[i][2]], gphi[cnd3[i][4]], gr[cnd3[i][3]], gphi[cnd3[i][5]], k, m, 6);

AddElemenit(search(cnd3[i][2], cnd3[i][k+4]), search(cnd3[i][3], cnd3[i][m+4]), s1);

}

local_b[k] = beta*numIn(gr[cnd3[i][2]], gphi[cnd3[i][4]], gr[cnd3[i][3]], gphi[cnd3[i][5]], k, k, 8);

}

else

for(int k = 0; k < 2; ++k)

{

for(int m = 0; m < 2; ++m)

{

s1 = beta*numIn(gr[cnd3[i][2]], gphi[cnd3[i][4]], gr[cnd3[i][3]], gphi[cnd3[i][5]], k, m, 7);

AddElemenit(search(cnd3[i][k+2], cnd3[i][4]), search(cnd3[i][m+2], cnd3[i][4]), s1);

}

local_b[k] = beta*numIn(gr[cnd3[i][2]], gphi[cnd3[i][4]], gr[cnd3[i][3]], gphi[cnd3[i][5]], k, k, 9);

}

gB[search(cnd3[i][2], cnd3[i][4])] += local_b[0];

gB[search(cnd3[i][3], cnd3[i][5])] += local_b[1];

}

}

void zeroman(int i, int r1, int phi1, int r2, int phi2)

{

int j = 0;

int z1 = search(r1, phi1);

int z2 = search(r2, phi2);

di[z1] = 1;

di[z2] = 1;

gB[z1] = lordC(i, gr[r1], gphi[phi1]);

gB[z2] = lordC(i, gr[r2], gphi[phi2]);

//обнуление верхней треугольной матрицы

for(; j < size; ++j)

if(jg[j] == z1 || jg[j] == z2)

ggu[j] = 0;

//обнуление нижней треугольной матрицы

for(j = ig[z1]; j < ig[z1+1]; ++j)

ggl[j] = 0;

for(j = ig[z2]; j < ig[z2+1]; ++j)

ggl[j] = 0;

}

//теперь учитываем ГЛАВНЫЕ КРАЕВЫЕ УСЛОВИЯ

void overlord()

{

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

zeroman(i, cnd1[i][2], cnd1[i][4], cnd1[i][3], cnd1[i][5]);

}

//подынтегральные функции (k - номер пфункции)

double locMatr(double rp, double phis, double r, double phi, double hr, double hphi, int i, int j, int k)

{

//локаные линейные базис-функции

double psi[4], dpsir[4], dpsphi[4];

double rl[2], phil[2];

rl[0] = (rp+hr-r)/hr;

rl[1] = (r-rp)/hr;

phil[0] = (phis+hphi-phi)/hphi;

phil[1] = (phi-phis)/hphi;

//собрание локальной матрицы массы

if(k == 0)

{

psi[0] = rl[0]*phil[0];

psi[1] = rl[1]*phil[0];

psi[2] = rl[0]*phil[1];

psi[3] = rl[1]*phil[1];

return psi[i]*psi[j]*r;

}

//вектора правой части

if(k == 2)

{

double local_f[4], lf;

local_f[0] = f(gr[xyk[kk][1]], gphi[xyk[kk][3]],kk);

local_f[1] = f(gr[xyk[kk][2]], gphi[xyk[kk][3]],kk);

local_f[2] = f(gr[xyk[kk][1]], gphi[xyk[kk][4]],kk);

local_f[3] = f(gr[xyk[kk][2]], gphi[xyk[kk][4]],kk);

psi[0] = rl[0]*phil[0];

psi[1] = rl[1]*phil[0];

psi[2] = rl[0]*phil[1];

psi[3] = rl[1]*phil[1];

lf = local_f[0] * psi[0] + local_f[1] * psi[1] + local_f[2] * psi[2] + local_f[3] * psi[3];

return lf*psi[i]*r;

}

//краевые условия второго типа по одной координате(phi)

if(k == 3)

{

double local_theta[2];

local_theta[0] = secondC(cnd2[kk][1], gr[cnd2[kk][2]], gphi[cnd2[kk][4]]);

local_theta[1] = secondC(cnd2[kk][1], gr[cnd2[kk][3]], gphi[cnd2[kk][5]]);

psi[0] = rl[0]*phil[0];

psi[1] = rl[0]*phil[1];

return (local_theta[0]*psi[0] + local_theta[1]*psi[1])*psi[i]*r;

}

//краевые условия второго типа по одной координате(r)

if(k == 4)

{

double local_theta[2];

local_theta[0] = secondC(cnd2[kk][1], gr[cnd2[kk][2]], gphi[cnd2[kk][4]]);

local_theta[1] = secondC(cnd2[kk][1], gr[cnd2[kk][3]], gphi[cnd2[kk][5]]);

psi[0] = rl[0]*phil[0];

psi[1] = rl[1]*phil[0];

return (local_theta[0]*psi[0] + local_theta[1]*psi[1])*psi[i]*r;

}

//краевые условия третьего типа по phi для матрицы

if(k == 6)

{

psi[0] = rl[0]*phil[0];

psi[1] = rl[0]*phil[1];

return psi[i]*psi[j]*r;

}

//краевые условия третьего типа по r для матрицы

if(k == 7)

{

psi[0] = rl[0]*phil[0];

psi[1] = rl[1]*phil[0];

return psi[i]*psi[j]*r;

}

//третьи краевые условия для вектора правой части по фи

if(k == 8)

{

double ub1, ub2;

ub1 = thirdC(cnd3[kk][1], gr[cnd3[kk][2]], gphi[cnd3[kk][4]]);

ub2 = thirdC(cnd3[kk][1], gr[cnd3[kk][3]], gphi[cnd3[kk][5]]);

psi[0] = rl[0]*phil[0];

psi[1] = rl[0]*phil[1];

return (ub1*psi[0] + ub2*psi[1])*psi[i]*r;

}

//третьи краевые условия для вектора правой части по r

if(k == 9)

{

double ub1, ub2;

ub1 = thirdC(cnd3[kk][1], gr[cnd3[kk][2]], gphi[cnd3[kk][4]]);

ub2 = thirdC(cnd3[kk][1], gr[cnd3[kk][3]], gphi[cnd3[kk][5]]);

psi[0] = rl[0]*phil[0];

psi[1] = rl[1]*phil[0];

return (ub1*psi[0] + ub2*psi[1])*psi[i]*r;

}

//раскладываем лямбду по биквадратичному базису и

//считаем элементы локальной матрицы жёсткости

double local_lambda[9], lam, rq[3], phiq[3], psix[9];

int l = k - 10;

local_lambda[0] = lambda(gr[xyk[l][1]], gphi[xyk[l][3]], 0);

local_lambda[1] = lambda(gr[xyk[l][1]]+hr/2, gphi[xyk[l][3]], 0);

local_lambda[2] = lambda(gr[xyk[l][2]], gphi[xyk[l][3]], 0);

local_lambda[3] = lambda(gr[xyk[l][1]], gphi[xyk[l][3]]+hphi/2, 0);

local_lambda[4] = lambda(gr[xyk[l][1]]+hr/2, gphi[xyk[l][3]]+hphi/2, 0);

local_lambda[5] = lambda(gr[xyk[l][2]], gphi[xyk[l][3]]+hphi/2, 0);

local_lambda[6] = lambda(gr[xyk[l][1]], gphi[xyk[l][4]], 0);

local_lambda[7] = lambda(gr[xyk[l][1]]+hr/2, gphi[xyk[l][4]], 0);

local_lambda[8] = lambda(gr[xyk[l][2]], gphi[xyk[l][4]], 0);

rq[0] = 2*(rl[1] - 0.5)*(rl[1] - 1);

rq[1] = -4*rl[1]*(rl[1] - 1);

rq[2] = 2*rl[1]*(rl[1] - 0.5);

phiq[0] = 2*(phil[1] - 0.5)*(phil[1] - 1);

phiq[1] = -4*phil[1]*(phil[1] - 1);

phiq[2] = 2*phil[1]*(phil[1] - 0.5);

psix[0] = rq[0]*phiq[0];

psix[1] = rq[1]*phiq[0];

psix[2] = rq[2]*phiq[0];

psix[3] = rq[0]*phiq[1];

psix[4] = rq[1]*phiq[1];

psix[5] = rq[2]*phiq[1];

psix[6] = rq[0]*phiq[2];

psix[7] = rq[1]*phiq[2];

psix[8] = rq[2]*phiq[2];

lam = 0;

for(int z = 0; z < 9; ++z)

lam += local_lambda[z]*psix[z];

//матрица жёсткости

dpsir[0] = -1/hr*phil[0];

dpsir[1] = 1/hr*phil[0];

dpsir[2] = -1/hr*phil[1];

dpsir[3] = phil[1]/hr;

dpsphi[0] = -rl[0]/hphi;

dpsphi[1] = -rl[1]/hphi;

dpsphi[2] = rl[0]/hphi;

dpsphi[3] = rl[1]/hphi;

return lam*r*(dpsir[i]*dpsir[j] + dpsphi[i]*dpsphi[j]/(r*r));

}

//численное интегрирование(кубатурная формула Гаусса)

double numIn(double r1, double phi1, double r2, double phi2, int i, int j, int k)

{

double sum = 0.0;

double hr = r2 - r1, hphi = phi2 - phi1;

double xh = r1 + r2, yh = phi1 + phi2;

double rp = (xh/2.0)+hr/(2*sqrt(3.0));

double xm = (xh/2.0)-hr/(2*sqrt(3.0));

double yp = (yh/2.0)+hphi/(2*sqrt(3.0));

double ym = (yh/2.0)-hphi/(2*sqrt(3.0));

//краевые условия второго типа по одной координате(phi)

if(k == 3)

{

sum = hphi/2*(locMatr(r1, phi1, rp, yp, 1, hphi, i, j, k) + locMatr(r1, phi1, xm, ym, 1, hphi, i, j, k));

return sum;

}

//краевые условия второго типа по одной координате(r)

if(k == 4)

{

sum = hr/2*(locMatr(r1, phi1, rp, yp, hr, 1, i, j, k) + locMatr(r1, phi1, xm, ym, hr, 1, i, j, k));

return sum;

}

//краевые условия третьего типа по phi

if(k == 6 || k == 8)

{

sum = hphi/2*(locMatr(r1, phi1, rp, yp, 1, hphi, i, j, k) + locMatr(r1, phi1, xm, ym, 1, hphi, i, j, k));

return sum;

}

//краевые условия третьего типа по r

if(k == 7 || k == 9)

{

sum = hr/2*(locMatr(r1, phi1, rp, yp, hr, 1, i, j, k) + locMatr(r1, phi1, xm, ym, hr, 1, i, j, k));

return sum;

}

sum = hr*hphi/4*(locMatr(r1, phi1, rp, yp, hr, hphi, i, j, k) + locMatr(r1, phi1, xm, yp, hr, hphi, i, j, k) +

locMatr(r1, phi1, xm, ym, hr, hphi, i, j, k) + locMatr(r1, phi1, rp, ym, hr, hphi, i, j, k));

return sum;

}

//теперь формирование локальных матриц численно

void nforming(int l)

{

double lA[4][4], lB[4], G[4][4], M[4][4];

kk = l;

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

{

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

{

M[i][j] = numIn(gr[xyk[l][1]], gphi[xyk[l][3]], gr[xyk[l][2]], gphi[xyk[l][4]], i, j, 0);

M[i][j] *= gamma(gr[xyk[l][1]], gphi[xyk[l][3]], l);

G[i][j] = numIn(gr[xyk[l][1]], gphi[xyk[l][3]], gr[xyk[l][2]], gphi[xyk[l][4]], i, j, 10+l);

lA[i][j] = G[i][j] + M[i][j];

AddElemenit(GlobalNum(l, i), GlobalNum(l, j), lA[i][j]);

}

lB[i] = numIn(gr[xyk[l][1]], gphi[xyk[l][3]], gr[xyk[l][2]], gphi[xyk[l][4]], i, i, 2);

gB[GlobalNum(l, i)] += lB[i];

}

}

void main(int argc, char **argv)

{

//считываем сетку

grid();

//считываем краевые условия всех типов

cond();

//формируем портрет матрицы

GeneratePortrait();

//собираем глобальные матрицу и вектор

BuildGlobal();

//учитываем вторые краевые условия

second();

//третьи

third();

//главные(естественные)

overlord();

Matrix *Matr = new Matrix(ig, jg, ggl, ggu, di, gB, N);

//решаем(ЛОС с LU - факторизацией)

Solver(Matr, q);

//рисуем

//pain(argc, argv, q);

Matr->~Matrix();

//ничего

printf_s("\nTo do nothing...\n");

_getch();

}





Поделиться с друзьями:


Дата добавления: 2015-08-18; Мы поможем в написании ваших работ!; просмотров: 522 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Свобода ничего не стоит, если она не включает в себя свободу ошибаться. © Махатма Ганди
==> читать все изречения...

2339 - | 2092 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.011 с.