Advertisement
Danila_lipatov

MPI_for_11_point

Dec 9th, 2024
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.61 KB | None | 0 0
  1. #include <mpi.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <stdlib.h>
  5.  
  6. #define L 1.0     // Длина стержня
  7. #define K 1.0     // Коэффициент теплопроводности
  8. #define H 0.02    // Шаг по пространству
  9. #define TAU 0.0002 // Шаг по времени
  10. #define T 0.1     // Время моделирования
  11.  
  12. double exact_solution(double x, double t, int m_terms) {
  13.     double u = 0.0;
  14.     for (int m = 0; m < m_terms; m++) {
  15.         double coef = pow(-1, m) / (2 * m + 1) * exp(-K * pow(M_PI * (2 * m + 1), 2) * t / pow(L, 2));
  16.         u += coef * sin(M_PI * (2 * m + 1) * x / L);
  17.     }
  18.     return 4 / M_PI * u;
  19. }
  20.  
  21. int main(int argc, char** argv) {
  22.     MPI_Init(&argc, &argv);
  23.  
  24.     int rank, size;
  25.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  26.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  27.  
  28.     int nx = (int)(L / H) + 1;  // Количество точек по пространству
  29.     int nt = (int)(T / TAU);    // Количество временных шагов
  30.     double ratio = K * TAU / (H * H);
  31.  
  32.     if (ratio >= 1.0) {
  33.         if (rank == 0) {
  34.             printf("Условие устойчивости не выполняется: K * TAU / H^2 >= 1\n");
  35.         }
  36.         MPI_Finalize();
  37.         return 1;
  38.     }
  39.     int points_per_proc = nx / size;
  40.     int remainder = nx % size;
  41.     int local_nx = (rank < remainder) ? points_per_proc + 1 : points_per_proc;
  42.     int start_idx = (rank < remainder) ? rank * local_nx : rank * points_per_proc + remainder;
  43.     int end_idx = start_idx + local_nx;
  44.  
  45.     double* u_local = (double*)malloc(local_nx * sizeof(double));
  46.     for (int i = 0; i < local_nx; i++) {
  47.         u_local[i] = 1.0; // Начальная температура
  48.     }
  49.  
  50.     for (int n = 0; n < nt; n++) {
  51.  
  52.         double u_left = 0.0, u_right = 0.0;
  53.  
  54.         if (rank > 0) {
  55.             MPI_Sendrecv(&u_local[0], 1, MPI_DOUBLE, rank - 1, 0, &u_left, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  56.         }
  57.  
  58.         if (rank < size - 1) {
  59.             MPI_Sendrecv(&u_local[local_nx - 1], 1, MPI_DOUBLE, rank + 1, 1, &u_right, 1, MPI_DOUBLE, rank + 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  60.         }
  61.  
  62.         double* u_new = (double*)malloc(local_nx * sizeof(double));
  63.         for (int i = 1; i < local_nx - 1; i++) {
  64.             u_new[i] = u_local[i] + ratio * (u_local[i - 1] - 2 * u_local[i] + u_local[i + 1]);
  65.         }
  66.  
  67.         if (rank > 0) {
  68.             u_new[0] = u_local[0] + ratio * (u_left - 2 * u_local[0] + u_local[1]);
  69.         }
  70.         if (rank < size - 1) {
  71.             u_new[local_nx - 1] = u_local[local_nx - 1] + ratio * (u_local[local_nx - 2] - 2 * u_local[local_nx - 1] + u_right);
  72.         }
  73.  
  74.         free(u_local);
  75.         u_local = u_new;
  76.     }
  77.  
  78.     double* u_global = NULL;
  79.     if (rank == 0) {
  80.         u_global = (double*)malloc(nx * sizeof(double));
  81.     }
  82.     MPI_Gather(u_local, local_nx, MPI_DOUBLE, u_global, points_per_proc, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  83.     if (rank == 0) {
  84.         printf("x\tExact Solution\tApproximate Solution\tAbsolute Error\n");
  85.         for (int i = 0; i < 15; i++) {
  86.             double x = i * 0.1;
  87.             double exact_value = exact_solution(x, T, 100);
  88.             double approx_value = u_global[i * (nx - 1) / 10]; // интерполяция для 11 точек
  89.             double error = fabs(exact_value - approx_value);
  90.  
  91.             printf("%.6f\t%.6f\t%.6f\t%.6f\n", x, exact_value, approx_value, error);
  92.         }
  93.     }
  94.  
  95.     free(u_local);
  96.     if (rank == 0) {
  97.         free(u_global);
  98.     }
  99.     MPI_Finalize();
  100.     return 0;
  101. }
  102.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement