Guest User

Untitled

a guest
May 20th, 2018
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.59 KB | None | 0 0
  1. /*
  2.  * Successive over relaxation
  3.  * (red-black SOR)
  4.  *
  5.  * Written by Rob van Nieuwpoort, 6-oct-2003
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <math.h>
  11. #include <string.h>
  12. #include <sys/time.h>
  13.  
  14. #define TOLERANCE 0.00002        /* termination criterion */
  15. #define MAGIC 0.8                /* magic factor */
  16.  
  17. int even (int i)
  18. {
  19.         return !(i & 1);
  20. }
  21.  
  22.  
  23. double stencil (double** G, int row, int col)
  24. {
  25.         return (G[row-1][col] + G[row+1][col] +
  26.                 G[row][col-1] + G[row][col+1] ) / 4.0;
  27. }
  28.  
  29.  
  30. void alloc_grid(double ***Gptr, int N)
  31. {
  32.         int i;
  33.         double** G = (double**)malloc(N*sizeof(double*));
  34.         if ( G == 0 ) {
  35.                 fprintf(stderr, "malloc failed\n");
  36.                 exit(42);
  37.         }
  38.  
  39.         for (i = 0; i<N; i++) { /* malloc the own range plus one more line */
  40.                 /* of overlap on each side */
  41.                 G[i] = (double*)malloc(N*sizeof(double));
  42.                 if ( G[i] == 0 ) {
  43.                         fprintf(stderr, "malloc failed\n");
  44.                         exit(42);
  45.                 }
  46.         }
  47.  
  48.         *Gptr = G;
  49. }
  50.  
  51.  
  52. void init_grid(double **G, int N)
  53. {
  54.         int i, j;
  55.  
  56.         /* initialize the grid */
  57.         for (i = 0; i < N; i++){
  58.                 for (j = 0; j < N; j++){
  59.                         if (i == 0) G[i][j] = 4.56;
  60.                         else if (i == N-1) G[i][j] = 9.85;
  61.                         else if (j == 0) G[i][j] = 7.32;
  62.                         else if (j == N-1) G[i][j] = 6.88;
  63.                         else G[i][j] = 0.0;
  64.                 }
  65.         }
  66. }
  67.  
  68.  
  69. void print_grid(double** G, int N)
  70. {
  71.         int i, j;
  72.  
  73.         for ( i = 1 ; i < N-1 ; i++ ) {
  74.                 for ( j = 1 ; j < N-1 ; j++ ) {
  75.                         printf("%10.3f ", G[i][j]);
  76.                 }
  77.                 printf("\n");
  78.         }
  79. }
  80.  
  81.  
  82. int main (int argc, char *argv[])
  83. {
  84.         int N;                     /* problem size */
  85.         int ncol,nrow;             /* number of rows and columns */
  86.         double Gnew,r,omega,       /* some float values */
  87.            stopdiff,maxdiff,diff;  /* differences btw grid points in iters */
  88.         double **G;                /* the grid */
  89.         int i,j,phase,iteration;   /* counters */
  90.         struct timeval start;
  91.         struct timeval end;
  92.         double time;
  93.         int print = 0;
  94.  
  95. /* set up problem size */
  96.         N = 1000;
  97.  
  98.         for(i=1; i<argc; i++) {
  99.                 if(!strcmp(argv[i], "-print")) {
  100.                         print = 1;
  101.                 } else {
  102.                         N = atoi(argv[i]);
  103.                 }
  104.         }
  105.  
  106.         fprintf(stderr, "Running %d x %d SOR\n", N, N);
  107.  
  108.         N += 2; /* add the two border lines */
  109.         /* finally N*N (from argv) array points will be computed */
  110.  
  111.         /* set up a quadratic grid */
  112.         ncol = nrow = N;
  113.         r        = 0.5 * ( cos( M_PI / ncol ) + cos( M_PI / nrow ) );
  114.         omega    = 2.0 / ( 1 + sqrt( 1 - r * r ) );
  115.         stopdiff = TOLERANCE / ( 2.0 - omega );
  116.         omega   *= MAGIC;
  117.  
  118.         alloc_grid(&G, N);
  119.         init_grid(G, N);
  120.  
  121.         if(gettimeofday(&start, 0) != 0) {
  122.                 fprintf(stderr, "could not do timing\n");
  123.                 exit(1);
  124.         }
  125.  
  126.         /* now do the "real" computation */
  127.         iteration = 0;
  128.         do {
  129.                 maxdiff = 0.0;
  130.                 for ( phase = 0; phase < 2 ; phase++){
  131.                         for ( i = 1 ; i < N-1 ; i++ ){
  132.                                 for ( j = 1 + (even(i) ^ phase); j < N-1 ; j += 2 ){
  133.                                         Gnew = stencil(G,i,j);
  134.                                         diff = fabs(Gnew - G[i][j]);
  135.                                         if ( diff > maxdiff )
  136.                                                 maxdiff = diff;
  137.                                         G[i][j] = G[i][j] + omega * (Gnew-G[i][j]);
  138.                                 }
  139.                         }
  140.                 }
  141.                 iteration++;
  142.         } while (maxdiff > stopdiff);
  143.  
  144.         if(gettimeofday(&end, 0) != 0) {
  145.                 fprintf(stderr, "could not do timing\n");
  146.                 exit(1);
  147.         }
  148.  
  149.         time = (end.tv_sec + (end.tv_usec / 1000000.0)) -
  150.                 (start.tv_sec + (start.tv_usec / 1000000.0));
  151.  
  152.         fprintf(stderr, "SOR took %10.3f seconds\n", time);
  153.  
  154.         printf("Used %5d iterations, diff is %10.6f, allowed diff is %10.6f\n",
  155.                iteration,maxdiff,stopdiff);
  156.  
  157.         if(print == 1) {
  158.                 print_grid(G, N);
  159.         }
  160.  
  161.         return 0;
  162. }
Add Comment
Please, Sign In to add comment