Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

KM2016 / Loaded_rod / fem3

.pdf
Скачиваний:
10
Добавлен:
14.03.2016
Размер:
32.49 Кб
Скачать

//Приложение к разделу 3 Однородный стержень // fem3.h

/*

#include <ctype.h> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h>

int knots_N, test, result;

double *q, *x, *solution, *up, *down, *diag ; double h, x_max;

double K[500][500];

void q_i(void); int output(int); void K_ij(void);

double quad_m(double x_1,double x_2); double quad_p(double x_1,double x_2);

void progon(int, double down[], double diag[], double up[], double q[]); int i_max(int N, int p, double V[]);

*/

//fem3.cpp

#include "fem3.h"

static double fun_q(double x) { // правая часть дифференциального уравнения //return (-6*x);

return 3.14159*3.14159*sin(3.14159*x); // return x*x*x*x;

}

int main(int argc,char *argv[]) {

x_max = 1; // задаём длину стержня

knots_N = 7; // задаём число узлов, включая узлы на границах

int N; // при нулевых граничных условиях следует решать задачу только для внутренних узлов N = knots_N-2;

x = new double[knots_N]; // выделение памяти для координат узлов h = x_max/(knots_N-1);

solution = new double[N]; // выделение памяти для решения K_ij(); // матрица

q_i(); // правая часть матричного уравнения

progon(N, down, diag, up, q); // решение матричного уравнения методом прогонки test = 1;

result = output(test); return result;

}

 

 

//Вывод решения в файл

 

int output(int test) {

 

 

FILE *out;

 

 

double u_i, x_i, sol_i, q_i;

 

out = fopen("results.dat", "wt");

 

if (test == 1) {

 

 

fprintf(out,"\n x

u(x)

solution\n");

x_i = 0; u_i = 0; sol_i = 0; fprintf(out,"%-12.3g%-12.3g%-12.3g\n",x_i, u_i, sol_i); for (int i=0;i<knots_N-2;i++) {

x_i = x[i]+h;

//u_i = pow(x_i,3.0) - x_i; u_i = sin(3.14159*x_i);

sol_i = solution[i]; fprintf(out,"%-12.3g%-12.7g%-12.7g\n",x_i, u_i, sol_i);

}

x_i = 1; u_i = 0; sol_i = 0; fprintf(out,"%-12.3g%-12.3g%-12.3g\n",x_i, u_i, sol_i); result = 1;

}

 

 

else if (test == 0)

{

 

fprintf(out,"\n x

q(x)

solution\n");

x_i = 0; sol_i = 0; q_i = fun_q(x_i);

fprintf(out,"%-12.3g%-12.3g%-12.7g\n",x_i, q_i, sol_i);

for (int i=0;i<knots_N-2;i++) {

 

x_i = x[i]+h; sol_i = solution[i]; q_i = fun_q(x_i);

fprintf(out,"%-12.3g%-12.7g%-12.7g\n",x_i, q_i, sol_i);

}

x_i = 1; sol_i = 0; fprintf(out,"%-12.3g%-12.3g%-12.7g\n",x_i, q_i, sol_i); result = 1;

}

else {

fprintf(out,"\n Sorry, no solution!\n"); result = 0;

}

fclose(out); return result;

}

// Вычисление матричных элементов

void K_ij(void) {

 

//построение матрицы К

 

for (int i=0; i < knots_N-2; i++) {

 

for (int j=0; j < knots_N-2;j++) {

 

if (i==j)

{ K[i][i] = 2./h; }

 

if ((i-j)==1)

{ K[i][j] = -1./h;

}

if ((i-j)==-1)

{ K[i][j] = -1./h;

}

if (abs((i-j))>1) { K[i][j] = 0.; }

 

}

 

 

}

 

 

down = new double[knots_N];

 

diag = new double[knots_N];

 

up = new double[knots_N];

 

for (int i=0; i < knots_N; i++) {

 

for (int j=0; j < knots_N;j++) {

 

if (i==j) { diag[i] = K[i][i]; }

 

if ((i-j)==1)

{ down[i] = K[i][j]; }

if ((i-j)==-1)

{ up[i] = K[i][j]; }

}

 

 

}

 

 

}

 

 

// Вычисление вектора правой части матричного уравнения void q_i(void) {

q = new double[knots_N]; // выделение памяти для правой части матричного уравнения for (int i = 0; i < knots_N; i++) {

x[i] = h*i;

}

for (int i = 0; i < knots_N-2; i++) {

q[i] = quad_m(x[i],x[i+1]) + quad_p(x[i+1],x[i+2]);

}

}

//Интегрирование назад из i - того узла double quad_m(double x_1,double x_2) {

double s = 0;

double h, dh, x_i, x_k,x_kp; h = (x_2 - x_1);

dh = h/5; x_i = x_2;

for (int k= 0; k<5; k++) { x_k = x_1 + dh*k; x_kp = x_k + dh;

s = s + 0.5*dh*( (1/h*(x_k - x_i + h))*fun_q(x_k) + (1/h*(x_kp - x_i + h))*fun_q(x_kp) );

}

return s;

}

//Интегрирование вперёд из i - того узла

double quad_p(double x_1,double x_2) { double h, dh, x_i, x_k, x_kp, s ;

h = (x_2 - x_1); dh = h/5;

x_i = x_1; s = 0;

for (int k= 0; k<5; k++) { x_k = x_1 + dh*k; x_kp = x_k + dh;

s = s + 0.5*dh*((-1/h*(x_k - x_i - h))*fun_q(x_k) + (-1/h*(x_kp - x_i - h))*fun_q(x_kp));

}

return s;

}

void progon(int n,double c[],double a[],double b[],double g[])

//Решение линейной трёхдиагональной матрицы методом прогонки

//int n - порядок марицы

//double c[] - входной вектор длины n - диагональные матричные элементы под главной диагональю

//c[0] не используется

//double a[] - входной вектор длины n - диагональные матричные элементы в главной диагонали

//разрушается в процессе вычислений

//double b[] - входной вектор длины n - диагональные матричные элементы над главной диагональю,

//b[n-1] не используется

//double g[ - входной вектор длины n - правая часть матричного уравнения,

//при вычислении разрушается и заменяется решением

{

int j,i; double r;

for(i=1;i<n;i++) { j=i-1; r=c[i]/a[j]; a[i]-=r*b[j]; g[i]-=r*g[j];

}

j=n-1; g[j]/=a[j];

for(i=n-2 ; i>=0; i--){ g[i]=(g[i]-b[i]*g[i+1])/a[i];

}

solution = g;

}

// Результаты вычислений /*

x

u(x)

solution

0

0

0

 

0.167

0.4999996

0.5004563

0.333

0.866025

0.8668159

0.5

1

1.000913

0.667

0.8660263

0.8668164

0.833

0.5000019

0.5004569

1

0

0

 

*/

 

 

 

Соседние файлы в папке Loaded_rod