Commit 1e6ef8e72e286128c10aeb45273e3a2705c92230
1 parent
6a98a5afa7
Exists in
master
Steady state heat
Showing 2 changed files with 436 additions and 0 deletions Inline Diff
lab3/omp_heat2D.c
View file @
1e6ef8e
| File was created | 1 | /**************************************************************************** | ||
| 2 | * DESCRIPTION: | |||
| 3 | * Serial HEAT2D Example - C Version | |||
| 4 | * This example is based on a simplified | |||
| 5 | * two-dimensional heat equation domain decomposition. The initial | |||
| 6 | * temperature is computed to be high in the middle of the domain and | |||
| 7 | * zero at the boundaries. The boundaries are held at zero throughout | |||
| 8 | * the simulation. During the time-stepping, an array containing two | |||
| 9 | * domains is used; these domains alternate between old data and new data. | |||
| 10 | * | |||
| 11 | * The physical region, and the boundary conditions, are suggested | |||
| 12 | by this diagram; | |||
| 13 | ||||
| 14 | u = 0 | |||
| 15 | +------------------+ | |||
| 16 | | | | |||
| 17 | u = 100 | | u = 100 | |||
| 18 | | | | |||
| 19 | +------------------+ | |||
| 20 | u = 100 | |||
| 21 | ||||
| 22 | Interrior point : | |||
| 23 | u[Central] = (1/4) * ( u[North] + u[South] + u[East] + u[West] ) | |||
| 24 | ||||
| 25 | ****************************************************************************/ | |||
| 26 | #include <stdio.h> | |||
| 27 | #include <stdlib.h> | |||
| 28 | #include <math.h> | |||
| 29 | #include <omp.h> | |||
| 30 | ||||
| 31 | #define N 500 | |||
| 32 | #define M 500 | |||
| 33 | ||||
| 34 | #define ITER_PRINT 100 | |||
| 35 | #define PRINT_DATA 1 | |||
| 36 | ||||
| 37 | #define EPSILON 1e-1 | |||
| 38 | ||||
| 39 | ||||
| 40 | void update(int nx,int ny, float *u, float *unew, float * diff); | |||
| 41 | void inidat(int nx, int ny, float *u, float *unew); | |||
| 42 | void prtdat(int nx, int ny, float *u,const char *fnam); | |||
| 43 | ||||
| 44 | ||||
| 45 | ||||
| 46 | ||||
| 47 | int main(int argc, char *argv[]) | |||
| 48 | { | |||
| 49 | ||||
| 50 | float diff=1.0; | |||
| 51 | ||||
| 52 | float *u = (float *)malloc(N * M * sizeof(float)); | |||
| 53 | float *unew = (float *)malloc(N * M * sizeof(float)); | |||
| 54 | ||||
| 55 | if(u==0 || unew ==0) | |||
| 56 | { | |||
| 57 | perror("Can't allocated data\n"); | |||
| 58 | return -1; | |||
| 59 | } | |||
| 60 | ||||
| 61 | printf ( "\n" ); | |||
| 62 | printf ( "HEATED_PLATE\n" ); | |||
| 63 | printf ( " Parallel OpenMP version, using %d Threads\n",omp_get_max_threads() ); | |||
| 64 | printf ( " A program to solve for the steady state temperature distribution\n" ); | |||
| 65 | printf ( " over a rectangular plate.\n" ); | |||
| 66 | printf ( " Spatial grid of %d by %d points.\n\n", M, N ); | |||
| 67 | ||||
| 68 | ||||
| 69 | /* Initialize grid and create input file */ | |||
| 70 | printf("Initializing grid\n"); | |||
| 71 | ||||
| 72 | inidat(N, M,u,unew); | |||
| 73 | ||||
| 74 | prtdat(N, M,u, "initial.dat"); | |||
| 75 | ||||
| 76 | ||||
| 77 | printf("Start computing\n"); | |||
| 78 | ||||
| 79 | int iter=0; | |||
| 80 | ||||
| 81 | /* | |||
| 82 | * iterate until the new solution unew differs from the old solution u | |||
| 83 | * by no more than EPSILON. | |||
| 84 | * */ | |||
| 85 | ||||
| 86 | while(diff> EPSILON) { | |||
| 87 | ||||
| 88 | update(N, M, u, unew,&diff); | |||
| 89 | ||||
| 90 | if(iter%ITER_PRINT==0) | |||
| 91 | printf("Iteration %d, diff = %f\n ", iter,diff); | |||
| 92 | ||||
| 93 | iter++; | |||
| 94 | } | |||
| 95 | ||||
| 96 | prtdat(N, M, u, "final.dat"); | |||
| 97 | ||||
| 98 | free(u); | |||
| 99 | free(unew); | |||
| 100 | } | |||
| 101 | ||||
| 102 | ||||
| 103 | ||||
| 104 | /**************************************************************************** | |||
| 105 | * subroutine update | |||
| 106 | ****************************************************************************/ | |||
| 107 | void update(int nx,int ny, float *u, float *unew, float * diff) | |||
| 108 | { | |||
| 109 | int ix, iy; | |||
| 110 | *diff=0.0; | |||
| 111 | ||||
| 112 | #pragma omp parallel for shared(nx,ny,u,unew) private (ix,iy) | |||
| 113 | for (ix = 1; ix < nx-1; ix++) { | |||
| 114 | for (iy = 1; iy < ny-1; iy++) { | |||
| 115 | unew[ix*ny+iy] = | |||
| 116 | (u[(ix+1)*ny+iy] + u[(ix-1)*ny+iy] + | |||
| 117 | u[ix*ny+iy+1] + u[ix*ny+iy-1] )/4.0; | |||
| 118 | ||||
| 119 | } | |||
| 120 | } | |||
| 121 | ||||
| 122 | //compute reduction | |||
| 123 | ||||
| 124 | ||||
| 125 | float mydiff; | |||
| 126 | ||||
| 127 | #pragma omp parallel shared(nx,ny,u,unew, diff) private (ix,iy,mydiff) | |||
| 128 | { | |||
| 129 | mydiff=0.0; | |||
| 130 | #pragma omp for | |||
| 131 | for (ix = 1; ix < nx-1; ix++) { | |||
| 132 | for (iy = 1; iy < ny-1; iy++) { | |||
| 133 | if (mydiff < fabs (unew[ix*ny+iy] - u[ix*ny+iy] )) | |||
| 134 | { | |||
| 135 | mydiff = fabs ( unew[ix*ny+iy] - u[ix*ny+iy] ); | |||
| 136 | } | |||
| 137 | } | |||
| 138 | } | |||
| 139 | ||||
| 140 | ||||
| 141 | # pragma omp critical | |||
| 142 | { | |||
| 143 | if (*diff < mydiff ) | |||
| 144 | { | |||
| 145 | *diff = mydiff; | |||
| 146 | } | |||
| 147 | } | |||
| 148 | ||||
| 149 | ||||
| 150 | #pragma omp for | |||
| 151 | for (ix = 1; ix < nx-1; ix++) { | |||
| 152 | for (iy = 1; iy < ny-1; iy++) { | |||
| 153 | u[ix*ny+iy] = unew[ix*ny+iy]; | |||
| 154 | } | |||
| 155 | } | |||
| 156 | ||||
| 157 | ||||
| 158 | ||||
| 159 | ||||
| 160 | } | |||
| 161 | } | |||
| 162 | ||||
| 163 | /***************************************************************************** | |||
| 164 | * Initialize Data | |||
| 165 | *****************************************************************************/ | |||
| 166 | void inidat(int nx, int ny, float *u, float *unew) | |||
| 167 | { | |||
| 168 | int ix, iy; |
lab3/ser_heat2D.c
View file @
1e6ef8e
| File was created | 1 | /**************************************************************************** | ||
| 2 | * DESCRIPTION: | |||
| 3 | * Serial HEAT2D Example - C Version | |||
| 4 | * This example is based on a simplified | |||
| 5 | * two-dimensional heat equation domain decomposition. The initial | |||
| 6 | * temperature is computed to be high in the middle of the domain and | |||
| 7 | * zero at the boundaries. The boundaries are held at zero throughout | |||
| 8 | * the simulation. During the time-stepping, an array containing two | |||
| 9 | * domains is used; these domains alternate between old data and new data. | |||
| 10 | * | |||
| 11 | * The physical region, and the boundary conditions, are suggested | |||
| 12 | by this diagram; | |||
| 13 | ||||
| 14 | u = 0 | |||
| 15 | +------------------+ | |||
| 16 | | | | |||
| 17 | u = 100 | | u = 100 | |||
| 18 | | | | |||
| 19 | +------------------+ | |||
| 20 | u = 100 | |||
| 21 | ||||
| 22 | Interrior point : | |||
| 23 | u[Central] = (1/4) * ( u[North] + u[South] + u[East] + u[West] ) | |||
| 24 | ||||
| 25 | ****************************************************************************/ | |||
| 26 | #include <stdio.h> | |||
| 27 | #include <stdlib.h> | |||
| 28 | #include <math.h> | |||
| 29 | ||||
| 30 | #define N 200 | |||
| 31 | #define M 200 | |||
| 32 | ||||
| 33 | #define ITER_PRINT 100 | |||
| 34 | #define PRINT_DATA 1 | |||
| 35 | ||||
| 36 | #define EPSILON 1e-1 | |||
| 37 | ||||
| 38 | ||||
| 39 | void update(int nx,int ny, float *u, float *unew, float * diff); | |||
| 40 | void inidat(int nx, int ny, float *u, float *unew); | |||
| 41 | void prtdat(int nx, int ny, float *u,const char *fnam); | |||
| 42 | ||||
| 43 | ||||
| 44 | ||||
| 45 | ||||
| 46 | int main(int argc, char *argv[]) | |||
| 47 | { | |||
| 48 | ||||
| 49 | float diff=1.0; | |||
| 50 | ||||
| 51 | float *u = (float *)malloc(N * M * sizeof(float)); | |||
| 52 | float *unew = (float *)malloc(N * M * sizeof(float)); | |||
| 53 | ||||
| 54 | if(u==0 || unew ==0) | |||
| 55 | { | |||
| 56 | perror("Can't allocated data\n"); | |||
| 57 | return -1; | |||
| 58 | } | |||
| 59 | ||||
| 60 | printf ( "\n" ); | |||
| 61 | printf ( "HEATED_PLATE\n" ); | |||
| 62 | printf ( " Serial version\n" ); | |||
| 63 | printf ( " A program to solve for the steady state temperature distribution\n" ); | |||
| 64 | printf ( " over a rectangular plate.\n" ); | |||
| 65 | printf ( "\n" ); | |||
| 66 | printf ( " Spatial grid of %d by %d points.\n\n", M, N ); | |||
| 67 | ||||
| 68 | ||||
| 69 | /* Initialize grid and create input file */ | |||
| 70 | printf("Initializing grid\n"); | |||
| 71 | ||||
| 72 | inidat(N, M,u,unew); | |||
| 73 | ||||
| 74 | prtdat(N, M,u, "initial.dat"); | |||
| 75 | ||||
| 76 | ||||
| 77 | printf("Start computing\n"); | |||
| 78 | ||||
| 79 | int iter=0; | |||
| 80 | ||||
| 81 | /* | |||
| 82 | * iterate until the new solution unew differs from the old solution u | |||
| 83 | * by no more than EPSILON. | |||
| 84 | * */ | |||
| 85 | ||||
| 86 | while(diff> EPSILON) { | |||
| 87 | ||||
| 88 | update(N, M, u, unew,&diff); | |||
| 89 | ||||
| 90 | if(iter%ITER_PRINT==0) | |||
| 91 | printf("Iteration %d, diff = %f\n ", iter,diff); | |||
| 92 | ||||
| 93 | iter++; | |||
| 94 | } | |||
| 95 | ||||
| 96 | prtdat(N, M, u, "final.dat"); | |||
| 97 | ||||
| 98 | free(u); | |||
| 99 | free(unew); | |||
| 100 | } | |||
| 101 | ||||
| 102 | ||||
| 103 | ||||
| 104 | /**************************************************************************** | |||
| 105 | * subroutine update | |||
| 106 | ****************************************************************************/ | |||
| 107 | void update(int nx,int ny, float *u, float *unew, float * diff) | |||
| 108 | { | |||
| 109 | int ix, iy; | |||
| 110 | *diff=0.0; | |||
| 111 | ||||
| 112 | for (ix = 1; ix < nx-1; ix++) { | |||
| 113 | for (iy = 1; iy < ny-1; iy++) { | |||
| 114 | unew[ix*ny+iy] = | |||
| 115 | (u[(ix+1)*ny+iy] + u[(ix-1)*ny+iy] + | |||
| 116 | u[ix*ny+iy+1] + u[ix*ny+iy-1] )/4.0; | |||
| 117 | ||||
| 118 | if (*diff < fabs (unew[ix*ny+iy] - u[ix*ny+iy] )) | |||
| 119 | { | |||
| 120 | *diff = fabs ( unew[ix*ny+iy] - u[ix*ny+iy] ); | |||
| 121 | } | |||
| 122 | } | |||
| 123 | ||||
| 124 | } | |||
| 125 | ||||
| 126 | ||||
| 127 | for (ix = 1; ix < nx-1; ix++) { | |||
| 128 | for (iy = 1; iy < ny-1; iy++) { | |||
| 129 | u[ix*ny+iy] = unew[ix*ny+iy]; | |||
| 130 | } | |||
| 131 | } | |||
| 132 | ||||
| 133 | } | |||
| 134 | ||||
| 135 | /***************************************************************************** | |||
| 136 | * Initialize Data | |||
| 137 | *****************************************************************************/ | |||
| 138 | void inidat(int nx, int ny, float *u, float *unew) | |||
| 139 | { | |||
| 140 | int ix, iy; | |||
| 141 | ||||
| 142 | /* | |||
| 143 | *Set boundary data and interrior values | |||
| 144 | * */ | |||
| 145 | for (ix = 0; ix < nx; ix++) | |||
| 146 | for (iy = 0; iy < ny; iy++) { | |||
| 147 | ||||
| 148 | if(ix==0) |