HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
BCIO.c
Go to the documentation of this file.
1 
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <basic.h>
9 #include <arrayfunctions.h>
10 #include <boundaryconditions.h>
11 #include <mpivars.h>
12 
19 int BCReadTurbulentInflowData(void *b,void *m,int ndims,int nvars,int *DomainSize)
20 {
21  DomainBoundary *boundary = (DomainBoundary*) b;
22  MPIVariables *mpi = (MPIVariables*) m;
23 
24  char *filename = boundary->UnsteadyDirichletFilename;
25  int *inflow_size = NULL;
26  double *inflow_data = NULL;
27  double *buffer = NULL;
28 
29  int dim = boundary->dim;
30  int face= boundary->face;
31  int d;
32 
33  if (!mpi->rank) {
34 
35  printf("Reading turbulent inflow boundary data from %s.\n",filename);
36 
37  FILE *in;
38  int ferr;
39 
40  /* calculate the number of processors that sit on unsteady boundary */
41  int nproc = 1;
42  for (d=0; d<ndims; d++) nproc *= mpi->iproc[d]; nproc /= mpi->iproc[dim];
43 
44  in = fopen(filename,"rb");
45  if (!in) {
46  fprintf(stderr,"Error in BCReadTurbulentInflowData(): cannot open unsteady boundary data file %s.\n",filename);
47  return(1);
48  }
49  int count = 0;
50  while ((!feof(in)) && (count < nproc)) {
51  int rank[ndims], size[ndims];
52  ferr = fread(rank,sizeof(int),ndims,in);
53  if (ferr != ndims) {
54  fprintf(stderr,"Error in BCReadTurbulentInflowData(): Error (1) in file reading, count %d.\n",count);
55  return(1);
56  }
57  if (rank[dim] != (face > 0 ? 0 : mpi->iproc[dim]-1) ) {
58  fprintf(stderr,"Error in BCReadTurbulentInflowData(): Error (2) in file reading, count %d.\n",count);
59  return(1);
60  }
61  ferr = fread(size,sizeof(int),ndims,in);
62  if (ferr != ndims) {
63  fprintf(stderr,"Error in BCReadTurbulentInflowData(): Error (3) in file reading, count %d.\n",count);
64  return(1);
65  }
66  int flag = 1;
67  for (d=0; d<ndims; d++) if ((d != dim) && (size[d] != DomainSize[d])) flag = 0;
68  if (!flag) {
69  fprintf(stderr,"Error in BCReadTurbulentInflowData(): Error (4) (dimension mismatch) in file reading, count %d.\n",count);
70  return(1);
71  }
72 
73  int data_size = nvars;
74  for (d=0; d<ndims; d++) data_size *= size[d];
75  buffer = (double*) calloc (data_size,sizeof(double));
76  ferr = fread(buffer,sizeof(double),data_size,in);
77  if (ferr != data_size) {
78  fprintf(stderr,"Error in BCReadTurbulentInflowData(): Error (6) in file reading, count %d.\n",count);
79  return(1);
80  }
81 
82  int rank1D = MPIRank1D(ndims,mpi->iproc,rank);
83 
84  if (!rank1D) {
85 
86  int index[ndims];
87  inflow_size = (int*) calloc (ndims, sizeof(int));
88  _ArrayCopy1D_(size,inflow_size,ndims);
89  inflow_data = (double*) calloc (data_size, sizeof(double));
90  ArrayCopynD(ndims,buffer,inflow_data,size,0,0,index,nvars);
91 
92  } else {
93 #ifndef serial
94  MPI_Request req[2] = {MPI_REQUEST_NULL,MPI_REQUEST_NULL};
95  MPI_Isend(size,ndims,MPI_INT,rank1D,2152,mpi->world,&req[0]);
96  MPI_Isend(buffer,data_size,MPI_DOUBLE,rank1D,2153,mpi->world,&req[1]);
97  MPI_Status status_arr[3];
98  MPI_Waitall(2,&req[0],status_arr);
99 #else
100  fprintf(stderr,"Error in BCReadTurbulentInflowData(): This is a serial run. Invalid (non-zero) rank read.\n");
101 #endif
102  }
103 
104  free(buffer);
105  count++;
106  }
107 
108  if (count < nproc) {
109  fprintf(stderr,"Error in BCReadTurbulentInflowData(): missing data in unsteady boundary data file %s.\n",filename);
110  fprintf(stderr,"Error in BCReadTurbulentInflowData(): should contain data for %d processors, ", nproc);
111  fprintf(stderr,"Error in BCReadTurbulentInflowData(): but contains data for %d processors!\n", count);
112  return(1);
113  }
114 
115  fclose(in);
116 
117  } else {
118 #ifndef serial
119  if (mpi->ip[dim] == (face > 0 ? 0 : mpi->iproc[dim]-1) ) {
120  MPI_Request req = MPI_REQUEST_NULL;
121  inflow_size = (int*) calloc (ndims,sizeof(int));
122  MPI_Irecv(inflow_size,ndims,MPI_INT,0,2152,mpi->world,&req);
123  MPI_Wait(&req,MPI_STATUS_IGNORE);
124  int data_size = nvars;
125  for (d=0; d<ndims; d++) data_size *= inflow_size[d];
126  inflow_data = (double*) calloc (data_size,sizeof(double));
127  MPI_Irecv(inflow_data,data_size,MPI_DOUBLE,0,2153,mpi->world,&req);
128  MPI_Wait(&req,MPI_STATUS_IGNORE);
129  }
130 #else
131  fprintf(stderr,"Error in BCReadTurbulentInflowData(): Serial code should not be here!.\n");
132 #endif
133  }
134 
135  boundary->UnsteadyDirichletSize = inflow_size;
136  boundary->UnsteadyDirichletData = inflow_data;
137 
138  return(0);
139 }
140 
147 int BCReadTemperatureData(void *b,void *m,int ndims,int nvars,int *DomainSize)
148 {
149  DomainBoundary *boundary = (DomainBoundary*) b;
150  MPIVariables *mpi = (MPIVariables*) m;
151 
152  char *filename = boundary->UnsteadyTemperatureFilename;
153  int *temperature_field_size = NULL;
154  double *time_level_data = NULL;
155  double *temperature_field_data = NULL;
156  double *time_buffer = NULL;
157  double *data_buffer = NULL;
158 
159  int dim = boundary->dim;
160  int face= boundary->face;
161  int d;
162 
163  if (!mpi->rank) {
164 
165  printf("Reading boundary temperature data from %s.\n",filename);
166 
167  FILE *in;
168  int ferr;
169 
170  /* calculate the number of processors that sit on this temperature boundary */
171  int nproc = 1;
172  for (d=0; d<ndims; d++) nproc *= mpi->iproc[d]; nproc /= mpi->iproc[dim];
173 
174  in = fopen(filename,"rb");
175  if (!in) {
176  fprintf(stderr,"Error in BCReadTemperatureData(): cannot open boundary temperature data file %s.\n",filename);
177  return(1);
178  }
179 
180  int count = 0;
181  while ((!feof(in)) && (count < nproc)) {
182 
183  int rank[ndims], size[ndims];
184  ferr = fread(rank,sizeof(int),ndims,in);
185  if (ferr != ndims) {
186  fprintf(stderr,"Error in BCReadTemperatureData(): Error (1) in file reading, count %d.\n",count);
187  return(1);
188  }
189  if (rank[dim] != (face > 0 ? 0 : mpi->iproc[dim]-1) ) {
190  fprintf(stderr,"Error in BCReadTemperatureData(): Error (2) in file reading, count %d.\n",count);
191  return(1);
192  }
193  ferr = fread(size,sizeof(int),ndims,in);
194  if (ferr != ndims) {
195  fprintf(stderr,"Error in BCReadTemperatureData(): Error (3) in file reading, count %d.\n",count);
196  return(1);
197  }
198 
199  int n_data = size[dim]; /* number of time levels for which temperature data is provided */
200  time_buffer = (double*) calloc (n_data,sizeof(double));
201  ferr = fread(time_buffer,sizeof(double),n_data,in);
202  if (ferr != n_data) {
203  fprintf(stderr,"Error in BCReadTemperatureData(): Error (5) in file reading, count %d.\n",count);
204  return(1);
205  }
206 
207  int data_size = 1;
208  for (d=0; d<ndims; d++) data_size *= size[d];
209  data_buffer = (double*) calloc (data_size,sizeof(double));
210  ferr = fread(data_buffer,sizeof(double),data_size,in);
211  if (ferr != data_size) {
212  fprintf(stderr,"Error in BCReadTemperatureData(): Error (6) in file reading, count %d.\n",count);
213  return(1);
214  }
215 
216  int rank1D = MPIRank1D(ndims,mpi->iproc,rank);
217 
218  if (!rank1D) {
219 
220  int index[ndims];
221 
222  temperature_field_size = (int*) calloc (ndims, sizeof(int));
223  _ArrayCopy1D_(size,temperature_field_size,ndims);
224 
225  time_level_data = (double*) calloc (size[dim], sizeof(double));
226  _ArrayCopy1D_(time_buffer,time_level_data,size[dim]);
227 
228  temperature_field_data = (double*) calloc (data_size, sizeof(double));
229  ArrayCopynD(ndims,data_buffer,temperature_field_data,size,0,0,index,1);
230 
231  } else {
232 
233 #ifndef serial
234  MPI_Request req[3] = {MPI_REQUEST_NULL,MPI_REQUEST_NULL,MPI_REQUEST_NULL};
235  MPI_Isend(size,ndims,MPI_INT,rank1D,2152,mpi->world,&req[0]);
236  MPI_Isend(time_buffer,size[dim],MPI_DOUBLE,rank1D,2154,mpi->world,&req[2]);
237  MPI_Isend(data_buffer,data_size,MPI_DOUBLE,rank1D,2153,mpi->world,&req[1]);
238  MPI_Status status_arr[3];
239  MPI_Waitall(3,&req[0],status_arr);
240 #else
241  fprintf(stderr,"Error in BCReadTemperatureData(): This is a serial run. Invalid (non-zero) rank read.\n");
242 #endif
243 
244  }
245 
246  free(time_buffer);
247  free(data_buffer);
248  count++;
249  }
250 
251  if (count < nproc) {
252  fprintf(stderr,"Error in BCReadTemperatureData(): missing data in unsteady boundary data file %s.\n",filename);
253  fprintf(stderr,"Error in BCReadTemperatureData(): should contain data for %d processors, ", nproc);
254  fprintf(stderr,"Error in BCReadTemperatureData(): but contains data for %d processors!\n", count);
255  return(1);
256  }
257 
258  fclose(in);
259 
260  } else {
261 
262 #ifndef serial
263  if (mpi->ip[dim] == (face > 0 ? 0 : mpi->iproc[dim]-1) ) {
264 
265  MPI_Request req = MPI_REQUEST_NULL;
266 
267  temperature_field_size = (int*) calloc (ndims,sizeof(int));
268  MPI_Irecv(temperature_field_size,ndims,MPI_INT,0,2152,mpi->world,&req);
269  MPI_Wait(&req,MPI_STATUS_IGNORE);
270 
271  int flag = 1;
272  for (d=0; d<ndims; d++) if ((d != dim) && (temperature_field_size[d] != DomainSize[d])) flag = 0;
273  if (!flag) {
274  fprintf(stderr,"Error in BCReadTemperatureData(): Error (4) (dimension mismatch) in file reading, rank %d.\n",mpi->rank);
275  return(1);
276  }
277 
278  time_level_data = (double*) calloc (temperature_field_size[dim],sizeof(double));
279  MPI_Irecv(time_level_data, temperature_field_size[dim], MPI_DOUBLE,0,2154,mpi->world,&req);
280  MPI_Wait(&req,MPI_STATUS_IGNORE);
281 
282  int data_size = 1;
283  for (d=0; d<ndims; d++) data_size *= temperature_field_size[d];
284  temperature_field_data = (double*) calloc (data_size,sizeof(double));
285  MPI_Irecv(temperature_field_data,data_size,MPI_DOUBLE,0,2153,mpi->world,&req);
286  MPI_Wait(&req,MPI_STATUS_IGNORE);
287 
288  }
289 #else
290  fprintf(stderr,"Error in BCReadTemperatureData(): Serial code should not be here!.\n");
291 #endif
292 
293  }
294 
295  boundary->UnsteadyTemperatureSize = temperature_field_size;
296  boundary->UnsteadyTimeLevels = time_level_data;
297  boundary->UnsteadyTemperatureData = temperature_field_data;
298 
299  return(0);
300 }
Containts the structures and definitions for boundary condition implementation.
MPI related function definitions.
char UnsteadyTemperatureFilename[_MAX_STRING_SIZE_]
int BCReadTemperatureData(void *b, void *m, int ndims, int nvars, int *DomainSize)
Definition: BCIO.c:147
Some basic definitions and macros.
Structure containing the variables and function pointers defining a boundary.
int MPIRank1D(int, int *, int *)
Definition: MPIRank1D.c:26
double * UnsteadyDirichletData
int BCReadTurbulentInflowData(void *b, void *m, int ndims, int nvars, int *DomainSize)
Definition: BCIO.c:19
double * UnsteadyTimeLevels
char UnsteadyDirichletFilename[_MAX_STRING_SIZE_]
MPI_Comm world
INLINE int ArrayCopynD(int, const double *, double *, int *, int, int, int *, int)
Structure of MPI-related variables.
double * UnsteadyTemperatureData
#define _ArrayCopy1D_(x, y, size)
Contains macros and function definitions for common array operations.