HydroCODE_2D 0.1
This is a implementation of fully explict forward Euler scheme for 2-D Euler equations of motion on Eulerian coordinate
io_control.c
浏览该文件的文档.
1
6#include <errno.h>
7#include <stdio.h>
8#include <string.h>
9#include <stdlib.h>
10#include <stdbool.h>
11#include <math.h>
12#include <ctype.h>
13
14#include "../include/var_struc.h"
15#include "../include/tools.h"
16
17/*
18 * To realize cross-platform programming.
19 * ACCESS: Determine access permissions for files or folders.
20 * - mode=0: Test for existence.
21 * - mode=2: Test for write permission.
22 * - mode=4: Test for read permission.
23 */
24#ifdef _WIN32
25#include <io.h>
26#define ACCESS(path,mode) _access((path),(mode))
27#elif __linux__
28#include <unistd.h>
29#define ACCESS(path,mode) access((path),(mode))
30#endif
31
32
40void example_io(const char *example, char *add_mkdir, const int i_or_o)
41{
42 const int dim = (int)config[0];
43 const int el = (int)config[8];
44 const int order = (int)config[9];
45
46 static int output_const = 0;
47 char str_tmp[11], str_order[11];
48 switch (dim)
49 {
50 case 1 :
51 strcpy(str_tmp, "one-dim/"); break;
52 case 2 :
53 strcpy(str_tmp, "two-dim/"); break;
54 case 3 :
55 strcpy(str_tmp, "three-dim/"); break;
56 default :
57 fprintf(stderr, "Strange computational dimension!\n");
58 exit(2);
59 }
60 if (i_or_o == 0) // Output
61 {
62 strcpy(add_mkdir, "../../data_out/");
63 strcat(add_mkdir, str_tmp);
64 switch (el)
65 {
66 case 0 :
67 strcpy(str_tmp, "EUL_"); break;
68 case 1 :
69 strcpy(str_tmp, "LAG_"); break;
70 case 2 :
71 strcpy(str_tmp, "ALE_"); break;
72 default :
73 fprintf(stderr, "Strange description method of fluid motion!\n");
74 exit(2);
75 }
76 strcat(add_mkdir, str_tmp);
77 sprintf(str_order, "%d_order/", order);
78 strcat(add_mkdir, str_order);
79 }
80 else // Input
81 {
82 strcpy(add_mkdir, "../../data_in/");
83 strcat(add_mkdir, str_tmp);
84 }
85 strcat(add_mkdir, example);
86
87 if (i_or_o == 0)
88 {
89 if(CreateDir(add_mkdir) == 1)
90 {
91#ifdef _WIN32
92 fprintf(stderr, "Output directory '%s' construction failed!\n", add_mkdir);
93#elif __linux__
94 fprintf(stderr, "\x1b[47;34mOutput directory '%s' construction failed!\x1b[0m\n", add_mkdir);
95#endif
96 exit(1);
97 }
98 else if(output_const == 0)
99 {
100#ifdef _WIN32
101 printf("Output directory '%s' has been constructed.\n", add_mkdir);
102#elif __linux__
103 printf("\x1b[47;34mOutput directory '%s' has been constructed.\x1b[0m\n", add_mkdir);
104#endif
105 output_const = 1;
106 }
107 }
108 else if (ACCESS(add_mkdir,4) == -1)
109 {
110 fprintf(stderr, "Input directory '%s' is nonexistent or unreadable!\n", add_mkdir);
111 exit(1);
112 }
113
114 strcat(add_mkdir, "/");
115}
116
117
124int flu_var_count(FILE * fp, const char * add)
125{
126 int num = 0; // Data number.
127 /* We read characters one by one from the data file.
128 * "flg" helps us to count.
129 * -# 1: when read a number-using character (0, 1, 2, ..., e, E, minus sign and dot).
130 * -# 0: when read a non-number-using character.
131 */
132 int flg = 0;
133 int ch;
134
135 while((ch = getc(fp)) != EOF) // Count the data number.
136 {
137 if (ch == 45 || ch == 46 || ch == 69 || ch == 101 || isdigit(ch))
138 flg = 1;
139 else if (!isspace(ch))
140 {
141 fprintf(stderr, "Input contains illegal character(ASCII=%d, flag=%d) in the file '%s'!\n", ch, flg, add);
142 return 0;
143 }
144 else if (flg) // Read in the space.
145 {
146 num++;
147 flg = 0;
148 }
149 }
150
151 rewind(fp);
152 return num;
153}
154
155
163int flu_var_count_line(FILE * fp, const char * add, int * n_x)
164{
165 int line = 0, column = 0;
166 /* We read characters one by one from the data file.
167 * "flg" helps us to count.
168 * -# 1: when read a number-using character (0, 1, 2, ..., e, E, minus sign and dot).
169 * -# 0: when read a non-number-using character.
170 */
171 int flag = 0;
172 int ch;
173
174 do { // Count the data line number.
175 ch = getc(fp);
176 if(ch == '\n' || ch == EOF)
177 {
178 if(flag)
179 ++column;
180 flag = 0;
181 if(column)
182 {
183 if(!line)
184 *n_x = column;
185 else if(column != *n_x)
186 {
187 printf("Error in input data file '%s', line=%d, column=%d, n_x=%d\n", add, line, column, *n_x);
188 return 0;
189 }
190 ++line;
191 column = 0;
192 }
193 }
194 else if(ch == 45 || ch == 46 || ch == 69 || ch == 101 || isdigit(ch))
195 flag = 1;
196 else if (!isspace(ch))
197 {
198 printf("Input contains illigal character(ASCII=%d, flag=%d) in the file '%s', line=%d!\n", ch, flag, add, line);
199 return 0;
200 }
201 else if(flag)
202 {
203 ++column;
204 flag = 0;
205 }
206 } while(ch != EOF);
207
208 rewind(fp);
209 return line;
210}
211
212
221int flu_var_read(FILE * fp, double * U, const int num)
222{
223 int idx = 0, j = 0; // j is a frequently used index for spatial variables.
224 char number[100]; // A string that stores a number.
225 char ch, *endptr;
226 // int sign = 1;
227
228 while((ch = getc(fp)) != EOF)
229 {
230 if(isspace(ch) && idx)
231 {
232 number[idx] = '\0';
233 idx = 0;
234 // format_string() and str2num() in 'str_num_common.c' are deprecated.
235 /*
236 sign = format_string(number);
237 if(!sign)
238 return j+1;
239 else if(j == num)
240 return j;
241 U[j] = sign * str2num(number);
242 */
243 errno = 0;
244 U[j] = strtod(number, &endptr);
245 if (errno == ERANGE || *endptr != '\0')
246 {
247 printf("The %dth entry in the initial data file is not a double-precision floats.\n", j+1);
248 return j+1;
249 }
250 else if(j == num)
251 {
252 printf("Error on the initial data file reading!\n");
253 return j;
254 }
255 ++j;
256 }
257 else if((ch == 46) || (ch == 45) || (ch == 69) || (ch == 101) || isdigit(ch))
258 number[idx++] = ch;
259 }
260 return 0;
261}
262
263
267static int compare_double(const void *a,const void *b)
268{
269 double ret = *(double*)a - *(double*)b;
270 if(ret > 0.0)
271 return 1;
272 else if(ret < 0.0)
273 return -1;
274 else
275 return 0;
276}
277
278
288int time_plot_read(const char * add_in, const int N_max, int * N_plot, double * time_plot[])
289{
290 _Bool r = true; // r: Whether to read data file successfully.
291 FILE * fp;
292 char add[FILENAME_MAX+40];
293 strcpy(add, add_in);
294 strcat(add, "time_plot.txt");
295 // Open the time data file for plotting.
296 if((fp = fopen(add, "r")) == NULL)
297 {
298 strcpy(add, add_in);
299 strcat(add, "time_plot.dat");
300 }
301 if((fp = fopen(add, "r")) == NULL)
302 {
303 printf("No time data file for plotting! Only the initial data and final result will be plotted.\n");
304 *N_plot = 2;
305 r = false;
306 }
307 else
308 *N_plot = flu_var_count(fp, add) + 2;
309 if (*N_plot < 2)
310 {
311 printf("Error in counting time data file for plotting!\n");
312 fclose(fp);
313 exit(2);
314 }
315 *time_plot = (double*)malloc((*N_plot)*sizeof(double));
316 if(*time_plot == NULL)
317 {
318 printf("NOT enough memory! time_plot[]\n");
319 exit(5);
320 }
321 (*time_plot)[0] = 0.0;
322 (*time_plot)[*N_plot - 1] = config[1];
323 if(r)
324 {
325 if(flu_var_read(fp, *time_plot + 1, *N_plot - 2))
326 {
327 fclose(fp);
328 exit(2);
329 }
330 printf("Load time data file for plotting! Plot time step is %d.\n", *N_plot - 2);
331 qsort(*time_plot, *N_plot-1, sizeof(double), compare_double);
332 fclose(fp);
333 }
334 return N_max<(*N_plot) ? N_max : (*N_plot);
335}
double config[N_CONF]
Initial configuration data array.
Definition: hydrocode.c:123
int flu_var_read(FILE *fp, double *U, const int num)
This function reads the initial data file to generate the initial data.
Definition: io_control.c:221
int flu_var_count_line(FILE *fp, const char *add, int *n_x)
This function counts the line and column number of the numbers are there in the initial data file.
Definition: io_control.c:163
static int compare_double(const void *a, const void *b)
Compare function of double for sort function 'qsort()'.
Definition: io_control.c:267
void example_io(const char *example, char *add_mkdir, const int i_or_o)
This function produces folder path for data input or output.
Definition: io_control.c:40
int flu_var_count(FILE *fp, const char *add)
This function counts how many numbers are there in the initial data file.
Definition: io_control.c:124
int time_plot_read(const char *add_in, const int N_max, int *N_plot, double *time_plot[])
This function reads the time data file for plotting 'time_plot.dat' and initialize tha array 'time_pl...
Definition: io_control.c:288
int CreateDir(const char *pPath)
This is a function that recursively creates folders.
Definition: sys_pro.c:72