initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / applications / utilities / postProcessing / dataConversion / foamToFieldview9 / write_binary_uns.c
blob105d042792fe4c7ed0c08c92e7e8b48c31ecd1e0
1 /*
2 ** Support functions for writing a combined (grid and results) file
3 ** in the binary FIELDVIEW unstructured format.
4 */
6 /* Include system stuff for I/O and string and exit functions. */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 /* Include the defines for the FV_* codes and wall_info values. */
12 #include "fv_reader_tags.h"
15 /* Don't change these - used by fv_encode_elem_header ! */
16 #define MAX_NUM_ELEM_FACES 6
17 #define BITS_PER_WALL 3
18 #define ELEM_TYPE_BIT_SHIFT (MAX_NUM_ELEM_FACES*BITS_PER_WALL)
22 ** fv_encode_elem_header: return an encoded binary element header
24 ** Input:
25 ** elem_type: integer element type as shown in fv_reader_tags.h
26 ** wall_info: array of integer "wall" flags, one for each face of
27 ** the element. The wall flags are used during streamline
28 ** calculation. Currently, the only meaningful values are
29 ** A_WALL and NOT_A_WALL as shown in fv_reader_tags.h.
30 ** Streamlines are forced away from faces marked as
31 ** "A_WALL", by limiting velocity and position very near
32 ** the wall.
33 ** Output:
34 ** Function return value is the encoded binary element header.
37 #ifdef __STDC__
38 unsigned int fv_encode_elem_header (int elem_type, int wall_info[])
39 #else
40 unsigned int fv_encode_elem_header (elem_type, wall_info)
41 int elem_type;
42 int wall_info[];
43 #endif
45 unsigned int header;
46 int i, nfaces;
48 switch (elem_type)
50 case FV_TET_ELEM_ID:
51 header = (1 << ELEM_TYPE_BIT_SHIFT);
52 nfaces = 4;
53 break;
54 case FV_HEX_ELEM_ID:
55 header = (4 << ELEM_TYPE_BIT_SHIFT);
56 nfaces = 6;
57 break;
58 case FV_PRISM_ELEM_ID:
59 header = (3 << ELEM_TYPE_BIT_SHIFT);
60 nfaces = 5;
61 break;
62 case FV_PYRA_ELEM_ID:
63 header = (2 << ELEM_TYPE_BIT_SHIFT);
64 nfaces = 5;
65 break;
66 default:
67 fprintf(stderr, "ERROR: Unknown element type\n");
68 return 0;
71 for (i = 0; i < nfaces; i++)
73 unsigned int u = wall_info[i];
74 if (u > A_WALL)
76 fprintf(stderr, "ERROR: Bad wall value\n");
77 return 0;
79 header |= (u << (i*BITS_PER_WALL));
81 return header;
85 ** fwrite_str80: write out a string padded to 80 characters.
87 ** Like fwrite, this returns the number of items written, which
88 ** should be 80 if successful, and less than 80 if it failed.
90 #ifdef __STDC__
91 size_t fwrite_str80 (char *str, FILE *fp)
92 #else
93 int fwrite_str80 (str, fp)
94 char *str;
95 FILE *fp;
96 #endif
98 char cbuf[80];
99 size_t len;
100 int i;
102 /* Most of this just to avoid garbage after the name. */
103 len = strlen(str);
104 strncpy(cbuf, str, len < 80 ? len : 80);
106 for (i = len; i < 80; i++)
107 cbuf[i] = '\0'; /* pad with zeros */
109 return fwrite(cbuf, sizeof(char), 80, fp);
114 ** Sample program which writes out a single unstructured grid containing
115 ** four hex elements, with pressure and velocity data at the nodes, and
116 ** surface data for temperature and velocity on some of the boundaries.
118 ** The data is written as a combined (grid and results) file in the
119 ** binary FIELDVIEW unstructured format.
121 ** For simplicity, no error checking is done on the calls to fwrite
122 ** and fwrite_str80.
124 #if 0 /***** CHANGE THIS TO "#if 1" TO RUN THE SAMPLE PROGRAM. *****/
125 int main()
127 char *file_name = "quad_hex.uns";
128 FILE *outfp;
129 int num_grids = 1;
130 int num_face_types = 5;
132 ** Note that one of the boundary type names is "wall."
133 ** The boundary name "wall" has no special meaning in FIELDVIEW.
134 ** Boundary types and element walls are independent pieces of
135 ** information. The only way to mark an element face as a wall
136 ** (for streamline calculation) is with the wall_info array passed
137 ** to fv_encode_elem_header.
139 static char *face_type_names[5] = { "bottom", "top", "wall",
140 "trimmed cell", "hanging node cell"};
142 ** Each boundary type is flagged with 1 or 0 depending on
143 ** whether surface results are present or absent (see below).
145 static int results_flag[5] = { 1, 1, 0, 1, 1 };
147 ** Each boundary type is flagged with 1 or 0 depending on
148 ** whether surface normals can be calculated from a "right
149 ** hand rule" (see below).
151 static int normals_flag[5] = { 1, 1, 0, 1, 1 };
154 ** Note that vector variables are specified by a ';' and vector name
155 ** following the first scalar name of 3 scalar components of the
156 ** vector. If writing 2-D results, the third component must still
157 ** be provided here, and its values must be written in the variables
158 ** section below (typically padded with zeros.)
160 int num_vars = 4;
161 static char *var_names[4] = { "pressure", "uvel; velocity", "vvel", "wvel" };
162 int num_bvars = 4;
163 static char *bvar_names[4] = { "temperature", "uvel; velocity", "vvel", "wvel" };
165 unsigned int elem_header;
166 int grid, i;
167 int ibuf[10];
169 int nnodes = 31; /* Number of nodes in the grid. */
170 const int num_faces_trim_cell = 7;
171 const int num_faces_hang_cell = 6;
173 /* Constants. */
174 static float consts[4] = { 1., 0., 0., 0. };
176 /* XYZ coordinates of the nodes. */
177 static float x[31] = {-1., -1., 1., 1., -1., -1., 1., 1., -1., -1., 1.,1., 2., 2., 3., 3., 2.5, 3., 2., 3., 3., 2., 2.5,
178 3., 3., 3., 2.5, 2., 2., 2.0, 2.5};
180 static float y[31] = {-1., -1., -1., -1., 1., 1., 1., 1., 3., 3., 3., 3.,
181 0., 0., 0., 0., 0., .5, 1., 1., 1., 1., .5,
182 2., 2., 1.5, 2., 2., 2., 1.45, 1.5};
184 static float z[31] = {-1., 1., -1., 1., -1., 1., -1., 1., -1., 1., -1.,1., 1., 0., 0., .5, 1., 1., 1., 1., 0., 0., .5,
185 0., 1., 1., 1., 1., 0., 1., 1.};
187 /* hex1 and hex2 are hex elements, defined as an array of node numbers. */
188 static int hex1[8] = {1,2,3,4,5,6,7,8};
189 static int hex2[8] = {5,6,7,8,9,10,11,12};
192 ** Face definitions for boundary faces.
193 ** All faces have 4 vertices. If the face is triangular,
194 ** the last vertex should be zero.
196 static int bot_faces[4] = { 1,2,4,3 };
197 static int top_faces[4] = { 9,10,12,11 };
198 static int wall_faces[8][4] =
199 { {1,2,6,5}, {5,6,10,9}, {3,4,8,7}, {7,8,12,11},
200 {1,3,7,5}, {5,7,11,9}, {2,4,8,6}, {6,8,12,10} };
202 /* Arbitrary Polyhedron faces: */
203 static int trim_cell_face[num_faces_trim_cell][6] =
204 { {5,13,14,15,16,17}, {3,16,18,17},
205 {5,15,21,20,18,16}, {5,13,17,18,20,19},
206 {4,13,19,22,14}, {4,14,22,21,15},
207 {4,19,20,21,22} };
209 static int hang_cell_face[num_faces_hang_cell][8] =
210 { {5,20,21,24,25,26},
211 {5,24,29,28,27,25},
212 {7,20,26,25,27,28,30,19},
213 {4,20,19,22,21},
214 {4,21,22,29,24},
215 {5,22,19,30,28,29} };
217 /* Wall values for element faces. */
218 static int hex1_walls[6] = { A_WALL, A_WALL, NOT_A_WALL,
219 NOT_A_WALL, A_WALL, A_WALL };
220 static int hex2_walls[6] = { A_WALL, A_WALL, NOT_A_WALL,
221 NOT_A_WALL, A_WALL, A_WALL };
223 /* 4 variables (pressure and velocity values) at the 31 grid nodes. */
224 static float vars[4][31] =
225 { {1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.10,1.11,
226 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.10,1.11,
227 1.12,1.13,1.14,1.15,1.16,1.17,1.18},
228 {0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,
229 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.10,1.11,
230 1.12,1.13,1.14,1.15,1.16,1.17,1.18},
231 {1.2,1.1,1.0,0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1,
232 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.10,1.11,
233 1.12,1.13,1.14,1.15,1.16,1.17,1.18},
234 {0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,
235 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.10,1.11,
236 1.12,1.13,1.14,1.15,1.16,1.17,1.18} };
239 ** 4 boundary variables (temperature and velocity values) defined on
240 ** the single top face, and the the single bottom face.
242 static float top_bvars[4] = { 1.0, 2.0,4.0,2.5 };
243 static float bot_bvars[4] = { 1.0, 4.5,3.0,3.0 };
245 /* Arbitrary Polyhedron boundary face variables: */
246 static float trim_cell_bvars[4][num_faces_trim_cell] =
247 { {1.0,1.1,1.2,1.3,1.4,1.5,1.6},
248 {1.7,1.8,1.9,1.1,1.11,1.12,1.13},
249 {1.14,1.15,1.16,1.17,1.18,1.19,1.2},
250 {1.21,1.22,1.23,1.24,1.25,1.26,1.27} };
252 static float hang_cell_bvars[4][num_faces_hang_cell] =
253 { {1.1,1.11,1.12,1.13,1.14,1.15},
254 {1.16,1.17,1.18,1.19,1.2,1.21},
255 {1.22,1.23,1.24,1.25,1.26,1.27},
256 {1.28,1.29,1.30,1.31,1.32,1.33} };
258 /* Open the file for binary write access. */
259 if ((outfp = fopen(file_name, "wb")) == NULL)
261 perror ("Cannot open output file");
262 exit(1);
265 /* Output the magic number. */
266 ibuf[0] = FV_MAGIC;
267 fwrite(ibuf, sizeof(int), 1, outfp);
269 /* Output file header and version number. */
270 fwrite_str80("FIELDVIEW", outfp);
273 ** This version of the FIELDVIEW unstructured file is "3.0".
274 ** This is written as two integers.
276 ibuf[0] = 3;
277 ibuf[1] = 0;
278 fwrite(ibuf, sizeof(int), 2, outfp);
280 /* File type code - new in version 2.7 */
281 ibuf[0] = FV_COMBINED_FILE;
282 fwrite(ibuf, sizeof(int), 1, outfp);
284 /* Reserved field, always write a zero - new in version 2.6 */
285 ibuf[0] = 0;
286 fwrite(ibuf, sizeof(int), 1, outfp);
288 /* Output constants for time, fsmach, alpha and re. */
289 fwrite(consts, sizeof(float), 4, outfp);
291 /* Output the number of grids. */
292 ibuf[0] = num_grids;
293 fwrite(ibuf, sizeof(int), 1, outfp);
296 ** Output the table of boundary types.
297 ** Each boundary type is preceded by 2 integer flags.
298 ** The first flag is an "surface results flag".
299 ** A value of 1 means surface results will be present for this
300 ** boundary type (if any boundary variables are specified in the
301 ** boundary variable names table below).
302 ** A value of 0 means no surface results will be present.
303 ** The second flag indicates whether boundary faces of this type have
304 ** consistent "clockness" for the purpose of calculating a surface
305 ** normal. A value of 1 means that all faces of this type are
306 ** written following a "right hand rule" for clockness. In other
307 ** words, if the vertices are written on counter-clockwise:
308 ** 4 --- 3
309 ** | |
310 ** 1 --- 2
311 ** then the normal to the face is pointing towards you (not away
312 ** from you). A value of 0 means that the faces do not have any
313 ** consistent clockness. The "clockness" of surface normals is
314 ** only used for calculating certain special surface integrals
315 ** that involve surface normals. If the surface normals flag
316 ** is 0, these special integrals will not be available.
318 ibuf[0] = num_face_types;
319 fwrite(ibuf, sizeof(int), 1, outfp);
320 for (i = 0; i < num_face_types; i++) {
321 ibuf[0] = results_flag[i];
322 ibuf[1] = normals_flag[i];
323 fwrite(ibuf, sizeof(int), 2, outfp);
324 fwrite_str80(face_type_names[i], outfp);
327 /* Output the table of variable names. */
328 /* The number of variables can be zero. */
329 ibuf[0] = num_vars;
330 fwrite(ibuf, sizeof(int), 1, outfp);
331 for (i = 0; i < num_vars; i++)
332 fwrite_str80(var_names[i], outfp);
335 ** Output the table of boundary variable names.
336 ** Boundary variables are associated with boundary faces, rather than
337 ** with grid nodes.
338 ** FIELDVIEW will automatically append "[BNDRY]" to each name
339 ** so boundary variables can be easily distinguished from ordinary
340 ** (grid node) variables.
341 ** The number of boundary variables can be different from the number
342 ** of ordinary variables. The number of boundary variables can be
343 ** zero.
345 ibuf[0] = num_bvars;
346 fwrite(ibuf, sizeof(int), 1, outfp);
347 for (i = 0; i < num_bvars; i++)
348 fwrite_str80(bvar_names[i], outfp);
350 /* Output grid data. */
351 for (grid = 0; grid < num_grids; grid++)
353 /* Output the node definition section for this grid. */
354 ibuf[0] = FV_NODES;
355 ibuf[1] = nnodes;
356 fwrite(ibuf, sizeof(int), 2, outfp);
359 ** Output the X, then Y, then Z node coordinates.
360 ** Note that all of the X coordinates are output before any of
361 ** the Y coordinates.
363 fwrite(x, sizeof(float), nnodes, outfp);
364 fwrite(y, sizeof(float), nnodes, outfp);
365 fwrite(z, sizeof(float), nnodes, outfp);
368 ** Output boundary faces of the 3 different types.
369 ** All faces have 4 vertices. If the face is triangular,
370 ** the last vertex should be zero.
371 ** TIP: A single boundary type can be broken into several sections
372 ** if you prefer. Also, boundary face sections do not have to
373 ** be in order. You may have a section of 10 faces of type 3,
374 ** followed by a section of 20 faces of type 2, followed by a
375 ** section of 15 more faces of type 3. Breaking a boundary
376 ** type into very many short sections is less efficient. The
377 ** boundaries will require more memory and be somewhat
378 ** slower to calculate in FIELDVIEW.
381 ibuf[0] = FV_FACES;
382 ibuf[1] = 1; /* first boundary type */
383 ibuf[2] = 1; /* number of faces of this type */
384 fwrite(ibuf, sizeof(int), 3, outfp);
385 fwrite(bot_faces, sizeof(int), 4, outfp);
387 ibuf[0] = FV_FACES;
388 ibuf[1] = 2; /* second boundary type */
389 ibuf[2] = 1; /* number of faces of this type */
390 fwrite(ibuf, sizeof(int), 3, outfp);
391 fwrite(top_faces, sizeof(int), 4, outfp);
393 ibuf[0] = FV_FACES;
394 ibuf[1] = 3; /* third boundary type */
395 ibuf[2] = 8; /* number of faces of this type */
396 fwrite(ibuf, sizeof(int), 3, outfp);
397 fwrite(wall_faces, sizeof(int), 8*4, outfp);
399 /* Arbitrary Polygon boundary faces:
400 ** The format (in psuedocode) is as follows:
401 ** >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
402 ** FV_ARB_POLY_FACES (section header)
403 ** BndryFaceType NumBndryFaces
405 ** [for N = 1, NumBndryFaces]
406 ** NumVertsFaceN Vert1 Vert2 ... Vert{NumVertsFaceN}
408 ** <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
409 ** * The above block should be repeated for different boundary face
410 ** types, as is the case for standard boundary faces.
411 ** * These blocks should be after the blocks for standard faces,
412 ** within the FIELDVIEW-Uns file.
413 ** * The node ordering for specifying faces should follow a
414 ** right-handed rule with the normal pointing away from the
415 ** cell center. So nodes should be given by traversing the face
416 ** in a counter-clockwise manner.
417 ** * Hanging nodes are not permitted on boundary faces.
420 ibuf[0] = FV_ARB_POLY_FACES;
421 ibuf[1] = 4; /* boundary face type */
422 ibuf[2] = 7; /* num faces for the trimmed cell */
424 fwrite(ibuf, sizeof(int), 3, outfp);
426 for(i = 0; i < num_faces_trim_cell; ++i) /* loop over the faces */
427 fwrite(trim_cell_face[i], sizeof(int), trim_cell_face[i][0] + 1,
428 outfp);
430 ibuf[0] = FV_ARB_POLY_FACES;
431 ibuf[1] = 5; /* boundary face type */
432 ibuf[2] = 6; /* num faces for the hanging node cell */
434 fwrite(ibuf, sizeof(int), 3, outfp);
436 for(i = 0; i < num_faces_hang_cell; ++i) /* loop over the faces */
437 fwrite(hang_cell_face[i], sizeof(int), hang_cell_face[i][0] + 1,
438 outfp);
441 ** Start an elements section.
442 ** There may be as many elements sections as needed.
443 ** Each section may contain a single element type or a
444 ** mixture of element types.
445 ** For maximum efficiency, each section should contain
446 ** a significant percentage of the elements in the grid.
447 ** The most efficient case is a single section containing
448 ** all elements in the grid.
450 ibuf[0] = FV_ELEMENTS;
451 ibuf[1] = 0; /* tet count */
452 ibuf[2] = 2; /* hex count */
453 ibuf[3] = 0; /* prism count */
454 ibuf[4] = 0; /* pyramid count */
455 fwrite(ibuf, sizeof(int), 5, outfp);
457 /* Write header for first element. */
458 elem_header = fv_encode_elem_header(FV_HEX_ELEM_ID, hex1_walls);
459 if (elem_header == 0)
461 fprintf (stderr, "fv_encode_elem_header failed for first hex.\n");
462 exit(1);
464 fwrite (&elem_header, sizeof(elem_header), 1, outfp);
466 /* Write node definition for first element. */
467 fwrite(hex1, sizeof(int), 8, outfp);
469 /* Write header for second element. */
470 elem_header = fv_encode_elem_header(FV_HEX_ELEM_ID, hex2_walls);
471 if (elem_header == 0)
473 fprintf (stderr, "fv_encode_elem_header failed for second hex.\n");
474 exit(1);
476 fwrite (&elem_header, sizeof(elem_header), 1, outfp);
478 /* Write node definition for second element. */
479 fwrite(hex2, sizeof(int), 8, outfp);
481 /* Arbitrary Polyhedron elements:
482 ** The format (in psuedocode) is as follows:
483 ** >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
484 ** FV_ARB_POLY_ELEMENTS (section header)
485 ** NumArbPolyElements
487 ** [for elem = 1, NumArbPolyElements]
488 ** {
489 ** NumFaces NumNodesElement CenterNode
491 ** [for face = 1, NumFaces]
492 ** WallFlag NumNodesFace FaceNode1 ... FaceNode{NumNodesFace}
493 ** NumHangNodes HangNode1 ... HangNode{NumHangNodes}
494 ** }
495 ** <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
496 ** * These blocks can be after or before the standard element blocks.
497 ** There can be any number of these for any one grid.
498 ** * The WallFlag has the same meaning as for standard elements,
499 ** i.e., A_WALL or NOT_A_WALL.
500 ** * The node ordering for specifying faces should follow a
501 ** right-handed rule with the normal pointing away from the
502 ** cell center. So nodes should be given by traversing the face
503 ** in a counter-clockwise manner.
504 ** * Hanging nodes are associated with a face interior and should
505 ** not be on an edge. Hanging nodes on an edge should be
506 ** interpretted as a regular face node.
508 ibuf[0] = FV_ARB_POLY_ELEMENTS;
509 ibuf[1] = 2; /* have 2 elements here */
511 fwrite(ibuf, sizeof(int), 2, outfp);
513 /* trimmed face element */
514 ibuf[0] = 7; /* num faces for the trimmed cell */
515 ibuf[1] = 11; /* number of nodes including a center node */
516 ibuf[2] = 23; /* the center node */
517 fwrite(ibuf, sizeof(int), 3, outfp);
519 ibuf[0] = A_WALL; /* wall value */
520 ibuf[1] = 0; /* number of hanging nodes */
522 for(i = 0; i < num_faces_trim_cell; ++i) /* write out face info */
524 fwrite(ibuf, sizeof(int), 1, outfp); /* write wall value */
525 fwrite(trim_cell_face[i], sizeof(int), trim_cell_face[i][0] + 1,
526 outfp); /* write num verts and verts */
527 fwrite(&ibuf[1], sizeof(int), 1, outfp); /* write num hang nodes */
530 /* hanging node element */
531 ibuf[0] = 6; /* num faces for the hanging node cell */
532 ibuf[1] = 12; /* number of nodes excluding a center node */
533 ibuf[2] = -1; /* the center node, this indicates that FIELDVIEW
534 ** should calculate the center node and associated
535 ** centernode variable values
537 fwrite(ibuf, sizeof(int), 3, outfp);
539 ibuf[0] = A_WALL; /* wall value */
540 ibuf[1] = 0; /* number of hanging nodes */
541 ibuf[2] = 1; /* number of hanging nodes for face 3 */
542 ibuf[3] = 31; /* the node number for the hanging node on face 3*/
544 for(i = 0; i < 2; ++i) /* write out face info for first 2 faces */
546 fwrite(ibuf, sizeof(int), 1, outfp); /* write wall value */
547 fwrite(hang_cell_face[i], sizeof(int), hang_cell_face[i][0] + 1,
548 outfp); /* write num verts and verts */
549 fwrite(&ibuf[1], sizeof(int), 1, outfp); /* write num hang nodes */
552 /* this face has a hanging node */
553 fwrite(ibuf, sizeof(int), 1, outfp);
554 fwrite(hang_cell_face[2], sizeof(int), hang_cell_face[2][0] + 1, outfp);
555 fwrite(&ibuf[2], sizeof(int), 2, outfp);
557 /* write out face info for last 3 faces */
558 for(i = 3; i < num_faces_hang_cell; ++i)
560 fwrite(ibuf, sizeof(int), 1, outfp); /* write wall value */
561 fwrite(hang_cell_face[i], sizeof(int), hang_cell_face[i][0] + 1,
562 outfp); /* write num verts and verts */
563 fwrite(&ibuf[1], sizeof(int), 1, outfp); /* write num hang nodes */
567 ** Output the variables data.
568 ** You must write the section header even if the number
569 ** of variables is zero.
571 ibuf[0] = FV_VARIABLES;
572 fwrite(ibuf, sizeof(int), 1, outfp);
575 ** Note that all of the data for the first variable is output
576 ** before any of the data for the second variable.
578 for (i = 0; i < num_vars; i++)
579 fwrite(vars[i], sizeof(float), nnodes, outfp);
582 ** Output the boundary variables data.
583 ** Remember that the Boundary Table above has a "surface results
584 ** flag" indicating which boundary types have surface results.
585 ** The data should be written in the same order as the faces in
586 ** the Boundary Faces section, skipping over faces whose boundary
587 ** type has a surface results flag of zero (false).
588 ** For each variable, you should write one number per boundary face.
589 ** You must write the section header even if the number of boundary
590 ** variables is zero.
592 ibuf[0] = FV_BNDRY_VARS;
593 fwrite(ibuf, sizeof(int), 1, outfp);
596 ** Note that all of the data for the first variable is output
597 ** before any of the data for the second variable.
599 for (i = 0; i < num_bvars; i++) {
600 int num_faces;
602 ** The data for the bottom face is written first for each
603 ** variable, because the bottom face was written first in the
604 ** "Boundary Faces" section.
605 ** The "wall" faces are skipped, because the surface results
606 ** flag for the wall boundary type was 0 (false) in the
607 ** Boundary Table section.
609 num_faces = 1; /* number of bottom faces */
610 fwrite(&bot_bvars[i], sizeof(float), num_faces, outfp);
611 num_faces = 1; /* number of top faces */
612 fwrite(&top_bvars[i], sizeof(float), num_faces, outfp);
615 /* Arbitrary Polyhedron boundary face results:
616 ** The format is the same as for standard boundary face results.
618 ibuf[0] = FV_ARB_POLY_BNDRY_VARS;
619 fwrite(ibuf, sizeof(int), 1, outfp);
621 for (i = 0; i < num_bvars; ++i)
623 int num_faces;
625 num_faces = 7; /* num faces for the trimmed cell */
626 fwrite(trim_cell_bvars[i], sizeof(float), num_faces, outfp);
628 num_faces = 6; /* num faces for the hanging node cell */
629 fwrite(hang_cell_bvars[i], sizeof(float), num_faces, outfp);
633 if (fclose(outfp) != 0)
635 perror ("Cannot close output file");
636 exit(1);
639 return 0;
641 #endif /* end commenting out the sample program */