Advertisement
lutaco

Untitled

May 28th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.68 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. int M, N; //размерность сетки
  6. double *prev; //массивы значений в предыдущий момент времени
  7. double **A;
  8. double *x;
  9. double T = 500.0; //граничное условие
  10. // double C = 1.0;
  11. // double R = 5.0;
  12. // double h = 1.0;
  13. int done = 0;
  14. double sec = 20;
  15. double d_time = 0.5;
  16. double c = 1;
  17. double den = 1;
  18. double alph = 1;
  19. double dx = 0.5;
  20. double dy = 0.5;
  21.  
  22. //ВНИМАТЕЛЬНО ПРОЧИТАЙ ОПИСАНИЕ МЕТОДА ГАУССА
  23.  
  24. //Берет номер узла и записывает общее оравнение для него
  25. void wrtk(int k, int i, int j) {
  26. double a = alph / c / den;
  27. A[k][(j + 1) * M + i] = a / dy / dy;
  28. A[k][(j - 1) * M + i] = a / dy / dy;
  29. A[k][j * M + i + 1] = a / dx / dx;
  30. A[k][j * M + i - 1] = a / dx / dx;
  31. A[k][j * M + i] = - (1 / d_time) - (2 * a / dx / dx) - (2 * a / dy / dy);
  32. x[k] = - prev[j * M + i] / d_time;
  33. }
  34.  
  35. //Заполняет матрицу коэффициентов А и вектор b(x)
  36. void mysolver(void) { //расчет значений
  37. int i, j;
  38. int k = 0;
  39. for (j = 0; j < N; j++) {
  40. for (i = 0; i < M; i++) {
  41. if (j == 0 ) {//нижняя граница
  42. A[k][j * M + i] = 1;
  43. A[k][(j + 1) * M + i] = -1;
  44. } else if (j == N - 1 && i > M / 2) {//Верхняя правая граница
  45. A[k][j * M + i] = 1;
  46. A[k][(j - 1) * M + i] = -1;
  47. } else if (j == N - 1) {//Верхняя правая
  48. A[k][j * M + i] = 1;
  49. x[k] = T;
  50. } else if (i == 0) {//левая
  51. A[k][j * M + i] = 1;
  52. x[k] = T;
  53. } else if (i == M - 1) {//Правая
  54. A[k][j * M + i] = 1;
  55. x[k] = T;
  56. } else {
  57. wrtk(k , i , j);
  58. }
  59. k++;
  60. }
  61. }
  62. }
  63.  
  64.  
  65. // Вот тут будь осторожнее. Нормальный метод Гаусса использует три массива A, b, x.
  66. // Я использую только А и x. Массив х играет роль b. После решения, ответы записываются в x. Сделано только для экономии памяти. Можно было бы использовать
  67. // и А и b и х. Но до обратного хода вектор х нахрен не нужен. А когда мы записываем ответ в x[i], b[i] нам уже больше не пригодится, поэтому для
  68. // экономии туда можно записаь результат. Почему ипользую A и х, а не А и b, хз. Разницы нет.
  69.  
  70. void gauss(int n) {
  71.  
  72. int i, j, k;
  73. double a;
  74. //Прямой ход метода Гаусса
  75. for ( k = 0; k < n; k++ )
  76. for ( j = k + 1; j < n; j++) {
  77. a = - A[j][k] / A[k][k];
  78. x[j] += x[k] * a;
  79. for ( i = k ; i < n; i++ )
  80. A[j][i] += A[k][i] * a;
  81. }
  82.  
  83. //Обратный ход
  84. x[n - 1] /= A[n - 1][n - 1];
  85. for ( i = n - 2; i >= 0; i-- ) {
  86. for ( j = i + 1; j < n; j++ )
  87. x[i] -= x[j] * A[i] [j];
  88. x[i] /= A[i][i];
  89. }
  90. }
  91.  
  92. int main(int argc, char* argv[]) {
  93. int n_time; //количество циклов
  94. int i, j, k;
  95. int nur;
  96.  
  97. M = 12/dx;
  98. N = 4/dy;
  99. n_time = sec * d_time;
  100. nur = M * N;
  101. FILE *gp=popen("gnuplot -persist","w");
  102.  
  103. prev = (double*) malloc(sizeof(double) * nur);
  104. A = (double**) malloc(sizeof(double*) * nur);
  105. x = (double*) malloc(sizeof(double) * nur);
  106.  
  107. for (k = 0; k < nur; k++) {
  108. A[k] = (double*) malloc(sizeof(double) * nur);
  109. }
  110.  
  111. memset(prev, 10, sizeof(double) * nur);//Установка начальной температуры
  112.  
  113.  
  114. for (k = 0; k < n_time; k++) {
  115.  
  116. memset(x, 0, sizeof(double) * nur ); // Инициалицируем х и А нулями
  117.  
  118. for (i = 0; i < nur; i++)
  119. memset(A[i], 0, sizeof(double) * nur);
  120. mysolver();
  121.  
  122. gauss(nur);
  123.  
  124. FILE *fd = fopen("output.txt", "w");
  125. memcpy(prev, x, sizeof(double) * nur);
  126. //Печать решения
  127. for (j = 0; j < N; j++) {
  128. for (i = 0; i < M; i++) {
  129.  
  130. fprintf(fd, "%.4f ", prev[j * M + i]);
  131. }
  132. }
  133. fclose(fd);
  134. fprintf(gp, "unset key\n");
  135. fprintf(gp, "set tic scale 0\n");
  136. fprintf(gp, "set palette rgb 33,13,10\n");//color
  137. fprintf(gp, "set cbrange [0:100]\n");//-10000:10000
  138. fprintf(gp, "unset cbtics\n");
  139. fprintf(gp, "set xrange [-0.5:%f]\n",24-0.5);
  140. fprintf(gp, "set yrange [-0.5:%f]\n",8-0.5);
  141. fprintf(gp, "set pm3d interpolate 0,0\n");
  142. fprintf(gp, "set pm3d map\n");
  143. //fprintf(gp,"do for[i=0:%d] {\n",n);
  144.  
  145. //fprintf(gp,"5 4 3 1 0\n2 2 0 0 1\n0 0 0 1 0\n0 0 0 2 3\n0 1 2 4 3\n");
  146. fprintf(gp, "splot \"output.txt\" matrix with pm3d\n");
  147. fflush(gp);
  148. }//k
  149.  
  150.  
  151.  
  152. return 0;
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement