1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #ifdef _WIN32
5 # include <io.h>
6 # define unlink _unlink
7 #else
8 # include <unistd.h>
9 #endif
10 #include "cgnslib.h"
11 
12 #ifndef CGNSTYPES_H
13 # define cgsize_t int
14 #endif
15 #ifndef CGNS_ENUMT
16 # define CGNS_ENUMT(e) e
17 # define CGNS_ENUMV(e) e
18 #endif
19 
20 #define NUM_SIDE 5
21 #define NUM_RANDOM 10
22 
23 float *xcoord;
24 float *ycoord;
25 float *zcoord;
26 float *fbuf;
27 
28 cgsize_t *elements;
29 cgsize_t *faces;
30 cgsize_t *parent;
31 cgsize_t *ptmp;
32 cgsize_t *ibuf, *pbuf;
33 cgsize_t *offsets;
34 
35 #define NODE_INDEX(I,J,K) ((I)+NUM_SIDE*(((J)-1)+NUM_SIDE*((K)-1)))
36 #define CELL_INDEX(I,J,K) ((I)+(NUM_SIDE-1)*(((J)-1)+(NUM_SIDE-1)*((K)-1)))
37 
irandom(int imin,int imax)38 int irandom(int imin, int imax) {
39     float r = (float)rand() / (float)RAND_MAX;
40     int i = imin + (int)(r * (float)(imax - imin));
41     if (i < imin) return imin;
42     if (i > imax) return imax;
43     return i;
44 }
45 
get_parent(int rmin,int rmax,int nelems,int nfaces)46 void get_parent(int rmin, int rmax, int nelems, int nfaces)
47 {
48     int i, j, k, n, nn, np;
49 
50     np = rmax - rmin + 1;
51     nn = rmin - nelems - 1;
52     for (n = 0, j = 0; j < 4; j++) {
53         k = j * nfaces + nn;
54         for (i = 0; i < np; i++)
55             ptmp[n++] = parent[k++];
56     }
57 }
58 
mixed_offset(int num,int nelems)59 int mixed_offset(int num, int nelems) {
60     int offset;
61     int nmixed = nelems << 1;
62 
63     if (--num < nmixed) {
64         int i = num >> 1;
65         offset = 14 * i;
66         if (num != (i << 1)) offset += 5;
67     }
68     else
69         offset = 14 * nelems + 5 * (num - nmixed);
70     return offset;
71 }
72 
main(int argc,char ** argv)73 int main (int argc, char **argv)
74 {
75     int n, i, j, k, l, nn, nf, np;
76     int nnodes, nelems, nfaces;
77     int cgfile, cgbase, cgzone, cgcoord, cgsol, cgfld;
78     int cgsect, cgelems, cgfaces;
79     cgsize_t size[3], rmin, rmax, nr;
80     cgsize_t is, ie;
81     char name[33];
82     CGNS_ENUMT( ElementType_t )  type;
83     static char *fname = "partial.cgns";
84 
85     if (argc > 1) {
86         n = 0;
87         if (argv[1][n] == '-') n++;
88         if (argv[1][n] == 'a' || argv[1][n] == 'A' || argv[1][n] == '1') {
89             if (NULL != strchr(argv[1], '2'))
90                 nn = CG_FILE_ADF2;
91             else
92                 nn = CG_FILE_ADF;
93         }
94         else if (argv[1][n] == 'h' || argv[1][n] == 'H' || argv[1][n] == '2') {
95             nn = CG_FILE_HDF5;
96         }
97         else if (argv[1][n] == '3') {
98             nn = CG_FILE_ADF2;
99         }
100         else {
101             fprintf(stderr, "unknown option\n");
102             exit (1);
103         }
104         if (cg_set_file_type(nn))
105             cg_error_exit();
106     }
107 
108     nnodes = NUM_SIDE * NUM_SIDE * NUM_SIDE;
109     xcoord = (float *) malloc (4 * nnodes * sizeof(float));
110     ycoord = xcoord + nnodes;
111     zcoord = ycoord + nnodes;
112     fbuf   = zcoord + nnodes;
113 
114     for (n = 0, k = 1; k <= NUM_SIDE; k++) {
115         for (j = 1; j <= NUM_SIDE; j++) {
116             for (i = 1; i <= NUM_SIDE; i++) {
117                 xcoord[n] = (float)i;
118                 ycoord[n] = (float)j;
119                 zcoord[n] = (float)k;
120                 n++;
121             }
122         }
123     }
124 
125     nelems = (NUM_SIDE - 1) * (NUM_SIDE - 1) * (NUM_SIDE - 1);
126     elements = (cgsize_t *) malloc (16 * nelems * sizeof(cgsize_t));
127     ibuf = elements + 8 * nelems;
128 
129     for (n = 0, k = 1; k < NUM_SIDE; k++) {
130         for (j = 1; j < NUM_SIDE; j++) {
131             for (i = 1; i < NUM_SIDE; i++) {
132                 nn = NODE_INDEX(i, j, k);
133                 elements[n++] = nn;
134                 elements[n++] = nn + 1;
135                 elements[n++] = nn + 1 + NUM_SIDE;
136                 elements[n++] = nn + NUM_SIDE;
137                 nn += NUM_SIDE * NUM_SIDE;
138                 elements[n++] = nn;
139                 elements[n++] = nn + 1;
140                 elements[n++] = nn + 1 + NUM_SIDE;
141                 elements[n++] = nn + NUM_SIDE;
142             }
143         }
144     }
145 
146     nfaces = 6 * (NUM_SIDE - 1) * (NUM_SIDE - 1);
147     faces = (cgsize_t *) malloc (18 * nfaces * sizeof(cgsize_t));
148     parent = faces + 4 * nfaces;
149     ptmp = parent + 4 * nfaces;
150     pbuf = ptmp + 4 * nfaces;
151 
152     for (n = 0; n < 4 * nfaces; n++)
153         parent[n] = 0;
154     np = nf = 0;
155     n = 2 * nfaces;
156 
157     i = 1;
158     for (k = 1; k < NUM_SIDE; k++) {
159         for (j = 1; j < NUM_SIDE; j++) {
160             nn = NODE_INDEX(i, j, k);
161             faces[nf++]  = nn;
162             faces[nf++]  = nn + NUM_SIDE * NUM_SIDE;
163             faces[nf++]  = nn + NUM_SIDE * (NUM_SIDE + 1);
164             faces[nf++]  = nn + NUM_SIDE;
165             parent[np]   = CELL_INDEX(i, j, k);
166             parent[np+n] = 5;
167             np++;
168         }
169     }
170     i = NUM_SIDE;
171     for (k = 1; k < NUM_SIDE; k++) {
172         for (j = 1; j < NUM_SIDE; j++) {
173             nn = NODE_INDEX(i, j, k);
174             faces[nf++]  = nn;
175             faces[nf++]  = nn + NUM_SIDE;
176             faces[nf++]  = nn + NUM_SIDE * (NUM_SIDE + 1);
177             faces[nf++]  = nn + NUM_SIDE * NUM_SIDE;
178             parent[np]   = CELL_INDEX(i-1, j, k);
179             parent[np+n] = 3;
180             np++;
181         }
182     }
183     j = 1;
184     for (k = 1; k < NUM_SIDE; k++) {
185         for (i = 1; i < NUM_SIDE; i++) {
186             nn = NODE_INDEX(i, j, k);
187             faces[nf++]  = nn;
188             faces[nf++]  = nn + 1;
189             faces[nf++]  = nn + 1 + NUM_SIDE * NUM_SIDE;
190             faces[nf++]  = nn + NUM_SIDE * NUM_SIDE;
191             parent[np]   = CELL_INDEX(i, j, k);
192             parent[np+n] = 2;
193             np++;
194         }
195     }
196     j = NUM_SIDE;
197     for (k = 1; k < NUM_SIDE; k++) {
198         for (i = 1; i < NUM_SIDE; i++) {
199             nn = NODE_INDEX(i, j, k);
200             faces[nf++]  = nn;
201             faces[nf++]  = nn + NUM_SIDE * NUM_SIDE;
202             faces[nf++]  = nn + 1 + NUM_SIDE * NUM_SIDE;
203             faces[nf++]  = nn + 1;
204             parent[np]   = CELL_INDEX(i, j-1, k);
205             parent[np+n] = 4;
206             np++;
207         }
208     }
209     k = 1;
210     for (j = 1; j < NUM_SIDE; j++) {
211         for (i = 1; i < NUM_SIDE; i++) {
212             nn = NODE_INDEX(i, j, k);
213             faces[nf++]  = nn;
214             faces[nf++]  = nn + NUM_SIDE;
215             faces[nf++]  = nn + NUM_SIDE + 1;
216             faces[nf++]  = nn + 1;
217             parent[np]   = CELL_INDEX(i, j, k);
218             parent[np+n] = 1;
219             np++;
220         }
221     }
222     k = NUM_SIDE;
223     for (j = 1; j < NUM_SIDE; j++) {
224         for (i = 1; i < NUM_SIDE; i++) {
225             nn = NODE_INDEX(i, j, k);
226             faces[nf++]  = nn;
227             faces[nf++]  = nn + 1;
228             faces[nf++]  = nn + NUM_SIDE + 1;
229             faces[nf++]  = nn + NUM_SIDE;
230             parent[np]   = CELL_INDEX(i, j, k-1);
231             parent[np+n] = 6;
232             np++;
233         }
234     }
235 
236     unlink (fname);
237     printf ("creating CGNS file %s\n", fname);
238     if (cg_open (fname, CG_MODE_WRITE, &cgfile) ||
239         cg_base_write (cgfile, "Base", 3, 3, &cgbase) ||
240         cg_gopath (cgfile, "/Base") ||
241         cg_dataclass_write (CGNS_ENUMV(NormalizedByDimensional)))
242         cg_error_exit ();
243 
244     /* create zone and sections */
245 
246     size[0] = nnodes;
247     size[1] = nelems;
248     size[2] = 0;
249 
250     if (cg_zone_write (cgfile, cgbase, "Zone", size,
251             CGNS_ENUMV(Unstructured), &cgzone) ||
252         cg_section_partial_write(cgfile, cgbase, cgzone, "Elements",
253 	    CGNS_ENUMV(HEXA_8), (cgsize_t)1, (cgsize_t)nelems, 0, &cgelems) ||
254         cg_section_partial_write(cgfile, cgbase, cgzone, "Faces",
255 	    CGNS_ENUMV(QUAD_4), (cgsize_t)(nelems + 1),
256 	    (cgsize_t)(nelems + nfaces), 0, &cgfaces))
257         cg_error_exit();
258 
259     /* write zone with partial write */
260 
261     puts("\nwriting zone with partial write");
262 
263     /* write every other coordinate plane */
264 
265     np = NUM_SIDE * NUM_SIDE;
266     for (k = 0; k < NUM_SIDE; k += 2) {
267         n    = k * np;
268         rmin = n + 1;
269         rmax = n + np;
270         printf("coordinates %d -> %d\n", (int)rmin, (int)rmax);
271         if (cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
272                 "CoordinateX", &rmin, &rmax, &xcoord[n], &cgcoord) ||
273             cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
274                 "CoordinateY", &rmin, &rmax, &ycoord[n], &cgcoord) ||
275             cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
276                 "CoordinateZ", &rmin, &rmax, &zcoord[n], &cgcoord))
277             cg_error_exit();
278     }
279 
280     /* write every other cell plane */
281 
282     np = (NUM_SIDE - 1) * (NUM_SIDE - 1);
283     for (k = 1; k < NUM_SIDE; k += 2) {
284         nn   = (k - 1) * np;
285         n    = nn << 3;
286         rmin = nn + 1;
287         rmax = nn + np;
288         printf("elements %d -> %d\n", (int)rmin, (int)rmax);
289         if (cg_elements_partial_write(cgfile, cgbase, cgzone,
290                 cgelems, rmin, rmax, &elements[n]))
291             cg_error_exit();
292     }
293 
294     /* write every other face */
295 
296     for (k = 0; k < 6; k += 2) {
297         nn   = k * np;
298         n    = nn << 2;
299         rmin = nn + 1 + nelems;
300         rmax = nn + np + nelems;
301         get_parent((int)rmin, (int)rmax, nelems, nfaces);
302         printf("faces %d -> %d\n", (int)rmin, (int)rmax);
303         if (cg_elements_partial_write(cgfile, cgbase, cgzone,
304                 cgfaces, rmin, rmax, &faces[n]) ||
305             cg_parent_data_partial_write(cgfile, cgbase, cgzone,
306                 cgfaces, rmin, rmax, ptmp))
307             cg_error_exit();
308     }
309 
310     /* write every other solution value */
311 
312     if (cg_sol_write(cgfile, cgbase, cgzone, "Solution", CGNS_ENUMV(Vertex), &cgsol))
313         cg_error_exit();
314 
315     puts("field -> 1,3,5,7 ...");
316     for (n = 0; n < nnodes; n += 2) {
317         rmin = n + 1;
318         rmax = n + 1;
319         if (cg_field_partial_write(cgfile, cgbase, cgzone, cgsol,
320 	        CGNS_ENUMV(RealSingle), "Field", &rmin, &rmax, &xcoord[n], &cgfld))
321             cg_error_exit();
322     }
323 
324     puts ("closing and reopening in modify mode");
325     cg_close (cgfile);
326 
327     if (cg_open (fname, CG_MODE_MODIFY, &cgfile))
328         cg_error_exit ();
329 
330     /* fill in missing coordinate planes */
331 
332     np = NUM_SIDE * NUM_SIDE;
333     for (k = 1; k < NUM_SIDE; k += 2) {
334         n    = k * np;
335         rmin = n + 1;
336         rmax = n + np;
337         printf("coordinates %d -> %d\n", (int)rmin, (int)rmax);
338         if (cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
339                 "CoordinateX", &rmin, &rmax, &xcoord[n], &cgcoord) ||
340             cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
341                 "CoordinateY", &rmin, &rmax, &ycoord[n], &cgcoord) ||
342             cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
343                 "CoordinateZ", &rmin, &rmax, &zcoord[n], &cgcoord))
344             cg_error_exit();
345     }
346 
347     /* fill in missing cell planes */
348 
349     np = (NUM_SIDE - 1) * (NUM_SIDE - 1);
350     for (k = 2; k < NUM_SIDE; k += 2) {
351         nn   = (k - 1) * np;
352         n    = nn << 3;
353         rmin = nn + 1;
354         rmax = nn + np;
355         printf("elements %d -> %d\n", (int)rmin, (int)rmax);
356         if (cg_elements_partial_write(cgfile, cgbase, cgzone,
357                 cgelems, rmin, rmax, &elements[n]))
358             cg_error_exit();
359     }
360 
361     /* fill in missing faces */
362 
363     for (k = 1; k < 6; k += 2) {
364         nn   = k * np;
365         n    = nn << 2;
366         rmin = nn + 1 + nelems;
367         rmax = nn + np + nelems;
368         get_parent((int)rmin, (int)rmax, nelems, nfaces);
369         printf("faces %d -> %d\n", (int)rmin, (int)rmax);
370         if (cg_elements_partial_write(cgfile, cgbase, cgzone,
371                 cgfaces, rmin, rmax, &faces[n]) ||
372             cg_parent_data_partial_write(cgfile, cgbase, cgzone,
373                 cgfaces, rmin, rmax, ptmp))
374             cg_error_exit();
375     }
376 
377     /* fill in missing solution values */
378 
379     puts("field -> 2,4,6,8 ...");
380     for (n = 1; n < nnodes; n += 2) {
381         rmin = n + 1;
382         rmax = n + 1;
383         if (cg_field_partial_write(cgfile, cgbase, cgzone, cgsol,
384 		CGNS_ENUMV(RealSingle), "Field", &rmin, &rmax, &xcoord[n], &cgfld))
385             cg_error_exit();
386     }
387 
388 #if NUM_RANDOM > 0
389 
390     /* do random insertion */
391 
392     printf("doing random modification\n");
393 
394     for (k = 0; k < NUM_RANDOM; k++) {
395         rmin = irandom(1, nnodes);
396         rmax = irandom(1, nnodes);
397         if (rmin > rmax) {
398             nr = rmin;
399             rmin = rmax;
400             rmax = nr;
401         }
402         n = (int)(rmin - 1);
403         printf("coordinates %d -> %d\n", (int)rmin, (int)rmax);
404         if (cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
405                 "CoordinateX", &rmin, &rmax, &xcoord[n], &cgcoord) ||
406             cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
407                 "CoordinateY", &rmin, &rmax, &ycoord[n], &cgcoord) ||
408             cg_coord_partial_write(cgfile, cgbase, cgzone, CGNS_ENUMV(RealSingle),
409                 "CoordinateZ", &rmin, &rmax, &zcoord[n], &cgcoord))
410             cg_error_exit();
411     }
412 
413     for (k = 0; k < NUM_RANDOM; k++) {
414         rmin = irandom(1, nelems);
415         rmax = irandom(1, nelems);
416         if (rmin > rmax) {
417             nr = rmin;
418             rmin = rmax;
419             rmax = nr;
420         }
421         n = (int)(rmin - 1) << 3;
422         printf("elements %d -> %d\n", (int)rmin, (int)rmax);
423         if (cg_elements_partial_write(cgfile, cgbase, cgzone,
424                 cgelems, rmin, rmax, &elements[n]))
425             cg_error_exit();
426     }
427 
428     for (k = 0; k < NUM_RANDOM; k++) {
429         rmin = irandom(1, nfaces);
430         rmax = irandom(1, nfaces);
431         if (rmin > rmax) {
432             nr = rmin;
433             rmin = rmax;
434             rmax = nr;
435         }
436         n = (int)(rmin - 1) << 2;
437         rmin += nelems;
438         rmax += nelems;
439         get_parent((int)rmin, (int)rmax, nelems, nfaces);
440         printf("faces %d -> %d\n", (int)rmin, (int)rmax);
441         if (cg_elements_partial_write(cgfile, cgbase, cgzone,
442                 cgfaces, rmin, rmax, &faces[n]) ||
443             cg_parent_data_partial_write(cgfile, cgbase, cgzone,
444                 cgfaces, rmin, rmax, ptmp))
445             cg_error_exit();
446     }
447 
448     for (k = 0; k < NUM_RANDOM; k++) {
449         rmin = irandom(1, nnodes);
450         rmax = irandom(1, nnodes);
451         if (rmin > rmax) {
452             nr = rmin;
453             rmin = rmax;
454             rmax = nr;
455         }
456         n = (int)rmin - 1;
457         printf("field %d -> %d\n", (int)rmin, (int)rmax);
458         if (cg_field_partial_write(cgfile, cgbase, cgzone, cgsol,
459 	        CGNS_ENUMV(RealSingle), "Field", &rmin, &rmax, &xcoord[n], &cgfld))
460             cg_error_exit();
461     }
462 
463 #endif
464 
465     /* check the data */
466 
467     puts("checking the data");
468 
469     nn = 0;
470 
471     /* check coordinates */
472 
473     rmin = 1;
474     rmax = nnodes;
475     if (cg_coord_read(cgfile, cgbase, cgzone, "CoordinateX",
476             CGNS_ENUMV(RealSingle), &rmin, &rmax, fbuf))
477         cg_error_exit();
478     for (np = 0, n = 0; n < nnodes; n++) {
479         if (fbuf[n] != xcoord[n]) np++;
480     }
481     nn += np;
482     if (np) printf("%d differences in CoordinateX\n", np);
483 
484     if (cg_coord_read(cgfile, cgbase, cgzone, "CoordinateY",
485 	    CGNS_ENUMV(RealSingle), &rmin, &rmax, fbuf))
486         cg_error_exit();
487     for (np = 0, n = 0; n < nnodes; n++) {
488         if (fbuf[n] != ycoord[n]) np++;
489     }
490     nn += np;
491     if (np) printf("%d differences in CoordinateY\n", np);
492 
493     if (cg_coord_read(cgfile, cgbase, cgzone, "CoordinateZ",
494 	    CGNS_ENUMV(RealSingle), &rmin, &rmax, fbuf))
495         cg_error_exit();
496     for (np = 0, n = 0; n < nnodes; n++) {
497         if (fbuf[n] != zcoord[n]) np++;
498     }
499     nn += np;
500     if (np) printf("%d differences in CoordinateZ\n", np);
501 
502     /* check elements */
503 
504     if (cg_section_read(cgfile, cgbase, cgzone, 1, name,
505             &type, &is, &ie, &k, &n) ||
506         cg_elements_read(cgfile, cgbase, cgzone, 1, ibuf, NULL))
507         cg_error_exit();
508     if (strcmp(name, "Elements") || type != CGNS_ENUMV(HEXA_8) || is != 1 ||
509         ie != nelems || k != 0 || n != 0) {
510         nn++;
511         puts("differences in Elements");
512     }
513     for (np = 0, n = 0; n < 8*nelems; n++) {
514         if (elements[n] != ibuf[n]) np++;
515     }
516     nn += np;
517     if (np) printf("%d differences in Elements connectivity\n", np);
518 
519     /* check faces */
520 
521     if (cg_section_read(cgfile, cgbase, cgzone, 2, name,
522             &type, &is, &ie, &k, &n) ||
523         cg_elements_read(cgfile, cgbase, cgzone, 2, ibuf, pbuf))
524         cg_error_exit();
525     if (strcmp(name, "Faces") || type != CGNS_ENUMV(QUAD_4) || is != (nelems+1) ||
526         ie != (nelems+nfaces) || k != 0 || n != 1) {
527         nn++;
528         puts("differences in Faces");
529     }
530     for (np = 0, n = 0; n < 4*nfaces; n++) {
531         if (faces[n] != ibuf[n]) np++;
532     }
533     nn += np;
534     if (np) printf("%d differences in Faces connectivity\n", np);
535 
536     for (np = 0, n = 0; n < 4*nfaces; n++) {
537         if (parent[n] != pbuf[n]) np++;
538     }
539     nn += np;
540     if (np) printf("%d differences in Faces parent data\n", np);
541 
542     /* check field */
543 
544     if (cg_field_read(cgfile, cgbase, cgzone, 1, "Field",
545 	    CGNS_ENUMV(RealSingle), &rmin, &rmax, fbuf))
546         cg_error_exit();
547     for (np = 0, n = 0; n < nnodes; n++) {
548         if (fbuf[n] != xcoord[n]) np++;
549     }
550     nn += np;
551     if (np) printf("%d differences in Field\n", np);
552 
553     if (nn == 0) puts("no diferences");
554 
555 #if NUM_RANDOM > 0
556 
557     /* do random checks */
558 
559     puts("doing random reads/checks");
560 
561     for (k = 0; k < NUM_RANDOM; k++) {
562         rmin = irandom(1, nnodes);
563         rmax = irandom(1, nnodes);
564         if (rmin > rmax) {
565             nr = rmin;
566             rmin = rmax;
567             rmax = nr;
568         }
569         printf("coordinates %d -> %d\n", (int)rmin, (int)rmax);
570         n = (int)rmin - 1;
571         np = 0;
572         nn = (int)(rmax - rmin) + 1;
573         if (cg_coord_read(cgfile, cgbase, cgzone, "CoordinateX",
574 	        CGNS_ENUMV(RealSingle), &rmin, &rmax, fbuf))
575             cg_error_exit();
576         for (i = 0; i < nn; i++) {
577             if (fbuf[i] != xcoord[n+i]) np++;
578         }
579 
580         if (cg_coord_read(cgfile, cgbase, cgzone, "CoordinateY",
581 	        CGNS_ENUMV(RealSingle), &rmin, &rmax, fbuf))
582             cg_error_exit();
583         for (i = 0; i < nn; i++) {
584             if (fbuf[i] != ycoord[n+i]) np++;
585         }
586 
587         if (cg_coord_read(cgfile, cgbase, cgzone, "CoordinateZ",
588 	        CGNS_ENUMV(RealSingle), &rmin, &rmax, fbuf))
589             cg_error_exit();
590         for (i = 0; i < nn; i++) {
591             if (fbuf[i] != zcoord[n+i]) np++;
592         }
593         if (np) printf("%d differences in Coordinates\n", np);
594     }
595 
596     for (k = 0; k < NUM_RANDOM; k++) {
597         rmin = irandom(1, nelems);
598         rmax = irandom(1, nelems);
599         if (rmin > rmax) {
600             nr = rmin;
601             rmin = rmax;
602             rmax = nr;
603         }
604         n = (int)(rmin - 1) << 3;
605         nn = (int)(rmax - rmin + 1) << 3;
606         printf("elements %d -> %d\n", (int)rmin, (int)rmax);
607         if (cg_ElementPartialSize(cgfile, cgbase, cgzone, 1,
608                 rmin, rmax, &nr) ||
609             cg_elements_partial_read(cgfile, cgbase, cgzone, 1,
610                 rmin, rmax, ibuf, NULL))
611             cg_error_exit();
612         if (nr != nn) puts("diference in element data size");
613         for (np = 0, i = 0; i < nn; i++) {
614             if (ibuf[i] != elements[n+i]) np++;
615         }
616         if (np) printf("%d differences in element connectivity\n", np);
617     }
618 
619     for (k = 0; k < NUM_RANDOM; k++) {
620         rmin = irandom(1, nfaces);
621         rmax = irandom(1, nfaces);
622         if (rmin > rmax) {
623             nr = rmin;
624             rmin = rmax;
625             rmax = nr;
626         }
627         n = (int)(rmin - 1) << 2;
628         nn = (int)(rmax - rmin + 1) << 2;
629         rmin += nelems;
630         rmax += nelems;
631         get_parent((int)rmin, (int)rmax, nelems, nfaces);
632         printf("faces %d -> %d\n", (int)rmin, (int)rmax);
633         if (cg_ElementPartialSize(cgfile, cgbase, cgzone, 2,
634                 rmin, rmax, &nr) ||
635             cg_elements_partial_read(cgfile, cgbase, cgzone, 2,
636                 rmin, rmax, ibuf, pbuf))
637             cg_error_exit();
638         if (nr != nn) puts("diference in face data size");
639         for (np = 0, i = 0; i < nn; i++) {
640             if (ibuf[i] != faces[n+i]) np++;
641         }
642         if (np) printf("%d differences in face connectivity\n", np);
643         for (np = 0, i = 0; i < nn; i++) {
644             if (pbuf[i] != ptmp[i]) np++;
645         }
646         if (np) printf("%d differences in face parent data\n", np);
647     }
648 
649     for (k = 0; k < NUM_RANDOM; k++) {
650         rmin = irandom(1, nnodes);
651         rmax = irandom(1, nnodes);
652         if (rmin > rmax) {
653             nr = rmin;
654             rmin = rmax;
655             rmax = nr;
656         }
657         n = (int)rmin - 1;
658         nn = (int)(rmax - rmin) + 1;
659         printf("field %d -> %d\n", (int)rmin, (int)rmax);
660         if (cg_field_read(cgfile, cgbase, cgzone, 1, "Field",
661 	        CGNS_ENUMV(RealSingle), &rmin, &rmax, fbuf))
662             cg_error_exit();
663         for (np = 0, i = 0; i < nn; i++) {
664             if (fbuf[i] != xcoord[n+i]) np++;
665         }
666         if (np) printf("%d differences in field data\n", np);
667     }
668 
669 #endif
670     free (xcoord);
671 
672     puts("deleting Elements and Faces and creating Mixed");
673 
674     /* delete sections and create as mixed */
675 
676     if (cg_goto(cgfile, cgbase, "Zone_t", 1, NULL) ||
677         cg_delete_node("Elements") || cg_delete_node("Faces"))
678         cg_error_exit();
679 
680     if (cg_section_partial_write(cgfile, cgbase, cgzone, "Mixed",
681 	    CGNS_ENUMV(MIXED), (cgsize_t)1, (cgsize_t)(nelems + nfaces),
682 	    0, &cgsect))
683         cg_error_exit();
684 
685     /* create mixed element connectivity */
686 
687     nn = (nelems << 3) + nelems + (nfaces << 2) + nfaces;
688     ptmp = (cgsize_t *) malloc (2 * nn * sizeof(cgsize_t));
689 
690     offsets = (cgsize_t *) malloc ((nelems+nfaces+1)* sizeof(cgsize_t));
691     offsets[0] = 0;
692 
693     i = j = n = l = 0;
694     for (nf = 0; nf < nelems; nf++) {
695         ptmp[n++] = CGNS_ENUMV(QUAD_4);
696         for (k = 0; k < 4; k++)
697             ptmp[n++] = faces[j++];
698         offsets[l+1] = offsets[l] + 5;
699         l++;
700         ptmp[n++] = CGNS_ENUMV(HEXA_8);
701         for (k = 0; k < 8; k++)
702             ptmp[n++] = elements[i++];
703         offsets[l+1] = offsets[l] + 9;
704         l++;
705     }
706     while (nf++ < nfaces) {
707         ptmp[n++] = CGNS_ENUMV(QUAD_4);
708         for (k = 0; k < 4; k++)
709             ptmp[n++] = faces[j++];
710         offsets[l+1] = offsets[l] + 5;
711         l++;
712     }
713 
714     free (elements);
715     elements = ptmp;
716     ibuf = elements + nn;
717 
718     /* create parent data */
719 
720     np = nelems + nfaces;
721     nn = np << 2;
722     ptmp = (cgsize_t *) malloc (3 * nn * sizeof(cgsize_t));
723 
724     for (n = 0; n < nfaces; n++)
725         parent[n] <<= 1;
726 
727     for (n = 0; n < nn; n++)
728         ptmp[n] = 0;
729     for (n = 0, j = 0; j < 4; j++) {
730         k = j * np;
731         for (i = 0; i < nelems; i++) {
732             ptmp[k] = parent[n++];
733             k += 2;
734         }
735         while (i++ < nfaces)
736             ptmp[k++] = parent[n++];
737     }
738 
739     free(faces);
740     parent = ptmp;
741     ptmp = parent + nn;
742     pbuf = ptmp + nn;
743 
744     rmin = 2 * nelems + 1;
745     rmax = np;
746     n = mixed_offset((int)rmin, nelems);
747     get_parent((int)rmin, (int)rmax, 0, np);
748 
749     printf("mixed %d -> %d\n", (int)rmin, (int)rmax);
750     if (cg_poly_elements_partial_write(cgfile, cgbase, cgzone,
751             cgsect, rmin, rmax, &elements[n], &offsets[rmin-1]) ||
752         cg_parent_data_partial_write(cgfile, cgbase, cgzone,
753             cgsect, rmin, rmax, ptmp))
754         cg_error_exit();
755 
756     printf("mixed %d -> %d (2 at a time)\n", 1, nelems << 1);
757     for (i = 0; i < nelems; i++) {
758         rmin = (i << 1) + 1;
759         rmax = rmin + 1;
760         n = mixed_offset((int)rmin, nelems);
761         get_parent((int)rmin, (int)rmax, 0, np);
762         if (cg_poly_elements_partial_write(cgfile, cgbase, cgzone,
763                 cgsect, rmin, rmax, &elements[n], &offsets[rmin-1]) ||
764             cg_parent_data_partial_write(cgfile, cgbase, cgzone,
765                 cgsect, rmin, rmax, ptmp))
766             cg_error_exit();
767     }
768 
769 #if NUM_RANDOM > 0
770 
771     /* do random writes */
772 
773     puts("doing random writes");
774 
775     for (k = 0; k < NUM_RANDOM; k++) {
776         rmin = irandom(1, np);
777         rmax = irandom(1, np);
778         if (rmin > rmax) {
779             nr = rmin;
780             rmin = rmax;
781             rmax = nr;
782         }
783         n = mixed_offset((int)rmin, nelems);
784         get_parent((int)rmin, (int)rmax, 0, np);
785         printf("mixed %d -> %d\n", (int)rmin, (int)rmax);
786         if (cg_poly_elements_partial_write(cgfile, cgbase, cgzone,
787                 cgsect, rmin, rmax, &elements[n], &offsets[rmin-1]) ||
788             cg_parent_data_partial_write(cgfile, cgbase, cgzone,
789                 cgsect, rmin, rmax, ptmp))
790             cg_error_exit();
791     }
792 
793 #endif
794 
795     puts("checking the data");
796 
797     if (cg_section_read(cgfile, cgbase, cgzone, cgsect, name,
798             &type, &is, &ie, &k, &n) ||
799         cg_poly_elements_read(cgfile, cgbase, cgzone, cgsect, ibuf, offsets, pbuf))
800         cg_error_exit();
801     if (strcmp(name, "Mixed") || type != CGNS_ENUMV(MIXED) || is != 1 ||
802         ie != np || k != 0 || n != 1) {
803         puts("differences in Mixed");
804     }
805     nn = mixed_offset(np, nelems);
806     for (i = 0, n = 0; n < nn; n++) {
807         if (elements[n] != ibuf[n]) i++;
808     }
809     if (i) printf("%d differences in Mixed connectivity\n", i);
810 
811     nn = (nelems + nfaces) << 2;
812     for (i = 0, n = 0; n < nn; n++) {
813         if (parent[n] != pbuf[n]) i++;
814     }
815     if (i) printf("%d differences in Mixed parent data\n", i);
816 
817 #if NUM_RANDOM > 0
818 
819     /* do random checks */
820 
821     puts("doing random reads/checks");
822 
823     for (k = 0; k < NUM_RANDOM; k++) {
824         rmin = irandom(1, np);
825         rmax = irandom(1, np);
826         if (rmin > rmax) {
827             nr = rmin;
828             rmin = rmax;
829             rmax = nr;
830         }
831         n = mixed_offset((int)rmin, nelems);
832         nn = mixed_offset((int)(rmax + 1), nelems) - n;
833         get_parent((int)rmin, (int)rmax, 0, np);
834         printf("mixed %d -> %d\n", (int)rmin, (int)rmax);
835         if (cg_ElementPartialSize(cgfile, cgbase, cgzone, cgsect,
836                 rmin, rmax, &nr) ||
837             cg_poly_elements_partial_read(cgfile, cgbase, cgzone, cgsect,
838                 rmin, rmax, ibuf, offsets, pbuf))
839             cg_error_exit();
840         if (nr != nn) puts("difference in mixed data size");
841         for (nf = 0, i = 0; i < nn; i++) {
842             if (ibuf[i] != elements[n+i]) nf++;
843         }
844         if (nf) printf("%d differences in mixed connectivity\n", nf);
845         nn = (int)(rmax - rmin + 1) << 2;
846         for (nf = 0, i = 0; i < nn; i++) {
847             if (pbuf[i] != ptmp[i]) nf++;
848         }
849         if (nf) printf("%d differences in mixed parent data\n", nf);
850     }
851 
852 #endif
853 
854     puts ("closing file");
855     cg_close (cgfile);
856     free (elements);
857     free (offsets);
858     free (parent);
859 
860     return 0;
861 }
862 
863