Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.81 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <mpi.h>
  3. #include <cmath>
  4.  
  5. double g(const double x)
  6. {
  7. return x * 0.9;
  8. }
  9.  
  10. double uol(const double x)
  11. {
  12. return sin(x);
  13. }
  14.  
  15. const double f0 = 0.0;
  16. const double f1 = 0.0;
  17.  
  18. int main(int arc, char** argv)
  19. {
  20. int size, rank;
  21. const auto msgtag = 12;
  22.  
  23. auto x = 0.0, time = 0.0;
  24. const auto tau = 0.2;
  25. const auto tmax = 1.0;
  26. const auto L = 10.0;
  27. auto l = 0;
  28.  
  29. const auto h = 0.1;
  30.  
  31. const auto r = tau * tau / (h * h);
  32.  
  33. const auto N = static_cast<int>(L / h) + 1;
  34.  
  35. //шапочка
  36.  
  37. if (MPI_Init(&arc, &argv) != MPI_SUCCESS) return 1;
  38.  
  39. if (MPI_Comm_size(MPI_COMM_WORLD, &size) != MPI_SUCCESS)
  40. {
  41. MPI_Finalize();
  42. return 2;
  43. }
  44.  
  45. if (MPI_Comm_rank(MPI_COMM_WORLD, &rank) != MPI_SUCCESS)
  46. {
  47. MPI_Finalize();
  48. return 3;
  49. }
  50.  
  51. MPI_Status status;
  52.  
  53. //Распределение отрезков по процессам
  54. auto l1 = N / size;
  55. auto l2 = N % size;
  56. const auto kol = new int[size];
  57.  
  58. for (auto i = 0; i < size; i++) kol[i] = l1;
  59.  
  60. if (l2)
  61. {
  62. if (rank == size - 1) l1++;
  63. l2--;
  64. kol[size - 1]++;
  65. }
  66.  
  67. if (l2)
  68. {
  69. if (rank < l2) l1++;
  70. for (auto i = 0; i < l2; i++) kol[i]++;
  71. }
  72.  
  73. auto n = l1;
  74.  
  75. if (!rank || rank == size - 1) n++; else n += 2;
  76.  
  77. auto u = new double[n];
  78. auto uold = new double[n];
  79.  
  80. auto sum = 0;
  81.  
  82.  
  83. if (rank)
  84. {
  85. for (auto i = 0; i < rank; i++) sum += kol[i];
  86. l = sum;
  87. sum--;
  88. x = h * sum; //Вычисляем смещение для каждого промежутка
  89. }
  90.  
  91. //Присваиваем начальные значения
  92.  
  93. for (auto i = 0; i < n; i++)
  94. {
  95. u[i] = g(x);
  96. uold[i] = u[i] - tau * uol(x);
  97. x += h;
  98. }
  99.  
  100. if (!rank) uold[0] = u[0] = f0;
  101. if (rank == size - 1) uold[n - 1] = u[n - 1] = f1;
  102.  
  103. const auto tn = MPI_Wtime(); //Начальное время
  104. do
  105. {
  106. const auto xn = h * sum;
  107.  
  108. for (auto i = 1; i < n - 1; i++)
  109. {
  110. const auto uu = u[i];
  111. u[i] = r * ((xn + i * h + h) * (xn + i * h + h) * (u[i + 2] - u[i + 1]) - (xn + i * h) * (xn + i * h) * (u[i + 1] - u[i])) + 2.0 * u[i] - uold[i];
  112. uold[i] = uu;
  113. }
  114.  
  115. //Начальные значения в краевых точках
  116. if (!rank) u[0] = f0;
  117. if (rank == size - 1) u[n - 1] = f1;
  118.  
  119. //Обмен данными между процессами
  120. if (rank & 1)
  121. {
  122. MPI_Ssend(&u[1], 1, MPI_DOUBLE, rank - 1, msgtag, MPI_COMM_WORLD);
  123. MPI_Recv(&u[0], 1, MPI_DOUBLE, rank - 1, msgtag, MPI_COMM_WORLD, &status);
  124.  
  125. if (rank != size - 1)
  126. {
  127. MPI_Ssend(&u[n - 2], 1, MPI_DOUBLE, rank + 1, msgtag, MPI_COMM_WORLD);
  128. MPI_Recv(&u[n - 1], 1, MPI_DOUBLE, rank + 1, msgtag, MPI_COMM_WORLD, &status);
  129. }
  130. }
  131.  
  132. else
  133. {
  134. if (rank != size - 1) {
  135. MPI_Recv(&u[n - 1], 1, MPI_DOUBLE, rank + 1, msgtag, MPI_COMM_WORLD, &status);
  136. MPI_Ssend(&u[n - 2], 1, MPI_DOUBLE, rank + 1, msgtag, MPI_COMM_WORLD);
  137. }
  138.  
  139. if (rank) {
  140. MPI_Recv(&u[0], 1, MPI_DOUBLE, rank - 1, msgtag, MPI_COMM_WORLD, &status);
  141. MPI_Ssend(&u[1], 1, MPI_DOUBLE, rank - 1, msgtag, MPI_COMM_WORLD);
  142. }
  143. }
  144.  
  145. time += tau; //Шаг по времени
  146.  
  147. } while (time <= tmax);
  148.  
  149. const auto tk = MPI_Wtime(); //Конечное время
  150.  
  151. //вывод
  152. int in, ik;
  153. if (!rank) in = 0; else in = 1;
  154. if (rank == size - 1) ik = n; else ik = n - 1;
  155.  
  156. for (auto i = 0; i < size; i++)
  157. {
  158. if (i == rank)
  159. {
  160. const auto f = fopen("Temperature.txt", "a"); // NOLINT(android-cloexec-fopen)
  161. for (auto j = in; j < ik; j++, l++)
  162. {
  163. fprintf(f, "u[%d] = %f\n", l, u[j]);
  164. }
  165. fclose(f);
  166.  
  167. }
  168. MPI_Barrier(MPI_COMM_WORLD);
  169. }
  170.  
  171. if (!rank)
  172. {
  173. const auto f = fopen("Temperature.txt", "a"); // NOLINT(android-cloexec-fopen)
  174. fprintf(f, "\nВремя вычислений: %f", tk - tn);
  175. fclose(f);
  176. }
  177.  
  178. delete[]u;
  179. delete[]kol;
  180. MPI_Finalize();
  181. return 0;
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement