Blame view

lab3/omp_heat2D.c 5.82 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

3604dfae0   kmazouzi   MPI version
37
  float update(int nx,int ny, float *u, float *unew);
1e6ef8e72   kmazouzi   Steady state heat
38
39
40
41
42
43
44
45
46
47
  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...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
      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
64
65
66
  
      float *u     = (float *)malloc(N * M * sizeof(float));
      float *unew  = (float *)malloc(N * M * sizeof(float));
d16e53ac3   kmazouzi   add program argum...
67

1e6ef8e72   kmazouzi   Steady state heat
68
69
70
71
72
73
      if(u==0 || unew ==0)
      {
          perror("Can't allocated data
  ");
          return -1;
      }
d16e53ac3   kmazouzi   add program argum...
74
75
76
77
78
79
80
81
82
83
84
85
86
      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
87
88
89
90
91
  
  
      /* Initialize grid and create input file */
      printf("Initializing grid
  ");
d16e53ac3   kmazouzi   add program argum...
92

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

1e6ef8e72   kmazouzi   Steady state heat
97
98
99
100
101
102
103
104
105
      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...
106

1e6ef8e72   kmazouzi   Steady state heat
107
      while(diff> EPSILON) {
3604dfae0   kmazouzi   MPI version
108
         diff = update(N, M, u, unew);
d16e53ac3   kmazouzi   add program argum...
109

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

1e6ef8e72   kmazouzi   Steady state heat
119
120
121
122
123
124
125
126
127
      free(u);
      free(unew);
  }
  
  
  
  /****************************************************************************
   *  subroutine update
   ****************************************************************************/
3604dfae0   kmazouzi   MPI version
128
  float update(int nx,int ny, float *u, float *unew)
1e6ef8e72   kmazouzi   Steady state heat
129
130
  {
      int ix, iy;
3604dfae0   kmazouzi   MPI version
131
      float diff=0.0;
1e6ef8e72   kmazouzi   Steady state heat
132
133
134
135
136
137
138
  
  #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...
139

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

d16e53ac3   kmazouzi   add program argum...
144
      float mydiff;
3604dfae0   kmazouzi   MPI version
145
146
147
  /**
   * IMPLEMENT OMP REDUCE MAX
   */
1e6ef8e72   kmazouzi   Steady state heat
148
  #pragma omp parallel  shared(nx,ny,u,unew, diff) private (ix,iy,mydiff)
d16e53ac3   kmazouzi   add program argum...
149
150
      {
          mydiff=0.0;
1e6ef8e72   kmazouzi   Steady state heat
151
  #pragma omp for
d16e53ac3   kmazouzi   add program argum...
152
153
154
155
156
157
          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
158
159
              }
          }
1e6ef8e72   kmazouzi   Steady state heat
160

3604dfae0   kmazouzi   MPI version
161
  #pragma omp critical
d16e53ac3   kmazouzi   add program argum...
162
          {
3604dfae0   kmazouzi   MPI version
163
              if (diff < mydiff )
d16e53ac3   kmazouzi   add program argum...
164
              {
3604dfae0   kmazouzi   MPI version
165
                  diff = mydiff;
d16e53ac3   kmazouzi   add program argum...
166
              }
1e6ef8e72   kmazouzi   Steady state heat
167
          }
1e6ef8e72   kmazouzi   Steady state heat
168

3604dfae0   kmazouzi   MPI version
169
170
171
  /*
   * COPY OLD DATA
   */
d16e53ac3   kmazouzi   add program argum...
172
173
174
175
176
177
178
  #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]; 
              }
          }   
      }
3604dfae0   kmazouzi   MPI version
179
180
  
      return diff;
1e6ef8e72   kmazouzi   Steady state heat
181
182
183
184
185
  }
  
  /*****************************************************************************
   *  Initialize Data
   *****************************************************************************/
3604dfae0   kmazouzi   MPI version
186

1e6ef8e72   kmazouzi   Steady state heat
187
188
189
190
191
192
193
  void inidat(int nx, int ny, float *u, float *unew) 
  {
      int ix, iy;
  
      /*
       *Set boundary data and interrior values
       * */
1e6ef8e72   kmazouzi   Steady state heat
194

3604dfae0   kmazouzi   MPI version
195
196
197
198
199
200
201
202
203
204
205
206
207
  #pragma omp parallel private (ix,iy)
      {
      // interior points
      #pragma omp for    
      for (ix = 1; ix < nx-1; ix++) 
          for (iy = 1; iy < ny-1; iy++) { 
              u[ix*ny+iy]=5.0; 
          }
  
     //boundary left
      #pragma omp for    
      for (ix = 1; ix < nx-1; ix++){ 
          u[ix*ny]=100.0; 
d16e53ac3   kmazouzi   add program argum...
208

3604dfae0   kmazouzi   MPI version
209
      }
d16e53ac3   kmazouzi   add program argum...
210

3604dfae0   kmazouzi   MPI version
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
      //boundary right
      #pragma omp for    
      for (ix = 1; ix < nx-1; ix++){ 
          u[ix*ny+ (ny-1)]=100.0; 
  
      }
  
      //boundary down
      #pragma omp for    
      for (iy = 0; iy < ny; iy++){ 
          u[(nx-1)*(ny)+iy]=100.0; 
  
      }
  
      //boundary top
      #pragma omp for 
      for (iy = 0; iy < ny; iy++){ 
          u[iy]=0.0; 
  
      }
     
      }
d16e53ac3   kmazouzi   add program argum...
233

1e6ef8e72   kmazouzi   Steady state heat
234
  }
3604dfae0   kmazouzi   MPI version
235

1e6ef8e72   kmazouzi   Steady state heat
236
237
238
239
240
  /**************************************************************************
   * Print Data to files
   **************************************************************************/
  void prtdat(int nx, int ny, float *u,const char *fnam)
  {
d16e53ac3   kmazouzi   add program argum...
241

1e6ef8e72   kmazouzi   Steady state heat
242
243
244
245
      int ix, iy;
      FILE *fp;
  
      if(ITER_PRINT==0)return;
d16e53ac3   kmazouzi   add program argum...
246

1e6ef8e72   kmazouzi   Steady state heat
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
      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);
  }