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

KM2016 / Loaded_rod / fem3

.html
Скачиваний:
27
Добавлен:
14.03.2016
Размер:
25 Кб
Скачать
☆

fem3.cpp //Приложение к разделу 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