Blame view

lab3/omp_heat2D.c 5.72 KB
1e6ef8e72   kmazouzi   Steady state heat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  /****************************************************************************
   * DESCRIPTION:  
   *   Serial HEAT2D Example - C Version
   *   This example is based on a simplified 
   *   two-dimensional heat equation domain decomposition.  The initial 
   *   temperature is computed to be high in the middle of the domain and 
   *   zero at the boundaries.  The boundaries are held at zero throughout 
   *   the simulation.  During the time-stepping, an array containing two 
   *   domains is used; these domains alternate between old data and new data.
   *
   *  The physical region, and the boundary conditions, are suggested
      by this diagram;
  
                     u = 0
               +------------------+
               |                  |
      u = 100  |                  | u = 100
               |                  |
               +------------------+
                     u = 100
  
  Interrior point :
    u[Central] = (1/4) * ( u[North] + u[South] + u[East] + u[West] )
  
   ****************************************************************************/
  #include <stdio.h>
  #include <stdlib.h>
  #include <math.h>
  #include <omp.h>
d16e53ac3   kmazouzi   add program argum...
30
31
  #define NN 50
  #define MM 50  
1e6ef8e72   kmazouzi   Steady state heat
32
33
34
  
  #define ITER_PRINT 100
  #define PRINT_DATA 1
d16e53ac3   kmazouzi   add program argum...
35
  #define _EPSILON 0.001
1e6ef8e72   kmazouzi   Steady state heat
36
37
38
39
40
41
42
43
44
45
46
47
48
  
  
  void update(int nx,int ny, float *u, float *unew, float * diff);
  void inidat(int nx, int ny, float *u, float *unew); 
  void prtdat(int nx, int ny, float *u,const char *fnam);
  
  
  
  
  int main(int argc, char *argv[])
  {
  
      float diff=1.0;
d16e53ac3   kmazouzi   add program argum...
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
      float EPSILON=_EPSILON;
      int N=NN,M=MM;
  
      if(argc !=3)
      {
          fprintf(stderr,"usage %s N EPSILON
   ", argv[0]);
          fprintf(stderr,"\t\twhere N is GRID size, EPSILON is  Tolerance
  "); 
          fprintf(stderr,"\t\texample N = 100, EPSILON = 0.1
  "); 
          return -1;
      } 
  
      N = M = atoi(argv[1]);
      EPSILON = atof(argv[2]);
1e6ef8e72   kmazouzi   Steady state heat
65
66
67
  
      float *u     = (float *)malloc(N * M * sizeof(float));
      float *unew  = (float *)malloc(N * M * sizeof(float));
d16e53ac3   kmazouzi   add program argum...
68

1e6ef8e72   kmazouzi   Steady state heat
69
70
71
72
73
74
      if(u==0 || unew ==0)
      {
          perror("Can't allocated data
  ");
          return -1;
      }
d16e53ac3   kmazouzi   add program argum...
75
76
77
78
79
80
81
82
83
84
85
86
87
      printf ( "
  " );
      printf ( "HEATED_PLATE
  " );
      printf ( "  Parallel OpenMP version, using %d Threads
  ",omp_get_max_threads() );
      printf ( "  A program to solve for the steady state temperature distribution
  " );
      printf ( "  over a rectangular plate.
  " );
      printf ( "  Spatial grid of %d by %d points.
  
  ", M, N );
1e6ef8e72   kmazouzi   Steady state heat
88
89
90
91
92
  
  
      /* Initialize grid and create input file */
      printf("Initializing grid
  ");
d16e53ac3   kmazouzi   add program argum...
93

1e6ef8e72   kmazouzi   Steady state heat
94
95
96
      inidat(N, M,u,unew);
  
      prtdat(N, M,u, "initial.dat");
d16e53ac3   kmazouzi   add program argum...
97

1e6ef8e72   kmazouzi   Steady state heat
98
99
100
101
102
103
104
105
106
      printf("Start computing
  ");
  
      int iter=0;
  
      /* 
       *   iterate until the  new solution unew differs from the old solution u
       *     by no more than EPSILON.
       *     */
d16e53ac3   kmazouzi   add program argum...
107

1e6ef8e72   kmazouzi   Steady state heat
108
109
110
      while(diff> EPSILON) {
  
          update(N, M, u, unew,&diff);
d16e53ac3   kmazouzi   add program argum...
111

1e6ef8e72   kmazouzi   Steady state heat
112
          if(iter%ITER_PRINT==0)
d16e53ac3   kmazouzi   add program argum...
113
114
              printf("Iteration %d, diff = %f
   ", iter,diff);
1e6ef8e72   kmazouzi   Steady state heat
115
116
117
118
119
  
          iter++;
      }
  
      prtdat(N, M, u, "final.dat");
d16e53ac3   kmazouzi   add program argum...
120

1e6ef8e72   kmazouzi   Steady state heat
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
      free(u);
      free(unew);
  }
  
  
  
  /****************************************************************************
   *  subroutine update
   ****************************************************************************/
  void update(int nx,int ny, float *u, float *unew, float * diff)
  {
      int ix, iy;
      *diff=0.0;
  
  #pragma omp parallel for shared(nx,ny,u,unew) private (ix,iy)
      for (ix = 1; ix < nx-1; ix++) {
          for (iy = 1; iy < ny-1; iy++) {
              unew[ix*ny+iy] =  
                  (u[(ix+1)*ny+iy] +  u[(ix-1)*ny+iy] +
                   u[ix*ny+iy+1] +  u[ix*ny+iy-1] )/4.0;
d16e53ac3   kmazouzi   add program argum...
141

1e6ef8e72   kmazouzi   Steady state heat
142
143
          }
      }
d16e53ac3   kmazouzi   add program argum...
144
      //compute reduction 
1e6ef8e72   kmazouzi   Steady state heat
145

d16e53ac3   kmazouzi   add program argum...
146
      float mydiff;
1e6ef8e72   kmazouzi   Steady state heat
147
  #pragma omp parallel  shared(nx,ny,u,unew, diff) private (ix,iy,mydiff)
d16e53ac3   kmazouzi   add program argum...
148
149
      {
          mydiff=0.0;
1e6ef8e72   kmazouzi   Steady state heat
150
  #pragma omp for
d16e53ac3   kmazouzi   add program argum...
151
152
153
154
155
156
          for (ix = 1; ix < nx-1; ix++) {
              for (iy = 1; iy < ny-1; iy++) {
                  if (mydiff < fabs (unew[ix*ny+iy] - u[ix*ny+iy] ))
                  {
                      mydiff = fabs ( unew[ix*ny+iy] - u[ix*ny+iy] );
                  }
1e6ef8e72   kmazouzi   Steady state heat
157
158
              }
          }
1e6ef8e72   kmazouzi   Steady state heat
159
160
161
  
  
  # pragma omp critical
d16e53ac3   kmazouzi   add program argum...
162
163
164
165
166
          {
              if (*diff < mydiff )
              {
                  *diff = mydiff;
              }
1e6ef8e72   kmazouzi   Steady state heat
167
          }
1e6ef8e72   kmazouzi   Steady state heat
168

d16e53ac3   kmazouzi   add program argum...
169
170
171
172
173
174
175
  #pragma omp for
          for (ix = 1; ix < nx-1; ix++) {
              for (iy = 1; iy < ny-1; iy++) {
                  u[ix*ny+iy] = unew[ix*ny+iy]; 
              }
          }   
      }
1e6ef8e72   kmazouzi   Steady state heat
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  }
  
  /*****************************************************************************
   *  Initialize Data
   *****************************************************************************/
  void inidat(int nx, int ny, float *u, float *unew) 
  {
      int ix, iy;
  
      /*
       *Set boundary data and interrior values
       * */
      for (ix = 0; ix < nx; ix++) 
          for (iy = 0; iy < ny; iy++) { 
  
              if(ix==0)
              {
                  u[ix*ny+iy]=0.0; 
              }
              else          
d16e53ac3   kmazouzi   add program argum...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
                  if(iy==0 && ix!=0)
                  {
                      u[ix*ny+iy]=100.0;
                  }else
  
                      if(ix==nx-1)
                      {
                          u[ix*ny+iy]=100.0;
                      }else
  
                          if(iy==ny-1 && ix!=0)
                          {   
                              u[ix*ny+iy]=100.0;
                          }else
  
                              u[ix*ny+iy]=0.0;
1e6ef8e72   kmazouzi   Steady state heat
212
213
214
215
216
217
218
219
          }
  }
  
  /**************************************************************************
   * Print Data to files
   **************************************************************************/
  void prtdat(int nx, int ny, float *u,const char *fnam)
  {
d16e53ac3   kmazouzi   add program argum...
220

1e6ef8e72   kmazouzi   Steady state heat
221
222
223
224
      int ix, iy;
      FILE *fp;
  
      if(ITER_PRINT==0)return;
d16e53ac3   kmazouzi   add program argum...
225

1e6ef8e72   kmazouzi   Steady state heat
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
      fp = fopen(fnam, "w");
  
      for (ix = 0 ; ix < nx; ix++) {
          for (iy =0; iy < ny; iy++) {
  
              fprintf(fp, "%8.3f", u[ix*ny+iy]);
  
              if(iy!=ny-1)
              {
                  fprintf(fp, " ");
              }else
              {
                  fprintf(fp, "
  ");
              }
          }
      }
  
      fclose(fp);
  }