HydroCODE_2D 0.1
This is a implementation of fully explict forward Euler scheme for 2-D Euler equations of motion on Eulerian coordinate
hydrocode.c
浏览该文件的文档.
1
90#include <errno.h>
91#include <stdio.h>
92#include <stdlib.h>
93#include <string.h>
94#include <math.h>
95
96#include "../include/var_struc.h"
97#include "../include/file_io.h"
98#include "../include/finite_volume.h"
99
104#ifdef DOXYGEN_PREDEFINED
105#define NODATPLOT
106#endif
111#ifdef DOXYGEN_PREDEFINED
112#define NOTECPLOT
113#endif
114
115double config[N_CONF];
116
120#define CV_INIT_MEM(v, N) \
121 do { \
122 for(k = 0; k < N; ++k) \
123 { \
124 CV[k].v = (double **)malloc(n_x * sizeof(double *)); \
125 if(CV[k].v == NULL) \
126 { \
127 printf("NOT enough memory! CV[%d].%s\n", k, #v); \
128 retval = 5; \
129 goto return_NULL; \
130 } \
131 for(j = 0; j < n_x; ++j) \
132 { \
133 CV[k].v[j] = (double *)malloc(n_y * sizeof(double)); \
134 if(CV[k].v[j] == NULL) \
135 { \
136 printf("NOT enough memory! CV[%d].%s[%d]\n", k, #v, j); \
137 retval = 5; \
138 goto return_NULL; \
139 } \
140 } \
141 } \
142 } while (0)
143
157int main(int argc, char *argv[])
158{
159 printf("\n");
160 int k, i, j, retval = 0;
161 for (k = 0; k < argc; k++)
162 printf("%s ", argv[k]);
163 printf("\n");
164 printf("TEST:\n %s\n", argv[1]);
165 if(argc < 5)
166 {
167 printf("Test Beginning: ARGuments Counter %d is less than 5.\n", argc);
168 return 4;
169 }
170 else
171 printf("Test Beginning: ARGuments Counter = %d.\n", argc);
172
173 // Initialize configuration data array
174 for(k = 1; k < N_CONF; k++)
175 config[k] = INFINITY;
176
177 // Set dimension.
178 int dim;
179 dim = atoi(argv[3]);
180 if (dim != 2)
181 {
182 printf("No appropriate dimension was entered!\n");
183 return 4;
184 }
185 config[0] = (double)dim;
186
187 printf("Configurating:\n");
188 char * endptr;
189 double conf_tmp;
190 for (k = 6; k < argc; k++)
191 {
192 errno = 0;
193 j = strtoul(argv[k], &endptr, 10);
194 if (errno != ERANGE && *endptr == '=')
195 {
196 endptr++;
197 errno = 0;
198 conf_tmp = strtod(endptr, &endptr);
199 if (errno != ERANGE && *endptr == '\0')
200 {
201 config[j] = conf_tmp;
202 printf("%3d-th configuration: %g (ARGument)\n", j, conf_tmp);
203 }
204 else
205 {
206 printf("Configuration error in ARGument variable %d! ERROR after '='!\n", k);
207 return 4;
208 }
209 }
210 else
211 {
212 printf("Configuration error in ARGument variable %d! ERROR before '='!\n", k);
213 return 4;
214 }
215 }
216
217 // Set order and scheme.
218 int order; // 1, 2
219 char * scheme; // Riemann_exact(Godunov), GRP
220 printf("Order[_Scheme]: %s\n",argv[4]);
221 errno = 0;
222 order = strtoul(argv[4], &scheme, 10);
223 if (*scheme == '_')
224 scheme++;
225 else if (*scheme != '\0' || errno == ERANGE)
226 {
227 printf("No order or Wrog scheme!\n");
228 return 4;
229 }
230 config[9] = (double)order;
231
232 /*
233 * We read the initial data files.
234 * The function initialize return a point pointing to the position
235 * of a block of memory consisting (m+1) variables of type double.
236 * The value of first array element of these variables is m.
237 * The following m variables are the initial value.
238 */
239 struct flu_var FV0 = _2D_initialize(argv[1]); // Structure of initial data array pointer.
240 /*
241 * m is the number of initial value as well as the number of grids.
242 * As m is frequently use to represent the number of grids,
243 * we do not use the name such as num_grid here to correspond to
244 * notation in the math theory.
245 */
246 const int n_x = (int)FV0.RHO[1], n_y = (int)FV0.RHO[0];
247 const double h_x = config[10], h_y = config[11], gamma = config[6];
248 // The number of times steps of the fluid data stored for plotting.
249 int N = 2; // (int)(config[5]) + 1;
250 double time_plot[2];
251
252 // Structure of fluid variables in computational cells array pointer.
253 struct cell_var_stru * CV = malloc(N * sizeof(struct cell_var_stru));
254 double ** X, ** Y;
255 double * cpu_time = malloc(N * sizeof(double));
256 X = (double **)malloc((n_x+1) * sizeof(double *));
257 Y = (double **)malloc((n_x+1) * sizeof(double *));
258 if(cpu_time == NULL)
259 {
260 printf("NOT enough memory! CPU_time\n");
261 retval = 5;
262 goto return_NULL;
263 }
264
265 if(X == NULL || Y == NULL)
266 {
267 printf("NOT enough memory! X or Y\n");
268 retval = 5;
269 goto return_NULL;
270 }
271 for(j = 0; j <= n_x; ++j)
272 {
273 X[j] = (double *)malloc((n_y+1) * sizeof(double));
274 Y[j] = (double *)malloc((n_y+1) * sizeof(double));
275 if(X[j] == NULL || Y[j] == NULL)
276 {
277 printf("NOT enough memory! X[%d] or Y[%d]\n", j, j);
278 retval = 5;
279 goto return_NULL;
280 }
281 }
282 if(CV == NULL)
283 {
284 printf("NOT enough memory! Cell Variables\n");
285 retval = 5;
286 goto return_NULL;
287 }
288 // Initialize arrays of fluid variables in cells.
289 CV_INIT_MEM(RHO, N);
290 CV_INIT_MEM(U, N);
291 CV_INIT_MEM(V, N);
292 CV_INIT_MEM(P, N);
293 CV_INIT_MEM(E, N);
294 // Initialize the values of energy in computational cells and (x,y)-coordinate of the cell interfaces.
295 for(j = 0; j <= n_x; ++j)
296 for(i = 0; i <= n_y; ++i)
297 {
298 X[j][i] = j * h_x;
299 Y[j][i] = i * h_y;
300 }
301 for(j = 0; j < n_x; ++j)
302 for(i = 0; i < n_y; ++i)
303 {
304 CV[0].RHO[j][i] = FV0.RHO[i*n_x + j + 2];
305 CV[0].U[j][i] = FV0.U[i*n_x + j + 2];
306 CV[0].V[j][i] = FV0.V[i*n_x + j + 2];
307 CV[0].P[j][i] = FV0.P[i*n_x + j + 2];
308 CV[0].E[j][i] = 0.5*CV[0].U[j][i]*CV[0].U[j][i] + CV[0].P[j][i]/(gamma - 1.0)/CV[0].RHO[j][i];
309 CV[0].E[j][i] += 0.5*CV[0].V[j][i]*CV[0].V[j][i];
310 }
311
312 _Bool const dim_split = (_Bool)config[33]; // Dimensional splitting?
313 if (strcmp(argv[5],"EUL") == 0) // Use GRP/Godunov scheme to solve it on Eulerian coordinate.
314 {
315 config[8] = (double)0;
316 switch(order)
317 {
318 case 1:
319 // Godunov_solver_2D_EUL_source(n_x, n_y, CV, cpu_time);
320 config[41] = 0.0; // alpha = 0.0
321 GRP_solver_2D_EUL_source(n_x, n_y, CV, cpu_time, time_plot);
322 break;
323 case 2:
324 if (dim_split)
325 GRP_solver_2D_split_EUL_source(n_x, n_y, CV, cpu_time, time_plot);
326 else
327 GRP_solver_2D_EUL_source(n_x, n_y, CV, cpu_time, time_plot);
328 break;
329 default:
330 printf("NOT appropriate order of the scheme! The order is %d.\n", order);
331 retval = 4;
332 goto return_NULL;
333 }
334 }
335 else
336 {
337 printf("NOT appropriate coordinate framework! The framework is %s.\n", argv[5]);
338 retval = 4;
339 goto return_NULL;
340 }
341
342 // Write the final data down.
343#ifndef NODATPLOT
344 _2D_file_write(n_x, n_y, N, CV, X, Y, cpu_time, argv[2], time_plot);
345#endif
346#ifndef NOTECPLOT
347 _2D_TEC_file_write(n_x, n_y, N, CV, X, Y, cpu_time, argv[2], time_plot);
348#endif
349
350 return_NULL:
351 free(FV0.RHO);
352 free(FV0.U);
353 free(FV0.V);
354 free(FV0.P);
355 FV0.RHO = NULL;
356 FV0.U = NULL;
357 FV0.V = NULL;
358 FV0.P = NULL;
359 for(k = 0; k < N; ++k)
360 {
361 for(j = 0; j < n_x; ++j)
362 {
363 free(CV[k].RHO[j]);
364 free(CV[k].U[j]);
365 free(CV[k].V[j]);
366 free(CV[k].P[j]);
367 free(CV[k].E[j]);
368 CV[k].RHO[j] = NULL;
369 CV[k].U[j] = NULL;
370 CV[k].V[j] = NULL;
371 CV[k].P[j] = NULL;
372 CV[k].E[j] = NULL;
373 }
374 free(CV[k].RHO);
375 free(CV[k].U);
376 free(CV[k].V);
377 free(CV[k].P);
378 free(CV[k].E);
379 CV[k].RHO = NULL;
380 CV[k].U = NULL;
381 CV[k].V = NULL;
382 CV[k].P = NULL;
383 CV[k].E = NULL;
384 }
385 free(CV);
386 CV = NULL;
387 for(j = 0; j <= n_x; ++j)
388 {
389 free(X[j]);
390 free(Y[j]);
391 X[j] = NULL;
392 Y[j] = NULL;
393 }
394 free(X);
395 free(Y);
396 X = NULL;
397 Y = NULL;
398 free(cpu_time);
399 cpu_time = NULL;
400
401 return retval;
402}
struct flu_var _2D_initialize(const char *name)
This function reads the 2-D initial data file of velocity/pressure/density.
Definition: _2D_file_in.c:79
void _2D_file_write(const int n_x, const int n_y, const int N, const struct cell_var_stru CV[], double **X, double **Y, const double *cpu_time, const char *name, const double *time_plot)
This function write the 2-D solution into output .dat files.
Definition: _2D_file_out.c:56
void _2D_TEC_file_write(const int n_x, const int n_y, const int N, const struct cell_var_stru CV[], double **X, double **Y, const double *cpu_time, const char *problem, const double *time_plot)
This function write the 2-D solution into Tecplot output files.
Definition: _2D_file_out.c:104
void GRP_solver_2D_split_EUL_source(const int m, const int n, struct cell_var_stru *CV, double *cpu_time, double *time_plot)
This function use GRP scheme to solve 2-D Euler equations of motion on Eulerian coordinate with dimen...
void GRP_solver_2D_EUL_source(const int m, const int n, struct cell_var_stru *CV, double *cpu_time, double *time_plot)
This function use GRP scheme to solve 2-D Euler equations of motion on Eulerian coordinate without di...
int main(int argc, char *argv[])
This is the main function which constructs the main structure of the Eulerian hydrocode.
Definition: hydrocode.c:157
double config[N_CONF]
Initial configuration data array.
Definition: hydrocode.c:115
#define CV_INIT_MEM(v, N)
N memory allocations to the initial fluid variable 'v' in the structure cell_var_stru.
Definition: hydrocode.c:120
pointer structure of VARiables on STRUctural computational grid CELLs.
Definition: var_struc.h:35
double ** U
Definition: var_struc.h:36
double ** RHO
Definition: var_struc.h:36
double ** V
Definition: var_struc.h:36
double ** P
Definition: var_struc.h:36
double ** E
density, velocity components in direction x and y, pressure, specific total energy.
Definition: var_struc.h:36
pointer structure of FLUid VARiables.
Definition: var_struc.h:30
double * P
Definition: var_struc.h:31
double * RHO
Definition: var_struc.h:31
double * U
Definition: var_struc.h:31
double * V
Definition: var_struc.h:31
#define N_CONF
Define the number of configuration parameters.
Definition: var_struc.h:24