Advertisement
lutaco

Untitled

Jun 5th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.89 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/time.h>
  6. #include <math.h>
  7. #include <stdbool.h>
  8. #include <mpi.h>
  9. #define WRITETOGNUPOT //вывод в файл
  10. double dx = 0.1;
  11. double dt = 0.01;
  12. double a = 0.1;
  13. #define LEFT 1
  14. #define RIGHT 2
  15. double dx2;
  16. double a2;
  17. struct timeval tv1,tv2,dtv;
  18. struct timezone tz;
  19. int lengthX;
  20.  
  21. void time_start() {
  22. gettimeofday(&tv1, &tz);
  23. }
  24.  
  25. int time_stop() {
  26. gettimeofday(&tv2, &tz);
  27. dtv.tv_sec = tv2.tv_sec - tv1.tv_sec;
  28. dtv.tv_usec = tv2.tv_usec - tv1.tv_usec;
  29. if (dtv.tv_usec < 0) {
  30. dtv.tv_sec--;
  31. dtv.tv_usec += 1000000;
  32. }
  33. return dtv.tv_sec * 1000 + dtv.tv_usec / 1000;
  34. }
  35.  
  36. FILE *out,*fp;
  37. void writeIntoFile(double* Z, int lengthX, double CurrentTime) { //вывод в файл
  38. int i;
  39. for (i = 0; i < lengthX; i++) {
  40. fprintf(out, "%d\t%lf\n", i, Z[i]);
  41. }
  42. fprintf(out, "\n\n");
  43. }
  44.  
  45. void openFiles(int lengthX, int timeInterval) { //открытие файлов
  46. out = fopen("out.txt", "w");
  47. fp = fopen("vgraph0.dat", "w");
  48. fprintf(fp, "set xrange[0:%d]\nset yrange[-100:100]\n", lengthX - 1);
  49. fprintf(fp, "do for [i=0:%d]{\n", timeInterval - 1);
  50. fprintf(fp, "plot 'out.txt' index i using 1:2 smooth bezier\npause 0.1}\npause -1\n");
  51. }
  52.  
  53. void calculateFisrtTime(double* Z0, double* Z1, int lengthX) { //инициализация массивов
  54. int i;
  55. int prev = 0;
  56. memset(Z0, lengthX * sizeof(double), 0);
  57. memset(Z1, lengthX * sizeof(double), 0);
  58. Z0[lengthX - 1] = 50;
  59. Z1[lengthX - 1] = 50;
  60. }
  61.  
  62. void calculate(double* Z0, double* Z1, int lengthX, double CurrentTime, int myrank, int total, double* zleft, double* zright) { //функция расчетов новых значений
  63. int i = 0;
  64. if (myrank != 0) {
  65. Z1[i] = dt * a * ((*zleft - 2 * Z0[i] + Z0[i + 1]) / dx2) + Z0[i];
  66. *zleft = Z1[i];
  67. }
  68. else
  69. Z1[0] = Z0[1] + 20;
  70.  
  71.  
  72. // printf("%f -2 %f %f %f\n", Z0[0], Z0[1], Z0[2], Z0[1]);
  73. for (i = 1; i < lengthX - 1; i++) {
  74. Z1[i] = dt * a * (Z0[i - 1] - 2 * Z0[i] + Z0[i + 1]) / dx2 + Z0[i];
  75. }
  76.  
  77. if (myrank != total - 1) {
  78. Z1[i] = dt * a * ((Z0[i - 1] - 2 * Z0[i] + *zright) / dx2) + Z0[i];
  79. *zright = Z1[i];
  80. }
  81. else
  82. Z1[lengthX - 1] = 50;
  83. // отправка и получение соседних значений
  84. if (myrank != total - 1) {
  85. MPI_Send((void*)(zright), 1, MPI_DOUBLE, myrank + 1, LEFT, MPI_COMM_WORLD);
  86. MPI_Recv((void*)(zright), 1, MPI_DOUBLE, myrank + 1, RIGHT, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  87. }
  88. if (myrank != 0) {
  89. MPI_Send((void*)(zleft), 1, MPI_DOUBLE, myrank - 1, RIGHT, MPI_COMM_WORLD);
  90. MPI_Recv((void*)(zleft), 1, MPI_DOUBLE, myrank - 1, LEFT, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  91. }
  92. }
  93.  
  94. int main(int argc, char **argv) {
  95. int myrank, total;
  96. if (argc < 3) {
  97. printf("./a.out #lengthX #timeInterval\n");
  98. exit(0);
  99. }
  100. lengthX = atoi(argv[1]);
  101. double timeInterval = atof(argv[2]);
  102. dx2 = dx * dx;
  103. double *Z0, *Z1;
  104. double CurrentTime = 0;
  105. int znumber = 1;
  106.  
  107. MPI_Init(&argc, &argv);
  108. MPI_Comm_size(MPI_COMM_WORLD, &total);
  109. MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  110. if (lengthX % total != 0) {
  111. printf("Incorrect!\n");
  112. exit(0);
  113. }
  114. int newlengthX = lengthX / total;
  115. double* z0;
  116. double* z1;
  117. double zleft;
  118. double zright;
  119. if (myrank == 0) { //инициализация массивов в основном процессе
  120. Z0 = (double*)calloc(lengthX, sizeof(double));
  121. Z1 = (double*)calloc(lengthX, sizeof(double));
  122. calculateFisrtTime(Z0, Z1, lengthX);
  123. #ifdef WRITETOGNUPOT
  124. openFiles(lengthX, timeInterval);
  125. writeIntoFile(Z0, lengthX, CurrentTime);
  126. #endif
  127. }
  128. CurrentTime += 1;
  129. z0 = (double*)calloc(newlengthX, sizeof(double));
  130. z1 = (double*)calloc(newlengthX, sizeof(double));
  131. int* displsSend;
  132. displsSend = (int *)calloc(total, sizeof(int));
  133. int numberOfProc;
  134. for (numberOfProc = 0; numberOfProc < total; numberOfProc++)
  135. displsSend[numberOfProc] = numberOfProc * newlengthX;
  136. int* displsSendCount;
  137. displsSendCount = (int *)calloc(total, sizeof(int));
  138. for (numberOfProc = 0; numberOfProc < total; numberOfProc++)
  139. displsSendCount[numberOfProc] = newlengthX;
  140. int i;
  141. for (i = 0; i < total; i++) { //рассылка процессам данных
  142. MPI_Scatterv((void *)(Z0), displsSendCount, displsSend, MPI_DOUBLE, (void *)(z0), newlengthX, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  143. MPI_Scatterv((void *)(Z1), displsSendCount, displsSend, MPI_DOUBLE, (void *)(z1), newlengthX, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  144. }
  145. zleft = z0[0];
  146. zright = z0[newlengthX - 1];
  147. //рассылка соседних значений
  148. if (myrank != total - 1) {
  149. MPI_Send((void*)(&zright), 1, MPI_DOUBLE, myrank + 1, LEFT, MPI_COMM_WORLD);
  150. MPI_Recv((void*)(&zright), 1, MPI_DOUBLE, myrank + 1, RIGHT, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  151. }
  152. if (myrank != 0) {
  153. MPI_Send((void*)(&zleft), 1, MPI_DOUBLE, myrank - 1, RIGHT, MPI_COMM_WORLD);
  154. MPI_Recv((void*)(&zleft), 1, MPI_DOUBLE, myrank - 1, LEFT, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  155. }
  156. if (myrank == 0)
  157. time_start();
  158. bool flag = 1;
  159. while (CurrentTime < timeInterval) {
  160. if (flag)
  161. calculate(z0, z1, newlengthX, CurrentTime, myrank, total, &zleft, &zright);
  162. else
  163. calculate(z1, z0, newlengthX, CurrentTime, myrank, total, &zleft, &zright);
  164. #ifdef WRITETOGNUPOT
  165. MPI_Barrier(MPI_COMM_WORLD);
  166. if (flag)
  167. MPI_Gatherv((void*)(z1), newlengthX, MPI_DOUBLE, (void*)(Z1), displsSendCount, displsSend, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  168. else
  169. MPI_Gatherv((void*)(z0), newlengthX, MPI_DOUBLE, (void*)(Z0), displsSendCount, displsSend, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  170. MPI_Barrier(MPI_COMM_WORLD);
  171. if (myrank == 0)
  172. if (flag)
  173. writeIntoFile(Z1, lengthX, CurrentTime);
  174. else
  175. writeIntoFile(Z0, lengthX, CurrentTime);
  176. #endif
  177. flag = !flag;
  178. CurrentTime += 1;
  179. }
  180. if (myrank == 0) {
  181. int ms = time_stop();
  182. printf("Time: %d milliseconds\n", ms);
  183. }
  184. MPI_Finalize();
  185. exit(0);
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement