Advertisement
Guest User

Untitled

a guest
Jan 16th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.82 KB | None | 0 0
  1. # include <stdlib.h>
  2. # include <stdio.h>
  3. # include <math.h>
  4.  
  5. # include "mpi.h"
  6.  
  7. int main ( int argc, char *argv[] );
  8. void heat_part ( int n, int p, int id, double x_min, double x_max, MPI_Comm parentComm );
  9.  
  10. /******************************************************************************/
  11.  
  12. int main ( int argc, char *argv[] )
  13. {
  14. double a = 0.0; // lewy brzeg przedzialu
  15. double b = 1.0; // prawy brzeg przedzialu
  16. int i;
  17. int id; // rank
  18. int n; // liczba punktow dla kazdego wezla
  19. int p; // size
  20. double x_max;
  21. double x_min;
  22.  
  23. MPI_Init ( &argc, &argv );
  24.  
  25. MPI_Comm_rank ( MPI_COMM_WORLD, &id );
  26.  
  27. MPI_Comm_size ( MPI_COMM_WORLD, &p );
  28.  
  29. n = 12; // liczba punktow dla kazdego wezla
  30. i = 0; // poczatkowa chwila czasu
  31.  
  32. // wspolrzedna lewego punktu dla wezla id
  33. x_min = ( ( double )( p * n + 1 - id * n - i ) * a
  34. + ( double )( id * n + i ) * b )
  35. / ( double ) ( p * n + 1 );
  36.  
  37. i = n + 1;
  38.  
  39. // wspolrzedna prawego punktu dla wezla id
  40. x_max = ( ( double )( p * n + 1 - id * n - i ) * a
  41. + ( double )( id * n + i ) * b )
  42. / ( double )( p * n + 1 );
  43.  
  44. heat_part ( n, p, id, x_min, x_max, NULL ); // obliczenia dla pojedynczego wezla
  45.  
  46. //MPI_Barrier( MPI_COMM_WORLD );
  47.  
  48. MPI_Finalize ( );
  49.  
  50. return 0;
  51. }
  52.  
  53. /******************************************************************************/
  54. // obliczenia dla pojedynczego wezla - pojedynczego podobszaru
  55. /******************************************************************************/
  56. void heat_part ( int n, int p, int id, double x_min, double x_max, MPI_Comm par3entComm )
  57. {
  58. double cfl;
  59. double *h;
  60. double *h_new;
  61. int i;
  62. int ierr;
  63. int j;
  64. int j_max;
  65. int j_min;
  66. double k;
  67. MPI_Status status;
  68. double t;
  69. double t_del;
  70. double t_max;
  71. double t_min;
  72. int tag;
  73. double wtime;
  74. double *x;
  75. double x_del;
  76.  
  77. h = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // rozwiazanie dla t_i
  78. h_new = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // rozwiazanie dla t_i+1
  79. x = ( double * ) malloc ( ( n + 2 ) * sizeof ( double ) ); // wspolrzedne punktow
  80.  
  81. k = 0.002 / ( double ) p; // przewodniosc cieplna
  82.  
  83. j_min = 0; // indeksy krokow czasowych - min i max
  84. j_max = 100;
  85. t_min = 0.0; // chwile czasu - min i max
  86. t_max = 10.0;
  87. t_del = ( t_max - t_min ) / ( double ) ( j_max - j_min ); // krok czasowy Delta t
  88.  
  89. x_del = ( x_max - x_min ) / ( double ) ( n + 1 ); // odstep miedzy punktami
  90. for ( i = 0; i <= n + 1; i++ )
  91. {
  92. x[i] = ( ( double ) ( i ) * x_max
  93. + ( double ) ( n + 1 - i ) * x_min )
  94. / ( double ) ( n + 1 );
  95. }
  96.  
  97. // ustawienie warunku poczatkowego
  98. for ( i = 0; i <= n + 1; i++ )
  99. {
  100. h[i] = 95.0;
  101. }
  102.  
  103. wtime = MPI_Wtime ( ); //poczatek pomiaru czasu
  104.  
  105. for ( j = 1; j <= j_max; j++ )
  106. {
  107.  
  108. // wymiana informacji z wezlami sasiednimi
  109. tag = 1;
  110.  
  111. if ( id < p - 1 )
  112. {
  113. MPI_Send ( &h[n], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD );
  114. }
  115.  
  116. if ( 0 < id )
  117. {
  118. MPI_Recv ( &h[0], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD, &status );
  119. }
  120.  
  121. tag = 2;
  122.  
  123. if ( 0 < id )
  124. {
  125. MPI_Send ( &h[1], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD );
  126. }
  127.  
  128. if ( id < p - 1 )
  129. {
  130. MPI_Recv ( &h[n+1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD, &status );
  131. }
  132.  
  133.  
  134. // implementacja wzoru roznicowego
  135. for ( i = 1; i <= n; i++ )
  136. {
  137. h_new[i] = h[i] + t_del * (
  138. k * ( h[i-1] - 2.0 * h[i] + h[i+1] ) / x_del / x_del
  139. + 2.0 * sin ( x[i] * t ) );
  140. }
  141.  
  142. // nowa chwila czasu
  143. t = ( ( double ) ( j - j_min ) * t_max
  144. + ( double ) ( j_max - j ) * t_min )
  145. / ( double ) ( j_max - j_min );
  146.  
  147. // przygotowanie do nastepnego kroku czasowego
  148. for ( i = 1; i < n + 1; i++ )
  149. {
  150. h[i] = h_new[i];
  151. }
  152.  
  153. // warunek brzegowy
  154. if ( 0 == id ) h[0] = 100.0 + 10.0 * sin ( t );
  155. if ( id == p - 1 ) h[n+1] = 75;
  156.  
  157. }
  158.  
  159. // koncowa wymiana informacji z wezlami sasiednimi
  160. tag = 11;
  161.  
  162. if ( id < p - 1 ) {
  163. MPI_Send ( &h[n], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD );
  164. }
  165.  
  166. if ( 0 < id ) {
  167. MPI_Recv ( &h[0], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD, &status );
  168. }
  169.  
  170. tag = 12;
  171.  
  172. if ( 0 < id )
  173. {
  174. MPI_Send ( &h[1], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD );
  175. }
  176.  
  177. if ( id < p - 1 )
  178. {
  179. MPI_Recv ( &h[n+1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD, &status );
  180. }
  181.  
  182. wtime = MPI_Wtime ( ) - wtime;
  183.  
  184.  
  185. // wydruk wyniku
  186. tag = 112;
  187.  
  188. MPI_Comm parentComm;
  189.  
  190. MPI_Comm_get_parent(&parentComm);
  191. // wydruk wyniku
  192. // MPI_Send (&h, sizeof(double)*( n + 2), MPI_DOUBLE, 0, 0, parentComm );
  193. if ( id == 0 )
  194. {
  195. printf ( "\n" );
  196. printf ( " Wall clock elapsed seconds = %f\n", wtime );
  197.  
  198. printf ( "%2d T= %f\n", id, t );
  199. printf ( "%2d X= ", id );
  200. for ( i = 0; i <= n + 1; i++ )
  201. {
  202. printf ( "%7.2f", x[i] );
  203. }
  204. printf ( "\n" );
  205. printf ( "%2d H= ", id );
  206. for ( i = 0; i <= n + 1; i++ )
  207. {
  208. printf ( "%7.2f", h[i] );
  209. }
  210. printf ( "\n" );
  211.  
  212. MPI_Send ( &h[1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD );
  213. }
  214.  
  215.  
  216. if(id!=0){
  217. MPI_Recv ( &h[0], 1, MPI_DOUBLE, id-1, tag, MPI_COMM_WORLD, &status );
  218. printf ( "%2d T= %f\n", id, t );
  219. printf ( "%2d X= ", id );
  220. for ( i = 0; i <= n + 1; i++ )
  221. {
  222. printf ( "%7.2f", x[i] );
  223. }
  224. printf ( "\n" );
  225. printf ( "%2d H= ", id );
  226. for ( i = 0; i <= n + 1; i++ )
  227. {
  228. printf ( "%7.2f", h[i] );
  229. }
  230. printf ( "\n" );
  231. if(id+1<p)
  232. MPI_Send ( &h[1], 1, MPI_DOUBLE, id+1, tag, MPI_COMM_WORLD );
  233. }
  234.  
  235.  
  236. free ( h );
  237. free ( h_new );
  238. free ( x );
  239.  
  240. return;
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement