UCFD_SPARSE  v1.0
Documentation
Loading...
Searching...
No Matches
mpi3d.c
Go to the documentation of this file.
1
21#include <math.h>
22#include <time.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <mpi.h>
26#include "pbutils.h"
27#include "readinput.h"
28#include "arrays.h"
29#include "lusgs.h"
30
31#define nvars 5
32#define ndims 3
33#define ncellface 6
34#define root 0
35
36double run(int rank, int *params);
37void write_output(int nprocs, int *params, double *times);
38
39int main(int argc, char **argv)
40{
41 int nprocs, rank;
42 int dm, dn, dl;
43 int err = 0;
44 int params[7];
45 double avtimei;
46
47 MPI_Init(&argc, &argv);
48 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
49 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
50
51 double *times = (double *)calloc(nprocs, sizeof(double));
52
53 if (rank == 0) {
54 if (argc < 2) {
55 printf("[Error] Input file argument is needed\n");
56 err = 1;
57 }
58 else {
59 FILE *inpfile = fopen(argv[1], "r");
60 if (inpfile == NULL) {
61 printf("[Error] Input file not found\n");
62 err = 1;
63 }
64 else {
65 input_params(inpfile, params);
66 dm = params[3];
67 dn = params[4];
68 dl = params[5];
69 fclose(inpfile);
70
71 if (nprocs != dm*dn*dl) {
72 printf("[Error] Partitioning number mismatch\n");
73 printf("%d processors, but total %d partitioning\n", nprocs, dm*dn*dl);
74 err = 1;
75 }
76 else {
77 printf("[Main] 3D hexahedral example starts...\n");
78 }
79 }
80 }
81 }
82
83 MPI_Bcast(&err, 1, MPI_INT, root, MPI_COMM_WORLD);
84 if (err == 1) return -1;
85
86 MPI_Bcast(&params, 7, MPI_INT, root, MPI_COMM_WORLD);
87
88 avtimei = run(rank, params);
89
90 MPI_Gather(&avtimei, 1, MPI_DOUBLE, times, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
91
92 if (rank == 0) {
93 printf("[Main] Run finished. Writing result...\n");
94 write_output(nprocs, params, times);
95 }
96
97 MPI_Finalize();
98 free(times);
99 return 0;
100}
101
102
103double run(int rank, int *params)
104{
105 const double gamma = 1.4;
106 const double rho = gamma;
107 const double u = 1.5;
108 const double v = 0.0;
109 const double w = 0.0;
110 const double p = 1.0;
111 const double et = p / (gamma - 1) + 0.5*rho*u*u;
112 const int bm = params[0]/params[3];
113 const int bn = params[1]/params[4];
114 const int bl = params[2]/params[5];
115 const int neles = bm*bn*bl;
116 const int nstep = params[6];
117 double start;
118 double avtime = 0.0;
119
120 if (rank == 0) printf("[Run] Allocating arrays...\n");
121 double **upts = (double **) malloc_2d(nvars, neles, sizeof(double));
122 double **rhs = (double **) malloc_2d(nvars, neles, sizeof(double));
123 double **dub = (double **) malloc_2d(nvars, neles, sizeof(double));
124 double *diag = (double *) calloc(neles, sizeof(double));
125 double **fspr = (double **) malloc_2d(ncellface, neles, sizeof(double));
126 double *dt = (double *) calloc(neles, sizeof(double));
127 double **fnorm_vol = (double **) malloc_2d(ncellface, neles, sizeof(double));
128 double ***vec_fnorm = (double ***) malloc_3d(ncellface, ndims, neles, sizeof(double));
129 int **nei_ele = (int **) malloc_2d(ncellface, neles, sizeof(int));
130 int *mapping = (int *)calloc(neles, sizeof(int));
131 int *unmapping = (int *)calloc(neles, sizeof(int));
132 double *tarr = (double *)malloc(sizeof(double)*nstep);
133
134 /* Pointer of each array */
135 double *uptsp = &upts[0][0];
136 double *rhsp = &rhs[0][0];
137 double *dubp = &dub[0][0];
138 double *fsprp = &fspr[0][0];
139 double *fnp = &fnorm_vol[0][0];
140 double *vfp = &vec_fnorm[0][0][0];
141 int *nep = &nei_ele[0][0];
142
143 /* Initialize */
144 if (rank == 0) printf("[Run] Initializing arrays...\n");
145 for (int i=0; i < neles; i++) {
146 upts[0][i] = rho;
147 upts[1][i] = rho*u;
148 upts[2][i] = rho*v;
149 upts[3][i] = rho*w;
150 upts[4][i] = et;
151
152 rhs[0][i] = rho;
153 rhs[1][i] = rho*u;
154 rhs[2][i] = rho*v;
155 rhs[3][i] = rho*w;
156 rhs[4][i] = et;
157
158 dub[0][i] = rho;
159 dub[1][i] = rho*u;
160 dub[2][i] = rho*v;
161 dub[3][i] = rho*w;
162 dub[4][i] = et;
163
164 dt[i] = 0.1;
165
166 for (int j=0; j<ncellface; j++) {
167 fnorm_vol[j][i] = 1.0;
168 fspr[j][i] = 1.0;
169 for (int k=0; k<ndims; k++) {
170 vec_fnorm[j][k][i] = 0.0;
171 }
172 }
173
174 vec_fnorm[0][1][i] = -1.0;
175 vec_fnorm[1][0][i] = -1.0;
176 vec_fnorm[2][2][i] = 1.0;
177 vec_fnorm[3][0][i] = 1.0;
178 vec_fnorm[4][2][i] = -1.0;
179 vec_fnorm[5][1][i] = 1.0;
180 }
181
182 if (rank == 0) printf("[Run] Constructing nei_ele array...\n");
183 make_nei_ele(bm, bn, bl, nei_ele);
184
185 if (rank == 0) printf("[Run] Processing Reverse Cuthill-McKee...\n");
186 make_reordering(neles, ncellface, nei_ele, mapping, unmapping);
187
188 if (rank == 0) printf("[Run] Starting iteration...\n");
189 MPI_Barrier(MPI_COMM_WORLD);
190 for (int i=0; i<nstep; i++) {
191 start = MPI_Wtime();
192 serial_pre_lusgs(neles, ncellface, 1.0, fnp, dt, diag, fsprp);
194 nep, mapping, unmapping, fnp, vfp, \
195 uptsp, rhsp, dubp, diag, fsprp);
197 nep, mapping, unmapping, fnp, vfp, \
198 uptsp, rhsp, dubp, diag, fsprp);
199 serial_update(neles, nvars, uptsp, rhsp);
200 MPI_Barrier(MPI_COMM_WORLD);
201 tarr[i] = (double) MPI_Wtime() - start;
202 }
203
204 for (int i=0; i<nstep; i++)
205 avtime += tarr[i];
206 avtime = avtime*1000/nstep;
207
208 //deallocate array
209 dealloc_2d((void **) upts);
210 dealloc_2d((void **) rhs);
211 dealloc_2d((void **) dub);
212 dealloc_2d((void **) fspr);
213 dealloc_2d((void **) fnorm_vol);
214 dealloc_3d((void ***) vec_fnorm);
215 dealloc_2d((void **) nei_ele);
216 free(mapping);
217 free(unmapping);
218 free(diag);
219 free(dt);
220 free(tarr);
221
222 return avtime;
223}
224
228void write_output(int nprocs, int *params, double *times)
229{
230 int m = params[0];
231 int n = params[1];
232 int l = params[2];
233 int dm = params[3];
234 int dn = params[4];
235 int dl = params[5];
236 int nstep = params[6];
237 int neles = m*n*l;
238 double avtime = 0.0;
239 char filename[100];
240
241 // Make filename
242 sprintf(filename, "MPIOUTPUT_c_%d_%d.txt", nprocs, neles);
243 FILE *outfile = fopen(filename, "w");
244 fprintf(outfile, "========= LU-SGS example output =========\n\n");
245 fprintf(outfile, "*** Problem setup ***\n");
246 fprintf(outfile, "Number of cores: %d\n", nprocs);
247 fprintf(outfile, "Number of iteration step: %d\n", nstep);
248 fprintf(outfile, "Number of elements: %d = %d x %d x %d\n", neles, m, n, l);
249 fprintf(outfile, "Partitioning with %d: %d x %d x %d\n", dm*dn*dl, dm, dn, dl);
250 fprintf(outfile, "Elements per core: %d = %d x %d x %d\n\n", neles/nprocs, m/dm, n/dn, l/dl);
251 fprintf(outfile, "*** Average runtime for each processor [ms] ***\n");
252 for (int i=0; i<nprocs; i++) {
253 avtime += times[i];
254 fprintf(outfile, "%lf\n", times[i]);
255 }
256 fprintf(outfile, "\n*** Average runtime for entire processors [ms] ***\n");
257 fprintf(outfile, "%lf\n", avtime/nprocs);
258
259 fclose(outfile);
260}
261
void dealloc_2d(void **mat)
Deallocate 2D array.
Definition: arrays.c:93
void ** malloc_2d(const size_t rows, const size_t cols, const size_t T)
Allocate 2D array.
Definition: arrays.c:33
void *** malloc_3d(const size_t rows, const size_t cols, const size_t depth, const size_t T)
Allocate 3D array.
Definition: arrays.c:52
void dealloc_3d(void ***mat)
Deallocate 3D array.
Definition: arrays.c:104
void serial_update(int neles, int nvars, double *uptsb, double *dub, double *subres)
Updates solution array.
Definition: blusgs.c:396
#define gamma
Definition: flux.c:24
void ns_serial_upper_sweep(int neles, int nfvars, int nface, int ndims, int *nei_ele, int *mapping, int *unmapping, double *fnorm_vol, double *vec_fnorm, double *uptsb, double *rhsb, double *dub, double *diag, double *fspr)
Upper sweep of LU-SGS method for Navier-Stokes equations.
Definition: lusgs.c:207
void ns_serial_lower_sweep(int neles, int nfvars, int nface, int ndims, int *nei_ele, int *mapping, int *unmapping, double *fnorm_vol, double *vec_fnorm, double *uptsb, double *rhsb, double *dub, double *diag, double *fspr)
Lower sweep of LU-SGS method for Navier-Stokes equations.
Definition: lusgs.c:75
void serial_pre_lusgs(int neles, int nface, double factor, double *fnorm_vol, double *dt, double *diag, double *fspr)
Computes Diagonal matrix for LU-SGS method.
Definition: lusgs.c:44
Header file for serial LU-SGS method.
void write_output(int nprocs, int *params, double *times)
Write output file as txt format.
Definition: mpi3d.c:228
#define ncellface
Definition: mpi3d.c:33
int main(int argc, char **argv)
Definition: mpi3d.c:39
#define ndims
Definition: mpi3d.c:32
#define nvars
Definition: mpi3d.c:31
#define root
Definition: mpi3d.c:34
double run(int rank, int *params)
Definition: mpi3d.c:103
void make_reordering(const int nele, const int nface, int **nei_ele, int *mapping, int *unmapping)
Reverse Cuthill-McKee algorithm using neighbor elements.
Definition: pbutils.c:99
void make_nei_ele(const int m, const int n, const int l, int **nei_ele)
Computes neighbor cell elements array.
Definition: pbutils.c:36
void input_params(FILE *fp, int *vars)
Definition: readinput.c:27