Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
input.h
Go to the documentation of this file.
1/** @file input.h
2 */
3/**
4# *input_pgm()*: Importing Portable Gray Map (PGM) images
5
6This function reads in the
7[PGM](http://en.wikipedia.org/wiki/Netpbm_format) file in file *fp*
8and imports the corresponding values into field *s*. The grayscale is
9normalised and inverted so that the maximum value in field *s* is one
10(black) and the minimum value is zero (white).
11
12By default the origin of the image (lower-left corner) is assumed to
13be at (0,0) and the width of the image is set to `L0`. This can be
14changed using the optional *ox*, *oy* and *width* parameters. */
15
16#include "utils.h"
17
19 double ox = 0., double oy = 0., double width = L0)
20{
21 char line[81];
22 if (!fgets (line, 81, fp)) {
23 fprintf (stderr, "input_pgm: could not read magic number\n");
24 exit (1);
25 }
26 if (strcmp (line, "P2\n") && strcmp (line, "P5\n")) {
27 fprintf (stderr, "input_pgm: magic number '%s' does not match PGM\n",
28 line);
29 exit (1);
30 }
31 int binary = !strcmp (line, "P5\n");
32 if (!fgets (line, 81, fp)) {
33 fprintf (stderr, "input_pgm: could not read width and height\n");
34 exit (1);
35 }
36 int W, H;
37 while (line[0] == '#' && fgets (line, 81, fp));
38 if (line[0] == '#' || sscanf (line, "%d %d", &W, &H) != 2) {
39 fprintf (stderr, "input_pgm: could not read width and height\n");
40 exit (1);
41 }
42 if (!fgets (line, 81, fp)) {
43 fprintf (stderr, "input_pgm: could not read maxval\n");
44 exit (1);
45 }
46 int maxval;
47 if (sscanf (line, "%d", &maxval) != 1) {
48 fprintf (stderr, "input_pgm: could not read maxval\n");
49 exit (1);
50 }
51 if (maxval < 256) {
52 unsigned char * a = qmalloc (W*H, unsigned char);
53 size_t n = 0;
54 if (binary)
55 n = fread (a, 1, W*H, fp);
56 else {
57 int v;
58 while (n < W*H && fscanf (fp, "%d ", &v) == 1)
59 a[n++] = v;
60 }
61 if (n != W*H) {
62 fprintf (stderr, "input_pgm: read only %ld values\n", n);
63 exit (1);
64 }
65 for (int _i = 0; _i < _N; _i++) /* foreach */ {
66 int i = (x - ox)*W/width, j = (y - oy)*W/width;
67 if (i >= 0 && i < W && j >= 0 && j < H)
68 s[] = 1. - a[(H - 1 - j)*W + i]/(double)maxval;
69 else
70 s[] = 0.;
71 }
72 free (a);
73 }
74 else {
75 unsigned short * a = qmalloc (W*H, unsigned short);
76 size_t n = 0;
77 if (binary)
78 n = fread (a, 2, W*H, fp);
79 else {
80 int v;
81 while (n < W*H && fscanf (fp, "%d ", &v) == 1)
82 a[n++] = v;
83 }
84 if (n != W*H) {
85 fprintf (stderr, "input_pgm: read only %ld values\n", n);
86 exit (1);
87 }
88 for (int _i = 0; _i < _N; _i++) /* foreach */ {
89 int i = (x - ox)*W/width, j = (y - oy)*W/width;
90 if (i >= 0 && i < W && j >= 0 && j < H)
91 s[] = 1. - a[(H - 1 - j)*W + i]/(double)maxval;
92 else
93 s[] = 0.;
94 }
95 free (a);
96 }
97}
98
99static void next_char (FILE * fp, int target)
100{
101 int c = fgetc(fp), para = 0;
102 while (c != EOF && (c != target || para > 0)) {
103 if (c == '{') para++;
104 if (c == '}') para--;
105 c = fgetc(fp);
106 }
107 if (c != target) {
108 fprintf (stderr, "input_gfs(): error: expecting '%c'\n", target);
109 exit (1);
110 }
111}
112
113static int next_string (FILE * fp, const char * target)
114{
115 int slen = strlen (target), para = 0;
116 char s[slen + 1];
117 s[slen] = '\0';
118 int len = 0, c = fgetc (fp);
119 while (c != EOF && len < slen) {
120 if (c == '{') para++;
121 if (c == '}') para--;
122 s[len++] = c;
123 c = fgetc (fp);
124 }
125 while (c != EOF && para >= 0) {
126 if (!strcmp (s, target) && para == 0)
127 break;
128 if (c == '{') para++;
129 if (c == '}') para--;
130 for (int i = 0; i < slen - 1; i++)
131 s[i] = s[i+1];
132 s[slen - 1] = c;
133 c = fgetc (fp);
134 }
135 if (strcmp (s, target))
136 c = -1;
137 return c;
138}
139
140/**
141# *input_gfs()*: Gerris simulation format
142
143The function reads simulation data in the format used in
144[Gerris](https://gerris.dalembert.upmc.fr) simulation files. This is
145the reciprocal function of [*output_gfs()*](output.h#output_gfs).
146
147The arguments and their default values are:
148
149*fp*
150: a file pointer. Default is *file* or stdin.
151
152*list*
153: a list of scalar fields to read. Default is *all*.
154
155*file*
156: the name of the file to read from (mutually exclusive with *fp*). */
157
158trace
160 scalar * list = NULL,
161 char * file = NULL)
162{
164
165 if (file && !(fp = fopen (file, "r"))) {
166 perror (file);
167 exit (1);
168 }
169
170 bool input_all = (list == all);
171 if (!list) list = all;
172
173 #if TREE
174 init_grid (1);
175 #endif
176
177 next_char (fp, '{');
178
179 char * s = qmalloc (1, char);
180 int len = 0;
181 int c = fgetc(fp);
182 while (c != EOF && c != '}') {
183 s[len++] = c;
184 s = (char *)realloc(s, (len + 1)*sizeof(char));
185 s[len] = '\0';
186 c = fgetc(fp);
187 }
188 if (c != '}') {
189 fprintf (stderr, "input_gfs(): error: expecting '}'\n");
190 exit (1);
191 }
192
193 char * s1 = strstr (s, "variables");
194 if (!s1) {
195 fprintf (stderr, "input_gfs(): error: expecting 'variables'\n");
196 exit (1);
197 }
198
199 s1 = strstr (s1, "=");
200 if (!s1) {
201 fprintf (stderr, "input_gfs(): error: expecting '='\n");
202 exit (1);
203 }
204 s1++;
205
206 while (strchr (" \t", *s1))
207 s1++;
208
209 scalar * input = NULL;
210 s1 = strtok (s1, ", \t");
211 while (s1) {
212 char * name = replace (s1, '_', '.', false);
213 bool found = false;
214 for (int _s = 0; _s < 1; _s++) /* scalar in list */
215 if (!is_constant(s) && s.name && !strcmp (s.name, name)) {
217 found = true; break;
218 }
219 if (!found) {
220 if (input_all) {
221 scalar s = {0} /* new scalar */;
222 free (s.name);
223 s.name = strdup (name);
225 }
226 else
228 }
229 free (name);
230 s1 = strtok (NULL, ", \t");
231 }
232 free (s);
233
234 next_char (fp, '{');
235 double t1 = 0.;
236 if (next_string (fp, "Time") >= 0) {
237 next_char (fp, '{');
238 next_char (fp, 't');
239 next_char (fp, '=');
240 if (fscanf (fp, "%lf", &t1) != 1) {
241 fprintf (stderr, "input_gfs(): error: expecting 't'\n");
242 exit (1);
243 }
244 next_char (fp, '}');
245 next_char (fp, '}');
246 }
247
248 if (next_string (fp, "Box") < 0) {
249 fprintf (stderr, "input_gfs(): error: expecting 'GfsBox'\n");
250 exit (1);
251 }
252
253 next_char (fp, '{');
254 next_char (fp, '{');
255 next_char (fp, '\n');
256
257 scalar * listm = {cm,fm};
260
261 for (int _i = 0; _i < _N; _i++) /* foreach_cell */ {
262 unsigned flags;
263 if (fread (&flags, sizeof (unsigned), 1, fp) != 1) {
264 fprintf (stderr, "input_gfs(): error: expecting 'flags'\n");
265 exit (1);
266 }
267 if (!(flags & (1 << 4)) && is_leaf(cell))
269 double a;
270 if (fread (&a, sizeof (double), 1, fp) != 1 || a != -1) {
271 fprintf (stderr, "input_gfs(): error: expecting '-1'\n");
272 exit (1);
273 }
274 for (int _s = 0; _s < 1; _s++) /* scalar in input */ {
275 if (fread (&a, sizeof (double), 1, fp) != 1) {
276 fprintf (stderr, "input_gfs(): error: expecting a scalar\n");
277 exit (1);
278 }
279 if (s.i != INT_MAX) {
280 if (s.v.x.i >= 0) {
281 // this is a vector component, we need to rotate from
282 // Z-ordering (Gerris) to N-ordering (Basilisk)
283#if dimension >= 2
284 if (s.v.x.i == s.i) {
285 s = s.v.y;
286 s[] = a;
287 }
288 else if (s.v.y.i == s.i) {
289 s = s.v.x;
290 s[] = - a;
291 }
292#endif
293#if dimension >= 3
294 else
295 s[] = a;
296#endif
297 }
298 else
299 s[] = a;
300 }
301 }
302 if (is_leaf(cell))
303 continue;
304 }
305 for (int _s = 0; _s < 1; _s++) /* scalar in listm */
306 if (!is_constant(s))
308 for (int _s = 0; _s < 1; _s++) /* scalar in input */
309 if (s.i != INT_MAX && !is_constant(s))
311
312 free (input);
313 if (file)
314 fclose (fp);
315
316 // the events are advanced to catch up with the time
317 while (t < t1 && events (false))
318 t = tnext;
319 events (false);
320}
321
322#define valgrd(v,i,j) ((v)[(j) + 1 + ((i) + 1)*(nx + 2)])
323
324static void bc_grd (double * v, int nx, int ny, bool periodic[2])
325{
326 if (periodic[0])
327 for (int i = 0; i < ny; i++) {
328 valgrd(v,i,-1) = valgrd(v,i,nx - 1);
329 valgrd(v,i,nx) = valgrd(v,i,0);
330 }
331 else
332 for (int i = 0; i < ny; i++) {
333 valgrd(v,i,-1) = valgrd(v,i,0);
334 valgrd(v,i,nx) = valgrd(v,i,nx - 1);
335 }
336 if (periodic[1])
337 for (int j = -1; j <= nx; j++) {
338 valgrd(v,-1,j) = valgrd(v,ny - 1,j);
339 valgrd(v,ny,j) = valgrd(v,0,j);
340 }
341 else
342 for (int j = -1; j <= nx; j++) {
343 valgrd(v,-1,j) = valgrd(v,0,j);
344 valgrd(v,ny,j) = valgrd(v,ny - 1,j);
345 }
346}
347
348/**
349# *input_grd()*: Raster format (Esri grid)
350
351This function reads a scalar field from a [Raster
352file](https://en.wikipedia.org/wiki/Esri_grid). This is the reciprocal
353function of [*output_grd()*](output.h#output_grd).
354
355The arguments and their default values are:
356
357*s*
358: the scalar where the data will be stored. No default value. You
359must specify this parameter
360
361*fp*
362: a file pointer. Default is *file* or stdin.
363
364*file*
365: the name of the file to read from (mutually exclusive with *fp*).
366
367*nodatavalue*
368: the value of the NoDataValue. Default is the same as that defined in
369the raster file.
370
371*linear*
372: if true, the raster data is bilinearly interpolated. Default is false.
373
374*periodic*
375: if true, the x-axis and/or y-axis are treated as periodic. Default
376is the same as the domain periodicity.
377
378*smooth*
379: the number of Laplacian smoothing passes applied to the data before
380interpolation. Default is zero.
381*/
382
384 FILE * fp = stdin, const char * file = NULL,
385 double nodatavalue = 0.12345678,
386 bool linear = false,
387 bool periodic[2] = {Period.x, Period.y},
388 int smooth = 0)
389{
390 scalar input = s;
391
392 if (file && !(fp = fopen (file, "r"))) {
393 perror (file);
394 exit (1);
395 }
396
397 // Variables for the Raster data
398 double DeltaGRD;
399 int nx, ny;
400 double XG0, YG0, ndv;
401
402 // header
403 char waste[100];
404 if (fscanf (fp, "%s %d", waste, &nx) != 2) {
405 fprintf (stderr, "input_grd(): error reading 'nx'\n");
406 if (file) fclose (fp);
407 return;
408 }
409 if (fscanf (fp, "%s %d", waste, &ny) != 2) {
410 fprintf (stderr, "input_grd(): error reading 'ny'\n");
411 if (file) fclose (fp);
412 return;
413 }
414 if (fscanf (fp, "%s %lf", waste, &XG0) != 2) {
415 fprintf (stderr, "input_grd(): error reading 'XG0'\n");
416 if (file) fclose (fp);
417 return;
418 }
419 if (fscanf (fp, "%s %lf", waste, &YG0) != 2) {
420 fprintf (stderr, "input_grd(): error reading 'YG0'\n");
421 if (file) fclose (fp);
422 return;
423 }
424 if (fscanf (fp, "%s %lf", waste, &DeltaGRD) != 2) {
425 fprintf (stderr, "input_grd(): error reading 'DeltaGRD'\n");
426 if (file) fclose (fp);
427 return;
428 }
429 if (fscanf (fp, "%s %lf", waste, &ndv) != 2) {
430 fprintf (stderr, "input_grd(): error reading 'ndv'\n");
431 if (file) fclose (fp);
432 return;
433 }
434
435 // default value of NoData value
436 if (nodatavalue == 0.12345678)
438
439 // read the data
440 double * value = qmalloc ((nx + 2)*(ny + 2), double);
441 for (int i = ny - 1; i >= 0; i--)
442 for (int j = 0 ; j < nx; j++) {
443 if (fscanf (fp, "%lf ", &valgrd(value,i,j)) != 1) {
444 fprintf (stderr, "input_grd(): error reading value %d,%d\n", i, j);
445 if (file) fclose (fp);
446 free (value);
447 return;
448 }
449 }
450 bc_grd (value, nx, ny, periodic);
451
452 // Laplacian smoothing
453 if (smooth > 0) {
454 double * smoothed = qmalloc ((nx + 2)*(ny + 2), double);
455 for (int s = 0; s < smooth; s++) {
456 for (int i = 0; i < ny; i++)
457 for (int j = 0 ; j < nx; j++) {
458 int n = 0;
459 valgrd(smoothed, i, j) = 0.;
460 for (int k = -1; k <= 1; k++)
461 for (int l = -1; l <= 1; l++)
462 if ((l != 0 || k != 0) &&
463 valgrd(value, i + k, j + l) != ndv)
464 valgrd(smoothed, i, j) += valgrd(value, i + k, j + l), n++;
465 if (n == 0)
466 valgrd(smoothed, i, j) = ndv;
467 else
468 valgrd(smoothed, i, j) /= n;
469 }
470 swap (double *, value, smoothed);
471 bc_grd (value, nx, ny, periodic);
472 }
473 free (smoothed);
474 }
475
476 bool warning = false;
477 foreach (serial) {
478 if (periodic[0]) {
479 while (x < XG0) x += nx*DeltaGRD;
480 while (x > XG0 + nx*DeltaGRD) x -= nx*DeltaGRD;
481 }
482 if (periodic[1]) {
483 while (y < YG0) y += ny*DeltaGRD;
484 while (y > YG0 + ny*DeltaGRD) y -= ny*DeltaGRD;
485 }
486 // Test if we are on the ring of data around the raster grid
487 int j1 = (x - XG0)/DeltaGRD;
488 int i1 = (y - YG0)/DeltaGRD;
489 if (i1 >= -1 && i1 < ny && j1 >= -1 && j1 < nx) {
490 if (linear &&
491 valgrd(value,i1,j1) != ndv && valgrd(value,i1,j1 + 1) != ndv &&
492 valgrd(value,i1 + 1,j1) != ndv && valgrd(value,i1 + 1,j1 + 1) != ndv) {
493 // bi-linear interpolation
494 double dx = x - (j1*DeltaGRD + XG0);
495 double dy = y - (i1*DeltaGRD + YG0);
496 input[] = (valgrd(value,i1,j1) +
497 dx*(valgrd(value,i1,j1 + 1) - valgrd(value,i1,j1))/DeltaGRD +
498 dy*(valgrd(value,i1 + 1,j1) - valgrd(value,i1,j1))/DeltaGRD +
499 dx*dy*(valgrd(value,i1,j1) + valgrd(value,i1 + 1,j1 + 1) -
500 valgrd(value,i1 + 1,j1) - valgrd(value,i1,j1 + 1))
501 /sq(DeltaGRD));
502 }
503 else
504 input[] = valgrd(value, i1, j1);
505 }
506 else {
507 input[] = nodatavalue;
508 warning = true;
509 }
510 }
511 free (value);
512
513 if (warning)
515 "%s:%d: warning: raster data is not covering all the simulation area\n",
517
518 if (file)
519 fclose (fp);
520}
const vector a
Definition all-mach.h:59
define k
define double double char flags
define l
free(list1)
define VT _attribute[s.i] v y scalar * list
Definition cartesian.h:276
int y
Definition common.h:76
int x
Definition common.h:76
scalar * all
Definition common.h:342
const scalar cm[]
Definition common.h:397
double L0
Definition common.h:36
struct @0 Period
static number sq(number x)
Definition common.h:11
#define swap(type, a, b)
Definition common.h:19
scalar * list_append(scalar *list, scalar s)
Definition common.h:188
const vector fm[]
Definition common.h:396
#define qmalloc(size, type)
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define file
Definition config.h:120
#define LINENO
Definition config.h:105
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define line line realloc(p, s) @ define pfree(p
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define line line line line strdup(s) @ define tracing(...) @ define end_tracing(...) @define tid() 0 @define pid() 0 @define npe() 1 @define mpi_all_reduce(v
Point point
Definition conserving.h:86
else return n
Definition curvature.h:101
scalar s
Definition embed-tree.h:56
*cs[i, 0, 0] a *[i -1, 0, 0] j
Definition embed.h:88
double v[2]
Definition embed.h:383
scalar int i
Definition embed.h:74
static int line
Definition errors.c:754
double t
Definition events.h:24
double tnext
Definition events.h:24
#define dx(s)
We first define some useful macros, following the notations in Bonneton et al, 2011.
#define dy(s)
#define init_grid(n)
Definition grid.h:1402
static int input(void)
Definition include.c:2085
static int target
Definition include.c:949
void input_pgm(scalar s, FILE *fp, double ox=0., double oy=0., double width=L0)
Definition input.h:18
trace void input_gfs(FILE *fp=stdin, scalar *list=NULL, char *file=NULL)
Definition input.h:159
static void next_char(FILE *fp, int target)
Definition input.h:99
void input_grd(scalar s, FILE *fp=stdin, const char *file=NULL, double nodatavalue=0.12345678, bool linear=false, bool periodic[2]={Period.x, Period.y}, int smooth=0)
Definition input.h:383
static int next_string(FILE *fp, const char *target)
Definition input.h:113
#define valgrd(v, i, j)
Definition input.h:322
static void bc_grd(double *v, int nx, int ny, bool periodic[2])
Definition input.h:324
FILE * fp
Definition mtrace.h:7
define is_active() cell(true) @define is_leaf(cell)(point.level
int events
Definition qcc.c:60
def _i
Definition stencils.h:405
static void set_dirty_stencil(scalar s)
Definition stencils.h:34
int i
Definition common.h:44
int refine_cell(Point point, scalar *list, int flag, Cache *refined)
Definition tree-common.h:23
#define periodic(dir)
Definition tree.h:1734
scalar c
Definition vof.h:57